mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-20 03:00:29 +00:00
refactor(coding-agent): fix compaction for branched sessions, consolidate hook context types
Compaction API: - prepareCompaction() now takes (pathEntries, settings) only - CompactionPreparation restructured: removed cutPoint/messagesToKeep/boundaryStart, added turnPrefixMessages/isSplitTurn/previousSummary/fileOps/settings - compact() now takes (preparation, model, apiKey, customInstructions?, signal?) - Fixed token overflow by using getPath() instead of getEntries() Hook types: - HookEventContext renamed to HookContext - HookCommandContext removed, RegisteredCommand.handler takes (args, ctx) - HookContext now includes model field - SessionBeforeCompactEvent: removed previousCompactions/model, added branchEntries - SessionBeforeTreeEvent: removed model (use ctx.model) - HookRunner.initialize() added for modes to set up callbacks
This commit is contained in:
parent
b4ce93c577
commit
ddda8b124c
12 changed files with 177 additions and 201 deletions
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
|
||||
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
||||
import type { Model } from "@mariozechner/pi-ai";
|
||||
import type { ModelRegistry } from "../model-registry.js";
|
||||
import type { SessionManager } from "../session-manager.js";
|
||||
import type { AppendEntryHandler, LoadedHook, SendMessageHandler } from "./loader.js";
|
||||
|
|
@ -11,9 +12,9 @@ import type {
|
|||
BeforeAgentStartEventResult,
|
||||
ContextEvent,
|
||||
ContextEventResult,
|
||||
HookContext,
|
||||
HookError,
|
||||
HookEvent,
|
||||
HookEventContext,
|
||||
HookMessageRenderer,
|
||||
HookUIContext,
|
||||
RegisteredCommand,
|
||||
|
|
@ -72,6 +73,7 @@ export class HookRunner {
|
|||
private modelRegistry: ModelRegistry;
|
||||
private timeout: number;
|
||||
private errorListeners: Set<HookErrorListener> = new Set();
|
||||
private getModel: () => Model<any> | undefined = () => undefined;
|
||||
|
||||
constructor(
|
||||
hooks: LoadedHook[],
|
||||
|
|
@ -89,6 +91,30 @@ export class HookRunner {
|
|||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize HookRunner with all required context.
|
||||
* Modes call this once the agent session is fully set up.
|
||||
*/
|
||||
initialize(options: {
|
||||
/** Function to get the current model */
|
||||
getModel: () => Model<any> | undefined;
|
||||
/** Handler for hooks to send messages */
|
||||
sendMessageHandler: SendMessageHandler;
|
||||
/** Handler for hooks to append entries */
|
||||
appendEntryHandler: AppendEntryHandler;
|
||||
/** UI context for interactive prompts */
|
||||
uiContext?: HookUIContext;
|
||||
/** Whether UI is available */
|
||||
hasUI?: boolean;
|
||||
}): void {
|
||||
this.getModel = options.getModel;
|
||||
this.setSendMessageHandler(options.sendMessageHandler);
|
||||
this.setAppendEntryHandler(options.appendEntryHandler);
|
||||
if (options.uiContext) {
|
||||
this.setUIContext(options.uiContext, options.hasUI ?? false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the UI context for hooks.
|
||||
* Call this when the mode initializes and UI is available.
|
||||
|
|
@ -217,13 +243,14 @@ export class HookRunner {
|
|||
/**
|
||||
* Create the event context for handlers.
|
||||
*/
|
||||
private createContext(): HookEventContext {
|
||||
private createContext(): HookContext {
|
||||
return {
|
||||
ui: this.uiContext,
|
||||
hasUI: this.hasUI,
|
||||
cwd: this.cwd,
|
||||
sessionManager: this.sessionManager,
|
||||
modelRegistry: this.modelRegistry,
|
||||
model: this.getModel(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,9 +88,9 @@ export interface HookUIContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Context passed to hook event handlers.
|
||||
* Context passed to hook event and command handlers.
|
||||
*/
|
||||
export interface HookEventContext {
|
||||
export interface HookContext {
|
||||
/** UI methods for user interaction */
|
||||
ui: HookUIContext;
|
||||
/** Whether UI is available (false in print mode) */
|
||||
|
|
@ -101,6 +101,8 @@ export interface HookEventContext {
|
|||
sessionManager: ReadonlySessionManager;
|
||||
/** Model registry - use for API key resolution and model retrieval */
|
||||
modelRegistry: ModelRegistry;
|
||||
/** Current model (may be undefined if no model is selected yet) */
|
||||
model: Model<any> | undefined;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
|
@ -152,14 +154,12 @@ export interface SessionBranchEvent {
|
|||
/** Fired before context compaction (can be cancelled or customized) */
|
||||
export interface SessionBeforeCompactEvent {
|
||||
type: "session_before_compact";
|
||||
/** Compaction preparation with cut point, messages to summarize/keep, etc. */
|
||||
/** Compaction preparation with messages to summarize, file ops, previous summary, etc. */
|
||||
preparation: CompactionPreparation;
|
||||
/** Previous compaction entries, newest first. Use for iterative summarization. */
|
||||
previousCompactions: CompactionEntry[];
|
||||
/** Branch entries (root to current leaf). Use to inspect custom state or previous compactions. */
|
||||
branchEntries: SessionEntry[];
|
||||
/** Optional user-provided instructions for the summary */
|
||||
customInstructions?: string;
|
||||
/** Current model */
|
||||
model: Model<any>;
|
||||
/** Abort signal - hooks should pass this to LLM calls and check it periodically */
|
||||
signal: AbortSignal;
|
||||
}
|
||||
|
|
@ -196,9 +196,7 @@ export interface SessionBeforeTreeEvent {
|
|||
type: "session_before_tree";
|
||||
/** Preparation data for the navigation */
|
||||
preparation: TreePreparation;
|
||||
/** Model to use for summarization (conversation model) */
|
||||
model: Model<any>;
|
||||
/** Abort signal - honors Escape during summarization */
|
||||
/** Abort signal - honors Escape during summarization (model available via ctx.model) */
|
||||
signal: AbortSignal;
|
||||
}
|
||||
|
||||
|
|
@ -529,7 +527,7 @@ export interface SessionBeforeTreeResult {
|
|||
* Handlers can return R, undefined, or void (bare return statements).
|
||||
*/
|
||||
// biome-ignore lint/suspicious/noConfusingVoidType: void allows bare return statements in handlers
|
||||
export type HookHandler<E, R = undefined> = (event: E, ctx: HookEventContext) => Promise<R | void> | R | void;
|
||||
export type HookHandler<E, R = undefined> = (event: E, ctx: HookContext) => Promise<R | void> | R | void;
|
||||
|
||||
export interface HookMessageRenderOptions {
|
||||
/** Whether the view is expanded */
|
||||
|
|
@ -546,24 +544,6 @@ export type HookMessageRenderer<T = unknown> = (
|
|||
theme: Theme,
|
||||
) => Component | undefined;
|
||||
|
||||
/**
|
||||
* Context passed to hook command handlers.
|
||||
*/
|
||||
export interface HookCommandContext {
|
||||
/** Arguments after the command name */
|
||||
args: string;
|
||||
/** UI methods for user interaction */
|
||||
ui: HookUIContext;
|
||||
/** Whether UI is available (false in print mode) */
|
||||
hasUI: boolean;
|
||||
/** Current working directory */
|
||||
cwd: string;
|
||||
/** Session manager (read-only) - use pi.sendMessage()/pi.appendEntry() for writes */
|
||||
sessionManager: ReadonlySessionManager;
|
||||
/** Model registry for API keys */
|
||||
modelRegistry: ModelRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command registration options.
|
||||
*/
|
||||
|
|
@ -571,7 +551,7 @@ export interface RegisteredCommand {
|
|||
name: string;
|
||||
description?: string;
|
||||
|
||||
handler: (ctx: HookCommandContext) => Promise<void>;
|
||||
handler: (args: string, ctx: HookContext) => Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue