perchai-cli 2.4.26 → 2.4.28
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/perch.mjs +238 -21
- package/package.json +1 -1
package/dist/perch.mjs
CHANGED
|
@@ -75566,6 +75566,7 @@ var init_payroll = __esm({
|
|
|
75566
75566
|
// lib/perchBusinessTools/index.ts
|
|
75567
75567
|
var init_perchBusinessTools = __esm({
|
|
75568
75568
|
"lib/perchBusinessTools/index.ts"() {
|
|
75569
|
+
"use strict";
|
|
75569
75570
|
init_generateAPAuditPacket();
|
|
75570
75571
|
init_inventoryFolder();
|
|
75571
75572
|
init_loadBusinessTables();
|
|
@@ -76921,6 +76922,8 @@ function buildTranscriptSegments(state) {
|
|
|
76921
76922
|
const terminalSegmentIdx = /* @__PURE__ */ new Map();
|
|
76922
76923
|
const workerRunIdx = /* @__PURE__ */ new Map();
|
|
76923
76924
|
const flockRunIdx = /* @__PURE__ */ new Map();
|
|
76925
|
+
const flockIdByWorkerId = /* @__PURE__ */ new Map();
|
|
76926
|
+
const flockWorkerIdByToolCallId = /* @__PURE__ */ new Map();
|
|
76924
76927
|
const diagnosticIdxByKey = /* @__PURE__ */ new Map();
|
|
76925
76928
|
const capabilityIdx = /* @__PURE__ */ new Map();
|
|
76926
76929
|
const liveCardIdx = /* @__PURE__ */ new Map();
|
|
@@ -76944,6 +76947,32 @@ function buildTranscriptSegments(state) {
|
|
|
76944
76947
|
if (runId) sandboxRunIdx.set(runId, idx);
|
|
76945
76948
|
if (toolCallId) sandboxRunIdx.set(toolCallId, idx);
|
|
76946
76949
|
}
|
|
76950
|
+
function updateFlockWorkerByWorkerId(workerId, updater) {
|
|
76951
|
+
if (!workerId) return false;
|
|
76952
|
+
const flockId = flockIdByWorkerId.get(workerId);
|
|
76953
|
+
if (!flockId) return false;
|
|
76954
|
+
const idx = flockRunIdx.get(flockId);
|
|
76955
|
+
if (idx === void 0) return true;
|
|
76956
|
+
const seg = segments[idx];
|
|
76957
|
+
if (seg?.kind !== "flock_run") return true;
|
|
76958
|
+
segments[idx] = {
|
|
76959
|
+
...seg,
|
|
76960
|
+
workers: seg.workers.map(
|
|
76961
|
+
(worker) => worker.workerId === workerId ? updater(worker) : worker
|
|
76962
|
+
)
|
|
76963
|
+
};
|
|
76964
|
+
return true;
|
|
76965
|
+
}
|
|
76966
|
+
function isFlockOwnedToolEvent(event) {
|
|
76967
|
+
return Boolean(
|
|
76968
|
+
event.workerId && flockIdByWorkerId.has(event.workerId) || event.toolCallId && flockWorkerIdByToolCallId.has(event.toolCallId)
|
|
76969
|
+
);
|
|
76970
|
+
}
|
|
76971
|
+
function isQuietFlockDiagnostic(event) {
|
|
76972
|
+
if (!event.workerId || !flockIdByWorkerId.has(event.workerId)) return false;
|
|
76973
|
+
if (event.code === "tool_call_budget_exhausted") return false;
|
|
76974
|
+
return event.code === "source_read_budget_reached" || event.code === "source_analysis_max_iteration_closing_attempted" || event.code === "source_analysis_max_iteration_synthesized" || event.code === "source_analysis_max_iteration_closing_fallback" || event.code === "source_analysis_max_iteration_incomplete" || /source-read budget|source-analysis|read-only source/i.test(event.message);
|
|
76975
|
+
}
|
|
76947
76976
|
function flushReasoning() {
|
|
76948
76977
|
if (!pendingReasoning) return;
|
|
76949
76978
|
segments.push({ kind: "reasoning", text: pendingReasoning, seq: seq++, timestamp: pendingReasoningTs });
|
|
@@ -77037,6 +77066,15 @@ function buildTranscriptSegments(state) {
|
|
|
77037
77066
|
ev.toolCallId ? [ev.toolCallId] : [],
|
|
77038
77067
|
ev.ts
|
|
77039
77068
|
);
|
|
77069
|
+
if (ev.workerId && flockIdByWorkerId.has(ev.workerId)) {
|
|
77070
|
+
if (ev.toolCallId) flockWorkerIdByToolCallId.set(ev.toolCallId, ev.workerId);
|
|
77071
|
+
updateFlockWorkerByWorkerId(ev.workerId, (worker) => ({
|
|
77072
|
+
...worker,
|
|
77073
|
+
toolCalls: (worker.toolCalls ?? 0) + 1,
|
|
77074
|
+
lastToolName: ev.toolName
|
|
77075
|
+
}));
|
|
77076
|
+
break;
|
|
77077
|
+
}
|
|
77040
77078
|
if (ev.workerId) {
|
|
77041
77079
|
const idx = segments.length;
|
|
77042
77080
|
segments.push({
|
|
@@ -77091,6 +77129,7 @@ function buildTranscriptSegments(state) {
|
|
|
77091
77129
|
}
|
|
77092
77130
|
case "tool_call_completed": {
|
|
77093
77131
|
flushReasoning();
|
|
77132
|
+
if (isFlockOwnedToolEvent(ev)) break;
|
|
77094
77133
|
const id = ev.toolCallId ?? ev.toolName;
|
|
77095
77134
|
const idx = toolCallIdx.get(id);
|
|
77096
77135
|
if (idx !== void 0) {
|
|
@@ -77107,6 +77146,7 @@ function buildTranscriptSegments(state) {
|
|
|
77107
77146
|
}
|
|
77108
77147
|
case "tool_result": {
|
|
77109
77148
|
flushReasoning();
|
|
77149
|
+
if (isFlockOwnedToolEvent(ev)) break;
|
|
77110
77150
|
const id = ev.toolCallId ?? ev.toolName;
|
|
77111
77151
|
if (ev.toolName === "run_sandbox_code") {
|
|
77112
77152
|
updateSandboxRun(ev.toolCallId, null, (seg) => ({ ...seg, resultText: ev.text }));
|
|
@@ -77135,6 +77175,7 @@ function buildTranscriptSegments(state) {
|
|
|
77135
77175
|
case "tool_output_delta": {
|
|
77136
77176
|
flushReasoning();
|
|
77137
77177
|
if (!ev.text) break;
|
|
77178
|
+
if (isFlockOwnedToolEvent(ev)) break;
|
|
77138
77179
|
const id = ev.toolCallId ?? ev.toolName;
|
|
77139
77180
|
if (ev.toolName === "run_sandbox_code") {
|
|
77140
77181
|
updateSandboxRun(ev.toolCallId, null, (seg) => ({ ...seg, resultText: `${seg.resultText ?? ""}${ev.text}` }));
|
|
@@ -77543,6 +77584,7 @@ function buildTranscriptSegments(state) {
|
|
|
77543
77584
|
case "diagnostic": {
|
|
77544
77585
|
flushReasoning();
|
|
77545
77586
|
if (!ev.message.trim()) break;
|
|
77587
|
+
if (isQuietFlockDiagnostic(ev)) break;
|
|
77546
77588
|
if (ev.code === "tool_call_budget_exhausted") {
|
|
77547
77589
|
let attributed = false;
|
|
77548
77590
|
if (ev.workerId) {
|
|
@@ -77694,6 +77736,7 @@ function buildTranscriptSegments(state) {
|
|
|
77694
77736
|
}
|
|
77695
77737
|
case "tool_call_failed": {
|
|
77696
77738
|
flushReasoning();
|
|
77739
|
+
if (isFlockOwnedToolEvent(ev)) break;
|
|
77697
77740
|
const id = ev.toolCallId ?? ev.toolName;
|
|
77698
77741
|
const idx = toolCallIdx.get(id);
|
|
77699
77742
|
if (idx !== void 0) {
|
|
@@ -77808,6 +77851,12 @@ function buildTranscriptSegments(state) {
|
|
|
77808
77851
|
}
|
|
77809
77852
|
case "worker_run_started": {
|
|
77810
77853
|
flushReasoning();
|
|
77854
|
+
if (updateFlockWorkerByWorkerId(ev.workerId, (worker) => ({
|
|
77855
|
+
...worker,
|
|
77856
|
+
status: worker.status === "queued" ? "running" : worker.status
|
|
77857
|
+
}))) {
|
|
77858
|
+
break;
|
|
77859
|
+
}
|
|
77811
77860
|
const idx = segments.length;
|
|
77812
77861
|
segments.push({
|
|
77813
77862
|
kind: "worker_run",
|
|
@@ -77824,6 +77873,12 @@ function buildTranscriptSegments(state) {
|
|
|
77824
77873
|
}
|
|
77825
77874
|
case "worker_run_completed": {
|
|
77826
77875
|
flushReasoning();
|
|
77876
|
+
if (updateFlockWorkerByWorkerId(ev.workerId, (worker) => ({
|
|
77877
|
+
...worker,
|
|
77878
|
+
status: ev.ok ? "done" : "failed"
|
|
77879
|
+
}))) {
|
|
77880
|
+
break;
|
|
77881
|
+
}
|
|
77827
77882
|
const runIdx = workerRunIdx.get(ev.workerId);
|
|
77828
77883
|
if (runIdx !== void 0) {
|
|
77829
77884
|
const seg = segments[runIdx];
|
|
@@ -77876,6 +77931,11 @@ function buildTranscriptSegments(state) {
|
|
|
77876
77931
|
if (idx === void 0) break;
|
|
77877
77932
|
const seg = segments[idx];
|
|
77878
77933
|
if (seg?.kind !== "flock_run") break;
|
|
77934
|
+
if (ev.accepted) {
|
|
77935
|
+
for (const worker of ev.workers) {
|
|
77936
|
+
flockIdByWorkerId.set(worker.workerId, ev.flockId);
|
|
77937
|
+
}
|
|
77938
|
+
}
|
|
77879
77939
|
segments[idx] = ev.accepted ? {
|
|
77880
77940
|
...seg,
|
|
77881
77941
|
status: "running",
|
|
@@ -77897,7 +77957,11 @@ function buildTranscriptSegments(state) {
|
|
|
77897
77957
|
if (seg?.kind !== "flock_run") break;
|
|
77898
77958
|
const known = seg.workers.some((worker) => worker.flockWorkerId === ev.flockWorkerId);
|
|
77899
77959
|
const workers = known ? seg.workers.map(
|
|
77900
|
-
(worker) => worker.flockWorkerId === ev.flockWorkerId ? {
|
|
77960
|
+
(worker) => worker.flockWorkerId === ev.flockWorkerId ? {
|
|
77961
|
+
...worker,
|
|
77962
|
+
status: ev.status,
|
|
77963
|
+
note: ev.detail ?? worker.note
|
|
77964
|
+
} : worker
|
|
77901
77965
|
) : [
|
|
77902
77966
|
...seg.workers,
|
|
77903
77967
|
{
|
|
@@ -77905,7 +77969,8 @@ function buildTranscriptSegments(state) {
|
|
|
77905
77969
|
workerId: ev.workerId,
|
|
77906
77970
|
displayName: ev.displayName,
|
|
77907
77971
|
nickname: ev.nickname,
|
|
77908
|
-
status: ev.status
|
|
77972
|
+
status: ev.status,
|
|
77973
|
+
note: ev.detail
|
|
77909
77974
|
}
|
|
77910
77975
|
];
|
|
77911
77976
|
segments[idx] = { ...seg, workers };
|
|
@@ -78308,9 +78373,13 @@ function segmentToCompact(seg) {
|
|
|
78308
78373
|
summary: seg.summary?.slice(0, 300),
|
|
78309
78374
|
flockWorkers: seg.workers.map((worker) => ({
|
|
78310
78375
|
flockWorkerId: worker.flockWorkerId,
|
|
78376
|
+
workerId: worker.workerId,
|
|
78311
78377
|
displayName: worker.displayName,
|
|
78312
78378
|
nickname: worker.nickname,
|
|
78313
|
-
status: worker.status
|
|
78379
|
+
status: worker.status,
|
|
78380
|
+
note: worker.note,
|
|
78381
|
+
toolCalls: worker.toolCalls,
|
|
78382
|
+
lastToolName: worker.lastToolName
|
|
78314
78383
|
}))
|
|
78315
78384
|
};
|
|
78316
78385
|
case "worker_tool_call":
|
|
@@ -91587,7 +91656,6 @@ function listFinancialPlaybooks() {
|
|
|
91587
91656
|
var AP_AUDIT_PACKET_DEF, PLAYBOOKS;
|
|
91588
91657
|
var init_registry2 = __esm({
|
|
91589
91658
|
"features/perchTerminal/runtime/financialPlaybooks/registry.ts"() {
|
|
91590
|
-
"use strict";
|
|
91591
91659
|
init_managedWorkflowRegistry2();
|
|
91592
91660
|
init_toolNames();
|
|
91593
91661
|
AP_AUDIT_PACKET_DEF = {
|
|
@@ -220709,11 +220777,11 @@ function flockTaskGate(rawTask) {
|
|
|
220709
220777
|
if (!task) {
|
|
220710
220778
|
return { ok: false, task, reason: "No task given. Usage: /flock <task>." };
|
|
220711
220779
|
}
|
|
220712
|
-
if (
|
|
220780
|
+
if (/(^|[\s([{])\/flock(?:\s|$)/i.test(task)) {
|
|
220713
220781
|
return {
|
|
220714
220782
|
ok: false,
|
|
220715
220783
|
task,
|
|
220716
|
-
reason: "
|
|
220784
|
+
reason: "Subagents cannot start another /flock run from inside a /flock request."
|
|
220717
220785
|
};
|
|
220718
220786
|
}
|
|
220719
220787
|
const wordCount = task.split(/\s+/).length;
|
|
@@ -221475,15 +221543,30 @@ function buildSpawnContext(input, flockId, signal, emit, worker) {
|
|
|
221475
221543
|
};
|
|
221476
221544
|
}
|
|
221477
221545
|
function buildFlockSummary(plan, outcomes, status, toolCallsUsed, wallTimeHit) {
|
|
221478
|
-
const header = status === "completed" ? `
|
|
221546
|
+
const header = status === "completed" ? `Subagents finished: ${plan.summary}.` : status === "partial" ? `Subagents finished with partial results (${plan.summary}).` : status === "cancelled" ? `Subagents stopped early${wallTimeHit ? " \u2014 wall-time cap reached" : ""}.` : `Subagents failed \u2014 no worker produced a usable result.`;
|
|
221479
221547
|
const lines = outcomes.map((outcome) => {
|
|
221480
221548
|
const mark = outcome.status === "done" ? "done" : outcome.status === "failed" ? "failed" : outcome.status;
|
|
221481
|
-
const
|
|
221549
|
+
const detailText = friendlyOutcomeDetail(outcome.detail);
|
|
221550
|
+
const detail = detailText ? ` \u2014 ${clampLine(detailText, 160)}` : "";
|
|
221482
221551
|
return `- ${outcome.worker.displayName} (${outcome.worker.nickname}): ${mark}${detail}`;
|
|
221483
221552
|
});
|
|
221484
221553
|
const footer = `Used ${toolCallsUsed}/${plan.caps.maxTotalToolCalls} tool calls across ${outcomes.length} workers.`;
|
|
221485
221554
|
return [header, ...lines, footer].join("\n");
|
|
221486
221555
|
}
|
|
221556
|
+
function friendlyOutcomeDetail(detail) {
|
|
221557
|
+
const clean = clampLine(detail, 220);
|
|
221558
|
+
if (!clean) return "";
|
|
221559
|
+
if (/Reached maximum \d+ tool-call iterations/i.test(clean)) {
|
|
221560
|
+
return "finished from gathered evidence";
|
|
221561
|
+
}
|
|
221562
|
+
if (/source-read budget|read-only source|source-analysis/i.test(clean)) {
|
|
221563
|
+
return "used gathered evidence";
|
|
221564
|
+
}
|
|
221565
|
+
if (/tool-call budget exhausted|Tool budget reached/i.test(clean)) {
|
|
221566
|
+
return "tool limit reached; finished from evidence";
|
|
221567
|
+
}
|
|
221568
|
+
return clean;
|
|
221569
|
+
}
|
|
221487
221570
|
function clampLine(text, max2) {
|
|
221488
221571
|
const clean = (text ?? "").replace(/\s+/g, " ").trim();
|
|
221489
221572
|
return clean.length > max2 ? `${clean.slice(0, max2 - 1)}\u2026` : clean;
|
|
@@ -230793,6 +230876,10 @@ var init_cliStandaloneOAuth = __esm({
|
|
|
230793
230876
|
});
|
|
230794
230877
|
|
|
230795
230878
|
// features/perchTerminal/runtime/contextMeterDisplay.ts
|
|
230879
|
+
function positiveInt3(value) {
|
|
230880
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return null;
|
|
230881
|
+
return Math.floor(value);
|
|
230882
|
+
}
|
|
230796
230883
|
function formatTokenK(n) {
|
|
230797
230884
|
if (n < 1e3) return `${Math.max(0, Math.round(n))}`;
|
|
230798
230885
|
return `${(n / 1e3).toFixed(n < 1e4 ? 1 : 0)}k`;
|
|
@@ -230811,12 +230898,17 @@ function resolvePrimaryContextTokens(snapshot) {
|
|
|
230811
230898
|
if (rowTokens > 0) return rowTokens;
|
|
230812
230899
|
return 0;
|
|
230813
230900
|
}
|
|
230814
|
-
function resolveContextMeterDisplay(snapshot) {
|
|
230815
|
-
const
|
|
230901
|
+
function resolveContextMeterDisplay(snapshot, activeModel) {
|
|
230902
|
+
const activeRawLimitTokens = positiveInt3(activeModel?.contextWindow) ?? positiveInt3(activeModel?.contextWindowTokens);
|
|
230903
|
+
const activeEffectiveLimitTokens = activeRawLimitTokens ? getEffectiveContextWindow({
|
|
230904
|
+
contextWindow: activeRawLimitTokens,
|
|
230905
|
+
maxOutputTokens: activeModel?.maxOutputTokens ?? null
|
|
230906
|
+
}) : null;
|
|
230907
|
+
const limitTokens = activeRawLimitTokens ?? snapshot?.rawContextWindowTokens ?? activeEffectiveLimitTokens ?? snapshot?.effectiveLimitTokens ?? snapshot?.contextLimitTokens ?? getEffectiveContextWindow();
|
|
230816
230908
|
const threadTokens = snapshot?.threadContextTokens ?? snapshot?.totalContextTokens ?? snapshot?.latestSendTokens ?? 0;
|
|
230817
230909
|
const primaryTokens = resolvePrimaryContextTokens(snapshot);
|
|
230818
230910
|
const rawLimitTokens = Math.max(1, limitTokens);
|
|
230819
|
-
const effectiveLimitTokens = snapshot?.effectiveLimitTokens ?? snapshot?.contextLimitTokens ?? rawLimitTokens;
|
|
230911
|
+
const effectiveLimitTokens = activeEffectiveLimitTokens ?? snapshot?.effectiveLimitTokens ?? snapshot?.contextLimitTokens ?? rawLimitTokens;
|
|
230820
230912
|
const reservedOutputTokens = Math.max(0, rawLimitTokens - effectiveLimitTokens);
|
|
230821
230913
|
const committedTokens = Math.min(rawLimitTokens, primaryTokens + reservedOutputTokens);
|
|
230822
230914
|
const workerUsageTokens = snapshot?.workerUsage?.reduce((sum, worker) => sum + Math.max(0, worker.totalTokens), 0) ?? 0;
|
|
@@ -230836,6 +230928,8 @@ function resolveContextMeterDisplay(snapshot) {
|
|
|
230836
230928
|
workerTokens,
|
|
230837
230929
|
jobTotalTokens: job,
|
|
230838
230930
|
limitTokens,
|
|
230931
|
+
effectiveLimitTokens,
|
|
230932
|
+
reservedOutputTokens,
|
|
230839
230933
|
composerLabel,
|
|
230840
230934
|
hasWorkers
|
|
230841
230935
|
};
|
|
@@ -285305,7 +285399,8 @@ ${HELP_TEXT}`);
|
|
|
285305
285399
|
trimRecentMessages(nextRecentMessages);
|
|
285306
285400
|
writeCliTurnResult(result3, parsed.json, writer, {
|
|
285307
285401
|
personaId: parsed.personaId,
|
|
285308
|
-
color: shouldUseCliColor()
|
|
285402
|
+
color: shouldUseCliColor(),
|
|
285403
|
+
activeContextModel: resolveCliActiveContextModel(connection)
|
|
285309
285404
|
});
|
|
285310
285405
|
await admitCliLearningMemory(connection, {
|
|
285311
285406
|
prompt: parsed.prompt,
|
|
@@ -285658,7 +285753,8 @@ async function runReadlineInteractivePerchCli(writer, deps, options) {
|
|
|
285658
285753
|
});
|
|
285659
285754
|
writeCliTurnResult(result2, false, writer, {
|
|
285660
285755
|
personaId: state.personaId,
|
|
285661
|
-
color: shouldUseCliColor()
|
|
285756
|
+
color: shouldUseCliColor(),
|
|
285757
|
+
activeContextModel: resolveCliActiveContextModel(connection)
|
|
285662
285758
|
});
|
|
285663
285759
|
appendRecentMessage(state.recentMessages, "user", prompt);
|
|
285664
285760
|
if (result2.assistantText.trim()) {
|
|
@@ -285844,6 +285940,8 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
285844
285940
|
const toolNamesById = /* @__PURE__ */ new Map();
|
|
285845
285941
|
const flockWorkerNames = /* @__PURE__ */ new Map();
|
|
285846
285942
|
const flockLimitMeta = /* @__PURE__ */ new Map();
|
|
285943
|
+
const aggregateToolIds = /* @__PURE__ */ new Map();
|
|
285944
|
+
const aggregateToolMeta = /* @__PURE__ */ new Map();
|
|
285847
285945
|
const clientRunId = createCliRunId();
|
|
285848
285946
|
const externalController = new AbortController();
|
|
285849
285947
|
const runtimeRun = registerRuntimeRun({
|
|
@@ -285907,11 +286005,28 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
285907
286005
|
case "tool_call_started": {
|
|
285908
286006
|
const toolId = event.toolCallId ?? `${event.toolName}-${Date.now()}`;
|
|
285909
286007
|
const name = humanizeCliToolName(event.toolName);
|
|
286008
|
+
const aggregateKind = cliToolAggregateKind(event.toolName);
|
|
285910
286009
|
toolInputsById.current.set(toolId, {
|
|
285911
286010
|
toolName: event.toolName,
|
|
285912
286011
|
input: event.input ?? {}
|
|
285913
286012
|
});
|
|
285914
286013
|
toolNamesById.set(toolId, name);
|
|
286014
|
+
if (aggregateKind) {
|
|
286015
|
+
aggregateToolIds.set(toolId, aggregateKind);
|
|
286016
|
+
const meta2 = getCliToolAggregateMeta(aggregateToolMeta, aggregateKind);
|
|
286017
|
+
meta2.started += 1;
|
|
286018
|
+
meta2.pending += 1;
|
|
286019
|
+
appendCliToolAggregateDetail(meta2, event.toolName, event.input ?? {}, "started");
|
|
286020
|
+
updateToolItem(cliToolAggregateItemId(aggregateKind), {
|
|
286021
|
+
label: "tool",
|
|
286022
|
+
text: renderCliToolAggregateText(aggregateKind, meta2),
|
|
286023
|
+
tone: "muted",
|
|
286024
|
+
detailLines: meta2.detailLines,
|
|
286025
|
+
expanded: false
|
|
286026
|
+
});
|
|
286027
|
+
setWorkingText(cliToolAggregateWorkingText(aggregateKind));
|
|
286028
|
+
break;
|
|
286029
|
+
}
|
|
285915
286030
|
const fileStart = buildFileToolDisplay(event.toolName, event.input ?? {}, "running");
|
|
285916
286031
|
if (fileStart) richToolIds.current.add(toolId);
|
|
285917
286032
|
updateToolItem(toolId, {
|
|
@@ -285927,6 +286042,22 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
285927
286042
|
case "tool_call_completed": {
|
|
285928
286043
|
const toolId = event.toolCallId ?? `${event.toolName}-${Date.now()}`;
|
|
285929
286044
|
const stored = toolInputsById.current.get(toolId);
|
|
286045
|
+
const aggregateKind = aggregateToolIds.get(toolId);
|
|
286046
|
+
if (aggregateKind) {
|
|
286047
|
+
const meta2 = getCliToolAggregateMeta(aggregateToolMeta, aggregateKind);
|
|
286048
|
+
meta2.pending = Math.max(0, meta2.pending - 1);
|
|
286049
|
+
meta2.done += 1;
|
|
286050
|
+
appendCliToolAggregateDetail(meta2, event.toolName, stored?.input ?? {}, "done");
|
|
286051
|
+
updateToolItem(cliToolAggregateItemId(aggregateKind), {
|
|
286052
|
+
label: "tool",
|
|
286053
|
+
text: renderCliToolAggregateText(aggregateKind, meta2),
|
|
286054
|
+
tone: meta2.failed > 0 ? "danger" : "success",
|
|
286055
|
+
detailLines: meta2.detailLines,
|
|
286056
|
+
expanded: false
|
|
286057
|
+
});
|
|
286058
|
+
setWorkingText("thinking");
|
|
286059
|
+
break;
|
|
286060
|
+
}
|
|
285930
286061
|
const fileDone = buildFileToolDisplay(event.toolName, stored?.input ?? {}, "done");
|
|
285931
286062
|
if (fileDone) {
|
|
285932
286063
|
richToolIds.current.add(toolId);
|
|
@@ -285956,6 +286087,22 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
285956
286087
|
case "tool_call_failed": {
|
|
285957
286088
|
const toolId = event.toolCallId ?? `${event.toolName}-${Date.now()}`;
|
|
285958
286089
|
const name = toolNamesById.get(toolId) ?? humanizeCliToolName(event.toolName);
|
|
286090
|
+
const stored = toolInputsById.current.get(toolId);
|
|
286091
|
+
const aggregateKind = aggregateToolIds.get(toolId);
|
|
286092
|
+
if (aggregateKind) {
|
|
286093
|
+
const meta2 = getCliToolAggregateMeta(aggregateToolMeta, aggregateKind);
|
|
286094
|
+
meta2.pending = Math.max(0, meta2.pending - 1);
|
|
286095
|
+
meta2.failed += 1;
|
|
286096
|
+
appendCliToolAggregateDetail(meta2, event.toolName, stored?.input ?? {}, "failed", event.error);
|
|
286097
|
+
updateToolItem(cliToolAggregateItemId(aggregateKind), {
|
|
286098
|
+
label: "tool",
|
|
286099
|
+
text: renderCliToolAggregateText(aggregateKind, meta2),
|
|
286100
|
+
tone: "danger",
|
|
286101
|
+
detailLines: meta2.detailLines,
|
|
286102
|
+
expanded: false
|
|
286103
|
+
});
|
|
286104
|
+
break;
|
|
286105
|
+
}
|
|
285959
286106
|
updateToolItem(toolId, {
|
|
285960
286107
|
label: "need",
|
|
285961
286108
|
text: `${name} \xB7 ${event.error ?? "needs attention"}`,
|
|
@@ -286515,7 +286662,10 @@ async function runInteractiveSlashCommand(input) {
|
|
|
286515
286662
|
`);
|
|
286516
286663
|
return "continue";
|
|
286517
286664
|
case "context":
|
|
286518
|
-
input.writer.stdout(renderCliContextDetails(
|
|
286665
|
+
input.writer.stdout(renderCliContextDetails(
|
|
286666
|
+
input.state.contextSnapshot,
|
|
286667
|
+
resolveCliActiveContextModel(input.getConnection?.() ?? null)
|
|
286668
|
+
));
|
|
286519
286669
|
return "continue";
|
|
286520
286670
|
case "memoryAudit": {
|
|
286521
286671
|
const audit = explainLearningAdmission({
|
|
@@ -286685,6 +286835,7 @@ function renderInteractiveStatus(state, connection, session, workspaceId) {
|
|
|
286685
286835
|
const signedIn = session === void 0 ? isCliModelConnectionReady(connection) : isStoredCliAuthSessionUsable(session);
|
|
286686
286836
|
const connectionStatus = isCliModelConnectionReady(connection) ? "connected" : "locked \xB7 run /login";
|
|
286687
286837
|
const color = shouldUseCliColor();
|
|
286838
|
+
const activeContextModel = resolveCliActiveContextModel(connection);
|
|
286688
286839
|
const lines = [
|
|
286689
286840
|
["version", CLI_PACKAGE_VERSION],
|
|
286690
286841
|
["cwd", state.cwd],
|
|
@@ -286697,7 +286848,7 @@ function renderInteractiveStatus(state, connection, session, workspaceId) {
|
|
|
286697
286848
|
["mode", state.chatMode],
|
|
286698
286849
|
["persona", state.personaId],
|
|
286699
286850
|
["thread", state.threadId],
|
|
286700
|
-
["context", renderCliContextMeter(state.contextSnapshot)],
|
|
286851
|
+
["context", renderCliContextMeter(state.contextSnapshot, activeContextModel)],
|
|
286701
286852
|
["saved", state.persistedThreadUpdatedAt ? new Date(state.persistedThreadUpdatedAt).toLocaleString() : "(new thread)"],
|
|
286702
286853
|
["local-tools", state.cliLocalTools ? "on" : "off"]
|
|
286703
286854
|
];
|
|
@@ -287045,21 +287196,21 @@ function isPermanentMemoryLike2(value) {
|
|
|
287045
287196
|
const memory = value;
|
|
287046
287197
|
return typeof memory.id === "string" && typeof memory.title === "string" && typeof memory.body === "string";
|
|
287047
287198
|
}
|
|
287048
|
-
function renderCliContextMeter(snapshot) {
|
|
287199
|
+
function renderCliContextMeter(snapshot, activeModel) {
|
|
287049
287200
|
if (!snapshot) return "Context";
|
|
287050
|
-
const meter = resolveContextMeterDisplay(snapshot);
|
|
287201
|
+
const meter = resolveContextMeterDisplay(snapshot, activeModel);
|
|
287051
287202
|
const percent2 = snapshot.contextPercentage ?? Math.round(meter.committedTokens / Math.max(1, meter.limitTokens) * 100);
|
|
287052
287203
|
const parts = [`${meter.composerLabel}`, `${Math.max(0, Math.min(100, percent2))}%`];
|
|
287053
287204
|
const compacted = snapshot.compactedRowCount ?? 0;
|
|
287054
287205
|
if (snapshot.compacted || compacted > 0) parts.push(`compacted ${compacted}`);
|
|
287055
287206
|
return parts.join(" \xB7 ");
|
|
287056
287207
|
}
|
|
287057
|
-
function renderCliContextDetails(snapshot) {
|
|
287208
|
+
function renderCliContextDetails(snapshot, activeModel) {
|
|
287058
287209
|
if (!snapshot) return "context no meter yet\n";
|
|
287059
|
-
const meter = resolveContextMeterDisplay(snapshot);
|
|
287210
|
+
const meter = resolveContextMeterDisplay(snapshot, activeModel);
|
|
287060
287211
|
const percent2 = snapshot.contextPercentage ?? Math.round(meter.committedTokens / Math.max(1, meter.limitTokens) * 100);
|
|
287061
287212
|
const lines = [
|
|
287062
|
-
["context", renderCliContextMeter(snapshot)],
|
|
287213
|
+
["context", renderCliContextMeter(snapshot, activeModel)],
|
|
287063
287214
|
["thread", `${formatCliTokenCount(meter.threadTokens)} tokens`],
|
|
287064
287215
|
["limit", `${formatCliTokenCount(meter.limitTokens)} tokens`],
|
|
287065
287216
|
["fill", `${Math.max(0, Math.min(100, percent2))}%`],
|
|
@@ -287079,6 +287230,10 @@ function humanizeCliToolName(name) {
|
|
|
287079
287230
|
function isCliModelConnectionReady(connection) {
|
|
287080
287231
|
return Boolean(connection?.authenticated && connection.founderModelSelection);
|
|
287081
287232
|
}
|
|
287233
|
+
function resolveCliActiveContextModel(connection) {
|
|
287234
|
+
if (!connection?.founderModelSelection) return null;
|
|
287235
|
+
return resolveModelForLane(connection.founderModelSelection, "chat");
|
|
287236
|
+
}
|
|
287082
287237
|
function renderCliAuthSummary(connection) {
|
|
287083
287238
|
if (isCliModelConnectionReady(connection)) {
|
|
287084
287239
|
return `signed in${connection.email ? ` as ${connection.email}` : ""}`;
|
|
@@ -287415,6 +287570,67 @@ function buildFileToolDisplay(toolName, input, phase, summary) {
|
|
|
287415
287570
|
]
|
|
287416
287571
|
};
|
|
287417
287572
|
}
|
|
287573
|
+
function cliToolAggregateKind(toolName) {
|
|
287574
|
+
const normalized = toolName.toLowerCase();
|
|
287575
|
+
if (normalized === "readlocalfile" || normalized === "readlocalsourcefile") return "read";
|
|
287576
|
+
if (normalized === "glob" || normalized === "grep" || normalized === "listlocalsources" || normalized === "statpath" || normalized === "validateworkspaceroot") return "search";
|
|
287577
|
+
return null;
|
|
287578
|
+
}
|
|
287579
|
+
function getCliToolAggregateMeta(store, kind) {
|
|
287580
|
+
const existing = store.get(kind);
|
|
287581
|
+
if (existing) return existing;
|
|
287582
|
+
const created = {
|
|
287583
|
+
started: 0,
|
|
287584
|
+
done: 0,
|
|
287585
|
+
failed: 0,
|
|
287586
|
+
pending: 0,
|
|
287587
|
+
detailLines: []
|
|
287588
|
+
};
|
|
287589
|
+
store.set(kind, created);
|
|
287590
|
+
return created;
|
|
287591
|
+
}
|
|
287592
|
+
function cliToolAggregateItemId(kind) {
|
|
287593
|
+
return `tool-aggregate-${kind}`;
|
|
287594
|
+
}
|
|
287595
|
+
function cliToolAggregateWorkingText(kind) {
|
|
287596
|
+
return kind === "read" ? "reading files" : "searching";
|
|
287597
|
+
}
|
|
287598
|
+
function renderCliToolAggregateText(kind, meta) {
|
|
287599
|
+
const completed = meta.done + meta.failed;
|
|
287600
|
+
const count = Math.max(completed, meta.started);
|
|
287601
|
+
const noun = kind === "read" ? `file${count === 1 ? "" : "s"}` : `path${count === 1 ? "" : "s"}`;
|
|
287602
|
+
const verb = kind === "read" ? "read" : "searched";
|
|
287603
|
+
const status = meta.pending > 0 ? `${meta.pending} running` : "done";
|
|
287604
|
+
const failed = meta.failed > 0 ? ` \xB7 ${meta.failed} failed` : "";
|
|
287605
|
+
return `${verb} ${count} ${noun} \xB7 ${status}${failed} \xB7 ctrl-e`;
|
|
287606
|
+
}
|
|
287607
|
+
function appendCliToolAggregateDetail(meta, toolName, input, status, error) {
|
|
287608
|
+
const label = humanizeCliToolName(toolName);
|
|
287609
|
+
const target = describeCliToolAggregateInput(toolName, input);
|
|
287610
|
+
const tail = error ? ` \xB7 ${error}` : "";
|
|
287611
|
+
meta.detailLines.push({
|
|
287612
|
+
tone: "meta",
|
|
287613
|
+
text: `${label}${target ? ` \xB7 ${target}` : ""} \xB7 ${status}${tail}`
|
|
287614
|
+
});
|
|
287615
|
+
if (meta.detailLines.length > INK_DETAIL_LINE_LIMIT) {
|
|
287616
|
+
meta.detailLines = meta.detailLines.slice(-INK_DETAIL_LINE_LIMIT);
|
|
287617
|
+
}
|
|
287618
|
+
}
|
|
287619
|
+
function describeCliToolAggregateInput(toolName, input) {
|
|
287620
|
+
const normalized = toolName.toLowerCase();
|
|
287621
|
+
if (normalized === "glob") {
|
|
287622
|
+
const pattern = stringValue8(input.pattern) ?? stringValue8(input.glob) ?? "*";
|
|
287623
|
+
const base = stringValue8(input.path) ?? stringValue8(input.cwd) ?? ".";
|
|
287624
|
+
return `${pattern} in ${shortFilePath(base)}`;
|
|
287625
|
+
}
|
|
287626
|
+
if (normalized === "grep") {
|
|
287627
|
+
const pattern = stringValue8(input.pattern) ?? stringValue8(input.query) ?? "";
|
|
287628
|
+
const base = stringValue8(input.path) ?? stringValue8(input.cwd) ?? ".";
|
|
287629
|
+
return `${pattern || "pattern"} in ${shortFilePath(base)}`;
|
|
287630
|
+
}
|
|
287631
|
+
const filePath = stringValue8(input.path) ?? stringValue8(input.filePath) ?? stringValue8(input.localSourceId) ?? stringValue8(input.cwd);
|
|
287632
|
+
return filePath ? shortFilePath(filePath) : null;
|
|
287633
|
+
}
|
|
287418
287634
|
function describeChangeSummary(summary) {
|
|
287419
287635
|
const kind = summary.changeKind ?? "changed";
|
|
287420
287636
|
const added = summary.linesAdded ?? 0;
|
|
@@ -287657,7 +287873,7 @@ function writeCliTurnResult(result2, json, writer, options = {}) {
|
|
|
287657
287873
|
color: options.color,
|
|
287658
287874
|
streamLabels: true
|
|
287659
287875
|
});
|
|
287660
|
-
const contextLine = `${paint("context".padEnd(12), "muted", options.color === true)} ${renderCliContextMeter(result2.contextSnapshot)}
|
|
287876
|
+
const contextLine = `${paint("context".padEnd(12), "muted", options.color === true)} ${renderCliContextMeter(result2.contextSnapshot, options.activeContextModel)}
|
|
287661
287877
|
`;
|
|
287662
287878
|
writer.stdout(`${rendered}${rendered.endsWith("\n") ? "" : "\n"}${contextLine}`);
|
|
287663
287879
|
}
|
|
@@ -287813,6 +288029,7 @@ var init_perch_cli = __esm({
|
|
|
287813
288029
|
init_cliAuthSession();
|
|
287814
288030
|
init_cliStandaloneOAuth();
|
|
287815
288031
|
init_contextMeterDisplay();
|
|
288032
|
+
init_modelRegistry();
|
|
287816
288033
|
init_threadSession();
|
|
287817
288034
|
init_runRegistry();
|
|
287818
288035
|
init_learningMemory();
|