opencrowd 0.15.2 → 0.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/opencrowd.js +264 -72
- package/package.json +1 -1
package/bundle/opencrowd.js
CHANGED
|
@@ -15432,6 +15432,13 @@ var init_primitives = __esm({
|
|
|
15432
15432
|
});
|
|
15433
15433
|
|
|
15434
15434
|
// ../../packages/protocol/dist/outcomes.js
|
|
15435
|
+
function upstreamRefusalSummary(error53) {
|
|
15436
|
+
const refusal = error53;
|
|
15437
|
+
if (!refusal || typeof refusal !== "object" || refusal.name !== "HostedRequestError" || refusal.code !== "upstream_refused")
|
|
15438
|
+
return void 0;
|
|
15439
|
+
const detail = typeof refusal.message === "string" ? refusal.message.trim() : "";
|
|
15440
|
+
return `The model provider refused this request before any payment, so nothing was charged${detail ? `: ${detail}` : "."} You can retry or send another message.`;
|
|
15441
|
+
}
|
|
15435
15442
|
var RUN_FAILURE_MESSAGE, RUN_OUTCOMES, RunOutcomeSchema, RESUME_CAUSES, ResumeCauseSchema, RunStateSchema;
|
|
15436
15443
|
var init_outcomes = __esm({
|
|
15437
15444
|
"../../packages/protocol/dist/outcomes.js"() {
|
|
@@ -15926,7 +15933,7 @@ var init_limits = __esm({
|
|
|
15926
15933
|
|
|
15927
15934
|
// ../../packages/protocol/dist/telemetry.js
|
|
15928
15935
|
function scrubText(text) {
|
|
15929
|
-
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(
|
|
15936
|
+
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(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+:[^\s/@]+@/gi, "$1[REDACTED]@");
|
|
15930
15937
|
}
|
|
15931
15938
|
function captureDetail(input2, maxBytes = 96 * 1024) {
|
|
15932
15939
|
let redacted = false;
|
|
@@ -16101,6 +16108,18 @@ function estimateContextTokens(value) {
|
|
|
16101
16108
|
function estimateModelInput(messages, tools) {
|
|
16102
16109
|
return messages.reduce((total, message) => total + estimateContextTokens(message), estimateContextTokens(tools) + 32);
|
|
16103
16110
|
}
|
|
16111
|
+
function isRequestTooLargeError(value, status) {
|
|
16112
|
+
if (status === 413)
|
|
16113
|
+
return true;
|
|
16114
|
+
const error53 = value;
|
|
16115
|
+
if (!error53 || typeof error53 !== "object")
|
|
16116
|
+
return false;
|
|
16117
|
+
if (["request_too_large", "payload_too_large", "request_entity_too_large", "body_too_large"].includes(String(error53.code)))
|
|
16118
|
+
return true;
|
|
16119
|
+
if (typeof error53.message === "string" && /request (?:body|entity|payload) (?:is )?too large|payload too large|request too large|body must be at most/i.test(error53.message))
|
|
16120
|
+
return true;
|
|
16121
|
+
return error53.error !== value && !!error53.error && isRequestTooLargeError(typeof error53.error === "string" ? { message: error53.error } : error53.error);
|
|
16122
|
+
}
|
|
16104
16123
|
function isContextWindowError(value) {
|
|
16105
16124
|
const error53 = value;
|
|
16106
16125
|
if (!error53 || typeof error53 !== "object")
|
|
@@ -16111,16 +16130,19 @@ function isContextWindowError(value) {
|
|
|
16111
16130
|
return true;
|
|
16112
16131
|
return error53.error !== value && !!error53.error && isContextWindowError(typeof error53.error === "string" ? { message: error53.error } : error53.error);
|
|
16113
16132
|
}
|
|
16114
|
-
var MODEL_REQUEST_MAX_BYTES, MODEL_MAX_MESSAGES, MODEL_GATEWAY_TIMEOUT_MS, MODEL_BRIDGE_TIMEOUT_MS, SERVICE_GATEWAY_TIMEOUT_MS, SERVICE_BRIDGE_TIMEOUT_MS, SERVICE_RESPONSE_MAX_BYTES, DEFAULT_CONTEXT_WINDOW, ContextWindowExceeded;
|
|
16133
|
+
var MODEL_REQUEST_MAX_BYTES, MODEL_SELLER_REQUEST_MAX_BYTES, MODEL_MAX_MESSAGES, MODEL_GATEWAY_TIMEOUT_MS, MODEL_BRIDGE_TIMEOUT_MS, SERVICE_GATEWAY_TIMEOUT_MS, SERVICE_BRIDGE_TIMEOUT_MS, HOSTED_TOOL_BRIDGE_TIMEOUT_MS, HOSTED_CONTROL_TOOL_TIMEOUT_MS, SERVICE_RESPONSE_MAX_BYTES, DEFAULT_CONTEXT_WINDOW, ContextWindowExceeded;
|
|
16115
16134
|
var init_context = __esm({
|
|
16116
16135
|
"../../packages/protocol/dist/context.js"() {
|
|
16117
16136
|
"use strict";
|
|
16118
16137
|
MODEL_REQUEST_MAX_BYTES = 16 * 1024 * 1024;
|
|
16138
|
+
MODEL_SELLER_REQUEST_MAX_BYTES = 5 * 1024 * 1024;
|
|
16119
16139
|
MODEL_MAX_MESSAGES = 1e3;
|
|
16120
16140
|
MODEL_GATEWAY_TIMEOUT_MS = 42e4;
|
|
16121
16141
|
MODEL_BRIDGE_TIMEOUT_MS = 2 * MODEL_GATEWAY_TIMEOUT_MS + 3e4;
|
|
16122
16142
|
SERVICE_GATEWAY_TIMEOUT_MS = 33e4;
|
|
16123
16143
|
SERVICE_BRIDGE_TIMEOUT_MS = MODEL_GATEWAY_TIMEOUT_MS + SERVICE_GATEWAY_TIMEOUT_MS + 3e4;
|
|
16144
|
+
HOSTED_TOOL_BRIDGE_TIMEOUT_MS = 9e4;
|
|
16145
|
+
HOSTED_CONTROL_TOOL_TIMEOUT_MS = 185e3;
|
|
16124
16146
|
SERVICE_RESPONSE_MAX_BYTES = 34 * 1024 * 1024;
|
|
16125
16147
|
DEFAULT_CONTEXT_WINDOW = 64e3;
|
|
16126
16148
|
ContextWindowExceeded = class extends Error {
|
|
@@ -16129,6 +16151,44 @@ var init_context = __esm({
|
|
|
16129
16151
|
}
|
|
16130
16152
|
});
|
|
16131
16153
|
|
|
16154
|
+
// ../../packages/protocol/dist/deadlines.js
|
|
16155
|
+
function withDeadline(work, timeoutMs, stage) {
|
|
16156
|
+
let timer;
|
|
16157
|
+
const started = work();
|
|
16158
|
+
started.catch(() => void 0);
|
|
16159
|
+
const expiry = new Promise((_resolve, reject) => {
|
|
16160
|
+
timer = setTimeout(() => reject(new DeadlineExceeded(stage, timeoutMs)), timeoutMs);
|
|
16161
|
+
});
|
|
16162
|
+
return Promise.race([started, expiry]).finally(() => clearTimeout(timer));
|
|
16163
|
+
}
|
|
16164
|
+
function deadline(totalMs, now = Date.now) {
|
|
16165
|
+
const expiresAt = now() + totalMs;
|
|
16166
|
+
return {
|
|
16167
|
+
/** Milliseconds left, never negative. */
|
|
16168
|
+
remaining: () => Math.max(0, expiresAt - now()),
|
|
16169
|
+
expired: () => now() >= expiresAt,
|
|
16170
|
+
/** The smaller of what is left and one operation's own ceiling. */
|
|
16171
|
+
slice: (operationMs) => Math.min(operationMs, Math.max(0, expiresAt - now()))
|
|
16172
|
+
};
|
|
16173
|
+
}
|
|
16174
|
+
var DeadlineExceeded;
|
|
16175
|
+
var init_deadlines = __esm({
|
|
16176
|
+
"../../packages/protocol/dist/deadlines.js"() {
|
|
16177
|
+
"use strict";
|
|
16178
|
+
DeadlineExceeded = class extends Error {
|
|
16179
|
+
stage;
|
|
16180
|
+
timeoutMs;
|
|
16181
|
+
code = "deadline_exceeded";
|
|
16182
|
+
constructor(stage, timeoutMs) {
|
|
16183
|
+
super(`${stage} did not finish within ${Math.round(timeoutMs / 1e3)}s`);
|
|
16184
|
+
this.stage = stage;
|
|
16185
|
+
this.timeoutMs = timeoutMs;
|
|
16186
|
+
this.name = "DeadlineExceeded";
|
|
16187
|
+
}
|
|
16188
|
+
};
|
|
16189
|
+
}
|
|
16190
|
+
});
|
|
16191
|
+
|
|
16132
16192
|
// ../../packages/protocol/dist/spending.js
|
|
16133
16193
|
function spendingDecision(input2) {
|
|
16134
16194
|
const amount = BigInt(input2.amount), committed = BigInt(input2.queryCommitted);
|
|
@@ -16242,6 +16302,7 @@ var init_dist = __esm({
|
|
|
16242
16302
|
init_seq();
|
|
16243
16303
|
init_codec();
|
|
16244
16304
|
init_context();
|
|
16305
|
+
init_deadlines();
|
|
16245
16306
|
init_spending();
|
|
16246
16307
|
init_financial_state();
|
|
16247
16308
|
}
|
|
@@ -57687,6 +57748,16 @@ var init_offers = __esm({
|
|
|
57687
57748
|
});
|
|
57688
57749
|
|
|
57689
57750
|
// ../../packages/economy/dist/discovery.js
|
|
57751
|
+
function bounded(work, timeoutMs, stage) {
|
|
57752
|
+
return withDeadline(work, timeoutMs, stage).catch((error53) => ({ ok: false, error: error53.message }));
|
|
57753
|
+
}
|
|
57754
|
+
function originOf(url3) {
|
|
57755
|
+
try {
|
|
57756
|
+
return new URL(url3).origin;
|
|
57757
|
+
} catch {
|
|
57758
|
+
return url3;
|
|
57759
|
+
}
|
|
57760
|
+
}
|
|
57690
57761
|
function searchResults(raw) {
|
|
57691
57762
|
const body = raw?.results?.results ? raw.results : raw?.data?.results ? raw.data : raw;
|
|
57692
57763
|
return Array.isArray(body?.results) ? body.results : Array.isArray(body?.services) ? body.services : [];
|
|
@@ -57728,12 +57799,16 @@ function ranked(ranking, schema) {
|
|
|
57728
57799
|
sources: ranking.sources
|
|
57729
57800
|
};
|
|
57730
57801
|
}
|
|
57731
|
-
var RANKED_NOTE, BaseServiceDiscovery;
|
|
57802
|
+
var PROBE_DEADLINE_MS, VERIFY_SWEEP_DEADLINE_MS, CATALOG_DEADLINE_MS, RANKED_NOTE, BaseServiceDiscovery;
|
|
57732
57803
|
var init_discovery = __esm({
|
|
57733
57804
|
"../../packages/economy/dist/discovery.js"() {
|
|
57734
57805
|
"use strict";
|
|
57735
57806
|
init_dist3();
|
|
57807
|
+
init_dist();
|
|
57736
57808
|
init_offers();
|
|
57809
|
+
PROBE_DEADLINE_MS = 15e3;
|
|
57810
|
+
VERIFY_SWEEP_DEADLINE_MS = 6e4;
|
|
57811
|
+
CATALOG_DEADLINE_MS = 45e3;
|
|
57737
57812
|
RANKED_NOTE = "Ranked by CrowdCode across Base, Solana and Tempo (AgentCash, Coinbase's x402 catalog, MPP catalog and CrowdCode reviews): quality first, then effective price on best_network (including about $0.03 to move USDC between your own networks when that network's balance is short), then your balance there. Prefer the highest-ranked service that fits the task, whatever its network. Each result's `networks` are the networks it can be paid on; between results that fit the task equally well, one you can pay from a balance you already hold beats one that needs a transfer first. transfer_needed means your balance on best_network is short: move USDC between your own networks first if you have a tool for that; otherwise say which network needs funds. New/unreviewed services are allowed. Inspect the chosen endpoint before paying.";
|
|
57738
57813
|
BaseServiceDiscovery = class {
|
|
57739
57814
|
searchApi;
|
|
@@ -57745,17 +57820,26 @@ var init_discovery = __esm({
|
|
|
57745
57820
|
this.options = options;
|
|
57746
57821
|
this.rails = options.rails ?? localRails(options.paymentNetwork);
|
|
57747
57822
|
}
|
|
57748
|
-
async inspect(input2) {
|
|
57823
|
+
async inspect(input2, budgetMs = PROBE_DEADLINE_MS) {
|
|
57749
57824
|
const key = `${input2.method ?? "POST"} ${input2.url}`;
|
|
57750
57825
|
const cached3 = this.cache.get(key);
|
|
57751
57826
|
if (input2.body === void 0 && cached3 && cached3.until > Date.now())
|
|
57752
57827
|
return { ok: true, data: cached3.data };
|
|
57753
|
-
|
|
57754
|
-
|
|
57755
|
-
|
|
57756
|
-
|
|
57757
|
-
|
|
57758
|
-
|
|
57828
|
+
if (budgetMs <= 0)
|
|
57829
|
+
return { ok: false, error: "Endpoint inspection ran out of time before it started" };
|
|
57830
|
+
let result;
|
|
57831
|
+
try {
|
|
57832
|
+
result = await withDeadline(() => checkEndpointSchema({
|
|
57833
|
+
url: input2.url,
|
|
57834
|
+
probe: true,
|
|
57835
|
+
sampleInputBody: input2.body && typeof input2.body === "object" ? input2.body : void 0,
|
|
57836
|
+
signal: AbortSignal.timeout(Math.min(1e4, budgetMs))
|
|
57837
|
+
}), budgetMs, `probe of ${originOf(input2.url)}`);
|
|
57838
|
+
} catch (error53) {
|
|
57839
|
+
if (!(error53 instanceof DeadlineExceeded))
|
|
57840
|
+
throw error53;
|
|
57841
|
+
return { ok: false, error: `${originOf(input2.url)} did not answer the inspection probe within ${Math.round(budgetMs / 1e3)}s` };
|
|
57842
|
+
}
|
|
57759
57843
|
if (!result.found)
|
|
57760
57844
|
return { ok: false, error: result.message ?? "Endpoint inspection failed" };
|
|
57761
57845
|
const advisory = result.advisories.find((a) => a.method === (input2.method ?? "POST").toUpperCase());
|
|
@@ -57813,17 +57897,31 @@ var init_discovery = __esm({
|
|
|
57813
57897
|
const reason = payableNetworks(offers, this.rails).includes(preferred) ? `your ${preferred} balance does not cover it` : `${preferred} is not offered`;
|
|
57814
57898
|
return `Pays ${networkLabel(offer)}${offer.network_name === preferred ? "" : ` (${reason})`}. ${quote}`;
|
|
57815
57899
|
}
|
|
57816
|
-
/**
|
|
57817
|
-
|
|
57900
|
+
/**
|
|
57901
|
+
* Probe candidates in order and keep the first `limit` this payer can
|
|
57902
|
+
* settle, within one shared time budget.
|
|
57903
|
+
*
|
|
57904
|
+
* `incomplete` is true when the budget ran out with candidates left. The
|
|
57905
|
+
* caller says so in the note: a short list of real, payable services is a
|
|
57906
|
+
* usable answer, and far better than the nine-minute silence this sweep used
|
|
57907
|
+
* to be capable of. Returning nothing at all would not be.
|
|
57908
|
+
*/
|
|
57909
|
+
async verified(candidates, limit, budgetMs = VERIFY_SWEEP_DEADLINE_MS) {
|
|
57818
57910
|
const services = [];
|
|
57911
|
+
const budget = deadline(budgetMs);
|
|
57912
|
+
let incomplete = false;
|
|
57819
57913
|
for (let i = 0; i < candidates.length && services.length < limit; i += 4) {
|
|
57914
|
+
if (budget.expired()) {
|
|
57915
|
+
incomplete = true;
|
|
57916
|
+
break;
|
|
57917
|
+
}
|
|
57820
57918
|
const batch = await Promise.all(candidates.slice(i, i + 4).map(async (c) => {
|
|
57821
57919
|
try {
|
|
57822
57920
|
const endpoint = c.endpoint ?? new URL(c.path, typeof c.origin === "string" ? c.origin : c.origin?.url).href;
|
|
57823
57921
|
let method = c.method ?? "POST";
|
|
57824
|
-
let inspection = await this.inspect({ url: endpoint, method });
|
|
57922
|
+
let inspection = await this.inspect({ url: endpoint, method }, budget.slice(PROBE_DEADLINE_MS));
|
|
57825
57923
|
if (!inspection.ok && !c.method)
|
|
57826
|
-
inspection = await this.inspect({ url: endpoint, method: method = "GET" });
|
|
57924
|
+
inspection = await this.inspect({ url: endpoint, method: method = "GET" }, budget.slice(PROBE_DEADLINE_MS));
|
|
57827
57925
|
const schema = inspection.data;
|
|
57828
57926
|
if (!inspection.ok || !schema?.payable)
|
|
57829
57927
|
return void 0;
|
|
@@ -57845,7 +57943,13 @@ var init_discovery = __esm({
|
|
|
57845
57943
|
}));
|
|
57846
57944
|
services.push(...batch.filter(Boolean));
|
|
57847
57945
|
}
|
|
57848
|
-
|
|
57946
|
+
if (budget.expired() && services.length < limit)
|
|
57947
|
+
incomplete = true;
|
|
57948
|
+
return { services: services.slice(0, limit), incomplete };
|
|
57949
|
+
}
|
|
57950
|
+
/** What the model is told when the probe budget cut a candidate list short. */
|
|
57951
|
+
partialNote(incomplete) {
|
|
57952
|
+
return incomplete ? " Some candidates were still being probed when the search's time budget ran out, so this list is partial; search again or narrow the query if nothing here fits." : "";
|
|
57849
57953
|
}
|
|
57850
57954
|
/** The networks this payer settles, as CrowdCode names them. */
|
|
57851
57955
|
networks() {
|
|
@@ -57861,38 +57965,48 @@ var init_discovery = __esm({
|
|
|
57861
57965
|
const limit = Math.min(20, Math.max(1, options.limit ?? 8));
|
|
57862
57966
|
const { rank, ...searchOptions } = options;
|
|
57863
57967
|
const [result, balances] = await Promise.all([
|
|
57864
|
-
this.searchApi(query, { ...searchOptions, limit: Math.min(50, limit * 3) })
|
|
57865
|
-
rank && this.options.balances ? this.options.balances().catch(() => void 0) : Promise.resolve(void 0)
|
|
57968
|
+
bounded(() => this.searchApi(query, { ...searchOptions, limit: Math.min(50, limit * 3) }), CATALOG_DEADLINE_MS, "AgentCash search"),
|
|
57969
|
+
rank && this.options.balances ? withDeadline(() => this.options.balances(), CATALOG_DEADLINE_MS, "wallet balance read").catch(() => void 0) : Promise.resolve(void 0)
|
|
57866
57970
|
]);
|
|
57867
57971
|
const candidates = result.ok ? searchResults(result.data) : [];
|
|
57868
57972
|
if (rank) {
|
|
57869
|
-
const ranking = await rank({
|
|
57973
|
+
const ranking = await bounded(() => rank({
|
|
57870
57974
|
query,
|
|
57871
57975
|
networks: this.networks(),
|
|
57872
57976
|
...balances ? { balances } : {},
|
|
57873
57977
|
candidates: candidates.map(agentCashCandidate).filter((candidate) => candidate !== void 0),
|
|
57874
57978
|
limit: Math.min(25, limit * 2)
|
|
57875
|
-
})
|
|
57979
|
+
}), CATALOG_DEADLINE_MS, "CrowdCode ranking");
|
|
57876
57980
|
const services = ranking.data?.services;
|
|
57877
57981
|
if (ranking.ok && Array.isArray(services)) {
|
|
57878
57982
|
const ordered = services.filter((service) => typeof service?.endpoint === "string").map((service) => ({ endpoint: service.endpoint, method: service.method ?? void 0, name: service.name, ranking: service }));
|
|
57879
|
-
|
|
57983
|
+
const verified2 = await this.verified(ordered, limit);
|
|
57984
|
+
return { ok: true, data: { services: verified2.services, note: `${RANKED_NOTE}${this.partialNote(verified2.incomplete)}` } };
|
|
57880
57985
|
}
|
|
57881
57986
|
}
|
|
57882
57987
|
if (!result.ok)
|
|
57883
57988
|
return result;
|
|
57989
|
+
const verified = await this.verified(candidates, limit);
|
|
57884
57990
|
return { ok: true, data: {
|
|
57885
|
-
services:
|
|
57886
|
-
note: `AgentCash discovery${rank ? " (CrowdCode ranking unavailable)" : ""}, verified ${describeRails(this.rails)}. New/unreviewed services are allowed. Inspect the chosen endpoint before paying
|
|
57991
|
+
services: verified.services,
|
|
57992
|
+
note: `AgentCash discovery${rank ? " (CrowdCode ranking unavailable)" : ""}, verified ${describeRails(this.rails)}. New/unreviewed services are allowed. Inspect the chosen endpoint before paying.${this.partialNote(verified.incomplete)}`
|
|
57887
57993
|
} };
|
|
57888
57994
|
}
|
|
57889
57995
|
async discoverEndpoints(origin) {
|
|
57890
|
-
|
|
57996
|
+
let result;
|
|
57997
|
+
try {
|
|
57998
|
+
result = await withDeadline(() => discoverOriginSchema({ target: origin, signal: AbortSignal.timeout(1e4) }), PROBE_DEADLINE_MS, `discovery of ${origin}`);
|
|
57999
|
+
} catch (error53) {
|
|
58000
|
+
if (!(error53 instanceof DeadlineExceeded))
|
|
58001
|
+
throw error53;
|
|
58002
|
+
return { ok: false, error: `${origin} did not answer its discovery document within ${Math.round(PROBE_DEADLINE_MS / 1e3)}s` };
|
|
58003
|
+
}
|
|
57891
58004
|
if (!result.found)
|
|
57892
58005
|
return { ok: false, error: result.message ?? "Provider discovery failed" };
|
|
57893
58006
|
const candidates = result.endpoints.filter((e6) => e6.protocols?.some((protocol) => protocol === "x402" || protocol === "mpp")).map((e6) => ({ ...e6, origin: result.origin }));
|
|
58007
|
+
const verified = await this.verified(candidates, 50);
|
|
57894
58008
|
return { ok: true, data: {
|
|
57895
|
-
services:
|
|
58009
|
+
services: verified.services,
|
|
57896
58010
|
guidance: result.guidance,
|
|
57897
58011
|
reads: result.endpoints.filter((e6) => ["siwx", "unprotected"].includes(e6.authMode ?? "")),
|
|
57898
58012
|
note: "Use read_service to poll job URLs. Do not buy the same generation twice."
|
|
@@ -58621,7 +58735,7 @@ function requestFor(endpoint, method, body) {
|
|
|
58621
58735
|
function inspectionKey(endpoint, method) {
|
|
58622
58736
|
return `${method} ${endpoint}`;
|
|
58623
58737
|
}
|
|
58624
|
-
function
|
|
58738
|
+
function originOf2(endpoint) {
|
|
58625
58739
|
try {
|
|
58626
58740
|
return new URL(endpoint).origin;
|
|
58627
58741
|
} catch {
|
|
@@ -59053,7 +59167,7 @@ var init_gateway = __esm({
|
|
|
59053
59167
|
};
|
|
59054
59168
|
}
|
|
59055
59169
|
async resolveApproval(endpoint, method, quotedCostCents, evidence) {
|
|
59056
|
-
const origin =
|
|
59170
|
+
const origin = originOf2(endpoint);
|
|
59057
59171
|
const rules = await loadApprovalRules(this.options.approvalRulesPath);
|
|
59058
59172
|
const rule = matchApprovalRule(rules, endpoint, origin);
|
|
59059
59173
|
if (rule?.decision === "block") {
|
|
@@ -59108,9 +59222,9 @@ var init_gateway = __esm({
|
|
|
59108
59222
|
return `quoted cost ${quotedCostCents}c exceeds the per-call cap ${caps.maxCostCents}c for ${endpoint}`;
|
|
59109
59223
|
}
|
|
59110
59224
|
if (caps.sessionMaxCents !== void 0) {
|
|
59111
|
-
const spent = (await listPurchases(this.options.session)).filter((state) =>
|
|
59225
|
+
const spent = (await listPurchases(this.options.session)).filter((state) => originOf2(state.record.endpoint) === originOf2(endpoint)).reduce((total, state) => total + state.record.charged_cost_cents, 0);
|
|
59112
59226
|
if (spent + quotedCostCents > caps.sessionMaxCents) {
|
|
59113
|
-
return `quoted cost would exceed the session cap ${caps.sessionMaxCents}c for ${
|
|
59227
|
+
return `quoted cost would exceed the session cap ${caps.sessionMaxCents}c for ${originOf2(endpoint)} (already ${spent}c)`;
|
|
59114
59228
|
}
|
|
59115
59229
|
}
|
|
59116
59230
|
return void 0;
|
|
@@ -59644,7 +59758,7 @@ async function completeWithContext(session, messages, options) {
|
|
|
59644
59758
|
options.state.retry = 0;
|
|
59645
59759
|
return response;
|
|
59646
59760
|
} catch (error53) {
|
|
59647
|
-
const overflow = error53 instanceof ContextWindowExceeded || !options.hosted && isContextWindowError(error53);
|
|
59761
|
+
const overflow = error53 instanceof ContextWindowExceeded || !options.hosted && (isContextWindowError(error53) || isRequestTooLargeError(error53));
|
|
59648
59762
|
if (!overflow || (options.state.retry ?? 0) >= 2)
|
|
59649
59763
|
throw error53;
|
|
59650
59764
|
options.state.retry = (options.state.retry ?? 0) + 1;
|
|
@@ -59670,10 +59784,12 @@ async function compactContext(session, messages, options) {
|
|
|
59670
59784
|
const count = (list2) => Math.ceil(list2.reduce((total, m) => total + measure(m).tokens, toolTokens) * scale);
|
|
59671
59785
|
const tokensBefore = count(messages);
|
|
59672
59786
|
const retry = options.state.retry ?? 0;
|
|
59673
|
-
const trigger = Math.floor(limits.trigger * 0.5 ** retry);
|
|
59674
|
-
const target = Math.min(limits.target, Math.floor(trigger * 0.5));
|
|
59675
59787
|
const bytes = (list2) => list2.reduce((total, m) => total + measure(m).bytes, toolBytes);
|
|
59676
|
-
const
|
|
59788
|
+
const budget = options.maxRequestBytes ?? (options.hosted ? MODEL_SELLER_REQUEST_MAX_BYTES : MODEL_REQUEST_MAX_BYTES);
|
|
59789
|
+
const byteCeiling = budget - 64 * 1024;
|
|
59790
|
+
const trigger = retry ? Math.min(Math.floor(limits.trigger * 0.5 ** retry), Math.floor(tokensBefore * 0.5)) : limits.trigger;
|
|
59791
|
+
const target = Math.min(limits.target, Math.floor(trigger * 0.5));
|
|
59792
|
+
const transportLimit = retry ? Math.floor(Math.min(byteCeiling, bytes(messages) * 0.5)) : byteCeiling;
|
|
59677
59793
|
if (tokensBefore <= trigger && bytes(messages) <= transportLimit && messages.length <= MODEL_MAX_MESSAGES && !retry)
|
|
59678
59794
|
return { tokensBefore, tokensAfter: tokensBefore };
|
|
59679
59795
|
const raw = messages.map((message) => JSON.stringify(message)).join("\n") + "\n";
|
|
@@ -59732,7 +59848,7 @@ async function compactContext(session, messages, options) {
|
|
|
59732
59848
|
entry.message.content = await externalize(entry.message, entry.index);
|
|
59733
59849
|
}
|
|
59734
59850
|
const tokensAfter = count(current());
|
|
59735
|
-
if (tokensAfter > trigger || bytes(current()) >
|
|
59851
|
+
if (tokensAfter > Math.max(trigger, limits.trigger) || bytes(current()) > byteCeiling || list.length > MODEL_MAX_MESSAGES)
|
|
59736
59852
|
throw new Error(`Context cannot fit after compaction: system instructions, tools and required references exceed the input budget. Original context: ${archivePath}`);
|
|
59737
59853
|
messages.splice(0, messages.length, ...current());
|
|
59738
59854
|
return { tokensBefore, tokensAfter, archivePath };
|
|
@@ -62532,9 +62648,9 @@ ${value.slice(-(scanLimit - prefixLength))}`;
|
|
|
62532
62648
|
);
|
|
62533
62649
|
}
|
|
62534
62650
|
const pollUrl = this.absolute(submitData.poll_url);
|
|
62535
|
-
const
|
|
62651
|
+
const deadline2 = Date.now() + budgetMs;
|
|
62536
62652
|
let lastStatus = submitData.status || "queued";
|
|
62537
|
-
while (Date.now() <
|
|
62653
|
+
while (Date.now() < deadline2) {
|
|
62538
62654
|
await sleep(intervalMs);
|
|
62539
62655
|
const pollResp = await this.fetchWithTimeout(pollUrl, {
|
|
62540
62656
|
method: "GET",
|
|
@@ -64270,7 +64386,7 @@ var init_chunk_GPMYUGHX = __esm({
|
|
|
64270
64386
|
});
|
|
64271
64387
|
|
|
64272
64388
|
// ../../node_modules/@x402/evm/dist/esm/chunk-X4BYNI7R.mjs
|
|
64273
|
-
async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion, chainId,
|
|
64389
|
+
async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion, chainId, deadline2, permittedAmount) {
|
|
64274
64390
|
const owner = signer.address;
|
|
64275
64391
|
const spender = getAddress(PERMIT2_ADDRESS);
|
|
64276
64392
|
const nonce = await signer.readContract({
|
|
@@ -64291,7 +64407,7 @@ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion,
|
|
|
64291
64407
|
spender,
|
|
64292
64408
|
value: approvalAmount,
|
|
64293
64409
|
nonce,
|
|
64294
|
-
deadline: BigInt(
|
|
64410
|
+
deadline: BigInt(deadline2)
|
|
64295
64411
|
};
|
|
64296
64412
|
const signature = await signer.signTypedData({
|
|
64297
64413
|
domain: domain3,
|
|
@@ -64305,7 +64421,7 @@ async function signEip2612Permit(signer, tokenAddress, tokenName, tokenVersion,
|
|
|
64305
64421
|
spender,
|
|
64306
64422
|
amount: approvalAmount.toString(),
|
|
64307
64423
|
nonce: nonce.toString(),
|
|
64308
|
-
deadline,
|
|
64424
|
+
deadline: deadline2,
|
|
64309
64425
|
signature,
|
|
64310
64426
|
version: "1"
|
|
64311
64427
|
};
|
|
@@ -64432,7 +64548,7 @@ async function trySignEip2612PermitExtension(signer, options, requirements, resu
|
|
|
64432
64548
|
} catch {
|
|
64433
64549
|
}
|
|
64434
64550
|
const permit2Auth = result.payload?.permit2Authorization;
|
|
64435
|
-
const
|
|
64551
|
+
const deadline2 = permit2Auth?.deadline ?? Math.floor(Date.now() / 1e3 + requirements.maxTimeoutSeconds).toString();
|
|
64436
64552
|
const info = await signEip2612Permit(
|
|
64437
64553
|
{
|
|
64438
64554
|
address: signer.address,
|
|
@@ -64443,7 +64559,7 @@ async function trySignEip2612PermitExtension(signer, options, requirements, resu
|
|
|
64443
64559
|
tokenName,
|
|
64444
64560
|
tokenVersion,
|
|
64445
64561
|
chainId,
|
|
64446
|
-
|
|
64562
|
+
deadline2,
|
|
64447
64563
|
requiredAllowance
|
|
64448
64564
|
);
|
|
64449
64565
|
return {
|
|
@@ -64861,10 +64977,10 @@ async function createUptoPermit2Payload(signer, x402Version2, paymentRequirement
|
|
|
64861
64977
|
const now = Math.floor(Date.now() / 1e3);
|
|
64862
64978
|
const nonce = createPermit2Nonce();
|
|
64863
64979
|
const validAfter = "0";
|
|
64864
|
-
const
|
|
64865
|
-
if (BigInt(
|
|
64980
|
+
const deadline2 = (now + paymentRequirements.maxTimeoutSeconds).toString();
|
|
64981
|
+
if (BigInt(deadline2) <= BigInt(validAfter)) {
|
|
64866
64982
|
throw new Error(
|
|
64867
|
-
`Invalid time window: deadline (${
|
|
64983
|
+
`Invalid time window: deadline (${deadline2}) must be after validAfter (${validAfter}). Check that maxTimeoutSeconds (${paymentRequirements.maxTimeoutSeconds}) is positive.`
|
|
64868
64984
|
);
|
|
64869
64985
|
}
|
|
64870
64986
|
const permit2Authorization = {
|
|
@@ -64875,7 +64991,7 @@ async function createUptoPermit2Payload(signer, x402Version2, paymentRequirement
|
|
|
64875
64991
|
},
|
|
64876
64992
|
spender: x402UptoPermit2ProxyAddress,
|
|
64877
64993
|
nonce,
|
|
64878
|
-
deadline,
|
|
64994
|
+
deadline: deadline2,
|
|
64879
64995
|
witness: {
|
|
64880
64996
|
to: getAddress(paymentRequirements.payTo),
|
|
64881
64997
|
facilitator: getAddress(facilitatorAddress),
|
|
@@ -87039,8 +87155,8 @@ function createHostedProvider(options) {
|
|
|
87039
87155
|
if (!operationId?.startsWith(`${options.runId}:llm:`))
|
|
87040
87156
|
throw new Error("Hosted model operation scope is missing");
|
|
87041
87157
|
const body = JSON.stringify({ runId: options.runId, sessionId: options.sessionId, operationId, messages: messages.map(({ contextArchive: _archive, ...message }) => message), tools });
|
|
87042
|
-
if (Buffer.byteLength(body) >
|
|
87043
|
-
throw new
|
|
87158
|
+
if (Buffer.byteLength(body) > MODEL_SELLER_REQUEST_MAX_BYTES)
|
|
87159
|
+
throw new ContextWindowExceeded(`Hosted request is ${Buffer.byteLength(body)} bytes, above the ${MODEL_SELLER_REQUEST_MAX_BYTES} a seller accepts`);
|
|
87044
87160
|
const result = await new Promise((resolve9, reject) => {
|
|
87045
87161
|
const req = request({
|
|
87046
87162
|
socketPath: options.socketPath,
|
|
@@ -87071,6 +87187,9 @@ function createHostedProvider(options) {
|
|
|
87071
87187
|
});
|
|
87072
87188
|
});
|
|
87073
87189
|
req.setTimeout(MODEL_BRIDGE_TIMEOUT_MS, () => req.destroy(new Error("Hosted bridge timed out")));
|
|
87190
|
+
const total = setTimeout(() => req.destroy(new Error("Hosted bridge exceeded its total deadline")), MODEL_BRIDGE_TIMEOUT_MS);
|
|
87191
|
+
total.unref?.();
|
|
87192
|
+
req.once("close", () => clearTimeout(total));
|
|
87074
87193
|
req.on("error", reject);
|
|
87075
87194
|
req.end(body);
|
|
87076
87195
|
}).catch((error53) => {
|
|
@@ -87104,10 +87223,14 @@ function rejectedRequest(status, text) {
|
|
|
87104
87223
|
return new HostedRequestError("model_failed", status, String(body.message ?? "The model response failed after payment settled. Its receipt is saved."));
|
|
87105
87224
|
if (body.paid !== false)
|
|
87106
87225
|
return void 0;
|
|
87107
|
-
|
|
87226
|
+
const upstream = body.upstream && typeof body.upstream === "object" && typeof body.upstream.code === "string" ? { status: Number(body.upstream.status) || status, code: body.upstream.code } : void 0;
|
|
87227
|
+
const refusal = { code: upstream?.code ?? body.error, message: body.message };
|
|
87228
|
+
if (isContextWindowError(refusal))
|
|
87108
87229
|
return new ContextWindowExceeded(String(body.message ?? "Provider context window exceeded"));
|
|
87230
|
+
if (isRequestTooLargeError(refusal, upstream?.status ?? status))
|
|
87231
|
+
return new ContextWindowExceeded(String(body.message ?? "The model provider refused this request as too large"));
|
|
87109
87232
|
const code = typeof body.error === "string" && body.error ? body.error : `http_${status}`;
|
|
87110
|
-
return new HostedRequestError(code, status, typeof body.message === "string" && body.message ? body.message : `The model request was rejected (${code})
|
|
87233
|
+
return new HostedRequestError(code, status, typeof body.message === "string" && body.message ? body.message : `The model request was rejected (${code})`, upstream);
|
|
87111
87234
|
} catch {
|
|
87112
87235
|
return void 0;
|
|
87113
87236
|
}
|
|
@@ -87159,8 +87282,11 @@ async function postHostedTool(options, name, args, settings = {}) {
|
|
|
87159
87282
|
}
|
|
87160
87283
|
});
|
|
87161
87284
|
});
|
|
87162
|
-
const timeoutMs = settings.timeoutMs ??
|
|
87285
|
+
const timeoutMs = settings.timeoutMs ?? HOSTED_TOOL_BRIDGE_TIMEOUT_MS;
|
|
87163
87286
|
req.setTimeout(timeoutMs, () => req.destroy(new HostedToolTimeout(name, timeoutMs)));
|
|
87287
|
+
const total = setTimeout(() => req.destroy(new HostedToolTimeout(name, timeoutMs)), timeoutMs);
|
|
87288
|
+
total.unref?.();
|
|
87289
|
+
req.once("close", () => clearTimeout(total));
|
|
87164
87290
|
req.on("error", reject);
|
|
87165
87291
|
req.end(body);
|
|
87166
87292
|
});
|
|
@@ -87183,7 +87309,8 @@ function createHostedToolExecutor(options) {
|
|
|
87183
87309
|
}
|
|
87184
87310
|
}
|
|
87185
87311
|
try {
|
|
87186
|
-
const
|
|
87312
|
+
const timeoutMs = ["deploy_service", "request_secret", "vault_request"].includes(name) ? HOSTED_CONTROL_TOOL_TIMEOUT_MS : void 0;
|
|
87313
|
+
const result = await postHostedTool(options, name, { ...args, ...source === void 0 ? {} : { source } }, { signal: context.signal, ...timeoutMs ? { timeoutMs } : {} });
|
|
87187
87314
|
if (result.ok)
|
|
87188
87315
|
return { ok: true, data: await boundResponse(context.session, result.data) };
|
|
87189
87316
|
return { ok: false, error: result.error ?? "tool failed" };
|
|
@@ -87207,12 +87334,18 @@ var init_hosted_provider = __esm({
|
|
|
87207
87334
|
HostedRequestError = class extends Error {
|
|
87208
87335
|
code;
|
|
87209
87336
|
status;
|
|
87210
|
-
|
|
87337
|
+
upstream;
|
|
87338
|
+
constructor(code, status, message, upstream) {
|
|
87211
87339
|
super(message);
|
|
87212
87340
|
this.code = code;
|
|
87213
87341
|
this.status = status;
|
|
87342
|
+
this.upstream = upstream;
|
|
87214
87343
|
this.name = "HostedRequestError";
|
|
87215
87344
|
}
|
|
87345
|
+
/** What the owner reads as the run's summary; undefined keeps the generic copy. */
|
|
87346
|
+
get summary() {
|
|
87347
|
+
return upstreamRefusalSummary(this);
|
|
87348
|
+
}
|
|
87216
87349
|
};
|
|
87217
87350
|
HOSTED_TOOL_REQUEST_BYTES = 1024 * 1024;
|
|
87218
87351
|
HostedToolTimeout = class extends Error {
|
|
@@ -87348,7 +87481,7 @@ function numberValue6(value) {
|
|
|
87348
87481
|
}
|
|
87349
87482
|
return void 0;
|
|
87350
87483
|
}
|
|
87351
|
-
var DEFAULT_CROWDCODE_BASE, LIST_CACHE_MS, FIND_TIMEOUT_MS, PAY_TIMEOUT_MS, RECONCILE_DELAY_MS, NOT_SENT_CODES, FREE_FETCH_TIMEOUT_MS, USDC_ATOMIC_PER_USD, TRANSFER_WAIT_MS, TRANSFER_POLL_MS, PREFERRED_MOVE_USD, MOVE_FEE_ALLOWANCE_USD, MOVE_FEE_ESTIMATE_USD, MAX_MOVE_FEE_SHARE, BASE_WORKING_RESERVE_USD, RAIL_NETWORK2, ServiceDirectory, HostedAgentCashAdapter, usd, isPending, HostedCrowdCodeAdapter, HOSTED_BRIDGE_TOOL;
|
|
87484
|
+
var DEFAULT_CROWDCODE_BASE, LIST_CACHE_MS, FIND_TIMEOUT_MS, DIRECTORY_TIMEOUT_MS, PAY_TIMEOUT_MS, RECONCILE_DELAY_MS, NOT_SENT_CODES, FREE_FETCH_TIMEOUT_MS, USDC_ATOMIC_PER_USD, TRANSFER_WAIT_MS, TRANSFER_POLL_MS, PREFERRED_MOVE_USD, MOVE_FEE_ALLOWANCE_USD, MOVE_FEE_ESTIMATE_USD, MAX_MOVE_FEE_SHARE, BASE_WORKING_RESERVE_USD, RAIL_NETWORK2, ServiceDirectory, HostedAgentCashAdapter, usd, isPending, HostedCrowdCodeAdapter, HOSTED_BRIDGE_TOOL;
|
|
87352
87485
|
var init_hosted_economy = __esm({
|
|
87353
87486
|
"../../packages/agent-runtime/dist/hosted-economy.js"() {
|
|
87354
87487
|
"use strict";
|
|
@@ -87362,6 +87495,7 @@ var init_hosted_economy = __esm({
|
|
|
87362
87495
|
DEFAULT_CROWDCODE_BASE = "https://crowdcode-backend.onrender.com";
|
|
87363
87496
|
LIST_CACHE_MS = 6e4;
|
|
87364
87497
|
FIND_TIMEOUT_MS = 2e4;
|
|
87498
|
+
DIRECTORY_TIMEOUT_MS = 2e4;
|
|
87365
87499
|
PAY_TIMEOUT_MS = SERVICE_GATEWAY_TIMEOUT_MS + 3e4;
|
|
87366
87500
|
RECONCILE_DELAY_MS = 2e3;
|
|
87367
87501
|
NOT_SENT_CODES = /* @__PURE__ */ new Set(["ENOENT", "ECONNREFUSED", "EACCES", "ENOTDIR"]);
|
|
@@ -87388,11 +87522,11 @@ var init_hosted_economy = __esm({
|
|
|
87388
87522
|
if (!force && this.cache && Date.now() - this.cache.fetchedAt < LIST_CACHE_MS) {
|
|
87389
87523
|
return this.cache.services;
|
|
87390
87524
|
}
|
|
87391
|
-
const response = await this.fetcher(`${this.base}/api/services`, { headers: { accept: "application/json" } });
|
|
87525
|
+
const response = await withDeadline(() => this.fetcher(`${this.base}/api/services`, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(DIRECTORY_TIMEOUT_MS) }), DIRECTORY_TIMEOUT_MS, "CrowdCode service list");
|
|
87392
87526
|
if (!response.ok) {
|
|
87393
87527
|
throw new Error(`CrowdCode service list unavailable (HTTP ${response.status})`);
|
|
87394
87528
|
}
|
|
87395
|
-
const payload = await response.json();
|
|
87529
|
+
const payload = await withDeadline(() => response.json(), DIRECTORY_TIMEOUT_MS, "CrowdCode service list body");
|
|
87396
87530
|
const rows = Array.isArray(payload) ? payload : objectValue5(payload)?.services;
|
|
87397
87531
|
const services = (Array.isArray(rows) ? rows : []).map(parseListedService).filter((row) => row !== void 0);
|
|
87398
87532
|
for (const service of services) {
|
|
@@ -87412,8 +87546,8 @@ var init_hosted_economy = __esm({
|
|
|
87412
87546
|
return this.idsByEndpoint.get(key);
|
|
87413
87547
|
}
|
|
87414
87548
|
async detail(serviceId) {
|
|
87415
|
-
const response = await this.fetcher(`${this.base}/api/services/${encodeURIComponent(serviceId)}`, { headers: { accept: "application/json" } });
|
|
87416
|
-
const body = objectValue5(await response.json().catch(() => void 0));
|
|
87549
|
+
const response = await withDeadline(() => this.fetcher(`${this.base}/api/services/${encodeURIComponent(serviceId)}`, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(DIRECTORY_TIMEOUT_MS) }), DIRECTORY_TIMEOUT_MS, "CrowdCode service detail");
|
|
87550
|
+
const body = objectValue5(await withDeadline(() => response.json(), DIRECTORY_TIMEOUT_MS, "CrowdCode service detail body").catch(() => void 0));
|
|
87417
87551
|
return { status: response.status, body };
|
|
87418
87552
|
}
|
|
87419
87553
|
};
|
|
@@ -87558,7 +87692,7 @@ var init_hosted_economy = __esm({
|
|
|
87558
87692
|
throw new SpendingDeclined();
|
|
87559
87693
|
if (reply.code === "approval_required")
|
|
87560
87694
|
throw new RuntimePause("waiting_for_approval", purchaseId, "Spending approval required. Review the quoted amount to continue.");
|
|
87561
|
-
if (reply.code === "expected_payment_required") {
|
|
87695
|
+
if (reply.code === "expected_payment_required" || reply.code === "upstream_refused") {
|
|
87562
87696
|
return this.fetchUnpaid(request2.url, method, body, request2.headers);
|
|
87563
87697
|
}
|
|
87564
87698
|
if (reply.code === "funding_required") {
|
|
@@ -87594,13 +87728,13 @@ var init_hosted_economy = __esm({
|
|
|
87594
87728
|
/** The supervisor found no 402: the endpoint is free, so the worker fetches it itself. */
|
|
87595
87729
|
async fetchUnpaid(url3, method, body, headers) {
|
|
87596
87730
|
try {
|
|
87597
|
-
const response = await this.fetcher(url3, {
|
|
87731
|
+
const response = await withDeadline(() => this.fetcher(url3, {
|
|
87598
87732
|
method,
|
|
87599
87733
|
signal: AbortSignal.timeout(FREE_FETCH_TIMEOUT_MS),
|
|
87600
87734
|
headers: { accept: "application/json", ...body !== void 0 ? { "content-type": "application/json" } : {}, ...headers ?? {} },
|
|
87601
87735
|
...body !== void 0 && method !== "GET" ? { body } : {}
|
|
87602
|
-
});
|
|
87603
|
-
const text = await response.text();
|
|
87736
|
+
}), FREE_FETCH_TIMEOUT_MS, "unpaid request");
|
|
87737
|
+
const text = await withDeadline(() => response.text(), FREE_FETCH_TIMEOUT_MS, "unpaid response body");
|
|
87604
87738
|
return {
|
|
87605
87739
|
ok: response.status < 400,
|
|
87606
87740
|
ambiguous: false,
|
|
@@ -87691,8 +87825,8 @@ var init_hosted_economy = __esm({
|
|
|
87691
87825
|
if (!reply.ok)
|
|
87692
87826
|
return { ok: false, error: describeTransferError(reply) };
|
|
87693
87827
|
let transfer2 = objectValue5(objectValue5(reply.data)?.transfer) ?? {};
|
|
87694
|
-
const
|
|
87695
|
-
while (isPending(transfer2) && stringValue5(transfer2.id) && Date.now() <
|
|
87828
|
+
const deadline2 = Date.now() + this.transferWait.totalMs;
|
|
87829
|
+
while (isPending(transfer2) && stringValue5(transfer2.id) && Date.now() < deadline2) {
|
|
87696
87830
|
await new Promise((resolve9) => setTimeout(resolve9, this.transferWait.pollMs));
|
|
87697
87831
|
const next = await postHostedTool(this.socket, "economy.transfer", { action: "status", transfer_id: transfer2.id }, { timeoutMs: 6e4 }).catch(() => void 0);
|
|
87698
87832
|
if (next?.ok)
|
|
@@ -87723,13 +87857,13 @@ var init_hosted_economy = __esm({
|
|
|
87723
87857
|
/** CrowdCode's cross-chain search and ranking over its public API. */
|
|
87724
87858
|
async findServices(search) {
|
|
87725
87859
|
try {
|
|
87726
|
-
const response = await this.directory.fetcher(`${this.directory.base}/api/services/find`, {
|
|
87860
|
+
const response = await withDeadline(() => this.directory.fetcher(`${this.directory.base}/api/services/find`, {
|
|
87727
87861
|
method: "POST",
|
|
87728
87862
|
signal: AbortSignal.timeout(FIND_TIMEOUT_MS),
|
|
87729
87863
|
headers: { accept: "application/json", "content-type": "application/json" },
|
|
87730
87864
|
body: JSON.stringify(search)
|
|
87731
|
-
});
|
|
87732
|
-
const body = objectValue5(await response.json().catch(() => void 0));
|
|
87865
|
+
}), FIND_TIMEOUT_MS + 5e3, "CrowdCode ranking");
|
|
87866
|
+
const body = objectValue5(await withDeadline(() => response.json(), FIND_TIMEOUT_MS, "CrowdCode ranking body").catch(() => void 0));
|
|
87733
87867
|
return response.ok && body?.ok !== false ? { ok: true, data: body } : { ok: false, error: `CrowdCode search failed (HTTP ${response.status})` };
|
|
87734
87868
|
} catch (error53) {
|
|
87735
87869
|
return { ok: false, error: `CrowdCode search unavailable: ${error53.message}` };
|
|
@@ -87806,6 +87940,44 @@ var init_hosted_economy = __esm({
|
|
|
87806
87940
|
}
|
|
87807
87941
|
});
|
|
87808
87942
|
|
|
87943
|
+
// ../../packages/agent-runtime/dist/tool-deadlines.js
|
|
87944
|
+
function toolDeadlineMs(name, env = process.env) {
|
|
87945
|
+
if (name === "run_shell")
|
|
87946
|
+
return SHELL_TIMEOUT_CEILING_MS + 12e4;
|
|
87947
|
+
void env;
|
|
87948
|
+
return TOOL_DEADLINE_MS[name] ?? DEFAULT_TOOL_DEADLINE_MS;
|
|
87949
|
+
}
|
|
87950
|
+
function toolDeadlineError(name, timeoutMs) {
|
|
87951
|
+
const seconds = Math.round(timeoutMs / 1e3);
|
|
87952
|
+
if (name === "call_paid_service")
|
|
87953
|
+
return `the paid call did not finish within ${seconds}s and its payment state is unknown. It was NOT retried and must not be retried automatically; check get_wallet_status and tell the owner the payment needs reconciling from the ledger.`;
|
|
87954
|
+
return `${name} did not finish within ${seconds}s and was abandoned. Nothing was charged for it. Try a different approach, or the same one once more if it is likely to have been a transient stall.`;
|
|
87955
|
+
}
|
|
87956
|
+
var TOOL_DEADLINE_MS, DEFAULT_TOOL_DEADLINE_MS;
|
|
87957
|
+
var init_tool_deadlines = __esm({
|
|
87958
|
+
"../../packages/agent-runtime/dist/tool-deadlines.js"() {
|
|
87959
|
+
"use strict";
|
|
87960
|
+
init_dist();
|
|
87961
|
+
init_dist2();
|
|
87962
|
+
TOOL_DEADLINE_MS = {
|
|
87963
|
+
// Its own ceiling is PAY_TIMEOUT_MS (gateway + 30s) for the payment, plus
|
|
87964
|
+
// inspection, the reputation check and one reconcile before that.
|
|
87965
|
+
call_paid_service: SERVICE_BRIDGE_TIMEOUT_MS + 12e4,
|
|
87966
|
+
// Catalogs, a ranking call and a bounded probe sweep.
|
|
87967
|
+
find_paid_service: 18e4,
|
|
87968
|
+
inspect_paid_service: 12e4,
|
|
87969
|
+
read_service: 12e4,
|
|
87970
|
+
review_paid_service: 12e4,
|
|
87971
|
+
// Quote, sign, submit, then wait for the funds to land (TRANSFER_WAIT_MS).
|
|
87972
|
+
bridge_usdc: 3e5,
|
|
87973
|
+
deploy_service: HOSTED_CONTROL_TOOL_TIMEOUT_MS + 6e4,
|
|
87974
|
+
request_secret: HOSTED_CONTROL_TOOL_TIMEOUT_MS + 6e4,
|
|
87975
|
+
vault_request: HOSTED_CONTROL_TOOL_TIMEOUT_MS + 6e4
|
|
87976
|
+
};
|
|
87977
|
+
DEFAULT_TOOL_DEADLINE_MS = 12e4;
|
|
87978
|
+
}
|
|
87979
|
+
});
|
|
87980
|
+
|
|
87809
87981
|
// ../../packages/agent-runtime/dist/worker.js
|
|
87810
87982
|
import { readFile as readFile13, mkdir as mkdir11 } from "node:fs/promises";
|
|
87811
87983
|
import { join as join21 } from "node:path";
|
|
@@ -87842,6 +88014,7 @@ var init_worker = __esm({
|
|
|
87842
88014
|
init_dist();
|
|
87843
88015
|
init_dist6();
|
|
87844
88016
|
init_hosted_economy();
|
|
88017
|
+
init_tool_deadlines();
|
|
87845
88018
|
init_knowledge();
|
|
87846
88019
|
MAX_WORKER_STATE_CHARS = 2 * 1024 * 1024;
|
|
87847
88020
|
RuntimePause = class extends Error {
|
|
@@ -88109,7 +88282,7 @@ var init_worker = __esm({
|
|
|
88109
88282
|
try {
|
|
88110
88283
|
if (saved?.approvalPending && name === "call_paid_service" && economy)
|
|
88111
88284
|
await economy.execute("inspect_paid_service", { url: args.url, method: args.method, sample_body: args.body });
|
|
88112
|
-
output3 = capToolResult(await invoke
|
|
88285
|
+
output3 = capToolResult(await this.withinDeadline(name, invoke));
|
|
88113
88286
|
if (financialState && name === "get_budget_status")
|
|
88114
88287
|
output3 = { ok: true, data: latestFinancialState };
|
|
88115
88288
|
if (financialState && name === "complete_session" && output3.ok && output3.data && typeof output3.data === "object")
|
|
@@ -88251,7 +88424,25 @@ var init_worker = __esm({
|
|
|
88251
88424
|
} else if (error53 instanceof SpendingDeclined)
|
|
88252
88425
|
await this.finish(runId, run, "user_stopped", error53.message);
|
|
88253
88426
|
else
|
|
88254
|
-
await this.finish(runId, run, "failed", RUN_FAILURE_MESSAGE);
|
|
88427
|
+
await this.finish(runId, run, "failed", upstreamRefusalSummary(error53) ?? RUN_FAILURE_MESSAGE);
|
|
88428
|
+
}
|
|
88429
|
+
}
|
|
88430
|
+
/**
|
|
88431
|
+
* The backstop deadline around one tool call.
|
|
88432
|
+
*
|
|
88433
|
+
* A `RuntimePause` must still travel: an approval or a funding stop is the
|
|
88434
|
+
* tool reporting a decision, not failing to answer. Everything else becomes
|
|
88435
|
+
* an ordinary tool error, so the loop keeps the turn and the model chooses
|
|
88436
|
+
* what to do instead of the owner losing the run.
|
|
88437
|
+
*/
|
|
88438
|
+
async withinDeadline(name, invoke) {
|
|
88439
|
+
const timeoutMs = (this.options.toolDeadlineMs ?? toolDeadlineMs)(name);
|
|
88440
|
+
try {
|
|
88441
|
+
return await withDeadline(invoke, timeoutMs, `tool ${name}`);
|
|
88442
|
+
} catch (error53) {
|
|
88443
|
+
if (!(error53 instanceof DeadlineExceeded))
|
|
88444
|
+
throw error53;
|
|
88445
|
+
return { ok: false, error: toolDeadlineError(name, timeoutMs) };
|
|
88255
88446
|
}
|
|
88256
88447
|
}
|
|
88257
88448
|
/** Keep the bundled knowledge tree when it loads; a broken snapshot must never fail a hosted run. */
|
|
@@ -89466,6 +89657,7 @@ var init_dist6 = __esm({
|
|
|
89466
89657
|
init_x402_proxy();
|
|
89467
89658
|
init_knowledge();
|
|
89468
89659
|
init_context2();
|
|
89660
|
+
init_tool_deadlines();
|
|
89469
89661
|
MockLlmProvider = class {
|
|
89470
89662
|
random;
|
|
89471
89663
|
endProbability;
|
|
@@ -90187,7 +90379,7 @@ function gradeTrajectory(entries) {
|
|
|
90187
90379
|
for (const call2 of calls) {
|
|
90188
90380
|
if (/_get_service_score$/.test(call2.name) || call2.name === "inspect_paid_service") {
|
|
90189
90381
|
report.score_checks += 1;
|
|
90190
|
-
const origin =
|
|
90382
|
+
const origin = originOf3(call2.arguments);
|
|
90191
90383
|
if (origin) {
|
|
90192
90384
|
scoredOrigins.add(origin);
|
|
90193
90385
|
}
|
|
@@ -90199,7 +90391,7 @@ function gradeTrajectory(entries) {
|
|
|
90199
90391
|
report.fetch_calls += 1;
|
|
90200
90392
|
if (hasPaymentEvidence(call2.result)) {
|
|
90201
90393
|
report.paid_calls += 1;
|
|
90202
|
-
const origin =
|
|
90394
|
+
const origin = originOf3(call2.arguments);
|
|
90203
90395
|
if (!origin || !scoredOrigins.has(origin)) {
|
|
90204
90396
|
report.paid_before_score += 1;
|
|
90205
90397
|
}
|
|
@@ -90270,7 +90462,7 @@ function searchKeys(value, pattern, depth) {
|
|
|
90270
90462
|
}
|
|
90271
90463
|
return false;
|
|
90272
90464
|
}
|
|
90273
|
-
function
|
|
90465
|
+
function originOf3(args) {
|
|
90274
90466
|
const candidate = args.url ?? args.api_endpoint ?? args.endpoint ?? args.origin ?? args.resource_url;
|
|
90275
90467
|
if (typeof candidate !== "string") {
|
|
90276
90468
|
return void 0;
|
|
@@ -91575,7 +91767,7 @@ function flattenService(detail) {
|
|
|
91575
91767
|
service_id: serviceId,
|
|
91576
91768
|
name: String(service.name ?? ""),
|
|
91577
91769
|
endpoint,
|
|
91578
|
-
origin:
|
|
91770
|
+
origin: originOf4(endpoint),
|
|
91579
91771
|
payment_provider: String(service.payment_provider ?? "unknown"),
|
|
91580
91772
|
score: Number(detail.score ?? 0),
|
|
91581
91773
|
n_eff: Number(detail.n_eff ?? 0),
|
|
@@ -91621,7 +91813,7 @@ async function fetchWithRetry(fetchImpl, url3) {
|
|
|
91621
91813
|
}
|
|
91622
91814
|
return void 0;
|
|
91623
91815
|
}
|
|
91624
|
-
function
|
|
91816
|
+
function originOf4(endpoint) {
|
|
91625
91817
|
try {
|
|
91626
91818
|
return new URL(endpoint).origin;
|
|
91627
91819
|
} catch {
|
package/package.json
CHANGED