Skip to content

fix: show actual configured model in plugin banner - #78

Closed
WuKongAI-CMU wants to merge 1 commit into
NVIDIA:mainfrom
WuKongAI-CMU:fix/dynamic-model-banner
Closed

fix: show actual configured model in plugin banner#78
WuKongAI-CMU wants to merge 1 commit into
NVIDIA:mainfrom
WuKongAI-CMU:fix/dynamic-model-banner

Conversation

@WuKongAI-CMU

Copy link
Copy Markdown
Contributor

Summary

Fixes #24 — the in-sandbox plugin banner now reflects the actual configured inference provider instead of a hardcoded default.

  • When the onboard config is unavailable (common inside the sandbox), queries the live openshell inference get --json for the actual model and endpoint
  • Falls back to the hardcoded default only if both the config file and OpenShell query fail
  • 3-second timeout on the OpenShell query to avoid blocking plugin registration

Test plan

  • TypeScript builds clean (npm run build)
  • Existing tests pass (19/19)
  • Manual: configure a non-default model, verify banner shows the correct model name
  • Manual: with no openshell installed, verify banner falls back gracefully to default

🤖 Generated with Claude Code

When the onboard config file is not available (e.g. inside the
sandbox), the plugin banner hardcoded the model as
nvidia/nemotron-3-super-120b-a12b regardless of what was actually
configured. Now the banner queries the live OpenShell inference
configuration as a fallback before resorting to the hardcoded default.

Closes NVIDIA#24

Signed-off-by: peteryuqin <peter.yuqin@gmail.com>
@WuKongAI-CMU

Copy link
Copy Markdown
Contributor Author

Closing to reduce my open PR count below the repo policy limit and refocus on a smaller set of higher-signal changes. I can revive this branch later if it becomes the right path again.

mafueee pushed a commit to mafueee/NemoClaw that referenced this pull request Mar 28, 2026
… logs (!55)

Closes NVIDIA#78

## What You Can Do

### Live policy updates
Update a running sandbox's network policy without recreating it:
```bash
nav sandbox policy set <sandbox> --policy new-policy.yaml --wait --timeout 60
```
The sandbox hot-reloads the policy within 30s (configurable). On failure, the previous policy stays active (last-known-good).

Idempotent — submitting the same policy twice returns the existing version:
```
✓ Policy version 3 submitted (hash: a1b2c3d4e5f6)
$ nav sandbox policy set test --policy same.yaml
· Policy unchanged (version 3, hash: a1b2c3d4e5f6)
```

### Policy history & inspection
```bash
nav sandbox policy list <sandbox>          # version history with status
nav sandbox policy get <sandbox>           # current policy metadata
nav sandbox policy get <sandbox> --full    # print full policy as YAML
nav sandbox policy get <sandbox> --rev 2 --full  # specific revision as YAML
```

### Sandbox logs
Stream logs from both the gateway and sandbox supervisor in one view:
```bash
nav sandbox logs <sandbox>                      # one-shot, last 2000 lines
nav sandbox logs <sandbox> --tail               # live streaming
nav sandbox logs <sandbox> --source sandbox     # supervisor logs only
nav sandbox logs <sandbox> --source gateway     # gateway logs only
nav sandbox logs <sandbox> --level warn         # warnings and errors only
nav sandbox logs <sandbox> --since 5m           # last 5 minutes
nav sandbox logs <sandbox> --tail --source sandbox --level info
```

Each log line is tagged with its source and includes structured fields:
```
[1772055394.673] [sandbox] [INFO ] [navigator_sandbox::proxy] CONNECT action=allow dst_host=api.anthropic.com dst_port=443 policy=claude_code
[1772055061.005] [gateway] [INFO ] [navigator_server::grpc] GetSandboxPolicy served from policy history
```

---

## Implementation

### Proto changes
- 7 new RPCs: `UpdateSandboxPolicy`, `GetSandboxPolicyStatus`, `ListSandboxPolicies`, `ReportPolicyStatus`, `GetSandboxLogs`, `PushSandboxLogs` (client-streaming)
- `SandboxLogLine`: added `source` (gateway/sandbox), `fields` (structured key-value map)
- `WatchSandboxRequest`: added `log_since_ms`, `log_sources`, `log_min_level`
- `GetSandboxLogsRequest`: added `sources`, `min_level`
- `PolicyStatus` enum, `SandboxPolicyRevision` message
- `Sandbox.current_policy_version` field

### Server
- **Policy persistence**: New `sandbox_policies` table (SQLite + Postgres) with per-sandbox monotonic versions, status tracking, and policy hash
- **UpdateSandboxPolicy**: Validates static field immutability (filesystem/landlock/process), network mode consistency (Block↔Proxy), deterministic hash comparison for idempotent updates
- **Lazy backfill**: First `GetSandboxPolicy` call creates version 1 from `spec.policy` for existing sandboxes
- **Log broker**: `TracingLogBus::publish_external()` injects sandbox-pushed logs into the same broadcast channel + tail buffer (2000 lines). Server forces `source="sandbox"` and `sandbox_id` on all pushed logs
- **Source/level filtering**: Applied server-side in both `GetSandboxLogs` and `WatchSandbox` streams
- **Version supersession**: When a new version is loaded, all older pending+loaded versions are marked superseded

### Sandbox
- **`OpaEngine::reload_from_proto()`**: Full `from_proto()` pipeline (L7 validation, access preset expansion) with atomic engine swap. On failure, previous engine untouched (LKG)
- **Policy poll loop**: Background task polls every 30s (configurable via `NAVIGATOR_POLICY_POLL_INTERVAL_SECS`), reports status via `ReportPolicyStatus` RPC
- **`LogPushLayer`**: Tracing layer captures events at INFO+ (configurable via `NAVIGATOR_LOG_PUSH_LEVEL`), sends structured fields via `PushSandboxLogs` client-streaming RPC. Background task batches 50 lines / flushes every 500ms. Best-effort (drops on full channel, never blocks)
- **`CachedNavigatorClient`**: Persistent mTLS channel for both policy polling and log push

### Database migration
- `002_create_sandbox_policies.sql` (SQLite + Postgres)

## Tests
- **Unit**: 8 policy persistence tests (put/get/list/status/supersede/isolation)
- **Integration**: 4 test files updated with new RPC stubs
- **E2E**: `test_live_policy_update_and_logs` — full lifecycle: create → set same (unchanged) → push new → wait for load → verify connectivity → push same (unchanged) → verify history → fetch logs

## Documentation
- `architecture/sandbox.md`: Log streaming architecture, LogPushLayer, push task, server broker, source tagging, structured fields, CLI filtering, failure modes
- `architecture/security-policy.md`: Live update semantics, deterministic hashing, CLI filter flags, policy inspection
- `architecture/plans/issue-78-sandbox-log-streaming.md`: Design plan for log streaming

## Security
- Trust boundary documented: shared mTLS cert model (per-sandbox auth tracked in NVIDIA#80)
- Server forces `source="sandbox"` and `sandbox_id` on pushed logs (can't impersonate gateway or other sandboxes)
- Per-batch line cap (100) prevents flooding
@wscurran wscurran added the bug-fix PR fixes a bug or regression label Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix hardcoded model identity shown by the in-sandbox plugin/banner so it reflects the actual configured inference provider

2 participants