oracular 0.15.0 → 0.16.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#74](https://github.com/Yuribenjamin/oracular/pull/74) [`7e6b6fc`](https://github.com/Yuribenjamin/oracular/commit/7e6b6fc3885dac0167b92661e188e3f779a73a45) Thanks [@Yuribenjamin](https://github.com/Yuribenjamin)! - **The outcome record keeps the estimate the reset wipes.** `createRecord` takes the state after `observe`, so on the record of an intent's own outcome event `p` is what the engine decides right after it, with `resetOnOutcome` the prior (0.150 where it had been 0.506 one event earlier). Replay recomputes everything from the events and never reads it, but people read the log, and the number that matters most on an outcome line was gone. `createRecord(state, event, options, previous)` takes the state from before the event as an optional fourth argument; the decision of each intent whose outcome the event is then gains `before`, its `p` and `lower` at `event.at` on that state. Every other record is byte for byte what it was. `RECORD_VERSION` stays 1: a new optional field does not change it, readers ignore fields they do not know, and `replay` and `tune` never read decisions, so a log with `before` replays on every release that reads version 1. Found by the second production integration.
8
+
3
9
  ## 0.15.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -264,7 +264,7 @@ evaluate(state, intent: string, at: number, opts?): { prediction, reveal, explan
264
264
  inspect(state, at: number, opts?): { at, intents: [{ intent, prediction, reveal, explanation }] } // evaluate for every intent
265
265
  evidenceToReveal(intentConfig, opts?): number // pseudo-counts at which shouldReveal first becomes true
266
266
  episodeClosed(prev, next): boolean // did an episode close between two states?
267
- createRecord(state, event, { installId, mode }): EventRecord // one recorder line: the event and what was decided
267
+ createRecord(state, event, { installId, mode }, previous?): EventRecord // one recorder line: the event and what was decided; with the state before the event, the outcome's record keeps the estimate the reset wipes
268
268
  createEndRecord(at, { installId, mode }): EndRecord // one recorder line: the episode ended
269
269
  serialize(state): string
270
270
  deserialize(json: string, opts?: { config?: EngineConfig; migrate?: Migrate }): EngineState
package/dist/index.cjs CHANGED
@@ -899,10 +899,11 @@ function normalizeRecordOptions(value) {
899
899
  }
900
900
  return { installId, mode, top };
901
901
  }
902
- function createRecord(state, event, opts) {
902
+ function createRecord(state, event, opts, previous) {
903
903
  const s = requireState(state);
904
904
  const { name, at } = validateEvent(event);
905
905
  const { installId, mode, top } = normalizeRecordOptions(opts);
906
+ const prev = previous === void 0 ? void 0 : requireState(previous);
906
907
  const learning = resolveLearning(s.config);
907
908
  const decisions = {};
908
909
  for (const [intentName, intent] of Object.entries(s.config.intents)) {
@@ -914,7 +915,7 @@ function createRecord(state, event, opts) {
914
915
  for (const signal of Object.keys(intent.signals)) {
915
916
  weights[signal] = rows.find((row) => row.signal === signal).effectiveWeight;
916
917
  }
917
- decisions[intentName] = {
918
+ const decision = {
918
919
  p: prediction.p,
919
920
  lower: prediction.lower,
920
921
  shouldReveal: decideReveal(prediction, reveal),
@@ -922,6 +923,17 @@ function createRecord(state, event, opts) {
922
923
  top: rows.filter((row) => row.contribution !== 0).slice(0, top).map((row) => ({ signal: row.signal, impact: row.impact })),
923
924
  weights
924
925
  };
926
+ const prevIntent = prev === void 0 ? void 0 : getOwn(prev.config.intents, intentName);
927
+ if (prev !== void 0 && prevIntent !== void 0 && intent.outcome === name) {
928
+ const was = buildPrediction(
929
+ assessIntent(prev, intentName, prevIntent, resolveLearning(prev.config), at),
930
+ intentName,
931
+ resolveReveal(prev.config, prevIntent, void 0),
932
+ at
933
+ );
934
+ decision.before = { p: was.p, lower: was.lower };
935
+ }
936
+ decisions[intentName] = decision;
925
937
  }
926
938
  return { v: RECORD_VERSION, kind: "event", installId, mode, event: { name, at }, decisions };
927
939
  }