llm: add dynamic tool loading (DTL) — Kimi system-tools + Anthropic tool-reference
Nightly Build / build (push) Successful in 6m51s
Nightly Build / build (push) Successful in 6m51s
Replace the old session_mcp_grants/stack_mcp_grants table pair with
a single activated_tools table that anchors each activation at the
assistant message_id that triggered it. The durable write moves from
the activate_tools tool itself to the round loop (handle_tool_call),
which has the message_id the DTL serializer positions injected tool
blocks against.
Introduce DtlMode (None / AnthropicToolReference / KimiSystemTools),
resolved per model from capabilities (opt-in via tool_search)
combined with the provider's dtl_format(). The message builder inserts
Kimi system {tools} blocks at the activation position, or emits
Anthropic tool_reference markers on the tool result. The tool-def
surface (all_tool_defs) switches shape: Anthropic declares everything
deferred; Kimi omits activated tools from the top-level array (system
takes over); None keeps the old grant-set logic.
Anthropic client: accept structured system arrays (cache_control on
the static block when DTL is active), carry defer_loading through
conversion, emit tool_reference blocks on result messages. Prompt
caching enabled exactly when DTL is active (anthropic provider).
MCP server list in the prompt is now a static catalogue (not split
Available/Active) — the split invalidated the cache on every activation.
Groundwork for providers.yaml dtl: key; Moonshot/Kimi providers wired
with kimi_system_tools and the k3* enrich now adds tool_search.
Compactor re-anchors activations whose message was compacted away.
This commit is contained in:
@@ -338,6 +338,17 @@ impl ContextCompactor {
|
||||
|
||||
let summary_id = chat_summaries::save(pool, stack_id, &summary_text, last_covered_id).await?;
|
||||
|
||||
// DTL: activations pinned to a message that was just compacted away would
|
||||
// otherwise lose their render position (the Kimi `system`+`tools` block).
|
||||
// Re-anchor them onto the first surviving message. Best-effort — a failure
|
||||
// only means the model may re-activate a tool after compaction.
|
||||
let first_surviving_id = messages[split].id;
|
||||
if let Err(e) = crate::db::activated_tools::reanchor_compacted(
|
||||
pool, stack_id, last_covered_id, first_surviving_id,
|
||||
).await {
|
||||
warn!(stack_id, error = %e, "compactor: failed to re-anchor DTL activations");
|
||||
}
|
||||
|
||||
info!(
|
||||
stack_id,
|
||||
summary_id,
|
||||
|
||||
Reference in New Issue
Block a user