diff --git a/README.md b/README.md index 9224bf1..1f90841 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ The Sandbox Agent acts as a universal adapter between your client application an |-----------|-------------| | **Server** | Rust daemon (`sandbox-agent server`) exposing the HTTP + SSE API | | **SDK** | TypeScript client with embedded and server modes | -| **Inspector** | [inspect.sandboxagent.dev](https://inspect.sandboxagent.dev) for browsing sessions and events | +| **Inspector** | Built-in UI at inspecting sessions and events | | **CLI** | `sandbox-agent` (same binary, plus npm wrapper) mirrors the HTTP endpoints | ## Get Started @@ -172,7 +172,7 @@ npx sandbox-agent --help ### Inspector -Debug sessions and events with the [Inspector UI](https://inspect.sandboxagent.dev). +Debug sessions and events with the built-in Inspector UI (e.g., `http://localhost:2468/ui/`). ![Sandbox Agent Inspector](./.github/media/inspector.png) diff --git a/docs/cli.mdx b/docs/cli.mdx index 1d48812..855bd44 100644 --- a/docs/cli.mdx +++ b/docs/cli.mdx @@ -19,11 +19,10 @@ sandbox-agent server [OPTIONS] | `-n, --no-token` | - | Disable authentication (local dev only) | | `-H, --host ` | `127.0.0.1` | Host to bind to | | `-p, --port ` | `2468` | Port to bind to | -| `-O, --cors-allow-origin ` | - | Additional CORS origin (repeatable, cumulative with Inspector) | +| `-O, --cors-allow-origin ` | - | CORS origin to allow (repeatable) | | `-M, --cors-allow-method ` | all | CORS allowed method (repeatable) | | `-A, --cors-allow-header
` | all | CORS allowed header (repeatable) | | `-C, --cors-allow-credentials` | - | Enable CORS credentials | -| `--no-inspector-cors` | - | Disable default Inspector CORS | | `--no-telemetry` | - | Disable anonymous telemetry | ```bash diff --git a/docs/cors.mdx b/docs/cors.mdx index c9fe888..5e50888 100644 --- a/docs/cors.mdx +++ b/docs/cors.mdx @@ -9,47 +9,26 @@ When calling the Sandbox Agent server from a browser, CORS (Cross-Origin Resourc ## Default Behavior -By default, the server allows CORS requests from the [Inspector](https://inspect.sandboxagent.dev): +By default, no CORS origins are allowed. You must explicitly specify origins for browser-based applications: ```bash -# Inspector CORS is enabled by default -sandbox-agent server --token "$SANDBOX_TOKEN" -``` - -This allows you to use the hosted Inspector to connect to any running Sandbox Agent server without additional configuration. - -## Adding Origins - -Use `--cors-allow-origin` to allow additional origins. These are **cumulative** with the default Inspector origin: - -```bash -# Allows both Inspector AND localhost:5173 sandbox-agent server \ --token "$SANDBOX_TOKEN" \ --cors-allow-origin "http://localhost:5173" ``` + +The built-in Inspector UI at `/ui/` is served from the same origin as the server, so it does not require CORS configuration. + + ## Options | Flag | Description | |------|-------------| -| `--cors-allow-origin` | Additional origins to allow (cumulative with Inspector) | +| `--cors-allow-origin` | Origins to allow | | `--cors-allow-method` | HTTP methods to allow (defaults to all if not specified) | | `--cors-allow-header` | Headers to allow (defaults to all if not specified) | | `--cors-allow-credentials` | Allow credentials (cookies, authorization headers) | -| `--no-inspector-cors` | Disable the default Inspector origin | - -## Disabling Inspector CORS - -To disable the default Inspector origin and only allow explicitly specified origins: - -```bash -# Only allows localhost:5173, not Inspector -sandbox-agent server \ - --token "$SANDBOX_TOKEN" \ - --no-inspector-cors \ - --cors-allow-origin "http://localhost:5173" -``` ## Multiple Origins diff --git a/docs/inspector.mdx b/docs/inspector.mdx index b095ff2..8e80c22 100644 --- a/docs/inspector.mdx +++ b/docs/inspector.mdx @@ -12,9 +12,9 @@ The Inspector is a web-based GUI for debugging and inspecting Sandbox Agent sess ## Open the Inspector -Visit [inspect.sandboxagent.dev](https://inspect.sandboxagent.dev) and enter your server URL and token to connect. +The Inspector UI is served at `/ui/` on your sandbox-agent server. For example, if your server is running at `http://localhost:2468`, open `http://localhost:2468/ui/` in your browser. -You can also generate a pre-filled Inspector URL from the TypeScript SDK: +You can also generate a pre-filled Inspector URL with authentication from the TypeScript SDK: ```typescript import { buildInspectorUrl } from "sandbox-agent"; @@ -24,7 +24,7 @@ const url = buildInspectorUrl({ token: process.env.SANDBOX_TOKEN, }); console.log(url); -// https://inspect.sandboxagent.dev?url=http%3A%2F%2F127.0.0.1%3A2468&token=... +// http://127.0.0.1:2468/ui/?token=... ``` ## Features diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index b8bce19..4902344 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -290,7 +290,7 @@ icon: "rocket" - Open the [Inspector UI](https://inspect.sandboxagent.dev) to inspect session state using a GUI. + Open the Inspector UI at `/ui/` on your server (e.g., `http://localhost:2468/ui/`) to inspect session state using a GUI. Sandbox Agent Inspector diff --git a/docs/sdks/typescript.mdx b/docs/sdks/typescript.mdx index cbaf598..7ebc165 100644 --- a/docs/sdks/typescript.mdx +++ b/docs/sdks/typescript.mdx @@ -132,7 +132,7 @@ const url = buildInspectorUrl({ headers: { "X-Custom-Header": "value" }, }); console.log(url); -// https://inspect.sandboxagent.dev?url=https%3A%2F%2Fyour-sandbox-agent.example.com&token=...&headers=... +// https://your-sandbox-agent.example.com/ui/?token=...&headers=... ``` Parameters: diff --git a/examples/shared/src/sandbox-agent-client.ts b/examples/shared/src/sandbox-agent-client.ts index 2ccd8f6..ff80f3b 100644 --- a/examples/shared/src/sandbox-agent-client.ts +++ b/examples/shared/src/sandbox-agent-client.ts @@ -18,8 +18,6 @@ export function ensureUrl(rawUrl: string): string { return `https://${rawUrl}`; } -const INSPECTOR_URL = "https://inspect.sandboxagent.dev"; - export function buildInspectorUrl({ baseUrl, token, @@ -30,14 +28,15 @@ export function buildInspectorUrl({ headers?: Record; }): string { const normalized = normalizeBaseUrl(ensureUrl(baseUrl)); - const params = new URLSearchParams({ url: normalized }); + const params = new URLSearchParams(); if (token) { params.set("token", token); } if (headers && Object.keys(headers).length > 0) { params.set("headers", JSON.stringify(headers)); } - return `${INSPECTOR_URL}?${params.toString()}`; + const queryString = params.toString(); + return `${normalized}/ui/${queryString ? `?${queryString}` : ""}`; } export function logInspectorUrl({ @@ -432,11 +431,11 @@ export async function runPrompt(options: RunPromptOptions): Promise { } } - // Print text deltas - if (event.type === "item.delta") { + // Print text deltas (only during assistant turn) + if (event.type === "item.delta" && isThinking) { const delta = (event.data as any)?.delta; if (delta) { - if (isThinking && !hasStartedOutput) { + if (!hasStartedOutput) { process.stdout.write("\r\x1b[K"); // Clear line hasStartedOutput = true; } diff --git a/frontend/packages/website/src/components/Inspector.tsx b/frontend/packages/website/src/components/Inspector.tsx index c0c7b71..7e29185 100644 --- a/frontend/packages/website/src/components/Inspector.tsx +++ b/frontend/packages/website/src/components/Inspector.tsx @@ -1,7 +1,5 @@ 'use client'; -import { ArrowRight } from 'lucide-react'; - export function Inspector() { return (
@@ -13,23 +11,13 @@ export function Inspector() { Inspect sessions, view event payloads, and troubleshoot without writing code.

-
); diff --git a/sdks/typescript/src/inspector.ts b/sdks/typescript/src/inspector.ts index 9c448e2..dfc830d 100644 --- a/sdks/typescript/src/inspector.ts +++ b/sdks/typescript/src/inspector.ts @@ -1,5 +1,3 @@ -const INSPECTOR_URL = "https://inspect.sandboxagent.dev"; - export interface InspectorUrlOptions { /** * Base URL of the sandbox-agent server. @@ -18,15 +16,17 @@ export interface InspectorUrlOptions { /** * Builds a URL to the sandbox-agent inspector UI with the given connection parameters. + * The inspector UI is served at /ui/ on the sandbox-agent server. */ export function buildInspectorUrl(options: InspectorUrlOptions): string { const normalized = options.baseUrl.replace(/\/+$/, ""); - const params = new URLSearchParams({ url: normalized }); + const params = new URLSearchParams(); if (options.token) { params.set("token", options.token); } if (options.headers && Object.keys(options.headers).length > 0) { params.set("headers", JSON.stringify(options.headers)); } - return `${INSPECTOR_URL}?${params.toString()}`; + const queryString = params.toString(); + return `${normalized}/ui/${queryString ? `?${queryString}` : ""}`; } diff --git a/server/packages/sandbox-agent/src/main.rs b/server/packages/sandbox-agent/src/main.rs index c0a57ff..8904ddd 100644 --- a/server/packages/sandbox-agent/src/main.rs +++ b/server/packages/sandbox-agent/src/main.rs @@ -79,10 +79,6 @@ struct ServerArgs { #[arg(long = "cors-allow-credentials", short = 'C')] cors_allow_credentials: bool, - /// Disable default CORS for the inspector (https://inspect.sandboxagent.dev) - #[arg(long = "no-inspector-cors")] - no_inspector_cors: bool, - #[arg(long = "no-telemetry")] no_telemetry: bool, } @@ -848,19 +844,11 @@ fn available_providers(credentials: &ExtractedCredentials) -> Vec { providers } -const INSPECTOR_ORIGIN: &str = "https://inspect.sandboxagent.dev"; - fn build_cors_layer(server: &ServerArgs) -> Result { let mut cors = CorsLayer::new(); - // Build origins list: inspector by default + any additional origins + // Build origins list from provided origins let mut origins = Vec::new(); - if !server.no_inspector_cors { - let inspector_origin = INSPECTOR_ORIGIN - .parse() - .map_err(|_| CliError::InvalidCorsOrigin(INSPECTOR_ORIGIN.to_string()))?; - origins.push(inspector_origin); - } for origin in &server.cors_allow_origin { let value = origin .parse()