@hue-run/sdk 0.20.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLI.md +10 -10
- package/README.md +2 -2
- package/WORLDS.md +14 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/world/client.d.ts +13 -2
- package/dist/world/client.js +24 -5
- package/dist/world/model-types.d.ts +8 -2
- package/dist/world/models.d.ts +3 -1
- package/dist/world/readiness.d.ts +18 -0
- package/dist/world/readiness.js +69 -0
- package/package.json +1 -1
package/CLI.md
CHANGED
|
@@ -42,7 +42,7 @@ project manifest are refused because managers can update ancestor locks; Python
|
|
|
42
42
|
The generated `hue.setup.mjs` or `hue_setup.py` always selects `captureContent: false` /
|
|
43
43
|
`capture_content=False`. For a supported application, setup installs the dependency and adds the
|
|
44
44
|
managed import and middleware registration to the existing entrypoint; an unreferenced helper is
|
|
45
|
-
not a completed integration. TypeScript uses `@hue-run/sdk@0.20.
|
|
45
|
+
not a completed integration. TypeScript uses `@hue-run/sdk@0.20.1`, `@opentelemetry/api@1.9.1` and
|
|
46
46
|
`@opentelemetry/context-async-hooks@2.11.0`; Python setup uses its separately tested package pin.
|
|
47
47
|
Content capture requires an ordinary account-managed key and a later explicit application decision.
|
|
48
48
|
|
|
@@ -379,8 +379,8 @@ and Hue never receives or stores them. The command is part of the `hue` executab
|
|
|
379
379
|
# LANGFUSE_PUBLIC_KEY=pk-lf-...
|
|
380
380
|
# LANGFUSE_SECRET_KEY=sk-lf-...
|
|
381
381
|
# LANGFUSE_BASE_URL=https://cloud.langfuse.com
|
|
382
|
-
npx -y @hue-run/sdk@0.20.
|
|
383
|
-
npx -y @hue-run/sdk@0.20.
|
|
382
|
+
npx -y @hue-run/sdk@0.20.1 import langfuse --env-path .env.langfuse --from 2026-01-01 --dry-run
|
|
383
|
+
npx -y @hue-run/sdk@0.20.1 import langfuse --env-path .env.langfuse --from 2026-01-01 --media
|
|
384
384
|
```
|
|
385
385
|
|
|
386
386
|
`LANGFUSE_PUBLIC_KEY` and `LANGFUSE_SECRET_KEY` come from the environment or `--env-path`
|
|
@@ -595,7 +595,7 @@ node packages/sdk-typescript/scripts/verify-package.mjs --artifacts-dir .artifac
|
|
|
595
595
|
# Set project to an existing supported fixture; use the same directory on resume.
|
|
596
596
|
project=/absolute/path/to/supported-fixture
|
|
597
597
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
598
|
-
--archive .artifacts/typescript/hue-run-sdk-0.20.
|
|
598
|
+
--archive .artifacts/typescript/hue-run-sdk-0.20.1.tgz \
|
|
599
599
|
--origin https://STAGING_ORIGIN \
|
|
600
600
|
--project "$project" --command setup \
|
|
601
601
|
--evidence .context/setup-staging-before-claim.json
|
|
@@ -606,7 +606,7 @@ the private local handoff and finish the real browser claim, then reconcile the
|
|
|
606
606
|
|
|
607
607
|
```sh
|
|
608
608
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
609
|
-
--archive .artifacts/typescript/hue-run-sdk-0.20.
|
|
609
|
+
--archive .artifacts/typescript/hue-run-sdk-0.20.1.tgz \
|
|
610
610
|
--origin https://STAGING_ORIGIN \
|
|
611
611
|
--project "$project" --command claim \
|
|
612
612
|
--evidence .context/setup-staging-after-claim.json
|
|
@@ -648,10 +648,10 @@ otherwise. Never hand the agent Hue-native tools (`context.tools`, `context.mcp`
|
|
|
648
648
|
production agent lacks. Pin the SDK, so the agent's repository gains no dependency:
|
|
649
649
|
|
|
650
650
|
```sh
|
|
651
|
-
npx -y @hue-run/sdk@0.20.
|
|
652
|
-
npx -y @hue-run/sdk@0.20.
|
|
653
|
-
npx -y @hue-run/sdk@0.20.
|
|
654
|
-
npx -y @hue-run/sdk@0.20.
|
|
651
|
+
npx -y @hue-run/sdk@0.20.1 eval --case "Refund an eligible charge" --command "node agent.js"
|
|
652
|
+
npx -y @hue-run/sdk@0.20.1 eval --case https://app.hue.run/projects/demo/scenarios/<id> --command "python agent.py" --timeout 120 --baseline <run id>
|
|
653
|
+
npx -y @hue-run/sdk@0.20.1 eval --set "Billing regressions" --scorer-version <id> --command "node agent.js" --save-version
|
|
654
|
+
npx -y @hue-run/sdk@0.20.1 eval --worker --command "node agent.js" --agent-key support-agent --revision <new-agent-revision>
|
|
655
655
|
```
|
|
656
656
|
|
|
657
657
|
One invocation creates one run holding every selected case; it prints the run URL
|
|
@@ -689,7 +689,7 @@ export default function runMyAgent(inputs: JsonValue, context: SimulationTargetC
|
|
|
689
689
|
```
|
|
690
690
|
|
|
691
691
|
```sh
|
|
692
|
-
npx -y @hue-run/sdk@0.20.
|
|
692
|
+
npx -y @hue-run/sdk@0.20.1 eval --case "Refund an eligible charge" ./hue-agent.ts --content
|
|
693
693
|
```
|
|
694
694
|
|
|
695
695
|
`--scenario` remains an alias for `--case` for existing scripts. Pass one selection flag.
|
package/README.md
CHANGED
|
@@ -536,8 +536,8 @@ the Langfuse project's own keys (`LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`, a
|
|
|
536
536
|
`HUE_API_KEY`:
|
|
537
537
|
|
|
538
538
|
```sh
|
|
539
|
-
npx -y @hue-run/sdk@0.20.
|
|
540
|
-
npx -y @hue-run/sdk@0.20.
|
|
539
|
+
npx -y @hue-run/sdk@0.20.1 import langfuse --env-path .env.langfuse --from 2026-01-01 --dry-run
|
|
540
|
+
npx -y @hue-run/sdk@0.20.1 import langfuse --env-path .env.langfuse --from 2026-01-01 --media
|
|
541
541
|
```
|
|
542
542
|
|
|
543
543
|
- It reads Langfuse Cloud and self-hosted v4 through the Observations API v2, and self-hosted v3
|
package/WORLDS.md
CHANGED
|
@@ -13,8 +13,9 @@ Your agent runs in your process while a disposable simulated world runs in Hue.
|
|
|
13
13
|
authoritative and records an ordered journal; Hue does not execute your agent code or provider
|
|
14
14
|
credentials.
|
|
15
15
|
|
|
16
|
-
A World is
|
|
17
|
-
state. Starting another instance does not
|
|
16
|
+
A World model is retained entity history. A World is a reconstructed starting state. A World
|
|
17
|
+
instance is an isolated running copy of that state. Starting another World instance does not
|
|
18
|
+
share the first World instance's changes. The handoff's
|
|
18
19
|
legacy `worldId` field identifies the runtime instance, not a durable World model.
|
|
19
20
|
|
|
20
21
|
## Reconstruct a user's World
|
|
@@ -52,6 +53,14 @@ reports that the World is preparing. Retries preserve the same request bytes and
|
|
|
52
53
|
Other failures keep the client's `maxAttempts` limit. Pass `{ signal }` as the last options
|
|
53
54
|
argument to cancel a preparation wait or an active request.
|
|
54
55
|
|
|
56
|
+
When the service reports preparation progress, `worldModel.processing` distinguishes retained
|
|
57
|
+
evidence from indexed evidence. A start's `preparation` also includes the selected evidence
|
|
58
|
+
cutoff. `HueWorldError.preparation` exposes the same bounded progress on a preparation refusal.
|
|
59
|
+
Insufficient evidence and processing limits stop identical retries. Useful later evidence or an
|
|
60
|
+
interpreter update can prepare the same unfinished request automatically. Retrying its original
|
|
61
|
+
idempotency key starts the first usable World selected for that request. Preparation requires no
|
|
62
|
+
review or publish action.
|
|
63
|
+
|
|
55
64
|
`listModels` and `listAccounts` accept `after` and `limit` for pagination. Use each account's
|
|
56
65
|
`providerInstanceKey` to distinguish connections, including several accounts for one app.
|
|
57
66
|
|
|
@@ -112,7 +121,9 @@ OAuth tokens or provider credentials in these fields.
|
|
|
112
121
|
|
|
113
122
|
## Publish an authored World
|
|
114
123
|
|
|
115
|
-
`createWorldClient`
|
|
124
|
+
`createWorldClient` uses `createWorld`, `listWorlds` and `getWorld` for World identities.
|
|
125
|
+
The compatibility names `createEnvironment`, `listEnvironments` and `getEnvironment` remain
|
|
126
|
+
available. The client also publishes authored definitions and starts World instances from their
|
|
116
127
|
immutable versions. Use `WorldDefinitionV2` and `WorldProviderInstance` for arbitrary registered
|
|
117
128
|
apps and multiple accounts of the same app. The deployment validates each app's JSON
|
|
118
129
|
configuration and supported dialects.
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Package version shared by the instrumentation scope and the export User-Agent. */
|
|
2
|
-
export declare const sdkVersion = "0.20.
|
|
2
|
+
export declare const sdkVersion = "0.20.1";
|
package/dist/version.js
CHANGED
package/dist/world/client.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type WorldPreparationProgress } from "./readiness.js";
|
|
1
2
|
import type { ActionInput, ActionResult, CoverageGapInput, CoverageGapResult, CreateRunInput, Environment, PublishableEnvironmentDefinition, EnvironmentIdentity, EnvironmentPage, EnvironmentPageOptions, EnvironmentRun, EnvironmentSummary, EnvironmentVersion, EnvironmentVersionSummary, FinishRunInput, SealedRun, StepPage, StepPageOptions, WorldEvidence, WorldEvidenceOptions } from "./types.js";
|
|
2
3
|
import type { PublishableWorldDefinition, WorldVersion } from "./definitions.js";
|
|
3
4
|
/** Connection and retry options for {@link createEnvironmentClient}. */
|
|
@@ -19,13 +20,17 @@ export declare class HueEnvironmentError extends Error {
|
|
|
19
20
|
readonly retryAfterMs?: number | undefined;
|
|
20
21
|
/** The server's `X-Hue-Diagnostic` code, when it is a short snake-case value. */
|
|
21
22
|
readonly diagnostic?: string | undefined;
|
|
23
|
+
/** Bounded, sanitized progress for a World preparation refusal. */
|
|
24
|
+
readonly preparation?: WorldPreparationProgress | undefined;
|
|
22
25
|
constructor(
|
|
23
26
|
/** HTTP status when Hue answered; absent for transport, timeout or parse failure. */
|
|
24
27
|
status?: number | undefined,
|
|
25
28
|
/** Hue's `Retry-After` in milliseconds, bounded, when a 429 or 503 carried one. */
|
|
26
29
|
retryAfterMs?: number | undefined,
|
|
27
30
|
/** The server's `X-Hue-Diagnostic` code, when it is a short snake-case value. */
|
|
28
|
-
diagnostic?: string | undefined
|
|
31
|
+
diagnostic?: string | undefined,
|
|
32
|
+
/** Bounded, sanitized progress for a World preparation refusal. */
|
|
33
|
+
preparation?: WorldPreparationProgress | undefined);
|
|
29
34
|
}
|
|
30
35
|
/** Starts one isolated instance from an immutable World version. */
|
|
31
36
|
export interface CreateInstanceInput extends Omit<CreateRunInput, "environmentVersionId"> {
|
|
@@ -34,7 +39,7 @@ export interface CreateInstanceInput extends Omit<CreateRunInput, "environmentVe
|
|
|
34
39
|
}
|
|
35
40
|
/** A connection failure or a status the client retries; seal polling continues through these. */
|
|
36
41
|
export declare function isTransientEnvironmentError(error: unknown): boolean;
|
|
37
|
-
/** Typed client for authored
|
|
42
|
+
/** Typed client for authored Worlds, isolated World instances and immutable journals. */
|
|
38
43
|
export declare class WorldClient {
|
|
39
44
|
#private;
|
|
40
45
|
/** Validated Hue origin. */
|
|
@@ -79,6 +84,12 @@ export declare class WorldClient {
|
|
|
79
84
|
}>;
|
|
80
85
|
/** Completes or abandons one instance and freezes its evidence. */
|
|
81
86
|
finishInstance(instanceId: string, input: FinishRunInput): Promise<SealedRun>;
|
|
87
|
+
/** Creates a World identity using the client's resource routes. */
|
|
88
|
+
createWorld(input: EnvironmentIdentity): Promise<EnvironmentSummary>;
|
|
89
|
+
/** Lists active Worlds. */
|
|
90
|
+
listWorlds(page?: EnvironmentPageOptions): Promise<EnvironmentPage>;
|
|
91
|
+
/** Reads a World and its immutable version summaries. */
|
|
92
|
+
getWorld(id: string): Promise<Environment>;
|
|
82
93
|
/** Creates an environment identity; this non-idempotent registry write is not retried. */
|
|
83
94
|
createEnvironment(input: EnvironmentIdentity): Promise<EnvironmentSummary>;
|
|
84
95
|
/** Lists active environment identities. */
|
package/dist/world/client.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readWorldPreparation, TERMINAL_WORLD_DIAGNOSTICS, } from "./readiness.js";
|
|
1
2
|
import { validateOptions } from "../config.js";
|
|
2
3
|
import { aggregateBounds, json, uuid, valueBounds } from "../evals/json.js";
|
|
3
4
|
/** Sanitized environment API failure that never includes response text or credentials. */
|
|
@@ -5,19 +6,23 @@ export class HueEnvironmentError extends Error {
|
|
|
5
6
|
status;
|
|
6
7
|
retryAfterMs;
|
|
7
8
|
diagnostic;
|
|
9
|
+
preparation;
|
|
8
10
|
constructor(
|
|
9
11
|
/** HTTP status when Hue answered; absent for transport, timeout or parse failure. */
|
|
10
12
|
status,
|
|
11
13
|
/** Hue's `Retry-After` in milliseconds, bounded, when a 429 or 503 carried one. */
|
|
12
14
|
retryAfterMs,
|
|
13
15
|
/** The server's `X-Hue-Diagnostic` code, when it is a short snake-case value. */
|
|
14
|
-
diagnostic
|
|
16
|
+
diagnostic,
|
|
17
|
+
/** Bounded, sanitized progress for a World preparation refusal. */
|
|
18
|
+
preparation) {
|
|
15
19
|
super(status
|
|
16
20
|
? `Hue environment request failed (HTTP ${status}${diagnostic ? `, ${diagnostic}` : ""})`
|
|
17
21
|
: "Hue environment connection or response failed");
|
|
18
22
|
this.status = status;
|
|
19
23
|
this.retryAfterMs = retryAfterMs;
|
|
20
24
|
this.diagnostic = diagnostic;
|
|
25
|
+
this.preparation = preparation;
|
|
21
26
|
this.name = "HueEnvironmentError";
|
|
22
27
|
}
|
|
23
28
|
}
|
|
@@ -31,7 +36,8 @@ const RETRYABLE = new Set([408, 429, 500, 502, 503, 504]);
|
|
|
31
36
|
/** A connection failure or a status the client retries; seal polling continues through these. */
|
|
32
37
|
export function isTransientEnvironmentError(error) {
|
|
33
38
|
return (error instanceof HueEnvironmentError &&
|
|
34
|
-
(error.status === undefined || RETRYABLE.has(error.status))
|
|
39
|
+
(error.status === undefined || RETRYABLE.has(error.status)) &&
|
|
40
|
+
!(error.status === 503 && TERMINAL_WORLD_DIAGNOSTICS.has(error.diagnostic ?? "")));
|
|
35
41
|
}
|
|
36
42
|
/** A `Retry-After` longer than this waits this long: Hue asks for a second, never minutes. */
|
|
37
43
|
const MAX_RETRY_AFTER_MS = 10_000;
|
|
@@ -59,7 +65,7 @@ const REQUEST_BOUNDS = { ...valueBounds, bytes: 1024 * 1024 };
|
|
|
59
65
|
* definition without relaxing action/run request envelopes.
|
|
60
66
|
*/
|
|
61
67
|
const ENVIRONMENT_PUBLICATION_BOUNDS = aggregateBounds(240_000 + 32);
|
|
62
|
-
/** Typed client for authored
|
|
68
|
+
/** Typed client for authored Worlds, isolated World instances and immutable journals. */
|
|
63
69
|
export class WorldClient {
|
|
64
70
|
/** Validated Hue origin. */
|
|
65
71
|
baseUrl;
|
|
@@ -106,8 +112,9 @@ export class WorldClient {
|
|
|
106
112
|
throw new HueEnvironmentError();
|
|
107
113
|
}
|
|
108
114
|
if (!response.ok) {
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
const diagnostic = diagnosticOf(response);
|
|
116
|
+
const preparation = await readWorldPreparation(response, diagnostic);
|
|
117
|
+
throw new HueEnvironmentError(response.status, response.status === 429 || response.status === 503 ? retryAfterMillis(response) : undefined, diagnostic, preparation);
|
|
111
118
|
}
|
|
112
119
|
try {
|
|
113
120
|
const reader = response.body?.getReader();
|
|
@@ -246,6 +253,18 @@ export class WorldClient {
|
|
|
246
253
|
finishInstance(instanceId, input) {
|
|
247
254
|
return this.finishRun(instanceId, input);
|
|
248
255
|
}
|
|
256
|
+
/** Creates a World identity using the client's resource routes. */
|
|
257
|
+
createWorld(input) {
|
|
258
|
+
return this.createEnvironment(input);
|
|
259
|
+
}
|
|
260
|
+
/** Lists active Worlds. */
|
|
261
|
+
listWorlds(page) {
|
|
262
|
+
return this.listEnvironments(page);
|
|
263
|
+
}
|
|
264
|
+
/** Reads a World and its immutable version summaries. */
|
|
265
|
+
getWorld(id) {
|
|
266
|
+
return this.getEnvironment(id);
|
|
267
|
+
}
|
|
249
268
|
/** Creates an environment identity; this non-idempotent registry write is not retried. */
|
|
250
269
|
createEnvironment(input) {
|
|
251
270
|
return this.requestOnce("POST", "/environments", input);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { WorldModelProcessing, WorldPreparationProgress } from "./readiness.js";
|
|
2
|
+
export type { WorldModelProcessing, WorldPreparationProgress } from "./readiness.js";
|
|
1
3
|
/** Project-scoped identity of the user or entity represented by a World model. */
|
|
2
4
|
export interface WorldEntity {
|
|
3
5
|
/** Identifier namespace, such as the application's user namespace. */
|
|
@@ -21,8 +23,10 @@ export interface WorldModel {
|
|
|
21
23
|
lastUsedAt: string | null;
|
|
22
24
|
/** Committed evidence sequence used for reconstruction. */
|
|
23
25
|
evidenceCutoff: number;
|
|
24
|
-
/**
|
|
26
|
+
/** Legacy retention or erasure state. Read `processing` for current indexing progress. */
|
|
25
27
|
status: "ready" | "preparing" | "erased";
|
|
28
|
+
/** Retained and indexed progress, when reported by Hue. */
|
|
29
|
+
processing?: WorldModelProcessing;
|
|
26
30
|
}
|
|
27
31
|
/** One app account bound to a World model. */
|
|
28
32
|
export interface WorldModelAccount {
|
|
@@ -53,7 +57,7 @@ export interface StartingWorld {
|
|
|
53
57
|
evidenceCutoff: number;
|
|
54
58
|
/** Immutable starting-state digest, or null while preparation is incomplete. */
|
|
55
59
|
digest: string | null;
|
|
56
|
-
/**
|
|
60
|
+
/** Starting-state preparation status. */
|
|
57
61
|
status: "ready" | "preparing";
|
|
58
62
|
}
|
|
59
63
|
/** Bounded pagination over World models or their accounts. */
|
|
@@ -109,6 +113,8 @@ export interface WorldModelResult {
|
|
|
109
113
|
export interface StartingWorldResult {
|
|
110
114
|
/** Immutable starting state, or an explicit preparing state. */
|
|
111
115
|
world: StartingWorld;
|
|
116
|
+
/** Progress of this requested starting World, when reported by Hue. */
|
|
117
|
+
preparation?: WorldPreparationProgress;
|
|
112
118
|
}
|
|
113
119
|
/** Acknowledgement that the World model has been erased. */
|
|
114
120
|
export interface ErasedWorldModel {
|
package/dist/world/models.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WorldClient, type WorldClientOptions } from "./client.js";
|
|
2
|
-
import type { CreateWorldModelInput, WorldModelResult, StartingWorldResult, ErasedWorldModel, ReproduceWorldInstanceInput, StartingWorld, StartWorldInstanceInput, WorldModelAccountPage, WorldModelPage, WorldModelPageOptions } from "./model-types.js";
|
|
2
|
+
import type { CreateWorldModelInput, WorldModelResult, StartingWorldResult, ErasedWorldModel, ReproduceWorldInstanceInput, StartingWorld, StartWorldInstanceInput, WorldModelAccountPage, WorldModelPage, WorldModelPageOptions, WorldPreparationProgress } from "./model-types.js";
|
|
3
3
|
import type { WorldHandoff } from "./types.js";
|
|
4
4
|
/** Reconstructed starting World and its isolated runtime connection. */
|
|
5
5
|
export interface WorldInstanceResult {
|
|
@@ -7,6 +7,8 @@ export interface WorldInstanceResult {
|
|
|
7
7
|
world: StartingWorld;
|
|
8
8
|
/** Fresh, instance-scoped connection and credentials. */
|
|
9
9
|
instance: WorldHandoff;
|
|
10
|
+
/** Progress of this requested starting World, when reported by Hue. */
|
|
11
|
+
preparation?: WorldPreparationProgress;
|
|
10
12
|
}
|
|
11
13
|
/** Project-key client for entity histories, reconstructed Worlds and isolated instances. */
|
|
12
14
|
export declare class WorldModelClient extends WorldClient {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Progress of one requested starting World. */
|
|
2
|
+
export interface WorldPreparationProgress {
|
|
3
|
+
/** Whether the request is preparing, usable, or waiting for changed evidence or dependencies. */
|
|
4
|
+
state: "preparing" | "insufficient_evidence" | "processing_limit" | "dependency_unavailable" | "ready";
|
|
5
|
+
/** Evidence cutoff selected for this request. */
|
|
6
|
+
selectedEvidenceCutoff: number;
|
|
7
|
+
/** Latest retained evidence cutoff. */
|
|
8
|
+
retainedEvidenceCutoff: number;
|
|
9
|
+
/** Latest indexed evidence cutoff for the current interpretation. */
|
|
10
|
+
readyEvidenceCutoff: number;
|
|
11
|
+
/** Whether retained evidence is still waiting for indexing. */
|
|
12
|
+
pendingEvidence: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Retained and indexed progress of an entity history. */
|
|
15
|
+
export interface WorldModelProcessing extends Omit<WorldPreparationProgress, "state" | "selectedEvidenceCutoff"> {
|
|
16
|
+
/** Indexing progress; a requested represented time may still lack required evidence. */
|
|
17
|
+
state: "indexed" | "preparing" | "insufficient_evidence" | "processing_limit" | "dependency_unavailable";
|
|
18
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const diagnosticStates = {
|
|
2
|
+
world_preparing: "preparing",
|
|
3
|
+
world_insufficient_evidence: "insufficient_evidence",
|
|
4
|
+
world_processing_limit: "processing_limit",
|
|
5
|
+
world_dependency_unavailable: "dependency_unavailable",
|
|
6
|
+
};
|
|
7
|
+
/** @internal Only numeric progress and an allowlisted state cross the error boundary. */
|
|
8
|
+
export async function readWorldPreparation(response, diagnostic) {
|
|
9
|
+
if (response.status !== 503 || diagnostic === undefined || !(diagnostic in diagnosticStates)) {
|
|
10
|
+
await response.body?.cancel().catch(() => { });
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
const reader = response.body?.getReader();
|
|
14
|
+
if (!reader)
|
|
15
|
+
return undefined;
|
|
16
|
+
try {
|
|
17
|
+
const chunks = [];
|
|
18
|
+
let size = 0;
|
|
19
|
+
for (;;) {
|
|
20
|
+
const { done, value } = await reader.read();
|
|
21
|
+
if (done)
|
|
22
|
+
break;
|
|
23
|
+
size += value.byteLength;
|
|
24
|
+
if (size > 16 * 1024)
|
|
25
|
+
return undefined;
|
|
26
|
+
chunks.push(value);
|
|
27
|
+
}
|
|
28
|
+
const body = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
29
|
+
if (!body || typeof body !== "object" || !("preparation" in body))
|
|
30
|
+
return undefined;
|
|
31
|
+
const value = body.preparation;
|
|
32
|
+
if (!value || typeof value !== "object")
|
|
33
|
+
return undefined;
|
|
34
|
+
const { state, selectedEvidenceCutoff: selected, retainedEvidenceCutoff: retained, readyEvidenceCutoff: ready, pendingEvidence, } = value;
|
|
35
|
+
const expectedState = diagnosticStates[diagnostic];
|
|
36
|
+
if (expectedState === undefined ||
|
|
37
|
+
state !== expectedState ||
|
|
38
|
+
!Number.isSafeInteger(selected) ||
|
|
39
|
+
!Number.isSafeInteger(retained) ||
|
|
40
|
+
!Number.isSafeInteger(ready) ||
|
|
41
|
+
typeof selected !== "number" ||
|
|
42
|
+
typeof retained !== "number" ||
|
|
43
|
+
typeof ready !== "number" ||
|
|
44
|
+
selected < 0 ||
|
|
45
|
+
ready < 0 ||
|
|
46
|
+
selected > retained ||
|
|
47
|
+
ready > retained ||
|
|
48
|
+
pendingEvidence !== retained > ready)
|
|
49
|
+
return undefined;
|
|
50
|
+
return {
|
|
51
|
+
state: expectedState,
|
|
52
|
+
selectedEvidenceCutoff: selected,
|
|
53
|
+
retainedEvidenceCutoff: retained,
|
|
54
|
+
readyEvidenceCutoff: ready,
|
|
55
|
+
pendingEvidence,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
await reader.cancel().catch(() => { });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** @internal These failures require changed evidence or processing, not another identical call. */
|
|
66
|
+
export const TERMINAL_WORLD_DIAGNOSTICS = new Set([
|
|
67
|
+
"world_insufficient_evidence",
|
|
68
|
+
"world_processing_limit",
|
|
69
|
+
]);
|