Skip to content

Commit 586db62

Browse files
committed
fix(server): cast finished listener call, remove stale TODO, document execute contract
1 parent fbc049c commit 586db62

4 files changed

Lines changed: 11 additions & 15 deletions

File tree

.betterer.results

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,5 @@
44
// https://phenomnomnominal.github.io/betterer/docs/results-file/#merge
55
//
66
exports[`TypeScript Strict Mode`] = {
7-
value: `{
8-
"src/server/events/execution_event_bus.ts:1102247656": [
9-
[233, 15, 4, "tsc: Expected 2 arguments, but got 1.", "2087764327"],
10-
[254, 15, 4, "tsc: Expected 2 arguments, but got 1.", "2087764327"]
11-
]
12-
}`
7+
value: `{}`
138
};

src/server/agent_execution/agent_executor.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ export interface AgentExecutor {
55
/**
66
* Executes the agent logic and publishes events to the bus.
77
*
8+
* Every call MUST publish either a `task` or a `message` event as its
9+
* first event — including follow-up turns where `requestContext.task`
10+
* is already set. The server enforces this ordering and rejects
11+
* streams that begin with a `statusUpdate` or `artifactUpdate`.
12+
*
813
* Multi-tenant implementations can read the tenant identifier from
914
* `requestContext.context.tenant`.
1015
*/

src/server/events/execution_event_bus.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ export class DefaultExecutionEventBus extends EventTarget implements ExecutionEv
231231

232232
private addFinishedListenerInternal(listener: Listener): void {
233233
const wrapped: WrappedListener = () => {
234-
listener.call(this);
234+
(listener as () => void).call(this);
235235
};
236236

237237
this.trackListener(this.finishedListeners, listener, wrapped);
@@ -252,7 +252,7 @@ export class DefaultExecutionEventBus extends EventTarget implements ExecutionEv
252252
private addFinishedListenerOnceInternal(listener: Listener): void {
253253
const wrapped: WrappedListener = () => {
254254
this.untrackWrappedListener(this.finishedListeners, listener, wrapped);
255-
listener.call(this);
255+
(listener as () => void).call(this);
256256
};
257257

258258
this.trackListener(this.finishedListeners, listener, wrapped);

src/server/transports/jsonrpc/jsonrpc_transport_handler.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,13 @@ export class JsonRpcTransportHandler {
131131
};
132132
}
133133
} catch (streamError) {
134-
// If the underlying agent stream throws an error, we need to yield a JSONRPCErrorResponse.
135-
// However, an AsyncGenerator is expected to yield JSONRPCResult.
136-
// This indicates an issue with how errors from the agent's stream are propagated.
137-
// For now, log it. The Express layer will handle the generator ending.
134+
// Re-thrown errors are caught by the Express layer, which
135+
// writes a final SSE `event: error` frame carrying the
136+
// JSON-RPC error envelope before closing the stream.
138137
console.error(
139138
`Error in agent event stream for ${method} (request ${requestId}):`,
140139
streamError
141140
);
142-
// Ideally, the Express layer should catch this and send a final error to the client if the stream breaks.
143-
// Or, the agentEventStream itself should yield a final error event that gets wrapped.
144-
// For now, we re-throw so it can be caught by the Express layer streaming support.
145141
throw streamError;
146142
}
147143
})();

0 commit comments

Comments
 (0)