@effect-uai/core 0.16.0 → 0.17.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/dist/decision-model/Decision.d.mts +155 -0
- package/dist/decision-model/Decision.d.mts.map +1 -0
- package/dist/decision-model/Decision.mjs +118 -0
- package/dist/decision-model/Decision.mjs.map +1 -0
- package/dist/decision-model/Decision.test.d.mts +1 -0
- package/dist/decision-model/Decision.test.mjs +164 -0
- package/dist/decision-model/Decision.test.mjs.map +1 -0
- package/dist/decision-model/DecisionModel.d.mts +45 -0
- package/dist/decision-model/DecisionModel.d.mts.map +1 -0
- package/dist/decision-model/DecisionModel.mjs +25 -0
- package/dist/decision-model/DecisionModel.mjs.map +1 -0
- package/dist/index.d.mts +4 -1
- package/dist/index.mjs +4 -1
- package/dist/math/Probability.d.mts +21 -0
- package/dist/math/Probability.d.mts.map +1 -0
- package/dist/math/Probability.mjs +31 -0
- package/dist/math/Probability.mjs.map +1 -0
- package/dist/math/Probability.test.d.mts +1 -0
- package/dist/math/Probability.test.mjs +95 -0
- package/dist/math/Probability.test.mjs.map +1 -0
- package/package.json +13 -1
- package/src/decision-model/Decision.test.ts +146 -0
- package/src/decision-model/Decision.ts +273 -0
- package/src/decision-model/DecisionModel.ts +53 -0
- package/src/index.ts +3 -0
- package/src/math/Probability.test.ts +61 -0
- package/src/math/Probability.ts +44 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { t as AiError } from "../AiError-DvhLIbmd.mjs";
|
|
2
|
+
import { Effect, Option, Schema } from "effect";
|
|
3
|
+
declare namespace Decision_d_exports {
|
|
4
|
+
export { Answer, AnswerFor, Answers, Boundary, ClassifyAnswer, ClassifyDecision, Decision, Decisions, Definition, Labels, Levels, ProbabilityAnswer, ProbabilityDecision, RateAnswer, RateDecision, assertKinds, classify, confidence, expectedLevel, make, margin, probabilitiesOf, probability, ranked, rate, topLevel, winner };
|
|
5
|
+
}
|
|
6
|
+
/** Labels mapped to what each one means. */
|
|
7
|
+
type Labels = Readonly<Record<string, string>>;
|
|
8
|
+
/** An ordered rubric, lowest level first. */
|
|
9
|
+
type Levels = readonly [string, string, ...ReadonlyArray<string>];
|
|
10
|
+
/** What a true and a false answer mean, when the boundary is subtle. */
|
|
11
|
+
type Boundary = {
|
|
12
|
+
readonly true?: string;
|
|
13
|
+
readonly false?: string;
|
|
14
|
+
};
|
|
15
|
+
type ClassifyDecision<L extends Labels = Labels> = {
|
|
16
|
+
readonly _tag: "Classify";
|
|
17
|
+
readonly instructions: string;
|
|
18
|
+
readonly criteria: L;
|
|
19
|
+
};
|
|
20
|
+
type RateDecision<V extends Levels = Levels> = {
|
|
21
|
+
readonly _tag: "Rate";
|
|
22
|
+
readonly instructions: string;
|
|
23
|
+
readonly criteria: V;
|
|
24
|
+
};
|
|
25
|
+
type ProbabilityDecision = {
|
|
26
|
+
readonly _tag: "Probability";
|
|
27
|
+
readonly instructions: string;
|
|
28
|
+
readonly criteria?: Boundary;
|
|
29
|
+
};
|
|
30
|
+
type Decision = ClassifyDecision | RateDecision | ProbabilityDecision;
|
|
31
|
+
/** Pick one label. Use {@link rate} when the options form a spectrum. */
|
|
32
|
+
declare const classify: <const L extends Labels>(decision: {
|
|
33
|
+
readonly instructions: string;
|
|
34
|
+
readonly criteria: L;
|
|
35
|
+
}) => ClassifyDecision<L>;
|
|
36
|
+
/** Place the input on an ordered rubric. */
|
|
37
|
+
declare const rate: <const V extends Levels>(decision: {
|
|
38
|
+
readonly instructions: string;
|
|
39
|
+
readonly criteria: V;
|
|
40
|
+
}) => RateDecision<V>;
|
|
41
|
+
/**
|
|
42
|
+
* How likely a statement is to hold. Named for its answer rather than for an
|
|
43
|
+
* act, unlike its siblings, so nobody reads the result as a boolean.
|
|
44
|
+
*/
|
|
45
|
+
declare const probability: (decision: {
|
|
46
|
+
readonly instructions: string;
|
|
47
|
+
readonly criteria?: Boundary;
|
|
48
|
+
}) => ProbabilityDecision;
|
|
49
|
+
/** Decisions keyed by the name their answer comes back under. */
|
|
50
|
+
type Decisions = {
|
|
51
|
+
readonly [name: string]: Decision;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* A reusable decision set bound to the shape it reads.
|
|
55
|
+
*
|
|
56
|
+
* `inputSchema` encodes the input on the way out, so a schema that omits a
|
|
57
|
+
* field keeps it from the model. That projection is the supported way to hold
|
|
58
|
+
* irrelevant or sensitive context out of a request.
|
|
59
|
+
*/
|
|
60
|
+
type Definition<A_, D extends Decisions = Decisions> = {
|
|
61
|
+
readonly inputSchema: Schema.Codec<A_, unknown, any, never>;
|
|
62
|
+
readonly decisions: D;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Build a decision set. Declare it once at module scope: the questions and
|
|
66
|
+
* their rubrics are the reviewed artifact, the input changes per call.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const triage = Decision.make({
|
|
71
|
+
* inputSchema: Schema.Struct({ message: Schema.String }),
|
|
72
|
+
* decisions: {
|
|
73
|
+
* department: Decision.classify({
|
|
74
|
+
* instructions: "Which team should handle this?",
|
|
75
|
+
* criteria: { billing: "Payments, invoicing", technical: "Bugs, outages" },
|
|
76
|
+
* }),
|
|
77
|
+
* },
|
|
78
|
+
* })
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
declare const make: <S extends Schema.Codec<any, any, any, never>, const D extends Decisions>(definition: {
|
|
82
|
+
readonly inputSchema: S;
|
|
83
|
+
readonly decisions: D;
|
|
84
|
+
}) => Definition<S["Type"], D>;
|
|
85
|
+
/**
|
|
86
|
+
* Score contract for {@link ClassifyAnswer.labels} and
|
|
87
|
+
* {@link RateAnswer.levels}: probabilities sum to 1 within floating-point
|
|
88
|
+
* error and are comparable within one answer. Whether they are *calibrated*,
|
|
89
|
+
* so a stated 0.8 means right about 80% of the time, is a property of the
|
|
90
|
+
* Layer and is documented per provider. No implementor promises calibration
|
|
91
|
+
* across requests, across decision kinds, or between a statement and its
|
|
92
|
+
* negation: `P(claim) != 1 - P(not claim)`. A threshold fitted against one
|
|
93
|
+
* model does not transfer to another.
|
|
94
|
+
*/
|
|
95
|
+
type ClassifyAnswer<L extends Labels = Labels> = {
|
|
96
|
+
readonly _tag: "Classify";
|
|
97
|
+
readonly labels: Readonly<Record<keyof L & string, number>>;
|
|
98
|
+
};
|
|
99
|
+
type RateAnswer<V extends Levels = Levels> = {
|
|
100
|
+
readonly _tag: "Rate";
|
|
101
|
+
/** Index-aligned with {@link RateAnswer.legend}. */
|
|
102
|
+
readonly levels: { readonly [K in keyof V]: number; };
|
|
103
|
+
/** The rubric, echoed so an index reads back as prose. */
|
|
104
|
+
readonly legend: Readonly<V>;
|
|
105
|
+
};
|
|
106
|
+
type ProbabilityAnswer = {
|
|
107
|
+
readonly _tag: "Probability";
|
|
108
|
+
readonly probability: number;
|
|
109
|
+
};
|
|
110
|
+
type Answer = ClassifyAnswer | RateAnswer | ProbabilityAnswer;
|
|
111
|
+
/** The answer a decision determines, keeping its labels or rubric. */
|
|
112
|
+
type AnswerFor<D> = D extends {
|
|
113
|
+
readonly _tag: "Classify";
|
|
114
|
+
readonly criteria: infer L extends Labels;
|
|
115
|
+
} ? ClassifyAnswer<L> : D extends {
|
|
116
|
+
readonly _tag: "Rate";
|
|
117
|
+
readonly criteria: infer V extends Levels;
|
|
118
|
+
} ? RateAnswer<V> : ProbabilityAnswer;
|
|
119
|
+
/** Answers keyed by their decision's name. */
|
|
120
|
+
type Answers<D extends Decisions> = { readonly [K in keyof D]: AnswerFor<D[K]>; };
|
|
121
|
+
/**
|
|
122
|
+
* Fail `AiError.Unsupported` naming every decision whose kind this provider
|
|
123
|
+
* cannot express. Bucket 1: omitting an answer would leave a hole where
|
|
124
|
+
* {@link Answers} promises a key.
|
|
125
|
+
*
|
|
126
|
+
* Reports all offenders at once, since the definition is known up front.
|
|
127
|
+
*/
|
|
128
|
+
declare const assertKinds: (decisions: Decisions, supported: ReadonlyArray<Decision["_tag"]>, provider: string) => Effect.Effect<void, AiError>;
|
|
129
|
+
/** A `Probability` answer's implied distribution is `[p, 1 - p]`. */
|
|
130
|
+
declare const probabilitiesOf: (answer: Answer) => ReadonlyArray<number>;
|
|
131
|
+
/** See {@link Probability.confidence}. Defined for every kind. */
|
|
132
|
+
declare const confidence: (answer: Answer) => number;
|
|
133
|
+
/** See {@link Probability.margin}. Defined for every kind. */
|
|
134
|
+
declare const margin: (answer: Answer) => number;
|
|
135
|
+
/**
|
|
136
|
+
* Labels best first. Ties keep first-seen order. Also the bridge to rank
|
|
137
|
+
* fusion: map to `label` and pass alongside another retriever's ordering.
|
|
138
|
+
*/
|
|
139
|
+
declare const ranked: <L extends Labels>(answer: ClassifyAnswer<L>) => ReadonlyArray<{
|
|
140
|
+
readonly label: keyof L & string;
|
|
141
|
+
readonly probability: number;
|
|
142
|
+
}>;
|
|
143
|
+
/** Highest-probability label. `None` only when the label set is empty. */
|
|
144
|
+
declare const winner: <L extends Labels>(answer: ClassifyAnswer<L>) => Option.Option<keyof L & string>;
|
|
145
|
+
/** Index of the highest-probability level. Ties resolve to the lowest. */
|
|
146
|
+
declare const topLevel: (answer: RateAnswer) => number;
|
|
147
|
+
/**
|
|
148
|
+
* Probability-weighted mean of the level indices, so it can land between
|
|
149
|
+
* them. Weakly calibrated in practice: a summary, not a magnitude to
|
|
150
|
+
* interpolate. Use {@link topLevel} with `legend` to name a level instead.
|
|
151
|
+
*/
|
|
152
|
+
declare const expectedLevel: (answer: RateAnswer) => number;
|
|
153
|
+
//#endregion
|
|
154
|
+
export { Answer, AnswerFor, Answers, Boundary, ClassifyAnswer, ClassifyDecision, Decision, Decisions, Definition, Labels, Levels, ProbabilityAnswer, ProbabilityDecision, RateAnswer, RateDecision, assertKinds, classify, confidence, expectedLevel, make, margin, probabilitiesOf, probability, ranked, rate, Decision_d_exports as t, topLevel, winner };
|
|
155
|
+
//# sourceMappingURL=Decision.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Decision.d.mts","names":[],"sources":["../../src/decision-model/Decision.ts"],"mappings":";;;;;;KA4BY,SAAS,SAAS;;KAGlB,sCAAsC;;KAGtC;WAAsB;WAAwB;;KAM9C,iBAAiB,UAAU,SAAS;WACrC;WACA;WACA,UAAU;;KAGT,aAAa,UAAU,SAAS;WACjC;WACA;WACA,UAAU;;KAGT;WACD;WACA;WACA,WAAW;;KAGV,WAAW,mBAAmB,eAAe;;cAG5C,iBAAkB,UAAU,QAAM;WACpC;WACA,UAAU;MACjB,iBAAiB;;cAGR,aAAc,UAAU,QAAM;WAChC;WACA,UAAU;MACjB,aAAa;;;;;cAMJ,cAAW;WACb;WACA,WAAW;MAClB;;KAGQ;YAAwB,eAAe;;;;;;;;;KAavC,WAAW,IAAI,UAAU,YAAY;WACtC,aAAa,OAAO,MAAM;WAC1B,WAAW;;;;;;;;;;;;;;;;;;;cAoBT,OACX,UAAU,OAAO,mCACX,UAAU,WAAS;WAEhB,aAAa;WACb,WAAW;MAClB,WAAW,WAAW;;;;;;;;;;;KAgBd,eAAe,UAAU,SAAS;WACnC;WACA,QAAQ,SAAS,aAAa;;KAG7B,WAAW,UAAU,SAAS;WAC/B;;WAEA,oBAAoB,WAAW;;WAE/B,QAAQ,SAAS;;KAGhB;WACD;WACA;;KAGC,SAAS,iBAAiB,aAAa;;KAGvC,UAAU,KAAK;WAChB;WACA,gBAAgB,UAAU;IAEjC,eAAe,KACf;WAAqB;WAAuB,gBAAgB,UAAU;IACpE,WAAW,KACX;;KAGM,QAAQ,UAAU,yBAAyB,WAAW,IAAI,UAAU,EAAE;;;;;;;;cAarE,cAAW,WACX,WAAS,WACT,cAAc,mBAAiB,qBAEzC,OAAO,aAAa;;cAsBV,kBAAkB,QAAQ,WAAW;;cASrC,aAAU,QAAY;;cAItB,SAAM,QAAY;;;;;cAWlB,SAAU,UAAU,QAAM,QAC7B,eAAe,OACtB;WAAyB,aAAa;WAAqB;;;cAQjD,SAAU,UAAU,QAAM,QAC7B,eAAe,OACtB,OAAO,aAAa;;cAQV,WAAQ,QAAY;;;;;;cAcpB,gBAAa,QAAY"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { n as __exportAll } from "../rolldown-runtime-EAsCxrDo.mjs";
|
|
2
|
+
import { Unsupported } from "../domain/AiError.mjs";
|
|
3
|
+
import { confidence as confidence$1, margin as margin$1 } from "../math/Probability.mjs";
|
|
4
|
+
import { Array, Effect, Match, Number, Option, Order, Record, pipe } from "effect";
|
|
5
|
+
//#region src/decision-model/Decision.ts
|
|
6
|
+
/**
|
|
7
|
+
* Typed questions about one input, answered with probabilities.
|
|
8
|
+
*
|
|
9
|
+
* A {@link Definition} pairs the shape being read with the questions asked of
|
|
10
|
+
* it. Build one at module scope and apply it per call with
|
|
11
|
+
* `DecisionModel.decide`.
|
|
12
|
+
*
|
|
13
|
+
* @experimental The model class this abstracts is new and the shape may change.
|
|
14
|
+
*/
|
|
15
|
+
var Decision_exports = /* @__PURE__ */ __exportAll({
|
|
16
|
+
assertKinds: () => assertKinds,
|
|
17
|
+
classify: () => classify,
|
|
18
|
+
confidence: () => confidence,
|
|
19
|
+
expectedLevel: () => expectedLevel,
|
|
20
|
+
make: () => make,
|
|
21
|
+
margin: () => margin,
|
|
22
|
+
probabilitiesOf: () => probabilitiesOf,
|
|
23
|
+
probability: () => probability,
|
|
24
|
+
ranked: () => ranked,
|
|
25
|
+
rate: () => rate,
|
|
26
|
+
topLevel: () => topLevel,
|
|
27
|
+
winner: () => winner
|
|
28
|
+
});
|
|
29
|
+
/** Pick one label. Use {@link rate} when the options form a spectrum. */
|
|
30
|
+
const classify = (decision) => ({
|
|
31
|
+
_tag: "Classify",
|
|
32
|
+
...decision
|
|
33
|
+
});
|
|
34
|
+
/** Place the input on an ordered rubric. */
|
|
35
|
+
const rate = (decision) => ({
|
|
36
|
+
_tag: "Rate",
|
|
37
|
+
...decision
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* How likely a statement is to hold. Named for its answer rather than for an
|
|
41
|
+
* act, unlike its siblings, so nobody reads the result as a boolean.
|
|
42
|
+
*/
|
|
43
|
+
const probability = (decision) => ({
|
|
44
|
+
_tag: "Probability",
|
|
45
|
+
...decision
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* Build a decision set. Declare it once at module scope: the questions and
|
|
49
|
+
* their rubrics are the reviewed artifact, the input changes per call.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const triage = Decision.make({
|
|
54
|
+
* inputSchema: Schema.Struct({ message: Schema.String }),
|
|
55
|
+
* decisions: {
|
|
56
|
+
* department: Decision.classify({
|
|
57
|
+
* instructions: "Which team should handle this?",
|
|
58
|
+
* criteria: { billing: "Payments, invoicing", technical: "Bugs, outages" },
|
|
59
|
+
* }),
|
|
60
|
+
* },
|
|
61
|
+
* })
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
const make = (definition) => definition;
|
|
65
|
+
/**
|
|
66
|
+
* Fail `AiError.Unsupported` naming every decision whose kind this provider
|
|
67
|
+
* cannot express. Bucket 1: omitting an answer would leave a hole where
|
|
68
|
+
* {@link Answers} promises a key.
|
|
69
|
+
*
|
|
70
|
+
* Reports all offenders at once, since the definition is known up front.
|
|
71
|
+
*/
|
|
72
|
+
const assertKinds = (decisions, supported, provider) => {
|
|
73
|
+
const offenders = pipe(Record.toEntries(decisions), Array.filter(([, decision]) => !supported.includes(decision._tag)), Array.map(([name, decision]) => `"${name}" is a ${decision._tag}`));
|
|
74
|
+
return offenders.length === 0 ? Effect.void : Effect.fail(new Unsupported({
|
|
75
|
+
provider,
|
|
76
|
+
capability: "decision",
|
|
77
|
+
reason: `${provider} answers ${supported.join(" / ")} only; ${offenders.join(", ")}.`
|
|
78
|
+
}));
|
|
79
|
+
};
|
|
80
|
+
/** A `Probability` answer's implied distribution is `[p, 1 - p]`. */
|
|
81
|
+
const probabilitiesOf = Match.type().pipe(Match.discriminatorsExhaustive("_tag")({
|
|
82
|
+
Classify: (answer) => Record.values(answer.labels),
|
|
83
|
+
Rate: (answer) => answer.levels,
|
|
84
|
+
Probability: (answer) => [answer.probability, 1 - answer.probability]
|
|
85
|
+
}));
|
|
86
|
+
/** See {@link Probability.confidence}. Defined for every kind. */
|
|
87
|
+
const confidence = (answer) => confidence$1(probabilitiesOf(answer));
|
|
88
|
+
/** See {@link Probability.margin}. Defined for every kind. */
|
|
89
|
+
const margin = (answer) => margin$1(probabilitiesOf(answer));
|
|
90
|
+
const byProbability = Order.mapInput(Order.flip(Order.Number), (outcome) => outcome.probability);
|
|
91
|
+
/**
|
|
92
|
+
* Labels best first. Ties keep first-seen order. Also the bridge to rank
|
|
93
|
+
* fusion: map to `label` and pass alongside another retriever's ordering.
|
|
94
|
+
*/
|
|
95
|
+
const ranked = (answer) => pipe(Record.toEntries(answer.labels), Array.map(([label, probability]) => ({
|
|
96
|
+
label,
|
|
97
|
+
probability
|
|
98
|
+
})), Array.sort(byProbability));
|
|
99
|
+
/** Highest-probability label. `None` only when the label set is empty. */
|
|
100
|
+
const winner = (answer) => pipe(ranked(answer), Array.head, Option.map((outcome) => outcome.label));
|
|
101
|
+
/** Index of the highest-probability level. Ties resolve to the lowest. */
|
|
102
|
+
const topLevel = (answer) => pipe(answer.levels, Array.reduce({
|
|
103
|
+
index: 0,
|
|
104
|
+
probability: -Infinity
|
|
105
|
+
}, (best, probability, index) => probability > best.probability ? {
|
|
106
|
+
index,
|
|
107
|
+
probability
|
|
108
|
+
} : best), (best) => best.index);
|
|
109
|
+
/**
|
|
110
|
+
* Probability-weighted mean of the level indices, so it can land between
|
|
111
|
+
* them. Weakly calibrated in practice: a summary, not a magnitude to
|
|
112
|
+
* interpolate. Use {@link topLevel} with `legend` to name a level instead.
|
|
113
|
+
*/
|
|
114
|
+
const expectedLevel = (answer) => pipe(answer.levels, Array.map((probability, index) => index * probability), Number.sumAll);
|
|
115
|
+
//#endregion
|
|
116
|
+
export { assertKinds, classify, confidence, expectedLevel, make, margin, probabilitiesOf, probability, ranked, rate, Decision_exports as t, topLevel, winner };
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=Decision.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Decision.mjs","names":["A","AiError.Unsupported","Probability.confidence","Probability.margin","N"],"sources":["../../src/decision-model/Decision.ts"],"sourcesContent":["/**\n * Typed questions about one input, answered with probabilities.\n *\n * A {@link Definition} pairs the shape being read with the questions asked of\n * it. Build one at module scope and apply it per call with\n * `DecisionModel.decide`.\n *\n * @experimental The model class this abstracts is new and the shape may change.\n */\nimport {\n Array as A,\n Effect,\n Match,\n Number as N,\n Option,\n Order,\n Record,\n type Schema,\n pipe,\n} from \"effect\"\nimport * as AiError from \"../domain/AiError.js\"\nimport * as Probability from \"../math/Probability.js\"\n\n// ---------------------------------------------------------------------------\n// Criteria\n// ---------------------------------------------------------------------------\n\n/** Labels mapped to what each one means. */\nexport type Labels = Readonly<Record<string, string>>\n\n/** An ordered rubric, lowest level first. */\nexport type Levels = readonly [string, string, ...ReadonlyArray<string>]\n\n/** What a true and a false answer mean, when the boundary is subtle. */\nexport type Boundary = { readonly true?: string; readonly false?: string }\n\n// ---------------------------------------------------------------------------\n// Decisions\n// ---------------------------------------------------------------------------\n\nexport type ClassifyDecision<L extends Labels = Labels> = {\n readonly _tag: \"Classify\"\n readonly instructions: string\n readonly criteria: L\n}\n\nexport type RateDecision<V extends Levels = Levels> = {\n readonly _tag: \"Rate\"\n readonly instructions: string\n readonly criteria: V\n}\n\nexport type ProbabilityDecision = {\n readonly _tag: \"Probability\"\n readonly instructions: string\n readonly criteria?: Boundary\n}\n\nexport type Decision = ClassifyDecision | RateDecision | ProbabilityDecision\n\n/** Pick one label. Use {@link rate} when the options form a spectrum. */\nexport const classify = <const L extends Labels>(decision: {\n readonly instructions: string\n readonly criteria: L\n}): ClassifyDecision<L> => ({ _tag: \"Classify\", ...decision })\n\n/** Place the input on an ordered rubric. */\nexport const rate = <const V extends Levels>(decision: {\n readonly instructions: string\n readonly criteria: V\n}): RateDecision<V> => ({ _tag: \"Rate\", ...decision })\n\n/**\n * How likely a statement is to hold. Named for its answer rather than for an\n * act, unlike its siblings, so nobody reads the result as a boolean.\n */\nexport const probability = (decision: {\n readonly instructions: string\n readonly criteria?: Boundary\n}): ProbabilityDecision => ({ _tag: \"Probability\", ...decision })\n\n/** Decisions keyed by the name their answer comes back under. */\nexport type Decisions = { readonly [name: string]: Decision }\n\n// ---------------------------------------------------------------------------\n// Definition\n// ---------------------------------------------------------------------------\n\n/**\n * A reusable decision set bound to the shape it reads.\n *\n * `inputSchema` encodes the input on the way out, so a schema that omits a\n * field keeps it from the model. That projection is the supported way to hold\n * irrelevant or sensitive context out of a request.\n */\nexport type Definition<A_, D extends Decisions = Decisions> = {\n readonly inputSchema: Schema.Codec<A_, unknown, any, never>\n readonly decisions: D\n}\n\n/**\n * Build a decision set. Declare it once at module scope: the questions and\n * their rubrics are the reviewed artifact, the input changes per call.\n *\n * @example\n * ```ts\n * const triage = Decision.make({\n * inputSchema: Schema.Struct({ message: Schema.String }),\n * decisions: {\n * department: Decision.classify({\n * instructions: \"Which team should handle this?\",\n * criteria: { billing: \"Payments, invoicing\", technical: \"Bugs, outages\" },\n * }),\n * },\n * })\n * ```\n */\nexport const make = <\n S extends Schema.Codec<any, any, any, never>,\n const D extends Decisions,\n>(definition: {\n readonly inputSchema: S\n readonly decisions: D\n}): Definition<S[\"Type\"], D> => definition\n\n// ---------------------------------------------------------------------------\n// Answers\n// ---------------------------------------------------------------------------\n\n/**\n * Score contract for {@link ClassifyAnswer.labels} and\n * {@link RateAnswer.levels}: probabilities sum to 1 within floating-point\n * error and are comparable within one answer. Whether they are *calibrated*,\n * so a stated 0.8 means right about 80% of the time, is a property of the\n * Layer and is documented per provider. No implementor promises calibration\n * across requests, across decision kinds, or between a statement and its\n * negation: `P(claim) != 1 - P(not claim)`. A threshold fitted against one\n * model does not transfer to another.\n */\nexport type ClassifyAnswer<L extends Labels = Labels> = {\n readonly _tag: \"Classify\"\n readonly labels: Readonly<Record<keyof L & string, number>>\n}\n\nexport type RateAnswer<V extends Levels = Levels> = {\n readonly _tag: \"Rate\"\n /** Index-aligned with {@link RateAnswer.legend}. */\n readonly levels: { readonly [K in keyof V]: number }\n /** The rubric, echoed so an index reads back as prose. */\n readonly legend: Readonly<V>\n}\n\nexport type ProbabilityAnswer = {\n readonly _tag: \"Probability\"\n readonly probability: number\n}\n\nexport type Answer = ClassifyAnswer | RateAnswer | ProbabilityAnswer\n\n/** The answer a decision determines, keeping its labels or rubric. */\nexport type AnswerFor<D> = D extends {\n readonly _tag: \"Classify\"\n readonly criteria: infer L extends Labels\n}\n ? ClassifyAnswer<L>\n : D extends { readonly _tag: \"Rate\"; readonly criteria: infer V extends Levels }\n ? RateAnswer<V>\n : ProbabilityAnswer\n\n/** Answers keyed by their decision's name. */\nexport type Answers<D extends Decisions> = { readonly [K in keyof D]: AnswerFor<D[K]> }\n\n// ---------------------------------------------------------------------------\n// Guards\n// ---------------------------------------------------------------------------\n\n/**\n * Fail `AiError.Unsupported` naming every decision whose kind this provider\n * cannot express. Bucket 1: omitting an answer would leave a hole where\n * {@link Answers} promises a key.\n *\n * Reports all offenders at once, since the definition is known up front.\n */\nexport const assertKinds = (\n decisions: Decisions,\n supported: ReadonlyArray<Decision[\"_tag\"]>,\n provider: string,\n): Effect.Effect<void, AiError.AiError> => {\n const offenders = pipe(\n Record.toEntries(decisions),\n A.filter(([, decision]) => !supported.includes(decision._tag)),\n A.map(([name, decision]) => `\"${name}\" is a ${decision._tag}`),\n )\n return offenders.length === 0\n ? Effect.void\n : Effect.fail(\n new AiError.Unsupported({\n provider,\n capability: \"decision\",\n reason: `${provider} answers ${supported.join(\" / \")} only; ${offenders.join(\", \")}.`,\n }),\n )\n}\n\n// ---------------------------------------------------------------------------\n// Reading an answer\n// ---------------------------------------------------------------------------\n\n/** A `Probability` answer's implied distribution is `[p, 1 - p]`. */\nexport const probabilitiesOf: (answer: Answer) => ReadonlyArray<number> = Match.type<Answer>().pipe(\n Match.discriminatorsExhaustive(\"_tag\")({\n Classify: (answer) => Record.values(answer.labels),\n Rate: (answer) => answer.levels,\n Probability: (answer) => [answer.probability, 1 - answer.probability],\n }),\n)\n\n/** See {@link Probability.confidence}. Defined for every kind. */\nexport const confidence = (answer: Answer): number =>\n Probability.confidence(probabilitiesOf(answer))\n\n/** See {@link Probability.margin}. Defined for every kind. */\nexport const margin = (answer: Answer): number => Probability.margin(probabilitiesOf(answer))\n\nconst byProbability = Order.mapInput(\n Order.flip(Order.Number),\n (outcome: { readonly probability: number }) => outcome.probability,\n)\n\n/**\n * Labels best first. Ties keep first-seen order. Also the bridge to rank\n * fusion: map to `label` and pass alongside another retriever's ordering.\n */\nexport const ranked = <L extends Labels>(\n answer: ClassifyAnswer<L>,\n): ReadonlyArray<{ readonly label: keyof L & string; readonly probability: number }> =>\n pipe(\n Record.toEntries(answer.labels),\n A.map(([label, probability]) => ({ label, probability })),\n A.sort(byProbability),\n )\n\n/** Highest-probability label. `None` only when the label set is empty. */\nexport const winner = <L extends Labels>(\n answer: ClassifyAnswer<L>,\n): Option.Option<keyof L & string> =>\n pipe(\n ranked(answer),\n A.head,\n Option.map((outcome) => outcome.label),\n )\n\n/** Index of the highest-probability level. Ties resolve to the lowest. */\nexport const topLevel = (answer: RateAnswer): number =>\n pipe(\n answer.levels as ReadonlyArray<number>,\n A.reduce({ index: 0, probability: -Infinity }, (best, probability, index) =>\n probability > best.probability ? { index, probability } : best,\n ),\n (best) => best.index,\n )\n\n/**\n * Probability-weighted mean of the level indices, so it can land between\n * them. Weakly calibrated in practice: a summary, not a magnitude to\n * interpolate. Use {@link topLevel} with `legend` to name a level instead.\n */\nexport const expectedLevel = (answer: RateAnswer): number =>\n pipe(\n answer.levels as ReadonlyArray<number>,\n A.map((probability, index) => index * probability),\n N.sumAll,\n )\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,MAAa,YAAoC,cAGrB;CAAE,MAAM;CAAY,GAAG;AAAS;;AAG5D,MAAa,QAAgC,cAGrB;CAAE,MAAM;CAAQ,GAAG;AAAS;;;;;AAMpD,MAAa,eAAe,cAGA;CAAE,MAAM;CAAe,GAAG;AAAS;;;;;;;;;;;;;;;;;;AAsC/D,MAAa,QAGX,eAG8B;;;;;;;;AA4DhC,MAAa,eACX,WACA,WACA,aACyC;CACzC,MAAM,YAAY,KAChB,OAAO,UAAU,SAAS,GAC1BA,MAAE,QAAQ,GAAG,cAAc,CAAC,UAAU,SAAS,SAAS,IAAI,CAAC,GAC7DA,MAAE,KAAK,CAAC,MAAM,cAAc,IAAI,KAAK,SAAS,SAAS,MAAM,CAC/D;CACA,OAAO,UAAU,WAAW,IACxB,OAAO,OACP,OAAO,KACL,IAAIC,YAAoB;EACtB;EACA,YAAY;EACZ,QAAQ,GAAG,SAAS,WAAW,UAAU,KAAK,KAAK,EAAE,SAAS,UAAU,KAAK,IAAI,EAAE;CACrF,CAAC,CACH;AACN;;AAOA,MAAa,kBAA6D,MAAM,KAAa,CAAC,CAAC,KAC7F,MAAM,yBAAyB,MAAM,CAAC,CAAC;CACrC,WAAW,WAAW,OAAO,OAAO,OAAO,MAAM;CACjD,OAAO,WAAW,OAAO;CACzB,cAAc,WAAW,CAAC,OAAO,aAAa,IAAI,OAAO,WAAW;AACtE,CAAC,CACH;;AAGA,MAAa,cAAc,WACzBC,aAAuB,gBAAgB,MAAM,CAAC;;AAGhD,MAAa,UAAU,WAA2BC,SAAmB,gBAAgB,MAAM,CAAC;AAE5F,MAAM,gBAAgB,MAAM,SAC1B,MAAM,KAAK,MAAM,MAAM,IACtB,YAA8C,QAAQ,WACzD;;;;;AAMA,MAAa,UACX,WAEA,KACE,OAAO,UAAU,OAAO,MAAM,GAC9BH,MAAE,KAAK,CAAC,OAAO,kBAAkB;CAAE;CAAO;AAAY,EAAE,GACxDA,MAAE,KAAK,aAAa,CACtB;;AAGF,MAAa,UACX,WAEA,KACE,OAAO,MAAM,GACbA,MAAE,MACF,OAAO,KAAK,YAAY,QAAQ,KAAK,CACvC;;AAGF,MAAa,YAAY,WACvB,KACE,OAAO,QACPA,MAAE,OAAO;CAAE,OAAO;CAAG,aAAa;AAAU,IAAI,MAAM,aAAa,UACjE,cAAc,KAAK,cAAc;CAAE;CAAO;AAAY,IAAI,IAC5D,IACC,SAAS,KAAK,KACjB;;;;;;AAOF,MAAa,iBAAiB,WAC5B,KACE,OAAO,QACPA,MAAE,KAAK,aAAa,UAAU,QAAQ,WAAW,GACjDI,OAAE,MACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { Unsupported } from "../domain/AiError.mjs";
|
|
2
|
+
import { assertKinds, classify, confidence, expectedLevel, make, margin, probabilitiesOf, probability, ranked, rate, topLevel, winner } from "./Decision.mjs";
|
|
3
|
+
import { DecisionModel, decide } from "./DecisionModel.mjs";
|
|
4
|
+
import { o as describe } from "../utils-CiH_DjFW.mjs";
|
|
5
|
+
import { n as globalExpect } from "../test.DNmyFkvJ-YPzDR0Co.mjs";
|
|
6
|
+
import { t as import_dist } from "../dist-BaenoU1A.mjs";
|
|
7
|
+
import { t as it } from "../dist-nohcnkD6.mjs";
|
|
8
|
+
import { Effect, Layer, Option, Ref, Schema } from "effect";
|
|
9
|
+
//#region src/decision-model/Decision.test.ts
|
|
10
|
+
const triage = make({
|
|
11
|
+
inputSchema: Schema.Struct({ message: Schema.String }),
|
|
12
|
+
decisions: {
|
|
13
|
+
department: classify({
|
|
14
|
+
instructions: "Which team should handle this?",
|
|
15
|
+
criteria: {
|
|
16
|
+
billing: "Payments, invoicing",
|
|
17
|
+
technical: "Bugs, outages"
|
|
18
|
+
}
|
|
19
|
+
}),
|
|
20
|
+
severity: rate({
|
|
21
|
+
instructions: "How severe is it?",
|
|
22
|
+
criteria: [
|
|
23
|
+
"Cosmetic",
|
|
24
|
+
"Degraded",
|
|
25
|
+
"Blocking"
|
|
26
|
+
]
|
|
27
|
+
}),
|
|
28
|
+
urgent: probability({ instructions: "Does this convey urgency?" })
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const fixture = {
|
|
32
|
+
department: {
|
|
33
|
+
_tag: "Classify",
|
|
34
|
+
labels: {
|
|
35
|
+
billing: .62,
|
|
36
|
+
technical: .38
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
severity: {
|
|
40
|
+
_tag: "Rate",
|
|
41
|
+
levels: [
|
|
42
|
+
0,
|
|
43
|
+
.7,
|
|
44
|
+
.3
|
|
45
|
+
],
|
|
46
|
+
legend: [
|
|
47
|
+
"Cosmetic",
|
|
48
|
+
"Degraded",
|
|
49
|
+
"Blocking"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
urgent: {
|
|
53
|
+
_tag: "Probability",
|
|
54
|
+
probability: .94
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* A fixed fixture cannot prove it satisfies the caller's `Answers<D>`. This is
|
|
59
|
+
* the boundary a provider casts at too, once it has decoded the wire.
|
|
60
|
+
*/
|
|
61
|
+
const fixed = (answers) => answers;
|
|
62
|
+
/** A `DecisionModel` layer that records what reached it. */
|
|
63
|
+
const recording = Effect.gen(function* () {
|
|
64
|
+
const calls = yield* Ref.make([]);
|
|
65
|
+
return {
|
|
66
|
+
calls,
|
|
67
|
+
layer: Layer.succeed(DecisionModel, { decide: (_definition, request) => Effect.as(Ref.update(calls, (seen) => [...seen, {
|
|
68
|
+
input: request.input,
|
|
69
|
+
model: request.model
|
|
70
|
+
}]), {
|
|
71
|
+
answers: fixed(fixture),
|
|
72
|
+
usage: {}
|
|
73
|
+
}) })
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
describe("the answer map is derived from the definition", () => {
|
|
77
|
+
it.effect("keeps each decision's label keys and rejects labels it never had", () => Effect.gen(function* () {
|
|
78
|
+
const { calls, layer } = yield* recording;
|
|
79
|
+
const result = yield* decide(triage, {
|
|
80
|
+
model: "jev-latest",
|
|
81
|
+
input: { message: "hi" }
|
|
82
|
+
}).pipe(Effect.provide(layer));
|
|
83
|
+
(0, import_dist.expectTypeOf)(result.answers.department.labels).toEqualTypeOf();
|
|
84
|
+
result.answers.department.labels.shipping;
|
|
85
|
+
result.answers.urgent.labels;
|
|
86
|
+
globalExpect(yield* Ref.get(calls)).toEqual([{
|
|
87
|
+
input: { message: "hi" },
|
|
88
|
+
model: "jev-latest"
|
|
89
|
+
}]);
|
|
90
|
+
}));
|
|
91
|
+
it("keeps the rubric as a tuple, so levels are positional rather than parsed", () => {
|
|
92
|
+
(0, import_dist.expectTypeOf)().toEqualTypeOf();
|
|
93
|
+
(0, import_dist.expectTypeOf)().toEqualTypeOf();
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
describe("reading an answer", () => {
|
|
97
|
+
it("derives a Probability answer's distribution as [p, 1 - p]", () => {
|
|
98
|
+
const [yes, no] = probabilitiesOf(fixture.urgent);
|
|
99
|
+
globalExpect(yes).toBeCloseTo(.94, 10);
|
|
100
|
+
globalExpect(no).toBeCloseTo(.06, 10);
|
|
101
|
+
});
|
|
102
|
+
it("ranks labels best first and names the winner", () => {
|
|
103
|
+
globalExpect(ranked(fixture.department)).toEqual([{
|
|
104
|
+
label: "billing",
|
|
105
|
+
probability: .62
|
|
106
|
+
}, {
|
|
107
|
+
label: "technical",
|
|
108
|
+
probability: .38
|
|
109
|
+
}]);
|
|
110
|
+
globalExpect(winner(fixture.department)).toStrictEqual(Option.some("billing"));
|
|
111
|
+
});
|
|
112
|
+
it("has no winner for an empty label set", () => {
|
|
113
|
+
globalExpect(winner({
|
|
114
|
+
_tag: "Classify",
|
|
115
|
+
labels: {}
|
|
116
|
+
})).toStrictEqual(Option.none());
|
|
117
|
+
});
|
|
118
|
+
it("reads a rubric by index and by expected value", () => {
|
|
119
|
+
globalExpect(topLevel(fixture.severity)).toBe(1);
|
|
120
|
+
globalExpect(expectedLevel(fixture.severity)).toBeCloseTo(1.3, 10);
|
|
121
|
+
globalExpect(fixture.severity.legend[topLevel(fixture.severity)]).toBe("Degraded");
|
|
122
|
+
});
|
|
123
|
+
it("resolves a level tie to the lowest index", () => {
|
|
124
|
+
globalExpect(topLevel({
|
|
125
|
+
_tag: "Rate",
|
|
126
|
+
levels: [.5, .5],
|
|
127
|
+
legend: ["a", "b"]
|
|
128
|
+
})).toBe(0);
|
|
129
|
+
});
|
|
130
|
+
it("computes certainty for every kind, including Probability", () => {
|
|
131
|
+
globalExpect(confidence(fixture.urgent)).toBeCloseTo(.67, 2);
|
|
132
|
+
globalExpect(margin(fixture.urgent)).toBeCloseTo(.88, 10);
|
|
133
|
+
globalExpect(margin(fixture.department)).toBeCloseTo(.24, 10);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe("assertKinds", () => {
|
|
137
|
+
const supported = ["Classify", "Probability"];
|
|
138
|
+
it.effect("passes when every kind is supported", () => {
|
|
139
|
+
const { department, urgent } = triage.decisions;
|
|
140
|
+
return assertKinds({
|
|
141
|
+
department,
|
|
142
|
+
urgent
|
|
143
|
+
}, supported, "nli");
|
|
144
|
+
});
|
|
145
|
+
it.effect("fails Unsupported and names every offender at once", () => Effect.gen(function* () {
|
|
146
|
+
const decisions = {
|
|
147
|
+
...triage.decisions,
|
|
148
|
+
impact: rate({
|
|
149
|
+
instructions: "How bad?",
|
|
150
|
+
criteria: ["low", "high"]
|
|
151
|
+
})
|
|
152
|
+
};
|
|
153
|
+
const error = yield* Effect.flip(assertKinds(decisions, supported, "nli"));
|
|
154
|
+
globalExpect(error).toBeInstanceOf(Unsupported);
|
|
155
|
+
if (error._tag !== "Unsupported") return;
|
|
156
|
+
globalExpect(error.reason).toContain("\"severity\" is a Rate");
|
|
157
|
+
globalExpect(error.reason).toContain("\"impact\" is a Rate");
|
|
158
|
+
globalExpect(error.reason).not.toContain("department");
|
|
159
|
+
}));
|
|
160
|
+
});
|
|
161
|
+
//#endregion
|
|
162
|
+
export {};
|
|
163
|
+
|
|
164
|
+
//# sourceMappingURL=Decision.test.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Decision.test.mjs","names":["Decision.make","Decision.classify","Decision.rate","Decision.probability","Decision.probabilitiesOf","Decision.ranked","Decision.winner","Decision.topLevel","Decision.expectedLevel","Decision.confidence","Decision.margin","Decision.assertKinds","AiError.Unsupported"],"sources":["../../src/decision-model/Decision.test.ts"],"sourcesContent":["import { describe, it } from \"@effect/vitest\"\nimport { Effect, Layer, Option, Ref, Schema } from \"effect\"\nimport { expect, expectTypeOf } from \"vitest\"\nimport * as AiError from \"../domain/AiError.js\"\nimport * as Decision from \"./Decision.js\"\nimport { decide, DecisionModel, type DecisionModelService } from \"./DecisionModel.js\"\n\nconst triage = Decision.make({\n inputSchema: Schema.Struct({ message: Schema.String }),\n decisions: {\n department: Decision.classify({\n instructions: \"Which team should handle this?\",\n criteria: { billing: \"Payments, invoicing\", technical: \"Bugs, outages\" },\n }),\n severity: Decision.rate({\n instructions: \"How severe is it?\",\n criteria: [\"Cosmetic\", \"Degraded\", \"Blocking\"],\n }),\n urgent: Decision.probability({ instructions: \"Does this convey urgency?\" }),\n },\n})\n\nconst fixture = {\n department: { _tag: \"Classify\", labels: { billing: 0.62, technical: 0.38 } },\n severity: { _tag: \"Rate\", levels: [0, 0.7, 0.3], legend: [\"Cosmetic\", \"Degraded\", \"Blocking\"] },\n urgent: { _tag: \"Probability\", probability: 0.94 },\n} as const\n\n/**\n * A fixed fixture cannot prove it satisfies the caller's `Answers<D>`. This is\n * the boundary a provider casts at too, once it has decoded the wire.\n */\nconst fixed = <D extends Decision.Decisions>(\n answers: Readonly<Record<string, Decision.Answer>>,\n): Decision.Answers<D> => answers as Decision.Answers<D>\n\ntype Call = { readonly input: unknown; readonly model: string }\n\n/** A `DecisionModel` layer that records what reached it. */\nconst recording = Effect.gen(function* () {\n const calls = yield* Ref.make<ReadonlyArray<Call>>([])\n const service: DecisionModelService = {\n decide: (_definition, request) =>\n Effect.as(\n Ref.update(calls, (seen) => [...seen, { input: request.input, model: request.model }]),\n { answers: fixed(fixture), usage: {} },\n ),\n }\n return { calls, layer: Layer.succeed(DecisionModel, service) }\n})\n\ndescribe(\"the answer map is derived from the definition\", () => {\n it.effect(\"keeps each decision's label keys and rejects labels it never had\", () =>\n Effect.gen(function* () {\n const { calls, layer } = yield* recording\n const result = yield* decide(triage, {\n model: \"jev-latest\",\n input: { message: \"hi\" },\n }).pipe(Effect.provide(layer))\n\n expectTypeOf(result.answers.department.labels).toEqualTypeOf<{\n readonly billing: number\n readonly technical: number\n }>()\n // @ts-expect-error shipping is not a label of this decision\n result.answers.department.labels.shipping\n // @ts-expect-error a Probability answer has no labels\n result.answers.urgent.labels\n\n // `decide` forwards both arguments rather than dropping either.\n expect(yield* Ref.get(calls)).toEqual([{ input: { message: \"hi\" }, model: \"jev-latest\" }])\n }),\n )\n\n it(\"keeps the rubric as a tuple, so levels are positional rather than parsed\", () => {\n type Severity = (typeof triage)[\"decisions\"][\"severity\"]\n expectTypeOf<Decision.AnswerFor<Severity>[\"levels\"]>().toEqualTypeOf<\n readonly [number, number, number]\n >()\n expectTypeOf<Decision.AnswerFor<Severity>[\"legend\"]>().toEqualTypeOf<\n readonly [\"Cosmetic\", \"Degraded\", \"Blocking\"]\n >()\n })\n})\n\ndescribe(\"reading an answer\", () => {\n it(\"derives a Probability answer's distribution as [p, 1 - p]\", () => {\n const [yes, no] = Decision.probabilitiesOf(fixture.urgent)\n expect(yes).toBeCloseTo(0.94, 10)\n expect(no).toBeCloseTo(0.06, 10)\n })\n\n it(\"ranks labels best first and names the winner\", () => {\n expect(Decision.ranked(fixture.department)).toEqual([\n { label: \"billing\", probability: 0.62 },\n { label: \"technical\", probability: 0.38 },\n ])\n expect(Decision.winner(fixture.department)).toStrictEqual(Option.some(\"billing\"))\n })\n\n it(\"has no winner for an empty label set\", () => {\n expect(Decision.winner({ _tag: \"Classify\", labels: {} })).toStrictEqual(Option.none())\n })\n\n it(\"reads a rubric by index and by expected value\", () => {\n expect(Decision.topLevel(fixture.severity)).toBe(1)\n expect(Decision.expectedLevel(fixture.severity)).toBeCloseTo(1.3, 10)\n expect(fixture.severity.legend[Decision.topLevel(fixture.severity)]).toBe(\"Degraded\")\n })\n\n it(\"resolves a level tie to the lowest index\", () => {\n expect(Decision.topLevel({ _tag: \"Rate\", levels: [0.5, 0.5], legend: [\"a\", \"b\"] })).toBe(0)\n })\n\n it(\"computes certainty for every kind, including Probability\", () => {\n expect(Decision.confidence(fixture.urgent)).toBeCloseTo(0.67, 2)\n expect(Decision.margin(fixture.urgent)).toBeCloseTo(0.88, 10)\n expect(Decision.margin(fixture.department)).toBeCloseTo(0.24, 10)\n })\n})\n\ndescribe(\"assertKinds\", () => {\n const supported = [\"Classify\", \"Probability\"] as const\n\n it.effect(\"passes when every kind is supported\", () => {\n const { department, urgent } = triage.decisions\n return Decision.assertKinds({ department, urgent }, supported, \"nli\")\n })\n\n it.effect(\"fails Unsupported and names every offender at once\", () =>\n Effect.gen(function* () {\n const decisions = {\n ...triage.decisions,\n impact: Decision.rate({ instructions: \"How bad?\", criteria: [\"low\", \"high\"] }),\n }\n const error = yield* Effect.flip(Decision.assertKinds(decisions, supported, \"nli\"))\n\n expect(error).toBeInstanceOf(AiError.Unsupported)\n if (error._tag !== \"Unsupported\") return\n\n expect(error.reason).toContain('\"severity\" is a Rate')\n expect(error.reason).toContain('\"impact\" is a Rate')\n expect(error.reason).not.toContain(\"department\")\n }),\n )\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { t as AiError } from "../AiError-DvhLIbmd.mjs";
|
|
2
|
+
import { Answers, Decisions, Definition } from "./Decision.mjs";
|
|
3
|
+
import { Context, Effect } from "effect";
|
|
4
|
+
declare namespace DecisionModel_d_exports {
|
|
5
|
+
export { CommonDecideRequest, DecideResponse, DecideUsage, DecisionModel, DecisionModelService, decide };
|
|
6
|
+
}
|
|
7
|
+
/** Optional throughout: not every backing reports token counts. */
|
|
8
|
+
type DecideUsage = {
|
|
9
|
+
readonly inputTokens?: number;
|
|
10
|
+
readonly outputTokens?: number;
|
|
11
|
+
};
|
|
12
|
+
type DecideResponse<D extends Decisions = Decisions> = {
|
|
13
|
+
readonly answers: Answers<D>;
|
|
14
|
+
readonly usage: DecideUsage;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Cross-provider decide request. The input is billed once for the whole
|
|
18
|
+
* definition, so batching decisions is cheaper than repeating the input.
|
|
19
|
+
*/
|
|
20
|
+
type CommonDecideRequest<A> = {
|
|
21
|
+
readonly input: A;
|
|
22
|
+
/** Each provider narrows this to its typed literal union. */
|
|
23
|
+
readonly model: string;
|
|
24
|
+
};
|
|
25
|
+
type DecisionModelService = {
|
|
26
|
+
readonly decide: <A, D extends Decisions>(definition: Definition<A, D>, request: CommonDecideRequest<A>) => Effect.Effect<DecideResponse<D>, AiError>;
|
|
27
|
+
};
|
|
28
|
+
declare const DecisionModel_base: Context.ServiceClass<DecisionModel, "@betalyra/effect-uai/DecisionModel", DecisionModelService>;
|
|
29
|
+
/**
|
|
30
|
+
* Answering typed questions about an input with probabilities instead of
|
|
31
|
+
* generating text. The model reports beliefs; the decision stays in the
|
|
32
|
+
* caller's code.
|
|
33
|
+
*
|
|
34
|
+
* Implementor contract: answer every decision or fail. Omitting one leaves a
|
|
35
|
+
* hole where {@link DecideResponse} promises a key, so a kind the backing
|
|
36
|
+
* cannot express is rejected up front with `Decision.assertKinds`.
|
|
37
|
+
*
|
|
38
|
+
* @experimental The model class this abstracts is new and the shape may change.
|
|
39
|
+
*/
|
|
40
|
+
declare class DecisionModel extends DecisionModel_base {}
|
|
41
|
+
/** Answer a definition's decisions about one input in one call. */
|
|
42
|
+
declare const decide: <A, D extends Decisions>(definition: Definition<A, D>, request: CommonDecideRequest<A>) => Effect.Effect<DecideResponse<D>, AiError, DecisionModel>;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { CommonDecideRequest, DecideResponse, DecideUsage, DecisionModel, DecisionModelService, decide, DecisionModel_d_exports as t };
|
|
45
|
+
//# sourceMappingURL=DecisionModel.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DecisionModel.d.mts","names":[],"sources":["../../src/decision-model/DecisionModel.ts"],"mappings":";;;;;;;KAKY;WACD;WACA;;KAGC,eAAe,UAAU,YAAqB;WAC/C,SAAS,QAAiB;WAC1B,OAAO;;;;;;KAON,oBAAoB;WACrB,OAAO;;WAEP;;KAGC;WACD,SAAS,GAAG,UAAU,WAC7B,YAAY,WAAoB,GAAG,IACnC,SAAS,oBAAoB,OAC1B,OAAO,OAAO,eAAe,IAAI;;;;;;;;;;;;;;cAc3B,sBAAsB;;cAKtB,SAAU,GAAG,UAAU,WAAkB,YACxC,WAAoB,GAAG,IAAE,SAC5B,oBAAoB,OAC5B,OAAO,OAAO,eAAe,IAAI,SAAiB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { n as __exportAll } from "../rolldown-runtime-EAsCxrDo.mjs";
|
|
2
|
+
import { Context, Effect } from "effect";
|
|
3
|
+
//#region src/decision-model/DecisionModel.ts
|
|
4
|
+
var DecisionModel_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
DecisionModel: () => DecisionModel,
|
|
6
|
+
decide: () => decide
|
|
7
|
+
});
|
|
8
|
+
/**
|
|
9
|
+
* Answering typed questions about an input with probabilities instead of
|
|
10
|
+
* generating text. The model reports beliefs; the decision stays in the
|
|
11
|
+
* caller's code.
|
|
12
|
+
*
|
|
13
|
+
* Implementor contract: answer every decision or fail. Omitting one leaves a
|
|
14
|
+
* hole where {@link DecideResponse} promises a key, so a kind the backing
|
|
15
|
+
* cannot express is rejected up front with `Decision.assertKinds`.
|
|
16
|
+
*
|
|
17
|
+
* @experimental The model class this abstracts is new and the shape may change.
|
|
18
|
+
*/
|
|
19
|
+
var DecisionModel = class extends Context.Service()("@betalyra/effect-uai/DecisionModel") {};
|
|
20
|
+
/** Answer a definition's decisions about one input in one call. */
|
|
21
|
+
const decide = (definition, request) => Effect.flatMap(DecisionModel, (m) => m.decide(definition, request));
|
|
22
|
+
//#endregion
|
|
23
|
+
export { DecisionModel, decide, DecisionModel_exports as t };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=DecisionModel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DecisionModel.mjs","names":[],"sources":["../../src/decision-model/DecisionModel.ts"],"sourcesContent":["import { Context, Effect } from \"effect\"\nimport type * as AiError from \"../domain/AiError.js\"\nimport type * as Decision from \"./Decision.js\"\n\n/** Optional throughout: not every backing reports token counts. */\nexport type DecideUsage = {\n readonly inputTokens?: number\n readonly outputTokens?: number\n}\n\nexport type DecideResponse<D extends Decision.Decisions = Decision.Decisions> = {\n readonly answers: Decision.Answers<D>\n readonly usage: DecideUsage\n}\n\n/**\n * Cross-provider decide request. The input is billed once for the whole\n * definition, so batching decisions is cheaper than repeating the input.\n */\nexport type CommonDecideRequest<A> = {\n readonly input: A\n /** Each provider narrows this to its typed literal union. */\n readonly model: string\n}\n\nexport type DecisionModelService = {\n readonly decide: <A, D extends Decision.Decisions>(\n definition: Decision.Definition<A, D>,\n request: CommonDecideRequest<A>,\n ) => Effect.Effect<DecideResponse<D>, AiError.AiError>\n}\n\n/**\n * Answering typed questions about an input with probabilities instead of\n * generating text. The model reports beliefs; the decision stays in the\n * caller's code.\n *\n * Implementor contract: answer every decision or fail. Omitting one leaves a\n * hole where {@link DecideResponse} promises a key, so a kind the backing\n * cannot express is rejected up front with `Decision.assertKinds`.\n *\n * @experimental The model class this abstracts is new and the shape may change.\n */\nexport class DecisionModel extends Context.Service<DecisionModel, DecisionModelService>()(\n \"@betalyra/effect-uai/DecisionModel\",\n) {}\n\n/** Answer a definition's decisions about one input in one call. */\nexport const decide = <A, D extends Decision.Decisions>(\n definition: Decision.Definition<A, D>,\n request: CommonDecideRequest<A>,\n): Effect.Effect<DecideResponse<D>, AiError.AiError, DecisionModel> =>\n Effect.flatMap(DecisionModel, (m) => m.decide(definition, request))\n"],"mappings":";;;;;;;;;;;;;;;;;;AA2CA,IAAa,gBAAb,cAAmC,QAAQ,QAA6C,CAAC,CACvF,oCACF,CAAC,CAAC,CAAC;;AAGH,MAAa,UACX,YACA,YAEA,OAAO,QAAQ,gBAAgB,MAAM,EAAE,OAAO,YAAY,OAAO,CAAC"}
|
package/dist/index.d.mts
CHANGED
|
@@ -8,6 +8,8 @@ import { t as BrowserTool_d_exports } from "./browser/BrowserTool.mjs";
|
|
|
8
8
|
import { t as Capabilities_d_exports } from "./capabilities/Capabilities.mjs";
|
|
9
9
|
import { n as AiError_d_exports } from "./AiError-DvhLIbmd.mjs";
|
|
10
10
|
import { t as Chunker_d_exports } from "./chunker/Chunker.mjs";
|
|
11
|
+
import { t as Decision_d_exports } from "./decision-model/Decision.mjs";
|
|
12
|
+
import { t as DecisionModel_d_exports } from "./decision-model/DecisionModel.mjs";
|
|
11
13
|
import { o as Audio_d_exports } from "./Audio-_nGR4V0X.mjs";
|
|
12
14
|
import { t as Citation_d_exports } from "./domain/Citation.mjs";
|
|
13
15
|
import { t as Music_d_exports } from "./domain/Music.mjs";
|
|
@@ -43,6 +45,7 @@ import { t as WebRead_d_exports } from "./web-read/WebRead.mjs";
|
|
|
43
45
|
import { t as WebReadTool_d_exports } from "./web-read/WebReadTool.mjs";
|
|
44
46
|
import { t as WebSearch_d_exports } from "./web-search/WebSearch.mjs";
|
|
45
47
|
import { t as WebSearchTool_d_exports } from "./web-search/WebSearchTool.mjs";
|
|
48
|
+
import { t as Probability_d_exports } from "./math/Probability.mjs";
|
|
46
49
|
import { t as Vector_d_exports } from "./math/Vector.mjs";
|
|
47
50
|
import { t as Tokenizer_d_exports } from "./tokenizer/Tokenizer.mjs";
|
|
48
51
|
import { t as Settle_d_exports } from "./streaming/Settle.mjs";
|
|
@@ -56,4 +59,4 @@ import { t as Multipart_d_exports } from "./streaming/Multipart.mjs";
|
|
|
56
59
|
import { t as SSE_d_exports } from "./streaming/SSE.mjs";
|
|
57
60
|
import { t as Metrics_d_exports } from "./observability/Metrics.mjs";
|
|
58
61
|
import { t as Telemetry_d_exports } from "./observability/Telemetry.mjs";
|
|
59
|
-
export { AiError_d_exports as AiError, Approval_d_exports as Approval, Audio_d_exports as Audio, Browser_d_exports as Browser, BrowserError_d_exports as BrowserError, BrowserTool_d_exports as BrowserTool, Capabilities_d_exports as Capabilities, Chunker_d_exports as Chunker, Citation_d_exports as Citation, DeepResearch_d_exports as DeepResearch, Embedding_d_exports as Embedding, EmbeddingModel_d_exports as EmbeddingModel, HistoryCheck_d_exports as HistoryCheck, Image_d_exports as Image, ImageGenerator_d_exports as ImageGenerator, Items_d_exports as Items, JSONL_d_exports as JSONL, Job_d_exports as Job, LanguageModel_d_exports as LanguageModel, Lines_d_exports as Lines, Loop_d_exports as Loop, Media_d_exports as Media, Memory_d_exports as Memory, Messenger_d_exports as Messenger, MessengerAdapter_d_exports as MessengerAdapter, MessengerError_d_exports as MessengerError, Metrics_d_exports as Metrics, Multipart_d_exports as Multipart, Music_d_exports as Music, MusicGenerator_d_exports as MusicGenerator, Realtime_d_exports as Realtime, RealtimeSession_d_exports as RealtimeSession, Reranker_d_exports as Reranker, Research_d_exports as Research, Retry_d_exports as Retry, SSE_d_exports as SSE, Sandbox_d_exports as Sandbox, SandboxError_d_exports as SandboxError, SandboxImage_d_exports as SandboxImage, SandboxNetwork_d_exports as SandboxNetwork, Settle_d_exports as Settle, SpeechSynthesizer_d_exports as SpeechSynthesizer, StructuredFormat_d_exports as StructuredFormat, Telemetry_d_exports as Telemetry, Tokenizer_d_exports as Tokenizer, Tool_d_exports as Tool, ToolEvent_d_exports as ToolEvent, ToolResult_d_exports as ToolResult, Toolkit_d_exports as Toolkit, Transcriber_d_exports as Transcriber, Transcript_d_exports as Transcript, Turn_d_exports as Turn, Vector_d_exports as Vector, WebRead_d_exports as WebRead, WebReadTool_d_exports as WebReadTool, WebSearch_d_exports as WebSearch, WebSearchTool_d_exports as WebSearchTool, WebSocketSession_d_exports as WebSocketSession };
|
|
62
|
+
export { AiError_d_exports as AiError, Approval_d_exports as Approval, Audio_d_exports as Audio, Browser_d_exports as Browser, BrowserError_d_exports as BrowserError, BrowserTool_d_exports as BrowserTool, Capabilities_d_exports as Capabilities, Chunker_d_exports as Chunker, Citation_d_exports as Citation, Decision_d_exports as Decision, DecisionModel_d_exports as DecisionModel, DeepResearch_d_exports as DeepResearch, Embedding_d_exports as Embedding, EmbeddingModel_d_exports as EmbeddingModel, HistoryCheck_d_exports as HistoryCheck, Image_d_exports as Image, ImageGenerator_d_exports as ImageGenerator, Items_d_exports as Items, JSONL_d_exports as JSONL, Job_d_exports as Job, LanguageModel_d_exports as LanguageModel, Lines_d_exports as Lines, Loop_d_exports as Loop, Media_d_exports as Media, Memory_d_exports as Memory, Messenger_d_exports as Messenger, MessengerAdapter_d_exports as MessengerAdapter, MessengerError_d_exports as MessengerError, Metrics_d_exports as Metrics, Multipart_d_exports as Multipart, Music_d_exports as Music, MusicGenerator_d_exports as MusicGenerator, Probability_d_exports as Probability, Realtime_d_exports as Realtime, RealtimeSession_d_exports as RealtimeSession, Reranker_d_exports as Reranker, Research_d_exports as Research, Retry_d_exports as Retry, SSE_d_exports as SSE, Sandbox_d_exports as Sandbox, SandboxError_d_exports as SandboxError, SandboxImage_d_exports as SandboxImage, SandboxNetwork_d_exports as SandboxNetwork, Settle_d_exports as Settle, SpeechSynthesizer_d_exports as SpeechSynthesizer, StructuredFormat_d_exports as StructuredFormat, Telemetry_d_exports as Telemetry, Tokenizer_d_exports as Tokenizer, Tool_d_exports as Tool, ToolEvent_d_exports as ToolEvent, ToolResult_d_exports as ToolResult, Toolkit_d_exports as Toolkit, Transcriber_d_exports as Transcriber, Transcript_d_exports as Transcript, Turn_d_exports as Turn, Vector_d_exports as Vector, WebRead_d_exports as WebRead, WebReadTool_d_exports as WebReadTool, WebSearch_d_exports as WebSearch, WebSearchTool_d_exports as WebSearchTool, WebSocketSession_d_exports as WebSocketSession };
|
package/dist/index.mjs
CHANGED
|
@@ -16,6 +16,9 @@ import { t as BrowserTool_exports } from "./browser/BrowserTool.mjs";
|
|
|
16
16
|
import { t as Capabilities_exports } from "./capabilities/Capabilities.mjs";
|
|
17
17
|
import { t as Chunker_exports } from "./chunker/Chunker.mjs";
|
|
18
18
|
import { t as Citation_exports } from "./domain/Citation.mjs";
|
|
19
|
+
import { t as Probability_exports } from "./math/Probability.mjs";
|
|
20
|
+
import { t as Decision_exports } from "./decision-model/Decision.mjs";
|
|
21
|
+
import { t as DecisionModel_exports } from "./decision-model/DecisionModel.mjs";
|
|
19
22
|
import { t as Job_exports } from "./job/Job.mjs";
|
|
20
23
|
import { t as DeepResearch_exports } from "./research/DeepResearch.mjs";
|
|
21
24
|
import { t as Music_exports } from "./domain/Music.mjs";
|
|
@@ -56,4 +59,4 @@ import { t as Multipart_exports } from "./streaming/Multipart.mjs";
|
|
|
56
59
|
import { t as SSE_exports } from "./streaming/SSE.mjs";
|
|
57
60
|
import { t as Metrics_exports } from "./observability/Metrics.mjs";
|
|
58
61
|
import { t as Telemetry_exports } from "./observability/Telemetry.mjs";
|
|
59
|
-
export { AiError_exports as AiError, Approval_exports as Approval, Audio_exports as Audio, Browser_exports as Browser, BrowserError_exports as BrowserError, BrowserTool_exports as BrowserTool, Capabilities_exports as Capabilities, Chunker_exports as Chunker, Citation_exports as Citation, DeepResearch_exports as DeepResearch, Embedding_exports as Embedding, EmbeddingModel_exports as EmbeddingModel, HistoryCheck_exports as HistoryCheck, Image_exports as Image, ImageGenerator_exports as ImageGenerator, Items_exports as Items, JSONL_exports as JSONL, Job_exports as Job, LanguageModel_exports as LanguageModel, Lines_exports as Lines, Loop_exports as Loop, Media_exports as Media, Memory_exports as Memory, Messenger_exports as Messenger, MessengerAdapter_exports as MessengerAdapter, MessengerError_exports as MessengerError, Metrics_exports as Metrics, Multipart_exports as Multipart, Music_exports as Music, MusicGenerator_exports as MusicGenerator, Realtime_exports as Realtime, RealtimeSession_exports as RealtimeSession, Reranker_exports as Reranker, Research_exports as Research, Retry_exports as Retry, SSE_exports as SSE, Sandbox_exports as Sandbox, SandboxError_exports as SandboxError, SandboxImage_exports as SandboxImage, SandboxNetwork_exports as SandboxNetwork, Settle_exports as Settle, SpeechSynthesizer_exports as SpeechSynthesizer, StructuredFormat_exports as StructuredFormat, Telemetry_exports as Telemetry, Tokenizer_exports as Tokenizer, Tool_exports as Tool, ToolEvent_exports as ToolEvent, ToolResult_exports as ToolResult, Toolkit_exports as Toolkit, Transcriber_exports as Transcriber, Transcript_exports as Transcript, Turn_exports as Turn, Vector_exports as Vector, WebRead_exports as WebRead, WebReadTool_exports as WebReadTool, WebSearch_exports as WebSearch, WebSearchTool_exports as WebSearchTool, WebSocketSession_exports as WebSocketSession };
|
|
62
|
+
export { AiError_exports as AiError, Approval_exports as Approval, Audio_exports as Audio, Browser_exports as Browser, BrowserError_exports as BrowserError, BrowserTool_exports as BrowserTool, Capabilities_exports as Capabilities, Chunker_exports as Chunker, Citation_exports as Citation, Decision_exports as Decision, DecisionModel_exports as DecisionModel, DeepResearch_exports as DeepResearch, Embedding_exports as Embedding, EmbeddingModel_exports as EmbeddingModel, HistoryCheck_exports as HistoryCheck, Image_exports as Image, ImageGenerator_exports as ImageGenerator, Items_exports as Items, JSONL_exports as JSONL, Job_exports as Job, LanguageModel_exports as LanguageModel, Lines_exports as Lines, Loop_exports as Loop, Media_exports as Media, Memory_exports as Memory, Messenger_exports as Messenger, MessengerAdapter_exports as MessengerAdapter, MessengerError_exports as MessengerError, Metrics_exports as Metrics, Multipart_exports as Multipart, Music_exports as Music, MusicGenerator_exports as MusicGenerator, Probability_exports as Probability, Realtime_exports as Realtime, RealtimeSession_exports as RealtimeSession, Reranker_exports as Reranker, Research_exports as Research, Retry_exports as Retry, SSE_exports as SSE, Sandbox_exports as Sandbox, SandboxError_exports as SandboxError, SandboxImage_exports as SandboxImage, SandboxNetwork_exports as SandboxNetwork, Settle_exports as Settle, SpeechSynthesizer_exports as SpeechSynthesizer, StructuredFormat_exports as StructuredFormat, Telemetry_exports as Telemetry, Tokenizer_exports as Tokenizer, Tool_exports as Tool, ToolEvent_exports as ToolEvent, ToolResult_exports as ToolResult, Toolkit_exports as Toolkit, Transcriber_exports as Transcriber, Transcript_exports as Transcript, Turn_exports as Turn, Vector_exports as Vector, WebRead_exports as WebRead, WebReadTool_exports as WebReadTool, WebSearch_exports as WebSearch, WebSearchTool_exports as WebSearchTool, WebSocketSession_exports as WebSocketSession };
|