mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 18:05:11 +00:00
fix(tools): tool registry now contains ALL built-in tools
- createAllTools() populates registry with all 7 built-in tools - --tools flag only sets initially active tools (default: read/bash/edit/write) - Hooks can enable any tool from registry via setActiveTools() - System prompt rebuilds with correct tool guidelines when tools change - Document tsx module resolution workaround in README
This commit is contained in:
parent
c447e62662
commit
2849623afc
2 changed files with 61 additions and 26 deletions
|
|
@ -1132,6 +1132,21 @@ import { getPackageDir, getThemeDir } from "./paths.js";
|
||||||
|
|
||||||
Never use `__dirname` directly for package assets.
|
Never use `__dirname` directly for package assets.
|
||||||
|
|
||||||
|
### Module Resolution with tsx
|
||||||
|
|
||||||
|
When running from source via `npx tsx src/cli.ts`, hooks loaded via jiti may get separate module instances from the main app. This can cause issues with global state (like the theme object).
|
||||||
|
|
||||||
|
**Workaround**: Functions like `getSettingsListTheme()` accept an optional theme parameter. In hooks, pass the theme from `ctx.ui.custom()`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
await ctx.ui.custom((tui, theme, done) => {
|
||||||
|
const settingsTheme = getSettingsListTheme(theme);
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
When running the built version (`node dist/cli.js` or installed via npm), this is not an issue.
|
||||||
|
|
||||||
### Debug Command
|
### Debug Command
|
||||||
|
|
||||||
`/debug` (hidden) writes rendered lines with ANSI codes to `~/.pi/agent/pi-debug.log` for TUI debugging, as well as the last set of messages that were sent to the LLM.
|
`/debug` (hidden) writes rendered lines with ANSI codes to `~/.pi/agent/pi-debug.log` for TUI debugging, as well as the last set of messages that were sent to the LLM.
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ import {
|
||||||
allTools,
|
allTools,
|
||||||
bashTool,
|
bashTool,
|
||||||
codingTools,
|
codingTools,
|
||||||
|
createAllTools,
|
||||||
createBashTool,
|
createBashTool,
|
||||||
createCodingTools,
|
createCodingTools,
|
||||||
createEditTool,
|
createEditTool,
|
||||||
|
|
@ -76,6 +77,7 @@ import {
|
||||||
readOnlyTools,
|
readOnlyTools,
|
||||||
readTool,
|
readTool,
|
||||||
type Tool,
|
type Tool,
|
||||||
|
type ToolName,
|
||||||
writeTool,
|
writeTool,
|
||||||
} from "./tools/index.js";
|
} from "./tools/index.js";
|
||||||
|
|
||||||
|
|
@ -567,8 +569,15 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
||||||
time("discoverContextFiles");
|
time("discoverContextFiles");
|
||||||
|
|
||||||
const autoResizeImages = settingsManager.getImageAutoResize();
|
const autoResizeImages = settingsManager.getImageAutoResize();
|
||||||
const builtInTools = options.tools ?? createCodingTools(cwd, { read: { autoResizeImages } });
|
// Create ALL built-in tools for the registry (hooks can enable any of them)
|
||||||
time("createCodingTools");
|
const allBuiltInToolsMap = createAllTools(cwd, { read: { autoResizeImages } });
|
||||||
|
// Determine initially active built-in tools (default: read, bash, edit, write)
|
||||||
|
const defaultActiveToolNames: ToolName[] = ["read", "bash", "edit", "write"];
|
||||||
|
const initialActiveToolNames: ToolName[] = options.tools
|
||||||
|
? options.tools.map((t) => t.name).filter((n): n is ToolName => n in allBuiltInToolsMap)
|
||||||
|
: defaultActiveToolNames;
|
||||||
|
const initialActiveBuiltInTools = initialActiveToolNames.map((name) => allBuiltInToolsMap[name]);
|
||||||
|
time("createAllTools");
|
||||||
|
|
||||||
let customToolsResult: CustomToolsLoadResult;
|
let customToolsResult: CustomToolsLoadResult;
|
||||||
if (options.customTools !== undefined) {
|
if (options.customTools !== undefined) {
|
||||||
|
|
@ -630,51 +639,61 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Create tool registry mapping name -> tool (for hook getTools/setTools)
|
// Create tool registry mapping name -> tool (for hook getTools/setTools)
|
||||||
// Cast to AgentTool since createCodingTools actually returns AgentTool[] (type is just Tool[])
|
// Registry contains ALL built-in tools so hooks can enable any of them
|
||||||
const toolRegistry = new Map<string, AgentTool>();
|
const toolRegistry = new Map<string, AgentTool>();
|
||||||
for (const tool of builtInTools as AgentTool[]) {
|
for (const [name, tool] of Object.entries(allBuiltInToolsMap)) {
|
||||||
toolRegistry.set(tool.name, tool);
|
toolRegistry.set(name, tool as AgentTool);
|
||||||
}
|
}
|
||||||
for (const tool of wrappedCustomTools as AgentTool[]) {
|
for (const tool of wrappedCustomTools as AgentTool[]) {
|
||||||
toolRegistry.set(tool.name, tool);
|
toolRegistry.set(tool.name, tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
let allToolsArray: Tool[] = [...builtInTools, ...wrappedCustomTools];
|
// Initially active tools = active built-in + custom
|
||||||
|
let activeToolsArray: Tool[] = [...initialActiveBuiltInTools, ...wrappedCustomTools];
|
||||||
time("combineTools");
|
time("combineTools");
|
||||||
|
|
||||||
// Wrap tools with hooks if available
|
// Wrap tools with hooks if available
|
||||||
let wrappedToolRegistry: Map<string, AgentTool> | undefined;
|
let wrappedToolRegistry: Map<string, AgentTool> | undefined;
|
||||||
if (hookRunner) {
|
if (hookRunner) {
|
||||||
allToolsArray = wrapToolsWithHooks(allToolsArray as AgentTool[], hookRunner);
|
activeToolsArray = wrapToolsWithHooks(activeToolsArray as AgentTool[], hookRunner);
|
||||||
// Also create a wrapped version of the registry for setTools
|
// Also create a wrapped version of the registry for setTools
|
||||||
wrappedToolRegistry = new Map<string, AgentTool>();
|
wrappedToolRegistry = new Map<string, AgentTool>();
|
||||||
for (const tool of allToolsArray as AgentTool[]) {
|
for (const tool of activeToolsArray as AgentTool[]) {
|
||||||
wrappedToolRegistry.set(tool.name, tool);
|
wrappedToolRegistry.set(tool.name, tool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let systemPrompt: string;
|
// Function to rebuild system prompt when tools change
|
||||||
|
// Captures static options (cwd, agentDir, skills, contextFiles, customPrompt)
|
||||||
|
const rebuildSystemPrompt = (toolNames: string[]): string => {
|
||||||
|
// Filter to valid tool names
|
||||||
|
const validToolNames = toolNames.filter((n): n is ToolName => n in allBuiltInToolsMap);
|
||||||
const defaultPrompt = buildSystemPromptInternal({
|
const defaultPrompt = buildSystemPromptInternal({
|
||||||
cwd,
|
cwd,
|
||||||
agentDir,
|
agentDir,
|
||||||
skills,
|
skills,
|
||||||
contextFiles,
|
contextFiles,
|
||||||
|
selectedTools: validToolNames,
|
||||||
});
|
});
|
||||||
time("buildSystemPrompt");
|
|
||||||
|
|
||||||
if (options.systemPrompt === undefined) {
|
if (options.systemPrompt === undefined) {
|
||||||
systemPrompt = defaultPrompt;
|
return defaultPrompt;
|
||||||
} else if (typeof options.systemPrompt === "string") {
|
} else if (typeof options.systemPrompt === "string") {
|
||||||
systemPrompt = buildSystemPromptInternal({
|
return buildSystemPromptInternal({
|
||||||
cwd,
|
cwd,
|
||||||
agentDir,
|
agentDir,
|
||||||
skills,
|
skills,
|
||||||
contextFiles,
|
contextFiles,
|
||||||
|
selectedTools: validToolNames,
|
||||||
customPrompt: options.systemPrompt,
|
customPrompt: options.systemPrompt,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
systemPrompt = options.systemPrompt(defaultPrompt);
|
return options.systemPrompt(defaultPrompt);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const systemPrompt = rebuildSystemPrompt(initialActiveToolNames);
|
||||||
|
time("buildSystemPrompt");
|
||||||
|
|
||||||
const slashCommands = options.slashCommands ?? discoverSlashCommands(cwd, agentDir);
|
const slashCommands = options.slashCommands ?? discoverSlashCommands(cwd, agentDir);
|
||||||
time("discoverSlashCommands");
|
time("discoverSlashCommands");
|
||||||
|
|
@ -684,7 +703,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
||||||
systemPrompt,
|
systemPrompt,
|
||||||
model,
|
model,
|
||||||
thinkingLevel,
|
thinkingLevel,
|
||||||
tools: allToolsArray,
|
tools: activeToolsArray,
|
||||||
},
|
},
|
||||||
convertToLlm,
|
convertToLlm,
|
||||||
transformContext: hookRunner
|
transformContext: hookRunner
|
||||||
|
|
@ -730,6 +749,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
||||||
skillsSettings: settingsManager.getSkillsSettings(),
|
skillsSettings: settingsManager.getSkillsSettings(),
|
||||||
modelRegistry,
|
modelRegistry,
|
||||||
toolRegistry: wrappedToolRegistry ?? toolRegistry,
|
toolRegistry: wrappedToolRegistry ?? toolRegistry,
|
||||||
|
rebuildSystemPrompt,
|
||||||
});
|
});
|
||||||
time("createAgentSession");
|
time("createAgentSession");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue