docs: add condensed design documentation for runtime loop, commands, and launcher
This commit is contained in:
parent
6b15769010
commit
cab55ed2fd
4 changed files with 221 additions and 0 deletions
50
docs/design/launcher_wails_migration.md
Normal file
50
docs/design/launcher_wails_migration.md
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# PicoClaw Launcher — Wails v2 Migration
|
||||
|
||||
## Overview
|
||||
|
||||
Desktop GUI for PicoClaw using Wails v2, replacing the previous HTTP server + browser approach.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
cmd/picoclaw-launcher/
|
||||
├── main.go # Wails bootstrap
|
||||
├── app.go # App struct with Go↔JS bindings
|
||||
├── helpers.go # Gateway process management
|
||||
├── tray.go # System tray integration
|
||||
├── wails.json # Wails project config
|
||||
├── frontend/
|
||||
│ ├── index.html # Single-file UI (3 tabs)
|
||||
│ └── wailsjs/ # Auto-generated bindings
|
||||
└── internal/server/
|
||||
├── setup.go # Config setup helpers
|
||||
└── setup_chat.go # AI chat server
|
||||
```
|
||||
|
||||
## UI: 3-Tab Layout
|
||||
|
||||
| Tab | Features |
|
||||
|-----|----------|
|
||||
| **Status** | Gateway start/stop/restart, real-time status |
|
||||
| **Chat** | AI chat interface, first-run setup questionnaire |
|
||||
| **Settings** | Model/channel/API key config, save/reload |
|
||||
|
||||
## Key Design Choices
|
||||
|
||||
- **Wails bindings** instead of HTTP: `window.go.main.App.GetConfig()` replaces `fetch('/api/config')`
|
||||
- **System tray**: minimize-to-tray on close, right-click menu for gateway control
|
||||
- **First-run setup**: guided overlay when no config exists → AI chat questionnaire
|
||||
- **Single index.html**: intentional for v1 (no build toolchain), will split if complexity grows
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
go tool wails build -o picoclaw-launcher
|
||||
# or via Taskfile:
|
||||
task build-launcher
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Wails v2 (declared as `tool` in go.mod, not linked into picoclaw binary)
|
||||
- WebView2 (Windows, auto-installed), GTK/WebKit (Linux), WebKit (macOS)
|
||||
39
docs/design/runtime_builtin_cmd.md
Normal file
39
docs/design/runtime_builtin_cmd.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Runtime Commands
|
||||
|
||||
## Slash Commands
|
||||
|
||||
All commands start with `/`, handled synchronously by `Reflector.HandleCommand()`.
|
||||
|
||||
| Command | Usage | Description |
|
||||
|---------|-------|-------------|
|
||||
| `/help` | `/help` | List all commands |
|
||||
| `/memory list` | `/memory list` | Show recent memories |
|
||||
| `/memory add` | `/memory add <text> #tags` | Add a memory |
|
||||
| `/memory delete` | `/memory delete <id>` | Delete by ID |
|
||||
| `/memory search` | `/memory search <tags>` | Search by tags |
|
||||
| `/memory stats` | `/memory stats` | Memory statistics |
|
||||
| `/cot feedback` | `/cot feedback <1\|0\|-1>` | Rate last CoT strategy |
|
||||
| `/cot stats` | `/cot stats` | CoT performance stats |
|
||||
| `/cot history` | `/cot history [N]` | Recent CoT usage |
|
||||
| `/shell` | `/shell <cmd> [args]` | Execute shell command |
|
||||
| `/show model` | `/show model` | Current model |
|
||||
| `/list agents` | `/list agents` | List agents |
|
||||
| `/switch model to` | `/switch model to <name>` | Switch model |
|
||||
| `/runtime status` | `/runtime status` | Runtime diagnostics |
|
||||
|
||||
## /shell Architecture
|
||||
|
||||
```
|
||||
/shell <cmd> <args>
|
||||
├─ Built-in (pure Go, cross-platform)
|
||||
│ ls, cat, head, tail, grep, wc, find, diff, tree,
|
||||
│ stat, pwd, echo, touch, mkdir, cp, mv
|
||||
└─ Dev Tool Passthrough (via exec tool)
|
||||
go, git, node, python, npm, cargo, make, jq, rg
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
- Built-in: Go stdlib only, auto-skip `.git`/`node_modules`, output capped at 4000 chars
|
||||
- Passthrough: whitelist + deny patterns (`| sh`, `$()`, etc.) + ExecTool workspace restriction
|
||||
- Unknown commands: rejected
|
||||
77
docs/design/runtime_loop_design.md
Normal file
77
docs/design/runtime_loop_design.md
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# Runtime Loop Design
|
||||
|
||||
> Status: Implemented | Date: 2026-03-02
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Message ──→ Phase 1 (Analyse) ──→ Phase 2 (Execute) ──→ Phase 3 (Reflect)
|
||||
```
|
||||
|
||||
| Phase | File | Responsibility |
|
||||
|-------|------|----------------|
|
||||
| **Analyse** | `analyser.go` | Lightweight LLM → intent, tags, CoT prompt |
|
||||
| **Execute** | `executor.go` | LLM iteration loop + tool calling |
|
||||
| **Reflect** | `reflector.go` | Turn scoring, TurnRecord persistence, slash commands |
|
||||
|
||||
## Turn Definition
|
||||
|
||||
One Turn = user message + Phase 1 result + all Phase 2 iterations + Phase 3 output.
|
||||
Multiple tool-call iterations within Phase 2 count as **one Turn**.
|
||||
|
||||
## Phase 1: Analyse
|
||||
|
||||
- Uses configurable `analyser_model` (fast/cheap model, falls back to main model)
|
||||
- Inputs: user message, Active Context, available tags, CoT learning data
|
||||
- Outputs: `intent`, `tags[]`, `cot_prompt`
|
||||
- After analysis: memory retrieval by tags, CoT injection into system prompt
|
||||
|
||||
## Phase 2: Execute
|
||||
|
||||
- LLM → tool call → tool result loop until no more tool calls
|
||||
- Retry logic for context window overflow with automatic compression
|
||||
- Reasoning output forwarded to dedicated channels
|
||||
|
||||
## Phase 3: Reflect
|
||||
|
||||
- **SyncPhase3** (< 2ms, before response sent): turn scoring + Active Context update
|
||||
- **AsyncPhase3** (after response): `go turnStore.Insert(record)` → SQLite
|
||||
- Slash commands: `/memory`, `/cot`, `/shell`, `/show`, `/list`, `/switch`, `/help`
|
||||
|
||||
## Scoring Rules
|
||||
|
||||
| Condition | Score |
|
||||
|-----------|-------|
|
||||
| Has tool calls | +3 |
|
||||
| Write/edit tools | +2 |
|
||||
| intent = task/code/debug | +3 |
|
||||
| Reply > 500 chars | +2 |
|
||||
| Short exchange < 80 chars | -2 |
|
||||
|
||||
## Memory Hierarchy
|
||||
|
||||
| Layer | Lifetime | Purpose |
|
||||
|-------|----------|---------|
|
||||
| Instant Memory | Per-turn | Dynamic window from TurnStore (score + tag filtering) |
|
||||
| Active Context | Per-session | `CurrentFiles` + `RecentErrors`, injected into user prompt |
|
||||
| Long-term Memory | Persistent | MemoryDigest batch extraction → `memory.db` |
|
||||
|
||||
## Multi-Model Support
|
||||
|
||||
| Config Field | Phase | Fallback |
|
||||
|-------------|-------|----------|
|
||||
| `model_name` | Phase 2 | — |
|
||||
| `analyser_model` | Phase 1 | → `model_name` |
|
||||
| `digest_model` | MemoryDigest | → `model_name` |
|
||||
|
||||
## Message Ordering (KV Cache Friendly)
|
||||
|
||||
```
|
||||
[system_prompt] → always cached
|
||||
[long_term_memory by tags] → cached when same tags
|
||||
[always_keep turns (score≥7)] → fixed position, append-only
|
||||
[recent turns] → rolling window
|
||||
[current user message] → new each turn
|
||||
```
|
||||
|
||||
Active Context injected as **user message** (not system prompt) to keep system prompt prefix stable.
|
||||
55
docs/design/runtime_loop_task.md
Normal file
55
docs/design/runtime_loop_task.md
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Runtime Loop Implementation Tasks
|
||||
|
||||
> Design ref: `docs/design/picoclaw_runtime_loop_design.md`
|
||||
|
||||
## Design Decisions
|
||||
|
||||
| Decision | Conclusion |
|
||||
|----------|------------|
|
||||
| Turn storage | SQLite `turns.db` |
|
||||
| Active Context fields | `CurrentFiles` + `RecentErrors` only |
|
||||
| Phase 1 short-circuit | No — short messages need Active Context most |
|
||||
| Async write | Direct `go insert()`, no channel buffer |
|
||||
| Token budget check | Periodic time-based archival instead |
|
||||
| Tag-gated tools | Deferred until tool count > 15 |
|
||||
| KV Cache | Fixed ordering (high-score first, by ID ASC) |
|
||||
|
||||
## Milestones
|
||||
|
||||
### M1: Turn Score + Phase 3 Timing — ✅
|
||||
|
||||
- [x] `score.go`: `CalcTurnScore(input) int`
|
||||
- [x] Split `RunPostLLM` → `SyncPhase3` (sync, < 2ms) + `AsyncPhase3` (goroutine)
|
||||
- [x] Adjust `runAgentLoop` timing: score → publish → async write
|
||||
|
||||
### M2: Active Context — ✅
|
||||
|
||||
- [x] `active_context.go`: per `channel:chatID` store
|
||||
- [x] Fields: `CurrentFiles` (5), `RecentErrors` (3)
|
||||
- [x] Injected as user message (not system prompt) for KV cache stability
|
||||
- [x] Flush to JSON on shutdown, load on startup
|
||||
|
||||
### M3: TurnStore — ✅
|
||||
|
||||
- [x] `turn_store.go`: SQLite `turns.db` with WAL mode
|
||||
- [x] Methods: Insert, QueryPending, QueryByScore, QueryByTags, QueryRecent, ArchiveOldProcessed
|
||||
- [x] Async insert via goroutine in AsyncPhase3
|
||||
|
||||
### M4: MemoryDigest — ✅
|
||||
|
||||
- [x] `memory_digest.go`: background worker (5min interval)
|
||||
- [x] QueryPending → group by channel → LLM batch extraction → MemoryStore
|
||||
- [x] Removed `MemoryExtractor` and `CotEvaluator` processors (kept `ErrorTracker`)
|
||||
|
||||
### M5: Instant Memory + KV Cache Ordering — ✅
|
||||
|
||||
- [x] `instant_memory.go`: dynamic window from TurnStore
|
||||
- [x] Cache-friendly message ordering: system → memory → high-score → recent → current
|
||||
- [x] Legacy SessionManager kept as fallback
|
||||
|
||||
## Deferred
|
||||
|
||||
| Item | Reason |
|
||||
|------|--------|
|
||||
| Tag-gated tool loading | Tool count < 10 currently |
|
||||
| Summary Anchor | Fixed ordering sufficient for v1 |
|
||||
Loading…
Add table
Reference in a new issue