mandala-computer-mcp 0.1.1 → 0.3.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 (66) hide show
  1. package/README.md +127 -16
  2. package/dist/api.d.ts +19 -6
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +261 -57
  5. package/dist/api.js.map +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +113 -8
  8. package/dist/cli.js.map +1 -1
  9. package/dist/errors.d.ts +74 -9
  10. package/dist/errors.d.ts.map +1 -1
  11. package/dist/errors.js +115 -25
  12. package/dist/errors.js.map +1 -1
  13. package/dist/events.d.ts +36 -4
  14. package/dist/events.d.ts.map +1 -1
  15. package/dist/events.js +223 -33
  16. package/dist/events.js.map +1 -1
  17. package/dist/format.d.ts +48 -0
  18. package/dist/format.d.ts.map +1 -1
  19. package/dist/format.js +31 -1
  20. package/dist/format.js.map +1 -1
  21. package/dist/http-body.d.ts +17 -0
  22. package/dist/http-body.d.ts.map +1 -0
  23. package/dist/http-body.js +48 -0
  24. package/dist/http-body.js.map +1 -0
  25. package/dist/http.d.ts.map +1 -1
  26. package/dist/http.js +177 -51
  27. package/dist/http.js.map +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +1 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/paths.d.ts +28 -18
  33. package/dist/paths.d.ts.map +1 -1
  34. package/dist/paths.js +85 -22
  35. package/dist/paths.js.map +1 -1
  36. package/dist/poll.d.ts +103 -0
  37. package/dist/poll.d.ts.map +1 -0
  38. package/dist/poll.js +129 -0
  39. package/dist/poll.js.map +1 -0
  40. package/dist/server.d.ts +1 -1
  41. package/dist/server.js +1 -1
  42. package/dist/tools/agent.d.ts.map +1 -1
  43. package/dist/tools/agent.js +14 -2
  44. package/dist/tools/agent.js.map +1 -1
  45. package/dist/tools/computers.d.ts.map +1 -1
  46. package/dist/tools/computers.js +346 -62
  47. package/dist/tools/computers.js.map +1 -1
  48. package/dist/tools/events.d.ts.map +1 -1
  49. package/dist/tools/events.js +295 -49
  50. package/dist/tools/events.js.map +1 -1
  51. package/dist/tools/guest.d.ts.map +1 -1
  52. package/dist/tools/guest.js +228 -32
  53. package/dist/tools/guest.js.map +1 -1
  54. package/dist/tools/input.d.ts.map +1 -1
  55. package/dist/tools/input.js +29 -3
  56. package/dist/tools/input.js.map +1 -1
  57. package/dist/tools/snapshots.d.ts.map +1 -1
  58. package/dist/tools/snapshots.js +478 -20
  59. package/dist/tools/snapshots.js.map +1 -1
  60. package/dist/tools/templates.d.ts.map +1 -1
  61. package/dist/tools/templates.js +52 -13
  62. package/dist/tools/templates.js.map +1 -1
  63. package/dist/tools/webhooks.d.ts.map +1 -1
  64. package/dist/tools/webhooks.js +116 -17
  65. package/dist/tools/webhooks.js.map +1 -1
  66. package/package.json +3 -2
package/dist/cli.js CHANGED
@@ -20,8 +20,10 @@ Environment
20
20
  MANDALA_MODEL_KEY an Anthropic key; enables the run_agent tool. stdio only
21
21
  — over HTTP each caller sends their own X-Model-Key, and
22
22
  this is ignored rather than spent on their runs
23
- MANDALA_NO_LIFECYCLE set to 1 to withhold create_computer, clone_computer,
24
- clone_snapshot, delete_computer and delete_snapshot
23
+ MANDALA_NO_LIFECYCLE 1, true, yes or on to withhold create_computer,
24
+ clone_computer, clone_snapshot, delete_computer and
25
+ delete_snapshot. Any other value is refused rather than
26
+ read as off, since a typo here would leave them enabled
25
27
  PORT, HOST for --http (default 3000, 127.0.0.1)
26
28
  MANDALA_ALLOWED_HOSTS, MANDALA_ALLOWED_ORIGINS
27
29
  comma-separated; which Host and Origin values to answer
@@ -39,6 +41,18 @@ Flags override the environment.`;
39
41
  * present, and anything following it is the next argument, not its value.
40
42
  */
41
43
  const BOOLEAN = new Set(['help', 'h', 'version', 'v', 'http', 'no-lifecycle']);
44
+ /**
45
+ * The yes-or-no flags whose VALUE is checked against a vocabulary.
46
+ *
47
+ * Not all of them, because the argument for refusing an unrecognised spelling
48
+ * does not reach the other four. `--http` and `--no-lifecycle` decide what the
49
+ * server exposes, so reading a misspelled no as a yes arms something — a
50
+ * listener nobody asked for, or the withholding of tools somebody wanted.
51
+ * `--help` and `--version` print and exit: nothing is armed either way, and
52
+ * refusing `--help=` would turn the one flag people reach for when they are
53
+ * already confused into another error. They keep the older, looser reading.
54
+ */
55
+ const CHECKED = new Set(['http', 'no-lifecycle']);
42
56
  const KNOWN = new Set([
43
57
  ...BOOLEAN,
44
58
  'port',
@@ -51,6 +65,61 @@ const KNOWN = new Set([
51
65
  ]);
52
66
  /** What `--http=…` may say to mean no. */
53
67
  const FALSEY = new Set(['false', '0', 'no', 'off']);
68
+ /** And its mirror, for the environment variables that are a yes-or-no. */
69
+ const TRUTHY = new Set(['true', '1', 'yes', 'on']);
70
+ /**
71
+ * The value of a yes-or-no FLAG, refusing a spelling it does not know.
72
+ *
73
+ * The same vocabulary and the same refusal as {@link envFlag} below, because
74
+ * `--no-lifecycle=…` and `MANDALA_NO_LIFECYCLE=…` are two spellings of one
75
+ * control and it would be a poor joke for them to disagree about what `yes`
76
+ * means. Only the wording of the message differs, since one names a flag and
77
+ * the other a variable.
78
+ */
79
+ function boolFlag(name, inline) {
80
+ const v = inline.trim().toLowerCase();
81
+ if (TRUTHY.has(v))
82
+ return true;
83
+ if (FALSEY.has(v))
84
+ return false;
85
+ throw new Error(`--${name}=${inline} is not a yes or a no. Use one of ${[...TRUTHY].join(', ')} to turn it ` +
86
+ `on — as does --${name} with no value at all — or one of ${[...FALSEY].join(', ')} to ` +
87
+ 'turn it off.');
88
+ }
89
+ /**
90
+ * A yes-or-no environment variable, refusing a spelling it does not know.
91
+ *
92
+ * REFUSED rather than read as no, which is the decision worth recording.
93
+ * `MANDALA_NO_LIFECYCLE` withholds the tools that create and delete computers,
94
+ * so it is a safety control, and the two wrong answers do not cost the same: an
95
+ * unrecognised value read as "no" leaves those tools registered on a server
96
+ * whose operator believes they are gone, and says nothing. A typo is far more
97
+ * likely than a deliberate `MANDALA_NO_LIFECYCLE=ture`, and the loud version
98
+ * costs one clear line at startup.
99
+ *
100
+ * Empty is unset, as everywhere else here — the ordinary shape of an unquoted
101
+ * assignment in a compose file, and `env` has already turned it into undefined.
102
+ */
103
+ function envFlag(name, raw) {
104
+ if (raw === undefined)
105
+ return false;
106
+ const v = raw.trim().toLowerCase();
107
+ // Here as well as in `env`, rather than only there. `env` folds an empty
108
+ // variable to undefined before this sees it, but that is the caller's
109
+ // behaviour and this reads as a general helper — `lifecycleEnabled` takes its
110
+ // value as a parameter, so a caller passing `process.env.X` straight in would
111
+ // otherwise refuse to start over `X=`, which is what an unquoted assignment
112
+ // in a compose file writes and what plugin.json's `${MANDALA_NO_LIFECYCLE:-}`
113
+ // expands to when it is unset.
114
+ if (!v)
115
+ return false;
116
+ if (TRUTHY.has(v))
117
+ return true;
118
+ if (FALSEY.has(v))
119
+ return false;
120
+ throw new Error(`${name}=${raw} is not a yes or a no. Use one of ${[...TRUTHY].join(', ')} to turn it on, ` +
121
+ `or one of ${[...FALSEY].join(', ')} (or leave it unset) to turn it off.`);
122
+ }
54
123
  /**
55
124
  * argv into flags.
56
125
  *
@@ -89,11 +158,43 @@ export function parse(argv) {
89
158
  // `--http=false` has to mean false. It is the one spelling that carries an
90
159
  // explicit answer, and reading it as the truthy string "false" would turn
91
160
  // the clearest way to say no into a yes.
92
- if (BOOLEAN.has(name))
93
- flags[name] = inline === undefined ? true : !FALSEY.has(inline.toLowerCase());
161
+ //
162
+ // Matched against BOTH vocabularies rather than "anything that is not a no
163
+ // is a yes", which is what this was and which made a misspelling of a NO
164
+ // into a YES. `--http=ture` started a network listener the operator was
165
+ // trying not to start, and `--no-lifecycle=fasle` withheld the tools that
166
+ // make and destroy computers from someone who meant to keep them. The
167
+ // second fails safe and the first does not, so the loose reading had to go
168
+ // (OPL-4515).
169
+ //
170
+ // Refused rather than defaulted, which is the same call `envFlag` makes one
171
+ // screen up for the environment half of the same controls, and the message
172
+ // is deliberately its twin. An empty `--http=` is refused too: it is
173
+ // neither a yes nor a no, and `--port=` is already refused for being
174
+ // neither a number nor absent. Refusing is also the only answer to `--http=`
175
+ // that neither arms nor disarms — reading it as "off" would let a launcher
176
+ // template whose variable failed to expand quietly turn a safety control
177
+ // off, which is the failure this whole change is about.
178
+ //
179
+ // Only the flags in CHECKED: `--help` and `--version` arm nothing, so the
180
+ // argument does not reach them and they keep the looser reading.
181
+ if (BOOLEAN.has(name)) {
182
+ flags[name] =
183
+ inline === undefined
184
+ ? true
185
+ : CHECKED.has(name)
186
+ ? boolFlag(name, inline)
187
+ : !FALSEY.has(inline.trim().toLowerCase());
188
+ }
94
189
  else if (inline !== undefined)
95
190
  flags[name] = inline;
96
- else if (argv[i + 1] && !argv[i + 1].startsWith('--'))
191
+ // PRESENT, not truthy. `--key ""` is a value token like any other, and a
192
+ // truthiness test skipped it: the flag became the boolean `true` and the
193
+ // empty token came round again as a stray argument, so the two spellings of
194
+ // one flag disagreed — `--key=` is the empty value `str()` documents, while
195
+ // `--key ""` died with `unexpected argument .`, naming nothing the user
196
+ // could act on.
197
+ else if (argv[i + 1] !== undefined && !argv[i + 1].startsWith('--'))
97
198
  flags[name] = argv[++i];
98
199
  else
99
200
  flags[name] = true;
@@ -115,9 +216,13 @@ export const wantsVersion = (flags) => Boolean(flags.version || flags.v);
115
216
  export function lifecycleEnabled(flags, configured = env('MANDALA_NO_LIFECYCLE')) {
116
217
  // Presence is what establishes precedence. `--no-lifecycle=false` carries a
117
218
  // false value deliberately and must not fall through to a true environment.
118
- const disabled = Object.hasOwn(flags, 'no-lifecycle')
119
- ? Boolean(flags['no-lifecycle'])
120
- : configured === '1';
219
+ // Validated before precedence is applied, and that ordering is the point. A
220
+ // misspelling is a mistake to report whether or not a flag happens to sit in
221
+ // front of it: an operator who set MANDALA_NO_LIFECYCLE=ture meaning to
222
+ // withhold the tools, under a launcher that also passes --no-lifecycle=false,
223
+ // would otherwise get exactly the silent arming this refusal exists to stop.
224
+ const fromEnv = envFlag('MANDALA_NO_LIFECYCLE', configured);
225
+ const disabled = Object.hasOwn(flags, 'no-lifecycle') ? Boolean(flags['no-lifecycle']) : fromEnv;
121
226
  return !disabled;
122
227
  }
123
228
  /**
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -19,6 +19,8 @@ export declare class MandalaError extends Error {
19
19
  export declare class APIError extends MandalaError {
20
20
  readonly status: number;
21
21
  readonly body?: unknown | undefined;
22
+ /** Parsed Retry-After delay in milliseconds; absent when missing or invalid. */
23
+ readonly retryAfterMs?: number | undefined;
22
24
  name: string;
23
25
  /**
24
26
  * The platform's own word for what KIND of refusal this is, where it sent
@@ -33,8 +35,42 @@ export declare class APIError extends MandalaError {
33
35
  * the caller who arrived a moment earlier heard.
34
36
  */
35
37
  readonly reason?: string;
36
- constructor(message: string, status: number, body?: unknown | undefined);
38
+ constructor(message: string, status: number, body?: unknown | undefined,
39
+ /** Parsed Retry-After delay in milliseconds; absent when missing or invalid. */
40
+ retryAfterMs?: number | undefined);
37
41
  }
42
+ /** Whether waiting can change a classified refusal's answer. */
43
+ export type ReasonKind = 'clears' | 'permanent';
44
+ /**
45
+ * How a refusal the platform classified behaves, or `undefined` for a word this
46
+ * version has no opinion about.
47
+ *
48
+ * The EXPORTED half of the two the sets above feed, and the split is
49
+ * deliberate. {@link reasonAdvice} beside it is this server's prose for a
50
+ * language model, tuned to how a model reads an MCP tool result and rewritten
51
+ * whenever one reads it wrong; publishing those sentences would make their
52
+ * wording something this package versions. What an embedder needs from here is
53
+ * narrower and does not move: whether waiting can change the answer.
54
+ *
55
+ * The raw word stays theirs. `APIError.reason` is public, the platform's set is
56
+ * documented and deliberately open, and switching on it is the supported path —
57
+ * this only offers the classification of the words this version knows, so an
58
+ * embedder need not duplicate a table that lives here. A word it has never
59
+ * heard of is `undefined` rather than a guess, which is the same contract
60
+ * `reasonAdvice` keeps and the reason "absent means unclassified" exists.
61
+ *
62
+ * NOT A RETRY PREDICATE. It classifies the WORD, and an error is more than its
63
+ * word: {@link isTransient} answers `MoveRequiredError` and
64
+ * {@link ConnectivityInterruptedError} before it ever looks at `reason`, because
65
+ * both are subclasses of branches that would otherwise say yes (OPL-3775,
66
+ * OPL-3855). A move-required 409 whose body also carries `reason: 'contention'`
67
+ * classifies here as `'clears'` while `isTransient` correctly says no — it is a
68
+ * decision about the size that was asked for, and it answers the same forever.
69
+ * So `if (reasonKind(err.reason) !== 'permanent') retry()` is the loop this
70
+ * sentence exists to prevent; ask {@link isTransient} whether to retry, and ask
71
+ * this what the platform's word meant.
72
+ */
73
+ export declare function reasonKind(reason: string | undefined): ReasonKind | undefined;
38
74
  /**
39
75
  * What to tell a model about a refusal the platform classified, or `undefined`.
40
76
  *
@@ -121,7 +157,7 @@ export declare class MoveRequiredError extends ConflictError {
121
157
  name: string;
122
158
  constructor(message: string, status: number, body: unknown,
123
159
  /** Whether a host in this region could run the size that was asked for. */
124
- movePossible: boolean);
160
+ movePossible: boolean, retryAfterMs?: number);
125
161
  }
126
162
  /**
127
163
  * 416 — the `Range` named no byte the file has.
@@ -141,7 +177,7 @@ export declare class RangeNotSatisfiableError extends APIError {
141
177
  name: string;
142
178
  constructor(message: string, status: number, body?: unknown,
143
179
  /** The file's real length, off `Content-Range`, when the response sent one. */
144
- size?: number | undefined);
180
+ size?: number | undefined, retryAfterMs?: number);
145
181
  }
146
182
  /**
147
183
  * 429 — the request is valid; the caller has spent a temporary rate budget.
@@ -157,12 +193,10 @@ export declare class RangeNotSatisfiableError extends APIError {
157
193
  * how a rate limit becomes a longer one.
158
194
  */
159
195
  export declare class RateLimitError extends APIError {
160
- /** From `Retry-After`, in milliseconds from now, when the response sent one. */
161
- readonly retryAfterMs?: number | undefined;
162
196
  name: string;
163
197
  constructor(message: string, status: number, body?: unknown,
164
198
  /** From `Retry-After`, in milliseconds from now, when the response sent one. */
165
- retryAfterMs?: number | undefined);
199
+ retryAfterMs?: number);
166
200
  }
167
201
  /** 503 — a hypervisor could not be reached, so an inventory would be short. */
168
202
  export declare class UnavailableError extends APIError {
@@ -310,6 +344,27 @@ export declare class GatewayTimeoutError extends APIError {
310
344
  export declare class OriginUnreachableError extends APIError {
311
345
  name: string;
312
346
  }
347
+ /**
348
+ * A 3xx, which this client answers rather than follows.
349
+ *
350
+ * Following one is the tempting default and it is wrong twice over. The bearer
351
+ * is the smaller half: `fetch` strips `Authorization` across origins but keeps
352
+ * it on a same-origin hop, so a redirect inside the configured origin carries
353
+ * the key to a path the operator did not name. The larger half is that a
354
+ * redirect is a CONFIGURATION fact — a `MANDALA_BASE_URL` missing its trailing
355
+ * path, an http URL for an https deployment, a tenant that has moved — and
356
+ * following it silently means the operator never learns the value they set is
357
+ * not the value in use, while every request pays an extra round trip forever.
358
+ *
359
+ * So it is surfaced, and it names the `Location`: the whole point is that the
360
+ * next thing the operator does is put that in `MANDALA_BASE_URL`. It is an
361
+ * `APIError` with the real status so {@link isTransientForPoll}'s `>= 500` rule
362
+ * files it with the 4xx, where it belongs — repeating the request unchanged
363
+ * cannot change the answer.
364
+ */
365
+ export declare class RedirectError extends APIError {
366
+ name: string;
367
+ }
313
368
  /**
314
369
  * 502, 520 — a proxy had no usable answer from the platform.
315
370
  *
@@ -386,7 +441,7 @@ export declare class OriginTLSError extends APIError {
386
441
  */
387
442
  export declare function platformSaid(body: unknown): string | undefined;
388
443
  /** Build the error for a status, with the platform's own message when it sent one. */
389
- export declare function errorForStatus(status: number, message: string, body?: unknown): APIError;
444
+ export declare function errorForStatus(status: number, message: string, body?: unknown, retryAfterMs?: number): APIError;
390
445
  /**
391
446
  * Whether an error is worth trying again without changing the request.
392
447
  *
@@ -537,6 +592,13 @@ export declare function isTransient(err: unknown): boolean;
537
592
  * SDK found that one; this is the same rule, and it is why all three now say
538
593
  * `>= 500`.
539
594
  *
595
+ * "Does not follow redirects" is a claim about `#fetch`'s `redirect: 'manual'`
596
+ * and is load-bearing HERE, in a way it was not while the default `'follow'`
597
+ * silently made it untrue: under `'follow'` a 3xx never reaches this predicate
598
+ * at all, so the paragraph above described a case that could not arise and the
599
+ * `>= 500` bound rested on nothing. {@link RedirectError} is what a 3xx
600
+ * becomes now. Change one and this paragraph is wrong again.
601
+ *
540
602
  * {@link APIError.reason} is deliberately NOT consulted here, and that is the
541
603
  * one place this predicate and {@link isTransient} part company (OPL-3898).
542
604
  * `unavailable` means the computer is not running, which is a permanent answer
@@ -544,8 +606,11 @@ export declare function isTransient(err: unknown): boolean;
544
606
  * may not be, since a computer coming up passes through it. The same generosity
545
607
  * as every unmapped 5xx below, for the same reason: this only ever replays a
546
608
  * read, and the loops above return a refusal of their own the moment the status
547
- * they are watching says stopped or suspended. mandala-computer-python's
548
- * `_is_transient_for_poll` draws the line in the same place.
609
+ * they are watching says stopped or suspended AND the platform says it is
610
+ * holding nothing for the machine — the qualification OPL-4631 added, because
611
+ * a start that has been admitted reads as stopped or suspended until its guest
612
+ * process exists. mandala-computer-python's `_is_transient_for_poll` draws the
613
+ * line in the same place.
549
614
  *
550
615
  * Everything at 5xx polls through, 502 and 520-523 included: they mean the
551
616
  * outcome is unknown, and a read whose outcome is unknown can simply be read
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/errors.js CHANGED
@@ -19,6 +19,7 @@ export class MandalaError extends Error {
19
19
  export class APIError extends MandalaError {
20
20
  status;
21
21
  body;
22
+ retryAfterMs;
22
23
  name = 'APIError';
23
24
  /**
24
25
  * The platform's own word for what KIND of refusal this is, where it sent
@@ -33,10 +34,13 @@ export class APIError extends MandalaError {
33
34
  * the caller who arrived a moment earlier heard.
34
35
  */
35
36
  reason;
36
- constructor(message, status, body) {
37
+ constructor(message, status, body,
38
+ /** Parsed Retry-After delay in milliseconds; absent when missing or invalid. */
39
+ retryAfterMs) {
37
40
  super(message);
38
41
  this.status = status;
39
42
  this.body = body;
43
+ this.retryAfterMs = retryAfterMs;
40
44
  this.reason = refusalReason(body);
41
45
  }
42
46
  }
@@ -54,6 +58,44 @@ export class APIError extends MandalaError {
54
58
  */
55
59
  const REASON_CLEARS = new Set(['contention', 'starting']);
56
60
  const REASON_PERMANENT = new Set(['unavailable', 'unsupported']);
61
+ /**
62
+ * How a refusal the platform classified behaves, or `undefined` for a word this
63
+ * version has no opinion about.
64
+ *
65
+ * The EXPORTED half of the two the sets above feed, and the split is
66
+ * deliberate. {@link reasonAdvice} beside it is this server's prose for a
67
+ * language model, tuned to how a model reads an MCP tool result and rewritten
68
+ * whenever one reads it wrong; publishing those sentences would make their
69
+ * wording something this package versions. What an embedder needs from here is
70
+ * narrower and does not move: whether waiting can change the answer.
71
+ *
72
+ * The raw word stays theirs. `APIError.reason` is public, the platform's set is
73
+ * documented and deliberately open, and switching on it is the supported path —
74
+ * this only offers the classification of the words this version knows, so an
75
+ * embedder need not duplicate a table that lives here. A word it has never
76
+ * heard of is `undefined` rather than a guess, which is the same contract
77
+ * `reasonAdvice` keeps and the reason "absent means unclassified" exists.
78
+ *
79
+ * NOT A RETRY PREDICATE. It classifies the WORD, and an error is more than its
80
+ * word: {@link isTransient} answers `MoveRequiredError` and
81
+ * {@link ConnectivityInterruptedError} before it ever looks at `reason`, because
82
+ * both are subclasses of branches that would otherwise say yes (OPL-3775,
83
+ * OPL-3855). A move-required 409 whose body also carries `reason: 'contention'`
84
+ * classifies here as `'clears'` while `isTransient` correctly says no — it is a
85
+ * decision about the size that was asked for, and it answers the same forever.
86
+ * So `if (reasonKind(err.reason) !== 'permanent') retry()` is the loop this
87
+ * sentence exists to prevent; ask {@link isTransient} whether to retry, and ask
88
+ * this what the platform's word meant.
89
+ */
90
+ export function reasonKind(reason) {
91
+ if (reason === undefined)
92
+ return undefined;
93
+ if (REASON_CLEARS.has(reason))
94
+ return 'clears';
95
+ if (REASON_PERMANENT.has(reason))
96
+ return 'permanent';
97
+ return undefined;
98
+ }
57
99
  /**
58
100
  * What to tell a model about a refusal the platform classified, or `undefined`.
59
101
  *
@@ -74,7 +116,14 @@ export function reasonAdvice(reason) {
74
116
  case 'starting':
75
117
  return 'the guest agent is still inside its boot window, so this is worth sending again in a moment';
76
118
  case 'unavailable':
77
- return 'the computer is not running, and this does NOT clear by waiting — start_computer is the fix, and retrying without it spends a turn every time';
119
+ // Softened from "does NOT clear by waiting", which was false of exactly
120
+ // the case OPL-4631 is about and is the sentence a model actually sees:
121
+ // the platform raises this whenever no guest process is up, so a start
122
+ // that has been admitted but has not launched yet lands here too, and
123
+ // telling that caller to start_computer is telling them to start it
124
+ // twice. This refusal cannot see the reservation — it is a
125
+ // reason code, not a computer — so it names the call that CAN.
126
+ return 'the computer is not running; if nothing is starting it this will not clear on its own and start_computer is the fix, and if a start is already under way wait_for_computer says so without starting a second one';
78
127
  case 'unsupported':
79
128
  return 'this computer cannot do it at all, so do not retry it — the answer is the same forever';
80
129
  default:
@@ -168,8 +217,8 @@ export class MoveRequiredError extends ConflictError {
168
217
  name = 'MoveRequiredError';
169
218
  constructor(message, status, body,
170
219
  /** Whether a host in this region could run the size that was asked for. */
171
- movePossible) {
172
- super(message, status, body);
220
+ movePossible, retryAfterMs) {
221
+ super(message, status, body, retryAfterMs);
173
222
  this.movePossible = movePossible;
174
223
  }
175
224
  }
@@ -210,8 +259,8 @@ export class RangeNotSatisfiableError extends APIError {
210
259
  name = 'RangeNotSatisfiableError';
211
260
  constructor(message, status, body,
212
261
  /** The file's real length, off `Content-Range`, when the response sent one. */
213
- size) {
214
- super(message, status, body);
262
+ size, retryAfterMs) {
263
+ super(message, status, body, retryAfterMs);
215
264
  this.size = size;
216
265
  }
217
266
  }
@@ -229,13 +278,12 @@ export class RangeNotSatisfiableError extends APIError {
229
278
  * how a rate limit becomes a longer one.
230
279
  */
231
280
  export class RateLimitError extends APIError {
232
- retryAfterMs;
233
281
  name = 'RateLimitError';
282
+ // biome-ignore lint/complexity/noUselessConstructor: Preserve the documented public constructor.
234
283
  constructor(message, status, body,
235
284
  /** From `Retry-After`, in milliseconds from now, when the response sent one. */
236
285
  retryAfterMs) {
237
- super(message, status, body);
238
- this.retryAfterMs = retryAfterMs;
286
+ super(message, status, body, retryAfterMs);
239
287
  }
240
288
  }
241
289
  /** 503 — a hypervisor could not be reached, so an inventory would be short. */
@@ -384,6 +432,27 @@ export class GatewayTimeoutError extends APIError {
384
432
  export class OriginUnreachableError extends APIError {
385
433
  name = 'OriginUnreachableError';
386
434
  }
435
+ /**
436
+ * A 3xx, which this client answers rather than follows.
437
+ *
438
+ * Following one is the tempting default and it is wrong twice over. The bearer
439
+ * is the smaller half: `fetch` strips `Authorization` across origins but keeps
440
+ * it on a same-origin hop, so a redirect inside the configured origin carries
441
+ * the key to a path the operator did not name. The larger half is that a
442
+ * redirect is a CONFIGURATION fact — a `MANDALA_BASE_URL` missing its trailing
443
+ * path, an http URL for an https deployment, a tenant that has moved — and
444
+ * following it silently means the operator never learns the value they set is
445
+ * not the value in use, while every request pays an extra round trip forever.
446
+ *
447
+ * So it is surfaced, and it names the `Location`: the whole point is that the
448
+ * next thing the operator does is put that in `MANDALA_BASE_URL`. It is an
449
+ * `APIError` with the real status so {@link isTransientForPoll}'s `>= 500` rule
450
+ * files it with the 4xx, where it belongs — repeating the request unchanged
451
+ * cannot change the answer.
452
+ */
453
+ export class RedirectError extends APIError {
454
+ name = 'RedirectError';
455
+ }
387
456
  /**
388
457
  * 502, 520 — a proxy had no usable answer from the platform.
389
458
  *
@@ -452,11 +521,8 @@ const BY_STATUS = {
452
521
  // arriving from anywhere else is still the right class with the platform's
453
522
  // own message on it.
454
523
  416: RangeNotSatisfiableError,
455
- // Reached through errorForStatus only when the response headers were not in
456
- // hand — Api.#error builds this one itself, for RangeNotSatisfiableError's
457
- // reason: `Retry-After` is on the headers and the number is worth keeping.
458
- // The entry is here so a 429 arriving from anywhere else is still the right
459
- // class, which is what {@link isTransient} now asks about.
524
+ // Retry-After is parsed by Api and passed through errorForStatus.
525
+ // A 429 built without headers still has the same public error class.
460
526
  429: RateLimitError,
461
527
  // The other status a proxy writes on its own, and it was the one gap left in
462
528
  // this range: with no entry it fell through to a bare APIError, so a model
@@ -615,7 +681,7 @@ export function platformSaid(body) {
615
681
  return typeof err === 'string' && err.length > 0 ? err : undefined;
616
682
  }
617
683
  /** Build the error for a status, with the platform's own message when it sent one. */
618
- export function errorForStatus(status, message, body) {
684
+ export function errorForStatus(status, message, body, retryAfterMs) {
619
685
  const Cls = BY_STATUS[status] ?? APIError;
620
686
  // The 409 that is an offer, told apart by its body. Before the substitutions
621
687
  // below because it never wants one: the platform's sentence here is the whole
@@ -624,7 +690,10 @@ export function errorForStatus(status, message, body) {
624
690
  if (Cls === ConflictError) {
625
691
  const offer = moveOffer(body);
626
692
  if (offer)
627
- return new MoveRequiredError(message, status, body, offer.possible);
693
+ return new MoveRequiredError(message, status, body, offer.possible, retryAfterMs);
694
+ }
695
+ if (Cls === RangeNotSatisfiableError) {
696
+ return new RangeNotSatisfiableError(message, status, body, undefined, retryAfterMs);
628
697
  }
629
698
  // Substituted for an empty body, which says nothing, and for a proxy's HTML
630
699
  // page, which says 500 characters of nothing. NOT for a structured message:
@@ -641,21 +710,21 @@ export function errorForStatus(status, message, body) {
641
710
  // that deployment than the generic outage prose here does, and discarding it
642
711
  // was the very thing the 504 and 520 guards exist to prevent.
643
712
  if (Cls === GatewayTimeoutError && !platformNamed(body)) {
644
- return new GatewayTimeoutError(gatewayTimeoutMessage(status), status, body);
713
+ return new GatewayTimeoutError(gatewayTimeoutMessage(status), status, body, retryAfterMs);
645
714
  }
646
715
  if (Cls === OriginResponseError && !platformNamed(body)) {
647
716
  // 502 and 520 share a class and not a message: one knows the request
648
717
  // arrived, the other cannot tell. See BAD_GATEWAY_MESSAGE.
649
718
  const said = status === 502 ? BAD_GATEWAY_MESSAGE : ORIGIN_RESPONSE_MESSAGE;
650
- return new OriginResponseError(said, status, body);
719
+ return new OriginResponseError(said, status, body, retryAfterMs);
651
720
  }
652
721
  if (Cls === OriginTLSError && !platformNamed(body)) {
653
- return new OriginTLSError(ORIGIN_TLS_MESSAGE, status, body);
722
+ return new OriginTLSError(ORIGIN_TLS_MESSAGE, status, body, retryAfterMs);
654
723
  }
655
724
  if (Cls === OriginUnreachableError && !platformNamed(body)) {
656
- return new OriginUnreachableError(ORIGIN_UNREACHABLE_MESSAGE, status, body);
725
+ return new OriginUnreachableError(ORIGIN_UNREACHABLE_MESSAGE, status, body, retryAfterMs);
657
726
  }
658
- return new Cls(message, status, body);
727
+ return new Cls(message, status, body, retryAfterMs);
659
728
  }
660
729
  /**
661
730
  * Whether an error is worth trying again without changing the request.
@@ -730,6 +799,14 @@ export function errorForStatus(status, message, body) {
730
799
  * what it can and cannot tell apart.
731
800
  */
732
801
  export function isTransient(err) {
802
+ // Preparation requires the original template and a token, and may have failed.
803
+ // A generic retry of the unchanged create is not the continuation protocol.
804
+ if (err instanceof APIError &&
805
+ err.body !== null &&
806
+ typeof err.body === 'object' &&
807
+ err.body.code === 'template_image_preparing') {
808
+ return false;
809
+ }
733
810
  // A move offer is a 409 and is NOT transient — it is a decision about the
734
811
  // size that was asked for, and the same request answers the same way forever.
735
812
  // First, because it is a subclass of the very branch below that would say yes
@@ -748,9 +825,12 @@ export function isTransient(err) {
748
825
  // an arbitrary exception may happen to have a `reason` property, and that is
749
826
  // neither this protocol nor retry advice.
750
827
  if (err instanceof APIError && err.reason !== undefined) {
751
- if (REASON_CLEARS.has(err.reason))
828
+ // Through the exported classifier rather than the sets directly, so what an
829
+ // embedder is told and what this server does are one answer and not two.
830
+ const kind = reasonKind(err.reason);
831
+ if (kind === 'clears')
752
832
  return true;
753
- if (REASON_PERMANENT.has(err.reason))
833
+ if (kind === 'permanent')
754
834
  return false;
755
835
  }
756
836
  return (err instanceof ConflictError ||
@@ -835,6 +915,13 @@ export function isTransient(err) {
835
915
  * SDK found that one; this is the same rule, and it is why all three now say
836
916
  * `>= 500`.
837
917
  *
918
+ * "Does not follow redirects" is a claim about `#fetch`'s `redirect: 'manual'`
919
+ * and is load-bearing HERE, in a way it was not while the default `'follow'`
920
+ * silently made it untrue: under `'follow'` a 3xx never reaches this predicate
921
+ * at all, so the paragraph above described a case that could not arise and the
922
+ * `>= 500` bound rested on nothing. {@link RedirectError} is what a 3xx
923
+ * becomes now. Change one and this paragraph is wrong again.
924
+ *
838
925
  * {@link APIError.reason} is deliberately NOT consulted here, and that is the
839
926
  * one place this predicate and {@link isTransient} part company (OPL-3898).
840
927
  * `unavailable` means the computer is not running, which is a permanent answer
@@ -842,8 +929,11 @@ export function isTransient(err) {
842
929
  * may not be, since a computer coming up passes through it. The same generosity
843
930
  * as every unmapped 5xx below, for the same reason: this only ever replays a
844
931
  * read, and the loops above return a refusal of their own the moment the status
845
- * they are watching says stopped or suspended. mandala-computer-python's
846
- * `_is_transient_for_poll` draws the line in the same place.
932
+ * they are watching says stopped or suspended AND the platform says it is
933
+ * holding nothing for the machine — the qualification OPL-4631 added, because
934
+ * a start that has been admitted reads as stopped or suspended until its guest
935
+ * process exists. mandala-computer-python's `_is_transient_for_poll` draws the
936
+ * line in the same place.
847
937
  *
848
938
  * Everything at 5xx polls through, 502 and 520-523 included: they mean the
849
939
  * outcome is unknown, and a read whose outcome is unknown can simply be read