fix(gateway): harden chat abort semantics
This commit is contained in:
@@ -74,6 +74,7 @@ export type ChatRunState = {
|
||||
registry: ChatRunRegistry;
|
||||
buffers: Map<string, string>;
|
||||
deltaSentAt: Map<string, number>;
|
||||
abortedRuns: Map<string, number>;
|
||||
clear: () => void;
|
||||
};
|
||||
|
||||
@@ -81,17 +82,20 @@ export function createChatRunState(): ChatRunState {
|
||||
const registry = createChatRunRegistry();
|
||||
const buffers = new Map<string, string>();
|
||||
const deltaSentAt = new Map<string, number>();
|
||||
const abortedRuns = new Map<string, number>();
|
||||
|
||||
const clear = () => {
|
||||
registry.clear();
|
||||
buffers.clear();
|
||||
deltaSentAt.clear();
|
||||
abortedRuns.clear();
|
||||
};
|
||||
|
||||
return {
|
||||
registry,
|
||||
buffers,
|
||||
deltaSentAt,
|
||||
abortedRuns,
|
||||
clear,
|
||||
};
|
||||
}
|
||||
@@ -212,6 +216,10 @@ export function createAgentEventHandler({
|
||||
const chatLink = chatRunState.registry.peek(evt.runId);
|
||||
const sessionKey =
|
||||
chatLink?.sessionKey ?? resolveSessionKeyForRun(evt.runId);
|
||||
const clientRunId = chatLink?.clientRunId ?? evt.runId;
|
||||
const isAborted =
|
||||
chatRunState.abortedRuns.has(clientRunId) ||
|
||||
chatRunState.abortedRuns.has(evt.runId);
|
||||
// Include sessionKey so Control UI can filter tool streams per session.
|
||||
const agentPayload = sessionKey ? { ...evt, sessionKey } : evt;
|
||||
const last = agentRunSeq.get(evt.runId) ?? 0;
|
||||
@@ -242,10 +250,16 @@ export function createAgentEventHandler({
|
||||
|
||||
if (sessionKey) {
|
||||
bridgeSendToSession(sessionKey, "agent", agentPayload);
|
||||
if (evt.stream === "assistant" && typeof evt.data?.text === "string") {
|
||||
const clientRunId = chatLink?.clientRunId ?? evt.runId;
|
||||
if (
|
||||
!isAborted &&
|
||||
evt.stream === "assistant" &&
|
||||
typeof evt.data?.text === "string"
|
||||
) {
|
||||
emitChatDelta(sessionKey, clientRunId, evt.seq, evt.data.text);
|
||||
} else if (lifecyclePhase === "end" || lifecyclePhase === "error") {
|
||||
} else if (
|
||||
!isAborted &&
|
||||
(lifecyclePhase === "end" || lifecyclePhase === "error")
|
||||
) {
|
||||
if (chatLink) {
|
||||
const finished = chatRunState.registry.shift(evt.runId);
|
||||
if (!finished) {
|
||||
@@ -268,6 +282,17 @@ export function createAgentEventHandler({
|
||||
evt.data?.error,
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
isAborted &&
|
||||
(lifecyclePhase === "end" || lifecyclePhase === "error")
|
||||
) {
|
||||
chatRunState.abortedRuns.delete(clientRunId);
|
||||
chatRunState.abortedRuns.delete(evt.runId);
|
||||
chatRunState.buffers.delete(clientRunId);
|
||||
chatRunState.deltaSentAt.delete(clientRunId);
|
||||
if (chatLink) {
|
||||
chatRunState.registry.remove(evt.runId, clientRunId, sessionKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user