perchai-cli 2.4.31 → 2.4.32

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.
Files changed (2) hide show
  1. package/dist/perch.mjs +93 -6
  2. 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();
@@ -75917,6 +75918,7 @@ function isTurnAbortedError(error) {
75917
75918
  var TURN_STOPPED_BY_USER_MESSAGE;
75918
75919
  var init_turnAbort = __esm({
75919
75920
  "features/perchTerminal/runtime/turnAbort.ts"() {
75921
+ "use strict";
75920
75922
  TURN_STOPPED_BY_USER_MESSAGE = "Turn stopped by user.";
75921
75923
  }
75922
75924
  });
@@ -76217,7 +76219,6 @@ function getToolDisplayName(toolName) {
76217
76219
  var NON_MODULE_TOOL_OWNERS, TOOL_RISK, TOOL_DISPLAY_NAMES;
76218
76220
  var init_catalog = __esm({
76219
76221
  "features/perchTerminal/runtime/toolSystem/catalog.ts"() {
76220
- "use strict";
76221
76222
  init_toolNames();
76222
76223
  NON_MODULE_TOOL_OWNERS = {
76223
76224
  [TOOL_NAMES.listSources]: "lane",
@@ -83125,6 +83126,7 @@ function listFinancialRoleIds() {
83125
83126
  var FINANCIAL_ROLE_REGISTRY, evidenceScoutManifest;
83126
83127
  var init_financialRoles = __esm({
83127
83128
  "features/perchTerminal/agentPlatform/financialRoles.ts"() {
83129
+ "use strict";
83128
83130
  FINANCIAL_ROLE_REGISTRY = /* @__PURE__ */ new Map();
83129
83131
  evidenceScoutManifest = {
83130
83132
  workerId: "evidence_scout",
@@ -91008,6 +91010,7 @@ Final answers lead with findings, name artifacts or delivery status, and give on
91008
91010
  var MARKET_DESK_TOOL_NAMES;
91009
91011
  var init_marketDeskAccess = __esm({
91010
91012
  "features/perchTerminal/runtime/marketDesk/marketDeskAccess.ts"() {
91013
+ "use strict";
91011
91014
  init_toolNames();
91012
91015
  MARKET_DESK_TOOL_NAMES = /* @__PURE__ */ new Set([
91013
91016
  TOOL_NAMES.getMarketSignal,
@@ -91687,7 +91690,6 @@ function listFinancialPlaybooks() {
91687
91690
  var AP_AUDIT_PACKET_DEF, PLAYBOOKS;
91688
91691
  var init_registry2 = __esm({
91689
91692
  "features/perchTerminal/runtime/financialPlaybooks/registry.ts"() {
91690
- "use strict";
91691
91693
  init_managedWorkflowRegistry2();
91692
91694
  init_toolNames();
91693
91695
  AP_AUDIT_PACKET_DEF = {
@@ -196813,6 +196815,7 @@ function recordDispatchBatchResult(tasks, result2, ctx, opts = {}) {
196813
196815
  var lifecycleByRun, MAX_LIFECYCLE_RUNS;
196814
196816
  var init_workerLifecycle = __esm({
196815
196817
  "features/perchTerminal/runtime/workers/workerLifecycle.ts"() {
196818
+ "use strict";
196816
196819
  init_workerManifest();
196817
196820
  lifecycleByRun = /* @__PURE__ */ new Map();
196818
196821
  MAX_LIFECYCLE_RUNS = 200;
@@ -216864,6 +216867,58 @@ function createSourceReadBudgetState() {
216864
216867
  syntheticResultIssued: false
216865
216868
  };
216866
216869
  }
216870
+ function createFailedReadBreakerState() {
216871
+ return { consecutiveFailedReads: 0, tripped: false };
216872
+ }
216873
+ function buildFailedReadBreakerSuppressionExecution(toolCall, state) {
216874
+ if (!state.tripped) return null;
216875
+ if (!FAILED_READ_BREAKER_TOOLS.has(toolCall.name)) return null;
216876
+ const timestamp = now5();
216877
+ return {
216878
+ toolCallId: toolCall.id,
216879
+ toolName: toolCall.name,
216880
+ toolKind: "read",
216881
+ riskLevel: "read",
216882
+ input: sanitizeToolInput(toolCall.arguments),
216883
+ ok: true,
216884
+ result: FAILED_READ_BREAKER_MESSAGE,
216885
+ output: {
216886
+ ok: true,
216887
+ suppressedFailedReadBreaker: true,
216888
+ consecutiveFailedReads: state.consecutiveFailedReads,
216889
+ message: FAILED_READ_BREAKER_MESSAGE
216890
+ },
216891
+ outputSummary: FAILED_READ_BREAKER_MESSAGE,
216892
+ durationMs: 0,
216893
+ startedAt: timestamp,
216894
+ completedAt: timestamp,
216895
+ desktopRequired: false,
216896
+ resultTruncated: false,
216897
+ evidence: []
216898
+ };
216899
+ }
216900
+ function recordFailedReadBreakerExecution(state, execution) {
216901
+ if (!FAILED_READ_BREAKER_TOOLS.has(execution.toolName)) return false;
216902
+ if (isSyntheticReadSuppressionExecution(execution) || execution.errorCode === "tool_call_budget_exhausted" || isFailedReadBreakerSuppressionExecution(execution)) {
216903
+ return false;
216904
+ }
216905
+ if (execution.ok) {
216906
+ state.consecutiveFailedReads = 0;
216907
+ return false;
216908
+ }
216909
+ state.consecutiveFailedReads += 1;
216910
+ if (!state.tripped && state.consecutiveFailedReads >= FAILED_READ_BREAKER_LIMIT) {
216911
+ state.tripped = true;
216912
+ return true;
216913
+ }
216914
+ return false;
216915
+ }
216916
+ function isFailedReadBreakerSuppressionExecution(execution) {
216917
+ const output = execution.output;
216918
+ return Boolean(
216919
+ output && typeof output === "object" && output.suppressedFailedReadBreaker === true
216920
+ );
216921
+ }
216867
216922
  function buildSourceReadBudgetSuppressionExecution(toolCall, budget, opts) {
216868
216923
  const limits = resolveSourceReadBudgetLimits(opts);
216869
216924
  if (!limits) return null;
@@ -217242,7 +217297,7 @@ function sanitizeMaxIterations(value, cap = MAX_ITERATIONS) {
217242
217297
  function now5() {
217243
217298
  return (/* @__PURE__ */ new Date()).toISOString();
217244
217299
  }
217245
- var MAX_ITERATIONS, MAX_WORKER_ITERATIONS, SOURCE_ANALYSIS_MAX_ITERATIONS, SUBSTANTIAL_FINAL_TEXT_MIN_CHARS, SUBSTANTIAL_FINAL_TEXT_MIN_WORDS, CHAT_SOURCE_READ_TOTAL_BUDGET, CHAT_SOURCE_READ_FAMILY_BUDGET, SOURCE_ANALYSIS_SOURCE_READ_TOTAL_BUDGET, SOURCE_ANALYSIS_SOURCE_READ_FAMILY_BUDGET, SOURCE_READ_BUDGET_MESSAGE, FINAL_TEXT_SUPPRESSIBLE_READ_TOOLS, DUPLICATE_READ_SUPPRESSIBLE_TOOLS, SOURCE_READ_BUDGET_COUNTED_TOOLS, SOURCE_READ_BUDGET_SUPPRESSIBLE_TOOLS, POST_BUDGET_SOURCE_ANALYSIS_FINISHER_TOOLS;
217300
+ var MAX_ITERATIONS, MAX_WORKER_ITERATIONS, SOURCE_ANALYSIS_MAX_ITERATIONS, SUBSTANTIAL_FINAL_TEXT_MIN_CHARS, SUBSTANTIAL_FINAL_TEXT_MIN_WORDS, CHAT_SOURCE_READ_TOTAL_BUDGET, CHAT_SOURCE_READ_FAMILY_BUDGET, SOURCE_ANALYSIS_SOURCE_READ_TOTAL_BUDGET, SOURCE_ANALYSIS_SOURCE_READ_FAMILY_BUDGET, SOURCE_READ_BUDGET_MESSAGE, FINAL_TEXT_SUPPRESSIBLE_READ_TOOLS, DUPLICATE_READ_SUPPRESSIBLE_TOOLS, SOURCE_READ_BUDGET_COUNTED_TOOLS, SOURCE_READ_BUDGET_SUPPRESSIBLE_TOOLS, POST_BUDGET_SOURCE_ANALYSIS_FINISHER_TOOLS, FAILED_READ_BREAKER_TOOLS, FAILED_READ_BREAKER_LIMIT, FAILED_READ_BREAKER_MESSAGE;
217246
217301
  var init_sourceReadPolicy = __esm({
217247
217302
  "features/perchTerminal/runtime/toolLoop/sourceReadPolicy.ts"() {
217248
217303
  "use strict";
@@ -217315,6 +217370,13 @@ var init_sourceReadPolicy = __esm({
217315
217370
  TOOL_NAMES.prepareSandboxInputs,
217316
217371
  TOOL_NAMES.runSandboxCode
217317
217372
  ]);
217373
+ FAILED_READ_BREAKER_TOOLS = /* @__PURE__ */ new Set([
217374
+ TOOL_NAMES.readLocalFile,
217375
+ TOOL_NAMES.readLocalSourceFile,
217376
+ TOOL_NAMES.printFile
217377
+ ]);
217378
+ FAILED_READ_BREAKER_LIMIT = 6;
217379
+ FAILED_READ_BREAKER_MESSAGE = `Stopped file reads after ${FAILED_READ_BREAKER_LIMIT} consecutive misses \u2014 the paths being guessed do not exist. Do not probe further paths. Use the context you were given, or finish from gathered evidence now.`;
217318
217380
  }
217319
217381
  });
217320
217382
 
@@ -217423,6 +217485,14 @@ async function executeToolBatch(toolCalls, ctx) {
217423
217485
  });
217424
217486
  return budgetSuppression;
217425
217487
  }
217488
+ const failedReadSuppression = buildFailedReadBreakerSuppressionExecution(
217489
+ toolCall,
217490
+ ctx.failedReadBreaker
217491
+ );
217492
+ if (failedReadSuppression) {
217493
+ ctx.sourceReadBudget.syntheticResultIssued = true;
217494
+ return failedReadSuppression;
217495
+ }
217426
217496
  const duplicateRead = buildDuplicateReadSuppressionExecution(
217427
217497
  toolCall,
217428
217498
  ctx.successfulReadToolSignatures
@@ -217521,6 +217591,14 @@ async function executeToolBatch(toolCalls, ctx) {
217521
217591
  ctx.untrustedContextAvailable = true;
217522
217592
  rememberSuccessfulReadExecution(ctx.successfulReadToolSignatures, execution);
217523
217593
  recordSuccessfulSourceReadExecution(ctx.sourceReadBudget, execution);
217594
+ if (recordFailedReadBreakerExecution(ctx.failedReadBreaker, execution)) {
217595
+ ctx.onEvent({
217596
+ type: "diagnostic",
217597
+ code: "failed_read_breaker_tripped",
217598
+ message: `${FAILED_READ_BREAKER_LIMIT} consecutive file reads failed \u2014 suppressing further file reads this run and finishing from gathered evidence.`,
217599
+ ts: now6()
217600
+ });
217601
+ }
217524
217602
  const updatedMode = permissionModeFromExecution(execution);
217525
217603
  if (updatedMode) ctx.permissionMode = updatedMode;
217526
217604
  const consecutiveArgFailureCount = updateConsecutiveRequiredArgFailures(
@@ -219281,6 +219359,7 @@ async function runModelToolLoop(input) {
219281
219359
  const successfulReadToolSignatures = /* @__PURE__ */ new Map();
219282
219360
  const sourceReadBudget = createSourceReadBudgetState();
219283
219361
  const consecutiveRequiredArgFailures = /* @__PURE__ */ new Map();
219362
+ const failedReadBreaker = createFailedReadBreakerState();
219284
219363
  const startMs = Date.now();
219285
219364
  let iterations = 0;
219286
219365
  let lastProvider = "unknown";
@@ -219573,6 +219652,7 @@ async function runModelToolLoop(input) {
219573
219652
  sourceReadBudget,
219574
219653
  successfulReadToolSignatures,
219575
219654
  consecutiveRequiredArgFailures,
219655
+ failedReadBreaker,
219576
219656
  permissionMode: effectivePermissionMode,
219577
219657
  realToolCallsStarted,
219578
219658
  firstPartyToolIntentUsed,
@@ -221532,9 +221612,15 @@ function buildFlockPlannerPrompts(ctx) {
221532
221612
  "- baseWorkerId: set ONLY to reuse an id from existingWorkers; otherwise null.",
221533
221613
  "- Decline (accepted=false, with reason) tasks that are trivial, conversational, or need no fanout."
221534
221614
  ].join("\n");
221535
- const roster = listWorkerContracts().filter(
221615
+ ensureFlockWorkersRegistered();
221616
+ const archetypeIds = new Set(listFlockRoleSpecs().map((spec) => spec.workerId));
221617
+ const surfacedContracts = listWorkerContracts().filter(
221536
221618
  (contract) => ctx.surface !== "cli" || !GUI_ONLY_WORKER_IDS.includes(contract.workerId)
221537
- ).slice(0, MAX_ROSTER_IN_PROMPT).map((contract) => ({ id: contract.workerId, name: contract.name }));
221619
+ );
221620
+ const roster = [
221621
+ ...surfacedContracts.filter((contract) => archetypeIds.has(contract.workerId)),
221622
+ ...surfacedContracts.filter((contract) => !archetypeIds.has(contract.workerId))
221623
+ ].slice(0, MAX_ROSTER_IN_PROMPT).map((contract) => ({ id: contract.workerId, name: contract.name }));
221538
221624
  const userPrompt = JSON.stringify({
221539
221625
  task: ctx.task,
221540
221626
  surface: ctx.surface,
@@ -221774,6 +221860,7 @@ var init_flockLlmPlanner = __esm({
221774
221860
  init_flockLimits();
221775
221861
  init_flockNicknames();
221776
221862
  init_flockPlanner();
221863
+ init_flockRoles();
221777
221864
  init_flockPlanner();
221778
221865
  FLOCK_FORBIDDEN_TOOLS = [
221779
221866
  ...WORKER_DISALLOWED_TOOLS,
@@ -221878,6 +221965,7 @@ async function runFlockTurn(input, deps, options = {}) {
221878
221965
  task: task.slice(0, 300),
221879
221966
  ts: now11()
221880
221967
  });
221968
+ ensureFlockWorkersRegistered();
221881
221969
  let plan = null;
221882
221970
  if (options.plannerModelCall !== null) {
221883
221971
  const llmCtx = {
@@ -221917,7 +222005,6 @@ async function runFlockTurn(input, deps, options = {}) {
221917
222005
  });
221918
222006
  return await finishTurn(plan.reason);
221919
222007
  }
221920
- ensureFlockWorkersRegistered();
221921
222008
  for (const worker of plan.workers) {
221922
222009
  if (!worker.dynamicManifest) continue;
221923
222010
  registerWorkerManifest(worker.dynamicManifest);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perchai-cli",
3
- "version": "2.4.31",
3
+ "version": "2.4.32",
4
4
  "description": "Perch AI command-line interface",
5
5
  "bin": {
6
6
  "perch": "bin/perch"