perchai-cli 2.4.35 → 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 +61 -24
- 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",
|
|
@@ -138643,6 +138640,7 @@ function offSandboxEvent(runId, handler) {
|
|
|
138643
138640
|
var LOCAL_WORKSPACE_ACCESS_UNAVAILABLE;
|
|
138644
138641
|
var init_bridge = __esm({
|
|
138645
138642
|
"features/perchTerminal/desktop/bridge.ts"() {
|
|
138643
|
+
"use strict";
|
|
138646
138644
|
LOCAL_WORKSPACE_ACCESS_UNAVAILABLE = "Local workspace access is unavailable. Open Perch Desktop or update the app.";
|
|
138647
138645
|
}
|
|
138648
138646
|
});
|
|
@@ -197922,6 +197920,15 @@ async function dispatchAgentHandler(args, ctx) {
|
|
|
197922
197920
|
const agentCtx = {
|
|
197923
197921
|
workspaceRoot,
|
|
197924
197922
|
desktopConnected: ctx.desktopConnected,
|
|
197923
|
+
// CLI surface: children inherit the local bridge and server auth, same as
|
|
197924
|
+
// flock's buildSpawnContext — otherwise filesystem workers fail with
|
|
197925
|
+
// worker_desktop_workspace_required on the CLI.
|
|
197926
|
+
cliLocalTools: ctx.cliLocalTools === true,
|
|
197927
|
+
scopedFolderPath: ctx.scopedFolderPath,
|
|
197928
|
+
cliServerAppUrl: ctx.cliServerAppUrl ?? null,
|
|
197929
|
+
cliServerAccessToken: ctx.cliServerAccessToken ?? null,
|
|
197930
|
+
marketDeskProxyAppUrl: ctx.marketDeskProxyAppUrl ?? null,
|
|
197931
|
+
marketDeskProxyAccessToken: ctx.marketDeskProxyAccessToken ?? null,
|
|
197925
197932
|
activeRootPath: ctx.activeRootPath,
|
|
197926
197933
|
permissionMode: ctx.permissionMode,
|
|
197927
197934
|
workspaceId: ctx.workspaceId,
|
|
@@ -205368,7 +205375,7 @@ function clampInt(value, min2, max2, fallback) {
|
|
|
205368
205375
|
const num = typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : fallback;
|
|
205369
205376
|
return Math.min(Math.max(num, min2), max2);
|
|
205370
205377
|
}
|
|
205371
|
-
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;
|
|
205372
205379
|
var init_adhocManifest = __esm({
|
|
205373
205380
|
"features/perchTerminal/runtime/workers/adhocManifest.ts"() {
|
|
205374
205381
|
"use strict";
|
|
@@ -205397,6 +205404,7 @@ var init_adhocManifest = __esm({
|
|
|
205397
205404
|
TOOL_NAMES.createDirectory
|
|
205398
205405
|
]);
|
|
205399
205406
|
ADHOC_MAX_ITERATIONS = 10;
|
|
205407
|
+
ADHOC_MAX_TOOL_CALLS = 40;
|
|
205400
205408
|
MAX_NAME_CHARS = 40;
|
|
205401
205409
|
MAX_CONTRACT_CHARS = 240;
|
|
205402
205410
|
DEFAULT_OUTPUT_CONTRACT = "Return a short structured summary of what was found or done.";
|
|
@@ -205485,6 +205493,14 @@ var init_spawnWorker = __esm({
|
|
|
205485
205493
|
handler: async (args, ctx) => {
|
|
205486
205494
|
let workerId = String(args.workerId ?? "");
|
|
205487
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
|
+
}
|
|
205488
205504
|
let adhocManifestId = null;
|
|
205489
205505
|
let adhocNickname = null;
|
|
205490
205506
|
const customSpec = parseAdhocSpec(args.custom);
|
|
@@ -205499,11 +205515,13 @@ var init_spawnWorker = __esm({
|
|
|
205499
205515
|
if (workerId && customSpec && !resolveWorkerManifest(workerId)) {
|
|
205500
205516
|
workerId = "";
|
|
205501
205517
|
}
|
|
205518
|
+
let adhocDisplayTitle;
|
|
205502
205519
|
if (!workerId && customSpec) {
|
|
205503
205520
|
const { manifest, droppedTools } = buildAdhocWorkerManifest(customSpec);
|
|
205504
205521
|
registerWorkerManifest(manifest);
|
|
205505
205522
|
adhocManifestId = manifest.workerId;
|
|
205506
205523
|
adhocNickname = flockNicknameFor(manifest.workerId, 0);
|
|
205524
|
+
adhocDisplayTitle = `${manifest.name} \xB7 ${adhocNickname}`;
|
|
205507
205525
|
workerId = manifest.workerId;
|
|
205508
205526
|
if (droppedTools.length > 0 && ctx.onEvent) {
|
|
205509
205527
|
ctx.onEvent({
|
|
@@ -205524,15 +205542,7 @@ var init_spawnWorker = __esm({
|
|
|
205524
205542
|
}
|
|
205525
205543
|
const context = typeof args.context === "string" || typeof args.context === "object" && args.context !== null && !Array.isArray(args.context) ? args.context : void 0;
|
|
205526
205544
|
const lane = typeof args.lane === "string" ? args.lane : void 0;
|
|
205527
|
-
const maxIterations = typeof args.maxIterations === "number" ? args.maxIterations : void 0;
|
|
205528
|
-
if (!ctx.onEvent) {
|
|
205529
|
-
return {
|
|
205530
|
-
ok: false,
|
|
205531
|
-
workerId,
|
|
205532
|
-
summary: "spawn_worker requires an event sink from the parent tool loop.",
|
|
205533
|
-
errorCode: "worker_event_sink_missing"
|
|
205534
|
-
};
|
|
205535
|
-
}
|
|
205545
|
+
const maxIterations = typeof args.maxIterations === "number" ? adhocManifestId ? Math.min(args.maxIterations, ADHOC_MAX_ITERATIONS) : args.maxIterations : void 0;
|
|
205536
205546
|
const enrichedContext = await threadPriorSpecialistContext({
|
|
205537
205547
|
threadId: ctx.threadId,
|
|
205538
205548
|
roleId: workerId,
|
|
@@ -205554,10 +205564,30 @@ Proceed with the available context. If a missing fact is essential, ask the user
|
|
|
205554
205564
|
].filter(Boolean).join("\n\n");
|
|
205555
205565
|
try {
|
|
205556
205566
|
const result2 = await spawnWorker(
|
|
205557
|
-
{ workerId, objective: workerObjective, context: enrichedContext, lane, maxIterations },
|
|
205558
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,
|
|
205559
205580
|
workspaceRoot: effectiveWorkspaceRoot(ctx),
|
|
205560
205581
|
desktopConnected: ctx.desktopConnected,
|
|
205582
|
+
// CLI surface: children inherit the local bridge and server auth,
|
|
205583
|
+
// same as flock's buildSpawnContext — without these, every worker
|
|
205584
|
+
// needing filesystem access dies with worker_desktop_workspace_required.
|
|
205585
|
+
cliLocalTools: ctx.cliLocalTools === true,
|
|
205586
|
+
scopedFolderPath: ctx.scopedFolderPath,
|
|
205587
|
+
cliServerAppUrl: ctx.cliServerAppUrl ?? null,
|
|
205588
|
+
cliServerAccessToken: ctx.cliServerAccessToken ?? null,
|
|
205589
|
+
marketDeskProxyAppUrl: ctx.marketDeskProxyAppUrl ?? null,
|
|
205590
|
+
marketDeskProxyAccessToken: ctx.marketDeskProxyAccessToken ?? null,
|
|
205561
205591
|
activeRootPath: ctx.activeRootPath,
|
|
205562
205592
|
permissionMode: ctx.permissionMode,
|
|
205563
205593
|
workspaceId: ctx.workspaceId,
|
|
@@ -220218,12 +220248,13 @@ async function spawnWorker(args, ctx) {
|
|
|
220218
220248
|
errorCode: "worker_not_found"
|
|
220219
220249
|
};
|
|
220220
220250
|
}
|
|
220251
|
+
const eventTitle = ctx.displayTitle?.trim() || manifest.name;
|
|
220221
220252
|
const runDiscriminator = ctx.runId ?? Date.now().toString(36);
|
|
220222
220253
|
const childThreadId = args.childThreadId ?? (ctx.threadId ? `${ctx.threadId}::worker::${args.workerId}::${runDiscriminator}` : null);
|
|
220223
220254
|
const workerRun = ctx.threadId ? await registerWorkerRun({
|
|
220224
220255
|
threadId: ctx.threadId,
|
|
220225
220256
|
workerId: args.workerId,
|
|
220226
|
-
title:
|
|
220257
|
+
title: eventTitle,
|
|
220227
220258
|
objective: args.objective,
|
|
220228
220259
|
context: args.context,
|
|
220229
220260
|
parentToolCallId: ctx.parentToolCallId ?? null,
|
|
@@ -220246,14 +220277,14 @@ async function spawnWorker(args, ctx) {
|
|
|
220246
220277
|
childThreadId,
|
|
220247
220278
|
workerRunId: runtimeWorkerRunId,
|
|
220248
220279
|
workerId: args.workerId,
|
|
220249
|
-
title:
|
|
220280
|
+
title: eventTitle
|
|
220250
220281
|
});
|
|
220251
220282
|
}
|
|
220252
220283
|
ctx.onEvent({
|
|
220253
220284
|
type: "worker_run_started",
|
|
220254
220285
|
workerId: args.workerId,
|
|
220255
220286
|
workerRunId: runtimeWorkerRunId,
|
|
220256
|
-
title:
|
|
220287
|
+
title: eventTitle,
|
|
220257
220288
|
objective: args.objective,
|
|
220258
220289
|
contextSummary: summarizeWorkerContextForTranscript(args.context),
|
|
220259
220290
|
childThreadId,
|
|
@@ -220460,18 +220491,24 @@ ${contextBlock}
|
|
|
220460
220491
|
attachOperatorScreenshots: isBrowserDeliveryRole(args.workerId)
|
|
220461
220492
|
};
|
|
220462
220493
|
const result2 = await runModelToolLoop(loopInput);
|
|
220494
|
+
const approvalBlocked = result2.stopReason === "approval_required" ? result2.pendingApproval ?? null : null;
|
|
220463
220495
|
const recoveredStructuredOutput = recoverWorkerStructuredOutput(args.workerId, args.objective, args.context, result2.toolCalls);
|
|
220464
220496
|
const structuredOutput = parseStructuredRecordFromModelText(result2.text) ?? recoveredStructuredOutput;
|
|
220465
220497
|
const missingRequiredOutput = result2.ok && Boolean(manifest.outputSchema) && !structuredOutput;
|
|
220466
220498
|
const verifierPartialOrFail = (args.workerId === "source_verifier" || args.workerId === "legal_citation_verifier") && structuredOutput !== null && typeof structuredOutput === "object" && structuredOutput.verificationStatus !== "pass";
|
|
220467
220499
|
const hasUsableOutput = Boolean(structuredOutput) || Boolean(recoveredStructuredOutput) || (result2.text?.trim().length ?? 0) > 50;
|
|
220468
|
-
const workerOk = (result2.ok || Boolean(recoveredStructuredOutput)) && !missingRequiredOutput;
|
|
220469
|
-
const usabilityStatus = resolveWorkerUsability({
|
|
220500
|
+
const workerOk = !approvalBlocked && (result2.ok || Boolean(recoveredStructuredOutput)) && !missingRequiredOutput;
|
|
220501
|
+
const usabilityStatus = approvalBlocked ? "needs_user_input" : resolveWorkerUsability({
|
|
220470
220502
|
workerOk,
|
|
220471
220503
|
hasUsableOutput,
|
|
220472
220504
|
verifierPartialOrFail
|
|
220473
220505
|
});
|
|
220474
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
|
+
}
|
|
220475
220512
|
if (verifierPartialOrFail && hasUsableOutput) {
|
|
220476
220513
|
workerWarnings.push(`Verification returned "${structuredOutput?.verificationStatus ?? "unknown"}" \u2014 output usable with caveat.`);
|
|
220477
220514
|
}
|
|
@@ -220483,7 +220520,7 @@ ${contextBlock}
|
|
|
220483
220520
|
}
|
|
220484
220521
|
const recoveredSummary = recoveredStructuredOutput ? summarizeRecoveredWorkerOutput(args.workerId, recoveredStructuredOutput) : null;
|
|
220485
220522
|
const summary = truncateSummary(
|
|
220486
|
-
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."
|
|
220487
220524
|
);
|
|
220488
220525
|
const durationMs = Date.now() - startMs;
|
|
220489
220526
|
let contextPacket = null;
|
|
@@ -220520,7 +220557,7 @@ ${contextBlock}
|
|
|
220520
220557
|
type: "worker_run_completed",
|
|
220521
220558
|
workerId: args.workerId,
|
|
220522
220559
|
workerRunId: runtimeWorkerRunId,
|
|
220523
|
-
title:
|
|
220560
|
+
title: eventTitle,
|
|
220524
220561
|
childThreadId,
|
|
220525
220562
|
persistedThreadId,
|
|
220526
220563
|
parentToolCallId: ctx.parentToolCallId ?? null,
|
|
@@ -220554,7 +220591,7 @@ ${contextBlock}
|
|
|
220554
220591
|
missingRequiredOutput,
|
|
220555
220592
|
verifierPartialOrFail,
|
|
220556
220593
|
error: result2.error
|
|
220557
|
-
}) : void 0,
|
|
220594
|
+
}) : approvalBlocked ? "worker_approval_required" : void 0,
|
|
220558
220595
|
workerOffThreadTokens: workerTokenEstimate,
|
|
220559
220596
|
contextPacket
|
|
220560
220597
|
}, { supabase: ctx.supabase ?? null });
|
|
@@ -220578,7 +220615,7 @@ ${contextBlock}
|
|
|
220578
220615
|
missingRequiredOutput,
|
|
220579
220616
|
verifierPartialOrFail,
|
|
220580
220617
|
error: result2.error
|
|
220581
|
-
}) : void 0,
|
|
220618
|
+
}) : approvalBlocked ? "worker_approval_required" : void 0,
|
|
220582
220619
|
warnings: workerWarnings.length > 0 ? workerWarnings : void 0
|
|
220583
220620
|
};
|
|
220584
220621
|
} catch (error) {
|
|
@@ -220589,7 +220626,7 @@ ${contextBlock}
|
|
|
220589
220626
|
type: "worker_run_completed",
|
|
220590
220627
|
workerId: args.workerId,
|
|
220591
220628
|
workerRunId: runtimeWorkerRunId,
|
|
220592
|
-
title:
|
|
220629
|
+
title: eventTitle,
|
|
220593
220630
|
childThreadId,
|
|
220594
220631
|
parentToolCallId: ctx.parentToolCallId ?? null,
|
|
220595
220632
|
ok: false,
|