factbag 0.0.0-alpha.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 +5 -0
- package/LICENSE +202 -0
- package/README.md +44 -0
- package/dist/core/chunk-4IP7CXNV.js +86 -0
- package/dist/core/chunk-UVOCOH2I.js +41 -0
- package/dist/core/chunk-X3LSDJL4.js +59 -0
- package/dist/core/chunk-YF4PP42K.js +8 -0
- package/dist/core/dsl/enumeration.d.ts +3 -0
- package/dist/core/dsl/formula.d.ts +62 -0
- package/dist/core/dsl/index.d.ts +21 -0
- package/dist/core/dsl/index.js +132 -0
- package/dist/core/dsl/operators/aggregate.d.ts +30 -0
- package/dist/core/dsl/operators/arithmetic.d.ts +27 -0
- package/dist/core/dsl/operators/comparison.d.ts +13 -0
- package/dist/core/dsl/predicate.d.ts +33 -0
- package/dist/core/dsl/types.d.ts +59 -0
- package/dist/core/dsl/variable.d.ts +3 -0
- package/dist/core/exceptions/programmer-errors.d.ts +36 -0
- package/dist/core/explanation/explain.d.ts +20 -0
- package/dist/core/explanation/index.d.ts +8 -0
- package/dist/core/explanation/index.js +187 -0
- package/dist/core/explanation/types.d.ts +172 -0
- package/dist/core/knowledge-base/assertions/exclusive-definitions.d.ts +3 -0
- package/dist/core/knowledge-base/index.d.ts +13 -0
- package/dist/core/knowledge-base/index.js +196 -0
- package/dist/core/knowledge-base/knowledge-base.d.ts +81 -0
- package/dist/core/query/index.d.ts +10 -0
- package/dist/core/query/index.js +1947 -0
- package/dist/core/query/query.d.ts +47 -0
- package/dist/core/solver/candidate-search.d.ts +12 -0
- package/dist/core/solver/goal-value.d.ts +6 -0
- package/dist/core/solver/matching.d.ts +10 -0
- package/dist/core/solver/query-validation/constructive-recursion.d.ts +3 -0
- package/dist/core/solver/query-validation/constructive-variable-use.d.ts +3 -0
- package/dist/core/solver/query-validation/context.d.ts +10 -0
- package/dist/core/solver/query-validation/index.d.ts +1 -0
- package/dist/core/solver/query-validation/utils.d.ts +27 -0
- package/dist/core/solver/query-validation/validate-query.d.ts +6 -0
- package/dist/core/solver/solve-all.d.ts +6 -0
- package/dist/core/solver/solve.d.ts +6 -0
- package/dist/core/types/annotations.d.ts +6 -0
- package/dist/core/types/atom.d.ts +55 -0
- package/dist/core/types/common.d.ts +7 -0
- package/dist/core/types/evidence-metadata.d.ts +18 -0
- package/dist/core/types/goal.d.ts +103 -0
- package/dist/core/types/judgment.d.ts +137 -0
- package/dist/core/types/literal.d.ts +25 -0
- package/dist/core/types/predicate.d.ts +35 -0
- package/dist/core/types/rule.d.ts +16 -0
- package/dist/core/types/schema.d.ts +33 -0
- package/dist/core/types/variable.d.ts +13 -0
- package/dist/core/utils/assert.d.ts +4 -0
- package/dist/core/utils/normalize-to-list.d.ts +2 -0
- package/dist/corpus/chunkers.d.ts +7 -0
- package/dist/corpus/corpus.d.ts +41 -0
- package/dist/corpus/index.d.ts +8 -0
- package/dist/corpus/index.js +312 -0
- package/dist/corpus/records.d.ts +8 -0
- package/dist/corpus/text.d.ts +6 -0
- package/dist/corpus/types.d.ts +62 -0
- package/dist/guards/guarded-kb.d.ts +59 -0
- package/dist/guards/index.d.ts +7 -0
- package/dist/guards/index.js +121 -0
- package/dist/guards/types.d.ts +15 -0
- package/dist/jev/chunk-2UXHML67.js +206 -0
- package/dist/jev/chunk-M7RHUI2O.js +15 -0
- package/dist/jev/classifier.d.ts +28 -0
- package/dist/jev/classifier.js +171 -0
- package/dist/jev/client.d.ts +62 -0
- package/dist/jev/errors.d.ts +22 -0
- package/dist/jev/errors.js +6 -0
- package/dist/jev/jobs.d.ts +61 -0
- package/dist/jev/resolve.d.ts +82 -0
- package/dist/jev/resolve.js +99 -0
- package/dist/jev/tools.d.ts +9 -0
- package/dist/jev/types.d.ts +63 -0
- package/package.json +92 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
admissionPolicy,
|
|
3
|
+
jevAdjudicator
|
|
4
|
+
} from "./chunk-2UXHML67.js";
|
|
5
|
+
|
|
6
|
+
// src/resolve.ts
|
|
7
|
+
function resolver(corpus, kb, config = {}) {
|
|
8
|
+
const admission = admissionPolicy(config.admission);
|
|
9
|
+
const adjudicator = jevAdjudicator(config.client);
|
|
10
|
+
const output = kb.fork();
|
|
11
|
+
const jobs = contradictions(output.literals()).flatMap((literals) => {
|
|
12
|
+
const [first] = literals;
|
|
13
|
+
if (first === void 0) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
const passages = passagesFor(literals, corpus);
|
|
17
|
+
let state = "ready";
|
|
18
|
+
const job = {
|
|
19
|
+
atom: first.atom,
|
|
20
|
+
passages,
|
|
21
|
+
async execute() {
|
|
22
|
+
if (state !== "ready") {
|
|
23
|
+
throw new Error(`The contradiction for ${formatAtom(first.atom)} is already ${state}`);
|
|
24
|
+
}
|
|
25
|
+
state = "running";
|
|
26
|
+
try {
|
|
27
|
+
const answers = await adjudicator.adjudicate({ atom: first.atom, passages });
|
|
28
|
+
const judgments = answers.map(({ passage, answer }) => {
|
|
29
|
+
const standing = standingOf(answer, admission);
|
|
30
|
+
const retracted2 = standing === "RETRACT" ? literals.filter(({ metadata }) => metadata?.source === passage.id) : [];
|
|
31
|
+
return { passage, standing, answer, retracted: retracted2 };
|
|
32
|
+
});
|
|
33
|
+
const retracted = judgments.flatMap(({ retracted: literal }) => literal);
|
|
34
|
+
output.retract(...retracted);
|
|
35
|
+
state = "settled";
|
|
36
|
+
return {
|
|
37
|
+
atom: first.atom,
|
|
38
|
+
judgments,
|
|
39
|
+
kept: literals.filter((literal) => !retracted.includes(literal)),
|
|
40
|
+
retracted
|
|
41
|
+
};
|
|
42
|
+
} catch (error) {
|
|
43
|
+
state = "ready";
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return [job];
|
|
49
|
+
});
|
|
50
|
+
return Object.assign(jobs.values(), { kb: output });
|
|
51
|
+
}
|
|
52
|
+
function contradictions(literals) {
|
|
53
|
+
const identities = /* @__PURE__ */ new Map();
|
|
54
|
+
const identity = (value) => {
|
|
55
|
+
if (typeof value === "object" && value !== null || typeof value === "function") {
|
|
56
|
+
if (value instanceof Date) {
|
|
57
|
+
return `date:${value.toISOString()}`;
|
|
58
|
+
}
|
|
59
|
+
const known = identities.get(value) ?? identities.size;
|
|
60
|
+
identities.set(value, known);
|
|
61
|
+
return `ref:${known}`;
|
|
62
|
+
}
|
|
63
|
+
return `${typeof value}:${String(value)}`;
|
|
64
|
+
};
|
|
65
|
+
const groups = /* @__PURE__ */ new Map();
|
|
66
|
+
for (const literal of literals) {
|
|
67
|
+
const { predicate, fields } = literal.atom;
|
|
68
|
+
const key = [predicate, ...predicate.paramNames.map((name) => fields[name])].map(identity).join("|");
|
|
69
|
+
groups.set(key, [...groups.get(key) ?? [], literal]);
|
|
70
|
+
}
|
|
71
|
+
return [...groups.values()].filter(
|
|
72
|
+
(group) => group.some(({ sign }) => sign === "+") && group.some(({ sign }) => sign === "-")
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
function passagesFor(literals, corpus) {
|
|
76
|
+
const passages = /* @__PURE__ */ new Map();
|
|
77
|
+
for (const { atom, metadata } of literals) {
|
|
78
|
+
const source = metadata?.source;
|
|
79
|
+
if (source === void 0) {
|
|
80
|
+
throw new Error(`Cannot resolve ${formatAtom(atom)}: evidence without a source`);
|
|
81
|
+
}
|
|
82
|
+
const { chunk } = corpus.resolve(source);
|
|
83
|
+
passages.set(chunk.id, chunk);
|
|
84
|
+
}
|
|
85
|
+
return [...passages.values()];
|
|
86
|
+
}
|
|
87
|
+
function formatAtom({ predicate, fields }) {
|
|
88
|
+
const values = predicate.paramNames.map((name) => {
|
|
89
|
+
const value = fields[name];
|
|
90
|
+
return typeof value === "object" && value !== null && "id" in value ? String(value.id) : String(value);
|
|
91
|
+
});
|
|
92
|
+
return `${predicate.name}(${values.join(", ")})`;
|
|
93
|
+
}
|
|
94
|
+
function standingOf({ probabilities }, policy) {
|
|
95
|
+
return probabilities.RETRACT >= policy.minimumProbability && probabilities.RETRACT - probabilities.KEEP > policy.ambiguityMargin ? "RETRACT" : "KEEP";
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
resolver
|
|
99
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GuardedKB } from "../guards/index.js";
|
|
2
|
+
import type { Tool } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Validate all exposed predicates before any corpus traversal or remote requests,
|
|
5
|
+
* and enumerate each one's candidates once against the KB. A predicate with more
|
|
6
|
+
* candidates than one request may carry becomes several tools, each with a slice of
|
|
7
|
+
* them. Query grants are excluded.
|
|
8
|
+
*/
|
|
9
|
+
export declare function prepareTools(access: GuardedKB): readonly Tool[];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Entity, EnumType, GroundAtom, PredicateDeclaration, RuntimeConstructor } from "../core/dsl/index.js";
|
|
2
|
+
import type { Operation } from "../guards/index.js";
|
|
3
|
+
import type { ChoiceResponse, JsonValue } from "@typesafe-ai/sdk";
|
|
4
|
+
/**
|
|
5
|
+
* Field domains accepted after registration. Open-ended scalar constructors are excluded.
|
|
6
|
+
*
|
|
7
|
+
* @beta
|
|
8
|
+
*/
|
|
9
|
+
export type SupportedField = BooleanConstructor | EnumType | RuntimeConstructor<Entity>;
|
|
10
|
+
/**
|
|
11
|
+
* A predicate refined during registration to supported finite field domains.
|
|
12
|
+
*
|
|
13
|
+
* @beta
|
|
14
|
+
*/
|
|
15
|
+
export type SupportedPredicate = PredicateDeclaration<Readonly<Record<string, SupportedField>>>;
|
|
16
|
+
/** A permitted effect on a validated predicate: any guarded operation that writes. */
|
|
17
|
+
export type Action = Exclude<Operation, "query">;
|
|
18
|
+
/**
|
|
19
|
+
* Interpretations of a passage's relationship to one complete fact.
|
|
20
|
+
*
|
|
21
|
+
* @beta
|
|
22
|
+
*/
|
|
23
|
+
export type Outcome = "ASSERT" | "DENY" | "IRRELEVANT";
|
|
24
|
+
/**
|
|
25
|
+
* Validated response retaining the full three-way distribution.
|
|
26
|
+
*
|
|
27
|
+
* @beta
|
|
28
|
+
*/
|
|
29
|
+
export type EvidenceChoice = ChoiceResponse<Record<Outcome, string>>;
|
|
30
|
+
/** One ground atom the model is asked about, with its fields encoded for the request. */
|
|
31
|
+
export type Candidate = Readonly<{
|
|
32
|
+
id: string;
|
|
33
|
+
atom: GroundAtom;
|
|
34
|
+
fields: Record<string, JsonValue>;
|
|
35
|
+
}>;
|
|
36
|
+
/** Everything needed to classify one validated predicate, fixed at run start. */
|
|
37
|
+
export type Tool = Readonly<{
|
|
38
|
+
predicate: SupportedPredicate;
|
|
39
|
+
actions: ReadonlySet<Action>;
|
|
40
|
+
candidates: readonly Candidate[];
|
|
41
|
+
}>;
|
|
42
|
+
/** A validated model response for one tool and chunk; nothing has been written yet. */
|
|
43
|
+
export type ToolResult = Readonly<{
|
|
44
|
+
tool: Tool;
|
|
45
|
+
/** The chunk id the answers were given for. */
|
|
46
|
+
source: string;
|
|
47
|
+
answers: readonly Readonly<{
|
|
48
|
+
candidate: Candidate;
|
|
49
|
+
answer: EvidenceChoice;
|
|
50
|
+
}>[];
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Whether one passage's evidence survives, judged against the passages it conflicts with.
|
|
54
|
+
*
|
|
55
|
+
* @beta
|
|
56
|
+
*/
|
|
57
|
+
export type Standing = "KEEP" | "RETRACT";
|
|
58
|
+
/**
|
|
59
|
+
* Validated response retaining the full distribution.
|
|
60
|
+
*
|
|
61
|
+
* @beta
|
|
62
|
+
*/
|
|
63
|
+
export type StandingChoice = ChoiceResponse<Record<Standing, string>>;
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "factbag",
|
|
3
|
+
"version": "0.0.0-alpha.0",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"logic",
|
|
6
|
+
"rules-engine",
|
|
7
|
+
"knowledge-base",
|
|
8
|
+
"explainability",
|
|
9
|
+
"typescript"
|
|
10
|
+
],
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/factbag/factbag/issues"
|
|
13
|
+
},
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"type": "module",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"CHANGELOG.md",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": "^22.18.0 || ^24.0.0 || ^26.0.0"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"description": "Explainable fact and rule evaluation, document provenance, permission controls, and Jev integration.",
|
|
30
|
+
"homepage": "https://github.com/factbag/factbag/tree/main/packages/factbag#readme",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/factbag/factbag.git",
|
|
34
|
+
"directory": "packages/factbag"
|
|
35
|
+
},
|
|
36
|
+
"exports": {
|
|
37
|
+
"./dsl": {
|
|
38
|
+
"types": "./dist/core/dsl/index.d.ts",
|
|
39
|
+
"import": "./dist/core/dsl/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./kb": {
|
|
42
|
+
"types": "./dist/core/knowledge-base/index.d.ts",
|
|
43
|
+
"import": "./dist/core/knowledge-base/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./query": {
|
|
46
|
+
"types": "./dist/core/query/index.d.ts",
|
|
47
|
+
"import": "./dist/core/query/index.js"
|
|
48
|
+
},
|
|
49
|
+
"./explain": {
|
|
50
|
+
"types": "./dist/core/explanation/index.d.ts",
|
|
51
|
+
"import": "./dist/core/explanation/index.js"
|
|
52
|
+
},
|
|
53
|
+
"./corpus": {
|
|
54
|
+
"types": "./dist/corpus/index.d.ts",
|
|
55
|
+
"import": "./dist/corpus/index.js"
|
|
56
|
+
},
|
|
57
|
+
"./guards": {
|
|
58
|
+
"types": "./dist/guards/index.d.ts",
|
|
59
|
+
"import": "./dist/guards/index.js"
|
|
60
|
+
},
|
|
61
|
+
"./jev/classifier": {
|
|
62
|
+
"types": "./dist/jev/classifier.d.ts",
|
|
63
|
+
"import": "./dist/jev/classifier.js"
|
|
64
|
+
},
|
|
65
|
+
"./jev/errors": {
|
|
66
|
+
"types": "./dist/jev/errors.d.ts",
|
|
67
|
+
"import": "./dist/jev/errors.js"
|
|
68
|
+
},
|
|
69
|
+
"./jev/resolve": {
|
|
70
|
+
"types": "./dist/jev/resolve.d.ts",
|
|
71
|
+
"import": "./dist/jev/resolve.js"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@factbag/core": "0.1.0-next.0",
|
|
76
|
+
"@factbag/corpus": "0.1.0-next.0",
|
|
77
|
+
"@factbag/guards": "0.1.0-next.0",
|
|
78
|
+
"@factbag/jev": "0.1.0-next.0",
|
|
79
|
+
"@typesafe-ai/sdk": "0.6.0"
|
|
80
|
+
},
|
|
81
|
+
"peerDependencies": {
|
|
82
|
+
"@typesafe-ai/sdk": "^0.6.0"
|
|
83
|
+
},
|
|
84
|
+
"peerDependenciesMeta": {
|
|
85
|
+
"@typesafe-ai/sdk": {
|
|
86
|
+
"optional": true
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"scripts": {
|
|
90
|
+
"build": "node ../../scripts/build-public-package.ts"
|
|
91
|
+
}
|
|
92
|
+
}
|