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:
NathanFlurry 2026-02-07 07:56:06 +00:00
parent 915d484845
commit c54f83e1a6
No known key found for this signature in database
GPG key ID: 6A5F43A4F3241BCA
13 changed files with 807 additions and 9 deletions

View file

@ -347,6 +347,68 @@ Requires a running Codex app-server process. Send the JSON-RPC request to the ap
- Requires an active app-server process (cannot query models without starting one)
- No standalone CLI command like `codex models`
## Command Execution & Process Management
### Agent Tool Execution
Codex executes commands via `LocalShellAction`. The agent proposes a command, and external clients approve/deny via JSON-RPC (`item/commandExecution/requestApproval`).
### Command Source Tracking (`ExecCommandSource`)
Codex is the only agent that explicitly tracks **who initiated a command** at the protocol level:
```json
{
"ExecCommandSource": {
"enum": ["agent", "user_shell", "unified_exec_startup", "unified_exec_interaction"]
}
}
```
| Source | Meaning |
|--------|---------|
| `agent` | Agent decided to run this command via tool call |
| `user_shell` | User ran a command in a shell (equivalent to Claude Code's `!` prefix) |
| `unified_exec_startup` | Startup script ran this command |
| `unified_exec_interaction` | Interactive execution |
This means user-initiated shell commands are **first-class protocol events** in Codex, not a client-side hack like Claude Code's `!` prefix.
### Command Execution Events
Codex emits structured events for command execution:
- `exec_command_begin` - Command started (includes `source`, `command`, `cwd`, `turn_id`)
- `exec_command_output_delta` - Streaming output chunk (includes `stream: stdout|stderr`)
- `exec_command_end` - Command completed (includes `exit_code`, `source`)
### Parsed Command Analysis (`CommandAction`)
Codex provides semantic analysis of what a command does:
```json
{
"commandActions": [
{ "type": "read", "path": "/src/main.ts" },
{ "type": "write", "path": "/src/utils.ts" },
{ "type": "install", "package": "lodash" }
]
}
```
Action types: `read`, `write`, `listFiles`, `search`, `install`, `remove`, `other`.
### Comparison
| Capability | Supported? | Notes |
|-----------|-----------|-------|
| Agent runs commands | Yes (`LocalShellAction`) | With approval workflow |
| User runs commands → agent sees output | Yes (`user_shell` source) | First-class protocol event |
| External API for command injection | Yes (JSON-RPC approval) | Can approve/deny before execution |
| Command source tracking | Yes (`ExecCommandSource` enum) | Distinguishes agent vs user vs startup |
| Background process management | No | |
| PTY / interactive terminal | No | |
## Notes
- SDK is dynamically imported to reduce bundle size