43 lines
1.7 KiB
JavaScript
43 lines
1.7 KiB
JavaScript
// pending.js -- 人工请求决策提交(卡片渲染在 notify-strip.js,数据源为 live snapshot)
|
||
|
||
import { api } from './api.js';
|
||
import { state } from './state.js';
|
||
|
||
// 防重入:同一 approval_id 同时只允许一个提交请求(连点保护)
|
||
const _inFlight = new Set();
|
||
|
||
/**
|
||
* 提交一个等待中的人工请求的决策。
|
||
*
|
||
* 阻塞式交互模型下,本函数只负责把答案交给后端:
|
||
* 后端写入等待注册表并唤醒阻塞中的工具,图在后台线程自然继续;
|
||
* 浮窗由下一次 live snapshot 自动移除,最终结果由
|
||
* /api/chat/complete 或 /api/chat/stream 返回——无需重渲染消息、
|
||
* 无需重启 live 流、更不会清空已积累的工具调用列表。
|
||
*
|
||
* 注意:Agent 运行期间 state.sending 恒为 true(本轮仍在后台执行),
|
||
* 因此这里绝不能以 state.sending 作为拦截条件,否则浮窗按钮全部失效。
|
||
*
|
||
* @param {string} [sessionId] - 目标会话 ID。cron 模式传 task_id;
|
||
* 缺省时回退 state.sessionId(chat)。
|
||
*/
|
||
async function handleHumanAction(requestId, decision, instruction, card, sessionId) {
|
||
if (!requestId || _inFlight.has(requestId)) return;
|
||
_inFlight.add(requestId);
|
||
try {
|
||
const fd = new FormData();
|
||
fd.append("session_id", sessionId || state.sessionId);
|
||
fd.append("approval_id", requestId);
|
||
fd.append("decision", decision);
|
||
fd.append("instruction", instruction || "");
|
||
await api("/api/human-action", { method: "POST", body: fd });
|
||
} finally {
|
||
_inFlight.delete(requestId);
|
||
}
|
||
// 注意:不修改 state.sending——本轮任务尚未结束,按钮状态由 sendChat 完成时统一恢复
|
||
}
|
||
|
||
export {
|
||
handleHumanAction,
|
||
};
|