feat: wire code agent runs to tool mode
This commit is contained in:
+93
-12
@@ -6507,6 +6507,8 @@ async function initSchema(pool2) {
|
||||
import crypto3 from "node:crypto";
|
||||
var DEFAULT_RUN_RETRY_DELAYS_MS = [1500, 5e3, 15e3];
|
||||
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["succeeded", "failed"]);
|
||||
var CODE_TOOL_MODES = /* @__PURE__ */ new Set(["code", "code-task", "code_task", "code-tool", "code_tool", "code_tool_task"]);
|
||||
var RUN_METADATA_KEY = "memindRun";
|
||||
function nowMs() {
|
||||
return Date.now();
|
||||
}
|
||||
@@ -6520,6 +6522,40 @@ function safeJsonParse(value, fallback = null) {
|
||||
function serializeMessage(message) {
|
||||
return JSON.stringify(message ?? {});
|
||||
}
|
||||
function normalizeAgentRunToolMode(value) {
|
||||
const normalized = String(value ?? "chat").trim().toLowerCase();
|
||||
if (!normalized || normalized === "chat") return "chat";
|
||||
if (CODE_TOOL_MODES.has(normalized)) return "code";
|
||||
throw new Error(`\u4E0D\u652F\u6301\u7684 tool_mode: ${value}`);
|
||||
}
|
||||
function normalizeTaskType(value) {
|
||||
const normalized = String(value ?? "").trim();
|
||||
return normalized || null;
|
||||
}
|
||||
function withRunMetadata(userMessage, { toolMode = "chat", taskType = null } = {}) {
|
||||
const message = userMessage && typeof userMessage === "object" && !Array.isArray(userMessage) ? { ...userMessage } : { value: userMessage };
|
||||
const metadata = message.metadata && typeof message.metadata === "object" && !Array.isArray(message.metadata) ? { ...message.metadata } : {};
|
||||
metadata[RUN_METADATA_KEY] = {
|
||||
...metadata[RUN_METADATA_KEY] && typeof metadata[RUN_METADATA_KEY] === "object" ? metadata[RUN_METADATA_KEY] : {},
|
||||
toolMode: normalizeAgentRunToolMode(toolMode),
|
||||
...taskType ? { taskType } : {}
|
||||
};
|
||||
return { ...message, metadata };
|
||||
}
|
||||
function getRunOptionsFromMessage(userMessage) {
|
||||
const metadata = userMessage?.metadata;
|
||||
const runMetadata = metadata?.[RUN_METADATA_KEY] ?? metadata?.agentRun ?? {};
|
||||
let toolMode = "chat";
|
||||
try {
|
||||
toolMode = normalizeAgentRunToolMode(runMetadata?.toolMode ?? metadata?.toolMode ?? "chat");
|
||||
} catch {
|
||||
toolMode = "chat";
|
||||
}
|
||||
return {
|
||||
toolMode,
|
||||
taskType: normalizeTaskType(runMetadata?.taskType ?? metadata?.taskType)
|
||||
};
|
||||
}
|
||||
function projectRun(row) {
|
||||
if (!row) return null;
|
||||
return {
|
||||
@@ -6578,11 +6614,19 @@ function createAgentRunGateway({
|
||||
);
|
||||
return rows[0] ?? null;
|
||||
}
|
||||
async function createRun(userId, { sessionId = null, requestId, userMessage }) {
|
||||
async function createRun(userId, {
|
||||
sessionId = null,
|
||||
requestId,
|
||||
userMessage,
|
||||
toolMode = "chat",
|
||||
taskType = null
|
||||
}) {
|
||||
const normalizedRequestId = String(requestId ?? "").trim();
|
||||
if (!normalizedRequestId) {
|
||||
throw new Error("\u7F3A\u5C11 request_id");
|
||||
}
|
||||
const normalizedToolMode = normalizeAgentRunToolMode(toolMode);
|
||||
const normalizedTaskType = normalizeTaskType(taskType);
|
||||
const existing = await getRunByRequest(userId, normalizedRequestId);
|
||||
if (existing) {
|
||||
if (autoDispatch && !TERMINAL_STATUSES.has(existing.status)) dispatchRun(existing.id);
|
||||
@@ -6590,6 +6634,10 @@ function createAgentRunGateway({
|
||||
}
|
||||
const runId = crypto3.randomUUID();
|
||||
const createdAt = nowMs();
|
||||
const runMessage = withRunMetadata(userMessage, {
|
||||
toolMode: normalizedToolMode,
|
||||
taskType: normalizedTaskType
|
||||
});
|
||||
await pool2.query(
|
||||
`INSERT INTO h5_agent_runs
|
||||
(id, user_id, agent_session_id, request_id, status, attempts,
|
||||
@@ -6600,12 +6648,16 @@ function createAgentRunGateway({
|
||||
userId,
|
||||
sessionId || null,
|
||||
normalizedRequestId,
|
||||
serializeMessage(userMessage),
|
||||
serializeMessage(runMessage),
|
||||
createdAt,
|
||||
createdAt
|
||||
]
|
||||
);
|
||||
await appendEvent(runId, "queued", { sessionId: sessionId || null });
|
||||
await appendEvent(runId, "queued", {
|
||||
sessionId: sessionId || null,
|
||||
toolMode: normalizedToolMode,
|
||||
taskType: normalizedTaskType
|
||||
});
|
||||
if (autoDispatch) dispatchRun(runId);
|
||||
return projectRun(await getRunById(runId));
|
||||
}
|
||||
@@ -6636,22 +6688,32 @@ function createAgentRunGateway({
|
||||
if (Number(claim?.affectedRows ?? 0) === 0) return;
|
||||
await appendEvent(runId, "running", { attempt: nextAttempt });
|
||||
try {
|
||||
const userMessage = safeJsonParse(row.user_message_json, {});
|
||||
const runOptions = getRunOptionsFromMessage(userMessage);
|
||||
let sessionId = row.agent_session_id ?? null;
|
||||
if (!sessionId) {
|
||||
const session = await tkmindProxy2.startSessionForUser(row.user_id);
|
||||
const sessionOptions = {};
|
||||
if (runOptions.toolMode === "code" && userAuth2?.getCodeAgentSessionPolicy) {
|
||||
sessionOptions.sessionPolicy = await userAuth2.getCodeAgentSessionPolicy(row.user_id);
|
||||
}
|
||||
const session = await tkmindProxy2.startSessionForUser(row.user_id, sessionOptions);
|
||||
sessionId = session.id;
|
||||
await pool2.query(
|
||||
`UPDATE h5_agent_runs SET agent_session_id = ?, updated_at = ? WHERE id = ?`,
|
||||
[sessionId, nowMs(), runId]
|
||||
);
|
||||
await appendEvent(runId, "session_started", { sessionId });
|
||||
await appendEvent(runId, "session_started", {
|
||||
sessionId,
|
||||
toolMode: runOptions.toolMode,
|
||||
taskType: runOptions.taskType
|
||||
});
|
||||
}
|
||||
const userMessage = safeJsonParse(row.user_message_json, {});
|
||||
await tkmindProxy2.submitSessionReplyForUser(
|
||||
row.user_id,
|
||||
sessionId,
|
||||
row.request_id,
|
||||
userMessage
|
||||
userMessage,
|
||||
{ toolMode: runOptions.toolMode }
|
||||
);
|
||||
await markRun(runId, "succeeded", {
|
||||
agent_session_id: sessionId,
|
||||
@@ -6688,6 +6750,8 @@ function createPostAgentRunsHandler({ userAuth: userAuth2, agentRunGateway: agen
|
||||
const sessionId = String(request.body?.session_id ?? "").trim() || null;
|
||||
const requestId = String(request.body?.request_id ?? "").trim();
|
||||
const userMessage = request.body?.user_message ?? null;
|
||||
const rawToolMode = request.body?.tool_mode ?? request.body?.toolMode ?? "chat";
|
||||
const taskType = String(request.body?.task_type ?? request.body?.taskType ?? "").trim() || null;
|
||||
if (!requestId) {
|
||||
response.status(400).json({ message: "\u7F3A\u5C11 request_id" });
|
||||
return;
|
||||
@@ -6696,6 +6760,15 @@ function createPostAgentRunsHandler({ userAuth: userAuth2, agentRunGateway: agen
|
||||
response.status(400).json({ message: "\u7F3A\u5C11 user_message" });
|
||||
return;
|
||||
}
|
||||
let toolMode = "chat";
|
||||
try {
|
||||
toolMode = normalizeAgentRunToolMode(rawToolMode);
|
||||
} catch (err) {
|
||||
response.status(400).json({
|
||||
message: err instanceof Error ? err.message : "\u4E0D\u652F\u6301\u7684 tool_mode"
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (sessionId) {
|
||||
const owns = await userAuth2.ownsSession(request.currentUser.id, sessionId);
|
||||
if (!owns) {
|
||||
@@ -6706,7 +6779,9 @@ function createPostAgentRunsHandler({ userAuth: userAuth2, agentRunGateway: agen
|
||||
const run = await agentRunGateway2.createRun(request.currentUser.id, {
|
||||
sessionId,
|
||||
requestId,
|
||||
userMessage
|
||||
userMessage,
|
||||
toolMode,
|
||||
taskType
|
||||
});
|
||||
response.status(202).json({ run });
|
||||
} catch (err) {
|
||||
@@ -9385,11 +9460,17 @@ function createTkmindProxy({
|
||||
imgproxySigner
|
||||
});
|
||||
}
|
||||
async function reconcileSessionPolicyForUser(userId, sessionId) {
|
||||
async function getSessionPolicyForToolMode(userId, toolMode = "chat") {
|
||||
if (toolMode === "code" && userAuth2.getCodeAgentSessionPolicy) {
|
||||
return userAuth2.getCodeAgentSessionPolicy(userId);
|
||||
}
|
||||
return userAuth2.getAgentSessionPolicy(userId);
|
||||
}
|
||||
async function reconcileSessionPolicyForUser(userId, sessionId, { toolMode = "chat" } = {}) {
|
||||
if (!userId || !sessionId) return;
|
||||
const target = await resolveTarget(sessionId);
|
||||
const workingDir = await userAuth2.resolveWorkingDir(userId);
|
||||
const sessionPolicy = await userAuth2.getAgentSessionPolicy(userId);
|
||||
const sessionPolicy = await getSessionPolicyForToolMode(userId, toolMode);
|
||||
const publishLayout = await userAuth2.getUserPublishLayout(userId);
|
||||
const userMemories = conversationMemoryService2?.listMemories ? await conversationMemoryService2.listMemories(userId, { limit: 40 }).catch(() => []) : [];
|
||||
await reconcileAgentSession(
|
||||
@@ -9410,7 +9491,7 @@ function createTkmindProxy({
|
||||
}
|
||||
);
|
||||
}
|
||||
async function submitSessionReplyForUser(userId, sessionId, requestId, userMessage) {
|
||||
async function submitSessionReplyForUser(userId, sessionId, requestId, userMessage, { toolMode = "chat" } = {}) {
|
||||
if (!userId || !sessionId) throw new Error("\u7F3A\u5C11\u4F1A\u8BDD\u4FE1\u606F");
|
||||
const owns = await userAuth2.ownsSession(userId, sessionId);
|
||||
if (!owns) throw new Error("\u65E0\u6743\u8BBF\u95EE\u8BE5\u4F1A\u8BDD");
|
||||
@@ -9421,7 +9502,7 @@ function createTkmindProxy({
|
||||
err.status = 402;
|
||||
throw err;
|
||||
}
|
||||
await reconcileSessionPolicyForUser(userId, sessionId);
|
||||
await reconcileSessionPolicyForUser(userId, sessionId, { toolMode });
|
||||
await applySessionLlmProvider(sessionId);
|
||||
const user = await userAuth2.getUserById(userId);
|
||||
if (!user) throw new Error("\u7528\u6237\u4E0D\u5B58\u5728");
|
||||
|
||||
Reference in New Issue
Block a user