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:
@@ -144,6 +144,7 @@ export async function runAssistantTurn(
|
||||
log: ctx.log,
|
||||
broker: ctx.broker,
|
||||
chatId,
|
||||
hooks: ctx.hooks,
|
||||
});
|
||||
} catch (err) {
|
||||
ctx.log.warn({ err, chatId }, 'auto-compaction failed; clearing flag and proceeding');
|
||||
@@ -214,6 +215,16 @@ export async function runAssistantTurn(
|
||||
|
||||
// ---- non-tool finish → finalize and exit ----
|
||||
if (result.toolCalls.length === 0) {
|
||||
// vWhale: Stop hook (best-effort, non-blocking).
|
||||
if (ctx.hooks) {
|
||||
ctx.hooks.run('Stop', {
|
||||
event: 'Stop',
|
||||
session_id: sessionId,
|
||||
chat_id: chatId,
|
||||
last_assistant_text: result.content.slice(0, 500),
|
||||
turn: stepNumber,
|
||||
}).catch(() => {});
|
||||
}
|
||||
await finalizeCompletion(ctx, iterArgs, result, state.startedAt, iterSession);
|
||||
break;
|
||||
}
|
||||
@@ -309,6 +320,22 @@ export async function runAssistantTurn(
|
||||
assistantMessageId = toolPhaseResult.nextAssistantId!;
|
||||
}
|
||||
|
||||
// vWhale: Stop hook at post-loop exit (best-effort, non-blocking).
|
||||
if (ctx.hooks) {
|
||||
const loaded = await loadContext(ctx.sql, sessionId, chatId);
|
||||
const lastAssistant = loaded?.history?.slice().reverse().find(
|
||||
(m: import('../../types/api.js').Message) => m.role === 'assistant',
|
||||
);
|
||||
const content = lastAssistant?.content ?? '';
|
||||
ctx.hooks.run('Stop', {
|
||||
event: 'Stop',
|
||||
session_id: sessionId,
|
||||
chat_id: chatId,
|
||||
last_assistant_text: content.slice(0, 500),
|
||||
turn: stepNumber,
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
// ---- post-loop: step-cap sentinel ----
|
||||
// When the loop exits because stepNumber reached effectiveCap, the last
|
||||
// iteration's tool phase returned 'continue' with a nextAssistantId that
|
||||
|
||||
Reference in New Issue
Block a user