@hue-run/sdk 0.19.0 → 0.20.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 (54) hide show
  1. package/CLI.md +27 -10
  2. package/ENVIRONMENTS.md +5 -2
  3. package/EVALUATIONS.md +6 -1
  4. package/README.md +12 -4
  5. package/WORLDS.md +122 -0
  6. package/dist/blobs.d.ts +2 -1
  7. package/dist/blobs.js +7 -5
  8. package/dist/cli/eval.d.ts +4 -0
  9. package/dist/cli/eval.js +434 -186
  10. package/dist/cli/listen.js +1 -1
  11. package/dist/environment/client.d.ts +2 -95
  12. package/dist/environment/client.js +2 -283
  13. package/dist/environment/tools.d.ts +2 -35
  14. package/dist/environment/tools.js +2 -30
  15. package/dist/environment/types.d.ts +2 -623
  16. package/dist/environment/types.js +2 -1
  17. package/dist/environment/world.d.ts +2 -65
  18. package/dist/environment/world.js +2 -171
  19. package/dist/environment.d.ts +7 -7
  20. package/dist/environment.js +3 -3
  21. package/dist/evals/attempt.d.ts +1 -1
  22. package/dist/evals/client.d.ts +3 -2
  23. package/dist/evals/client.js +2 -1
  24. package/dist/evals/environment-target.d.ts +3 -3
  25. package/dist/evals/environment-target.js +3 -3
  26. package/dist/evals/failure.js +1 -1
  27. package/dist/evals/local-worker.d.ts +8 -3
  28. package/dist/evals/local-worker.js +10 -2
  29. package/dist/evals/simulation.d.ts +6 -3
  30. package/dist/evals/simulation.js +2 -1
  31. package/dist/evals/types.d.ts +2 -2
  32. package/dist/inline-files.d.ts +21 -4
  33. package/dist/inline-files.js +100 -14
  34. package/dist/large-media.d.ts +2 -1
  35. package/dist/large-media.js +7 -4
  36. package/dist/version.d.ts +1 -1
  37. package/dist/version.js +1 -1
  38. package/dist/world/client.d.ts +150 -0
  39. package/dist/world/client.js +368 -0
  40. package/dist/world/definitions.d.ts +47 -0
  41. package/dist/world/definitions.js +1 -0
  42. package/dist/world/model-types.d.ts +117 -0
  43. package/dist/world/model-types.js +1 -0
  44. package/dist/world/models.d.ts +40 -0
  45. package/dist/world/models.js +56 -0
  46. package/dist/world/tools.d.ts +35 -0
  47. package/dist/world/tools.js +30 -0
  48. package/dist/world/types.d.ts +625 -0
  49. package/dist/world/types.js +1 -0
  50. package/dist/world/world.d.ts +65 -0
  51. package/dist/world/world.js +175 -0
  52. package/dist/world.d.ts +13 -0
  53. package/dist/world.js +5 -0
  54. package/package.json +8 -2
@@ -102,6 +102,74 @@ function base64Header(header) {
102
102
  return semicolon !== -1 && `${header.slice(semicolon)};`.includes(";base64;");
103
103
  }
104
104
  const hexPair = /^[0-9A-Fa-f]{2}$/;
105
+ /** Raw 16-bit PCM media types and the byte order of their samples, as Hue's reader names them. */
106
+ const pcmEndian = new Map([
107
+ ["audio/l16", "big"],
108
+ ["audio/pcm", "little"],
109
+ ["audio/x-pcm", "little"],
110
+ ]);
111
+ /** One media type parameter (`name=value`, the value a token or a quoted string) or an empty one,
112
+ * then the `;` that ends it or the end of the type (RFC 9110 section 8.3.1). */
113
+ const pcmParameter = /[ \t]*(?:([!#$%&'*+.^_`|~0-9A-Za-z-]+)[ \t]*=[ \t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+|"(?:[^"\\]|\\.)*")[ \t]*)?(;|$)/y;
114
+ /** A whole number written in decimal digits alone, within `[min, max]`. */
115
+ function wholeIn(value, min, max) {
116
+ if (value === undefined || !/^\d{1,7}$/.test(value))
117
+ return undefined;
118
+ const number = Number(value);
119
+ return number >= min && number <= max ? number : undefined;
120
+ }
121
+ /**
122
+ * The canonical media type of raw 16-bit PCM whose type declares its format, as Hue's reader reads
123
+ * one and names it: `audio/pcm;rate=<Hz>;channels=<n>` for little-endian `audio/pcm` and
124
+ * `audio/x-pcm`, `audio/L16;rate=<Hz>;channels=<n>` for big-endian `audio/L16`, `rate` a whole
125
+ * 8000 to 192000 and `channels` 1 or 2 (1 when absent). Undefined for any other type, raw PCM
126
+ * without a rate or with any other parameter included: Hue plays raw PCM only in a format its
127
+ * type declares.
128
+ */
129
+ export function pcmMediaType(mediaType) {
130
+ if (mediaType.length > 255)
131
+ return undefined;
132
+ const endian = pcmEndian.get(mediaType.split(";", 1)[0].trim().toLowerCase());
133
+ if (!endian)
134
+ return undefined;
135
+ const parameters = new Map();
136
+ const start = mediaType.indexOf(";");
137
+ if (start !== -1) {
138
+ pcmParameter.lastIndex = start + 1;
139
+ for (;;) {
140
+ const match = pcmParameter.exec(mediaType);
141
+ if (!match)
142
+ return undefined;
143
+ if (match[1] !== undefined) {
144
+ const name = match[1].toLowerCase();
145
+ if (parameters.has(name))
146
+ return undefined;
147
+ const value = match[2];
148
+ parameters.set(name, value.startsWith('"') ? value.slice(1, -1).replace(/\\(.)/g, "$1") : value);
149
+ }
150
+ if (match[3] === "")
151
+ break;
152
+ }
153
+ }
154
+ for (const name of parameters.keys())
155
+ if (name !== "rate" && name !== "channels")
156
+ return undefined;
157
+ const rate = wholeIn(parameters.get("rate"), 8_000, 192_000);
158
+ const channels = parameters.has("channels") ? wholeIn(parameters.get("channels"), 1, 2) : 1;
159
+ if (rate === undefined || channels === undefined)
160
+ return undefined;
161
+ return `${endian === "big" ? "audio/L16" : "audio/pcm"};rate=${rate};channels=${channels}`;
162
+ }
163
+ /** The media type a `data:` URL's header (between `data:` and its comma) gives its file: raw PCM
164
+ * whose parameters declare its format as its canonical type (`pcmMediaType`), any other type
165
+ * without its parameters. Empty when the header names no type. */
166
+ export function headerMediaType(header) {
167
+ const type = header.split(";", 1)[0].trim();
168
+ if (!type)
169
+ return type;
170
+ const declared = header.endsWith(";base64") ? header.slice(0, -";base64".length) : header;
171
+ return pcmMediaType(declared) ?? type;
172
+ }
105
173
  /** RFC 2397 data without `;base64`: percent-escaped octets, other characters as UTF-8. Undefined
106
174
  * when a `%` does not start an escape. */
107
175
  function percentDecoded(payload) {
@@ -135,7 +203,7 @@ export function inlineFileBytes(content) {
135
203
  ? Buffer.from(payload, "base64")
136
204
  : undefined;
137
205
  const header = url?.[1];
138
- const mediaType = header === undefined ? undefined : header.split(";")[0].trim();
206
+ const mediaType = header === undefined ? undefined : headerMediaType(header);
139
207
  return {
140
208
  bytes: decoded ?? Buffer.from(content, "utf8"),
141
209
  decoded: decoded !== undefined,
@@ -143,6 +211,8 @@ export function inlineFileBytes(content) {
143
211
  ...(decoded !== undefined && !url ? { bareBase64: true } : {}),
144
212
  };
145
213
  }
214
+ /** OpenAI's `pcm16` audio: raw 16-bit little-endian PCM, 24 kHz mono, as Hue's reader types it. */
215
+ const PCM16 = "audio/pcm;rate=24000;channels=1";
146
216
  const audioTypes = {
147
217
  wav: "audio/wav",
148
218
  mp3: "audio/mpeg",
@@ -152,7 +222,7 @@ const audioTypes = {
152
222
  aac: "audio/aac",
153
223
  m4a: "audio/mp4",
154
224
  webm: "audio/webm",
155
- pcm16: "audio/pcm",
225
+ pcm16: PCM16,
156
226
  };
157
227
  const documentTypes = {
158
228
  pdf: "application/pdf",
@@ -342,16 +412,18 @@ export function contentPath(part, pointer = "") {
342
412
  }
343
413
  /** A media type as a `data:` URL declares one: `type/subtype`, no parameters. */
344
414
  const declaredMediaType = /^[A-Za-z0-9][A-Za-z0-9!#$&^_.+-]*\/[A-Za-z0-9!#$&^_.+-]+$/;
345
- /** The media type a whole string that is a `data:` URL declares, when it declares one: such a
346
- * string is a file wherever it sits. A web URL, or any other text, is not. */
415
+ /** The media type of a whole string that is a `data:` URL declaring one (`headerMediaType`): such
416
+ * a string is a file wherever it sits. A web URL, or any other text, is not. */
347
417
  function dataUrlType(text) {
348
418
  if (!text.startsWith("data:"))
349
419
  return undefined;
350
420
  const header = dataUrl.exec(text);
351
421
  if (!header)
352
422
  return undefined;
353
- const type = header[1].split(";")[0].trim();
354
- return declaredMediaType.test(type) && isMediaContentType(type) ? type : undefined;
423
+ const type = header[1].split(";", 1)[0].trim();
424
+ return declaredMediaType.test(type) && isMediaContentType(type)
425
+ ? headerMediaType(header[1])
426
+ : undefined;
355
427
  }
356
428
  /** The modality a media type implies, as Hue's reader names it. */
357
429
  export function modalityOf(mediaType) {
@@ -387,7 +459,7 @@ const audioFormats = {
387
459
  m4a: "audio/mp4",
388
460
  mp4: "audio/mp4",
389
461
  webm: "audio/webm",
390
- pcm16: "audio/pcm",
462
+ pcm16: PCM16,
391
463
  pcm: "audio/pcm",
392
464
  };
393
465
  function audioFormatMediaType(format) {
@@ -654,17 +726,27 @@ export function mediaIn(value, source) {
654
726
  }
655
727
  /**
656
728
  * An attribute's recorded text read for files as Hue's reader reads that attribute: JSON by its
657
- * convention; metadata as JSON when it reads as an object or array, otherwise as the text itself;
658
- * an OpenLLMetry content as the parts list it encodes (any other content stays text); an
659
- * OpenInference image URL as the text itself. Undefined for text that reading finds nothing in.
660
- * Throws for JSON that does not parse or nests too deep.
729
+ * convention, text that does not parse as the text itself (a Langfuse SDK records a string input
730
+ * or output as it is, so a whole `data:` URL is a file); metadata as JSON when it reads as an
731
+ * object or array, otherwise as the text itself; an OpenLLMetry content as the parts list it
732
+ * encodes (any other content stays text); an OpenInference image URL as the text itself.
733
+ * Undefined for text that reading finds nothing in. Throws for metadata or parts JSON that does
734
+ * not parse.
661
735
  */
662
736
  export function readMediaText(key, text) {
663
737
  /** JSON text read as Hue's reader reads it: text it keeps as text holds no file. */
664
738
  const json = (parsed) => (readerParses(parsed) ? mediaIn(parsed, text) : undefined);
665
739
  switch (readingOf(key)) {
666
- case "json":
667
- return json(JSON.parse(text));
740
+ case "json": {
741
+ let parsed;
742
+ try {
743
+ parsed = JSON.parse(text);
744
+ }
745
+ catch {
746
+ return mediaIn(text);
747
+ }
748
+ return json(parsed);
749
+ }
668
750
  case "metadata":
669
751
  return /^\s*[[{]/.test(text) ? json(JSON.parse(text)) : mediaIn(text);
670
752
  case "parts": {
@@ -729,8 +811,12 @@ export function mediaBytes(file) {
729
811
  return { bytes: Buffer.from(file.content, "base64"), decoded: true };
730
812
  return inlineFileBytes(file.content);
731
813
  }
814
+ /** The type a file is reserved and listed under: the type its part declares, else its `data:`
815
+ * URL's, raw PCM whose type declares its format in its canonical form (`pcmMediaType`). */
732
816
  export function mediaContentType(file, decoded) {
733
- return ((isMediaContentType(file.contentType) ? file.contentType : undefined) ??
817
+ return ((isMediaContentType(file.contentType)
818
+ ? (pcmMediaType(file.contentType) ?? file.contentType)
819
+ : undefined) ??
734
820
  (isMediaContentType(decoded.urlMediaType) ? decoded.urlMediaType : undefined) ??
735
821
  (decoded.decoded ? "application/octet-stream" : "text/plain; charset=utf-8"));
736
822
  }
@@ -67,7 +67,8 @@ export interface LargeMediaValue extends MediaValue {
67
67
  * An attribute's recorded text read for files as `readMediaText` reads it, its long base64 and
68
68
  * base64 `data:` URL strings read in place (see {@link skeletonOf}). Undefined for text whose JSON
69
69
  * around those strings is over the 8 Mi bound, or that reading finds nothing in. Throws for JSON
70
- * that does not parse.
70
+ * that does not parse, except text read by JSON convention that is a `data:` URL, which is read
71
+ * as the text itself, as `readMediaText` reads it.
71
72
  */
72
73
  export declare function readLargeMediaText(key: string, text: string, longUnits?: number): Promise<LargeMediaValue | undefined>;
73
74
  /**
@@ -1,5 +1,5 @@
1
1
  import { randomBytes } from "node:crypto";
2
- import { MAX_INLINE_FILE_TEXT, mediaIn, placedMediaText, readerParses, readingOf, } from "./inline-files.js";
2
+ import { headerMediaType, MAX_INLINE_FILE_TEXT, mediaIn, placedMediaText, readerParses, readingOf, } from "./inline-files.js";
3
3
  /**
4
4
  * Inline media in a value too long for the media inspection bounds (8 Mi UTF-16 code units for one
5
5
  * attribute, 16 Mi for a record), read without parsing the files out of it. A span's own attribute
@@ -218,7 +218,8 @@ async function skeletonOf(text, longUnits, held) {
218
218
  * An attribute's recorded text read for files as `readMediaText` reads it, its long base64 and
219
219
  * base64 `data:` URL strings read in place (see {@link skeletonOf}). Undefined for text whose JSON
220
220
  * around those strings is over the 8 Mi bound, or that reading finds nothing in. Throws for JSON
221
- * that does not parse.
221
+ * that does not parse, except text read by JSON convention that is a `data:` URL, which is read
222
+ * as the text itself, as `readMediaText` reads it.
222
223
  */
223
224
  export async function readLargeMediaText(key, text, longUnits = LONG_STRING_UNITS) {
224
225
  const reading = readingOf(key);
@@ -255,7 +256,9 @@ export async function readLargeMediaText(key, text, longUnits = LONG_STRING_UNIT
255
256
  };
256
257
  switch (reading) {
257
258
  case "json":
258
- return json();
259
+ // No JSON text starts with `data:`: such text is the text itself, as `readMediaText` reads
260
+ // text that does not parse, and a whole `data:` URL is the file.
261
+ return text.startsWith("data:") ? whole() : json();
259
262
  case "metadata":
260
263
  return /^\s*[[{]/.test(text) ? json() : whole();
261
264
  case "parts":
@@ -408,7 +411,7 @@ export function longFileBytes(file, long) {
408
411
  ...(file.base64 ? {} : { bareBase64: true }),
409
412
  source,
410
413
  };
411
- const mediaType = long.header.split(";")[0].trim();
414
+ const mediaType = headerMediaType(long.header);
412
415
  return {
413
416
  size: source.size,
414
417
  decoded: true,
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.19.0";
2
+ export declare const sdkVersion = "0.20.0";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Generated by scripts/write-version.mjs from package.json; do not edit by hand.
2
2
  /** Package version shared by the instrumentation scope and the export User-Agent. */
3
- export const sdkVersion = "0.19.0";
3
+ export const sdkVersion = "0.20.0";
@@ -0,0 +1,150 @@
1
+ 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
+ import type { PublishableWorldDefinition, WorldVersion } from "./definitions.js";
3
+ /** Connection and retry options for {@link createEnvironmentClient}. */
4
+ export interface EnvironmentClientOptions {
5
+ /** Project service key sent as a bearer token; server-side only. */
6
+ apiKey: string;
7
+ /** Hue origin; defaults to `https://app.hue.run`. */
8
+ baseUrl?: string;
9
+ /** Per-request deadline in milliseconds. */
10
+ timeoutMillis?: number;
11
+ /** Attempts for idempotent run mutations, 1–10; defaults to 4. */
12
+ maxAttempts?: number;
13
+ }
14
+ /** Sanitized environment API failure that never includes response text or credentials. */
15
+ export declare class HueEnvironmentError extends Error {
16
+ /** HTTP status when Hue answered; absent for transport, timeout or parse failure. */
17
+ readonly status?: number | undefined;
18
+ /** Hue's `Retry-After` in milliseconds, bounded, when a 429 or 503 carried one. */
19
+ readonly retryAfterMs?: number | undefined;
20
+ /** The server's `X-Hue-Diagnostic` code, when it is a short snake-case value. */
21
+ readonly diagnostic?: string | undefined;
22
+ constructor(
23
+ /** HTTP status when Hue answered; absent for transport, timeout or parse failure. */
24
+ status?: number | undefined,
25
+ /** Hue's `Retry-After` in milliseconds, bounded, when a 429 or 503 carried one. */
26
+ retryAfterMs?: number | undefined,
27
+ /** The server's `X-Hue-Diagnostic` code, when it is a short snake-case value. */
28
+ diagnostic?: string | undefined);
29
+ }
30
+ /** Starts one isolated instance from an immutable World version. */
31
+ export interface CreateInstanceInput extends Omit<CreateRunInput, "environmentVersionId"> {
32
+ /** Immutable World version to instantiate. */
33
+ worldVersionId: string;
34
+ }
35
+ /** A connection failure or a status the client retries; seal polling continues through these. */
36
+ export declare function isTransientEnvironmentError(error: unknown): boolean;
37
+ /** Typed client for authored environments, isolated runs and immutable journals. */
38
+ export declare class WorldClient {
39
+ #private;
40
+ /** Validated Hue origin. */
41
+ readonly baseUrl: string;
42
+ private readonly timeoutMillis;
43
+ private readonly maxAttempts;
44
+ constructor(options: EnvironmentClientOptions);
45
+ /** Compatibility clients override only resource routing. */
46
+ protected resourcePath(path: string): string;
47
+ private send;
48
+ private page;
49
+ /** Creates an isolated instance from an immutable World version. */
50
+ createInstance(input: CreateInstanceInput, options?: {
51
+ signal?: AbortSignal;
52
+ }): Promise<EnvironmentRun>;
53
+ /** Reads current or sealed instance state. */
54
+ getInstance(instanceId: string, options?: {
55
+ signal?: AbortSignal;
56
+ }): Promise<{
57
+ id: string;
58
+ environmentVersionId: string;
59
+ executionId: string | null;
60
+ seed: string;
61
+ status: "open" | "completed" | "abandoned" | "expired";
62
+ stepCount: number;
63
+ maxSteps: number;
64
+ clockNs: string;
65
+ expiresAt: string;
66
+ createdAt: string;
67
+ sealedAt: string | null;
68
+ stateDigest: string;
69
+ finalState?: import("./types.js").JsonValue;
70
+ worldId?: string;
71
+ lifecycle?: import("./types.js").WorldLifecycle;
72
+ completingUntil?: string | null;
73
+ traceExternalId?: string | null;
74
+ surfaces?: import("./types.js").WorldSurface[];
75
+ flags?: import("./types.js").WorldFlag[];
76
+ connection?: null;
77
+ validity: "environment_incomplete" | "not_assessed";
78
+ coverageGap: import("./types.js").CoverageGap | null;
79
+ }>;
80
+ /** Completes or abandons one instance and freezes its evidence. */
81
+ finishInstance(instanceId: string, input: FinishRunInput): Promise<SealedRun>;
82
+ /** Creates an environment identity; this non-idempotent registry write is not retried. */
83
+ createEnvironment(input: EnvironmentIdentity): Promise<EnvironmentSummary>;
84
+ /** Lists active environment identities. */
85
+ listEnvironments(page?: EnvironmentPageOptions): Promise<EnvironmentPage>;
86
+ /** Reads one environment and its immutable version summaries. */
87
+ getEnvironment(id: string): Promise<Environment>;
88
+ /** Publishes an immutable definition; this non-idempotent registry write is not retried. */
89
+ publishVersion(environmentId: string, definition: PublishableWorldDefinition): Promise<EnvironmentVersionSummary>;
90
+ /** Reads a full immutable environment version and generated action catalog. */
91
+ getVersion(id: string): Promise<WorldVersion>;
92
+ /** Creates or recovers one fresh isolated world using a stable idempotency key. */
93
+ createRun(input: CreateRunInput, options?: {
94
+ signal?: AbortSignal;
95
+ }): Promise<EnvironmentRun>;
96
+ /** Reads authoritative current or sealed world state. */
97
+ getRun(runId: string, options?: {
98
+ signal?: AbortSignal;
99
+ }): Promise<{
100
+ id: string;
101
+ environmentVersionId: string;
102
+ executionId: string | null;
103
+ seed: string;
104
+ status: "open" | "completed" | "abandoned" | "expired";
105
+ stepCount: number;
106
+ maxSteps: number;
107
+ clockNs: string;
108
+ expiresAt: string;
109
+ createdAt: string;
110
+ sealedAt: string | null;
111
+ stateDigest: string;
112
+ finalState?: import("./types.js").JsonValue;
113
+ worldId?: string;
114
+ lifecycle?: import("./types.js").WorldLifecycle;
115
+ completingUntil?: string | null;
116
+ traceExternalId?: string | null;
117
+ surfaces?: import("./types.js").WorldSurface[];
118
+ flags?: import("./types.js").WorldFlag[];
119
+ connection?: null;
120
+ validity: "environment_incomplete" | "not_assessed";
121
+ coverageGap: import("./types.js").CoverageGap | null;
122
+ }>;
123
+ /** Record a known coverage gap with durable identity; retries reuse the exact request. */
124
+ recordCoverageGap(runId: string, input: CoverageGapInput): Promise<CoverageGapResult>;
125
+ /** Invokes an action; repeating an invocation identity replays its recorded result. */
126
+ act(runId: string, input: ActionInput): Promise<ActionResult>;
127
+ /** Pages the immutable journal by step ordinal. */
128
+ listSteps(runId: string, page?: StepPageOptions): Promise<StepPage>;
129
+ /** Seals a world as completed or abandoned and freezes its evidence. */
130
+ finishRun(runId: string, input: FinishRunInput): Promise<SealedRun>;
131
+ /** Reads a sealed world's evaluator-only evidence with the project key; a world token never
132
+ * can. An open world answers 409 until it is sealed. */
133
+ getEvidence(runId: string, options?: WorldEvidenceOptions): Promise<WorldEvidence>;
134
+ }
135
+ /** Creates a typed simulated-environment client. */
136
+ /** Compatibility client using the original REST resource names. */
137
+ export declare class EnvironmentClient extends WorldClient {
138
+ /** Publishes the definition shapes supported by the compatibility client. */
139
+ publishVersion(environmentId: string, definition: PublishableEnvironmentDefinition): Promise<EnvironmentVersionSummary>;
140
+ /** Reads the definition using the compatibility client's original return type. */
141
+ getVersion(id: string): Promise<EnvironmentVersion>;
142
+ protected resourcePath(path: string): string;
143
+ }
144
+ /** Creates the compatibility client using the original REST resource names. */
145
+ export declare function createEnvironmentClient(options: EnvironmentClientOptions): EnvironmentClient;
146
+ /** Connection options for the World API client. */
147
+ export type WorldClientOptions = EnvironmentClientOptions;
148
+ /** Creates a World API client using canonical World and instance routes. */
149
+ export declare function createWorldClient(options: WorldClientOptions): WorldClient;
150
+ export { HueEnvironmentError as HueWorldError, isTransientEnvironmentError as isTransientWorldError, };