fix(gateway): harden agent provider routing

This commit is contained in:
Peter Steinberger
2026-01-09 23:00:23 +01:00
parent 3adec35632
commit 79f5ccc99d
18 changed files with 327 additions and 89 deletions

2
src/agents/lanes.ts Normal file
View File

@@ -0,0 +1,2 @@
export const AGENT_LANE_NESTED = "nested" as const;
export const AGENT_LANE_SUBAGENT = "subagent" as const;

View File

@@ -8,6 +8,8 @@ import {
resolveStorePath,
} from "../config/sessions.js";
import { callGateway } from "../gateway/call.js";
import { INTERNAL_MESSAGE_PROVIDER } from "../utils/message-provider.js";
import { AGENT_LANE_NESTED } from "./lanes.js";
import { readLatestAssistantReply, runAgentStep } from "./tools/agent-step.js";
import { resolveAnnounceTarget } from "./tools/sessions-announce-target.js";
import { isAnnounceSkip } from "./tools/sessions-send-helpers.js";
@@ -241,7 +243,8 @@ export async function runSubagentAnnounceFlow(params: {
message: "Sub-agent announce step.",
extraSystemPrompt: announcePrompt,
timeoutMs: params.timeoutMs,
lane: "nested",
provider: INTERNAL_MESSAGE_PROVIDER,
lane: AGENT_LANE_NESTED,
});
if (

View File

@@ -1,6 +1,8 @@
import crypto from "node:crypto";
import { callGateway } from "../../gateway/call.js";
import { INTERNAL_MESSAGE_PROVIDER } from "../../utils/message-provider.js";
import { AGENT_LANE_NESTED } from "../lanes.js";
import { extractAssistantText, stripToolMessages } from "./sessions-helpers.js";
export async function readLatestAssistantReply(params: {
@@ -34,8 +36,8 @@ export async function runAgentStep(params: {
sessionKey: params.sessionKey,
idempotencyKey: stepIdem,
deliver: false,
provider: params.provider ?? "webchat",
lane: params.lane ?? "nested",
provider: params.provider ?? INTERNAL_MESSAGE_PROVIDER,
lane: params.lane ?? AGENT_LANE_NESTED,
extraSystemPrompt: params.extraSystemPrompt,
},
timeoutMs: 10_000,

View File

@@ -10,7 +10,11 @@ import {
parseAgentSessionKey,
} from "../../routing/session-key.js";
import { SESSION_LABEL_MAX_LENGTH } from "../../sessions/session-label.js";
import type { GatewayMessageProvider } from "../../utils/message-provider.js";
import {
type GatewayMessageProvider,
INTERNAL_MESSAGE_PROVIDER,
} from "../../utils/message-provider.js";
import { AGENT_LANE_NESTED } from "../lanes.js";
import { readLatestAssistantReply, runAgentStep } from "./agent-step.js";
import type { AnyAgentTool } from "./common.js";
import { jsonResult, readStringParam } from "./common.js";
@@ -297,8 +301,8 @@ export function createSessionsSendTool(opts?: {
sessionKey: resolvedKey,
idempotencyKey,
deliver: false,
provider: "webchat",
lane: "nested",
provider: INTERNAL_MESSAGE_PROVIDER,
lane: AGENT_LANE_NESTED,
extraSystemPrompt: agentMessageContext,
};
const requesterSessionKey = opts?.agentSessionKey;
@@ -362,7 +366,7 @@ export function createSessionsSendTool(opts?: {
message: incomingMessage,
extraSystemPrompt: replyPrompt,
timeoutMs: announceTimeoutMs,
lane: "nested",
lane: AGENT_LANE_NESTED,
});
if (!replyText || isReplySkip(replyText)) {
break;
@@ -388,7 +392,7 @@ export function createSessionsSendTool(opts?: {
message: "Agent-to-agent announce step.",
extraSystemPrompt: announcePrompt,
timeoutMs: announceTimeoutMs,
lane: "nested",
lane: AGENT_LANE_NESTED,
});
if (
announceTarget &&

View File

@@ -11,6 +11,7 @@ import {
} from "../../routing/session-key.js";
import type { GatewayMessageProvider } from "../../utils/message-provider.js";
import { resolveAgentConfig } from "../agent-scope.js";
import { AGENT_LANE_SUBAGENT } from "../lanes.js";
import { buildSubagentSystemPrompt } from "../subagent-announce.js";
import { registerSubagentRun } from "../subagent-registry.js";
import type { AnyAgentTool } from "./common.js";
@@ -174,7 +175,7 @@ export function createSessionsSpawnTool(opts?: {
provider: opts?.agentProvider,
idempotencyKey: childIdem,
deliver: false,
lane: "subagent",
lane: AGENT_LANE_SUBAGENT,
extraSystemPrompt: childSystemPrompt,
timeout: runTimeoutSeconds > 0 ? runTimeoutSeconds : undefined,
label: label || undefined,