oracular 0.2.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.
- package/CHANGELOG.md +22 -0
- package/README.md +44 -9
- package/dist/cli.js +656 -0
- package/dist/index.cjs +177 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +223 -30
- package/dist/index.d.ts +223 -30
- package/dist/index.js +175 -18
- package/dist/index.js.map +1 -1
- package/package.json +13 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Version of the serialized state shape, stored in every state as `state.version`.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Version of the serialized state shape, stored in every state as `state.version`. Bumped only
|
|
3
|
+
* when `EngineState` changes incompatibly, and every bump ships its migration: {@link deserialize}
|
|
4
|
+
* upgrades states saved by earlier versions of this library on its own (version 1, written by
|
|
5
|
+
* oracular 0.1.0 to 0.2.x, becomes version 2) and calls your `migrate` function only for a version
|
|
6
|
+
* it does not know.
|
|
5
7
|
*
|
|
6
8
|
* @example
|
|
7
9
|
* ```ts
|
|
8
10
|
* import { STATE_VERSION, deserialize } from 'oracular';
|
|
9
11
|
*
|
|
10
12
|
* const state = deserialize(saved, {
|
|
13
|
+
* config,
|
|
14
|
+
* // Only reached for versions this library cannot migrate itself, such as a state written by a
|
|
15
|
+
* // newer oracular before a rollback.
|
|
11
16
|
* migrate: (stored, version) => {
|
|
12
|
-
*
|
|
13
|
-
* throw new Error(`cannot migrate version ${version} to ${STATE_VERSION}`);
|
|
17
|
+
* throw new Error(`cannot read oracular state version ${version} (this build reads ${STATE_VERSION})`);
|
|
14
18
|
* },
|
|
15
19
|
* });
|
|
16
20
|
* ```
|
|
17
21
|
*/
|
|
18
|
-
declare const STATE_VERSION:
|
|
22
|
+
declare const STATE_VERSION: 2;
|
|
23
|
+
/**
|
|
24
|
+
* Version of the recorder format: the `v` field of every record that {@link createRecord} and
|
|
25
|
+
* {@link createEndRecord} produce. A new optional field does not change it; readers ignore fields
|
|
26
|
+
* they do not know and skip records of a `kind` they do not know. Anything a reader written for
|
|
27
|
+
* this version could misread bumps it.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { RECORD_VERSION } from 'oracular';
|
|
32
|
+
*
|
|
33
|
+
* const record = JSON.parse(line);
|
|
34
|
+
* if (record.v !== RECORD_VERSION) throw new Error(`unsupported recorder format ${record.v}`);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare const RECORD_VERSION: 1;
|
|
19
38
|
|
|
20
39
|
/**
|
|
21
40
|
* Options that decide when `shouldReveal` fires and how long cooldowns last. Resolved per call →
|
|
@@ -48,9 +67,9 @@ interface RevealOptions {
|
|
|
48
67
|
interface LearningConfig {
|
|
49
68
|
/** Half-life of learned hit/miss counts, in the same unit as `at`. Omit for no forgetting. */
|
|
50
69
|
halfLife?: number;
|
|
51
|
-
/** A perfectly predictive signal converges to `gain × |initial weight|`. Default 2. */
|
|
70
|
+
/** A perfectly predictive signal converges to `gain × |initial weight|`. Default 2; at most 1e6. */
|
|
52
71
|
gain?: number;
|
|
53
|
-
/** Pseudo-count behind the developer's initial weight: how many observed episodes it takes to weigh as much as the prior. Default 10. */
|
|
72
|
+
/** Pseudo-count behind the developer's initial weight: how many observed episodes it takes to weigh as much as the prior. Default 10; at most 1e6. */
|
|
54
73
|
priorEpisodes?: number;
|
|
55
74
|
}
|
|
56
75
|
/**
|
|
@@ -72,16 +91,27 @@ interface LearningConfig {
|
|
|
72
91
|
interface IntentConfig {
|
|
73
92
|
/** Prior probability, strictly between 0 and 1. */
|
|
74
93
|
prior: number;
|
|
75
|
-
/** Strength of the prior as a pseudo-count, greater than 0. */
|
|
94
|
+
/** Strength of the prior as a pseudo-count, greater than 0 and at most 1e6. */
|
|
76
95
|
priorStrength: number;
|
|
77
96
|
/** Half-life of evidence, in the same unit as `at`. Evidence decays back toward the prior. */
|
|
78
97
|
halfLife: number;
|
|
79
|
-
/** Event name → initial weight. Positive is evidence for the intent, negative against. Non-zero. */
|
|
98
|
+
/** Event name → initial weight. Positive is evidence for the intent, negative against. Non-zero, between −1e6 and 1e6. */
|
|
80
99
|
signals: Record<string, number>;
|
|
81
100
|
/** Event name that confirms the intent happened, e.g. `'checkout.completed'`. */
|
|
82
101
|
outcome?: string;
|
|
83
102
|
/** Reset α, β and contributions to the prior when the outcome arrives. Default true. */
|
|
84
103
|
resetOnOutcome?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Repeats of a signal within one episode add less: the n-th occurrence adds
|
|
106
|
+
* `w × log2(1 + 1/n)`, so ten occurrences add 3.46 weights, not ten. The count restarts when
|
|
107
|
+
* the episode ends or this intent's outcome arrives. Default: true when `episodeTimeout` is
|
|
108
|
+
* set, false otherwise, because without an idle timeout episodes end only when the app calls
|
|
109
|
+
* `endEpisode`, and if it never does the count would never restart. Set true to saturate
|
|
110
|
+
* anyway (your app ends every episode itself), or false for intents where the repetition
|
|
111
|
+
* itself is the evidence (a user stuck on the same step), so every occurrence adds its full
|
|
112
|
+
* weight.
|
|
113
|
+
*/
|
|
114
|
+
saturate?: boolean;
|
|
85
115
|
/** Reveal defaults for this intent. */
|
|
86
116
|
reveal?: RevealOptions;
|
|
87
117
|
}
|
|
@@ -144,6 +174,11 @@ interface IntentState {
|
|
|
144
174
|
interface EpisodeIntentRecord {
|
|
145
175
|
/** Signals seen since the episode started (or since this intent's last outcome). */
|
|
146
176
|
seen: string[];
|
|
177
|
+
/**
|
|
178
|
+
* How many times each signal in `seen` has occurred over the same span; its keys are exactly the
|
|
179
|
+
* signals in `seen`. Repeats saturate: the n-th occurrence adds less than the first.
|
|
180
|
+
*/
|
|
181
|
+
counts: Record<string, number>;
|
|
147
182
|
/** Whether the outcome arrived in this episode. */
|
|
148
183
|
resolved: boolean;
|
|
149
184
|
}
|
|
@@ -237,7 +272,10 @@ interface SignalExplanation {
|
|
|
237
272
|
initialWeight: number;
|
|
238
273
|
/** What this user's history alone says the weight should be. */
|
|
239
274
|
learnedWeight: number;
|
|
240
|
-
/**
|
|
275
|
+
/**
|
|
276
|
+
* The blend of initial and learned weight: what the signal adds the first time it occurs in an
|
|
277
|
+
* episode. Repeats within the episode add less (see {@link IntentConfig.saturate}).
|
|
278
|
+
*/
|
|
241
279
|
effectiveWeight: number;
|
|
242
280
|
hits: number;
|
|
243
281
|
misses: number;
|
|
@@ -274,8 +312,9 @@ interface Evaluation {
|
|
|
274
312
|
explanation: SignalExplanation[];
|
|
275
313
|
}
|
|
276
314
|
/**
|
|
277
|
-
* Turns a stored state of
|
|
278
|
-
* JSON as-is and the version it declares.
|
|
315
|
+
* Turns a stored state of a version this library cannot migrate itself into a current
|
|
316
|
+
* `EngineState`. Receives the parsed JSON as-is and the version it declares. States saved by
|
|
317
|
+
* oracular 0.1.0 to 0.2.x (version 1) never reach it: `deserialize` upgrades those on its own.
|
|
279
318
|
*
|
|
280
319
|
* @example
|
|
281
320
|
* ```ts
|
|
@@ -297,9 +336,103 @@ type Migrate = (stored: unknown, version: number) => EngineState;
|
|
|
297
336
|
interface DeserializeOptions {
|
|
298
337
|
/** The app's current config. Validated, swapped in, and used to prune signals and intents no longer declared. */
|
|
299
338
|
config?: EngineConfig;
|
|
300
|
-
/**
|
|
339
|
+
/**
|
|
340
|
+
* Called when the stored version is neither `STATE_VERSION` nor one this library migrates
|
|
341
|
+
* itself (states from oracular 0.1.0 to 0.2.x are upgraded without it).
|
|
342
|
+
*/
|
|
301
343
|
migrate?: Migrate;
|
|
302
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
* Whether the app acted on reveals when a record was made: `'shadow'` when it only computed them
|
|
347
|
+
* (nothing shown to the user), `'live'` when it showed them. Replay only measures shadow periods
|
|
348
|
+
* honestly: once a reveal is live, the reveal itself causes outcomes.
|
|
349
|
+
*/
|
|
350
|
+
type RecordMode = 'shadow' | 'live';
|
|
351
|
+
/**
|
|
352
|
+
* What every record needs from the app, for {@link createRecord} and {@link createEndRecord}.
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```ts
|
|
356
|
+
* const recording: RecordOptions = { installId: storedInstallId, mode: 'shadow' };
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
interface RecordOptions {
|
|
360
|
+
/**
|
|
361
|
+
* A random id the app generates once, on first use, and stores (for example
|
|
362
|
+
* `crypto.randomUUID()`). It groups one install's records across exports and nothing else; never
|
|
363
|
+
* derive it from the device, the account or anything else about the user.
|
|
364
|
+
*/
|
|
365
|
+
installId: string;
|
|
366
|
+
/** Whether reveals are shown to the user right now. */
|
|
367
|
+
mode: RecordMode;
|
|
368
|
+
/** How many signals to list in `top`, by size of impact. Default 3. */
|
|
369
|
+
top?: number;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* What the engine decided for one intent at the moment of a record. It is there to compare what
|
|
373
|
+
* shipped with what a different config would have done; replay recomputes everything from the
|
|
374
|
+
* events and never reads it.
|
|
375
|
+
*/
|
|
376
|
+
interface RecordedDecision {
|
|
377
|
+
/** As {@link Prediction.p}. */
|
|
378
|
+
p: number;
|
|
379
|
+
/** As {@link Prediction.lower}. */
|
|
380
|
+
lower: number;
|
|
381
|
+
/** What `shouldReveal` returned with the state's own reveal options. */
|
|
382
|
+
shouldReveal: boolean;
|
|
383
|
+
/** As {@link Prediction.suppressedUntil}. */
|
|
384
|
+
suppressedUntil: number | null;
|
|
385
|
+
/** Signals currently holding evidence, largest |impact| first, at most `RecordOptions.top`. */
|
|
386
|
+
top: {
|
|
387
|
+
signal: string;
|
|
388
|
+
impact: number;
|
|
389
|
+
}[];
|
|
390
|
+
/** Effective weight of every declared signal, in config order. */
|
|
391
|
+
weights: Record<string, number>;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* One line of a recorder log: an event the app observed and what the engine decided right after
|
|
395
|
+
* it. The event (`name` and `at`, never `props`) is what replay recomputes from; the decisions
|
|
396
|
+
* are kept apart so they can never be mistaken for inputs.
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* ```ts
|
|
400
|
+
* state = observe(state, event);
|
|
401
|
+
* log.append(JSON.stringify(createRecord(state, event, recording)));
|
|
402
|
+
* ```
|
|
403
|
+
*/
|
|
404
|
+
interface EventRecord {
|
|
405
|
+
v: typeof RECORD_VERSION;
|
|
406
|
+
kind: 'event';
|
|
407
|
+
installId: string;
|
|
408
|
+
mode: RecordMode;
|
|
409
|
+
event: {
|
|
410
|
+
name: string;
|
|
411
|
+
at: number;
|
|
412
|
+
};
|
|
413
|
+
/** One entry per declared intent. */
|
|
414
|
+
decisions: Record<string, RecordedDecision>;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* One line of a recorder log: the app ended the episode with {@link endEpisode}. Replay needs it
|
|
418
|
+
* to reproduce the misses that the episode's end records; episodes that end through
|
|
419
|
+
* `episodeTimeout` need no record.
|
|
420
|
+
*
|
|
421
|
+
* @example
|
|
422
|
+
* ```ts
|
|
423
|
+
* state = endEpisode(state, at);
|
|
424
|
+
* log.append(JSON.stringify(createEndRecord(at, recording)));
|
|
425
|
+
* ```
|
|
426
|
+
*/
|
|
427
|
+
interface EndRecord {
|
|
428
|
+
v: typeof RECORD_VERSION;
|
|
429
|
+
kind: 'end';
|
|
430
|
+
installId: string;
|
|
431
|
+
mode: RecordMode;
|
|
432
|
+
at: number;
|
|
433
|
+
}
|
|
434
|
+
/** A line of a recorder log. */
|
|
435
|
+
type RecorderRecord = EventRecord | EndRecord;
|
|
303
436
|
|
|
304
437
|
/**
|
|
305
438
|
* {@link predict}, {@link shouldReveal} and {@link explain} in one call, from a single decay
|
|
@@ -328,8 +461,10 @@ declare function evaluate(state: EngineState, intent: string, at: number, opts?:
|
|
|
328
461
|
/**
|
|
329
462
|
* How much positive evidence an intent needs before {@link shouldReveal} first becomes true:
|
|
330
463
|
* the smallest pseudo-count `w` such that Beta(α₀ + w, β₀) clears both `p ≥ threshold` and
|
|
331
|
-
* `p − z·sd ≥ threshold`. Divide by a signal's weight and round up for the number of
|
|
332
|
-
*
|
|
464
|
+
* `p − z·sd ≥ threshold`. Divide by a signal's weight and round up for the number of full-weight
|
|
465
|
+
* occurrences that open the gate: distinct signals, or one occurrence per episode. Repeats within
|
|
466
|
+
* one episode add less (n of them add `w × log2(1 + n)`, see {@link IntentConfig.saturate}).
|
|
467
|
+
* Solved numerically to 1e-9.
|
|
333
468
|
*
|
|
334
469
|
* Cooldowns and decay are not part of the answer: this is the evidence needed at one instant.
|
|
335
470
|
*
|
|
@@ -342,7 +477,7 @@ declare function evaluate(state: EngineState, intent: string, at: number, opts?:
|
|
|
342
477
|
* @example
|
|
343
478
|
* ```ts
|
|
344
479
|
* const needed = evidenceToReveal(config.intents.upgrade); // ≈ 15.1 for the quickstart config
|
|
345
|
-
* Math.ceil(needed / 3); // 6 signals of weight 3
|
|
480
|
+
* Math.ceil(needed / 3); // 6 full-weight signals of weight 3
|
|
346
481
|
* ```
|
|
347
482
|
*/
|
|
348
483
|
declare function evidenceToReveal(intent: IntentConfig, opts?: RevealOptions): number;
|
|
@@ -378,10 +513,14 @@ declare function explain(state: EngineState, intent: string, at: number, opts?:
|
|
|
378
513
|
*
|
|
379
514
|
* For every intent the event is a signal of: decay its evidence to `event.at`, then add the
|
|
380
515
|
* signal's effective weight to α (positive) or β (negative) and remember the signal for this
|
|
381
|
-
* episode.
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
516
|
+
* episode. Repeats within an episode saturate: the n-th occurrence of a signal adds
|
|
517
|
+
* `w × log2(1 + 1/n)`, counted since the episode started or the intent's outcome last arrived.
|
|
518
|
+
* That is the default when `config.episodeTimeout` is set, and `IntentConfig.saturate` overrides
|
|
519
|
+
* it either way; otherwise every occurrence adds all of `w`. For every intent the event is the
|
|
520
|
+
* outcome of: give the remembered signals a hit, count the episode toward the base rate, record
|
|
521
|
+
* `lastOutcomeAt`, and (by default) reset the evidence to the prior. Any event opens or extends
|
|
522
|
+
* the current episode; an idle gap longer than `config.episodeTimeout` closes the previous
|
|
523
|
+
* episode first.
|
|
385
524
|
*
|
|
386
525
|
* @param state - The current state. Not mutated.
|
|
387
526
|
* @param event - `name` is matched against every intent's signals and outcome; `at` is the
|
|
@@ -503,6 +642,56 @@ declare function shouldReveal(state: EngineState, intent: string, at: number, op
|
|
|
503
642
|
*/
|
|
504
643
|
declare function markRevealed(state: EngineState, intent: string, at: number): EngineState;
|
|
505
644
|
|
|
645
|
+
/**
|
|
646
|
+
* A recorder record for an event: the event itself and, for every intent, what the engine decides
|
|
647
|
+
* right after it. Call it with the state `observe` returned for that event, then append
|
|
648
|
+
* `JSON.stringify(record)` as one line of the log (NDJSON). The record holds the event's `name` and
|
|
649
|
+
* `at`, never its `props`.
|
|
650
|
+
*
|
|
651
|
+
* Each decision is what {@link evaluate} reports at `event.at` with the state's own reveal
|
|
652
|
+
* options: `p`, `lower`, `shouldReveal`, `suppressedUntil`, the signals with the largest impact,
|
|
653
|
+
* and the effective weight of every signal. Pure: the install id comes from the app, never from
|
|
654
|
+
* here. See the Shadow mode guide for the whole workflow.
|
|
655
|
+
*
|
|
656
|
+
* @param state - The state after `observe(state, event)`. Not mutated.
|
|
657
|
+
* @param event - The event just observed. Only `name` and `at` are recorded.
|
|
658
|
+
* @param opts - `installId` (generated and stored by the app), `mode` (`'shadow'` while
|
|
659
|
+
* reveals are computed but not shown, `'live'` once they are), and `top` (default 3).
|
|
660
|
+
* @returns A plain, JSON-serializable {@link EventRecord}.
|
|
661
|
+
* @throws `TypeError` when `state` is not an engine state, the event is malformed, `opts` is
|
|
662
|
+
* not an object, has an unknown key, an empty `installId` or a `mode` other than
|
|
663
|
+
* `'shadow'` or `'live'`.
|
|
664
|
+
* @throws `RangeError` when `opts.top` is negative or fractional.
|
|
665
|
+
* @example
|
|
666
|
+
* ```ts
|
|
667
|
+
* const recording = { installId: localStorage.getItem('oracular.install')!, mode: 'shadow' } as const;
|
|
668
|
+
*
|
|
669
|
+
* const event = { name: 'pricing.viewed', at: Date.now() };
|
|
670
|
+
* state = observe(state, event);
|
|
671
|
+
* appendLine(JSON.stringify(createRecord(state, event, recording)));
|
|
672
|
+
* ```
|
|
673
|
+
*/
|
|
674
|
+
declare function createRecord(state: EngineState, event: IntentEvent, opts: RecordOptions): EventRecord;
|
|
675
|
+
/**
|
|
676
|
+
* A recorder record for the end of an episode. Write one whenever the app calls
|
|
677
|
+
* {@link endEpisode}, with the same `at`, so that replay can end the episode at the same moment
|
|
678
|
+
* and reproduce the misses it records. Episodes that close through `episodeTimeout` need none:
|
|
679
|
+
* replay applies the timeout itself.
|
|
680
|
+
*
|
|
681
|
+
* @param at - The time passed to `endEpisode`.
|
|
682
|
+
* @param opts - The same options as for {@link createRecord}; `top` is accepted and ignored.
|
|
683
|
+
* @returns A plain, JSON-serializable {@link EndRecord}.
|
|
684
|
+
* @throws `TypeError` when `at` is not a finite number or `opts` is malformed.
|
|
685
|
+
* @throws `RangeError` when `opts.top` is negative or fractional.
|
|
686
|
+
* @example
|
|
687
|
+
* ```ts
|
|
688
|
+
* const at = Date.now();
|
|
689
|
+
* state = endEpisode(state, at);
|
|
690
|
+
* appendLine(JSON.stringify(createEndRecord(at, recording)));
|
|
691
|
+
* ```
|
|
692
|
+
*/
|
|
693
|
+
declare function createEndRecord(at: number, opts: RecordOptions): EndRecord;
|
|
694
|
+
|
|
506
695
|
/**
|
|
507
696
|
* The state as a JSON string, for the host app to persist wherever it likes. The state is plain
|
|
508
697
|
* data, so this is `JSON.stringify` after a shape check. The output never contains event props.
|
|
@@ -521,19 +710,22 @@ declare function serialize(state: EngineState): string;
|
|
|
521
710
|
*
|
|
522
711
|
* Always pass the app's current `config`: it is validated and replaces the stored snapshot,
|
|
523
712
|
* intents and signals no longer declared are dropped (α and β are recomputed from the kept
|
|
524
|
-
* contributions), and newly declared intents start at their prior.
|
|
525
|
-
*
|
|
713
|
+
* contributions), and newly declared intents start at their prior. States saved by oracular
|
|
714
|
+
* 0.1.0 to 0.2.x are upgraded to the current shape on their own; `migrate` is only for a version
|
|
715
|
+
* this library does not know.
|
|
526
716
|
*
|
|
527
717
|
* @param json - A string produced by {@link serialize}.
|
|
528
718
|
* @param opts - `config`: the app's current config. `migrate`: called as
|
|
529
|
-
* `migrate(stored, version)` when the stored version
|
|
530
|
-
* it must return a state of the current version.
|
|
719
|
+
* `migrate(stored, version)` when the stored version is neither {@link STATE_VERSION} nor one
|
|
720
|
+
* this library migrates itself; it must return a state of the current version.
|
|
531
721
|
* @returns A validated state that satisfies the engine's invariants.
|
|
532
722
|
* @throws `SyntaxError` when `json` is not valid JSON.
|
|
533
723
|
* @throws `TypeError` when the stored data, the result of `migrate`, `opts` or `opts.config`
|
|
534
724
|
* has the wrong shape.
|
|
535
|
-
* @throws `RangeError` when the stored version
|
|
536
|
-
* `migrate` does not return the current version,
|
|
725
|
+
* @throws `RangeError` when the stored version is unknown and no `migrate` is given, when
|
|
726
|
+
* `migrate` does not return the current version, when a stored number is out of range, or
|
|
727
|
+
* when stored numbers are finite but too large to compute with (a tampered or corrupted state
|
|
728
|
+
* that would otherwise answer NaN).
|
|
537
729
|
* @example
|
|
538
730
|
* ```ts
|
|
539
731
|
* const saved = localStorage.getItem('oracular');
|
|
@@ -552,8 +744,9 @@ declare function deserialize(json: string, opts?: DeserializeOptions): EngineSta
|
|
|
552
744
|
* strictly: unknown keys, non-finite numbers and out-of-range values throw.
|
|
553
745
|
* @returns A new, JSON-serializable state. `config` is not mutated.
|
|
554
746
|
* @throws `TypeError` when a value has the wrong type or a key is not recognised.
|
|
555
|
-
* @throws `RangeError` when a number is out of range, for example a `prior` outside (0, 1)
|
|
556
|
-
* signal weight of 0.
|
|
747
|
+
* @throws `RangeError` when a number is out of range, for example a `prior` outside (0, 1), a
|
|
748
|
+
* signal weight of 0, or a weight, `priorStrength`, `learning.gain` or
|
|
749
|
+
* `learning.priorEpisodes` beyond 1e6 (larger values could overflow the arithmetic).
|
|
557
750
|
* @example
|
|
558
751
|
* ```ts
|
|
559
752
|
* const state = createState({
|
|
@@ -571,4 +764,4 @@ declare function deserialize(json: string, opts?: DeserializeOptions): EngineSta
|
|
|
571
764
|
*/
|
|
572
765
|
declare function createState(config: EngineConfig): EngineState;
|
|
573
766
|
|
|
574
|
-
export { type DeserializeOptions, type EngineConfig, type EngineState, type EpisodeIntentRecord, type EpisodeState, type EvaluateOptions, type Evaluation, type ExplainOptions, type IntentConfig, type IntentEvent, type IntentState, type LearningConfig, type Migrate, type Prediction, type RevealOptions, STATE_VERSION, type SignalContribution, type SignalExplanation, type SignalRecord, createState, deserialize, endEpisode, episodeClosed, evaluate, evidenceToReveal, explain, markRevealed, observe, predict, serialize, shouldReveal };
|
|
767
|
+
export { type DeserializeOptions, type EndRecord, type EngineConfig, type EngineState, type EpisodeIntentRecord, type EpisodeState, type EvaluateOptions, type Evaluation, type EventRecord, type ExplainOptions, type IntentConfig, type IntentEvent, type IntentState, type LearningConfig, type Migrate, type Prediction, RECORD_VERSION, type RecordMode, type RecordOptions, type RecordedDecision, type RecorderRecord, type RevealOptions, STATE_VERSION, type SignalContribution, type SignalExplanation, type SignalRecord, createEndRecord, createRecord, createState, deserialize, endEpisode, episodeClosed, evaluate, evidenceToReveal, explain, markRevealed, observe, predict, serialize, shouldReveal };
|