opencrowd 0.5.4 → 0.6.1

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/bundle/opencrowd.js +652 -221
  2. package/package.json +1 -1
@@ -15548,7 +15548,7 @@ var init_commands = __esm({
15548
15548
  });
15549
15549
 
15550
15550
  // ../../packages/protocol/dist/events.js
15551
- var eventBase, runScoped, turnField, WorkerReadyEventSchema, CommandAcceptedEventSchema, CommandRejectionReasonSchema, CommandRejectedEventSchema, RunStateEventSchema, AssistantDeltaEventSchema, AssistantMessageEventSchema, ToolStartedEventSchema, ToolStatusSchema, ToolFinishedEventSchema, ArtifactCreatedEventSchema, UsageUpdatedEventSchema, ApprovalRequestSchema, ApprovalRequiredEventSchema, FundingRequiredEventSchema, DelegationProblemSchema, DelegationRequiredEventSchema, PaymentUnknownEventSchema, CheckpointReasonSchema, CheckpointCompletedEventSchema, RunFinishedEventSchema, RuntimeErrorEventSchema, UserMessageEventSchema, EVENT_TYPES, EventTypeSchema, EventSchema;
15551
+ var eventBase, runScoped, turnField, WorkerReadyEventSchema, CommandAcceptedEventSchema, CommandRejectionReasonSchema, CommandRejectedEventSchema, RunStateEventSchema, AssistantDeltaEventSchema, AssistantMessageEventSchema, ToolStartedEventSchema, ToolStatusSchema, ToolFinishedEventSchema, ModelStartedEventSchema, ModelFinishedEventSchema, ArtifactCreatedEventSchema, UsageUpdatedEventSchema, ApprovalRequestSchema, ApprovalRequiredEventSchema, FundingRequiredEventSchema, DelegationProblemSchema, DelegationRequiredEventSchema, PaymentUnknownEventSchema, CheckpointReasonSchema, CheckpointCompletedEventSchema, RunFinishedEventSchema, RuntimeErrorEventSchema, UserMessageEventSchema, EVENT_TYPES, EventTypeSchema, EventSchema;
15552
15552
  var init_events = __esm({
15553
15553
  "../../packages/protocol/dist/events.js"() {
15554
15554
  "use strict";
@@ -15667,6 +15667,22 @@ var init_events = __esm({
15667
15667
  ...turnField
15668
15668
  })
15669
15669
  });
15670
+ ModelStartedEventSchema = external_exports.looseObject({
15671
+ ...runScoped,
15672
+ type: external_exports.literal("model.started"),
15673
+ payload: external_exports.looseObject({ callId: IdSchema, model: external_exports.string(), ...turnField })
15674
+ });
15675
+ ModelFinishedEventSchema = external_exports.looseObject({
15676
+ ...runScoped,
15677
+ type: external_exports.literal("model.finished"),
15678
+ payload: external_exports.looseObject({
15679
+ callId: IdSchema,
15680
+ model: external_exports.string(),
15681
+ status: ToolStatusSchema,
15682
+ durationMs: external_exports.number().nonnegative(),
15683
+ ...turnField
15684
+ })
15685
+ });
15670
15686
  ArtifactCreatedEventSchema = external_exports.looseObject({
15671
15687
  ...runScoped,
15672
15688
  type: external_exports.literal("artifact.created"),
@@ -15805,6 +15821,8 @@ var init_events = __esm({
15805
15821
  "assistant.delta",
15806
15822
  "assistant.message",
15807
15823
  "user.message",
15824
+ "model.started",
15825
+ "model.finished",
15808
15826
  "tool.started",
15809
15827
  "tool.finished",
15810
15828
  "artifact.created",
@@ -15826,6 +15844,8 @@ var init_events = __esm({
15826
15844
  RunStateEventSchema,
15827
15845
  AssistantDeltaEventSchema,
15828
15846
  AssistantMessageEventSchema,
15847
+ ModelStartedEventSchema,
15848
+ ModelFinishedEventSchema,
15829
15849
  ToolStartedEventSchema,
15830
15850
  ToolFinishedEventSchema,
15831
15851
  ArtifactCreatedEventSchema,
@@ -15875,6 +15895,48 @@ var init_redact = __esm({
15875
15895
  }
15876
15896
  });
15877
15897
 
15898
+ // ../../packages/protocol/dist/telemetry.js
15899
+ function scrubText(text) {
15900
+ return text.replace(/-----BEGIN [^-]*PRIVATE KEY-----[\s\S]*?-----END [^-]*PRIVATE KEY-----/g, "[REDACTED]").replace(/\bBearer\s+[A-Za-z0-9._~+\/-]+=*/gi, "Bearer [REDACTED]").replace(/\b(?:sk-[A-Za-z0-9_-]{16,}|ph[csx]_[A-Za-z0-9_-]{16,}|gh[pousr]_[A-Za-z0-9]{20,}|eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)\b/g, "[REDACTED]").replace(/\b((?:[A-Z_]*(?:SECRET|PASSWORD|API_KEY|PRIVATE_KEY|ACCESS_TOKEN)[A-Z_]*|authorization|cookie|signature|x-amz-signature)\s*[=:]\s*)[^\s&,;]+/gi, "$1[REDACTED]").replace(/(https?:\/\/)[^\s/@]+:[^\s/@]+@/g, "$1[REDACTED]@");
15901
+ }
15902
+ function captureDetail(input2, maxBytes = 96 * 1024) {
15903
+ let redacted = false;
15904
+ const clean3 = (value2, depth = 0) => {
15905
+ if (depth > 30)
15906
+ return "[depth limit]";
15907
+ if (typeof value2 === "string") {
15908
+ const s3 = scrubText(value2);
15909
+ redacted ||= s3 !== value2;
15910
+ return s3;
15911
+ }
15912
+ if (Array.isArray(value2))
15913
+ return value2.map((v) => clean3(v, depth + 1));
15914
+ if (value2 && typeof value2 === "object") {
15915
+ return Object.fromEntries(Object.entries(value2).map(([key, v]) => {
15916
+ if (isSensitiveKey(key) || /^(signature|privatekey|seedphrase|mnemonic)$/i.test(key)) {
15917
+ redacted = true;
15918
+ return [key, "[REDACTED]"];
15919
+ }
15920
+ return [key, clean3(v, depth + 1)];
15921
+ }));
15922
+ }
15923
+ return typeof value2 === "bigint" ? value2.toString() : value2 ?? null;
15924
+ };
15925
+ const value = clean3(input2), json3 = JSON.stringify(value), bytes = new TextEncoder().encode(json3).length;
15926
+ return {
15927
+ value: bytes > maxBytes ? { preview: json3.slice(0, Math.floor(maxBytes / 6)) } : value,
15928
+ redacted,
15929
+ truncated: bytes > maxBytes,
15930
+ bytes
15931
+ };
15932
+ }
15933
+ var init_telemetry = __esm({
15934
+ "../../packages/protocol/dist/telemetry.js"() {
15935
+ "use strict";
15936
+ init_redact();
15937
+ }
15938
+ });
15939
+
15878
15940
  // ../../packages/protocol/dist/seq.js
15879
15941
  var init_seq = __esm({
15880
15942
  "../../packages/protocol/dist/seq.js"() {
@@ -16052,6 +16114,41 @@ var init_spending = __esm({
16052
16114
  }
16053
16115
  });
16054
16116
 
16117
+ // ../../packages/protocol/dist/financial-state.js
16118
+ var usdc, FinancialStateSchema;
16119
+ var init_financial_state = __esm({
16120
+ "../../packages/protocol/dist/financial-state.js"() {
16121
+ "use strict";
16122
+ init_zod();
16123
+ usdc = external_exports.string().regex(/^\d+\.\d{6}$/);
16124
+ FinancialStateSchema = external_exports.discriminatedUnion("status", [
16125
+ external_exports.object({
16126
+ status: external_exports.literal("available"),
16127
+ run_id: external_exports.string().uuid(),
16128
+ observed_at: external_exports.string().datetime(),
16129
+ currency: external_exports.literal("USDC"),
16130
+ wallet: external_exports.object({
16131
+ balance_status: external_exports.enum(["available", "unavailable"]),
16132
+ balance_usdc: usdc.nullable(),
16133
+ reserved_usdc: usdc,
16134
+ available_usdc: usdc.nullable()
16135
+ }),
16136
+ current_run: external_exports.object({
16137
+ inference_spent_usdc: usdc,
16138
+ service_spent_usdc: usdc,
16139
+ total_spent_usdc: usdc,
16140
+ reserved_usdc: usdc,
16141
+ budget_limit_usdc: usdc,
16142
+ remaining_budget_usdc: usdc,
16143
+ per_call_approval_threshold_usdc: usdc,
16144
+ approval_mode: external_exports.enum(["auto", "ask", "off"])
16145
+ })
16146
+ }),
16147
+ external_exports.object({ status: external_exports.literal("unavailable"), reason: external_exports.string() })
16148
+ ]);
16149
+ }
16150
+ });
16151
+
16055
16152
  // ../../packages/protocol/dist/index.js
16056
16153
  var init_dist = __esm({
16057
16154
  "../../packages/protocol/dist/index.js"() {
@@ -16062,10 +16159,12 @@ var init_dist = __esm({
16062
16159
  init_commands();
16063
16160
  init_events();
16064
16161
  init_redact();
16162
+ init_telemetry();
16065
16163
  init_seq();
16066
16164
  init_codec();
16067
16165
  init_context();
16068
16166
  init_spending();
16167
+ init_financial_state();
16069
16168
  }
16070
16169
  });
16071
16170
 
@@ -16348,7 +16447,7 @@ function normalizeConfig(value) {
16348
16447
  const proxyDefaults = providerDefaults(raw["openrouter-x402-proxy"] ?? raw.x402, DEFAULT_CONFIG["openrouter-x402-proxy"]);
16349
16448
  const mcpServers = recordValue(raw.mcpServers);
16350
16449
  const servers = { ...DEFAULT_CONFIG.mcpServers, ...mcpServers };
16351
- if (servers.crowdcode?.command === "npx" && ["0.5", "0.5.2"].some((version6) => JSON.stringify(servers.crowdcode.args) === JSON.stringify(["--yes", `crowdcode-mcp@${version6}`]))) {
16450
+ if (servers.crowdcode?.command === "npx" && ["0.5", "0.5.2", "0.5.3"].some((version6) => JSON.stringify(servers.crowdcode.args) === JSON.stringify(["--yes", `crowdcode-mcp@${version6}`]))) {
16352
16451
  servers.crowdcode = { ...servers.crowdcode, args: [...DEFAULT_CONFIG.mcpServers.crowdcode.args] };
16353
16452
  }
16354
16453
  return {
@@ -16398,7 +16497,7 @@ var init_config = __esm({
16398
16497
  configVersion: 3,
16399
16498
  mcpServers: {
16400
16499
  agentcash: { command: "npx", args: ["--yes", "agentcash@0.17"] },
16401
- crowdcode: { command: "npx", args: ["--yes", "crowdcode-mcp@0.5.3"] }
16500
+ crowdcode: { command: "npx", args: ["--yes", "crowdcode-mcp@0.6.0"] }
16402
16501
  },
16403
16502
  // GAIA provider benchmark (2026-08-25): same-model BlockRun matched the
16404
16503
  // current route's accuracy and completed the sample 6.7x faster. The
@@ -33523,6 +33622,9 @@ var init_crowdcode = __esm({
33523
33622
  constructor(connection) {
33524
33623
  this.connection = connection;
33525
33624
  }
33625
+ async manage(name, args) {
33626
+ return this.connection.call(name, args);
33627
+ }
33526
33628
  async getServiceScore(query) {
33527
33629
  const result = await this.connection.call("get_service_score", {
33528
33630
  ...query.apiEndpoint ? { api_endpoint: query.apiEndpoint } : {},
@@ -33555,6 +33657,53 @@ var init_crowdcode = __esm({
33555
33657
  }
33556
33658
  });
33557
33659
 
33660
+ // ../../packages/economy/dist/crowdcode-preferences.js
33661
+ import { mkdir as mkdir8, readFile as readFile8, rename as rename2, writeFile as writeFile4 } from "node:fs/promises";
33662
+ import { dirname as dirname7, join as join9 } from "node:path";
33663
+ import { randomUUID as randomUUID4 } from "node:crypto";
33664
+ var CrowdCodePreferences;
33665
+ var init_crowdcode_preferences = __esm({
33666
+ "../../packages/economy/dist/crowdcode-preferences.js"() {
33667
+ "use strict";
33668
+ CrowdCodePreferences = class {
33669
+ session;
33670
+ constructor(session) {
33671
+ this.session = session;
33672
+ }
33673
+ path(scope) {
33674
+ return join9(scope === "session" ? this.session.sessionDir : this.session.workspaceRoot, "crowdcode-preferences.json");
33675
+ }
33676
+ async read(scope) {
33677
+ try {
33678
+ const value = JSON.parse(await readFile8(this.path(scope), "utf8"));
33679
+ return typeof value.enabled === "boolean" ? value.enabled : void 0;
33680
+ } catch (error53) {
33681
+ if (error53.code === "ENOENT")
33682
+ return void 0;
33683
+ throw error53;
33684
+ }
33685
+ }
33686
+ async status() {
33687
+ const default_enabled = await this.read("default") ?? true;
33688
+ const session_enabled = await this.read("session");
33689
+ return { enabled: session_enabled ?? default_enabled, default_enabled, scope: session_enabled === void 0 ? "default" : "session" };
33690
+ }
33691
+ async write(scope, enabled) {
33692
+ const path3 = this.path(scope), temporary = `${path3}.${randomUUID4()}.tmp`;
33693
+ await mkdir8(dirname7(path3), { recursive: true });
33694
+ await writeFile4(temporary, JSON.stringify({ enabled }) + "\n", { mode: 384 });
33695
+ await rename2(temporary, path3);
33696
+ }
33697
+ async set(enabled, scope) {
33698
+ await this.write(scope, enabled);
33699
+ if (scope === "default")
33700
+ await this.write("session");
33701
+ return this.status();
33702
+ }
33703
+ };
33704
+ }
33705
+ });
33706
+
33558
33707
  // ../../packages/economy/dist/media.js
33559
33708
  import { createHash as createHash2 } from "node:crypto";
33560
33709
  async function extractMedia(session, value, depth = 0) {
@@ -33586,14 +33735,14 @@ var init_media = __esm({
33586
33735
  });
33587
33736
 
33588
33737
  // ../../packages/economy/dist/purchases.js
33589
- import { appendFile as appendFile3, mkdir as mkdir8, readFile as readFile8 } from "node:fs/promises";
33590
- import { dirname as dirname7, join as join9 } from "node:path";
33591
- import { randomUUID as randomUUID4 } from "node:crypto";
33738
+ import { appendFile as appendFile3, mkdir as mkdir9, readFile as readFile9 } from "node:fs/promises";
33739
+ import { dirname as dirname8, join as join10 } from "node:path";
33740
+ import { randomUUID as randomUUID5 } from "node:crypto";
33592
33741
  function purchasesPath(session) {
33593
- return join9(session.sessionDir, "purchases.jsonl");
33742
+ return join10(session.sessionDir, "purchases.jsonl");
33594
33743
  }
33595
33744
  function newPurchaseId() {
33596
- return `pur_${randomUUID4().slice(0, 12)}`;
33745
+ return `pur_${randomUUID5().slice(0, 12)}`;
33597
33746
  }
33598
33747
  async function appendPurchase(session, record3) {
33599
33748
  await appendPurchaseEvent(session, { type: "purchase", record: record3 });
@@ -33609,16 +33758,20 @@ async function recordReviewSubmitted(session, purchaseId, rating) {
33609
33758
  async function recordReviewFailed(session, purchaseId) {
33610
33759
  await appendPurchaseEvent(session, { type: "review_failed", purchase_id: purchaseId, attempted_at: (/* @__PURE__ */ new Date()).toISOString() });
33611
33760
  }
33761
+ async function skipPendingReviews(session) {
33762
+ for (const state of await pendingRequiredReviews(session))
33763
+ await appendPurchaseEvent(session, { type: "review_skipped", purchase_id: state.record.purchase_id });
33764
+ }
33612
33765
  async function appendPurchaseEvent(session, event) {
33613
33766
  const path3 = purchasesPath(session);
33614
- await mkdir8(dirname7(path3), { recursive: true });
33767
+ await mkdir9(dirname8(path3), { recursive: true });
33615
33768
  await appendFile3(path3, `${JSON.stringify(event)}
33616
33769
  `, "utf8");
33617
33770
  }
33618
33771
  async function listPurchases(session) {
33619
33772
  let text;
33620
33773
  try {
33621
- text = await readFile8(purchasesPath(session), "utf8");
33774
+ text = await readFile9(purchasesPath(session), "utf8");
33622
33775
  } catch (error53) {
33623
33776
  if (error53.code === "ENOENT") {
33624
33777
  return [];
@@ -33641,6 +33794,10 @@ async function listPurchases(session) {
33641
33794
  record: event.record,
33642
33795
  reviewStatus: event.record.review_required ? "pending" : "not_required"
33643
33796
  });
33797
+ } else if (event.type === "review_skipped") {
33798
+ const state = states.get(event.purchase_id);
33799
+ if (state)
33800
+ state.reviewStatus = "not_required";
33644
33801
  } else if (event.type === "review_failed") {
33645
33802
  const state = states.get(event.purchase_id);
33646
33803
  if (state)
@@ -33683,6 +33840,8 @@ var init_purchases = __esm({
33683
33840
  });
33684
33841
 
33685
33842
  // ../../packages/economy/dist/gateway.js
33843
+ import { readFile as readFile10, writeFile as writeFile5 } from "node:fs/promises";
33844
+ import { join as join11 } from "node:path";
33686
33845
  function inspectionKey(endpoint, method) {
33687
33846
  return `${method} ${endpoint}`;
33688
33847
  }
@@ -33743,11 +33902,17 @@ var GATEWAY_TOOL_NAMES, EconomyGateway, GATEWAY_TOOL_DEFINITIONS;
33743
33902
  var init_gateway = __esm({
33744
33903
  "../../packages/economy/dist/gateway.js"() {
33745
33904
  "use strict";
33905
+ init_crowdcode_preferences();
33746
33906
  init_media();
33747
33907
  init_dist2();
33748
33908
  init_approvals();
33749
33909
  init_purchases();
33750
33910
  GATEWAY_TOOL_NAMES = [
33911
+ "crowdcode_status",
33912
+ "set_crowdcode_enabled",
33913
+ "request_service",
33914
+ "list_my_reviews",
33915
+ "delete_my_review",
33751
33916
  "read_service",
33752
33917
  "get_wallet_status",
33753
33918
  "find_paid_service",
@@ -33758,10 +33923,36 @@ var init_gateway = __esm({
33758
33923
  ];
33759
33924
  EconomyGateway = class {
33760
33925
  options;
33761
- inspections = /* @__PURE__ */ new Map();
33926
+ /**
33927
+ * Inspections are keyed by endpoint+method and persisted under the session so
33928
+ * a run resumed on a fresh gateway instance (funds pause, worker restart) still
33929
+ * honours the inspect-before-call rule instead of failing its first call.
33930
+ */
33931
+ inspections;
33762
33932
  constructor(options) {
33763
33933
  this.options = options;
33764
33934
  }
33935
+ get inspectionsPath() {
33936
+ return join11(this.options.session.sessionDir, "inspections.json");
33937
+ }
33938
+ async loadInspections() {
33939
+ if (this.inspections)
33940
+ return this.inspections;
33941
+ const map3 = /* @__PURE__ */ new Map();
33942
+ try {
33943
+ const stored = JSON.parse(await readFile10(this.inspectionsPath, "utf8"));
33944
+ for (const [key, value] of Object.entries(stored))
33945
+ map3.set(key, value);
33946
+ } catch {
33947
+ }
33948
+ this.inspections = map3;
33949
+ return map3;
33950
+ }
33951
+ async rememberInspection(key, inspection) {
33952
+ const map3 = await this.loadInspections();
33953
+ map3.set(key, inspection);
33954
+ await writeFile5(this.inspectionsPath, JSON.stringify(Object.fromEntries(map3)), "utf8");
33955
+ }
33765
33956
  definitions() {
33766
33957
  return GATEWAY_TOOL_DEFINITIONS;
33767
33958
  }
@@ -33770,11 +33961,17 @@ var init_gateway = __esm({
33770
33961
  }
33771
33962
  /** True while a confirmed paid purchase still needs its required review. */
33772
33963
  async hasPendingRequiredReviews() {
33773
- return (await pendingRequiredReviews(this.options.session)).length > 0;
33964
+ return await this.crowdcodeEnabled() && (await pendingRequiredReviews(this.options.session)).length > 0;
33774
33965
  }
33775
33966
  async execute(name, args, operationId) {
33776
33967
  try {
33777
33968
  switch (name) {
33969
+ case "crowdcode_status":
33970
+ case "set_crowdcode_enabled":
33971
+ case "request_service":
33972
+ case "list_my_reviews":
33973
+ case "delete_my_review":
33974
+ return await this.manageCrowdCode(name, args);
33778
33975
  case "get_wallet_status":
33779
33976
  return await this.getWalletStatus();
33780
33977
  case "find_paid_service":
@@ -33798,6 +33995,38 @@ var init_gateway = __esm({
33798
33995
  return { ok: false, error: error53.message };
33799
33996
  }
33800
33997
  }
33998
+ async crowdcodeEnabled() {
33999
+ if (!this.options.hostedSpending && !this.options.crowdcode.manage)
34000
+ return true;
34001
+ const status = await this.manageCrowdCode("crowdcode_status", {});
34002
+ if (!status.ok)
34003
+ throw new Error(status.error ?? "CrowdCode preferences unavailable");
34004
+ return status.data?.enabled === true;
34005
+ }
34006
+ async manageCrowdCode(name, args) {
34007
+ if (name === "set_crowdcode_enabled") {
34008
+ if (typeof args.enabled !== "boolean" || args.scope !== void 0 && args.scope !== "session" && args.scope !== "default")
34009
+ return { ok: false, error: "Provide enabled (boolean) and scope (session or default)" };
34010
+ }
34011
+ if (this.options.hostedSpending && (name === "crowdcode_status" || name === "set_crowdcode_enabled")) {
34012
+ const preferences = new CrowdCodePreferences(this.options.session);
34013
+ const data = name === "crowdcode_status" ? await preferences.status() : await preferences.set(args.enabled, args.scope ?? "session");
34014
+ if (name === "set_crowdcode_enabled" && args.enabled === false)
34015
+ await skipPendingReviews(this.options.session);
34016
+ return { ok: true, data };
34017
+ }
34018
+ if (name === "request_service" && !await this.crowdcodeEnabled())
34019
+ return { ok: false, error: "CrowdCode is off. Turn it on to submit service requests." };
34020
+ if (!this.options.crowdcode.manage)
34021
+ return { ok: false, error: "CrowdCode management is unavailable" };
34022
+ const result = await this.options.crowdcode.manage(name, args);
34023
+ if (result.ok && name === "set_crowdcode_enabled" && args.enabled === false)
34024
+ await skipPendingReviews(this.options.session);
34025
+ return result;
34026
+ }
34027
+ async serviceEvidence(endpoint) {
34028
+ return await this.crowdcodeEnabled() ? this.options.crowdcode.getServiceScore({ apiEndpoint: endpoint }) : { ok: true, unproven: true, summary: "CrowdCode is off; reputation checks and submissions are disabled." };
34029
+ }
33801
34030
  async getWalletStatus() {
33802
34031
  const result = await this.options.agentcash.getBalance();
33803
34032
  if (!result.ok) {
@@ -33832,10 +34061,10 @@ var init_gateway = __esm({
33832
34061
  if (!schema.ok) {
33833
34062
  return { ok: false, error: schema.error };
33834
34063
  }
33835
- const evidence = await this.options.crowdcode.getServiceScore({ apiEndpoint: endpoint });
34064
+ const evidence = await this.serviceEvidence(endpoint);
33836
34065
  const rail = railFromSchema(schema.data);
33837
34066
  const priceCeilingCents = priceCeilingFromSchema(schema.data);
33838
- this.inspections.set(inspectionKey(endpoint, method), {
34067
+ await this.rememberInspection(inspectionKey(endpoint, method), {
33839
34068
  endpoint,
33840
34069
  method,
33841
34070
  rail,
@@ -33869,7 +34098,7 @@ var init_gateway = __esm({
33869
34098
  error: "external-service purchases are disabled (approval mode `off`). Local tools and LLM inference remain available; switch with /approval ask|auto."
33870
34099
  };
33871
34100
  }
33872
- const pending = await pendingRequiredReviews(session);
34101
+ const pending = await this.crowdcodeEnabled() ? await pendingRequiredReviews(session) : [];
33873
34102
  if (pending.length > 0) {
33874
34103
  return {
33875
34104
  ok: false,
@@ -33881,7 +34110,7 @@ var init_gateway = __esm({
33881
34110
  return { ok: false, error: "call_paid_service requires `url`" };
33882
34111
  }
33883
34112
  const method = (stringArg(args.method) ?? "POST").toUpperCase();
33884
- const inspection = this.inspections.get(inspectionKey(endpoint, method));
34113
+ const inspection = (await this.loadInspections()).get(inspectionKey(endpoint, method));
33885
34114
  if (!inspection) {
33886
34115
  return { ok: false, error: `inspect_paid_service must run for ${method} ${endpoint} before call_paid_service` };
33887
34116
  }
@@ -33908,7 +34137,7 @@ var init_gateway = __esm({
33908
34137
  if (quotedCostCents === void 0) {
33909
34138
  return { ok: false, error: "no price ceiling: pass `max_cost_cents` (the inspection did not report a price)" };
33910
34139
  }
33911
- const evidence = await this.options.crowdcode.getServiceScore({ apiEndpoint: endpoint });
34140
+ const evidence = await this.serviceEvidence(endpoint);
33912
34141
  if (!evidence.ok) {
33913
34142
  return {
33914
34143
  ok: false,
@@ -33967,7 +34196,7 @@ var init_gateway = __esm({
33967
34196
  artifact_path: artifact?.path,
33968
34197
  // Confirmed paid successes AND paid failures require reviews; free,
33969
34198
  // SIWX, and unknown outcomes create no paid receipt to review.
33970
- review_required: paid && supportedRail,
34199
+ review_required: paid && supportedRail && await this.crowdcodeEnabled(),
33971
34200
  evidence: result.payment,
33972
34201
  notes: result.ambiguous ? `${result.ambiguityReason ?? "ambiguous"}: payment state unknown; never auto-retried` : result.error
33973
34202
  };
@@ -33989,6 +34218,7 @@ var init_gateway = __esm({
33989
34218
  if (outcome === "unknown") {
33990
34219
  const missingReceipt = result.ambiguityReason === "missing_receipt";
33991
34220
  const unsupportedReceipt = result.ambiguityReason === "unsupported_receipt";
34221
+ const timedOut = result.ambiguityReason === "timeout";
33992
34222
  return {
33993
34223
  ok: false,
33994
34224
  error: missingReceipt ? [
@@ -33997,6 +34227,9 @@ var init_gateway = __esm({
33997
34227
  ].join(" ") : unsupportedReceipt ? [
33998
34228
  `the call to ${endpoint} returned a settlement receipt on an unsupported payment rail (recorded as purchase ${purchaseId}).`,
33999
34229
  "It was NOT retried and must not be retried automatically; reconcile the payment manually before continuing."
34230
+ ].join(" ") : timedOut ? [
34231
+ `the call to ${endpoint} did not answer within the wait limit and its payment state is unknown (recorded as purchase ${purchaseId}).`,
34232
+ "The stored purchase was checked once without a final result. It was NOT retried and must not be retried automatically; the owner can reconcile it from the payment ledger."
34000
34233
  ].join(" ") : [
34001
34234
  `the call to ${endpoint} failed in transport and its payment state is unknown (recorded as purchase ${purchaseId}).`,
34002
34235
  "It was NOT retried and must not be retried automatically; verify the service state before calling again."
@@ -34083,6 +34316,8 @@ var init_gateway = __esm({
34083
34316
  return void 0;
34084
34317
  }
34085
34318
  async reviewPaidService(args) {
34319
+ if (!await this.crowdcodeEnabled())
34320
+ return { ok: false, error: "CrowdCode is off; review submission is disabled." };
34086
34321
  const purchaseId = stringArg(args.purchase_id);
34087
34322
  const rating = intArg(args.rating);
34088
34323
  const reason = stringArg(args.reason);
@@ -34164,6 +34399,11 @@ var init_gateway = __esm({
34164
34399
  }
34165
34400
  };
34166
34401
  GATEWAY_TOOL_DEFINITIONS = [
34402
+ { name: "crowdcode_status", description: "Check whether CrowdCode is enabled for this session and by default.", parameters: { type: "object", properties: {}, additionalProperties: false } },
34403
+ { name: "set_crowdcode_enabled", description: "Handle 'CrowdCode on/off'. Disable reputation checks, automatic reviews and requests. Default scope is this session; scope default also sets the agent default for future sessions. Listing and deleting your reviews remain available while off. Does not change spending permissions.", parameters: { type: "object", properties: { enabled: { type: "boolean" }, scope: { type: "string", enum: ["session", "default"] } }, required: ["enabled"], additionalProperties: false } },
34404
+ { name: "request_service", description: "Before finishing a real task, record a concrete service worth paying for that would fix an observed failure, poor result, excessive cost or detour. State exact input, paid deliverable, acceptance criteria, actual obstacle and why paying is worthwhile. No purchase or spending authority is required. Skip generic Python/runtime wishes, web search that worked well, and gaps without a sellable remedy. Submit distinct gaps once; submit nothing if everything worked well and cheaply. Exclude private data and secrets.", parameters: { type: "object", properties: { service_description: { type: "string", maxLength: 8e3 }, task_context: { type: "string", maxLength: 4e3 } }, required: ["service_description"], additionalProperties: false } },
34405
+ { name: "list_my_reviews", description: "List this agent's own submitted reviews with IDs for selective deletion; works while CrowdCode is off. Paginate with next_before_id.", parameters: { type: "object", properties: { before_id: { type: "integer", minimum: 0 }, limit: { type: "integer", minimum: 1, maximum: 100 } }, additionalProperties: false } },
34406
+ { name: "delete_my_review", description: "Delete one of this agent's reviews when the user asks, using its ID from list_my_reviews. Works while CrowdCode is off. Never delete unrelated reviews.", parameters: { type: "object", properties: { review_id: { type: "integer", minimum: 1 } }, required: ["review_id"], additionalProperties: false } },
34167
34407
  {
34168
34408
  name: "read_service",
34169
34409
  description: "Read a service URL without payment, authenticating with the wallet when required (SIWX). Use this to poll a paid generation job until complete; never resubmit a pending job. Download returned media URLs with run_shell.",
@@ -34452,7 +34692,7 @@ async function sharedEconomyRuntime(log) {
34452
34692
  agentcash: new McpAgentCashAdapter(agentcashConnection),
34453
34693
  crowdcode: new McpCrowdCodeAdapter(crowdcodeConnection),
34454
34694
  instructions: () => [agentcashConnection, crowdcodeConnection].map((connection) => connection.instructions()).filter((text) => Boolean(text)).map((text, index2) => `Instructions from the ${index2 === 0 ? "agentcash" : "crowdcode"} vendor:
34455
- ${text.slice(0, 2400)}`),
34695
+ ${text.slice(0, 16e3)}`),
34456
34696
  close: async () => {
34457
34697
  await Promise.all([agentcashConnection.close(), crowdcodeConnection.close()]);
34458
34698
  shared = void 0;
@@ -34518,7 +34758,7 @@ var init_dist4 = __esm({
34518
34758
 
34519
34759
  // ../../packages/agent-runtime/dist/context.js
34520
34760
  import { createHash as createHash3 } from "node:crypto";
34521
- import { relative as relative3, join as join10 } from "node:path";
34761
+ import { relative as relative3, join as join12 } from "node:path";
34522
34762
  async function completeWithContext(session, messages, options) {
34523
34763
  for (; ; ) {
34524
34764
  options.signal?.throwIfAborted();
@@ -34576,13 +34816,13 @@ async function compactContext(session, messages, options) {
34576
34816
  return { tokensBefore, tokensAfter: tokensBefore };
34577
34817
  const raw = messages.map((message) => JSON.stringify(message)).join("\n") + "\n";
34578
34818
  const digest = createHash3("sha256").update(raw).digest("hex");
34579
- const dir = await containedPath(session.sessionDir, join10("context", digest));
34580
- const path3 = join10(dir, "transcript.jsonl");
34819
+ const dir = await containedPath(session.sessionDir, join12("context", digest));
34820
+ const path3 = join12(dir, "transcript.jsonl");
34581
34821
  await atomicWrite(path3, raw);
34582
34822
  const archivePath = relative3(session.workspaceRoot, path3).split("\\").join("/");
34583
34823
  const ref = (index2) => `${relative3(session.workspaceRoot, dir).split("\\").join("/")}/message-${index2 + 1}.txt`;
34584
34824
  const externalize = async (message, index2) => {
34585
- await atomicWrite(join10(dir, `message-${index2 + 1}.txt`), messages[index2].content);
34825
+ await atomicWrite(join12(dir, `message-${index2 + 1}.txt`), messages[index2].content);
34586
34826
  return `[Full ${message.role} message saved verbatim to ${ref(index2)}. Use rg/grep and sed/head/tail to read relevant portions before proceeding; do not load the entire file.]`;
34587
34827
  };
34588
34828
  const list = messages.map((m, index2) => ({ message: structuredClone(m), index: index2 })).filter(({ message }) => !message.contextArchive);
@@ -34644,11 +34884,11 @@ var init_context2 = __esm({
34644
34884
  });
34645
34885
 
34646
34886
  // ../../packages/agent-runtime/dist/knowledge.js
34647
- import { access, cp, mkdir as mkdir9, readFile as readFile9, writeFile as writeFile4 } from "node:fs/promises";
34648
- import { dirname as dirname8, join as join11, resolve as resolve4 } from "node:path";
34887
+ import { access, cp, mkdir as mkdir10, readFile as readFile11, writeFile as writeFile6 } from "node:fs/promises";
34888
+ import { dirname as dirname9, join as join13, resolve as resolve4 } from "node:path";
34649
34889
  import { fileURLToPath } from "node:url";
34650
34890
  function bundledKnowledgeDir() {
34651
- return resolve4(dirname8(fileURLToPath(import.meta.url)), "..", "knowledge");
34891
+ return resolve4(dirname9(fileURLToPath(import.meta.url)), "..", "knowledge");
34652
34892
  }
34653
34893
  function knowledgeDisabledByEnv() {
34654
34894
  const value = process.env.OPENCROWD_KNOWLEDGE_DIR?.trim().toLowerCase();
@@ -34664,7 +34904,7 @@ async function resolveKnowledgeDir(options = {}) {
34664
34904
  }
34665
34905
  const bundled = bundledKnowledgeDir();
34666
34906
  try {
34667
- await access(join11(bundled, "L0.md"));
34907
+ await access(join13(bundled, "L0.md"));
34668
34908
  return bundled;
34669
34909
  } catch {
34670
34910
  return void 0;
@@ -34677,20 +34917,20 @@ async function loadKnowledgeTree(session, options = {}) {
34677
34917
  }
34678
34918
  let l0;
34679
34919
  try {
34680
- l0 = (await readFile9(join11(dir, "L0.md"), "utf8")).trim();
34920
+ l0 = (await readFile11(join13(dir, "L0.md"), "utf8")).trim();
34681
34921
  } catch {
34682
34922
  return void 0;
34683
34923
  }
34684
34924
  const version6 = await readVersion(dir, l0);
34685
- const target = join11(session.artifactsDir, "knowledge");
34925
+ const target = join13(session.artifactsDir, "knowledge");
34686
34926
  if (await currentVersion(target) !== version6) {
34687
- await mkdir9(session.artifactsDir, { recursive: true });
34927
+ await mkdir10(session.artifactsDir, { recursive: true });
34688
34928
  await cp(dir, target, {
34689
34929
  recursive: true,
34690
34930
  force: true,
34691
34931
  filter: (source) => !source.endsWith("proposal.raw.txt")
34692
34932
  });
34693
- await writeFile4(join11(target, VERSION_FILE), `${version6}
34933
+ await writeFile6(join13(target, VERSION_FILE), `${version6}
34694
34934
  `, "utf8");
34695
34935
  }
34696
34936
  if (session.knowledge?.version !== version6 || session.knowledge?.source !== dir) {
@@ -34708,7 +34948,7 @@ function renderCapabilityIndex(l0) {
34708
34948
  }
34709
34949
  async function readVersion(dir, l0) {
34710
34950
  try {
34711
- const meta4 = JSON.parse(await readFile9(join11(dir, "meta.json"), "utf8"));
34951
+ const meta4 = JSON.parse(await readFile11(join13(dir, "meta.json"), "utf8"));
34712
34952
  if (typeof meta4.content_hash === "string" && meta4.content_hash) {
34713
34953
  return meta4.id ? `${meta4.id}@${meta4.content_hash}` : meta4.content_hash;
34714
34954
  }
@@ -34719,7 +34959,7 @@ async function readVersion(dir, l0) {
34719
34959
  }
34720
34960
  async function currentVersion(target) {
34721
34961
  try {
34722
- return (await readFile9(join11(target, VERSION_FILE), "utf8")).trim();
34962
+ return (await readFile11(join13(target, VERSION_FILE), "utf8")).trim();
34723
34963
  } catch {
34724
34964
  return void 0;
34725
34965
  }
@@ -35345,7 +35585,7 @@ function alphabet(letters) {
35345
35585
  };
35346
35586
  }
35347
35587
  // @__NO_SIDE_EFFECTS__
35348
- function join12(separator = "") {
35588
+ function join14(separator = "") {
35349
35589
  astr("join", separator);
35350
35590
  return {
35351
35591
  encode: (from16) => {
@@ -35425,7 +35665,7 @@ function radix(num2) {
35425
35665
  var genBase58, base58;
35426
35666
  var init_esm = __esm({
35427
35667
  "../../node_modules/@scure/base/lib/esm/index.js"() {
35428
- genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join12(""));
35668
+ genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join14(""));
35429
35669
  base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
35430
35670
  }
35431
35671
  });
@@ -79842,14 +80082,29 @@ var init_llm_runtime = __esm({
79842
80082
 
79843
80083
  // ../../packages/agent-runtime/dist/economy-tools.js
79844
80084
  function economyTools(economy, options = {}) {
80085
+ let reflected = false;
80086
+ const supportsReflection = economy.definitions().some((tool) => tool.name === "request_service");
79845
80087
  return {
79846
80088
  definitions: economy.definitions().filter((tool) => !options.hidden?.has(tool.name)),
79847
80089
  execute: async (name, args, operationId) => {
79848
80090
  if (options.resuming && name === "call_paid_service")
79849
80091
  await economy.execute("inspect_paid_service", { url: args.url, method: args.method, sample_body: args.body });
79850
- return economy.execute(name, args, operationId);
80092
+ const result = await economy.execute(name, args, operationId);
80093
+ if (name === "request_service" && result.ok)
80094
+ reflected = true;
80095
+ return result;
79851
80096
  },
79852
- completionGate: async () => !await economy.hasPendingRequiredReviews() ? void 0 : "a paid purchase still needs its required review; submit it with review_paid_service"
80097
+ completionGate: async (alreadyNudged = false) => {
80098
+ const pending = await economy.hasPendingRequiredReviews();
80099
+ const review = pending ? "A paid purchase still needs its required review; submit it with review_paid_service." : "";
80100
+ if (reflected || alreadyNudged || !supportsReflection)
80101
+ return review || void 0;
80102
+ reflected = true;
80103
+ const status = await economy.execute("crowdcode_status", {});
80104
+ if (!status.ok || !status.data?.enabled)
80105
+ return review || void 0;
80106
+ return [review, "Before your final answer, reflect once: What concrete services would have been worth paying for to solve this task? For each observed failure, poor result, excessive cost or avoidable detour with a reusable paid remedy, call request_service. Specify exact inputs, the paid deliverable, acceptance criteria, the actual use case and why paying would help. A prior purchase or spending permission is not required. Do not invent budgets. Skip generic local computation, ordinary agent mistakes without a sellable remedy, and services such as web search that already worked well. If everything worked well and cheaply, submit nothing. Then finish the user's task."].filter(Boolean).join(" ");
80107
+ }
79853
80108
  };
79854
80109
  }
79855
80110
  var init_economy_tools = __esm({
@@ -79860,9 +80115,9 @@ var init_economy_tools = __esm({
79860
80115
  });
79861
80116
 
79862
80117
  // ../../packages/agent-runtime/dist/runtime.js
79863
- import { readFile as readFile10, rm as rm2 } from "node:fs/promises";
79864
- import { join as join17 } from "node:path";
79865
- import { randomUUID as randomUUID5 } from "node:crypto";
80118
+ import { readFile as readFile12, rm as rm2 } from "node:fs/promises";
80119
+ import { join as join19 } from "node:path";
80120
+ import { randomUUID as randomUUID6 } from "node:crypto";
79866
80121
  function createOpenCrowdRuntime(options) {
79867
80122
  const storage = options.storage ?? localRuntimeStorage;
79868
80123
  async function prepare(session, runOptions) {
@@ -79889,10 +80144,10 @@ function createOpenCrowdRuntime(options) {
79889
80144
  };
79890
80145
  }
79891
80146
  async function execute2(session, task, runOptions = {}) {
79892
- const path3 = join17(session.sessionDir, "query-checkpoint.json");
80147
+ const path3 = join19(session.sessionDir, "query-checkpoint.json");
79893
80148
  let persisted;
79894
80149
  try {
79895
- persisted = JSON.parse(await readFile10(path3, "utf8"));
80150
+ persisted = JSON.parse(await readFile12(path3, "utf8"));
79896
80151
  } catch (error53) {
79897
80152
  if (error53.code !== "ENOENT")
79898
80153
  throw error53;
@@ -79900,7 +80155,7 @@ function createOpenCrowdRuntime(options) {
79900
80155
  const resuming = task === "" && !!persisted;
79901
80156
  if (persisted && !resuming)
79902
80157
  throw new Error("A query is unfinished. Resume it or decline its pending approval before starting another query.");
79903
- const saved = resuming ? persisted : { id: runOptions.runId ?? randomUUID5(), task };
80158
+ const saved = resuming ? persisted : { id: runOptions.runId ?? randomUUID6(), task };
79904
80159
  await beginQuery(session, saved.id);
79905
80160
  const checkpoint = async (value) => {
79906
80161
  saved.checkpoint = value;
@@ -79962,7 +80217,7 @@ import { isAbsolute as isAbsolute3 } from "node:path";
79962
80217
  function createHostedProvider(options) {
79963
80218
  if (!isAbsolute3(options.socketPath))
79964
80219
  throw new Error("Hosted bridge socket must be absolute");
79965
- const tools = [...OPEN_CROWD_TOOLS.filter((tool) => !["spawn_subagent", "check_subagents"].includes(tool.name)), ...options.extraTools ?? []];
80220
+ const tools = [...OPEN_CROWD_TOOLS.filter((tool) => !["spawn_subagent", "check_subagents"].includes(tool.name)).map((tool) => tool.name === "get_budget_status" ? { ...tool, description: "Read authoritative hosted finances: live USDC wallet balance, settled inference and service spending, pending holds, and remaining authorized budget for this run." } : tool), ...options.extraTools ?? []];
79966
80221
  return {
79967
80222
  async complete(messages, context) {
79968
80223
  const operationId = context?.operationId;
@@ -80042,6 +80297,16 @@ function rejectedRequest(status, text) {
80042
80297
  return void 0;
80043
80298
  }
80044
80299
  }
80300
+ async function readHostedFinancialState(options) {
80301
+ try {
80302
+ const reply = await postHostedTool(options, "economy.balance", {}, { timeoutMs: 1e4 });
80303
+ const parsed = FinancialStateSchema.safeParse(reply.data?.financial_state);
80304
+ if (reply.ok && parsed.success && parsed.data.status === "available" && parsed.data.run_id === options.runId)
80305
+ return parsed.data;
80306
+ } catch {
80307
+ }
80308
+ return { status: "unavailable", reason: "Hosted financial state could not be read. Do not infer balance or spending from the local session budget." };
80309
+ }
80045
80310
  async function postHostedTool(options, name, args, settings = {}) {
80046
80311
  if (!isAbsolute3(options.socketPath))
80047
80312
  throw new Error("Hosted bridge socket must be absolute");
@@ -80076,7 +80341,8 @@ async function postHostedTool(options, name, args, settings = {}) {
80076
80341
  }
80077
80342
  });
80078
80343
  });
80079
- req.setTimeout(settings.timeoutMs ?? SERVICE_BRIDGE_TIMEOUT_MS, () => req.destroy(new Error("Hosted tool timed out")));
80344
+ const timeoutMs = settings.timeoutMs ?? SERVICE_BRIDGE_TIMEOUT_MS;
80345
+ req.setTimeout(timeoutMs, () => req.destroy(new HostedToolTimeout(name, timeoutMs)));
80080
80346
  req.on("error", reject);
80081
80347
  req.end(body);
80082
80348
  });
@@ -80110,7 +80376,7 @@ function createHostedToolExecutor(options) {
80110
80376
  }
80111
80377
  };
80112
80378
  }
80113
- var HostedRequestError, HOSTED_TOOL_REQUEST_BYTES;
80379
+ var HostedRequestError, HOSTED_TOOL_REQUEST_BYTES, HostedToolTimeout;
80114
80380
  var init_hosted_provider = __esm({
80115
80381
  "../../packages/agent-runtime/dist/hosted-provider.js"() {
80116
80382
  "use strict";
@@ -80128,29 +80394,39 @@ var init_hosted_provider = __esm({
80128
80394
  }
80129
80395
  };
80130
80396
  HOSTED_TOOL_REQUEST_BYTES = 1024 * 1024;
80397
+ HostedToolTimeout = class extends Error {
80398
+ timeoutMs;
80399
+ code = "hosted_tool_timeout";
80400
+ constructor(name, timeoutMs) {
80401
+ super(`Hosted tool ${name} timed out after ${Math.round(timeoutMs / 1e3)}s`);
80402
+ this.timeoutMs = timeoutMs;
80403
+ this.name = "HostedToolTimeout";
80404
+ }
80405
+ };
80131
80406
  }
80132
80407
  });
80133
80408
 
80134
80409
  // ../../packages/agent-runtime/dist/hosted-economy.js
80135
- import { randomUUID as randomUUID6, createHash as createHash4 } from "node:crypto";
80136
- import { join as join18 } from "node:path";
80410
+ import { randomUUID as randomUUID7, createHash as createHash4 } from "node:crypto";
80411
+ import { join as join20 } from "node:path";
80137
80412
  function createHostedEconomy(options) {
80138
80413
  const fetcher = options.fetcher ?? fetch;
80139
80414
  const socket = { socketPath: options.socketPath, runId: options.runId, sessionId: options.sessionId };
80140
80415
  const directory = new ServiceDirectory(fetcher, (options.crowdcodeBase ?? DEFAULT_CROWDCODE_BASE).replace(/\/+$/, ""));
80141
80416
  return new EconomyGateway({
80142
80417
  session: options.session,
80143
- agentcash: new HostedAgentCashAdapter(directory, socket, fetcher),
80418
+ agentcash: new HostedAgentCashAdapter(directory, socket, fetcher, options.reconcileDelayMs),
80144
80419
  crowdcode: new HostedCrowdCodeAdapter(directory, socket),
80145
80420
  approvalMode: "auto",
80146
80421
  hostedSpending: true,
80147
80422
  minServiceScore: 2,
80148
80423
  // Hosted rules live with the agent's session, never in a user config dir.
80149
- approvalRulesPath: join18(options.session.sessionDir, "approval-rules.json")
80424
+ approvalRulesPath: join20(options.session.sessionDir, "approval-rules.json")
80150
80425
  });
80151
80426
  }
80152
80427
  function hostedDynamicTools(economy) {
80153
- return economyTools(economy, { hidden: HIDDEN_HOSTED_TOOLS });
80428
+ const tools = economyTools(economy, { hidden: HIDDEN_HOSTED_TOOLS });
80429
+ return { ...tools, definitions: tools.definitions.map((tool) => tool.name === "get_wallet_status" ? { ...tool, description: "Read this hosted agent's USDC wallet balance and authoritative current-run inference spending, service spending, payment holds and authorized budget. Read-only." } : tool) };
80154
80430
  }
80155
80431
  function parseListedService(raw) {
80156
80432
  const row = objectValue4(raw);
@@ -80214,7 +80490,7 @@ function numberValue6(value) {
80214
80490
  }
80215
80491
  return void 0;
80216
80492
  }
80217
- var DEFAULT_CROWDCODE_BASE, LIST_CACHE_MS, PAY_TIMEOUT_MS, FREE_FETCH_TIMEOUT_MS, USDC_ATOMIC_PER_USD, HIDDEN_HOSTED_TOOLS, ServiceDirectory, HostedAgentCashAdapter, HostedCrowdCodeAdapter;
80493
+ var DEFAULT_CROWDCODE_BASE, LIST_CACHE_MS, PAY_TIMEOUT_MS, RECONCILE_DELAY_MS, NOT_SENT_CODES, FREE_FETCH_TIMEOUT_MS, USDC_ATOMIC_PER_USD, HIDDEN_HOSTED_TOOLS, ServiceDirectory, HostedAgentCashAdapter, HostedCrowdCodeAdapter;
80218
80494
  var init_hosted_economy = __esm({
80219
80495
  "../../packages/agent-runtime/dist/hosted-economy.js"() {
80220
80496
  "use strict";
@@ -80222,14 +80498,17 @@ var init_hosted_economy = __esm({
80222
80498
  init_worker();
80223
80499
  init_dist2();
80224
80500
  init_dist4();
80501
+ init_dist();
80225
80502
  init_hosted_provider();
80226
80503
  init_economy_tools();
80227
80504
  DEFAULT_CROWDCODE_BASE = "https://crowdcode-backend.onrender.com";
80228
80505
  LIST_CACHE_MS = 6e4;
80229
- PAY_TIMEOUT_MS = 12e4;
80506
+ PAY_TIMEOUT_MS = SERVICE_GATEWAY_TIMEOUT_MS + 3e4;
80507
+ RECONCILE_DELAY_MS = 2e3;
80508
+ NOT_SENT_CODES = /* @__PURE__ */ new Set(["ENOENT", "ECONNREFUSED", "EACCES", "ENOTDIR"]);
80230
80509
  FREE_FETCH_TIMEOUT_MS = 3e4;
80231
80510
  USDC_ATOMIC_PER_USD = 1e6;
80232
- HIDDEN_HOSTED_TOOLS = /* @__PURE__ */ new Set(["bridge_usdc", "get_wallet_status"]);
80511
+ HIDDEN_HOSTED_TOOLS = /* @__PURE__ */ new Set(["bridge_usdc"]);
80233
80512
  ServiceDirectory = class {
80234
80513
  fetcher;
80235
80514
  base;
@@ -80276,12 +80555,14 @@ var init_hosted_economy = __esm({
80276
80555
  directory;
80277
80556
  socket;
80278
80557
  fetcher;
80558
+ reconcileDelayMs;
80279
80559
  /** Rails observed by inspection; `fetch` refuses anything but Base x402 regardless of the caller's rail. */
80280
80560
  inspectedRails = /* @__PURE__ */ new Map();
80281
- constructor(directory, socket, fetcher) {
80561
+ constructor(directory, socket, fetcher, reconcileDelayMs = RECONCILE_DELAY_MS) {
80282
80562
  this.directory = directory;
80283
80563
  this.socket = socket;
80284
80564
  this.fetcher = fetcher;
80565
+ this.reconcileDelayMs = reconcileDelayMs;
80285
80566
  this.discovery = new BaseServiceDiscovery(async (query, options) => {
80286
80567
  const reply = await postHostedTool(this.socket, "economy.read", {
80287
80568
  url: "https://agentcash.dev/api/search",
@@ -80336,25 +80617,32 @@ var init_hosted_economy = __esm({
80336
80617
  const method = request2.method.toUpperCase();
80337
80618
  const body = request2.body === void 0 ? void 0 : typeof request2.body === "string" ? request2.body : JSON.stringify(request2.body);
80338
80619
  const hash5 = request2.operationId ? createHash4("sha256").update(`${this.socket.runId}:${request2.operationId}`).digest("hex") : void 0;
80339
- const purchaseId = hash5 ? `${hash5.slice(0, 8)}-${hash5.slice(8, 12)}-4${hash5.slice(13, 16)}-8${hash5.slice(17, 20)}-${hash5.slice(20, 32)}` : randomUUID6();
80340
- let reply;
80620
+ const purchaseId = hash5 ? `${hash5.slice(0, 8)}-${hash5.slice(8, 12)}-4${hash5.slice(13, 16)}-8${hash5.slice(17, 20)}-${hash5.slice(20, 32)}` : randomUUID7();
80621
+ const payArgs = {
80622
+ purchase_request_id: purchaseId,
80623
+ service_id: serviceId,
80624
+ url: request2.url,
80625
+ method,
80626
+ body,
80627
+ max_cost_cents: Math.ceil(request2.maxAmountUsd * 100)
80628
+ };
80629
+ const timeoutMs = Math.min(request2.timeoutMs ?? PAY_TIMEOUT_MS, PAY_TIMEOUT_MS);
80630
+ let reply, timedOut = false;
80341
80631
  try {
80342
- reply = await postHostedTool(this.socket, "economy.pay", {
80343
- purchase_request_id: purchaseId,
80344
- service_id: serviceId,
80345
- url: request2.url,
80346
- method,
80347
- body,
80348
- max_cost_cents: Math.ceil(request2.maxAmountUsd * 100)
80349
- }, { timeoutMs: request2.timeoutMs ?? PAY_TIMEOUT_MS });
80632
+ reply = await postHostedTool(this.socket, "economy.pay", payArgs, { timeoutMs });
80350
80633
  } catch (error53) {
80351
- return {
80352
- ok: false,
80353
- ambiguous: true,
80354
- ambiguityReason: "transport",
80355
- data: void 0,
80356
- error: `payment request to the supervisor failed in transport: ${error53.message}`
80357
- };
80634
+ timedOut = error53 instanceof HostedToolTimeout;
80635
+ const recovered = await this.reconcile(error53, payArgs, timeoutMs);
80636
+ if (!recovered) {
80637
+ return {
80638
+ ok: false,
80639
+ ambiguous: true,
80640
+ ambiguityReason: timedOut ? "timeout" : "transport",
80641
+ data: void 0,
80642
+ error: timedOut ? `the paid call did not answer within ${Math.round(timeoutMs / 1e3)}s and its stored purchase has no final result yet` : `payment request to the supervisor failed in transport: ${error53.message}`
80643
+ };
80644
+ }
80645
+ reply = recovered;
80358
80646
  }
80359
80647
  if (reply.ok) {
80360
80648
  const data = objectValue4(reply.data) ?? {};
@@ -80387,13 +80675,29 @@ var init_hosted_economy = __esm({
80387
80675
  return {
80388
80676
  ok: false,
80389
80677
  ambiguous: true,
80390
- ambiguityReason: "transport",
80678
+ ambiguityReason: timedOut ? "timeout" : "transport",
80391
80679
  data: void 0,
80392
- error: reply.error ?? "the supervisor could not determine whether the payment settled"
80680
+ error: timedOut ? `the paid call did not answer within ${Math.round(timeoutMs / 1e3)}s and its stored purchase has no final result yet` : reply.error ?? "the supervisor could not determine whether the payment settled"
80393
80681
  };
80394
80682
  }
80395
80683
  return refuse(reply.code ? `${reply.error ?? "payment refused"} (${reply.code})` : reply.error ?? "payment refused");
80396
80684
  }
80685
+ /**
80686
+ * Re-post the same purchase once. A finished attempt replays from the ledger;
80687
+ * an attempt still in flight answers payment_unknown; a request that never
80688
+ * reached the supervisor is not reconciled because nothing was started.
80689
+ */
80690
+ async reconcile(error53, payArgs, timeoutMs) {
80691
+ const code = error53?.code;
80692
+ if (typeof code === "string" && NOT_SENT_CODES.has(code))
80693
+ return void 0;
80694
+ await new Promise((resolve9) => setTimeout(resolve9, this.reconcileDelayMs));
80695
+ try {
80696
+ return await postHostedTool(this.socket, "economy.pay", payArgs, { timeoutMs });
80697
+ } catch {
80698
+ return void 0;
80699
+ }
80700
+ }
80397
80701
  /** The supervisor found no 402: the endpoint is free, so the worker fetches it itself. */
80398
80702
  async fetchUnpaid(url3, method, body, headers) {
80399
80703
  try {
@@ -80423,6 +80727,9 @@ var init_hosted_economy = __esm({
80423
80727
  HostedCrowdCodeAdapter = class {
80424
80728
  directory;
80425
80729
  socket;
80730
+ async manage(name, args) {
80731
+ return postHostedTool(this.socket, "economy.crowdcode", { name, ...args });
80732
+ }
80426
80733
  constructor(directory, socket) {
80427
80734
  this.directory = directory;
80428
80735
  this.socket = socket;
@@ -80484,9 +80791,9 @@ var init_hosted_economy = __esm({
80484
80791
  });
80485
80792
 
80486
80793
  // ../../packages/agent-runtime/dist/worker.js
80487
- import { readFile as readFile11, mkdir as mkdir10 } from "node:fs/promises";
80488
- import { join as join19 } from "node:path";
80489
- import { createHash as createHash5, randomUUID as randomUUID7 } from "node:crypto";
80794
+ import { readFile as readFile13, mkdir as mkdir11 } from "node:fs/promises";
80795
+ import { join as join21 } from "node:path";
80796
+ import { createHash as createHash5, randomUUID as randomUUID8 } from "node:crypto";
80490
80797
  function isWaiting(outcome) {
80491
80798
  return ["waiting_for_approval", "waiting_for_funds", "waiting_for_delegation", "payment_unknown"].includes(outcome);
80492
80799
  }
@@ -80513,6 +80820,7 @@ var RuntimePause, MachineWorker;
80513
80820
  var init_worker = __esm({
80514
80821
  "../../packages/agent-runtime/dist/worker.js"() {
80515
80822
  "use strict";
80823
+ init_dist();
80516
80824
  init_dist2();
80517
80825
  init_dist2();
80518
80826
  init_dist();
@@ -80541,13 +80849,13 @@ var init_worker = __esm({
80541
80849
  constructor(options) {
80542
80850
  this.options = options;
80543
80851
  this.paths = resolveAgentPaths({ agentHome: options.agentHome });
80544
- this.statePath = join19(this.paths.metadata, "worker.json");
80852
+ this.statePath = join21(this.paths.metadata, "worker.json");
80545
80853
  }
80546
80854
  async initialize() {
80547
80855
  await containedPath(this.paths.home, "metadata/worker.json");
80548
- await mkdir10(this.paths.metadata, { recursive: true });
80856
+ await mkdir11(this.paths.metadata, { recursive: true });
80549
80857
  try {
80550
- this.state = JSON.parse(await readFile11(this.statePath, "utf8"));
80858
+ this.state = JSON.parse(await readFile13(this.statePath, "utf8"));
80551
80859
  if (this.state.version !== 1 || !Number.isSafeInteger(this.state.seq) || !this.state.commands || !this.state.runs) {
80552
80860
  throw new Error("worker checkpoint version or shape is invalid");
80553
80861
  }
@@ -80574,7 +80882,7 @@ var init_worker = __esm({
80574
80882
  await this.mutate(() => {
80575
80883
  line = encodeEvent({
80576
80884
  protocolVersion: 1,
80577
- id: this.options.id?.() ?? randomUUID7(),
80885
+ id: this.options.id?.() ?? randomUUID8(),
80578
80886
  seq: ++this.state.seq,
80579
80887
  emittedAt: (this.options.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
80580
80888
  type,
@@ -80683,9 +80991,9 @@ var init_worker = __esm({
80683
80991
  } else if (!run) {
80684
80992
  run = {
80685
80993
  start: command,
80686
- sessionId: command.payload.session.sessionId ?? randomUUID7(),
80994
+ sessionId: command.payload.session.sessionId ?? randomUUID8(),
80687
80995
  commandId: command.id,
80688
- checkpointId: randomUUID7(),
80996
+ checkpointId: randomUUID8(),
80689
80997
  tools: /* @__PURE__ */ Object.create(null)
80690
80998
  };
80691
80999
  }
@@ -80732,9 +81040,18 @@ var init_worker = __esm({
80732
81040
  const hosted = this.options.hostedTools?.(run.start, session);
80733
81041
  const economy = this.options.economy?.(run.start, session);
80734
81042
  const dynamicTools = economy ? hostedDynamicTools(economy) : void 0;
81043
+ let latestFinancialState = { status: "unavailable", reason: "Hosted financial state has not been read." };
81044
+ const financialState = this.options.financialState ? async () => {
81045
+ try {
81046
+ latestFinancialState = await this.options.financialState(run.start, session);
81047
+ } catch {
81048
+ latestFinancialState = { status: "unavailable", reason: "Hosted financial state could not be read; do not use local budget figures." };
81049
+ }
81050
+ return latestFinancialState;
81051
+ } : void 0;
80735
81052
  const record3 = async (name, args, invoke) => {
80736
81053
  const call2 = run.checkpoint?.response?.toolCalls.find((c) => c.name === name && !run.checkpoint?.completedTools[c.id]);
80737
- const id = `${run.checkpoint?.turn ?? 0}:${call2?.id ?? randomUUID7()}`;
81054
+ const id = `${run.checkpoint?.turn ?? 0}:${call2?.id ?? randomUUID8()}`;
80738
81055
  const digest = createHash5("sha256").update(JSON.stringify({ name, args })).digest("hex");
80739
81056
  const saved = run.tools[id];
80740
81057
  if (saved && saved.digest !== digest)
@@ -80748,17 +81065,31 @@ var init_worker = __esm({
80748
81065
  await this.mutate(() => {
80749
81066
  run.tools[id] = { digest };
80750
81067
  });
80751
- await this.emit("tool.started", { toolCallId: id, toolName: name, input: summarizeToolInput(name, args) }, runId, run.commandId);
81068
+ await this.emit("tool.started", { toolCallId: id, toolName: name, input: summarizeToolInput(name, args), details: captureDetail({ input: args }), turn: run.checkpoint?.turn ?? 0 }, runId, run.commandId);
81069
+ const started = Date.now();
80752
81070
  let output3;
80753
81071
  try {
80754
81072
  if (saved?.approvalPending && name === "call_paid_service" && economy)
80755
81073
  await economy.execute("inspect_paid_service", { url: args.url, method: args.method, sample_body: args.body });
80756
81074
  output3 = await invoke();
81075
+ if (financialState && name === "get_budget_status")
81076
+ output3 = { ok: true, data: latestFinancialState };
81077
+ if (financialState && name === "complete_session" && output3.ok && output3.data && typeof output3.data === "object")
81078
+ output3 = { ...output3, data: { ...output3.data, budget: latestFinancialState } };
80757
81079
  } catch (error53) {
80758
81080
  if (error53 instanceof RuntimePause && error53.outcome === "waiting_for_approval")
80759
81081
  await this.mutate(() => {
80760
81082
  run.tools[id].approvalPending = true;
80761
81083
  });
81084
+ await this.emit("tool.finished", {
81085
+ toolCallId: id,
81086
+ toolName: name,
81087
+ status: error53 instanceof RuntimePause ? "blocked" : signal.aborted ? "cancelled" : "error",
81088
+ durationMs: Date.now() - started,
81089
+ turn: run.checkpoint?.turn ?? 0,
81090
+ error: scrubText(error53 instanceof Error ? error53.message : String(error53)),
81091
+ details: captureDetail({ error: error53 instanceof Error ? { name: error53.name, message: error53.message, stack: error53.stack } : String(error53) })
81092
+ }, runId, run.commandId);
80762
81093
  throw error53;
80763
81094
  }
80764
81095
  await this.mutate(() => {
@@ -80768,7 +81099,10 @@ var init_worker = __esm({
80768
81099
  toolCallId: id,
80769
81100
  toolName: name,
80770
81101
  status: output3.ok ? "ok" : "error",
80771
- error: output3.error
81102
+ error: output3.error ? scrubText(output3.error) : void 0,
81103
+ durationMs: Date.now() - started,
81104
+ turn: run.checkpoint?.turn ?? 0,
81105
+ details: captureDetail({ output: output3 })
80772
81106
  }, runId, run.commandId);
80773
81107
  if (name === "save_file" && output3.ok)
80774
81108
  await this.emit("artifact.created", {
@@ -80778,6 +81112,42 @@ var init_worker = __esm({
80778
81112
  }, runId, run.commandId);
80779
81113
  return output3;
80780
81114
  };
81115
+ const baseProvider = this.options.provider(run.start, session, dynamicTools?.definitions ?? []);
81116
+ const provider = {
81117
+ complete: async (messages, context) => {
81118
+ const callId = randomUUID8(), started = Date.now(), turn = run.checkpoint?.turn ?? 0;
81119
+ await this.emit("model.started", {
81120
+ callId,
81121
+ model: run.start.payload.modelPolicy.model ?? "demo",
81122
+ turn,
81123
+ details: captureDetail({ input: messages })
81124
+ }, runId, run.commandId);
81125
+ try {
81126
+ const result2 = await baseProvider.complete(messages, context);
81127
+ await this.emit("model.finished", {
81128
+ callId,
81129
+ model: run.start.payload.modelPolicy.model ?? "demo",
81130
+ turn,
81131
+ status: "ok",
81132
+ durationMs: Date.now() - started,
81133
+ usage: result2.usage,
81134
+ details: captureDetail({ output: result2 })
81135
+ }, runId, run.commandId);
81136
+ return result2;
81137
+ } catch (error53) {
81138
+ await this.emit("model.finished", {
81139
+ callId,
81140
+ model: run.start.payload.modelPolicy.model ?? "demo",
81141
+ turn,
81142
+ status: error53 instanceof RuntimePause ? "blocked" : signal.aborted ? "cancelled" : "error",
81143
+ durationMs: Date.now() - started,
81144
+ error: scrubText(error53 instanceof Error ? error53.message : String(error53)),
81145
+ details: captureDetail({ error: error53 instanceof Error ? { name: error53.name, message: error53.message, stack: error53.stack } : String(error53) })
81146
+ }, runId, run.commandId);
81147
+ throw error53;
81148
+ }
81149
+ }
81150
+ };
80781
81151
  const acknowledgedMessages = /* @__PURE__ */ new Set();
80782
81152
  const result = await runAgentTaskDetailed(session, run.start.payload.prompt, {
80783
81153
  inbox: {
@@ -80800,24 +81170,25 @@ var init_worker = __esm({
80800
81170
  maxTurns: run.start.payload.maxTurns,
80801
81171
  contextWindowTokens: run.start.payload.modelPolicy.contextWindowTokens,
80802
81172
  maxOutputTokens: run.start.payload.modelPolicy.maxOutputTokens,
80803
- provider: this.options.provider(run.start, session, dynamicTools?.definitions ?? []),
81173
+ provider,
81174
+ financialState,
80804
81175
  history: run.checkpoint ? void 0 : await this.history(session),
80805
81176
  ...dynamicTools ? {
80806
81177
  dynamicTools: { definitions: dynamicTools.definitions, execute: (name, args) => record3(name, args, () => dynamicTools.execute(name, args, `${run.checkpoint?.turn ?? 0}:${run.checkpoint?.response?.toolCalls.find((c) => c.name === name && !run.checkpoint?.completedTools[c.id])?.id}`)) },
80807
- completionGate: () => dynamicTools.completionGate(),
81178
+ completionGate: (alreadyNudged) => dynamicTools.completionGate(alreadyNudged),
80808
81179
  knowledge: await this.knowledgeOption(session)
80809
81180
  } : {},
80810
81181
  onCheckpoint: async (checkpoint) => {
80811
81182
  await this.mutate(() => {
80812
81183
  run.checkpoint = checkpoint;
80813
- run.checkpointId = randomUUID7();
81184
+ run.checkpointId = randomUUID8();
80814
81185
  });
80815
- await atomicWrite(join19(session.sessionDir, "messages.jsonl"), checkpoint.messages.filter((m) => m.role !== "system").map((message) => JSON.stringify({ type: "message", timestamp: (/* @__PURE__ */ new Date()).toISOString(), message }) + "\n").join(""));
81186
+ await atomicWrite(join21(session.sessionDir, "messages.jsonl"), checkpoint.messages.filter((m) => m.role !== "system").map((message) => JSON.stringify({ type: "message", timestamp: (/* @__PURE__ */ new Date()).toISOString(), message }) + "\n").join(""));
80816
81187
  },
80817
81188
  onMessage: async (message) => {
80818
81189
  if (message.role === "assistant" && message.content)
80819
81190
  await this.emit("assistant.message", {
80820
- messageId: randomUUID7(),
81191
+ messageId: randomUUID8(),
80821
81192
  content: message.content
80822
81193
  }, runId, run.commandId);
80823
81194
  },
@@ -80825,6 +81196,13 @@ var init_worker = __esm({
80825
81196
  });
80826
81197
  await this.finish(runId, run, result.outcome === "stopped" ? "user_stopped" : result.outcome, String(result.summary.final_message ?? ""));
80827
81198
  } catch (error53) {
81199
+ if (!(error53 instanceof RuntimePause) && !signal.aborted)
81200
+ await this.emit("runtime.error", {
81201
+ code: "run_exception",
81202
+ message: scrubText(error53 instanceof Error ? error53.message : String(error53)),
81203
+ fatal: false,
81204
+ details: captureDetail({ error: error53 instanceof Error ? { name: error53.name, message: error53.message, stack: error53.stack } : String(error53) })
81205
+ }, runId, run.commandId);
80828
81206
  if (signal.aborted)
80829
81207
  await this.finish(runId, run, "cancelled", "Run cancelled");
80830
81208
  else if (error53 instanceof RuntimePause) {
@@ -80849,7 +81227,7 @@ var init_worker = __esm({
80849
81227
  }
80850
81228
  async history(session) {
80851
81229
  try {
80852
- return (await readFile11(join19(session.sessionDir, "messages.jsonl"), "utf8")).split("\n").filter(Boolean).map((line) => JSON.parse(line).message).filter(Boolean);
81230
+ return (await readFile13(join21(session.sessionDir, "messages.jsonl"), "utf8")).split("\n").filter(Boolean).map((line) => JSON.parse(line).message).filter(Boolean);
80853
81231
  } catch (error53) {
80854
81232
  if (error53.code === "ENOENT")
80855
81233
  return [];
@@ -80860,7 +81238,7 @@ var init_worker = __esm({
80860
81238
  await this.mutate(() => {
80861
81239
  run.outcome = outcome;
80862
81240
  run.summary = summary;
80863
- run.checkpointId = randomUUID7();
81241
+ run.checkpointId = randomUUID8();
80864
81242
  if (!isWaiting(outcome) && this.state.activeRunId === runId)
80865
81243
  this.state.activeRunId = void 0;
80866
81244
  });
@@ -80887,7 +81265,7 @@ var init_worker = __esm({
80887
81265
  });
80888
81266
 
80889
81267
  // ../../packages/agent-runtime/dist/inbox.js
80890
- import { readFile as readFile12 } from "node:fs/promises";
81268
+ import { readFile as readFile14 } from "node:fs/promises";
80891
81269
  var FileSteeringInbox;
80892
81270
  var init_inbox = __esm({
80893
81271
  "../../packages/agent-runtime/dist/inbox.js"() {
@@ -80901,7 +81279,7 @@ var init_inbox = __esm({
80901
81279
  }
80902
81280
  async read() {
80903
81281
  try {
80904
- return JSON.parse(await readFile12(this.path, "utf8"));
81282
+ return JSON.parse(await readFile14(this.path, "utf8"));
80905
81283
  } catch (e6) {
80906
81284
  if (e6.code === "ENOENT")
80907
81285
  return [];
@@ -80929,8 +81307,8 @@ var init_inbox = __esm({
80929
81307
 
80930
81308
  // ../../packages/agent-runtime/dist/index.js
80931
81309
  import { createHash as createHash6 } from "node:crypto";
80932
- import { appendFile as appendFile4, mkdir as mkdir11, readFile as readFile13 } from "node:fs/promises";
80933
- import { join as join20 } from "node:path";
81310
+ import { appendFile as appendFile4, mkdir as mkdir12, readFile as readFile15 } from "node:fs/promises";
81311
+ import { join as join22 } from "node:path";
80934
81312
  function lastUserMessageIndex(messages) {
80935
81313
  for (let index2 = messages.length - 1; index2 >= 0; index2 -= 1) {
80936
81314
  if (messages[index2].role === "user") {
@@ -81120,8 +81498,10 @@ async function runAgentTaskDetailed(session, task, options = {}) {
81120
81498
  "Try to solve the user's task completely. Use local files and bash when they are sufficient, but remember they are bounded by the user's installed tools, credentials, network, open ports, and process lifetime.",
81121
81499
  "Before repeatedly fighting the local environment, decide whether the task needs external capability such as hosting, persistent infrastructure, remote compute, specialized APIs, live data, or access the user's device does not have."
81122
81500
  ];
81501
+ if (options.hosted)
81502
+ systemPromptParts.push("You operate this service for its owner. Inference and paid tools debit its USDC wallet. When authorized to build or sell a service, take concrete steps within the owner's configured scope and budget. Ask only for missing information or permissions that materially block progress. Report actual costs and outcomes. Financial sustainability is the owner's business objective; respect their stop controls.", "Financial state: the current hosted financial snapshot is authoritative; historical local session budget figures are not wallet balances and may omit inference spending. Wallet balance, pending payment holds, settled inference spend, settled service spend, and remaining run budget are separate. Spending totals cover only the identified current run. A budget limit does not supply funds. An unavailable balance is unknown, not zero. The snapshot before a model call excludes that call's eventual charge; never claim a response was free or that you spent nothing merely because no paid tool ran. Use get_budget_status or get_wallet_status for refreshed financial state. Respect approval mode and per-call limits; over-limit requests require the owner's approval.");
81123
81503
  if (options.dynamicTools) {
81124
- systemPromptParts.push("When the local computer is not the right environment, or after one clear local capability failure, buy external capability: find_paid_service to discover, inspect_paid_service to see the exact schema/price/reputation, call_paid_service to execute through the enforced purchase lifecycle, and review_paid_service for the required review after every confirmed paid call (success or failure). The same review tool accepts unpaid experiences; review relevant free results or failed attempts without inventing payment evidence. Distinguish provider faults from local errors and uncertain failures.", ...options.hosted ? ["Discover services through AgentCash search and provider catalogs. You can use new services without prior CrowdCode reviews. Only x402 USDC on Base is payable, within the user's configured limits; over-limit quotes request approval. Use read_service for authenticated job polling and never resubmit a pending generation job."] : [], capabilityIndex ?? DEFAULT_CAPABILITY_INDEX, "When a task needs current web facts, search results, or unfamiliar page content, make one paid web search your FIRST move \u2014 do not serially guess URLs with curl; one paid search replaces minutes of blind fetching and costs less than the LLM turns it saves.", "Approval, budget, reputation, and payment rails are enforced in code \u2014 you cannot bypass them, so state costs plainly and never invent payment details.", "Each tool result includes the budget before and after that tool call. Never ask for wallet private keys or secrets.", ...options.promptSections ?? []);
81504
+ systemPromptParts.push("When the local computer is not the right environment, or after one clear local capability failure, buy external capability: find_paid_service to discover, inspect_paid_service to see the exact schema/price/reputation, call_paid_service to execute through the enforced purchase lifecycle, and review_paid_service for the required review after every confirmed paid call (success or failure). The same review tool accepts unpaid experiences; review relevant free results or failed attempts without inventing payment evidence. Distinguish provider faults from local errors and uncertain failures.", ...options.hosted ? ["Discover services through AgentCash search and provider catalogs. You can use new services without prior CrowdCode reviews. Only x402 USDC on Base is payable, within the user's configured limits; over-limit quotes request approval. Use read_service for authenticated job polling and never resubmit a pending generation job."] : [], capabilityIndex ?? DEFAULT_CAPABILITY_INDEX, "When a task needs current web facts, search results, or unfamiliar page content, make one paid web search your FIRST move \u2014 do not serially guess URLs with curl; one paid search replaces minutes of blind fetching and costs less than the LLM turns it saves.", "Approval, budget, reputation, and payment rails are enforced in code \u2014 you cannot bypass them, so state costs plainly and never invent payment details.", "When the user says CrowdCode on/off, call set_crowdcode_enabled; default to session scope unless they ask for a persistent default. Use list_my_reviews and delete_my_review for user-directed review management, including while off. Before finishing a substantive task, consider concrete paid services that would fix real shortcomings and submit qualifying demand with request_service, unless CrowdCode is off. Never invent a purchase or demand.", "Each tool result includes the budget before and after that tool call. Never ask for wallet private keys or secrets.", ...options.promptSections ?? []);
81125
81505
  } else {
81126
81506
  systemPromptParts.push("Paid external services are unavailable in this run; work with local tools only and say so if the task truly requires external capability.");
81127
81507
  }
@@ -81141,11 +81521,24 @@ async function runAgentTaskDetailed(session, task, options = {}) {
81141
81521
  ...options.history ?? [],
81142
81522
  { role: "user", content: task }
81143
81523
  ];
81524
+ let financial = { status: "unavailable", reason: "Hosted financial state has not been read." };
81525
+ const refreshFinancialState = async () => {
81526
+ if (!options.financialState)
81527
+ return;
81528
+ try {
81529
+ financial = FinancialStateSchema.parse(await options.financialState());
81530
+ } catch {
81531
+ financial = { status: "unavailable", reason: "Hosted financial state could not be read; do not use local budget figures." };
81532
+ }
81533
+ };
81534
+ const currentBudget = () => options.financialState ? financial : budgetStatus(session);
81535
+ const financialPrefix = "Current hosted financial snapshot: ";
81144
81536
  if (!options.resume)
81145
81537
  await options.onMessage?.({ role: "user", content: task });
81146
81538
  const maxTurns = options.maxTurns ?? 100;
81147
81539
  const repeatedFailures = new Map(options.resume?.repeatedFailures);
81148
81540
  let completionNudges = options.resume?.completionNudges ?? 0;
81541
+ let pendingFinalMessage = options.resume?.pendingFinalMessage;
81149
81542
  let outputContinuationNudges = options.resume?.outputContinuationNudges ?? 0;
81150
81543
  let outputContinuationPrefix = options.resume?.outputContinuationPrefix ?? "";
81151
81544
  let serviceCallFailures = options.resume?.serviceCallFailures ?? 0;
@@ -81159,6 +81552,7 @@ async function runAgentTaskDetailed(session, task, options = {}) {
81159
81552
  context: contextState,
81160
81553
  deliveredMessageIds: [...deliveredMessageIds],
81161
81554
  completionNudges,
81555
+ pendingFinalMessage,
81162
81556
  outputContinuationNudges,
81163
81557
  outputContinuationPrefix,
81164
81558
  serviceCallFailures,
@@ -81172,8 +81566,11 @@ async function runAgentTaskDetailed(session, task, options = {}) {
81172
81566
  messages.push({ role: "user", content: message.prompt });
81173
81567
  deliveredMessageIds.add(message.id);
81174
81568
  }
81175
- if (fresh.length)
81569
+ if (fresh.length) {
81570
+ pendingFinalMessage = void 0;
81571
+ outputContinuationPrefix = "";
81176
81572
  await checkpoint(turn);
81573
+ }
81177
81574
  for (const message of fresh)
81178
81575
  await options.onMessage?.({ role: "user", content: message.prompt });
81179
81576
  if (pending.length)
@@ -81201,6 +81598,15 @@ async function runAgentTaskDetailed(session, task, options = {}) {
81201
81598
  options.onProgress?.({ type: "calling_llm", message: `Calling LLM provider (turn ${turn + 1}/${maxTurns})` });
81202
81599
  let response;
81203
81600
  try {
81601
+ if (options.financialState && !restored?.response && !contextState.prepared) {
81602
+ await refreshFinancialState();
81603
+ const snapshot = { role: "system", content: financialPrefix + JSON.stringify(financial) };
81604
+ const index2 = messages.findIndex((m) => m.role === "system" && m.content.startsWith(financialPrefix));
81605
+ if (index2 === -1)
81606
+ messages.splice(1, 0, snapshot);
81607
+ else
81608
+ messages[index2] = snapshot;
81609
+ }
81204
81610
  response = restored?.response ?? await completeWithContext(session, messages, {
81205
81611
  provider: provider instanceof MockLlmProvider ? { complete: (input2) => completeMockLlmCall(session, provider, input2, turn + 1) } : provider,
81206
81612
  tools: wireToolDefinitions(enabledTools, dynamicDefinitions),
@@ -81217,6 +81623,7 @@ async function runAgentTaskDetailed(session, task, options = {}) {
81217
81623
  }
81218
81624
  });
81219
81625
  options.signal?.throwIfAborted();
81626
+ await refreshFinancialState();
81220
81627
  } catch (error53) {
81221
81628
  if (error53 instanceof BudgetExhaustedError) {
81222
81629
  const summary2 = await completeSession(session, `Stopped: the session budget is exhausted (${error53.message}).`);
@@ -81250,7 +81657,10 @@ ${outputContinuationPrefix}`);
81250
81657
  if (response.toolCalls.length === 0) {
81251
81658
  if (await injectMessages(turn + 1))
81252
81659
  continue;
81253
- const blocker = await options.completionGate?.();
81660
+ const finalMessage = response.content.trim() ? outputContinuationPrefix + response.content : pendingFinalMessage ?? outputContinuationPrefix;
81661
+ if (finalMessage.trim())
81662
+ pendingFinalMessage = finalMessage;
81663
+ const blocker = await options.completionGate?.(completionNudges > 0);
81254
81664
  if (blocker) {
81255
81665
  if (completionNudges >= 1) {
81256
81666
  const summary3 = await completeSession(session, `Stopped: ${blocker}`);
@@ -81260,9 +81670,12 @@ ${outputContinuationPrefix}`);
81260
81670
  const nudge = { role: "user", content: `You cannot finish yet: ${blocker}` };
81261
81671
  messages.push(nudge);
81262
81672
  await options.onMessage?.(nudge);
81673
+ await checkpoint(turn + 1);
81263
81674
  continue;
81264
81675
  }
81265
- const summary2 = await completeSession(session, outputContinuationPrefix + (response.content || "Session completed."));
81676
+ if (!pendingFinalMessage?.trim())
81677
+ throw new Error("The model ended without an answer.");
81678
+ const summary2 = await completeSession(session, pendingFinalMessage);
81266
81679
  return { outcome: "completed", summary: summary2, turns: turn + 1 };
81267
81680
  }
81268
81681
  const spawnedThisTurn = /* @__PURE__ */ new Map();
@@ -81305,7 +81718,7 @@ ${outputContinuationPrefix}`);
81305
81718
  message: `Tool call: ${summarizeToolCall(call2)}`,
81306
81719
  data: { tool: call2.name, arguments: call2.arguments }
81307
81720
  });
81308
- const budgetBeforeToolCall = budgetStatus(session);
81721
+ const budgetBeforeToolCall = currentBudget();
81309
81722
  const callArguments = call2.name === "complete_session" && outputContinuationPrefix ? {
81310
81723
  ...call2.arguments,
81311
81724
  final_message: outputContinuationPrefix + (typeof call2.arguments.final_message === "string" ? call2.arguments.final_message : "")
@@ -81343,7 +81756,13 @@ ${outputContinuationPrefix}`);
81343
81756
  } else {
81344
81757
  result = { ok: false, error: `unknown tool: ${call2.name}` };
81345
81758
  }
81346
- const budgetAfterToolCall = budgetStatus(session);
81759
+ await refreshFinancialState();
81760
+ const budgetAfterToolCall = currentBudget();
81761
+ if (options.financialState && call2.name === "get_budget_status")
81762
+ result = { ok: true, data: financial };
81763
+ if (options.financialState && call2.name === "complete_session" && result.ok && result.data && typeof result.data === "object") {
81764
+ result = { ...result, data: { ...result.data, budget: financial } };
81765
+ }
81347
81766
  options.onProgress?.({
81348
81767
  type: "tool_result",
81349
81768
  message: `Tool result: ${summarizeToolResult(call2.name, result)}`,
@@ -81364,6 +81783,8 @@ ${outputContinuationPrefix}`);
81364
81783
  await checkpoint(turn, response, completedTools);
81365
81784
  await options.onMessage?.(toolMessage);
81366
81785
  }
81786
+ if (call2.name === "call_paid_service" && result.ok)
81787
+ serviceCallFailures = 0;
81367
81788
  if (!result.ok) {
81368
81789
  if (call2.name === "call_paid_service") {
81369
81790
  serviceCallFailures += 1;
@@ -81387,7 +81808,12 @@ ${outputContinuationPrefix}`);
81387
81808
  const result = completedTools[call2.id];
81388
81809
  if (await injectMessages(turn + 1))
81389
81810
  continue;
81390
- const blocker = await options.completionGate?.();
81811
+ if (!result.ok)
81812
+ continue;
81813
+ const finalMessage = result.data && typeof result.data === "object" ? result.data.final_message : void 0;
81814
+ if (typeof finalMessage === "string" && finalMessage.trim())
81815
+ pendingFinalMessage = finalMessage;
81816
+ const blocker = await options.completionGate?.(completionNudges > 0);
81391
81817
  if (blocker) {
81392
81818
  if (completionNudges >= 1) {
81393
81819
  const summary3 = await completeSession(session, `Stopped: ${blocker}`);
@@ -81395,23 +81821,25 @@ ${outputContinuationPrefix}`);
81395
81821
  }
81396
81822
  completionNudges += 1;
81397
81823
  const gateMessage = {
81398
- role: "tool",
81399
- toolCallId: call2.id,
81400
- content: JSON.stringify({ result: { ok: false, error: `cannot complete yet: ${blocker}` } })
81824
+ role: "user",
81825
+ content: `You cannot finish yet: ${blocker}`
81401
81826
  };
81402
81827
  messages.push(gateMessage);
81403
81828
  await options.onMessage?.(gateMessage);
81829
+ await checkpoint(turn + 1);
81404
81830
  continue;
81405
81831
  }
81832
+ if (!pendingFinalMessage?.trim())
81833
+ throw new Error("The model ended without an answer.");
81406
81834
  const backgroundResults = backgroundSubagents.size > 0 ? await drainBackground() : void 0;
81407
- if (result.ok && result.data && typeof result.data === "object") {
81408
- const summary3 = { ...result.data };
81835
+ if (result.data && typeof result.data === "object") {
81836
+ const summary3 = { ...result.data, final_message: pendingFinalMessage };
81409
81837
  if (backgroundResults) {
81410
81838
  summary3.background_subagents = backgroundResults;
81411
81839
  }
81412
81840
  return { outcome: "completed", summary: summary3, turns: turn + 1 };
81413
81841
  }
81414
- const summary2 = await completeSession(session, outputContinuationPrefix + (response.content || result.error || "Session completed."));
81842
+ const summary2 = await completeSession(session, pendingFinalMessage);
81415
81843
  if (backgroundResults) {
81416
81844
  summary2.background_subagents = backgroundResults;
81417
81845
  }
@@ -81449,9 +81877,9 @@ async function runSubagentTask(session, args, subagent, index2, parentOptions, o
81449
81877
  return { ok: false, error: "spawn_subagent requires a task" };
81450
81878
  }
81451
81879
  const subagentId = `${session.sessionId}#sub${index2}`;
81452
- const trajectoryDir = join20(session.sessionDir, "subagents", operationKey ?? String(index2));
81453
- const trajectoryPath = join20(trajectoryDir, "messages.jsonl");
81454
- await mkdir11(trajectoryDir, { recursive: true });
81880
+ const trajectoryDir = join22(session.sessionDir, "subagents", operationKey ?? String(index2));
81881
+ const trajectoryPath = join22(trajectoryDir, "messages.jsonl");
81882
+ await mkdir12(trajectoryDir, { recursive: true });
81455
81883
  const record3 = async (message) => {
81456
81884
  await appendFile4(trajectoryPath, `${JSON.stringify({ type: "message", timestamp: (/* @__PURE__ */ new Date()).toISOString(), message })}
81457
81885
  `, "utf8");
@@ -81481,11 +81909,11 @@ async function runSubagentTask(session, args, subagent, index2, parentOptions, o
81481
81909
  ].filter(Boolean).join("\n\n")
81482
81910
  }
81483
81911
  ];
81484
- const statePath = join20(trajectoryDir, "checkpoint.json");
81912
+ const statePath = join22(trajectoryDir, "checkpoint.json");
81485
81913
  let saved;
81486
81914
  if (operationKey)
81487
81915
  try {
81488
- saved = JSON.parse(await readFile13(statePath, "utf8"));
81916
+ saved = JSON.parse(await readFile15(statePath, "utf8"));
81489
81917
  } catch (e6) {
81490
81918
  if (e6.code !== "ENOENT")
81491
81919
  throw e6;
@@ -81903,6 +82331,8 @@ function summarizeToolResult(name, result) {
81903
82331
  return `call_paid_service ${String(data.outcome ?? "?")} HTTP ${String(data.status ?? "?")}, charged ${formatCents(Number(data.charged_cost_cents ?? 0))}${data.artifact_path ? `, saved ${String(data.artifact_path)}` : ""}`;
81904
82332
  }
81905
82333
  if (name === "get_budget_status" && result.data && typeof result.data === "object") {
82334
+ if ("status" in result.data)
82335
+ return `hosted finances: ${String(result.data.status)}`;
81906
82336
  const data = result.data;
81907
82337
  return `remaining ${formatCents(Number(data.remaining_cents ?? 0))}`;
81908
82338
  }
@@ -82202,7 +82632,7 @@ var init_dist6 = __esm({
82202
82632
 
82203
82633
  // src/shared.ts
82204
82634
  import { readdir } from "node:fs/promises";
82205
- import { join as join21, resolve as resolve5 } from "node:path";
82635
+ import { join as join23, resolve as resolve5 } from "node:path";
82206
82636
  import { stdout as output } from "node:process";
82207
82637
  function renderKeyValues(value) {
82208
82638
  return Object.entries(value).filter(([, item]) => item !== void 0).map(([key, item]) => ` ${style(key, "muted").padEnd(24)} ${formatCell(item, 80, key)}`).join("\n");
@@ -82324,7 +82754,7 @@ function isConsumedOption(args, index2, options) {
82324
82754
  return options.includes(args[index2]) || index2 > 0 && options.includes(args[index2 - 1]);
82325
82755
  }
82326
82756
  async function latestSessionId(workspaceRoot) {
82327
- const sessionsDir = join21(resolve5(workspaceRoot), "sessions");
82757
+ const sessionsDir = join23(resolve5(workspaceRoot), "sessions");
82328
82758
  try {
82329
82759
  const entries = await readdir(sessionsDir, { withFileTypes: true });
82330
82760
  return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort().at(-1);
@@ -82357,6 +82787,7 @@ async function workerCommand(args) {
82357
82787
  provider: (run, session, extraTools) => socketPath ? createHostedProvider({ socketPath, runId: run.runId, sessionId: session.sessionId, extraTools }) : createWorkerDemoProvider(),
82358
82788
  hostedTools: socketPath ? (run, session) => createHostedToolExecutor({ socketPath, runId: run.runId, sessionId: session.sessionId }) : void 0,
82359
82789
  economy: socketPath ? (run, session) => createHostedEconomy({ socketPath, runId: run.runId, sessionId: session.sessionId, session }) : void 0,
82790
+ financialState: socketPath ? (run, session) => readHostedFinancialState({ socketPath, runId: run.runId, sessionId: session.sessionId }) : void 0,
82360
82791
  output: (line) => {
82361
82792
  process.stdout.write(line);
82362
82793
  }
@@ -82471,8 +82902,8 @@ var init_doctor = __esm({
82471
82902
  });
82472
82903
 
82473
82904
  // ../../packages/evals/dist/gaia.js
82474
- import { mkdir as mkdir12, readFile as readFile14, writeFile as writeFile5, access as access2 } from "node:fs/promises";
82475
- import { dirname as dirname10, join as join23 } from "node:path";
82905
+ import { mkdir as mkdir13, readFile as readFile16, writeFile as writeFile7, access as access2 } from "node:fs/promises";
82906
+ import { dirname as dirname11, join as join25 } from "node:path";
82476
82907
  import { homedir as homedir7 } from "node:os";
82477
82908
  function isUnsupportedModality(fileName) {
82478
82909
  if (!fileName) {
@@ -82482,18 +82913,18 @@ function isUnsupportedModality(fileName) {
82482
82913
  return UNSUPPORTED_EXTENSIONS.some((extension2) => lower.endsWith(extension2));
82483
82914
  }
82484
82915
  function defaultGaiaCacheDir() {
82485
- return process.env.OPENCROWD_GAIA_CACHE_DIR ?? join23(homedir7(), ".cache", "opencrowd", "gaia", "2023", "validation");
82916
+ return process.env.OPENCROWD_GAIA_CACHE_DIR ?? join25(homedir7(), ".cache", "opencrowd", "gaia", "2023", "validation");
82486
82917
  }
82487
82918
  async function fetchGaiaValidation(options = {}) {
82488
82919
  const cacheDir = options.cacheDir ?? defaultGaiaCacheDir();
82489
- await mkdir12(cacheDir, { recursive: true });
82490
- const metadataPath = join23(cacheDir, "metadata.jsonl");
82920
+ await mkdir13(cacheDir, { recursive: true });
82921
+ const metadataPath = join25(cacheDir, "metadata.jsonl");
82491
82922
  let metadataText;
82492
82923
  try {
82493
- metadataText = await readFile14(metadataPath, "utf8");
82924
+ metadataText = await readFile16(metadataPath, "utf8");
82494
82925
  } catch {
82495
82926
  metadataText = await fetchValidationRows(options);
82496
- await writeFile5(metadataPath, metadataText, "utf8");
82927
+ await writeFile7(metadataPath, metadataText, "utf8");
82497
82928
  }
82498
82929
  return metadataText.split(/\r?\n/).filter(Boolean).map((line) => parseGaiaRecord(JSON.parse(line)));
82499
82930
  }
@@ -82542,7 +82973,7 @@ async function ensureGaiaAttachments(questions, options = {}) {
82542
82973
  const cacheDir = options.cacheDir ?? defaultGaiaCacheDir();
82543
82974
  for (const question of questions) {
82544
82975
  if (question.file_name && !isUnsupportedModality(question.file_name)) {
82545
- const filePath = join23(cacheDir, question.file_name);
82976
+ const filePath = join25(cacheDir, question.file_name);
82546
82977
  await cachedDownload(filePath, `${GAIA_BASE_URL}/${encodeURIComponent(question.file_name)}`, options, true);
82547
82978
  question.file_path = filePath;
82548
82979
  }
@@ -82572,7 +83003,7 @@ function parseGaiaRecord(record3) {
82572
83003
  async function cachedDownload(path3, url3, options, binary = false) {
82573
83004
  try {
82574
83005
  await access2(path3);
82575
- return binary ? "" : await readFile14(path3, "utf8");
83006
+ return binary ? "" : await readFile16(path3, "utf8");
82576
83007
  } catch {
82577
83008
  }
82578
83009
  options.log?.(`fetching ${url3}`);
@@ -82591,14 +83022,14 @@ async function cachedDownload(path3, url3, options, binary = false) {
82591
83022
  if (!response.ok) {
82592
83023
  throw new Error(`GAIA download failed: ${response.status} ${response.statusText} for ${url3}`);
82593
83024
  }
82594
- await mkdir12(dirname10(path3), { recursive: true });
83025
+ await mkdir13(dirname11(path3), { recursive: true });
82595
83026
  if (binary) {
82596
83027
  const buffer2 = Buffer.from(await response.arrayBuffer());
82597
- await writeFile5(path3, buffer2);
83028
+ await writeFile7(path3, buffer2);
82598
83029
  return "";
82599
83030
  }
82600
83031
  const text = await response.text();
82601
- await writeFile5(path3, text, "utf8");
83032
+ await writeFile7(path3, text, "utf8");
82602
83033
  return text;
82603
83034
  }
82604
83035
  var GAIA_BASE_URL, GAIA_ROWS_URL, GAIA_TIERS, UNSUPPORTED_EXTENSIONS;
@@ -82632,9 +83063,9 @@ var init_gaia = __esm({
82632
83063
  });
82633
83064
 
82634
83065
  // ../../packages/evals/dist/grader.js
82635
- import { readFile as readFile15 } from "node:fs/promises";
83066
+ import { readFile as readFile17 } from "node:fs/promises";
82636
83067
  async function gradeTrajectoryFile(path3) {
82637
- const text = await readFile15(path3, "utf8");
83068
+ const text = await readFile17(path3, "utf8");
82638
83069
  const entries = text.split(/\r?\n/).filter(Boolean).map((line) => JSON.parse(line));
82639
83070
  return gradeTrajectory(entries);
82640
83071
  }
@@ -82767,8 +83198,8 @@ var init_grader = __esm({
82767
83198
  // ../../packages/evals/dist/harnesses.js
82768
83199
  import { execFile } from "node:child_process";
82769
83200
  import { promisify } from "node:util";
82770
- import { copyFile, mkdir as mkdir13, readFile as readFile16 } from "node:fs/promises";
82771
- import { basename, join as join24 } from "node:path";
83201
+ import { copyFile, mkdir as mkdir14, readFile as readFile18 } from "node:fs/promises";
83202
+ import { basename, join as join26 } from "node:path";
82772
83203
  function resolveHarness(name) {
82773
83204
  switch (name) {
82774
83205
  case "opencrowd":
@@ -82797,7 +83228,7 @@ function gaiaPrompt(question, attachmentNote) {
82797
83228
  }
82798
83229
  async function countPaidPurchases(path3) {
82799
83230
  try {
82800
- const text = await readFile16(path3, "utf8");
83231
+ const text = await readFile18(path3, "utf8");
82801
83232
  return text.split(/\r?\n/).filter(Boolean).filter((line) => {
82802
83233
  const entry = asRecord3(parseJson3(line));
82803
83234
  const outcome = asRecord3(entry.record).outcome ?? entry.outcome;
@@ -82812,7 +83243,7 @@ async function comparatorPrompt(context) {
82812
83243
  return context.prompt;
82813
83244
  }
82814
83245
  const name = basename(context.attachmentPath);
82815
- await copyFile(context.attachmentPath, join24(context.runDir, name));
83246
+ await copyFile(context.attachmentPath, join26(context.runDir, name));
82816
83247
  return `${context.prompt}
82817
83248
 
82818
83249
  An input file is available in the working directory at ./${name}`;
@@ -82906,11 +83337,11 @@ var init_harnesses = __esm({
82906
83337
  let prompt = context.prompt;
82907
83338
  if (context.attachmentPath) {
82908
83339
  const name = basename(context.attachmentPath);
82909
- await mkdir13(session.artifactsDir, { recursive: true });
82910
- await copyFile(context.attachmentPath, join24(session.artifactsDir, name));
83340
+ await mkdir14(session.artifactsDir, { recursive: true });
83341
+ await copyFile(context.attachmentPath, join26(session.artifactsDir, name));
82911
83342
  prompt = `${prompt}
82912
83343
 
82913
- An input file is available at the session artifact path \`${name}\` (use read_file, or run_shell against ${join24(session.artifactsDir, name)}).`;
83344
+ An input file is available at the session artifact path \`${name}\` (use read_file, or run_shell against ${join26(session.artifactsDir, name)}).`;
82914
83345
  }
82915
83346
  const llm = context.testMode ? void 0 : await resolveLlmRuntime(session, {
82916
83347
  model: context.model,
@@ -82941,7 +83372,7 @@ An input file is available at the session artifact path \`${name}\` (use read_fi
82941
83372
  onMessage: (message) => appendConversationMessage(session, message)
82942
83373
  });
82943
83374
  const budget = asRecord3(result.summary.budget);
82944
- const trajectoryPath = join24(session.sessionDir, "messages.jsonl");
83375
+ const trajectoryPath = join26(session.sessionDir, "messages.jsonl");
82945
83376
  return {
82946
83377
  final_message: String(result.summary.final_message ?? ""),
82947
83378
  turns: result.turns,
@@ -82952,7 +83383,7 @@ An input file is available at the session artifact path \`${name}\` (use read_fi
82952
83383
  knowledge_version: session.knowledge?.version,
82953
83384
  session_dir: session.sessionDir,
82954
83385
  artifacts_dir: session.artifactsDir,
82955
- paid_calls: await countPaidPurchases(join24(session.sessionDir, "purchases.jsonl")),
83386
+ paid_calls: await countPaidPurchases(join26(session.sessionDir, "purchases.jsonl")),
82956
83387
  model_policy: llm?.models,
82957
83388
  compliance: await gradeTrajectoryFile(trajectoryPath).catch(() => void 0)
82958
83389
  };
@@ -83155,8 +83586,8 @@ var init_scorer = __esm({
83155
83586
  });
83156
83587
 
83157
83588
  // ../../packages/evals/dist/runner.js
83158
- import { appendFile as appendFile5, mkdir as mkdir14, writeFile as writeFile6 } from "node:fs/promises";
83159
- import { join as join25, resolve as resolve6 } from "node:path";
83589
+ import { appendFile as appendFile5, mkdir as mkdir15, writeFile as writeFile8 } from "node:fs/promises";
83590
+ import { join as join27, resolve as resolve6 } from "node:path";
83160
83591
  async function runGaiaBenchmark(options) {
83161
83592
  const log = options.log ?? (() => void 0);
83162
83593
  const harnesses = options.harnesses.map(resolveHarness);
@@ -83182,8 +83613,8 @@ async function runGaiaBenchmark(options) {
83182
83613
  }
83183
83614
  const runId = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
83184
83615
  const resultsDir = resolve6(options.workspaceRoot, "evals", "gaia", runId);
83185
- await mkdir14(resultsDir, { recursive: true });
83186
- const resultsPath = join25(resultsDir, "results.jsonl");
83616
+ await mkdir15(resultsDir, { recursive: true });
83617
+ const resultsPath = join27(resultsDir, "results.jsonl");
83187
83618
  log(`GAIA ${options.tier}: ${runnable.length} questions, ${skipped.length} skipped (unsupported modality), results in ${resultsDir}`);
83188
83619
  const parallel = Math.max(1, options.parallel ?? 4);
83189
83620
  const rows = [];
@@ -83209,13 +83640,13 @@ async function runGaiaBenchmark(options) {
83209
83640
  harnesses: harnesses.map((harness) => summarizeHarness(harness, rows.filter((row) => row.harness === harness.name))),
83210
83641
  rows
83211
83642
  };
83212
- await writeFile6(join25(resultsDir, "report.json"), `${JSON.stringify(report, null, 2)}
83643
+ await writeFile8(join27(resultsDir, "report.json"), `${JSON.stringify(report, null, 2)}
83213
83644
  `, "utf8");
83214
83645
  return report;
83215
83646
  }
83216
83647
  async function runOneQuestion(harness, question, resultsDir, options) {
83217
- const runDir = join25(resultsDir, harness.name, question.task_id);
83218
- await mkdir14(runDir, { recursive: true });
83648
+ const runDir = join27(resultsDir, harness.name, question.task_id);
83649
+ await mkdir15(runDir, { recursive: true });
83219
83650
  const prompt = gaiaPrompt(question);
83220
83651
  const started = Date.now();
83221
83652
  let run;
@@ -83346,9 +83777,9 @@ var init_runner = __esm({
83346
83777
  });
83347
83778
 
83348
83779
  // ../../packages/evals/dist/tasks.js
83349
- import { readFile as readFile17 } from "node:fs/promises";
83780
+ import { readFile as readFile19 } from "node:fs/promises";
83350
83781
  import { createHash as createHash7 } from "node:crypto";
83351
- import { dirname as dirname11, join as join26 } from "node:path";
83782
+ import { dirname as dirname12, join as join28 } from "node:path";
83352
83783
  import { fileURLToPath as fileURLToPath2 } from "node:url";
83353
83784
  import { homedir as homedir8 } from "node:os";
83354
83785
  async function loadTaskSet(name, options = {}) {
@@ -83370,10 +83801,10 @@ async function loadTaskSet(name, options = {}) {
83370
83801
  }
83371
83802
  }
83372
83803
  function tasksDir() {
83373
- return join26(dirname11(fileURLToPath2(import.meta.url)), "..", "tasks");
83804
+ return join28(dirname12(fileURLToPath2(import.meta.url)), "..", "tasks");
83374
83805
  }
83375
83806
  async function loadUsageTasks() {
83376
- const raw = JSON.parse(await readFile17(join26(tasksDir(), "usage.json"), "utf8"));
83807
+ const raw = JSON.parse(await readFile19(join28(tasksDir(), "usage.json"), "utf8"));
83377
83808
  return raw.tasks.map((task) => ({
83378
83809
  task_id: String(task.id),
83379
83810
  suite: "usage",
@@ -83385,7 +83816,7 @@ async function loadUsageTasks() {
83385
83816
  capability: typeof task.capability === "string" ? task.capability : void 0,
83386
83817
  expect_paid: task.expect_paid,
83387
83818
  file_name: typeof task.attachment === "string" ? task.attachment : void 0,
83388
- file_path: typeof task.attachment === "string" ? join26(tasksDir(), "attachments", task.attachment) : void 0
83819
+ file_path: typeof task.attachment === "string" ? join28(tasksDir(), "attachments", task.attachment) : void 0
83389
83820
  }));
83390
83821
  }
83391
83822
  async function loadGaiaHard(options = {}) {
@@ -83411,13 +83842,13 @@ function gaiaToTask(question) {
83411
83842
  };
83412
83843
  }
83413
83844
  function defaultAssistantBenchCachePath() {
83414
- return process.env.OPENCROWD_ASSISTANTBENCH_CACHE ?? join26(homedir8(), ".cache", "opencrowd", "assistantbench", "validation.jsonl");
83845
+ return process.env.OPENCROWD_ASSISTANTBENCH_CACHE ?? join28(homedir8(), ".cache", "opencrowd", "assistantbench", "validation.jsonl");
83415
83846
  }
83416
83847
  async function loadAssistantBench(options = {}) {
83417
83848
  const cachePath = defaultAssistantBenchCachePath();
83418
83849
  let text;
83419
83850
  try {
83420
- text = await readFile17(cachePath, "utf8");
83851
+ text = await readFile19(cachePath, "utf8");
83421
83852
  } catch {
83422
83853
  options.log?.(`fetching ${ASSISTANTBENCH_ROWS_URL}`);
83423
83854
  const headers = options.hfToken ? { authorization: `Bearer ${options.hfToken}` } : {};
@@ -83428,9 +83859,9 @@ async function loadAssistantBench(options = {}) {
83428
83859
  const body = await response.json();
83429
83860
  text = `${(body.rows ?? []).map((item) => JSON.stringify(item.row)).join("\n")}
83430
83861
  `;
83431
- const { mkdir: mkdir20, writeFile: writeFile11 } = await import("node:fs/promises");
83432
- await mkdir20(dirname11(cachePath), { recursive: true });
83433
- await writeFile11(cachePath, text, "utf8");
83862
+ const { mkdir: mkdir21, writeFile: writeFile13 } = await import("node:fs/promises");
83863
+ await mkdir21(dirname12(cachePath), { recursive: true });
83864
+ await writeFile13(cachePath, text, "utf8");
83434
83865
  }
83435
83866
  const rows = text.split(/\r?\n/).filter(Boolean).map((line) => JSON.parse(line));
83436
83867
  const selected = seededSample(rows, ASSISTANTBENCH_COUNT, `${options.seed ?? DEFAULT_SEED}:assistantbench`, (row) => String(row.id));
@@ -83486,9 +83917,9 @@ var init_tasks = __esm({
83486
83917
  });
83487
83918
 
83488
83919
  // ../../packages/evals/dist/scoring.js
83489
- import { readFile as readFile18, stat } from "node:fs/promises";
83920
+ import { readFile as readFile20, stat } from "node:fs/promises";
83490
83921
  import { resolve as resolveDns } from "node:dns/promises";
83491
- import { join as join27 } from "node:path";
83922
+ import { join as join29 } from "node:path";
83492
83923
  async function scoreTask(task, finalMessage, context = {}) {
83493
83924
  const answer = extractAnswerText(finalMessage);
83494
83925
  const spec = task.scorer;
@@ -83533,7 +83964,7 @@ async function scoreTask(task, finalMessage, context = {}) {
83533
83964
  return { score: 0, correct: false, detail: "no artifacts dir" };
83534
83965
  }
83535
83966
  for (const name of spec.names) {
83536
- const path3 = join27(context.artifactsDir, name);
83967
+ const path3 = join29(context.artifactsDir, name);
83537
83968
  let size5;
83538
83969
  try {
83539
83970
  size5 = (await stat(path3)).size;
@@ -83543,7 +83974,7 @@ async function scoreTask(task, finalMessage, context = {}) {
83543
83974
  if (spec.min_bytes !== void 0 && size5 < spec.min_bytes) {
83544
83975
  return { score: 0, correct: false, detail: `${name} too small (${size5} bytes)` };
83545
83976
  }
83546
- const buffer2 = await readFile18(path3);
83977
+ const buffer2 = await readFile20(path3);
83547
83978
  if (spec.image && !looksLikeImage(buffer2)) {
83548
83979
  return { score: 0, correct: false, detail: `${name} is not a PNG/JPEG/WebP` };
83549
83980
  }
@@ -83730,8 +84161,8 @@ var init_scoring = __esm({
83730
84161
  });
83731
84162
 
83732
84163
  // ../../packages/evals/dist/suite.js
83733
- import { appendFile as appendFile6, mkdir as mkdir15, writeFile as writeFile7 } from "node:fs/promises";
83734
- import { join as join28, resolve as resolve7 } from "node:path";
84164
+ import { appendFile as appendFile6, mkdir as mkdir16, writeFile as writeFile9 } from "node:fs/promises";
84165
+ import { join as join30, resolve as resolve7 } from "node:path";
83735
84166
  async function runSuite(options) {
83736
84167
  const log = options.log ?? (() => void 0);
83737
84168
  const harness = resolveHarness(options.harness ?? "opencrowd");
@@ -83745,8 +84176,8 @@ async function runSuite(options) {
83745
84176
  }
83746
84177
  const runId = `${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}${options.tag ? `-${slug(options.tag)}` : ""}`;
83747
84178
  const resultsDir = resolve7(options.resultsRoot, runId);
83748
- await mkdir15(resultsDir, { recursive: true });
83749
- const resultsPath = join28(resultsDir, "results.jsonl");
84179
+ await mkdir16(resultsDir, { recursive: true });
84180
+ const resultsPath = join30(resultsDir, "results.jsonl");
83750
84181
  log(`suite ${options.set}${options.tag ? ` [${options.tag}]` : ""}: ${tasks.length} tasks, knowledge=${options.knowledgeDir ?? "none"}, results in ${resultsDir}`);
83751
84182
  const limit = createLimiter3(Math.max(1, options.parallel ?? 3));
83752
84183
  const rows = await Promise.all(tasks.map((task, index2) => limit(async () => {
@@ -83770,15 +84201,15 @@ async function runSuite(options) {
83770
84201
  summary: summarize(rows),
83771
84202
  rows
83772
84203
  };
83773
- await writeFile7(join28(resultsDir, "report.json"), `${JSON.stringify(report, null, 2)}
84204
+ await writeFile9(join30(resultsDir, "report.json"), `${JSON.stringify(report, null, 2)}
83774
84205
  `, "utf8");
83775
- await writeFile7(join28(resultsDir, "report.md"), `${renderSuiteReport(report)}
84206
+ await writeFile9(join30(resultsDir, "report.md"), `${renderSuiteReport(report)}
83776
84207
  `, "utf8");
83777
84208
  return report;
83778
84209
  }
83779
84210
  async function runOneTask(harnessName, harness, task, resultsDir, runId, options) {
83780
- const runDir = join28(resultsDir, harnessName, task.task_id);
83781
- await mkdir15(runDir, { recursive: true });
84211
+ const runDir = join30(resultsDir, harnessName, task.task_id);
84212
+ await mkdir16(runDir, { recursive: true });
83782
84213
  const started = Date.now();
83783
84214
  let run;
83784
84215
  try {
@@ -83937,13 +84368,13 @@ var init_suite = __esm({
83937
84368
  });
83938
84369
 
83939
84370
  // ../../packages/evals/dist/evidence.js
83940
- import { mkdir as mkdir16, readFile as readFile19, writeFile as writeFile8 } from "node:fs/promises";
83941
- import { dirname as dirname12 } from "node:path";
84371
+ import { mkdir as mkdir17, readFile as readFile21, writeFile as writeFile10 } from "node:fs/promises";
84372
+ import { dirname as dirname13 } from "node:path";
83942
84373
  async function fetchCrowdCodeEvidence(options = {}) {
83943
84374
  const cachePath = options.cachePath;
83944
84375
  if (cachePath && options.useCache !== false) {
83945
84376
  try {
83946
- return JSON.parse(await readFile19(cachePath, "utf8"));
84377
+ return JSON.parse(await readFile21(cachePath, "utf8"));
83947
84378
  } catch {
83948
84379
  }
83949
84380
  }
@@ -83955,8 +84386,8 @@ async function fetchCrowdCodeEvidence(options = {}) {
83955
84386
  const exported = await fetchGatedExport(fetchImpl, baseUrl, exportToken, log);
83956
84387
  if (exported) {
83957
84388
  if (cachePath) {
83958
- await mkdir16(dirname12(cachePath), { recursive: true });
83959
- await writeFile8(cachePath, `${JSON.stringify(exported, null, 1)}
84389
+ await mkdir17(dirname13(cachePath), { recursive: true });
84390
+ await writeFile10(cachePath, `${JSON.stringify(exported, null, 1)}
83960
84391
  `, "utf8");
83961
84392
  }
83962
84393
  return exported;
@@ -83986,8 +84417,8 @@ async function fetchCrowdCodeEvidence(options = {}) {
83986
84417
  }
83987
84418
  };
83988
84419
  if (cachePath) {
83989
- await mkdir16(dirname12(cachePath), { recursive: true });
83990
- await writeFile8(cachePath, `${JSON.stringify(bundle, null, 1)}
84420
+ await mkdir17(dirname13(cachePath), { recursive: true });
84421
+ await writeFile10(cachePath, `${JSON.stringify(bundle, null, 1)}
83991
84422
  `, "utf8");
83992
84423
  }
83993
84424
  return bundle;
@@ -84155,8 +84586,8 @@ var init_evidence = __esm({
84155
84586
 
84156
84587
  // ../../packages/evals/dist/knowledge.js
84157
84588
  import { createHash as createHash8 } from "node:crypto";
84158
- import { mkdir as mkdir17, readdir as readdir2, readFile as readFile20, writeFile as writeFile9 } from "node:fs/promises";
84159
- import { dirname as dirname13, join as join29, relative as relative4 } from "node:path";
84589
+ import { mkdir as mkdir18, readdir as readdir2, readFile as readFile22, writeFile as writeFile11 } from "node:fs/promises";
84590
+ import { dirname as dirname14, join as join31, relative as relative4 } from "node:path";
84160
84591
  function approxTokens(text) {
84161
84592
  return Math.ceil(text.length / 4);
84162
84593
  }
@@ -84245,32 +84676,32 @@ function validateTree(tree, evidence) {
84245
84676
  };
84246
84677
  }
84247
84678
  async function writeTree(dir, tree, meta4) {
84248
- await mkdir17(dir, { recursive: true });
84679
+ await mkdir18(dir, { recursive: true });
84249
84680
  for (const [name, content] of Object.entries(tree)) {
84250
- const path3 = join29(dir, name);
84251
- await mkdir17(dirname13(path3), { recursive: true });
84252
- await writeFile9(path3, content.endsWith("\n") ? content : `${content}
84681
+ const path3 = join31(dir, name);
84682
+ await mkdir18(dirname14(path3), { recursive: true });
84683
+ await writeFile11(path3, content.endsWith("\n") ? content : `${content}
84253
84684
  `, "utf8");
84254
84685
  }
84255
- await writeFile9(join29(dir, "meta.json"), `${JSON.stringify(meta4, null, 2)}
84686
+ await writeFile11(join31(dir, "meta.json"), `${JSON.stringify(meta4, null, 2)}
84256
84687
  `, "utf8");
84257
84688
  }
84258
84689
  async function readTree(dir) {
84259
84690
  const tree = {};
84260
84691
  const walk3 = async (current) => {
84261
84692
  for (const entry of await readdir2(current, { withFileTypes: true })) {
84262
- const path3 = join29(current, entry.name);
84693
+ const path3 = join31(current, entry.name);
84263
84694
  if (entry.isDirectory()) {
84264
84695
  await walk3(path3);
84265
84696
  } else if (entry.name.endsWith(".md")) {
84266
- tree[relative4(dir, path3)] = await readFile20(path3, "utf8");
84697
+ tree[relative4(dir, path3)] = await readFile22(path3, "utf8");
84267
84698
  }
84268
84699
  }
84269
84700
  };
84270
84701
  await walk3(dir);
84271
84702
  let meta4;
84272
84703
  try {
84273
- meta4 = JSON.parse(await readFile20(join29(dir, "meta.json"), "utf8"));
84704
+ meta4 = JSON.parse(await readFile22(join31(dir, "meta.json"), "utf8"));
84274
84705
  } catch {
84275
84706
  meta4 = void 0;
84276
84707
  }
@@ -84278,7 +84709,7 @@ async function readTree(dir) {
84278
84709
  }
84279
84710
  async function updateTreeMeta(dir, patch) {
84280
84711
  const { meta: meta4 } = await readTree(dir);
84281
- await writeFile9(join29(dir, "meta.json"), `${JSON.stringify({ ...meta4 ?? {}, ...patch }, null, 2)}
84712
+ await writeFile11(join31(dir, "meta.json"), `${JSON.stringify({ ...meta4 ?? {}, ...patch }, null, 2)}
84282
84713
  `, "utf8");
84283
84714
  }
84284
84715
  async function proposeTree(options) {
@@ -84394,23 +84825,23 @@ var init_knowledge2 = __esm({
84394
84825
  });
84395
84826
 
84396
84827
  // ../../packages/evals/dist/evolve.js
84397
- import { mkdir as mkdir18, readFile as readFile21, writeFile as writeFile10 } from "node:fs/promises";
84398
- import { join as join30, resolve as resolve8 } from "node:path";
84828
+ import { mkdir as mkdir19, readFile as readFile23, writeFile as writeFile12 } from "node:fs/promises";
84829
+ import { join as join32, resolve as resolve8 } from "node:path";
84399
84830
  async function runEvolution(options) {
84400
84831
  const log = options.log ?? (() => void 0);
84401
84832
  const root = resolve8(options.resultsRoot);
84402
- const treesDir = join30(root, "trees");
84403
- const runsDir = join30(root, "runs");
84404
- await mkdir18(treesDir, { recursive: true });
84405
- await mkdir18(runsDir, { recursive: true });
84406
- const evidencePath = options.evidencePath ?? join30(root, "evidence", "crowdcode-evidence.json");
84833
+ const treesDir = join32(root, "trees");
84834
+ const runsDir = join32(root, "runs");
84835
+ await mkdir19(treesDir, { recursive: true });
84836
+ await mkdir19(runsDir, { recursive: true });
84837
+ const evidencePath = options.evidencePath ?? join32(root, "evidence", "crowdcode-evidence.json");
84407
84838
  const evidence = await fetchCrowdCodeEvidence({ cachePath: evidencePath, useCache: !options.refreshEvidence, log });
84408
84839
  const digest = renderEvidenceDigest(evidence, { detailTop: 90, maxReviewsPerService: 4 });
84409
84840
  const evidenceHash = hashContent(digest);
84410
84841
  log(`evidence: ${evidence.stats.services} services, ${evidence.stats.reviews} reviews, digest ~${Math.round(digest.length / 4)} tokens`);
84411
84842
  const heldin = await loadTaskSet("heldin", { hfToken: options.hfToken, log });
84412
84843
  const proposer = await buildProposerProviders(root, options.proposerModels);
84413
- const archivePath = join30(root, "archive.json");
84844
+ const archivePath = join32(root, "archive.json");
84414
84845
  const archive = await readArchive(archivePath) ?? {
84415
84846
  started_at: (/* @__PURE__ */ new Date()).toISOString(),
84416
84847
  agent_model: options.agentModel,
@@ -84418,9 +84849,9 @@ async function runEvolution(options) {
84418
84849
  entries: []
84419
84850
  };
84420
84851
  const save = async () => {
84421
- await writeFile10(archivePath, `${JSON.stringify(archive, null, 2)}
84852
+ await writeFile12(archivePath, `${JSON.stringify(archive, null, 2)}
84422
84853
  `, "utf8");
84423
- await writeFile10(join30(root, "frontier.md"), `${renderArchive(archive)}
84854
+ await writeFile12(join32(root, "frontier.md"), `${renderArchive(archive)}
84424
84855
  `, "utf8");
84425
84856
  };
84426
84857
  const evaluate = async (entry, knowledgeDir) => {
@@ -84447,7 +84878,7 @@ async function runEvolution(options) {
84447
84878
  if (!archive.entries.some((entry) => entry.id === "baseline")) {
84448
84879
  const baseline = { id: "baseline", generation: 0, children: 0, status: "evaluated" };
84449
84880
  if (options.baselineReport) {
84450
- const report = JSON.parse(await readFile21(options.baselineReport, "utf8"));
84881
+ const report = JSON.parse(await readFile23(options.baselineReport, "utf8"));
84451
84882
  const rows = report.rows.filter((row) => row.suite === "usage");
84452
84883
  baseline.report_dir = report.results_dir;
84453
84884
  baseline.metrics = metricsOfRows(rows);
@@ -84528,7 +84959,7 @@ async function runEvolution(options) {
84528
84959
  }
84529
84960
  const best = bestEntry(archive);
84530
84961
  if (best?.dir) {
84531
- await writeFile10(join30(root, "BEST"), `${best.dir}
84962
+ await writeFile12(join32(root, "BEST"), `${best.dir}
84532
84963
  `, "utf8");
84533
84964
  }
84534
84965
  await save();
@@ -84561,9 +84992,9 @@ async function proposeCandidate(input2) {
84561
84992
  log: input2.log
84562
84993
  });
84563
84994
  const validation = validateTree(proposal.tree, input2.evidence);
84564
- const dir = join30(input2.treesDir, id);
84565
- await mkdir18(dir, { recursive: true });
84566
- await writeFile10(join30(dir, "proposal.raw.txt"), proposal.rawResponse, "utf8");
84995
+ const dir = join32(input2.treesDir, id);
84996
+ await mkdir19(dir, { recursive: true });
84997
+ await writeFile12(join32(dir, "proposal.raw.txt"), proposal.rawResponse, "utf8");
84567
84998
  if (!validation.ok) {
84568
84999
  errors = validation.errors;
84569
85000
  input2.log(`${id}: invalid (${validation.errors.join("; ")})`);
@@ -84650,7 +85081,7 @@ function metricsOfRows(rows) {
84650
85081
  };
84651
85082
  }
84652
85083
  async function casesFromReport(reportDir) {
84653
- const report = JSON.parse(await readFile21(join30(reportDir, "report.json"), "utf8"));
85084
+ const report = JSON.parse(await readFile23(join32(reportDir, "report.json"), "utf8"));
84654
85085
  const cases = [];
84655
85086
  for (const row of report.rows) {
84656
85087
  cases.push({
@@ -84671,7 +85102,7 @@ async function casesFromReport(reportDir) {
84671
85102
  async function summarizeTrajectory(path3) {
84672
85103
  let text;
84673
85104
  try {
84674
- text = await readFile21(path3, "utf8");
85105
+ text = await readFile23(path3, "utf8");
84675
85106
  } catch {
84676
85107
  return void 0;
84677
85108
  }
@@ -84703,7 +85134,7 @@ async function summarizeTrajectory(path3) {
84703
85134
  return steps.length > 0 ? steps.join(" -> ") : void 0;
84704
85135
  }
84705
85136
  async function buildProposerProviders(root, models) {
84706
- const session = await createOpenCrowdSession({ workspaceRoot: join30(root, "proposer"), approvalMode: "auto", shellEnabled: false });
85137
+ const session = await createOpenCrowdSession({ workspaceRoot: join32(root, "proposer"), approvalMode: "auto", shellEnabled: false });
84707
85138
  const providers = /* @__PURE__ */ new Map();
84708
85139
  for (const model of new Set(models)) {
84709
85140
  const llm = await resolveLlmRuntime(session, { model, subagentModel: "off", nonInteractive: true });
@@ -84720,7 +85151,7 @@ async function buildProposerProviders(root, models) {
84720
85151
  }
84721
85152
  async function readArchive(path3) {
84722
85153
  try {
84723
- return JSON.parse(await readFile21(path3, "utf8"));
85154
+ return JSON.parse(await readFile23(path3, "utf8"));
84724
85155
  } catch {
84725
85156
  return void 0;
84726
85157
  }
@@ -84865,8 +85296,8 @@ init_dist2();
84865
85296
  init_dist4();
84866
85297
  init_dist6();
84867
85298
  init_shared();
84868
- import { copyFile as copyFile2, mkdir as mkdir19, readFile as readFile22, rm as rm3 } from "node:fs/promises";
84869
- import { basename as basename2, join as join31 } from "node:path";
85299
+ import { copyFile as copyFile2, mkdir as mkdir20, readFile as readFile24, rm as rm3 } from "node:fs/promises";
85300
+ import { basename as basename2, join as join33 } from "node:path";
84870
85301
  import { createInterface as createInterface2 } from "node:readline/promises";
84871
85302
  import { stdin as input, stdout as output2 } from "node:process";
84872
85303
 
@@ -85597,8 +86028,8 @@ function indent(text) {
85597
86028
 
85598
86029
  // src/tui/app.tsx
85599
86030
  init_dist2();
85600
- import { join as join22 } from "node:path";
85601
- import { randomUUID as randomUUID8 } from "node:crypto";
86031
+ import { join as join24 } from "node:path";
86032
+ import { randomUUID as randomUUID9 } from "node:crypto";
85602
86033
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
85603
86034
  import { Box, render, Static, Text, useApp, useInput, usePaste, useStdout } from "ink";
85604
86035
  init_dist6();
@@ -85637,7 +86068,7 @@ function App({ session: initialSession, initialTestMode, initialTestSeed, defaul
85637
86068
  const runningRef = useRef(false);
85638
86069
  const inboxPausedRef = useRef(false);
85639
86070
  const [inboxRevision, setInboxRevision] = useState(0);
85640
- const inbox = useMemo(() => new FileSteeringInbox(join22(session.sessionDir, "inbox.json")), [session.sessionDir]);
86071
+ const inbox = useMemo(() => new FileSteeringInbox(join24(session.sessionDir, "inbox.json")), [session.sessionDir]);
85641
86072
  const [activity, setActivity] = useState("");
85642
86073
  const [spinnerFrame, setSpinnerFrame] = useState(0);
85643
86074
  const [modal, setModal] = useState(null);
@@ -86071,7 +86502,7 @@ function App({ session: initialSession, initialTestMode, initialTestSeed, defaul
86071
86502
  if (text) {
86072
86503
  setInput("");
86073
86504
  setCursor(0);
86074
- void inbox.push({ id: randomUUID8(), prompt: text }).then(() => {
86505
+ void inbox.push({ id: randomUUID9(), prompt: text }).then(() => {
86075
86506
  push({ kind: "user", text: `${text} (queued)` });
86076
86507
  setInboxRevision((n) => n + 1);
86077
86508
  }).catch((e6) => push({ kind: "error", text: e6.message }));
@@ -86490,7 +86921,7 @@ async function main(argv) {
86490
86921
  case "--version":
86491
86922
  case "-v":
86492
86923
  case "version": {
86493
- const pkg2 = JSON.parse(await readFile22(new URL("../package.json", import.meta.url), "utf8"));
86924
+ const pkg2 = JSON.parse(await readFile24(new URL("../package.json", import.meta.url), "utf8"));
86494
86925
  console.log(pkg2.version);
86495
86926
  return;
86496
86927
  }
@@ -86595,11 +87026,11 @@ async function headlessRunCommand(args) {
86595
87026
  let task = prompt;
86596
87027
  if (attach) {
86597
87028
  const attachmentName = basename2(attach);
86598
- await mkdir19(session.artifactsDir, { recursive: true });
86599
- await copyFile2(attach, join31(session.artifactsDir, attachmentName));
87029
+ await mkdir20(session.artifactsDir, { recursive: true });
87030
+ await copyFile2(attach, join33(session.artifactsDir, attachmentName));
86600
87031
  task = `${prompt}
86601
87032
 
86602
- An input file is available at the session artifact path \`${attachmentName}\` (use read_file, or run_shell against ${join31(session.artifactsDir, attachmentName)}).`;
87033
+ An input file is available at the session artifact path \`${attachmentName}\` (use read_file, or run_shell against ${join33(session.artifactsDir, attachmentName)}).`;
86603
87034
  }
86604
87035
  const result = await runPersistentAgentTaskDetailed(session, task, {
86605
87036
  model: readOption(args, "--model"),
@@ -86623,7 +87054,7 @@ An input file is available at the session artifact path \`${attachmentName}\` (u
86623
87054
  final_message: result.summary.final_message ?? null,
86624
87055
  session_id: session.sessionId,
86625
87056
  session_dir: session.sessionDir,
86626
- trajectory_path: join31(session.sessionDir, "messages.jsonl"),
87057
+ trajectory_path: join33(session.sessionDir, "messages.jsonl"),
86627
87058
  turns: result.turns,
86628
87059
  model_policy: session.models ?? null,
86629
87060
  usdc_spent_cents: {
@@ -86706,7 +87137,7 @@ async function ledgerCommand(args) {
86706
87137
  if (!sessionId) {
86707
87138
  throw new Error("no local sessions found");
86708
87139
  }
86709
- const rows = await readLedger(join31(process.cwd(), "sessions", sessionId, "ledger.csv"));
87140
+ const rows = await readLedger(join33(process.cwd(), "sessions", sessionId, "ledger.csv"));
86710
87141
  printValue("Ledger", rows, {
86711
87142
  json: json3,
86712
87143
  pretty: renderTable(rows.map(asRecord), [
@@ -86743,7 +87174,7 @@ async function resumeCommand(args) {
86743
87174
  } catch (e6) {
86744
87175
  if (!(e6 instanceof SpendingDeclined)) throw e6;
86745
87176
  }
86746
- await rm3(join31(session.sessionDir, "query-checkpoint.json"), { force: true });
87177
+ await rm3(join33(session.sessionDir, "query-checkpoint.json"), { force: true });
86747
87178
  console.log("Query declined. Nothing was paid for the pending call.");
86748
87179
  return;
86749
87180
  }
@@ -86882,7 +87313,7 @@ async function evalsSuiteCommand(rest) {
86882
87313
  const report = await runSuite2({
86883
87314
  set: set3,
86884
87315
  harness: readOption(rest, "--harness") ?? "opencrowd",
86885
- resultsRoot: readOption(rest, "--out") ?? join31(process.cwd(), "evals", "suite"),
87316
+ resultsRoot: readOption(rest, "--out") ?? join33(process.cwd(), "evals", "suite"),
86886
87317
  tag: readOption(rest, "--tag"),
86887
87318
  knowledgeDir: readOption(rest, "--knowledge"),
86888
87319
  hfToken: readOption(rest, "--hf-token") ?? process.env.HF_TOKEN,
@@ -86901,7 +87332,7 @@ async function evalsSuiteCommand(rest) {
86901
87332
  async function evalsEvolveCommand(rest) {
86902
87333
  const { runEvolution: runEvolution2, renderArchive: renderArchive2 } = await Promise.resolve().then(() => (init_dist7(), dist_exports));
86903
87334
  const { archive, best } = await runEvolution2({
86904
- resultsRoot: readOption(rest, "--out") ?? join31(process.cwd(), "evals", "evolve"),
87335
+ resultsRoot: readOption(rest, "--out") ?? join33(process.cwd(), "evals", "evolve"),
86905
87336
  evidencePath: readOption(rest, "--evidence"),
86906
87337
  refreshEvidence: rest.includes("--refresh-evidence"),
86907
87338
  generations: Number(readOption(rest, "--generations") ?? 2),