@wrongstack/core 0.313.0 → 0.313.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chronicle/index.js +84 -6391
- package/dist/chronicle/project-server.js +84 -4868
- package/dist/chunk-2BUUIMQB.js +225 -0
- package/dist/chunk-2FK4WTFF.js +207 -0
- package/dist/chunk-2FQL4PDC.js +292 -0
- package/dist/chunk-2KKODIQU.js +2256 -0
- package/dist/chunk-2YU4WVBW.js +134 -0
- package/dist/chunk-3E244UDA.js +356 -0
- package/dist/chunk-3XPVB7BA.js +135 -0
- package/dist/chunk-4LJJYBAU.js +388 -0
- package/dist/chunk-4VWO3ZXL.js +342 -0
- package/dist/chunk-4XV6IR37.js +187 -0
- package/dist/chunk-4ZHTKJHM.js +183 -0
- package/dist/chunk-52RTVH4M.js +361 -0
- package/dist/chunk-57GEWK5X.js +26 -0
- package/dist/chunk-5DSMEVA4.js +931 -0
- package/dist/chunk-5RP3QTRL.js +1223 -0
- package/dist/chunk-5S437PRC.js +50 -0
- package/dist/chunk-5XDUGTKN.js +511 -0
- package/dist/chunk-62V2AFVG.js +422 -0
- package/dist/chunk-65RDIOR2.js +2470 -0
- package/dist/chunk-6AKOTGLM.js +597 -0
- package/dist/chunk-7ZHZE5EO.js +28 -0
- package/dist/chunk-A455ATZB.js +140 -0
- package/dist/chunk-AD7ZFZCS.js +46 -0
- package/dist/chunk-AI4LLQ2U.js +856 -0
- package/dist/chunk-ASX6AW36.js +789 -0
- package/dist/chunk-AT4V4XGI.js +3522 -0
- package/dist/chunk-AWNQ6ED6.js +311 -0
- package/dist/chunk-B4AMLZPB.js +9 -0
- package/dist/chunk-BAKVJLEV.js +417 -0
- package/dist/chunk-BJHVULHO.js +55 -0
- package/dist/chunk-CB2HFKTP.js +9 -0
- package/dist/chunk-CE4ZOCOI.js +1640 -0
- package/dist/chunk-CQQL4ZOQ.js +151 -0
- package/dist/chunk-DEIQMBD2.js +65 -0
- package/dist/chunk-E6I5RXVK.js +58 -0
- package/dist/chunk-EFEHDQGY.js +1589 -0
- package/dist/chunk-EODDVJBM.js +82 -0
- package/dist/chunk-EPC3GZD4.js +308 -0
- package/dist/chunk-FAYRX2AD.js +13 -0
- package/dist/chunk-FFSX2QDQ.js +362 -0
- package/dist/chunk-FHAMQS7Q.js +5856 -0
- package/dist/chunk-FIV4IJL7.js +2263 -0
- package/dist/chunk-FNXVT7HF.js +52 -0
- package/dist/chunk-FSWCWSTS.js +395 -0
- package/dist/chunk-FW5LDDMJ.js +16464 -0
- package/dist/chunk-FXQLIX3K.js +211 -0
- package/dist/chunk-G5AAKEEZ.js +228 -0
- package/dist/chunk-G5S3S5ZN.js +38 -0
- package/dist/chunk-GAZEWQEZ.js +231 -0
- package/dist/chunk-GFJOMSHG.js +125 -0
- package/dist/chunk-GFXZTHNI.js +158 -0
- package/dist/chunk-GM54GJBU.js +960 -0
- package/dist/chunk-GPQ3NJPR.js +900 -0
- package/dist/chunk-GTCU6DZ3.js +1 -0
- package/dist/chunk-H5E77KUJ.js +15 -0
- package/dist/chunk-H72H4XDU.js +1023 -0
- package/dist/chunk-HA4ZYA6T.js +178 -0
- package/dist/chunk-I45KAW2N.js +5020 -0
- package/dist/chunk-IQ35HMQL.js +1396 -0
- package/dist/chunk-IYFBFX34.js +86 -0
- package/dist/chunk-JJPMWPB6.js +109 -0
- package/dist/chunk-JTHKOYWU.js +663 -0
- package/dist/chunk-JVGPR3TS.js +365 -0
- package/dist/chunk-JVKB2TBL.js +48 -0
- package/dist/chunk-JX7VBZDK.js +31 -0
- package/dist/chunk-K3G6JBUC.js +5232 -0
- package/dist/chunk-K4YUNKU7.js +589 -0
- package/dist/chunk-KBZGE6LN.js +710 -0
- package/dist/chunk-KDQJCT2J.js +45 -0
- package/dist/chunk-KI4L2DUL.js +560 -0
- package/dist/chunk-KJ2ZTQSL.js +47 -0
- package/dist/chunk-KSJ5UTP7.js +154 -0
- package/dist/chunk-LHOA5DWA.js +28 -0
- package/dist/chunk-LX5QWLBL.js +27 -0
- package/dist/chunk-LZDDLNCZ.js +279 -0
- package/dist/chunk-M2WF6AXG.js +115 -0
- package/dist/chunk-M7BS2K6U.js +1 -0
- package/dist/chunk-NDBIPFNY.js +102 -0
- package/dist/chunk-NEMIWEXC.js +1199 -0
- package/dist/chunk-NFAYHPRH.js +323 -0
- package/dist/chunk-O37BQ65S.js +21 -0
- package/dist/chunk-O74MJHXU.js +187 -0
- package/dist/chunk-OJZEX73F.js +112 -0
- package/dist/chunk-PAAWLLZX.js +74 -0
- package/dist/chunk-PFXFQQRT.js +339 -0
- package/dist/chunk-PFZO3C6H.js +14 -0
- package/dist/chunk-PHH7LD45.js +113 -0
- package/dist/chunk-QRTG4XTI.js +188 -0
- package/dist/chunk-QVOVMXJR.js +1351 -0
- package/dist/chunk-RCQYT2I4.js +757 -0
- package/dist/chunk-RD6DEE36.js +1178 -0
- package/dist/chunk-RJIZEJ42.js +30 -0
- package/dist/chunk-RPOA7IAE.js +150 -0
- package/dist/chunk-SN2DQRL6.js +1172 -0
- package/dist/chunk-SQJVFEBV.js +41 -0
- package/dist/chunk-SQP64RCS.js +5391 -0
- package/dist/chunk-SVT4RNTR.js +49 -0
- package/dist/chunk-SWUFN7XM.js +43 -0
- package/dist/chunk-SXMVYC5H.js +174 -0
- package/dist/chunk-SZ6AYUIZ.js +23 -0
- package/dist/chunk-T3KGZBU5.js +3171 -0
- package/dist/chunk-TBRL2RCC.js +9 -0
- package/dist/chunk-TRT2HRWZ.js +18 -0
- package/dist/chunk-TYW2GI5I.js +1077 -0
- package/dist/chunk-UIWONWVG.js +4959 -0
- package/dist/chunk-VB3H5WWB.js +151 -0
- package/dist/chunk-W4A6QA3D.js +258 -0
- package/dist/chunk-WBPVKEEE.js +227 -0
- package/dist/chunk-WEBMSQP2.js +123 -0
- package/dist/chunk-WOEZV3Q4.js +333 -0
- package/dist/chunk-WQQON3SV.js +473 -0
- package/dist/chunk-WQTOVMGV.js +119 -0
- package/dist/chunk-WZO23AWO.js +2779 -0
- package/dist/chunk-XBDP4QPW.js +7 -0
- package/dist/chunk-XEBHSJLT.js +103 -0
- package/dist/chunk-XQ2ECNK3.js +1 -0
- package/dist/chunk-XQ2XGIBF.js +2086 -0
- package/dist/chunk-Y2GE5TSI.js +355 -0
- package/dist/chunk-YBUJCZ57.js +351 -0
- package/dist/chunk-YNCVSFGF.js +149 -0
- package/dist/chunk-YUPMXOGP.js +282 -0
- package/dist/chunk-YY6APYUM.js +49 -0
- package/dist/chunk-Z2IJUO45.js +691 -0
- package/dist/chunk-ZEHUCJHY.js +129 -0
- package/dist/chunk-ZYU2YOJ6.js +1496 -0
- package/dist/chunk-ZZ4V3WIZ.js +163 -0
- package/dist/coordination/agents/index.js +145 -6260
- package/dist/coordination/index.js +365 -34324
- package/dist/coordination/mailbox-project-server.js +48 -3276
- package/dist/coordination/provider-status-tracker.d.ts +4 -0
- package/dist/core/agent.d.ts +14 -1
- package/dist/core/index.js +267 -12480
- package/dist/core/model-ref.js +5 -23
- package/dist/core/provider-runner.d.ts +36 -1
- package/dist/design/index.js +50 -1087
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.js +1599 -21888
- package/dist/execution/prompt-enhancer.js +16 -535
- package/dist/execution/retry-policy.d.ts +31 -1
- package/dist/extension/index.js +7 -311
- package/dist/goal/index.js +33 -3435
- package/dist/hooks/index.js +14 -1138
- package/dist/hq/index.js +112 -5139
- package/dist/hq/protocol.js +21 -668
- package/dist/index.js +1410 -92656
- package/dist/infrastructure/index.js +64 -4811
- package/dist/kernel/events/provider-events.d.ts +15 -0
- package/dist/kernel/index.js +14 -992
- package/dist/models/index.js +40 -1117
- package/dist/notifications/index.js +3 -108
- package/dist/observability/index.js +17 -279
- package/dist/plugin/index.js +584 -14835
- package/dist/prompts/index.js +14 -948
- package/dist/registry/index.js +9 -822
- package/dist/registry-R23UBE7H.js +14 -0
- package/dist/replay/index.js +6 -84
- package/dist/review-finding-store-DKAV3AS6.js +21 -0
- package/dist/review-report-store-OWY3EC3N.js +19 -0
- package/dist/security/index.js +114 -2202
- package/dist/session-catalog/index.js +36 -2103
- package/dist/session-catalog/project-server.js +42 -1435
- package/dist/skills/index.js +35 -1578
- package/dist/storage/index.js +182 -15600
- package/dist/tasking/index.js +10 -676
- package/dist/tools/index.js +52 -9590
- package/dist/types/config/autonomy.d.ts +5 -0
- package/dist/types/config/ui.d.ts +1 -1
- package/dist/types/errors.d.ts +18 -0
- package/dist/types/index.js +121 -1342
- package/dist/types/provider-runner.d.ts +8 -0
- package/dist/types/session-markers.js +8 -144
- package/dist/utils/error.js +3 -4
- package/dist/utils/expect-defined.js +3 -9
- package/dist/utils/heap-watchdog.js +6 -706
- package/dist/utils/index.js +269 -5685
- package/dist/utils/sage-output-block.js +5 -42
- package/dist/wiring/proxy-rewrite.d.ts +18 -0
- package/dist/wiring/proxy-rewrite.js +18 -121
- package/dist/worktree/index.js +6 -887
- package/package.json +4 -4
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import {
|
|
2
|
+
truncate
|
|
3
|
+
} from "./chunk-B4AMLZPB.js";
|
|
4
|
+
import {
|
|
5
|
+
ERROR_CODES,
|
|
6
|
+
WrongStackError
|
|
7
|
+
} from "./chunk-WOEZV3Q4.js";
|
|
8
|
+
|
|
9
|
+
// src/types/quota-regex.ts
|
|
10
|
+
var QUOTA_EXHAUSTED_RE = /(?:insufficient|exhausted|depleted|exceeded|no|not enough)[-_\s]*(?:quota|credit|balance)|(?:quota|credit|balance)(?:\s+(?:has|have))?(?:\s+been)?[-_\s]*(?:exhausted|depleted|exceeded|insufficient)|billing[_\s-]*(?:hard[_\s-]*)?limit|payment required|spending limit|plan limit|(?:usage|credit)[-_\s]*(?:quota|limit)(?![-_\w])|usage[-_\s]*(?:limit|quota)[-_\s]*(?:reached|exceeded|for)/i;
|
|
11
|
+
var ROUTE_SCOPED_QUOTA_RE = /\b(?:for|on)\s+(?:(?:this|the)\s+)?(?:route|model)\b|\b(?:route|model)(?:[-_\s]+[\w.-]+)?[-_\s]*(?:quota|limit)\b|\b(?:quota|limit).{0,24}\b(?:for|on)\s+(?:(?:this|the)\s+)?(?:route|model)\b/i;
|
|
12
|
+
|
|
13
|
+
// src/types/provider.ts
|
|
14
|
+
var REASONING_EFFORT_LEVELS = [
|
|
15
|
+
"none",
|
|
16
|
+
"minimal",
|
|
17
|
+
"low",
|
|
18
|
+
"medium",
|
|
19
|
+
"high",
|
|
20
|
+
"xhigh",
|
|
21
|
+
"max"
|
|
22
|
+
];
|
|
23
|
+
function isReasoningEffort(value) {
|
|
24
|
+
return typeof value === "string" && REASONING_EFFORT_LEVELS.includes(value);
|
|
25
|
+
}
|
|
26
|
+
function effectiveInputTokens(usage) {
|
|
27
|
+
return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
|
|
28
|
+
}
|
|
29
|
+
function freshInputTokens(usage) {
|
|
30
|
+
return Math.max(0, effectiveInputTokens(usage) - (usage.cacheRead ?? 0));
|
|
31
|
+
}
|
|
32
|
+
function promptCacheHitRatio(usage) {
|
|
33
|
+
const total = effectiveInputTokens(usage);
|
|
34
|
+
if (!Number.isFinite(total) || total <= 0) return 0;
|
|
35
|
+
const cached = Number.isFinite(usage.cacheRead) ? Math.max(0, usage.cacheRead ?? 0) : 0;
|
|
36
|
+
return Math.min(1, cached / total);
|
|
37
|
+
}
|
|
38
|
+
var CONTEXT_OVERFLOW_RE = /context.length|context.window|maximum context|max.*tokens?.*exceeded|(?:prompt|request|input|messages?).{0,12}too (?:large|long)|exceeds the context|\btokens\b.*exceed|too many tokens|reduce the length|resulted in \d+ tokens|context_length_exceeded/i;
|
|
39
|
+
var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
|
|
40
|
+
var RATE_LIMIT_EXCEEDED_RE = /rate[-_\s]*limit[-_\s]*exceeded/i;
|
|
41
|
+
function classifyProviderError(status, body, message) {
|
|
42
|
+
const type = body?.type;
|
|
43
|
+
const text = [message, body?.message, type, body?.raw].filter(Boolean).join("\n");
|
|
44
|
+
if (status === 0) return "network";
|
|
45
|
+
if (status === 408) return "timeout";
|
|
46
|
+
if (status === 599) return "stream_hang";
|
|
47
|
+
if (QUOTA_EXHAUSTED_RE.test(text)) return "quota_exhausted";
|
|
48
|
+
if (status === 402) return "quota_exhausted";
|
|
49
|
+
if (status === 429 && body?.message && body.type !== "rate_limit_exceeded" && RATE_LIMIT_EXCEEDED_RE.test(body.message)) {
|
|
50
|
+
return "quota_exhausted";
|
|
51
|
+
}
|
|
52
|
+
if (type === "rate_limit_error" || status === 429) return "rate_limit";
|
|
53
|
+
if (type === "overloaded_error" || status === 529) return "overloaded";
|
|
54
|
+
if (status >= 500) return "server";
|
|
55
|
+
if (type === "authentication_error" || type === "permission_error" || status === 401 || status === 403) {
|
|
56
|
+
return "auth";
|
|
57
|
+
}
|
|
58
|
+
if (type === "content_filter" || CONTENT_FILTER_RE.test(text)) return "content_filter";
|
|
59
|
+
if (status === 413 || status >= 400 && CONTEXT_OVERFLOW_RE.test(text)) {
|
|
60
|
+
return "context_overflow";
|
|
61
|
+
}
|
|
62
|
+
if (status >= 400) return "invalid_request";
|
|
63
|
+
return "unknown";
|
|
64
|
+
}
|
|
65
|
+
var MAX_RESET_HINT_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
66
|
+
var RESET_HINT_LEAD_RE = /(?:try again|retry|resets?|resetting|available|returns?|back online|usable again)\s+(?:in|after)\s+/i;
|
|
67
|
+
var RESET_AT_LEAD_RE = /resets?\s+(?:at|on)\s+/i;
|
|
68
|
+
var DURATION_TOKEN_RE = /(\d+(?:\.\d+)?)\s*(ms|secs?|seconds?|s|mins?|minutes?|m|hrs?|hours?|h|days?|d)(?![a-z])/gi;
|
|
69
|
+
var UNIT_MS = {
|
|
70
|
+
ms: 1,
|
|
71
|
+
s: 1e3,
|
|
72
|
+
m: 6e4,
|
|
73
|
+
h: 36e5,
|
|
74
|
+
d: 864e5
|
|
75
|
+
};
|
|
76
|
+
function unitMs(unit) {
|
|
77
|
+
const u = unit.toLowerCase();
|
|
78
|
+
if (u === "ms") return 1;
|
|
79
|
+
if (u.startsWith("s")) return UNIT_MS["s"];
|
|
80
|
+
if (u.startsWith("m")) return UNIT_MS["m"];
|
|
81
|
+
if (u.startsWith("h")) return UNIT_MS["h"];
|
|
82
|
+
return UNIT_MS["d"];
|
|
83
|
+
}
|
|
84
|
+
var ISO_TIMESTAMP_RE = /(\d{4}-\d{2}-\d{2}(?:[T ]\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:\s*(?:Z|[+-]\d{2}:?\d{2}|UTC|GMT))?)?)/i;
|
|
85
|
+
function parseResetHintMs(message, now = Date.now()) {
|
|
86
|
+
if (!message) return void 0;
|
|
87
|
+
const lead = RESET_HINT_LEAD_RE.exec(message);
|
|
88
|
+
if (lead) {
|
|
89
|
+
const window = message.slice(lead.index + lead[0].length, lead.index + lead[0].length + 80);
|
|
90
|
+
let total = 0;
|
|
91
|
+
let matched = false;
|
|
92
|
+
DURATION_TOKEN_RE.lastIndex = 0;
|
|
93
|
+
for (let m = DURATION_TOKEN_RE.exec(window); m; m = DURATION_TOKEN_RE.exec(window)) {
|
|
94
|
+
const value = Number.parseFloat(m[1]);
|
|
95
|
+
if (Number.isFinite(value) && value > 0) {
|
|
96
|
+
total += value * unitMs(m[2]);
|
|
97
|
+
matched = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (!matched) {
|
|
101
|
+
const bare = /^(?:an?\s+)?(second|minute|hour|day)\b/i.exec(window.trim());
|
|
102
|
+
if (bare) {
|
|
103
|
+
total = unitMs(bare[1]);
|
|
104
|
+
matched = true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (matched && total > 0) {
|
|
108
|
+
return Math.min(total, MAX_RESET_HINT_MS);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const atLead = RESET_AT_LEAD_RE.exec(message);
|
|
112
|
+
if (atLead) {
|
|
113
|
+
const window = message.slice(atLead.index + atLead[0].length);
|
|
114
|
+
const iso = ISO_TIMESTAMP_RE.exec(window);
|
|
115
|
+
if (iso) {
|
|
116
|
+
const normalized = iso[1].replace(/^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2})/, "$1T$2").replace(/\s*(UTC|GMT)$/i, "Z");
|
|
117
|
+
const ts = Date.parse(normalized);
|
|
118
|
+
if (Number.isFinite(ts) && ts > now) {
|
|
119
|
+
return Math.min(ts - now, MAX_RESET_HINT_MS);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return void 0;
|
|
124
|
+
}
|
|
125
|
+
function isRetryableKind(kind) {
|
|
126
|
+
return RETRYABLE_BY_KIND[kind];
|
|
127
|
+
}
|
|
128
|
+
var RETRYABLE_BY_KIND = {
|
|
129
|
+
rate_limit: true,
|
|
130
|
+
quota_exhausted: false,
|
|
131
|
+
overloaded: true,
|
|
132
|
+
server: true,
|
|
133
|
+
timeout: true,
|
|
134
|
+
network: true,
|
|
135
|
+
stream_hang: true,
|
|
136
|
+
auth: false,
|
|
137
|
+
context_overflow: false,
|
|
138
|
+
content_filter: false,
|
|
139
|
+
invalid_request: false,
|
|
140
|
+
unknown: false
|
|
141
|
+
};
|
|
142
|
+
function isFallbackWorthy(kind) {
|
|
143
|
+
return FALLBACK_WORTHY_BY_KIND[kind];
|
|
144
|
+
}
|
|
145
|
+
var FALLBACK_WORTHY_BY_KIND = {
|
|
146
|
+
rate_limit: true,
|
|
147
|
+
quota_exhausted: true,
|
|
148
|
+
overloaded: true,
|
|
149
|
+
server: true,
|
|
150
|
+
timeout: true,
|
|
151
|
+
network: true,
|
|
152
|
+
stream_hang: true,
|
|
153
|
+
auth: false,
|
|
154
|
+
context_overflow: false,
|
|
155
|
+
content_filter: false,
|
|
156
|
+
invalid_request: false,
|
|
157
|
+
unknown: false
|
|
158
|
+
};
|
|
159
|
+
var ProviderError = class extends WrongStackError {
|
|
160
|
+
status;
|
|
161
|
+
retryable;
|
|
162
|
+
providerId;
|
|
163
|
+
/** Canonical failure classification — see {@link ProviderErrorKind}. */
|
|
164
|
+
kind;
|
|
165
|
+
body;
|
|
166
|
+
/**
|
|
167
|
+
* Duck-type guard: checks whether an unknown value *looks like* a
|
|
168
|
+
* ProviderError by probing for its structural properties. Use this
|
|
169
|
+
* anywhere the constructor identity might cross a package boundary
|
|
170
|
+
* (e.g. `@wrongstack/providers` creates the error, but the runner in
|
|
171
|
+
* `@wrongstack/core` checks it). A plain `instanceof ProviderError`
|
|
172
|
+
* can fail when npm hoists duplicate copies of `@wrongstack/core`,
|
|
173
|
+
* each with its own class identity.
|
|
174
|
+
*
|
|
175
|
+
* The check tests for the four invariant properties defined in the
|
|
176
|
+
* constructor: `name === 'ProviderError'`, `status` (number),
|
|
177
|
+
* `retryable` (boolean), and `kind` (string). This tolerates both
|
|
178
|
+
* true `ProviderError` instances and cross-boundary copies.
|
|
179
|
+
*/
|
|
180
|
+
static isProviderError(err) {
|
|
181
|
+
if (!err || typeof err !== "object") return false;
|
|
182
|
+
const e = err;
|
|
183
|
+
const name = e.name;
|
|
184
|
+
if (typeof name !== "string" || !name.endsWith("Error")) return false;
|
|
185
|
+
return typeof e.status === "number" && typeof e.retryable === "boolean" && typeof e.kind === "string" && typeof e.describe === "function";
|
|
186
|
+
}
|
|
187
|
+
constructor(message, status, retryable, providerId, opts = {}) {
|
|
188
|
+
const kind = opts.kind ?? classifyProviderError(status, opts.body, message);
|
|
189
|
+
super({
|
|
190
|
+
message,
|
|
191
|
+
code: kindToCode(kind),
|
|
192
|
+
subsystem: "provider",
|
|
193
|
+
severity: status >= 500 ? "error" : "warning",
|
|
194
|
+
recoverable: retryable,
|
|
195
|
+
context: { providerId, status },
|
|
196
|
+
cause: opts.cause
|
|
197
|
+
});
|
|
198
|
+
this.name = "ProviderError";
|
|
199
|
+
this.status = status;
|
|
200
|
+
this.retryable = retryable;
|
|
201
|
+
this.providerId = providerId;
|
|
202
|
+
this.kind = kind;
|
|
203
|
+
this.body = opts.body;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Render a one-line, user-facing description. Designed for the CLI/TUI
|
|
207
|
+
* status line and the agent's retry warning. Avoids dumping raw JSON
|
|
208
|
+
* (which is what users see today when a 529 lands and the log message
|
|
209
|
+
* includes the full `{"type":"error",...}` body).
|
|
210
|
+
*
|
|
211
|
+
* Examples:
|
|
212
|
+
* "minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0…]"
|
|
213
|
+
* "openai rate limited (429): Retry after 12s"
|
|
214
|
+
* "anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'"
|
|
215
|
+
* "groq HTTP 500 (server error)"
|
|
216
|
+
*/
|
|
217
|
+
describe() {
|
|
218
|
+
const kind = describeStatus(this.status, this.body?.type);
|
|
219
|
+
const head = `${this.providerId} ${kind}`;
|
|
220
|
+
const detail = this.body?.message?.trim();
|
|
221
|
+
const reqId = this.body?.requestId ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? "\u2026" : ""}]` : "";
|
|
222
|
+
if (detail && detail.length > 0) {
|
|
223
|
+
return `${head}: ${truncate(detail, 240)}${reqId}`;
|
|
224
|
+
}
|
|
225
|
+
return `${head}${reqId}`;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
function isContextOverflowShaped(err) {
|
|
229
|
+
if (!(err instanceof ProviderError) && !ProviderError.isProviderError(err)) return false;
|
|
230
|
+
const providerErr = err;
|
|
231
|
+
if (providerErr.kind === "context_overflow" || providerErr.status === 413) return true;
|
|
232
|
+
if (providerErr.status < 400) return false;
|
|
233
|
+
const text = [
|
|
234
|
+
providerErr.message,
|
|
235
|
+
providerErr.body?.message,
|
|
236
|
+
providerErr.body?.type,
|
|
237
|
+
providerErr.body?.raw
|
|
238
|
+
].filter(Boolean).join("\n");
|
|
239
|
+
return CONTEXT_OVERFLOW_RE.test(text);
|
|
240
|
+
}
|
|
241
|
+
function describeStatus(status, type) {
|
|
242
|
+
if (status === 0) return "network error";
|
|
243
|
+
if (status === 599) return `stream hang (${status})`;
|
|
244
|
+
if (type === "overloaded_error" || status === 529) return `overloaded (${status})`;
|
|
245
|
+
if (type === "rate_limit_error" || status === 429) return `rate limited (${status})`;
|
|
246
|
+
if (type === "authentication_error" || status === 401) return `auth failed (${status})`;
|
|
247
|
+
if (type === "permission_error" || status === 403) return `forbidden (${status})`;
|
|
248
|
+
if (type === "not_found_error" || status === 404) return `not found (${status})`;
|
|
249
|
+
if (type === "content_filter") return `content filtered (${status})`;
|
|
250
|
+
if (type === "invalid_request_error" || status === 400) return `invalid request (${status})`;
|
|
251
|
+
if (status === 408) return `timeout (${status})`;
|
|
252
|
+
if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;
|
|
253
|
+
if (type) return `${type} (${status})`;
|
|
254
|
+
return `HTTP ${status}`;
|
|
255
|
+
}
|
|
256
|
+
var StreamHangError = class extends ProviderError {
|
|
257
|
+
/** Name of the provider that hung, e.g. "zai", "anthropic". */
|
|
258
|
+
hungProviderId;
|
|
259
|
+
/** Model that was being called when the hang occurred. */
|
|
260
|
+
hungModel;
|
|
261
|
+
/** How long (ms) we waited for the next chunk before declaring a hang. */
|
|
262
|
+
hangTimeoutMs;
|
|
263
|
+
/** How many bytes were received before the hang. */
|
|
264
|
+
bytesReceived;
|
|
265
|
+
/** Elapsed time (ms) from the start of the stream until the hang. */
|
|
266
|
+
elapsedMs;
|
|
267
|
+
constructor(opts) {
|
|
268
|
+
super(
|
|
269
|
+
`Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,
|
|
270
|
+
599,
|
|
271
|
+
true,
|
|
272
|
+
// always retryable
|
|
273
|
+
opts.providerId,
|
|
274
|
+
{
|
|
275
|
+
body: {
|
|
276
|
+
message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`
|
|
277
|
+
},
|
|
278
|
+
cause: opts.cause
|
|
279
|
+
}
|
|
280
|
+
);
|
|
281
|
+
this.name = "StreamHangError";
|
|
282
|
+
this.hungProviderId = opts.providerId;
|
|
283
|
+
this.hungModel = opts.model;
|
|
284
|
+
this.hangTimeoutMs = opts.hangTimeoutMs;
|
|
285
|
+
this.bytesReceived = opts.bytesReceived;
|
|
286
|
+
this.elapsedMs = opts.elapsedMs;
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
var KIND_TO_CODE = {
|
|
290
|
+
network: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
291
|
+
timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,
|
|
292
|
+
rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,
|
|
293
|
+
quota_exhausted: ERROR_CODES.PROVIDER_RATE_LIMITED,
|
|
294
|
+
auth: ERROR_CODES.PROVIDER_AUTH_FAILED,
|
|
295
|
+
overloaded: ERROR_CODES.PROVIDER_OVERLOADED,
|
|
296
|
+
context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,
|
|
297
|
+
server: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
298
|
+
stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,
|
|
299
|
+
content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
300
|
+
invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,
|
|
301
|
+
unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST
|
|
302
|
+
};
|
|
303
|
+
function kindToCode(kind) {
|
|
304
|
+
return KIND_TO_CODE[kind];
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export {
|
|
308
|
+
QUOTA_EXHAUSTED_RE,
|
|
309
|
+
ROUTE_SCOPED_QUOTA_RE,
|
|
310
|
+
REASONING_EFFORT_LEVELS,
|
|
311
|
+
isReasoningEffort,
|
|
312
|
+
effectiveInputTokens,
|
|
313
|
+
freshInputTokens,
|
|
314
|
+
promptCacheHitRatio,
|
|
315
|
+
classifyProviderError,
|
|
316
|
+
parseResetHintMs,
|
|
317
|
+
isRetryableKind,
|
|
318
|
+
isFallbackWorthy,
|
|
319
|
+
ProviderError,
|
|
320
|
+
isContextOverflowShaped,
|
|
321
|
+
StreamHangError
|
|
322
|
+
};
|
|
323
|
+
//# sourceMappingURL=chunk-NFAYHPRH.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// src/types/blocks.ts
|
|
2
|
+
function isTextBlock(b) {
|
|
3
|
+
return b.type === "text";
|
|
4
|
+
}
|
|
5
|
+
function isToolUseBlock(b) {
|
|
6
|
+
return b.type === "tool_use";
|
|
7
|
+
}
|
|
8
|
+
function isToolResultBlock(b) {
|
|
9
|
+
return b.type === "tool_result";
|
|
10
|
+
}
|
|
11
|
+
function isImageBlock(b) {
|
|
12
|
+
return b.type === "image";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
isTextBlock,
|
|
17
|
+
isToolUseBlock,
|
|
18
|
+
isToolResultBlock,
|
|
19
|
+
isImageBlock
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=chunk-O37BQ65S.js.map
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ERROR_CODES,
|
|
3
|
+
WrongStackError
|
|
4
|
+
} from "./chunk-WOEZV3Q4.js";
|
|
5
|
+
|
|
6
|
+
// src/kernel/container.ts
|
|
7
|
+
var Container = class {
|
|
8
|
+
entries = /* @__PURE__ */ new Map();
|
|
9
|
+
/**
|
|
10
|
+
* Tokens currently mid-resolve. Tracked so we can detect circular
|
|
11
|
+
* dependencies (A → B → A) and throw a structured error instead of
|
|
12
|
+
* overflowing the call stack with "Maximum call stack size exceeded".
|
|
13
|
+
*
|
|
14
|
+
* Not a memoization cache — the per-entry `cache` field is the source
|
|
15
|
+
* of truth for "have I built this before?". This set only lives for
|
|
16
|
+
* the duration of a single resolve call.
|
|
17
|
+
*/
|
|
18
|
+
resolving = /* @__PURE__ */ new Set();
|
|
19
|
+
bind(token, factory, opts = {}) {
|
|
20
|
+
if (this.entries.has(token)) {
|
|
21
|
+
throw new WrongStackError({
|
|
22
|
+
message: `Container: token "${token.description ?? "unknown"}" already bound`,
|
|
23
|
+
code: ERROR_CODES.CONTAINER_TOKEN_ALREADY_BOUND,
|
|
24
|
+
subsystem: "container",
|
|
25
|
+
context: { token: token.description }
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
this.entries.set(token, {
|
|
29
|
+
factory,
|
|
30
|
+
singleton: opts.singleton ?? true,
|
|
31
|
+
decorators: [],
|
|
32
|
+
hasCache: false,
|
|
33
|
+
owner: opts.owner ?? "core"
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
override(token, factory, opts = {}) {
|
|
37
|
+
const existing = this.entries.get(token);
|
|
38
|
+
if (!existing) {
|
|
39
|
+
throw new WrongStackError({
|
|
40
|
+
message: `Container: cannot override "${token.description ?? "unknown"}" \u2014 not bound`,
|
|
41
|
+
code: ERROR_CODES.CONTAINER_TOKEN_NOT_BOUND,
|
|
42
|
+
subsystem: "container",
|
|
43
|
+
context: { token: token.description }
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
this.entries.set(token, {
|
|
47
|
+
factory,
|
|
48
|
+
singleton: opts.singleton ?? existing.singleton,
|
|
49
|
+
decorators: existing.decorators,
|
|
50
|
+
hasCache: false,
|
|
51
|
+
owner: opts.owner ?? existing.owner
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
decorate(token, decorator, owner = "core") {
|
|
55
|
+
const existing = this.entries.get(token);
|
|
56
|
+
if (!existing) {
|
|
57
|
+
throw new WrongStackError({
|
|
58
|
+
message: `Container: cannot decorate "${token.description ?? "unknown"}" \u2014 not bound`,
|
|
59
|
+
code: ERROR_CODES.CONTAINER_TOKEN_NOT_BOUND,
|
|
60
|
+
subsystem: "container",
|
|
61
|
+
context: { token: token.description }
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
existing.decorators.push(decorator);
|
|
65
|
+
existing.cache = void 0;
|
|
66
|
+
existing.hasCache = false;
|
|
67
|
+
existing.owner = `${existing.owner}+${owner}`;
|
|
68
|
+
}
|
|
69
|
+
resolve(token) {
|
|
70
|
+
const entry = this.entries.get(token);
|
|
71
|
+
if (!entry) {
|
|
72
|
+
throw new WrongStackError({
|
|
73
|
+
message: `Container: token "${token.description ?? "unknown"}" not bound`,
|
|
74
|
+
code: ERROR_CODES.CONTAINER_TOKEN_NOT_BOUND,
|
|
75
|
+
subsystem: "container",
|
|
76
|
+
context: { token: token.description }
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (entry.singleton && entry.hasCache) {
|
|
80
|
+
return entry.cache;
|
|
81
|
+
}
|
|
82
|
+
if (this.resolving.has(token)) {
|
|
83
|
+
const cycle = this.describeCycle(token);
|
|
84
|
+
throw new WrongStackError({
|
|
85
|
+
message: `Container: circular dependency detected \u2014 ${cycle}`,
|
|
86
|
+
code: ERROR_CODES.CONTAINER_CIRCULAR_DEPENDENCY,
|
|
87
|
+
subsystem: "container",
|
|
88
|
+
context: { token: token.description, cycle }
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
this.resolving.add(token);
|
|
92
|
+
try {
|
|
93
|
+
let value = entry.factory(this);
|
|
94
|
+
for (const d of entry.decorators) {
|
|
95
|
+
value = d(value, this);
|
|
96
|
+
}
|
|
97
|
+
if (entry.singleton) {
|
|
98
|
+
entry.cache = value;
|
|
99
|
+
entry.hasCache = true;
|
|
100
|
+
}
|
|
101
|
+
return value;
|
|
102
|
+
} finally {
|
|
103
|
+
this.resolving.delete(token);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Build a human-readable description of the dependency cycle that
|
|
108
|
+
* caused the resolution to re-enter. Lists the tokens in the order
|
|
109
|
+
* they were entered, then appends the re-entered token to close the
|
|
110
|
+
* loop. Falls back to a generic message if the resolving set is
|
|
111
|
+
* somehow empty (shouldn't happen, but defensive).
|
|
112
|
+
*/
|
|
113
|
+
describeCycle(reentry) {
|
|
114
|
+
const descs = [];
|
|
115
|
+
const seen = /* @__PURE__ */ new Set();
|
|
116
|
+
for (const t of this.resolving) {
|
|
117
|
+
if (seen.has(t)) continue;
|
|
118
|
+
seen.add(t);
|
|
119
|
+
descs.push(t.description ?? "unknown");
|
|
120
|
+
}
|
|
121
|
+
descs.push(reentry.description ?? "unknown");
|
|
122
|
+
return descs.join(" \u2192 ");
|
|
123
|
+
}
|
|
124
|
+
has(token) {
|
|
125
|
+
return this.entries.has(token);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Resolve a token if it is bound, otherwise return undefined.
|
|
129
|
+
* Unlike `resolve()`, this does not throw if the token is unbound.
|
|
130
|
+
*
|
|
131
|
+
* Single map lookup — `has()` + `resolve()` would walk the entries
|
|
132
|
+
* map twice. The bound check is folded into the resolve path so a
|
|
133
|
+
* non-existent token can never enter the `resolving` cycle-detection
|
|
134
|
+
* set.
|
|
135
|
+
*/
|
|
136
|
+
safeResolve(token) {
|
|
137
|
+
if (!this.entries.has(token)) return void 0;
|
|
138
|
+
return this.resolve(token);
|
|
139
|
+
}
|
|
140
|
+
ownerOf(token) {
|
|
141
|
+
return this.entries.get(token)?.owner;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Remove a token's binding (along with any decorators stacked on it).
|
|
145
|
+
* Returns true if the token existed. Use this to withdraw temporary
|
|
146
|
+
* bindings installed by a short-lived run or plugin — without it, the
|
|
147
|
+
* entry persists in the map forever.
|
|
148
|
+
*/
|
|
149
|
+
unbind(token) {
|
|
150
|
+
return this.entries.delete(token);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Drop every binding. Intended for tests and short-lived CLI invocations
|
|
154
|
+
* that rebuild the container from scratch. Production code should prefer
|
|
155
|
+
* `unbind` on the specific tokens it owns.
|
|
156
|
+
*/
|
|
157
|
+
clear() {
|
|
158
|
+
this.entries.clear();
|
|
159
|
+
}
|
|
160
|
+
list() {
|
|
161
|
+
return Array.from(this.entries.entries()).map(([token, entry]) => ({
|
|
162
|
+
token,
|
|
163
|
+
owner: entry.owner
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Inspect a binding's full shape, including decorator count and whether
|
|
168
|
+
* a singleton value is cached. Returns null if the token is unbound.
|
|
169
|
+
* Decorator and factory function references are not exposed — only counts
|
|
170
|
+
* and metadata, to keep internal state hidden.
|
|
171
|
+
*/
|
|
172
|
+
inspect(token) {
|
|
173
|
+
const entry = this.entries.get(token);
|
|
174
|
+
if (!entry) return null;
|
|
175
|
+
return {
|
|
176
|
+
owner: entry.owner,
|
|
177
|
+
singleton: entry.singleton,
|
|
178
|
+
decoratorCount: entry.decorators.length,
|
|
179
|
+
cached: entry.hasCache
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export {
|
|
185
|
+
Container
|
|
186
|
+
};
|
|
187
|
+
//# sourceMappingURL=chunk-O74MJHXU.js.map
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// src/types/config/fleet-chat.ts
|
|
2
|
+
var FLEET_CHAT_VERBOSITY_VALUES = ["off", "full"];
|
|
3
|
+
function resolveFleetChatVerbosity(autonomy) {
|
|
4
|
+
const explicit = autonomy?.fleetChatVerbosity;
|
|
5
|
+
if (explicit && FLEET_CHAT_VERBOSITY_VALUES.includes(explicit)) {
|
|
6
|
+
return explicit;
|
|
7
|
+
}
|
|
8
|
+
return "off";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// src/types/config/ui.ts
|
|
12
|
+
var THEME_PRESET_IDS = [
|
|
13
|
+
"catppuccin",
|
|
14
|
+
"tokyo-night",
|
|
15
|
+
"nord",
|
|
16
|
+
"cyberpunk",
|
|
17
|
+
"dracula",
|
|
18
|
+
"gruvbox-dark",
|
|
19
|
+
"solarized-dark",
|
|
20
|
+
"one-dark",
|
|
21
|
+
"monokai",
|
|
22
|
+
"rose-pine",
|
|
23
|
+
"kanagawa",
|
|
24
|
+
"ayu-dark",
|
|
25
|
+
"everforest",
|
|
26
|
+
"night-owl",
|
|
27
|
+
"synthwave",
|
|
28
|
+
"github-dark",
|
|
29
|
+
"material-ocean",
|
|
30
|
+
"nightfox",
|
|
31
|
+
"oxocarbon",
|
|
32
|
+
"catppuccin-macchiato",
|
|
33
|
+
"catppuccin-frappe",
|
|
34
|
+
"gruvbox-material",
|
|
35
|
+
"tokyo-night-storm",
|
|
36
|
+
"rose-pine-moon",
|
|
37
|
+
"zenburn",
|
|
38
|
+
"palenight",
|
|
39
|
+
"horizon",
|
|
40
|
+
"sonokai",
|
|
41
|
+
"edge-dark",
|
|
42
|
+
"moonfly",
|
|
43
|
+
"melange",
|
|
44
|
+
"poimandres",
|
|
45
|
+
"vitesse-dark",
|
|
46
|
+
"aura",
|
|
47
|
+
"dark-plus",
|
|
48
|
+
"monochrome",
|
|
49
|
+
"matrix",
|
|
50
|
+
"amber",
|
|
51
|
+
"cyber-noir",
|
|
52
|
+
"cobalt-mono",
|
|
53
|
+
"blood-moon",
|
|
54
|
+
"cobalt2",
|
|
55
|
+
"shades-of-purple",
|
|
56
|
+
"flexoki-dark",
|
|
57
|
+
"laserwave",
|
|
58
|
+
"andromeda",
|
|
59
|
+
"github-dark-dimmed",
|
|
60
|
+
"snazzy",
|
|
61
|
+
"tokyo-night-moon",
|
|
62
|
+
"gruvbox-dark-hard"
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
// src/types/spec.ts
|
|
66
|
+
var DEFAULT_SPEC_TEMPLATE = {
|
|
67
|
+
id: "default",
|
|
68
|
+
name: "Default Feature Spec",
|
|
69
|
+
description: "Standard template for feature specifications",
|
|
70
|
+
sections: [
|
|
71
|
+
{ type: "overview", title: "Overview", level: 1 },
|
|
72
|
+
{ type: "requirements", title: "Requirements", level: 1 },
|
|
73
|
+
{ type: "architecture", title: "Architecture", level: 1 },
|
|
74
|
+
{ type: "api", title: "API Design", level: 1 },
|
|
75
|
+
{ type: "data", title: "Data Model", level: 1 },
|
|
76
|
+
{ type: "security", title: "Security", level: 1 },
|
|
77
|
+
{ type: "acceptance", title: "Acceptance Criteria", level: 1 }
|
|
78
|
+
],
|
|
79
|
+
defaultRequirements: [
|
|
80
|
+
{ type: "functional", priority: "high", acceptanceCriteria: [], blockedBy: [], implements: [] },
|
|
81
|
+
{
|
|
82
|
+
type: "non-functional",
|
|
83
|
+
priority: "medium",
|
|
84
|
+
acceptanceCriteria: [],
|
|
85
|
+
blockedBy: [],
|
|
86
|
+
implements: []
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// src/types/tool.ts
|
|
92
|
+
var ToolErrorCategory = /* @__PURE__ */ ((ToolErrorCategory2) => {
|
|
93
|
+
ToolErrorCategory2["TRANSIENT"] = "transient";
|
|
94
|
+
ToolErrorCategory2["NOT_FOUND"] = "not_found";
|
|
95
|
+
ToolErrorCategory2["PERMISSION"] = "permission";
|
|
96
|
+
ToolErrorCategory2["VALIDATION"] = "validation";
|
|
97
|
+
ToolErrorCategory2["FATAL"] = "fatal";
|
|
98
|
+
return ToolErrorCategory2;
|
|
99
|
+
})(ToolErrorCategory || {});
|
|
100
|
+
|
|
101
|
+
// src/types/tool-markers.ts
|
|
102
|
+
var MALFORMED_ARG_MARKERS = ["__raw", "__raw_arguments", "_raw"];
|
|
103
|
+
|
|
104
|
+
export {
|
|
105
|
+
FLEET_CHAT_VERBOSITY_VALUES,
|
|
106
|
+
resolveFleetChatVerbosity,
|
|
107
|
+
THEME_PRESET_IDS,
|
|
108
|
+
DEFAULT_SPEC_TEMPLATE,
|
|
109
|
+
ToolErrorCategory,
|
|
110
|
+
MALFORMED_ARG_MARKERS
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=chunk-OJZEX73F.js.map
|