Files
james.maesandClaude Opus 4.7 508cf924d0 docs(packages): per-package README files
Adds README.md to each of the 13 SPM packages (AgentCore, Bus, Config,
DevOverlay, Harness, Keychain, Logging, MCP, Memory, Replay, Shell, Vision,
Voice). Each covers purpose, key public types, deps, consumers, invariants
(pulled from CLAUDE.md + grep-gates + audit findings), test stack, and
notable files. Memory README explicitly marks the package functionally OFF
until vec0.dylib + Ollama models land.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 17:13:33 -05:00

56 lines
3.8 KiB
Markdown

# AgentCore
The agent loop, LLM provider protocol, and concrete providers. Four library products: shared types (`AgentCore`), the orchestrator (`AgentOrchestrator`), and two providers (`AnthropicProvider`, `OllamaProvider`).
## Key public types
| Type | Purpose |
|------|---------|
| `LLMProvider` (protocol) | Provider-agnostic streaming contract — returns `AsyncThrowingStream<LLMEvent, Error>` |
| `LLMEvent` | Stream event union — `tokenDelta`, `thinkingDelta`, `toolUseRequested`, `usage`, `messageStop` |
| `LLMMessage` | Provider-neutral chat message (role + content blocks, including `ImageBlock`) |
| `ToolSchema` / `ToolChoice` | Tool advertising + tool-choice discipline (`auto`, `none`, `required`) |
| `ImageBlock` | Multimodal extension (Plan 07-05 / D-18); base64 + media type |
| `ModelID` | Strong-typed model identifier (`claude-opus-4-7`, `qwen2.5-coder:32b`) |
| `TurnID` / `TurnNonce` | Turn identity (`TurnID` on bus + replay; `TurnNonce` for SEC-06, never on bus) |
| `CacheHints` | `eligibleForSystemPrompt` (≥1024 tokens), `extended-cache-ttl` beta header guard |
| `UntrustedWrapper` | Prompt-injection isolation around tool results |
| `ToolResultPacker` | 8 KB cap on model-facing tool result content (Opus 4.7 footgun) |
| `BoundedAsyncChannel` | `dropOldest`-policy bounded channel for orch → replay events |
| `AnthropicProvider` | Streaming SSE Opus 4.7 via Anthropic Messages API |
| `OllamaProvider` | Native NDJSON `/api/chat` + OpenAI-compat `/v1/chat/completions` |
| `AgentOrchestrator` | Actor — turn-lifecycle owner, tool dispatch, cap-recovery, retry |
| `OrchestratorEvent` | One-consumer event stream — state changes, tokens, tool starts/ends |
## Depends on
`Keychain`, `Replay`, `Vision`, `Logging`, `Config`. External: `swift-log`.
## Used by
`App/AppDelegate`, `App/Voice/VoiceOrchestratorAdapter.swift`, `App/MCPBusGatewayAdapter.swift`, `packages/Memory`, `packages/Vision`, `packages/Harness`, `packages/DevOverlay`, `packages/MCP`.
## Key invariants / contracts
- **`LLMProvider` cancellation through `Task.isCancelled`** — provider task closes the underlying transport on consumer cancel.
- **Tool-choice mandatory.** Cap-recovery turns pass `.none` (Anthropic `{"type":"none"}`; Ollama drops `tools` array entirely).
- **`turnNonce` never on the bus or in any `OrchestratorEvent`** (SEC-06).
- **Tool result content capped at 8 KB before model.** Full bytes still go to replay.
- **`extended-cache-ttl` requires the beta header** AND `ttl: "1h"` on `cache_control`. Without the header, 1h is silently ignored.
- **Cache hints gated on prompts ≥1024 tokens** (`CacheHints.eligibleForSystemPrompt`).
- **Anthropic SSE: close on `message_stop`, not `message_delta`.** Swallow `ping`. Route `thinking_delta` to its own case. Treat `stop_reason: "refusal"` first-class. Emit `partial_tool_use_at_disconnect` on mid-delta termination.
- **Ollama NDJSON: `tool_calls` arrive on the chunk preceding `done: true`** — decoder reads `tool_calls` whenever seen, never gates on `done`.
- **One-consumer invariant on `OrchestratorEvent` stream** — `scripts/check-orchestrator-events-single-consumer.sh`.
## Tests
19 swift-testing + 72 XCTest. Includes SSE fixture corpus (`packages/Harness/Sources/Harness/Corpus/SSEFixtureCorpus.swift`), NDJSON fixture corpus, tool-cap-recovery scenarios, retry-budget tests. Live-network tests gated by `JARVIS_REAL_MODELS=1`.
## Notable files
- `Sources/AgentCore/LLMProvider.swift` — the core protocol + multimodal overload
- `Sources/AgentOrchestrator/AgentOrchestrator.swift` — the turn-lifecycle actor
- `Sources/AnthropicProvider/SSEDecoder.swift` — SSE parser with all the footgun cases
- `Sources/OllamaProvider/NDJSONDecoder.swift` — `/api/chat` decoder; tool_calls-before-done
- `Sources/AgentCore/CacheHints.swift` — Track A streamTruncated fix