@vtxmacro/cli 2026.10.48 → 2026.10.49
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/bin/exo-harness.ts +188 -93
- package/bin/vtx-mcp.js +190 -121
- package/bin/vtx-service-bootstrap.js +120 -87
- package/bin/vtx-service-launcher.js +53 -44
- package/bin/vtx.js +3081 -3465
- package/package.json +1 -1
package/bin/exo-harness.ts
CHANGED
|
@@ -2,6 +2,75 @@
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
4
|
|
|
5
|
+
// lib/shared-contracts.generated.ts
|
|
6
|
+
var AI_SNAPSHOT_WIRE_FORMAT = {
|
|
7
|
+
"compact_transport_version": 2,
|
|
8
|
+
"packed_fields": 3,
|
|
9
|
+
"packed_entry_fields": 2
|
|
10
|
+
};
|
|
11
|
+
var HYPERLIQUID_EXCHANGE_SPECIFICATION = {
|
|
12
|
+
"l1_signing_chain_id": 1337,
|
|
13
|
+
"action_nonce_bytes": 8,
|
|
14
|
+
"max_orders_per_batch": 16,
|
|
15
|
+
"position_tpsl_order_count": 2,
|
|
16
|
+
"price_significant_figures": 5,
|
|
17
|
+
"integer_price_minimum": 1e5,
|
|
18
|
+
"perp_price_max_decimals": 6,
|
|
19
|
+
"hip3_asset_id_base": 1e5,
|
|
20
|
+
"hip3_asset_id_dex_stride": 1e4,
|
|
21
|
+
"trailing_retracement_pct_max_decimals": 3,
|
|
22
|
+
"good_til_cancelled_time_in_force": "Gtc",
|
|
23
|
+
"max_deployer_fee_scale": 3,
|
|
24
|
+
"deployer_fee_scale_multiplier": 2,
|
|
25
|
+
"growth_mode_fee_factor": 0.1,
|
|
26
|
+
"aligned_quote_non_deployer_fee_factor": 0.8
|
|
27
|
+
};
|
|
28
|
+
var HYPERLIQUID_ROW_WEIGHTED_INFO_CHARGE = {
|
|
29
|
+
"base_weight": 20,
|
|
30
|
+
"rows_per_extra_weight": 20,
|
|
31
|
+
"request_types": [
|
|
32
|
+
"userFills",
|
|
33
|
+
"userFillsByTime",
|
|
34
|
+
"historicalOrders",
|
|
35
|
+
"twapHistory",
|
|
36
|
+
"userTwapSliceFills",
|
|
37
|
+
"userFunding",
|
|
38
|
+
"userNonFundingLedgerUpdates"
|
|
39
|
+
]
|
|
40
|
+
};
|
|
41
|
+
var PROVIDER_OUT_OF_CREDIT = {
|
|
42
|
+
"payment_required_status": 402,
|
|
43
|
+
"error_codes": [
|
|
44
|
+
"insufficient_quota",
|
|
45
|
+
"insufficient_balance",
|
|
46
|
+
"billing_error",
|
|
47
|
+
"credit_balance_exhausted",
|
|
48
|
+
"exceeded_current_quota_error",
|
|
49
|
+
"arrearage",
|
|
50
|
+
"1113"
|
|
51
|
+
],
|
|
52
|
+
"provider_phrases": [
|
|
53
|
+
"insufficient balance",
|
|
54
|
+
"insufficient credits",
|
|
55
|
+
"credit balance is too low",
|
|
56
|
+
"please recharge",
|
|
57
|
+
"no resource package",
|
|
58
|
+
"used all available credits",
|
|
59
|
+
"prepayment credits are depleted",
|
|
60
|
+
"insufficient_quota",
|
|
61
|
+
"insufficient_balance",
|
|
62
|
+
"billing_error",
|
|
63
|
+
"credit_balance_exhausted",
|
|
64
|
+
"exceeded_current_quota",
|
|
65
|
+
"arrearage"
|
|
66
|
+
],
|
|
67
|
+
"provider_failure_markers": [
|
|
68
|
+
"provider request failed"
|
|
69
|
+
],
|
|
70
|
+
"vtx_phrase": "the ai provider account is out of credit",
|
|
71
|
+
"attempt_summary_marker": "out of credit"
|
|
72
|
+
};
|
|
73
|
+
|
|
5
74
|
// lib/constants.ts
|
|
6
75
|
var MS_PER_SECOND = 1e3;
|
|
7
76
|
var SECONDS_PER_MINUTE = 60;
|
|
@@ -21,23 +90,6 @@ var BYTES_PER_KIB = 1024;
|
|
|
21
90
|
var BYTES_PER_MIB = BYTES_PER_KIB * BYTES_PER_KIB;
|
|
22
91
|
var INT32_MIN = -(2 ** 31);
|
|
23
92
|
var INT32_MAX = 2 ** 31 - 1;
|
|
24
|
-
var CANDLE_TIMEFRAME_SECONDS = {
|
|
25
|
-
"1m": SECONDS_PER_MINUTE,
|
|
26
|
-
"3m": 3 * SECONDS_PER_MINUTE,
|
|
27
|
-
"5m": 5 * SECONDS_PER_MINUTE,
|
|
28
|
-
"15m": 15 * SECONDS_PER_MINUTE,
|
|
29
|
-
"30m": 30 * SECONDS_PER_MINUTE,
|
|
30
|
-
"1h": SECONDS_PER_HOUR,
|
|
31
|
-
"2h": 2 * SECONDS_PER_HOUR,
|
|
32
|
-
"4h": 4 * SECONDS_PER_HOUR,
|
|
33
|
-
"6h": 6 * SECONDS_PER_HOUR,
|
|
34
|
-
"8h": 8 * SECONDS_PER_HOUR,
|
|
35
|
-
"12h": 12 * SECONDS_PER_HOUR,
|
|
36
|
-
"1d": SECONDS_PER_DAY,
|
|
37
|
-
"3d": 3 * SECONDS_PER_DAY,
|
|
38
|
-
"1w": SECONDS_PER_WEEK,
|
|
39
|
-
"1M": 30 * SECONDS_PER_DAY
|
|
40
|
-
};
|
|
41
93
|
var HTTP_STATUS = {
|
|
42
94
|
OK: 200,
|
|
43
95
|
ACCEPTED: 202,
|
|
@@ -71,30 +123,17 @@ var SECONDS_PER_AI_COST_ESTIMATE_PERIOD = SECONDS_PER_DAY * AI_COST_ESTIMATE_PER
|
|
|
71
123
|
var INFERENCE_HOST_MODEL_ID_MAX_CHARS = 256;
|
|
72
124
|
var RETRY_AFTER_HEADER_MAX_CHARS = 128;
|
|
73
125
|
var EXO_POLICY_MAX_TOOL_ROUNDS = 64;
|
|
74
|
-
var HYPERLIQUID_EXCHANGE_SPECIFICATION = {
|
|
75
|
-
// Chain ID of the phantom-agent EIP-712 domain L1 actions sign.
|
|
76
|
-
l1_signing_chain_id: 1337,
|
|
77
|
-
// A signed action hash appends the nonce (and expiresAfter) as big-endian uint64.
|
|
78
|
-
action_nonce_bytes: 8,
|
|
79
|
-
// Largest atomic order group VTX sends.
|
|
80
|
-
max_orders_per_batch: 16,
|
|
81
|
-
// A positionTpsl group is exactly one stop-loss and one take-profit order.
|
|
82
|
-
position_tpsl_order_count: 2,
|
|
83
|
-
// Prices carry at most this many significant figures...
|
|
84
|
-
price_significant_figures: 5,
|
|
85
|
-
// ...unless they are integers at or above this, which keep every digit.
|
|
86
|
-
integer_price_minimum: 1e5,
|
|
87
|
-
// A perp price has at most this many decimals minus the asset's szDecimals.
|
|
88
|
-
perp_price_max_decimals: 6,
|
|
89
|
-
// A HIP-3 builder-DEX asset ID is base + dex index * stride + index in meta.
|
|
90
|
-
hip3_asset_id_base: 1e5,
|
|
91
|
-
hip3_asset_id_dex_stride: 1e4,
|
|
92
|
-
// A trailing stop's percent retracement carries at most this many decimals.
|
|
93
|
-
trailing_retracement_pct_max_decimals: 3,
|
|
94
|
-
// Good-til-cancelled time in force as the order wire spells it.
|
|
95
|
-
good_til_cancelled_time_in_force: "Gtc"
|
|
96
|
-
};
|
|
97
126
|
var HYPERLIQUID_TIF_GTC = HYPERLIQUID_EXCHANGE_SPECIFICATION.good_til_cancelled_time_in_force;
|
|
127
|
+
var HYPERLIQUID_ROW_WEIGHTED_INFO_REQUESTS = HYPERLIQUID_ROW_WEIGHTED_INFO_CHARGE.request_types;
|
|
128
|
+
var HYPERLIQUID_ROW_WEIGHTED_INFO_BASE_WEIGHT = HYPERLIQUID_ROW_WEIGHTED_INFO_CHARGE.base_weight;
|
|
129
|
+
var HYPERLIQUID_INFO_ROWS_PER_EXTRA_WEIGHT = HYPERLIQUID_ROW_WEIGHTED_INFO_CHARGE.rows_per_extra_weight;
|
|
130
|
+
var HYPERLIQUID_MAX_DEPLOYER_FEE_SCALE = HYPERLIQUID_EXCHANGE_SPECIFICATION.max_deployer_fee_scale;
|
|
131
|
+
var HYPERLIQUID_DEPLOYER_FEE_SCALE_MULTIPLIER = HYPERLIQUID_EXCHANGE_SPECIFICATION.deployer_fee_scale_multiplier;
|
|
132
|
+
var HYPERLIQUID_GROWTH_MODE_FEE_FACTOR = HYPERLIQUID_EXCHANGE_SPECIFICATION.growth_mode_fee_factor;
|
|
133
|
+
var HYPERLIQUID_ALIGNED_QUOTE_NON_DEPLOYER_FEE_FACTOR = HYPERLIQUID_EXCHANGE_SPECIFICATION.aligned_quote_non_deployer_fee_factor;
|
|
134
|
+
var AI_SNAPSHOT_COMPACT_TRANSPORT_VERSION = AI_SNAPSHOT_WIRE_FORMAT.compact_transport_version;
|
|
135
|
+
var AI_SNAPSHOT_PACKED_FIELDS = AI_SNAPSHOT_WIRE_FORMAT.packed_fields;
|
|
136
|
+
var AI_SNAPSHOT_PACKED_ENTRY_FIELDS = AI_SNAPSHOT_WIRE_FORMAT.packed_entry_fields;
|
|
98
137
|
|
|
99
138
|
// lib/runtime-policy.generated.json
|
|
100
139
|
var runtime_policy_generated_default = {
|
|
@@ -649,8 +688,7 @@ var runtime_policy_generated_default = {
|
|
|
649
688
|
debug_navbar_profile_entries: 12
|
|
650
689
|
},
|
|
651
690
|
login_page: {
|
|
652
|
-
desktop_bridge_poll_ms: 250
|
|
653
|
-
turnstile_site_key_log_chars: 10
|
|
691
|
+
desktop_bridge_poll_ms: 250
|
|
654
692
|
},
|
|
655
693
|
screener_page: {
|
|
656
694
|
search_save_debounce_ms: 250,
|
|
@@ -849,6 +887,9 @@ var runtime_policy_generated_default = {
|
|
|
849
887
|
max_fills_per_execution: 20,
|
|
850
888
|
max_fill_payload_bytes: 32768
|
|
851
889
|
},
|
|
890
|
+
prompt_contract: {
|
|
891
|
+
contract_version: "2026-08-24.1"
|
|
892
|
+
},
|
|
852
893
|
loop_early_return_retry_milliseconds: 5e3,
|
|
853
894
|
window_handoff_cleanup_retry_milliseconds: 1e3,
|
|
854
895
|
ai_schedule_pause_min_milliseconds: 1e3,
|
|
@@ -1342,9 +1383,9 @@ var runtime_policy_generated_default = {
|
|
|
1342
1383
|
page_start_poll_seconds: 1,
|
|
1343
1384
|
profiles_read_timeout_seconds: 30,
|
|
1344
1385
|
command_notice_reconnect_max_seconds: 60,
|
|
1345
|
-
sleep_quiet_milliseconds:
|
|
1386
|
+
sleep_quiet_milliseconds: 1500,
|
|
1346
1387
|
sleep_max_seconds: 60,
|
|
1347
|
-
sleep_min_seconds:
|
|
1388
|
+
sleep_min_seconds: 5,
|
|
1348
1389
|
sleep_alarm_grace_seconds: 15,
|
|
1349
1390
|
sleep_elastic_below_milliseconds: 1e3,
|
|
1350
1391
|
sleep_request_wait_milliseconds: 4e3,
|
|
@@ -1522,73 +1563,127 @@ var closingJsonObjectDocument = (text) => {
|
|
|
1522
1563
|
};
|
|
1523
1564
|
var agentAnswerJsonDocument = (text) => closingJsonFenceDocument(text) ?? closingJsonObjectDocument(text);
|
|
1524
1565
|
|
|
1525
|
-
// lib/
|
|
1566
|
+
// lib/runtime/provider-credit.ts
|
|
1567
|
+
var ERROR_CODES = new Set(PROVIDER_OUT_OF_CREDIT.error_codes.map((code) => code.toLowerCase()));
|
|
1568
|
+
var PROVIDER_PHRASES = PROVIDER_OUT_OF_CREDIT.provider_phrases;
|
|
1569
|
+
var PROVIDER_FAILURE_MARKERS = PROVIDER_OUT_OF_CREDIT.provider_failure_markers;
|
|
1570
|
+
var PAYMENT_REQUIRED_TEXT = `(http ${PROVIDER_OUT_OF_CREDIT.payment_required_status}`;
|
|
1571
|
+
var hasOutOfCreditWords = (normalized) => PROVIDER_PHRASES.some((phrase) => normalized.includes(phrase)) || [...ERROR_CODES].some((code) => normalized.includes(`[${code}]`));
|
|
1572
|
+
var PROVIDER_OUT_OF_CREDIT_PHRASE = PROVIDER_OUT_OF_CREDIT.vtx_phrase;
|
|
1573
|
+
var PROVIDER_OUT_OF_CREDIT_ATTEMPT_MARKER = PROVIDER_OUT_OF_CREDIT.attempt_summary_marker;
|
|
1574
|
+
var providerOutOfCreditErrorCode = (payload) => {
|
|
1575
|
+
const errorNode = payload?.error;
|
|
1576
|
+
if (!errorNode || typeof errorNode !== "object") return null;
|
|
1577
|
+
for (const field of ["code", "type"]) {
|
|
1578
|
+
const value = errorNode[field];
|
|
1579
|
+
const code = typeof value === "number" ? String(value) : typeof value === "string" ? value.trim() : "";
|
|
1580
|
+
if (code && ERROR_CODES.has(code.toLowerCase())) return code;
|
|
1581
|
+
}
|
|
1582
|
+
return null;
|
|
1583
|
+
};
|
|
1584
|
+
var isProviderOutOfCreditReply = (statusCode, detail) => {
|
|
1585
|
+
if (statusCode === PROVIDER_OUT_OF_CREDIT.payment_required_status) return true;
|
|
1586
|
+
return hasOutOfCreditWords(String(detail || "").toLowerCase());
|
|
1587
|
+
};
|
|
1588
|
+
|
|
1589
|
+
// lib/inference-host/provider-refusal.ts
|
|
1526
1590
|
var HOST_RUNTIME_POLICY = runtime_policy_generated_default.external_inference.host_runtime;
|
|
1527
|
-
var record = (value) => value
|
|
1528
|
-
var
|
|
1529
|
-
|
|
1530
|
-
if (
|
|
1531
|
-
|
|
1591
|
+
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1592
|
+
var refusalWords = (payload, rawText) => {
|
|
1593
|
+
const error = record(payload).error;
|
|
1594
|
+
if (typeof error === "string") return error;
|
|
1595
|
+
const message = record(error).message ?? record(payload).message;
|
|
1596
|
+
if (typeof message === "string") return message;
|
|
1597
|
+
return payload === null ? rawText : "";
|
|
1532
1598
|
};
|
|
1533
|
-
var
|
|
1534
|
-
|
|
1535
|
-
const
|
|
1599
|
+
var isProviderOutOfCreditRefusal = (statusCode, payload, rawText = "") => providerOutOfCreditErrorCode(payload) !== null || isProviderOutOfCreditReply(statusCode, refusalWords(payload, rawText));
|
|
1600
|
+
var readProviderOutOfCreditRefusal = async (statusCode, body) => {
|
|
1601
|
+
const byStatus = isProviderOutOfCreditReply(statusCode, "");
|
|
1602
|
+
if (byStatus || !body) {
|
|
1603
|
+
void body?.cancel().catch(() => void 0);
|
|
1604
|
+
return byStatus;
|
|
1605
|
+
}
|
|
1606
|
+
const reader = body.getReader();
|
|
1536
1607
|
const chunks = [];
|
|
1537
1608
|
let bytes = 0;
|
|
1538
1609
|
let timer;
|
|
1539
|
-
const
|
|
1540
|
-
timer = setTimeout(() => reject(new Error("
|
|
1610
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
1611
|
+
timer = setTimeout(() => reject(new Error("provider_error_body_deadline")), HOST_RUNTIME_POLICY.provider_error_body_timeout_ms);
|
|
1541
1612
|
});
|
|
1542
1613
|
try {
|
|
1543
1614
|
for (; ; ) {
|
|
1544
|
-
const part = await Promise.race([reader.read(),
|
|
1615
|
+
const part = await Promise.race([reader.read(), deadline]);
|
|
1545
1616
|
if (part.done) break;
|
|
1546
1617
|
bytes += part.value.byteLength;
|
|
1547
|
-
if (bytes > HOST_RUNTIME_POLICY.provider_error_body_max_bytes) return
|
|
1618
|
+
if (bytes > HOST_RUNTIME_POLICY.provider_error_body_max_bytes) return false;
|
|
1548
1619
|
chunks.push(part.value);
|
|
1549
1620
|
}
|
|
1550
|
-
const
|
|
1551
|
-
|
|
1621
|
+
const rawText = Buffer.concat(chunks).toString("utf8");
|
|
1622
|
+
let payload = null;
|
|
1623
|
+
try {
|
|
1624
|
+
payload = JSON.parse(rawText);
|
|
1625
|
+
} catch {
|
|
1626
|
+
}
|
|
1627
|
+
return isProviderOutOfCreditRefusal(statusCode, payload, rawText);
|
|
1552
1628
|
} catch {
|
|
1553
|
-
return
|
|
1629
|
+
return false;
|
|
1554
1630
|
} finally {
|
|
1555
1631
|
if (timer) clearTimeout(timer);
|
|
1556
1632
|
void reader.cancel().catch(() => void 0);
|
|
1557
1633
|
}
|
|
1558
1634
|
};
|
|
1635
|
+
|
|
1636
|
+
// lib/inference-host/exo-harness.ts
|
|
1637
|
+
var HOST_RUNTIME_POLICY2 = runtime_policy_generated_default.external_inference.host_runtime;
|
|
1638
|
+
var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1639
|
+
var validModel = (value) => typeof value === "string" && Boolean(value.trim()) && value.length <= INFERENCE_HOST_MODEL_ID_MAX_CHARS && !/[\u0000-\u001f\u007f]/u.test(value);
|
|
1640
|
+
var count = (value) => {
|
|
1641
|
+
if (!Number.isSafeInteger(value) || Number(value) < 0) throw new Error("exo_usage_invalid");
|
|
1642
|
+
return Number(value);
|
|
1643
|
+
};
|
|
1644
|
+
var providerRejectionCode = async (response) => {
|
|
1645
|
+
if (response.status === HTTP_STATUS.UNAUTHORIZED) {
|
|
1646
|
+
await response.body?.cancel().catch(() => void 0);
|
|
1647
|
+
return "exo_invalid_api_key";
|
|
1648
|
+
}
|
|
1649
|
+
const clientRefusal = response.status >= HTTP_CLIENT_ERROR_MIN && response.status < HTTP_SERVER_ERROR_MIN;
|
|
1650
|
+
if (clientRefusal && await readProviderOutOfCreditRefusal(response.status, response.body)) return "exo_out_of_credit";
|
|
1651
|
+
if (!clientRefusal) await response.body?.cancel().catch(() => void 0);
|
|
1652
|
+
return response.status === HTTP_STATUS.TOO_MANY_REQUESTS ? "exo_rate_limited" : "exo_provider_rejected";
|
|
1653
|
+
};
|
|
1559
1654
|
var retryAfterDeadline = (value) => {
|
|
1560
1655
|
if (!value || value.length > RETRY_AFTER_HEADER_MAX_CHARS) return null;
|
|
1561
1656
|
const now = Date.now();
|
|
1562
1657
|
const trimmed = value.trim();
|
|
1563
1658
|
const deadline = /^\d+(?:\.\d+)?$/u.test(trimmed) ? now + Number(trimmed) * MS_PER_SECOND : Date.parse(trimmed);
|
|
1564
|
-
return Number.isFinite(deadline) && deadline >= now && deadline - now <=
|
|
1659
|
+
return Number.isFinite(deadline) && deadline >= now && deadline - now <= HOST_RUNTIME_POLICY2.exo_provider_retry_after_max_ms ? Math.ceil(deadline) : null;
|
|
1565
1660
|
};
|
|
1566
|
-
var textOf = (response) => (Array.isArray(response.output) ? response.output : []).flatMap((item) =>
|
|
1661
|
+
var textOf = (response) => (Array.isArray(response.output) ? response.output : []).flatMap((item) => record2(item).type === "message" && Array.isArray(record2(item).content) ? record2(item).content : []).filter((part) => record2(part).type === "output_text").map((part) => typeof record2(part).text === "string" ? record2(part).text : "").join("");
|
|
1567
1662
|
var unwrapJsonFence = (text) => {
|
|
1568
1663
|
const match = /^```(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n```$/iu.exec(text.trim());
|
|
1569
1664
|
return match ? match[1] : agentAnswerJsonDocument(text) ?? text;
|
|
1570
1665
|
};
|
|
1571
1666
|
var veniceToolParameters = (value) => {
|
|
1572
1667
|
if (typeof value === "boolean") return value;
|
|
1573
|
-
const schema =
|
|
1574
|
-
const existingProperties =
|
|
1668
|
+
const schema = record2(value);
|
|
1669
|
+
const existingProperties = record2(schema.properties);
|
|
1575
1670
|
const properties = Object.fromEntries(Object.entries(existingProperties).map(([name, child]) => [name, veniceToolParameters(child)]));
|
|
1576
1671
|
const result = { ...schema, ...schema.properties ? { properties } : {} };
|
|
1577
1672
|
const union = Array.isArray(schema.anyOf) ? schema.anyOf : Array.isArray(schema.oneOf) ? schema.oneOf : null;
|
|
1578
1673
|
if (!union?.length || schema.type !== void 0 && schema.type !== "object") return result;
|
|
1579
|
-
const branches = union.map(
|
|
1674
|
+
const branches = union.map(record2);
|
|
1580
1675
|
if (!branches.every((branch) => branch.type === "object")) return result;
|
|
1581
|
-
const commonNames = Object.keys(
|
|
1676
|
+
const commonNames = Object.keys(record2(branches[0].properties)).filter((name) => branches.every((branch) => Object.hasOwn(record2(branch.properties), name)));
|
|
1582
1677
|
const common = {};
|
|
1583
1678
|
for (const name of commonNames) {
|
|
1584
|
-
const fields = branches.map((branch) =>
|
|
1679
|
+
const fields = branches.map((branch) => record2(record2(branch.properties)[name]));
|
|
1585
1680
|
const derived = {};
|
|
1586
1681
|
const type = fields[0].type;
|
|
1587
1682
|
if (typeof type === "string" && fields.every((field) => field.type === type)) derived.type = type;
|
|
1588
1683
|
if (fields.every((field) => Array.isArray(field.enum))) {
|
|
1589
1684
|
derived.enum = [...new Map(fields.flatMap((field) => field.enum).map((entry) => [JSON.stringify(entry), entry])).values()];
|
|
1590
1685
|
}
|
|
1591
|
-
common[name] = typeof properties[name] === "boolean" ? properties[name] : { ...derived, ...
|
|
1686
|
+
common[name] = typeof properties[name] === "boolean" ? properties[name] : { ...derived, ...record2(properties[name]) };
|
|
1592
1687
|
}
|
|
1593
1688
|
const required = (Array.isArray(branches[0].required) ? branches[0].required : []).filter((name) => typeof name === "string" && branches.every((branch) => Array.isArray(branch.required) && branch.required.includes(name)));
|
|
1594
1689
|
return {
|
|
@@ -1599,8 +1694,8 @@ var veniceToolParameters = (value) => {
|
|
|
1599
1694
|
};
|
|
1600
1695
|
};
|
|
1601
1696
|
var chatResponseEvents = (events) => events.map((event) => {
|
|
1602
|
-
const data =
|
|
1603
|
-
const messages = Array.isArray(data.messages) ? data.messages.map(
|
|
1697
|
+
const data = record2(event);
|
|
1698
|
+
const messages = Array.isArray(data.messages) ? data.messages.map(record2) : [];
|
|
1604
1699
|
if (data.type !== "messages" || messages.length <= 1 || !messages.every((message) => message.role === "assistant")) return event;
|
|
1605
1700
|
const content = messages.flatMap((message) => {
|
|
1606
1701
|
if (Array.isArray(message.content)) return message.content;
|
|
@@ -1611,15 +1706,15 @@ var chatResponseEvents = (events) => events.map((event) => {
|
|
|
1611
1706
|
return { ...data, messages: [{ role: "assistant", content }] };
|
|
1612
1707
|
});
|
|
1613
1708
|
var chatRequestMessages = (harness, events) => {
|
|
1614
|
-
const requests = events.map((event) =>
|
|
1709
|
+
const requests = events.map((event) => record2(record2(event).data)).filter((event) => event.type === "tool_requested");
|
|
1615
1710
|
let index = 0;
|
|
1616
1711
|
const messages = harness.materializeEventsToMessages(events).map((message) => {
|
|
1617
1712
|
if (message.role !== "assistant" || !Array.isArray(message.content)) return message;
|
|
1618
1713
|
return { ...message, content: message.content.map((part) => {
|
|
1619
|
-
const content =
|
|
1714
|
+
const content = record2(part);
|
|
1620
1715
|
if (content.type !== "tool_call") return part;
|
|
1621
1716
|
const event = requests[index++];
|
|
1622
|
-
const request =
|
|
1717
|
+
const request = record2(event?.request);
|
|
1623
1718
|
const args = request.arguments;
|
|
1624
1719
|
if (!event || event.tool_call_id !== content.tool_call_id || request.function_name !== content.tool_name || args === null || typeof args !== "object" || Array.isArray(args)) throw new Error("exo_chat_arguments_invalid");
|
|
1625
1720
|
return { ...content, arguments: args };
|
|
@@ -1665,7 +1760,7 @@ var exo_harness_default = {
|
|
|
1665
1760
|
const source = process.env.VTX_EXO_SOURCE_ROOT;
|
|
1666
1761
|
if (brokerUrl.protocol !== "http:" || brokerUrl.hostname !== "127.0.0.1" || brokerUrl.username || brokerUrl.password || brokerUrl.pathname !== "/" || brokerUrl.search || brokerUrl.hash || !token || !source) throw new Error("exo_bridge_invalid");
|
|
1667
1762
|
const broker = async (path, body, deadlineAtMs) => {
|
|
1668
|
-
const timeoutMs = deadlineAtMs === void 0 ?
|
|
1763
|
+
const timeoutMs = deadlineAtMs === void 0 ? HOST_RUNTIME_POLICY2.exo_bridge_request_timeout_ms : deadlineAtMs - Date.now();
|
|
1669
1764
|
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1) throw new Error("exo_deadline_reached");
|
|
1670
1765
|
const response = await nativeFetch(new URL(path, brokerUrl), {
|
|
1671
1766
|
method: body === void 0 ? "GET" : "POST",
|
|
@@ -1675,7 +1770,7 @@ var exo_harness_default = {
|
|
|
1675
1770
|
signal: AbortSignal.timeout(timeoutMs)
|
|
1676
1771
|
});
|
|
1677
1772
|
if (!response.ok) throw new Error("exo_bridge_rejected");
|
|
1678
|
-
return
|
|
1773
|
+
return record2(await response.json());
|
|
1679
1774
|
};
|
|
1680
1775
|
let dispatched = false;
|
|
1681
1776
|
let terminalKnown = true;
|
|
@@ -1699,8 +1794,8 @@ var exo_harness_default = {
|
|
|
1699
1794
|
const inputTokens = count(nativeUsage.input_tokens);
|
|
1700
1795
|
const outputTokens = count(nativeUsage.output_tokens);
|
|
1701
1796
|
const totalTokens = count(nativeUsage.total_tokens);
|
|
1702
|
-
const cachedTokens = count(
|
|
1703
|
-
const reasoningTokens = count(
|
|
1797
|
+
const cachedTokens = count(record2(nativeUsage.input_tokens_details).cached_tokens ?? 0);
|
|
1798
|
+
const reasoningTokens = count(record2(nativeUsage.output_tokens_details).reasoning_tokens ?? 0);
|
|
1704
1799
|
if (totalTokens !== inputTokens + outputTokens || cachedTokens > inputTokens || reasoningTokens > outputTokens) throw new Error("exo_usage_invalid");
|
|
1705
1800
|
usage.inputTokens = count(usage.inputTokens + inputTokens);
|
|
1706
1801
|
usage.outputTokens = count(usage.outputTokens + outputTokens);
|
|
@@ -1728,7 +1823,7 @@ var exo_harness_default = {
|
|
|
1728
1823
|
globalThis.fetch = async (resource, options) => {
|
|
1729
1824
|
const url = new URL(resource instanceof Request ? resource.url : String(resource));
|
|
1730
1825
|
if (url.href !== providerEndpoint || options?.method !== "POST" || !activeDispatch || roundDispatch || typeof options.body !== "string") throw new Error("exo_dispatch_rejected");
|
|
1731
|
-
const payload =
|
|
1826
|
+
const payload = record2(JSON.parse(options.body));
|
|
1732
1827
|
if (payload.model !== input.providerModel || payload.stream === true) throw new Error("exo_request_identity_mismatch");
|
|
1733
1828
|
const format = { name: "vtx_result", strict: true, schema: input.outputSchema };
|
|
1734
1829
|
if (input.provider === "venice") {
|
|
@@ -1749,11 +1844,11 @@ var exo_harness_default = {
|
|
|
1749
1844
|
else payload.reasoning = { effort: input.nativeReasoningEffort };
|
|
1750
1845
|
payload.text = { format: { type: "json_schema", ...format } };
|
|
1751
1846
|
}
|
|
1752
|
-
if (Array.isArray(payload.tools)) payload.tools = payload.tools.map((tool) => input.provider === "venice" ? { ...
|
|
1753
|
-
...
|
|
1847
|
+
if (Array.isArray(payload.tools)) payload.tools = payload.tools.map((tool) => input.provider === "venice" ? { ...record2(tool), function: {
|
|
1848
|
+
...record2(record2(tool).function),
|
|
1754
1849
|
strict: false,
|
|
1755
|
-
parameters: veniceToolParameters(
|
|
1756
|
-
} } : { ...
|
|
1850
|
+
parameters: veniceToolParameters(record2(record2(tool).function).parameters)
|
|
1851
|
+
} } : { ...record2(tool), strict: false });
|
|
1757
1852
|
await broker("/dispatch", { model: input.providerModel, reasoningEffort: input.reasoningEffort });
|
|
1758
1853
|
roundDispatch = true;
|
|
1759
1854
|
dispatched = true;
|
|
@@ -1765,21 +1860,20 @@ var exo_harness_default = {
|
|
|
1765
1860
|
headers.set("x-should-retry", "false");
|
|
1766
1861
|
if (!response.ok && response.status >= HTTP_CLIENT_ERROR_MIN && response.status < HTTP_SERVER_ERROR_MIN && response.status !== HTTP_STATUS.REQUEST_TIMEOUT) terminalKnown = true;
|
|
1767
1862
|
if (!response.ok) {
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
if (response.status !== HTTP_STATUS.TOO_MANY_REQUESTS) await response.body?.cancel();
|
|
1863
|
+
failureCode = await providerRejectionCode(response);
|
|
1864
|
+
retryAtMs = failureCode === "exo_rate_limited" ? retryAfterDeadline(response.headers.get("retry-after")) : null;
|
|
1771
1865
|
return new Response(JSON.stringify({ error: { message: failureCode, code: failureCode } }), { status: response.status, headers });
|
|
1772
1866
|
}
|
|
1773
1867
|
if (input.provider === "venice") {
|
|
1774
1868
|
try {
|
|
1775
|
-
const raw =
|
|
1869
|
+
const raw = record2(await response.clone().json());
|
|
1776
1870
|
const choices = Array.isArray(raw.choices) ? raw.choices : [];
|
|
1777
|
-
const choice =
|
|
1871
|
+
const choice = record2(choices[0]);
|
|
1778
1872
|
terminalKnown = choices.length === 1 && ["stop", "tool_calls", "length", "content_filter"].includes(String(choice.finish_reason));
|
|
1779
1873
|
if (!validModel(raw.model) || typeof raw.id !== "string" || !raw.id) throw new Error("exo_response_identity_mismatch");
|
|
1780
|
-
const controls =
|
|
1781
|
-
if (controls.disable_thinking !== true || controls.strip_thinking_response !== false || controls.include_venice_system_prompt !== false || controls.enable_web_search !== "off" || controls.enable_web_scraping !== false || controls.enable_x_search !== false || controls.enable_web_citations !== false ||
|
|
1782
|
-
const nativeUsage =
|
|
1874
|
+
const controls = record2(raw.venice_parameters);
|
|
1875
|
+
if (controls.disable_thinking !== true || controls.strip_thinking_response !== false || controls.include_venice_system_prompt !== false || controls.enable_web_search !== "off" || controls.enable_web_scraping !== false || controls.enable_x_search !== false || controls.enable_web_citations !== false || record2(choice.message).reasoning_content || record2(choice.message).reasoning || (record2(record2(raw.usage).completion_tokens_details).reasoning_tokens ?? 0) !== 0 || raw.reasoning_effort !== void 0 && raw.reasoning_effort !== "none") throw new Error("exo_response_effort_mismatch");
|
|
1876
|
+
const nativeUsage = record2(raw.usage);
|
|
1783
1877
|
addUsage({
|
|
1784
1878
|
input_tokens: nativeUsage.prompt_tokens,
|
|
1785
1879
|
output_tokens: nativeUsage.completion_tokens,
|
|
@@ -1790,7 +1884,7 @@ var exo_harness_default = {
|
|
|
1790
1884
|
lastCompletedResponseId = raw.id;
|
|
1791
1885
|
currentReceipt = { responseId: raw.id, providerModel: raw.model, reasoningEffort: input.reasoningEffort };
|
|
1792
1886
|
if (choices.length !== 1 || !["stop", "tool_calls"].includes(String(choice.finish_reason))) throw new Error("exo_response_incomplete");
|
|
1793
|
-
const hasTools = Array.isArray(
|
|
1887
|
+
const hasTools = Array.isArray(record2(choice.message).tool_calls) && record2(choice.message).tool_calls.length > 0;
|
|
1794
1888
|
if (choice.finish_reason === "tool_calls" !== hasTools) throw new Error("exo_response_incomplete");
|
|
1795
1889
|
} catch (error) {
|
|
1796
1890
|
failureCode = error instanceof Error && /^exo_[a-z_]+$/u.test(error.message) ? error.message : "exo_response_invalid";
|
|
@@ -1824,9 +1918,9 @@ var exo_harness_default = {
|
|
|
1824
1918
|
terminalKnown = true;
|
|
1825
1919
|
if (!validModel(response.model) || typeof response.id !== "string" || !response.id) throw new Error("exo_response_identity_mismatch");
|
|
1826
1920
|
if (input.provider === "openai") {
|
|
1827
|
-
const effectiveEffort =
|
|
1921
|
+
const effectiveEffort = record2(response.reasoning).effort ?? null;
|
|
1828
1922
|
if (effectiveEffort !== input.nativeReasoningEffort) throw new Error("exo_response_effort_mismatch");
|
|
1829
|
-
addUsage(
|
|
1923
|
+
addUsage(record2(response.usage));
|
|
1830
1924
|
lastCompletedResponseId = response.id;
|
|
1831
1925
|
currentReceipt = { responseId: response.id, providerModel: response.model, reasoningEffort: input.reasoningEffort };
|
|
1832
1926
|
}
|
|
@@ -1878,5 +1972,6 @@ var exo_harness_default = {
|
|
|
1878
1972
|
};
|
|
1879
1973
|
export {
|
|
1880
1974
|
exo_harness_default as default,
|
|
1975
|
+
providerRejectionCode,
|
|
1881
1976
|
unwrapJsonFence
|
|
1882
1977
|
};
|