systemoneprompts 0.1.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/LICENSE +21 -0
- package/README.md +214 -0
- package/dist/answers.d.ts +21 -0
- package/dist/answers.d.ts.map +1 -0
- package/dist/answers.js +104 -0
- package/dist/answers.js.map +1 -0
- package/dist/cli/cache.d.ts +2 -0
- package/dist/cli/cache.d.ts.map +1 -0
- package/dist/cli/cache.js +26 -0
- package/dist/cli/cache.js.map +1 -0
- package/dist/cli/check.d.ts +2 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +28 -0
- package/dist/cli/check.js.map +1 -0
- package/dist/cli/env.d.ts +2 -0
- package/dist/cli/env.d.ts.map +1 -0
- package/dist/cli/env.js +29 -0
- package/dist/cli/env.js.map +1 -0
- package/dist/cli/eval.d.ts +18 -0
- package/dist/cli/eval.d.ts.map +1 -0
- package/dist/cli/eval.js +314 -0
- package/dist/cli/eval.js.map +1 -0
- package/dist/cli/generate.d.ts +5 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +93 -0
- package/dist/cli/generate.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +76 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/io.d.ts +28 -0
- package/dist/cli/io.d.ts.map +1 -0
- package/dist/cli/io.js +88 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/cli/run.d.ts +7 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +63 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/client.d.ts +65 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +301 -0
- package/dist/client.js.map +1 -0
- package/dist/cloudflare.d.ts +29 -0
- package/dist/cloudflare.d.ts.map +1 -0
- package/dist/cloudflare.js +159 -0
- package/dist/cloudflare.js.map +1 -0
- package/dist/definition/check.d.ts +9 -0
- package/dist/definition/check.d.ts.map +1 -0
- package/dist/definition/check.js +26 -0
- package/dist/definition/check.js.map +1 -0
- package/dist/definition/diagnostics.d.ts +29 -0
- package/dist/definition/diagnostics.d.ts.map +1 -0
- package/dist/definition/diagnostics.js +74 -0
- package/dist/definition/diagnostics.js.map +1 -0
- package/dist/definition/locate.d.ts +23 -0
- package/dist/definition/locate.d.ts.map +1 -0
- package/dist/definition/locate.js +211 -0
- package/dist/definition/locate.js.map +1 -0
- package/dist/definition/parse.d.ts +15 -0
- package/dist/definition/parse.d.ts.map +1 -0
- package/dist/definition/parse.js +170 -0
- package/dist/definition/parse.js.map +1 -0
- package/dist/definition/schema.d.ts +39 -0
- package/dist/definition/schema.d.ts.map +1 -0
- package/dist/definition/schema.js +11 -0
- package/dist/definition/schema.js.map +1 -0
- package/dist/dev/cache.d.ts +58 -0
- package/dist/dev/cache.d.ts.map +1 -0
- package/dist/dev/cache.js +287 -0
- package/dist/dev/cache.js.map +1 -0
- package/dist/dev/index.d.ts +2 -0
- package/dist/dev/index.d.ts.map +1 -0
- package/dist/dev/index.js +3 -0
- package/dist/dev/index.js.map +1 -0
- package/dist/factors/evaluate.d.ts +21 -0
- package/dist/factors/evaluate.d.ts.map +1 -0
- package/dist/factors/evaluate.js +199 -0
- package/dist/factors/evaluate.js.map +1 -0
- package/dist/factors/graph.d.ts +7 -0
- package/dist/factors/graph.d.ts.map +1 -0
- package/dist/factors/graph.js +39 -0
- package/dist/factors/graph.js.map +1 -0
- package/dist/factors/schema.d.ts +54 -0
- package/dist/factors/schema.d.ts.map +1 -0
- package/dist/factors/schema.js +235 -0
- package/dist/factors/schema.js.map +1 -0
- package/dist/generate/generate.d.ts +16 -0
- package/dist/generate/generate.d.ts.map +1 -0
- package/dist/generate/generate.js +100 -0
- package/dist/generate/generate.js.map +1 -0
- package/dist/generate/types.d.ts +10 -0
- package/dist/generate/types.d.ts.map +1 -0
- package/dist/generate/types.js +126 -0
- package/dist/generate/types.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +6 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/json.js +52 -0
- package/dist/json.js.map +1 -0
- package/dist/model.d.ts +9 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +22 -0
- package/dist/model.js.map +1 -0
- package/dist/native.d.ts +97 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +2 -0
- package/dist/native.js.map +1 -0
- package/dist/patterns/index.d.ts +3 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +3 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/patterns/options.d.ts +2 -0
- package/dist/patterns/options.d.ts.map +1 -0
- package/dist/patterns/options.js +7 -0
- package/dist/patterns/options.js.map +1 -0
- package/dist/patterns/run-many.d.ts +41 -0
- package/dist/patterns/run-many.d.ts.map +1 -0
- package/dist/patterns/run-many.js +51 -0
- package/dist/patterns/run-many.js.map +1 -0
- package/dist/patterns/walk-taxonomy.d.ts +37 -0
- package/dist/patterns/walk-taxonomy.d.ts.map +1 -0
- package/dist/patterns/walk-taxonomy.js +81 -0
- package/dist/patterns/walk-taxonomy.js.map +1 -0
- package/dist/questions/references.d.ts +12 -0
- package/dist/questions/references.d.ts.map +1 -0
- package/dist/questions/references.js +76 -0
- package/dist/questions/references.js.map +1 -0
- package/dist/questions/schema.d.ts +18 -0
- package/dist/questions/schema.d.ts.map +1 -0
- package/dist/questions/schema.js +169 -0
- package/dist/questions/schema.js.map +1 -0
- package/dist/state/paths.d.ts +13 -0
- package/dist/state/paths.d.ts.map +1 -0
- package/dist/state/paths.js +70 -0
- package/dist/state/paths.js.map +1 -0
- package/dist/state/requirements.d.ts +25 -0
- package/dist/state/requirements.d.ts.map +1 -0
- package/dist/state/requirements.js +189 -0
- package/dist/state/requirements.js.map +1 -0
- package/docs/SPEC.html +57 -0
- package/docs/skills/systemoneprompts/SKILL.md +239 -0
- package/docs/skills/systemoneprompts/references/application-data.md +79 -0
- package/package.json +94 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { parse as parseToml, TomlError } from "smol-toml";
|
|
3
|
+
import { parseFactors } from "../factors/schema.js";
|
|
4
|
+
import { isJsonValue, isPlainObject } from "../json.js";
|
|
5
|
+
import { validateQuestions } from "../questions/schema.js";
|
|
6
|
+
import { parseRequirements } from "../state/requirements.js";
|
|
7
|
+
import { diagnostic, nearestMatch, SystemOnePromptsError } from "./diagnostics.js";
|
|
8
|
+
import { indexSource, locate } from "./locate.js";
|
|
9
|
+
import { KNOWN_TOP_LEVEL, } from "./schema.js";
|
|
10
|
+
const META_KEYS = ["title", "version", "description"];
|
|
11
|
+
const KNOWN_TABLES = ["requires", "questions", "factors", "data"];
|
|
12
|
+
/**
|
|
13
|
+
* Parse a TOML definition into native TypeSafe objects.
|
|
14
|
+
*
|
|
15
|
+
* Throws `SystemOnePromptsError` only when the TOML itself is invalid. Structural problems
|
|
16
|
+
* (bad field types, malformed questions, unknown factor fields) are collected in
|
|
17
|
+
* `definition.diagnostics`; the offending entries are omitted from the result.
|
|
18
|
+
* Run `checkDefinition` for cross-cutting checks (references, cycles, lint).
|
|
19
|
+
*/
|
|
20
|
+
export function parseDefinition(source, opts = {}) {
|
|
21
|
+
const filename = opts.filename;
|
|
22
|
+
let raw;
|
|
23
|
+
try {
|
|
24
|
+
raw = parseToml(source);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
throw wrapTomlError(error, filename);
|
|
28
|
+
}
|
|
29
|
+
if (!isPlainObject(raw)) {
|
|
30
|
+
throw new SystemOnePromptsError(diagnostic("error", "toml-root", "definition must be a TOML table", { filename, line: 1 }));
|
|
31
|
+
}
|
|
32
|
+
const index = indexSource(source, filename);
|
|
33
|
+
const diagnostics = [];
|
|
34
|
+
const meta = Object.create(null);
|
|
35
|
+
const parsedData = parseData(raw.data, index);
|
|
36
|
+
diagnostics.push(...parsedData.diagnostics);
|
|
37
|
+
for (const key of META_KEYS) {
|
|
38
|
+
const value = raw[key];
|
|
39
|
+
if (value === undefined)
|
|
40
|
+
continue;
|
|
41
|
+
if (typeof value === "string")
|
|
42
|
+
meta[key] = value;
|
|
43
|
+
else {
|
|
44
|
+
diagnostics.push(diagnostic("error", "meta-string", `\`${key}\` must be a string`, locate(index, { key })));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
let model;
|
|
48
|
+
if (raw.model !== undefined) {
|
|
49
|
+
if (typeof raw.model === "string" && raw.model.trim() !== "")
|
|
50
|
+
model = raw.model.trim();
|
|
51
|
+
else {
|
|
52
|
+
diagnostics.push(diagnostic("error", "model-string", "`model` must be a non-empty string", locate(index, { key: "model" })));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
56
|
+
if (KNOWN_TOP_LEVEL.includes(key))
|
|
57
|
+
continue;
|
|
58
|
+
if (isPlainObject(value) || Array.isArray(value)) {
|
|
59
|
+
const suggestion = nearestMatch(key, KNOWN_TABLES);
|
|
60
|
+
diagnostics.push(diagnostic("warning", "unknown-table", `unknown top-level table [${key}]`, locate(index, { table: key, key }), suggestion ? `did you mean [${suggestion}]?` : undefined));
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
64
|
+
meta[key] = value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const requires = parseRequirements(raw.requires, index);
|
|
68
|
+
diagnostics.push(...requires.diagnostics);
|
|
69
|
+
const questions = validateQuestions(raw.questions, index);
|
|
70
|
+
diagnostics.push(...questions.diagnostics);
|
|
71
|
+
const factors = parseFactors(raw.factors, new Set(Object.keys(questions.questions)), index);
|
|
72
|
+
diagnostics.push(...factors.diagnostics);
|
|
73
|
+
return {
|
|
74
|
+
meta,
|
|
75
|
+
model,
|
|
76
|
+
requires: requires.requires,
|
|
77
|
+
questions: questions.questions,
|
|
78
|
+
factors: factors.factors,
|
|
79
|
+
factorDefinitions: factors.factorDefinitions,
|
|
80
|
+
data: parsedData.data,
|
|
81
|
+
diagnostics,
|
|
82
|
+
source: { filename, text: source, index },
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
export async function loadDefinition(path) {
|
|
86
|
+
const text = await readFile(path, "utf8");
|
|
87
|
+
return parseDefinition(text, { filename: path });
|
|
88
|
+
}
|
|
89
|
+
function wrapTomlError(error, filename) {
|
|
90
|
+
if (error instanceof TomlError) {
|
|
91
|
+
const line = "line" in error && typeof error.line === "number" ? error.line : undefined;
|
|
92
|
+
const column = "column" in error && typeof error.column === "number" ? error.column : undefined;
|
|
93
|
+
return new SystemOnePromptsError(diagnostic("error", "toml-syntax", error.message, { filename, line, column }));
|
|
94
|
+
}
|
|
95
|
+
const message = error instanceof Error ? error.message : "failed to parse TOML";
|
|
96
|
+
return new SystemOnePromptsError(diagnostic("error", "toml-syntax", message, { filename }));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Parse the application-owned data namespace. The root is deliberately a
|
|
100
|
+
* table, while all descendants are only constrained by the JSON value rules.
|
|
101
|
+
* Invalid trees are discarded as a unit so callers cannot accidentally use a
|
|
102
|
+
* partially valid application configuration.
|
|
103
|
+
*/
|
|
104
|
+
function parseData(raw, index) {
|
|
105
|
+
const empty = () => Object.create(null);
|
|
106
|
+
if (raw === undefined)
|
|
107
|
+
return { data: empty(), diagnostics: [] };
|
|
108
|
+
if (!isPlainObject(raw)) {
|
|
109
|
+
return {
|
|
110
|
+
data: empty(),
|
|
111
|
+
diagnostics: [
|
|
112
|
+
diagnostic("error", "data-type", "`data` must be a TOML table", locate(index, { table: "data", key: "data" })),
|
|
113
|
+
],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (isJsonValue(raw))
|
|
117
|
+
return { data: raw, diagnostics: [] };
|
|
118
|
+
const invalid = findInvalidJson(raw, ["data"]);
|
|
119
|
+
const path = invalid?.path ?? ["data"];
|
|
120
|
+
return {
|
|
121
|
+
data: empty(),
|
|
122
|
+
diagnostics: [
|
|
123
|
+
diagnostic("error", "data-json", `\`data\` contains a non-JSON-compatible value at ${formatDataPath(path)}`, locateDataPath(index, path)),
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function findInvalidJson(value, path) {
|
|
128
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
129
|
+
return undefined;
|
|
130
|
+
if (typeof value === "number")
|
|
131
|
+
return Number.isFinite(value) ? undefined : { path };
|
|
132
|
+
if (Array.isArray(value)) {
|
|
133
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
134
|
+
if (!(index in value))
|
|
135
|
+
return { path: [...path, `[${index}]`] };
|
|
136
|
+
const invalid = findInvalidJson(value[index], [...path, `[${index}]`]);
|
|
137
|
+
if (invalid)
|
|
138
|
+
return invalid;
|
|
139
|
+
}
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
if (!isPlainObject(value))
|
|
143
|
+
return { path };
|
|
144
|
+
for (const [key, child] of Object.entries(value)) {
|
|
145
|
+
const invalid = findInvalidJson(child, [...path, key]);
|
|
146
|
+
if (invalid)
|
|
147
|
+
return invalid;
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
function locateDataPath(index, path) {
|
|
152
|
+
const serialized = JSON.stringify(path);
|
|
153
|
+
const location = index.keyPaths?.get(serialized) ?? index.tablePaths?.get(serialized);
|
|
154
|
+
return location ?? locate(index, { table: "data", key: "data" });
|
|
155
|
+
}
|
|
156
|
+
function formatDataPath(path) {
|
|
157
|
+
let result = "";
|
|
158
|
+
for (const segment of path) {
|
|
159
|
+
if (segment.startsWith("["))
|
|
160
|
+
result += segment;
|
|
161
|
+
else if (result === "")
|
|
162
|
+
result = segment;
|
|
163
|
+
else if (/^[A-Za-z0-9_-]+$/.test(segment))
|
|
164
|
+
result += `.${segment}`;
|
|
165
|
+
else
|
|
166
|
+
result += `[${JSON.stringify(segment)}]`;
|
|
167
|
+
}
|
|
168
|
+
return `\`${result}\``;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/definition/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { FactorDef, FactorTable } from "../factors/schema.js";
|
|
2
|
+
import type { JsonValue, Questions } from "../native.js";
|
|
3
|
+
import type { Requirements } from "../state/requirements.js";
|
|
4
|
+
import type { Diagnostic } from "./diagnostics.js";
|
|
5
|
+
import type { SourceIndex } from "./locate.js";
|
|
6
|
+
export declare const KNOWN_TOP_LEVEL: readonly ["title", "version", "description", "model", "requires", "questions", "factors", "data"];
|
|
7
|
+
/** Verbatim `[factors]` tables, keyed by factor id — the input to `createFactorEvaluator`. */
|
|
8
|
+
export type FactorDefinitions = Record<string, FactorTable>;
|
|
9
|
+
/** Application-owned JSON-compatible data from the optional `[data]` table. */
|
|
10
|
+
export type DefinitionData = Record<string, JsonValue>;
|
|
11
|
+
export interface DefinitionMeta {
|
|
12
|
+
title?: string;
|
|
13
|
+
version?: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
[key: string]: string | number | boolean | undefined;
|
|
16
|
+
}
|
|
17
|
+
export interface DefinitionSource {
|
|
18
|
+
filename?: string;
|
|
19
|
+
text: string;
|
|
20
|
+
index: SourceIndex;
|
|
21
|
+
}
|
|
22
|
+
export interface Definition {
|
|
23
|
+
meta: DefinitionMeta;
|
|
24
|
+
/** TOML `model` pin; `undefined` lets the JEV default (or `TYPESAFE_DEFAULT_MODEL`) apply. */
|
|
25
|
+
model?: string;
|
|
26
|
+
requires: Requirements;
|
|
27
|
+
/** Native TypeSafe/JEV question objects. */
|
|
28
|
+
questions: Questions;
|
|
29
|
+
/** Parsed factor definitions, normalised into operator / predicate nodes. */
|
|
30
|
+
factors: Record<string, FactorDef>;
|
|
31
|
+
/** Verbatim factor tables; pass to `createFactorEvaluator`. */
|
|
32
|
+
factorDefinitions: FactorDefinitions;
|
|
33
|
+
/** Application-owned JSON-compatible data; systemoneprompts does not interpret it. */
|
|
34
|
+
data: DefinitionData;
|
|
35
|
+
/** Structural problems found while parsing (bad types, unknown fields, malformed questions). */
|
|
36
|
+
diagnostics: Diagnostic[];
|
|
37
|
+
source: DefinitionSource;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/definition/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAO,MAAM,eAAe,mGASlB,CAAC;AAEX,8FAA8F;AAC9F,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAE5D,+EAA+E;AAC/E,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACtD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,8FAA8F;IAC9F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,4CAA4C;IAC5C,SAAS,EAAE,SAAS,CAAC;IACrB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,+DAA+D;IAC/D,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,sFAAsF;IACtF,IAAI,EAAE,cAAc,CAAC;IACrB,gGAAgG;IAChG,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,MAAM,EAAE,gBAAgB,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/definition/schema.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,OAAO;IACP,SAAS;IACT,aAAa;IACb,OAAO;IACP,UAAU;IACV,WAAW;IACX,SAAS;IACT,MAAM;CACE,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { TypeSafeClientError } from "../client.js";
|
|
2
|
+
import type { Fetch } from "../native.js";
|
|
3
|
+
export type CacheMode = "read-write" | "read-only" | "refresh";
|
|
4
|
+
export interface CachingFetchOptions {
|
|
5
|
+
dir?: string;
|
|
6
|
+
mode?: CacheMode;
|
|
7
|
+
fetch?: Fetch;
|
|
8
|
+
}
|
|
9
|
+
/** Cumulative counts since the fetch was created; `keys` are the question ids of the last request. */
|
|
10
|
+
export interface CacheStats {
|
|
11
|
+
requests: number;
|
|
12
|
+
hits: number;
|
|
13
|
+
misses: number;
|
|
14
|
+
keys: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface CachedEntry {
|
|
17
|
+
hash: string;
|
|
18
|
+
requestedModel?: string;
|
|
19
|
+
reportedModel: string;
|
|
20
|
+
answer: unknown;
|
|
21
|
+
}
|
|
22
|
+
export interface CachingFetch extends Fetch {
|
|
23
|
+
stats(): CacheStats;
|
|
24
|
+
readonly dir: string;
|
|
25
|
+
}
|
|
26
|
+
/** Read-only miss. A `TypeSafeClientError` so `TypeSafeClient` surfaces it without retrying. */
|
|
27
|
+
export declare class CacheMissError extends TypeSafeClientError {
|
|
28
|
+
readonly ids: string[];
|
|
29
|
+
constructor(ids: string[]);
|
|
30
|
+
}
|
|
31
|
+
export declare function defaultCacheDir(cwd?: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* A `fetch` for `new TypeSafeClient({ fetch })` that caches System One answers per
|
|
34
|
+
* `(model, id, state, question)`. `id` is required so two questions with identical
|
|
35
|
+
* bodies cannot share an entry. `state` is the request state as sent; callers that
|
|
36
|
+
* need inspect-isolation send separate requests. A request is split into cached hits
|
|
37
|
+
* and a smaller live request for the misses; the merged response reports only the
|
|
38
|
+
* tokens actually spent. Non-System-One traffic passes through.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createCachingFetch(opts?: CachingFetchOptions): CachingFetch;
|
|
41
|
+
/** Cache key: sha256 of the canonical JSON of `{ model, id, state, question }`. */
|
|
42
|
+
export declare function questionHash(parts: {
|
|
43
|
+
model?: string;
|
|
44
|
+
id?: string;
|
|
45
|
+
state: unknown;
|
|
46
|
+
question: unknown;
|
|
47
|
+
}): string;
|
|
48
|
+
export declare function cacheStats(dir?: string): Promise<{
|
|
49
|
+
entries: number;
|
|
50
|
+
models: Record<string, number>;
|
|
51
|
+
drift: Array<{
|
|
52
|
+
requested?: string;
|
|
53
|
+
reported: string;
|
|
54
|
+
count: number;
|
|
55
|
+
}>;
|
|
56
|
+
}>;
|
|
57
|
+
export declare function clearCache(dir?: string): Promise<void>;
|
|
58
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/dev/cache.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,sGAAsG;AACtG,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,YAAa,SAAQ,KAAK;IACzC,KAAK,IAAI,UAAU,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,gGAAgG;AAChG,qBAAa,cAAe,SAAQ,mBAAmB;IACrD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC;gBAEX,GAAG,EAAE,MAAM,EAAE;CAK1B;AAID,wBAAgB,eAAe,CAAC,GAAG,SAAgB,GAAG,MAAM,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,GAAE,mBAAwB,GAAG,YAAY,CA2I/E;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB,GAAG,MAAM,CAQT;AAED,wBAAsB,UAAU,CAAC,GAAG,SAAoB,GAAG,OAAO,CAAC;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE,CAAC,CAkBD;AAED,wBAAsB,UAAU,CAAC,GAAG,SAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvE"}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, readdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, join } from "node:path";
|
|
4
|
+
import { isAnswerForQuestion, isAnswerShape } from "../answers.js";
|
|
5
|
+
import { TypeSafeClientError } from "../client.js";
|
|
6
|
+
import { canonicalJson, isPlainObject } from "../json.js";
|
|
7
|
+
/** Read-only miss. A `TypeSafeClientError` so `TypeSafeClient` surfaces it without retrying. */
|
|
8
|
+
export class CacheMissError extends TypeSafeClientError {
|
|
9
|
+
ids;
|
|
10
|
+
constructor(ids) {
|
|
11
|
+
super(`cache miss in read-only mode: ${ids.map((id) => `\`${id}\``).join(", ")}`);
|
|
12
|
+
this.name = "CacheMissError";
|
|
13
|
+
this.ids = ids;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const SYSTEMONE_PATH = "/v1/systemone";
|
|
17
|
+
export function defaultCacheDir(cwd = process.cwd()) {
|
|
18
|
+
return join(cwd, ".systemoneprompts", "cache");
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A `fetch` for `new TypeSafeClient({ fetch })` that caches System One answers per
|
|
22
|
+
* `(model, id, state, question)`. `id` is required so two questions with identical
|
|
23
|
+
* bodies cannot share an entry. `state` is the request state as sent; callers that
|
|
24
|
+
* need inspect-isolation send separate requests. A request is split into cached hits
|
|
25
|
+
* and a smaller live request for the misses; the merged response reports only the
|
|
26
|
+
* tokens actually spent. Non-System-One traffic passes through.
|
|
27
|
+
*/
|
|
28
|
+
export function createCachingFetch(opts = {}) {
|
|
29
|
+
const dir = opts.dir ?? defaultCacheDir();
|
|
30
|
+
const mode = opts.mode ?? "read-write";
|
|
31
|
+
const baseFetch = opts.fetch ?? globalThis.fetch;
|
|
32
|
+
const stats = { requests: 0, hits: 0, misses: 0, keys: [] };
|
|
33
|
+
const cachingFetch = (async (input, init) => {
|
|
34
|
+
if (!isSystemOneRequest(input, init) || typeof init?.body !== "string") {
|
|
35
|
+
return baseFetch(input, init);
|
|
36
|
+
}
|
|
37
|
+
let payload;
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(init.body);
|
|
40
|
+
if (!isPlainObject(parsed))
|
|
41
|
+
return baseFetch(input, init);
|
|
42
|
+
payload = parsed;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return baseFetch(input, init);
|
|
46
|
+
}
|
|
47
|
+
if (!isPlainObject(payload.questions)) {
|
|
48
|
+
return baseFetch(input, init);
|
|
49
|
+
}
|
|
50
|
+
const model = typeof payload.model === "string" ? payload.model : undefined;
|
|
51
|
+
const state = payload.state;
|
|
52
|
+
const questions = payload.questions;
|
|
53
|
+
const ids = Object.keys(questions);
|
|
54
|
+
const hits = dictionary();
|
|
55
|
+
const misses = dictionary();
|
|
56
|
+
for (const id of ids) {
|
|
57
|
+
const question = questions[id];
|
|
58
|
+
const hash = questionHash({ model, id, state, question });
|
|
59
|
+
if (mode === "refresh") {
|
|
60
|
+
misses[id] = question;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const cached = await readEntry(dir, hash, question);
|
|
64
|
+
if (cached) {
|
|
65
|
+
hits[id] = cached;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
misses[id] = question;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const missIds = Object.keys(misses);
|
|
72
|
+
stats.requests += 1;
|
|
73
|
+
stats.hits += ids.length - missIds.length;
|
|
74
|
+
stats.misses += missIds.length;
|
|
75
|
+
stats.keys = ids;
|
|
76
|
+
if (missIds.length === 0) {
|
|
77
|
+
return jsonResponse({
|
|
78
|
+
model: firstReportedModel(hits) ?? model ?? "jev-latest",
|
|
79
|
+
answers: Object.fromEntries(ids.map((id) => [id, hits[id].answer])),
|
|
80
|
+
usage: { input_tokens: 0, output_tokens: 0 },
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (mode === "read-only") {
|
|
84
|
+
throw new CacheMissError(missIds);
|
|
85
|
+
}
|
|
86
|
+
const response = await baseFetch(input, {
|
|
87
|
+
...init,
|
|
88
|
+
headers: withoutContentLength(init.headers),
|
|
89
|
+
body: JSON.stringify({ ...payload, questions: misses }),
|
|
90
|
+
});
|
|
91
|
+
// Hand errors back untouched so TypeSafeClient sees the real status, headers, and body.
|
|
92
|
+
if (!response.ok)
|
|
93
|
+
return response;
|
|
94
|
+
let result;
|
|
95
|
+
let answers;
|
|
96
|
+
try {
|
|
97
|
+
const parsed = await response.clone().json();
|
|
98
|
+
if (isPlainObject(parsed)) {
|
|
99
|
+
result = parsed;
|
|
100
|
+
if (isPlainObject(parsed.answers))
|
|
101
|
+
answers = parsed.answers;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// A cached hit still makes it possible to return a useful merged response.
|
|
106
|
+
}
|
|
107
|
+
const validLiveAnswers = dictionary();
|
|
108
|
+
if (answers) {
|
|
109
|
+
for (const id of missIds) {
|
|
110
|
+
if (Object.hasOwn(answers, id) && isAnswerForQuestion(misses[id], answers[id])) {
|
|
111
|
+
validLiveAnswers[id] = answers[id];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const allMissesValid = missIds.every((id) => Object.hasOwn(validLiveAnswers, id));
|
|
116
|
+
const hitIds = Object.keys(hits);
|
|
117
|
+
if (!allMissesValid && hitIds.length === 0)
|
|
118
|
+
return response;
|
|
119
|
+
const reportedModel = (result && typeof result.model === "string" ? result.model : undefined) ??
|
|
120
|
+
firstReportedModel(hits) ??
|
|
121
|
+
model ??
|
|
122
|
+
"jev-latest";
|
|
123
|
+
for (const id of Object.keys(validLiveAnswers)) {
|
|
124
|
+
const hash = questionHash({ model, id, state, question: misses[id] });
|
|
125
|
+
const entry = {
|
|
126
|
+
hash,
|
|
127
|
+
requestedModel: model,
|
|
128
|
+
reportedModel,
|
|
129
|
+
answer: validLiveAnswers[id],
|
|
130
|
+
};
|
|
131
|
+
await writeEntry(dir, hash, entry);
|
|
132
|
+
hits[id] = entry;
|
|
133
|
+
}
|
|
134
|
+
const usage = result && isPlainObject(result.usage) ? result.usage : { input_tokens: 0, output_tokens: 0 };
|
|
135
|
+
const mergedAnswers = dictionary();
|
|
136
|
+
for (const id of ids) {
|
|
137
|
+
if (hits[id])
|
|
138
|
+
mergedAnswers[id] = hits[id].answer;
|
|
139
|
+
else if (Object.hasOwn(validLiveAnswers, id))
|
|
140
|
+
mergedAnswers[id] = validLiveAnswers[id];
|
|
141
|
+
}
|
|
142
|
+
return jsonResponse({
|
|
143
|
+
model: reportedModel,
|
|
144
|
+
answers: mergedAnswers,
|
|
145
|
+
usage,
|
|
146
|
+
}, response.status, response.statusText, response.headers);
|
|
147
|
+
});
|
|
148
|
+
cachingFetch.stats = () => ({ ...stats, keys: [...stats.keys] });
|
|
149
|
+
Object.defineProperty(cachingFetch, "dir", { value: dir });
|
|
150
|
+
if (baseFetch.systemonepromptsCloudflare === true) {
|
|
151
|
+
cachingFetch.systemonepromptsCloudflare = true;
|
|
152
|
+
}
|
|
153
|
+
return cachingFetch;
|
|
154
|
+
}
|
|
155
|
+
/** Cache key: sha256 of the canonical JSON of `{ model, id, state, question }`. */
|
|
156
|
+
export function questionHash(parts) {
|
|
157
|
+
const payload = {};
|
|
158
|
+
for (const [key, value] of Object.entries(parts)) {
|
|
159
|
+
if (key === "model" && value == null)
|
|
160
|
+
continue;
|
|
161
|
+
if (key === "id" && value == null)
|
|
162
|
+
continue;
|
|
163
|
+
payload[key] = value;
|
|
164
|
+
}
|
|
165
|
+
return createHash("sha256").update(canonicalJson(payload)).digest("hex");
|
|
166
|
+
}
|
|
167
|
+
export async function cacheStats(dir = defaultCacheDir()) {
|
|
168
|
+
const files = await listEntries(dir);
|
|
169
|
+
const models = dictionary();
|
|
170
|
+
const driftMap = new Map();
|
|
171
|
+
let entries = 0;
|
|
172
|
+
for (const file of files) {
|
|
173
|
+
const hash = basename(file, ".json");
|
|
174
|
+
const raw = await readEntryFile(file, hash);
|
|
175
|
+
if (!raw)
|
|
176
|
+
continue;
|
|
177
|
+
entries += 1;
|
|
178
|
+
const reported = raw.reportedModel;
|
|
179
|
+
models[reported] = (models[reported] ?? 0) + 1;
|
|
180
|
+
const key = JSON.stringify([raw.requestedModel ?? null, reported]);
|
|
181
|
+
const existing = driftMap.get(key) ?? { requested: raw.requestedModel, reported, count: 0 };
|
|
182
|
+
existing.count += 1;
|
|
183
|
+
driftMap.set(key, existing);
|
|
184
|
+
}
|
|
185
|
+
return { entries, models, drift: [...driftMap.values()] };
|
|
186
|
+
}
|
|
187
|
+
export async function clearCache(dir = defaultCacheDir()) {
|
|
188
|
+
await rm(dir, { recursive: true, force: true });
|
|
189
|
+
}
|
|
190
|
+
async function readEntry(dir, hash, question) {
|
|
191
|
+
return readEntryFile(entryPath(dir, hash), hash, question);
|
|
192
|
+
}
|
|
193
|
+
async function writeEntry(dir, hash, entry) {
|
|
194
|
+
const path = entryPath(dir, hash);
|
|
195
|
+
await mkdir(dirname(path), { recursive: true });
|
|
196
|
+
const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`;
|
|
197
|
+
try {
|
|
198
|
+
await writeFile(temporaryPath, `${JSON.stringify(entry, null, 2)}\n`);
|
|
199
|
+
await rename(temporaryPath, path);
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
await rm(temporaryPath, { force: true }).catch(() => undefined);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function entryPath(dir, hash) {
|
|
206
|
+
return join(dir, hash.slice(0, 2), `${hash}.json`);
|
|
207
|
+
}
|
|
208
|
+
async function listEntries(dir) {
|
|
209
|
+
try {
|
|
210
|
+
await stat(dir);
|
|
211
|
+
const out = [];
|
|
212
|
+
const shards = await readdir(dir, { withFileTypes: true });
|
|
213
|
+
for (const shard of shards) {
|
|
214
|
+
if (!shard.isDirectory())
|
|
215
|
+
continue;
|
|
216
|
+
const files = await readdir(join(dir, shard.name));
|
|
217
|
+
for (const file of files) {
|
|
218
|
+
if (file.endsWith(".json"))
|
|
219
|
+
out.push(join(dir, shard.name, file));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
return [];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function isSystemOneRequest(input, init) {
|
|
229
|
+
try {
|
|
230
|
+
const url = new URL(input);
|
|
231
|
+
if (!url.pathname.endsWith(SYSTEMONE_PATH))
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
if (!input.includes(SYSTEMONE_PATH))
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
return (init?.method ?? "GET").toUpperCase() === "POST";
|
|
239
|
+
}
|
|
240
|
+
function withoutContentLength(headers) {
|
|
241
|
+
const next = new Headers(headers);
|
|
242
|
+
next.delete("content-length");
|
|
243
|
+
return next;
|
|
244
|
+
}
|
|
245
|
+
function jsonResponse(body, status = 200, statusText = "OK", headers) {
|
|
246
|
+
const responseHeaders = new Headers(headers);
|
|
247
|
+
responseHeaders.delete("content-length");
|
|
248
|
+
responseHeaders.delete("content-encoding");
|
|
249
|
+
responseHeaders.delete("transfer-encoding");
|
|
250
|
+
if (!responseHeaders.has("content-type"))
|
|
251
|
+
responseHeaders.set("content-type", "application/json");
|
|
252
|
+
return new Response(JSON.stringify(body), {
|
|
253
|
+
status,
|
|
254
|
+
statusText,
|
|
255
|
+
headers: responseHeaders,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
function firstReportedModel(hits) {
|
|
259
|
+
for (const entry of Object.values(hits)) {
|
|
260
|
+
if (entry.reportedModel)
|
|
261
|
+
return entry.reportedModel;
|
|
262
|
+
}
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
function dictionary() {
|
|
266
|
+
return Object.create(null);
|
|
267
|
+
}
|
|
268
|
+
function readEntryFile(file, hash, question) {
|
|
269
|
+
return readFile(file, "utf8")
|
|
270
|
+
.then((raw) => JSON.parse(raw))
|
|
271
|
+
.then((value) => (isCachedEntry(value, hash, question) ? value : undefined))
|
|
272
|
+
.catch(() => undefined);
|
|
273
|
+
}
|
|
274
|
+
function isCachedEntry(value, hash, question) {
|
|
275
|
+
if (!/^[0-9a-f]{64}$/.test(hash))
|
|
276
|
+
return false;
|
|
277
|
+
if (!isPlainObject(value) || value.hash !== hash)
|
|
278
|
+
return false;
|
|
279
|
+
if (typeof value.reportedModel !== "string" || value.reportedModel.length === 0)
|
|
280
|
+
return false;
|
|
281
|
+
if (Object.hasOwn(value, "requestedModel") && typeof value.requestedModel !== "string")
|
|
282
|
+
return false;
|
|
283
|
+
return (Object.hasOwn(value, "answer") &&
|
|
284
|
+
isAnswerShape(value.answer) &&
|
|
285
|
+
(question === undefined || isAnswerForQuestion(question, value.answer)));
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/dev/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dev/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAChB,cAAc,EACd,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,YAAY,GACb,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dev/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAEL,cAAc,EAKd,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,YAAY,GACb,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Questions, SystemOneResult } from "../native.js";
|
|
2
|
+
import type { Comparator, FactorTable } from "./schema.js";
|
|
3
|
+
/** The `answers` object System One returns for a set of questions. */
|
|
4
|
+
export type AnswersFor<Q extends Questions> = SystemOneResult<Q>["answers"];
|
|
5
|
+
/** A bare Noul reference in a Boolean context means `noul >= 0.5`. Fixed by design. */
|
|
6
|
+
export declare const NOUL_CUTOFF = 0.5;
|
|
7
|
+
/**
|
|
8
|
+
* Compile verbatim factor tables into a pure evaluator: answers in, Booleans out.
|
|
9
|
+
* Structural problems and cycles throw here; missing answers throw at evaluation time
|
|
10
|
+
* (never silently `false`, which `not` would flip into a wrong `true`).
|
|
11
|
+
*/
|
|
12
|
+
export declare function createFactorEvaluator<Q extends Questions = Questions, F = Record<string, boolean>>(defs: Record<string, FactorTable>): (answers: AnswersFor<Q>) => F;
|
|
13
|
+
/**
|
|
14
|
+
* Known-answer rule aligned with pi-start-smart `isKnownAnswer`:
|
|
15
|
+
* explicit `missing`, confidence 0, and a bare Noul of 0.5 are unknown.
|
|
16
|
+
* Missing answers are unknown (not an error) when the predicate asks about known-ness.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isKnownNativeAnswer(answer: unknown): boolean;
|
|
19
|
+
/** All comparators present in `cmp` must hold (they are ANDed). */
|
|
20
|
+
export declare function compare(value: number, cmp: Comparator): boolean;
|
|
21
|
+
//# sourceMappingURL=evaluate.d.ts.map
|