clementine-agent 1.0.62 → 1.0.64
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/dist/agent/assistant.js +78 -2
- package/package.json +1 -1
package/dist/agent/assistant.js
CHANGED
|
@@ -702,6 +702,21 @@ export class PersonalAssistant {
|
|
|
702
702
|
if (sysMsg.mcp_servers) {
|
|
703
703
|
this._lastMcpStatus = sysMsg.mcp_servers;
|
|
704
704
|
this._lastMcpStatusTime = new Date().toISOString();
|
|
705
|
+
// Diagnostic (1.0.64+): log per-server connection status on every
|
|
706
|
+
// init so we can tell whether "No such tool available" errors are
|
|
707
|
+
// caused by a failed spawn vs misconfigured allowedTools vs session
|
|
708
|
+
// weirdness. Single-line grep target: 'SDK init — MCP servers'.
|
|
709
|
+
try {
|
|
710
|
+
const statuses = sysMsg.mcp_servers.map((s) => `${s.name}:${s.status}`);
|
|
711
|
+
logger.info({
|
|
712
|
+
statuses,
|
|
713
|
+
toolCount: Array.isArray(sysMsg.tools) ? sysMsg.tools.length : 0,
|
|
714
|
+
sessionId: sysMsg.session_id,
|
|
715
|
+
cwd: sysMsg.cwd,
|
|
716
|
+
model: sysMsg.model,
|
|
717
|
+
}, 'SDK init — MCP servers');
|
|
718
|
+
}
|
|
719
|
+
catch { /* non-fatal */ }
|
|
705
720
|
}
|
|
706
721
|
// Auto-register Claude Desktop integrations from the authoritative tool
|
|
707
722
|
// list the SDK reports on init. Previously the claude-integrations file
|
|
@@ -1624,7 +1639,16 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
|
|
|
1624
1639
|
...(fallback ? { fallbackModel: fallback } : {}),
|
|
1625
1640
|
permissionMode: effectivePermissionMode,
|
|
1626
1641
|
allowDangerouslySkipPermissions: true,
|
|
1627
|
-
|
|
1642
|
+
// SDK field semantics (per node_modules/@anthropic-ai/claude-agent-sdk/sdk.d.ts):
|
|
1643
|
+
// - `tools` → which built-in tools the model can see (Read, Bash, Task, …)
|
|
1644
|
+
// - `mcpServers` → MCP servers to spawn; all their declared tools are exposed automatically
|
|
1645
|
+
// - `allowedTools` → auto-allow list covering both built-ins AND MCP tool names
|
|
1646
|
+
// (MCP names MUST live here, not in `tools` — that was the bug
|
|
1647
|
+
// producing `<tool_use_error>No such tool available: mcp__*__*`
|
|
1648
|
+
// for every Extension and custom stdio server).
|
|
1649
|
+
// - `disallowedTools` → blocklist, takes precedence.
|
|
1650
|
+
tools: disableAllTools ? [] : allowedTools.filter(t => !t.startsWith('mcp__')),
|
|
1651
|
+
allowedTools: disableAllTools ? [] : allowedTools,
|
|
1628
1652
|
disallowedTools: disallowed,
|
|
1629
1653
|
...(streaming ? { includePartialMessages: true } : {}),
|
|
1630
1654
|
mcpServers: {
|
|
@@ -2237,6 +2261,20 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
|
|
|
2237
2261
|
eventLog.emitQueryStart(sessionKey, prompt, { model: sdkOptions.model ?? undefined, source: 'chat' });
|
|
2238
2262
|
}
|
|
2239
2263
|
try {
|
|
2264
|
+
// Diagnostic (1.0.64+): log the exact options we hand to query().
|
|
2265
|
+
// Compare against a known-working standalone call to pinpoint
|
|
2266
|
+
// config drift. Single-line grep target: 'query() options'.
|
|
2267
|
+
logger.info({
|
|
2268
|
+
sessionKey,
|
|
2269
|
+
cwd: sdkOptions.cwd,
|
|
2270
|
+
mcpServerKeys: Object.keys(sdkOptions.mcpServers ?? {}),
|
|
2271
|
+
toolsCount: Array.isArray(sdkOptions.tools) ? sdkOptions.tools.length : 'preset-or-omitted',
|
|
2272
|
+
allowedToolsCount: sdkOptions.allowedTools?.length ?? 0,
|
|
2273
|
+
disallowedToolsCount: sdkOptions.disallowedTools?.length ?? 0,
|
|
2274
|
+
hasResume: !!sdkOptions.resume,
|
|
2275
|
+
resumeSessionId: sdkOptions.resume,
|
|
2276
|
+
model: sdkOptions.model,
|
|
2277
|
+
}, 'query() options');
|
|
2240
2278
|
const stream = query({ prompt, options: sdkOptions });
|
|
2241
2279
|
let gotStreamEvents = false;
|
|
2242
2280
|
for await (const message of stream) {
|
|
@@ -2600,6 +2638,41 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
|
|
|
2600
2638
|
})(),
|
|
2601
2639
|
replyPreview: responseText.slice(0, 200).replace(/\n/g, ' '),
|
|
2602
2640
|
}, 'Contradiction validator pass');
|
|
2641
|
+
// Diagnostic (1.0.64+): dump EVERY tool_result whose content
|
|
2642
|
+
// looks like the SDK's "No such tool available" error, with
|
|
2643
|
+
// its full content + corresponding tool_use. The specific
|
|
2644
|
+
// pairing is what we need to diagnose whether a particular
|
|
2645
|
+
// server failed to register vs a specific tool was dropped.
|
|
2646
|
+
try {
|
|
2647
|
+
const useById = new Map();
|
|
2648
|
+
for (const msg of collectedSdkMessages) {
|
|
2649
|
+
if (msg.type !== 'assistant' || !msg.message?.content)
|
|
2650
|
+
continue;
|
|
2651
|
+
for (const b of (Array.isArray(msg.message.content) ? msg.message.content : [])) {
|
|
2652
|
+
if (b?.type === 'tool_use' && b.id && b.name)
|
|
2653
|
+
useById.set(b.id, b.name);
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
for (const msg of collectedSdkMessages) {
|
|
2657
|
+
if (msg.type !== 'user' || !msg.message?.content)
|
|
2658
|
+
continue;
|
|
2659
|
+
for (const b of (Array.isArray(msg.message.content) ? msg.message.content : [])) {
|
|
2660
|
+
if (b?.type !== 'tool_result')
|
|
2661
|
+
continue;
|
|
2662
|
+
const contentStr = typeof b.content === 'string' ? b.content : JSON.stringify(b.content);
|
|
2663
|
+
if (/tool_use_error/i.test(contentStr)) {
|
|
2664
|
+
logger.warn({
|
|
2665
|
+
sessionKey,
|
|
2666
|
+
tool_use_id: b.tool_use_id,
|
|
2667
|
+
tool_name: useById.get(b.tool_use_id) ?? '(unknown)',
|
|
2668
|
+
is_error: b.is_error,
|
|
2669
|
+
content: contentStr.slice(0, 600),
|
|
2670
|
+
}, 'SDK tool_use_error surfaced');
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
catch { /* non-fatal */ }
|
|
2603
2676
|
}
|
|
2604
2677
|
const finding = detectContradiction(responseText, toolCallRecords);
|
|
2605
2678
|
if (finding) {
|
|
@@ -3175,7 +3248,10 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
|
|
|
3175
3248
|
model: AUTO_MEMORY_MODEL,
|
|
3176
3249
|
permissionMode: 'bypassPermissions',
|
|
3177
3250
|
allowDangerouslySkipPermissions: true,
|
|
3178
|
-
tools
|
|
3251
|
+
// MCP tool names live in allowedTools, not tools. See note at
|
|
3252
|
+
// buildOptions — `tools` is for built-ins only.
|
|
3253
|
+
tools: [],
|
|
3254
|
+
allowedTools: [
|
|
3179
3255
|
mcpTool('memory_write'),
|
|
3180
3256
|
mcpTool('memory_search'),
|
|
3181
3257
|
mcpTool('note_create'),
|