mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-15 11:02:20 +00:00
fix: credential detection and provider auth status (#120)
## Summary Fix credential detection bugs and add credential availability status to the API. Consolidate Claude fallback models and add `sonnet` alias. Builds on #109 (OAuth token support). Related issues: - Fixes #117 (Claude, Codex not showing up in gigacode) - Related to #113 (Default agent should be Claude Code) ## Changes ### Credential detection fixes - **`agent-credentials/src/lib.rs`**: Fix `?` operator bug in `extract_claude_credentials` - now continues to next config path if one is missing instead of returning early ### API credential status - **`sandbox-agent/src/router.rs`**: Add `credentialsAvailable` field to `AgentInfo` struct - **`/v1/agents`** endpoint now reports whether each agent has valid credentials ### OpenCode provider improvements - **`sandbox-agent/src/opencode_compat.rs`**: Build `connected` array based on actual credential availability, not just model presence - Check provider-specific credentials for OpenCode groups (e.g., `opencode:anthropic` only connected if Anthropic creds available) - Add logging when credential extraction fails in model cache building ### Fallback model consolidation - Renamed `claude_oauth_fallback_models()` → `claude_fallback_models()` (used for all fallback cases, not just OAuth) - Added `sonnet` to fallback models (confirmed working via headless CLI test) - Added `codex_fallback_models()` for Codex when credentials missing - Added comment explaining aliases work for both API and OAuth users ### Documentation - **`docs/credentials.mdx`**: New reference doc covering credential sources, extraction behavior, and error handling - Documents that extraction failures are silent (not errors) - Documents that agents spawn without credential pre-validation ### Inspector UI - **`AgentsTab.tsx`**: Added credential status pill showing "Authenticated" or "No Credentials" ## Error Handling Philosophy - **Extraction failures are silent**: Missing/malformed config files don't error, just continue to next source - **Agents spawn without credential validation**: No pre-flight auth check; agent's native error surfaces if credentials are missing - **Fallback models for UI**: When credentials missing, show alias-based models so users can still configure sessions ## Validation - Tested Claude Code model aliases via headless CLI: - `claude --model default --print "say hi"` ✓ - `claude --model sonnet --print "say hi"` ✓ - `claude --model haiku --print "say hi"` ✓ - Build passes - TypeScript types regenerated with `credentialsAvailable` field
This commit is contained in:
parent
915d484845
commit
c54f83e1a6
13 changed files with 807 additions and 9 deletions
144
docs/credentials.mdx
Normal file
144
docs/credentials.mdx
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
---
|
||||
title: "Credentials"
|
||||
description: "How sandbox-agent discovers and uses provider credentials."
|
||||
icon: "key"
|
||||
---
|
||||
|
||||
Sandbox-agent automatically discovers API credentials from environment variables and agent config files. Credentials are used to authenticate with AI providers (Anthropic, OpenAI) when spawning agents.
|
||||
|
||||
## Credential sources
|
||||
|
||||
Credentials are extracted in priority order. The first valid credential found for each provider is used.
|
||||
|
||||
### Environment variables (highest priority)
|
||||
|
||||
**API keys** (checked first):
|
||||
|
||||
| Variable | Provider |
|
||||
|----------|----------|
|
||||
| `ANTHROPIC_API_KEY` | Anthropic |
|
||||
| `CLAUDE_API_KEY` | Anthropic (fallback) |
|
||||
| `OPENAI_API_KEY` | OpenAI |
|
||||
| `CODEX_API_KEY` | OpenAI (fallback) |
|
||||
|
||||
**OAuth tokens** (checked if no API key found):
|
||||
|
||||
| Variable | Provider |
|
||||
|----------|----------|
|
||||
| `CLAUDE_CODE_OAUTH_TOKEN` | Anthropic (OAuth) |
|
||||
| `ANTHROPIC_AUTH_TOKEN` | Anthropic (OAuth fallback) |
|
||||
|
||||
OAuth tokens from environment variables are only used when `include_oauth` is enabled (the default).
|
||||
|
||||
### Agent config files
|
||||
|
||||
If no environment variable is set, sandbox-agent checks agent-specific config files:
|
||||
|
||||
| Agent | Config path | Provider |
|
||||
|-------|-------------|----------|
|
||||
| Amp | `~/.amp/config.json` | Anthropic |
|
||||
| Claude Code | `~/.claude.json`, `~/.claude/.credentials.json` | Anthropic |
|
||||
| Codex | `~/.codex/auth.json` | OpenAI |
|
||||
| OpenCode | `~/.local/share/opencode/auth.json` | Both |
|
||||
|
||||
OAuth tokens are supported for Claude Code, Codex, and OpenCode. Expired tokens are automatically skipped.
|
||||
|
||||
## Provider requirements by agent
|
||||
|
||||
| Agent | Required provider |
|
||||
|-------|-------------------|
|
||||
| Claude Code | Anthropic |
|
||||
| Amp | Anthropic |
|
||||
| Codex | OpenAI |
|
||||
| OpenCode | Anthropic or OpenAI |
|
||||
| Mock | None |
|
||||
|
||||
## Error handling behavior
|
||||
|
||||
Sandbox-agent uses a **best-effort, fail-forward** approach to credentials:
|
||||
|
||||
### Extraction failures are silent
|
||||
|
||||
If a config file is missing, unreadable, or malformed, extraction continues to the next source. No errors are thrown. Missing credentials simply mean the provider is marked as unavailable.
|
||||
|
||||
```
|
||||
~/.claude.json missing → try ~/.claude/.credentials.json
|
||||
~/.claude/.credentials.json missing → try OpenCode config
|
||||
All sources exhausted → anthropic = None (not an error)
|
||||
```
|
||||
|
||||
### Agents spawn without credential validation
|
||||
|
||||
When you send a message to a session, sandbox-agent does **not** pre-validate credentials. The agent process is spawned with whatever credentials were found (or none), and the agent's native error surfaces if authentication fails.
|
||||
|
||||
This design:
|
||||
- Lets you test agent error handling behavior
|
||||
- Avoids duplicating provider-specific auth validation
|
||||
- Ensures sandbox-agent faithfully proxies agent behavior
|
||||
|
||||
For example, sending a message to Claude Code without Anthropic credentials will spawn the agent, which will then emit its own "ANTHROPIC_API_KEY not set" error through the event stream.
|
||||
|
||||
## Checking credential status
|
||||
|
||||
### API endpoint
|
||||
|
||||
The `GET /v1/agents` endpoint includes a `credentialsAvailable` field for each agent:
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": [
|
||||
{
|
||||
"id": "claude",
|
||||
"installed": true,
|
||||
"credentialsAvailable": true,
|
||||
...
|
||||
},
|
||||
{
|
||||
"id": "codex",
|
||||
"installed": true,
|
||||
"credentialsAvailable": false,
|
||||
...
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### TypeScript SDK
|
||||
|
||||
```typescript
|
||||
const { agents } = await client.listAgents();
|
||||
for (const agent of agents) {
|
||||
console.log(`${agent.id}: ${agent.credentialsAvailable ? 'authenticated' : 'no credentials'}`);
|
||||
}
|
||||
```
|
||||
|
||||
### OpenCode compatibility
|
||||
|
||||
The `/opencode/provider` endpoint returns a `connected` array listing providers with valid credentials:
|
||||
|
||||
```json
|
||||
{
|
||||
"all": [...],
|
||||
"connected": ["claude", "mock"]
|
||||
}
|
||||
```
|
||||
|
||||
## Passing credentials explicitly
|
||||
|
||||
You can override auto-discovered credentials by setting environment variables before starting sandbox-agent:
|
||||
|
||||
```bash
|
||||
export ANTHROPIC_API_KEY=sk-ant-...
|
||||
export OPENAI_API_KEY=sk-...
|
||||
sandbox-agent daemon start
|
||||
```
|
||||
|
||||
Or when using the SDK in embedded mode:
|
||||
|
||||
```typescript
|
||||
const client = await SandboxAgentClient.spawn({
|
||||
env: {
|
||||
ANTHROPIC_API_KEY: process.env.MY_ANTHROPIC_KEY,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
|
@ -70,6 +70,7 @@
|
|||
"cli",
|
||||
"inspector",
|
||||
"session-transcript-schema",
|
||||
"credentials",
|
||||
"gigacode",
|
||||
{
|
||||
"group": "AI",
|
||||
|
|
|
|||
|
|
@ -805,12 +805,17 @@
|
|||
"required": [
|
||||
"id",
|
||||
"installed",
|
||||
"credentialsAvailable",
|
||||
"capabilities"
|
||||
],
|
||||
"properties": {
|
||||
"capabilities": {
|
||||
"$ref": "#/components/schemas/AgentCapabilities"
|
||||
},
|
||||
"credentialsAvailable": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the agent's required provider credentials are available"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue