@gobing-ai/ts-ai-decision 0.5.32 → 0.5.33

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/README.md CHANGED
@@ -27,7 +27,7 @@ create a cycle with the bundled built-ins.
27
27
  |------------|---------|---------|------------|-------|---------------|
28
28
  | `typesafe` | TypeSafe Jev (hosted) | this package (`@typesafe-ai/sdk` 0.7.0) | built-in, lazy; hub default | `TYPESAFE_API_KEY` | from the API |
29
29
  | `fm-local` | Apple Foundation Models via `fm` (ADR-029/030) | `ts-decision-fm` | built-in, lazy | macOS on Apple silicon, `fm` CLI | k-sample frequencies |
30
- | `laya-local` | Laya on MLX, warm Python worker (ADR-027/028) | `ts-laya-mlx` | built-in, lazy | Apple silicon, Laya model + Python env | from the local model |
30
+ | `laya-local` | Laya on MLX, warm Python worker (ADR-027/028) | `ts-laya-mlx` (optional; installed on macOS only, ADR-041) | built-in, lazy | Apple silicon, Laya model + Python env. Other hosts fall back (`no-backend`) | from the local model |
31
31
  | `llm-agent` | Any `ts-ai-runner` coding agent / model (ADR-038) | this package (`ts-ai-runner` surface) | built-in, lazy | an installed agent CLI | k-sample frequencies (accepted = all samples agreed) |
32
32
  | `clef` | Cloudflare Workers AI Clef (ADR-037) | `ts-decision-clef` | consumer-registered | Cloudflare account ID + API token | from the API |
33
33
 
@@ -1,7 +1,42 @@
1
- import { type DecisionMaker, type DecisionMakerOptions } from '@gobing-ai/ts-ai-runner';
1
+ import { type DecisionDriver, type DecisionMaker, type DecisionMakerOptions } from '@gobing-ai/ts-ai-runner';
2
2
  import { type FmDriverOptions } from '@gobing-ai/ts-decision-fm';
3
- import { type LayaDriverOptions } from '@gobing-ai/ts-laya-mlx';
4
3
  import { type AgentDriverOptions } from './agent-driver';
4
+ /**
5
+ * Options forwarded to `createLayaDriver`. Same fields as `LayaDriverOptions` in
6
+ * `@gobing-ai/ts-laya-mlx`. Declared here so published `.d.ts` files do not import
7
+ * that package: it is an optional, macOS-only dependency (ADR-041) and is absent
8
+ * on other platforms.
9
+ */
10
+ export interface LayaLocalDriverOptions {
11
+ pythonPath?: string;
12
+ module?: string;
13
+ workerScript?: string;
14
+ cwd?: string;
15
+ modelId?: string;
16
+ modelPath?: string;
17
+ revision?: string;
18
+ cacheDir?: string;
19
+ dtype?: 'float32' | 'float16' | 'bfloat16';
20
+ batchSize?: number;
21
+ startupTimeoutMs?: number;
22
+ requestTimeoutMs?: number;
23
+ env?: Record<string, string | undefined>;
24
+ platform?: string;
25
+ arch?: string;
26
+ core?: 'mlx-python' | 'mlx-native' | 'auto';
27
+ /** Same role as `LayaDriverOptions.client`. Typed wide so the optional module's class stays assignable. */
28
+ client?: unknown;
29
+ /** Same role as `LayaDriverOptions.nativeLoader`. */
30
+ nativeLoader?: unknown;
31
+ }
32
+ /**
33
+ * Load the bundled Laya driver. The package is an `optionalDependency` with
34
+ * `"os": ["darwin"]`, so non-macOS installs do not contain it. Only the import
35
+ * failure is rewritten; factory errors propagate unchanged.
36
+ *
37
+ * @internal Tests pass `load` because a workspace link always resolves.
38
+ */
39
+ export declare function resolveBundledLayaDriver(options?: LayaLocalDriverOptions, load?: () => Promise<unknown>): Promise<DecisionDriver>;
5
40
  /** A maker, or a lazy factory for one (sync or async). Factories run on first `resolve` and are memoised on success. */
6
41
  export type MakerSource = DecisionMaker | (() => DecisionMaker | Promise<DecisionMaker>);
7
42
  /** Options for the four built-in makers pre-registered by {@link DecisionMakerRegistry} (task 0091 R2, task 0115 R8). */
@@ -11,7 +46,7 @@ export interface BuiltinMakerOptions {
11
46
  /** Driver options for the bundled drivers; the fm platform check runs at first resolve, not registration. */
12
47
  readonly driverOptions?: {
13
48
  readonly 'fm-local'?: FmDriverOptions;
14
- readonly 'laya-local'?: LayaDriverOptions;
49
+ readonly 'laya-local'?: LayaLocalDriverOptions;
15
50
  readonly 'llm-agent'?: AgentDriverOptions;
16
51
  };
17
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAE5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,gBAAgB,CAAC;AAI5E,wHAAwH;AACxH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;AAEzF,yHAAyH;AACzH,MAAM,WAAW,mBAAmB;IAChC,oGAAoG;IACpG,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACnF,6GAA6G;IAC7G,QAAQ,CAAC,aAAa,CAAC,EAAE;QACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;QACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC;QAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;KAC7C,CAAC;CACL;AAID;;;;;;;;GAQG;AACH,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAGpB;IAEJ,mGAAmG;gBACvF,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,KAAK,CAAA;KAAE;IA4ChE,oGAAoG;IACpG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAWjD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,KAAK,IAAI,MAAM,EAAE;IAIjB;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA4BnD;;;;;OAKG;IACG,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAc9C"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAE5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,gBAAgB,CAAC;AAI5E;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,GAAG,MAAM,CAAC;IAC5C,2GAA2G;IAC3G,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAID;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC1C,OAAO,GAAE,sBAA2B,EACpC,IAAI,GAAE,MAAM,OAAO,CAAC,OAAO,CAA0C,GACtE,OAAO,CAAC,cAAc,CAAC,CAmBzB;AAED,wHAAwH;AACxH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;AAEzF,yHAAyH;AACzH,MAAM,WAAW,mBAAmB;IAChC,oGAAoG;IACpG,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACnF,6GAA6G;IAC7G,QAAQ,CAAC,aAAa,CAAC,EAAE;QACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;QACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,sBAAsB,CAAC;QAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,kBAAkB,CAAC;KAC7C,CAAC;CACL;AAID;;;;;;;;GAQG;AACH,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAGpB;IAEJ,mGAAmG;gBACvF,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,KAAK,CAAA;KAAE;IAgDhE,oGAAoG;IACpG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAWjD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,KAAK,IAAI,MAAM,EAAE;IAIjB;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA4BnD;;;;;OAKG;IACG,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAc9C"}
package/dist/registry.js CHANGED
@@ -1,9 +1,30 @@
1
- import { createDecisionMaker, resolveApiKey, } from '@gobing-ai/ts-ai-runner';
1
+ import { createDecisionMaker, DecisionConfigError, resolveApiKey, } from '@gobing-ai/ts-ai-runner';
2
2
  import { createFmDriver } from '@gobing-ai/ts-decision-fm';
3
- import { createLayaDriver } from '@gobing-ai/ts-laya-mlx';
4
3
  import { createAgentDriver } from './agent-driver.js';
5
4
  import { DecisionRegistryError, UnknownDecisionMakerError } from './errors.js';
6
5
  import { createTypesafeDriver } from './typesafe-driver.js';
6
+ const LAYA_DRIVER_PACKAGE = '@gobing-ai/ts-laya-mlx';
7
+ /**
8
+ * Load the bundled Laya driver. The package is an `optionalDependency` with
9
+ * `"os": ["darwin"]`, so non-macOS installs do not contain it. Only the import
10
+ * failure is rewritten; factory errors propagate unchanged.
11
+ *
12
+ * @internal Tests pass `load` because a workspace link always resolves.
13
+ */
14
+ export async function resolveBundledLayaDriver(options = {}, load = () => import('@gobing-ai/ts-laya-mlx')) {
15
+ let loaded;
16
+ try {
17
+ loaded = await load();
18
+ }
19
+ catch (cause) {
20
+ throw new DecisionConfigError(`The 'laya-local' maker requires '${LAYA_DRIVER_PACKAGE}', an optional dependency installed only on macOS. On macOS, install it with 'bun add ${LAYA_DRIVER_PACKAGE}'.`, 'LAYA_BACKEND', { cause });
21
+ }
22
+ const record = loaded !== null && typeof loaded === 'object' ? loaded : {};
23
+ if (typeof record.createLayaDriver !== 'function') {
24
+ throw new DecisionConfigError(`Module '${LAYA_DRIVER_PACKAGE}' does not export createLayaDriver`, 'LAYA_BACKEND');
25
+ }
26
+ return record.createLayaDriver(options);
27
+ }
7
28
  const NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
8
29
  /**
9
30
  * Registry mapping plain names to {@link DecisionMaker}s (task 0091, ADR-033
@@ -39,7 +60,11 @@ export class DecisionMakerRegistry {
39
60
  ...makerOptions,
40
61
  }));
41
62
  this.register('fm-local', () => createDecisionMaker({ driver: createFmDriver(driverOptions['fm-local'] ?? {}), ...makerOptions }));
42
- this.register('laya-local', () => {
63
+ // Dynamic import: a top-level import would throw on hosts where the
64
+ // optional macOS package was not installed, and the rest of the hub
65
+ // would fail to load. A missing module becomes LAYA_BACKEND, which
66
+ // DecisionHub maps to reason 'no-backend'.
67
+ this.register('laya-local', async () => {
43
68
  const driverOpts = {
44
69
  ...driverOptions['laya-local'],
45
70
  };
@@ -47,7 +72,7 @@ export class DecisionMakerRegistry {
47
72
  driverOpts.env = makerOptions.env;
48
73
  }
49
74
  return createDecisionMaker({
50
- driver: createLayaDriver(driverOpts),
75
+ driver: await resolveBundledLayaDriver(driverOpts),
51
76
  ...makerOptions,
52
77
  });
53
78
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/ts-ai-decision",
3
- "version": "0.5.32",
3
+ "version": "0.5.33",
4
4
  "description": "@gobing-ai/ts-ai-decision — Declarative YAML decision catalog over the ts-ai-runner DecisionMaker surface.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -51,15 +51,17 @@
51
51
  "release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-ai-decision-v<version> && git push --tags' && exit 1"
52
52
  },
53
53
  "dependencies": {
54
- "@gobing-ai/ts-ai-runner": "^0.5.32",
55
- "@gobing-ai/ts-decision-fm": "^0.5.32",
56
- "@gobing-ai/ts-laya-mlx": "^0.5.32",
57
- "@gobing-ai/ts-runtime": "^0.5.32",
54
+ "@gobing-ai/ts-ai-runner": "^0.5.33",
55
+ "@gobing-ai/ts-decision-fm": "^0.5.33",
56
+ "@gobing-ai/ts-runtime": "^0.5.33",
58
57
  "@typesafe-ai/sdk": "0.7.0",
59
58
  "zod": "^4.1.0"
60
59
  },
60
+ "optionalDependencies": {
61
+ "@gobing-ai/ts-laya-mlx": "^0.5.33"
62
+ },
61
63
  "devDependencies": {
62
- "@gobing-ai/ts-utils": "^0.5.32",
64
+ "@gobing-ai/ts-utils": "^0.5.33",
63
65
  "@types/bun": "1.4.3"
64
66
  },
65
67
  "publishConfig": {
package/src/registry.ts CHANGED
@@ -1,15 +1,78 @@
1
1
  import {
2
2
  createDecisionMaker,
3
+ DecisionConfigError,
4
+ type DecisionDriver,
3
5
  type DecisionMaker,
4
6
  type DecisionMakerOptions,
5
7
  resolveApiKey,
6
8
  } from '@gobing-ai/ts-ai-runner';
7
9
  import { createFmDriver, type FmDriverOptions } from '@gobing-ai/ts-decision-fm';
8
- import { createLayaDriver, type LayaDriverOptions } from '@gobing-ai/ts-laya-mlx';
9
10
  import { type AgentDriverOptions, createAgentDriver } from './agent-driver';
10
11
  import { DecisionRegistryError, UnknownDecisionMakerError } from './errors';
11
12
  import { createTypesafeDriver } from './typesafe-driver';
12
13
 
14
+ /**
15
+ * Options forwarded to `createLayaDriver`. Same fields as `LayaDriverOptions` in
16
+ * `@gobing-ai/ts-laya-mlx`. Declared here so published `.d.ts` files do not import
17
+ * that package: it is an optional, macOS-only dependency (ADR-041) and is absent
18
+ * on other platforms.
19
+ */
20
+ export interface LayaLocalDriverOptions {
21
+ pythonPath?: string;
22
+ module?: string;
23
+ workerScript?: string;
24
+ cwd?: string;
25
+ modelId?: string;
26
+ modelPath?: string;
27
+ revision?: string;
28
+ cacheDir?: string;
29
+ dtype?: 'float32' | 'float16' | 'bfloat16';
30
+ batchSize?: number;
31
+ startupTimeoutMs?: number;
32
+ requestTimeoutMs?: number;
33
+ env?: Record<string, string | undefined>;
34
+ platform?: string;
35
+ arch?: string;
36
+ core?: 'mlx-python' | 'mlx-native' | 'auto';
37
+ /** Same role as `LayaDriverOptions.client`. Typed wide so the optional module's class stays assignable. */
38
+ client?: unknown;
39
+ /** Same role as `LayaDriverOptions.nativeLoader`. */
40
+ nativeLoader?: unknown;
41
+ }
42
+
43
+ const LAYA_DRIVER_PACKAGE = '@gobing-ai/ts-laya-mlx';
44
+
45
+ /**
46
+ * Load the bundled Laya driver. The package is an `optionalDependency` with
47
+ * `"os": ["darwin"]`, so non-macOS installs do not contain it. Only the import
48
+ * failure is rewritten; factory errors propagate unchanged.
49
+ *
50
+ * @internal Tests pass `load` because a workspace link always resolves.
51
+ */
52
+ export async function resolveBundledLayaDriver(
53
+ options: LayaLocalDriverOptions = {},
54
+ load: () => Promise<unknown> = () => import('@gobing-ai/ts-laya-mlx'),
55
+ ): Promise<DecisionDriver> {
56
+ let loaded: unknown;
57
+ try {
58
+ loaded = await load();
59
+ } catch (cause) {
60
+ throw new DecisionConfigError(
61
+ `The 'laya-local' maker requires '${LAYA_DRIVER_PACKAGE}', an optional dependency installed only on macOS. On macOS, install it with 'bun add ${LAYA_DRIVER_PACKAGE}'.`,
62
+ 'LAYA_BACKEND',
63
+ { cause },
64
+ );
65
+ }
66
+ const record = loaded !== null && typeof loaded === 'object' ? (loaded as { createLayaDriver?: unknown }) : {};
67
+ if (typeof record.createLayaDriver !== 'function') {
68
+ throw new DecisionConfigError(
69
+ `Module '${LAYA_DRIVER_PACKAGE}' does not export createLayaDriver`,
70
+ 'LAYA_BACKEND',
71
+ );
72
+ }
73
+ return record.createLayaDriver(options);
74
+ }
75
+
13
76
  /** A maker, or a lazy factory for one (sync or async). Factories run on first `resolve` and are memoised on success. */
14
77
  export type MakerSource = DecisionMaker | (() => DecisionMaker | Promise<DecisionMaker>);
15
78
 
@@ -20,7 +83,7 @@ export interface BuiltinMakerOptions {
20
83
  /** Driver options for the bundled drivers; the fm platform check runs at first resolve, not registration. */
21
84
  readonly driverOptions?: {
22
85
  readonly 'fm-local'?: FmDriverOptions;
23
- readonly 'laya-local'?: LayaDriverOptions;
86
+ readonly 'laya-local'?: LayaLocalDriverOptions;
24
87
  readonly 'llm-agent'?: AgentDriverOptions;
25
88
  };
26
89
  }
@@ -68,15 +131,19 @@ export class DecisionMakerRegistry {
68
131
  this.register('fm-local', () =>
69
132
  createDecisionMaker({ driver: createFmDriver(driverOptions['fm-local'] ?? {}), ...makerOptions }),
70
133
  );
71
- this.register('laya-local', () => {
72
- const driverOpts: LayaDriverOptions = {
134
+ // Dynamic import: a top-level import would throw on hosts where the
135
+ // optional macOS package was not installed, and the rest of the hub
136
+ // would fail to load. A missing module becomes LAYA_BACKEND, which
137
+ // DecisionHub maps to reason 'no-backend'.
138
+ this.register('laya-local', async () => {
139
+ const driverOpts: LayaLocalDriverOptions = {
73
140
  ...driverOptions['laya-local'],
74
141
  };
75
142
  if (makerOptions.env && driverOpts.env === undefined) {
76
143
  driverOpts.env = makerOptions.env as Record<string, string | undefined>;
77
144
  }
78
145
  return createDecisionMaker({
79
- driver: createLayaDriver(driverOpts),
146
+ driver: await resolveBundledLayaDriver(driverOpts),
80
147
  ...makerOptions,
81
148
  });
82
149
  });