efcb5a2901
Vision, domain model, architecture, patterns, process flows, UML diagrams, API contracts, tech stack, constraints, milestones (M1-M11), decision log (6 ADRs), and risk register. Key decisions: single binary, pull-based streaming, Mistral as M1 reference provider, discriminated unions, multi-provider collaboration as core identity.
69 lines
3.6 KiB
Markdown
69 lines
3.6 KiB
Markdown
---
|
|
essential: constraints
|
|
status: complete
|
|
last_updated: 2026-04-02
|
|
project: gnoma
|
|
depends_on: [domain-model]
|
|
---
|
|
|
|
# Constraints & Trade-offs
|
|
|
|
## Non-Functional Requirements
|
|
|
|
| Constraint | Target | Measurement |
|
|
|-----------|--------|-------------|
|
|
| First token latency | Dominated by provider, not gnoma overhead | Time from Submit() to first EventTextDelta |
|
|
| Binary size | < 20 MB (static, no CGO) | `ls -lh bin/gnoma` |
|
|
| Memory per session | < 50 MB baseline (excluding context window) | `runtime.MemStats` |
|
|
| Startup time | < 200ms to TUI ready | Wall clock from exec to first render |
|
|
| Provider support | 5+ providers from M2 | Count of passing provider integration tests |
|
|
| Context window | Up to 200k tokens managed | Token tracker reports |
|
|
|
|
## Trade-offs
|
|
|
|
### Single binary over daemon architecture
|
|
|
|
- **Chose:** Single Go binary, goroutines + channels for all communication
|
|
- **Over:** Client-server split with gRPC IPC (gnoma + gnomad)
|
|
- **Because:** Simpler deployment, no daemon lifecycle, no protobuf codegen. Go's goroutine model provides sufficient isolation.
|
|
- **Consequence:** True process isolation for tool sandboxing requires future work. Multi-client scenarios (IDE + TUI) need serve mode added later.
|
|
|
|
### Pull-based stream over channels or iter.Seq
|
|
|
|
- **Chose:** `Next() / Current() / Err() / Close()` interface
|
|
- **Over:** Channel-based streaming or Go 1.23+ `iter.Seq` range functions
|
|
- **Because:** Matches 3 of 4 SDKs natively (zero-overhead adapter). Supports explicit resource cleanup via `Close()`. Consumer controls backpressure.
|
|
- **Consequence:** Google's range-based SDK needs a goroutine bridge. Slightly more verbose than range-based iteration.
|
|
|
|
### json.RawMessage passthrough over typed schemas
|
|
|
|
- **Chose:** Tool parameters and arguments as `json.RawMessage`
|
|
- **Over:** Typed JSON Schema library or code-generated types
|
|
- **Because:** Zero-cost passthrough — no serialize/deserialize between provider and tool. No JSON Schema library as a core dependency.
|
|
- **Consequence:** Schema validation happens at tool boundaries, not centrally. Type safety relies on tool implementations parsing their own args.
|
|
|
|
### Sequential tool execution (MVP) over parallel
|
|
|
|
- **Chose:** Execute tools one at a time in the agentic loop
|
|
- **Over:** Parallel execution via errgroup with read/write partitioning
|
|
- **Because:** Simpler to test, debug, and implement permission prompts. Parallel execution adds complexity around error collection and ordering.
|
|
- **Consequence:** Multiple tool calls in a single turn execute sequentially. Performance impact is minimal for most workloads. Parallel execution planned for post-MVP.
|
|
|
|
### Discriminated union structs over interface hierarchies
|
|
|
|
- **Chose:** Struct with Type discriminant field for Content and Event types
|
|
- **Over:** Interface-based variant types (e.g., `TextContent`, `ToolCallContent` implementing `Content`)
|
|
- **Because:** Zero allocation, cache-friendly, works with switch exhaustiveness. Go interfaces for data variants incur boxing overhead.
|
|
- **Consequence:** Adding a new content type requires updating switch statements. Acceptable for a small, stable set of variants.
|
|
|
|
### Mistral as M1 reference provider over Anthropic
|
|
|
|
- **Chose:** Implement Mistral adapter first as the reference
|
|
- **Over:** Starting with Anthropic (richest content model)
|
|
- **Because:** User maintains the Mistral Go SDK, knows its internals. Good baseline — similar to OpenAI's API shape. Anthropic's unique features (thinking blocks, cache tokens) are better added as an M2 extension.
|
|
- **Consequence:** Thinking block support tested later. Cache token tracking added with Anthropic provider.
|
|
|
|
## Changelog
|
|
|
|
- 2026-04-02: Initial version
|