Conversation
…e runs Since vercel#2690 emitTurnEpilogue emitted turn.completed without the turn's messages. dispatchMemoryLifecycleEvent only runs completed-turn capture when messages are present, so every memory provider's capture["turn.completed"] was skipped silently from 0.51.0 onward; only compaction-time capture still ran. Restore the optional messages parameter and pass session.history from the four paths that settle a turn (conversation and task, plain and structured), as before vercel#2690. Fixes vercel#3223 Signed-off-by: Guglielmo Porcellini <5994936+gugu91@users.noreply.github.com>
Contributor
|
@gugu91 is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
gugu91
marked this pull request as ready for review
September 17, 2026 15:43
This was referenced Sep 24, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #3223 (p0). Since 0.51.0 no memory provider's
capture["turn.completed"]has run. This restores the one argument that was lost and adds a regression test.The problem
turn.completedskips memory capture because it arrives without the turn's messages.handleEvent(event, messages)inexecution/workflow-steps.tsforwards both arguments todispatchMemoryLifecycleEvent, which only captures when messages are present:#2690 (
aae26311, "graduate background subagents to workflow tools") removed themessagesparameter fromemitTurnEpilogueinharness/emission.tsand thesession.historyarguments at its call sites intool-loop.ts. Since thenmessagesis alwaysundefined, the guard returns before thetry, and nothing is logged. Recall kept working becauseturn.startedhas no such guard, and compaction-time capture kept working becausecompaction.requestedstill passes messages, so the regression stayed hidden.How we hit it
We integrated
@supermemory/eveon 0.52.4 and the agent could only recall facts it had saved with theremembertool. A recorder provider in our fixture stack logged everyturn.startedand noturn.completedacross many turns, and the live Supermemory container held onlysource_type: "memory"documents, none of type"conversation". Reading the shippeddistled to the guard above and then to #2690. #3223 already reports the same diagnosis with reproductions on 0.51.0, 0.52.x, 0.54.3 and 0.55.0. The maintainer-bot draft #3224 has only the failing test and has been idle since 2026-09-10, so this PR carries that test forward with the fix.Why this fixes it
emitTurnEpiloguetakes an optionalmessagesagain and passes it as the second argument of the emit, as it did before #2690. The four places that settle a turn passsession.history:finishConversationTurnandfinishTaskTurn, plain pathfinishConversationTurnandfinishTaskTurn, structured path, throughemitStructuredResult, which gains the same parameterEach site reads the history after
persistStructuredAssistantTurnandclearTurnClientContextState, so the provider receives the settled history including the assistant response. The five other callers ofemitTurnEpilogueend a turn without a model response (session limits, input requests, authorization parking, proxied subagent input and authorization events). They keep omittingmessageson purpose, so a turn with no answer captures nothing. The public event stream does not change:messagesis the side-channel argument ofHarnessEmitFn, not part of the event.Testing
Unit, this repo
harness/tool-loop.test.ts: a conversation turn throughcreateToolLoopHarnesswith a mock model, asserting theturn.completedemit receives the same array asresult.session.history. Onmainit fails withexpected undefined to deeply equal [ { content: 'Hi', … }, … ]; with the fix it passes.pnpm test:unit: 8756 passed, 1 skipped, 4 failed. The 4 failures (execution/session-callback-request.test.ts×3,self-modification/registry-add.test.ts×1) fail the same way on a cleanmaincheckout in this environment and do not touch memory or the harness.pnpm test:integration: 871 passed across 112 files.pnpm lint: 0 errors, only pre-existing warnings inapps/templates.pnpm typecheck: 47/47 tasks.oxfmt --checkclean on the touched files.Live, our app against Supermemory with a real model
source_type: "memory"from theremembertool, and none of type"conversation".my dog is called kestrel-…) and no tool calls in the stream. About 20 seconds later the container had a newsource_type: "conversation"document withstatus: "done". A new chat asking "what's my dog called?" answeredkestrel-…with no tool calls, so the provider's turn-start search found the captured turn.Checklist
CONTRIBUTING.mdevepackagegit commit --signoff)