diff --git a/index.ts b/index.ts index 8d5016e..c7c1a2e 100644 --- a/index.ts +++ b/index.ts @@ -126,6 +126,7 @@ async function runPlugin(ctx: any, options: any, dataDir: string) { currentStepID: string | null context: MatrixEventContext finalResponse?: string + done: boolean // true после finish:stop } const sessionsBySessionID = new Map() @@ -253,6 +254,10 @@ async function runPlugin(ctx: any, options: any, dataDir: string) { if (eventType === "session.step.ended" && sessionId && assistantMsgID) { const state = sessionsBySessionID.get(sessionId) + + // Skip steps after final (finish:stop) — they are re-projections/duplicates + if (state?.done) continue + const step = state?.steps.get(assistantMsgID) const finish = eventData?.data?.finish || "" @@ -262,13 +267,15 @@ async function runPlugin(ctx: any, options: any, dataDir: string) { log(`Step ${step.tools.length} tool(s), ${step.text.length} chars text → sent to ${state.context.roomId}`) } - // If this is the final step, resolve the pending promise + // If this is the final step, mark done and resolve the pending promise if (finish === "stop" && state) { + state.done = true const pending = pendingResponses.get(sessionId) if (pending && state.finalResponse) { pendingResponses.delete(sessionId) pending.resolve(state.finalResponse) } + sessionsBySessionID.delete(sessionId) } continue @@ -430,6 +437,7 @@ async function runPlugin(ctx: any, options: any, dataDir: string) { currentStepID: null, context, finalResponse: undefined, + done: false, }) // Wait for response text from event subscription