@vtxmacro/cli 2026.10.48 → 2026.10.50
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 +207 -94
- package/bin/vtx-mcp.js +521 -122
- package/bin/vtx-service-bootstrap.js +139 -88
- package/bin/vtx-service-launcher.js +72 -45
- package/bin/vtx.js +6602 -4510
- package/package.json +1 -1
package/bin/exo-harness.ts
CHANGED
|
@@ -2,6 +2,80 @@
|
|
|
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 HYPERLIQUID_CANDLE_SNAPSHOT_CHARGE = {
|
|
42
|
+
"base_weight": 20,
|
|
43
|
+
"rows_per_extra_weight": 60,
|
|
44
|
+
"max_rows": 5e3
|
|
45
|
+
};
|
|
46
|
+
var PROVIDER_OUT_OF_CREDIT = {
|
|
47
|
+
"payment_required_status": 402,
|
|
48
|
+
"error_codes": [
|
|
49
|
+
"insufficient_quota",
|
|
50
|
+
"insufficient_balance",
|
|
51
|
+
"billing_error",
|
|
52
|
+
"credit_balance_exhausted",
|
|
53
|
+
"exceeded_current_quota_error",
|
|
54
|
+
"arrearage",
|
|
55
|
+
"1113"
|
|
56
|
+
],
|
|
57
|
+
"provider_phrases": [
|
|
58
|
+
"insufficient balance",
|
|
59
|
+
"insufficient credits",
|
|
60
|
+
"credit balance is too low",
|
|
61
|
+
"please recharge",
|
|
62
|
+
"no resource package",
|
|
63
|
+
"used all available credits",
|
|
64
|
+
"prepayment credits are depleted",
|
|
65
|
+
"insufficient_quota",
|
|
66
|
+
"insufficient_balance",
|
|
67
|
+
"billing_error",
|
|
68
|
+
"credit_balance_exhausted",
|
|
69
|
+
"exceeded_current_quota",
|
|
70
|
+
"arrearage"
|
|
71
|
+
],
|
|
72
|
+
"provider_failure_markers": [
|
|
73
|
+
"provider request failed"
|
|
74
|
+
],
|
|
75
|
+
"vtx_phrase": "the ai provider account is out of credit",
|
|
76
|
+
"attempt_summary_marker": "out of credit"
|
|
77
|
+
};
|
|
78
|
+
|
|
5
79
|
// lib/constants.ts
|
|
6
80
|
var MS_PER_SECOND = 1e3;
|
|
7
81
|
var SECONDS_PER_MINUTE = 60;
|
|
@@ -21,23 +95,6 @@ var BYTES_PER_KIB = 1024;
|
|
|
21
95
|
var BYTES_PER_MIB = BYTES_PER_KIB * BYTES_PER_KIB;
|
|
22
96
|
var INT32_MIN = -(2 ** 31);
|
|
23
97
|
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
98
|
var HTTP_STATUS = {
|
|
42
99
|
OK: 200,
|
|
43
100
|
ACCEPTED: 202,
|
|
@@ -71,30 +128,21 @@ var SECONDS_PER_AI_COST_ESTIMATE_PERIOD = SECONDS_PER_DAY * AI_COST_ESTIMATE_PER
|
|
|
71
128
|
var INFERENCE_HOST_MODEL_ID_MAX_CHARS = 256;
|
|
72
129
|
var RETRY_AFTER_HEADER_MAX_CHARS = 128;
|
|
73
130
|
var EXO_POLICY_MAX_TOOL_ROUNDS = 64;
|
|
74
|
-
var
|
|
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
|
-
};
|
|
131
|
+
var UINT32_RANGE = 2 ** 32;
|
|
97
132
|
var HYPERLIQUID_TIF_GTC = HYPERLIQUID_EXCHANGE_SPECIFICATION.good_til_cancelled_time_in_force;
|
|
133
|
+
var HYPERLIQUID_CANDLE_SNAPSHOT_BASE_WEIGHT = HYPERLIQUID_CANDLE_SNAPSHOT_CHARGE.base_weight;
|
|
134
|
+
var HYPERLIQUID_CANDLE_SNAPSHOT_ROWS_PER_WEIGHT = HYPERLIQUID_CANDLE_SNAPSHOT_CHARGE.rows_per_extra_weight;
|
|
135
|
+
var HYPERLIQUID_CANDLE_SNAPSHOT_MAX_ROWS = HYPERLIQUID_CANDLE_SNAPSHOT_CHARGE.max_rows;
|
|
136
|
+
var HYPERLIQUID_ROW_WEIGHTED_INFO_REQUESTS = HYPERLIQUID_ROW_WEIGHTED_INFO_CHARGE.request_types;
|
|
137
|
+
var HYPERLIQUID_ROW_WEIGHTED_INFO_BASE_WEIGHT = HYPERLIQUID_ROW_WEIGHTED_INFO_CHARGE.base_weight;
|
|
138
|
+
var HYPERLIQUID_INFO_ROWS_PER_EXTRA_WEIGHT = HYPERLIQUID_ROW_WEIGHTED_INFO_CHARGE.rows_per_extra_weight;
|
|
139
|
+
var HYPERLIQUID_MAX_DEPLOYER_FEE_SCALE = HYPERLIQUID_EXCHANGE_SPECIFICATION.max_deployer_fee_scale;
|
|
140
|
+
var HYPERLIQUID_DEPLOYER_FEE_SCALE_MULTIPLIER = HYPERLIQUID_EXCHANGE_SPECIFICATION.deployer_fee_scale_multiplier;
|
|
141
|
+
var HYPERLIQUID_GROWTH_MODE_FEE_FACTOR = HYPERLIQUID_EXCHANGE_SPECIFICATION.growth_mode_fee_factor;
|
|
142
|
+
var HYPERLIQUID_ALIGNED_QUOTE_NON_DEPLOYER_FEE_FACTOR = HYPERLIQUID_EXCHANGE_SPECIFICATION.aligned_quote_non_deployer_fee_factor;
|
|
143
|
+
var AI_SNAPSHOT_COMPACT_TRANSPORT_VERSION = AI_SNAPSHOT_WIRE_FORMAT.compact_transport_version;
|
|
144
|
+
var AI_SNAPSHOT_PACKED_FIELDS = AI_SNAPSHOT_WIRE_FORMAT.packed_fields;
|
|
145
|
+
var AI_SNAPSHOT_PACKED_ENTRY_FIELDS = AI_SNAPSHOT_WIRE_FORMAT.packed_entry_fields;
|
|
98
146
|
|
|
99
147
|
// lib/runtime-policy.generated.json
|
|
100
148
|
var runtime_policy_generated_default = {
|
|
@@ -649,8 +697,7 @@ var runtime_policy_generated_default = {
|
|
|
649
697
|
debug_navbar_profile_entries: 12
|
|
650
698
|
},
|
|
651
699
|
login_page: {
|
|
652
|
-
desktop_bridge_poll_ms: 250
|
|
653
|
-
turnstile_site_key_log_chars: 10
|
|
700
|
+
desktop_bridge_poll_ms: 250
|
|
654
701
|
},
|
|
655
702
|
screener_page: {
|
|
656
703
|
search_save_debounce_ms: 250,
|
|
@@ -795,6 +842,11 @@ var runtime_policy_generated_default = {
|
|
|
795
842
|
trading: {
|
|
796
843
|
engine: {
|
|
797
844
|
client_runtime: {
|
|
845
|
+
candle_series: {
|
|
846
|
+
full_refresh_seconds: 600,
|
|
847
|
+
overlap_candles: 2,
|
|
848
|
+
delta_max_candles: 60
|
|
849
|
+
},
|
|
798
850
|
reconcile: {
|
|
799
851
|
tick_interval_seconds: 30,
|
|
800
852
|
wake_jitter_max_ms: 1e3,
|
|
@@ -839,7 +891,8 @@ var runtime_policy_generated_default = {
|
|
|
839
891
|
},
|
|
840
892
|
panel_reads: {
|
|
841
893
|
device_open_orders_reuse_seconds: 2,
|
|
842
|
-
all_view_profile_concurrency: 2
|
|
894
|
+
all_view_profile_concurrency: 2,
|
|
895
|
+
display_account_fresh_seconds: 60
|
|
843
896
|
},
|
|
844
897
|
account_stream: {
|
|
845
898
|
fill_forward_interval_ms: 1e3,
|
|
@@ -849,6 +902,9 @@ var runtime_policy_generated_default = {
|
|
|
849
902
|
max_fills_per_execution: 20,
|
|
850
903
|
max_fill_payload_bytes: 32768
|
|
851
904
|
},
|
|
905
|
+
prompt_contract: {
|
|
906
|
+
contract_version: "2026-08-24.1"
|
|
907
|
+
},
|
|
852
908
|
loop_early_return_retry_milliseconds: 5e3,
|
|
853
909
|
window_handoff_cleanup_retry_milliseconds: 1e3,
|
|
854
910
|
ai_schedule_pause_min_milliseconds: 1e3,
|
|
@@ -1202,6 +1258,8 @@ var runtime_policy_generated_default = {
|
|
|
1202
1258
|
reserve_margin_weight: 40,
|
|
1203
1259
|
demand_bucket_seconds: 60,
|
|
1204
1260
|
demand_horizon_seconds: 3600,
|
|
1261
|
+
rescue_quiet_release_minutes: 5,
|
|
1262
|
+
rescue_quiet_release_gap_multiplier: 2,
|
|
1205
1263
|
capacity_cut_percent: 70,
|
|
1206
1264
|
capacity_min_weight: 240,
|
|
1207
1265
|
capacity_recovery_weight_per_minute: 120,
|
|
@@ -1301,6 +1359,7 @@ var runtime_policy_generated_default = {
|
|
|
1301
1359
|
}
|
|
1302
1360
|
},
|
|
1303
1361
|
cache: {
|
|
1362
|
+
available_assets_ttl_seconds: 300,
|
|
1304
1363
|
order_history_ttl_seconds: 30,
|
|
1305
1364
|
twap_history_ttl_seconds: 30,
|
|
1306
1365
|
twap_fills_ttl_seconds: 30,
|
|
@@ -1342,9 +1401,9 @@ var runtime_policy_generated_default = {
|
|
|
1342
1401
|
page_start_poll_seconds: 1,
|
|
1343
1402
|
profiles_read_timeout_seconds: 30,
|
|
1344
1403
|
command_notice_reconnect_max_seconds: 60,
|
|
1345
|
-
sleep_quiet_milliseconds:
|
|
1404
|
+
sleep_quiet_milliseconds: 1500,
|
|
1346
1405
|
sleep_max_seconds: 60,
|
|
1347
|
-
sleep_min_seconds:
|
|
1406
|
+
sleep_min_seconds: 5,
|
|
1348
1407
|
sleep_alarm_grace_seconds: 15,
|
|
1349
1408
|
sleep_elastic_below_milliseconds: 1e3,
|
|
1350
1409
|
sleep_request_wait_milliseconds: 4e3,
|
|
@@ -1522,73 +1581,127 @@ var closingJsonObjectDocument = (text) => {
|
|
|
1522
1581
|
};
|
|
1523
1582
|
var agentAnswerJsonDocument = (text) => closingJsonFenceDocument(text) ?? closingJsonObjectDocument(text);
|
|
1524
1583
|
|
|
1525
|
-
// lib/
|
|
1584
|
+
// lib/runtime/provider-credit.ts
|
|
1585
|
+
var ERROR_CODES = new Set(PROVIDER_OUT_OF_CREDIT.error_codes.map((code) => code.toLowerCase()));
|
|
1586
|
+
var PROVIDER_PHRASES = PROVIDER_OUT_OF_CREDIT.provider_phrases;
|
|
1587
|
+
var PROVIDER_FAILURE_MARKERS = PROVIDER_OUT_OF_CREDIT.provider_failure_markers;
|
|
1588
|
+
var PAYMENT_REQUIRED_TEXT = `(http ${PROVIDER_OUT_OF_CREDIT.payment_required_status}`;
|
|
1589
|
+
var hasOutOfCreditWords = (normalized) => PROVIDER_PHRASES.some((phrase) => normalized.includes(phrase)) || [...ERROR_CODES].some((code) => normalized.includes(`[${code}]`));
|
|
1590
|
+
var PROVIDER_OUT_OF_CREDIT_PHRASE = PROVIDER_OUT_OF_CREDIT.vtx_phrase;
|
|
1591
|
+
var PROVIDER_OUT_OF_CREDIT_ATTEMPT_MARKER = PROVIDER_OUT_OF_CREDIT.attempt_summary_marker;
|
|
1592
|
+
var providerOutOfCreditErrorCode = (payload) => {
|
|
1593
|
+
const errorNode = payload?.error;
|
|
1594
|
+
if (!errorNode || typeof errorNode !== "object") return null;
|
|
1595
|
+
for (const field of ["code", "type"]) {
|
|
1596
|
+
const value = errorNode[field];
|
|
1597
|
+
const code = typeof value === "number" ? String(value) : typeof value === "string" ? value.trim() : "";
|
|
1598
|
+
if (code && ERROR_CODES.has(code.toLowerCase())) return code;
|
|
1599
|
+
}
|
|
1600
|
+
return null;
|
|
1601
|
+
};
|
|
1602
|
+
var isProviderOutOfCreditReply = (statusCode, detail) => {
|
|
1603
|
+
if (statusCode === PROVIDER_OUT_OF_CREDIT.payment_required_status) return true;
|
|
1604
|
+
return hasOutOfCreditWords(String(detail || "").toLowerCase());
|
|
1605
|
+
};
|
|
1606
|
+
|
|
1607
|
+
// lib/inference-host/provider-refusal.ts
|
|
1526
1608
|
var HOST_RUNTIME_POLICY = runtime_policy_generated_default.external_inference.host_runtime;
|
|
1527
|
-
var record = (value) => value
|
|
1528
|
-
var
|
|
1529
|
-
|
|
1530
|
-
if (
|
|
1531
|
-
|
|
1609
|
+
var record = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1610
|
+
var refusalWords = (payload, rawText) => {
|
|
1611
|
+
const error = record(payload).error;
|
|
1612
|
+
if (typeof error === "string") return error;
|
|
1613
|
+
const message = record(error).message ?? record(payload).message;
|
|
1614
|
+
if (typeof message === "string") return message;
|
|
1615
|
+
return payload === null ? rawText : "";
|
|
1532
1616
|
};
|
|
1533
|
-
var
|
|
1534
|
-
|
|
1535
|
-
const
|
|
1617
|
+
var isProviderOutOfCreditRefusal = (statusCode, payload, rawText = "") => providerOutOfCreditErrorCode(payload) !== null || isProviderOutOfCreditReply(statusCode, refusalWords(payload, rawText));
|
|
1618
|
+
var readProviderOutOfCreditRefusal = async (statusCode, body) => {
|
|
1619
|
+
const byStatus = isProviderOutOfCreditReply(statusCode, "");
|
|
1620
|
+
if (byStatus || !body) {
|
|
1621
|
+
void body?.cancel().catch(() => void 0);
|
|
1622
|
+
return byStatus;
|
|
1623
|
+
}
|
|
1624
|
+
const reader = body.getReader();
|
|
1536
1625
|
const chunks = [];
|
|
1537
1626
|
let bytes = 0;
|
|
1538
1627
|
let timer;
|
|
1539
|
-
const
|
|
1540
|
-
timer = setTimeout(() => reject(new Error("
|
|
1628
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
1629
|
+
timer = setTimeout(() => reject(new Error("provider_error_body_deadline")), HOST_RUNTIME_POLICY.provider_error_body_timeout_ms);
|
|
1541
1630
|
});
|
|
1542
1631
|
try {
|
|
1543
1632
|
for (; ; ) {
|
|
1544
|
-
const part = await Promise.race([reader.read(),
|
|
1633
|
+
const part = await Promise.race([reader.read(), deadline]);
|
|
1545
1634
|
if (part.done) break;
|
|
1546
1635
|
bytes += part.value.byteLength;
|
|
1547
|
-
if (bytes > HOST_RUNTIME_POLICY.provider_error_body_max_bytes) return
|
|
1636
|
+
if (bytes > HOST_RUNTIME_POLICY.provider_error_body_max_bytes) return false;
|
|
1548
1637
|
chunks.push(part.value);
|
|
1549
1638
|
}
|
|
1550
|
-
const
|
|
1551
|
-
|
|
1639
|
+
const rawText = Buffer.concat(chunks).toString("utf8");
|
|
1640
|
+
let payload = null;
|
|
1641
|
+
try {
|
|
1642
|
+
payload = JSON.parse(rawText);
|
|
1643
|
+
} catch {
|
|
1644
|
+
}
|
|
1645
|
+
return isProviderOutOfCreditRefusal(statusCode, payload, rawText);
|
|
1552
1646
|
} catch {
|
|
1553
|
-
return
|
|
1647
|
+
return false;
|
|
1554
1648
|
} finally {
|
|
1555
1649
|
if (timer) clearTimeout(timer);
|
|
1556
1650
|
void reader.cancel().catch(() => void 0);
|
|
1557
1651
|
}
|
|
1558
1652
|
};
|
|
1653
|
+
|
|
1654
|
+
// lib/inference-host/exo-harness.ts
|
|
1655
|
+
var HOST_RUNTIME_POLICY2 = runtime_policy_generated_default.external_inference.host_runtime;
|
|
1656
|
+
var record2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1657
|
+
var validModel = (value) => typeof value === "string" && Boolean(value.trim()) && value.length <= INFERENCE_HOST_MODEL_ID_MAX_CHARS && !/[\u0000-\u001f\u007f]/u.test(value);
|
|
1658
|
+
var count = (value) => {
|
|
1659
|
+
if (!Number.isSafeInteger(value) || Number(value) < 0) throw new Error("exo_usage_invalid");
|
|
1660
|
+
return Number(value);
|
|
1661
|
+
};
|
|
1662
|
+
var providerRejectionCode = async (response) => {
|
|
1663
|
+
if (response.status === HTTP_STATUS.UNAUTHORIZED) {
|
|
1664
|
+
await response.body?.cancel().catch(() => void 0);
|
|
1665
|
+
return "exo_invalid_api_key";
|
|
1666
|
+
}
|
|
1667
|
+
const clientRefusal = response.status >= HTTP_CLIENT_ERROR_MIN && response.status < HTTP_SERVER_ERROR_MIN;
|
|
1668
|
+
if (clientRefusal && await readProviderOutOfCreditRefusal(response.status, response.body)) return "exo_out_of_credit";
|
|
1669
|
+
if (!clientRefusal) await response.body?.cancel().catch(() => void 0);
|
|
1670
|
+
return response.status === HTTP_STATUS.TOO_MANY_REQUESTS ? "exo_rate_limited" : "exo_provider_rejected";
|
|
1671
|
+
};
|
|
1559
1672
|
var retryAfterDeadline = (value) => {
|
|
1560
1673
|
if (!value || value.length > RETRY_AFTER_HEADER_MAX_CHARS) return null;
|
|
1561
1674
|
const now = Date.now();
|
|
1562
1675
|
const trimmed = value.trim();
|
|
1563
1676
|
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 <=
|
|
1677
|
+
return Number.isFinite(deadline) && deadline >= now && deadline - now <= HOST_RUNTIME_POLICY2.exo_provider_retry_after_max_ms ? Math.ceil(deadline) : null;
|
|
1565
1678
|
};
|
|
1566
|
-
var textOf = (response) => (Array.isArray(response.output) ? response.output : []).flatMap((item) =>
|
|
1679
|
+
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
1680
|
var unwrapJsonFence = (text) => {
|
|
1568
1681
|
const match = /^```(?:json)?[ \t]*\r?\n([\s\S]*?)\r?\n```$/iu.exec(text.trim());
|
|
1569
1682
|
return match ? match[1] : agentAnswerJsonDocument(text) ?? text;
|
|
1570
1683
|
};
|
|
1571
1684
|
var veniceToolParameters = (value) => {
|
|
1572
1685
|
if (typeof value === "boolean") return value;
|
|
1573
|
-
const schema =
|
|
1574
|
-
const existingProperties =
|
|
1686
|
+
const schema = record2(value);
|
|
1687
|
+
const existingProperties = record2(schema.properties);
|
|
1575
1688
|
const properties = Object.fromEntries(Object.entries(existingProperties).map(([name, child]) => [name, veniceToolParameters(child)]));
|
|
1576
1689
|
const result = { ...schema, ...schema.properties ? { properties } : {} };
|
|
1577
1690
|
const union = Array.isArray(schema.anyOf) ? schema.anyOf : Array.isArray(schema.oneOf) ? schema.oneOf : null;
|
|
1578
1691
|
if (!union?.length || schema.type !== void 0 && schema.type !== "object") return result;
|
|
1579
|
-
const branches = union.map(
|
|
1692
|
+
const branches = union.map(record2);
|
|
1580
1693
|
if (!branches.every((branch) => branch.type === "object")) return result;
|
|
1581
|
-
const commonNames = Object.keys(
|
|
1694
|
+
const commonNames = Object.keys(record2(branches[0].properties)).filter((name) => branches.every((branch) => Object.hasOwn(record2(branch.properties), name)));
|
|
1582
1695
|
const common = {};
|
|
1583
1696
|
for (const name of commonNames) {
|
|
1584
|
-
const fields = branches.map((branch) =>
|
|
1697
|
+
const fields = branches.map((branch) => record2(record2(branch.properties)[name]));
|
|
1585
1698
|
const derived = {};
|
|
1586
1699
|
const type = fields[0].type;
|
|
1587
1700
|
if (typeof type === "string" && fields.every((field) => field.type === type)) derived.type = type;
|
|
1588
1701
|
if (fields.every((field) => Array.isArray(field.enum))) {
|
|
1589
1702
|
derived.enum = [...new Map(fields.flatMap((field) => field.enum).map((entry) => [JSON.stringify(entry), entry])).values()];
|
|
1590
1703
|
}
|
|
1591
|
-
common[name] = typeof properties[name] === "boolean" ? properties[name] : { ...derived, ...
|
|
1704
|
+
common[name] = typeof properties[name] === "boolean" ? properties[name] : { ...derived, ...record2(properties[name]) };
|
|
1592
1705
|
}
|
|
1593
1706
|
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
1707
|
return {
|
|
@@ -1599,8 +1712,8 @@ var veniceToolParameters = (value) => {
|
|
|
1599
1712
|
};
|
|
1600
1713
|
};
|
|
1601
1714
|
var chatResponseEvents = (events) => events.map((event) => {
|
|
1602
|
-
const data =
|
|
1603
|
-
const messages = Array.isArray(data.messages) ? data.messages.map(
|
|
1715
|
+
const data = record2(event);
|
|
1716
|
+
const messages = Array.isArray(data.messages) ? data.messages.map(record2) : [];
|
|
1604
1717
|
if (data.type !== "messages" || messages.length <= 1 || !messages.every((message) => message.role === "assistant")) return event;
|
|
1605
1718
|
const content = messages.flatMap((message) => {
|
|
1606
1719
|
if (Array.isArray(message.content)) return message.content;
|
|
@@ -1611,15 +1724,15 @@ var chatResponseEvents = (events) => events.map((event) => {
|
|
|
1611
1724
|
return { ...data, messages: [{ role: "assistant", content }] };
|
|
1612
1725
|
});
|
|
1613
1726
|
var chatRequestMessages = (harness, events) => {
|
|
1614
|
-
const requests = events.map((event) =>
|
|
1727
|
+
const requests = events.map((event) => record2(record2(event).data)).filter((event) => event.type === "tool_requested");
|
|
1615
1728
|
let index = 0;
|
|
1616
1729
|
const messages = harness.materializeEventsToMessages(events).map((message) => {
|
|
1617
1730
|
if (message.role !== "assistant" || !Array.isArray(message.content)) return message;
|
|
1618
1731
|
return { ...message, content: message.content.map((part) => {
|
|
1619
|
-
const content =
|
|
1732
|
+
const content = record2(part);
|
|
1620
1733
|
if (content.type !== "tool_call") return part;
|
|
1621
1734
|
const event = requests[index++];
|
|
1622
|
-
const request =
|
|
1735
|
+
const request = record2(event?.request);
|
|
1623
1736
|
const args = request.arguments;
|
|
1624
1737
|
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
1738
|
return { ...content, arguments: args };
|
|
@@ -1665,7 +1778,7 @@ var exo_harness_default = {
|
|
|
1665
1778
|
const source = process.env.VTX_EXO_SOURCE_ROOT;
|
|
1666
1779
|
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
1780
|
const broker = async (path, body, deadlineAtMs) => {
|
|
1668
|
-
const timeoutMs = deadlineAtMs === void 0 ?
|
|
1781
|
+
const timeoutMs = deadlineAtMs === void 0 ? HOST_RUNTIME_POLICY2.exo_bridge_request_timeout_ms : deadlineAtMs - Date.now();
|
|
1669
1782
|
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1) throw new Error("exo_deadline_reached");
|
|
1670
1783
|
const response = await nativeFetch(new URL(path, brokerUrl), {
|
|
1671
1784
|
method: body === void 0 ? "GET" : "POST",
|
|
@@ -1675,7 +1788,7 @@ var exo_harness_default = {
|
|
|
1675
1788
|
signal: AbortSignal.timeout(timeoutMs)
|
|
1676
1789
|
});
|
|
1677
1790
|
if (!response.ok) throw new Error("exo_bridge_rejected");
|
|
1678
|
-
return
|
|
1791
|
+
return record2(await response.json());
|
|
1679
1792
|
};
|
|
1680
1793
|
let dispatched = false;
|
|
1681
1794
|
let terminalKnown = true;
|
|
@@ -1699,8 +1812,8 @@ var exo_harness_default = {
|
|
|
1699
1812
|
const inputTokens = count(nativeUsage.input_tokens);
|
|
1700
1813
|
const outputTokens = count(nativeUsage.output_tokens);
|
|
1701
1814
|
const totalTokens = count(nativeUsage.total_tokens);
|
|
1702
|
-
const cachedTokens = count(
|
|
1703
|
-
const reasoningTokens = count(
|
|
1815
|
+
const cachedTokens = count(record2(nativeUsage.input_tokens_details).cached_tokens ?? 0);
|
|
1816
|
+
const reasoningTokens = count(record2(nativeUsage.output_tokens_details).reasoning_tokens ?? 0);
|
|
1704
1817
|
if (totalTokens !== inputTokens + outputTokens || cachedTokens > inputTokens || reasoningTokens > outputTokens) throw new Error("exo_usage_invalid");
|
|
1705
1818
|
usage.inputTokens = count(usage.inputTokens + inputTokens);
|
|
1706
1819
|
usage.outputTokens = count(usage.outputTokens + outputTokens);
|
|
@@ -1728,7 +1841,7 @@ var exo_harness_default = {
|
|
|
1728
1841
|
globalThis.fetch = async (resource, options) => {
|
|
1729
1842
|
const url = new URL(resource instanceof Request ? resource.url : String(resource));
|
|
1730
1843
|
if (url.href !== providerEndpoint || options?.method !== "POST" || !activeDispatch || roundDispatch || typeof options.body !== "string") throw new Error("exo_dispatch_rejected");
|
|
1731
|
-
const payload =
|
|
1844
|
+
const payload = record2(JSON.parse(options.body));
|
|
1732
1845
|
if (payload.model !== input.providerModel || payload.stream === true) throw new Error("exo_request_identity_mismatch");
|
|
1733
1846
|
const format = { name: "vtx_result", strict: true, schema: input.outputSchema };
|
|
1734
1847
|
if (input.provider === "venice") {
|
|
@@ -1749,11 +1862,11 @@ var exo_harness_default = {
|
|
|
1749
1862
|
else payload.reasoning = { effort: input.nativeReasoningEffort };
|
|
1750
1863
|
payload.text = { format: { type: "json_schema", ...format } };
|
|
1751
1864
|
}
|
|
1752
|
-
if (Array.isArray(payload.tools)) payload.tools = payload.tools.map((tool) => input.provider === "venice" ? { ...
|
|
1753
|
-
...
|
|
1865
|
+
if (Array.isArray(payload.tools)) payload.tools = payload.tools.map((tool) => input.provider === "venice" ? { ...record2(tool), function: {
|
|
1866
|
+
...record2(record2(tool).function),
|
|
1754
1867
|
strict: false,
|
|
1755
|
-
parameters: veniceToolParameters(
|
|
1756
|
-
} } : { ...
|
|
1868
|
+
parameters: veniceToolParameters(record2(record2(tool).function).parameters)
|
|
1869
|
+
} } : { ...record2(tool), strict: false });
|
|
1757
1870
|
await broker("/dispatch", { model: input.providerModel, reasoningEffort: input.reasoningEffort });
|
|
1758
1871
|
roundDispatch = true;
|
|
1759
1872
|
dispatched = true;
|
|
@@ -1765,21 +1878,20 @@ var exo_harness_default = {
|
|
|
1765
1878
|
headers.set("x-should-retry", "false");
|
|
1766
1879
|
if (!response.ok && response.status >= HTTP_CLIENT_ERROR_MIN && response.status < HTTP_SERVER_ERROR_MIN && response.status !== HTTP_STATUS.REQUEST_TIMEOUT) terminalKnown = true;
|
|
1767
1880
|
if (!response.ok) {
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
if (response.status !== HTTP_STATUS.TOO_MANY_REQUESTS) await response.body?.cancel();
|
|
1881
|
+
failureCode = await providerRejectionCode(response);
|
|
1882
|
+
retryAtMs = failureCode === "exo_rate_limited" ? retryAfterDeadline(response.headers.get("retry-after")) : null;
|
|
1771
1883
|
return new Response(JSON.stringify({ error: { message: failureCode, code: failureCode } }), { status: response.status, headers });
|
|
1772
1884
|
}
|
|
1773
1885
|
if (input.provider === "venice") {
|
|
1774
1886
|
try {
|
|
1775
|
-
const raw =
|
|
1887
|
+
const raw = record2(await response.clone().json());
|
|
1776
1888
|
const choices = Array.isArray(raw.choices) ? raw.choices : [];
|
|
1777
|
-
const choice =
|
|
1889
|
+
const choice = record2(choices[0]);
|
|
1778
1890
|
terminalKnown = choices.length === 1 && ["stop", "tool_calls", "length", "content_filter"].includes(String(choice.finish_reason));
|
|
1779
1891
|
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 =
|
|
1892
|
+
const controls = record2(raw.venice_parameters);
|
|
1893
|
+
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");
|
|
1894
|
+
const nativeUsage = record2(raw.usage);
|
|
1783
1895
|
addUsage({
|
|
1784
1896
|
input_tokens: nativeUsage.prompt_tokens,
|
|
1785
1897
|
output_tokens: nativeUsage.completion_tokens,
|
|
@@ -1790,7 +1902,7 @@ var exo_harness_default = {
|
|
|
1790
1902
|
lastCompletedResponseId = raw.id;
|
|
1791
1903
|
currentReceipt = { responseId: raw.id, providerModel: raw.model, reasoningEffort: input.reasoningEffort };
|
|
1792
1904
|
if (choices.length !== 1 || !["stop", "tool_calls"].includes(String(choice.finish_reason))) throw new Error("exo_response_incomplete");
|
|
1793
|
-
const hasTools = Array.isArray(
|
|
1905
|
+
const hasTools = Array.isArray(record2(choice.message).tool_calls) && record2(choice.message).tool_calls.length > 0;
|
|
1794
1906
|
if (choice.finish_reason === "tool_calls" !== hasTools) throw new Error("exo_response_incomplete");
|
|
1795
1907
|
} catch (error) {
|
|
1796
1908
|
failureCode = error instanceof Error && /^exo_[a-z_]+$/u.test(error.message) ? error.message : "exo_response_invalid";
|
|
@@ -1824,9 +1936,9 @@ var exo_harness_default = {
|
|
|
1824
1936
|
terminalKnown = true;
|
|
1825
1937
|
if (!validModel(response.model) || typeof response.id !== "string" || !response.id) throw new Error("exo_response_identity_mismatch");
|
|
1826
1938
|
if (input.provider === "openai") {
|
|
1827
|
-
const effectiveEffort =
|
|
1939
|
+
const effectiveEffort = record2(response.reasoning).effort ?? null;
|
|
1828
1940
|
if (effectiveEffort !== input.nativeReasoningEffort) throw new Error("exo_response_effort_mismatch");
|
|
1829
|
-
addUsage(
|
|
1941
|
+
addUsage(record2(response.usage));
|
|
1830
1942
|
lastCompletedResponseId = response.id;
|
|
1831
1943
|
currentReceipt = { responseId: response.id, providerModel: response.model, reasoningEffort: input.reasoningEffort };
|
|
1832
1944
|
}
|
|
@@ -1878,5 +1990,6 @@ var exo_harness_default = {
|
|
|
1878
1990
|
};
|
|
1879
1991
|
export {
|
|
1880
1992
|
exo_harness_default as default,
|
|
1993
|
+
providerRejectionCode,
|
|
1881
1994
|
unwrapJsonFence
|
|
1882
1995
|
};
|