mirror of
https://github.com/Darkatse/TauriTavern.git
synced 2026-10-19 07:35:14 +00:00
- Introduce the Agent domain model, run/workspace/checkpoint repositories, and a file-backed workspace store with event journaling. - Wire the runtime service into Tauri commands and expose the frontend Agent API for starting, observing, cancelling, reading, and committing runs. - Derive workspaces from stable chat identity while keeping each run isolated, and make unsupported Phase 1 paths fail fast. - Document the Agent architecture, API contract, workspace model, LLM gateway, tool/MCP boundaries, and implementation plan.
7 KiB
7 KiB
window.__TAURITAVERN__.api.agent — Agent API Draft
本文档是 Agent Host ABI 草案。它描述前端/扩展可见的稳定入口,不等同于 Rust 内部 service/repository。
状态:Phase 1 已实现最小骨架,本文仍包含后续阶段 API 草案。
1. 入口
await (window.__TAURITAVERN__?.ready ?? window.__TAURITAVERN_MAIN_READY__);
const agent = window.__TAURITAVERN__.api.agent;
Agent API 必须挂在 window.__TAURITAVERN__.api.agent。不要新增散落全局。
2. 方法概览
type TauriTavernAgentApi = {
startRun(input: AgentStartRunInput): Promise<AgentRunHandle>;
subscribe(runId: string, handler: (event: AgentRunEvent) => void, options?: AgentSubscribeOptions): Promise<TauriTavernHostUnsubscribe>;
cancel(runId: string): Promise<void>;
approveToolCall(input: AgentApproveToolCallInput): Promise<void>;
listRuns(input: AgentListRunsInput): Promise<AgentRunSummary[]>;
readEvents(input: AgentReadEventsInput): Promise<AgentReadEventsResult>;
readWorkspaceFile(input: AgentReadWorkspaceFileInput): Promise<AgentWorkspaceFile>;
readDiff(input: AgentReadDiffInput): Promise<AgentDiff>;
rollback(input: AgentRollbackInput): Promise<AgentRollbackResult>;
commit(input: AgentCommitInput): Promise<AgentCommitResult>;
};
subscribe() 返回的 unsubscribe 必须幂等。
3. startRun
type AgentStartRunInput = {
chatRef: AgentChatRef;
stableChatId?: string;
generationType: 'normal' | 'regenerate' | 'swipe' | 'continue' | 'quiet' | 'impersonate';
profileId?: string;
promptSnapshot?: unknown;
generationIntent?: AgentGenerationIntent;
workspaceMode?: 'new-run' | 'resume-run';
resumeRunId?: string;
options?: {
autoCommit?: boolean;
stream?: boolean;
};
};
type AgentRunHandle = {
runId: string;
status: AgentRunStatus;
workspaceId: string;
stableChatId: string;
};
身份语义:
stableChatId是聊天的长期稳定身份。workspaceId必须由kind + stableChatId派生,不得由可变的chatRef文件名直接决定。runId是一次 Agent 执行身份,每次 normal/regenerate/swipe/continue 都必须生成新的runId。- 同一稳定聊天的多次 run 应共享同一个 chat workspace,但各自拥有独立 run workspace。
Public Host ABI 可以允许调用方省略 stableChatId,但 api.agent.startRun() 必须在调用 Rust command 前通过 api.chat.open(chatRef).stableId() 解析并校验。Rust command 不应自行读取 SillyTavern metadata。
短期允许 promptSnapshot,长期目标是 generationIntent。
要求:
stableChatId进入 backend DTO 前必须非空;无法解析时 fail-fast。promptSnapshot与generationIntent至少提供一个。resume-run必须提供resumeRunId。autoCommit默认由 profile/output policy 决定。- 参数无效必须 reject,不静默回退 Legacy Generate。
4. subscribe
type AgentSubscribeOptions = {
replay?: 'none' | 'from-seq';
afterSeq?: number;
};
语义:
- 默认不复播全部历史。
- UI 首次打开 run 页面应先
readEvents(),再subscribe()。 - 如果订阅期间漏事件,调用方可用
afterSeq补拉。 - 底层 Tauri 事件名不是 Public Contract。
5. cancel
await agent.cancel(runId);
语义:
- 写
run_cancel_requested。 - 尽力取消当前模型请求或工具调用。
- Cancel 不是 failure。
- Cancel 后不能自动 commit。
6. approveToolCall
type AgentApproveToolCallInput = {
runId: string;
callId: string;
approved: boolean;
reason?: string;
};
语义:
- 审批结果写 journal。
- 拒绝工具不等同 run failure;具体后续由 plan/profile policy 决定。
7. readEvents
type AgentReadEventsInput = {
runId: string;
afterSeq?: number;
beforeSeq?: number;
limit?: number;
};
type AgentReadEventsResult = {
runId: string;
events: AgentRunEvent[];
hasMoreBefore: boolean;
hasMoreAfter: boolean;
};
要求:
limit必须有上限。- 移动端 UI 不应一次读取完整巨大 journal。
8. readWorkspaceFile
type AgentReadWorkspaceFileInput = {
runId: string;
path: string;
checkpointId?: string;
};
type AgentWorkspaceFile = {
runId: string;
path: string;
text?: string;
bytes?: number;
mime?: string;
sha256?: string;
};
路径必须是 workspace relative path。非法路径直接 reject。
9. readDiff
type AgentReadDiffInput = {
runId: string;
fromCheckpointId?: string;
toCheckpointId?: string;
paths?: string[];
};
type AgentDiff = {
runId: string;
fromCheckpointId?: string;
toCheckpointId?: string;
files: Array<{
path: string;
status: 'added' | 'modified' | 'deleted' | 'unchanged';
unifiedDiff?: string;
}>;
};
第一期可以只支持文本 artifact 的 diff。
10. rollback
type AgentRollbackInput = {
runId: string;
checkpointId: string;
scope?: 'workspace' | 'committed-message';
};
语义:
workspace:只恢复 run workspace,不修改 chat。committed-message:重组 artifact 并修改已提交聊天消息,必须走 chat 保存契约。
11. commit
type AgentCommitInput = {
runId: string;
checkpointId?: string;
};
type AgentCommitResult = {
runId: string;
chatRef: AgentChatRef;
stableChatId: string;
messageIndex?: number;
messageId?: string;
};
Commit 必须:
- 读取 manifest。
- 校验 required artifact。
- 校验当前 active chat 与 run 的
stableChatId一致。 - 通过既有 chat 保存契约写入。
- 写 agent metadata。
- 追加
run_committedevent。
12. Event Envelope
type AgentRunEvent = {
seq: number;
id: string;
runId: string;
timestamp: string;
level: 'debug' | 'info' | 'warn' | 'error';
type: AgentRunEventType;
payload: unknown;
};
事件类型见 docs/Agent/RunEventJournal.md。
Agent event 不等同 SillyTavern eventSource 事件,不得伪装成 GENERATION_* 或 TOOL_CALLS_*。
13. Errors
错误建议结构:
type AgentApiError = {
code: string;
message: string;
runId?: string;
eventSeq?: number;
retryable?: boolean;
details?: unknown;
};
常见 code:
agent.invalid_intent
agent.invalid_profile
agent.policy_violation
agent.not_found
workspace.path_denied
workspace.required_artifact_missing
model.request_failed
tool.policy_denied
commit.cursor_integrity
commit.save_failed
14. Rust Command 草案
start_agent_run(dto, channel?)
cancel_agent_run(run_id)
approve_agent_tool_call(dto)
list_agent_runs(chat_ref)
read_agent_run_events(dto)
read_agent_workspace_file(dto)
read_agent_diff(dto)
rollback_agent_run(dto)
commit_agent_run(dto)
Command 层必须是薄封装。Agent loop 不写在 command 内。
15. Compatibility
Agent Mode off:
Generate()行为不变。ToolManager行为不变。api.chat行为不变。
Agent Mode on:
- 短期可使用 dryRun 生成 prompt snapshot。
- dryRun 不是纯函数,调用方必须理解它仍会触发上游事件。
- Agent tool loop 不递归
Generate()。