@pentoshi/clai 3.8.43 → 3.8.46
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 +249 -251
- package/dist/agent/compaction-summary.d.ts +10 -1
- package/dist/agent/compaction-summary.js +30 -1
- package/dist/agent/compaction-summary.js.map +1 -1
- package/dist/agent/context-manager.js +15 -7
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/continue-orient.js +8 -1
- package/dist/agent/continue-orient.js.map +1 -1
- package/dist/agent/must-continue.js +1 -1
- package/dist/agent/must-continue.js.map +1 -1
- package/dist/agent/plan-tool.d.ts +4 -0
- package/dist/agent/plan-tool.js +59 -3
- package/dist/agent/plan-tool.js.map +1 -1
- package/dist/agent/reliability-policy.d.ts +3 -2
- package/dist/agent/reliability-policy.js +3 -2
- package/dist/agent/reliability-policy.js.map +1 -1
- package/dist/agent/runner.js +91 -3
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/session-policy.d.ts +8 -0
- package/dist/agent/session-policy.js +2 -0
- package/dist/agent/session-policy.js.map +1 -1
- package/dist/agent/task-sync.d.ts +58 -0
- package/dist/agent/task-sync.js +110 -0
- package/dist/agent/task-sync.js.map +1 -0
- package/dist/app/adapters/agent-event-adapter.js +12 -3
- package/dist/app/adapters/agent-event-adapter.js.map +1 -1
- package/dist/app/adapters/quiet-meta-tools.d.ts +6 -1
- package/dist/app/adapters/quiet-meta-tools.js +8 -1
- package/dist/app/adapters/quiet-meta-tools.js.map +1 -1
- package/dist/app/controllers/session-compact-helper.js +2 -2
- package/dist/app/controllers/session-compact-helper.js.map +1 -1
- package/dist/app/controllers/session-controller.js +3 -2
- package/dist/app/controllers/session-controller.js.map +1 -1
- package/dist/attachments/clipboard-image.d.ts +10 -0
- package/dist/attachments/clipboard-image.js +188 -0
- package/dist/attachments/clipboard-image.js.map +1 -0
- package/dist/attachments/image-content.d.ts +3 -0
- package/dist/attachments/image-content.js +51 -0
- package/dist/attachments/image-content.js.map +1 -0
- package/dist/attachments/service.js +6 -2
- package/dist/attachments/service.js.map +1 -1
- package/dist/commands/providers.js +4 -2
- package/dist/commands/providers.js.map +1 -1
- package/dist/commands/search-providers.d.ts +1 -0
- package/dist/commands/search-providers.js +4 -2
- package/dist/commands/search-providers.js.map +1 -1
- package/dist/llm/capabilities.d.ts +5 -0
- package/dist/llm/capabilities.js +37 -4
- package/dist/llm/capabilities.js.map +1 -1
- package/dist/llm/http.d.ts +9 -1
- package/dist/llm/http.js +33 -3
- package/dist/llm/http.js.map +1 -1
- package/dist/llm/nvidia.js +10 -3
- package/dist/llm/nvidia.js.map +1 -1
- package/dist/llm/router.d.ts +6 -0
- package/dist/llm/router.js +37 -7
- package/dist/llm/router.js.map +1 -1
- package/dist/prompts/embedded.js +2 -2
- package/dist/prompts/embedded.js.map +1 -1
- package/dist/prompts/index.js +1 -1
- package/dist/prompts/system.agent.md +6 -4
- package/dist/prompts/system.ask.md +1 -1
- package/dist/repl/prompt-line.js +39 -6
- package/dist/repl/prompt-line.js.map +1 -1
- package/dist/repl.js +1 -1
- package/dist/repl.js.map +1 -1
- package/dist/store/config.d.ts +5 -1
- package/dist/store/config.js +9 -1
- package/dist/store/config.js.map +1 -1
- package/dist/store/history.js +43 -5
- package/dist/store/history.js.map +1 -1
- package/dist/store/keys.js +1 -0
- package/dist/store/keys.js.map +1 -1
- package/dist/tools/definitions.js +18 -9
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/http.d.ts +6 -1
- package/dist/tools/http.js +247 -68
- package/dist/tools/http.js.map +1 -1
- package/dist/tools/registry.js +2 -1
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/web/decode.d.ts +17 -0
- package/dist/tools/web/decode.js +65 -0
- package/dist/tools/web/decode.js.map +1 -0
- package/dist/tools/web/fetch-core.js +14 -20
- package/dist/tools/web/fetch-core.js.map +1 -1
- package/dist/tools/web/providers/exa.d.ts +51 -0
- package/dist/tools/web/providers/exa.js +303 -0
- package/dist/tools/web/providers/exa.js.map +1 -0
- package/dist/tools/web/readable.d.ts +5 -5
- package/dist/tools/web/readable.js +34 -12
- package/dist/tools/web/readable.js.map +1 -1
- package/dist/tools/web/search.d.ts +3 -1
- package/dist/tools/web/search.js +6 -4
- package/dist/tools/web/search.js.map +1 -1
- package/dist/tools/web/types.d.ts +25 -2
- package/dist/tools/web/types.js +32 -0
- package/dist/tools/web/types.js.map +1 -1
- package/dist/tui-v2/actions/action-id.d.ts +1 -1
- package/dist/tui-v2/actions/action-id.js +1 -0
- package/dist/tui-v2/actions/action-id.js.map +1 -1
- package/dist/tui-v2/actions/chord-from-key.js +4 -2
- package/dist/tui-v2/actions/chord-from-key.js.map +1 -1
- package/dist/tui-v2/actions/format-shortcuts.js +1 -0
- package/dist/tui-v2/actions/format-shortcuts.js.map +1 -1
- package/dist/tui-v2/actions/keymap.js +3 -0
- package/dist/tui-v2/actions/keymap.js.map +1 -1
- package/dist/tui-v2/app/App.js +15 -1
- package/dist/tui-v2/app/App.js.map +1 -1
- package/dist/tui-v2/app/commands/key-commands.js +1 -1
- package/dist/tui-v2/app/commands/key-commands.js.map +1 -1
- package/dist/tui-v2/app/commands/picker-commands.js +59 -8
- package/dist/tui-v2/app/commands/picker-commands.js.map +1 -1
- package/dist/tui-v2/app/mode-cycle.d.ts +6 -0
- package/dist/tui-v2/app/mode-cycle.js +23 -0
- package/dist/tui-v2/app/mode-cycle.js.map +1 -0
- package/dist/tui-v2/components/composer/composer-input-box.js +1 -1
- package/dist/tui-v2/components/composer/composer-input-box.js.map +1 -1
- package/dist/tui-v2/components/status/status-line.d.ts +1 -0
- package/dist/tui-v2/components/status/status-line.js +2 -2
- package/dist/tui-v2/components/status/status-line.js.map +1 -1
- package/dist/tui-v2/components/transcript/intro-card.js +11 -5
- package/dist/tui-v2/components/transcript/intro-card.js.map +1 -1
- package/dist/tui-v2/composer/composer-editor.js +11 -9
- package/dist/tui-v2/composer/composer-editor.js.map +1 -1
- package/dist/tui-v2/composer/composer-image-paste.d.ts +19 -0
- package/dist/tui-v2/composer/composer-image-paste.js +56 -0
- package/dist/tui-v2/composer/composer-image-paste.js.map +1 -0
- package/dist/ui/keys.d.ts +1 -0
- package/dist/ui/keys.js +4 -0
- package/dist/ui/keys.js.map +1 -1
- package/dist/ui/mentions.d.ts +2 -16
- package/dist/ui/mentions.js +132 -102
- package/dist/ui/mentions.js.map +1 -1
- package/dist/version.generated.d.ts +2 -2
- package/dist/version.generated.js +2 -2
- package/package.json +1 -1
|
@@ -10,8 +10,9 @@ import { getConfig, providerCategory } from "../store/config.js";
|
|
|
10
10
|
import { AUTO_COMPACT_TOKEN_BUDGET } from "./context-manager.js";
|
|
11
11
|
/** Hard auto-compact ceiling — never raise soft past this. */
|
|
12
12
|
export const HARD_COMPACT_TOKEN_BUDGET = AUTO_COMPACT_TOKEN_BUDGET;
|
|
13
|
-
/** E1 default:
|
|
14
|
-
|
|
13
|
+
/** E1 default: auto-compact trigger. Matches the hard ceiling so compaction
|
|
14
|
+
* fires at ~100k estimated tokens; lower via config/env for earlier compaction. */
|
|
15
|
+
export const DEFAULT_SOFT_COMPACT_TOKEN_BUDGET = 100_000;
|
|
15
16
|
/** E2 default fs passthrough (was 400k). Full body always on disk when truncated. */
|
|
16
17
|
export const DEFAULT_FS_PASSTHROUGH_CAP_CHARS = 64_000;
|
|
17
18
|
/** E4: warn when free-cloud context is this large. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reliability-policy.js","sourceRoot":"","sources":["../../src/agent/reliability-policy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,yBAAyB,GAAG,yBAAyB,CAAC;AAEnE
|
|
1
|
+
{"version":3,"file":"reliability-policy.js","sourceRoot":"","sources":["../../src/agent/reliability-policy.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/runner.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { streamWithProvider, completeWithProvider } from "../llm/router.js";
|
|
3
|
+
import { streamWithProvider, completeWithProvider, isEmptyCompletionError } from "../llm/router.js";
|
|
4
4
|
import { resolveToolDialect } from "../llm/capabilities.js";
|
|
5
5
|
import { syntheticToolCallId, isTextOnlyModel, fromWireName, } from "../llm/tool-protocol.js";
|
|
6
6
|
import { sanitizeAssistantText } from "../ui/ansi-box.js";
|
|
@@ -39,6 +39,7 @@ import { createSessionPolicy, isPreApprovalAllowedTool, isPlanModeAllowedShellCo
|
|
|
39
39
|
import { saveToolOutput, summarizeOutput, formatToolContext, } from "./tool-output-formatting.js";
|
|
40
40
|
import { codingSessionFromContext, isProtocolPlaceholderOutput, progressPauseMode, } from "./progress-pause-policy.js";
|
|
41
41
|
import { renderPlanForTerminal, planContextMessage, handlePlanTool, resolvePlanTaskId, } from "./plan-tool.js";
|
|
42
|
+
import { readTaskUpdateArgs, distinctAdvancingTaskIds, isSimultaneousTaskAdvance, batchUpdateSignature, buildMultiUpdateReminder, multiUpdateToast, } from "./task-sync.js";
|
|
42
43
|
import { absorbLooseWorkIntoLedger, applyDestinationCwd, canMarkTaskDone, hasLocalRuntimeProof, hasRemoteWorkProof, isDevServerCall, isEvidenceWorkTool, isFeatureImplementationCall, isPackageInstallCommand, isPlanPreflightTool, isPortListeningOutput, isReadOnlyReconTool, isRemoteActiveTestCall, isRemoteObservationTask, isRemoteReconToolCall, isRuntimeObservationTask, isScaffoldCreateCommand, isServerReadyOutput, ledgerFromTaskEvidence, pickPendingTaskForToolCall, recordTaskWorkSuccess, resolveUserDestinationHint, taskEvidenceFromLedger, TOOL_ABORT_GRACE_MS, toolHardBudgetMs, toolStallBudgetMs, userAskedForFeatureApp, } from "./task-evidence.js";
|
|
43
44
|
import { buildSessionStateBlock, inferNextHint, upsertSessionStateMessage, } from "./session-state.js";
|
|
44
45
|
import { buildContinueOrientation } from "./continue-orient.js";
|
|
@@ -290,6 +291,12 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
290
291
|
};
|
|
291
292
|
let lastAnswer = "";
|
|
292
293
|
const session = options.session ?? createSessionPolicy();
|
|
294
|
+
// Defensive init: external/legacy callers may build a policy without the
|
|
295
|
+
// newer sync-guard holders. Never dereference an undefined holder.
|
|
296
|
+
if (!session.pendingTaskBatch)
|
|
297
|
+
session.pendingTaskBatch = { value: undefined };
|
|
298
|
+
if (!session.pendingDependency)
|
|
299
|
+
session.pendingDependency = { value: undefined };
|
|
293
300
|
// One-shot CLI / tests that never entered TUI/REPL still need an isolated
|
|
294
301
|
// scratch+output workspace. No-op when a session already bound one.
|
|
295
302
|
if (!getActiveSessionWorkspace()) {
|
|
@@ -789,6 +796,9 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
789
796
|
refreshSessionState(activePlan);
|
|
790
797
|
let pendingCalls = [];
|
|
791
798
|
let narrowNmapDispatchCount = 0;
|
|
799
|
+
// Multi-task sync guard state (recomputed per model message before execution).
|
|
800
|
+
let batchRemindCalls = new Set();
|
|
801
|
+
let batchReminderNote = "";
|
|
792
802
|
const deferredPostToolMessages = [];
|
|
793
803
|
/**
|
|
794
804
|
* Latest plan seen during tool execution. SESSION STATE is refreshed once
|
|
@@ -915,6 +925,20 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
915
925
|
narrowNmapDispatchCount += 1;
|
|
916
926
|
}
|
|
917
927
|
}
|
|
928
|
+
// Held batch task update: one reminder for the whole simultaneous set,
|
|
929
|
+
// no execution, until the model re-issues the identical batch to confirm.
|
|
930
|
+
if (call.name === "task.update" && batchRemindCalls.has(rawCall)) {
|
|
931
|
+
if (!alreadyPrintedIds.has(toolEventId)) {
|
|
932
|
+
const toolCallLine = chalk.cyan(` ▶ ${call.name}`) +
|
|
933
|
+
chalk.gray(` ${formatToolArgs(call)}`);
|
|
934
|
+
writeToolCall(toolEventId, call, styleToolChatter(call, toolCallLine) + "\n");
|
|
935
|
+
alreadyPrintedIds.add(toolEventId);
|
|
936
|
+
}
|
|
937
|
+
const result = { ok: false, output: batchReminderNote, exitCode: 1 };
|
|
938
|
+
emitToolResult(toolEventId, result, batchReminderNote);
|
|
939
|
+
writeToolOutput(toolEventId, "held\n", chalk.yellow(" ⚠") + "\n");
|
|
940
|
+
return { ok: false, call, result, contextOutput: batchReminderNote };
|
|
941
|
+
}
|
|
918
942
|
const retryReasonRaw = call.args._retryReason;
|
|
919
943
|
const retryReason = retryReasonRaw && typeof retryReasonRaw === "object"
|
|
920
944
|
? {
|
|
@@ -1013,7 +1037,9 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
1013
1037
|
autoApprove: !isPlanMode,
|
|
1014
1038
|
});
|
|
1015
1039
|
if (planResult.handled) {
|
|
1016
|
-
|
|
1040
|
+
if (!planResult.reminder) {
|
|
1041
|
+
loopGuard.recordAttempt(step, call.name, call.args, planResult.ok, 0);
|
|
1042
|
+
}
|
|
1017
1043
|
if (planResult.ok && call.name === "task.update") {
|
|
1018
1044
|
const stateRaw = typeof call.args.state === "string" ? call.args.state : "";
|
|
1019
1045
|
const taskIdRaw = typeof call.args.taskId === "string"
|
|
@@ -1066,6 +1092,9 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
1066
1092
|
writeToolCall(toolEventId, call, styleToolChatter(call, toolCallLine) + "\n");
|
|
1067
1093
|
alreadyPrintedIds.add(toolEventId);
|
|
1068
1094
|
}
|
|
1095
|
+
if (planResult.reminder && planResult.toast) {
|
|
1096
|
+
writeNotice("warn", planResult.toast, chalk.yellow(` ⚠ ${planResult.toast}\n`));
|
|
1097
|
+
}
|
|
1069
1098
|
if (planResult.plan) {
|
|
1070
1099
|
writePlanUpdate(planResult.plan, planResult.display);
|
|
1071
1100
|
// Refresh sticky root only if path already exists (not bare Desktop).
|
|
@@ -2023,7 +2052,7 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
2023
2052
|
};
|
|
2024
2053
|
async function maybeAutoCompact(reason, force = false) {
|
|
2025
2054
|
const beforeTokens = estimateNextRequestTokens(messages);
|
|
2026
|
-
// E1:
|
|
2055
|
+
// E1: auto-compact trigger (default 100k, matches hard ceiling).
|
|
2027
2056
|
const compactTrigger = autoCompactTriggerTokens();
|
|
2028
2057
|
if (!force && beforeTokens < compactTrigger)
|
|
2029
2058
|
return;
|
|
@@ -2407,6 +2436,22 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
2407
2436
|
continue; // already shown above
|
|
2408
2437
|
writeNotice("warn", notice, chalk.yellow(` ⚠ ${notice}\n`));
|
|
2409
2438
|
}
|
|
2439
|
+
// A fully empty model completion (no text, no tool calls) must not
|
|
2440
|
+
// kill the turn. It shows up most after auto-compaction, when the
|
|
2441
|
+
// tail ends on re-injected system context and the model has nothing
|
|
2442
|
+
// to answer. Append a trailing user nudge (so the turn no longer
|
|
2443
|
+
// ends on system messages) and retry, bounded like the
|
|
2444
|
+
// successful-but-empty path below.
|
|
2445
|
+
if (!options.signal?.aborted &&
|
|
2446
|
+
isEmptyCompletionError(streamError) &&
|
|
2447
|
+
emptyVisibleRetries < 3) {
|
|
2448
|
+
emptyVisibleRetries += 1;
|
|
2449
|
+
writeNotice("warn", "model streamed an empty response — nudging it to continue", chalk.yellow(" ⚠ model streamed an empty response — nudging it to continue\n"));
|
|
2450
|
+
messages.push(recoveryUserMessage("Your previous response was empty. Continue the task now: emit your next tool call, " +
|
|
2451
|
+
"or give your final answer if every required step is already complete and verified. " +
|
|
2452
|
+
"Do not reply with an empty message."));
|
|
2453
|
+
continue;
|
|
2454
|
+
}
|
|
2410
2455
|
throw streamError;
|
|
2411
2456
|
}
|
|
2412
2457
|
}
|
|
@@ -3369,6 +3414,49 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
3369
3414
|
if (res.lastAnswer === "Aborted.")
|
|
3370
3415
|
aborted = true;
|
|
3371
3416
|
};
|
|
3417
|
+
// Multi-task sync guard: when one model message advances more than one
|
|
3418
|
+
// distinct task at once, hold the whole set behind a single reminder.
|
|
3419
|
+
// The model confirms by re-issuing the identical batch; a single-task
|
|
3420
|
+
// (or non-advancing) message clears any pending confirmation.
|
|
3421
|
+
batchRemindCalls = new Set();
|
|
3422
|
+
batchReminderNote = "";
|
|
3423
|
+
{
|
|
3424
|
+
const livePlanForBatch = await loadPlan(session.sessionId).catch(() => undefined);
|
|
3425
|
+
const intents = [];
|
|
3426
|
+
for (const b of toRun) {
|
|
3427
|
+
const parsed = readTaskUpdateArgs(b.call);
|
|
3428
|
+
if (!parsed)
|
|
3429
|
+
continue;
|
|
3430
|
+
const resolvedId = livePlanForBatch
|
|
3431
|
+
? resolvePlanTaskId(livePlanForBatch, parsed.taskId) ?? parsed.taskId
|
|
3432
|
+
: parsed.taskId;
|
|
3433
|
+
intents.push({ call: b.call, taskId: resolvedId, state: parsed.state });
|
|
3434
|
+
}
|
|
3435
|
+
if (isSimultaneousTaskAdvance(intents)) {
|
|
3436
|
+
const signature = batchUpdateSignature(intents);
|
|
3437
|
+
if (session.pendingTaskBatch.value === signature) {
|
|
3438
|
+
session.pendingTaskBatch.value = undefined;
|
|
3439
|
+
writeNotice("info", "confirmed batch task update — applying", chalk.dim(" ℹ confirmed batch task update — applying\n"));
|
|
3440
|
+
}
|
|
3441
|
+
else {
|
|
3442
|
+
session.pendingTaskBatch.value = signature;
|
|
3443
|
+
const descriptors = intents.map((intent) => ({
|
|
3444
|
+
taskId: intent.taskId,
|
|
3445
|
+
title: livePlanForBatch?.tasks.find((t) => t.id === intent.taskId)
|
|
3446
|
+
?.title ?? "",
|
|
3447
|
+
targetState: intent.state,
|
|
3448
|
+
}));
|
|
3449
|
+
batchReminderNote = buildMultiUpdateReminder(descriptors);
|
|
3450
|
+
for (const intent of intents)
|
|
3451
|
+
batchRemindCalls.add(intent.call);
|
|
3452
|
+
const advancing = distinctAdvancingTaskIds(intents).length;
|
|
3453
|
+
writeNotice("warn", multiUpdateToast(advancing), chalk.yellow(` ⚠ ${multiUpdateToast(advancing)}\n`));
|
|
3454
|
+
}
|
|
3455
|
+
}
|
|
3456
|
+
else {
|
|
3457
|
+
session.pendingTaskBatch.value = undefined;
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3372
3460
|
const groups = groupToolCallsForExecution(allCalls, isParallelSafe, PARALLEL_LIMIT);
|
|
3373
3461
|
for (const group of groups) {
|
|
3374
3462
|
if (aborted || awaitingPlanApproval || governorPauseReason)
|