TauriTavern/docs/Agent/LlmGateway.md
Darkatse d2420cc180 feat(agent): Add Phase 2C context read tools
Add read-only Agent tools for inspecting current chat context and
run-scoped World Info activation.

- Register chat_search, chat_read_messages, and worldinfo_read_activated
- Add message-indexed JSONL readers for character and group chats
- Return chat search snippets with stable message refs instead of full text
- Capture dry-run World Info activation in Agent prompt snapshots
- Keep World Info tool output focused on entry name, lorebook, and content
- Wire context tools through the existing registry, dispatcher, journal, and tool result flow
- Add coverage for chat message reads, chat search dispatch, and activated World Info reads
2026-04-28 23:41:21 -04:00

6.6 KiB
Raw Blame History

TauriTavern Agent LLM Gateway

本文档定义 Agent Runtime 与现有 LLM 调用链之间的边界。

结论先行:Agent 长期需要 provider-agnostic LlmGateway,但当前已落地实现必须复用现有 ChatCompletionService,不能新建一套绕过现有 policy、日志、proxy、secret、prompt cache 的 HTTP 路径。

1. Ground of Truth

当前后端 LLM 事实:

  • Provider source 定义在 ChatCompletionSource,代码已覆盖 OpenAI、OpenRouter、Custom、Claude、Makersuite/Gemini、VertexAI、DeepSeek、Cohere、Groq、Moonshot、NanoGPT、Chutes、SiliconFlow、Zai 等。见 src-tauri/src/domain/repositories/chat_completion_repository.rs:8。
  • Payload builder 由 application/services/chat_completion_service/payload/mod.rs 按 provider 分发。见 src-tauri/src/application/services/chat_completion_service/payload/mod.rs:25。
  • ChatCompletionService 负责 source 解析、iOS policy、endpoint override、feature policy、settings、secret、prompt caching、payload build、generate/generate_stream/cancel。见 src-tauri/src/application/services/chat_completion_service/mod.rs:302、src-tauri/src/application/services/chat_completion_service/mod.rs:358。
  • LLM API 日志依赖 LoggingChatCompletionRepository wrapper。见 src-tauri/src/app/bootstrap.rs:372。
  • Custom Native API 文档强调 tool_call_id 透明性与 native metadata 保真。见 docs/CurrentState/NativeApiFormats.md:145。

因此 Agent 文档不要复制旧 provider 列表,也不要以 docs/BackendStructure.md 中较旧的 provider 描述作为完整事实源。以代码与 docs/CurrentState/NativeApiFormats.md 为准。

2. Gateway 目标

LlmGatewayService 的目标:

  • 给 Agent Runtime 提供统一的 ModelRequest / ModelResponse / ModelDelta。
  • 隔离 OpenAI、Claude、Gemini、Responses、OpenAI-compatible、Custom Native 等格式差异。
  • 保留 native metadata、tool_call_id、reasoning、prompt cache、provider-specific flags。
  • 复用现有 ChatCompletionService 的 policy/logging/cancel 能力。
  • 让 Profile 切换模型时,Agent loop 不关心 provider payload 细节。

它不是:

  • 新 HTTP client。
  • 新 provider registry。
  • 绕过 ChatCompletionService 的捷径。
  • MCP Sampling 的实现。

3. 当前 Wrapper

当前状态(2026-04-29):已有轻量 AgentModelGateway wrapper,复用 ChatCompletionService::generate_with_cancel() 驱动非 streaming 工具循环;Phase 2C 已在该循环中接入 chat/worldinfo/workspace 内建工具。完整 provider-agnostic ModelRequest / ModelResponse 抽象仍未落地。

当前调用链:

AgentRuntimeService
  -> LlmGatewayService
    -> ChatCompletionService.generate / generate_stream
      -> ChatCompletionRepository
        -> LoggingChatCompletionRepository
          -> HttpChatCompletionRepository

输入仍可由 PromptSnapshot 提供,并转为现有 ChatCompletionGenerateRequestDto。

要求:

  • 使用现有 source/model/settings/payload 字段。
  • 使用现有 cancellation registry 或等价 watch channel。
  • 使用现有 logging wrapper。
  • 使用现有 prompt cache policy。
  • 保留 provider-native metadata。
  • 失败时写 Agent journal。

禁止:

  • 直接调用 HttpChatCompletionRepository。
  • 绕过 HttpClientPool。
  • 自行读取 secret。
  • 自行拼 endpoint override。
  • 因 Agent Mode 而关闭 LLM API log。

4. 长期 ModelRequest

长期建议领域模型:

ModelRequest {
    request_id,
    profile_id,
    model,
    messages,
    tools,
    tool_choice,
    response_format,
    generation_config,
    cache_policy,
    metadata,
}

ModelMessage:

ModelMessage {
    role,
    name,
    content,
    native,
}

ContentPart:

Text
Image
File
Resource
ToolCall
ToolResult
Reasoning
Native

native 必须能保留 provider-specific block,不得清洗未知字段。

5. Tool Call 透明性

Tool call id 必须当作不透明字符串。

禁止:

  • 假设 tool_call_id 是 OpenAI UUID。
  • 重写 provider 返回的 call id。
  • 丢弃 Claude/Gemini/Responses 的 native tool metadata。
  • 把 Gemini thought signature/native blocks 压平成普通文本。

原因:某些 provider 的后续 stateless history 或 tool loop 需要原样回放 native metadata。

6. Streaming 边界

Agent 有两种事件流:

Provider stream
  来自 ChatCompletionService/Repository 的 SSE data 或 normalized chunk。

Agent run event stream
  AgentRunEvent:model_delta、tool_call_requested、checkpoint_created 等语义事件。

两者不能混用。

当前 ChatCompletionStreamEvent::Chunk { data } 只是 provider SSE data 桥接,不是 Agent timeline event。Agent UI 必须订阅 api.agent.subscribe(runId, handler) 的 run event。

7. Cancellation

Agent cancel 应传播到当前模型请求。

要求:

  • 每个 model request 有 request id。
  • request id 遵守现有后端 cancel id 风格:短、稳定、可校验。
  • run cancel 写 run_cancel_requested,再 signal model request。
  • model cancelled 不是 failure,run 进入 Cancelled 或按 state machine 停止。

如果模型请求已经完成但 commit 未开始,cancel 必须阻止 commit。

8. Policy

Gateway 必须遵守:

  • iOS policy source allowlist。
  • iOS policy endpoint override。
  • web search/request image capability。
  • settings 中的 provider 配置。
  • secret 暴露策略。
  • prompt caching opt-in/opt-out。
  • model/profile tool support 声明。

Policy denied 必须 fail-fast 并写 journal,不允许静默降级为另一个 provider 或另一个模型。

9. Prompt Cache

Prompt cache 是 provider 能力,不是 Agent 自己随意拼 header。

Agent 可以在 ModelRequest.cache_policy 中表达意图,但具体是否启用、如何写 header、是否需要 beta header,必须由 existing provider logic 或正式 adapter 决定。

Custom Claude Messages 的 header 兼容策略尤其不能被 Agent 硬编码覆盖。

10. Error Contract

Gateway 错误建议:

model.provider_denied
model.unsupported_tool_call
model.request_build_failed
model.request_failed
model.stream_failed
model.cancelled
model.native_metadata_lost

model.native_metadata_lost 应作为开发期 fail-fast 或测试失败,不应在生产静默发生。

11. Tests

最低测试:

  • Agent gateway 通过 mock ChatCompletionService 验证不直接打 HTTP。
  • provider source denied 时 run failed。
  • stream chunk 转为 model_delta,但不泄漏为 raw provider event。
  • tool_call_id opaque round-trip。
  • Gemini native metadata round-trip。
  • cancel propagates。
  • LLM API log 不因 Agent 关闭。