Share project JSON transport, interaction replies and report selectors. Settle tool progress consistently for direct streams, reconnects and history, preserving failure reasons and stopped state.
61 lines
3.4 KiB
TypeScript
61 lines
3.4 KiB
TypeScript
import type { AgentPermissionReply, AgentPermissionRequest, AgentQuestionRequest } from "@/features/agent";
|
|
import { showMapNotice } from "@/features/map/core";
|
|
import { toPermissionStatus, type PermissionOverride, type QuestionOverride } from "./agent-session-message-state";
|
|
import type { AgentSessionRuntime } from "./agent-session-runtime";
|
|
import type { WorkbenchSessionResources } from "./workbench-session-resources";
|
|
|
|
export function createAgentInteractionReplies(resources: WorkbenchSessionResources, setters: {
|
|
permission: (value: Record<string, PermissionOverride>) => void;
|
|
question: (value: Record<string, QuestionOverride>) => void;
|
|
}) {
|
|
const permissionUpdate = (target: AgentSessionRuntime, id: string, value: PermissionOverride) => {
|
|
target.permissionOverrides = { ...target.permissionOverrides, [id]: value };
|
|
if (resources.activeAgent === target) setters.permission(target.permissionOverrides);
|
|
resources.notify();
|
|
};
|
|
const questionUpdate = (target: AgentSessionRuntime, id: string, value: QuestionOverride) => {
|
|
target.questionOverrides = { ...target.questionOverrides, [id]: value };
|
|
if (resources.activeAgent === target) setters.question(target.questionOverrides);
|
|
resources.notify();
|
|
};
|
|
const submit = async <T extends PermissionOverride | QuestionOverride>(
|
|
request: { sessionId: string; requestId: string },
|
|
update: (target: AgentSessionRuntime, id: string, value: T | { status: "submitting" } | { status: "error"; error: string }) => void,
|
|
execute: (target: AgentSessionRuntime) => Promise<unknown>,
|
|
success: T,
|
|
failure: { id: string; title: string; message: string }
|
|
) => {
|
|
const target = resources.activeAgent;
|
|
if (!target || target.sessionId !== request.sessionId) return;
|
|
const apply = (value: T | { status: "submitting" } | { status: "error"; error: string }) => update(target, request.requestId, value);
|
|
apply({ status: "submitting" });
|
|
try {
|
|
await execute(target);
|
|
apply(success);
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : failure.message;
|
|
apply({ status: "error", error: message });
|
|
showMapNotice({ id: failure.id, tone: "error", title: failure.title, message });
|
|
}
|
|
};
|
|
const questionFailure = { id: "agent-question-status", title: "Agent 问题提交失败", message: "问题回复提交失败。" };
|
|
return {
|
|
replyPermission: (permission: AgentPermissionRequest, reply: AgentPermissionReply) => submit<PermissionOverride>(
|
|
permission, permissionUpdate,
|
|
(target) => target.client.replyPermission(permission.requestId, { sessionId: permission.sessionId, reply }),
|
|
{ status: toPermissionStatus(reply) },
|
|
{ id: "agent-permission-status", title: "Agent 权限提交失败", message: "权限请求提交失败。" }
|
|
),
|
|
replyQuestion: (question: AgentQuestionRequest, answers: string[][]) => submit<QuestionOverride>(
|
|
question, questionUpdate,
|
|
(target) => target.client.replyQuestion(question.requestId, { sessionId: question.sessionId, answers }),
|
|
{ status: "answered", answers }, questionFailure
|
|
),
|
|
rejectQuestion: (question: AgentQuestionRequest) => submit<QuestionOverride>(
|
|
question, questionUpdate,
|
|
(target) => target.client.rejectQuestion(question.requestId, { sessionId: question.sessionId }),
|
|
{ status: "rejected" }, { ...questionFailure, message: "问题跳过失败。" }
|
|
)
|
|
};
|
|
}
|