fix: wait on agent.wait for sessions_send
This commit is contained in:
@@ -123,17 +123,29 @@ describe("sessions tools", () => {
|
||||
|
||||
it("sessions_send supports fire-and-forget and wait", async () => {
|
||||
callGatewayMock.mockReset();
|
||||
const calls: Array<{ method?: string; expectFinal?: boolean }> = [];
|
||||
const calls: Array<{ method?: string; params?: unknown }> = [];
|
||||
callGatewayMock.mockImplementation(async (opts: unknown) => {
|
||||
const request = opts as { method?: string; expectFinal?: boolean };
|
||||
const request = opts as { method?: string; params?: unknown };
|
||||
calls.push(request);
|
||||
if (request.method === "agent") {
|
||||
return { runId: "run-1", status: "accepted" };
|
||||
return { runId: "run-1", status: "accepted", acceptedAt: 1234 };
|
||||
}
|
||||
if (request.method === "agent.wait") {
|
||||
return { runId: "run-1", status: "ok" };
|
||||
}
|
||||
if (request.method === "chat.history") {
|
||||
return {
|
||||
messages: [
|
||||
{ role: "assistant", content: [{ type: "text", text: "done" }] },
|
||||
{
|
||||
role: "assistant",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "done",
|
||||
},
|
||||
],
|
||||
timestamp: 20,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -156,7 +168,7 @@ describe("sessions tools", () => {
|
||||
const waitPromise = tool.execute("call6", {
|
||||
sessionKey: "main",
|
||||
message: "wait",
|
||||
timeoutSeconds: 5,
|
||||
timeoutSeconds: 1,
|
||||
});
|
||||
const waited = await waitPromise;
|
||||
expect(waited.details).toMatchObject({
|
||||
@@ -166,7 +178,13 @@ describe("sessions tools", () => {
|
||||
});
|
||||
|
||||
const agentCalls = calls.filter((call) => call.method === "agent");
|
||||
expect(agentCalls[0]?.expectFinal).toBeUndefined();
|
||||
expect(agentCalls[1]?.expectFinal).toBe(true);
|
||||
const waitCalls = calls.filter((call) => call.method === "agent.wait");
|
||||
const historyOnlyCalls = calls.filter(
|
||||
(call) => call.method === "chat.history",
|
||||
);
|
||||
expect(agentCalls).toHaveLength(2);
|
||||
expect(waitCalls).toHaveLength(1);
|
||||
expect(historyOnlyCalls).toHaveLength(1);
|
||||
expect(waitCalls[0]?.params).toMatchObject({ afterMs: 1234 });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1536,7 +1536,8 @@ function createNodesTool(): AnyAgentTool {
|
||||
const node = readStringParam(params, "node", { required: true });
|
||||
const nodeId = await resolveNodeId(gatewayOpts, node);
|
||||
const maxAgeMs =
|
||||
typeof params.maxAgeMs === "number" && Number.isFinite(params.maxAgeMs)
|
||||
typeof params.maxAgeMs === "number" &&
|
||||
Number.isFinite(params.maxAgeMs)
|
||||
? params.maxAgeMs
|
||||
: undefined;
|
||||
const desiredAccuracy =
|
||||
@@ -2736,7 +2737,7 @@ function createSessionsSendTool(): AnyAgentTool {
|
||||
? Math.max(0, Math.floor(params.timeoutSeconds))
|
||||
: 30;
|
||||
const idempotencyKey = crypto.randomUUID();
|
||||
let runId = idempotencyKey;
|
||||
let runId: string = idempotencyKey;
|
||||
const displayKey = resolveDisplaySessionKey({
|
||||
key: sessionKey,
|
||||
alias,
|
||||
@@ -2776,39 +2777,22 @@ function createSessionsSendTool(): AnyAgentTool {
|
||||
}
|
||||
}
|
||||
|
||||
let acceptedAt: number | undefined;
|
||||
try {
|
||||
const response = (await callGateway({
|
||||
method: "agent",
|
||||
params: sendParams,
|
||||
expectFinal: true,
|
||||
timeoutMs: timeoutSeconds * 1000,
|
||||
})) as { runId?: string; status?: string };
|
||||
timeoutMs: 10_000,
|
||||
})) as { runId?: string; acceptedAt?: number };
|
||||
if (typeof response?.runId === "string" && response.runId) {
|
||||
runId = response.runId;
|
||||
}
|
||||
if (typeof response?.acceptedAt === "number") {
|
||||
acceptedAt = response.acceptedAt;
|
||||
}
|
||||
} catch (err) {
|
||||
const message =
|
||||
err instanceof Error ? err.message : String(err ?? "error");
|
||||
if (message.includes("gateway timeout")) {
|
||||
try {
|
||||
const cached = (await callGateway({
|
||||
method: "agent",
|
||||
params: sendParams,
|
||||
timeoutMs: 5_000,
|
||||
})) as { runId?: string };
|
||||
if (typeof cached?.runId === "string" && cached.runId) {
|
||||
runId = cached.runId;
|
||||
}
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
return jsonResult({
|
||||
runId,
|
||||
status: "timeout",
|
||||
error: message,
|
||||
sessionKey: displayKey,
|
||||
});
|
||||
}
|
||||
return jsonResult({
|
||||
runId,
|
||||
status: "error",
|
||||
@@ -2817,6 +2801,49 @@ function createSessionsSendTool(): AnyAgentTool {
|
||||
});
|
||||
}
|
||||
|
||||
const timeoutMs = timeoutSeconds * 1000;
|
||||
let waitStatus: string | undefined;
|
||||
let waitError: string | undefined;
|
||||
try {
|
||||
const wait = (await callGateway({
|
||||
method: "agent.wait",
|
||||
params: {
|
||||
runId,
|
||||
afterMs: acceptedAt,
|
||||
timeoutMs,
|
||||
},
|
||||
timeoutMs: timeoutMs + 2000,
|
||||
})) as { status?: string; error?: string };
|
||||
waitStatus = typeof wait?.status === "string" ? wait.status : undefined;
|
||||
waitError = typeof wait?.error === "string" ? wait.error : undefined;
|
||||
} catch (err) {
|
||||
const message =
|
||||
err instanceof Error ? err.message : String(err ?? "error");
|
||||
return jsonResult({
|
||||
runId,
|
||||
status: message.includes("gateway timeout") ? "timeout" : "error",
|
||||
error: message,
|
||||
sessionKey: displayKey,
|
||||
});
|
||||
}
|
||||
|
||||
if (waitStatus === "timeout") {
|
||||
return jsonResult({
|
||||
runId,
|
||||
status: "timeout",
|
||||
error: waitError,
|
||||
sessionKey: displayKey,
|
||||
});
|
||||
}
|
||||
if (waitStatus === "error") {
|
||||
return jsonResult({
|
||||
runId,
|
||||
status: "error",
|
||||
error: waitError ?? "agent error",
|
||||
sessionKey: displayKey,
|
||||
});
|
||||
}
|
||||
|
||||
const history = (await callGateway({
|
||||
method: "chat.history",
|
||||
params: { sessionKey: resolvedKey, limit: 50 },
|
||||
|
||||
Reference in New Issue
Block a user