perchai-cli 2.4.36 → 2.4.37
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 +43 -25
- package/package.json +1 -1
package/dist/perch.mjs
CHANGED
|
@@ -75917,7 +75917,6 @@ function isTurnAbortedError(error) {
|
|
|
75917
75917
|
var TURN_STOPPED_BY_USER_MESSAGE;
|
|
75918
75918
|
var init_turnAbort = __esm({
|
|
75919
75919
|
"features/perchTerminal/runtime/turnAbort.ts"() {
|
|
75920
|
-
"use strict";
|
|
75921
75920
|
TURN_STOPPED_BY_USER_MESSAGE = "Turn stopped by user.";
|
|
75922
75921
|
}
|
|
75923
75922
|
});
|
|
@@ -76218,7 +76217,6 @@ function getToolDisplayName(toolName) {
|
|
|
76218
76217
|
var NON_MODULE_TOOL_OWNERS, TOOL_RISK, TOOL_DISPLAY_NAMES;
|
|
76219
76218
|
var init_catalog = __esm({
|
|
76220
76219
|
"features/perchTerminal/runtime/toolSystem/catalog.ts"() {
|
|
76221
|
-
"use strict";
|
|
76222
76220
|
init_toolNames();
|
|
76223
76221
|
NON_MODULE_TOOL_OWNERS = {
|
|
76224
76222
|
[TOOL_NAMES.listSources]: "lane",
|
|
@@ -83126,7 +83124,6 @@ function listFinancialRoleIds() {
|
|
|
83126
83124
|
var FINANCIAL_ROLE_REGISTRY, evidenceScoutManifest;
|
|
83127
83125
|
var init_financialRoles = __esm({
|
|
83128
83126
|
"features/perchTerminal/agentPlatform/financialRoles.ts"() {
|
|
83129
|
-
"use strict";
|
|
83130
83127
|
FINANCIAL_ROLE_REGISTRY = /* @__PURE__ */ new Map();
|
|
83131
83128
|
evidenceScoutManifest = {
|
|
83132
83129
|
workerId: "evidence_scout",
|
|
@@ -86724,7 +86721,6 @@ function truncateHistoryLine(value, max2) {
|
|
|
86724
86721
|
}
|
|
86725
86722
|
var init_operatorTruth = __esm({
|
|
86726
86723
|
"features/perchTerminal/runtime/operatorTruth.ts"() {
|
|
86727
|
-
"use strict";
|
|
86728
86724
|
}
|
|
86729
86725
|
});
|
|
86730
86726
|
|
|
@@ -138644,6 +138640,7 @@ function offSandboxEvent(runId, handler) {
|
|
|
138644
138640
|
var LOCAL_WORKSPACE_ACCESS_UNAVAILABLE;
|
|
138645
138641
|
var init_bridge = __esm({
|
|
138646
138642
|
"features/perchTerminal/desktop/bridge.ts"() {
|
|
138643
|
+
"use strict";
|
|
138647
138644
|
LOCAL_WORKSPACE_ACCESS_UNAVAILABLE = "Local workspace access is unavailable. Open Perch Desktop or update the app.";
|
|
138648
138645
|
}
|
|
138649
138646
|
});
|
|
@@ -205378,7 +205375,7 @@ function clampInt(value, min2, max2, fallback) {
|
|
|
205378
205375
|
const num = typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : fallback;
|
|
205379
205376
|
return Math.min(Math.max(num, min2), max2);
|
|
205380
205377
|
}
|
|
205381
|
-
var ADHOC_FORBIDDEN_TOOLS, ADHOC_WRITE_TOOLS, ADHOC_MAX_ITERATIONS, MAX_NAME_CHARS, MAX_CONTRACT_CHARS, DEFAULT_OUTPUT_CONTRACT;
|
|
205378
|
+
var ADHOC_FORBIDDEN_TOOLS, ADHOC_WRITE_TOOLS, ADHOC_MAX_ITERATIONS, ADHOC_MAX_TOOL_CALLS, MAX_NAME_CHARS, MAX_CONTRACT_CHARS, DEFAULT_OUTPUT_CONTRACT;
|
|
205382
205379
|
var init_adhocManifest = __esm({
|
|
205383
205380
|
"features/perchTerminal/runtime/workers/adhocManifest.ts"() {
|
|
205384
205381
|
"use strict";
|
|
@@ -205407,6 +205404,7 @@ var init_adhocManifest = __esm({
|
|
|
205407
205404
|
TOOL_NAMES.createDirectory
|
|
205408
205405
|
]);
|
|
205409
205406
|
ADHOC_MAX_ITERATIONS = 10;
|
|
205407
|
+
ADHOC_MAX_TOOL_CALLS = 40;
|
|
205410
205408
|
MAX_NAME_CHARS = 40;
|
|
205411
205409
|
MAX_CONTRACT_CHARS = 240;
|
|
205412
205410
|
DEFAULT_OUTPUT_CONTRACT = "Return a short structured summary of what was found or done.";
|
|
@@ -205495,6 +205493,14 @@ var init_spawnWorker = __esm({
|
|
|
205495
205493
|
handler: async (args, ctx) => {
|
|
205496
205494
|
let workerId = String(args.workerId ?? "");
|
|
205497
205495
|
const objective = String(args.objective ?? "");
|
|
205496
|
+
if (!ctx.onEvent) {
|
|
205497
|
+
return {
|
|
205498
|
+
ok: false,
|
|
205499
|
+
workerId,
|
|
205500
|
+
summary: "spawn_worker requires an event sink from the parent tool loop.",
|
|
205501
|
+
errorCode: "worker_event_sink_missing"
|
|
205502
|
+
};
|
|
205503
|
+
}
|
|
205498
205504
|
let adhocManifestId = null;
|
|
205499
205505
|
let adhocNickname = null;
|
|
205500
205506
|
const customSpec = parseAdhocSpec(args.custom);
|
|
@@ -205509,11 +205515,13 @@ var init_spawnWorker = __esm({
|
|
|
205509
205515
|
if (workerId && customSpec && !resolveWorkerManifest(workerId)) {
|
|
205510
205516
|
workerId = "";
|
|
205511
205517
|
}
|
|
205518
|
+
let adhocDisplayTitle;
|
|
205512
205519
|
if (!workerId && customSpec) {
|
|
205513
205520
|
const { manifest, droppedTools } = buildAdhocWorkerManifest(customSpec);
|
|
205514
205521
|
registerWorkerManifest(manifest);
|
|
205515
205522
|
adhocManifestId = manifest.workerId;
|
|
205516
205523
|
adhocNickname = flockNicknameFor(manifest.workerId, 0);
|
|
205524
|
+
adhocDisplayTitle = `${manifest.name} \xB7 ${adhocNickname}`;
|
|
205517
205525
|
workerId = manifest.workerId;
|
|
205518
205526
|
if (droppedTools.length > 0 && ctx.onEvent) {
|
|
205519
205527
|
ctx.onEvent({
|
|
@@ -205534,15 +205542,7 @@ var init_spawnWorker = __esm({
|
|
|
205534
205542
|
}
|
|
205535
205543
|
const context = typeof args.context === "string" || typeof args.context === "object" && args.context !== null && !Array.isArray(args.context) ? args.context : void 0;
|
|
205536
205544
|
const lane = typeof args.lane === "string" ? args.lane : void 0;
|
|
205537
|
-
const maxIterations = typeof args.maxIterations === "number" ? args.maxIterations : void 0;
|
|
205538
|
-
if (!ctx.onEvent) {
|
|
205539
|
-
return {
|
|
205540
|
-
ok: false,
|
|
205541
|
-
workerId,
|
|
205542
|
-
summary: "spawn_worker requires an event sink from the parent tool loop.",
|
|
205543
|
-
errorCode: "worker_event_sink_missing"
|
|
205544
|
-
};
|
|
205545
|
-
}
|
|
205545
|
+
const maxIterations = typeof args.maxIterations === "number" ? adhocManifestId ? Math.min(args.maxIterations, ADHOC_MAX_ITERATIONS) : args.maxIterations : void 0;
|
|
205546
205546
|
const enrichedContext = await threadPriorSpecialistContext({
|
|
205547
205547
|
threadId: ctx.threadId,
|
|
205548
205548
|
roleId: workerId,
|
|
@@ -205564,8 +205564,19 @@ Proceed with the available context. If a missing fact is essential, ask the user
|
|
|
205564
205564
|
].filter(Boolean).join("\n\n");
|
|
205565
205565
|
try {
|
|
205566
205566
|
const result2 = await spawnWorker(
|
|
205567
|
-
{ workerId, objective: workerObjective, context: enrichedContext, lane, maxIterations },
|
|
205568
205567
|
{
|
|
205568
|
+
workerId,
|
|
205569
|
+
objective: workerObjective,
|
|
205570
|
+
context: enrichedContext,
|
|
205571
|
+
lane,
|
|
205572
|
+
maxIterations,
|
|
205573
|
+
// Ad-hoc workers get a hard real-tool-call ceiling (observed live:
|
|
205574
|
+
// an unbounded 66-call run). Registered workers keep their existing
|
|
205575
|
+
// behavior — suites and managed workflows own their own budgets.
|
|
205576
|
+
maxToolCalls: adhocManifestId ? ADHOC_MAX_TOOL_CALLS : void 0
|
|
205577
|
+
},
|
|
205578
|
+
{
|
|
205579
|
+
displayTitle: adhocDisplayTitle,
|
|
205569
205580
|
workspaceRoot: effectiveWorkspaceRoot(ctx),
|
|
205570
205581
|
desktopConnected: ctx.desktopConnected,
|
|
205571
205582
|
// CLI surface: children inherit the local bridge and server auth,
|
|
@@ -220237,12 +220248,13 @@ async function spawnWorker(args, ctx) {
|
|
|
220237
220248
|
errorCode: "worker_not_found"
|
|
220238
220249
|
};
|
|
220239
220250
|
}
|
|
220251
|
+
const eventTitle = ctx.displayTitle?.trim() || manifest.name;
|
|
220240
220252
|
const runDiscriminator = ctx.runId ?? Date.now().toString(36);
|
|
220241
220253
|
const childThreadId = args.childThreadId ?? (ctx.threadId ? `${ctx.threadId}::worker::${args.workerId}::${runDiscriminator}` : null);
|
|
220242
220254
|
const workerRun = ctx.threadId ? await registerWorkerRun({
|
|
220243
220255
|
threadId: ctx.threadId,
|
|
220244
220256
|
workerId: args.workerId,
|
|
220245
|
-
title:
|
|
220257
|
+
title: eventTitle,
|
|
220246
220258
|
objective: args.objective,
|
|
220247
220259
|
context: args.context,
|
|
220248
220260
|
parentToolCallId: ctx.parentToolCallId ?? null,
|
|
@@ -220265,14 +220277,14 @@ async function spawnWorker(args, ctx) {
|
|
|
220265
220277
|
childThreadId,
|
|
220266
220278
|
workerRunId: runtimeWorkerRunId,
|
|
220267
220279
|
workerId: args.workerId,
|
|
220268
|
-
title:
|
|
220280
|
+
title: eventTitle
|
|
220269
220281
|
});
|
|
220270
220282
|
}
|
|
220271
220283
|
ctx.onEvent({
|
|
220272
220284
|
type: "worker_run_started",
|
|
220273
220285
|
workerId: args.workerId,
|
|
220274
220286
|
workerRunId: runtimeWorkerRunId,
|
|
220275
|
-
title:
|
|
220287
|
+
title: eventTitle,
|
|
220276
220288
|
objective: args.objective,
|
|
220277
220289
|
contextSummary: summarizeWorkerContextForTranscript(args.context),
|
|
220278
220290
|
childThreadId,
|
|
@@ -220479,18 +220491,24 @@ ${contextBlock}
|
|
|
220479
220491
|
attachOperatorScreenshots: isBrowserDeliveryRole(args.workerId)
|
|
220480
220492
|
};
|
|
220481
220493
|
const result2 = await runModelToolLoop(loopInput);
|
|
220494
|
+
const approvalBlocked = result2.stopReason === "approval_required" ? result2.pendingApproval ?? null : null;
|
|
220482
220495
|
const recoveredStructuredOutput = recoverWorkerStructuredOutput(args.workerId, args.objective, args.context, result2.toolCalls);
|
|
220483
220496
|
const structuredOutput = parseStructuredRecordFromModelText(result2.text) ?? recoveredStructuredOutput;
|
|
220484
220497
|
const missingRequiredOutput = result2.ok && Boolean(manifest.outputSchema) && !structuredOutput;
|
|
220485
220498
|
const verifierPartialOrFail = (args.workerId === "source_verifier" || args.workerId === "legal_citation_verifier") && structuredOutput !== null && typeof structuredOutput === "object" && structuredOutput.verificationStatus !== "pass";
|
|
220486
220499
|
const hasUsableOutput = Boolean(structuredOutput) || Boolean(recoveredStructuredOutput) || (result2.text?.trim().length ?? 0) > 50;
|
|
220487
|
-
const workerOk = (result2.ok || Boolean(recoveredStructuredOutput)) && !missingRequiredOutput;
|
|
220488
|
-
const usabilityStatus = resolveWorkerUsability({
|
|
220500
|
+
const workerOk = !approvalBlocked && (result2.ok || Boolean(recoveredStructuredOutput)) && !missingRequiredOutput;
|
|
220501
|
+
const usabilityStatus = approvalBlocked ? "needs_user_input" : resolveWorkerUsability({
|
|
220489
220502
|
workerOk,
|
|
220490
220503
|
hasUsableOutput,
|
|
220491
220504
|
verifierPartialOrFail
|
|
220492
220505
|
});
|
|
220493
220506
|
const workerWarnings = [];
|
|
220507
|
+
if (approvalBlocked) {
|
|
220508
|
+
workerWarnings.push(
|
|
220509
|
+
"Worker stopped at an approval gate \u2014 the gated action did not run."
|
|
220510
|
+
);
|
|
220511
|
+
}
|
|
220494
220512
|
if (verifierPartialOrFail && hasUsableOutput) {
|
|
220495
220513
|
workerWarnings.push(`Verification returned "${structuredOutput?.verificationStatus ?? "unknown"}" \u2014 output usable with caveat.`);
|
|
220496
220514
|
}
|
|
@@ -220502,7 +220520,7 @@ ${contextBlock}
|
|
|
220502
220520
|
}
|
|
220503
220521
|
const recoveredSummary = recoveredStructuredOutput ? summarizeRecoveredWorkerOutput(args.workerId, recoveredStructuredOutput) : null;
|
|
220504
220522
|
const summary = truncateSummary(
|
|
220505
|
-
workerOk ? !result2.ok && recoveredSummary ? recoveredSummary : result2.text || recoveredSummary || (recoveredStructuredOutput ? JSON.stringify(recoveredStructuredOutput) : "") : missingRequiredOutput ? result2.text || "Worker stopped without returning the required structured JSON output." : result2.text || result2.error || "Worker failed before producing output."
|
|
220523
|
+
approvalBlocked ? `Blocked at an approval gate: ${approvalBlocked.toolName ?? "a gated tool"} requires approval in the current permission mode${approvalBlocked.reason ? ` (${approvalBlocked.reason})` : ""}. The action did not run. Approve it interactively, or re-run under /permission take_the_wheel.` : workerOk ? !result2.ok && recoveredSummary ? recoveredSummary : result2.text || recoveredSummary || (recoveredStructuredOutput ? JSON.stringify(recoveredStructuredOutput) : "") : missingRequiredOutput ? result2.text || "Worker stopped without returning the required structured JSON output." : result2.text || result2.error || "Worker failed before producing output."
|
|
220506
220524
|
);
|
|
220507
220525
|
const durationMs = Date.now() - startMs;
|
|
220508
220526
|
let contextPacket = null;
|
|
@@ -220539,7 +220557,7 @@ ${contextBlock}
|
|
|
220539
220557
|
type: "worker_run_completed",
|
|
220540
220558
|
workerId: args.workerId,
|
|
220541
220559
|
workerRunId: runtimeWorkerRunId,
|
|
220542
|
-
title:
|
|
220560
|
+
title: eventTitle,
|
|
220543
220561
|
childThreadId,
|
|
220544
220562
|
persistedThreadId,
|
|
220545
220563
|
parentToolCallId: ctx.parentToolCallId ?? null,
|
|
@@ -220573,7 +220591,7 @@ ${contextBlock}
|
|
|
220573
220591
|
missingRequiredOutput,
|
|
220574
220592
|
verifierPartialOrFail,
|
|
220575
220593
|
error: result2.error
|
|
220576
|
-
}) : void 0,
|
|
220594
|
+
}) : approvalBlocked ? "worker_approval_required" : void 0,
|
|
220577
220595
|
workerOffThreadTokens: workerTokenEstimate,
|
|
220578
220596
|
contextPacket
|
|
220579
220597
|
}, { supabase: ctx.supabase ?? null });
|
|
@@ -220597,7 +220615,7 @@ ${contextBlock}
|
|
|
220597
220615
|
missingRequiredOutput,
|
|
220598
220616
|
verifierPartialOrFail,
|
|
220599
220617
|
error: result2.error
|
|
220600
|
-
}) : void 0,
|
|
220618
|
+
}) : approvalBlocked ? "worker_approval_required" : void 0,
|
|
220601
220619
|
warnings: workerWarnings.length > 0 ? workerWarnings : void 0
|
|
220602
220620
|
};
|
|
220603
220621
|
} catch (error) {
|
|
@@ -220608,7 +220626,7 @@ ${contextBlock}
|
|
|
220608
220626
|
type: "worker_run_completed",
|
|
220609
220627
|
workerId: args.workerId,
|
|
220610
220628
|
workerRunId: runtimeWorkerRunId,
|
|
220611
|
-
title:
|
|
220629
|
+
title: eventTitle,
|
|
220612
220630
|
childThreadId,
|
|
220613
220631
|
parentToolCallId: ctx.parentToolCallId ?? null,
|
|
220614
220632
|
ok: false,
|