chore: remove inspect.sandboxagent.dev in favor of /ui/

This commit is contained in:
Nathan Flurry 2026-02-01 21:58:54 -08:00
parent cacb63ef17
commit 05488f157c
10 changed files with 26 additions and 73 deletions

View file

@ -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 | | **Server** | Rust daemon (`sandbox-agent server`) exposing the HTTP + SSE API |
| **SDK** | TypeScript client with embedded and server modes | | **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 | | **CLI** | `sandbox-agent` (same binary, plus npm wrapper) mirrors the HTTP endpoints |
## Get Started ## Get Started
@ -172,7 +172,7 @@ npx sandbox-agent --help
### Inspector ### 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) ![Sandbox Agent Inspector](./.github/media/inspector.png)

View file

@ -19,11 +19,10 @@ sandbox-agent server [OPTIONS]
| `-n, --no-token` | - | Disable authentication (local dev only) | | `-n, --no-token` | - | Disable authentication (local dev only) |
| `-H, --host <HOST>` | `127.0.0.1` | Host to bind to | | `-H, --host <HOST>` | `127.0.0.1` | Host to bind to |
| `-p, --port <PORT>` | `2468` | Port to bind to | | `-p, --port <PORT>` | `2468` | Port to bind to |
| `-O, --cors-allow-origin <ORIGIN>` | - | Additional CORS origin (repeatable, cumulative with Inspector) | | `-O, --cors-allow-origin <ORIGIN>` | - | CORS origin to allow (repeatable) |
| `-M, --cors-allow-method <METHOD>` | all | CORS allowed method (repeatable) | | `-M, --cors-allow-method <METHOD>` | all | CORS allowed method (repeatable) |
| `-A, --cors-allow-header <HEADER>` | all | CORS allowed header (repeatable) | | `-A, --cors-allow-header <HEADER>` | all | CORS allowed header (repeatable) |
| `-C, --cors-allow-credentials` | - | Enable CORS credentials | | `-C, --cors-allow-credentials` | - | Enable CORS credentials |
| `--no-inspector-cors` | - | Disable default Inspector CORS |
| `--no-telemetry` | - | Disable anonymous telemetry | | `--no-telemetry` | - | Disable anonymous telemetry |
```bash ```bash

View file

@ -9,47 +9,26 @@ When calling the Sandbox Agent server from a browser, CORS (Cross-Origin Resourc
## Default Behavior ## 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 ```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 \ sandbox-agent server \
--token "$SANDBOX_TOKEN" \ --token "$SANDBOX_TOKEN" \
--cors-allow-origin "http://localhost:5173" --cors-allow-origin "http://localhost:5173"
``` ```
<Note>
The built-in Inspector UI at `/ui/` is served from the same origin as the server, so it does not require CORS configuration.
</Note>
## Options ## Options
| Flag | Description | | 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-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-header` | Headers to allow (defaults to all if not specified) |
| `--cors-allow-credentials` | Allow credentials (cookies, authorization headers) | | `--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 ## Multiple Origins

View file

@ -12,9 +12,9 @@ The Inspector is a web-based GUI for debugging and inspecting Sandbox Agent sess
## Open the Inspector ## 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 ```typescript
import { buildInspectorUrl } from "sandbox-agent"; import { buildInspectorUrl } from "sandbox-agent";
@ -24,7 +24,7 @@ const url = buildInspectorUrl({
token: process.env.SANDBOX_TOKEN, token: process.env.SANDBOX_TOKEN,
}); });
console.log(url); 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 ## Features

View file

@ -290,7 +290,7 @@ icon: "rocket"
</Step> </Step>
<Step title="Test with Inspector"> <Step title="Test with Inspector">
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.
<Frame> <Frame>
<img src="/images/inspector.png" alt="Sandbox Agent Inspector" /> <img src="/images/inspector.png" alt="Sandbox Agent Inspector" />

View file

@ -132,7 +132,7 @@ const url = buildInspectorUrl({
headers: { "X-Custom-Header": "value" }, headers: { "X-Custom-Header": "value" },
}); });
console.log(url); 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: Parameters:

View file

@ -18,8 +18,6 @@ export function ensureUrl(rawUrl: string): string {
return `https://${rawUrl}`; return `https://${rawUrl}`;
} }
const INSPECTOR_URL = "https://inspect.sandboxagent.dev";
export function buildInspectorUrl({ export function buildInspectorUrl({
baseUrl, baseUrl,
token, token,
@ -30,14 +28,15 @@ export function buildInspectorUrl({
headers?: Record<string, string>; headers?: Record<string, string>;
}): string { }): string {
const normalized = normalizeBaseUrl(ensureUrl(baseUrl)); const normalized = normalizeBaseUrl(ensureUrl(baseUrl));
const params = new URLSearchParams({ url: normalized }); const params = new URLSearchParams();
if (token) { if (token) {
params.set("token", token); params.set("token", token);
} }
if (headers && Object.keys(headers).length > 0) { if (headers && Object.keys(headers).length > 0) {
params.set("headers", JSON.stringify(headers)); params.set("headers", JSON.stringify(headers));
} }
return `${INSPECTOR_URL}?${params.toString()}`; const queryString = params.toString();
return `${normalized}/ui/${queryString ? `?${queryString}` : ""}`;
} }
export function logInspectorUrl({ export function logInspectorUrl({
@ -432,11 +431,11 @@ export async function runPrompt(options: RunPromptOptions): Promise<void> {
} }
} }
// Print text deltas // Print text deltas (only during assistant turn)
if (event.type === "item.delta") { if (event.type === "item.delta" && isThinking) {
const delta = (event.data as any)?.delta; const delta = (event.data as any)?.delta;
if (delta) { if (delta) {
if (isThinking && !hasStartedOutput) { if (!hasStartedOutput) {
process.stdout.write("\r\x1b[K"); // Clear line process.stdout.write("\r\x1b[K"); // Clear line
hasStartedOutput = true; hasStartedOutput = true;
} }

View file

@ -1,7 +1,5 @@
'use client'; 'use client';
import { ArrowRight } from 'lucide-react';
export function Inspector() { export function Inspector() {
return ( return (
<section className="relative overflow-hidden border-t border-white/5 py-24"> <section className="relative overflow-hidden border-t border-white/5 py-24">
@ -13,23 +11,13 @@ export function Inspector() {
Inspect sessions, view event payloads, and troubleshoot without writing code. Inspect sessions, view event payloads, and troubleshoot without writing code.
</p> </p>
<div className="mb-10 overflow-hidden rounded-2xl border border-white/10 shadow-2xl"> <div className="overflow-hidden rounded-2xl border border-white/10 shadow-2xl">
<img <img
src="/images/inspector.png" src="/images/inspector.png"
alt="Sandbox Agent Inspector" alt="Sandbox Agent Inspector"
className="w-full" className="w-full"
/> />
</div> </div>
<a
href="https://inspect.sandboxagent.dev"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md border border-white/10 bg-white px-5 py-2.5 text-sm font-medium text-black subpixel-antialiased shadow-sm transition-colors hover:bg-zinc-200"
>
Open Inspector
<ArrowRight className="h-4 w-4" />
</a>
</div> </div>
</section> </section>
); );

View file

@ -1,5 +1,3 @@
const INSPECTOR_URL = "https://inspect.sandboxagent.dev";
export interface InspectorUrlOptions { export interface InspectorUrlOptions {
/** /**
* Base URL of the sandbox-agent server. * 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. * 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 { export function buildInspectorUrl(options: InspectorUrlOptions): string {
const normalized = options.baseUrl.replace(/\/+$/, ""); const normalized = options.baseUrl.replace(/\/+$/, "");
const params = new URLSearchParams({ url: normalized }); const params = new URLSearchParams();
if (options.token) { if (options.token) {
params.set("token", options.token); params.set("token", options.token);
} }
if (options.headers && Object.keys(options.headers).length > 0) { if (options.headers && Object.keys(options.headers).length > 0) {
params.set("headers", JSON.stringify(options.headers)); params.set("headers", JSON.stringify(options.headers));
} }
return `${INSPECTOR_URL}?${params.toString()}`; const queryString = params.toString();
return `${normalized}/ui/${queryString ? `?${queryString}` : ""}`;
} }

View file

@ -79,10 +79,6 @@ struct ServerArgs {
#[arg(long = "cors-allow-credentials", short = 'C')] #[arg(long = "cors-allow-credentials", short = 'C')]
cors_allow_credentials: bool, 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")] #[arg(long = "no-telemetry")]
no_telemetry: bool, no_telemetry: bool,
} }
@ -848,19 +844,11 @@ fn available_providers(credentials: &ExtractedCredentials) -> Vec<String> {
providers providers
} }
const INSPECTOR_ORIGIN: &str = "https://inspect.sandboxagent.dev";
fn build_cors_layer(server: &ServerArgs) -> Result<CorsLayer, CliError> { fn build_cors_layer(server: &ServerArgs) -> Result<CorsLayer, CliError> {
let mut cors = CorsLayer::new(); 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(); 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 { for origin in &server.cors_allow_origin {
let value = origin let value = origin
.parse() .parse()