Skip to content

Commit 1960114

Browse files
committed
fix(gateway): validate turns before session binding
1 parent 2ed9a8c commit 1960114

2 files changed

Lines changed: 23 additions & 6 deletions

File tree

src/gateway/conversation-turn.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,13 @@ describe("runGatewayConversationTurn", () => {
516516

517517
it("rejects unsupported channels before registering or sending", async () => {
518518
const deps = createDeps();
519+
const {
520+
sessionId: _sessionId,
521+
sessionKey: _sessionKey,
522+
role: _role,
523+
...unbound
524+
} = conversation;
525+
deps.resolveConversation.mockReturnValue(unbound);
519526
deps.resolveOutboundChannelPlugin.mockReturnValueOnce({ outbound: {} } as never);
520527

521528
await expect(
@@ -532,6 +539,9 @@ describe("runGatewayConversationTurn", () => {
532539
deps,
533540
),
534541
).rejects.toBeInstanceOf(ConversationInputError);
542+
expect(deps.resolveOutboundSessionRoute).not.toHaveBeenCalled();
543+
expect(deps.ensureOutboundSessionEntry).not.toHaveBeenCalled();
544+
expect(deps.beginOperation).not.toHaveBeenCalled();
535545
expect(deps.registerPendingConversationTurn).not.toHaveBeenCalled();
536546
expect(deps.runMessageAction).not.toHaveBeenCalled();
537547
});

src/gateway/conversation-turn.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,19 @@ export async function runGatewayConversationTurn(
262262
channel: discoveredConversation.channel,
263263
cfg: params.config,
264264
});
265+
const candidatePreparedMessageId = begun
266+
? begun.record.preparedMessageId
267+
: prepareConversationMessageId({
268+
plugin,
269+
config: params.config,
270+
conversation: discoveredConversation,
271+
message: params.message,
272+
});
273+
if (!candidatePreparedMessageId) {
274+
throw new ConversationInputError(
275+
`Conversation turn ${params.turnId} is missing its prepared message id`,
276+
);
277+
}
265278
const conversation = await ensureConversationContextBinding({
266279
deps,
267280
scope,
@@ -271,12 +284,6 @@ export async function runGatewayConversationTurn(
271284
plugin,
272285
});
273286
if (!begun) {
274-
const candidatePreparedMessageId = prepareConversationMessageId({
275-
plugin,
276-
config: params.config,
277-
conversation,
278-
message: params.message,
279-
});
280287
try {
281288
begun = deps.beginOperation(scope, {
282289
operationId: params.turnId,

0 commit comments

Comments
 (0)