| import type { SystemMessage, UserMessage } from '#/llm/message'; |
| import type { AgentEmitted } from '#/agent/machine'; |
| import { createSystemEntry, createUserEntry, type SystemEntry, type UserEntry } from '#/agent/turn'; |
| import type { ToolDefinition } from '#/tool/tool'; |
|
|
| export interface AgentPluginTarget { |
| kind: 'agent'; |
| on(type: AgentEmitted['type'], handler: (event: AgentEmitted) => void): unknown; |
| notify(message: UserMessage): void; |
| remind(key: string, message: UserMessage | SystemMessage): void; |
| } |
|
|
| export type PluginTarget = AgentPluginTarget; |
|
|
| export interface Plugin { |
| readonly name: string; |
| tools?(): readonly ToolDefinition[]; |
| connect?(target: PluginTarget): void; |
| } |
|
|
| export function collectPluginTools(plugins: readonly Plugin[]): readonly ToolDefinition[] { |
| return plugins.flatMap((plugin) => plugin.tools?.() ?? []); |
| } |
|
|
| export interface AgentPluginSource { |
| on(type: AgentEmitted['type'], handler: (event: AgentEmitted) => void): unknown; |
| send( |
| event: |
| | { type: 'input.notify'; entry: UserEntry } |
| | { type: 'input.remind'; key: string; entry: SystemEntry | UserEntry }, |
| ): void; |
| } |
|
|
| export function connectPlugins(actor: AgentPluginSource, plugins: readonly Plugin[]): void { |
| const target: AgentPluginTarget = { |
| kind: 'agent', |
| on: (type, handler) => { |
| actor.on(type, handler); |
| }, |
| notify: (message) => { |
| actor.send({ type: 'input.notify', entry: { message } }); |
| }, |
| remind: (key, message) => { |
| actor.send({ |
| type: 'input.remind', |
| key, |
| entry: message.role === 'system' ? createSystemEntry(message) : createUserEntry(message), |
| }); |
| }, |
| }; |
| for (const plugin of plugins) { |
| plugin.connect?.(target); |
| } |
| } |
|
|