mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 09:01:14 +00:00
Add context event for non-destructive message modification before LLM calls
- Add contextTransform option to Agent (runs before messageTransformer) - Deep copy messages before passing to contextTransform (modifications are ephemeral) - Add ContextEvent and ContextEventResult types - Add emitContext() to HookRunner (chains multiple handlers) - Wire up in sdk.ts when creating Agent with hooks Enables dynamic context pruning: hooks can modify messages sent to LLM without changing session data. See discussion #330.
This commit is contained in:
parent
9e165d1d81
commit
77fe3f1a13
6 changed files with 89 additions and 2 deletions
|
|
@ -55,6 +55,8 @@ export interface AgentOptions {
|
|||
transport: AgentTransport;
|
||||
// Transform app messages to LLM-compatible messages before sending to transport
|
||||
messageTransformer?: (messages: AppMessage[]) => Message[] | Promise<Message[]>;
|
||||
// Called before messageTransformer - can modify messages before they're sent to LLM (non-destructive)
|
||||
contextTransform?: (messages: AppMessage[]) => Promise<AppMessage[] | undefined>;
|
||||
// Queue mode: "all" = send all queued messages at once, "one-at-a-time" = send one queued message per turn
|
||||
queueMode?: "all" | "one-at-a-time";
|
||||
}
|
||||
|
|
@ -75,6 +77,7 @@ export class Agent {
|
|||
private abortController?: AbortController;
|
||||
private transport: AgentTransport;
|
||||
private messageTransformer: (messages: AppMessage[]) => Message[] | Promise<Message[]>;
|
||||
private contextTransform?: (messages: AppMessage[]) => Promise<AppMessage[] | undefined>;
|
||||
private messageQueue: Array<QueuedMessage<AppMessage>> = [];
|
||||
private queueMode: "all" | "one-at-a-time";
|
||||
private runningPrompt?: Promise<void>;
|
||||
|
|
@ -84,6 +87,7 @@ export class Agent {
|
|||
this._state = { ...this._state, ...opts.initialState };
|
||||
this.transport = opts.transport;
|
||||
this.messageTransformer = opts.messageTransformer || defaultMessageTransformer;
|
||||
this.contextTransform = opts.contextTransform;
|
||||
this.queueMode = opts.queueMode || "one-at-a-time";
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +302,18 @@ export class Agent {
|
|||
},
|
||||
};
|
||||
|
||||
const llmMessages = await this.messageTransformer(this._state.messages);
|
||||
// Apply context transform (hooks can modify messages non-destructively)
|
||||
// Deep copy so modifications don't affect the original state
|
||||
let messagesToSend = this._state.messages;
|
||||
if (this.contextTransform) {
|
||||
const messagesCopy = JSON.parse(JSON.stringify(messagesToSend)) as AppMessage[];
|
||||
const transformed = await this.contextTransform(messagesCopy);
|
||||
if (transformed) {
|
||||
messagesToSend = transformed;
|
||||
}
|
||||
}
|
||||
|
||||
const llmMessages = await this.messageTransformer(messagesToSend);
|
||||
|
||||
return { llmMessages, cfg, model };
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue