fix: clarify sessions_send delivery semantics

This commit is contained in:
Peter Steinberger
2026-01-10 00:32:20 +01:00
parent 96e17d407a
commit a25922a21f
7 changed files with 96 additions and 13 deletions

View File

@@ -243,7 +243,11 @@ describe("sessions tools", () => {
message: "ping",
timeoutSeconds: 0,
});
expect(fire.details).toMatchObject({ status: "accepted", runId: "run-1" });
expect(fire.details).toMatchObject({
status: "accepted",
runId: "run-1",
delivery: { status: "pending", mode: "announce" },
});
await new Promise((resolve) => setTimeout(resolve, 0));
await new Promise((resolve) => setTimeout(resolve, 0));
@@ -256,6 +260,7 @@ describe("sessions tools", () => {
expect(waited.details).toMatchObject({
status: "ok",
reply: "done",
delivery: { status: "pending", mode: "announce" },
});
expect(typeof (waited.details as { runId?: string }).runId).toBe("string");
await new Promise((resolve) => setTimeout(resolve, 0));

View File

@@ -4,6 +4,8 @@ import { Type } from "@sinclair/typebox";
import { loadConfig } from "../../config/config.js";
import { callGateway } from "../../gateway/call.js";
import { formatErrorMessage } from "../../infra/errors.js";
import { createSubsystemLogger } from "../../logging.js";
import {
isSubagentSessionKey,
normalizeAgentId,
@@ -35,6 +37,8 @@ import {
resolvePingPongTurns,
} from "./sessions-send-helpers.js";
const log = createSubsystemLogger("agents/sessions-send");
const SessionsSendToolSchema = Type.Object({
sessionKey: Type.Optional(Type.String()),
label: Type.Optional(
@@ -308,11 +312,13 @@ export function createSessionsSendTool(opts?: {
const requesterSessionKey = opts?.agentSessionKey;
const requesterProvider = opts?.agentProvider;
const maxPingPongTurns = resolvePingPongTurns(cfg);
const delivery = { status: "pending", mode: "announce" as const };
const runAgentToAgentFlow = async (
roundOneReply?: string,
runInfo?: { runId: string },
) => {
const runContextId = runInfo?.runId ?? runId;
try {
let primaryReply = roundOneReply;
let latestReply = roundOneReply;
@@ -400,20 +406,32 @@ export function createSessionsSendTool(opts?: {
announceReply.trim() &&
!isAnnounceSkip(announceReply)
) {
await callGateway({
method: "send",
params: {
to: announceTarget.to,
message: announceReply.trim(),
try {
await callGateway({
method: "send",
params: {
to: announceTarget.to,
message: announceReply.trim(),
provider: announceTarget.provider,
accountId: announceTarget.accountId,
idempotencyKey: crypto.randomUUID(),
},
timeoutMs: 10_000,
});
} catch (err) {
log.warn("sessions_send announce delivery failed", {
runId: runContextId,
provider: announceTarget.provider,
accountId: announceTarget.accountId,
idempotencyKey: crypto.randomUUID(),
},
timeoutMs: 10_000,
});
to: announceTarget.to,
error: formatErrorMessage(err),
});
}
}
} catch {
// Best-effort follow-ups; ignore failures to avoid breaking the caller response.
} catch (err) {
log.warn("sessions_send announce flow failed", {
runId: runContextId,
error: formatErrorMessage(err),
});
}
};
@@ -432,6 +450,7 @@ export function createSessionsSendTool(opts?: {
runId,
status: "accepted",
sessionKey: displayKey,
delivery,
});
} catch (err) {
const messageText =
@@ -535,6 +554,7 @@ export function createSessionsSendTool(opts?: {
status: "ok",
reply,
sessionKey: displayKey,
delivery,
});
},
};