oracular 0.14.0 → 0.15.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 +8 -0
- package/README.md +2 -1
- package/dist/index.cjs +12 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/presets.d.cts +12 -0
- package/dist/presets.d.ts +12 -0
- package/package.json +1 -1
- package/schema/config.schema.json +4 -0
package/dist/index.d.cts
CHANGED
|
@@ -138,6 +138,18 @@ interface IntentConfig {
|
|
|
138
138
|
* weight.
|
|
139
139
|
*/
|
|
140
140
|
saturate?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Each outcome is an episode of its own for this intent, rather than the session. After the
|
|
143
|
+
* outcome arrives, the intent's bookkeeping starts over: a later outcome in the same session
|
|
144
|
+
* counts as another episode even with nothing seen since, and signals seen after an outcome
|
|
145
|
+
* take a miss at the session's close (or wait under `attribution`), as a first attempt would.
|
|
146
|
+
* Default false: the episode is the session, a repeated outcome with nothing seen since counts
|
|
147
|
+
* nothing, and signals seen after an outcome are neutral at the close. For intents shaped as
|
|
148
|
+
* attempts (an upload that fails, then completes, then completes again), where the second
|
|
149
|
+
* attempt is the contrast learning needs. With it set, a duplicated outcome event counts twice:
|
|
150
|
+
* dedupe such events in the app.
|
|
151
|
+
*/
|
|
152
|
+
episodePerOutcome?: boolean;
|
|
141
153
|
/**
|
|
142
154
|
* How long a closed episode's signals wait for the outcome before they take a miss, in the same
|
|
143
155
|
* unit as `at`. With it set, an episode that ends without the outcome is held instead of
|
|
@@ -657,7 +669,8 @@ declare function explain(state: EngineState, intent: string, at: number, opts?:
|
|
|
657
669
|
* it either way; otherwise every occurrence adds all of `w`. For every intent the event is the
|
|
658
670
|
* outcome of: give the signals remembered since the episode started or the outcome last arrived a
|
|
659
671
|
* hit and count the episode toward the base rate (a repeated outcome with nothing seen since
|
|
660
|
-
* counts nothing
|
|
672
|
+
* counts nothing, unless `IntentConfig.episodePerOutcome` makes every outcome an episode of its
|
|
673
|
+
* own for the intent), credit
|
|
661
674
|
* the closed episodes still waiting under `IntentConfig.attribution` by `2^(−age / halfLife)`
|
|
662
675
|
* each, record `lastOutcomeAt`, and (by default) reset the evidence to the prior. Any event opens
|
|
663
676
|
* or extends the current episode; an idle gap longer than `config.episodeTimeout` closes the
|
package/dist/index.d.ts
CHANGED
|
@@ -138,6 +138,18 @@ interface IntentConfig {
|
|
|
138
138
|
* weight.
|
|
139
139
|
*/
|
|
140
140
|
saturate?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Each outcome is an episode of its own for this intent, rather than the session. After the
|
|
143
|
+
* outcome arrives, the intent's bookkeeping starts over: a later outcome in the same session
|
|
144
|
+
* counts as another episode even with nothing seen since, and signals seen after an outcome
|
|
145
|
+
* take a miss at the session's close (or wait under `attribution`), as a first attempt would.
|
|
146
|
+
* Default false: the episode is the session, a repeated outcome with nothing seen since counts
|
|
147
|
+
* nothing, and signals seen after an outcome are neutral at the close. For intents shaped as
|
|
148
|
+
* attempts (an upload that fails, then completes, then completes again), where the second
|
|
149
|
+
* attempt is the contrast learning needs. With it set, a duplicated outcome event counts twice:
|
|
150
|
+
* dedupe such events in the app.
|
|
151
|
+
*/
|
|
152
|
+
episodePerOutcome?: boolean;
|
|
141
153
|
/**
|
|
142
154
|
* How long a closed episode's signals wait for the outcome before they take a miss, in the same
|
|
143
155
|
* unit as `at`. With it set, an episode that ends without the outcome is held instead of
|
|
@@ -657,7 +669,8 @@ declare function explain(state: EngineState, intent: string, at: number, opts?:
|
|
|
657
669
|
* it either way; otherwise every occurrence adds all of `w`. For every intent the event is the
|
|
658
670
|
* outcome of: give the signals remembered since the episode started or the outcome last arrived a
|
|
659
671
|
* hit and count the episode toward the base rate (a repeated outcome with nothing seen since
|
|
660
|
-
* counts nothing
|
|
672
|
+
* counts nothing, unless `IntentConfig.episodePerOutcome` makes every outcome an episode of its
|
|
673
|
+
* own for the intent), credit
|
|
661
674
|
* the closed episodes still waiting under `IntentConfig.attribution` by `2^(−age / halfLife)`
|
|
662
675
|
* each, record `lastOutcomeAt`, and (by default) reset the evidence to the prior. Any event opens
|
|
663
676
|
* or extends the current episode; an idle gap longer than `config.episodeTimeout` closes the
|
package/dist/index.js
CHANGED
|
@@ -284,6 +284,7 @@ var INTENT_KEYS = [
|
|
|
284
284
|
"outcome",
|
|
285
285
|
"resetOnOutcome",
|
|
286
286
|
"saturate",
|
|
287
|
+
"episodePerOutcome",
|
|
287
288
|
"attribution",
|
|
288
289
|
"reveal"
|
|
289
290
|
];
|
|
@@ -441,6 +442,12 @@ function normalizeIntentConfig(value, path, strict = true) {
|
|
|
441
442
|
if (typeof record2.saturate !== "boolean") typeError(`${path}.saturate`, "must be a boolean");
|
|
442
443
|
out.saturate = record2.saturate;
|
|
443
444
|
}
|
|
445
|
+
if (record2.episodePerOutcome !== void 0) {
|
|
446
|
+
if (typeof record2.episodePerOutcome !== "boolean") {
|
|
447
|
+
typeError(`${path}.episodePerOutcome`, "must be a boolean");
|
|
448
|
+
}
|
|
449
|
+
out.episodePerOutcome = record2.episodePerOutcome;
|
|
450
|
+
}
|
|
444
451
|
if (record2.attribution !== void 0) {
|
|
445
452
|
out.attribution = expectPositive(record2.attribution, `${path}.attribution`);
|
|
446
453
|
}
|
|
@@ -757,7 +764,9 @@ function observe(state, event) {
|
|
|
757
764
|
}
|
|
758
765
|
if (isOutcome) {
|
|
759
766
|
const record2 = episodeRecord(episode, intentName);
|
|
760
|
-
if (!record2.resolved || record2.seen.length > 0
|
|
767
|
+
if (!record2.resolved || record2.seen.length > 0 || intent.episodePerOutcome === true) {
|
|
768
|
+
is = recordEpisode(is, record2.seen, 1);
|
|
769
|
+
}
|
|
761
770
|
is = creditPending(is, intent, at);
|
|
762
771
|
episode = markResolved(episode, intentName);
|
|
763
772
|
is = { ...is, lastOutcomeAt: at };
|
|
@@ -810,7 +819,8 @@ function closeEpisode(state, at) {
|
|
|
810
819
|
const intents = { ...state.intents };
|
|
811
820
|
for (const [intentName, intent] of Object.entries(state.config.intents)) {
|
|
812
821
|
const record2 = episodeRecord(state.episode, intentName);
|
|
813
|
-
if (record2.resolved)
|
|
822
|
+
if (record2.resolved && (intent.episodePerOutcome !== true || record2.seen.length === 0))
|
|
823
|
+
continue;
|
|
814
824
|
let is = getIntentState(state, intentName, intent);
|
|
815
825
|
is = settlePending(is, intent, learning, at);
|
|
816
826
|
is = intent.attribution === void 0 ? recordEpisode(is, record2.seen, 0) : deferEpisode(is, record2.seen, at);
|