@gobing-ai/ts-ai-runner 0.5.29 → 0.5.32

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
@@ -500,7 +500,7 @@ Agent-specific behavior:
500
500
  | `gemini` *(deprecated)* | `gemini` | 1 | env-only | `-p`, `-r latest` (resume), `-m`, `-o` |
501
501
  | `pi` | `pi` | 1 | `pi --list-models` | `--no-session`, `-p`, `-c` (resume), `--model`, `--mode` |
502
502
  | `omp` | `omp` | 1 | `omp --list-models` | `--no-session`, `-p`, `-c` (resume), `--model`, `--mode` |
503
- | `opencode` | `opencode` | 1 | `opencode providers` | `run`, `-c`, `-m`, `--format json` |
503
+ | `opencode` | `opencode` | 1 | `opencode providers` | `run`, `--auto` (headless `ask` auto-rejects otherwise), `-c`, `-m`, `--format json` |
504
504
  | `antigravity-cli` | `agy` | 1 | env-only | `-p`, `--continue`, `--model` |
505
505
  | `openclaw` | `openclaw` | 2 | `openclaw health` | `agent --local -m` |
506
506
  | `hermes` | `hermes` | 1 | `hermes doctor` | `chat -q`, `--continue`, `-m` |
@@ -740,11 +740,31 @@ shared state and get typed, discriminated answers back. Questions are built with
740
740
  answers are decoded into neutral `ChoiceAnswer` / `ScoreAnswer` / `NoulAnswer` types — no SDK type
741
741
  crosses this boundary.
742
742
 
743
- Named backends are selected with `backend:`: `typesafe` (the default, reads `TYPESAFE_API_KEY`),
744
- `laya-local` (`@gobing-ai/ts-laya-mlx`), and `fm-local` (`@gobing-ai/ts-decision-fm`). Both local
745
- backends resolve their driver by dynamic import on first use — this package declares no dependency
746
- on either driver package (ADR-028); install the one you select. For typed, non-default driver
747
- options, construct the driver yourself and pass it as `driver:`.
743
+ Named backends are selected with `backend:`: `laya-local` (`@gobing-ai/ts-laya-mlx`), `fm-local`
744
+ (`@gobing-ai/ts-decision-fm`) and — deprecated — `typesafe` (`@gobing-ai/ts-ai-decision`). All three
745
+ resolve their driver by dynamic import on first use: this package declares no dependency on any
746
+ driver package (ADR-028/ADR-039); install the one you select. For typed, non-default driver options,
747
+ construct the driver yourself and pass it as `driver:`.
748
+
749
+ **TypeSafe moved out (ADR-039, 2026-10-19).** `createTypesafeDriver` and the pinned
750
+ `@typesafe-ai/sdk` dependency now live in `@gobing-ai/ts-ai-decision`; this package keeps only the
751
+ neutral contract, the validators, the sampled-driver core and `createDecisionMaker`.
752
+
753
+ ```ts
754
+ import { createDecisionMaker } from '@gobing-ai/ts-ai-runner';
755
+ import { createTypesafeDriver } from '@gobing-ai/ts-ai-decision'; // preferred
756
+
757
+ const decisions = createDecisionMaker({ driver: createTypesafeDriver({ apiKey }) });
758
+ ```
759
+
760
+ The `typesafe` backend name — including the implicit default — still works for one release through a
761
+ deprecated dynamic import, so it now **requires `@gobing-ai/ts-ai-decision` to be installed**:
762
+
763
+ - missing key → `DecisionConfigError` `TYPESAFE_API_KEY` (unchanged, and checked before the import);
764
+ - package not installed → `DecisionConfigError` `TYPESAFE_BACKEND` naming the `bun add` command.
765
+
766
+ The bridge is removed in the next minor. `resolveApiKey` stays exported here and is what both the
767
+ bridge and the `ts-ai-decision` registry use, so `TYPESAFE_API_KEY` precedence is unchanged.
748
768
 
749
769
  ### Batch `ask` — many questions, one request
750
770
 
@@ -847,6 +867,41 @@ errors from its own boundary. Driver-local concerns the neutral validators do no
847
867
  question/option counts, JSON-serializability of `state`, provider response caps) stay in the
848
868
  driver — see [`@gobing-ai/ts-decision-clef`](../decision-clef/README.md) for a worked example.
849
869
 
870
+ ### Sampled-driver core
871
+
872
+ Every backend that answers by drawing k samples from a model shares one
873
+ engine-agnostic core in this package (`src/decision/sampled-driver.ts`). It
874
+ imports nothing — no SDK, no workspace package, no platform API — so a driver
875
+ package outside `ts-ai-runner` can build on it without a cycle. A backend
876
+ supplies only the per-ask session hook; rendering, enum enforcement, parsing
877
+ and frequency estimation come from the core.
878
+
879
+ ```ts
880
+ import { createSampledDriver, extractJsonAnswer } from '@gobing-ai/ts-ai-runner';
881
+
882
+ const driver = createSampledDriver({
883
+ name: 'my-backend',
884
+ samples: 5, // k draws per ask; collapsed to 1 when deterministic
885
+ concurrency: 1, // max draws in flight
886
+ sampleLabel: 'my-backend', // prefix in enum-violation messages
887
+ async open({ instructions, prompt, questions }) {
888
+ const scratch = await openScratchDir();
889
+ return {
890
+ sample: async () => extractJsonAnswer(await runModel(instructions, prompt, scratch)),
891
+ close: () => removeScratchDir(scratch),
892
+ };
893
+ },
894
+ });
895
+ ```
896
+
897
+ `ask` validates the map (nonempty, at least two options per question) **before**
898
+ calling `open`, draws k samples at most `concurrency` at a time, enum-checks
899
+ every sample against `declaredOptions`, and always runs `close` — then reduces
900
+ the draws to empirical frequencies (ADR-030). The exported helpers are
901
+ `DECISION_INSTRUCTIONS`, `buildPrompt`, `buildEnumSchema`, `declaredOptions`,
902
+ `formatDesc`, `requireEnumValue`, `extractJsonAnswer`, `entropyConfidence`,
903
+ `estimateChoice`, `estimateScore` and `estimateNoul`.
904
+
850
905
  ### Adding a backend driver
851
906
 
852
907
  Additional backend drivers are the intended extension point. A driver implements only `ask` —
@@ -1 +1 @@
1
- {"version":3,"file":"shims.d.ts","sourceRoot":"","sources":["../../src/agents/shims.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shims.d.ts","sourceRoot":"","sources":["../../src/agents/shims.ts"],"names":[],"mappings":"AAIA,gEAAgE;AAChE,MAAM,MAAM,SAAS,GACf,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,IAAI,GACJ,UAAU,GACV,iBAAiB,GACjB,UAAU,GACV,QAAQ,GACR,KAAK,GACL,MAAM,GACN,UAAU,GACV,IAAI,CAAC;AAEX,0CAA0C;AAC1C,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzC,mEAAmE;AACnE,MAAM,WAAW,WAAW;IACxB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC1B,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;AASnD,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC7B,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC;CACnC;AAED,qDAAqD;AACrD,MAAM,WAAW,SAAS;IACtB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;IACrB,sFAAsF;IACtF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,wFAAwF;IACxF,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IACvC,2GAA2G;IAC3G,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,oCAAoC;IACpC,cAAc,IAAI,WAAW,CAAC;IAC9B,yCAAyC;IACzC,iBAAiB,IAAI,WAAW,CAAC;IACjC,yCAAyC;IACzC,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,WAAW,CAAC;IACtD,8DAA8D;IAC9D,cAAc,IAAI,WAAW,GAAG,IAAI,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;CACrE;AAkWD,6DAA6D;AAC7D,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAa9D,CAAC;AAEF,kEAAkE;AAClE,MAAM,WAAW,sBAAsB;IACnC,oFAAoF;IACpF,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,oEAAoE;IACpE,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,2GAA2G;IAC3G,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAC;IAC3C,sGAAsG;IACtG,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,4GAA4G;IAC5G,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CAC1B;AAyHD,6EAA6E;AAC7E,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,GAAG,sBAAsB,CAElF;AAED,mEAAmE;AACnE,eAAO,MAAM,cAAc,EAAE,SAAS,SAAS,EAU9C,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,aAAa,EAAE,SAAS,SAAS,EAa7C,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,SAAS,CAAyB,CAAC;AAU1E;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAQrE;AAED;mEACmE;AACnE,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAMxD"}
@@ -136,7 +136,15 @@ const opencodeShim = {
136
136
  getHelpCommand: () => ({ command: 'opencode', args: ['--help'] }),
137
137
  getVersionCommand: () => ({ command: 'opencode', args: ['--version'] }),
138
138
  getPromptCommand: (options) => {
139
- const args = ['run', options.input ?? ''];
139
+ // `opencode run` is non-interactive and auto-REJECTS any permission the
140
+ // operator's config declares `ask` — there is no user to prompt, so the
141
+ // tool call dead-ends (probed 2026-10-18 on opencode 2.0.32: fsWrite
142
+ // landed, shell was rejected with "this non-interactive run cannot ask
143
+ // the user for permission"). `--auto` auto-approves exactly the
144
+ // permissions that are not explicitly denied, so an operator `deny`
145
+ // rule still holds; without it any non-default permission policy makes
146
+ // the shim unusable for tool-using work.
147
+ const args = ['run', options.input ?? '', '--auto'];
140
148
  if (options.continue === true)
141
149
  args.push('-c');
142
150
  if (options.model !== undefined)
@@ -31,7 +31,14 @@ export type DecisionBackend = 'typesafe' | 'laya-local' | 'fm-local';
31
31
  export interface DecisionMakerOptions {
32
32
  /** Custom driver — when supplied, `backend` is ignored, no default driver is constructed and no key is required. */
33
33
  driver?: DecisionDriver;
34
- /** Named backend selector. Default: `'typesafe'`. Resolution order: `driver` → `backend` → `'typesafe'`. */
34
+ /**
35
+ * Named backend selector. Default: `'typesafe'`. Resolution order: `driver` → `backend` → `'typesafe'`.
36
+ *
37
+ * @deprecated `'typesafe'` (including the implicit default) now loads its driver from
38
+ * `@gobing-ai/ts-ai-decision` through a dynamic import, so it requires that package to be
39
+ * installed. Prefer `driver: createTypesafeDriver(...)` imported from `@gobing-ai/ts-ai-decision`;
40
+ * this bridge is removed in the next minor (ADR-039).
41
+ */
35
42
  backend?: DecisionBackend;
36
43
  /** Injected env record; defaults to `getProcessEnv()` (doctor-runner convention). */
37
44
  env?: Record<string, string | undefined>;
@@ -46,12 +53,26 @@ export interface DecisionMakerOptions {
46
53
  fetch?: typeof fetch;
47
54
  [key: string]: unknown;
48
55
  }
56
+ /**
57
+ * Resolve the key per R7: `options.apiKey ?? (options.env ?? getProcessEnv()).TYPESAFE_API_KEY`.
58
+ * Throws before any driver construction or request.
59
+ */
60
+ export declare function resolveApiKey(options: DecisionMakerOptions): string;
49
61
  /**
50
62
  * @internal Exported for task 0086 R9 branch tests: `importModule` lets tests
51
63
  * simulate package-import failures that cannot occur in-workspace (workspace
52
64
  * links always resolve).
53
65
  */
54
66
  export declare function resolveLayaDriver(options: DecisionMakerOptions, importModule?: (specifier: string) => Promise<unknown>): Promise<DecisionDriver>;
67
+ /**
68
+ * Resolve the `typesafe` driver from `@gobing-ai/ts-ai-decision` (task 0116 R5, ADR-039).
69
+ *
70
+ * The driver moved out of this package, which is now the contract-only surface. The key is
71
+ * resolved FIRST so a missing key keeps its exact pre-move error and no import is attempted.
72
+ *
73
+ * @internal Exported for the branch tests; see {@link resolveLayaDriver}.
74
+ */
75
+ export declare function resolveTypesafeDriver(options: DecisionMakerOptions, importModule?: (specifier: string) => Promise<unknown>): Promise<DecisionDriver>;
55
76
  /** @internal Exported for task 0086 R9 branch tests; see {@link resolveLayaDriver}. */
56
77
  export declare function resolveFmDriver(options: DecisionMakerOptions, importModule?: (specifier: string) => Promise<unknown>): Promise<DecisionDriver>;
57
78
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"decision-maker.d.ts","sourceRoot":"","sources":["../../src/decision/decision-maker.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACR,UAAU,EACV,YAAY,EACZ,cAAc,EACd,aAAa,EACb,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,WAAW,EACd,MAAM,SAAS,CAAC;AAKjB,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC1B,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sFAAsF;IACtF,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE;QAC/C,KAAK,EAAE,aAAa,CAAC;QACrB,SAAS,EAAE,CAAC,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,yEAAyE;IACzE,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EACzB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,GACxB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5B,gFAAgF;IAChF,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1G,wEAAwE;IACxE,IAAI,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,IAAI,CAAC;QAAC,EAAE,CAAC,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACrG;;;;OAIG;IACH,OAAO,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,gEAAgE;AAChE,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;AAErE,qFAAqF;AACrF,MAAM,WAAW,oBAAoB;IACjC,oHAAoH;IACpH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,4GAA4G;IAC5G,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,qFAAqF;IACrF,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAoBD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACnC,OAAO,EAAE,oBAAoB,EAC7B,YAAY,GAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAoC,GACzF,OAAO,CAAC,cAAc,CAAC,CAuBzB;AAID,uFAAuF;AACvF,wBAAsB,eAAe,CACjC,OAAO,EAAE,oBAAoB,EAC7B,YAAY,GAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAoC,GACzF,OAAO,CAAC,cAAc,CAAC,CAkBzB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CA8DrF"}
1
+ {"version":3,"file":"decision-maker.d.ts","sourceRoot":"","sources":["../../src/decision/decision-maker.ts"],"names":[],"mappings":"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"}
@@ -7,13 +7,12 @@
7
7
  import { getProcessEnv } from '@gobing-ai/ts-runtime';
8
8
  import { DecisionConfigError } from './errors.js';
9
9
  import { q } from './types.js';
10
- import { createTypesafeDriver } from './typesafe-driver.js';
11
10
  import { validateAnswers, validateQuestions } from './validation.js';
12
11
  /**
13
12
  * Resolve the key per R7: `options.apiKey ?? (options.env ?? getProcessEnv()).TYPESAFE_API_KEY`.
14
13
  * Throws before any driver construction or request.
15
14
  */
16
- function resolveApiKey(options) {
15
+ export function resolveApiKey(options) {
17
16
  const env = options.env ?? getProcessEnv();
18
17
  const apiKey = options.apiKey ?? env.TYPESAFE_API_KEY;
19
18
  if (!apiKey) {
@@ -43,6 +42,36 @@ export async function resolveLayaDriver(options, importModule = (specifier) => i
43
42
  }
44
43
  return mod.createLayaDriver(options);
45
44
  }
45
+ const TYPESAFE_DRIVER_PACKAGE = '@gobing-ai/ts-ai-decision';
46
+ /**
47
+ * Resolve the `typesafe` driver from `@gobing-ai/ts-ai-decision` (task 0116 R5, ADR-039).
48
+ *
49
+ * The driver moved out of this package, which is now the contract-only surface. The key is
50
+ * resolved FIRST so a missing key keeps its exact pre-move error and no import is attempted.
51
+ *
52
+ * @internal Exported for the branch tests; see {@link resolveLayaDriver}.
53
+ */
54
+ export async function resolveTypesafeDriver(options, importModule = (specifier) => import(specifier)) {
55
+ const apiKey = resolveApiKey(options);
56
+ let mod;
57
+ try {
58
+ mod = (await importModule(TYPESAFE_DRIVER_PACKAGE));
59
+ }
60
+ catch (cause) {
61
+ throw new DecisionConfigError(`The 'typesafe' backend requires '${TYPESAFE_DRIVER_PACKAGE}' to be installed; install it with 'bun add ${TYPESAFE_DRIVER_PACKAGE}'`, 'TYPESAFE_BACKEND', { cause });
62
+ }
63
+ if (typeof mod.createTypesafeDriver !== 'function') {
64
+ throw new DecisionConfigError(`Module '${TYPESAFE_DRIVER_PACKAGE}' does not export createTypesafeDriver`, 'TYPESAFE_BACKEND');
65
+ }
66
+ return mod.createTypesafeDriver({
67
+ apiKey,
68
+ model: options.model,
69
+ baseURL: options.baseURL,
70
+ timeoutMs: options.timeoutMs,
71
+ maxRetries: options.maxRetries,
72
+ fetch: options.fetch,
73
+ });
74
+ }
46
75
  const FM_DRIVER_PACKAGE = '@gobing-ai/ts-decision-fm';
47
76
  /** @internal Exported for task 0086 R9 branch tests; see {@link resolveLayaDriver}. */
48
77
  export async function resolveFmDriver(options, importModule = (specifier) => import(specifier)) {
@@ -72,14 +101,7 @@ export function createDecisionMaker(options = {}) {
72
101
  return resolvedDriver;
73
102
  const backend = options.backend ?? 'typesafe';
74
103
  if (backend === 'typesafe') {
75
- resolvedDriver = createTypesafeDriver({
76
- apiKey: resolveApiKey(options),
77
- model: options.model,
78
- baseURL: options.baseURL,
79
- timeoutMs: options.timeoutMs,
80
- maxRetries: options.maxRetries,
81
- fetch: options.fetch,
82
- });
104
+ resolvedDriver = await resolveTypesafeDriver(options);
83
105
  return resolvedDriver;
84
106
  }
85
107
  if (backend === 'laya-local') {
@@ -0,0 +1,115 @@
1
+ /**
2
+ * The engine-agnostic sampled-driver core (task 0114 R1, ADR-038): prompt
3
+ * rendering, per-question enum options, answer parsing and frequency
4
+ * estimation, shared by every backend that answers by drawing k samples from a
5
+ * model. A backend supplies only the per-ask session hook.
6
+ *
7
+ * Pure by contract (R2): imports only the sibling `types` and `errors` modules —
8
+ * no SDK, no workspace package, no platform API. That is what lets a driver
9
+ * package outside `ts-ai-runner` build on it without a cycle.
10
+ */
11
+ import type { ChoiceAnswer, DecisionDriver, DecisionState, Desc, NoulAnswer, Question, ScoreAnswer } from './types';
12
+ /**
13
+ * Fixed instructions text. It never asks for confidence, certainty or a
14
+ * probability — self-reported confidence would be fabricated calibration, which
15
+ * the decision contract forbids (ADR-030).
16
+ */
17
+ export declare const DECISION_INSTRUCTIONS: string;
18
+ /** The constrained-output schema over the whole question map (fm passes it to `fm respond --schema`). */
19
+ export interface EnumSchema {
20
+ type: 'object';
21
+ title: string;
22
+ 'x-order': string[];
23
+ required: string[];
24
+ additionalProperties: false;
25
+ properties: Record<string, {
26
+ type: 'string';
27
+ enum: string[];
28
+ }>;
29
+ }
30
+ /** One ask's sampling session; opened once per ask and closed in `finally`. */
31
+ export interface SampleSession {
32
+ /** Return one sample as a key → option-string record (parsed, not yet enum-checked). */
33
+ sample(): Promise<Record<string, string>>;
34
+ /** Release per-ask resources (temp schema file, scratch dir). Called on success and failure. */
35
+ close?(): void | Promise<void>;
36
+ }
37
+ /** Configuration for {@link createSampledDriver}. */
38
+ export interface SampledDriverOptions {
39
+ /** Driver name reported through `DecisionDriver.name`. */
40
+ readonly name: string;
41
+ /** Samples per ask. Default: 5. Ignored when `deterministic`. Positive integer. */
42
+ readonly samples?: number;
43
+ /** One sample; the sampler is expected to decode greedily. Default: false. */
44
+ readonly deterministic?: boolean;
45
+ /** Max samples in flight. Default: 1 (sequential). Positive integer. */
46
+ readonly concurrency?: number;
47
+ /** Prefix used in enum-violation messages. Default: `name` (fm passes `'fm'`). */
48
+ readonly sampleLabel?: string;
49
+ /** Open the per-ask session. Receives the rendered texts and the validated request. */
50
+ open(ctx: {
51
+ instructions: string;
52
+ prompt: string;
53
+ questions: Record<string, Question>;
54
+ state: DecisionState;
55
+ model?: string;
56
+ }): Promise<SampleSession>;
57
+ /** Override the default {@link DECISION_INSTRUCTIONS} text. */
58
+ readonly instructions?: string;
59
+ }
60
+ /** A {@link DecisionDriver} built on sample frequencies, with the estimator it declares (ADR-030). */
61
+ export interface SampledDecisionDriver extends DecisionDriver {
62
+ readonly estimator: {
63
+ readonly kind: 'sample-frequency';
64
+ readonly samples: number;
65
+ readonly greedy: boolean;
66
+ };
67
+ }
68
+ /** Build the enum schema over the whole question map: one call answers every key. */
69
+ export declare function buildEnumSchema(questions: Record<string, Question>): EnumSchema;
70
+ /** Format a {@link Desc} into prompt text: strings verbatim, structured values JSON, absence empty. */
71
+ export declare function formatDesc(desc: Desc | undefined): string;
72
+ /** The declared option values of a question, in declaration order (estimation + validation share this). */
73
+ export declare function declaredOptions(question: Question): string[];
74
+ /**
75
+ * Render the positional prompt: the state as text (JSON when structured), then
76
+ * one block per question key with the prompt `Desc` and its options with
77
+ * descriptions — choice label keys, score level indices with the rubric text,
78
+ * noul `yes`/`no` with any outcome descriptions.
79
+ */
80
+ export declare function buildPrompt(state: DecisionState, questions: Record<string, Question>): string;
81
+ /**
82
+ * Laya reference `confidence_from_probs` on the empirical distribution:
83
+ * `1 − H(p) / ln(n)` over the n declared options. One-hot ⇒ 1, uniform ⇒ 0.
84
+ */
85
+ export declare function entropyConfidence(probabilities: number[]): number;
86
+ /**
87
+ * Choice frequencies over every supplied label (unsampled ⇒ 0). The answer
88
+ * label is the most frequent with ties broken by label declaration order.
89
+ */
90
+ export declare function estimateChoice(labels: readonly string[], samples: readonly string[]): ChoiceAnswer<string>;
91
+ /**
92
+ * Score frequencies over the level indices `0…n-1`. The answer score is the
93
+ * most frequent level with ties going to the lower level; the legend maps each
94
+ * index back to its rubric description.
95
+ */
96
+ export declare function estimateScore(rubric: readonly Desc[], samples: readonly string[]): ScoreAnswer;
97
+ /** Noul is a bare yes-probability — no `confidence` key, by contract. */
98
+ export declare function estimateNoul(samples: readonly string[]): NoulAnswer;
99
+ /** A parsed value outside the declared enum is a schema violation, never an answer. */
100
+ export declare function requireEnumValue(parsed: Record<string, string>, key: string, allowed: readonly string[], label?: string): string;
101
+ /**
102
+ * Lenient answer parser for models without constrained decoding (task 0114 R6).
103
+ * Tries the whole text, then the first fenced block, then the first balanced
104
+ * object in prose. The result must be a flat object of string values.
105
+ */
106
+ export declare function extractJsonAnswer(text: string): Record<string, string>;
107
+ /**
108
+ * Build a sampled driver: k draws through one per-ask {@link SampleSession},
109
+ * enum-checked against the declared options and reduced to sample frequencies.
110
+ *
111
+ * The order inside `ask` is the contract (R5): validate → render → open →
112
+ * sample → enum-check → estimate, with `close` in `finally` either way.
113
+ */
114
+ export declare function createSampledDriver(options: SampledDriverOptions): SampledDecisionDriver;
115
+ //# sourceMappingURL=sampled-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampled-driver.d.ts","sourceRoot":"","sources":["../../src/decision/sampled-driver.ts"],"names":[],"mappings":"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"}