HookMessageWriter
Background
Chat hardcodes message origin per method (user() → User, assistant() → Model, etc.).
Hooks that queue messages via the queue-message action need to set origin: Hook.
Interfaces
Two separate interfaces keep the concerns apart:
MessageWriter— clean interface without origin params. Used byChatand the publicservice.queue()API.HookMessageWriter— same methods but with a requiredoriginparam. Used internally by hooks.
MessageQueue implements both. Each method accepts an optional origin: when called via MessageWriter the caller omits it (default User/Tool), when called via HookMessageWriter the caller passes it explicitly (e.g. ChatMessageOrigin.Hook).
Wiring
JsonHookRegistry receives a HookMessageWriter and a JsonHookControls object via constructor injection:
constructor(
private _hookWriter?: HookMessageWriter,
private _controls?: JsonHookControls
)
ChatService passes this._messageQueue (as HookMessageWriter) and this (as JsonHookControls).
JsonHookControls is a minimal interface replacing the old JsonHookService:
export interface JsonHookControls {
setNeedsResend(): void;
interrupt(needsResend?: boolean): void;
}
ChatMessageOrigin
Every ChatMessage carries a required origin field:
| Value | Source |
|---|---|
User |
chat.user(), queue().user() |
Model |
chat.assistant(), chat.reasoning() |
Tool |
chat.tool(), queue().tool() |
Hook |
Hook queue-message action |
System |
System prompt via chat.getSystem() |
Files
| File | Role |
|---|---|
src/chats/chat.ts |
MessageWriter, HookMessageWriter, ChatMessageOrigin, ChatMessage.origin |
src/chats/queue.ts |
MessageQueue implements both writer interfaces |
src/hooks/json-hooks.ts |
JsonHookControls, JsonHookRegistry accepts hook writer + controls |
src/chats/service.ts |
ChatService implements JsonHookControls, wires MessageQueue to registry |
src/index.ts |
Public API exports (does NOT re-export hook-internal types) |