fix(pi-claude-cli): unblock parameterless MCP tool calls in triage
Triage with claude-sonnet-4-6 via pi-claude-cli kept looping on
fn_review_spec calls that were rejected by pi's validator with
"root: must be object". Parameterless MCP tools (schema
{type:"object", properties:{}}) emit zero input_json_delta events,
so partialJson stayed "" and the catch fell through to
finalArgs = "" — a string, which TypeBox's Type.Object({}) rightly
refuses. Default empty partialJson to {} so the call lands.
Also:
- Add a 2-step reminder loop in triage before swapping to the
fallback planning model — primary models that wrote PROMPT.md
but forgot fn_review_spec recover from a nudge, no need to pay
the cold-start tax of a new triage on a different model.
- Inject @runfusion/fusion's own pi extension into dashboard/
daemon/serve sessions and propagate the path to createFnAgent
via setHostExtensionPaths so fn_* tools register globally
without requiring `pi install npm:@runfusion/fusion`.
- Drop the "historical" qualifier from replayed tool labels —
Claude was reading "TOOL RESULT (historical Read):" as
"previous session, ignore" and looping on verification.
- Remove subprocess-lifecycle stderr debug logs that landed for
hang diagnosis — root cause is fixed, the noise can go.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,24 @@ export interface AgentResult {
|
||||
sessionFile?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process-global list of extension paths to inject into every createFnAgent
|
||||
* session. Set once at startup by the host (cli's dashboard/daemon/serve)
|
||||
* before any sessions are created. The paths are passed to pi's
|
||||
* `DefaultResourceLoader` as `additionalExtensionPaths` so the cli's own
|
||||
* `@runfusion/fusion` extension (registering `fn_*` tools) is loaded inside
|
||||
* every agent session — including chat sessions that pass no `customTools`.
|
||||
*/
|
||||
let hostExtensionPaths: string[] = [];
|
||||
|
||||
export function setHostExtensionPaths(paths: readonly string[]): void {
|
||||
hostExtensionPaths = [...paths];
|
||||
}
|
||||
|
||||
export function getHostExtensionPaths(): readonly string[] {
|
||||
return hostExtensionPaths;
|
||||
}
|
||||
|
||||
export interface PromptableSession extends AgentSession {
|
||||
promptWithFallback: (prompt: string, options?: unknown) => Promise<void>;
|
||||
}
|
||||
@@ -1066,6 +1084,10 @@ export async function createFnAgent(options: AgentOptions): Promise<AgentResult>
|
||||
settingsManager,
|
||||
systemPromptOverride: () => options.systemPrompt,
|
||||
appendSystemPromptOverride: () => [],
|
||||
// Inject host-supplied extension paths (e.g. cli's own `@runfusion/fusion`
|
||||
// extension that registers `fn_*` tools) so they're loaded inside every
|
||||
// agent session, including chat sessions that don't pass `customTools`.
|
||||
...(hostExtensionPaths.length > 0 ? { additionalExtensionPaths: [...hostExtensionPaths] } : {}),
|
||||
...(skillsOverrideFn ? { skillsOverride: skillsOverrideFn } : {}),
|
||||
});
|
||||
await resourceLoader.reload();
|
||||
|
||||
Reference in New Issue
Block a user