@albinocrabs/o-switcher 0.1.0 → 0.2.0
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/CHANGELOG.md +27 -0
- package/LICENSE +199 -21
- package/README.md +88 -288
- package/dist/{chunk-BTDKGS7P.js → chunk-7ITX5623.js} +122 -237
- package/dist/chunk-TJ7ZGZHD.cjs +1736 -0
- package/dist/index.cjs +567 -1976
- package/dist/index.js +281 -225
- package/dist/plugin.cjs +111 -1024
- package/dist/plugin.d.cts +1 -1
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.js +100 -35
- package/package.json +56 -14
- package/src/registry/types.ts +65 -0
- package/src/state-bridge.ts +119 -0
- package/src/tui.tsx +214 -0
- package/CONTRIBUTING.md +0 -72
- package/dist/chunk-BTDKGS7P.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/plugin.cjs.map +0 -1
- package/dist/plugin.js.map +0 -1
- package/docs/api-reference.md +0 -286
- package/docs/architecture.md +0 -511
- package/docs/examples.md +0 -190
- package/docs/getting-started.md +0 -316
- package/scripts/collect-errors.ts +0 -159
- package/scripts/corpus.jsonl +0 -5
package/dist/index.js
CHANGED
|
@@ -1,72 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
ConfigValidationError,
|
|
5
|
-
DEFAULT_ALPHA,
|
|
6
|
-
DEFAULT_BACKOFF_BASE_MS,
|
|
7
|
-
DEFAULT_BACKOFF_JITTER,
|
|
8
|
-
DEFAULT_BACKOFF_MAX_MS,
|
|
9
|
-
DEFAULT_BACKOFF_MULTIPLIER,
|
|
10
|
-
DEFAULT_BACKOFF_PARAMS,
|
|
11
|
-
DEFAULT_FAILOVER_BUDGET,
|
|
12
|
-
DEFAULT_RETRY,
|
|
13
|
-
DEFAULT_RETRY_BUDGET,
|
|
14
|
-
DEFAULT_TIMEOUT_MS,
|
|
15
|
-
DualBreaker,
|
|
16
|
-
EXCLUSION_REASONS,
|
|
17
|
-
ErrorClassSchema,
|
|
18
|
-
INITIAL_HEALTH_SCORE,
|
|
19
|
-
REDACT_PATHS,
|
|
20
|
-
SwitcherConfigSchema,
|
|
21
|
-
TARGET_STATES,
|
|
22
|
-
TargetConfigSchema,
|
|
23
|
-
TargetRegistry,
|
|
24
|
-
addProfile,
|
|
25
|
-
applyConfigDiff,
|
|
26
|
-
checkHardRejects,
|
|
27
|
-
computeBackoffMs,
|
|
28
|
-
computeConfigDiff,
|
|
29
|
-
computeCooldownMs,
|
|
30
|
-
computeScore,
|
|
31
|
-
createAdmissionController,
|
|
32
|
-
createAuditLogger,
|
|
33
|
-
createAuthWatcher,
|
|
34
|
-
createCircuitBreaker,
|
|
35
|
-
createConcurrencyTracker,
|
|
36
|
-
createCooldownManager,
|
|
37
|
-
createFailoverOrchestrator,
|
|
38
|
-
createLogSubscriber,
|
|
39
|
-
createOperatorTools,
|
|
40
|
-
createProfileTools,
|
|
41
|
-
createRegistry,
|
|
42
|
-
createRequestLogger,
|
|
43
|
-
createRequestTraceBuffer,
|
|
44
|
-
createRetryPolicy,
|
|
45
|
-
createRoutingEventBus,
|
|
46
|
-
disableTarget,
|
|
47
|
-
discoverTargets,
|
|
48
|
-
discoverTargetsFromProfiles,
|
|
49
|
-
drainTarget,
|
|
50
|
-
generateCorrelationId,
|
|
51
|
-
getExclusionReason,
|
|
52
|
-
getTargetStateTransition,
|
|
53
|
-
inspectRequest,
|
|
54
|
-
isRetryable,
|
|
55
|
-
listProfiles,
|
|
56
|
-
listTargets,
|
|
57
|
-
loadProfiles,
|
|
58
|
-
nextProfileId,
|
|
59
|
-
normalizeLatency,
|
|
60
|
-
pauseTarget,
|
|
61
|
-
reloadConfig,
|
|
62
|
-
removeProfile,
|
|
63
|
-
resumeTarget,
|
|
64
|
-
saveProfiles,
|
|
65
|
-
selectTarget,
|
|
66
|
-
updateHealthScore,
|
|
67
|
-
updateLatencyEma,
|
|
68
|
-
validateConfig
|
|
69
|
-
} from "./chunk-BTDKGS7P.js";
|
|
1
|
+
import { createRequestLogger, generateCorrelationId } from './chunk-7ITX5623.js';
|
|
2
|
+
export { ADMISSION_RESULTS, BackoffConfigSchema, ConfigValidationError, DEFAULT_ALPHA, DEFAULT_BACKOFF_BASE_MS, DEFAULT_BACKOFF_JITTER, DEFAULT_BACKOFF_MAX_MS, DEFAULT_BACKOFF_MULTIPLIER, DEFAULT_BACKOFF_PARAMS, DEFAULT_FAILOVER_BUDGET, DEFAULT_RETRY, DEFAULT_RETRY_BUDGET, DEFAULT_TIMEOUT_MS, DualBreaker, EXCLUSION_REASONS, ErrorClassSchema, INITIAL_HEALTH_SCORE, REDACT_PATHS, SwitcherConfigSchema, TARGET_STATES, TargetConfigSchema, TargetRegistry, addProfile, applyConfigDiff, checkHardRejects, computeBackoffMs, computeConfigDiff, computeCooldownMs, computeScore, createAdmissionController, createAuditLogger, createAuthWatcher, createCircuitBreaker, createConcurrencyTracker, createCooldownManager, createFailoverOrchestrator, createLogSubscriber, createOperatorTools, createProfileTools, createRegistry, createRequestLogger, createRequestTraceBuffer, createRetryPolicy, createRoutingEventBus, disableTarget, discoverTargets, discoverTargetsFromProfiles, drainTarget, generateCorrelationId, getExclusionReason, getTargetStateTransition, inspectRequest, isRetryable, listProfiles, listTargets, loadProfiles, nextProfileId, normalizeLatency, pauseTarget, reloadConfig, removeProfile, resumeTarget, saveProfiles, selectTarget, updateHealthScore, updateLatencyEma, validateConfig } from './chunk-7ITX5623.js';
|
|
3
|
+
import { timingSafeEqual } from 'crypto';
|
|
70
4
|
|
|
71
5
|
// src/mode/detection.ts
|
|
72
6
|
var detectDeploymentMode = (hint) => {
|
|
@@ -103,51 +37,245 @@ var getModeCapabilities = (mode) => {
|
|
|
103
37
|
// src/errors/corpus.ts
|
|
104
38
|
var PROVIDER_PATTERNS = [
|
|
105
39
|
// Anthropic
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
{
|
|
114
|
-
|
|
40
|
+
{
|
|
41
|
+
provider: "anthropic",
|
|
42
|
+
http_status: 400,
|
|
43
|
+
error_type_field: "error.type",
|
|
44
|
+
error_type_value: "invalid_request_error",
|
|
45
|
+
error_class: "PolicyFailure"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
provider: "anthropic",
|
|
49
|
+
http_status: 401,
|
|
50
|
+
error_type_field: "error.type",
|
|
51
|
+
error_type_value: "authentication_error",
|
|
52
|
+
error_class: "AuthFailure"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
provider: "anthropic",
|
|
56
|
+
http_status: 402,
|
|
57
|
+
error_type_field: "error.type",
|
|
58
|
+
error_type_value: "billing_error",
|
|
59
|
+
error_class: "QuotaExhausted"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
provider: "anthropic",
|
|
63
|
+
http_status: 403,
|
|
64
|
+
error_type_field: "error.type",
|
|
65
|
+
error_type_value: "permission_error",
|
|
66
|
+
error_class: "PermissionFailure"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
provider: "anthropic",
|
|
70
|
+
http_status: 404,
|
|
71
|
+
error_type_field: "error.type",
|
|
72
|
+
error_type_value: "not_found_error",
|
|
73
|
+
error_class: "ModelUnavailable"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
provider: "anthropic",
|
|
77
|
+
http_status: 429,
|
|
78
|
+
error_type_field: "error.type",
|
|
79
|
+
error_type_value: "rate_limit_error",
|
|
80
|
+
error_class: "RateLimited"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
provider: "anthropic",
|
|
84
|
+
http_status: 500,
|
|
85
|
+
error_type_field: "error.type",
|
|
86
|
+
error_type_value: "api_error",
|
|
87
|
+
error_class: "TransientServerFailure"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
provider: "anthropic",
|
|
91
|
+
http_status: 504,
|
|
92
|
+
error_type_field: "error.type",
|
|
93
|
+
error_type_value: "timeout_error",
|
|
94
|
+
error_class: "TransportFailure"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
provider: "anthropic",
|
|
98
|
+
http_status: 529,
|
|
99
|
+
error_type_field: "error.type",
|
|
100
|
+
error_type_value: "overloaded_error",
|
|
101
|
+
error_class: "RateLimited",
|
|
102
|
+
notes: "Server capacity exhaustion; backoff on same provider, do NOT failover"
|
|
103
|
+
},
|
|
115
104
|
// OpenAI
|
|
116
|
-
{
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
{
|
|
105
|
+
{
|
|
106
|
+
provider: "openai",
|
|
107
|
+
http_status: 400,
|
|
108
|
+
error_type_field: "error.code",
|
|
109
|
+
error_type_value: "",
|
|
110
|
+
error_class: "PolicyFailure"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
provider: "openai",
|
|
114
|
+
http_status: 401,
|
|
115
|
+
error_type_field: "error.code",
|
|
116
|
+
error_type_value: "invalid_api_key",
|
|
117
|
+
error_class: "AuthFailure"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
provider: "openai",
|
|
121
|
+
http_status: 403,
|
|
122
|
+
error_type_field: "error.code",
|
|
123
|
+
error_type_value: "unsupported_country_region_territory",
|
|
124
|
+
error_class: "RegionRestriction",
|
|
125
|
+
notes: "GeoIP block \u2014 collected 2026-04-11 from real API"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
provider: "openai",
|
|
129
|
+
http_status: 403,
|
|
130
|
+
error_type_field: "error.code",
|
|
131
|
+
error_type_value: "",
|
|
132
|
+
error_class: "PermissionFailure"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
provider: "openai",
|
|
136
|
+
http_status: 429,
|
|
137
|
+
error_type_field: "error.code",
|
|
138
|
+
error_type_value: "rate_limit_exceeded",
|
|
139
|
+
error_class: "RateLimited"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
provider: "openai",
|
|
143
|
+
http_status: 429,
|
|
144
|
+
error_type_field: "error.code",
|
|
145
|
+
error_type_value: "insufficient_quota",
|
|
146
|
+
error_class: "QuotaExhausted",
|
|
147
|
+
notes: "Billing exhausted -- NOT retryable"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
provider: "openai",
|
|
151
|
+
http_status: 500,
|
|
152
|
+
error_type_field: "error.code",
|
|
153
|
+
error_type_value: "",
|
|
154
|
+
error_class: "TransientServerFailure"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
provider: "openai",
|
|
158
|
+
http_status: 503,
|
|
159
|
+
error_type_field: "error.code",
|
|
160
|
+
error_type_value: "",
|
|
161
|
+
error_class: "TransientServerFailure"
|
|
162
|
+
},
|
|
124
163
|
// Google Vertex AI / Gemini
|
|
125
|
-
{
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
164
|
+
{
|
|
165
|
+
provider: "google",
|
|
166
|
+
http_status: 400,
|
|
167
|
+
error_type_field: "error.status",
|
|
168
|
+
error_type_value: "INVALID_ARGUMENT",
|
|
169
|
+
error_class: "PolicyFailure"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
provider: "google",
|
|
173
|
+
http_status: 403,
|
|
174
|
+
error_type_field: "error.status",
|
|
175
|
+
error_type_value: "PERMISSION_DENIED",
|
|
176
|
+
error_class: "PermissionFailure"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
provider: "google",
|
|
180
|
+
http_status: 429,
|
|
181
|
+
error_type_field: "error.status",
|
|
182
|
+
error_type_value: "RESOURCE_EXHAUSTED",
|
|
183
|
+
error_class: "RateLimited"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
provider: "google",
|
|
187
|
+
http_status: 500,
|
|
188
|
+
error_type_field: "error.status",
|
|
189
|
+
error_type_value: "INTERNAL",
|
|
190
|
+
error_class: "TransientServerFailure"
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
provider: "google",
|
|
194
|
+
http_status: 503,
|
|
195
|
+
error_type_field: "error.status",
|
|
196
|
+
error_type_value: "UNAVAILABLE",
|
|
197
|
+
error_class: "TransientServerFailure"
|
|
198
|
+
},
|
|
130
199
|
// AWS Bedrock
|
|
131
|
-
{
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
200
|
+
{
|
|
201
|
+
provider: "bedrock",
|
|
202
|
+
http_status: 429,
|
|
203
|
+
error_type_field: "__type",
|
|
204
|
+
error_type_value: "ThrottlingException",
|
|
205
|
+
error_class: "RateLimited"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
provider: "bedrock",
|
|
209
|
+
http_status: 408,
|
|
210
|
+
error_type_field: "__type",
|
|
211
|
+
error_type_value: "ModelTimeoutException",
|
|
212
|
+
error_class: "TransportFailure"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
provider: "bedrock",
|
|
216
|
+
http_status: 424,
|
|
217
|
+
error_type_field: "__type",
|
|
218
|
+
error_type_value: "ModelNotReadyException",
|
|
219
|
+
error_class: "ModelUnavailable"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
provider: "bedrock",
|
|
223
|
+
http_status: 403,
|
|
224
|
+
error_type_field: "__type",
|
|
225
|
+
error_type_value: "AccessDeniedException",
|
|
226
|
+
error_class: "PermissionFailure"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
provider: "bedrock",
|
|
230
|
+
http_status: 400,
|
|
231
|
+
error_type_field: "__type",
|
|
232
|
+
error_type_value: "ValidationException",
|
|
233
|
+
error_class: "PolicyFailure"
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
provider: "bedrock",
|
|
237
|
+
http_status: 500,
|
|
238
|
+
error_type_field: "__type",
|
|
239
|
+
error_type_value: "InternalServerException",
|
|
240
|
+
error_class: "TransientServerFailure"
|
|
241
|
+
}
|
|
137
242
|
];
|
|
138
243
|
var HEURISTIC_PATTERNS = [
|
|
139
244
|
// Transport errors (high confidence -- these are unambiguous)
|
|
140
|
-
{
|
|
245
|
+
{
|
|
246
|
+
pattern: /ECONNREFUSED|ECONNRESET|ETIMEDOUT/,
|
|
247
|
+
error_class: "TransportFailure",
|
|
248
|
+
confidence: "high"
|
|
249
|
+
},
|
|
141
250
|
// Quota patterns (before rate limit to avoid misclassification -- Pitfall 2/3)
|
|
142
|
-
{
|
|
143
|
-
|
|
251
|
+
{
|
|
252
|
+
pattern: /quota\s*(?:exceeded|exhausted)/i,
|
|
253
|
+
error_class: "QuotaExhausted",
|
|
254
|
+
confidence: "medium"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
pattern: /insufficient\s*quota/i,
|
|
258
|
+
error_class: "QuotaExhausted",
|
|
259
|
+
confidence: "medium",
|
|
260
|
+
provider: "openai"
|
|
261
|
+
},
|
|
144
262
|
{ pattern: /billing/i, error_class: "QuotaExhausted", confidence: "low", provider: "openai" },
|
|
145
263
|
// Rate limit patterns
|
|
146
264
|
{ pattern: /rate\s*limit/i, error_class: "RateLimited", confidence: "medium" },
|
|
147
265
|
{ pattern: /too many requests/i, error_class: "RateLimited", confidence: "medium" },
|
|
148
266
|
{ pattern: /retry\s*after/i, error_class: "RateLimited", confidence: "medium" },
|
|
149
|
-
{
|
|
150
|
-
|
|
267
|
+
{
|
|
268
|
+
pattern: /overloaded/i,
|
|
269
|
+
error_class: "RateLimited",
|
|
270
|
+
confidence: "medium",
|
|
271
|
+
provider: "anthropic"
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
pattern: /resource\s*exhausted/i,
|
|
275
|
+
error_class: "RateLimited",
|
|
276
|
+
confidence: "medium",
|
|
277
|
+
provider: "google"
|
|
278
|
+
},
|
|
151
279
|
// Auth patterns
|
|
152
280
|
{ pattern: /authentication/i, error_class: "AuthFailure", confidence: "medium" },
|
|
153
281
|
{ pattern: /invalid\s*api\s*key/i, error_class: "AuthFailure", confidence: "medium" },
|
|
@@ -156,14 +284,31 @@ var HEURISTIC_PATTERNS = [
|
|
|
156
284
|
{ pattern: /permission\s*denied/i, error_class: "PermissionFailure", confidence: "medium" },
|
|
157
285
|
{ pattern: /forbidden/i, error_class: "PermissionFailure", confidence: "low" },
|
|
158
286
|
// Model availability patterns
|
|
159
|
-
{
|
|
287
|
+
{
|
|
288
|
+
pattern: /model\s*not\s*(?:available|ready|found)/i,
|
|
289
|
+
error_class: "ModelUnavailable",
|
|
290
|
+
confidence: "medium"
|
|
291
|
+
},
|
|
160
292
|
{ pattern: /not\s*found/i, error_class: "ModelUnavailable", confidence: "low" },
|
|
161
293
|
// Transport patterns (lower confidence than ECONNREFUSED)
|
|
162
294
|
{ pattern: /timeout/i, error_class: "TransportFailure", confidence: "low" },
|
|
163
295
|
// Region restriction (requires both keywords)
|
|
164
|
-
{
|
|
165
|
-
|
|
166
|
-
|
|
296
|
+
{
|
|
297
|
+
pattern: /unsupported.country.*region.*territory/i,
|
|
298
|
+
error_class: "RegionRestriction",
|
|
299
|
+
confidence: "high",
|
|
300
|
+
notes: "OpenAI GeoIP block \u2014 collected 2026-04-11"
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
pattern: /country.*region.*not supported/i,
|
|
304
|
+
error_class: "RegionRestriction",
|
|
305
|
+
confidence: "high"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
pattern: /region.*restrict|restrict.*region/i,
|
|
309
|
+
error_class: "RegionRestriction",
|
|
310
|
+
confidence: "low"
|
|
311
|
+
}
|
|
167
312
|
];
|
|
168
313
|
var TEMPORAL_QUOTA_PATTERN = /too many tokens per (?:day|month|hour|week)/i;
|
|
169
314
|
|
|
@@ -451,10 +596,7 @@ var createStreamStitcher = (_requestId) => {
|
|
|
451
596
|
* @param provenance - Segment provenance without visible_offset (computed here).
|
|
452
597
|
*/
|
|
453
598
|
addSegment(buffer, provenance) {
|
|
454
|
-
const visibleOffset = segments.reduce(
|
|
455
|
-
(sum, entry) => sum + entry.text.length,
|
|
456
|
-
0
|
|
457
|
-
);
|
|
599
|
+
const visibleOffset = segments.reduce((sum, entry) => sum + entry.text.length, 0);
|
|
458
600
|
segments.push({
|
|
459
601
|
text: buffer.snapshot(),
|
|
460
602
|
provenance: { ...provenance, visible_offset: visibleOffset }
|
|
@@ -520,7 +662,7 @@ var createExecutionOrchestrator = (deps) => ({
|
|
|
520
662
|
async execute(request) {
|
|
521
663
|
const requestId = request.request_id || generateCorrelationId();
|
|
522
664
|
const auditCollector = createAuditCollector(deps.logger, requestId);
|
|
523
|
-
const stitcher = createStreamStitcher(
|
|
665
|
+
const stitcher = createStreamStitcher();
|
|
524
666
|
const startMs = Date.now();
|
|
525
667
|
const heuristicFlags = [];
|
|
526
668
|
let outcome = "failure";
|
|
@@ -538,9 +680,7 @@ var createExecutionOrchestrator = (deps) => ({
|
|
|
538
680
|
for (const chunk of adapterResult.chunks) {
|
|
539
681
|
buffer.append(chunk);
|
|
540
682
|
}
|
|
541
|
-
heuristicFlags.push(
|
|
542
|
-
adapterResult.detection_mode === "heuristic"
|
|
543
|
-
);
|
|
683
|
+
heuristicFlags.push(adapterResult.detection_mode === "heuristic");
|
|
544
684
|
const value = { buffer, adapterResult };
|
|
545
685
|
return {
|
|
546
686
|
success: adapterResult.success,
|
|
@@ -562,7 +702,12 @@ var createExecutionOrchestrator = (deps) => ({
|
|
|
562
702
|
outcome = "success";
|
|
563
703
|
finalTarget = failoverResult.target_id;
|
|
564
704
|
const attemptValue = failoverResult.value;
|
|
565
|
-
const continuationMode = stitcher.segmentCount() === 0 ? "same_target_resume" :
|
|
705
|
+
const continuationMode = stitcher.segmentCount() === 0 ? "same_target_resume" : determineContinuationMode(
|
|
706
|
+
stitcher.assemble().segments[stitcher.segmentCount() - 1].source_target_id,
|
|
707
|
+
failoverResult.target_id,
|
|
708
|
+
true
|
|
709
|
+
// same model assumption in plugin-only mode
|
|
710
|
+
);
|
|
566
711
|
stitcher.addSegment(attemptValue.buffer, {
|
|
567
712
|
request_id: requestId,
|
|
568
713
|
segment_id: stitcher.segmentCount(),
|
|
@@ -577,12 +722,8 @@ var createExecutionOrchestrator = (deps) => ({
|
|
|
577
722
|
const stitchedOutput = stitcher.assemble();
|
|
578
723
|
const isDegraded2 = deps.mode === "plugin-only";
|
|
579
724
|
const isHeuristic2 = heuristicFlags.some(Boolean);
|
|
580
|
-
const uniqueModes = [
|
|
581
|
-
|
|
582
|
-
];
|
|
583
|
-
const uniqueTargets = [
|
|
584
|
-
...new Set(stitchedOutput.segments.map((s) => s.source_target_id))
|
|
585
|
-
];
|
|
725
|
+
const uniqueModes = [...new Set(stitchedOutput.segments.map((s) => s.continuation_mode))];
|
|
726
|
+
const uniqueTargets = [...new Set(stitchedOutput.segments.map((s) => s.source_target_id))];
|
|
586
727
|
const provenance2 = {
|
|
587
728
|
request_id: requestId,
|
|
588
729
|
segments: stitchedOutput.segments,
|
|
@@ -620,17 +761,20 @@ var createExecutionOrchestrator = (deps) => ({
|
|
|
620
761
|
auditCollector.flush(outcome, finalTarget);
|
|
621
762
|
const requestLogger = createRequestLogger(deps.logger, requestId);
|
|
622
763
|
const endMs = Date.now();
|
|
623
|
-
requestLogger.info(
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
764
|
+
requestLogger.info(
|
|
765
|
+
{
|
|
766
|
+
event: "request_summary",
|
|
767
|
+
component: "execution",
|
|
768
|
+
outcome,
|
|
769
|
+
total_attempts: summaryAttempts,
|
|
770
|
+
total_failovers: summaryFailovers,
|
|
771
|
+
total_retries: summaryRetries,
|
|
772
|
+
latency_ms: endMs - startMs,
|
|
773
|
+
targets_used: summaryTargets,
|
|
774
|
+
final_target: finalTarget ?? null
|
|
775
|
+
},
|
|
776
|
+
"Request complete"
|
|
777
|
+
);
|
|
634
778
|
}
|
|
635
779
|
}
|
|
636
780
|
});
|
|
@@ -714,20 +858,17 @@ var createSdkAdapter = (_deps) => ({
|
|
|
714
858
|
var createModeAdapter = (mode, deps) => {
|
|
715
859
|
switch (mode) {
|
|
716
860
|
case "plugin-only":
|
|
717
|
-
return createPluginAdapter(
|
|
861
|
+
return createPluginAdapter();
|
|
718
862
|
case "server-companion":
|
|
719
|
-
return createServerAdapter(
|
|
863
|
+
return createServerAdapter();
|
|
720
864
|
case "sdk-control":
|
|
721
|
-
return createSdkAdapter(
|
|
865
|
+
return createSdkAdapter();
|
|
722
866
|
default: {
|
|
723
867
|
const _exhaustive = mode;
|
|
724
868
|
throw new Error(`Unknown deployment mode: ${String(_exhaustive)}`);
|
|
725
869
|
}
|
|
726
870
|
}
|
|
727
871
|
};
|
|
728
|
-
|
|
729
|
-
// src/operator/server-auth.ts
|
|
730
|
-
import { timingSafeEqual } from "crypto";
|
|
731
872
|
var validateBearerToken = (authHeader, expectedToken) => {
|
|
732
873
|
if (authHeader === void 0) {
|
|
733
874
|
return { authorized: false, reason: "missing Authorization header" };
|
|
@@ -746,90 +887,5 @@ var validateBearerToken = (authHeader, expectedToken) => {
|
|
|
746
887
|
}
|
|
747
888
|
return { authorized: true };
|
|
748
889
|
};
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
BackoffConfigSchema,
|
|
752
|
-
ConfigValidationError,
|
|
753
|
-
DEFAULT_ALPHA,
|
|
754
|
-
DEFAULT_BACKOFF_BASE_MS,
|
|
755
|
-
DEFAULT_BACKOFF_JITTER,
|
|
756
|
-
DEFAULT_BACKOFF_MAX_MS,
|
|
757
|
-
DEFAULT_BACKOFF_MULTIPLIER,
|
|
758
|
-
DEFAULT_BACKOFF_PARAMS,
|
|
759
|
-
DEFAULT_FAILOVER_BUDGET,
|
|
760
|
-
DEFAULT_RETRY,
|
|
761
|
-
DEFAULT_RETRY_BUDGET,
|
|
762
|
-
DEFAULT_TIMEOUT_MS,
|
|
763
|
-
DualBreaker,
|
|
764
|
-
EXCLUSION_REASONS,
|
|
765
|
-
ErrorClassSchema,
|
|
766
|
-
HEURISTIC_PATTERNS,
|
|
767
|
-
INITIAL_HEALTH_SCORE,
|
|
768
|
-
PROVIDER_PATTERNS,
|
|
769
|
-
REDACT_PATHS,
|
|
770
|
-
SwitcherConfigSchema,
|
|
771
|
-
TARGET_STATES,
|
|
772
|
-
TEMPORAL_QUOTA_PATTERN,
|
|
773
|
-
TargetConfigSchema,
|
|
774
|
-
TargetRegistry,
|
|
775
|
-
addProfile,
|
|
776
|
-
applyConfigDiff,
|
|
777
|
-
checkHardRejects,
|
|
778
|
-
classify,
|
|
779
|
-
computeBackoffMs,
|
|
780
|
-
computeConfigDiff,
|
|
781
|
-
computeCooldownMs,
|
|
782
|
-
computeScore,
|
|
783
|
-
createAdmissionController,
|
|
784
|
-
createAuditCollector,
|
|
785
|
-
createAuditLogger,
|
|
786
|
-
createAuthWatcher,
|
|
787
|
-
createCircuitBreaker,
|
|
788
|
-
createConcurrencyTracker,
|
|
789
|
-
createCooldownManager,
|
|
790
|
-
createExecutionOrchestrator,
|
|
791
|
-
createFailoverOrchestrator,
|
|
792
|
-
createLogSubscriber,
|
|
793
|
-
createModeAdapter,
|
|
794
|
-
createOperatorTools,
|
|
795
|
-
createProfileTools,
|
|
796
|
-
createRegistry,
|
|
797
|
-
createRequestLogger,
|
|
798
|
-
createRequestTraceBuffer,
|
|
799
|
-
createRetryPolicy,
|
|
800
|
-
createRoutingEventBus,
|
|
801
|
-
createStreamBuffer,
|
|
802
|
-
createStreamStitcher,
|
|
803
|
-
detectDeploymentMode,
|
|
804
|
-
determineContinuationMode,
|
|
805
|
-
directSignalFromResponse,
|
|
806
|
-
disableTarget,
|
|
807
|
-
discoverTargets,
|
|
808
|
-
discoverTargetsFromProfiles,
|
|
809
|
-
drainTarget,
|
|
810
|
-
extractRetryAfterMs,
|
|
811
|
-
generateCorrelationId,
|
|
812
|
-
getExclusionReason,
|
|
813
|
-
getModeCapabilities,
|
|
814
|
-
getSignalFidelity,
|
|
815
|
-
getTargetStateTransition,
|
|
816
|
-
heuristicSignalFromEvent,
|
|
817
|
-
inspectRequest,
|
|
818
|
-
isRetryable,
|
|
819
|
-
listProfiles,
|
|
820
|
-
listTargets,
|
|
821
|
-
loadProfiles,
|
|
822
|
-
nextProfileId,
|
|
823
|
-
normalizeLatency,
|
|
824
|
-
pauseTarget,
|
|
825
|
-
reloadConfig,
|
|
826
|
-
removeProfile,
|
|
827
|
-
resumeTarget,
|
|
828
|
-
saveProfiles,
|
|
829
|
-
selectTarget,
|
|
830
|
-
updateHealthScore,
|
|
831
|
-
updateLatencyEma,
|
|
832
|
-
validateBearerToken,
|
|
833
|
-
validateConfig
|
|
834
|
-
};
|
|
835
|
-
//# sourceMappingURL=index.js.map
|
|
890
|
+
|
|
891
|
+
export { HEURISTIC_PATTERNS, PROVIDER_PATTERNS, TEMPORAL_QUOTA_PATTERN, classify, createAuditCollector, createExecutionOrchestrator, createModeAdapter, createStreamBuffer, createStreamStitcher, detectDeploymentMode, determineContinuationMode, directSignalFromResponse, extractRetryAfterMs, getModeCapabilities, getSignalFidelity, heuristicSignalFromEvent, validateBearerToken };
|