mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 09:01:14 +00:00
Fix agent event ordering: update state before emitting events
Previously, Agent.emit() was called before state was updated (e.g., appendMessage). This meant event handlers saw stale state - when message_end fired, agent.state.messages didn't include the message yet. Now state is updated first, then events are emitted, so handlers see consistent state that matches the event.
This commit is contained in:
parent
1194fb8afa
commit
2b0aa5ed8e
4 changed files with 321 additions and 659 deletions
951
package-lock.json
generated
951
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -255,25 +255,20 @@ export class Agent {
|
|||
cfg,
|
||||
this.abortController.signal,
|
||||
)) {
|
||||
// Pass through all events directly
|
||||
this.emit(ev as AgentEvent);
|
||||
|
||||
// Update internal state as needed
|
||||
// Update internal state BEFORE emitting events
|
||||
// so handlers see consistent state
|
||||
switch (ev.type) {
|
||||
case "message_start": {
|
||||
// Track streaming message
|
||||
partial = ev.message;
|
||||
this._state.streamMessage = ev.message;
|
||||
break;
|
||||
}
|
||||
case "message_update": {
|
||||
// Update streaming message
|
||||
partial = ev.message;
|
||||
this._state.streamMessage = ev.message;
|
||||
break;
|
||||
}
|
||||
case "message_end": {
|
||||
// Add completed message to state
|
||||
partial = null;
|
||||
this._state.streamMessage = null;
|
||||
this.appendMessage(ev.message as AppMessage);
|
||||
|
|
@ -293,7 +288,6 @@ export class Agent {
|
|||
break;
|
||||
}
|
||||
case "turn_end": {
|
||||
// Capture error from turn_end event
|
||||
if (ev.message.role === "assistant" && ev.message.errorMessage) {
|
||||
this._state.error = ev.message.errorMessage;
|
||||
}
|
||||
|
|
@ -304,6 +298,9 @@ export class Agent {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Emit after state is updated
|
||||
this.emit(ev as AgentEvent);
|
||||
}
|
||||
|
||||
// Handle any remaining partial message
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ describe.skipIf(!process.env.ANTHROPIC_API_KEY && !process.env.ANTHROPIC_OAUTH_T
|
|||
// Find assistant's response
|
||||
const messageEndEvents = events.filter((e) => e.type === "message_end") as AgentEvent[];
|
||||
const assistantMessage = messageEndEvents.find(
|
||||
(e) => e.type === "message_end" && (e as any).message?.role === "assistant",
|
||||
(e) => e.type === "message_end" && e.message?.role === "assistant",
|
||||
) as any;
|
||||
|
||||
expect(assistantMessage).toBeDefined();
|
||||
|
|
|
|||
|
|
@ -1,22 +1,8 @@
|
|||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "sitegeist",
|
||||
"path": "../sitegeist"
|
||||
},
|
||||
{
|
||||
"name": "pi-mono",
|
||||
"path": "."
|
||||
},
|
||||
{
|
||||
"name": "mini-lit",
|
||||
"path": "../mini-lit"
|
||||
},
|
||||
{
|
||||
"path": "../../agent-tools/browser-tools"
|
||||
},
|
||||
{
|
||||
"path": "../pi-terminal-bench"
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue