新增: Agent 中继模式——u-relay 客户端接入远端 agent 指令链

This commit is contained in:
lxy
2026-08-29 01:43:34 +08:00
parent dde53378c3
commit 99f38726a2
6 changed files with 517 additions and 7 deletions
+39
View File
@@ -547,6 +547,45 @@ export async function chat(opts: {
return { reply: r.reply, op: normalizeOp(r.op) }
}
/** SEP 分隔标记(对话回复与 JSON 操作的分隔),导出给 relay 等 Transport 复用 */
export const CHAT_SEP = SEP
/**
* 解析 chat 协议回复文本:SEP 前为自然语言回复,SEP 后为 JSON 操作。
* 供 AiPanelSSE 路径)与 AgentPanel(relay 路径)共用,避免复制粘贴。
*/
export function parseChatReply(text: string): { reply: string; op: AiOp | null } {
const parts = text.split(SEP)
return {
reply: (parts[0] || '').trim(),
op: parts.length > 1 ? normalizeOp(tryParse(parts.slice(1).join(SEP))) : null
}
}
/**
* 组装 Agent 请求 prompt:用户指令 + chat 协议要求 + deck 上下文。
* 大 deck(序列化 >700KB)降级为「当前页完整 JSON + 全deck大纲摘要」,防超 1MiB 帧上限。
*/
export function buildAgentPrompt(input: string): string {
const SYS_AGENT =
SYS_BASE +
'\n任务:你是通过中继接入的远程 Agent。根据用户指令编辑当前演示。\n' +
'回复格式:先用中文说明你将做什么,如需修改 PPT,在回复最后另起一行输出分隔标记 ' + SEP + ',紧随其后输出 JSON 操作。\n' +
'JSON 操作格式:{"action":"add_page|update_page|create_all|answer","slides":[...],"target":页码(从1开始,可选)}\n' +
'- add_page:在 target 页后插入新页;- update_page:替换 target 页;- create_all:整体替换;- answer:仅回答不改稿。\n' +
'没有改动时不要输出分隔标记。不要使用 markdown 代码块。'
const deck = store.getDeck()
let body: string
const full = JSON.stringify(deck)
if (full.length > 700 * 1024) {
// 超大 deck 降级:大纲摘要 + 当前页完整 JSON
body = deckContext(store.getCurrentIndex(), null)
} else {
body = '完整 deck JSON\n' + full + '\n当前页码:第 ' + (store.getCurrentIndex() + 1) + ' 页'
}
return SYS_AGENT + '\n\n' + body + '\n\n用户指令:' + input
}
function normalizeOp(json: any): AiOp | null {
if (!json) return null
let action: AiOp['action'] = json.action || 'answer'