feat: DeepSeek API integration + Whale lift (hooks, tool repair, MCP permissions, token tracking)

DeepSeek API:
- @ai-sdk/deepseek provider replaces openai-compatible for deepseek-* models
- Token tracking: cache_hit/reasoning tokens flow API → DB → WS frames → UI
- thinking effort levels (off/low/medium/high/xhigh/max) via AGENTS.md frontmatter
- V4 models: deepseek-v4-flash, deepseek-v4-pro
- Wired for both chat and coder panes

Whale lifts:
- Tool input repair (schema-based type coercion, markdown link unwrapping)
- Hooks system (6 lifecycle events, shell exec, JSON stdin/stdout contract)
- Per-MCP-server permissions (allow/ask/deny)
- token tracking UI (cache N, think N in message stats line)

Infra:
- New DB columns: messages.cache_tokens, messages.reasoning_tokens
- New WS frame fields: cache_tokens, reasoning_tokens on message_complete
- coder provider snapshot merges DeepSeek models alongside llama-swap
This commit is contained in:
2026-06-08 01:24:23 +00:00
parent 31e5d9d4ab
commit c4079dd85c
29 changed files with 916 additions and 42 deletions

View File

@@ -126,8 +126,8 @@ SELECT
FROM message_parts p
WHERE p.message_id = m.id AND p.kind = 'reasoning' AND p.hidden_at IS NULL) AS reasoning_parts,
-- NEW columns MUST be appended at the end: CREATE OR REPLACE VIEW can't
-- reorder/rename existing columns (42P16). m.model added last.
m.model
-- reorder/rename existing columns (42P16). cache_tokens and reasoning_tokens added last.
m.model, m.cache_tokens, m.reasoning_tokens
FROM messages m;
-- v1.13.20: drop legacy tool_calls/tool_results columns. Reads have routed
@@ -204,6 +204,8 @@ ALTER TABLE messages ADD COLUMN IF NOT EXISTS ctx_used INTEGER;
ALTER TABLE messages ADD COLUMN IF NOT EXISTS ctx_max INTEGER;
ALTER TABLE messages ADD COLUMN IF NOT EXISTS started_at TIMESTAMPTZ;
ALTER TABLE messages ADD COLUMN IF NOT EXISTS finished_at TIMESTAMPTZ;
ALTER TABLE messages ADD COLUMN IF NOT EXISTS cache_tokens INTEGER;
ALTER TABLE messages ADD COLUMN IF NOT EXISTS reasoning_tokens INTEGER;
ALTER TABLE sessions ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp();