@pentoshi/clai 3.11.33 → 3.11.35
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/runner.js +51 -9
- package/dist/agent/runner.js.map +1 -1
- package/dist/llm/tool-protocol.d.ts +8 -0
- package/dist/llm/tool-protocol.js +96 -3
- package/dist/llm/tool-protocol.js.map +1 -1
- package/dist/tools/capabilities.js +5 -4
- package/dist/tools/capabilities.js.map +1 -1
- package/dist/tools/fs.js +17 -5
- package/dist/tools/fs.js.map +1 -1
- package/dist/tools/registry.d.ts +1 -0
- package/dist/tools/registry.js +12 -1
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/wordlists.js +4 -4
- package/dist/tools/wordlists.js.map +1 -1
- package/dist/version.generated.d.ts +2 -2
- package/dist/version.generated.js +2 -2
- package/package.json +1 -1
package/dist/agent/runner.js
CHANGED
|
@@ -923,6 +923,8 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
923
923
|
// Track tool calls truncated by the token limit so we can ask the model
|
|
924
924
|
// to retry in smaller pieces instead of leaking broken JSON as an answer.
|
|
925
925
|
let truncatedToolRetries = 0;
|
|
926
|
+
/** Consecutive model rounds whose native tool arguments were unusable. */
|
|
927
|
+
let malformedNativeArgsRounds = 0;
|
|
926
928
|
let bareToolJsonRetries = 0;
|
|
927
929
|
// Track a ```tool fence that is present but whose JSON could not be parsed
|
|
928
930
|
// (e.g. malformed extra/missing braces that are NOT simple truncation). We
|
|
@@ -3730,7 +3732,45 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
3730
3732
|
}
|
|
3731
3733
|
}
|
|
3732
3734
|
}
|
|
3735
|
+
if (nativeToolCalls.length) {
|
|
3736
|
+
const unparseable = nativeToolCalls.filter((tc) => Boolean(tc.args?._parseError));
|
|
3737
|
+
if (unparseable.length > 0) {
|
|
3738
|
+
malformedNativeArgsRounds += 1;
|
|
3739
|
+
if (malformedNativeArgsRounds >= 2) {
|
|
3740
|
+
const names = [...new Set(unparseable.map((tc) => tc.name))].join(", ");
|
|
3741
|
+
for (const entry of deferredToolCalls) {
|
|
3742
|
+
if (!entry.shown || entry.call.name === "…")
|
|
3743
|
+
continue;
|
|
3744
|
+
writeToolBlocked(entry.eventId, entry.call.name, "Native tool arguments were unusable again; nothing ran. Reissue as a fenced tool block.", chalk.yellow(" ⚠ native tool arguments were unusable again — nothing ran\n"));
|
|
3745
|
+
}
|
|
3746
|
+
markTextOnlyModel(provider, model);
|
|
3747
|
+
writeNotice("warn", "native tool arguments keep arriving unusable — switching this model to the text tool protocol", chalk.yellow(" ⚠ native tool arguments keep arriving unusable — switching this model to the text tool protocol\n"));
|
|
3748
|
+
commitAssistantRetry(assistantText.visible);
|
|
3749
|
+
messages.push(recoveryUserMessage(`Your native ${names || "tool"} call arguments were not usable, so nothing ran. ` +
|
|
3750
|
+
"Do not repeat that call. Emit exactly one complete fenced ```tool block with valid JSON arguments now."));
|
|
3751
|
+
nativeToolCalls = [];
|
|
3752
|
+
call = undefined;
|
|
3753
|
+
deferredToolCalls.length = 0;
|
|
3754
|
+
continue;
|
|
3755
|
+
}
|
|
3756
|
+
}
|
|
3757
|
+
else {
|
|
3758
|
+
malformedNativeArgsRounds = 0;
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3733
3761
|
if (!canonicalAssistantVisible.trim() && !call) {
|
|
3762
|
+
const incompleteNativeStream = nativeToolCalls.length === 0 &&
|
|
3763
|
+
deferredToolCalls.some((entry) => entry.shown && entry.call.name !== "…");
|
|
3764
|
+
if (incompleteNativeStream) {
|
|
3765
|
+
const reason = "The provider began this native tool call but never completed it. Nothing ran; reissue a complete call.";
|
|
3766
|
+
for (const deferred of deferredToolCalls) {
|
|
3767
|
+
if (!deferred.shown || deferred.call.name === "…")
|
|
3768
|
+
continue;
|
|
3769
|
+
writeToolBlocked(deferred.eventId, deferred.call.name, reason, chalk.yellow(` ⚠ ${reason}\n`));
|
|
3770
|
+
}
|
|
3771
|
+
markTextOnlyModel(provider, model);
|
|
3772
|
+
writeNotice("warn", "provider abandoned a native tool call — switching this model to the text tool protocol", chalk.yellow(" ⚠ provider abandoned a native tool call — switching this model to the text tool protocol\n"));
|
|
3773
|
+
}
|
|
3734
3774
|
emptyVisibleRetries += 1;
|
|
3735
3775
|
if (emptyVisibleRetries <= 3) {
|
|
3736
3776
|
if (assistantText.hasThinking) {
|
|
@@ -3743,15 +3783,17 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
3743
3783
|
retryWithoutThinking = true;
|
|
3744
3784
|
commitAssistantRetry(assistantText.visible);
|
|
3745
3785
|
// Keep nudges SHORT — cheap models lose the key instruction in long text.
|
|
3746
|
-
const buildNudge =
|
|
3747
|
-
?
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
"
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
:
|
|
3754
|
-
"
|
|
3786
|
+
const buildNudge = incompleteNativeStream
|
|
3787
|
+
? "Your native tool call was incomplete, so nothing ran. Use exactly one complete fenced ```tool block now; do not repeat the incomplete native call."
|
|
3788
|
+
: isPlanMode && !activePlan
|
|
3789
|
+
? toolsAttached
|
|
3790
|
+
? "No visible output. In plan mode: gather context or call plan.create when ready (do not only describe the plan)."
|
|
3791
|
+
: "No visible output. In plan mode: emit a ```tool block for research/recon or plan.create. " +
|
|
3792
|
+
"Do NOT hide tool calls in <think> tags — put them in the visible response."
|
|
3793
|
+
: toolsAttached
|
|
3794
|
+
? "No visible output. " + toolNudge(true)
|
|
3795
|
+
: "No visible output. Emit a ```tool block or give your final answer. " +
|
|
3796
|
+
"Do NOT hide tool calls in <think> tags — put them in the visible response.";
|
|
3755
3797
|
messages.push(recoveryUserMessage(buildNudge));
|
|
3756
3798
|
continue;
|
|
3757
3799
|
}
|