@phuetz/code-buddy 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -4
- package/dist/agent/autonomous/agentic-coding-runner.d.ts +2 -2
- package/dist/agent/autonomous/agentic-coding-runner.js +24 -24
- package/dist/agent/autonomous/checkpoint-manager.d.ts +2 -2
- package/dist/agent/base-agent.d.ts +1 -1
- package/dist/agent/base-agent.js +1 -1
- package/dist/agent/execution/tool-selection-strategy.js +4 -1
- package/dist/agent/hermes-tool-parity-local.js +2 -2
- package/dist/agent/tool-handler.js +2 -2
- package/dist/codebuddy/providers/provider-chatgpt-responses.d.ts +4 -0
- package/dist/codebuddy/providers/provider-chatgpt-responses.js +34 -13
- package/dist/codebuddy/providers/provider-openai-compat.js +8 -0
- package/dist/codebuddy/tool-definitions/code-explorer-tools.d.ts +8 -0
- package/dist/codebuddy/tool-definitions/code-explorer-tools.js +24 -0
- package/dist/codebuddy/tool-definitions/graph-tools.d.ts +1 -1
- package/dist/codebuddy/tool-definitions/graph-tools.js +1 -1
- package/dist/codebuddy/tool-definitions/index.d.ts +1 -1
- package/dist/codebuddy/tool-definitions/index.js +2 -2
- package/dist/codebuddy/tools.d.ts +2 -2
- package/dist/codebuddy/tools.js +28 -13
- package/dist/collaboration/ai-colab-manager.js +9 -4
- package/dist/commands/cli/code-explorer-commands.d.ts +7 -0
- package/dist/commands/cli/code-explorer-commands.js +40 -0
- package/dist/commands/cli/native-engine-commands.js +64 -0
- package/dist/commands/handlers/channel-handlers.js +39 -22
- package/dist/commands/handlers/graph-handlers.d.ts +1 -1
- package/dist/commands/handlers/graph-handlers.js +1 -1
- package/dist/config/model-tools.js +1 -1
- package/dist/daemon/autonomous-loop.d.ts +0 -7
- package/dist/daemon/autonomous-loop.js +24 -14
- package/dist/fleet/capability-registry.js +9 -1
- package/dist/fleet/colab-store.d.ts +109 -3
- package/dist/fleet/colab-store.js +181 -6
- package/dist/index.js +28 -11
- package/dist/input/text-to-speech.js +16 -1
- package/dist/kanban/colab-kanban-adapter.d.ts +31 -0
- package/dist/kanban/colab-kanban-adapter.js +232 -0
- package/dist/knowledge/community-detector.d.ts +1 -1
- package/dist/knowledge/community-detector.js +1 -1
- package/dist/knowledge/process-detector.d.ts +1 -1
- package/dist/knowledge/process-detector.js +1 -1
- package/dist/plugins/{gitnexus/GitNexusMCPClient.d.ts → code-explorer/CodeExplorerMCPClient.d.ts} +9 -9
- package/dist/plugins/{gitnexus/GitNexusMCPClient.js → code-explorer/CodeExplorerMCPClient.js} +17 -17
- package/dist/plugins/{gitnexus/GitNexusManager.d.ts → code-explorer/CodeExplorerManager.d.ts} +16 -16
- package/dist/plugins/{gitnexus/GitNexusManager.js → code-explorer/CodeExplorerManager.js} +35 -35
- package/dist/plugins/code-explorer/index.d.ts +9 -0
- package/dist/plugins/code-explorer/index.js +8 -0
- package/dist/providers/provider-catalog.js +23 -1
- package/dist/services/prompt-builder.js +9 -9
- package/dist/skills/parser.js +1 -1
- package/dist/tools/{gitnexus-tool.d.ts → code-explorer-tool.d.ts} +9 -9
- package/dist/tools/{gitnexus-tool.js → code-explorer-tool.js} +16 -16
- package/dist/tools/metadata.js +3 -3
- package/dist/tools/registry/code-explorer-tools.d.ts +18 -0
- package/dist/tools/registry/{gitnexus-tools.js → code-explorer-tools.js} +14 -14
- package/dist/tools/registry/graph-tools.d.ts +1 -1
- package/dist/tools/registry/graph-tools.js +1 -1
- package/dist/tools/registry/index.d.ts +1 -1
- package/dist/tools/registry/index.js +6 -6
- package/dist/tools/registry/kanban-tools.d.ts +1 -1
- package/dist/tools/registry/kanban-tools.js +2 -2
- package/dist/voice/local-whisper.d.ts +9 -0
- package/dist/voice/local-whisper.js +93 -0
- package/package.json +1 -1
- package/dist/codebuddy/tool-definitions/gitnexus-tools.d.ts +0 -8
- package/dist/codebuddy/tool-definitions/gitnexus-tools.js +0 -24
- package/dist/commands/cli/gitnexus-commands.d.ts +0 -7
- package/dist/commands/cli/gitnexus-commands.js +0 -42
- package/dist/plugins/gitnexus/index.d.ts +0 -9
- package/dist/plugins/gitnexus/index.js +0 -8
- package/dist/tools/registry/gitnexus-tools.d.ts +0 -18
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<p align="center">
|
|
18
18
|
<a href="https://github.com/phuetz/code-buddy/stargazers"><img src="https://img.shields.io/github/stars/phuetz/code-buddy?style=flat-square&logo=github&color=feca57&label=Star" alt="GitHub stars"/></a>
|
|
19
19
|
<img src="https://img.shields.io/badge/Tests-27K%2B-00d26a?style=flat-square&logo=jest" alt="Tests"/>
|
|
20
|
-
<img src="https://img.shields.io/badge/v1.
|
|
20
|
+
<img src="https://img.shields.io/badge/v1.4.0-GA-blueviolet?style=flat-square" alt="Version 1.4.0 GA"/>
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
23
|
<br/>
|
|
@@ -101,13 +101,32 @@ An open-source, multi-provider AI coding agent with a terminal UI, an HTTP/WebSo
|
|
|
101
101
|
<img src="docs/screenshots/self-audit-bug-1.png" alt="Self-audit bug found" width="820"/>
|
|
102
102
|
</p>
|
|
103
103
|
|
|
104
|
+
**On your phone — chat with the same agent over Telegram.** Code Buddy runs as a messaging-channel bot, so the agent you use in the terminal is reachable from your pocket. Real, unedited captures (the bot is named *"Lisa"* here). The system prompt and tools **scale to each question** — light and instant for plain chat, escalating to load tools only when the request needs them (the same on-demand pattern as Codex / Claude):
|
|
105
|
+
|
|
106
|
+
<table>
|
|
107
|
+
<tr>
|
|
108
|
+
<td width="33%" align="center" valign="top">
|
|
109
|
+
<img src="docs/screenshots/telegram-companion-chat.jpg" alt="Telegram chat: instant greeting, the time, and tomorrow's live weather in Paris via web search" width="250"/><br/>
|
|
110
|
+
<sub><b>Chat + live tools, on demand</b><br/>"Bonjour" answers instantly; <i>"what time is it?"</i> and <i>"tomorrow's weather in Paris?"</i> pull the time and <b><code>web_search</code></b> tools — only when actually asked.</sub>
|
|
111
|
+
</td>
|
|
112
|
+
<td width="33%" align="center" valign="top">
|
|
113
|
+
<img src="docs/screenshots/telegram-companion-selfcode.jpg" alt="Telegram chat: the agent confirms it can read and inspect its own source code via view_file" width="250"/><br/>
|
|
114
|
+
<sub><b>Reads its own code</b><br/>Confirms it can inspect its own source (or any accessible file) via <code>view_file</code> — then introduces its recursive self-improvement →</sub>
|
|
115
|
+
</td>
|
|
116
|
+
<td width="33%" align="center" valign="top">
|
|
117
|
+
<img src="docs/screenshots/telegram-companion-recursive.jpg" alt="Telegram chat: the agent explains its recursive self-improvement — Manus-inspired lessons in RULE / PATTERN / CONTEXT categories, stored in .codebuddy/lessons.md" width="250"/><br/>
|
|
118
|
+
<sub><b>Improves itself across sessions</b><br/>The <code>lessons_*</code> loop (Manus-inspired): after each fix or success it extracts <b>RULE / PATTERN / CONTEXT</b> lessons, persisted to <code>.codebuddy/lessons.md</code> (project + global). <i>Accurate — matches its real source.</i></sub>
|
|
119
|
+
</td>
|
|
120
|
+
</tr>
|
|
121
|
+
</table>
|
|
122
|
+
|
|
104
123
|
More desktop demos (Fleet, Autonomy, Companion, …) and captures: [`cowork/readme.md`](cowork/readme.md#demo) · [`docs/screenshots/`](docs/screenshots/README.md).
|
|
105
124
|
|
|
106
125
|
---
|
|
107
126
|
|
|
108
127
|
## What's shipped
|
|
109
128
|
|
|
110
|
-
**1.
|
|
129
|
+
**1.4.0 GA — these aren't roadmap items.** The captures above are unedited, and the core runs today:
|
|
111
130
|
|
|
112
131
|
- ✅ **`$0` local coding agent** — a local Ollama model reasons on screen, then calls tools to do real work. *(the demos above)*
|
|
113
132
|
- ✅ **ChatGPT Plus/Pro → `gpt-5.5` at `$0`** — `buddy login`, flat-fee, no API key, no per-token metering.
|
|
@@ -301,7 +320,7 @@ Code Buddy is one engine — terminal, desktop, and HTTP — that an LLM drives
|
|
|
301
320
|
| [Config & modes](#config--modes) | TOML profiles, permission/agent/security modes, model-aware limits | [configuration.md](docs/configuration.md) |
|
|
302
321
|
|
|
303
322
|
### Providers & login
|
|
304
|
-
Code Buddy talks to **15 LLM providers** through one OpenAI-compatible dispatcher (`src/codebuddy/client.ts`), picking exactly one strategy at startup: Grok, Claude, GPT, Gemini, Ollama, LM Studio, AWS Bedrock, Azure, Groq, Together, Fireworks, OpenRouter, vLLM, Copilot, Mistral. **`buddy login`** signs into a ChatGPT Plus/Pro subscription (routed via OpenAI's Codex Responses backend) and **`buddy login xai`** into SuperGrok — both **flat-fee, no API key, cost reported `$0.0000`** (no per-token metering). Multiple logins coexist: **`buddy llm`** lists them, **`buddy llm ensemble "<q>"`** asks them all and synthesizes one answer, and `CODEBUDDY_LLM_FAILOVER=1` auto-continues on the next active LLM when one errors (per-provider circuit breakers). `[model_pairs]` in TOML splits an *architect* and *editor* model.
|
|
323
|
+
Code Buddy talks to **15 LLM providers** through one OpenAI-compatible dispatcher (`src/codebuddy/client.ts`), picking exactly one strategy at startup: Grok, Claude, GPT, Gemini, Ollama, LM Studio, AWS Bedrock, Azure, Groq, Together, Fireworks, OpenRouter, vLLM, Copilot, Mistral. **`buddy login`** signs into a ChatGPT Plus/Pro subscription (routed via OpenAI's Codex Responses backend) and **`buddy login xai`** into SuperGrok — both **flat-fee, no API key, cost reported `$0.0000`** (no per-token metering). Multiple logins coexist: **`buddy llm`** lists them, **`buddy llm ensemble "<q>"`** asks them all and synthesizes one answer, and `CODEBUDDY_LLM_FAILOVER=1` auto-continues on the next active LLM when one errors (per-provider circuit breakers). `[model_pairs]` in TOML splits an *architect* and *editor* model. **Validated live (2026-06-23, real keys / local):** chat works on **Mistral, Ollama, Gemini, xAI/Grok, OpenRouter and DeepSeek**; agentic tool-use (real `create_file`/`bash` calls) is confirmed on **Mistral** and **Grok**. Ollama/Grok/ChatGPT are also reproduced in [`docs/proof.md`](docs/proof.md). Anthropic is wired but its key needs API credits to verify. Other listed providers share the same dispatcher but aren't individually load-tested here.
|
|
305
324
|
|
|
306
325
|
### The agentic loop
|
|
307
326
|
The core is a stateful multi-turn loop (`src/agent/execution/agent-executor.ts`, `runTurnLoop`): the LLM proposes tool calls, the executor validates + confirms + runs them, feeds results back, and loops until done or you stop. A **middleware pipeline** (`src/agent/middleware/`) adds turn/cost limits, reasoning injection, workflow guards, auto-repair, and quality gates in priority order. Before any risky action the **ConfirmationService** checks permission mode → declarative rules → session flags → the Guardian Agent, and fail-closed guards block catastrophic commands (`rm -rf /`, fork bombs, `drop database`). Run it interactively (`buddy`), one-shot (`buddy -p "<task>"`), or fully autonomous (`buddy --yolo`).
|
|
@@ -337,7 +356,7 @@ Layered, fail-closed safety: the **Guardian Agent** scores each operation 0–10
|
|
|
337
356
|
Code Buddy runs on **20+ messaging platforms** — Telegram, Discord, Slack, WhatsApp, Signal, Matrix, IRC, Nostr, Mattermost, Nextcloud Talk, iMessage (real persistent transports with auto-reconnect) plus REST/webhook adapters (Teams, Google Chat, Feishu, LINE, ntfy, DingTalk, WeCom, …). **DM pairing** prevents unauthorized credit burn: an unknown user gets a 6-char code (15-min TTL) you approve via `buddy pairing approve`. (A few niche adapters — Twitch/Tlon/Gmail — are in-process stubs, and Feishu real-time *inbound* needs the Lark SDK installed.)
|
|
338
357
|
|
|
339
358
|
### Git & code intelligence
|
|
340
|
-
`buddy dev run` plans + implements + tests + **auto-commits** with a Conventional-Commit message; **`/pr`** opens a summarized PR; `lsp_rename`/`lsp_code_action` drive language servers for safe refactors; the **bug finder** flags 25+ patterns across 6 languages. For whole-repo understanding, the optional **Code Explorer** (the `gitnexus` MCP server) pre-indexes the repo into a knowledge graph with 31 tools for impact/blast-radius, coupling, hotspots, and execution traces. Code Buddy also runs as an **ACP** agent (`buddy acp`) so editors like Zed can drive it natively.
|
|
359
|
+
`buddy dev run` plans + implements + tests + **auto-commits** with a Conventional-Commit message; **`/pr`** opens a summarized PR; `lsp_rename`/`lsp_code_action` drive language servers for safe refactors; the **bug finder** flags 25+ patterns across 6 languages. For whole-repo understanding, the optional **[Code Explorer](https://github.com/phuetz/code-explorer)** (the `gitnexus` MCP server — a standalone Rust code-intelligence engine) pre-indexes the repo into a knowledge graph with 31 tools for impact/blast-radius, coupling, hotspots, and execution traces, answering structural questions with ~40× less context. Code Buddy also runs as an **ACP** agent (`buddy acp`) so editors like Zed can drive it natively.
|
|
341
360
|
|
|
342
361
|
### Config & modes
|
|
343
362
|
Configure via env vars, **TOML profiles** (`[profiles.<name>]`, `buddy --profile`), and per-project `.codebuddy/settings.json`. **Permission modes** gate approvals, **agent modes** (`plan`/`code`/`ask`/`architect`) restrict the tool surface, and **security modes** (`suggest`/`auto-edit`/`full-auto`) tune the approval flow. Per-model capabilities (context window, max output, patch format) live in `src/config/model-tools.ts`. The UI ships in **English and French (complete)**; `de`/`es`/`ja`/`zh` are registered locale scaffolds that currently fall back to English.
|
|
@@ -2,7 +2,7 @@ import { type AgenticCodingApprovalDecision, type AgenticCodingExecutionGate, ty
|
|
|
2
2
|
import { type AgenticCodingCheckpoint } from './checkpoint-manager.js';
|
|
3
3
|
import { normalizeGitPath, isPathAllowedByContract, resolveRepoPath } from './agentic-coding-paths.js';
|
|
4
4
|
export { normalizeGitPath, isPathAllowedByContract, resolveRepoPath };
|
|
5
|
-
import { type
|
|
5
|
+
import { type CodeExplorerContext, type WorldModelInvariants } from '../../tools/code-explorer-tool.js';
|
|
6
6
|
import type { FleetDispatchProfile } from '../../fleet/dispatch-profile.js';
|
|
7
7
|
import { persistRunArtifact, applyDeclaredEdits, previewDeclaredEdits, runVerificationCommands } from './agentic-coding-edits.js';
|
|
8
8
|
export { persistRunArtifact, applyDeclaredEdits, previewDeclaredEdits, runVerificationCommands };
|
|
@@ -1648,7 +1648,7 @@ export interface AgenticCodingRunReport {
|
|
|
1648
1648
|
verificationRequested: boolean;
|
|
1649
1649
|
workflow: AgenticCodingWorkflowReport;
|
|
1650
1650
|
workflowBuilderProposal?: AgenticCodingWorkflowBuilderProposalReport;
|
|
1651
|
-
|
|
1651
|
+
codeexplorerEvidence?: CodeExplorerContext;
|
|
1652
1652
|
worldModelInvariants?: WorldModelInvariants | null;
|
|
1653
1653
|
}
|
|
1654
1654
|
export interface AgenticCodingObservabilityReport {
|
|
@@ -12,7 +12,7 @@ import { normalizeGitPath, isPathAllowedByContract, resolveRepoPath, } from './a
|
|
|
12
12
|
// Re-export the extracted path helpers for backward compatibility — they used
|
|
13
13
|
// to be defined in this module and are imported from here elsewhere.
|
|
14
14
|
export { normalizeGitPath, isPathAllowedByContract, resolveRepoPath };
|
|
15
|
-
import {
|
|
15
|
+
import { CodeExplorerTool } from '../../tools/code-explorer-tool.js';
|
|
16
16
|
import { evaluateScope } from '../scope-awareness.js';
|
|
17
17
|
import { getActiveRunStore, RunStore } from '../../observability/run-store.js';
|
|
18
18
|
import { ConfirmationService } from '../../utils/confirmation-service.js';
|
|
@@ -2473,13 +2473,13 @@ export function buildAgenticCodingEditProposalProducerDispatch(report, artifacts
|
|
|
2473
2473
|
`Recommended tool call: ${fleet.invocation?.tool ?? 'none'} ${JSON.stringify(fleet.invocation?.args ?? {})}`,
|
|
2474
2474
|
...fleet.safety.map((note) => `- ${note}`),
|
|
2475
2475
|
] : []),
|
|
2476
|
-
...(report.
|
|
2476
|
+
...(report.codeexplorerEvidence ? [
|
|
2477
2477
|
'',
|
|
2478
|
-
'===
|
|
2479
|
-
`Likely Files to Edit: ${JSON.stringify(report.
|
|
2480
|
-
`Dependent Symbols: ${JSON.stringify(report.
|
|
2481
|
-
`Tests to Watch: ${JSON.stringify(report.
|
|
2482
|
-
`Notes: ${report.
|
|
2478
|
+
'=== CodeExplorer Context & Insights ===',
|
|
2479
|
+
`Likely Files to Edit: ${JSON.stringify(report.codeexplorerEvidence.likelyFiles)}`,
|
|
2480
|
+
`Dependent Symbols: ${JSON.stringify(report.codeexplorerEvidence.dependentSymbols)}`,
|
|
2481
|
+
`Tests to Watch: ${JSON.stringify(report.codeexplorerEvidence.testsToWatch)}`,
|
|
2482
|
+
`Notes: ${report.codeexplorerEvidence.notes || 'None'}`
|
|
2483
2483
|
] : []),
|
|
2484
2484
|
...(report.worldModelInvariants ? [
|
|
2485
2485
|
'',
|
|
@@ -2847,7 +2847,7 @@ export function aggregateReports(reports, originalContract, options, status) {
|
|
|
2847
2847
|
}
|
|
2848
2848
|
const uniqueBlockedReasons = Array.from(new Set(blockedReasons));
|
|
2849
2849
|
const uniqueValidationErrors = Array.from(new Set(validationErrors));
|
|
2850
|
-
const
|
|
2850
|
+
const codeexplorerEvidence = reports.find(r => r.codeexplorerEvidence)?.codeexplorerEvidence;
|
|
2851
2851
|
const worldModelInvariants = reports.find(r => r.worldModelInvariants)?.worldModelInvariants;
|
|
2852
2852
|
const plan = buildExecutionPlan({
|
|
2853
2853
|
approvalDecision: undefined,
|
|
@@ -2901,7 +2901,7 @@ export function aggregateReports(reports, originalContract, options, status) {
|
|
|
2901
2901
|
verification,
|
|
2902
2902
|
verificationRequested: Boolean(options.runVerification),
|
|
2903
2903
|
workflow: buildWorkflowReport(plan),
|
|
2904
|
-
|
|
2904
|
+
codeexplorerEvidence,
|
|
2905
2905
|
worldModelInvariants,
|
|
2906
2906
|
};
|
|
2907
2907
|
}
|
|
@@ -2972,7 +2972,7 @@ export function buildFinalReport(checkpoint) {
|
|
|
2972
2972
|
verification,
|
|
2973
2973
|
verificationRequested: Boolean(options.runVerification),
|
|
2974
2974
|
workflow: buildWorkflowReport(plan),
|
|
2975
|
-
|
|
2975
|
+
codeexplorerEvidence: checkpoint.codeexplorerEvidence,
|
|
2976
2976
|
worldModelInvariants: checkpoint.worldModelInvariants,
|
|
2977
2977
|
};
|
|
2978
2978
|
}
|
|
@@ -3173,24 +3173,24 @@ export async function runAgenticCodingCell(options) {
|
|
|
3173
3173
|
const repo = contract?.repo ?? '';
|
|
3174
3174
|
const rulesFiles = contract ? await collectRulesFiles(contract.repo) : [];
|
|
3175
3175
|
const executionGate = contract ? assessAgenticCodingExecutionGate(contract) : undefined;
|
|
3176
|
-
let
|
|
3176
|
+
let codeexplorerEvidence;
|
|
3177
3177
|
let worldModelInvariants = null;
|
|
3178
|
-
if (checkpointToResume?.
|
|
3179
|
-
|
|
3178
|
+
if (checkpointToResume?.codeexplorerEvidence) {
|
|
3179
|
+
codeexplorerEvidence = checkpointToResume.codeexplorerEvidence;
|
|
3180
3180
|
}
|
|
3181
3181
|
else if (contract) {
|
|
3182
|
-
observability.stepStart('
|
|
3183
|
-
const
|
|
3184
|
-
|
|
3185
|
-
observability.stepEnd('
|
|
3182
|
+
observability.stepStart('code-explorer-context', { task: contract.task });
|
|
3183
|
+
const codeExplorer = new CodeExplorerTool();
|
|
3184
|
+
codeexplorerEvidence = await codeExplorer.ask(contract.task);
|
|
3185
|
+
observability.stepEnd('code-explorer-context', { hasEvidence: Boolean(codeexplorerEvidence) });
|
|
3186
3186
|
}
|
|
3187
3187
|
if (checkpointToResume?.worldModelInvariants !== undefined) {
|
|
3188
3188
|
worldModelInvariants = checkpointToResume.worldModelInvariants;
|
|
3189
3189
|
}
|
|
3190
3190
|
else if (contract) {
|
|
3191
3191
|
observability.stepStart('world-model-read', { repo: contract.repo });
|
|
3192
|
-
const
|
|
3193
|
-
worldModelInvariants = await
|
|
3192
|
+
const codeExplorer = new CodeExplorerTool();
|
|
3193
|
+
worldModelInvariants = await codeExplorer.readWorldModel();
|
|
3194
3194
|
observability.stepEnd('world-model-read', { hasInvariants: Boolean(worldModelInvariants) });
|
|
3195
3195
|
}
|
|
3196
3196
|
let dirtyFiles = [];
|
|
@@ -3249,7 +3249,7 @@ export async function runAgenticCodingCell(options) {
|
|
|
3249
3249
|
verificationRequested: Boolean(options.runVerification),
|
|
3250
3250
|
workflow: buildWorkflowReport(plan),
|
|
3251
3251
|
workflowBuilderProposal,
|
|
3252
|
-
|
|
3252
|
+
codeexplorerEvidence,
|
|
3253
3253
|
worldModelInvariants,
|
|
3254
3254
|
});
|
|
3255
3255
|
}
|
|
@@ -3277,7 +3277,7 @@ export async function runAgenticCodingCell(options) {
|
|
|
3277
3277
|
contract: finalContract,
|
|
3278
3278
|
step: 'initialized',
|
|
3279
3279
|
timestamp: new Date().toISOString(),
|
|
3280
|
-
|
|
3280
|
+
codeexplorerEvidence,
|
|
3281
3281
|
worldModelInvariants,
|
|
3282
3282
|
});
|
|
3283
3283
|
observability.stepEnd('checkpoint-save', { checkpointStep: 'initialized', runId: options.runId });
|
|
@@ -3473,7 +3473,7 @@ export async function runAgenticCodingCell(options) {
|
|
|
3473
3473
|
edges: [],
|
|
3474
3474
|
},
|
|
3475
3475
|
workflowBuilderProposal,
|
|
3476
|
-
|
|
3476
|
+
codeexplorerEvidence,
|
|
3477
3477
|
worldModelInvariants,
|
|
3478
3478
|
};
|
|
3479
3479
|
const tempArtifacts = deriveAgenticCodingProposalLoopArtifacts(options.editProposalFile || path.join(path.dirname(taskFile), 'proposal-loop.json'));
|
|
@@ -3611,7 +3611,7 @@ export async function runAgenticCodingCell(options) {
|
|
|
3611
3611
|
verificationRequested: Boolean(options.runVerification),
|
|
3612
3612
|
workflow: buildWorkflowReport(plan),
|
|
3613
3613
|
workflowBuilderProposal,
|
|
3614
|
-
|
|
3614
|
+
codeexplorerEvidence,
|
|
3615
3615
|
worldModelInvariants,
|
|
3616
3616
|
});
|
|
3617
3617
|
}
|
|
@@ -5550,7 +5550,7 @@ export function buildAgenticCodingProposalLoopCoworkWorkspace(check, queue, step
|
|
|
5550
5550
|
kind: 'agentic-coding-harness-contract',
|
|
5551
5551
|
label: 'Harness / security and orchestration contract',
|
|
5552
5552
|
mode: 'passive',
|
|
5553
|
-
objective: 'Converge Cowork, Code Buddy,
|
|
5553
|
+
objective: 'Converge Cowork, Code Buddy, CodeExplorer, Fleet and workflow artifacts around explicit authority boundaries.',
|
|
5554
5554
|
safetyNotes: [
|
|
5555
5555
|
'Harness data is display metadata only.',
|
|
5556
5556
|
'It defines what each artifact means; it does not execute, approve, write memory, push or deploy.',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AgenticCodingTaskContract } from './agentic-coding-contract.js';
|
|
2
2
|
import type { AgenticCodingRunOptions, AgenticCodingRunReport, AgenticCodingVerificationResult } from './agentic-coding-runner.js';
|
|
3
|
-
import {
|
|
3
|
+
import { CodeExplorerContext, WorldModelInvariants } from '../../tools/code-explorer-tool.js';
|
|
4
4
|
export interface AgenticCodingCheckpoint {
|
|
5
5
|
runId: string;
|
|
6
6
|
options: AgenticCodingRunOptions;
|
|
@@ -12,7 +12,7 @@ export interface AgenticCodingCheckpoint {
|
|
|
12
12
|
reports?: AgenticCodingRunReport[];
|
|
13
13
|
timestamp: string;
|
|
14
14
|
verification?: AgenticCodingVerificationResult[];
|
|
15
|
-
|
|
15
|
+
codeexplorerEvidence?: CodeExplorerContext;
|
|
16
16
|
worldModelInvariants?: WorldModelInvariants | null;
|
|
17
17
|
}
|
|
18
18
|
export declare function getCheckpointPath(runId: string): string;
|
|
@@ -192,7 +192,7 @@ export declare abstract class BaseAgent extends EventEmitter implements Agent {
|
|
|
192
192
|
getMCPClient(): MCPClient;
|
|
193
193
|
protected initializeMCP(): void;
|
|
194
194
|
/** Resolves once MCP server initialization has settled (or no-op if MCP was
|
|
195
|
-
* never started). Headless/one-shot callers await this so the
|
|
195
|
+
* never started). Headless/one-shot callers await this so the code-explorer-style
|
|
196
196
|
* MCP tools are registered before the first turn instead of racing init. */
|
|
197
197
|
getMCPReady(): Promise<void>;
|
|
198
198
|
getContextStats(): import("./facades/agent-context-facade.js").ContextStats;
|
package/dist/agent/base-agent.js
CHANGED
|
@@ -317,7 +317,7 @@ export class BaseAgent extends EventEmitter {
|
|
|
317
317
|
this.infrastructureFacade.initializeMCP();
|
|
318
318
|
}
|
|
319
319
|
/** Resolves once MCP server initialization has settled (or no-op if MCP was
|
|
320
|
-
* never started). Headless/one-shot callers await this so the
|
|
320
|
+
* never started). Headless/one-shot callers await this so the code-explorer-style
|
|
321
321
|
* MCP tools are registered before the first turn instead of racing init. */
|
|
322
322
|
getMCPReady() {
|
|
323
323
|
return this.infrastructureFacade.getMCPReady();
|
|
@@ -39,7 +39,10 @@ const DEFAULT_CONFIG = {
|
|
|
39
39
|
// "agent proposes, human approves" path, so the model must always see it (a
|
|
40
40
|
// RAG-gated propose tool would rarely surface). `lessons_list` stays out
|
|
41
41
|
// (admin-style, not needed per-turn). Wakes the dormant feature in lessons-tracker.ts.
|
|
42
|
-
|
|
42
|
+
// `tool_search` is ALWAYS exposed so the model can discover & pull ANY tool
|
|
43
|
+
// on demand when the per-query TF-IDF subset missed it (progressive disclosure,
|
|
44
|
+
// like Codex/Claude). Without it, a tool outside the top-K is unreachable.
|
|
45
|
+
alwaysInclude: ['view_file', 'bash', 'search', 'str_replace_editor', 'web_search', 'remember', 'memory_propose', 'lessons_add', 'lessons_propose', 'lessons_search', 'tool_search'],
|
|
43
46
|
useAdaptiveThreshold: true,
|
|
44
47
|
enableCaching: true,
|
|
45
48
|
cacheTTLMs: 5 * 60 * 1000, // 5 minutes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, AGENT_TOOLS, FIRECRAWL_TOOLS, LSP_TOOLS, SECRETS_TOOLS, ADVISOR_TOOLS, ASK_USER_QUESTION_TOOLS, EXIT_PLAN_MODE_TOOLS, CODEBASE_REPLACE_TOOLS, SESSION_TOOLS,
|
|
1
|
+
import { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, AGENT_TOOLS, FIRECRAWL_TOOLS, LSP_TOOLS, SECRETS_TOOLS, ADVISOR_TOOLS, ASK_USER_QUESTION_TOOLS, EXIT_PLAN_MODE_TOOLS, CODEBASE_REPLACE_TOOLS, SESSION_TOOLS, CODE_EXPLORER_TOOLS, } from '../codebuddy/tool-definitions/index.js';
|
|
2
2
|
import { FLEET_TOOLS } from '../codebuddy/fleet-tool-defs.js';
|
|
3
3
|
import { buildHermesToolParityManifest, } from './hermes-tool-parity-manifest.js';
|
|
4
4
|
export function collectOfflineBuiltinTools() {
|
|
@@ -32,7 +32,7 @@ export function collectOfflineBuiltinTools() {
|
|
|
32
32
|
CODEBASE_REPLACE_TOOLS,
|
|
33
33
|
SESSION_TOOLS,
|
|
34
34
|
FLEET_TOOLS,
|
|
35
|
-
|
|
35
|
+
CODE_EXPLORER_TOOLS,
|
|
36
36
|
];
|
|
37
37
|
const byName = new Map();
|
|
38
38
|
for (const tool of groups.flat()) {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* Tool instances are lazy-loaded on first access for optimal startup time.
|
|
17
17
|
*/
|
|
18
18
|
import { TextEditorTool, MorphEditorTool, ImageTool, BashTool, } from "../tools/index.js";
|
|
19
|
-
import { getFormalToolRegistry, createTextEditorTools, createBashTools, createLsTools, createSearchTools, createWebTools, createTodoTools, createCronjobTools, createDockerTools, createKubernetesTools, createGitTools, createMiscTools, createBrowserTools, createProcessTools, createVisionTools, createScriptTools, createPlanTools, createKnowledgeTools, createRelationshipIntelligenceTools, createInternetScoutTools, createLeadScoutTools, createBrowserOperatorTools, createWindowsTools, createMemoryTools, createParallelTools, createAttentionTools, createSkillsInspectionTools, createLessonsTools, createUserModelTools, createAliasTools, createMultimodalTools, createAdvancedTools, createCanvasTools, createLspTools, createMergeConflictTools, createVulnScannerTools, createCodebaseReplaceTools, createAdvisorTools, createFleetTools, createAskUserQuestionTools, createExitPlanModeTools, createGuiTools, createSessionTools,
|
|
19
|
+
import { getFormalToolRegistry, createTextEditorTools, createBashTools, createLsTools, createSearchTools, createWebTools, createTodoTools, createCronjobTools, createDockerTools, createKubernetesTools, createGitTools, createMiscTools, createBrowserTools, createProcessTools, createVisionTools, createScriptTools, createPlanTools, createKnowledgeTools, createRelationshipIntelligenceTools, createInternetScoutTools, createLeadScoutTools, createBrowserOperatorTools, createWindowsTools, createMemoryTools, createParallelTools, createAttentionTools, createSkillsInspectionTools, createLessonsTools, createUserModelTools, createAliasTools, createMultimodalTools, createAdvancedTools, createCanvasTools, createLspTools, createMergeConflictTools, createVulnScannerTools, createCodebaseReplaceTools, createAdvisorTools, createFleetTools, createAskUserQuestionTools, createExitPlanModeTools, createGuiTools, createSessionTools, createCodeExplorerTools, createScreenpipeTools, } from "../tools/registry/index.js";
|
|
20
20
|
import { createRegisterToolTool } from "../tools/register-tool-handler.js";
|
|
21
21
|
import { getMCPManager } from "../codebuddy/tools.js";
|
|
22
22
|
import { getErrorMessage } from "../errors/index.js";
|
|
@@ -238,7 +238,7 @@ export class ToolHandler {
|
|
|
238
238
|
...createExitPlanModeTools(),
|
|
239
239
|
...createGuiTools(),
|
|
240
240
|
...createSessionTools(),
|
|
241
|
-
...
|
|
241
|
+
...createCodeExplorerTools(),
|
|
242
242
|
...createScreenpipeTools(),
|
|
243
243
|
// Self-improvement: the agent can author its own tools (opt-in only).
|
|
244
244
|
...(process.env.CODEBUDDY_SELF_IMPROVE === 'true' ? [createRegisterToolTool()] : []),
|
|
@@ -124,6 +124,10 @@ export declare class ChatGptResponsesProvider implements Provider {
|
|
|
124
124
|
*/
|
|
125
125
|
private lastTurnReasoningItems;
|
|
126
126
|
private disableModelFallback;
|
|
127
|
+
/** The model this provider was constructed with (the user's configured
|
|
128
|
+
* session model). Never mutated by per-call overrides or fallback, so it is
|
|
129
|
+
* the safe remap target when a mis-routed / non-Codex model arrives. */
|
|
130
|
+
private readonly configuredModel;
|
|
127
131
|
constructor(opts: ChatGptResponsesProviderOptions);
|
|
128
132
|
setModel(model: string): void;
|
|
129
133
|
chat(messages: CodeBuddyMessage[], tools?: CodeBuddyTool[], opts?: ChatOptions): Promise<CodeBuddyResponse>;
|
|
@@ -54,11 +54,7 @@ function pickFallbackModel(current) {
|
|
|
54
54
|
return FALLBACK_MODELS[idx + 1] ?? null;
|
|
55
55
|
}
|
|
56
56
|
/** Models served only by the classic OpenAI API — the ChatGPT/Codex backend
|
|
57
|
-
* never exposes them.
|
|
58
|
-
* choice (e.g. a secondary call inheriting the global `gpt-4o` config default
|
|
59
|
-
* instead of the active session model), remap proactively to the known-good
|
|
60
|
-
* Codex model. This skips a guaranteed-failed round-trip and the noisy
|
|
61
|
-
* user-facing warning. (smoke-test finding F7, 2026-05-29) */
|
|
57
|
+
* never exposes them. (smoke-test finding F7, 2026-05-29) */
|
|
62
58
|
const CODEX_UNSUPPORTED_MODELS = new Set([
|
|
63
59
|
'gpt-4o',
|
|
64
60
|
'gpt-4o-mini',
|
|
@@ -66,13 +62,33 @@ const CODEX_UNSUPPORTED_MODELS = new Set([
|
|
|
66
62
|
'gpt-4',
|
|
67
63
|
'gpt-3.5-turbo',
|
|
68
64
|
]);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
/** True when the ChatGPT/Codex backend can actually serve `model`: the gpt-5
|
|
66
|
+
* family, the o-series reasoning models, and codex-suffixed slugs. Classic
|
|
67
|
+
* gpt-4* (CODEX_UNSUPPORTED_MODELS) and other vendors' models (grok-*,
|
|
68
|
+
* claude-*, gemini-*, …) are NOT served and would 400. */
|
|
69
|
+
function isCodexServableModel(model) {
|
|
70
|
+
if (CODEX_UNSUPPORTED_MODELS.has(model))
|
|
71
|
+
return false;
|
|
72
|
+
if (FALLBACK_MODELS.includes(model))
|
|
73
|
+
return true;
|
|
74
|
+
return /^gpt-5/i.test(model) || /^o[1-9]/i.test(model) || /codex/i.test(model);
|
|
75
|
+
}
|
|
76
|
+
/** When a model the Codex backend cannot serve reaches this provider WITHOUT an
|
|
77
|
+
* explicit `--model`, remap proactively — preferring the user's configured
|
|
78
|
+
* session model — instead of firing a guaranteed-failed round-trip (and a
|
|
79
|
+
* confusing fallback to yet another unsupported slug). Two real mis-routes hit
|
|
80
|
+
* this: a secondary call inheriting a classic `gpt-4o` default (F7), and the
|
|
81
|
+
* agent's task-router handing back a `grok-*` coding model on a ChatGPT session
|
|
82
|
+
* (which otherwise 400s, then falls back to gpt-5.2 and 400s again → crash).
|
|
83
|
+
* An explicit `--model` is always respected. (cross-vendor fix, 2026-06-21) */
|
|
84
|
+
function resolveCodexModel(model, hasExplicitModel, configuredModel) {
|
|
85
|
+
if (hasExplicitModel || isCodexServableModel(model))
|
|
86
|
+
return model;
|
|
87
|
+
const target = configuredModel && isCodexServableModel(configuredModel)
|
|
88
|
+
? configuredModel
|
|
89
|
+
: (FALLBACK_MODELS[0] ?? 'gpt-5.2');
|
|
90
|
+
logger.debug(`[chatgpt-responses] "${model}" is not served by the Codex backend; using "${target}". Set --model to override.`);
|
|
91
|
+
return target;
|
|
76
92
|
}
|
|
77
93
|
// ─────────────────────────────────────────────────────────────────────
|
|
78
94
|
// Provider implementation
|
|
@@ -96,10 +112,15 @@ export class ChatGptResponsesProvider {
|
|
|
96
112
|
*/
|
|
97
113
|
lastTurnReasoningItems = [];
|
|
98
114
|
disableModelFallback;
|
|
115
|
+
/** The model this provider was constructed with (the user's configured
|
|
116
|
+
* session model). Never mutated by per-call overrides or fallback, so it is
|
|
117
|
+
* the safe remap target when a mis-routed / non-Codex model arrives. */
|
|
118
|
+
configuredModel;
|
|
99
119
|
constructor(opts) {
|
|
100
120
|
this.authProvider = opts.authProvider;
|
|
101
121
|
this.refreshAuth = opts.refreshAuth ?? opts.authProvider;
|
|
102
122
|
this.currentModel = opts.model;
|
|
123
|
+
this.configuredModel = opts.model;
|
|
103
124
|
this.promptCacheKey = `cb-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
104
125
|
this.disableModelFallback = opts.disableModelFallback ?? false;
|
|
105
126
|
}
|
|
@@ -148,7 +169,7 @@ export class ChatGptResponsesProvider {
|
|
|
148
169
|
};
|
|
149
170
|
}
|
|
150
171
|
async *chatStream(messages, tools = [], opts = {}) {
|
|
151
|
-
const model = resolveCodexModel(opts.model ?? this.currentModel, opts.model != null);
|
|
172
|
+
const model = resolveCodexModel(opts.model ?? this.currentModel, opts.model != null, this.configuredModel);
|
|
152
173
|
// If this is a brand-new conversational turn (last user message has
|
|
153
174
|
// no preceding tool round in messages), drop any stale reasoning
|
|
154
175
|
// blobs from the previous turn — they belonged to a different
|
|
@@ -317,6 +317,14 @@ export class OpenAICompatProvider {
|
|
|
317
317
|
if (this.isLocalInference()) {
|
|
318
318
|
return false;
|
|
319
319
|
}
|
|
320
|
+
// `search_parameters` is an xAI/Grok-specific field. Sending it to other
|
|
321
|
+
// OpenAI-compatible providers (Mistral, Groq, Together, Fireworks, …)
|
|
322
|
+
// is rejected with HTTP 422. When search is off (the default) there is
|
|
323
|
+
// nothing to send anyway, so omit the field — a plain request must never
|
|
324
|
+
// carry a disabled-search config that breaks the upstream.
|
|
325
|
+
if (!searchParams.mode || searchParams.mode === 'off') {
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
320
328
|
if (this.isXaiProvider()) {
|
|
321
329
|
logger.debug('Skipping deprecated search_parameters for xAI provider', {
|
|
322
330
|
source: 'OpenAICompatProvider',
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeExplorer Tool Definitions
|
|
3
|
+
*
|
|
4
|
+
* OpenAI function calling schema for the CodeExplorer tool.
|
|
5
|
+
*/
|
|
6
|
+
import type { CodeBuddyTool } from './types.js';
|
|
7
|
+
export declare const CODE_EXPLORER_ASK_TOOL: CodeBuddyTool;
|
|
8
|
+
export declare const CODE_EXPLORER_TOOLS: CodeBuddyTool[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeExplorer Tool Definitions
|
|
3
|
+
*
|
|
4
|
+
* OpenAI function calling schema for the CodeExplorer tool.
|
|
5
|
+
*/
|
|
6
|
+
export const CODE_EXPLORER_ASK_TOOL = {
|
|
7
|
+
type: 'function',
|
|
8
|
+
function: {
|
|
9
|
+
name: 'code_explorer_ask',
|
|
10
|
+
description: 'Consult CodeExplorer for a query or code understanding request. Returns related files, dependent symbols, tests to watch, and technical recommendations. This is a read-only tool.',
|
|
11
|
+
parameters: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
query: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'The query or task description to ask CodeExplorer about.',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
required: ['query'],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
export const CODE_EXPLORER_TOOLS = [CODE_EXPLORER_ASK_TOOL];
|
|
24
|
+
//# sourceMappingURL=code-explorer-tools.js.map
|
|
@@ -37,6 +37,6 @@ export { EXIT_PLAN_MODE_TOOL, EXIT_PLAN_MODE_TOOLS, } from './exit-plan-mode-too
|
|
|
37
37
|
export { CODEBASE_REPLACE_TOOL, CODEBASE_REPLACE_TOOLS, } from './codebase-replace-tools.js';
|
|
38
38
|
export { GENERATE_DOCUMENT_TOOL, DOCUMENT_GENERATOR_TOOLS, } from './document-tools.js';
|
|
39
39
|
export { SESSION_TOOLS } from './session-tools.js';
|
|
40
|
-
export {
|
|
40
|
+
export { CODE_EXPLORER_ASK_TOOL, CODE_EXPLORER_TOOLS, } from './code-explorer-tools.js';
|
|
41
41
|
export type { CodeBuddyTool as Tool } from './types.js';
|
|
42
42
|
export * from "./windows-tools.js";
|
|
@@ -68,7 +68,7 @@ export { CODEBASE_REPLACE_TOOL, CODEBASE_REPLACE_TOOLS, } from './codebase-repla
|
|
|
68
68
|
export { GENERATE_DOCUMENT_TOOL, DOCUMENT_GENERATOR_TOOLS, } from './document-tools.js';
|
|
69
69
|
// Session tools (multi-agent coordination — Phase E wake)
|
|
70
70
|
export { SESSION_TOOLS } from './session-tools.js';
|
|
71
|
-
//
|
|
72
|
-
export {
|
|
71
|
+
// CodeExplorer tools
|
|
72
|
+
export { CODE_EXPLORER_ASK_TOOL, CODE_EXPLORER_TOOLS, } from './code-explorer-tools.js';
|
|
73
73
|
export * from "./windows-tools.js";
|
|
74
74
|
//# sourceMappingURL=index.js.map
|
|
@@ -27,8 +27,8 @@ export declare function getBuiltinToolNames(): string[];
|
|
|
27
27
|
export declare function initializeToolRegistry(): void;
|
|
28
28
|
export declare function getMCPManager(): MCPManager;
|
|
29
29
|
/**
|
|
30
|
-
* True when the Code Explorer (
|
|
31
|
-
* one `
|
|
30
|
+
* True when the Code Explorer (code-explorer) MCP tools are connected — i.e. at least
|
|
31
|
+
* one `mcp__code-explorer__*` tool is registered. Used to conditionally steer the
|
|
32
32
|
* agent toward Code Explorer for relationship/impact questions. Returns false
|
|
33
33
|
* (no behavior change) whenever Code Explorer is not installed.
|
|
34
34
|
*/
|
package/dist/codebuddy/tools.js
CHANGED
|
@@ -15,7 +15,7 @@ import { applyToolFilter } from "../utils/tool-filter.js";
|
|
|
15
15
|
import { TOOL_METADATA } from "../tools/metadata.js";
|
|
16
16
|
import { getPluginMarketplace } from "../plugins/marketplace.js";
|
|
17
17
|
// Import modular tool definitions
|
|
18
|
-
import { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, AGENT_TOOLS, FIRECRAWL_TOOLS, LSP_TOOLS, SECRETS_TOOLS, ADVISOR_TOOLS, ASK_USER_QUESTION_TOOLS, EXIT_PLAN_MODE_TOOLS, CODEBASE_REPLACE_TOOLS, SESSION_TOOLS,
|
|
18
|
+
import { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, AGENT_TOOLS, FIRECRAWL_TOOLS, LSP_TOOLS, SECRETS_TOOLS, ADVISOR_TOOLS, ASK_USER_QUESTION_TOOLS, EXIT_PLAN_MODE_TOOLS, CODEBASE_REPLACE_TOOLS, SESSION_TOOLS, CODE_EXPLORER_TOOLS, WINDOWS_TOOLS, } from "./tool-definitions/index.js";
|
|
19
19
|
import { FLEET_TOOLS } from "./fleet-tool-defs.js";
|
|
20
20
|
// Explicit re-exports from tool-definitions (no blanket export *)
|
|
21
21
|
export { CORE_TOOLS, MORPH_EDIT_TOOL, isMorphEnabled, SEARCH_TOOLS, TODO_TOOLS, KANBAN_TOOLS, MESSAGING_TOOLS, YUANBAO_TOOLS, HOMEASSISTANT_TOOLS, MOA_TOOLS, SPOTIFY_TOOLS, X_SEARCH_TOOLS, FEISHU_TOOLS, CRON_TOOLS, WEB_TOOLS, ADVANCED_TOOLS, MULTIMODAL_TOOLS, COMPUTER_CONTROL_TOOLS, BROWSER_TOOLS, CANVAS_TOOLS, REASON_TOOL, EXECUTE_CODE_TOOL, WINDOWS_TOOLS, } from "./tool-definitions/index.js";
|
|
@@ -50,7 +50,7 @@ export function getBuiltinToolNames() {
|
|
|
50
50
|
CODEBASE_REPLACE_TOOLS,
|
|
51
51
|
SESSION_TOOLS,
|
|
52
52
|
FLEET_TOOLS,
|
|
53
|
-
|
|
53
|
+
CODE_EXPLORER_TOOLS,
|
|
54
54
|
WINDOWS_TOOLS,
|
|
55
55
|
];
|
|
56
56
|
return Array.from(new Set(groups.flatMap((tools) => tools.map((tool) => tool.function.name))));
|
|
@@ -145,8 +145,8 @@ export function initializeToolRegistry() {
|
|
|
145
145
|
// Fleet tools — peer_delegate, list_peers (Phase (d).17). Always available;
|
|
146
146
|
// peer_delegate returns a clear error when no peers are connected.
|
|
147
147
|
registerGroup(FLEET_TOOLS);
|
|
148
|
-
//
|
|
149
|
-
registerGroup(
|
|
148
|
+
// CodeExplorer tools
|
|
149
|
+
registerGroup(CODE_EXPLORER_TOOLS);
|
|
150
150
|
isRegistryInitialized = true;
|
|
151
151
|
logger.debug('Tool registry initialized with built-in tools');
|
|
152
152
|
}
|
|
@@ -162,14 +162,14 @@ export function getMCPManager() {
|
|
|
162
162
|
return mcpManager;
|
|
163
163
|
}
|
|
164
164
|
/**
|
|
165
|
-
* True when the Code Explorer (
|
|
166
|
-
* one `
|
|
165
|
+
* True when the Code Explorer (code-explorer) MCP tools are connected — i.e. at least
|
|
166
|
+
* one `mcp__code-explorer__*` tool is registered. Used to conditionally steer the
|
|
167
167
|
* agent toward Code Explorer for relationship/impact questions. Returns false
|
|
168
168
|
* (no behavior change) whenever Code Explorer is not installed.
|
|
169
169
|
*/
|
|
170
170
|
export function isCodeExplorerAvailable() {
|
|
171
171
|
try {
|
|
172
|
-
return getMCPManager().getTools().some((t) => t.name.startsWith('
|
|
172
|
+
return getMCPManager().getTools().some((t) => t.name.startsWith('mcp__code-explorer__'));
|
|
173
173
|
}
|
|
174
174
|
catch {
|
|
175
175
|
return false;
|
|
@@ -387,18 +387,33 @@ export async function getAllCodeBuddyTools() {
|
|
|
387
387
|
}
|
|
388
388
|
// Apply CLI tool filter (--enabled-tools, --disabled-tools, --allowed-tools)
|
|
389
389
|
allTools = applyToolFilter(allTools);
|
|
390
|
-
// When Code Explorer (
|
|
390
|
+
// When Code Explorer (code-explorer) is connected, make the built-in graph tools
|
|
391
391
|
// defer to it at the decision point — its graph is broader / more complete.
|
|
392
392
|
// Conditional & non-mutating: returns fresh objects only for code_graph /
|
|
393
|
-
// codebase_map, and only when a
|
|
394
|
-
if (allTools.some((t) => t.function.name.startsWith('
|
|
395
|
-
const DEFER = ' NOTE: Code Explorer (
|
|
396
|
-
'dead-code and cycle questions PREFER its MCP tools (`
|
|
397
|
-
'`query` / `find_cycles`); use this built-in only as a fallback if a
|
|
393
|
+
// codebase_map, and only when a code-explorer tool is present (no change otherwise).
|
|
394
|
+
if (allTools.some((t) => t.function.name.startsWith('mcp__code-explorer__'))) {
|
|
395
|
+
const DEFER = ' NOTE: Code Explorer (code-explorer) is available — for code-relationship, blast-radius/impact, ' +
|
|
396
|
+
'dead-code and cycle questions PREFER its MCP tools (`mcp__code-explorer__impact` / `context` / ' +
|
|
397
|
+
'`query` / `find_cycles`); use this built-in only as a fallback if a code-explorer tool errors.';
|
|
398
398
|
allTools = allTools.map((t) => t.function.name === 'code_graph' || t.function.name === 'codebase_map'
|
|
399
399
|
? { ...t, function: { ...t.function, description: (t.function.description ?? '') + DEFER } }
|
|
400
400
|
: t);
|
|
401
401
|
}
|
|
402
|
+
// Populate the `tool_search` BM25 index so the model can DISCOVER any tool on
|
|
403
|
+
// demand (progressive disclosure, like Codex/Claude). It was never
|
|
404
|
+
// initialized, leaving tool_search blind ("No tools found"). Index the full
|
|
405
|
+
// set (built-in + MCP + plugin) so a tool outside the per-query TF-IDF subset
|
|
406
|
+
// is still reachable when the model calls tool_search.
|
|
407
|
+
try {
|
|
408
|
+
const { initToolSearchIndex } = await import('../tools/tool-search.js');
|
|
409
|
+
initToolSearchIndex(allTools.map((t) => ({
|
|
410
|
+
name: t.function.name,
|
|
411
|
+
description: t.function.description ?? '',
|
|
412
|
+
})));
|
|
413
|
+
}
|
|
414
|
+
catch {
|
|
415
|
+
// tool-search is optional — never block tool assembly.
|
|
416
|
+
}
|
|
402
417
|
return allTools;
|
|
403
418
|
}
|
|
404
419
|
// ============================================================================
|
|
@@ -16,8 +16,13 @@ export class AIColabManager {
|
|
|
16
16
|
workLog = [];
|
|
17
17
|
constructor(workingDirectory = process.cwd()) {
|
|
18
18
|
this.colabFilePath = path.join(workingDirectory, 'COLAB.md');
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
// The shared fleet board `.codebuddy/colab-tasks.json` is now owned solely by
|
|
20
|
+
// FleetColabStore (the kanban_* tools + the autonomous daemon). This legacy
|
|
21
|
+
// `/colab` manager uses an incompatible schema (`not_started` status, no
|
|
22
|
+
// version/comment preservation, non-atomic full-file rewrite), so it writes
|
|
23
|
+
// its OWN files to avoid clobbering the unified board. See ColabKanbanAdapter.
|
|
24
|
+
this.tasksFilePath = path.join(workingDirectory, '.codebuddy', 'ai-colab-tasks.json');
|
|
25
|
+
this.workLogFilePath = path.join(workingDirectory, '.codebuddy', 'ai-colab-worklog.json');
|
|
21
26
|
this.config = {
|
|
22
27
|
project: 'Code Buddy',
|
|
23
28
|
version: '1.0.0',
|
|
@@ -317,8 +322,8 @@ Couverture de tests actuelle: ${this.config.currentCoverage}% (objectif: ${this.
|
|
|
317
322
|
|
|
318
323
|
- \`COLAB.md\` - Document de coordination principal
|
|
319
324
|
- \`CLAUDE.md\` - Instructions de build et développement
|
|
320
|
-
- \`.codebuddy/colab-tasks.json\` - Tâches en cours
|
|
321
|
-
- \`.codebuddy/colab-worklog.json\` - Journal de travail
|
|
325
|
+
- \`.codebuddy/ai-colab-tasks.json\` - Tâches en cours
|
|
326
|
+
- \`.codebuddy/ai-colab-worklog.json\` - Journal de travail
|
|
322
327
|
|
|
323
328
|
### Règles de Collaboration
|
|
324
329
|
|