mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-18 19:03:48 +00:00
chore: recover ottawa workspace state
This commit is contained in:
parent
5d65013aa5
commit
25a31c8ab7
265 changed files with 1249 additions and 42839 deletions
29
server/packages/sandbox-agent/builtin-skills/CLAUDE.md
Normal file
29
server/packages/sandbox-agent/builtin-skills/CLAUDE.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Sandbox Agent Runtime
|
||||
|
||||
You are running inside a Sandbox Agent runtime.
|
||||
|
||||
## Process Management — MANDATORY
|
||||
|
||||
IMPORTANT: You MUST use the Sandbox Agent process HTTP API instead of running
|
||||
commands directly via the Bash tool for ALL of the following:
|
||||
|
||||
- Starting dev servers, build watchers, or any long-running background process
|
||||
- Monitoring, stopping, or restarting processes
|
||||
- Checking logs from background processes
|
||||
|
||||
Do NOT use the Bash tool with `run_in_background`, `&`, or `nohup` for these.
|
||||
Do NOT run `npm run dev`, `python -m http.server`, or similar
|
||||
commands directly in Bash. Instead, use curl to call the process HTTP API.
|
||||
|
||||
One-shot commands like `npm run build`, `npm test`, `make`, etc. that run to
|
||||
completion should be run directly with the Bash tool as normal.
|
||||
|
||||
Use the `sandbox-agent-processes` skill (auto-loaded) for the full API reference.
|
||||
Quick reference:
|
||||
|
||||
- **Start a managed process:** `curl -s -X POST $SANDBOX_AGENT_URL/v1/processes -H "Content-Type: application/json" -d '{"command":"npm","args":["run","dev"]}'`
|
||||
- **Check logs:** `curl -s "$SANDBOX_AGENT_URL/v1/processes/proc_1/logs?tail=20"`
|
||||
- **Stop a process:** `curl -s -X POST $SANDBOX_AGENT_URL/v1/processes/proc_1/stop`
|
||||
|
||||
The only exception is simple, quick inline commands (e.g., `ls`, `cat`, `echo`,
|
||||
`git status`) that do not need lifecycle management.
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
---
|
||||
name: sandbox-agent-processes
|
||||
description: >-
|
||||
Start, stop, and monitor long-lived processes (dev servers, builds, watchers)
|
||||
and run one-shot commands inside the sandbox via the Sandbox Agent process HTTP API.
|
||||
TRIGGER when: user asks to start a dev server, run a build watcher,
|
||||
manage background processes, check process logs, or needs a long-running command
|
||||
that outlives a single shell execution.
|
||||
DO NOT TRIGGER when: user wants to run a simple inline shell command with the Bash tool.
|
||||
user-invocable: false
|
||||
---
|
||||
|
||||
# Sandbox Agent Process Management
|
||||
|
||||
You are running inside a Sandbox Agent runtime. Use the process HTTP API
|
||||
documented below to manage processes. All endpoints are under `/v1/processes`.
|
||||
|
||||
The server URL is `$SANDBOX_AGENT_URL`. Use it as the base for all curl
|
||||
commands (e.g., `curl -s $SANDBOX_AGENT_URL/v1/processes`).
|
||||
All curl commands below should be run via the Bash tool.
|
||||
|
||||
---
|
||||
|
||||
## Run a one-shot command
|
||||
|
||||
Execute a command to completion and get stdout/stderr/exit code.
|
||||
|
||||
```bash
|
||||
curl -s -X POST $SANDBOX_AGENT_URL/v1/processes/run \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"command": "make",
|
||||
"args": ["build"],
|
||||
"cwd": "/workspace",
|
||||
"timeoutMs": 60000
|
||||
}'
|
||||
```
|
||||
|
||||
**Request fields:**
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `command` | string | yes | Program to execute |
|
||||
| `args` | string[] | no | Command arguments |
|
||||
| `cwd` | string | no | Working directory |
|
||||
| `env` | object | no | Extra environment variables |
|
||||
| `timeoutMs` | number | no | Timeout in ms (default: 30000) |
|
||||
| `maxOutputBytes` | number | no | Cap on captured output (default: 1MB) |
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"exitCode": 0,
|
||||
"timedOut": false,
|
||||
"stdout": "...",
|
||||
"stderr": "",
|
||||
"stdoutTruncated": false,
|
||||
"stderrTruncated": false,
|
||||
"durationMs": 2345
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Create a managed process
|
||||
|
||||
Spawn a long-lived process (e.g., dev server) that persists until stopped.
|
||||
|
||||
```bash
|
||||
curl -s -X POST $SANDBOX_AGENT_URL/v1/processes \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"command": "npm",
|
||||
"args": ["run", "dev"],
|
||||
"cwd": "/workspace"
|
||||
}'
|
||||
```
|
||||
|
||||
**Request fields:**
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `command` | string | yes | Program to execute |
|
||||
| `args` | string[] | no | Command arguments |
|
||||
| `cwd` | string | no | Working directory |
|
||||
| `env` | object | no | Extra environment variables |
|
||||
| `tty` | bool | no | Allocate a PTY (default: false) |
|
||||
| `interactive` | bool | no | Mark as interactive (default: false) |
|
||||
|
||||
**Response** (`ProcessInfo`):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "proc_1",
|
||||
"command": "npm",
|
||||
"args": ["run", "dev"],
|
||||
"cwd": "/workspace",
|
||||
"tty": false,
|
||||
"interactive": false,
|
||||
"status": "running",
|
||||
"pid": 12345,
|
||||
"exitCode": null,
|
||||
"createdAtMs": 1709866543221,
|
||||
"exitedAtMs": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## List processes
|
||||
|
||||
```bash
|
||||
curl -s $SANDBOX_AGENT_URL/v1/processes
|
||||
```
|
||||
|
||||
Returns `{ "processes": [ ...ProcessInfo ] }`.
|
||||
|
||||
---
|
||||
|
||||
## Get a single process
|
||||
|
||||
```bash
|
||||
curl -s $SANDBOX_AGENT_URL/v1/processes/proc_1
|
||||
```
|
||||
|
||||
Returns a `ProcessInfo` object. Check `status` (`"running"` or `"exited"`) and `exitCode`.
|
||||
|
||||
---
|
||||
|
||||
## Stop a process (SIGTERM)
|
||||
|
||||
```bash
|
||||
curl -s -X POST $SANDBOX_AGENT_URL/v1/processes/proc_1/stop
|
||||
```
|
||||
|
||||
Optionally wait for the process to exit:
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$SANDBOX_AGENT_URL/v1/processes/proc_1/stop?waitMs=5000"
|
||||
```
|
||||
|
||||
Returns updated `ProcessInfo`.
|
||||
|
||||
---
|
||||
|
||||
## Kill a process (SIGKILL)
|
||||
|
||||
```bash
|
||||
curl -s -X POST $SANDBOX_AGENT_URL/v1/processes/proc_1/kill
|
||||
```
|
||||
|
||||
Same interface as stop. Use when SIGTERM is not sufficient.
|
||||
|
||||
---
|
||||
|
||||
## Delete a process
|
||||
|
||||
Remove a stopped process from the list. Fails with 409 if still running.
|
||||
|
||||
```bash
|
||||
curl -s -X DELETE $SANDBOX_AGENT_URL/v1/processes/proc_1
|
||||
```
|
||||
|
||||
Returns 204 on success.
|
||||
|
||||
---
|
||||
|
||||
## Fetch process logs
|
||||
|
||||
Get buffered log output from a managed process.
|
||||
|
||||
```bash
|
||||
# All logs
|
||||
curl -s $SANDBOX_AGENT_URL/v1/processes/proc_1/logs
|
||||
|
||||
# Last 50 entries
|
||||
curl -s "$SANDBOX_AGENT_URL/v1/processes/proc_1/logs?tail=50"
|
||||
|
||||
# Only stdout
|
||||
curl -s "$SANDBOX_AGENT_URL/v1/processes/proc_1/logs?stream=stdout"
|
||||
```
|
||||
|
||||
**Query parameters:**
|
||||
|
||||
| Param | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `stream` | string | `stdout`, `stderr`, `combined`, or `pty` |
|
||||
| `tail` | number | Return only the last N entries |
|
||||
| `since` | number | Only entries with sequence > this value |
|
||||
| `follow` | bool | Stream live via SSE (see below) |
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"processId": "proc_1",
|
||||
"stream": "combined",
|
||||
"entries": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"stream": "stdout",
|
||||
"timestampMs": 1709866543221,
|
||||
"data": "aGVsbG8=",
|
||||
"encoding": "base64"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Log entry `data` is base64-encoded. Decode it to read the output.
|
||||
|
||||
---
|
||||
|
||||
## Follow logs via SSE
|
||||
|
||||
Stream live log output using Server-Sent Events:
|
||||
|
||||
```bash
|
||||
curl -s -N "$SANDBOX_AGENT_URL/v1/processes/proc_1/logs?follow=true"
|
||||
```
|
||||
|
||||
Each SSE event has type `log` and contains a JSON `ProcessLogEntry` as data.
|
||||
Use `since=<sequence>` to resume from a known position.
|
||||
|
||||
---
|
||||
|
||||
## Send input to a process
|
||||
|
||||
Write to a process's stdin (or PTY input for tty processes).
|
||||
|
||||
```bash
|
||||
curl -s -X POST $SANDBOX_AGENT_URL/v1/processes/proc_1/input \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"data": "echo hello\n", "encoding": "utf8"}'
|
||||
```
|
||||
|
||||
**Request fields:**
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `data` | string | yes | Input data |
|
||||
| `encoding` | string | no | `utf8`, `text`, or `base64` (default: `utf8`) |
|
||||
|
||||
Returns `{ "bytesWritten": 12 }`.
|
||||
|
||||
---
|
||||
|
||||
## Resize terminal (PTY only)
|
||||
|
||||
For processes started with `"tty": true`:
|
||||
|
||||
```bash
|
||||
curl -s -X POST $SANDBOX_AGENT_URL/v1/processes/proc_1/terminal/resize \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"cols": 120, "rows": 40}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Get/set runtime configuration
|
||||
|
||||
```bash
|
||||
# Get current config
|
||||
curl -s $SANDBOX_AGENT_URL/v1/processes/config
|
||||
|
||||
# Update config
|
||||
curl -s -X POST $SANDBOX_AGENT_URL/v1/processes/config \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"maxConcurrentProcesses": 32,
|
||||
"defaultRunTimeoutMs": 60000,
|
||||
"maxRunTimeoutMs": 300000,
|
||||
"maxOutputBytes": 2097152,
|
||||
"maxLogBytesPerProcess": 10485760,
|
||||
"maxInputBytesPerRequest": 65536
|
||||
}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common patterns
|
||||
|
||||
### Start a dev server and check it's running
|
||||
|
||||
```bash
|
||||
curl -s -X POST $SANDBOX_AGENT_URL/v1/processes \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"command":"npm","args":["run","dev"],"cwd":"/workspace"}'
|
||||
|
||||
# Wait a moment, then check logs for startup confirmation
|
||||
curl -s "$SANDBOX_AGENT_URL/v1/processes/proc_1/logs?tail=20"
|
||||
```
|
||||
|
||||
### Run a build and check for errors
|
||||
|
||||
```bash
|
||||
curl -s -X POST $SANDBOX_AGENT_URL/v1/processes/run \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"command":"npm","args":["run","build"],"cwd":"/workspace","timeoutMs":120000}'
|
||||
```
|
||||
|
||||
Check `exitCode` in the response. Non-zero means failure — read `stderr` for details.
|
||||
|
||||
### Stop and clean up a process
|
||||
|
||||
```bash
|
||||
curl -s -X POST "$SANDBOX_AGENT_URL/v1/processes/proc_1/stop?waitMs=5000"
|
||||
curl -s -X DELETE $SANDBOX_AGENT_URL/v1/processes/proc_1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error responses
|
||||
|
||||
Errors use `application/problem+json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "about:blank",
|
||||
"status": 409,
|
||||
"title": "Conflict",
|
||||
"detail": "max concurrent process limit reached (64)"
|
||||
}
|
||||
```
|
||||
|
||||
| Status | Meaning |
|
||||
|--------|---------|
|
||||
| 400 | Bad request (invalid encoding, malformed body) |
|
||||
| 404 | Process not found |
|
||||
| 409 | Conflict (process still running, or limit reached) |
|
||||
| 413 | Input payload too large |
|
||||
| 501 | Process API not supported on this platform |
|
||||
|
|
@ -26,6 +26,7 @@ struct AcpProxyRuntimeInner {
|
|||
agent_manager: Arc<AgentManager>,
|
||||
require_preinstall: bool,
|
||||
request_timeout: Duration,
|
||||
server_url: Option<String>,
|
||||
instances: RwLock<HashMap<String, Arc<ProxyInstance>>>,
|
||||
instance_locks: Mutex<HashMap<String, Arc<Mutex<()>>>>,
|
||||
install_locks: Mutex<HashMap<AgentId, Arc<Mutex<()>>>>,
|
||||
|
|
@ -56,7 +57,7 @@ pub type PinBoxSseStream =
|
|||
std::pin::Pin<Box<dyn Stream<Item = Result<Event, std::convert::Infallible>> + Send>>;
|
||||
|
||||
impl AcpProxyRuntime {
|
||||
pub fn new(agent_manager: Arc<AgentManager>) -> Self {
|
||||
pub fn new(agent_manager: Arc<AgentManager>, server_url: Option<String>) -> Self {
|
||||
let require_preinstall = std::env::var("SANDBOX_AGENT_REQUIRE_PREINSTALL")
|
||||
.ok()
|
||||
.is_some_and(|value| {
|
||||
|
|
@ -76,6 +77,7 @@ impl AcpProxyRuntime {
|
|||
agent_manager,
|
||||
require_preinstall,
|
||||
request_timeout,
|
||||
server_url,
|
||||
instances: RwLock::new(HashMap::new()),
|
||||
instance_locks: Mutex::new(HashMap::new()),
|
||||
install_locks: Mutex::new(HashMap::new()),
|
||||
|
|
@ -313,12 +315,17 @@ impl AcpProxyRuntime {
|
|||
"create_instance: launch spec resolved, spawning"
|
||||
);
|
||||
|
||||
let mut env = launch.env;
|
||||
if let Some(url) = &self.inner.server_url {
|
||||
env.insert("SANDBOX_AGENT_URL".to_string(), url.clone());
|
||||
}
|
||||
|
||||
let spawn_started = std::time::Instant::now();
|
||||
let runtime = AdapterRuntime::start(
|
||||
LaunchSpec {
|
||||
program: launch.program,
|
||||
args: launch.args,
|
||||
env: launch.env,
|
||||
env,
|
||||
},
|
||||
self.inner.request_timeout,
|
||||
)
|
||||
|
|
|
|||
162
server/packages/sandbox-agent/src/builtin_skills.rs
Normal file
162
server/packages/sandbox-agent/src/builtin_skills.rs
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
//! Built-in skills and CLAUDE.md instructions that are automatically written
|
||||
//! to the agent's config directory when an agent instance is created.
|
||||
//!
|
||||
//! Each skill is embedded at compile time from `builtin-skills/` and written to
|
||||
//! disk so the agent process can discover it. A global CLAUDE.md with behavioral
|
||||
//! directives is also injected into `~/.claude/CLAUDE.md`.
|
||||
//!
|
||||
//! Set `SANDBOX_AGENT_SKIP_BUILTIN_SKILLS=1` to disable auto-injection.
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Embedded content of the sandbox-agent-processes skill.
|
||||
const SANDBOX_AGENT_PROCESSES_SKILL: &str =
|
||||
include_str!("../builtin-skills/sandbox-agent-processes/SKILL.md");
|
||||
|
||||
/// Embedded CLAUDE.md with behavioral directives for the agent.
|
||||
const BUILTIN_CLAUDE_MD: &str = include_str!("../builtin-skills/CLAUDE.md");
|
||||
|
||||
/// Marker used to identify the sandbox-agent-managed section in CLAUDE.md.
|
||||
const CLAUDE_MD_MARKER_START: &str = "<!-- BEGIN SANDBOX-AGENT-MANAGED -->";
|
||||
const CLAUDE_MD_MARKER_END: &str = "<!-- END SANDBOX-AGENT-MANAGED -->";
|
||||
|
||||
/// Returns `true` if built-in skill injection is disabled via environment variable.
|
||||
fn is_disabled() -> bool {
|
||||
std::env::var("SANDBOX_AGENT_SKIP_BUILTIN_SKILLS")
|
||||
.ok()
|
||||
.is_some_and(|v| {
|
||||
let t = v.trim();
|
||||
t == "1" || t.eq_ignore_ascii_case("true") || t.eq_ignore_ascii_case("yes")
|
||||
})
|
||||
}
|
||||
|
||||
/// Writes all built-in skills and the global CLAUDE.md to the agent's personal
|
||||
/// config directory (`~/.claude/`). No-op if `SANDBOX_AGENT_SKIP_BUILTIN_SKILLS=1`.
|
||||
///
|
||||
/// The `server_url` is substituted into the content so the agent knows which
|
||||
/// endpoint to call.
|
||||
pub fn write_builtin_skills(server_url: Option<&str>) {
|
||||
if is_disabled() {
|
||||
tracing::debug!("builtin skills: injection disabled via SANDBOX_AGENT_SKIP_BUILTIN_SKILLS");
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(home) = dirs::home_dir() else {
|
||||
tracing::warn!("builtin skills: cannot determine home directory, skipping");
|
||||
return;
|
||||
};
|
||||
|
||||
let claude_dir = home.join(".claude");
|
||||
|
||||
// Write skills
|
||||
let skills_dir = claude_dir.join("skills");
|
||||
write_skill(
|
||||
&skills_dir,
|
||||
"sandbox-agent-processes",
|
||||
SANDBOX_AGENT_PROCESSES_SKILL,
|
||||
server_url,
|
||||
);
|
||||
|
||||
// Write/update CLAUDE.md with behavioral directives
|
||||
write_claude_md(&claude_dir, server_url);
|
||||
}
|
||||
|
||||
/// Writes a single skill's SKILL.md into `{skills_dir}/{name}/SKILL.md`,
|
||||
/// creating directories as needed.
|
||||
fn write_skill(skills_dir: &PathBuf, name: &str, content: &str, server_url: Option<&str>) {
|
||||
let dir = skills_dir.join(name);
|
||||
if let Err(err) = fs::create_dir_all(&dir) {
|
||||
tracing::warn!(
|
||||
skill = name,
|
||||
error = %err,
|
||||
"builtin skills: failed to create skill directory"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let final_content = substitute_url(content, server_url);
|
||||
|
||||
let path = dir.join("SKILL.md");
|
||||
match fs::write(&path, final_content) {
|
||||
Ok(()) => {
|
||||
tracing::info!(skill = name, path = %path.display(), "builtin skills: written");
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::warn!(
|
||||
skill = name,
|
||||
error = %err,
|
||||
"builtin skills: failed to write SKILL.md"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes or updates the sandbox-agent-managed section of `~/.claude/CLAUDE.md`.
|
||||
///
|
||||
/// If the file already exists, only the section between the marker comments is
|
||||
/// replaced. If no markers exist, the section is appended. If the file does not
|
||||
/// exist, it is created.
|
||||
fn write_claude_md(claude_dir: &PathBuf, server_url: Option<&str>) {
|
||||
let path = claude_dir.join("CLAUDE.md");
|
||||
let managed_block = format!(
|
||||
"{}\n{}\n{}",
|
||||
CLAUDE_MD_MARKER_START,
|
||||
substitute_url(BUILTIN_CLAUDE_MD, server_url).trim(),
|
||||
CLAUDE_MD_MARKER_END,
|
||||
);
|
||||
|
||||
let new_content = match fs::read_to_string(&path) {
|
||||
Ok(existing) => {
|
||||
if let (Some(start), Some(end)) = (
|
||||
existing.find(CLAUDE_MD_MARKER_START),
|
||||
existing.find(CLAUDE_MD_MARKER_END),
|
||||
) {
|
||||
// Replace existing managed section
|
||||
let before = existing[..start].trim_end();
|
||||
let after = existing[end + CLAUDE_MD_MARKER_END.len()..].trim_start();
|
||||
if before.is_empty() && after.is_empty() {
|
||||
format!("{}\n", managed_block)
|
||||
} else if before.is_empty() {
|
||||
format!("{}\n\n{}", managed_block, after)
|
||||
} else if after.is_empty() {
|
||||
format!("{}\n\n{}\n", before, managed_block)
|
||||
} else {
|
||||
format!("{}\n\n{}\n\n{}", before, managed_block, after)
|
||||
}
|
||||
} else {
|
||||
// Append managed section
|
||||
if existing.trim().is_empty() {
|
||||
managed_block
|
||||
} else {
|
||||
format!("{}\n\n{}\n", existing.trim_end(), managed_block)
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
// File doesn't exist, create it
|
||||
format!("{}\n", managed_block)
|
||||
}
|
||||
};
|
||||
|
||||
match fs::write(&path, new_content) {
|
||||
Ok(()) => {
|
||||
tracing::info!(path = %path.display(), "builtin skills: CLAUDE.md written");
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::warn!(
|
||||
error = %err,
|
||||
"builtin skills: failed to write CLAUDE.md"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace `$SANDBOX_AGENT_URL` placeholder with the actual server URL.
|
||||
fn substitute_url(content: &str, server_url: Option<&str>) -> String {
|
||||
if let Some(url) = server_url {
|
||||
content.replace("$SANDBOX_AGENT_URL", url)
|
||||
} else {
|
||||
content.to_string()
|
||||
}
|
||||
}
|
||||
|
|
@ -421,7 +421,9 @@ fn run_server(cli: &CliConfig, server: &ServerArgs) -> Result<(), CliError> {
|
|||
|
||||
let agent_manager = AgentManager::new(default_install_dir())
|
||||
.map_err(|err| CliError::Server(err.to_string()))?;
|
||||
let state = Arc::new(AppState::with_branding(auth, agent_manager, branding));
|
||||
let server_url = format!("http://{}:{}", server.host, server.port);
|
||||
crate::builtin_skills::write_builtin_skills(Some(&server_url));
|
||||
let state = Arc::new(AppState::with_branding(auth, agent_manager, branding, Some(server_url)));
|
||||
let (mut router, state) = build_router_with_state(state);
|
||||
|
||||
let cors = build_cors_layer(server)?;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! Sandbox agent core utilities.
|
||||
|
||||
mod acp_proxy_runtime;
|
||||
pub mod builtin_skills;
|
||||
pub mod cli;
|
||||
pub mod daemon;
|
||||
mod process_runtime;
|
||||
|
|
|
|||
|
|
@ -93,16 +93,17 @@ pub struct AppState {
|
|||
|
||||
impl AppState {
|
||||
pub fn new(auth: AuthConfig, agent_manager: AgentManager) -> Self {
|
||||
Self::with_branding(auth, agent_manager, BrandingMode::SandboxAgent)
|
||||
Self::with_branding(auth, agent_manager, BrandingMode::SandboxAgent, None)
|
||||
}
|
||||
|
||||
pub fn with_branding(
|
||||
auth: AuthConfig,
|
||||
agent_manager: AgentManager,
|
||||
branding: BrandingMode,
|
||||
server_url: Option<String>,
|
||||
) -> Self {
|
||||
let agent_manager = Arc::new(agent_manager);
|
||||
let acp_proxy = Arc::new(AcpProxyRuntime::new(agent_manager.clone()));
|
||||
let acp_proxy = Arc::new(AcpProxyRuntime::new(agent_manager.clone(), server_url));
|
||||
let opencode_server_manager = Arc::new(OpenCodeServerManager::new(
|
||||
agent_manager.clone(),
|
||||
OpenCodeServerManagerConfig {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue