@tangle-network/agent-core 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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -0
  3. package/dist/auth/browser.d.ts +22 -0
  4. package/dist/auth/browser.d.ts.map +1 -0
  5. package/dist/auth/browser.js +43 -0
  6. package/dist/auth/browser.js.map +1 -0
  7. package/dist/auth/index.d.ts +430 -0
  8. package/dist/auth/index.d.ts.map +1 -0
  9. package/dist/auth/index.js +841 -0
  10. package/dist/auth/index.js.map +1 -0
  11. package/dist/computer-use/index.d.ts +122 -0
  12. package/dist/computer-use/index.d.ts.map +1 -0
  13. package/dist/computer-use/index.js +422 -0
  14. package/dist/computer-use/index.js.map +1 -0
  15. package/dist/errors-DJ6U6cHY.js +146 -0
  16. package/dist/errors-DJ6U6cHY.js.map +1 -0
  17. package/dist/events/index.d.ts +2 -0
  18. package/dist/events/index.js +2 -0
  19. package/dist/events-CUWh9qrv.js +263 -0
  20. package/dist/events-CUWh9qrv.js.map +1 -0
  21. package/dist/index-CFA8kgHJ.d.ts +352 -0
  22. package/dist/index-CFA8kgHJ.d.ts.map +1 -0
  23. package/dist/index-CtebBodu.d.ts +108 -0
  24. package/dist/index-CtebBodu.d.ts.map +1 -0
  25. package/dist/index-DiQX9bjq.d.ts +55 -0
  26. package/dist/index-DiQX9bjq.d.ts.map +1 -0
  27. package/dist/index-DlPznmKA.d.ts +158 -0
  28. package/dist/index-DlPznmKA.d.ts.map +1 -0
  29. package/dist/index-z2wPdzFb.d.ts +133 -0
  30. package/dist/index-z2wPdzFb.d.ts.map +1 -0
  31. package/dist/index.d.ts +565 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +822 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/resilience/index.d.ts +2 -0
  36. package/dist/resilience/index.js +2 -0
  37. package/dist/resilience-BQzDfw_C.js +221 -0
  38. package/dist/resilience-BQzDfw_C.js.map +1 -0
  39. package/dist/sse/index.d.ts +174 -0
  40. package/dist/sse/index.d.ts.map +1 -0
  41. package/dist/sse/index.js +303 -0
  42. package/dist/sse/index.js.map +1 -0
  43. package/dist/transport/index.d.ts +2 -0
  44. package/dist/transport/index.js +2 -0
  45. package/dist/transport-mKLoQep5.js +427 -0
  46. package/dist/transport-mKLoQep5.js.map +1 -0
  47. package/dist/types/index.d.ts +2 -0
  48. package/dist/types/index.js +2 -0
  49. package/dist/types-D5VLaol0.js +31 -0
  50. package/dist/types-D5VLaol0.js.map +1 -0
  51. package/dist/types-DC6OJ1um.js +331 -0
  52. package/dist/types-DC6OJ1um.js.map +1 -0
  53. package/dist/types-DiDSGM8K.d.ts +320 -0
  54. package/dist/types-DiDSGM8K.d.ts.map +1 -0
  55. package/package.json +132 -0
@@ -0,0 +1,422 @@
1
+ //#region src/computer-use/action.ts
2
+ var ComputerUseError = class extends Error {
3
+ code;
4
+ constructor(message, code = "COMPUTER_USE_FAILED") {
5
+ super(message);
6
+ this.name = "ComputerUseError";
7
+ this.code = code;
8
+ }
9
+ };
10
+ /**
11
+ * Provider-agnostic translation error. Both the Anthropic and OpenAI
12
+ * translators throw this; the sandbox API and MCP server catch it
13
+ * with `instanceof` to surface the failure as a tool result rather
14
+ * than a 5xx.
15
+ */
16
+ var ComputerActionTranslationError = class extends Error {
17
+ code;
18
+ constructor(message, code = "COMPUTER_USE_UNSUPPORTED_ACTION") {
19
+ super(message);
20
+ this.name = "ComputerActionTranslationError";
21
+ this.code = code;
22
+ }
23
+ };
24
+ const VALID_ACTION_TYPES = new Set([
25
+ "screenshot",
26
+ "cursor_position",
27
+ "click",
28
+ "double_click",
29
+ "move",
30
+ "drag",
31
+ "type",
32
+ "keypress",
33
+ "scroll",
34
+ "wait"
35
+ ]);
36
+ const VALID_BUTTONS = new Set([
37
+ "left",
38
+ "middle",
39
+ "right"
40
+ ]);
41
+ function ensureFiniteInt(value, label) {
42
+ if (typeof value !== "number" || !Number.isFinite(value)) throw new ComputerUseError(`Action field "${label}" must be a finite number, got ${typeof value}`, "COMPUTER_USE_INVALID_ACTION");
43
+ return Number.isInteger(value) ? value : Math.round(value);
44
+ }
45
+ /**
46
+ * Parse and validate an unknown payload into a typed ComputerUseAction.
47
+ * Throws ComputerUseError with COMPUTER_USE_INVALID_ACTION on any
48
+ * structural problem.
49
+ */
50
+ function parseAction(input) {
51
+ if (!input || typeof input !== "object") throw new ComputerUseError("Action must be an object", "COMPUTER_USE_INVALID_ACTION");
52
+ const obj = input;
53
+ const type = obj.type;
54
+ if (typeof type !== "string" || !VALID_ACTION_TYPES.has(type)) throw new ComputerUseError(`Unknown action type "${String(type)}". Valid: ${[...VALID_ACTION_TYPES].join(", ")}`, "COMPUTER_USE_INVALID_ACTION");
55
+ switch (type) {
56
+ case "screenshot": return { type: "screenshot" };
57
+ case "cursor_position": return { type: "cursor_position" };
58
+ case "click": {
59
+ const x = ensureFiniteInt(obj.x, "x");
60
+ const y = ensureFiniteInt(obj.y, "y");
61
+ const button = obj.button ?? "left";
62
+ if (typeof button !== "string" || !VALID_BUTTONS.has(button)) throw new ComputerUseError(`Invalid button "${String(button)}". Valid: left, middle, right`, "COMPUTER_USE_INVALID_ACTION");
63
+ return {
64
+ type: "click",
65
+ x,
66
+ y,
67
+ button
68
+ };
69
+ }
70
+ case "double_click": return {
71
+ type: "double_click",
72
+ x: ensureFiniteInt(obj.x, "x"),
73
+ y: ensureFiniteInt(obj.y, "y")
74
+ };
75
+ case "move": return {
76
+ type: "move",
77
+ x: ensureFiniteInt(obj.x, "x"),
78
+ y: ensureFiniteInt(obj.y, "y")
79
+ };
80
+ case "drag": {
81
+ const from = obj.from;
82
+ const to = obj.to;
83
+ if (!from || !to) throw new ComputerUseError("drag requires both from and to {x,y}", "COMPUTER_USE_INVALID_ACTION");
84
+ return {
85
+ type: "drag",
86
+ from: {
87
+ x: ensureFiniteInt(from.x, "from.x"),
88
+ y: ensureFiniteInt(from.y, "from.y")
89
+ },
90
+ to: {
91
+ x: ensureFiniteInt(to.x, "to.x"),
92
+ y: ensureFiniteInt(to.y, "to.y")
93
+ }
94
+ };
95
+ }
96
+ case "type": {
97
+ const text = obj.text;
98
+ if (typeof text !== "string") throw new ComputerUseError("type action requires string field \"text\"", "COMPUTER_USE_INVALID_ACTION");
99
+ return {
100
+ type: "type",
101
+ text,
102
+ delayMs: obj.delayMs === void 0 ? void 0 : ensureFiniteInt(obj.delayMs, "delayMs")
103
+ };
104
+ }
105
+ case "keypress": {
106
+ const keys = obj.keys;
107
+ if (!Array.isArray(keys) || keys.length === 0) throw new ComputerUseError("keypress requires non-empty keys[] array", "COMPUTER_USE_INVALID_ACTION");
108
+ const normalized = [];
109
+ for (const k of keys) {
110
+ if (typeof k !== "string" || k.length === 0) throw new ComputerUseError("keypress keys[] must be non-empty strings", "COMPUTER_USE_INVALID_ACTION");
111
+ normalized.push(normalizeKey(k));
112
+ }
113
+ return {
114
+ type: "keypress",
115
+ keys: normalized
116
+ };
117
+ }
118
+ case "scroll": {
119
+ const deltaY = obj.deltaY === void 0 ? void 0 : ensureFiniteInt(obj.deltaY, "deltaY");
120
+ const deltaX = obj.deltaX === void 0 ? void 0 : ensureFiniteInt(obj.deltaX, "deltaX");
121
+ if ((deltaY === void 0 || deltaY === 0) && (deltaX === void 0 || deltaX === 0)) throw new ComputerUseError("scroll requires at least one non-zero deltaY or deltaX", "COMPUTER_USE_INVALID_ACTION");
122
+ return {
123
+ type: "scroll",
124
+ x: ensureFiniteInt(obj.x, "x"),
125
+ y: ensureFiniteInt(obj.y, "y"),
126
+ ...deltaY ? { deltaY } : {},
127
+ ...deltaX ? { deltaX } : {}
128
+ };
129
+ }
130
+ case "wait": {
131
+ const ms = ensureFiniteInt(obj.ms, "ms");
132
+ if (ms < 0) throw new ComputerUseError("wait.ms must be non-negative", "COMPUTER_USE_INVALID_ACTION");
133
+ return {
134
+ type: "wait",
135
+ ms
136
+ };
137
+ }
138
+ }
139
+ }
140
+ /**
141
+ * Map common provider key aliases (cmd, enter, page_up, …) onto the X11
142
+ * keysym names xdotool expects. Anything not in the map passes through
143
+ * unchanged so callers can supply real keysyms directly.
144
+ *
145
+ * This is the union of what the sidecar and the claude-code provider
146
+ * each used to maintain separately.
147
+ */
148
+ const KEY_ALIASES = {
149
+ cmd: "super",
150
+ command: "super",
151
+ win: "super",
152
+ windows: "super",
153
+ meta: "super",
154
+ super_l: "super",
155
+ super_r: "super",
156
+ enter: "Return",
157
+ return: "Return",
158
+ esc: "Escape",
159
+ escape: "Escape",
160
+ tab: "Tab",
161
+ backspace: "BackSpace",
162
+ delete: "Delete",
163
+ del: "Delete",
164
+ up: "Up",
165
+ down: "Down",
166
+ left: "Left",
167
+ right: "Right",
168
+ pageup: "Prior",
169
+ page_up: "Prior",
170
+ pagedown: "Next",
171
+ page_down: "Next",
172
+ home: "Home",
173
+ end: "End",
174
+ space: "space",
175
+ ctrl: "ctrl",
176
+ control: "ctrl",
177
+ alt: "alt",
178
+ shift: "shift"
179
+ };
180
+ function normalizeKey(key) {
181
+ return KEY_ALIASES[key.toLowerCase()] ?? key;
182
+ }
183
+ //#endregion
184
+ //#region src/computer-use/anthropic.ts
185
+ /**
186
+ * Anthropic `computer` tool → internal ComputerUseAction translator.
187
+ *
188
+ * The Anthropic Claude API (and `claude-code` CLI when run with the
189
+ * computer-use beta) emits tool-use blocks of the form:
190
+ *
191
+ * { name: 'computer', input: { action, coordinate?, text?, ... } }
192
+ *
193
+ * This module translates the input shape into the canonical sidecar
194
+ * action vocabulary defined in `./action.ts`. Pure function — no I/O,
195
+ * no side effects.
196
+ */
197
+ function requireCoordinate(input, field) {
198
+ const value = input[field];
199
+ if (!Array.isArray(value) || value.length !== 2 || typeof value[0] !== "number" || typeof value[1] !== "number") throw new ComputerActionTranslationError(`Anthropic computer.${input.action} requires "${field}: [x, y]"`, "COMPUTER_USE_INVALID_ACTION");
200
+ return value;
201
+ }
202
+ function requireText(input) {
203
+ if (typeof input.text !== "string" || input.text.length === 0) throw new ComputerActionTranslationError(`Anthropic computer.${input.action} requires non-empty "text"`, "COMPUTER_USE_INVALID_ACTION");
204
+ return input.text;
205
+ }
206
+ /**
207
+ * Translate an Anthropic `computer` tool input into the sidecar action.
208
+ * Throws `ComputerActionTranslationError` for malformed inputs or
209
+ * unrecognized action names; the caller should surface the error as a
210
+ * tool_result with `is_error: true` so the model can react.
211
+ */
212
+ function translateAnthropicComputerAction(input) {
213
+ switch (input.action) {
214
+ case "screenshot": return { type: "screenshot" };
215
+ case "cursor_position": return { type: "cursor_position" };
216
+ case "left_click":
217
+ case "right_click":
218
+ case "middle_click": {
219
+ const [x, y] = requireCoordinate(input, "coordinate");
220
+ return {
221
+ type: "click",
222
+ x,
223
+ y,
224
+ button: input.action === "left_click" ? "left" : input.action === "right_click" ? "right" : "middle"
225
+ };
226
+ }
227
+ case "double_click": {
228
+ const [x, y] = requireCoordinate(input, "coordinate");
229
+ return {
230
+ type: "double_click",
231
+ x,
232
+ y
233
+ };
234
+ }
235
+ case "mouse_move": {
236
+ const [x, y] = requireCoordinate(input, "coordinate");
237
+ return {
238
+ type: "move",
239
+ x,
240
+ y
241
+ };
242
+ }
243
+ case "left_click_drag": {
244
+ const [fromX, fromY] = requireCoordinate(input, "start_coordinate");
245
+ const [toX, toY] = requireCoordinate(input, "coordinate");
246
+ return {
247
+ type: "drag",
248
+ from: {
249
+ x: fromX,
250
+ y: fromY
251
+ },
252
+ to: {
253
+ x: toX,
254
+ y: toY
255
+ }
256
+ };
257
+ }
258
+ case "type": return {
259
+ type: "type",
260
+ text: requireText(input)
261
+ };
262
+ case "key": return {
263
+ type: "keypress",
264
+ keys: requireText(input).split("+").map((token) => normalizeKey(token.trim()))
265
+ };
266
+ case "scroll": {
267
+ const [x, y] = requireCoordinate(input, "coordinate");
268
+ const direction = input.scroll_direction ?? "down";
269
+ const magnitude = typeof input.scroll_amount === "number" && input.scroll_amount > 0 ? input.scroll_amount : 3;
270
+ switch (direction) {
271
+ case "up": return {
272
+ type: "scroll",
273
+ x,
274
+ y,
275
+ deltaY: -magnitude
276
+ };
277
+ case "down": return {
278
+ type: "scroll",
279
+ x,
280
+ y,
281
+ deltaY: magnitude
282
+ };
283
+ case "left": return {
284
+ type: "scroll",
285
+ x,
286
+ y,
287
+ deltaX: -magnitude
288
+ };
289
+ case "right": return {
290
+ type: "scroll",
291
+ x,
292
+ y,
293
+ deltaX: magnitude
294
+ };
295
+ default: throw new ComputerActionTranslationError(`Unknown scroll_direction "${direction}"`, "COMPUTER_USE_INVALID_ACTION");
296
+ }
297
+ }
298
+ default: throw new ComputerActionTranslationError(`Unknown Anthropic computer action: ${input.action}`, "COMPUTER_USE_UNSUPPORTED_ACTION");
299
+ }
300
+ }
301
+ //#endregion
302
+ //#region src/computer-use/openai.ts
303
+ /**
304
+ * OpenAI `computer_use_preview` tool → internal ComputerUseAction
305
+ * translator.
306
+ *
307
+ * The OpenAI Responses API emits computer-use tool calls with action
308
+ * objects shaped per the `computer_use_preview` spec, e.g.:
309
+ *
310
+ * { type: "click", x: 100, y: 200, button: "left" }
311
+ * { type: "drag", path: [{ x: 0, y: 0 }, { x: 50, y: 50 }] }
312
+ * { type: "scroll", x, y, scroll_x: 0, scroll_y: -3 }
313
+ * { type: "keypress", keys: ["ENTER"] }
314
+ *
315
+ * These are close to but not identical to the sidecar's internal action
316
+ * shape (`./action.ts`). The differences this translator handles:
317
+ * - drag.path[] (start + end points) → drag.from/to
318
+ * - scroll_x/scroll_y → deltaX/deltaY
319
+ * - click button "wheel"|"back"|"forward" → unsupported error
320
+ * - cursor_position has no OpenAI equivalent (model uses screenshots)
321
+ */
322
+ function requireNumber(value, label) {
323
+ if (typeof value !== "number" || !Number.isFinite(value)) throw new ComputerActionTranslationError(`OpenAI computer_use action requires numeric "${label}"`, "COMPUTER_USE_INVALID_ACTION");
324
+ return value;
325
+ }
326
+ function requireXY(input) {
327
+ return {
328
+ x: requireNumber(input.x, "x"),
329
+ y: requireNumber(input.y, "y")
330
+ };
331
+ }
332
+ /**
333
+ * Translate an OpenAI `computer_use_preview` action into the sidecar
334
+ * action. Throws `ComputerActionTranslationError` for unsupported
335
+ * variants (wheel/back/forward buttons) or malformed inputs.
336
+ */
337
+ function translateOpenAIComputerAction(input) {
338
+ switch (input.type) {
339
+ case "screenshot": return { type: "screenshot" };
340
+ case "click": {
341
+ const { x, y } = requireXY(input);
342
+ const buttonRaw = input.button ?? "left";
343
+ if (buttonRaw !== "left" && buttonRaw !== "middle" && buttonRaw !== "right") throw new ComputerActionTranslationError(`OpenAI computer_use click button "${buttonRaw}" is not supported by the sidecar (only left/middle/right)`, "COMPUTER_USE_UNSUPPORTED_ACTION");
344
+ return {
345
+ type: "click",
346
+ x,
347
+ y,
348
+ button: buttonRaw
349
+ };
350
+ }
351
+ case "double_click": return {
352
+ type: "double_click",
353
+ ...requireXY(input)
354
+ };
355
+ case "move": return {
356
+ type: "move",
357
+ ...requireXY(input)
358
+ };
359
+ case "drag": {
360
+ if (!Array.isArray(input.path) || input.path.length < 2) throw new ComputerActionTranslationError("OpenAI computer_use drag requires path[] with at least 2 points", "COMPUTER_USE_INVALID_ACTION");
361
+ const start = input.path[0];
362
+ const end = input.path[input.path.length - 1];
363
+ return {
364
+ type: "drag",
365
+ from: {
366
+ x: requireNumber(start.x, "path[0].x"),
367
+ y: requireNumber(start.y, "path[0].y")
368
+ },
369
+ to: {
370
+ x: requireNumber(end.x, "path[last].x"),
371
+ y: requireNumber(end.y, "path[last].y")
372
+ }
373
+ };
374
+ }
375
+ case "type": {
376
+ const text = input.text;
377
+ if (typeof text !== "string" || text.length === 0) throw new ComputerActionTranslationError("OpenAI computer_use type action requires non-empty string \"text\"", "COMPUTER_USE_INVALID_ACTION");
378
+ return {
379
+ type: "type",
380
+ text
381
+ };
382
+ }
383
+ case "keypress":
384
+ if (!Array.isArray(input.keys) || input.keys.length === 0) throw new ComputerActionTranslationError("OpenAI computer_use keypress requires non-empty keys[]", "COMPUTER_USE_INVALID_ACTION");
385
+ return {
386
+ type: "keypress",
387
+ keys: input.keys.map((k) => {
388
+ if (typeof k !== "string" || k.length === 0) throw new ComputerActionTranslationError("OpenAI computer_use keypress keys[] must be non-empty strings", "COMPUTER_USE_INVALID_ACTION");
389
+ return normalizeKey(k);
390
+ })
391
+ };
392
+ case "scroll": {
393
+ const { x, y } = requireXY(input);
394
+ const sx = typeof input.scroll_x === "number" && Number.isFinite(input.scroll_x) ? input.scroll_x : 0;
395
+ const sy = typeof input.scroll_y === "number" && Number.isFinite(input.scroll_y) ? input.scroll_y : 0;
396
+ if (sx === 0 && sy === 0) throw new ComputerActionTranslationError("OpenAI computer_use scroll requires non-zero scroll_x or scroll_y", "COMPUTER_USE_INVALID_ACTION");
397
+ const action = {
398
+ type: "scroll",
399
+ x,
400
+ y
401
+ };
402
+ if (sy !== 0) action.deltaY = sy;
403
+ if (sx !== 0) action.deltaX = sx;
404
+ return action;
405
+ }
406
+ case "wait":
407
+ if (typeof input.ms === "number" && Number.isFinite(input.ms)) return {
408
+ type: "wait",
409
+ ms: Math.max(0, Math.round(input.ms))
410
+ };
411
+ if (typeof input.duration === "number" && Number.isFinite(input.duration)) return {
412
+ type: "wait",
413
+ ms: Math.max(0, Math.round(input.duration * 1e3))
414
+ };
415
+ throw new ComputerActionTranslationError("OpenAI computer_use wait requires numeric \"ms\" or \"duration\"", "COMPUTER_USE_INVALID_ACTION");
416
+ default: throw new ComputerActionTranslationError(`Unknown OpenAI computer_use action type: ${input.type}`, "COMPUTER_USE_UNSUPPORTED_ACTION");
417
+ }
418
+ }
419
+ //#endregion
420
+ export { ComputerActionTranslationError, ComputerUseError, normalizeKey, parseAction, translateAnthropicComputerAction, translateOpenAIComputerAction };
421
+
422
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/computer-use/action.ts","../../src/computer-use/anthropic.ts","../../src/computer-use/openai.ts"],"sourcesContent":["/**\n * Computer-use action schema — single source of truth.\n *\n * The sidecar's REST/MCP routes accept this union; provider translators\n * (Anthropic `computer`, OpenAI `computer_use_preview`) emit it. Keeping\n * the type, validator, and key alias table in one place prevents the\n * three-way drift that previously existed across sidecar + claude-code\n * provider + ad-hoc dispatchers.\n */\n\nexport type MouseButton = \"left\" | \"middle\" | \"right\";\n\nexport type ComputerUseAction =\n | { type: \"screenshot\" }\n | { type: \"cursor_position\" }\n | { type: \"click\"; x: number; y: number; button?: MouseButton }\n | { type: \"double_click\"; x: number; y: number }\n | { type: \"move\"; x: number; y: number }\n | {\n type: \"drag\";\n from: { x: number; y: number };\n to: { x: number; y: number };\n }\n | { type: \"type\"; text: string; delayMs?: number }\n | { type: \"keypress\"; keys: string[] }\n | {\n type: \"scroll\";\n x: number;\n y: number;\n deltaY?: number;\n deltaX?: number;\n }\n | { type: \"wait\"; ms: number };\n\nexport type ComputerUseActionType = ComputerUseAction[\"type\"];\n\nexport class ComputerUseError extends Error {\n readonly code: string;\n constructor(message: string, code = \"COMPUTER_USE_FAILED\") {\n super(message);\n this.name = \"ComputerUseError\";\n this.code = code;\n }\n}\n\n/**\n * Provider-agnostic translation error. Both the Anthropic and OpenAI\n * translators throw this; the sandbox API and MCP server catch it\n * with `instanceof` to surface the failure as a tool result rather\n * than a 5xx.\n */\nexport class ComputerActionTranslationError extends Error {\n readonly code: string;\n constructor(message: string, code = \"COMPUTER_USE_UNSUPPORTED_ACTION\") {\n super(message);\n this.name = \"ComputerActionTranslationError\";\n this.code = code;\n }\n}\n\nconst VALID_ACTION_TYPES = new Set<ComputerUseActionType>([\n \"screenshot\",\n \"cursor_position\",\n \"click\",\n \"double_click\",\n \"move\",\n \"drag\",\n \"type\",\n \"keypress\",\n \"scroll\",\n \"wait\",\n]);\n\nconst VALID_BUTTONS: ReadonlySet<MouseButton> = new Set([\n \"left\",\n \"middle\",\n \"right\",\n]);\n\nfunction ensureFiniteInt(value: unknown, label: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new ComputerUseError(\n `Action field \"${label}\" must be a finite number, got ${typeof value}`,\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n return Number.isInteger(value) ? value : Math.round(value);\n}\n\n/**\n * Parse and validate an unknown payload into a typed ComputerUseAction.\n * Throws ComputerUseError with COMPUTER_USE_INVALID_ACTION on any\n * structural problem.\n */\nexport function parseAction(input: unknown): ComputerUseAction {\n if (!input || typeof input !== \"object\") {\n throw new ComputerUseError(\n \"Action must be an object\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n const obj = input as Record<string, unknown>;\n const type = obj.type;\n if (\n typeof type !== \"string\" ||\n !VALID_ACTION_TYPES.has(type as ComputerUseActionType)\n ) {\n throw new ComputerUseError(\n `Unknown action type \"${String(type)}\". Valid: ${[...VALID_ACTION_TYPES].join(\", \")}`,\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n\n switch (type as ComputerUseActionType) {\n case \"screenshot\":\n return { type: \"screenshot\" };\n case \"cursor_position\":\n return { type: \"cursor_position\" };\n case \"click\": {\n const x = ensureFiniteInt(obj.x, \"x\");\n const y = ensureFiniteInt(obj.y, \"y\");\n const button = obj.button ?? \"left\";\n if (\n typeof button !== \"string\" ||\n !VALID_BUTTONS.has(button as MouseButton)\n ) {\n throw new ComputerUseError(\n `Invalid button \"${String(button)}\". Valid: left, middle, right`,\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n return { type: \"click\", x, y, button: button as MouseButton };\n }\n case \"double_click\":\n return {\n type: \"double_click\",\n x: ensureFiniteInt(obj.x, \"x\"),\n y: ensureFiniteInt(obj.y, \"y\"),\n };\n case \"move\":\n return {\n type: \"move\",\n x: ensureFiniteInt(obj.x, \"x\"),\n y: ensureFiniteInt(obj.y, \"y\"),\n };\n case \"drag\": {\n const from = obj.from as Record<string, unknown> | undefined;\n const to = obj.to as Record<string, unknown> | undefined;\n if (!from || !to) {\n throw new ComputerUseError(\n \"drag requires both from and to {x,y}\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n return {\n type: \"drag\",\n from: {\n x: ensureFiniteInt(from.x, \"from.x\"),\n y: ensureFiniteInt(from.y, \"from.y\"),\n },\n to: {\n x: ensureFiniteInt(to.x, \"to.x\"),\n y: ensureFiniteInt(to.y, \"to.y\"),\n },\n };\n }\n case \"type\": {\n const text = obj.text;\n if (typeof text !== \"string\") {\n throw new ComputerUseError(\n 'type action requires string field \"text\"',\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n const delayMs =\n obj.delayMs === undefined\n ? undefined\n : ensureFiniteInt(obj.delayMs, \"delayMs\");\n return { type: \"type\", text, delayMs };\n }\n case \"keypress\": {\n const keys = obj.keys;\n if (!Array.isArray(keys) || keys.length === 0) {\n throw new ComputerUseError(\n \"keypress requires non-empty keys[] array\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n const normalized: string[] = [];\n for (const k of keys) {\n if (typeof k !== \"string\" || k.length === 0) {\n throw new ComputerUseError(\n \"keypress keys[] must be non-empty strings\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n // Normalize on parse so the sidecar runtime can pass keys\n // straight to xdotool. Translators do their own normalization\n // for the same reason; calling normalizeKey twice is a no-op.\n normalized.push(normalizeKey(k));\n }\n return { type: \"keypress\", keys: normalized };\n }\n case \"scroll\": {\n const deltaY =\n obj.deltaY === undefined\n ? undefined\n : ensureFiniteInt(obj.deltaY, \"deltaY\");\n const deltaX =\n obj.deltaX === undefined\n ? undefined\n : ensureFiniteInt(obj.deltaX, \"deltaX\");\n // Reject (undefined, 0) on both axes — runScroll's wheel-button\n // dispatch skips zero, so the action would be a silent no-op\n // otherwise. Translators always emit non-zero, but a direct\n // parseAction caller could otherwise dispatch a successful\n // no-op scroll.\n const noY = deltaY === undefined || deltaY === 0;\n const noX = deltaX === undefined || deltaX === 0;\n if (noY && noX) {\n throw new ComputerUseError(\n \"scroll requires at least one non-zero deltaY or deltaX\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n // Treat 0 the same as undefined when shaping the return — runScroll\n // skips both branches on a zero axis, and the OpenAI translator\n // already strips zeros. Keep the on-the-wire shape consistent\n // across both code paths.\n return {\n type: \"scroll\",\n x: ensureFiniteInt(obj.x, \"x\"),\n y: ensureFiniteInt(obj.y, \"y\"),\n ...(deltaY ? { deltaY } : {}),\n ...(deltaX ? { deltaX } : {}),\n };\n }\n case \"wait\": {\n const ms = ensureFiniteInt(obj.ms, \"ms\");\n if (ms < 0) {\n throw new ComputerUseError(\n \"wait.ms must be non-negative\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n return { type: \"wait\", ms };\n }\n }\n}\n\n/**\n * Map common provider key aliases (cmd, enter, page_up, …) onto the X11\n * keysym names xdotool expects. Anything not in the map passes through\n * unchanged so callers can supply real keysyms directly.\n *\n * This is the union of what the sidecar and the claude-code provider\n * each used to maintain separately.\n */\nconst KEY_ALIASES: Record<string, string> = {\n cmd: \"super\",\n command: \"super\",\n win: \"super\",\n windows: \"super\",\n meta: \"super\",\n super_l: \"super\",\n super_r: \"super\",\n enter: \"Return\",\n return: \"Return\",\n esc: \"Escape\",\n escape: \"Escape\",\n tab: \"Tab\",\n backspace: \"BackSpace\",\n delete: \"Delete\",\n del: \"Delete\",\n up: \"Up\",\n down: \"Down\",\n left: \"Left\",\n right: \"Right\",\n pageup: \"Prior\",\n page_up: \"Prior\",\n pagedown: \"Next\",\n page_down: \"Next\",\n home: \"Home\",\n end: \"End\",\n space: \"space\",\n ctrl: \"ctrl\",\n control: \"ctrl\",\n alt: \"alt\",\n shift: \"shift\",\n};\n\nexport function normalizeKey(key: string): string {\n const lower = key.toLowerCase();\n return KEY_ALIASES[lower] ?? key;\n}\n","/**\n * Anthropic `computer` tool → internal ComputerUseAction translator.\n *\n * The Anthropic Claude API (and `claude-code` CLI when run with the\n * computer-use beta) emits tool-use blocks of the form:\n *\n * { name: 'computer', input: { action, coordinate?, text?, ... } }\n *\n * This module translates the input shape into the canonical sidecar\n * action vocabulary defined in `./action.ts`. Pure function — no I/O,\n * no side effects.\n */\n\nimport {\n ComputerActionTranslationError,\n type ComputerUseAction,\n normalizeKey,\n} from \"./action.js\";\n\nexport interface AnthropicComputerInput {\n action: string;\n coordinate?: [number, number];\n start_coordinate?: [number, number];\n text?: string;\n scroll_direction?: \"up\" | \"down\" | \"left\" | \"right\";\n scroll_amount?: number;\n duration?: number;\n}\n\nfunction requireCoordinate(\n input: AnthropicComputerInput,\n field: \"coordinate\" | \"start_coordinate\",\n): [number, number] {\n const value = input[field];\n if (\n !Array.isArray(value) ||\n value.length !== 2 ||\n typeof value[0] !== \"number\" ||\n typeof value[1] !== \"number\"\n ) {\n throw new ComputerActionTranslationError(\n `Anthropic computer.${input.action} requires \"${field}: [x, y]\"`,\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n return value as [number, number];\n}\n\nfunction requireText(input: AnthropicComputerInput): string {\n if (typeof input.text !== \"string\" || input.text.length === 0) {\n throw new ComputerActionTranslationError(\n `Anthropic computer.${input.action} requires non-empty \"text\"`,\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n return input.text;\n}\n\n/**\n * Translate an Anthropic `computer` tool input into the sidecar action.\n * Throws `ComputerActionTranslationError` for malformed inputs or\n * unrecognized action names; the caller should surface the error as a\n * tool_result with `is_error: true` so the model can react.\n */\nexport function translateAnthropicComputerAction(\n input: AnthropicComputerInput,\n): ComputerUseAction {\n switch (input.action) {\n case \"screenshot\":\n return { type: \"screenshot\" };\n\n case \"cursor_position\":\n return { type: \"cursor_position\" };\n\n case \"left_click\":\n case \"right_click\":\n case \"middle_click\": {\n const [x, y] = requireCoordinate(input, \"coordinate\");\n const button =\n input.action === \"left_click\"\n ? \"left\"\n : input.action === \"right_click\"\n ? \"right\"\n : \"middle\";\n return { type: \"click\", x, y, button };\n }\n\n case \"double_click\": {\n const [x, y] = requireCoordinate(input, \"coordinate\");\n return { type: \"double_click\", x, y };\n }\n\n case \"mouse_move\": {\n const [x, y] = requireCoordinate(input, \"coordinate\");\n return { type: \"move\", x, y };\n }\n\n case \"left_click_drag\": {\n const [fromX, fromY] = requireCoordinate(input, \"start_coordinate\");\n const [toX, toY] = requireCoordinate(input, \"coordinate\");\n return {\n type: \"drag\",\n from: { x: fromX, y: fromY },\n to: { x: toX, y: toY },\n };\n }\n\n case \"type\":\n return { type: \"type\", text: requireText(input) };\n\n case \"key\": {\n const text = requireText(input);\n const keys = text.split(\"+\").map((token) => normalizeKey(token.trim()));\n return { type: \"keypress\", keys };\n }\n\n case \"scroll\": {\n const [x, y] = requireCoordinate(input, \"coordinate\");\n const direction = input.scroll_direction ?? \"down\";\n const magnitude =\n typeof input.scroll_amount === \"number\" && input.scroll_amount > 0\n ? input.scroll_amount\n : 3;\n switch (direction) {\n case \"up\":\n return { type: \"scroll\", x, y, deltaY: -magnitude };\n case \"down\":\n return { type: \"scroll\", x, y, deltaY: magnitude };\n case \"left\":\n return { type: \"scroll\", x, y, deltaX: -magnitude };\n case \"right\":\n return { type: \"scroll\", x, y, deltaX: magnitude };\n default:\n throw new ComputerActionTranslationError(\n `Unknown scroll_direction \"${direction}\"`,\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n }\n\n default:\n throw new ComputerActionTranslationError(\n `Unknown Anthropic computer action: ${input.action}`,\n \"COMPUTER_USE_UNSUPPORTED_ACTION\",\n );\n }\n}\n","/**\n * OpenAI `computer_use_preview` tool → internal ComputerUseAction\n * translator.\n *\n * The OpenAI Responses API emits computer-use tool calls with action\n * objects shaped per the `computer_use_preview` spec, e.g.:\n *\n * { type: \"click\", x: 100, y: 200, button: \"left\" }\n * { type: \"drag\", path: [{ x: 0, y: 0 }, { x: 50, y: 50 }] }\n * { type: \"scroll\", x, y, scroll_x: 0, scroll_y: -3 }\n * { type: \"keypress\", keys: [\"ENTER\"] }\n *\n * These are close to but not identical to the sidecar's internal action\n * shape (`./action.ts`). The differences this translator handles:\n * - drag.path[] (start + end points) → drag.from/to\n * - scroll_x/scroll_y → deltaX/deltaY\n * - click button \"wheel\"|\"back\"|\"forward\" → unsupported error\n * - cursor_position has no OpenAI equivalent (model uses screenshots)\n */\n\nimport {\n ComputerActionTranslationError,\n type ComputerUseAction,\n normalizeKey,\n} from \"./action.js\";\n\nexport interface OpenAIComputerInput {\n type: string;\n x?: number;\n y?: number;\n button?: string;\n text?: string;\n keys?: string[];\n path?: Array<{ x: number; y: number }>;\n scroll_x?: number;\n scroll_y?: number;\n ms?: number;\n duration?: number;\n}\n\nfunction requireNumber(value: number | undefined, label: string): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new ComputerActionTranslationError(\n `OpenAI computer_use action requires numeric \"${label}\"`,\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n return value;\n}\n\nfunction requireXY(input: OpenAIComputerInput): { x: number; y: number } {\n return {\n x: requireNumber(input.x, \"x\"),\n y: requireNumber(input.y, \"y\"),\n };\n}\n\n/**\n * Translate an OpenAI `computer_use_preview` action into the sidecar\n * action. Throws `ComputerActionTranslationError` for unsupported\n * variants (wheel/back/forward buttons) or malformed inputs.\n */\nexport function translateOpenAIComputerAction(\n input: OpenAIComputerInput,\n): ComputerUseAction {\n switch (input.type) {\n case \"screenshot\":\n return { type: \"screenshot\" };\n\n case \"click\": {\n const { x, y } = requireXY(input);\n const buttonRaw = input.button ?? \"left\";\n if (\n buttonRaw !== \"left\" &&\n buttonRaw !== \"middle\" &&\n buttonRaw !== \"right\"\n ) {\n throw new ComputerActionTranslationError(\n `OpenAI computer_use click button \"${buttonRaw}\" is not supported by the sidecar (only left/middle/right)`,\n \"COMPUTER_USE_UNSUPPORTED_ACTION\",\n );\n }\n return { type: \"click\", x, y, button: buttonRaw };\n }\n\n case \"double_click\":\n return { type: \"double_click\", ...requireXY(input) };\n\n case \"move\":\n return { type: \"move\", ...requireXY(input) };\n\n case \"drag\": {\n if (!Array.isArray(input.path) || input.path.length < 2) {\n throw new ComputerActionTranslationError(\n \"OpenAI computer_use drag requires path[] with at least 2 points\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n const start = input.path[0];\n const end = input.path[input.path.length - 1];\n return {\n type: \"drag\",\n from: {\n x: requireNumber(start.x, \"path[0].x\"),\n y: requireNumber(start.y, \"path[0].y\"),\n },\n to: {\n x: requireNumber(end.x, \"path[last].x\"),\n y: requireNumber(end.y, \"path[last].y\"),\n },\n };\n }\n\n case \"type\": {\n const text = input.text;\n if (typeof text !== \"string\" || text.length === 0) {\n throw new ComputerActionTranslationError(\n 'OpenAI computer_use type action requires non-empty string \"text\"',\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n return { type: \"type\", text };\n }\n\n case \"keypress\": {\n if (!Array.isArray(input.keys) || input.keys.length === 0) {\n throw new ComputerActionTranslationError(\n \"OpenAI computer_use keypress requires non-empty keys[]\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n const keys = input.keys.map((k) => {\n if (typeof k !== \"string\" || k.length === 0) {\n throw new ComputerActionTranslationError(\n \"OpenAI computer_use keypress keys[] must be non-empty strings\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n return normalizeKey(k);\n });\n return { type: \"keypress\", keys };\n }\n\n case \"scroll\": {\n const { x, y } = requireXY(input);\n const sx =\n typeof input.scroll_x === \"number\" && Number.isFinite(input.scroll_x)\n ? input.scroll_x\n : 0;\n const sy =\n typeof input.scroll_y === \"number\" && Number.isFinite(input.scroll_y)\n ? input.scroll_y\n : 0;\n if (sx === 0 && sy === 0) {\n throw new ComputerActionTranslationError(\n \"OpenAI computer_use scroll requires non-zero scroll_x or scroll_y\",\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n const action: ComputerUseAction = { type: \"scroll\", x, y };\n if (sy !== 0) action.deltaY = sy;\n if (sx !== 0) action.deltaX = sx;\n return action;\n }\n\n case \"wait\": {\n // OpenAI's wait uses `ms`; older preview drafts used `duration`\n // (seconds). Accept both, prefer ms. Match parseAction's strict\n // contract — neither field is a hard validation error rather\n // than a silent default, so the two paths claiming this\n // vocabulary agree.\n if (typeof input.ms === \"number\" && Number.isFinite(input.ms)) {\n return { type: \"wait\", ms: Math.max(0, Math.round(input.ms)) };\n }\n if (\n typeof input.duration === \"number\" &&\n Number.isFinite(input.duration)\n ) {\n return {\n type: \"wait\",\n ms: Math.max(0, Math.round(input.duration * 1000)),\n };\n }\n throw new ComputerActionTranslationError(\n 'OpenAI computer_use wait requires numeric \"ms\" or \"duration\"',\n \"COMPUTER_USE_INVALID_ACTION\",\n );\n }\n\n default:\n throw new ComputerActionTranslationError(\n `Unknown OpenAI computer_use action type: ${input.type}`,\n \"COMPUTER_USE_UNSUPPORTED_ACTION\",\n );\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ //#region src/errors/index.ts
2
+ /** SDK error with structured metadata */
3
+ var SDKError = class SDKError extends Error {
4
+ code;
5
+ status;
6
+ retryable;
7
+ retryAfterMs;
8
+ context;
9
+ constructor(message, options) {
10
+ super(message, { cause: options.cause });
11
+ this.name = "SDKError";
12
+ this.code = options.code;
13
+ this.status = options.status;
14
+ this.retryable = options.retryable ?? this.inferRetryable(options.code, options.status);
15
+ this.retryAfterMs = options.retryAfterMs;
16
+ this.context = options.context;
17
+ }
18
+ inferRetryable(code, status) {
19
+ if (code === "NETWORK" || code === "TIMEOUT") return true;
20
+ if (code === "RATE_LIMITED") return true;
21
+ if (code === "SERVER" && status && status >= 500) return true;
22
+ if (code === "AUTH_EXPIRED") return true;
23
+ return false;
24
+ }
25
+ /** Create from HTTP response */
26
+ static fromResponse(status, body) {
27
+ const message = SDKError.extractMessageFromBody(body) ?? `HTTP ${status}`;
28
+ if (status === 401) return new SDKError(message, {
29
+ code: "AUTH",
30
+ status,
31
+ retryable: false,
32
+ context: { body }
33
+ });
34
+ if (status === 403) return new SDKError(message, {
35
+ code: "AUTH",
36
+ status,
37
+ retryable: false,
38
+ context: { body }
39
+ });
40
+ if (status === 404) return new SDKError(message, {
41
+ code: "NOT_FOUND",
42
+ status,
43
+ retryable: false,
44
+ context: { body }
45
+ });
46
+ if (status === 422 || status === 400) return new SDKError(message, {
47
+ code: "VALIDATION",
48
+ status,
49
+ retryable: false,
50
+ context: { body }
51
+ });
52
+ if (status === 429) return new SDKError(message, {
53
+ code: "RATE_LIMITED",
54
+ status,
55
+ retryable: true,
56
+ retryAfterMs: typeof body === "object" && body !== null && "retryAfter" in body ? Number(body.retryAfter) * 1e3 : 1e3,
57
+ context: { body }
58
+ });
59
+ if (status >= 500) return new SDKError(message, {
60
+ code: "SERVER",
61
+ status,
62
+ retryable: true,
63
+ context: { body }
64
+ });
65
+ return new SDKError(message, {
66
+ code: "UNKNOWN",
67
+ status,
68
+ context: { body }
69
+ });
70
+ }
71
+ /** Create from caught error */
72
+ static fromError(error) {
73
+ if (error instanceof SDKError) return error;
74
+ if (error instanceof Error) {
75
+ if (error.name === "TypeError" && error.message.includes("fetch")) return new SDKError("Network request failed", {
76
+ code: "NETWORK",
77
+ cause: error
78
+ });
79
+ if (error.name === "AbortError") return new SDKError("Request cancelled", {
80
+ code: "CANCELLED",
81
+ retryable: false,
82
+ cause: error
83
+ });
84
+ if (error.message.includes("timeout") || error.name === "TimeoutError") return new SDKError("Request timeout", {
85
+ code: "TIMEOUT",
86
+ cause: error
87
+ });
88
+ return new SDKError(error.message, {
89
+ code: "UNKNOWN",
90
+ cause: error
91
+ });
92
+ }
93
+ return new SDKError(String(error), { code: "UNKNOWN" });
94
+ }
95
+ /**
96
+ * Extract a human-readable message from a parsed error response body.
97
+ *
98
+ * Probes shapes seen across our upstreams:
99
+ * - `{ message: "..." }` — most internal services
100
+ * - `{ error: "..." }` — flat-error shape
101
+ * - `{ error: { message: "..." } }` — Hetzner Cloud API
102
+ * - `{ error: { details: "..." } }` — Hetzner field-level details
103
+ * - `string` — non-JSON text/plain errors
104
+ *
105
+ * Returns null if no message-like field is present so callers can
106
+ * fall back to "HTTP <status>". Without this, Hetzner 422s logged
107
+ * as opaque "HTTP 422" because the message lives at
108
+ * `body.error.message`, blocking diagnosis of every autoscaler
109
+ * failure (issue #785).
110
+ */
111
+ static extractMessageFromBody(body) {
112
+ if (typeof body === "string" && body.trim().length > 0) return body.length > 500 ? `${body.slice(0, 500)}…` : body;
113
+ if (typeof body !== "object" || body === null) return null;
114
+ const top = body;
115
+ if (typeof top.message === "string" && top.message.length > 0) return top.message;
116
+ if (typeof top.error === "string" && top.error.length > 0) return top.error;
117
+ if (typeof top.error === "object" && top.error !== null) {
118
+ const inner = top.error;
119
+ const message = typeof inner.message === "string" && inner.message.length > 0 ? inner.message : null;
120
+ const details = typeof inner.details === "string" && inner.details.length > 0 ? inner.details : null;
121
+ const parts = [
122
+ typeof inner.code === "string" && inner.code.length > 0 ? inner.code : null,
123
+ message,
124
+ details
125
+ ].filter((part) => part !== null);
126
+ if (parts.length > 0) return parts.join(": ");
127
+ }
128
+ return null;
129
+ }
130
+ /** Check if error is retryable after token refresh */
131
+ isAuthExpired() {
132
+ return this.code === "AUTH_EXPIRED" || this.code === "AUTH" && this.status === 401;
133
+ }
134
+ };
135
+ /** Type guard for SDKError */
136
+ function isSDKError(error) {
137
+ return error instanceof SDKError;
138
+ }
139
+ /** Type guard for retryable errors */
140
+ function isRetryable(error) {
141
+ return isSDKError(error) && error.retryable;
142
+ }
143
+ //#endregion
144
+ export { isRetryable as n, isSDKError as r, SDKError as t };
145
+
146
+ //# sourceMappingURL=errors-DJ6U6cHY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-DJ6U6cHY.js","names":[],"sources":["../src/errors/index.ts"],"sourcesContent":["/**\n * SDK Error Types\n *\n * Structured errors with codes, retry hints, and context.\n */\n\n/** Error categories for routing and handling */\nexport type ErrorCode =\n | \"NETWORK\"\n | \"TIMEOUT\"\n | \"AUTH\"\n | \"AUTH_EXPIRED\"\n | \"VALIDATION\"\n | \"NOT_FOUND\"\n | \"RATE_LIMITED\"\n | \"SERVER\"\n | \"CANCELLED\"\n | \"UNKNOWN\";\n\n/** SDK error with structured metadata */\nexport class SDKError extends Error {\n readonly code: ErrorCode;\n readonly status?: number;\n readonly retryable: boolean;\n readonly retryAfterMs?: number;\n readonly context?: Record<string, unknown>;\n\n constructor(\n message: string,\n options: {\n code: ErrorCode;\n status?: number;\n retryable?: boolean;\n retryAfterMs?: number;\n context?: Record<string, unknown>;\n cause?: Error;\n },\n ) {\n super(message, { cause: options.cause });\n this.name = \"SDKError\";\n this.code = options.code;\n this.status = options.status;\n this.retryable =\n options.retryable ?? this.inferRetryable(options.code, options.status);\n this.retryAfterMs = options.retryAfterMs;\n this.context = options.context;\n }\n\n private inferRetryable(code: ErrorCode, status?: number): boolean {\n // Network issues and server errors are typically retryable\n if (code === \"NETWORK\" || code === \"TIMEOUT\") return true;\n if (code === \"RATE_LIMITED\") return true;\n if (code === \"SERVER\" && status && status >= 500) return true;\n // Auth expired can be retried after refresh\n if (code === \"AUTH_EXPIRED\") return true;\n // Client errors are not retryable\n return false;\n }\n\n /** Create from HTTP response */\n static fromResponse(status: number, body?: unknown): SDKError {\n const message = SDKError.extractMessageFromBody(body) ?? `HTTP ${status}`;\n\n if (status === 401) {\n return new SDKError(message, {\n code: \"AUTH\",\n status,\n retryable: false,\n context: { body },\n });\n }\n if (status === 403) {\n return new SDKError(message, {\n code: \"AUTH\",\n status,\n retryable: false,\n context: { body },\n });\n }\n if (status === 404) {\n return new SDKError(message, {\n code: \"NOT_FOUND\",\n status,\n retryable: false,\n context: { body },\n });\n }\n if (status === 422 || status === 400) {\n return new SDKError(message, {\n code: \"VALIDATION\",\n status,\n retryable: false,\n context: { body },\n });\n }\n if (status === 429) {\n const retryAfter =\n typeof body === \"object\" && body !== null && \"retryAfter\" in body\n ? Number((body as { retryAfter: unknown }).retryAfter) * 1000\n : 1000;\n return new SDKError(message, {\n code: \"RATE_LIMITED\",\n status,\n retryable: true,\n retryAfterMs: retryAfter,\n context: { body },\n });\n }\n if (status >= 500) {\n return new SDKError(message, {\n code: \"SERVER\",\n status,\n retryable: true,\n context: { body },\n });\n }\n return new SDKError(message, {\n code: \"UNKNOWN\",\n status,\n context: { body },\n });\n }\n\n /** Create from caught error */\n static fromError(error: unknown): SDKError {\n if (error instanceof SDKError) return error;\n\n if (error instanceof Error) {\n // Detect network errors\n if (error.name === \"TypeError\" && error.message.includes(\"fetch\")) {\n return new SDKError(\"Network request failed\", {\n code: \"NETWORK\",\n cause: error,\n });\n }\n if (error.name === \"AbortError\") {\n return new SDKError(\"Request cancelled\", {\n code: \"CANCELLED\",\n retryable: false,\n cause: error,\n });\n }\n if (error.message.includes(\"timeout\") || error.name === \"TimeoutError\") {\n return new SDKError(\"Request timeout\", {\n code: \"TIMEOUT\",\n cause: error,\n });\n }\n return new SDKError(error.message, { code: \"UNKNOWN\", cause: error });\n }\n\n return new SDKError(String(error), { code: \"UNKNOWN\" });\n }\n\n /**\n * Extract a human-readable message from a parsed error response body.\n *\n * Probes shapes seen across our upstreams:\n * - `{ message: \"...\" }` — most internal services\n * - `{ error: \"...\" }` — flat-error shape\n * - `{ error: { message: \"...\" } }` — Hetzner Cloud API\n * - `{ error: { details: \"...\" } }` — Hetzner field-level details\n * - `string` — non-JSON text/plain errors\n *\n * Returns null if no message-like field is present so callers can\n * fall back to \"HTTP <status>\". Without this, Hetzner 422s logged\n * as opaque \"HTTP 422\" because the message lives at\n * `body.error.message`, blocking diagnosis of every autoscaler\n * failure (issue #785).\n */\n private static extractMessageFromBody(body: unknown): string | null {\n if (typeof body === \"string\" && body.trim().length > 0) {\n return body.length > 500 ? `${body.slice(0, 500)}…` : body;\n }\n if (typeof body !== \"object\" || body === null) return null;\n\n const top = body as { message?: unknown; error?: unknown };\n if (typeof top.message === \"string\" && top.message.length > 0) {\n return top.message;\n }\n if (typeof top.error === \"string\" && top.error.length > 0) {\n return top.error;\n }\n if (typeof top.error === \"object\" && top.error !== null) {\n const inner = top.error as {\n message?: unknown;\n details?: unknown;\n code?: unknown;\n };\n const message =\n typeof inner.message === \"string\" && inner.message.length > 0\n ? inner.message\n : null;\n const details =\n typeof inner.details === \"string\" && inner.details.length > 0\n ? inner.details\n : null;\n const code =\n typeof inner.code === \"string\" && inner.code.length > 0\n ? inner.code\n : null;\n const parts = [code, message, details].filter(\n (part): part is string => part !== null,\n );\n if (parts.length > 0) return parts.join(\": \");\n }\n return null;\n }\n\n /** Check if error is retryable after token refresh */\n isAuthExpired(): boolean {\n return (\n this.code === \"AUTH_EXPIRED\" ||\n (this.code === \"AUTH\" && this.status === 401)\n );\n }\n}\n\n/** Type guard for SDKError */\nexport function isSDKError(error: unknown): error is SDKError {\n return error instanceof SDKError;\n}\n\n/** Type guard for retryable errors */\nexport function isRetryable(error: unknown): boolean {\n return isSDKError(error) && error.retryable;\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { a as EventChannel, c as EventBufferConfig, i as ChannelHandler, n as EventDeduplicator, o as BufferedEvent, r as ChannelConfig, s as EventBuffer, t as DeduplicatorConfig } from "../index-DlPznmKA.js";
2
+ export { BufferedEvent, ChannelConfig, ChannelHandler, DeduplicatorConfig, EventBuffer, EventBufferConfig, EventChannel, EventDeduplicator };
@@ -0,0 +1,2 @@
1
+ import { n as EventChannel, r as EventBuffer, t as EventDeduplicator } from "../events-CUWh9qrv.js";
2
+ export { EventBuffer, EventChannel, EventDeduplicator };