bulkhead-runtime 0.1.0 → 2026.4.5-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/README.md +344 -262
  2. package/dist/cli.js +5 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config/index.d.ts +28 -0
  5. package/dist/config/index.d.ts.map +1 -1
  6. package/dist/config/index.js +9 -6
  7. package/dist/config/index.js.map +1 -1
  8. package/dist/credentials/store.d.ts.map +1 -1
  9. package/dist/credentials/store.js +39 -15
  10. package/dist/credentials/store.js.map +1 -1
  11. package/dist/index.d.ts +18 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +38 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/infra/warning-filter.js +1 -1
  16. package/dist/infra/warning-filter.js.map +1 -1
  17. package/dist/logging/subsystem.d.ts +15 -1
  18. package/dist/logging/subsystem.d.ts.map +1 -1
  19. package/dist/logging/subsystem.js +310 -45
  20. package/dist/logging/subsystem.js.map +1 -1
  21. package/dist/memory/embedding-batch.d.ts +38 -0
  22. package/dist/memory/embedding-batch.d.ts.map +1 -0
  23. package/dist/memory/embedding-batch.js +253 -0
  24. package/dist/memory/embedding-batch.js.map +1 -0
  25. package/dist/memory/embedding-cache.d.ts +16 -0
  26. package/dist/memory/embedding-cache.d.ts.map +1 -0
  27. package/dist/memory/embedding-cache.js +113 -0
  28. package/dist/memory/embedding-cache.js.map +1 -0
  29. package/dist/memory/embeddings-debug.js +1 -1
  30. package/dist/memory/embeddings.d.ts +1 -0
  31. package/dist/memory/embeddings.d.ts.map +1 -1
  32. package/dist/memory/embeddings.js +115 -92
  33. package/dist/memory/embeddings.js.map +1 -1
  34. package/dist/memory/file-indexer.d.ts +26 -0
  35. package/dist/memory/file-indexer.d.ts.map +1 -0
  36. package/dist/memory/file-indexer.js +258 -0
  37. package/dist/memory/file-indexer.js.map +1 -0
  38. package/dist/memory/hybrid.d.ts.map +1 -1
  39. package/dist/memory/hybrid.js +6 -2
  40. package/dist/memory/hybrid.js.map +1 -1
  41. package/dist/memory/index.d.ts +5 -0
  42. package/dist/memory/index.d.ts.map +1 -1
  43. package/dist/memory/index.js +5 -2
  44. package/dist/memory/index.js.map +1 -1
  45. package/dist/memory/session-indexer.d.ts +41 -0
  46. package/dist/memory/session-indexer.d.ts.map +1 -0
  47. package/dist/memory/session-indexer.js +367 -0
  48. package/dist/memory/session-indexer.js.map +1 -0
  49. package/dist/memory/simple-manager.d.ts +6 -0
  50. package/dist/memory/simple-manager.d.ts.map +1 -1
  51. package/dist/memory/simple-manager.js +35 -12
  52. package/dist/memory/simple-manager.js.map +1 -1
  53. package/dist/memory/ssrf.d.ts +18 -0
  54. package/dist/memory/ssrf.d.ts.map +1 -0
  55. package/dist/memory/ssrf.js +305 -0
  56. package/dist/memory/ssrf.js.map +1 -0
  57. package/dist/package.json +8 -5
  58. package/dist/platform/platform.d.ts.map +1 -1
  59. package/dist/platform/platform.js +30 -7
  60. package/dist/platform/platform.js.map +1 -1
  61. package/dist/platform/types.d.ts +2 -0
  62. package/dist/platform/types.d.ts.map +1 -1
  63. package/dist/runtime/agent.d.ts +8 -0
  64. package/dist/runtime/agent.d.ts.map +1 -1
  65. package/dist/runtime/agent.js +194 -46
  66. package/dist/runtime/agent.js.map +1 -1
  67. package/dist/runtime/api-key-rotation.d.ts +26 -0
  68. package/dist/runtime/api-key-rotation.d.ts.map +1 -0
  69. package/dist/runtime/api-key-rotation.js +174 -0
  70. package/dist/runtime/api-key-rotation.js.map +1 -0
  71. package/dist/runtime/context-guard.d.ts +32 -0
  72. package/dist/runtime/context-guard.d.ts.map +1 -0
  73. package/dist/runtime/context-guard.js +61 -0
  74. package/dist/runtime/context-guard.js.map +1 -0
  75. package/dist/runtime/failover-error.d.ts +62 -0
  76. package/dist/runtime/failover-error.d.ts.map +1 -0
  77. package/dist/runtime/failover-error.js +733 -0
  78. package/dist/runtime/failover-error.js.map +1 -0
  79. package/dist/runtime/failover-policy.d.ts +5 -0
  80. package/dist/runtime/failover-policy.d.ts.map +1 -0
  81. package/dist/runtime/failover-policy.js +18 -0
  82. package/dist/runtime/failover-policy.js.map +1 -0
  83. package/dist/runtime/index.d.ts +11 -0
  84. package/dist/runtime/index.d.ts.map +1 -1
  85. package/dist/runtime/index.js +11 -0
  86. package/dist/runtime/index.js.map +1 -1
  87. package/dist/runtime/memory-flush.d.ts +24 -0
  88. package/dist/runtime/memory-flush.d.ts.map +1 -0
  89. package/dist/runtime/memory-flush.js +64 -0
  90. package/dist/runtime/memory-flush.js.map +1 -0
  91. package/dist/runtime/memory-tools.d.ts +14 -0
  92. package/dist/runtime/memory-tools.d.ts.map +1 -0
  93. package/dist/runtime/memory-tools.js +58 -0
  94. package/dist/runtime/memory-tools.js.map +1 -0
  95. package/dist/runtime/model-fallback.d.ts +56 -0
  96. package/dist/runtime/model-fallback.d.ts.map +1 -0
  97. package/dist/runtime/model-fallback.js +301 -0
  98. package/dist/runtime/model-fallback.js.map +1 -0
  99. package/dist/runtime/model-fallback.types.d.ts +14 -0
  100. package/dist/runtime/model-fallback.types.d.ts.map +1 -0
  101. package/dist/runtime/model-fallback.types.js +3 -0
  102. package/dist/runtime/model-fallback.types.js.map +1 -0
  103. package/dist/runtime/retry.d.ts +24 -0
  104. package/dist/runtime/retry.d.ts.map +1 -0
  105. package/dist/runtime/retry.js +102 -0
  106. package/dist/runtime/retry.js.map +1 -0
  107. package/dist/runtime/session-pruning.d.ts +22 -0
  108. package/dist/runtime/session-pruning.d.ts.map +1 -0
  109. package/dist/runtime/session-pruning.js +118 -0
  110. package/dist/runtime/session-pruning.js.map +1 -0
  111. package/dist/runtime/stream-adapters.d.ts +11 -0
  112. package/dist/runtime/stream-adapters.d.ts.map +1 -0
  113. package/dist/runtime/stream-adapters.js +46 -0
  114. package/dist/runtime/stream-adapters.js.map +1 -0
  115. package/dist/runtime/subagent.d.ts +83 -0
  116. package/dist/runtime/subagent.d.ts.map +1 -0
  117. package/dist/runtime/subagent.js +190 -0
  118. package/dist/runtime/subagent.js.map +1 -0
  119. package/dist/runtime/tool-result-truncation.d.ts +25 -0
  120. package/dist/runtime/tool-result-truncation.d.ts.map +1 -0
  121. package/dist/runtime/tool-result-truncation.js +115 -0
  122. package/dist/runtime/tool-result-truncation.js.map +1 -0
  123. package/dist/sandbox/cgroup.d.ts +4 -1
  124. package/dist/sandbox/cgroup.d.ts.map +1 -1
  125. package/dist/sandbox/cgroup.js +28 -15
  126. package/dist/sandbox/cgroup.js.map +1 -1
  127. package/dist/sandbox/index.d.ts +2 -1
  128. package/dist/sandbox/index.d.ts.map +1 -1
  129. package/dist/sandbox/index.js +2 -1
  130. package/dist/sandbox/index.js.map +1 -1
  131. package/dist/sandbox/ipc.d.ts +4 -1
  132. package/dist/sandbox/ipc.d.ts.map +1 -1
  133. package/dist/sandbox/ipc.js +33 -17
  134. package/dist/sandbox/ipc.js.map +1 -1
  135. package/dist/sandbox/manager.d.ts +1 -2
  136. package/dist/sandbox/manager.d.ts.map +1 -1
  137. package/dist/sandbox/manager.js +136 -130
  138. package/dist/sandbox/manager.js.map +1 -1
  139. package/dist/sandbox/namespace.d.ts +1 -1
  140. package/dist/sandbox/namespace.d.ts.map +1 -1
  141. package/dist/sandbox/namespace.js +36 -37
  142. package/dist/sandbox/namespace.js.map +1 -1
  143. package/dist/sandbox/rootfs.d.ts +6 -1
  144. package/dist/sandbox/rootfs.d.ts.map +1 -1
  145. package/dist/sandbox/rootfs.js +114 -30
  146. package/dist/sandbox/rootfs.js.map +1 -1
  147. package/dist/sandbox/seccomp-apply.d.ts +9 -0
  148. package/dist/sandbox/seccomp-apply.d.ts.map +1 -0
  149. package/dist/sandbox/seccomp-apply.js +227 -0
  150. package/dist/sandbox/seccomp-apply.js.map +1 -0
  151. package/dist/sandbox/seccomp.js +3 -3
  152. package/dist/sandbox/seccomp.js.map +1 -1
  153. package/dist/sandbox/types.d.ts +1 -3
  154. package/dist/sandbox/types.d.ts.map +1 -1
  155. package/dist/sandbox/types.js.map +1 -1
  156. package/dist/sandbox/worker.d.ts +3 -0
  157. package/dist/sandbox/worker.d.ts.map +1 -1
  158. package/dist/sandbox/worker.js +84 -17
  159. package/dist/sandbox/worker.js.map +1 -1
  160. package/dist/sessions/index.d.ts +1 -0
  161. package/dist/sessions/index.d.ts.map +1 -1
  162. package/dist/sessions/index.js +1 -0
  163. package/dist/sessions/index.js.map +1 -1
  164. package/dist/sessions/store.d.ts +2 -2
  165. package/dist/sessions/store.d.ts.map +1 -1
  166. package/dist/sessions/store.js +49 -27
  167. package/dist/sessions/store.js.map +1 -1
  168. package/dist/sessions/transcript-events.d.ts +11 -0
  169. package/dist/sessions/transcript-events.d.ts.map +1 -0
  170. package/dist/sessions/transcript-events.js +40 -0
  171. package/dist/sessions/transcript-events.js.map +1 -0
  172. package/dist/shared/agent-session.d.ts +10 -0
  173. package/dist/shared/agent-session.d.ts.map +1 -0
  174. package/dist/shared/agent-session.js +33 -0
  175. package/dist/shared/agent-session.js.map +1 -0
  176. package/dist/shared/constants.d.ts +6 -0
  177. package/dist/shared/constants.d.ts.map +1 -0
  178. package/dist/shared/constants.js +11 -0
  179. package/dist/shared/constants.js.map +1 -0
  180. package/dist/shared/fs.d.ts +7 -0
  181. package/dist/shared/fs.d.ts.map +1 -0
  182. package/dist/shared/fs.js +14 -0
  183. package/dist/shared/fs.js.map +1 -0
  184. package/dist/shared/index.d.ts +4 -0
  185. package/dist/shared/index.d.ts.map +1 -0
  186. package/dist/shared/index.js +4 -0
  187. package/dist/shared/index.js.map +1 -0
  188. package/dist/skills/enablement.d.ts.map +1 -1
  189. package/dist/skills/enablement.js +2 -2
  190. package/dist/skills/enablement.js.map +1 -1
  191. package/dist/workspace/runner.d.ts.map +1 -1
  192. package/dist/workspace/runner.js +436 -105
  193. package/dist/workspace/runner.js.map +1 -1
  194. package/dist/workspace/types.d.ts +1 -0
  195. package/dist/workspace/types.d.ts.map +1 -1
  196. package/dist/workspace/workspace.d.ts.map +1 -1
  197. package/dist/workspace/workspace.js +12 -3
  198. package/dist/workspace/workspace.js.map +1 -1
  199. package/package.json +1 -1
@@ -0,0 +1,301 @@
1
+ // Ported from OpenClaw src/agents/model-fallback.ts
2
+ // Removed: auth profile store, cooldown probes, image model fallback, model alias index
3
+ // Kept: all fallback logic, error classification, context overflow short-circuit
4
+ import { createSubsystemLogger } from "../logging/subsystem.js";
5
+ import { FailoverError, coerceToFailoverError, describeFailoverError, isFailoverError, isTimeoutError, isLikelyContextOverflowError, } from "./failover-error.js";
6
+ const log = createSubsystemLogger("model-fallback");
7
+ // --- Cooldown tracking (adapted from OpenClaw auth-profiles/usage.ts) ---
8
+ const MIN_PROBE_INTERVAL_MS = 30_000;
9
+ const PROBE_MARGIN_MS = 2 * 60 * 1000;
10
+ const DEFAULT_COOLDOWN_MS = 60_000;
11
+ const RATE_LIMIT_COOLDOWN_MS = 30_000;
12
+ const BILLING_COOLDOWN_MS = 5 * 60_000;
13
+ const AUTH_COOLDOWN_MS = 10 * 60_000;
14
+ export function createCooldownStore() {
15
+ return {
16
+ providerCooldowns: new Map(),
17
+ lastProbeAttempt: new Map(),
18
+ };
19
+ }
20
+ const globalStore = createCooldownStore();
21
+ function resolveStore(store) {
22
+ return store ?? globalStore;
23
+ }
24
+ function cooldownKey(provider, model) {
25
+ return model ? `${provider}/${model}` : provider;
26
+ }
27
+ function getCooldownMs(reason) {
28
+ switch (reason) {
29
+ case "rate_limit":
30
+ case "overloaded": return RATE_LIMIT_COOLDOWN_MS;
31
+ case "billing": return BILLING_COOLDOWN_MS;
32
+ case "auth":
33
+ case "auth_permanent": return AUTH_COOLDOWN_MS;
34
+ default: return DEFAULT_COOLDOWN_MS;
35
+ }
36
+ }
37
+ export function recordProviderCooldown(provider, reason, model, store) {
38
+ const s = resolveStore(store);
39
+ const key = cooldownKey(provider, model);
40
+ const until = Date.now() + getCooldownMs(reason);
41
+ s.providerCooldowns.set(key, { until, reason, model });
42
+ if (reason !== "rate_limit" && reason !== "overloaded") {
43
+ s.providerCooldowns.set(cooldownKey(provider), { until, reason });
44
+ }
45
+ }
46
+ export function isProviderInCooldown(provider, model, store) {
47
+ const s = resolveStore(store);
48
+ const now = Date.now();
49
+ const providerEntry = s.providerCooldowns.get(cooldownKey(provider));
50
+ if (providerEntry && now < providerEntry.until) {
51
+ if (providerEntry.reason === "rate_limit" && model && providerEntry.model && providerEntry.model !== model) {
52
+ return false;
53
+ }
54
+ return true;
55
+ }
56
+ if (model) {
57
+ const modelEntry = s.providerCooldowns.get(cooldownKey(provider, model));
58
+ if (modelEntry && now < modelEntry.until)
59
+ return true;
60
+ }
61
+ return false;
62
+ }
63
+ export function getSoonestCooldownExpiry(candidates, store) {
64
+ const s = resolveStore(store);
65
+ let soonest = null;
66
+ for (const c of candidates) {
67
+ const entry = s.providerCooldowns.get(cooldownKey(c.provider, c.model))
68
+ ?? s.providerCooldowns.get(cooldownKey(c.provider));
69
+ if (!entry)
70
+ continue;
71
+ if (soonest === null || entry.until < soonest)
72
+ soonest = entry.until;
73
+ }
74
+ return soonest;
75
+ }
76
+ function shouldProbe(provider, store) {
77
+ const now = Date.now();
78
+ const last = store.lastProbeAttempt.get(provider) ?? 0;
79
+ if (now - last < MIN_PROBE_INTERVAL_MS)
80
+ return false;
81
+ const entry = store.providerCooldowns.get(cooldownKey(provider));
82
+ if (!entry)
83
+ return true;
84
+ return now >= entry.until - PROBE_MARGIN_MS;
85
+ }
86
+ function markProbe(provider, store) {
87
+ store.lastProbeAttempt.set(provider, Date.now());
88
+ }
89
+ export function clearCooldowns(store) {
90
+ const s = resolveStore(store);
91
+ s.providerCooldowns.clear();
92
+ s.lastProbeAttempt.clear();
93
+ }
94
+ // --- LiveSessionModelSwitchError (from OpenClaw live-model-switch.ts) ---
95
+ export class LiveSessionModelSwitchError extends Error {
96
+ provider;
97
+ model;
98
+ constructor(provider, model) {
99
+ super(`Live session model switch requested: ${provider}/${model}`);
100
+ this.name = "LiveSessionModelSwitchError";
101
+ this.provider = provider;
102
+ this.model = model;
103
+ }
104
+ }
105
+ export class FallbackSummaryError extends Error {
106
+ attempts;
107
+ soonestCooldownExpiry;
108
+ constructor(message, attempts, soonestCooldownExpiry, cause) {
109
+ super(message, { cause });
110
+ this.name = "FallbackSummaryError";
111
+ this.attempts = attempts;
112
+ this.soonestCooldownExpiry = soonestCooldownExpiry;
113
+ }
114
+ }
115
+ export function isFallbackSummaryError(err) {
116
+ return err instanceof FallbackSummaryError;
117
+ }
118
+ function isFallbackAbortError(err) {
119
+ if (!err || typeof err !== "object")
120
+ return false;
121
+ if (isFailoverError(err))
122
+ return false;
123
+ const name = "name" in err ? String(err.name) : "";
124
+ return name === "AbortError";
125
+ }
126
+ function shouldRethrowAbort(err) {
127
+ return isFallbackAbortError(err) && !isTimeoutError(err);
128
+ }
129
+ function modelKey(provider, model) {
130
+ return `${provider}/${model}`;
131
+ }
132
+ function normalizeModelRef(provider, model) {
133
+ return { provider: provider.trim(), model: model.trim() };
134
+ }
135
+ export function parseFallbackRef(raw, defaultProvider) {
136
+ const parts = raw.split("/");
137
+ if (parts.length >= 2) {
138
+ return { provider: parts[0], model: parts.slice(1).join("/") };
139
+ }
140
+ return { provider: defaultProvider, model: raw };
141
+ }
142
+ export function resolveFallbackCandidates(provider, model, fallbacks) {
143
+ const seen = new Set();
144
+ const candidates = [];
145
+ const addCandidate = (candidate) => {
146
+ if (!candidate.provider || !candidate.model)
147
+ return;
148
+ const key = modelKey(candidate.provider, candidate.model);
149
+ if (seen.has(key))
150
+ return;
151
+ seen.add(key);
152
+ candidates.push(candidate);
153
+ };
154
+ addCandidate(normalizeModelRef(provider, model));
155
+ for (const raw of fallbacks ?? []) {
156
+ const trimmed = String(raw ?? "").trim();
157
+ if (!trimmed)
158
+ continue;
159
+ addCandidate(parseFallbackRef(trimmed, provider));
160
+ }
161
+ return candidates;
162
+ }
163
+ async function runFallbackCandidate(params) {
164
+ try {
165
+ const result = params.options
166
+ ? await params.run(params.provider, params.model, params.options)
167
+ : await params.run(params.provider, params.model);
168
+ return { ok: true, result };
169
+ }
170
+ catch (err) {
171
+ const normalizedFailover = coerceToFailoverError(err, {
172
+ provider: params.provider,
173
+ model: params.model,
174
+ });
175
+ if (shouldRethrowAbort(err) && !normalizedFailover)
176
+ throw err;
177
+ return { ok: false, error: normalizedFailover ?? err };
178
+ }
179
+ }
180
+ function throwFallbackFailureSummary(params) {
181
+ if (params.attempts.length <= 1 && params.lastError)
182
+ throw params.lastError;
183
+ const summary = params.attempts.length > 0 ? params.attempts.map(params.formatAttempt).join(" | ") : "unknown";
184
+ throw new FallbackSummaryError(`All ${params.label} failed (${params.attempts.length || params.candidates.length}): ${summary}`, params.attempts, params.soonestCooldownExpiry ?? null, params.lastError instanceof Error ? params.lastError : undefined);
185
+ }
186
+ export async function runWithModelFallback(params) {
187
+ const store = resolveStore(params.cooldownStore);
188
+ const candidates = resolveFallbackCandidates(params.provider, params.model, params.fallbacks);
189
+ const hasFallbackCandidates = candidates.length > 1;
190
+ const attempts = [];
191
+ let lastError;
192
+ for (let i = 0; i < candidates.length; i += 1) {
193
+ const candidate = candidates[i];
194
+ const isPrimary = i === 0;
195
+ if (isProviderInCooldown(candidate.provider, candidate.model, store)) {
196
+ const isProbable = isPrimary && hasFallbackCandidates && shouldProbe(candidate.provider, store);
197
+ if (!isProbable) {
198
+ const entry = store.providerCooldowns.get(cooldownKey(candidate.provider, candidate.model))
199
+ ?? store.providerCooldowns.get(cooldownKey(candidate.provider));
200
+ const reason = entry?.reason ?? "unknown";
201
+ if (reason === "auth" || reason === "auth_permanent" || reason === "billing") {
202
+ attempts.push({
203
+ provider: candidate.provider,
204
+ model: candidate.model,
205
+ error: `Provider ${candidate.provider} has ${reason} issue (skipping)`,
206
+ reason,
207
+ });
208
+ log.debug(`skipping ${candidate.provider}/${candidate.model}: ${reason} cooldown`);
209
+ continue;
210
+ }
211
+ attempts.push({
212
+ provider: candidate.provider,
213
+ model: candidate.model,
214
+ error: `Provider ${candidate.provider} is in cooldown`,
215
+ reason,
216
+ });
217
+ log.debug(`skipping ${candidate.provider}/${candidate.model}: cooldown`);
218
+ continue;
219
+ }
220
+ markProbe(candidate.provider, store);
221
+ log.debug(`probing ${candidate.provider}/${candidate.model} despite cooldown`);
222
+ }
223
+ const runResult = await runFallbackCandidate({
224
+ run: params.run,
225
+ ...candidate,
226
+ });
227
+ if (runResult.ok) {
228
+ if (i > 0 || attempts.length > 0) {
229
+ log.info(`fallback succeeded: ${candidate.provider}/${candidate.model} after ${i} failures`);
230
+ }
231
+ return {
232
+ result: runResult.result,
233
+ provider: candidate.provider,
234
+ model: candidate.model,
235
+ attempts,
236
+ };
237
+ }
238
+ const err = runResult.error;
239
+ // Context overflow: throw immediately, do not try fallback models
240
+ const errMessage = err instanceof Error ? err.message : String(err);
241
+ if (isLikelyContextOverflowError(errMessage))
242
+ throw err;
243
+ // LiveSessionModelSwitchError: wrap as overloaded to continue chain
244
+ if (err instanceof LiveSessionModelSwitchError) {
245
+ const switchNormalized = new FailoverError(errMessage, {
246
+ reason: "overloaded",
247
+ provider: candidate.provider,
248
+ model: candidate.model,
249
+ });
250
+ lastError = switchNormalized;
251
+ const described = describeFailoverError(switchNormalized);
252
+ attempts.push({
253
+ provider: candidate.provider,
254
+ model: candidate.model,
255
+ error: described.message,
256
+ reason: described.reason ?? "unknown",
257
+ status: described.status,
258
+ code: described.code,
259
+ });
260
+ continue;
261
+ }
262
+ const normalized = coerceToFailoverError(err, {
263
+ provider: candidate.provider,
264
+ model: candidate.model,
265
+ }) ?? err;
266
+ const isKnownFailover = isFailoverError(normalized);
267
+ if (!isKnownFailover && i === candidates.length - 1)
268
+ throw err;
269
+ lastError = isKnownFailover ? normalized : err;
270
+ const described = describeFailoverError(normalized);
271
+ if (described.reason && described.reason !== "format" && described.reason !== "unknown") {
272
+ recordProviderCooldown(candidate.provider, described.reason, candidate.model, store);
273
+ }
274
+ attempts.push({
275
+ provider: candidate.provider,
276
+ model: candidate.model,
277
+ error: described.message,
278
+ reason: described.reason ?? "unknown",
279
+ status: described.status,
280
+ code: described.code,
281
+ });
282
+ log.warn(`${candidate.provider}/${candidate.model} failed: ${described.message}` +
283
+ (described.reason ? ` (${described.reason})` : ""));
284
+ await params.onError?.({
285
+ provider: candidate.provider,
286
+ model: candidate.model,
287
+ error: isKnownFailover ? normalized : err,
288
+ attempt: i + 1,
289
+ total: candidates.length,
290
+ });
291
+ }
292
+ throwFallbackFailureSummary({
293
+ attempts,
294
+ candidates,
295
+ lastError,
296
+ label: "models",
297
+ formatAttempt: (attempt) => `${attempt.provider}/${attempt.model}: ${attempt.error}${attempt.reason ? ` (${attempt.reason})` : ""}`,
298
+ soonestCooldownExpiry: getSoonestCooldownExpiry(candidates, store),
299
+ });
300
+ }
301
+ //# sourceMappingURL=model-fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-fallback.js","sourceRoot":"","sources":["../../src/runtime/model-fallback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { FailoverReason } from "./failover-error.js";
2
+ export type ModelCandidate = {
3
+ provider: string;
4
+ model: string;
5
+ };
6
+ export type FallbackAttempt = {
7
+ provider: string;
8
+ model: string;
9
+ error: string;
10
+ reason?: FailoverReason;
11
+ status?: number;
12
+ code?: string;
13
+ };
14
+ //# sourceMappingURL=model-fallback.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-fallback.types.d.ts","sourceRoot":"","sources":["../../src/runtime/model-fallback.types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC"}
@@ -0,0 +1,3 @@
1
+ // Ported verbatim from OpenClaw src/agents/model-fallback.types.ts
2
+ export {};
3
+ //# sourceMappingURL=model-fallback.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-fallback.types.js","sourceRoot":"","sources":["../../src/runtime/model-fallback.types.ts"],"names":[],"mappings":"AAAA,mEAAmE"}
@@ -0,0 +1,24 @@
1
+ export type RetryConfig = {
2
+ attempts?: number;
3
+ minDelayMs?: number;
4
+ maxDelayMs?: number;
5
+ jitter?: number;
6
+ };
7
+ export type RetryInfo = {
8
+ attempt: number;
9
+ maxAttempts: number;
10
+ delayMs: number;
11
+ err: unknown;
12
+ label?: string;
13
+ };
14
+ export type RetryOptions = RetryConfig & {
15
+ label?: string;
16
+ shouldRetry?: (err: unknown, attempt: number) => boolean;
17
+ retryAfterMs?: (err: unknown) => number | undefined;
18
+ onRetry?: (info: RetryInfo) => void;
19
+ };
20
+ export declare function resolveRetryConfig(defaults?: Required<RetryConfig>, overrides?: RetryConfig): Required<RetryConfig>;
21
+ export declare function retryAsync<T>(fn: () => Promise<T>, attemptsOrOptions?: number | RetryOptions, initialDelayMs?: number): Promise<T>;
22
+ export declare function isRetryableError(message: string): boolean;
23
+ export declare function isContextOverflowError(message: string): boolean;
24
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/runtime/retry.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACzD,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CACrC,CAAC;AA6BF,wBAAgB,kBAAkB,CAChC,QAAQ,GAAE,QAAQ,CAAC,WAAW,CAAwB,EACtD,SAAS,CAAC,EAAE,WAAW,GACtB,QAAQ,CAAC,WAAW,CAAC,CAMvB;AAQD,wBAAsB,UAAU,CAAC,CAAC,EAChC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,iBAAiB,GAAE,MAAM,GAAG,YAAgB,EAC5C,cAAc,SAAM,GACnB,OAAO,CAAC,CAAC,CAAC,CAyDZ;AAGD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE/D"}
@@ -0,0 +1,102 @@
1
+ // Ported from OpenClaw src/infra/retry.ts
2
+ // Identical logic: resolveRetryConfig, retryAfterMs, dual overload, jitter
3
+ import * as crypto from "node:crypto";
4
+ const DEFAULT_RETRY_CONFIG = {
5
+ attempts: 3,
6
+ minDelayMs: 300,
7
+ maxDelayMs: 30_000,
8
+ jitter: 0,
9
+ };
10
+ function generateSecureFraction() {
11
+ const buf = crypto.randomBytes(4);
12
+ return buf.readUInt32BE(0) / 0xffffffff;
13
+ }
14
+ function sleep(ms) {
15
+ return new Promise((r) => setTimeout(r, ms));
16
+ }
17
+ const asFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
18
+ const clampNumber = (value, fallback, min, max) => {
19
+ const next = asFiniteNumber(value);
20
+ if (next === undefined)
21
+ return fallback;
22
+ const floor = typeof min === "number" ? min : Number.NEGATIVE_INFINITY;
23
+ const ceiling = typeof max === "number" ? max : Number.POSITIVE_INFINITY;
24
+ return Math.min(Math.max(next, floor), ceiling);
25
+ };
26
+ export function resolveRetryConfig(defaults = DEFAULT_RETRY_CONFIG, overrides) {
27
+ const attempts = Math.max(1, Math.round(clampNumber(overrides?.attempts, defaults.attempts, 1)));
28
+ const minDelayMs = Math.max(0, Math.round(clampNumber(overrides?.minDelayMs, defaults.minDelayMs, 0)));
29
+ const maxDelayMs = Math.max(minDelayMs, Math.round(clampNumber(overrides?.maxDelayMs, defaults.maxDelayMs, 0)));
30
+ const jitter = clampNumber(overrides?.jitter, defaults.jitter, 0, 1);
31
+ return { attempts, minDelayMs, maxDelayMs, jitter };
32
+ }
33
+ function applyJitter(delayMs, jitter) {
34
+ if (jitter <= 0)
35
+ return delayMs;
36
+ const offset = (generateSecureFraction() * 2 - 1) * jitter;
37
+ return Math.max(0, Math.round(delayMs * (1 + offset)));
38
+ }
39
+ export async function retryAsync(fn, attemptsOrOptions = 3, initialDelayMs = 300) {
40
+ if (typeof attemptsOrOptions === "number") {
41
+ const attempts = Math.max(1, Math.round(attemptsOrOptions));
42
+ let lastErr;
43
+ for (let i = 0; i < attempts; i += 1) {
44
+ try {
45
+ return await fn();
46
+ }
47
+ catch (err) {
48
+ lastErr = err;
49
+ if (i === attempts - 1)
50
+ break;
51
+ const delay = initialDelayMs * 2 ** i;
52
+ await sleep(delay);
53
+ }
54
+ }
55
+ throw lastErr ?? new Error("Retry failed");
56
+ }
57
+ const options = attemptsOrOptions;
58
+ const resolved = resolveRetryConfig(DEFAULT_RETRY_CONFIG, options);
59
+ const maxAttempts = resolved.attempts;
60
+ const minDelayMs = resolved.minDelayMs;
61
+ const maxDelayMs = Number.isFinite(resolved.maxDelayMs) && resolved.maxDelayMs > 0
62
+ ? resolved.maxDelayMs
63
+ : Number.POSITIVE_INFINITY;
64
+ const jitter = resolved.jitter;
65
+ const shouldRetry = options.shouldRetry ?? (() => true);
66
+ let lastErr;
67
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
68
+ try {
69
+ return await fn();
70
+ }
71
+ catch (err) {
72
+ lastErr = err;
73
+ if (attempt >= maxAttempts || !shouldRetry(err, attempt))
74
+ break;
75
+ const retryAfterMs = options.retryAfterMs?.(err);
76
+ const hasRetryAfter = typeof retryAfterMs === "number" && Number.isFinite(retryAfterMs);
77
+ const baseDelay = hasRetryAfter
78
+ ? Math.max(retryAfterMs, minDelayMs)
79
+ : minDelayMs * 2 ** (attempt - 1);
80
+ let delay = Math.min(baseDelay, maxDelayMs);
81
+ delay = applyJitter(delay, jitter);
82
+ delay = Math.min(Math.max(delay, minDelayMs), maxDelayMs);
83
+ options.onRetry?.({
84
+ attempt,
85
+ maxAttempts,
86
+ delayMs: delay,
87
+ err,
88
+ label: options.label,
89
+ });
90
+ await sleep(delay);
91
+ }
92
+ }
93
+ throw lastErr ?? new Error("Retry failed");
94
+ }
95
+ // Re-export convenience matchers used by other modules
96
+ export function isRetryableError(message) {
97
+ return /(rate[_ ]limit|too many requests|429|resource has been exhausted|5\d\d|timeout|econnreset|socket hang up|fetch failed)/i.test(message);
98
+ }
99
+ export function isContextOverflowError(message) {
100
+ return /(context.*(length|window|limit|overflow|too long|exceed)|max.*tokens|token.*limit|maximum.*context)/i.test(message);
101
+ }
102
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/runtime/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface SessionPruningOptions {
2
+ contextWindowTokens: number;
3
+ softTrimRatio?: number;
4
+ hardClearRatio?: number;
5
+ }
6
+ export interface PruneResult {
7
+ pruned: boolean;
8
+ softTrimmed: number;
9
+ hardCleared: number;
10
+ originalTokens: number;
11
+ prunedTokens: number;
12
+ }
13
+ interface AgentMessage {
14
+ role: string;
15
+ content?: unknown;
16
+ }
17
+ export declare function pruneContextMessages(messages: AgentMessage[], options: SessionPruningOptions): {
18
+ messages: AgentMessage[];
19
+ result: PruneResult;
20
+ };
21
+ export {};
22
+ //# sourceMappingURL=session-pruning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-pruning.d.ts","sourceRoot":"","sources":["../../src/runtime/session-pruning.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,qBAAqB;IACpC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAiDD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,qBAAqB,GAC7B;IAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,CAiEnD"}
@@ -0,0 +1,118 @@
1
+ // Ported from OpenClaw src/agents/pi-hooks/context-pruning/pruner.ts
2
+ // Trims old tool results in-memory before sending to the model.
3
+ // Soft-trim: head+tail truncation. Hard-clear: replace with placeholder.
4
+ import { createSubsystemLogger } from "../logging/subsystem.js";
5
+ const log = createSubsystemLogger("session-pruning");
6
+ const CHARS_PER_TOKEN = 4;
7
+ const DEFAULT_SOFT_TRIM_RATIO = 0.7;
8
+ const DEFAULT_HARD_CLEAR_RATIO = 0.85;
9
+ const MIN_RESULT_CHARS_TO_PRUNE = 2000;
10
+ const TRUNCATION_MARKER = "\n\n[… content trimmed to fit context window …]\n";
11
+ const CLEAR_PLACEHOLDER = "[tool output cleared to fit context window]";
12
+ const HEAD_RATIO = 0.3;
13
+ const TAIL_RATIO = 0.7;
14
+ function estimateMessageTokens(msg) {
15
+ if (!msg.content)
16
+ return 4;
17
+ if (typeof msg.content === "string")
18
+ return Math.ceil(msg.content.length / CHARS_PER_TOKEN) + 4;
19
+ if (Array.isArray(msg.content)) {
20
+ let total = 4;
21
+ for (const block of msg.content) {
22
+ if (block.type === "text" && typeof block.text === "string") {
23
+ total += Math.ceil(block.text.length / CHARS_PER_TOKEN);
24
+ }
25
+ else if (block.type === "tool_result" && typeof block.content === "string") {
26
+ total += Math.ceil(block.content.length / CHARS_PER_TOKEN);
27
+ }
28
+ else {
29
+ total += 50;
30
+ }
31
+ }
32
+ return total;
33
+ }
34
+ return Math.ceil(JSON.stringify(msg.content).length / CHARS_PER_TOKEN) + 4;
35
+ }
36
+ function estimateTotalTokens(messages) {
37
+ let total = 0;
38
+ for (const msg of messages)
39
+ total += estimateMessageTokens(msg);
40
+ return total;
41
+ }
42
+ function isToolResultBlock(block) {
43
+ return block.type === "tool_result" || block.type === "tool_use_result";
44
+ }
45
+ function getToolResultText(block) {
46
+ if (typeof block.content === "string")
47
+ return block.content;
48
+ if (Array.isArray(block.content)) {
49
+ const textParts = block.content
50
+ .filter((p) => p.type === "text" && typeof p.text === "string")
51
+ .map((p) => p.text);
52
+ return textParts.length > 0 ? textParts.join("\n") : null;
53
+ }
54
+ return null;
55
+ }
56
+ function truncateText(text, maxChars) {
57
+ if (text.length <= maxChars)
58
+ return text;
59
+ const headChars = Math.floor(maxChars * HEAD_RATIO);
60
+ const tailChars = Math.floor(maxChars * TAIL_RATIO);
61
+ return text.slice(0, headChars) + TRUNCATION_MARKER + text.slice(-tailChars);
62
+ }
63
+ export function pruneContextMessages(messages, options) {
64
+ const { contextWindowTokens } = options;
65
+ const softTrimRatio = options.softTrimRatio ?? DEFAULT_SOFT_TRIM_RATIO;
66
+ const hardClearRatio = options.hardClearRatio ?? DEFAULT_HARD_CLEAR_RATIO;
67
+ const originalTokens = estimateTotalTokens(messages);
68
+ const softThreshold = contextWindowTokens * softTrimRatio;
69
+ const hardThreshold = contextWindowTokens * hardClearRatio;
70
+ if (originalTokens <= softThreshold) {
71
+ return {
72
+ messages,
73
+ result: { pruned: false, softTrimmed: 0, hardCleared: 0, originalTokens, prunedTokens: originalTokens },
74
+ };
75
+ }
76
+ let softTrimmed = 0;
77
+ let hardCleared = 0;
78
+ const recentBoundary = Math.max(0, messages.length - 6);
79
+ const prunedMessages = [];
80
+ for (let msgIdx = 0; msgIdx < messages.length; msgIdx++) {
81
+ const msg = messages[msgIdx];
82
+ if (msg.role === "system" || msg.role === "user" || msgIdx >= recentBoundary || !Array.isArray(msg.content)) {
83
+ prunedMessages.push(msg);
84
+ continue;
85
+ }
86
+ const needsHardClear = originalTokens > hardThreshold;
87
+ const newContent = msg.content.map((block) => {
88
+ if (!isToolResultBlock(block))
89
+ return block;
90
+ const text = getToolResultText(block);
91
+ if (!text || text.length < MIN_RESULT_CHARS_TO_PRUNE)
92
+ return block;
93
+ if (needsHardClear) {
94
+ hardCleared++;
95
+ return { ...block, content: CLEAR_PLACEHOLDER };
96
+ }
97
+ const maxChars = Math.max(500, Math.floor(text.length * 0.3));
98
+ softTrimmed++;
99
+ return { ...block, content: truncateText(text, maxChars) };
100
+ });
101
+ prunedMessages.push({ ...msg, content: newContent });
102
+ }
103
+ const prunedTokens = estimateTotalTokens(prunedMessages);
104
+ if (softTrimmed > 0 || hardCleared > 0) {
105
+ log.info("pruned context messages", {
106
+ originalTokens,
107
+ prunedTokens,
108
+ softTrimmed,
109
+ hardCleared,
110
+ saved: originalTokens - prunedTokens,
111
+ });
112
+ }
113
+ return {
114
+ messages: prunedMessages,
115
+ result: { pruned: softTrimmed > 0 || hardCleared > 0, softTrimmed, hardCleared, originalTokens, prunedTokens },
116
+ };
117
+ }
118
+ //# sourceMappingURL=session-pruning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-pruning.js","sourceRoot":"","sources":["../../src/runtime/session-pruning.ts"],"names":[],"mappings":"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"}