@sema-agent/core
Version:
Stateless, task-oriented AI agent core
1,122 lines • 81.3 kB
JavaScript
import { Type } from "typebox";
import { isNotificationInjectionOutcome } from "../core/task-notification.js";
import { defineTool } from "../core/tools.js";
import { normalizeAgentName, DURABLE_AGENT_HANDLE_RE, DURABLE_AGENT_HEARTBEAT_MS } from "../core/task-registry.js";
import { announceTranscriptIntegrityGapOnce, canAccessAgentRecord, clearRevivedRowTerminalPayload } from "../core/background-agent-store.js";
import { uuidv7 } from "../internal/harness.js";
import { MAILBOX_TOMBSTONED_RECIPIENT_CODE, mailboxCrossProcessMountVerdict } from "../core/mailbox-store.js";
import { peerSendVerdictSeverity } from "./cross-session-judge.js";
import { parsePeerSessionAddress, peerSessionBoxHandle, resolvePeerSessions } from "./peer-directory.js";
import { peerIdleMachineFor } from "./peer-idle.js";
import { PEER_IDLE_OUTSTANDING_CAP, PEER_IDLE_SUBSCRIPTION_TTL_MS, peerIdleNoticeLabel } from "./peer-notices.js";
import { escapeAttributeValue, escapeEnvelopeTag, isObserverTaskId, OBSERVER_SENDMESSAGE_SENDER_REFUSAL, OBSERVER_SENDMESSAGE_TARGET_REFUSAL, } from "./observer.js";
import { inlineUntrusted } from "../core/untrusted-text.js";
import { neutralizePeerBody } from "./cross-session-envelope.js";
import { SUBAGENT_RESUME_CAP, SubagentRetainLedger, getSessionRetainLedger } from "./retain-ledger.js";
import { createSubagentResume } from "./subagent.js";
import { appendHopToken, judgePeerAdmission, peerAxisToken, resolvePeerLaneConfig, PEER_MESSAGE_NOTICE, } from "./peer-admission.js";
import { toolFace } from "../core/tool-catalog-entries.js";
import { thrownText } from "../core/thrown-value.js";
import { assertNoRetiredKeys } from "../core/retired-keys.js";
import { resolveSubagentTranscriptTier } from "../core/wiring-manifest.js";
export const SEND_MESSAGE_TOOL_NAME = "SendMessage";
let uplinkSeqGlobal = Date.now();
const UPLINK_RESULT_MAX = 8000;
function clipCarrierMessage(text) {
return text.length > UPLINK_RESULT_MAX ? `${text.slice(0, UPLINK_RESULT_MAX)}\n[message truncated: ${text.length} chars total]` : text;
}
export const SEND_MESSAGE_SUMMARY_MAX = 200;
const RETIRED_SEND_MESSAGE_OPTION_KEYS = {
admission: "the peer lane's knob table is `SendMessageToolOptions.lane` (the same fields; the Runner mount threads `RunnerDeps.peerLane` there)",
};
function assertNoRetiredSendMessageOptions(opts) {
assertNoRetiredKeys(opts, RETIRED_SEND_MESSAGE_OPTION_KEYS, "SendMessageToolOptions");
}
export function clipSendMessageSummary(raw) {
return raw.length > SEND_MESSAGE_SUMMARY_MAX
? `${raw.slice(0, SEND_MESSAGE_SUMMARY_MAX)} [summary truncated: ${raw.length} chars total]`
: raw;
}
const TEAMMATE_MESSAGE_TAG = "teammate-message";
function frameTeammateMessage(args) {
const summaryAttr = args.summary !== undefined ? ` summary="${escapeAttributeValue(args.summary)}"` : "";
const body = escapeEnvelopeTag(TEAMMATE_MESSAGE_TAG, neutralizePeerBody(args.text));
return `<${TEAMMATE_MESSAGE_TAG} teammate_id="${escapeAttributeValue(args.from)}"${summaryAttr}>\n${body}\n</${TEAMMATE_MESSAGE_TAG}>`;
}
const REVIVE_LEASE_TTL_MS = 5 * 60_000;
const PEER_REFUSAL_TEXT_MAX = 1200;
const sendMessageTargetLanes = new Map();
function withTargetLane(key, fn) {
const prev = sendMessageTargetLanes.get(key) ?? Promise.resolve();
const run = prev.then(fn, fn);
const tail = run.then(() => undefined, () => undefined);
sendMessageTargetLanes.set(key, tail);
void tail.then(() => {
if (sendMessageTargetLanes.get(key) === tail)
sendMessageTargetLanes.delete(key);
});
return run;
}
function targetLaneKey(scope, targetId) {
return JSON.stringify([scope ?? "", targetId]);
}
const OPERATOR_CONTINUATION_CTX = Symbol("sema.operator_continuation");
export function sendMessageContinuationTier(seats) {
const tier3Capable = seats.agentStore !== undefined && seats.mailbox !== undefined && seats.reviveSpawn !== undefined;
return tier3Capable ? resolveSubagentTranscriptTier(true, seats.runner.sessions) : "none";
}
export function createSendMessageTool(opts) {
assertNoRetiredSendMessageOptions(opts);
const continuationTier = sendMessageContinuationTier(opts);
const notifyWhenIdleParameter = {
notify_when_idle: Type.Optional(Type.Boolean({
description: "Ask a peer SESSION of this engine to send you ONE notice when it next goes idle (finishes its turn with nothing queued) or exits — opt-in, one-shot, no polling. With a message: deliver it now AND subscribe. Without a message (omit it): a pure subscription that costs the other session nothing. Peer sessions only (not agents or teammates), and only from the main conversation.",
})),
urgent: Type.Optional(Type.Boolean({
description: "Peer sessions only: mark this message urgent. The recipient reads it ahead of the other messages of the same round and its inbox notice counts it; it does NOT wake the recipient or change when it reads — the recipient's own setting decides that.",
})),
};
const peerLane = (() => {
if (opts.peerDirectory === undefined)
return { active: false };
if (opts.mailbox === undefined)
return { active: false, reason: "a peer-session directory is wired but no mailbox store is (the lane parks messages in the recipient's durable session box)" };
const verdict = mailboxCrossProcessMountVerdict(opts.mailbox);
return verdict.ok ? { active: true } : { active: false, reason: verdict.reason };
})();
const baseParameters = Type.Object({
to: Type.String({ description: 'Recipient: the agent\'s name, or its task_id (a…) returned by the Agent tool with run_in_background. "main" is reserved for the spawning conversation.' }),
message: Type.String({ description: "The follow-up request. The agent continues from its full prior context." }),
summary: Type.Optional(Type.String({ maxLength: 200, description: "A 5-10 word summary shown as a preview in the UI (required when message is a string)" })),
});
const sendMessageParameters = peerLane.active
? Type.Object({ ...baseParameters.properties, message: Type.Optional(Type.String({ description: `${baseParameters.properties.message.description ?? ""} Optional only for a pure notify_when_idle subscription.`.trim() })), ...notifyWhenIdleParameter })
: baseParameters;
const retrievalMounted = opts.retrievalToolMounted;
const retrievalHedge = retrievalMounted === undefined ? " (where that tool is mounted)" : "";
const RETRIEVE_NOW = retrievalMounted === false
? "its result cannot be collected by this run (no TaskOutput is mounted beside this tool) — do not wait for it, and say so in your answer if the result matters"
: `retrieve its result NOW with TaskOutput(task_id, block: true)${retrievalHedge} rather than ending your turn`;
const RETRIEVE_LATER = retrievalMounted === false
? "its result cannot be collected by this run (no TaskOutput is mounted beside this tool)"
: "retrieve its status and result with TaskOutput(task_id) where mounted";
const WAIT_NOW = retrievalMounted === false
? "do not wait for it — this face has no TaskOutput to block on, and"
: `wait for it NOW with TaskOutput(task_id, block: true)${retrievalHedge} —`;
const CHECK_LATER = retrievalMounted === false
? "its completion cannot be checked from this face (no TaskOutput is mounted beside this tool)"
: "check for its completion with TaskOutput(task_id) where mounted";
const capitalize = (text) => `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
const completionMode = opts.oneShot === true ? "one_shot" : (opts.notificationWired ?? opts.notify !== undefined) ? "notified" : "silent";
const notifyWired = completionMode === "notified";
const NO_COMPLETION_NOTICE = completionMode === "one_shot"
? `this is a ONE-SHOT submission — there is no later turn for a completion notification to land in, so ${RETRIEVE_NOW}`
: `its completion is NOT announced on this mount — ${RETRIEVE_LATER}`;
const AWAIT_COMPLETION = notifyWired
? "Wait for its completion notification"
: completionMode === "one_shot"
? `${capitalize(WAIT_NOW)} this one-shot submission ends with this turn`
: capitalize(CHECK_LATER);
const awaitCompletion = notifyWired
? "wait for its completion notification"
: completionMode === "one_shot"
? `${WAIT_NOW} this one-shot submission ends with this turn`
: CHECK_LATER;
const sendMessagePins = new Map();
const pinGuard = (targetId, targetName, rung, to) => {
if (rung === "other")
return undefined;
const pinKey = normalizeAgentName(targetName ?? "");
if (pinKey === "")
return undefined;
const pinned = sendMessagePins.get(pinKey);
if (pinned === undefined || pinned.id === targetId) {
sendMessagePins.set(pinKey, { id: targetId, name: targetName ?? to });
return undefined;
}
if (rung === "ref") {
sendMessagePins.set(pinKey, { id: targetId, name: targetName ?? to });
return undefined;
}
if (targetName !== undefined && normalizeAgentName(to) === pinKey && normalizeAgentName(pinned.name) !== pinKey) {
return undefined;
}
return {
content: `Message not sent: "${inlineUntrusted(to, 120)}" now resolves to a different agent than it did earlier in ` +
`this run — this name previously resolved to ${pinned.id.slice(0, 64)}, which it no longer reaches. Nothing was sent.\n` +
`It now resolves to ${targetId.slice(0, 64)}. To message that agent, re-send with its task_id: ` +
`{"to": "${targetId.slice(0, 64)}", …}. To reach the earlier agent, use its task_id ` +
`${pinned.id.slice(0, 64)} from its spawn result.`,
details: { error: "rebound", to, taskId: targetId, previousTaskId: pinned.id },
isError: true,
};
};
return defineTool({
name: SEND_MESSAGE_TOOL_NAME,
...toolFace("send-message"),
executionMode: "parallel",
description: `Send a follow-up message to a previously spawned background agent. ` +
`Your plain text output is NOT visible to other agents — to communicate, you MUST call this tool. Messages addressed to you are delivered automatically; you don't check an inbox. ` +
`'to' is the agent's name (set at spawn via Agent({name})) or its task_id (a…). A RUNNING agent receives the ` +
`message at its next turn (queued — never interrupts its current work); a FINISHED agent resumes as a new ` +
`background run with its full prior conversation preserved, so don't re-explain what it already knows. Names ` +
`keep working after an agent completes; but if a name you already messaged is later taken by a NEWER agent, the ` +
`send is refused rather than silently redirected — re-send with the task_id of whichever agent you meant. ` +
(notifyWired
? `You will be notified automatically when it completes — prefer ending your turn; do not poll. `
: completionMode === "one_shot"
? `This is a ONE-SHOT submission: there is no later turn for a completion notification to land in, so do NOT end your turn expecting one${retrievalMounted === false
? "; a continued agent's result cannot be collected by this run (no TaskOutput is mounted beside this tool) — say so if the result matters"
: ` — wait actively with TaskOutput(task_id, block: true)${retrievalHedge} when you need a continued agent's result`}. `
: `A finished agent is NOT announced on this mount${retrievalMounted === false
? ", and its result cannot be collected by this run (no TaskOutput is mounted beside this tool) — do not end your turn to wait for a notification that never comes"
: " — check on it with TaskOutput(task_id) where mounted rather than ending your turn to wait for a notification that never comes"}. `) +
(continuationTier === "full"
? `Continuing a finished agent works for agents with a durable record — by name or task_id, even across restarts — and for runs that retain sub-agent sessions; when neither covers it you get an honest error and should launch a new agent with the needed context instead.`
: continuationTier === "rows"
? `Continuing a finished agent works by name or task_id while this engine process still holds its conversation, and for runs that retain sub-agent sessions — its record outlives a restart but its conversation does not, so after a restart it cannot be continued; when neither covers it you get an honest error and should launch a new agent with the needed context instead.`
: `Continuing a finished agent requires the run to retain sub-agent sessions; when the session was not ` +
`retained (or is no longer held) you get an honest error and should launch a new agent with the needed context instead.`) +
(peerLane.active
? ` Peer SESSIONS — other sessions of this engine for the same user${opts.peerListingMounted === false ? "" : opts.peerListingMounted === true ? " (list them with ListAgents)" : " (list them with ListAgents where that tool is mounted)"} — are addressed by name, by \`name [ref]\` when a name is ambiguous, or by their \`session.<id>\` address. A message to a peer is parked durably in its session box and read at its next turn boundary (an offline peer reads it when it next runs); the receipt confirms the box accepted it, not that the peer acted on it.`
: ""),
parameters: sendMessageParameters,
execute: async (args, ctx) => {
const a = args;
const operatorUserInitiated = ctx[OPERATOR_CONTINUATION_CTX] === true;
const to = String(a.to ?? "").trim();
const message = String(a.message ?? "").trim();
const notifyWhenIdle = a.notify_when_idle === true;
const urgent = a.urgent === true;
if (!to)
return { content: "Message not sent: 'to' was empty. Pass the agent's task_id (a…).", details: { error: "empty to" }, isError: true };
if (!message && !notifyWhenIdle)
return { content: "Message not sent: 'message' was empty.", details: { error: "empty message" }, isError: true };
if (to === "*") {
return {
content: 'Message not sent: broadcast (to: "*") is no longer supported — send a message per recipient.',
details: { error: "broadcast_unsupported", to },
isError: true,
};
}
if (to.includes("@")) {
return {
content: "Message not sent: to must be a bare teammate name — there is only one team per session.",
details: { error: "qualified_name_unsupported", to },
isError: true,
};
}
const summaryArg = typeof a.summary === "string" ? a.summary.trim() : "";
if (summaryArg === "" && message !== "") {
return {
content: "Message not sent: summary is required when message is a string — pass a 5-10 word summary of the follow-up.",
details: { error: "summary_required", to },
isError: true,
};
}
const summary = clipSendMessageSummary(summaryArg);
const senderId = ctx.taskId ?? opts.owner;
const [parentTaskId, parentSessionId] = ctx.parentTaskId !== undefined ? [ctx.parentTaskId, ctx.parentSessionId] : [opts.parentTaskId, opts.parentSessionId];
const senderName = ctx.spawnedAgentName ?? opts.senderName;
const senderIsChild = parentTaskId !== undefined || opts.uplink !== undefined || opts.uplinkSessionId !== undefined || senderName !== undefined || opts.siblingRetain !== undefined;
const senderLabel = senderName ?? (senderIsChild ? senderId ?? "main" : "main");
if (senderId !== undefined && isObserverTaskId(senderId)) {
return { content: OBSERVER_SENDMESSAGE_SENDER_REFUSAL, details: { error: "observer_sender" }, isError: true };
}
if (isObserverTaskId(to)) {
return { content: OBSERVER_SENDMESSAGE_TARGET_REFUSAL, details: { error: "observer_target", to }, isError: true };
}
const admissionConfig = resolvePeerLaneConfig(opts.lane, opts.onNotice);
const guardScope = ctx.principal ?? opts.scope ?? opts.peerSelfSession?.scope;
const selfRef = ctx.peerSelfRef ?? opts.peerSelf;
const directMountSessionId = ctx.sessionId ?? opts.sessionId ?? opts.peerSelfSession?.sessionId;
const directMountTaskId = ctx.taskId ?? opts.owner;
const senderKey = selfRef?.current.key ??
(directMountSessionId !== undefined
? peerAxisToken(guardScope, "s", directMountSessionId)
: directMountTaskId !== undefined
? peerAxisToken(guardScope, "t", directMountTaskId)
: undefined);
const inboundChain = (ctx.peerInboundChainRef ?? opts.peerInbound)?.current ?? [];
const prospectiveChain = appendHopToken(inboundChain, senderKey);
const admitFor = (recipientKey, ownTokens) => judgePeerAdmission(guardScope, recipientKey, { senderKey, body: message, prospectiveChain, ownTokens }, admissionConfig);
const DEDUP_RETRY_NOTE = "Note: resending the identical text within the dedup window reads as duplicate — rephrase or wait it out.";
const admissionRefusal = (reason, whoLabel) => {
const text = reason === "rate_limited"
? `you are sending messages to ${whoLabel} faster than its rate limit — the budget refills on its own; slow down and resend in a moment.`
: reason === "duplicate"
? `an identical message was already sent to ${whoLabel} moments ago — if this is genuinely new, rephrase it or wait out the dedup window.`
: reason === "hop_loop"
? `this message has already passed through ${whoLabel} too many times (a forwarding loop) — stop relaying it; act on it or drop it.`
: `this message's forwarding chain is too long (runaway relay) — stop relaying it; act on it or drop it.`;
return { content: `Message not sent: ${text}`, details: { error: reason, code: reason, to }, isError: true };
};
const peerRefusal = (code, text, extra) => {
const verdict = { ok: false, code, severity: peerSendVerdictSeverity(code), message: text };
return { content: `Message not sent: ${text.slice(0, PEER_REFUSAL_TEXT_MAX)}`, details: { error: code, code, to, verdict, ...extra }, isError: true };
};
const peerSelfSessionId = opts.peerSelfSession?.sessionId ?? directMountSessionId;
const peerScope = guardScope ?? opts.peerSelfSession?.scope;
let ownRowName;
const resolvePeerTarget = async () => {
try {
const rows = await opts.peerDirectory.listPeerSessions({ scope: peerScope ?? "" });
if (peerSelfSessionId !== undefined)
ownRowName = rows.find((r) => r.sessionId.toLowerCase() === peerSelfSessionId.toLowerCase())?.name;
return resolvePeerSessions(rows, to, peerSelfSessionId !== undefined ? { sessionId: peerSelfSessionId } : undefined);
}
catch (e) {
return { status: "directory_fault", message: thrownText(e) };
}
};
const deliverToPeerSession = async (c) => {
const record = c.record;
const handle = peerSessionBoxHandle(record.sessionId);
const peerLabel = `peer session "${inlineUntrusted(record.name, 64)}" (${handle})`;
if (peerScope === undefined)
return peerRefusal("peer_send.other", `this mount has no scope axis, so ${peerLabel}'s box cannot be addressed.`);
if (record.inboundPosture === "unavailable") {
return peerRefusal("peer_send.recipient_refuses", `${peerLabel} advertises that it does not accept cross-session messages (its crossSessionInbound is "refuse"). Nothing was parked.`);
}
const modeClass = opts.peerSelfSession?.modeClass?.();
const now = Date.now();
let boxFull = false;
try {
boxFull = (await opts.mailbox.peekCount(peerScope, handle)) >= admissionConfig.maxQueuedPeerMessages;
}
catch {
}
if (boxFull) {
return { content: `Message not sent: ${inlineUntrusted(peerLabel, 200)}'s session box is at its queued-message limit (${admissionConfig.maxQueuedPeerMessages.toFixed(0)}) — the message was NOT queued; it drains the box at its next turn. Resend later. ${DEDUP_RETRY_NOTE.slice(0, 200)}`, details: { error: "queue_full", code: "queue_full", to }, isError: true };
}
let seq;
if (message !== "") {
const recipientKey = peerAxisToken(peerScope, "s", record.sessionId);
const storedContent = `[${summary}] ${clipCarrierMessage(message)}`;
const sendVerdict = judgePeerAdmission(peerScope, recipientKey, { senderKey, body: storedContent, prospectiveChain, ownTokens: [recipientKey] }, admissionConfig, undefined, "send");
if (!sendVerdict.ok)
return admissionRefusal(sendVerdict.reason, peerLabel);
const peerMeta = {
...(peerSelfSessionId !== undefined ? { fromSession: peerSelfSessionId } : {}),
...(modeClass === "bypass" || modeClass === "prompting" ? { fromMode: modeClass } : {}),
...(senderKey !== undefined ? { senderKey } : {}),
kind: "peer_message",
...(urgent ? { urgent: true } : {}),
};
try {
seq = await opts.mailbox.append(peerScope, handle, { from: ownRowName ?? opts.peerSelfSession?.name ?? senderLabel, content: storedContent, sentAt: now, hopChain: prospectiveChain, peerMeta });
}
catch (e) {
if (e?.code === MAILBOX_TOMBSTONED_RECIPIENT_CODE) {
return peerRefusal("peer_send.invalid_target", `${peerLabel} is being deleted — its box no longer accepts messages. Nothing was parked; do not retry.`);
}
return peerRefusal("peer_send.other", `the session box refused the message (${thrownText(e)}) — nothing was parked. ${DEDUP_RETRY_NOTE}`);
}
}
let subscription;
let subscriptionSeq;
if (notifyWhenIdle) {
if (peerSelfSessionId === undefined) {
subscription = { ok: false, code: "peer_send.other", severity: "error", message: "this mount has no session identity, so no idle notice could be addressed back to it — no subscription was made." };
}
else {
const ask = peerIdleMachineFor(peerScope, peerSelfSessionId).requester.request(record.sessionId, peerIdleNoticeLabel(record.name) ?? handle);
if (!ask.ok) {
subscription = { ok: false, code: "peer_send.subscription_cap", severity: peerSendVerdictSeverity("peer_send.subscription_cap"), message: `you already hold ${PEER_IDLE_OUTSTANDING_CAP} outstanding idle subscriptions — no new one was made; wait for a notice or for one to expire.` };
}
else {
const subMeta = {
fromSession: peerSelfSessionId,
...(modeClass === "bypass" || modeClass === "prompting" ? { fromMode: modeClass } : {}),
kind: "idle_subscription",
};
try {
subscriptionSeq = await opts.mailbox.append(peerScope, handle, { from: ownRowName ?? opts.peerSelfSession?.name ?? senderLabel, content: `[idle subscription] ${ownRowName ?? opts.peerSelfSession?.name ?? senderLabel} asked to be told once when this session next goes idle`, sentAt: now, hopChain: [], peerMeta: subMeta });
subscription = { ok: true, disposition: record.liveness !== "live" ? "parked_offline" : "queued", via: "store" };
}
catch (e) {
peerIdleMachineFor(peerScope, peerSelfSessionId).requester.settle(record.sessionId, "unavailable");
subscription = { ok: false, code: e?.code === MAILBOX_TOMBSTONED_RECIPIENT_CODE ? "peer_send.invalid_target" : "peer_send.other", severity: "error", message: `the session box refused the subscription record (${(thrownText(e)).slice(0, 200)}) — no subscription was made.` };
}
}
}
}
let rowRestored = "present";
try {
const rowsNow = await opts.peerDirectory.listPeerSessions({ scope: peerScope });
const nowRow = rowsNow.find((r) => r.sessionId.toLowerCase() === record.sessionId.toLowerCase());
if (nowRow?.liveness === "deleted")
rowRestored = "deleted_meanwhile";
else if (nowRow === undefined) {
rowRestored = opts.peerDirectory.restorePeerSession !== undefined && (await opts.peerDirectory.restorePeerSession(record)) ? "restored" : "unrestorable";
}
}
catch {
}
const rowNote = rowRestored === "unrestorable"
? " Note: the peer's directory row disappeared while this message was being parked and this directory cannot restore it — the message is safe in the box (it drains by session id), but the name may not resolve until that session next registers; its session.<id> address still does."
: rowRestored === "deleted_meanwhile"
? " Note: that session was DELETED while this message was being parked — its box is being retired and this message will not be read; do not resend to it."
: "";
const offline = record.liveness !== "live";
const subscriptionNote = subscription === undefined
? ""
: subscription.ok
? ` Idle subscription recorded (one-shot, expires unheard after ${PEER_IDLE_SUBSCRIPTION_TTL_MS / 3_600_000} h): you will get ONE automated notice when that session next goes idle or exits${offline ? " — it is offline now, so the ask waits in its box with the message" : ""}. Do not poll for it.`
: ` Idle subscription NOT made (${subscription.code}): ${subscription.message}`;
if (seq === undefined) {
if (subscription === undefined || !subscription.ok) {
return { content: `Subscription not made: ${subscription?.message ?? "nothing to do"}`, details: { error: subscription?.code ?? "peer_send.other", code: subscription?.code ?? "peer_send.other", to, ...(subscription !== undefined ? { subscription } : {}) }, isError: true };
}
return {
content: `Idle subscription recorded for ${peerLabel} (record seq ${subscriptionSeq}): you will get ONE automated notice when that session next goes idle or exits (one-shot; it expires unheard after ${PEER_IDLE_SUBSCRIPTION_TTL_MS / 3_600_000} h). No message was sent. Do not poll for it; continue with your task.${rowNote}`,
details: { type: "send-message", status: "peer_idle_subscribed", to, address: handle, subscription, ...(subscriptionSeq !== undefined ? { subscriptionSeq } : {}), ...(rowRestored !== "present" ? { directoryRow: rowRestored } : {}) },
};
}
const verdict = { ok: true, disposition: offline ? "parked_offline" : "queued", via: "store" };
return {
content: offline
? `Message parked for ${peerLabel}: that session is offline, so the message was parked durably in its session box (seq ${seq}) and will be delivered when it next runs — subject to the deployment's mailbox retirement policy, which does not notify you. Continue with your task; do not resend the same content.${subscriptionNote}${rowNote}`
: `Message queued for ${peerLabel} (seq ${seq}): it is parked durably in that session's box and will be read at its next turn boundary. This receipt confirms acceptance into the box, not the peer's judgment of the message. Continue with your task; do not resend the same content.${subscriptionNote}${rowNote}`,
details: { type: "send-message", status: offline ? "peer_parked_offline" : "peer_queued", to, address: handle, seq, verdict, ...(subscription !== undefined ? { subscription } : {}), ...(subscriptionSeq !== undefined ? { subscriptionSeq } : {}), ...(rowRestored !== "present" ? { directoryRow: rowRestored } : {}) },
};
};
const settlePeerResolution = async (r) => {
switch (r.status) {
case "directory_fault":
return peerRefusal("peer_send.other", `the peer-session directory could not be read (${r.message}) — nothing was sent.`);
case "not_found":
return undefined;
case "self":
return peerRefusal("peer_send.invalid_target", `"${inlineUntrusted(to, 120)}" is this session — a session cannot send a cross-session message to itself.`);
case "deleted":
return peerRefusal("peer_send.invalid_target", `peer session "${inlineUntrusted(r.candidate.record.name, 64)}" was deleted — its address no longer accepts messages. Nothing was parked.`);
case "stale_ref":
return peerRefusal("peer_send.invalid_target", `the ref [${r.ref}] no longer resolves (the peer set changed since you listed it) — re-run ListAgents and re-send with a current ref.`);
case "ambiguous":
return { content: `Message not sent: ${inlineUntrusted(r.message, 1000)}`, details: { error: "ambiguous", to, candidates: r.candidates.map((c) => ({ name: c.record.name, ref: c.ref, address: peerSessionBoxHandle(c.record.sessionId), liveness: c.record.liveness })) }, isError: true };
case "found": {
const guard = pinGuard(peerSessionBoxHandle(r.candidate.record.sessionId), r.candidate.record.name, r.rung === "name" ? "name" : "ref", to);
if (guard !== undefined)
return guard;
return await withTargetLane(targetLaneKey(peerScope, peerSessionBoxHandle(r.candidate.record.sessionId)), () => deliverToPeerSession(r.candidate));
}
default: {
const _exhaustive = r;
void _exhaustive;
return undefined;
}
}
};
if (notifyWhenIdle) {
if (!peerLane.active) {
return peerRefusal("peer_send.invalid_target", peerLane.reason !== undefined ? `notify_when_idle is only supported for peer sessions of this engine, and the cross-session lane is unavailable on this mount — ${peerLane.reason}. Nothing was sent.` : `notify_when_idle is only supported for peer sessions of this engine, and cross-session addressing is not mounted here (no peer-session directory). Nothing was sent.`);
}
if (senderIsChild) {
return peerRefusal("peer_send.invalid_target", "notify_when_idle is only available from the main conversation of this session (not from a subagent or teammate). Nothing was sent.");
}
const settled = await settlePeerResolution(await resolvePeerTarget());
return settled ?? peerRefusal("peer_send.invalid_target", `notify_when_idle is only supported for peer sessions of this engine (not teammates, subagents or agents), and no peer session is registered as "${inlineUntrusted(to, 120)}". Nothing was sent.`);
}
if (parsePeerSessionAddress(to) !== undefined) {
if (!peerLane.active) {
return peerRefusal("peer_send.invalid_target", peerLane.reason !== undefined ? `cross-session addressing is unavailable on this mount — ${peerLane.reason}. Nothing was sent.` : `cross-session addressing is not mounted here (no peer-session directory), so "${inlineUntrusted(to, 120)}" cannot be delivered.`);
}
const settled = await settlePeerResolution(await resolvePeerTarget());
return settled ?? peerRefusal("peer_send.invalid_target", `no session is registered at "${inlineUntrusted(to, 120)}" — nothing was parked (a message is only ever parked for a session that exists or existed).`);
}
if (normalizeAgentName(to) === "main") {
if (opts.uplink && senderId !== undefined) {
const uplinkIdentity = opts.uplinkRecipient?.current;
if (uplinkIdentity?.key !== undefined) {
const verdict = admitFor(uplinkIdentity.key, uplinkIdentity.ownTokens);
if (!verdict.ok)
return admissionRefusal(verdict.reason, "main");
}
const uplinkBody = message.length > UPLINK_RESULT_MAX ? `${message.slice(0, UPLINK_RESULT_MAX)}\n[uplink truncated: ${message.length} chars total — read the agent's transcript for the rest]` : message;
const uplinkSeq = ++uplinkSeqGlobal;
let outcome;
try {
const reported = await opts.uplink({
task_id: senderId,
task_type: "background_agent",
status: "event",
summary: `message from ${senderLabel}: ${summary}`,
result: `${uplinkBody}\n\n${PEER_MESSAGE_NOTICE}`,
seq: uplinkSeq,
peer: { hopChain: prospectiveChain, ...(directMountSessionId !== undefined ? { fromSession: directMountSessionId } : {}), ...(senderKey !== undefined ? { senderKey } : {}) },
agentMessage: { from: senderLabel, body: uplinkBody },
_sema_provenance: { kind: "agent_message", from: senderLabel, taskId: senderId, seq: uplinkSeq },
}, { priority: "next" });
outcome = isNotificationInjectionOutcome(reported) ? reported : undefined;
}
catch (e) {
return { content: `Message not sent: the parent's notification lane rejected it (${thrownText(e)}). ${DEDUP_RETRY_NOTE}`, details: { error: "uplink_failed", to }, isError: true };
}
const mainLabel = opts.uplinkSessionId !== undefined ? `session ${inlineUntrusted(opts.uplinkSessionId, 96)}` : "the spawning conversation";
const content = outcome === "parked_durably"
? `Message parked durably for main (${mainLabel}): it has no run in progress, so the message was appended to its durable session box and is read at the start of its next run (it survives a restart). Continue with your task; do not wait for a reply.`
: outcome === "parked"
? `Message parked in process for main (${mainLabel}): it has no run in progress, so the message waits in this process for its next run — a restart of this process loses it. Continue with your task; do not wait for a reply.`
: outcome === "dropped_duplicate"
? `Message not re-sent to main (${mainLabel}): it already delivered this exact message. Continue with your task; do not resend the same content.`
: `Message sent to main — queued for ${mainLabel} at its next turn boundary (accepted into its lane, not yet read). If that run finishes before reading it, the message may not survive. Continue with your task; do not wait for a reply.`;
return {
content,
details: { type: "send-message", status: "uplinked", to: "main", seq: uplinkSeq, ...(outcome !== undefined ? { disposition: outcome } : {}), ...(opts.uplinkSessionId !== undefined ? { session: opts.uplinkSessionId } : {}) },
};
}
if (!senderIsChild) {
return {
content: `You are the main conversation — "main" addresses you. Send to a named agent instead.`,
details: { error: "main_is_self", to },
isError: true,
};
}
return {
content: `Message not sent: "main" (${opts.uplinkSessionId !== undefined ? `session ${inlineUntrusted(opts.uplinkSessionId, 96)}` : "the spawning conversation"}) is not a deliverable target from this run — no live lane into it is wired here. ` +
`Your completion is reported to it automatically — finish your task and your final report will be relayed.`,
details: { error: "main_not_deliverable", to, ...(opts.uplinkSessionId !== undefined ? { session: opts.uplinkSessionId } : {}) },
isError: true,
};
}
const access = {
owner: ctx.taskId ?? opts.owner,
scope: ctx.principal ?? opts.scope,
...((ctx.sessionId ?? opts.sessionId) !== undefined ? { sessionId: ctx.sessionId ?? opts.sessionId } : {}),
};
const parentAccess = parentTaskId !== undefined
? { ...access, owner: parentTaskId, ...(parentSessionId !== undefined ? { sessionId: parentSessionId } : {}) }
: undefined;
const tier3Revive = async (handle) => {
if (opts.agentStore === undefined || opts.mailbox === undefined || opts.reviveSpawn === undefined)
return undefined;
const scope = access.scope;
if (scope === undefined)
return undefined;
let row;
try {
row = await opts.agentStore.get(handle, scope);
}
catch {
return undefined;
}
if (!row)
return undefined;
if (!canAccessAgentRecord(row, access)) {
if (parentAccess === undefined)
return undefined;
if (!canAccessAgentRecord(row, parentAccess))
return undefined;
}
if (row.agentType === "fork")
return undefined;
const whoT3 = handle === to ? `agent ${handle}` : `agent "${to}" (${handle})`;
if (row.status === "killed" && row.stoppedBy === "user" && !operatorUserInitiated) {
return {
content: `Message not sent: ${whoT3} was stopped by the user and was not resumed. Treat its work as cancelled; only start a new agent for it if the user explicitly asks.`,
details: { error: "killed", to, stoppedBy: row.stoppedBy },
isError: true,
};
}
if (row.status === "parked") {
return {
content: `Message not sent: ${whoT3} is parked on a pending approval — it resumes when the approval is decided (durable approval inbox), not by message delivery. Send again after it resumes.`,
details: { error: "parked_pending_approval", code: "parked_pending_approval", to },
isError: true,
};
}
if (row.status === "running") {
if (row.writerId === opts.registry.writerId) {
return {
content: `Message not sent: ${whoT3} is currently running in this process but its mid-run delivery channel is not reachable from here. ${AWAIT_COMPLETION}, then send again to continue it.`,
details: { error: "still_running", to },
isError: true,
};
}
if (Date.now() - row.updatedAt > 10 * DURABLE_AGENT_HEARTBEAT_MS) {
return {
content: `Message not sent: ${whoT3} last ran on another host that has stopped renewing its record (no heartbeat). Its row will be settled by the stale-row sweep — send again after that to revive it.`,
details: { error: "host_gone", to },
isError: true,
};
}
return {
content: `Message not sent: ${whoT3} is running on another host — this process has no delivery channel to it. ${AWAIT_COMPLETION}, then send again to continue it.`,
details: { error: "running_elsewhere", to },
isError: true,
};
}
if (row.sessionId === undefined)
return undefined;
const t3RecipientKey = peerAxisToken(scope, "h", handle);
const t3Verdict = admitFor(t3RecipientKey, [t3RecipientKey, peerAxisToken(scope, "s", row.sessionId)]);
if (!t3Verdict.ok)
return admissionRefusal(t3Verdict.reason, whoT3);
let boxFull = false;
try {
boxFull = (await opts.mailbox.peekCount(scope, handle)) >= admissionConfig.maxQueuedPeerMessages;
}
catch {
}
if (boxFull) {
const queueFullReceipt = (guidance) => ({
content: `Message not sent: ${whoT3}'s mailbox is at its queued-message limit (${admissionConfig.maxQueuedPeerMessages}) — the message was NOT queued. ${guidance} ${DEDUP_RETRY_NOTE}`,
details: { error: "queue_full", code: "queue_full", to },
isError: true,
});
if (!opts.registry.beginDurableClaim(handle)) {
return queueFullReceipt(`Another lifecycle operation currently owns this agent's claim — resend in a moment.`);
}
try {
const now = Date.now();
const nextSeq = (row.seq ?? 1) + 1;
const claimed = { ...row, status: "running", writerId: opts.registry.writerId, writerEpoch: (row.writerEpoch ?? 0) + 1, updatedAt: now, seq: nextSeq };
clearRevivedRowTerminalPayload(claimed);
let won = false;
try {
won = await opts.agentStore.update(handle, scope, claimed, { rev: row.rev });
}
catch {
won = false;
}
if (!won) {
return queueFullReceipt(`Another delivery claimed the agent's record first — this send did not start a backlog drain; a later resend will try again.`);
}
const claimedRev = row.rev + 1;
const rollbackDrain = async () => {
try {
await opts.agentStore.update(handle, scope, { ...row, updatedAt: Date.now() }, { rev: claimedRev });
}
catch {
}
};
try {
await opts.runner.sessions.acquire(row.sessionId, { requireExisting: true });
}
catch (e) {
await rollbackDrain();
if (e?.code === "not_found") {
announceTranscriptIntegrityGapOnce(handle, scope, opts.onTranscriptIntegrityGap);
return queueFullReceipt(`No transcript found for agent ${handle}, so a revival cannot drain the backlog.`);
}
return queueFullReceipt(`Its transcript store did not answer (${thrownText(e)}) — this send did not start a backlog drain; a later resend will try again.`);
}
const drainLeaseOwner = `${opts.registry.writerId}:${ctx.toolCallId}`;
let drainLease = null;
try {
drainLease = await opts.mailbox.claimLease(scope, handle, drainLeaseOwner, REVIVE_LEASE_TTL_MS);
}
catch {
drainLease = null;
}
if (drainLease === null) {
await rollbackDrain();
return queueFullReceipt(`No backlog batch was claimable this time — this send did not start a backlog drain; a later resend will try again.`);
}
const drainPrompt = `${drainLease.messages.map((m) => frameTeammateMessage({ from: m.from ?? "main", text: m.content })).join("\n")}\n\n${PEER_MESSAGE_NOTICE}`;
const drainSeed = drainLease.messages[drainLease.messages.length - 1]?.hopChain ?? [];
let drainSpawned;
try {
drainSpawned = await opts.reviveSpawn({ row: claimed, rev: claimedRev, prompt: drainPrompt, peerSeed: { hopChain: [...drainSeed] } });
}
catch (e) {
drainSpawned = { isError: true, content: thrownText(e) };
}
if (drainSpawned.isError === true) {
try {
await opts.mailbox.releaseLease(scope, handle, drainLeaseOwner);
}
catch {
}
await rollbackDrain();
return queueFullReceipt(`Reviving it to drain the backlog failed (${drainSpawned.content}) — this send did not start a backlog drain; a later resend will try again.`);
}
try {
await opts.mailbox.ack(scope, handle, drainLeaseOwner, drainLease.maxSeq);
}
catch {
}
return queueFullReceipt(`The agent is being revived to digest its ${drainLease.messages.length} queued message(s) — resend after it settles.`);
}
finally {
opts.registry.endDurableClaim(handle);
}
}
if (!opts.registry.beginDurableClaim(handle)) {
return {
content: `Message not sent: ${whoT3} is being revived or recycled right now — send again in a moment. ${DEDUP_RETRY_NOTE}`,
details: { error: "claim_contended", to },
isError: true,
};
}
try {
const now = Date.now();
const nextSeq = (row.seq ?? 1) + 1;
const claimed = { ...row, status: "running", writerId: opts.registry.writerId, writerEpoch: (row.writerEpoch ?? 0) + 1, updatedAt: now, seq: nextSeq };
clearRevivedRowTerminalPayload(claimed);
let won = false;
try {
won = await opts.agentStore.update(handle, scope, claimed, { rev: row.rev });
}
catch {
won = false;
}
if (!won) {
let fresh = null;
try {
fresh = await opts.agentStore.get(handle, scope);
}
catch {
}
if (fresh?.status === "running") {
return {
content: `Message not sent: ${whoT3} was just revived by another delivery — it is running now. Send again to reach the running agent. ${DEDUP_RETRY_NOTE}`,
details: { error: "claim_lost", to },
isError: true,
};
}
return {
content: `Message not sent: ${whoT3}'s durable record changed underneath this delivery — send again. ${DEDUP_RETRY_NOTE}`,
details: { error: "claim_lost", to },
isError: true,
};
}
const claimedRev = row.rev + 1;
const rollback = async () => {
try {
await opts.agentStore.update(handle, scope, { ...row, updatedAt: Date.now() }, { rev: claimedRev });
}
catch {
}
};
try {
await opts.runner.sessions.acquire(row.sessionId, { requireExisting: true });
}
catch (e) {
await rollback();
if (e?.code === "not_found") {
announceTranscriptIntegrityGapOnce(handle, scope, opts.onTranscriptIntegrityGap);
return {
content: `Message not sent: no transcript found for agent ${handle} — it cannot be revived. Launch a new agent with the needed context instead.`,
details: { error: "resume.session_not_found", to },
isError: true,
};
}
return {
content: `Message not sent: ${whoT3}'s transcript store did not answer (${thrownText(e)}) — nothing was parked; send again. ${DEDUP_RETRY_NOTE}`,
details: { error: "session_store_unavailable", to },
isError: true,
};
}
const clipped = clipCarrierMessage(message);
try {
await opts.mailbox.append(scope, handle, { from: senderLabel, content: `[${summary}] ${clipped}`, sentAt: now, hopChain: prospectiveChain });
}
catch (e) {
await rollback();
if (e?.code === MAILBOX_TOMBSTONED_RECIPIENT_CODE) {
return {
content: `Message not sent: that agent is being deleted — its mailbox no longer accepts messages, so nothing was parked and it was not revived. Do not retry; launch a new agent with the needed context instead.`,
details: { error: "mailbox_recipient_deleted", to },
isError: true,
};
}
return {
content: `Message not sent: the durable mailbox refused the message (${thrownText(e)}) — nothing was parked and the agent was not revived. ${DEDUP_RETRY_NOTE}`,
details: { error: "mailbox_failed", to },
isError: true,
};
}
const leaseOwner = `${opts.registry.writerId}:${ctx.toolCallId}`;
let lease = null;
try {
lease = await opts.mailbox.claimLease(scope, handle, leaseOwner, REVIVE_LEASE_TTL_MS);
}
catch {
lease = null;
}
if (lease === null) {
await rollback();
return {
content: `Message not sent now: ${whoT3}'s mailbox is leased by another in-flight revival. Your message is queued and will be delivered with the next successful revival — do not resend the same content.`,
details: { error: "mailbox_leased", to },
};
}
const revivePrompt = `${lease.messages
.map((m) => frameTeammateMessage({ from: m.from ?? "main", text: m.content }))
.join("\n")}\n\n${PEER_MESSAGE_NOTICE}`;
const reviveSeed = lease.messages[lease.messages.length - 1]?.hopChain ?? [];
let spawned;
try {
spawned = await opts.reviveSpawn({ row: claimed, rev: claimedRev, prompt: revivePrompt, peerSeed: { hopChain: [...reviveSeed] } });
}
catch (e) {
spawned = { isError: true, content: thrownText(e), details: { error: "revive_failed" } };
}
if (spawned.isError === true) {
try {
await opts.mailbox.releaseLease(scope, handle, leaseOwner);
}
catch {
}
await rollback();
const code = spawned.details?.error;
return {
content: `Message not sent: ${whoT3} could not be revived — ${spawned.content}\nYour message remains queued and will be delivered if a later revival succeeds; do not resend the same content.`,
details: { error: code ?? "revive_failed", to },
};
}
try {
await opts.mailbox.ack(scope, handle, leaseOwner, lease.maxSeq);
}
catch {
}
const priorCount = lease.messages.length - 1;
return {
content: `Message sent — ${whoT3} was revived in the background with its prior context intact${priorCount > 0 ? ` (${priorCount} earlier pending message(s) delivered with it)` : ""}. ` +
(notifyWired
? `You will be notified automatically when it completes. Continue with other work — do not poll.`
: `${NO_COMPLETION_NOTICE.charAt(0).toUpperCase()}${NO_COMPLETION_NOTICE.slice(1)}.`),
details: { type: "send-message", status: "revived", to, task_id: handle, seq: nextSeq, ...(priorCount > 0 ? { priorMessages: priorCount } : {}) },
};
}
finally {
opts.registry.endDurableClaim(handle);
}
};
let idRow = opts.registry.getAccessibleTask(to, access);
let resolvedAccess = access;
if (!idRow && parentAccess !== undefined) {
const siblingById = opts.registry.getAccessibleTask(to, parentAccess);
if (siblingById) {
idRow = siblingById;
resolvedAccess = parentAccess;
}
}
if (!idRow && DURABLE_AGENT_HANDLE_RE.test(to)) {
const revived = await tier3Revive(to);
if (revived !== undefined)
return revived;
}
let target = idRow;
if (!target) {
let byName = opts.registry.resolveBackgroundAgentByName(to, access);
let parentByName;
if (byName.status === "not_found" && parentAccess !== undefined) {
const sibling = opts.registry.resolveBackgroundAgentByName(to, parentAccess);
parentByName = sibling;
if (sibling.status === "found" || sibling.status === "ambiguous") {
byName = sibling;
resolvedAccess = parentAccess;
}
}
if (byName.status === "ambiguous") {
return { content: `Message not sent: ${byName.message}`, details: { error: "ambiguous", to }, isError: true };
}
if (byName.status === "found") {
const h = byName.handle;
target = { task_id: h.id, type: h.type, status: h.status, createdAt: h.createdAt, ...(h.toolUseId !== undefined ? { toolUseId: h.toolUseId } : {}), ...(h.sessionScoped ? { sessionScoped: true } : {}), ...(h.description !== undefined ? { description: h.description } : {}), ...(h.name !== undefined ? { name: h.name } : {}), ...(h.agentType !== undefined ? { agentType: h.agentType } : {}), ...(h.owner !== undefined ? { owner: h.owner } : {}), ...(h.scope !== undefined ? { scope: h.scope } : {}), ...(h.parentTaskId !== undefined ? { parentTaskId: h.parentTaskId } : {}), ...(h.parentSessionId !== undefined ? { parentSessionId: h.parentSessionId } : {}), ...(h.rootSessionId !== undefined ? { rootSessionId: h.rootSessionId } : {}) };
}
else {
let rosterHit;
if (opts.roster) {
try {
rosterHit = await opts.roster.resolve(to, access);
if (rosterHit === undefined && parentAccess !== undefined)
rosterHit = await opts.roster.resolve(to, parentAccess);
}
catch {
}
}
if (rosterHit !== undefined) {
{
const guard = pinGuard(rosterHit.agentId, to, "name", to);
if (guard !== undefined)
return guard;
}
const revived = await tier3Revive(rosterHit.agentId);
if (revived !== undefined)
return revived;
return {
content: `Message not sent: "${to}" is on the durable roster (agent ${rosterHit.agentId}) but not reachable in this run — its session belongs to an earlier process. ` +
`Launch a new agent with the needed context instead.`,
details: { error: "roster_only", to, agentId: rosterHit.agentId },
isError: true,
};
}
const suggestion = byName.suggestion ?? (parentByName?.status === "not_found" ? parentByName.suggestion : undefined);
const ownLabels = opts.registry.runningBackgroundAgentLabels(access);
const labels = parentAccess !== undefined
? [...ownLabels, ...opts.registry.runningBackgroundAgentLabels(parentAccess).filter((l) => !ownLabels.includes(l))]
: ownLabels;
if (peerLane.active) {
const settled = await settlePeerResolution(await resolvePeerTarget());
if (settled !== undefined)
return settled;
}
else if (peerLane.reason !== undefined) {
return peerRefusal("peer_send.other", `no agent matches "${inlineUntrusted(to, 120)}", and the cross-session lane that could reach a peer session by that name is unavailable on this mount — ${peerLane.reason}.`);
}
if (DURABLE_AGENT_HANDLE_RE.test(to)) {
return {
content: `Message not sent: no transcript found for agent ${to} — launch a new agent with the needed context instead.`,
details: { error: "not_found", to },
isError: true,
};
}
const reachable = [
...(opts.uplink !== undefined ? ['"main" (the conversation that spawned you)'] : []),
"background agents you spawned, by name or task_id",
...(peerLane.active ? ["peer sessions listed by ListAgents"] : ["no peer sessions (no cross-session lane on this mount)"]),
];
return {
content: `Message not sent: no agent matches "${to}" (unknown id or name, or not yours).` +
(suggestion !== undefined ? ` Did you mean: ${suggestion}?` : "") +
(labels.length > 0 ? ` Running background agents: ${labels.join(", ")}.` : "") +
` Reachable from here: ${reachable.join("; ").slice(0, 300)}.` +
` Note: a completed foreground agent is not resumable (its transcript is not retained) — spawn with run_in_background to keep an agent addressable, or launch a new agent.`,
details: { error: "not_found", to, ...(suggestion !== undefined ? { suggestion } : {}) },
isError: true,
};
}
}
const row = target;
if (row === undefined)
return { content: `Message not sent: no agent named "${to}" is reachable.`, details: { error: "not_found", to }, isError: true };
const targetId = row.task_id;
const who = targetId === to ? `agent ${targetId}` : `agent "${to}" (${targetId})`;
if (row.type !== "background_agent") {
return { content: `Message not sent: ${targetId} is a ${row.type} task, not a background agent.`, details: { error: "wrong_type", to }, isError: true };
}
{
const rung = idRow !== undefined
? "ref"
: row.name !== undefined && (row.name === to || normalizeAgentName(row.name) === normalizeAgentName(to))
? "name"
: "other";
const guard = pinGuard(targetId, row.name, rung, to);
if (guard !== undefined)
return guard;
}
if (row.status === "running" || row.status === "pending") {
return await withTargetLane(targetLaneKey(access.scope, targetId), async () => {
const liveRecipientKey = peerAxisToken(resolvedAccess.scope, "h", targetId);
const liveVerdict = admitFor(liveRecipientKey, [liveRecipientKey]);
if (!liveVerdict.ok)
return admissionRefusal(liveVerdict.reason, who);
const s2Clipped = clipCarrierMessage(message);
const teammateXml = `${frameTeammateMessage({ from: senderLabel, summary, text: s2Clipped })}\n\n${PEER_MESSAGE_NOTICE}`;
const delivered = await opts.registry.deliverToRunningAgent(targetId, resolvedAccess, {
task_id: senderLabel,
task_type: "background_agent",
status: "event",
summary: `message from ${senderLabel}: ${summary}`,
result: teammateXml,
seq: ++uplinkSeqGlobal,
peer: { hopChain: prospectiveChain },
}, { priority: "next" });
if (delivered.ok) {
const receiptText = delivered.disposition === "parked"
? `Message parked for ${who}: the agent finished before reading it — it will be delivered when the agent is next continued. ${notifyWired ? "You will be notified of its completion; continue with other work." : `Note: ${NO_COMPLETION_NOTICE}.`}`
: delivered.disposition === "pending"
? `Message accepted for ${who} but delivery is UNCONFIRMED (its channel did not confirm within the wait window) — it stays queued and will deliver if the channel binds. ${notifyWired ? "You will be notified of the agent's completion either way" : `Note: ${NO_COMPLETION_NOTICE}`}; resend then if it went unanswered. ${DEDUP_RETRY_NOTE}`
: `Message queued for delivery to ${who} at its next turn. If it finishes before reading it, the message may not survive — ${notifyWired ? "you will be notified of its completion either way" : NO_COMPLETION_NOTICE}; resend then if it went unanswered. ${notifyWired ? "Continue with other work; do not poll. " : ""}${DEDUP_RETRY_NOTE}`;
return {
content: receiptText,
details: { type: "send-message", status: "delivered_running", disposition: delivered.disposition, to, task_id: targetId, summary },
};
}
if (delivered.reason === "no_channel") {
return {
content: `Message not sent: ${who} is still running and this deployment has no mid-run delivery channel for it. ${AWAIT_COMPLETION}, then SendMessage to continue it. ${DEDUP_RETRY_NOTE}`,
details: { error: "still_running", to },
isError: true,
};
}
if (delivered.reason === "queue_full") {
return {
content: `Message not sent: ${who} is still starting up and its startup message buffer is full — resend in a moment. ${DEDUP_RETRY_NOTE}`,
details: { error: "queue_full", code: "queue_full", to },
isError: true,
};
}
const nowRow = opts.registry.getAccessibleTask(targetId, resolvedAccess);
if (nowRow?.status === "parked") {
return {
content: `Message not sent: ${who} is parked on a pending approval — it resumes when the approval is decided, not by message delivery. Send again after it resumes. ${DEDUP_RETRY_NOTE}`,
details: { error: "parked_pending_approval", code: "parked_pending_approval", to },
isError: true,
};
}
const stillLive = nowRow !== undefined && (nowRow.status === "running" || nowRow.status === "pending");
return stillLive
? {
content: `Message not sent: ${who} is still starting up (it has not begun reading messages yet) — the message was not delivered. Send again shortly. ${DEDUP_RETRY_NOTE}`,
details: { error: "settle_race", to },
isError: true,
}
: {
content: `Message not sent: ${who} just finished (delivery raced its completion). Send again to continue it from its transcript. ${DEDUP_RETRY_NOTE}`,
details: { error: "settle_race", to },
isError: true,
};
});
}
if (row.status === "killed") {
const by = opts.registry.getStopAttribution(targetId);
if (by === "user" && !operatorUserInitiated) {
return {
content: `Message not sent: ${who} was stopped by the user and was not resumed. Treat its work as cancelled; only start a new agent for it if the user explicitly asks.`,
details: { error: "killed", to, stoppedBy: by },
isError: true,
};
}
}
const runLedger = ctx.subagentRetain ?? opts.retain;
const smLedgerSessionId = ctx.sessionId ?? opts.sessionId ?? opts.sessionRetainLedgerKey;
const sessionLedger = smLedgerSessionId !== undefined ? getSessionRetainLedger(smLedgerSessionId) : undefined;
const knows = (l) => l !== undefined && row.toolUseId !== undefined && (l.get(row.toolUseId) !== undefined || l.wasEvicted(row.toolUseId));
const siblingLedger = opts.siblingRetain;
const liveRetainEntry = row.toolUseId !== undefined ? (sessionLedger?.get(row.toolUseId) ?? runLedger?.get(row.toolUseId) ?? siblingLedger?.get(row.toolUseId)) : undefined;
if (liveRetainEntry === undefined) {
const revived = await tier3Revive(targetId);
if (revived !== undefined)
return revived;
}
const ledger = (knows(sessionLedger) ? sessionLedger : undefined) ?? (knows(runLedger) ? runLedger : undefined) ?? (knows(siblingLedger) ? siblingLedger : undefined) ?? runLedger ?? sessionLedger ?? siblingLedger;
const resumeToolUseId = row.toolUseId;
if (!ledger || resumeToolUseId === undefined) {
return {
content: `Message not sent: ${who}'s session was not retained (this run did not enable retainSubagentSessions), so it cannot be continued — relaunch a new agent with the needed context instead.`,
details: { error: "not_retained", to },
isError: true,
};
}
if (ledger.get(resumeToolUseId)?.running === true) {
return {
content: `Message not sent: ${who} (or a prior follow-up to it) is still running — ${awaitCompletion}.`,
details: { error: "steering.still_running", to },
isError: true,
};
}
return await withTargetLane(targetLaneKey(access.scope, targetId), async () => {
const l3Entry = ledger.get(resumeToolUseId);
const l3RecipientKey = peerAxisToken(access.scope, "h", targetId);
const l3Verdict = admitFor(l3RecipientKey, [
l3RecipientKey,
...(l3Entry?.childSessionId !== undefined ? [peerAxisToken(access.scope, "s", l3Entry.childSessionId)] : []),
]);
if (!l3Verdict.ok)
return admissionRefusal(l3Verdict.reason, who);
const resume = createSubagentResume({
ledger,
parentToolCallId: resumeToolUseId,
runner: opts.runner,
peerOrigin: { hopChain: prospectiveChain },
...(opts.notify !== undefined && selfRef !== undefined ? { currentParentPeerRef: selfRef } : {}),
...(opts.notify ? { notify: opts.notify } : {}),
...(opts.sink ? { sink: opts.sink } : {}),
registry: opts.registry,
taskId: targetId,
taskAccess: resolvedAccess,
...((ctx.onBackgroundChildEvent ?? opts.onBackgroundChildEvent) ? { bgSink: ctx.onBackgroundChildEvent ?? opts.onBackgroundChildEvent } : {}),
sessionScoped: row.sessionScoped === true,
...(row.description !== undefined ? { rowDescription: row.description } : {}),
...(row.name !== undefined ? { rowName: row.name } : {}),
...(row.agentType !== undefined ? { rowAgentType: row.agentType } : {}),
...(row.owner !== undefined ? { rowOwner: row.owner } : {}),
...(row.scope !== undefined ? { rowScope: row.scope } : {}),
...(row.parentTaskId !== undefined ? { rowParentTaskId: row.parentTaskId } : {}),
...(row.parentSessionId !== undefined ? { rowParentSessionId: row.parentSessionId } : {}),
...(row.rootSessionId !== undefined ? { rowRootSessionId: row.rootSessionId } : {}),
...(row.createdAt !== undefined ? { rowSpawnedAt: row.createdAt } : {}),
...(opts.onNotifyError !== undefined ? { onNotifyError: opts.onNotifyError } : {}),
...(opts.notify ? { currentParentNotify: opts.notify } : {}),
...(ctx.onQuestion !== undefined && row.sessionScoped !== true ? { currentOnQuestion: ctx.onQuestion } : {}),
currentClamps: {
...(ctx.handsReadOnly === true ? { handsReadOnly: true } : {}),
...(ctx.readFace === "roots" ? { readFaceRoots: true } : {}),
...(ctx.writeFace === "roots" ? { writeFaceRoots: true } : {}),
...(ctx.readDenyPatterns !== undefined ? { readDenyPatterns: ctx.readDenyPatterns } : {}),
...(ctx.interactiveTools === false ? { interactiveTools: false } : {}),
...(ctx.oneShot === true ? { oneShot: true } : {}),
...(ctx.memoryPersistenceCapable === false ? { memoryPersistenceCapable: false } : {}),
...(ctx.parentSpecSeat?.memoryOff === true ? { memoryOff: true } : {}),
...(ctx.parentSpecSeat?.fileHistory === "disabled" ? { fileHistory: "disabled" } : {}),
},
...(ctx.autoModeReview !== undefined ? { currentAutoModeReview: ctx.autoModeReview } : {}),
});
const fromPrefix = senderIsChild ? `(message from teammate "${senderLabel}")\n` : "";
try {
const safeSummary = escapeEnvelopeTag(TEAMMATE_MESSAGE_TAG, summary);
const safeMessage = escapeEnvelopeTag(TEAMMATE_MESSAGE_TAG, message);
const marker = await resume(`${fromPrefix}[${safeSummary}] ${safeMessage}`);
return {
content: `Message sent — ${who} resumed in the background with its prior context intact (correlation marker [${marker}]).\n` +
(notifyWired
? `You will be notified automatically when it completes; its reply will carry [${marker}]. Continue with other work — do not poll.`
: `Its reply will carry [${marker}], but ${NO_COMPLETION_NOTICE}.`),
details: { type: "send-message", status: "resumed", to, task_id: targetId, marker, summary },
};
}
catch (e) {
const code = e?.code;
const text = code === "resume.retain_off"
? `${who}'s session was not retained (retainSubagentSessions is off) — relaunch a new agent instead.`
: code === "resume.evicted"
?
`${who} is no longer held in this run's fast lane (retain window or capacity passed, or the parent run ended) — relaunch a new agent with the needed context instead.`
: code === "resume.session_not_found"
? `no transcript found for ${who} — relaunch a new agent with the needed context instead.`
: code === "resume.cap"
? `${who} reached its resume cap (${SUBAGENT_RESUME_CAP} follow-ups per agent) — relaunch a new agent instead.`
: code === "steering.still_running"
?
`${who} (or a prior follow-up to it) is still running — ${awaitCompletion}. ${DEDUP_RETRY_NOTE}`
: code === "resume.row_recycling"
?
`${who}'s registry row is being adjudicated right now (a revival claim or a reap sweep holds it) — send again in a moment. ${DEDUP_RETRY_NOTE}`
: code === "resume.row_gone"
? `${who}'s registry row no longer exists (terminal GC) — relaunch a new agent instead.`
: `${thrownText(e)} ${DEDUP_RETRY_NOTE}`;
return { content: `Message not sent: ${text}`, details: { error: code ?? "resume_failed", to }, isError: true };
}
});
},
}, opts.enrichCtx !== undefined ? { enrichCtx: opts.enrichCtx } : {});
}
export function createAgentContinuationVerb(opts) {
assertNoRetiredSendMessageOptions(opts);
const { owner: _mo, scope: _ms, sessionId: _msid, parentTaskId: _mpt, parentSessionId: _mps, ...mountWithoutIdentity } = opts;
const mountLedgerKey = opts.sessionId;
return async (handle, content, access, o) => {
const tool = createSendMessageTool({
...mountWithoutIdentity,
...(mountLedgerKey !== undefined ? { sessionRetainLedgerKey: mountLedgerKey } : {}),
...(access.owner !== undefined ? { owner: access.owner } : {}),
...(access.scope !== undefined ? { scope: access.scope } : {}),
...(access.sessionId !== undefined ? { sessionId: access.sessionId } : {}),
enrichCtx: (base) => {
const enriched = {
...base,
...(access.owner !== undefined ? { taskId: access.owner } : {}),
...(access.scope !== undefined ? { principal: access.scope } : {}),
...(access.sessionId !== undefined ? { sessionId: access.sessionId } : {}),
};
if (o?.userInitiated === true)
enriched[OPERATOR_CONTINUATION_CTX] = true;
return enriched;
},
});
const summaryRaw = (o?.summary ?? content).replace(/\s+/g, " ").trim().slice(0, 200);
const summary = summaryRaw === "" ? "operator follow-up" : summaryRaw;
const out = await tool.execute(`op-${uuidv7()}`, { to: handle, message: content, summary });
const text = out.content
.filter((c) => c.type === "text")
.map((c) => c.text)
.join("\n");
return { content: text, ...(out.details !== undefined ? { details: out.details } : {}), ...(out.isError === true ? { isError: true } : {}) };
};
}