oracular 0.6.0 → 0.7.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 +12 -0
- package/README.md +23 -7
- package/dist/index.cjs +12 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +81 -10
- package/dist/index.d.ts +81 -10
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/inspect.cjs +67 -0
- package/dist/inspect.cjs.map +1 -0
- package/dist/inspect.d.cts +143 -0
- package/dist/inspect.d.ts +143 -0
- package/dist/inspect.js +64 -0
- package/dist/inspect.js.map +1 -0
- package/dist/presets.cjs +86 -0
- package/dist/presets.cjs.map +1 -0
- package/dist/presets.d.cts +129 -0
- package/dist/presets.d.ts +129 -0
- package/dist/presets.js +83 -0
- package/dist/presets.js.map +1 -0
- package/package.json +33 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/math.ts","../src/util.ts","../src/learning.ts","../src/attribution.ts","../src/intent.ts","../src/config.ts","../src/episode.ts","../src/version.ts","../src/state.ts","../src/assess.ts","../src/evaluate.ts","../src/evidence.ts","../src/explain.ts","../src/observe.ts","../src/predict.ts","../src/recorder.ts","../src/migrate.ts","../src/serialize.ts","../src/units.ts","../src/validate.ts"],"names":["record","explain","typeError"],"mappings":"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","file":"index.cjs","sourcesContent":["/** 2^(−elapsed / halfLife). Returns 1 for zero, negative or non-finite elapsed time. */\nexport function decayFactor(elapsed: number, halfLife: number): number {\n if (!(elapsed > 0) || !Number.isFinite(elapsed)) return 1;\n return 2 ** (-elapsed / halfLife);\n}\n\nexport function betaMean(alpha: number, beta: number): number {\n return alpha / (alpha + beta);\n}\n\nexport function betaVariance(alpha: number, beta: number): number {\n const n = alpha + beta;\n return (alpha * beta) / (n * n * (n + 1));\n}\n\nexport function betaSd(alpha: number, beta: number): number {\n return Math.sqrt(betaVariance(alpha, beta));\n}\n\nexport function clamp01(x: number): number {\n if (x < 0) return 0;\n if (x > 1) return 1;\n return x;\n}\n\n/**\n * What the n-th occurrence of a signal within one episode adds, as a fraction of its weight:\n * log2(1 + 1/n), so that n occurrences add log2(1 + n) weights in total. 1 for the first\n * occurrence, 0.585 for the second, 0.415 for the third; every doubling adds one more weight.\n */\nexport function repeatFactor(n: number): number {\n return Math.log1p(1 / n) / Math.LN2;\n}\n\n/** Laplace-smoothed rate: (successes + 1) / (total + 2). Always strictly inside (0, 1). */\nexport function laplace(successes: number, total: number): number {\n return (successes + 1) / (total + 2);\n}\n\n/**\n * How far a rate `q` sits from a base rate `b`, scaled to [−1, 1]:\n * +1 when q is 1, 0 when q equals b, −1 when q is 0.\n */\nexport function lift(q: number, b: number): number {\n if (q >= b) return b >= 1 ? 0 : (q - b) / (1 - b);\n return b <= 0 ? 0 : (q - b) / b;\n}\n","export function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Own-property check, so event names like \"constructor\" never hit Object.prototype. */\nexport function hasOwn(record: object, key: string): boolean {\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Object.hasOwn is ES2022; this library targets ES2020 runtimes.\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\nexport function getOwn<T>(record: Record<string, T>, key: string): T | undefined {\n return hasOwn(record, key) ? record[key] : undefined;\n}\n\nexport function mapRecord<T, U>(\n record: Record<string, T>,\n fn: (value: T, key: string) => U,\n): Record<string, U> {\n const out: Record<string, U> = {};\n for (const [key, value] of Object.entries(record)) {\n out[key] = fn(value, key);\n }\n return out;\n}\n","import type { ResolvedLearning } from './config';\nimport { decayFactor, laplace, lift } from './math';\nimport type { IntentConfig, IntentState, SignalRecord } from './types';\nimport { getOwn, mapRecord } from './util';\n\nconst NONE: SignalRecord = { hits: 0, misses: 0 };\n\n/** Decays learned counts toward 0 by 2^(−Δt / learning.halfLife) and moves the anchor to `at`. */\nexport function decayLearned(\n state: IntentState,\n learning: ResolvedLearning,\n at: number,\n): IntentState {\n if (state.learnedAt === null) return { ...state, learnedAt: at };\n const learnedAt = Math.max(state.learnedAt, at);\n const d = learning.halfLife === null ? 1 : decayFactor(at - state.learnedAt, learning.halfLife);\n if (d === 1) return learnedAt === state.learnedAt ? state : { ...state, learnedAt };\n return {\n ...state,\n learnedAt,\n learned: mapRecord(state.learned, (r) => ({ hits: r.hits * d, misses: r.misses * d })),\n episodes: { hits: state.episodes.hits * d, misses: state.episodes.misses * d },\n };\n}\n\nexport interface SignalWeights {\n initial: number;\n learned: number;\n effective: number;\n hits: number;\n misses: number;\n}\n\n/**\n * initial: the developer's weight w0.\n * learned: gain · |w0| · lift(qWith, qWithout), where qWith is the Laplace-smoothed outcome\n * rate of episodes in which the signal was seen (hits / (hits + misses)) and\n * qWithout the Laplace-smoothed outcome rate of the intent's other episodes\n * (episodes without the signal). 0 until the signal has completed an episode.\n * effective: (k · w0 + nEff · learned) / (k + nEff), with k = learning.priorEpisodes and\n * nEff = (nWith · nWithout) / (nWith + nWithout): the comparison is only trusted once\n * the signal has been both present and absent. A signal that has never been absent\n * (or never present) has no counterfactual, nEff is 0, and the developer's weight stands.\n */\nexport function signalWeights(\n state: IntentState,\n intent: IntentConfig,\n learning: ResolvedLearning,\n signal: string,\n): SignalWeights {\n const initial = getOwn(intent.signals, signal);\n if (initial === undefined) {\n throw new RangeError(`oracular: ${JSON.stringify(signal)} is not a signal of this intent`);\n }\n const record = getOwn(state.learned, signal) ?? NONE;\n const nWith = record.hits + record.misses;\n const qWith = laplace(record.hits, nWith);\n // The contrast: episodes of this intent in which the signal was not seen. hits + misses counts\n // the episodes it was seen in (one record per episode), so the rest is the complement.\n const totalEpisodes = state.episodes.hits + state.episodes.misses;\n const nWithout = Math.max(0, totalEpisodes - nWith);\n const outcomesWithout = Math.min(nWithout, Math.max(0, state.episodes.hits - record.hits));\n const qWithout = laplace(outcomesWithout, nWithout);\n // Nothing has been learned about a signal until it has been seen in a completed episode.\n const learned = nWith === 0 ? 0 : learning.gain * Math.abs(initial) * lift(qWith, qWithout);\n // Learning needs contrast: weight the comparison by how much of both sides has been seen.\n const nEff = nWith + nWithout === 0 ? 0 : (nWith * nWithout) / (nWith + nWithout);\n const k = learning.priorEpisodes;\n const effective = (k * initial + nEff * learned) / (k + nEff);\n return { initial, learned, effective, hits: record.hits, misses: record.misses };\n}\n\n/**\n * Counts one episode for the listed signals and for the base rate: `credit` of a hit and\n * `1 − credit` of a miss. 1 when the outcome arrived in the episode, 0 when it ended without it,\n * and in between for an episode a later outcome credits under `attribution` (see attribution.ts).\n * Whatever the credit, the episode counts exactly once.\n */\nexport function recordEpisode(\n state: IntentState,\n signals: readonly string[],\n credit: number,\n): IntentState {\n const miss = 1 - credit;\n const learned = { ...state.learned };\n for (const signal of signals) {\n const r = getOwn(learned, signal) ?? NONE;\n learned[signal] = { hits: r.hits + credit, misses: r.misses + miss };\n }\n const episodes = { hits: state.episodes.hits + credit, misses: state.episodes.misses + miss };\n return { ...state, learned, episodes };\n}\n","import type { ResolvedLearning } from './config';\nimport { decayLearned, recordEpisode } from './learning';\nimport { decayFactor } from './math';\nimport type { IntentConfig, IntentState, PendingEpisode } from './types';\n\n/** Most closed episodes one intent keeps waiting for its outcome. Past it the oldest is a miss at once. */\nexport const MAX_PENDING = 32;\n\n/**\n * When a waiting episode's window ends: its close plus the intent's `attribution`. 0 when the\n * intent no longer sets one, so an episode held under an earlier config settles on the next touch.\n */\nfunction expiry(episode: PendingEpisode, intent: IntentConfig): number {\n return episode.endedAt + (intent.attribution ?? 0);\n}\n\n/**\n * Brings the learned counts up to `at`. Every waiting episode whose window has ended by then is a\n * miss, recorded at the moment its window ended (the counts are decayed to that moment first, as\n * for an episode that closes by timing out), and the counts are then decayed to `at`. Every path\n * that reads or writes learned counts goes through here, so no verdict lands out of order.\n */\nexport function settlePending(\n state: IntentState,\n intent: IntentConfig,\n learning: ResolvedLearning,\n at: number,\n): IntentState {\n let is = state;\n let settled = 0;\n for (const episode of state.pending) {\n const end = expiry(episode, intent);\n if (!(end < at)) break;\n is = recordEpisode(decayLearned(is, learning, end), episode.seen, 0);\n settled++;\n }\n if (settled > 0) is = { ...is, pending: state.pending.slice(settled) };\n return decayLearned(is, learning, at);\n}\n\n/**\n * Holds a closed episode for the intent's outcome instead of counting it, in order of close. Past\n * {@link MAX_PENDING} the oldest is a miss at once, so the stored state stays bounded whatever the\n * session cadence.\n */\nexport function deferEpisode(\n state: IntentState,\n seen: readonly string[],\n endedAt: number,\n): IntentState {\n const pending = insert(state.pending, { endedAt, seen: [...seen] });\n if (pending.length <= MAX_PENDING) return { ...state, pending };\n const [oldest, ...rest] = pending;\n return { ...recordEpisode(state, (oldest as PendingEpisode).seen, 0), pending: rest };\n}\n\n/** Keeps the list in order of close; a clock that went backwards inserts before later closes. */\nfunction insert(pending: readonly PendingEpisode[], episode: PendingEpisode): PendingEpisode[] {\n let i = pending.length;\n while (i > 0 && (pending[i - 1] as PendingEpisode).endedAt > episode.endedAt) i--;\n return [...pending.slice(0, i), episode, ...pending.slice(i)];\n}\n\n/**\n * The outcome arrived at `at`: every waiting episode gets the share `2^(−age / halfLife)` of a hit\n * that its evidence would still hold now, and the rest of a miss, so each episode still counts\n * exactly once. The list is then empty.\n */\nexport function creditPending(state: IntentState, intent: IntentConfig, at: number): IntentState {\n if (state.pending.length === 0) return state;\n let is = state;\n for (const episode of state.pending) {\n is = recordEpisode(is, episode.seen, decayFactor(at - episode.endedAt, intent.halfLife));\n }\n return { ...is, pending: [] };\n}\n","import { decayFactor } from './math';\nimport type { IntentConfig, IntentState, SignalContribution } from './types';\nimport { getOwn, mapRecord } from './util';\n\nexport function priorCounts(intent: IntentConfig): { alpha0: number; beta0: number } {\n return {\n alpha0: intent.prior * intent.priorStrength,\n beta0: (1 - intent.prior) * intent.priorStrength,\n };\n}\n\nexport function initIntent(intent: IntentConfig): IntentState {\n const { alpha0, beta0 } = priorCounts(intent);\n return {\n alpha: alpha0,\n beta: beta0,\n updatedAt: null,\n contributions: {},\n learned: {},\n episodes: { hits: 0, misses: 0 },\n pending: [],\n learnedAt: null,\n lastRevealedAt: null,\n lastOutcomeAt: null,\n revealCount: 0,\n };\n}\n\n/**\n * The one place α and β are written: always the prior plus the sum of contributions,\n * so the invariant α = α0 + Σ contributions.alpha (and β likewise) holds by construction.\n */\nexport function withContributions(\n state: IntentState,\n intent: IntentConfig,\n contributions: Record<string, SignalContribution>,\n): IntentState {\n const { alpha0, beta0 } = priorCounts(intent);\n let alpha = alpha0;\n let beta = beta0;\n for (const c of Object.values(contributions)) {\n alpha += c.alpha;\n beta += c.beta;\n }\n return { ...state, alpha, beta, contributions };\n}\n\n/** Decays evidence toward the prior by 2^(−Δt / halfLife) and moves the anchor to `at`. */\nexport function decayIntent(state: IntentState, intent: IntentConfig, at: number): IntentState {\n if (state.updatedAt === null) return { ...state, updatedAt: at };\n const d = decayFactor(at - state.updatedAt, intent.halfLife);\n const updatedAt = Math.max(state.updatedAt, at);\n if (d === 1) return updatedAt === state.updatedAt ? state : { ...state, updatedAt };\n const contributions = mapRecord(state.contributions, (c) => ({\n alpha: c.alpha * d,\n beta: c.beta * d,\n }));\n return withContributions({ ...state, updatedAt }, intent, contributions);\n}\n\n/** Adds `weight` pseudo-counts for the intent (positive → α) or against it (negative → β). */\nexport function applySignal(\n state: IntentState,\n intent: IntentConfig,\n signal: string,\n weight: number,\n): IntentState {\n const prev = getOwn(state.contributions, signal) ?? { alpha: 0, beta: 0 };\n const next: SignalContribution =\n weight >= 0\n ? { alpha: prev.alpha + weight, beta: prev.beta }\n : { alpha: prev.alpha, beta: prev.beta - weight };\n return withContributions(state, intent, { ...state.contributions, [signal]: next });\n}\n\n/** Drops all evidence; α and β return to the prior. Learned data is untouched. */\nexport function resetToPrior(state: IntentState, intent: IntentConfig): IntentState {\n return withContributions(state, intent, {});\n}\n","import type {\n EngineConfig,\n EvaluateOptions,\n ExplainOptions,\n IntentConfig,\n LearningConfig,\n RevealOptions,\n} from './types';\nimport { isRecord } from './util';\n\nexport const DEFAULT_THRESHOLD = 0.5;\nexport const DEFAULT_Z = 1.28;\nexport const DEFAULT_GAIN = 2;\nexport const DEFAULT_PRIOR_EPISODES = 10;\n/**\n * Largest accepted magnitude for weights, `priorStrength`, `learning.gain` and\n * `learning.priorEpisodes`: far beyond any real config, and small enough that the Beta and\n * learning arithmetic can never overflow to Infinity or NaN.\n */\nexport const MAX_MAGNITUDE = 1e6;\n\n// Exported for tests/schema.test.ts, which pins schema/config.schema.json to these lists.\nexport const CONFIG_KEYS = ['intents', 'episodeTimeout', 'learning', 'reveal'] as const;\nexport const INTENT_KEYS = [\n 'prior',\n 'priorStrength',\n 'halfLife',\n 'signals',\n 'outcome',\n 'resetOnOutcome',\n 'saturate',\n 'attribution',\n 'reveal',\n] as const;\nexport const REVEAL_KEYS = ['threshold', 'z', 'cooldown'] as const;\nexport const LEARNING_KEYS = ['halfLife', 'gain', 'priorEpisodes'] as const;\nconst EXPLAIN_KEYS = ['nonZero', 'limit'] as const;\n\nfunction typeError(path: string, message: string): never {\n throw new TypeError(`oracular: ${path} ${message}`);\n}\n\nfunction rangeError(path: string, message: string): never {\n throw new RangeError(`oracular: ${path} ${message}`);\n}\n\nfunction expectRecord(value: unknown, path: string): Record<string, unknown> {\n if (!isRecord(value)) typeError(path, 'must be a plain object');\n return value;\n}\n\nfunction expectKeys(\n record: Record<string, unknown>,\n allowed: readonly string[],\n path: string,\n): void {\n for (const key of Object.keys(record)) {\n if (!allowed.includes(key)) {\n typeError(\n `${path}.${key}`,\n `is not a recognised option (expected one of: ${allowed.join(', ')})`,\n );\n }\n }\n}\n\nfunction expectNumber(value: unknown, path: string): number {\n if (typeof value !== 'number' || !Number.isFinite(value))\n typeError(path, 'must be a finite number');\n return value;\n}\n\nfunction expectPositive(value: unknown, path: string): number {\n const n = expectNumber(value, path);\n if (n <= 0) rangeError(path, 'must be greater than 0');\n return n;\n}\n\n/** A positive number no larger than {@link MAX_MAGNITUDE}. */\nfunction expectBoundedPositive(value: unknown, path: string): number {\n const n = expectPositive(value, path);\n if (n > MAX_MAGNITUDE) rangeError(path, `must be at most ${MAX_MAGNITUDE}`);\n return n;\n}\n\nfunction expectNonNegative(value: unknown, path: string): number {\n const n = expectNumber(value, path);\n if (n < 0) rangeError(path, 'must be 0 or greater');\n return n;\n}\n\nfunction expectOpenUnit(value: unknown, path: string): number {\n const n = expectNumber(value, path);\n if (n <= 0 || n >= 1) rangeError(path, 'must be strictly between 0 and 1');\n return n;\n}\n\nfunction expectClosedUnit(value: unknown, path: string): number {\n const n = expectNumber(value, path);\n if (n < 0 || n > 1) rangeError(path, 'must be between 0 and 1');\n return n;\n}\n\nexport function expectName(value: unknown, path: string): string {\n if (typeof value !== 'string' || value.length === 0)\n typeError(path, 'must be a non-empty string');\n return value;\n}\n\n/** Keys of user-named records must be usable as own properties of a plain object. */\nfunction expectKeyName(name: string, path: string): string {\n if (name.length === 0) typeError(path, 'names must be non-empty strings');\n if (name === '__proto__') typeError(path, 'must not use the reserved name \"__proto__\"');\n return name;\n}\n\n/** Validates reveal options and returns a copy with only the defined keys. */\nexport function normalizeRevealOptions(value: unknown, path: string): RevealOptions {\n const record = expectRecord(value, path);\n expectKeys(record, REVEAL_KEYS, path);\n const out: RevealOptions = {};\n if (record.threshold !== undefined) {\n out.threshold = expectClosedUnit(record.threshold, `${path}.threshold`);\n }\n if (record.z !== undefined) out.z = expectNonNegative(record.z, `${path}.z`);\n if (record.cooldown !== undefined) {\n out.cooldown = expectNonNegative(record.cooldown, `${path}.cooldown`);\n }\n return out;\n}\n\nfunction normalizeLearning(value: unknown, path: string): LearningConfig {\n const record = expectRecord(value, path);\n expectKeys(record, LEARNING_KEYS, path);\n const out: LearningConfig = {};\n if (record.halfLife !== undefined)\n out.halfLife = expectPositive(record.halfLife, `${path}.halfLife`);\n if (record.gain !== undefined) out.gain = expectBoundedPositive(record.gain, `${path}.gain`);\n if (record.priorEpisodes !== undefined) {\n out.priorEpisodes = expectBoundedPositive(record.priorEpisodes, `${path}.priorEpisodes`);\n }\n return out;\n}\n\n/** Validates one intent's config and returns a copy with only the defined, recognised keys. */\nexport function normalizeIntentConfig(value: unknown, path: string): IntentConfig {\n const record = expectRecord(value, path);\n expectKeys(record, INTENT_KEYS, path);\n const signalsRecord = expectRecord(record.signals, `${path}.signals`);\n const signals: Record<string, number> = {};\n for (const [name, weight] of Object.entries(signalsRecord)) {\n expectKeyName(name, `${path}.signals`);\n const w = expectNumber(weight, `${path}.signals[${JSON.stringify(name)}]`);\n if (w === 0) {\n rangeError(\n `${path}.signals[${JSON.stringify(name)}]`,\n 'must be non-zero (positive is evidence for the intent, negative is evidence against)',\n );\n }\n if (Math.abs(w) > MAX_MAGNITUDE) {\n rangeError(\n `${path}.signals[${JSON.stringify(name)}]`,\n `must be between -${MAX_MAGNITUDE} and ${MAX_MAGNITUDE}`,\n );\n }\n signals[name] = w;\n }\n const out: IntentConfig = {\n prior: expectOpenUnit(record.prior, `${path}.prior`),\n priorStrength: expectBoundedPositive(record.priorStrength, `${path}.priorStrength`),\n halfLife: expectPositive(record.halfLife, `${path}.halfLife`),\n signals,\n };\n if (record.outcome !== undefined) out.outcome = expectName(record.outcome, `${path}.outcome`);\n if (record.resetOnOutcome !== undefined) {\n if (typeof record.resetOnOutcome !== 'boolean') {\n typeError(`${path}.resetOnOutcome`, 'must be a boolean');\n }\n out.resetOnOutcome = record.resetOnOutcome;\n }\n if (record.saturate !== undefined) {\n if (typeof record.saturate !== 'boolean') typeError(`${path}.saturate`, 'must be a boolean');\n out.saturate = record.saturate;\n }\n if (record.attribution !== undefined) {\n out.attribution = expectPositive(record.attribution, `${path}.attribution`);\n }\n if (record.reveal !== undefined)\n out.reveal = normalizeRevealOptions(record.reveal, `${path}.reveal`);\n return out;\n}\n\n/**\n * Validates a config and returns a fresh copy holding only the defined, recognised keys,\n * so that it survives a JSON round trip unchanged.\n */\nexport function normalizeConfig(value: unknown): EngineConfig {\n const record = expectRecord(value, 'config');\n expectKeys(record, CONFIG_KEYS, 'config');\n const intentsRecord = expectRecord(record.intents, 'config.intents');\n const names = Object.keys(intentsRecord);\n if (names.length === 0) typeError('config.intents', 'must declare at least one intent');\n const intents: Record<string, IntentConfig> = {};\n for (const name of names) {\n expectKeyName(name, 'config.intents');\n intents[name] = normalizeIntentConfig(\n intentsRecord[name],\n `config.intents[${JSON.stringify(name)}]`,\n );\n }\n const out: EngineConfig = { intents };\n if (record.episodeTimeout !== undefined) {\n out.episodeTimeout = expectPositive(record.episodeTimeout, 'config.episodeTimeout');\n }\n if (record.learning !== undefined)\n out.learning = normalizeLearning(record.learning, 'config.learning');\n if (record.reveal !== undefined)\n out.reveal = normalizeRevealOptions(record.reveal, 'config.reveal');\n return out;\n}\n\n/** Validates explain filters and returns a copy with only the defined keys. */\nexport function normalizeExplainOptions(value: unknown, path: string): ExplainOptions {\n const record = expectRecord(value, path);\n expectKeys(record, EXPLAIN_KEYS, path);\n const out: ExplainOptions = {};\n if (record.nonZero !== undefined) {\n if (typeof record.nonZero !== 'boolean') typeError(`${path}.nonZero`, 'must be a boolean');\n out.nonZero = record.nonZero;\n }\n if (record.limit !== undefined) {\n const n = expectNumber(record.limit, `${path}.limit`);\n if (!Number.isInteger(n) || n < 0)\n rangeError(`${path}.limit`, 'must be a non-negative integer');\n out.limit = n;\n }\n return out;\n}\n\n/** Splits `evaluate` options into reveal overrides and explain filters, rejecting unknown keys. */\nexport function splitEvaluateOptions(\n value: EvaluateOptions | undefined,\n path: string,\n): { reveal: RevealOptions; explain: ExplainOptions } {\n if (value === undefined) return { reveal: {}, explain: {} };\n const record = expectRecord(value, path);\n expectKeys(record, [...REVEAL_KEYS, ...EXPLAIN_KEYS], path);\n const reveal: Record<string, unknown> = {};\n const explain: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(record)) {\n if ((REVEAL_KEYS as readonly string[]).includes(key)) reveal[key] = v;\n else explain[key] = v;\n }\n return {\n reveal: normalizeRevealOptions(reveal, path),\n explain: normalizeExplainOptions(explain, path),\n };\n}\n\nexport interface ResolvedReveal {\n threshold: number;\n z: number;\n cooldown: number;\n}\n\nexport function resolveReveal(\n config: EngineConfig | undefined,\n intent: IntentConfig,\n opts: RevealOptions | undefined,\n normalized = false,\n): ResolvedReveal {\n const o = opts === undefined ? {} : normalized ? opts : normalizeRevealOptions(opts, 'options');\n return {\n threshold:\n o.threshold ?? intent.reveal?.threshold ?? config?.reveal?.threshold ?? DEFAULT_THRESHOLD,\n z: o.z ?? intent.reveal?.z ?? config?.reveal?.z ?? DEFAULT_Z,\n cooldown: o.cooldown ?? intent.reveal?.cooldown ?? config?.reveal?.cooldown ?? intent.halfLife,\n };\n}\n\nexport interface ResolvedLearning {\n /** null means learned counts never decay. */\n halfLife: number | null;\n gain: number;\n priorEpisodes: number;\n}\n\nexport function resolveLearning(config: EngineConfig): ResolvedLearning {\n return {\n halfLife: config.learning?.halfLife ?? null,\n gain: config.learning?.gain ?? DEFAULT_GAIN,\n priorEpisodes: config.learning?.priorEpisodes ?? DEFAULT_PRIOR_EPISODES,\n };\n}\n\nexport function expectTimestamp(value: unknown, path: string): number {\n return expectNumber(value, path);\n}\n\nexport function validateEvent(event: unknown): { name: string; at: number } {\n if (!isRecord(event)) typeError('event', 'must be an object like { name, at }');\n const name = expectName(event.name, 'event.name');\n const at = expectTimestamp(event.at, 'event.at');\n if (event.props !== undefined && !isRecord(event.props)) {\n typeError('event.props', 'must be a plain object when present');\n }\n return { name, at };\n}\n","import type { EpisodeIntentRecord, EpisodeState } from './types';\nimport { getOwn } from './util';\n\nexport function emptyEpisode(): EpisodeState {\n return { startedAt: null, lastEventAt: null, intents: {} };\n}\n\n/** If the episode has been idle longer than `timeout` by `at`, the moment it timed out; otherwise null. */\nexport function timedOutAt(\n episode: EpisodeState,\n timeout: number | undefined,\n at: number,\n): number | null {\n if (timeout === undefined || episode.lastEventAt === null) return null;\n return at - episode.lastEventAt > timeout ? episode.lastEventAt + timeout : null;\n}\n\n/** Opens the episode if needed and records activity at `at`. */\nexport function extendEpisode(episode: EpisodeState, at: number): EpisodeState {\n return {\n startedAt: episode.startedAt ?? at,\n lastEventAt: episode.lastEventAt === null ? at : Math.max(episode.lastEventAt, at),\n intents: episode.intents,\n };\n}\n\nexport function episodeRecord(episode: EpisodeState, intent: string): EpisodeIntentRecord {\n return getOwn(episode.intents, intent) ?? { seen: [], counts: {}, resolved: false };\n}\n\n/** How many times `signal` has occurred for `intent` in this episode (since its last outcome). */\nexport function occurrences(episode: EpisodeState, intent: string, signal: string): number {\n return getOwn(episodeRecord(episode, intent).counts, signal) ?? 0;\n}\n\n/** Remembers one more occurrence of `signal`: added to `seen` the first time, counted every time. */\nexport function markSeen(episode: EpisodeState, intent: string, signal: string): EpisodeState {\n const record = episodeRecord(episode, intent);\n const seen = record.seen.includes(signal) ? record.seen : [...record.seen, signal];\n const counts = { ...record.counts, [signal]: (getOwn(record.counts, signal) ?? 0) + 1 };\n return { ...episode, intents: { ...episode.intents, [intent]: { ...record, seen, counts } } };\n}\n\nexport function markResolved(episode: EpisodeState, intent: string): EpisodeState {\n return {\n ...episode,\n intents: { ...episode.intents, [intent]: { seen: [], counts: {}, resolved: true } },\n };\n}\n","/**\n * Version of the serialized state shape, stored in every state as `state.version`. Bumped only\n * when `EngineState` changes incompatibly, and every bump ships its migration: {@link deserialize}\n * upgrades states saved by earlier versions of this library on its own (version 1, written by\n * oracular 0.1.0 to 0.2.x, and version 2, written by 0.3.0 to 0.5.x, become version 3) and calls\n * your `migrate` function only for a version it does not know.\n *\n * @example\n * ```ts\n * import { STATE_VERSION, deserialize } from 'oracular';\n *\n * const state = deserialize(saved, {\n * config,\n * // Only reached for versions this library cannot migrate itself, such as a state written by a\n * // newer oracular before a rollback.\n * migrate: (stored, version) => {\n * throw new Error(`cannot read oracular state version ${version} (this build reads ${STATE_VERSION})`);\n * },\n * });\n * ```\n */\nexport const STATE_VERSION = 3 as const;\n\n/**\n * Version of the recorder format: the `v` field of every record that {@link createRecord} and\n * {@link createEndRecord} produce. A new optional field does not change it; readers ignore fields\n * they do not know and skip records of a `kind` they do not know. Anything a reader written for\n * this version could misread bumps it.\n *\n * @example\n * ```ts\n * import { RECORD_VERSION } from 'oracular';\n *\n * const record = JSON.parse(line);\n * if (record.v !== RECORD_VERSION) throw new Error(`unsupported recorder format ${record.v}`);\n * ```\n */\nexport const RECORD_VERSION = 1 as const;\n","import { normalizeConfig } from './config';\nimport { emptyEpisode } from './episode';\nimport { initIntent } from './intent';\nimport type { EngineConfig, EngineState, IntentConfig, IntentState } from './types';\nimport { getOwn, isRecord } from './util';\nimport { STATE_VERSION } from './version';\n\n/**\n * Builds a fresh engine state from a config. Every intent starts at its prior and no episode is\n * open. The config is validated and a normalized copy is stored inside the state, so a persisted\n * state remembers the weights it was built with; pass your current config to {@link deserialize}\n * when loading.\n *\n * @param config - Intents with their priors and signals, plus engine-wide options. Validated\n * strictly: unknown keys, non-finite numbers and out-of-range values throw.\n * @returns A new, JSON-serializable state. `config` is not mutated.\n * @throws `TypeError` when a value has the wrong type or a key is not recognised.\n * @throws `RangeError` when a number is out of range, for example a `prior` outside (0, 1), a\n * signal weight of 0, or a weight, `priorStrength`, `learning.gain` or\n * `learning.priorEpisodes` beyond 1e6 (larger values could overflow the arithmetic).\n * @example\n * ```ts\n * const state = createState({\n * intents: {\n * upgrade: {\n * prior: 0.05,\n * priorStrength: 10,\n * halfLife: 7 * 24 * 60 * 60 * 1000,\n * signals: { 'pricing.viewed': 3, 'limit.hit': 2, 'plan.downgraded': -4 },\n * outcome: 'upgrade.completed',\n * },\n * },\n * });\n * ```\n */\nexport function createState(config: EngineConfig): EngineState {\n const normalized = normalizeConfig(config);\n const intents: Record<string, IntentState> = {};\n for (const [name, intent] of Object.entries(normalized.intents)) {\n intents[name] = initIntent(intent);\n }\n return { version: STATE_VERSION, config: normalized, intents, episode: emptyEpisode() };\n}\n\nexport function requireState(state: unknown): EngineState {\n if (\n !isRecord(state) ||\n state.version !== STATE_VERSION ||\n !isRecord(state.config) ||\n !isRecord(state.intents) ||\n !isRecord(state.episode)\n ) {\n throw new TypeError('oracular: state must be an EngineState from createState or deserialize');\n }\n return state as unknown as EngineState;\n}\n\nexport function requireIntentConfig(state: EngineState, name: string): IntentConfig {\n const intent = getOwn(state.config.intents, name);\n if (intent === undefined) {\n throw new RangeError(`oracular: unknown intent ${JSON.stringify(name)}`);\n }\n return intent;\n}\n\n/** The stored intent state, or a fresh prior if the intent was added to the config after the state was created. */\nexport function getIntentState(\n state: EngineState,\n name: string,\n intent: IntentConfig,\n): IntentState {\n return getOwn(state.intents, name) ?? initIntent(intent);\n}\n","import { settlePending } from './attribution';\nimport type { ResolvedLearning, ResolvedReveal } from './config';\nimport { decayIntent } from './intent';\nimport { signalWeights } from './learning';\nimport { betaMean, betaSd, clamp01 } from './math';\nimport { getIntentState } from './state';\nimport type {\n EngineState,\n ExplainOptions,\n IntentConfig,\n IntentState,\n Prediction,\n SignalExplanation,\n} from './types';\nimport { getOwn } from './util';\n\n/**\n * The intent brought up to `at` without storing anything: evidence decayed, waiting episodes whose\n * window has passed settled as misses, learned counts decayed.\n */\nexport function assessIntent(\n state: EngineState,\n name: string,\n intent: IntentConfig,\n learning: ResolvedLearning,\n at: number,\n): IntentState {\n const is = decayIntent(getIntentState(state, name, intent), intent, at);\n return settlePending(is, intent, learning, at);\n}\n\n/** The end of a cooldown that started at `since`, if it is still running at `at`. */\nfunction cooldownEnd(since: number | null, cooldown: number, at: number): number | null {\n if (since === null) return null;\n const end = since + cooldown;\n return at < end ? end : null;\n}\n\nexport function buildPrediction(\n is: IntentState,\n name: string,\n reveal: ResolvedReveal,\n at: number,\n): Prediction {\n const p = betaMean(is.alpha, is.beta);\n const sd = betaSd(is.alpha, is.beta);\n const revealEnd = cooldownEnd(is.lastRevealedAt, reveal.cooldown, at);\n const outcomeEnd = cooldownEnd(is.lastOutcomeAt, reveal.cooldown, at);\n const suppressedUntil =\n revealEnd === null\n ? outcomeEnd\n : outcomeEnd === null\n ? revealEnd\n : Math.max(revealEnd, outcomeEnd);\n return {\n intent: name,\n p,\n sd,\n lower: clamp01(p - reveal.z * sd),\n confidence: clamp01(1 - 2 * sd),\n evidence: is.alpha + is.beta,\n revealed: revealEnd !== null,\n revealedAt: is.lastRevealedAt,\n suppressedUntil,\n };\n}\n\nexport function decideReveal(prediction: Prediction, reveal: ResolvedReveal): boolean {\n return (\n prediction.suppressedUntil === null &&\n prediction.p >= reveal.threshold &&\n prediction.lower >= reveal.threshold\n );\n}\n\nexport function buildExplanation(\n is: IntentState,\n intent: IntentConfig,\n learning: ResolvedLearning,\n opts: ExplainOptions,\n): SignalExplanation[] {\n const p = betaMean(is.alpha, is.beta);\n const out: SignalExplanation[] = [];\n for (const signal of Object.keys(intent.signals)) {\n const c = getOwn(is.contributions, signal) ?? { alpha: 0, beta: 0 };\n const w = signalWeights(is, intent, learning, signal);\n const without = betaMean(is.alpha - c.alpha, is.beta - c.beta);\n out.push({\n signal,\n contribution: c.alpha - c.beta,\n impact: p - without,\n initialWeight: w.initial,\n learnedWeight: w.learned,\n effectiveWeight: w.effective,\n hits: w.hits,\n misses: w.misses,\n });\n }\n out.sort((a, b) => Math.abs(b.impact) - Math.abs(a.impact) || compare(a.signal, b.signal));\n const filtered = opts.nonZero ? out.filter((row) => row.contribution !== 0) : out;\n return opts.limit === undefined ? filtered : filtered.slice(0, opts.limit);\n}\n\nfunction compare(a: string, b: string): number {\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n}\n","import { assessIntent, buildExplanation, buildPrediction, decideReveal } from './assess';\nimport {\n expectName,\n expectTimestamp,\n resolveLearning,\n resolveReveal,\n splitEvaluateOptions,\n} from './config';\nimport { requireIntentConfig, requireState } from './state';\nimport type { EngineState, EvaluateOptions, Evaluation } from './types';\n\n/**\n * {@link predict}, {@link shouldReveal} and {@link explain} in one call, from a single decay\n * pass over the intent. The three results are identical to what the separate functions return\n * for the same inputs; this is the one to call on every event when you need all of them.\n * Read-only.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - The time to evaluate at.\n * @param opts - Reveal overrides (`threshold`, `z`, `cooldown`) and explain filters (`nonZero`,\n * `limit`) in one object.\n * @returns `prediction` (as `predict`), `reveal` (as `shouldReveal`) and `explanation` (as\n * `explain` with the same filters).\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state, `at` is not finite, or `opts` is\n * malformed.\n * @example\n * ```ts\n * const { prediction, reveal, explanation } = evaluate(state, 'upgrade', Date.now(), { limit: 3 });\n * if (reveal) showOffer(explanation[0]?.signal);\n * ```\n */\nexport function evaluate(\n state: EngineState,\n intent: string,\n at: number,\n opts?: EvaluateOptions,\n): Evaluation {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const t = expectTimestamp(at, 'at');\n const config = requireIntentConfig(s, name);\n const split = splitEvaluateOptions(opts, 'options');\n const reveal = resolveReveal(s.config, config, split.reveal, true);\n const learning = resolveLearning(s.config);\n const is = assessIntent(s, name, config, learning, t);\n const prediction = buildPrediction(is, name, reveal, t);\n return {\n prediction,\n reveal: decideReveal(prediction, reveal),\n explanation: buildExplanation(is, config, learning, split.explain),\n };\n}\n","import { normalizeIntentConfig, resolveReveal } from './config';\nimport { priorCounts } from './intent';\nimport { betaMean, betaSd, clamp01 } from './math';\nimport type { IntentConfig, RevealOptions } from './types';\n\n/**\n * How much positive evidence an intent needs before {@link shouldReveal} first becomes true:\n * the smallest pseudo-count `w` such that Beta(α₀ + w, β₀) clears both `p ≥ threshold` and\n * `p − z·sd ≥ threshold`. Divide by a signal's weight and round up for the number of full-weight\n * occurrences that open the gate: distinct signals, or one occurrence per episode. Repeats within\n * one episode add less (n of them add `w × log2(1 + n)`, see {@link IntentConfig.saturate}).\n * Solved numerically to 1e-9.\n *\n * Cooldowns and decay are not part of the answer: this is the evidence needed at one instant.\n *\n * @param intent - One intent's config, validated as `createState` would.\n * @param opts - `threshold` and `z` overrides, resolved as call → intent → defaults (there is\n * no engine config here). `cooldown` is accepted and ignored.\n * @returns The pseudo-count sum; 0 when the prior alone already clears the gate; `Infinity`\n * when no finite amount of evidence can (threshold 1).\n * @throws `TypeError` or `RangeError` when `intent` or `opts` is invalid.\n * @example\n * ```ts\n * const needed = evidenceToReveal(config.intents.upgrade); // ≈ 15.1 for the quickstart config\n * Math.ceil(needed / 3); // 6 full-weight signals of weight 3\n * ```\n */\nexport function evidenceToReveal(intent: IntentConfig, opts?: RevealOptions): number {\n const config = normalizeIntentConfig(intent, 'intent');\n const { threshold, z } = resolveReveal(undefined, config, opts);\n const { alpha0, beta0 } = priorCounts(config);\n\n const open = (w: number): boolean => {\n const alpha = alpha0 + w;\n const p = betaMean(alpha, beta0);\n return p >= threshold && clamp01(p - z * betaSd(alpha, beta0)) >= threshold;\n };\n\n if (threshold >= 1) return Number.POSITIVE_INFINITY;\n if (open(0)) return 0;\n\n // Bracket the first crossing geometrically, then bisect. Both p and the lower bound keep\n // rising with evidence past the first crossing, so the first opening is the answer.\n let lo = 0;\n let hi = 1;\n while (!open(hi)) {\n lo = hi;\n hi *= 2;\n if (hi > 1e15) return Number.POSITIVE_INFINITY;\n }\n for (let i = 0; i < 200 && hi - lo > 1e-9; i++) {\n const mid = (lo + hi) / 2;\n if (open(mid)) hi = mid;\n else lo = mid;\n }\n return hi;\n}\n","import { assessIntent, buildExplanation } from './assess';\nimport { expectName, expectTimestamp, normalizeExplainOptions, resolveLearning } from './config';\nimport { requireIntentConfig, requireState } from './state';\nimport type { EngineState, ExplainOptions, SignalExplanation } from './types';\n\n/**\n * Why the intent's p is what it is at time `at`: one entry per declared signal, the ones that\n * matter most first. `contribution` is the signed pseudo-count the signal currently holds after\n * decay, `impact` is how much p would change if that contribution were removed, and the three\n * weights show what the developer said, what this user's history says, and what the next\n * occurrence will actually add. Read-only.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - The time to evaluate at; contributions and learned counts are decayed to it.\n * @param opts - Optional filters: `nonZero` keeps only signals that currently hold evidence,\n * `limit` caps the number of rows. Default: every declared signal.\n * @returns One {@link SignalExplanation} per declared signal, sorted by |impact| descending,\n * then by name, then filtered by `opts`. Empty for an intent that declares no signals.\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state, `at` is not finite, or `opts` is\n * malformed.\n * @example\n * ```ts\n * for (const row of explain(state, 'upgrade', Date.now(), { nonZero: true })) {\n * console.log(row.signal, row.impact.toFixed(2), row.effectiveWeight.toFixed(2));\n * }\n * ```\n */\nexport function explain(\n state: EngineState,\n intent: string,\n at: number,\n opts?: ExplainOptions,\n): SignalExplanation[] {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const t = expectTimestamp(at, 'at');\n const config = requireIntentConfig(s, name);\n const filters = opts === undefined ? {} : normalizeExplainOptions(opts, 'options');\n const learning = resolveLearning(s.config);\n return buildExplanation(assessIntent(s, name, config, learning, t), config, learning, filters);\n}\n","import { creditPending, deferEpisode, settlePending } from './attribution';\nimport { expectTimestamp, resolveLearning, validateEvent } from './config';\nimport {\n emptyEpisode,\n episodeRecord,\n extendEpisode,\n markResolved,\n markSeen,\n occurrences,\n timedOutAt,\n} from './episode';\nimport { applySignal, decayIntent, resetToPrior } from './intent';\nimport { recordEpisode, signalWeights } from './learning';\nimport { repeatFactor } from './math';\nimport { getIntentState, requireState } from './state';\nimport type { EngineState, IntentEvent, IntentState } from './types';\nimport { hasOwn } from './util';\n\n/**\n * Feeds one event to the engine.\n *\n * For every intent the event is a signal of: decay its evidence to `event.at`, then add the\n * signal's effective weight to α (positive) or β (negative) and remember the signal for this\n * episode. Repeats within an episode saturate: the n-th occurrence of a signal adds\n * `w × log2(1 + 1/n)`, counted since the episode started or the intent's outcome last arrived.\n * That is the default when `config.episodeTimeout` is set, and `IntentConfig.saturate` overrides\n * it either way; otherwise every occurrence adds all of `w`. For every intent the event is the\n * outcome of: give the remembered signals a hit, count the episode toward the base rate, credit\n * the closed episodes still waiting under `IntentConfig.attribution` by `2^(−age / halfLife)`\n * each, record `lastOutcomeAt`, and (by default) reset the evidence to the prior. Any event opens\n * or extends the current episode; an idle gap longer than `config.episodeTimeout` closes the\n * previous episode first.\n *\n * @param state - The current state. Not mutated.\n * @param event - `name` is matched against every intent's signals and outcome; `at` is the\n * event's timestamp, in the same unit as your durations; `props` are accepted and ignored,\n * and never stored.\n * @returns The next state. Intents the event does not touch keep their stored numbers; their\n * decay is applied when they are next read or updated.\n * @throws `TypeError` when `state` is not an engine state, or the event has no non-empty\n * `name`, no finite `at`, or a `props` that is not a plain object.\n * @example\n * ```ts\n * let state = createState(config);\n * state = observe(state, { name: 'pricing.viewed', at: Date.now() });\n * state = observe(state, { name: 'upgrade.completed', at: Date.now() }); // outcome\n * ```\n */\nexport function observe(state: EngineState, event: IntentEvent): EngineState {\n let s = requireState(state);\n const { name, at } = validateEvent(event);\n\n const closeAt = timedOutAt(s.episode, s.config.episodeTimeout, at);\n if (closeAt !== null) s = closeEpisode(s, closeAt);\n\n const learning = resolveLearning(s.config);\n const intents: Record<string, IntentState> = { ...s.intents };\n let episode = extendEpisode(s.episode, at);\n\n for (const [intentName, intent] of Object.entries(s.config.intents)) {\n const isSignal = hasOwn(intent.signals, name);\n const isOutcome = intent.outcome === name;\n if (!isSignal && !isOutcome) continue;\n\n let is = getIntentState(s, intentName, intent);\n is = decayIntent(is, intent, at);\n is = settlePending(is, intent, learning, at);\n\n if (isSignal) {\n const { effective } = signalWeights(is, intent, learning, name);\n const n = occurrences(episode, intentName, name) + 1;\n const saturate = intent.saturate ?? s.config.episodeTimeout !== undefined;\n const factor = saturate ? repeatFactor(n) : 1;\n is = applySignal(is, intent, name, effective * factor);\n // An event that is also the intent's outcome must not learn from itself.\n if (!isOutcome) episode = markSeen(episode, intentName, name);\n }\n\n if (isOutcome) {\n is = recordEpisode(is, episodeRecord(episode, intentName).seen, 1);\n is = creditPending(is, intent, at);\n episode = markResolved(episode, intentName);\n is = { ...is, lastOutcomeAt: at };\n if (intent.resetOnOutcome ?? true) is = resetToPrior(is, intent);\n }\n\n intents[intentName] = is;\n }\n\n return { ...s, intents, episode };\n}\n\n/**\n * Ends the current episode at `at`. Every intent whose outcome did not arrive gives a miss to\n * each signal seen this episode and counts the episode toward its base rate, or, with\n * `IntentConfig.attribution` set, holds the episode for the outcome instead. Call it when a\n * session ends: tab closed, app backgrounded, user signed out.\n *\n * @param state - The current state. Not mutated.\n * @param at - When the episode ended. If it had already timed out under\n * `config.episodeTimeout`, it is closed at the moment it timed out instead.\n * @returns The next state with no open episode, or the very same state object when no episode\n * was open.\n * @throws `TypeError` when `state` is not an engine state or `at` is not a finite number.\n * @example\n * ```ts\n * window.addEventListener('pagehide', () => {\n * state = endEpisode(state, Date.now());\n * localStorage.setItem('oracular', serialize(state));\n * });\n * ```\n */\nexport function endEpisode(state: EngineState, at: number): EngineState {\n const s = requireState(state);\n const t = expectTimestamp(at, 'at');\n if (s.episode.startedAt === null) return s;\n const closeAt = timedOutAt(s.episode, s.config.episodeTimeout, t);\n return closeEpisode(s, closeAt ?? t);\n}\n\nfunction closeEpisode(state: EngineState, at: number): EngineState {\n const learning = resolveLearning(state.config);\n const intents: Record<string, IntentState> = { ...state.intents };\n for (const [intentName, intent] of Object.entries(state.config.intents)) {\n const record = episodeRecord(state.episode, intentName);\n if (record.resolved) continue;\n let is = getIntentState(state, intentName, intent);\n is = settlePending(is, intent, learning, at);\n is =\n intent.attribution === undefined\n ? recordEpisode(is, record.seen, 0)\n : deferEpisode(is, record.seen, at);\n intents[intentName] = is;\n }\n return { ...state, intents, episode: emptyEpisode() };\n}\n\n/**\n * Whether an episode closed between two states: `prev` had an open episode and `next` either\n * has none or has a different one. Useful after `observe` or `endEpisode` to react to a\n * session ending, for example to persist, or to read the misses it produced as\n * `next.intents[x].episodes.misses - prev.intents[x].episodes.misses` (0 for an intent with\n * `attribution` set, whose verdict waits).\n *\n * @param prev - The state before the operation.\n * @param next - The state after it.\n * @returns True when `prev.episode.startedAt` is not null and differs from\n * `next.episode.startedAt`.\n * @throws `TypeError` when either argument is not an engine state.\n * @example\n * ```ts\n * const next = observe(state, event);\n * if (episodeClosed(state, next)) persist(next);\n * ```\n */\nexport function episodeClosed(prev: EngineState, next: EngineState): boolean {\n const a = requireState(prev);\n const b = requireState(next);\n return a.episode.startedAt !== null && b.episode.startedAt !== a.episode.startedAt;\n}\n","import { buildPrediction, decideReveal } from './assess';\nimport { expectName, expectTimestamp, resolveReveal } from './config';\nimport { decayIntent } from './intent';\nimport { getIntentState, requireIntentConfig, requireState } from './state';\nimport type { EngineState, Prediction, RevealOptions } from './types';\n\n/**\n * The intent's current estimate at time `at`: the Beta mean p, its standard deviation, the\n * lower confidence bound that {@link shouldReveal} tests, and the cooldown status. Read-only:\n * the stored state is decayed to `at` for the reading but not changed.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - The time to evaluate at, in the same unit as your durations.\n * @param opts - Overrides for `threshold`, `z` and `cooldown`, resolved as call → intent →\n * engine → defaults. `z` sets `lower`; `cooldown` sets `revealed` and `suppressedUntil`;\n * `threshold` only matters to {@link shouldReveal}.\n * @returns The prediction. `p`, `sd`, `lower` and `confidence` are in [0, 1]; `evidence` is\n * α + β.\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state, `at` is not finite, or `opts` is\n * malformed.\n * @example\n * ```ts\n * const { p, lower, suppressedUntil } = predict(state, 'upgrade', Date.now());\n * if (suppressedUntil !== null) scheduleNextCheck(suppressedUntil);\n * ```\n */\nexport function predict(\n state: EngineState,\n intent: string,\n at: number,\n opts?: RevealOptions,\n): Prediction {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const t = expectTimestamp(at, 'at');\n const config = requireIntentConfig(s, name);\n const reveal = resolveReveal(s.config, config, opts);\n const is = decayIntent(getIntentState(s, name, config), config, t);\n return buildPrediction(is, name, reveal, t);\n}\n\n/**\n * Whether to act on the intent now. True when p ≥ `threshold`, the lower confidence bound\n * p − z·sd also clears `threshold`, and no cooldown is running: neither the one started by\n * {@link markRevealed} nor the one started by the intent's outcome event.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - The time to evaluate at.\n * @param opts - Overrides for `threshold` (default 0.5), `z` (default 1.28, a one-sided 90%\n * bound) and `cooldown` (default: the intent's `halfLife`).\n * @returns True when the app should show, offer or reveal whatever this intent gates.\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state, `at` is not finite, or `opts` is\n * malformed.\n * @example\n * ```ts\n * if (shouldReveal(state, 'upgrade', Date.now())) {\n * showUpgradeOffer();\n * state = markRevealed(state, 'upgrade', Date.now());\n * }\n * ```\n */\nexport function shouldReveal(\n state: EngineState,\n intent: string,\n at: number,\n opts?: RevealOptions,\n): boolean {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const config = requireIntentConfig(s, name);\n const reveal = resolveReveal(s.config, config, opts);\n return decideReveal(predict(s, name, at, opts), reveal);\n}\n\n/**\n * Records that the app acted on the intent at `at`. Starts the reveal cooldown, during which\n * `predict().revealed` is true and {@link shouldReveal} is false, and increments\n * `revealCount`. Evidence and learned data are untouched.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - When the reveal happened.\n * @returns The next state.\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state or `at` is not finite.\n * @example\n * ```ts\n * state = markRevealed(state, 'upgrade', Date.now());\n * predict(state, 'upgrade', Date.now()).revealed; // true until the cooldown ends\n * ```\n */\nexport function markRevealed(state: EngineState, intent: string, at: number): EngineState {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const t = expectTimestamp(at, 'at');\n const config = requireIntentConfig(s, name);\n const is = getIntentState(s, name, config);\n return {\n ...s,\n intents: {\n ...s.intents,\n [name]: { ...is, lastRevealedAt: t, revealCount: is.revealCount + 1 },\n },\n };\n}\n","import { assessIntent, buildExplanation, buildPrediction, decideReveal } from './assess';\nimport {\n expectName,\n expectTimestamp,\n resolveLearning,\n resolveReveal,\n validateEvent,\n} from './config';\nimport { requireState } from './state';\nimport type {\n EndRecord,\n EngineState,\n EventRecord,\n IntentEvent,\n RecordedDecision,\n RecordMode,\n RecordOptions,\n} from './types';\nimport { isRecord } from './util';\nimport { RECORD_VERSION } from './version';\n\nconst RECORD_KEYS = ['installId', 'mode', 'top'];\nconst DEFAULT_TOP = 3;\n\nfunction normalizeRecordOptions(value: unknown): Required<RecordOptions> {\n if (!isRecord(value)) {\n throw new TypeError('oracular: options must be an object like { installId, mode }');\n }\n for (const key of Object.keys(value)) {\n if (!RECORD_KEYS.includes(key)) {\n throw new TypeError(\n `oracular: options.${key} is not a recognised option (expected one of: ${RECORD_KEYS.join(', ')})`,\n );\n }\n }\n const installId = expectName(value.installId, 'options.installId');\n const mode = value.mode;\n if (mode !== 'shadow' && mode !== 'live') {\n throw new TypeError('oracular: options.mode must be \"shadow\" or \"live\"');\n }\n let top = DEFAULT_TOP;\n if (value.top !== undefined) {\n if (typeof value.top !== 'number' || !Number.isFinite(value.top)) {\n throw new TypeError('oracular: options.top must be a finite number');\n }\n if (!Number.isInteger(value.top) || value.top < 0) {\n throw new RangeError('oracular: options.top must be a non-negative integer');\n }\n top = value.top;\n }\n return { installId, mode: mode as RecordMode, top };\n}\n\n/**\n * A recorder record for an event: the event itself and, for every intent, what the engine decides\n * right after it. Call it with the state `observe` returned for that event, then append\n * `JSON.stringify(record)` as one line of the log (NDJSON). The record holds the event's `name` and\n * `at`, never its `props`.\n *\n * Each decision is what {@link evaluate} reports at `event.at` with the state's own reveal\n * options: `p`, `lower`, `shouldReveal`, `suppressedUntil`, the signals with the largest impact,\n * and the effective weight of every signal. Pure: the install id comes from the app, never from\n * here. See the Shadow mode guide for the whole workflow.\n *\n * @param state - The state after `observe(state, event)`. Not mutated.\n * @param event - The event just observed. Only `name` and `at` are recorded.\n * @param opts - `installId` (generated and stored by the app), `mode` (`'shadow'` while\n * reveals are computed but not shown, `'live'` once they are), and `top` (default 3).\n * @returns A plain, JSON-serializable {@link EventRecord}.\n * @throws `TypeError` when `state` is not an engine state, the event is malformed, `opts` is\n * not an object, has an unknown key, an empty `installId` or a `mode` other than\n * `'shadow'` or `'live'`.\n * @throws `RangeError` when `opts.top` is negative or fractional.\n * @example\n * ```ts\n * const recording = { installId: localStorage.getItem('oracular.install')!, mode: 'shadow' } as const;\n *\n * const event = { name: 'pricing.viewed', at: Date.now() };\n * state = observe(state, event);\n * appendLine(JSON.stringify(createRecord(state, event, recording)));\n * ```\n */\nexport function createRecord(\n state: EngineState,\n event: IntentEvent,\n opts: RecordOptions,\n): EventRecord {\n const s = requireState(state);\n const { name, at } = validateEvent(event);\n const { installId, mode, top } = normalizeRecordOptions(opts);\n const learning = resolveLearning(s.config);\n const decisions: Record<string, RecordedDecision> = {};\n for (const [intentName, intent] of Object.entries(s.config.intents)) {\n const reveal = resolveReveal(s.config, intent, undefined);\n const is = assessIntent(s, intentName, intent, learning, at);\n const prediction = buildPrediction(is, intentName, reveal, at);\n const rows = buildExplanation(is, intent, learning, {});\n const weights: Record<string, number> = {};\n for (const signal of Object.keys(intent.signals)) {\n weights[signal] = (\n rows.find((row) => row.signal === signal) as { effectiveWeight: number }\n ).effectiveWeight;\n }\n decisions[intentName] = {\n p: prediction.p,\n lower: prediction.lower,\n shouldReveal: decideReveal(prediction, reveal),\n suppressedUntil: prediction.suppressedUntil,\n top: rows\n .filter((row) => row.contribution !== 0)\n .slice(0, top)\n .map((row) => ({ signal: row.signal, impact: row.impact })),\n weights,\n };\n }\n return { v: RECORD_VERSION, kind: 'event', installId, mode, event: { name, at }, decisions };\n}\n\n/**\n * A recorder record for the end of an episode. Write one whenever the app calls\n * {@link endEpisode}, with the same `at`, so that replay can end the episode at the same moment\n * and reproduce the misses it records. Episodes that close through `episodeTimeout` need none:\n * replay applies the timeout itself.\n *\n * @param at - The time passed to `endEpisode`.\n * @param opts - The same options as for {@link createRecord}; `top` is accepted and ignored.\n * @returns A plain, JSON-serializable {@link EndRecord}.\n * @throws `TypeError` when `at` is not a finite number or `opts` is malformed.\n * @throws `RangeError` when `opts.top` is negative or fractional.\n * @example\n * ```ts\n * const at = Date.now();\n * state = endEpisode(state, at);\n * appendLine(JSON.stringify(createEndRecord(at, recording)));\n * ```\n */\nexport function createEndRecord(at: number, opts: RecordOptions): EndRecord {\n const t = expectTimestamp(at, 'at');\n const { installId, mode } = normalizeRecordOptions(opts);\n return { v: RECORD_VERSION, kind: 'end', installId, mode, at: t };\n}\n","import { hasOwn, isRecord } from './util';\n\ntype Stored = Record<string, unknown>;\n\n/**\n * Migrations this library applies itself, keyed by the version they upgrade from. Each turns the\n * parsed JSON of one version into the shape of the next. Input that is malformed in ways a\n * migration does not need to look at is passed through untouched, so that parsing afterwards\n * rejects it with the same precise error it would give any other malformed state.\n */\nconst MIGRATIONS: Record<number, (stored: Stored) => Stored> = {\n 1: fromV1,\n 2: fromV2,\n};\n\n/** Whether `version` is one this library can bring up to date on its own. */\nexport function canMigrate(version: number): boolean {\n return hasOwn(MIGRATIONS, String(version));\n}\n\n/** Applies the built-in migrations, one version at a time, until none applies. */\nexport function migrateStored(stored: Stored): Stored {\n let current = stored;\n while (typeof current.version === 'number' && canMigrate(current.version)) {\n current = (MIGRATIONS[current.version] as (stored: Stored) => Stored)(current);\n }\n return current;\n}\n\n/**\n * Version 1 (oracular 0.1.0 to 0.2.x) → 2. Version 2 counts how often each signal occurred in the\n * open episode, so that repeats can saturate. A version 1 state only knows which signals were\n * seen, not how often, so each seen signal counts once: the lower bound. Nothing else changes, so\n * α, β and every learned count, and therefore every estimate, are exactly what they were.\n */\nfunction fromV1(stored: Stored): Stored {\n const episode = stored.episode;\n if (!isRecord(episode) || !isRecord(episode.intents)) return { ...stored, version: 2 };\n const intents: Stored = {};\n for (const key of Object.keys(episode.intents)) {\n if (key === '__proto__') continue;\n const record = episode.intents[key];\n if (isRecord(record) && Array.isArray(record.seen)) {\n const counts: Record<string, number> = {};\n for (const signal of record.seen) {\n if (typeof signal === 'string' && signal !== '__proto__') counts[signal] = 1;\n }\n intents[key] = { ...record, counts };\n } else {\n intents[key] = record;\n }\n }\n return { ...stored, version: 2, episode: { ...episode, intents } };\n}\n\n/**\n * Version 2 (oracular 0.3.0 to 0.5.x) → 3. Version 3 lets an intent hold closed episodes that wait\n * for the outcome under `IntentConfig.attribution`. A version 2 state holds none, so every intent\n * gets an empty list and nothing else changes: α, β and every learned count, and therefore every\n * estimate, are exactly what they were.\n */\nfunction fromV2(stored: Stored): Stored {\n if (!isRecord(stored.intents)) return { ...stored, version: 3 };\n const intents: Stored = {};\n for (const key of Object.keys(stored.intents)) {\n if (key === '__proto__') continue;\n const intent = stored.intents[key];\n intents[key] = isRecord(intent) ? { ...intent, pending: [] } : intent;\n }\n return { ...stored, version: 3, intents };\n}\n","import { MAX_PENDING } from './attribution';\nimport { normalizeConfig, resolveLearning } from './config';\nimport { initIntent, withContributions } from './intent';\nimport { signalWeights } from './learning';\nimport { canMigrate, migrateStored } from './migrate';\nimport { requireState } from './state';\nimport type {\n DeserializeOptions,\n EngineConfig,\n EngineState,\n EpisodeIntentRecord,\n EpisodeState,\n IntentState,\n PendingEpisode,\n SignalContribution,\n SignalRecord,\n} from './types';\nimport { getOwn, hasOwn, isRecord } from './util';\nimport { STATE_VERSION } from './version';\n\n/**\n * The state as a JSON string, for the host app to persist wherever it likes. The state is plain\n * data, so this is `JSON.stringify` after a shape check. The output never contains event props.\n *\n * @param state - The state to persist.\n * @returns A JSON string that {@link deserialize} restores losslessly.\n * @throws `TypeError` when `state` is not an engine state.\n * @example\n * ```ts\n * localStorage.setItem('oracular', serialize(state));\n * ```\n */\nexport function serialize(state: EngineState): string {\n return JSON.stringify(requireState(state));\n}\n\n/**\n * Restores a state saved with {@link serialize}.\n *\n * Always pass the app's current `config`: it is validated and replaces the stored snapshot,\n * intents and signals no longer declared are dropped (α and β are recomputed from the kept\n * contributions), and newly declared intents start at their prior. States saved by oracular\n * 0.1.0 to 0.5.x are upgraded to the current shape on their own; `migrate` is only for a version\n * this library does not know.\n *\n * @param json - A string produced by {@link serialize}.\n * @param opts - `config`: the app's current config. `migrate`: called as\n * `migrate(stored, version)` when the stored version is neither {@link STATE_VERSION} nor one\n * this library migrates itself; it must return a state of the current version.\n * @returns A validated state that satisfies the engine's invariants.\n * @throws `SyntaxError` when `json` is not valid JSON.\n * @throws `TypeError` when the stored data, the result of `migrate`, `opts` or `opts.config`\n * has the wrong shape.\n * @throws `RangeError` when the stored version is unknown and no `migrate` is given, when\n * `migrate` does not return the current version, when a stored number is out of range, or\n * when stored numbers are finite but too large to compute with (a tampered or corrupted state\n * that would otherwise answer NaN).\n * @example\n * ```ts\n * const saved = localStorage.getItem('oracular');\n * let state = saved ? deserialize(saved, { config }) : createState(config);\n * ```\n */\nexport function deserialize(json: string, opts: DeserializeOptions = {}): EngineState {\n if (typeof json !== 'string') throw new TypeError('oracular: deserialize expects a JSON string');\n if (!isRecord(opts)) throw new TypeError('oracular: options must be a plain object');\n for (const key of Object.keys(opts)) {\n if (key !== 'config' && key !== 'migrate') {\n throw new TypeError(\n `oracular: options.${key} is not a recognised option (expected one of: config, migrate)`,\n );\n }\n }\n if (opts.migrate !== undefined && typeof opts.migrate !== 'function') {\n throw new TypeError('oracular: options.migrate must be a function');\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (error) {\n throw new SyntaxError(`oracular: stored state is not valid JSON (${(error as Error).message})`);\n }\n if (!isRecord(parsed) || typeof parsed.version !== 'number') {\n throw new TypeError('oracular: stored state has no numeric version field');\n }\n\n let stored: unknown = parsed;\n if (parsed.version !== STATE_VERSION) {\n if (canMigrate(parsed.version)) {\n stored = migrateStored(parsed);\n } else if (opts.migrate === undefined) {\n throw new RangeError(\n `oracular: stored state is version ${parsed.version} but this library reads versions 1 to ${STATE_VERSION}; pass a migrate function`,\n );\n } else {\n stored = opts.migrate(parsed, parsed.version);\n }\n }\n\n const raw = parseState(stored);\n const config = opts.config === undefined ? raw.config : normalizeConfig(opts.config);\n return requireComputable(reconcile(raw, config));\n}\n\n// ---- parsing: field types only; keys are reconciled against the config afterwards ----\n\nfunction typeError(path: string, message: string): never {\n throw new TypeError(`oracular: ${path} ${message}`);\n}\n\nfunction record(value: unknown, path: string): Record<string, unknown> {\n if (!isRecord(value)) typeError(path, 'must be a plain object');\n return value;\n}\n\nfunction finite(value: unknown, path: string): number {\n if (typeof value !== 'number' || !Number.isFinite(value))\n typeError(path, 'must be a finite number');\n return value;\n}\n\nfunction nonNegative(value: unknown, path: string): number {\n const n = finite(value, path);\n if (n < 0) throw new RangeError(`oracular: ${path} must be 0 or greater`);\n return n;\n}\n\nfunction nullOrFinite(value: unknown, path: string): number | null {\n return value === null ? null : finite(value, path);\n}\n\nfunction signalRecord(value: unknown, path: string): SignalRecord {\n const r = record(value, path);\n return {\n hits: nonNegative(r.hits, `${path}.hits`),\n misses: nonNegative(r.misses, `${path}.misses`),\n };\n}\n\nfunction contribution(value: unknown, path: string): SignalContribution {\n const r = record(value, path);\n return {\n alpha: nonNegative(r.alpha, `${path}.alpha`),\n beta: nonNegative(r.beta, `${path}.beta`),\n };\n}\n\nfunction mapOwn<T>(\n value: unknown,\n path: string,\n fn: (item: unknown, itemPath: string) => T,\n): Record<string, T> {\n const r = record(value, path);\n const out: Record<string, T> = {};\n for (const key of Object.keys(r)) {\n if (key === '__proto__') continue;\n out[key] = fn(r[key], `${path}[${JSON.stringify(key)}]`);\n }\n return out;\n}\n\nfunction pendingEpisodes(value: unknown, path: string): PendingEpisode[] {\n if (!Array.isArray(value)) typeError(path, 'must be an array');\n if (value.length > MAX_PENDING) {\n throw new RangeError(`oracular: ${path} must hold at most ${MAX_PENDING} episodes`);\n }\n return value.map((item, i) => {\n const r = record(item, `${path}[${i}]`);\n if (!Array.isArray(r.seen) || !r.seen.every((s) => typeof s === 'string')) {\n typeError(`${path}[${i}].seen`, 'must be an array of strings');\n }\n return { endedAt: finite(r.endedAt, `${path}[${i}].endedAt`), seen: r.seen as string[] };\n });\n}\n\nfunction intentState(value: unknown, path: string): IntentState {\n const r = record(value, path);\n const revealCount = finite(r.revealCount, `${path}.revealCount`);\n if (!Number.isInteger(revealCount) || revealCount < 0) {\n throw new RangeError(`oracular: ${path}.revealCount must be a non-negative integer`);\n }\n return {\n alpha: finite(r.alpha, `${path}.alpha`),\n beta: finite(r.beta, `${path}.beta`),\n updatedAt: nullOrFinite(r.updatedAt, `${path}.updatedAt`),\n contributions: mapOwn(r.contributions, `${path}.contributions`, contribution),\n learned: mapOwn(r.learned, `${path}.learned`, signalRecord),\n episodes: signalRecord(r.episodes, `${path}.episodes`),\n pending: pendingEpisodes(r.pending, `${path}.pending`),\n learnedAt: nullOrFinite(r.learnedAt, `${path}.learnedAt`),\n lastRevealedAt: nullOrFinite(r.lastRevealedAt, `${path}.lastRevealedAt`),\n lastOutcomeAt: nullOrFinite(r.lastOutcomeAt, `${path}.lastOutcomeAt`),\n revealCount,\n };\n}\n\nfunction occurrenceCount(value: unknown, path: string): number {\n const n = finite(value, path);\n if (!Number.isInteger(n) || n < 1) {\n throw new RangeError(`oracular: ${path} must be a positive integer`);\n }\n return n;\n}\n\nfunction episodeIntent(value: unknown, path: string): EpisodeIntentRecord {\n const r = record(value, path);\n if (!Array.isArray(r.seen) || !r.seen.every((s) => typeof s === 'string')) {\n typeError(`${path}.seen`, 'must be an array of strings');\n }\n const counts = mapOwn(r.counts, `${path}.counts`, occurrenceCount);\n if (typeof r.resolved !== 'boolean') typeError(`${path}.resolved`, 'must be a boolean');\n return { seen: r.seen as string[], counts, resolved: r.resolved };\n}\n\nfunction episodeState(value: unknown, path: string): EpisodeState {\n const r = record(value, path);\n return {\n startedAt: nullOrFinite(r.startedAt, `${path}.startedAt`),\n lastEventAt: nullOrFinite(r.lastEventAt, `${path}.lastEventAt`),\n intents: mapOwn(r.intents, `${path}.intents`, episodeIntent),\n };\n}\n\nfunction parseState(value: unknown): EngineState {\n const r = record(value, 'state');\n if (r.version !== STATE_VERSION) {\n throw new RangeError(`oracular: state.version must be ${STATE_VERSION} after migration`);\n }\n return {\n version: STATE_VERSION,\n config: normalizeConfig(r.config),\n intents: mapOwn(r.intents, 'state.intents', intentState),\n episode: episodeState(r.episode, 'state.episode'),\n };\n}\n\n// ---- computability: finite numbers that are still too large to compute with ----\n\n/**\n * Every stored number is checked to be finite, but finite is not enough: a contribution near\n * 1e308 makes α·β overflow, and learned counts near 1e308 make the contrast weighting overflow,\n * so the state would answer NaN. Such a state was tampered with or corrupted; reject it.\n */\nfunction requireComputable(state: EngineState): EngineState {\n const learning = resolveLearning(state.config);\n for (const [name, intent] of Object.entries(state.config.intents)) {\n const is = state.intents[name] as IntentState;\n const path = `state.intents[${JSON.stringify(name)}]`;\n if (!Number.isFinite(is.alpha + is.beta) || !Number.isFinite(is.alpha * is.beta)) {\n throw new RangeError(`oracular: ${path} holds more evidence than can be computed with`);\n }\n for (const signal of Object.keys(intent.signals)) {\n const w = signalWeights(is, intent, learning, signal);\n if (!Number.isFinite(w.learned) || !Number.isFinite(w.effective)) {\n throw new RangeError(\n `oracular: ${path} holds learned counts for ${JSON.stringify(signal)} too large to compute with`,\n );\n }\n }\n }\n return state;\n}\n\n// ---- reconciling: make the state agree with a config ----\n\nfunction keep<T>(source: Record<string, T>, declared: Record<string, unknown>): Record<string, T> {\n const out: Record<string, T> = {};\n for (const [key, value] of Object.entries(source)) {\n if (hasOwn(declared, key)) out[key] = value;\n }\n return out;\n}\n\n/** Waiting episodes with their seen lists pruned to declared signals, each once, in order of close. */\nfunction keepPending(\n pending: readonly PendingEpisode[],\n signals: Record<string, number>,\n): PendingEpisode[] {\n return pending\n .map((episode) => ({\n endedAt: episode.endedAt,\n seen: episode.seen.filter((s, i) => hasOwn(signals, s) && episode.seen.indexOf(s) === i),\n }))\n .sort((a, b) => a.endedAt - b.endedAt);\n}\n\n/**\n * Drops intents and signals the config no longer declares, starts newly declared intents at\n * their prior, and recomputes α and β as the (possibly new) prior plus the kept contributions.\n */\nfunction reconcile(raw: EngineState, config: EngineConfig): EngineState {\n const intents: Record<string, IntentState> = {};\n const episodeIntents: Record<string, EpisodeIntentRecord> = {};\n\n for (const [name, intent] of Object.entries(config.intents)) {\n const stored = getOwn(raw.intents, name);\n if (stored === undefined) {\n intents[name] = initIntent(intent);\n } else {\n intents[name] = withContributions(\n {\n ...stored,\n learned: keep(stored.learned, intent.signals),\n pending: keepPending(stored.pending, intent.signals),\n },\n intent,\n keep(stored.contributions, intent.signals),\n );\n }\n const episode = getOwn(raw.episode.intents, name);\n if (episode !== undefined && raw.episode.startedAt !== null) {\n const seen = episode.seen.filter(\n (s, i) => hasOwn(intent.signals, s) && episode.seen.indexOf(s) === i,\n );\n // One count per seen signal and no other: a seen signal without one counts once.\n const counts: Record<string, number> = {};\n for (const s of seen) counts[s] = getOwn(episode.counts, s) ?? 1;\n episodeIntents[name] = { seen, counts, resolved: episode.resolved };\n }\n }\n\n return {\n version: STATE_VERSION,\n config,\n intents,\n episode: {\n startedAt: raw.episode.startedAt,\n lastEventAt: raw.episode.startedAt === null ? null : raw.episode.lastEventAt,\n intents: episodeIntents,\n },\n };\n}\n","/** The units of {@link ms}: each takes a count and returns milliseconds. */\nexport interface Units {\n /** `n` seconds in milliseconds: `n × 1000`. */\n readonly seconds: (n: number) => number;\n /** `n` minutes in milliseconds: `n × 60 000`. */\n readonly minutes: (n: number) => number;\n /** `n` hours in milliseconds: `n × 3 600 000`. */\n readonly hours: (n: number) => number;\n /** `n` days in milliseconds: `n × 86 400 000`. */\n readonly days: (n: number) => number;\n /** `n` weeks in milliseconds: `n × 604 800 000`. */\n readonly weeks: (n: number) => number;\n}\n\n/**\n * Durations in milliseconds, the unit of `Date.now()`: `ms.days(7)` is `604800000`. Plain\n * multiplications and nothing else, for `halfLife`, `cooldown`, `episodeTimeout` and\n * `learning.halfLife` when your timestamps are in milliseconds. If your `at` is in another unit,\n * write durations in that unit instead: the engine only needs the two to agree.\n *\n * @example\n * ```ts\n * const config = {\n * episodeTimeout: ms.minutes(30),\n * intents: {\n * upgrade: {\n * prior: 0.05,\n * priorStrength: 10,\n * halfLife: ms.days(7),\n * signals: { 'pricing.viewed': 3 },\n * reveal: { cooldown: ms.weeks(2) },\n * },\n * },\n * };\n * ```\n */\nexport const ms: Units = {\n seconds: (n) => n * 1_000,\n minutes: (n) => n * 60_000,\n hours: (n) => n * 3_600_000,\n days: (n) => n * 86_400_000,\n weeks: (n) => n * 604_800_000,\n};\n","import { normalizeConfig } from './config';\nimport type { EngineConfig } from './types';\n\n/**\n * Checks a config exactly as {@link createState} and {@link deserialize} do, without building a\n * state, and returns the normalized copy they would store: only the recognised keys, in a fixed\n * order, with every `undefined` dropped, so it survives a JSON round trip unchanged. Use it to\n * fail fast at startup or in a test, or on a config loaded from a file, before the engine runs.\n *\n * @param config - The config to check. Typed `unknown` so parsed JSON can be passed as it is.\n * @returns A fresh, normalized {@link EngineConfig}. `config` is not mutated.\n * @throws `TypeError` when a value has the wrong type or a key is not recognised.\n * @throws `RangeError` when a number is out of range: a `prior` outside (0, 1), a signal weight of\n * 0, or a weight, `priorStrength`, `learning.gain` or `learning.priorEpisodes` beyond 1e6.\n * @example\n * ```ts\n * import { readFileSync } from 'node:fs';\n * import { validateConfig } from 'oracular';\n *\n * // Throws with the offending path in the message, e.g. config.intents[\"upgrade\"].prior\n * const config = validateConfig(JSON.parse(readFileSync('oracular.config.json', 'utf8')));\n * ```\n */\nexport function validateConfig(config: unknown): EngineConfig {\n return normalizeConfig(config);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/math.ts","../src/util.ts","../src/learning.ts","../src/attribution.ts","../src/intent.ts","../src/config.ts","../src/episode.ts","../src/version.ts","../src/state.ts","../src/assess.ts","../src/evaluate.ts","../src/evidence.ts","../src/explain.ts","../src/observe.ts","../src/predict.ts","../src/recorder.ts","../src/migrate.ts","../src/serialize.ts","../src/units.ts","../src/validate.ts"],"names":["record","explain","typeError"],"mappings":"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","file":"index.cjs","sourcesContent":["/** 2^(−elapsed / halfLife). Returns 1 for zero, negative or non-finite elapsed time. */\nexport function decayFactor(elapsed: number, halfLife: number): number {\n if (!(elapsed > 0) || !Number.isFinite(elapsed)) return 1;\n return 2 ** (-elapsed / halfLife);\n}\n\nexport function betaMean(alpha: number, beta: number): number {\n return alpha / (alpha + beta);\n}\n\nexport function betaVariance(alpha: number, beta: number): number {\n const n = alpha + beta;\n return (alpha * beta) / (n * n * (n + 1));\n}\n\nexport function betaSd(alpha: number, beta: number): number {\n return Math.sqrt(betaVariance(alpha, beta));\n}\n\nexport function clamp01(x: number): number {\n if (x < 0) return 0;\n if (x > 1) return 1;\n return x;\n}\n\n/**\n * What the n-th occurrence of a signal within one episode adds, as a fraction of its weight:\n * log2(1 + 1/n), so that n occurrences add log2(1 + n) weights in total. 1 for the first\n * occurrence, 0.585 for the second, 0.415 for the third; every doubling adds one more weight.\n */\nexport function repeatFactor(n: number): number {\n return Math.log1p(1 / n) / Math.LN2;\n}\n\n/** Laplace-smoothed rate: (successes + 1) / (total + 2). Always strictly inside (0, 1). */\nexport function laplace(successes: number, total: number): number {\n return (successes + 1) / (total + 2);\n}\n\n/**\n * How far a rate `q` sits from a base rate `b`, scaled to [−1, 1]:\n * +1 when q is 1, 0 when q equals b, −1 when q is 0.\n */\nexport function lift(q: number, b: number): number {\n if (q >= b) return b >= 1 ? 0 : (q - b) / (1 - b);\n return b <= 0 ? 0 : (q - b) / b;\n}\n","export function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Own-property check, so event names like \"constructor\" never hit Object.prototype. */\nexport function hasOwn(record: object, key: string): boolean {\n // biome-ignore lint/suspicious/noPrototypeBuiltins: Object.hasOwn is ES2022; this library targets ES2020 runtimes.\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\nexport function getOwn<T>(record: Record<string, T>, key: string): T | undefined {\n return hasOwn(record, key) ? record[key] : undefined;\n}\n\nexport function mapRecord<T, U>(\n record: Record<string, T>,\n fn: (value: T, key: string) => U,\n): Record<string, U> {\n const out: Record<string, U> = {};\n for (const [key, value] of Object.entries(record)) {\n out[key] = fn(value, key);\n }\n return out;\n}\n","import type { ResolvedLearning } from './config';\nimport { decayFactor, laplace, lift } from './math';\nimport type { IntentConfig, IntentState, SignalRecord } from './types';\nimport { getOwn, mapRecord } from './util';\n\nconst NONE: SignalRecord = { hits: 0, misses: 0 };\n\n/** Decays learned counts toward 0 by 2^(−Δt / learning.halfLife) and moves the anchor to `at`. */\nexport function decayLearned(\n state: IntentState,\n learning: ResolvedLearning,\n at: number,\n): IntentState {\n if (state.learnedAt === null) return { ...state, learnedAt: at };\n const learnedAt = Math.max(state.learnedAt, at);\n const d = learning.halfLife === null ? 1 : decayFactor(at - state.learnedAt, learning.halfLife);\n if (d === 1) return learnedAt === state.learnedAt ? state : { ...state, learnedAt };\n return {\n ...state,\n learnedAt,\n learned: mapRecord(state.learned, (r) => ({ hits: r.hits * d, misses: r.misses * d })),\n episodes: { hits: state.episodes.hits * d, misses: state.episodes.misses * d },\n };\n}\n\nexport interface SignalWeights {\n initial: number;\n learned: number;\n effective: number;\n hits: number;\n misses: number;\n}\n\n/**\n * initial: the developer's weight w0.\n * learned: gain · |w0| · lift(qWith, qWithout), where qWith is the Laplace-smoothed outcome\n * rate of episodes in which the signal was seen (hits / (hits + misses)) and\n * qWithout the Laplace-smoothed outcome rate of the intent's other episodes\n * (episodes without the signal). 0 until the signal has completed an episode.\n * effective: (k · w0 + nEff · learned) / (k + nEff), with k = learning.priorEpisodes and\n * nEff = (nWith · nWithout) / (nWith + nWithout): the comparison is only trusted once\n * the signal has been both present and absent. A signal that has never been absent\n * (or never present) has no counterfactual, nEff is 0, and the developer's weight stands.\n */\nexport function signalWeights(\n state: IntentState,\n intent: IntentConfig,\n learning: ResolvedLearning,\n signal: string,\n): SignalWeights {\n const initial = getOwn(intent.signals, signal);\n if (initial === undefined) {\n throw new RangeError(`oracular: ${JSON.stringify(signal)} is not a signal of this intent`);\n }\n const record = getOwn(state.learned, signal) ?? NONE;\n const nWith = record.hits + record.misses;\n const qWith = laplace(record.hits, nWith);\n // The contrast: episodes of this intent in which the signal was not seen. hits + misses counts\n // the episodes it was seen in (one record per episode), so the rest is the complement.\n const totalEpisodes = state.episodes.hits + state.episodes.misses;\n const nWithout = Math.max(0, totalEpisodes - nWith);\n const outcomesWithout = Math.min(nWithout, Math.max(0, state.episodes.hits - record.hits));\n const qWithout = laplace(outcomesWithout, nWithout);\n // Nothing has been learned about a signal until it has been seen in a completed episode.\n const learned = nWith === 0 ? 0 : learning.gain * Math.abs(initial) * lift(qWith, qWithout);\n // Learning needs contrast: weight the comparison by how much of both sides has been seen.\n const nEff = nWith + nWithout === 0 ? 0 : (nWith * nWithout) / (nWith + nWithout);\n const k = learning.priorEpisodes;\n const effective = (k * initial + nEff * learned) / (k + nEff);\n return { initial, learned, effective, hits: record.hits, misses: record.misses };\n}\n\n/**\n * Counts one episode for the listed signals and for the base rate: `credit` of a hit and\n * `1 − credit` of a miss. 1 when the outcome arrived in the episode, 0 when it ended without it,\n * and in between for an episode a later outcome credits under `attribution` (see attribution.ts).\n * Whatever the credit, the episode counts exactly once.\n */\nexport function recordEpisode(\n state: IntentState,\n signals: readonly string[],\n credit: number,\n): IntentState {\n const miss = 1 - credit;\n const learned = { ...state.learned };\n for (const signal of signals) {\n const r = getOwn(learned, signal) ?? NONE;\n learned[signal] = { hits: r.hits + credit, misses: r.misses + miss };\n }\n const episodes = { hits: state.episodes.hits + credit, misses: state.episodes.misses + miss };\n return { ...state, learned, episodes };\n}\n","import type { ResolvedLearning } from './config';\nimport { decayLearned, recordEpisode } from './learning';\nimport { decayFactor } from './math';\nimport type { IntentConfig, IntentState, PendingEpisode } from './types';\n\n/** Most closed episodes one intent keeps waiting for its outcome. Past it the oldest is a miss at once. */\nexport const MAX_PENDING = 32;\n\n/**\n * When a waiting episode's window ends: its close plus the intent's `attribution`. 0 when the\n * intent no longer sets one, so an episode held under an earlier config settles on the next touch.\n */\nfunction expiry(episode: PendingEpisode, intent: IntentConfig): number {\n return episode.endedAt + (intent.attribution ?? 0);\n}\n\n/**\n * Brings the learned counts up to `at`. Every waiting episode whose window has ended by then is a\n * miss, recorded at the moment its window ended (the counts are decayed to that moment first, as\n * for an episode that closes by timing out), and the counts are then decayed to `at`. Every path\n * that reads or writes learned counts goes through here, so no verdict lands out of order.\n */\nexport function settlePending(\n state: IntentState,\n intent: IntentConfig,\n learning: ResolvedLearning,\n at: number,\n): IntentState {\n let is = state;\n let settled = 0;\n for (const episode of state.pending) {\n const end = expiry(episode, intent);\n if (!(end < at)) break;\n is = recordEpisode(decayLearned(is, learning, end), episode.seen, 0);\n settled++;\n }\n if (settled > 0) is = { ...is, pending: state.pending.slice(settled) };\n return decayLearned(is, learning, at);\n}\n\n/**\n * Holds a closed episode for the intent's outcome instead of counting it, in order of close. Past\n * {@link MAX_PENDING} the oldest is a miss at once, so the stored state stays bounded whatever the\n * session cadence.\n */\nexport function deferEpisode(\n state: IntentState,\n seen: readonly string[],\n endedAt: number,\n): IntentState {\n const pending = insert(state.pending, { endedAt, seen: [...seen] });\n if (pending.length <= MAX_PENDING) return { ...state, pending };\n const [oldest, ...rest] = pending;\n return { ...recordEpisode(state, (oldest as PendingEpisode).seen, 0), pending: rest };\n}\n\n/** Keeps the list in order of close; a clock that went backwards inserts before later closes. */\nfunction insert(pending: readonly PendingEpisode[], episode: PendingEpisode): PendingEpisode[] {\n let i = pending.length;\n while (i > 0 && (pending[i - 1] as PendingEpisode).endedAt > episode.endedAt) i--;\n return [...pending.slice(0, i), episode, ...pending.slice(i)];\n}\n\n/**\n * The outcome arrived at `at`: every waiting episode gets the share `2^(−age / halfLife)` of a hit\n * that its evidence would still hold now, and the rest of a miss, so each episode still counts\n * exactly once. The list is then empty.\n */\nexport function creditPending(state: IntentState, intent: IntentConfig, at: number): IntentState {\n if (state.pending.length === 0) return state;\n let is = state;\n for (const episode of state.pending) {\n is = recordEpisode(is, episode.seen, decayFactor(at - episode.endedAt, intent.halfLife));\n }\n return { ...is, pending: [] };\n}\n","import { decayFactor } from './math';\nimport type { IntentConfig, IntentState, SignalContribution } from './types';\nimport { getOwn, mapRecord } from './util';\n\nexport function priorCounts(intent: IntentConfig): { alpha0: number; beta0: number } {\n return {\n alpha0: intent.prior * intent.priorStrength,\n beta0: (1 - intent.prior) * intent.priorStrength,\n };\n}\n\nexport function initIntent(intent: IntentConfig): IntentState {\n const { alpha0, beta0 } = priorCounts(intent);\n return {\n alpha: alpha0,\n beta: beta0,\n updatedAt: null,\n contributions: {},\n learned: {},\n episodes: { hits: 0, misses: 0 },\n pending: [],\n learnedAt: null,\n lastRevealedAt: null,\n lastOutcomeAt: null,\n revealCount: 0,\n };\n}\n\n/**\n * The one place α and β are written: always the prior plus the sum of contributions,\n * so the invariant α = α0 + Σ contributions.alpha (and β likewise) holds by construction.\n */\nexport function withContributions(\n state: IntentState,\n intent: IntentConfig,\n contributions: Record<string, SignalContribution>,\n): IntentState {\n const { alpha0, beta0 } = priorCounts(intent);\n let alpha = alpha0;\n let beta = beta0;\n for (const c of Object.values(contributions)) {\n alpha += c.alpha;\n beta += c.beta;\n }\n return { ...state, alpha, beta, contributions };\n}\n\n/** Decays evidence toward the prior by 2^(−Δt / halfLife) and moves the anchor to `at`. */\nexport function decayIntent(state: IntentState, intent: IntentConfig, at: number): IntentState {\n if (state.updatedAt === null) return { ...state, updatedAt: at };\n const d = decayFactor(at - state.updatedAt, intent.halfLife);\n const updatedAt = Math.max(state.updatedAt, at);\n if (d === 1) return updatedAt === state.updatedAt ? state : { ...state, updatedAt };\n const contributions = mapRecord(state.contributions, (c) => ({\n alpha: c.alpha * d,\n beta: c.beta * d,\n }));\n return withContributions({ ...state, updatedAt }, intent, contributions);\n}\n\n/** Adds `weight` pseudo-counts for the intent (positive → α) or against it (negative → β). */\nexport function applySignal(\n state: IntentState,\n intent: IntentConfig,\n signal: string,\n weight: number,\n): IntentState {\n const prev = getOwn(state.contributions, signal) ?? { alpha: 0, beta: 0 };\n const next: SignalContribution =\n weight >= 0\n ? { alpha: prev.alpha + weight, beta: prev.beta }\n : { alpha: prev.alpha, beta: prev.beta - weight };\n return withContributions(state, intent, { ...state.contributions, [signal]: next });\n}\n\n/** Drops all evidence; α and β return to the prior. Learned data is untouched. */\nexport function resetToPrior(state: IntentState, intent: IntentConfig): IntentState {\n return withContributions(state, intent, {});\n}\n","import type {\n EngineConfig,\n EvaluateOptions,\n ExplainOptions,\n IntentConfig,\n LearningConfig,\n RevealOptions,\n} from './types';\nimport { isRecord } from './util';\n\nexport const DEFAULT_THRESHOLD = 0.5;\nexport const DEFAULT_Z = 1.28;\nexport const DEFAULT_GAIN = 2;\nexport const DEFAULT_PRIOR_EPISODES = 10;\n/**\n * Largest accepted magnitude for weights, `priorStrength`, `learning.gain` and\n * `learning.priorEpisodes`: far beyond any real config, and small enough that the Beta and\n * learning arithmetic can never overflow to Infinity or NaN.\n */\nexport const MAX_MAGNITUDE = 1e6;\n\n// Exported for tests/schema.test.ts, which pins schema/config.schema.json to these lists.\nexport const CONFIG_KEYS = ['intents', 'episodeTimeout', 'learning', 'reveal'] as const;\nexport const INTENT_KEYS = [\n 'prior',\n 'priorStrength',\n 'halfLife',\n 'signals',\n 'outcome',\n 'resetOnOutcome',\n 'saturate',\n 'attribution',\n 'reveal',\n] as const;\nexport const REVEAL_KEYS = ['threshold', 'z', 'cooldown'] as const;\nexport const LEARNING_KEYS = ['halfLife', 'gain', 'priorEpisodes'] as const;\nconst EXPLAIN_KEYS = ['nonZero', 'limit'] as const;\n\nfunction typeError(path: string, message: string): never {\n throw new TypeError(`oracular: ${path} ${message}`);\n}\n\nfunction rangeError(path: string, message: string): never {\n throw new RangeError(`oracular: ${path} ${message}`);\n}\n\nfunction expectRecord(value: unknown, path: string): Record<string, unknown> {\n if (!isRecord(value)) typeError(path, 'must be a plain object');\n return value;\n}\n\nfunction expectKeys(\n record: Record<string, unknown>,\n allowed: readonly string[],\n path: string,\n): void {\n for (const key of Object.keys(record)) {\n if (!allowed.includes(key)) {\n typeError(\n `${path}.${key}`,\n `is not a recognised option (expected one of: ${allowed.join(', ')})`,\n );\n }\n }\n}\n\nfunction expectNumber(value: unknown, path: string): number {\n if (typeof value !== 'number' || !Number.isFinite(value))\n typeError(path, 'must be a finite number');\n return value;\n}\n\nfunction expectPositive(value: unknown, path: string): number {\n const n = expectNumber(value, path);\n if (n <= 0) rangeError(path, 'must be greater than 0');\n return n;\n}\n\n/** A positive number no larger than {@link MAX_MAGNITUDE}. */\nfunction expectBoundedPositive(value: unknown, path: string): number {\n const n = expectPositive(value, path);\n if (n > MAX_MAGNITUDE) rangeError(path, `must be at most ${MAX_MAGNITUDE}`);\n return n;\n}\n\nfunction expectNonNegative(value: unknown, path: string): number {\n const n = expectNumber(value, path);\n if (n < 0) rangeError(path, 'must be 0 or greater');\n return n;\n}\n\nfunction expectOpenUnit(value: unknown, path: string): number {\n const n = expectNumber(value, path);\n if (n <= 0 || n >= 1) rangeError(path, 'must be strictly between 0 and 1');\n return n;\n}\n\nfunction expectClosedUnit(value: unknown, path: string): number {\n const n = expectNumber(value, path);\n if (n < 0 || n > 1) rangeError(path, 'must be between 0 and 1');\n return n;\n}\n\nexport function expectName(value: unknown, path: string): string {\n if (typeof value !== 'string' || value.length === 0)\n typeError(path, 'must be a non-empty string');\n return value;\n}\n\n/** Keys of user-named records must be usable as own properties of a plain object. */\nfunction expectKeyName(name: string, path: string): string {\n if (name.length === 0) typeError(path, 'names must be non-empty strings');\n if (name === '__proto__') typeError(path, 'must not use the reserved name \"__proto__\"');\n return name;\n}\n\n/** Validates reveal options and returns a copy with only the defined keys. */\nexport function normalizeRevealOptions(value: unknown, path: string): RevealOptions {\n const record = expectRecord(value, path);\n expectKeys(record, REVEAL_KEYS, path);\n const out: RevealOptions = {};\n if (record.threshold !== undefined) {\n out.threshold = expectClosedUnit(record.threshold, `${path}.threshold`);\n }\n if (record.z !== undefined) out.z = expectNonNegative(record.z, `${path}.z`);\n if (record.cooldown !== undefined) {\n out.cooldown = expectNonNegative(record.cooldown, `${path}.cooldown`);\n }\n return out;\n}\n\nfunction normalizeLearning(value: unknown, path: string): LearningConfig {\n const record = expectRecord(value, path);\n expectKeys(record, LEARNING_KEYS, path);\n const out: LearningConfig = {};\n if (record.halfLife !== undefined)\n out.halfLife = expectPositive(record.halfLife, `${path}.halfLife`);\n if (record.gain !== undefined) out.gain = expectBoundedPositive(record.gain, `${path}.gain`);\n if (record.priorEpisodes !== undefined) {\n out.priorEpisodes = expectBoundedPositive(record.priorEpisodes, `${path}.priorEpisodes`);\n }\n return out;\n}\n\n/** Validates one intent's config and returns a copy with only the defined, recognised keys. */\nexport function normalizeIntentConfig(value: unknown, path: string): IntentConfig {\n const record = expectRecord(value, path);\n expectKeys(record, INTENT_KEYS, path);\n const signalsRecord = expectRecord(record.signals, `${path}.signals`);\n const signals: Record<string, number> = {};\n for (const [name, weight] of Object.entries(signalsRecord)) {\n expectKeyName(name, `${path}.signals`);\n const w = expectNumber(weight, `${path}.signals[${JSON.stringify(name)}]`);\n if (w === 0) {\n rangeError(\n `${path}.signals[${JSON.stringify(name)}]`,\n 'must be non-zero (positive is evidence for the intent, negative is evidence against)',\n );\n }\n if (Math.abs(w) > MAX_MAGNITUDE) {\n rangeError(\n `${path}.signals[${JSON.stringify(name)}]`,\n `must be between -${MAX_MAGNITUDE} and ${MAX_MAGNITUDE}`,\n );\n }\n signals[name] = w;\n }\n const out: IntentConfig = {\n prior: expectOpenUnit(record.prior, `${path}.prior`),\n priorStrength: expectBoundedPositive(record.priorStrength, `${path}.priorStrength`),\n halfLife: expectPositive(record.halfLife, `${path}.halfLife`),\n signals,\n };\n if (record.outcome !== undefined) out.outcome = expectName(record.outcome, `${path}.outcome`);\n if (record.resetOnOutcome !== undefined) {\n if (typeof record.resetOnOutcome !== 'boolean') {\n typeError(`${path}.resetOnOutcome`, 'must be a boolean');\n }\n out.resetOnOutcome = record.resetOnOutcome;\n }\n if (record.saturate !== undefined) {\n if (typeof record.saturate !== 'boolean') typeError(`${path}.saturate`, 'must be a boolean');\n out.saturate = record.saturate;\n }\n if (record.attribution !== undefined) {\n out.attribution = expectPositive(record.attribution, `${path}.attribution`);\n }\n if (record.reveal !== undefined)\n out.reveal = normalizeRevealOptions(record.reveal, `${path}.reveal`);\n return out;\n}\n\n/**\n * Validates a config and returns a fresh copy holding only the defined, recognised keys,\n * so that it survives a JSON round trip unchanged.\n */\nexport function normalizeConfig(value: unknown): EngineConfig {\n const record = expectRecord(value, 'config');\n expectKeys(record, CONFIG_KEYS, 'config');\n const intentsRecord = expectRecord(record.intents, 'config.intents');\n const names = Object.keys(intentsRecord);\n if (names.length === 0) typeError('config.intents', 'must declare at least one intent');\n const intents: Record<string, IntentConfig> = {};\n for (const name of names) {\n expectKeyName(name, 'config.intents');\n intents[name] = normalizeIntentConfig(\n intentsRecord[name],\n `config.intents[${JSON.stringify(name)}]`,\n );\n }\n const out: EngineConfig = { intents };\n if (record.episodeTimeout !== undefined) {\n out.episodeTimeout = expectPositive(record.episodeTimeout, 'config.episodeTimeout');\n }\n if (record.learning !== undefined)\n out.learning = normalizeLearning(record.learning, 'config.learning');\n if (record.reveal !== undefined)\n out.reveal = normalizeRevealOptions(record.reveal, 'config.reveal');\n return out;\n}\n\n/** Validates explain filters and returns a copy with only the defined keys. */\nexport function normalizeExplainOptions(value: unknown, path: string): ExplainOptions {\n const record = expectRecord(value, path);\n expectKeys(record, EXPLAIN_KEYS, path);\n const out: ExplainOptions = {};\n if (record.nonZero !== undefined) {\n if (typeof record.nonZero !== 'boolean') typeError(`${path}.nonZero`, 'must be a boolean');\n out.nonZero = record.nonZero;\n }\n if (record.limit !== undefined) {\n const n = expectNumber(record.limit, `${path}.limit`);\n if (!Number.isInteger(n) || n < 0)\n rangeError(`${path}.limit`, 'must be a non-negative integer');\n out.limit = n;\n }\n return out;\n}\n\n/** Splits `evaluate` options into reveal overrides and explain filters, rejecting unknown keys. */\nexport function splitEvaluateOptions(\n value: EvaluateOptions | undefined,\n path: string,\n): { reveal: RevealOptions; explain: ExplainOptions } {\n if (value === undefined) return { reveal: {}, explain: {} };\n const record = expectRecord(value, path);\n expectKeys(record, [...REVEAL_KEYS, ...EXPLAIN_KEYS], path);\n const reveal: Record<string, unknown> = {};\n const explain: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(record)) {\n if ((REVEAL_KEYS as readonly string[]).includes(key)) reveal[key] = v;\n else explain[key] = v;\n }\n return {\n reveal: normalizeRevealOptions(reveal, path),\n explain: normalizeExplainOptions(explain, path),\n };\n}\n\nexport interface ResolvedReveal {\n threshold: number;\n z: number;\n cooldown: number;\n}\n\nexport function resolveReveal(\n config: EngineConfig | undefined,\n intent: IntentConfig,\n opts: RevealOptions | undefined,\n normalized = false,\n): ResolvedReveal {\n const o = opts === undefined ? {} : normalized ? opts : normalizeRevealOptions(opts, 'options');\n return {\n threshold:\n o.threshold ?? intent.reveal?.threshold ?? config?.reveal?.threshold ?? DEFAULT_THRESHOLD,\n z: o.z ?? intent.reveal?.z ?? config?.reveal?.z ?? DEFAULT_Z,\n cooldown: o.cooldown ?? intent.reveal?.cooldown ?? config?.reveal?.cooldown ?? intent.halfLife,\n };\n}\n\nexport interface ResolvedLearning {\n /** null means learned counts never decay. */\n halfLife: number | null;\n gain: number;\n priorEpisodes: number;\n}\n\nexport function resolveLearning(config: EngineConfig): ResolvedLearning {\n return {\n halfLife: config.learning?.halfLife ?? null,\n gain: config.learning?.gain ?? DEFAULT_GAIN,\n priorEpisodes: config.learning?.priorEpisodes ?? DEFAULT_PRIOR_EPISODES,\n };\n}\n\nexport function expectTimestamp(value: unknown, path: string): number {\n return expectNumber(value, path);\n}\n\nexport function validateEvent(event: unknown): { name: string; at: number } {\n if (!isRecord(event)) typeError('event', 'must be an object like { name, at }');\n const name = expectName(event.name, 'event.name');\n const at = expectTimestamp(event.at, 'event.at');\n if (event.props !== undefined && !isRecord(event.props)) {\n typeError('event.props', 'must be a plain object when present');\n }\n return { name, at };\n}\n","import type { EpisodeIntentRecord, EpisodeState } from './types';\nimport { getOwn } from './util';\n\nexport function emptyEpisode(): EpisodeState {\n return { startedAt: null, lastEventAt: null, intents: {} };\n}\n\n/** If the episode has been idle longer than `timeout` by `at`, the moment it timed out; otherwise null. */\nexport function timedOutAt(\n episode: EpisodeState,\n timeout: number | undefined,\n at: number,\n): number | null {\n if (timeout === undefined || episode.lastEventAt === null) return null;\n return at - episode.lastEventAt > timeout ? episode.lastEventAt + timeout : null;\n}\n\n/** Opens the episode if needed and records activity at `at`. */\nexport function extendEpisode(episode: EpisodeState, at: number): EpisodeState {\n return {\n startedAt: episode.startedAt ?? at,\n lastEventAt: episode.lastEventAt === null ? at : Math.max(episode.lastEventAt, at),\n intents: episode.intents,\n };\n}\n\nexport function episodeRecord(episode: EpisodeState, intent: string): EpisodeIntentRecord {\n return getOwn(episode.intents, intent) ?? { seen: [], counts: {}, resolved: false };\n}\n\n/** How many times `signal` has occurred for `intent` in this episode (since its last outcome). */\nexport function occurrences(episode: EpisodeState, intent: string, signal: string): number {\n return getOwn(episodeRecord(episode, intent).counts, signal) ?? 0;\n}\n\n/** Remembers one more occurrence of `signal`: added to `seen` the first time, counted every time. */\nexport function markSeen(episode: EpisodeState, intent: string, signal: string): EpisodeState {\n const record = episodeRecord(episode, intent);\n const seen = record.seen.includes(signal) ? record.seen : [...record.seen, signal];\n const counts = { ...record.counts, [signal]: (getOwn(record.counts, signal) ?? 0) + 1 };\n return { ...episode, intents: { ...episode.intents, [intent]: { ...record, seen, counts } } };\n}\n\nexport function markResolved(episode: EpisodeState, intent: string): EpisodeState {\n return {\n ...episode,\n intents: { ...episode.intents, [intent]: { seen: [], counts: {}, resolved: true } },\n };\n}\n","/**\n * Version of the serialized state shape, stored in every state as `state.version`. Bumped only\n * when `EngineState` changes incompatibly, and every bump ships its migration: {@link deserialize}\n * upgrades states saved by earlier versions of this library on its own (version 1, written by\n * oracular 0.1.0 to 0.2.x, and version 2, written by 0.3.0 to 0.5.x, become version 3), reads a\n * state one version newer than its own as its own (a version bump only adds fields, so a rollback\n * by one release keeps the user's history), and calls your `migrate` function only for a version\n * it does not know.\n *\n * @example\n * ```ts\n * import { STATE_VERSION, deserialize } from 'oracular';\n *\n * const state = deserialize(saved, {\n * config,\n * // Only reached for versions this library cannot migrate itself, such as a state written by a\n * // newer oracular before a rollback.\n * migrate: (stored, version) => {\n * throw new Error(`cannot read oracular state version ${version} (this build reads ${STATE_VERSION})`);\n * },\n * });\n * ```\n */\nexport const STATE_VERSION = 3 as const;\n\n/**\n * Version of the recorder format: the `v` field of every record that {@link createRecord} and\n * {@link createEndRecord} produce. A new optional field does not change it; readers ignore fields\n * they do not know and skip records of a `kind` they do not know. Anything a reader written for\n * this version could misread bumps it.\n *\n * @example\n * ```ts\n * import { RECORD_VERSION } from 'oracular';\n *\n * const record = JSON.parse(line);\n * if (record.v !== RECORD_VERSION) throw new Error(`unsupported recorder format ${record.v}`);\n * ```\n */\nexport const RECORD_VERSION = 1 as const;\n","import { normalizeConfig } from './config';\nimport { emptyEpisode } from './episode';\nimport { initIntent } from './intent';\nimport type { EngineConfig, EngineState, IntentConfig, IntentState } from './types';\nimport { getOwn, isRecord } from './util';\nimport { STATE_VERSION } from './version';\n\n/**\n * Builds a fresh engine state from a config. Every intent starts at its prior and no episode is\n * open. The config is validated and a normalized copy is stored inside the state, so a persisted\n * state remembers the weights it was built with; pass your current config to {@link deserialize}\n * when loading.\n *\n * @param config - Intents with their priors and signals, plus engine-wide options. Validated\n * strictly: unknown keys, non-finite numbers and out-of-range values throw.\n * @returns A new, JSON-serializable state. `config` is not mutated.\n * @throws `TypeError` when a value has the wrong type or a key is not recognised.\n * @throws `RangeError` when a number is out of range, for example a `prior` outside (0, 1), a\n * signal weight of 0, or a weight, `priorStrength`, `learning.gain` or\n * `learning.priorEpisodes` beyond 1e6 (larger values could overflow the arithmetic).\n * @example\n * ```ts\n * const state = createState({\n * intents: {\n * upgrade: {\n * prior: 0.05,\n * priorStrength: 10,\n * halfLife: 7 * 24 * 60 * 60 * 1000,\n * signals: { 'pricing.viewed': 3, 'limit.hit': 2, 'plan.downgraded': -4 },\n * outcome: 'upgrade.completed',\n * },\n * },\n * });\n * ```\n */\nexport function createState(config: EngineConfig): EngineState {\n const normalized = normalizeConfig(config);\n const intents: Record<string, IntentState> = {};\n for (const [name, intent] of Object.entries(normalized.intents)) {\n intents[name] = initIntent(intent);\n }\n return { version: STATE_VERSION, config: normalized, intents, episode: emptyEpisode() };\n}\n\nexport function requireState(state: unknown): EngineState {\n if (\n !isRecord(state) ||\n state.version !== STATE_VERSION ||\n !isRecord(state.config) ||\n !isRecord(state.intents) ||\n !isRecord(state.episode)\n ) {\n throw new TypeError('oracular: state must be an EngineState from createState or deserialize');\n }\n return state as unknown as EngineState;\n}\n\nexport function requireIntentConfig(state: EngineState, name: string): IntentConfig {\n const intent = getOwn(state.config.intents, name);\n if (intent === undefined) {\n throw new RangeError(`oracular: unknown intent ${JSON.stringify(name)}`);\n }\n return intent;\n}\n\n/** The stored intent state, or a fresh prior if the intent was added to the config after the state was created. */\nexport function getIntentState(\n state: EngineState,\n name: string,\n intent: IntentConfig,\n): IntentState {\n return getOwn(state.intents, name) ?? initIntent(intent);\n}\n","import { settlePending } from './attribution';\nimport type { ResolvedLearning, ResolvedReveal } from './config';\nimport { decayIntent } from './intent';\nimport { signalWeights } from './learning';\nimport { betaMean, betaSd, clamp01 } from './math';\nimport { getIntentState } from './state';\nimport type {\n EngineState,\n ExplainOptions,\n IntentConfig,\n IntentState,\n Prediction,\n SignalExplanation,\n} from './types';\nimport { getOwn } from './util';\n\n/**\n * The intent brought up to `at` without storing anything: evidence decayed, waiting episodes whose\n * window has passed settled as misses, learned counts decayed.\n */\nexport function assessIntent(\n state: EngineState,\n name: string,\n intent: IntentConfig,\n learning: ResolvedLearning,\n at: number,\n): IntentState {\n const is = decayIntent(getIntentState(state, name, intent), intent, at);\n return settlePending(is, intent, learning, at);\n}\n\n/** The end of a cooldown that started at `since`, if it is still running at `at`. */\nfunction cooldownEnd(since: number | null, cooldown: number, at: number): number | null {\n if (since === null) return null;\n const end = since + cooldown;\n return at < end ? end : null;\n}\n\nexport function buildPrediction(\n is: IntentState,\n name: string,\n reveal: ResolvedReveal,\n at: number,\n): Prediction {\n const p = betaMean(is.alpha, is.beta);\n const sd = betaSd(is.alpha, is.beta);\n const revealEnd = cooldownEnd(is.lastRevealedAt, reveal.cooldown, at);\n const outcomeEnd = cooldownEnd(is.lastOutcomeAt, reveal.cooldown, at);\n const suppressedUntil =\n revealEnd === null\n ? outcomeEnd\n : outcomeEnd === null\n ? revealEnd\n : Math.max(revealEnd, outcomeEnd);\n return {\n intent: name,\n p,\n sd,\n lower: clamp01(p - reveal.z * sd),\n confidence: clamp01(1 - 2 * sd),\n evidence: is.alpha + is.beta,\n revealed: revealEnd !== null,\n revealedAt: is.lastRevealedAt,\n suppressedUntil,\n };\n}\n\nexport function decideReveal(prediction: Prediction, reveal: ResolvedReveal): boolean {\n return (\n prediction.suppressedUntil === null &&\n prediction.p >= reveal.threshold &&\n prediction.lower >= reveal.threshold\n );\n}\n\nexport function buildExplanation(\n is: IntentState,\n intent: IntentConfig,\n learning: ResolvedLearning,\n opts: ExplainOptions,\n): SignalExplanation[] {\n const p = betaMean(is.alpha, is.beta);\n const out: SignalExplanation[] = [];\n for (const signal of Object.keys(intent.signals)) {\n const c = getOwn(is.contributions, signal) ?? { alpha: 0, beta: 0 };\n const w = signalWeights(is, intent, learning, signal);\n const without = betaMean(is.alpha - c.alpha, is.beta - c.beta);\n out.push({\n signal,\n contribution: c.alpha - c.beta,\n impact: p - without,\n initialWeight: w.initial,\n learnedWeight: w.learned,\n effectiveWeight: w.effective,\n hits: w.hits,\n misses: w.misses,\n });\n }\n out.sort((a, b) => Math.abs(b.impact) - Math.abs(a.impact) || compare(a.signal, b.signal));\n const filtered = opts.nonZero ? out.filter((row) => row.contribution !== 0) : out;\n return opts.limit === undefined ? filtered : filtered.slice(0, opts.limit);\n}\n\nfunction compare(a: string, b: string): number {\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n}\n","import { assessIntent, buildExplanation, buildPrediction, decideReveal } from './assess';\nimport {\n expectName,\n expectTimestamp,\n resolveLearning,\n resolveReveal,\n splitEvaluateOptions,\n} from './config';\nimport { requireIntentConfig, requireState } from './state';\nimport type { EngineState, EvaluateOptions, Evaluation, Snapshot } from './types';\n\n/**\n * {@link predict}, {@link shouldReveal} and {@link explain} in one call, from a single decay\n * pass over the intent. The three results are identical to what the separate functions return\n * for the same inputs; this is the one to call on every event when you need all of them.\n * Read-only.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - The time to evaluate at.\n * @param opts - Reveal overrides (`threshold`, `z`, `cooldown`) and explain filters (`nonZero`,\n * `limit`) in one object.\n * @returns `prediction` (as `predict`), `reveal` (as `shouldReveal`) and `explanation` (as\n * `explain` with the same filters).\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state, `at` is not finite, or `opts` is\n * malformed.\n * @example\n * ```ts\n * const { prediction, reveal, explanation } = evaluate(state, 'upgrade', Date.now(), { limit: 3 });\n * if (reveal) showOffer(explanation[0]?.signal);\n * ```\n */\nexport function evaluate(\n state: EngineState,\n intent: string,\n at: number,\n opts?: EvaluateOptions,\n): Evaluation {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const t = expectTimestamp(at, 'at');\n const config = requireIntentConfig(s, name);\n const split = splitEvaluateOptions(opts, 'options');\n const reveal = resolveReveal(s.config, config, split.reveal, true);\n const learning = resolveLearning(s.config);\n const is = assessIntent(s, name, config, learning, t);\n const prediction = buildPrediction(is, name, reveal, t);\n return {\n prediction,\n reveal: decideReveal(prediction, reveal),\n explanation: buildExplanation(is, config, learning, split.explain),\n };\n}\n\n/**\n * {@link evaluate} for every declared intent at once, in config order: the whole engine's view at\n * one moment, as plain data. This is what to log, assert on, or hand to `renderInspector` from\n * `oracular/inspect` for a live panel. Read-only.\n *\n * @param state - The current state. Not mutated.\n * @param at - The time to evaluate at.\n * @param opts - Reveal overrides and explain filters, applied to every intent.\n * @returns `at` and one {@link IntentSnapshot} per intent.\n * @throws `TypeError` when `state` is not an engine state, `at` is not finite, or `opts` is\n * malformed.\n * @example\n * ```ts\n * for (const { intent, prediction, reveal } of inspect(state, Date.now()).intents) {\n * console.log(intent, prediction.p.toFixed(3), reveal ? 'reveal' : '');\n * }\n * ```\n */\nexport function inspect(state: EngineState, at: number, opts?: EvaluateOptions): Snapshot {\n const s = requireState(state);\n const intents = Object.keys(s.config.intents).map((intent) => ({\n intent,\n ...evaluate(s, intent, at, opts),\n }));\n return { at, intents };\n}\n","import { normalizeIntentConfig, resolveReveal } from './config';\nimport { priorCounts } from './intent';\nimport { betaMean, betaSd, clamp01 } from './math';\nimport type { IntentConfig, RevealOptions } from './types';\n\n/**\n * How much positive evidence an intent needs before {@link shouldReveal} first becomes true:\n * the smallest pseudo-count `w` such that Beta(α₀ + w, β₀) clears both `p ≥ threshold` and\n * `p − z·sd ≥ threshold`. Divide by a signal's weight and round up for the number of full-weight\n * occurrences that open the gate: distinct signals, or one occurrence per episode. Repeats within\n * one episode add less (n of them add `w × log2(1 + n)`, see {@link IntentConfig.saturate}).\n * Solved numerically to 1e-9.\n *\n * Cooldowns and decay are not part of the answer: this is the evidence needed at one instant.\n *\n * @param intent - One intent's config, validated as `createState` would.\n * @param opts - `threshold` and `z` overrides, resolved as call → intent → defaults (there is\n * no engine config here). `cooldown` is accepted and ignored.\n * @returns The pseudo-count sum; 0 when the prior alone already clears the gate; `Infinity`\n * when no finite amount of evidence can (threshold 1).\n * @throws `TypeError` or `RangeError` when `intent` or `opts` is invalid.\n * @example\n * ```ts\n * const needed = evidenceToReveal(config.intents.upgrade); // ≈ 15.1 for the quickstart config\n * Math.ceil(needed / 3); // 6 full-weight signals of weight 3\n * ```\n */\nexport function evidenceToReveal(intent: IntentConfig, opts?: RevealOptions): number {\n const config = normalizeIntentConfig(intent, 'intent');\n const { threshold, z } = resolveReveal(undefined, config, opts);\n const { alpha0, beta0 } = priorCounts(config);\n\n const open = (w: number): boolean => {\n const alpha = alpha0 + w;\n const p = betaMean(alpha, beta0);\n return p >= threshold && clamp01(p - z * betaSd(alpha, beta0)) >= threshold;\n };\n\n if (threshold >= 1) return Number.POSITIVE_INFINITY;\n if (open(0)) return 0;\n\n // Bracket the first crossing geometrically, then bisect. Both p and the lower bound keep\n // rising with evidence past the first crossing, so the first opening is the answer.\n let lo = 0;\n let hi = 1;\n while (!open(hi)) {\n lo = hi;\n hi *= 2;\n if (hi > 1e15) return Number.POSITIVE_INFINITY;\n }\n for (let i = 0; i < 200 && hi - lo > 1e-9; i++) {\n const mid = (lo + hi) / 2;\n if (open(mid)) hi = mid;\n else lo = mid;\n }\n return hi;\n}\n","import { assessIntent, buildExplanation } from './assess';\nimport { expectName, expectTimestamp, normalizeExplainOptions, resolveLearning } from './config';\nimport { requireIntentConfig, requireState } from './state';\nimport type { EngineState, ExplainOptions, SignalExplanation } from './types';\n\n/**\n * Why the intent's p is what it is at time `at`: one entry per declared signal, the ones that\n * matter most first. `contribution` is the signed pseudo-count the signal currently holds after\n * decay, `impact` is how much p would change if that contribution were removed, and the three\n * weights show what the developer said, what this user's history says, and what the next\n * occurrence will actually add. Read-only.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - The time to evaluate at; contributions and learned counts are decayed to it.\n * @param opts - Optional filters: `nonZero` keeps only signals that currently hold evidence,\n * `limit` caps the number of rows. Default: every declared signal.\n * @returns One {@link SignalExplanation} per declared signal, sorted by |impact| descending,\n * then by name, then filtered by `opts`. Empty for an intent that declares no signals.\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state, `at` is not finite, or `opts` is\n * malformed.\n * @example\n * ```ts\n * for (const row of explain(state, 'upgrade', Date.now(), { nonZero: true })) {\n * console.log(row.signal, row.impact.toFixed(2), row.effectiveWeight.toFixed(2));\n * }\n * ```\n */\nexport function explain(\n state: EngineState,\n intent: string,\n at: number,\n opts?: ExplainOptions,\n): SignalExplanation[] {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const t = expectTimestamp(at, 'at');\n const config = requireIntentConfig(s, name);\n const filters = opts === undefined ? {} : normalizeExplainOptions(opts, 'options');\n const learning = resolveLearning(s.config);\n return buildExplanation(assessIntent(s, name, config, learning, t), config, learning, filters);\n}\n","import { creditPending, deferEpisode, settlePending } from './attribution';\nimport { expectTimestamp, resolveLearning, validateEvent } from './config';\nimport {\n emptyEpisode,\n episodeRecord,\n extendEpisode,\n markResolved,\n markSeen,\n occurrences,\n timedOutAt,\n} from './episode';\nimport { applySignal, decayIntent, resetToPrior } from './intent';\nimport { recordEpisode, signalWeights } from './learning';\nimport { repeatFactor } from './math';\nimport { getIntentState, requireState } from './state';\nimport type { EngineState, IntentEvent, IntentState } from './types';\nimport { hasOwn } from './util';\n\n/**\n * Feeds one event to the engine.\n *\n * For every intent the event is a signal of: decay its evidence to `event.at`, then add the\n * signal's effective weight to α (positive) or β (negative) and remember the signal for this\n * episode. Repeats within an episode saturate: the n-th occurrence of a signal adds\n * `w × log2(1 + 1/n)`, counted since the episode started or the intent's outcome last arrived.\n * That is the default when `config.episodeTimeout` is set, and `IntentConfig.saturate` overrides\n * it either way; otherwise every occurrence adds all of `w`. For every intent the event is the\n * outcome of: give the remembered signals a hit, count the episode toward the base rate, credit\n * the closed episodes still waiting under `IntentConfig.attribution` by `2^(−age / halfLife)`\n * each, record `lastOutcomeAt`, and (by default) reset the evidence to the prior. Any event opens\n * or extends the current episode; an idle gap longer than `config.episodeTimeout` closes the\n * previous episode first.\n *\n * @param state - The current state. Not mutated.\n * @param event - `name` is matched against every intent's signals and outcome; `at` is the\n * event's timestamp, in the same unit as your durations; `props` are accepted and ignored,\n * and never stored.\n * @returns The next state. Intents the event does not touch keep their stored numbers; their\n * decay is applied when they are next read or updated.\n * @throws `TypeError` when `state` is not an engine state, or the event has no non-empty\n * `name`, no finite `at`, or a `props` that is not a plain object.\n * @example\n * ```ts\n * let state = createState(config);\n * state = observe(state, { name: 'pricing.viewed', at: Date.now() });\n * state = observe(state, { name: 'upgrade.completed', at: Date.now() }); // outcome\n * ```\n */\nexport function observe(state: EngineState, event: IntentEvent): EngineState {\n let s = requireState(state);\n const { name, at } = validateEvent(event);\n\n const closeAt = timedOutAt(s.episode, s.config.episodeTimeout, at);\n if (closeAt !== null) s = closeEpisode(s, closeAt);\n\n const learning = resolveLearning(s.config);\n const intents: Record<string, IntentState> = { ...s.intents };\n let episode = extendEpisode(s.episode, at);\n\n for (const [intentName, intent] of Object.entries(s.config.intents)) {\n const isSignal = hasOwn(intent.signals, name);\n const isOutcome = intent.outcome === name;\n if (!isSignal && !isOutcome) continue;\n\n let is = getIntentState(s, intentName, intent);\n is = decayIntent(is, intent, at);\n is = settlePending(is, intent, learning, at);\n\n if (isSignal) {\n const { effective } = signalWeights(is, intent, learning, name);\n const n = occurrences(episode, intentName, name) + 1;\n const saturate = intent.saturate ?? s.config.episodeTimeout !== undefined;\n const factor = saturate ? repeatFactor(n) : 1;\n is = applySignal(is, intent, name, effective * factor);\n // An event that is also the intent's outcome must not learn from itself.\n if (!isOutcome) episode = markSeen(episode, intentName, name);\n }\n\n if (isOutcome) {\n is = recordEpisode(is, episodeRecord(episode, intentName).seen, 1);\n is = creditPending(is, intent, at);\n episode = markResolved(episode, intentName);\n is = { ...is, lastOutcomeAt: at };\n if (intent.resetOnOutcome ?? true) is = resetToPrior(is, intent);\n }\n\n intents[intentName] = is;\n }\n\n return { ...s, intents, episode };\n}\n\n/**\n * Ends the current episode at `at`. Every intent whose outcome did not arrive gives a miss to\n * each signal seen this episode and counts the episode toward its base rate, or, with\n * `IntentConfig.attribution` set, holds the episode for the outcome instead. Call it when a\n * session ends: tab closed, app backgrounded, user signed out.\n *\n * @param state - The current state. Not mutated.\n * @param at - When the episode ended. If it had already timed out under\n * `config.episodeTimeout`, it is closed at the moment it timed out instead.\n * @returns The next state with no open episode, or the very same state object when no episode\n * was open.\n * @throws `TypeError` when `state` is not an engine state or `at` is not a finite number.\n * @example\n * ```ts\n * window.addEventListener('pagehide', () => {\n * state = endEpisode(state, Date.now());\n * localStorage.setItem('oracular', serialize(state));\n * });\n * ```\n */\nexport function endEpisode(state: EngineState, at: number): EngineState {\n const s = requireState(state);\n const t = expectTimestamp(at, 'at');\n if (s.episode.startedAt === null) return s;\n const closeAt = timedOutAt(s.episode, s.config.episodeTimeout, t);\n return closeEpisode(s, closeAt ?? t);\n}\n\nfunction closeEpisode(state: EngineState, at: number): EngineState {\n const learning = resolveLearning(state.config);\n const intents: Record<string, IntentState> = { ...state.intents };\n for (const [intentName, intent] of Object.entries(state.config.intents)) {\n const record = episodeRecord(state.episode, intentName);\n if (record.resolved) continue;\n let is = getIntentState(state, intentName, intent);\n is = settlePending(is, intent, learning, at);\n is =\n intent.attribution === undefined\n ? recordEpisode(is, record.seen, 0)\n : deferEpisode(is, record.seen, at);\n intents[intentName] = is;\n }\n return { ...state, intents, episode: emptyEpisode() };\n}\n\n/**\n * Whether an episode closed between two states: `prev` had an open episode and `next` either\n * has none or has a different one. Useful after `observe` or `endEpisode` to react to a\n * session ending, for example to persist, or to read the misses it produced as\n * `next.intents[x].episodes.misses - prev.intents[x].episodes.misses` (0 for an intent with\n * `attribution` set, whose verdict waits).\n *\n * @param prev - The state before the operation.\n * @param next - The state after it.\n * @returns True when `prev.episode.startedAt` is not null and differs from\n * `next.episode.startedAt`.\n * @throws `TypeError` when either argument is not an engine state.\n * @example\n * ```ts\n * const next = observe(state, event);\n * if (episodeClosed(state, next)) persist(next);\n * ```\n */\nexport function episodeClosed(prev: EngineState, next: EngineState): boolean {\n const a = requireState(prev);\n const b = requireState(next);\n return a.episode.startedAt !== null && b.episode.startedAt !== a.episode.startedAt;\n}\n","import { buildPrediction, decideReveal } from './assess';\nimport { expectName, expectTimestamp, resolveReveal } from './config';\nimport { decayIntent } from './intent';\nimport { getIntentState, requireIntentConfig, requireState } from './state';\nimport type { EngineState, Prediction, RevealOptions } from './types';\n\n/**\n * The intent's current estimate at time `at`: the Beta mean p, its standard deviation, the\n * lower confidence bound that {@link shouldReveal} tests, and the cooldown status. Read-only:\n * the stored state is decayed to `at` for the reading but not changed.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - The time to evaluate at, in the same unit as your durations.\n * @param opts - Overrides for `threshold`, `z` and `cooldown`, resolved as call → intent →\n * engine → defaults. `z` sets `lower`; `cooldown` sets `revealed` and `suppressedUntil`;\n * `threshold` only matters to {@link shouldReveal}.\n * @returns The prediction. `p`, `sd`, `lower` and `confidence` are in [0, 1]; `evidence` is\n * α + β.\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state, `at` is not finite, or `opts` is\n * malformed.\n * @example\n * ```ts\n * const { p, lower, suppressedUntil } = predict(state, 'upgrade', Date.now());\n * if (suppressedUntil !== null) scheduleNextCheck(suppressedUntil);\n * ```\n */\nexport function predict(\n state: EngineState,\n intent: string,\n at: number,\n opts?: RevealOptions,\n): Prediction {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const t = expectTimestamp(at, 'at');\n const config = requireIntentConfig(s, name);\n const reveal = resolveReveal(s.config, config, opts);\n const is = decayIntent(getIntentState(s, name, config), config, t);\n return buildPrediction(is, name, reveal, t);\n}\n\n/**\n * Whether to act on the intent now. True when p ≥ `threshold`, the lower confidence bound\n * p − z·sd also clears `threshold`, and no cooldown is running: neither the one started by\n * {@link markRevealed} nor the one started by the intent's outcome event.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - The time to evaluate at.\n * @param opts - Overrides for `threshold` (default 0.5), `z` (default 1.28, a one-sided 90%\n * bound) and `cooldown` (default: the intent's `halfLife`).\n * @returns True when the app should show, offer or reveal whatever this intent gates.\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state, `at` is not finite, or `opts` is\n * malformed.\n * @example\n * ```ts\n * if (shouldReveal(state, 'upgrade', Date.now())) {\n * showUpgradeOffer();\n * state = markRevealed(state, 'upgrade', Date.now());\n * }\n * ```\n */\nexport function shouldReveal(\n state: EngineState,\n intent: string,\n at: number,\n opts?: RevealOptions,\n): boolean {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const config = requireIntentConfig(s, name);\n const reveal = resolveReveal(s.config, config, opts);\n return decideReveal(predict(s, name, at, opts), reveal);\n}\n\n/**\n * Records that the app acted on the intent at `at`. Starts the reveal cooldown, during which\n * `predict().revealed` is true and {@link shouldReveal} is false, and increments\n * `revealCount`. Evidence and learned data are untouched.\n *\n * @param state - The current state. Not mutated.\n * @param intent - Name of an intent declared in the config.\n * @param at - When the reveal happened.\n * @returns The next state.\n * @throws `RangeError` when `intent` is not declared in the config.\n * @throws `TypeError` when `state` is not an engine state or `at` is not finite.\n * @example\n * ```ts\n * state = markRevealed(state, 'upgrade', Date.now());\n * predict(state, 'upgrade', Date.now()).revealed; // true until the cooldown ends\n * ```\n */\nexport function markRevealed(state: EngineState, intent: string, at: number): EngineState {\n const s = requireState(state);\n const name = expectName(intent, 'intent');\n const t = expectTimestamp(at, 'at');\n const config = requireIntentConfig(s, name);\n const is = getIntentState(s, name, config);\n return {\n ...s,\n intents: {\n ...s.intents,\n [name]: { ...is, lastRevealedAt: t, revealCount: is.revealCount + 1 },\n },\n };\n}\n","import { assessIntent, buildExplanation, buildPrediction, decideReveal } from './assess';\nimport {\n expectName,\n expectTimestamp,\n resolveLearning,\n resolveReveal,\n validateEvent,\n} from './config';\nimport { requireState } from './state';\nimport type {\n EndRecord,\n EngineState,\n EventRecord,\n IntentEvent,\n RecordedDecision,\n RecordMode,\n RecordOptions,\n} from './types';\nimport { isRecord } from './util';\nimport { RECORD_VERSION } from './version';\n\nconst RECORD_KEYS = ['installId', 'mode', 'top'];\nconst DEFAULT_TOP = 3;\n\nfunction normalizeRecordOptions(value: unknown): Required<RecordOptions> {\n if (!isRecord(value)) {\n throw new TypeError('oracular: options must be an object like { installId, mode }');\n }\n for (const key of Object.keys(value)) {\n if (!RECORD_KEYS.includes(key)) {\n throw new TypeError(\n `oracular: options.${key} is not a recognised option (expected one of: ${RECORD_KEYS.join(', ')})`,\n );\n }\n }\n const installId = expectName(value.installId, 'options.installId');\n const mode = value.mode;\n if (mode !== 'shadow' && mode !== 'live') {\n throw new TypeError('oracular: options.mode must be \"shadow\" or \"live\"');\n }\n let top = DEFAULT_TOP;\n if (value.top !== undefined) {\n if (typeof value.top !== 'number' || !Number.isFinite(value.top)) {\n throw new TypeError('oracular: options.top must be a finite number');\n }\n if (!Number.isInteger(value.top) || value.top < 0) {\n throw new RangeError('oracular: options.top must be a non-negative integer');\n }\n top = value.top;\n }\n return { installId, mode: mode as RecordMode, top };\n}\n\n/**\n * A recorder record for an event: the event itself and, for every intent, what the engine decides\n * right after it. Call it with the state `observe` returned for that event, then append\n * `JSON.stringify(record)` as one line of the log (NDJSON). The record holds the event's `name` and\n * `at`, never its `props`.\n *\n * Each decision is what {@link evaluate} reports at `event.at` with the state's own reveal\n * options: `p`, `lower`, `shouldReveal`, `suppressedUntil`, the signals with the largest impact,\n * and the effective weight of every signal. Pure: the install id comes from the app, never from\n * here. See the Shadow mode guide for the whole workflow.\n *\n * @param state - The state after `observe(state, event)`. Not mutated.\n * @param event - The event just observed. Only `name` and `at` are recorded.\n * @param opts - `installId` (generated and stored by the app), `mode` (`'shadow'` while\n * reveals are computed but not shown, `'live'` once they are), and `top` (default 3).\n * @returns A plain, JSON-serializable {@link EventRecord}.\n * @throws `TypeError` when `state` is not an engine state, the event is malformed, `opts` is\n * not an object, has an unknown key, an empty `installId` or a `mode` other than\n * `'shadow'` or `'live'`.\n * @throws `RangeError` when `opts.top` is negative or fractional.\n * @example\n * ```ts\n * const recording = { installId: localStorage.getItem('oracular.install')!, mode: 'shadow' } as const;\n *\n * const event = { name: 'pricing.viewed', at: Date.now() };\n * state = observe(state, event);\n * appendLine(JSON.stringify(createRecord(state, event, recording)));\n * ```\n */\nexport function createRecord(\n state: EngineState,\n event: IntentEvent,\n opts: RecordOptions,\n): EventRecord {\n const s = requireState(state);\n const { name, at } = validateEvent(event);\n const { installId, mode, top } = normalizeRecordOptions(opts);\n const learning = resolveLearning(s.config);\n const decisions: Record<string, RecordedDecision> = {};\n for (const [intentName, intent] of Object.entries(s.config.intents)) {\n const reveal = resolveReveal(s.config, intent, undefined);\n const is = assessIntent(s, intentName, intent, learning, at);\n const prediction = buildPrediction(is, intentName, reveal, at);\n const rows = buildExplanation(is, intent, learning, {});\n const weights: Record<string, number> = {};\n for (const signal of Object.keys(intent.signals)) {\n weights[signal] = (\n rows.find((row) => row.signal === signal) as { effectiveWeight: number }\n ).effectiveWeight;\n }\n decisions[intentName] = {\n p: prediction.p,\n lower: prediction.lower,\n shouldReveal: decideReveal(prediction, reveal),\n suppressedUntil: prediction.suppressedUntil,\n top: rows\n .filter((row) => row.contribution !== 0)\n .slice(0, top)\n .map((row) => ({ signal: row.signal, impact: row.impact })),\n weights,\n };\n }\n return { v: RECORD_VERSION, kind: 'event', installId, mode, event: { name, at }, decisions };\n}\n\n/**\n * A recorder record for the end of an episode. Write one whenever the app calls\n * {@link endEpisode}, with the same `at`, so that replay can end the episode at the same moment\n * and reproduce the misses it records. Episodes that close through `episodeTimeout` need none:\n * replay applies the timeout itself.\n *\n * @param at - The time passed to `endEpisode`.\n * @param opts - The same options as for {@link createRecord}; `top` is accepted and ignored.\n * @returns A plain, JSON-serializable {@link EndRecord}.\n * @throws `TypeError` when `at` is not a finite number or `opts` is malformed.\n * @throws `RangeError` when `opts.top` is negative or fractional.\n * @example\n * ```ts\n * const at = Date.now();\n * state = endEpisode(state, at);\n * appendLine(JSON.stringify(createEndRecord(at, recording)));\n * ```\n */\nexport function createEndRecord(at: number, opts: RecordOptions): EndRecord {\n const t = expectTimestamp(at, 'at');\n const { installId, mode } = normalizeRecordOptions(opts);\n return { v: RECORD_VERSION, kind: 'end', installId, mode, at: t };\n}\n","import { hasOwn, isRecord } from './util';\n\ntype Stored = Record<string, unknown>;\n\n/**\n * Migrations this library applies itself, keyed by the version they upgrade from. Each turns the\n * parsed JSON of one version into the shape of the next. Input that is malformed in ways a\n * migration does not need to look at is passed through untouched, so that parsing afterwards\n * rejects it with the same precise error it would give any other malformed state.\n */\nconst MIGRATIONS: Record<number, (stored: Stored) => Stored> = {\n 1: fromV1,\n 2: fromV2,\n};\n\n/** Whether `version` is one this library can bring up to date on its own. */\nexport function canMigrate(version: number): boolean {\n return hasOwn(MIGRATIONS, String(version));\n}\n\n/** Applies the built-in migrations, one version at a time, until none applies. */\nexport function migrateStored(stored: Stored): Stored {\n let current = stored;\n while (typeof current.version === 'number' && canMigrate(current.version)) {\n current = (MIGRATIONS[current.version] as (stored: Stored) => Stored)(current);\n }\n return current;\n}\n\n/**\n * Version 1 (oracular 0.1.0 to 0.2.x) → 2. Version 2 counts how often each signal occurred in the\n * open episode, so that repeats can saturate. A version 1 state only knows which signals were\n * seen, not how often, so each seen signal counts once: the lower bound. Nothing else changes, so\n * α, β and every learned count, and therefore every estimate, are exactly what they were.\n */\nfunction fromV1(stored: Stored): Stored {\n const episode = stored.episode;\n if (!isRecord(episode) || !isRecord(episode.intents)) return { ...stored, version: 2 };\n const intents: Stored = {};\n for (const key of Object.keys(episode.intents)) {\n if (key === '__proto__') continue;\n const record = episode.intents[key];\n if (isRecord(record) && Array.isArray(record.seen)) {\n const counts: Record<string, number> = {};\n for (const signal of record.seen) {\n if (typeof signal === 'string' && signal !== '__proto__') counts[signal] = 1;\n }\n intents[key] = { ...record, counts };\n } else {\n intents[key] = record;\n }\n }\n return { ...stored, version: 2, episode: { ...episode, intents } };\n}\n\n/**\n * Version 2 (oracular 0.3.0 to 0.5.x) → 3. Version 3 lets an intent hold closed episodes that wait\n * for the outcome under `IntentConfig.attribution`. A version 2 state holds none, so every intent\n * gets an empty list and nothing else changes: α, β and every learned count, and therefore every\n * estimate, are exactly what they were.\n */\nfunction fromV2(stored: Stored): Stored {\n if (!isRecord(stored.intents)) return { ...stored, version: 3 };\n const intents: Stored = {};\n for (const key of Object.keys(stored.intents)) {\n if (key === '__proto__') continue;\n const intent = stored.intents[key];\n intents[key] = isRecord(intent) ? { ...intent, pending: [] } : intent;\n }\n return { ...stored, version: 3, intents };\n}\n","import { MAX_PENDING } from './attribution';\nimport { normalizeConfig, resolveLearning } from './config';\nimport { initIntent, withContributions } from './intent';\nimport { signalWeights } from './learning';\nimport { canMigrate, migrateStored } from './migrate';\nimport { requireState } from './state';\nimport type {\n DeserializeOptions,\n EngineConfig,\n EngineState,\n EpisodeIntentRecord,\n EpisodeState,\n IntentState,\n PendingEpisode,\n SignalContribution,\n SignalRecord,\n} from './types';\nimport { getOwn, hasOwn, isRecord } from './util';\nimport { STATE_VERSION } from './version';\n\n/**\n * The state as a JSON string, for the host app to persist wherever it likes. The state is plain\n * data, so this is `JSON.stringify` after a shape check. The output never contains event props.\n *\n * @param state - The state to persist.\n * @returns A JSON string that {@link deserialize} restores losslessly.\n * @throws `TypeError` when `state` is not an engine state.\n * @example\n * ```ts\n * localStorage.setItem('oracular', serialize(state));\n * ```\n */\nexport function serialize(state: EngineState): string {\n return JSON.stringify(requireState(state));\n}\n\n/**\n * Restores a state saved with {@link serialize}.\n *\n * Always pass the app's current `config`: it is validated and replaces the stored snapshot,\n * intents and signals no longer declared are dropped (α and β are recomputed from the kept\n * contributions), and newly declared intents start at their prior. States saved by oracular\n * 0.1.0 to 0.5.x are upgraded to the current shape on their own, and a state one version newer\n * than {@link STATE_VERSION} (written by the next release, read after a rollback) is read as the\n * current one, ignoring the fields it adds; `migrate` is only for a version this library does\n * not know.\n *\n * @param json - A string produced by {@link serialize}.\n * @param opts - `config`: the app's current config. `migrate`: called as\n * `migrate(stored, version)` when the stored version is neither {@link STATE_VERSION} nor one\n * this library migrates itself; it must return a state of the current version.\n * @returns A validated state that satisfies the engine's invariants.\n * @throws `SyntaxError` when `json` is not valid JSON.\n * @throws `TypeError` when the stored data, the result of `migrate`, `opts` or `opts.config`\n * has the wrong shape.\n * @throws `RangeError` when the stored version is neither one this library reads (1 to one past\n * {@link STATE_VERSION}) nor handled by a given `migrate`, when `migrate` does not return the\n * current version, when a stored number is out of range, or\n * when stored numbers are finite but too large to compute with (a tampered or corrupted state\n * that would otherwise answer NaN).\n * @example\n * ```ts\n * const saved = localStorage.getItem('oracular');\n * let state = saved ? deserialize(saved, { config }) : createState(config);\n * ```\n */\nexport function deserialize(json: string, opts: DeserializeOptions = {}): EngineState {\n if (typeof json !== 'string') throw new TypeError('oracular: deserialize expects a JSON string');\n if (!isRecord(opts)) throw new TypeError('oracular: options must be a plain object');\n for (const key of Object.keys(opts)) {\n if (key !== 'config' && key !== 'migrate') {\n throw new TypeError(\n `oracular: options.${key} is not a recognised option (expected one of: config, migrate)`,\n );\n }\n }\n if (opts.migrate !== undefined && typeof opts.migrate !== 'function') {\n throw new TypeError('oracular: options.migrate must be a function');\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (error) {\n throw new SyntaxError(`oracular: stored state is not valid JSON (${(error as Error).message})`);\n }\n if (!isRecord(parsed) || typeof parsed.version !== 'number') {\n throw new TypeError('oracular: stored state has no numeric version field');\n }\n\n let stored: unknown = parsed;\n if (parsed.version !== STATE_VERSION) {\n if (canMigrate(parsed.version)) {\n stored = migrateStored(parsed);\n } else if (parsed.version === STATE_VERSION + 1) {\n // The next state version only adds fields (the stability policy), so this release reads it\n // as its own and ignores what it does not know: a rollback by one release keeps the user's\n // history, and only what the newer version added is lost.\n stored = { ...parsed, version: STATE_VERSION };\n } else if (opts.migrate === undefined) {\n throw new RangeError(\n `oracular: stored state is version ${parsed.version} but this library reads versions 1 to ${STATE_VERSION + 1}; pass a migrate function`,\n );\n } else {\n stored = opts.migrate(parsed, parsed.version);\n }\n }\n\n const raw = parseState(stored);\n const config = opts.config === undefined ? raw.config : normalizeConfig(opts.config);\n return requireComputable(reconcile(raw, config));\n}\n\n// ---- parsing: field types only; keys are reconciled against the config afterwards ----\n\nfunction typeError(path: string, message: string): never {\n throw new TypeError(`oracular: ${path} ${message}`);\n}\n\nfunction record(value: unknown, path: string): Record<string, unknown> {\n if (!isRecord(value)) typeError(path, 'must be a plain object');\n return value;\n}\n\nfunction finite(value: unknown, path: string): number {\n if (typeof value !== 'number' || !Number.isFinite(value))\n typeError(path, 'must be a finite number');\n return value;\n}\n\nfunction nonNegative(value: unknown, path: string): number {\n const n = finite(value, path);\n if (n < 0) throw new RangeError(`oracular: ${path} must be 0 or greater`);\n return n;\n}\n\nfunction nullOrFinite(value: unknown, path: string): number | null {\n return value === null ? null : finite(value, path);\n}\n\nfunction signalRecord(value: unknown, path: string): SignalRecord {\n const r = record(value, path);\n return {\n hits: nonNegative(r.hits, `${path}.hits`),\n misses: nonNegative(r.misses, `${path}.misses`),\n };\n}\n\nfunction contribution(value: unknown, path: string): SignalContribution {\n const r = record(value, path);\n return {\n alpha: nonNegative(r.alpha, `${path}.alpha`),\n beta: nonNegative(r.beta, `${path}.beta`),\n };\n}\n\nfunction mapOwn<T>(\n value: unknown,\n path: string,\n fn: (item: unknown, itemPath: string) => T,\n): Record<string, T> {\n const r = record(value, path);\n const out: Record<string, T> = {};\n for (const key of Object.keys(r)) {\n if (key === '__proto__') continue;\n out[key] = fn(r[key], `${path}[${JSON.stringify(key)}]`);\n }\n return out;\n}\n\nfunction pendingEpisodes(value: unknown, path: string): PendingEpisode[] {\n if (!Array.isArray(value)) typeError(path, 'must be an array');\n if (value.length > MAX_PENDING) {\n throw new RangeError(`oracular: ${path} must hold at most ${MAX_PENDING} episodes`);\n }\n return value.map((item, i) => {\n const r = record(item, `${path}[${i}]`);\n if (!Array.isArray(r.seen) || !r.seen.every((s) => typeof s === 'string')) {\n typeError(`${path}[${i}].seen`, 'must be an array of strings');\n }\n return { endedAt: finite(r.endedAt, `${path}[${i}].endedAt`), seen: r.seen as string[] };\n });\n}\n\nfunction intentState(value: unknown, path: string): IntentState {\n const r = record(value, path);\n const revealCount = finite(r.revealCount, `${path}.revealCount`);\n if (!Number.isInteger(revealCount) || revealCount < 0) {\n throw new RangeError(`oracular: ${path}.revealCount must be a non-negative integer`);\n }\n return {\n alpha: finite(r.alpha, `${path}.alpha`),\n beta: finite(r.beta, `${path}.beta`),\n updatedAt: nullOrFinite(r.updatedAt, `${path}.updatedAt`),\n contributions: mapOwn(r.contributions, `${path}.contributions`, contribution),\n learned: mapOwn(r.learned, `${path}.learned`, signalRecord),\n episodes: signalRecord(r.episodes, `${path}.episodes`),\n pending: pendingEpisodes(r.pending, `${path}.pending`),\n learnedAt: nullOrFinite(r.learnedAt, `${path}.learnedAt`),\n lastRevealedAt: nullOrFinite(r.lastRevealedAt, `${path}.lastRevealedAt`),\n lastOutcomeAt: nullOrFinite(r.lastOutcomeAt, `${path}.lastOutcomeAt`),\n revealCount,\n };\n}\n\nfunction occurrenceCount(value: unknown, path: string): number {\n const n = finite(value, path);\n if (!Number.isInteger(n) || n < 1) {\n throw new RangeError(`oracular: ${path} must be a positive integer`);\n }\n return n;\n}\n\nfunction episodeIntent(value: unknown, path: string): EpisodeIntentRecord {\n const r = record(value, path);\n if (!Array.isArray(r.seen) || !r.seen.every((s) => typeof s === 'string')) {\n typeError(`${path}.seen`, 'must be an array of strings');\n }\n const counts = mapOwn(r.counts, `${path}.counts`, occurrenceCount);\n if (typeof r.resolved !== 'boolean') typeError(`${path}.resolved`, 'must be a boolean');\n return { seen: r.seen as string[], counts, resolved: r.resolved };\n}\n\nfunction episodeState(value: unknown, path: string): EpisodeState {\n const r = record(value, path);\n return {\n startedAt: nullOrFinite(r.startedAt, `${path}.startedAt`),\n lastEventAt: nullOrFinite(r.lastEventAt, `${path}.lastEventAt`),\n intents: mapOwn(r.intents, `${path}.intents`, episodeIntent),\n };\n}\n\nfunction parseState(value: unknown): EngineState {\n const r = record(value, 'state');\n if (r.version !== STATE_VERSION) {\n throw new RangeError(`oracular: state.version must be ${STATE_VERSION} after migration`);\n }\n return {\n version: STATE_VERSION,\n config: normalizeConfig(r.config),\n intents: mapOwn(r.intents, 'state.intents', intentState),\n episode: episodeState(r.episode, 'state.episode'),\n };\n}\n\n// ---- computability: finite numbers that are still too large to compute with ----\n\n/**\n * Every stored number is checked to be finite, but finite is not enough: a contribution near\n * 1e308 makes α·β overflow, and learned counts near 1e308 make the contrast weighting overflow,\n * so the state would answer NaN. Such a state was tampered with or corrupted; reject it.\n */\nfunction requireComputable(state: EngineState): EngineState {\n const learning = resolveLearning(state.config);\n for (const [name, intent] of Object.entries(state.config.intents)) {\n const is = state.intents[name] as IntentState;\n const path = `state.intents[${JSON.stringify(name)}]`;\n if (!Number.isFinite(is.alpha + is.beta) || !Number.isFinite(is.alpha * is.beta)) {\n throw new RangeError(`oracular: ${path} holds more evidence than can be computed with`);\n }\n for (const signal of Object.keys(intent.signals)) {\n const w = signalWeights(is, intent, learning, signal);\n if (!Number.isFinite(w.learned) || !Number.isFinite(w.effective)) {\n throw new RangeError(\n `oracular: ${path} holds learned counts for ${JSON.stringify(signal)} too large to compute with`,\n );\n }\n }\n }\n return state;\n}\n\n// ---- reconciling: make the state agree with a config ----\n\nfunction keep<T>(source: Record<string, T>, declared: Record<string, unknown>): Record<string, T> {\n const out: Record<string, T> = {};\n for (const [key, value] of Object.entries(source)) {\n if (hasOwn(declared, key)) out[key] = value;\n }\n return out;\n}\n\n/** Waiting episodes with their seen lists pruned to declared signals, each once, in order of close. */\nfunction keepPending(\n pending: readonly PendingEpisode[],\n signals: Record<string, number>,\n): PendingEpisode[] {\n return pending\n .map((episode) => ({\n endedAt: episode.endedAt,\n seen: episode.seen.filter((s, i) => hasOwn(signals, s) && episode.seen.indexOf(s) === i),\n }))\n .sort((a, b) => a.endedAt - b.endedAt);\n}\n\n/**\n * Drops intents and signals the config no longer declares, starts newly declared intents at\n * their prior, and recomputes α and β as the (possibly new) prior plus the kept contributions.\n */\nfunction reconcile(raw: EngineState, config: EngineConfig): EngineState {\n const intents: Record<string, IntentState> = {};\n const episodeIntents: Record<string, EpisodeIntentRecord> = {};\n\n for (const [name, intent] of Object.entries(config.intents)) {\n const stored = getOwn(raw.intents, name);\n if (stored === undefined) {\n intents[name] = initIntent(intent);\n } else {\n intents[name] = withContributions(\n {\n ...stored,\n learned: keep(stored.learned, intent.signals),\n pending: keepPending(stored.pending, intent.signals),\n },\n intent,\n keep(stored.contributions, intent.signals),\n );\n }\n const episode = getOwn(raw.episode.intents, name);\n if (episode !== undefined && raw.episode.startedAt !== null) {\n const seen = episode.seen.filter(\n (s, i) => hasOwn(intent.signals, s) && episode.seen.indexOf(s) === i,\n );\n // One count per seen signal and no other: a seen signal without one counts once.\n const counts: Record<string, number> = {};\n for (const s of seen) counts[s] = getOwn(episode.counts, s) ?? 1;\n episodeIntents[name] = { seen, counts, resolved: episode.resolved };\n }\n }\n\n return {\n version: STATE_VERSION,\n config,\n intents,\n episode: {\n startedAt: raw.episode.startedAt,\n lastEventAt: raw.episode.startedAt === null ? null : raw.episode.lastEventAt,\n intents: episodeIntents,\n },\n };\n}\n","/** The units of {@link ms}: each takes a count and returns milliseconds. */\nexport interface Units {\n /** `n` seconds in milliseconds: `n × 1000`. */\n readonly seconds: (n: number) => number;\n /** `n` minutes in milliseconds: `n × 60 000`. */\n readonly minutes: (n: number) => number;\n /** `n` hours in milliseconds: `n × 3 600 000`. */\n readonly hours: (n: number) => number;\n /** `n` days in milliseconds: `n × 86 400 000`. */\n readonly days: (n: number) => number;\n /** `n` weeks in milliseconds: `n × 604 800 000`. */\n readonly weeks: (n: number) => number;\n}\n\n/**\n * Durations in milliseconds, the unit of `Date.now()`: `ms.days(7)` is `604800000`. Plain\n * multiplications and nothing else, for `halfLife`, `cooldown`, `episodeTimeout` and\n * `learning.halfLife` when your timestamps are in milliseconds. If your `at` is in another unit,\n * write durations in that unit instead: the engine only needs the two to agree.\n *\n * @example\n * ```ts\n * const config = {\n * episodeTimeout: ms.minutes(30),\n * intents: {\n * upgrade: {\n * prior: 0.05,\n * priorStrength: 10,\n * halfLife: ms.days(7),\n * signals: { 'pricing.viewed': 3 },\n * reveal: { cooldown: ms.weeks(2) },\n * },\n * },\n * };\n * ```\n */\nexport const ms: Units = {\n seconds: (n) => n * 1_000,\n minutes: (n) => n * 60_000,\n hours: (n) => n * 3_600_000,\n days: (n) => n * 86_400_000,\n weeks: (n) => n * 604_800_000,\n};\n","import { normalizeConfig } from './config';\nimport type { EngineConfig } from './types';\n\n/**\n * Checks a config exactly as {@link createState} and {@link deserialize} do, without building a\n * state, and returns the normalized copy they would store: only the recognised keys, in a fixed\n * order, with every `undefined` dropped, so it survives a JSON round trip unchanged. Use it to\n * fail fast at startup or in a test, or on a config loaded from a file, before the engine runs.\n *\n * @param config - The config to check. Typed `unknown` so parsed JSON can be passed as it is.\n * @returns A fresh, normalized {@link EngineConfig}. `config` is not mutated.\n * @throws `TypeError` when a value has the wrong type or a key is not recognised.\n * @throws `RangeError` when a number is out of range: a `prior` outside (0, 1), a signal weight of\n * 0, or a weight, `priorStrength`, `learning.gain` or `learning.priorEpisodes` beyond 1e6.\n * @example\n * ```ts\n * import { readFileSync } from 'node:fs';\n * import { validateConfig } from 'oracular';\n *\n * // Throws with the offending path in the message, e.g. config.intents[\"upgrade\"].prior\n * const config = validateConfig(JSON.parse(readFileSync('oracular.config.json', 'utf8')));\n * ```\n */\nexport function validateConfig(config: unknown): EngineConfig {\n return normalizeConfig(config);\n}\n"]}
|