perchai-cli 2.4.25 → 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 +253 -31
- package/package.json +1 -1
package/dist/perch.mjs
CHANGED
|
@@ -75918,7 +75918,6 @@ function isTurnAbortedError(error) {
|
|
|
75918
75918
|
var TURN_STOPPED_BY_USER_MESSAGE;
|
|
75919
75919
|
var init_turnAbort = __esm({
|
|
75920
75920
|
"features/perchTerminal/runtime/turnAbort.ts"() {
|
|
75921
|
-
"use strict";
|
|
75922
75921
|
TURN_STOPPED_BY_USER_MESSAGE = "Turn stopped by user.";
|
|
75923
75922
|
}
|
|
75924
75923
|
});
|
|
@@ -76219,6 +76218,7 @@ function getToolDisplayName(toolName) {
|
|
|
76219
76218
|
var NON_MODULE_TOOL_OWNERS, TOOL_RISK, TOOL_DISPLAY_NAMES;
|
|
76220
76219
|
var init_catalog = __esm({
|
|
76221
76220
|
"features/perchTerminal/runtime/toolSystem/catalog.ts"() {
|
|
76221
|
+
"use strict";
|
|
76222
76222
|
init_toolNames();
|
|
76223
76223
|
NON_MODULE_TOOL_OWNERS = {
|
|
76224
76224
|
[TOOL_NAMES.listSources]: "lane",
|
|
@@ -76922,6 +76922,8 @@ function buildTranscriptSegments(state) {
|
|
|
76922
76922
|
const terminalSegmentIdx = /* @__PURE__ */ new Map();
|
|
76923
76923
|
const workerRunIdx = /* @__PURE__ */ new Map();
|
|
76924
76924
|
const flockRunIdx = /* @__PURE__ */ new Map();
|
|
76925
|
+
const flockIdByWorkerId = /* @__PURE__ */ new Map();
|
|
76926
|
+
const flockWorkerIdByToolCallId = /* @__PURE__ */ new Map();
|
|
76925
76927
|
const diagnosticIdxByKey = /* @__PURE__ */ new Map();
|
|
76926
76928
|
const capabilityIdx = /* @__PURE__ */ new Map();
|
|
76927
76929
|
const liveCardIdx = /* @__PURE__ */ new Map();
|
|
@@ -76945,6 +76947,32 @@ function buildTranscriptSegments(state) {
|
|
|
76945
76947
|
if (runId) sandboxRunIdx.set(runId, idx);
|
|
76946
76948
|
if (toolCallId) sandboxRunIdx.set(toolCallId, idx);
|
|
76947
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
|
+
}
|
|
76948
76976
|
function flushReasoning() {
|
|
76949
76977
|
if (!pendingReasoning) return;
|
|
76950
76978
|
segments.push({ kind: "reasoning", text: pendingReasoning, seq: seq++, timestamp: pendingReasoningTs });
|
|
@@ -77038,6 +77066,15 @@ function buildTranscriptSegments(state) {
|
|
|
77038
77066
|
ev.toolCallId ? [ev.toolCallId] : [],
|
|
77039
77067
|
ev.ts
|
|
77040
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
|
+
}
|
|
77041
77078
|
if (ev.workerId) {
|
|
77042
77079
|
const idx = segments.length;
|
|
77043
77080
|
segments.push({
|
|
@@ -77092,6 +77129,7 @@ function buildTranscriptSegments(state) {
|
|
|
77092
77129
|
}
|
|
77093
77130
|
case "tool_call_completed": {
|
|
77094
77131
|
flushReasoning();
|
|
77132
|
+
if (isFlockOwnedToolEvent(ev)) break;
|
|
77095
77133
|
const id = ev.toolCallId ?? ev.toolName;
|
|
77096
77134
|
const idx = toolCallIdx.get(id);
|
|
77097
77135
|
if (idx !== void 0) {
|
|
@@ -77108,6 +77146,7 @@ function buildTranscriptSegments(state) {
|
|
|
77108
77146
|
}
|
|
77109
77147
|
case "tool_result": {
|
|
77110
77148
|
flushReasoning();
|
|
77149
|
+
if (isFlockOwnedToolEvent(ev)) break;
|
|
77111
77150
|
const id = ev.toolCallId ?? ev.toolName;
|
|
77112
77151
|
if (ev.toolName === "run_sandbox_code") {
|
|
77113
77152
|
updateSandboxRun(ev.toolCallId, null, (seg) => ({ ...seg, resultText: ev.text }));
|
|
@@ -77136,6 +77175,7 @@ function buildTranscriptSegments(state) {
|
|
|
77136
77175
|
case "tool_output_delta": {
|
|
77137
77176
|
flushReasoning();
|
|
77138
77177
|
if (!ev.text) break;
|
|
77178
|
+
if (isFlockOwnedToolEvent(ev)) break;
|
|
77139
77179
|
const id = ev.toolCallId ?? ev.toolName;
|
|
77140
77180
|
if (ev.toolName === "run_sandbox_code") {
|
|
77141
77181
|
updateSandboxRun(ev.toolCallId, null, (seg) => ({ ...seg, resultText: `${seg.resultText ?? ""}${ev.text}` }));
|
|
@@ -77544,6 +77584,7 @@ function buildTranscriptSegments(state) {
|
|
|
77544
77584
|
case "diagnostic": {
|
|
77545
77585
|
flushReasoning();
|
|
77546
77586
|
if (!ev.message.trim()) break;
|
|
77587
|
+
if (isQuietFlockDiagnostic(ev)) break;
|
|
77547
77588
|
if (ev.code === "tool_call_budget_exhausted") {
|
|
77548
77589
|
let attributed = false;
|
|
77549
77590
|
if (ev.workerId) {
|
|
@@ -77695,6 +77736,7 @@ function buildTranscriptSegments(state) {
|
|
|
77695
77736
|
}
|
|
77696
77737
|
case "tool_call_failed": {
|
|
77697
77738
|
flushReasoning();
|
|
77739
|
+
if (isFlockOwnedToolEvent(ev)) break;
|
|
77698
77740
|
const id = ev.toolCallId ?? ev.toolName;
|
|
77699
77741
|
const idx = toolCallIdx.get(id);
|
|
77700
77742
|
if (idx !== void 0) {
|
|
@@ -77809,6 +77851,12 @@ function buildTranscriptSegments(state) {
|
|
|
77809
77851
|
}
|
|
77810
77852
|
case "worker_run_started": {
|
|
77811
77853
|
flushReasoning();
|
|
77854
|
+
if (updateFlockWorkerByWorkerId(ev.workerId, (worker) => ({
|
|
77855
|
+
...worker,
|
|
77856
|
+
status: worker.status === "queued" ? "running" : worker.status
|
|
77857
|
+
}))) {
|
|
77858
|
+
break;
|
|
77859
|
+
}
|
|
77812
77860
|
const idx = segments.length;
|
|
77813
77861
|
segments.push({
|
|
77814
77862
|
kind: "worker_run",
|
|
@@ -77825,6 +77873,12 @@ function buildTranscriptSegments(state) {
|
|
|
77825
77873
|
}
|
|
77826
77874
|
case "worker_run_completed": {
|
|
77827
77875
|
flushReasoning();
|
|
77876
|
+
if (updateFlockWorkerByWorkerId(ev.workerId, (worker) => ({
|
|
77877
|
+
...worker,
|
|
77878
|
+
status: ev.ok ? "done" : "failed"
|
|
77879
|
+
}))) {
|
|
77880
|
+
break;
|
|
77881
|
+
}
|
|
77828
77882
|
const runIdx = workerRunIdx.get(ev.workerId);
|
|
77829
77883
|
if (runIdx !== void 0) {
|
|
77830
77884
|
const seg = segments[runIdx];
|
|
@@ -77877,6 +77931,11 @@ function buildTranscriptSegments(state) {
|
|
|
77877
77931
|
if (idx === void 0) break;
|
|
77878
77932
|
const seg = segments[idx];
|
|
77879
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
|
+
}
|
|
77880
77939
|
segments[idx] = ev.accepted ? {
|
|
77881
77940
|
...seg,
|
|
77882
77941
|
status: "running",
|
|
@@ -77898,7 +77957,11 @@ function buildTranscriptSegments(state) {
|
|
|
77898
77957
|
if (seg?.kind !== "flock_run") break;
|
|
77899
77958
|
const known = seg.workers.some((worker) => worker.flockWorkerId === ev.flockWorkerId);
|
|
77900
77959
|
const workers = known ? seg.workers.map(
|
|
77901
|
-
(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
|
|
77902
77965
|
) : [
|
|
77903
77966
|
...seg.workers,
|
|
77904
77967
|
{
|
|
@@ -77906,7 +77969,8 @@ function buildTranscriptSegments(state) {
|
|
|
77906
77969
|
workerId: ev.workerId,
|
|
77907
77970
|
displayName: ev.displayName,
|
|
77908
77971
|
nickname: ev.nickname,
|
|
77909
|
-
status: ev.status
|
|
77972
|
+
status: ev.status,
|
|
77973
|
+
note: ev.detail
|
|
77910
77974
|
}
|
|
77911
77975
|
];
|
|
77912
77976
|
segments[idx] = { ...seg, workers };
|
|
@@ -78309,9 +78373,13 @@ function segmentToCompact(seg) {
|
|
|
78309
78373
|
summary: seg.summary?.slice(0, 300),
|
|
78310
78374
|
flockWorkers: seg.workers.map((worker) => ({
|
|
78311
78375
|
flockWorkerId: worker.flockWorkerId,
|
|
78376
|
+
workerId: worker.workerId,
|
|
78312
78377
|
displayName: worker.displayName,
|
|
78313
78378
|
nickname: worker.nickname,
|
|
78314
|
-
status: worker.status
|
|
78379
|
+
status: worker.status,
|
|
78380
|
+
note: worker.note,
|
|
78381
|
+
toolCalls: worker.toolCalls,
|
|
78382
|
+
lastToolName: worker.lastToolName
|
|
78315
78383
|
}))
|
|
78316
78384
|
};
|
|
78317
78385
|
case "worker_tool_call":
|
|
@@ -90909,7 +90977,6 @@ Final answers lead with findings, name artifacts or delivery status, and give on
|
|
|
90909
90977
|
var MARKET_DESK_TOOL_NAMES;
|
|
90910
90978
|
var init_marketDeskAccess = __esm({
|
|
90911
90979
|
"features/perchTerminal/runtime/marketDesk/marketDeskAccess.ts"() {
|
|
90912
|
-
"use strict";
|
|
90913
90980
|
init_toolNames();
|
|
90914
90981
|
MARKET_DESK_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
90915
90982
|
TOOL_NAMES.getMarketSignal,
|
|
@@ -200071,6 +200138,7 @@ function recordDispatchBatchResult(tasks, result2, ctx, opts = {}) {
|
|
|
200071
200138
|
var lifecycleByRun, MAX_LIFECYCLE_RUNS;
|
|
200072
200139
|
var init_workerLifecycle = __esm({
|
|
200073
200140
|
"features/perchTerminal/runtime/workers/workerLifecycle.ts"() {
|
|
200141
|
+
"use strict";
|
|
200074
200142
|
init_workerManifest();
|
|
200075
200143
|
lifecycleByRun = /* @__PURE__ */ new Map();
|
|
200076
200144
|
MAX_LIFECYCLE_RUNS = 200;
|
|
@@ -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
|
};
|
|
@@ -285205,12 +285299,12 @@ var init_build2 = __esm({
|
|
|
285205
285299
|
// scripts/perch-cli.ts
|
|
285206
285300
|
var perch_cli_exports = {};
|
|
285207
285301
|
__export(perch_cli_exports, {
|
|
285208
|
-
|
|
285302
|
+
FLOCK_NICKNAME_ACCENTS: () => FLOCK_NICKNAME_ACCENTS,
|
|
285209
285303
|
HELP_TEXT: () => HELP_TEXT,
|
|
285210
285304
|
INTERACTIVE_HELP_TEXT: () => INTERACTIVE_HELP_TEXT,
|
|
285211
285305
|
PERCH_SPLASH_COMMANDS: () => PERCH_SPLASH_COMMANDS,
|
|
285212
285306
|
flockEventToCliRow: () => flockEventToCliRow,
|
|
285213
|
-
|
|
285307
|
+
flockNicknameAccentColor: () => flockNicknameAccentColor,
|
|
285214
285308
|
parseInteractiveSlashCommand: () => parseInteractiveSlashCommand,
|
|
285215
285309
|
parsePerchCli: () => parsePerchCli,
|
|
285216
285310
|
runPerchCli: () => runPerchCli
|
|
@@ -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"}`,
|
|
@@ -286334,8 +286481,12 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
286334
286481
|
if (dotParts.length < 2 && !limitMatch) {
|
|
286335
286482
|
return renderTranscriptRow(key, "flock", line, tone, showLabel);
|
|
286336
286483
|
}
|
|
286337
|
-
|
|
286338
|
-
|
|
286484
|
+
if (limitMatch) {
|
|
286485
|
+
return renderTranscriptRow(key, "flock", line, tone, showLabel);
|
|
286486
|
+
}
|
|
286487
|
+
const name = dotParts[0];
|
|
286488
|
+
const nickname = dotParts[1] ?? "";
|
|
286489
|
+
const restText = dotParts.length > 2 ? ` \xB7 ${dotParts.slice(2).join(" \xB7 ")}` : "";
|
|
286339
286490
|
return React11.createElement(
|
|
286340
286491
|
Ink2.Box,
|
|
286341
286492
|
{ key },
|
|
@@ -286354,7 +286505,8 @@ async function runInkInteractivePerchCli(writer, deps, options) {
|
|
|
286354
286505
|
React11.createElement(
|
|
286355
286506
|
Ink2.Text,
|
|
286356
286507
|
null,
|
|
286357
|
-
React11.createElement(Ink2.Text, { color:
|
|
286508
|
+
React11.createElement(Ink2.Text, { color: bodyColorForInkTone(tone) }, `${name} \xB7 `),
|
|
286509
|
+
React11.createElement(Ink2.Text, { color: flockNicknameAccentColor(nickname), bold: true }, nickname),
|
|
286358
286510
|
React11.createElement(Ink2.Text, { color: bodyColorForInkTone(tone) }, restText)
|
|
286359
286511
|
)
|
|
286360
286512
|
)
|
|
@@ -286510,7 +286662,10 @@ async function runInteractiveSlashCommand(input) {
|
|
|
286510
286662
|
`);
|
|
286511
286663
|
return "continue";
|
|
286512
286664
|
case "context":
|
|
286513
|
-
input.writer.stdout(renderCliContextDetails(
|
|
286665
|
+
input.writer.stdout(renderCliContextDetails(
|
|
286666
|
+
input.state.contextSnapshot,
|
|
286667
|
+
resolveCliActiveContextModel(input.getConnection?.() ?? null)
|
|
286668
|
+
));
|
|
286514
286669
|
return "continue";
|
|
286515
286670
|
case "memoryAudit": {
|
|
286516
286671
|
const audit = explainLearningAdmission({
|
|
@@ -286680,6 +286835,7 @@ function renderInteractiveStatus(state, connection, session, workspaceId) {
|
|
|
286680
286835
|
const signedIn = session === void 0 ? isCliModelConnectionReady(connection) : isStoredCliAuthSessionUsable(session);
|
|
286681
286836
|
const connectionStatus = isCliModelConnectionReady(connection) ? "connected" : "locked \xB7 run /login";
|
|
286682
286837
|
const color = shouldUseCliColor();
|
|
286838
|
+
const activeContextModel = resolveCliActiveContextModel(connection);
|
|
286683
286839
|
const lines = [
|
|
286684
286840
|
["version", CLI_PACKAGE_VERSION],
|
|
286685
286841
|
["cwd", state.cwd],
|
|
@@ -286692,7 +286848,7 @@ function renderInteractiveStatus(state, connection, session, workspaceId) {
|
|
|
286692
286848
|
["mode", state.chatMode],
|
|
286693
286849
|
["persona", state.personaId],
|
|
286694
286850
|
["thread", state.threadId],
|
|
286695
|
-
["context", renderCliContextMeter(state.contextSnapshot)],
|
|
286851
|
+
["context", renderCliContextMeter(state.contextSnapshot, activeContextModel)],
|
|
286696
286852
|
["saved", state.persistedThreadUpdatedAt ? new Date(state.persistedThreadUpdatedAt).toLocaleString() : "(new thread)"],
|
|
286697
286853
|
["local-tools", state.cliLocalTools ? "on" : "off"]
|
|
286698
286854
|
];
|
|
@@ -287040,21 +287196,21 @@ function isPermanentMemoryLike2(value) {
|
|
|
287040
287196
|
const memory = value;
|
|
287041
287197
|
return typeof memory.id === "string" && typeof memory.title === "string" && typeof memory.body === "string";
|
|
287042
287198
|
}
|
|
287043
|
-
function renderCliContextMeter(snapshot) {
|
|
287199
|
+
function renderCliContextMeter(snapshot, activeModel) {
|
|
287044
287200
|
if (!snapshot) return "Context";
|
|
287045
|
-
const meter = resolveContextMeterDisplay(snapshot);
|
|
287201
|
+
const meter = resolveContextMeterDisplay(snapshot, activeModel);
|
|
287046
287202
|
const percent2 = snapshot.contextPercentage ?? Math.round(meter.committedTokens / Math.max(1, meter.limitTokens) * 100);
|
|
287047
287203
|
const parts = [`${meter.composerLabel}`, `${Math.max(0, Math.min(100, percent2))}%`];
|
|
287048
287204
|
const compacted = snapshot.compactedRowCount ?? 0;
|
|
287049
287205
|
if (snapshot.compacted || compacted > 0) parts.push(`compacted ${compacted}`);
|
|
287050
287206
|
return parts.join(" \xB7 ");
|
|
287051
287207
|
}
|
|
287052
|
-
function renderCliContextDetails(snapshot) {
|
|
287208
|
+
function renderCliContextDetails(snapshot, activeModel) {
|
|
287053
287209
|
if (!snapshot) return "context no meter yet\n";
|
|
287054
|
-
const meter = resolveContextMeterDisplay(snapshot);
|
|
287210
|
+
const meter = resolveContextMeterDisplay(snapshot, activeModel);
|
|
287055
287211
|
const percent2 = snapshot.contextPercentage ?? Math.round(meter.committedTokens / Math.max(1, meter.limitTokens) * 100);
|
|
287056
287212
|
const lines = [
|
|
287057
|
-
["context", renderCliContextMeter(snapshot)],
|
|
287213
|
+
["context", renderCliContextMeter(snapshot, activeModel)],
|
|
287058
287214
|
["thread", `${formatCliTokenCount(meter.threadTokens)} tokens`],
|
|
287059
287215
|
["limit", `${formatCliTokenCount(meter.limitTokens)} tokens`],
|
|
287060
287216
|
["fill", `${Math.max(0, Math.min(100, percent2))}%`],
|
|
@@ -287074,6 +287230,10 @@ function humanizeCliToolName(name) {
|
|
|
287074
287230
|
function isCliModelConnectionReady(connection) {
|
|
287075
287231
|
return Boolean(connection?.authenticated && connection.founderModelSelection);
|
|
287076
287232
|
}
|
|
287233
|
+
function resolveCliActiveContextModel(connection) {
|
|
287234
|
+
if (!connection?.founderModelSelection) return null;
|
|
287235
|
+
return resolveModelForLane(connection.founderModelSelection, "chat");
|
|
287236
|
+
}
|
|
287077
287237
|
function renderCliAuthSummary(connection) {
|
|
287078
287238
|
if (isCliModelConnectionReady(connection)) {
|
|
287079
287239
|
return `signed in${connection.email ? ` as ${connection.email}` : ""}`;
|
|
@@ -287109,12 +287269,12 @@ function colorForInkTone(tone) {
|
|
|
287109
287269
|
return CLI_BRAND.patina;
|
|
287110
287270
|
}
|
|
287111
287271
|
}
|
|
287112
|
-
function
|
|
287272
|
+
function flockNicknameAccentColor(name) {
|
|
287113
287273
|
let hash = 0;
|
|
287114
287274
|
for (let i = 0; i < name.length; i++) {
|
|
287115
287275
|
hash = hash * 31 + name.charCodeAt(i) >>> 0;
|
|
287116
287276
|
}
|
|
287117
|
-
return
|
|
287277
|
+
return FLOCK_NICKNAME_ACCENTS[hash % FLOCK_NICKNAME_ACCENTS.length];
|
|
287118
287278
|
}
|
|
287119
287279
|
function bodyColorForInkTone(tone) {
|
|
287120
287280
|
switch (tone) {
|
|
@@ -287410,6 +287570,67 @@ function buildFileToolDisplay(toolName, input, phase, summary) {
|
|
|
287410
287570
|
]
|
|
287411
287571
|
};
|
|
287412
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
|
+
}
|
|
287413
287634
|
function describeChangeSummary(summary) {
|
|
287414
287635
|
const kind = summary.changeKind ?? "changed";
|
|
287415
287636
|
const added = summary.linesAdded ?? 0;
|
|
@@ -287652,7 +287873,7 @@ function writeCliTurnResult(result2, json, writer, options = {}) {
|
|
|
287652
287873
|
color: options.color,
|
|
287653
287874
|
streamLabels: true
|
|
287654
287875
|
});
|
|
287655
|
-
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)}
|
|
287656
287877
|
`;
|
|
287657
287878
|
writer.stdout(`${rendered}${rendered.endsWith("\n") ? "" : "\n"}${contextLine}`);
|
|
287658
287879
|
}
|
|
@@ -287798,7 +288019,7 @@ function defaultWriter() {
|
|
|
287798
288019
|
stderr: (text) => process.stderr.write(text)
|
|
287799
288020
|
};
|
|
287800
288021
|
}
|
|
287801
|
-
var execFileAsync3, DEFAULT_CLI_LOGIN_APP_URL, CLI_PACKAGE_VERSION, CLI_BRAND, ANSI2, HELP_TEXT, INTERACTIVE_HELP_TEXT, FLOCK_STATUS_LABELS, INK_LABEL_WIDTH, INK_ROW_LIMIT, INK_DETAIL_LINE_LIMIT, INK_DIVIDER, PERCH_MOTION_FRAMES, PERCH_SPLASH_WIDTH, PERCH_SPLASH_SCENE, PERCH_SPLASH_COMMANDS,
|
|
288022
|
+
var execFileAsync3, DEFAULT_CLI_LOGIN_APP_URL, CLI_PACKAGE_VERSION, CLI_BRAND, ANSI2, HELP_TEXT, INTERACTIVE_HELP_TEXT, FLOCK_STATUS_LABELS, INK_LABEL_WIDTH, INK_ROW_LIMIT, INK_DETAIL_LINE_LIMIT, INK_DIVIDER, PERCH_MOTION_FRAMES, PERCH_SPLASH_WIDTH, PERCH_SPLASH_SCENE, PERCH_SPLASH_COMMANDS, FLOCK_NICKNAME_ACCENTS;
|
|
287802
288023
|
var init_perch_cli = __esm({
|
|
287803
288024
|
"scripts/perch-cli.ts"() {
|
|
287804
288025
|
"use strict";
|
|
@@ -287808,6 +288029,7 @@ var init_perch_cli = __esm({
|
|
|
287808
288029
|
init_cliAuthSession();
|
|
287809
288030
|
init_cliStandaloneOAuth();
|
|
287810
288031
|
init_contextMeterDisplay();
|
|
288032
|
+
init_modelRegistry();
|
|
287811
288033
|
init_threadSession();
|
|
287812
288034
|
init_runRegistry();
|
|
287813
288035
|
init_learningMemory();
|
|
@@ -287934,7 +288156,7 @@ Commands:
|
|
|
287934
288156
|
["/permission", "change autonomy for the next turns"],
|
|
287935
288157
|
["/login", "connect your Perch account"]
|
|
287936
288158
|
];
|
|
287937
|
-
|
|
288159
|
+
FLOCK_NICKNAME_ACCENTS = [
|
|
287938
288160
|
CLI_BRAND.patinaActive,
|
|
287939
288161
|
CLI_BRAND.bronze,
|
|
287940
288162
|
CLI_BRAND.bronzeGlint
|