mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-20 10:01:21 +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,
|
ExtensionRunner,
|
||||||
type ExtensionUIContext,
|
type ExtensionUIContext,
|
||||||
type InputSource,
|
type InputSource,
|
||||||
|
type MessageEndEvent,
|
||||||
|
type MessageStartEvent,
|
||||||
|
type MessageUpdateEvent,
|
||||||
type SessionBeforeCompactResult,
|
type SessionBeforeCompactResult,
|
||||||
type SessionBeforeForkResult,
|
type SessionBeforeForkResult,
|
||||||
type SessionBeforeSwitchResult,
|
type SessionBeforeSwitchResult,
|
||||||
type SessionBeforeTreeResult,
|
type SessionBeforeTreeResult,
|
||||||
type ShutdownHandler,
|
type ShutdownHandler,
|
||||||
type ToolDefinition,
|
type ToolDefinition,
|
||||||
|
type ToolExecutionEndEvent,
|
||||||
|
type ToolExecutionStartEvent,
|
||||||
|
type ToolExecutionUpdateEvent,
|
||||||
type ToolInfo,
|
type ToolInfo,
|
||||||
type TreePreparation,
|
type TreePreparation,
|
||||||
type TurnEndEvent,
|
type TurnEndEvent,
|
||||||
|
|
@ -444,6 +450,51 @@ export class AgentSession {
|
||||||
};
|
};
|
||||||
await this._extensionRunner.emit(extensionEvent);
|
await this._extensionRunner.emit(extensionEvent);
|
||||||
this._turnIndex++;
|
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,
|
LoadExtensionsResult,
|
||||||
LsToolCallEvent,
|
LsToolCallEvent,
|
||||||
LsToolResultEvent,
|
LsToolResultEvent,
|
||||||
|
// Events - Message
|
||||||
|
MessageEndEvent,
|
||||||
// Message Rendering
|
// Message Rendering
|
||||||
MessageRenderer,
|
MessageRenderer,
|
||||||
MessageRenderOptions,
|
MessageRenderOptions,
|
||||||
|
MessageStartEvent,
|
||||||
|
MessageUpdateEvent,
|
||||||
ModelSelectEvent,
|
ModelSelectEvent,
|
||||||
ModelSelectSource,
|
ModelSelectSource,
|
||||||
// Provider Registration
|
// Provider Registration
|
||||||
|
|
@ -124,6 +128,10 @@ export type {
|
||||||
ToolCallEventResult,
|
ToolCallEventResult,
|
||||||
// Tools
|
// Tools
|
||||||
ToolDefinition,
|
ToolDefinition,
|
||||||
|
// Events - Tool Execution
|
||||||
|
ToolExecutionEndEvent,
|
||||||
|
ToolExecutionStartEvent,
|
||||||
|
ToolExecutionUpdateEvent,
|
||||||
ToolInfo,
|
ToolInfo,
|
||||||
ToolRenderResultOptions,
|
ToolRenderResultOptions,
|
||||||
ToolResultEvent,
|
ToolResultEvent,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import type {
|
||||||
} from "@mariozechner/pi-agent-core";
|
} from "@mariozechner/pi-agent-core";
|
||||||
import type {
|
import type {
|
||||||
Api,
|
Api,
|
||||||
|
AssistantMessageEvent,
|
||||||
AssistantMessageEventStream,
|
AssistantMessageEventStream,
|
||||||
Context,
|
Context,
|
||||||
ImageContent,
|
ImageContent,
|
||||||
|
|
@ -512,6 +513,51 @@ export interface TurnEndEvent {
|
||||||
toolResults: ToolResultMessage[];
|
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
|
// Model Events
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
@ -752,6 +798,12 @@ export type ExtensionEvent =
|
||||||
| AgentEndEvent
|
| AgentEndEvent
|
||||||
| TurnStartEvent
|
| TurnStartEvent
|
||||||
| TurnEndEvent
|
| TurnEndEvent
|
||||||
|
| MessageStartEvent
|
||||||
|
| MessageUpdateEvent
|
||||||
|
| MessageEndEvent
|
||||||
|
| ToolExecutionStartEvent
|
||||||
|
| ToolExecutionUpdateEvent
|
||||||
|
| ToolExecutionEndEvent
|
||||||
| ModelSelectEvent
|
| ModelSelectEvent
|
||||||
| UserBashEvent
|
| UserBashEvent
|
||||||
| InputEvent
|
| InputEvent
|
||||||
|
|
@ -883,6 +935,12 @@ export interface ExtensionAPI {
|
||||||
on(event: "agent_end", handler: ExtensionHandler<AgentEndEvent>): void;
|
on(event: "agent_end", handler: ExtensionHandler<AgentEndEvent>): void;
|
||||||
on(event: "turn_start", handler: ExtensionHandler<TurnStartEvent>): void;
|
on(event: "turn_start", handler: ExtensionHandler<TurnStartEvent>): void;
|
||||||
on(event: "turn_end", handler: ExtensionHandler<TurnEndEvent>): 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: "model_select", handler: ExtensionHandler<ModelSelectEvent>): void;
|
||||||
on(event: "tool_call", handler: ExtensionHandler<ToolCallEvent, ToolCallEventResult>): void;
|
on(event: "tool_call", handler: ExtensionHandler<ToolCallEvent, ToolCallEventResult>): void;
|
||||||
on(event: "tool_result", handler: ExtensionHandler<ToolResultEvent, ToolResultEventResult>): void;
|
on(event: "tool_result", handler: ExtensionHandler<ToolResultEvent, ToolResultEventResult>): void;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue