mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-16 11:03:44 +00:00
WIP: Add hook API for dynamic tool control with plan-mode hook example
- Add pi.getTools() and pi.setTools(toolNames) to HookAPI - Hooks can now enable/disable tools dynamically - Changes take effect on next agent turn New example hook: plan-mode.ts - Claude Code-style read-only exploration mode - /plan command toggles plan mode on/off - Plan mode tools: read, bash, grep, find, ls - Edit/write tools disabled in plan mode - Injects context telling agent about restrictions - After each response, prompts to execute/stay/refine - State persists across sessions
This commit is contained in:
parent
5b95ccf830
commit
059292ead1
14 changed files with 304 additions and 8 deletions
|
|
@ -13,7 +13,14 @@
|
|||
* Modes use this class and add their own I/O layer on top.
|
||||
*/
|
||||
|
||||
import type { Agent, AgentEvent, AgentMessage, AgentState, ThinkingLevel } from "@mariozechner/pi-agent-core";
|
||||
import type {
|
||||
Agent,
|
||||
AgentEvent,
|
||||
AgentMessage,
|
||||
AgentState,
|
||||
AgentTool,
|
||||
ThinkingLevel,
|
||||
} from "@mariozechner/pi-agent-core";
|
||||
import type { AssistantMessage, ImageContent, Message, Model, TextContent } from "@mariozechner/pi-ai";
|
||||
import { isContextOverflow, modelsAreEqual, supportsXhigh } from "@mariozechner/pi-ai";
|
||||
import { getAuthPath } from "../config.js";
|
||||
|
|
@ -75,6 +82,8 @@ export interface AgentSessionConfig {
|
|||
skillsSettings?: Required<SkillsSettings>;
|
||||
/** Model registry for API key resolution and model discovery */
|
||||
modelRegistry: ModelRegistry;
|
||||
/** Tool registry for hook getTools/setTools - maps name to tool */
|
||||
toolRegistry?: Map<string, AgentTool>;
|
||||
}
|
||||
|
||||
/** Options for AgentSession.prompt() */
|
||||
|
|
@ -174,6 +183,9 @@ export class AgentSession {
|
|||
// Model registry for API key resolution
|
||||
private _modelRegistry: ModelRegistry;
|
||||
|
||||
// Tool registry for hook getTools/setTools
|
||||
private _toolRegistry: Map<string, AgentTool>;
|
||||
|
||||
constructor(config: AgentSessionConfig) {
|
||||
this.agent = config.agent;
|
||||
this.sessionManager = config.sessionManager;
|
||||
|
|
@ -184,6 +196,7 @@ export class AgentSession {
|
|||
this._customTools = config.customTools ?? [];
|
||||
this._skillsSettings = config.skillsSettings;
|
||||
this._modelRegistry = config.modelRegistry;
|
||||
this._toolRegistry = config.toolRegistry ?? new Map();
|
||||
|
||||
// Always subscribe to agent events for internal handling
|
||||
// (session persistence, hooks, auto-compaction, retry logic)
|
||||
|
|
@ -417,6 +430,30 @@ export class AgentSession {
|
|||
return this.agent.state.isStreaming;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of currently active tools.
|
||||
* Returns the names of tools currently set on the agent.
|
||||
*/
|
||||
getActiveToolNames(): string[] {
|
||||
return this.agent.state.tools.map((t) => t.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set active tools by name.
|
||||
* Only tools in the registry can be enabled. Unknown tool names are ignored.
|
||||
* Changes take effect on the next agent turn.
|
||||
*/
|
||||
setActiveToolsByName(toolNames: string[]): void {
|
||||
const tools: AgentTool[] = [];
|
||||
for (const name of toolNames) {
|
||||
const tool = this._toolRegistry.get(name);
|
||||
if (tool) {
|
||||
tools.push(tool);
|
||||
}
|
||||
}
|
||||
this.agent.setTools(tools);
|
||||
}
|
||||
|
||||
/** Whether auto-compaction is currently running */
|
||||
get isCompacting(): boolean {
|
||||
return this._autoCompactionAbortController !== undefined || this._compactionAbortController !== undefined;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue