mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 18:01:22 +00:00
feat(extensions): forward message and tool execution events to extensions (#1375)
The extension system currently only forwards agent_start, agent_end, turn_start, and turn_end events. This means extensions cannot access streaming text (token-by-token), message lifecycle, or tool execution progress — all of which are available to internal subscribers. This adds forwarding for the remaining 6 agent event types: - message_start, message_update, message_end - tool_execution_start, tool_execution_update, tool_execution_end These follow the exact same pattern as the existing forwarded events: new interfaces in types.ts, exports in index.ts, and else-if blocks in _emitExtensionEvent(). The new types are included in ExtensionEvent and automatically flow through RunnerEmitEvent (they're not in the exclusion list). This enables extensions to build real-time UIs, streaming WebSocket bridges, and other integrations that need fine-grained event access. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Mario Zechner <badlogicgames@gmail.com>
This commit is contained in:
parent
4793f7c92d
commit
ff5148e7cc
3 changed files with 117 additions and 0 deletions
|
|
@ -50,12 +50,18 @@ import {
|
|||
ExtensionRunner,
|
||||
type ExtensionUIContext,
|
||||
type InputSource,
|
||||
type MessageEndEvent,
|
||||
type MessageStartEvent,
|
||||
type MessageUpdateEvent,
|
||||
type SessionBeforeCompactResult,
|
||||
type SessionBeforeForkResult,
|
||||
type SessionBeforeSwitchResult,
|
||||
type SessionBeforeTreeResult,
|
||||
type ShutdownHandler,
|
||||
type ToolDefinition,
|
||||
type ToolExecutionEndEvent,
|
||||
type ToolExecutionStartEvent,
|
||||
type ToolExecutionUpdateEvent,
|
||||
type ToolInfo,
|
||||
type TreePreparation,
|
||||
type TurnEndEvent,
|
||||
|
|
@ -444,6 +450,51 @@ export class AgentSession {
|
|||
};
|
||||
await this._extensionRunner.emit(extensionEvent);
|
||||
this._turnIndex++;
|
||||
} else if (event.type === "message_start") {
|
||||
const extensionEvent: MessageStartEvent = {
|
||||
type: "message_start",
|
||||
message: event.message,
|
||||
};
|
||||
await this._extensionRunner.emit(extensionEvent);
|
||||
} else if (event.type === "message_update") {
|
||||
const extensionEvent: MessageUpdateEvent = {
|
||||
type: "message_update",
|
||||
message: event.message,
|
||||
assistantMessageEvent: event.assistantMessageEvent,
|
||||
};
|
||||
await this._extensionRunner.emit(extensionEvent);
|
||||
} else if (event.type === "message_end") {
|
||||
const extensionEvent: MessageEndEvent = {
|
||||
type: "message_end",
|
||||
message: event.message,
|
||||
};
|
||||
await this._extensionRunner.emit(extensionEvent);
|
||||
} else if (event.type === "tool_execution_start") {
|
||||
const extensionEvent: ToolExecutionStartEvent = {
|
||||
type: "tool_execution_start",
|
||||
toolCallId: event.toolCallId,
|
||||
toolName: event.toolName,
|
||||
args: event.args,
|
||||
};
|
||||
await this._extensionRunner.emit(extensionEvent);
|
||||
} else if (event.type === "tool_execution_update") {
|
||||
const extensionEvent: ToolExecutionUpdateEvent = {
|
||||
type: "tool_execution_update",
|
||||
toolCallId: event.toolCallId,
|
||||
toolName: event.toolName,
|
||||
args: event.args,
|
||||
partialResult: event.partialResult,
|
||||
};
|
||||
await this._extensionRunner.emit(extensionEvent);
|
||||
} else if (event.type === "tool_execution_end") {
|
||||
const extensionEvent: ToolExecutionEndEvent = {
|
||||
type: "tool_execution_end",
|
||||
toolCallId: event.toolCallId,
|
||||
toolName: event.toolName,
|
||||
result: event.result,
|
||||
isError: event.isError,
|
||||
};
|
||||
await this._extensionRunner.emit(extensionEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,9 +81,13 @@ export type {
|
|||
LoadExtensionsResult,
|
||||
LsToolCallEvent,
|
||||
LsToolResultEvent,
|
||||
// Events - Message
|
||||
MessageEndEvent,
|
||||
// Message Rendering
|
||||
MessageRenderer,
|
||||
MessageRenderOptions,
|
||||
MessageStartEvent,
|
||||
MessageUpdateEvent,
|
||||
ModelSelectEvent,
|
||||
ModelSelectSource,
|
||||
// Provider Registration
|
||||
|
|
@ -124,6 +128,10 @@ export type {
|
|||
ToolCallEventResult,
|
||||
// Tools
|
||||
ToolDefinition,
|
||||
// Events - Tool Execution
|
||||
ToolExecutionEndEvent,
|
||||
ToolExecutionStartEvent,
|
||||
ToolExecutionUpdateEvent,
|
||||
ToolInfo,
|
||||
ToolRenderResultOptions,
|
||||
ToolResultEvent,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import type {
|
|||
} from "@mariozechner/pi-agent-core";
|
||||
import type {
|
||||
Api,
|
||||
AssistantMessageEvent,
|
||||
AssistantMessageEventStream,
|
||||
Context,
|
||||
ImageContent,
|
||||
|
|
@ -512,6 +513,51 @@ export interface TurnEndEvent {
|
|||
toolResults: ToolResultMessage[];
|
||||
}
|
||||
|
||||
/** Fired when a message starts (user, assistant, or toolResult) */
|
||||
export interface MessageStartEvent {
|
||||
type: "message_start";
|
||||
message: AgentMessage;
|
||||
}
|
||||
|
||||
/** Fired during assistant message streaming with token-by-token updates */
|
||||
export interface MessageUpdateEvent {
|
||||
type: "message_update";
|
||||
message: AgentMessage;
|
||||
assistantMessageEvent: AssistantMessageEvent;
|
||||
}
|
||||
|
||||
/** Fired when a message ends */
|
||||
export interface MessageEndEvent {
|
||||
type: "message_end";
|
||||
message: AgentMessage;
|
||||
}
|
||||
|
||||
/** Fired when a tool starts executing */
|
||||
export interface ToolExecutionStartEvent {
|
||||
type: "tool_execution_start";
|
||||
toolCallId: string;
|
||||
toolName: string;
|
||||
args: any;
|
||||
}
|
||||
|
||||
/** Fired during tool execution with partial/streaming output */
|
||||
export interface ToolExecutionUpdateEvent {
|
||||
type: "tool_execution_update";
|
||||
toolCallId: string;
|
||||
toolName: string;
|
||||
args: any;
|
||||
partialResult: any;
|
||||
}
|
||||
|
||||
/** Fired when a tool finishes executing */
|
||||
export interface ToolExecutionEndEvent {
|
||||
type: "tool_execution_end";
|
||||
toolCallId: string;
|
||||
toolName: string;
|
||||
result: any;
|
||||
isError: boolean;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Model Events
|
||||
// ============================================================================
|
||||
|
|
@ -752,6 +798,12 @@ export type ExtensionEvent =
|
|||
| AgentEndEvent
|
||||
| TurnStartEvent
|
||||
| TurnEndEvent
|
||||
| MessageStartEvent
|
||||
| MessageUpdateEvent
|
||||
| MessageEndEvent
|
||||
| ToolExecutionStartEvent
|
||||
| ToolExecutionUpdateEvent
|
||||
| ToolExecutionEndEvent
|
||||
| ModelSelectEvent
|
||||
| UserBashEvent
|
||||
| InputEvent
|
||||
|
|
@ -883,6 +935,12 @@ export interface ExtensionAPI {
|
|||
on(event: "agent_end", handler: ExtensionHandler<AgentEndEvent>): void;
|
||||
on(event: "turn_start", handler: ExtensionHandler<TurnStartEvent>): void;
|
||||
on(event: "turn_end", handler: ExtensionHandler<TurnEndEvent>): void;
|
||||
on(event: "message_start", handler: ExtensionHandler<MessageStartEvent>): void;
|
||||
on(event: "message_update", handler: ExtensionHandler<MessageUpdateEvent>): void;
|
||||
on(event: "message_end", handler: ExtensionHandler<MessageEndEvent>): void;
|
||||
on(event: "tool_execution_start", handler: ExtensionHandler<ToolExecutionStartEvent>): void;
|
||||
on(event: "tool_execution_update", handler: ExtensionHandler<ToolExecutionUpdateEvent>): void;
|
||||
on(event: "tool_execution_end", handler: ExtensionHandler<ToolExecutionEndEvent>): void;
|
||||
on(event: "model_select", handler: ExtensionHandler<ModelSelectEvent>): void;
|
||||
on(event: "tool_call", handler: ExtensionHandler<ToolCallEvent, ToolCallEventResult>): void;
|
||||
on(event: "tool_result", handler: ExtensionHandler<ToolResultEvent, ToolResultEventResult>): void;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue