@effect-agent/ai-decision 0.1.0-beta.102
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/README.md +47 -0
- package/dist/DecisionModel-BQpmPcHb.mjs +96 -0
- package/dist/DecisionModel-BQpmPcHb.mjs.map +1 -0
- package/dist/DecisionModel.d.mts +37 -0
- package/dist/DecisionModel.mjs +3 -0
- package/dist/DecisionQuery.d.mts +59 -0
- package/dist/DecisionQuery.mjs +48 -0
- package/dist/DecisionQuery.mjs.map +1 -0
- package/dist/DecisionSchema.d.mts +313 -0
- package/dist/DecisionSchema.mjs +177 -0
- package/dist/DecisionSchema.mjs.map +1 -0
- package/dist/DecisionSet.d.mts +27 -0
- package/dist/DecisionSet.mjs +20 -0
- package/dist/DecisionSet.mjs.map +1 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +5 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/package.json +1 -0
- package/src/DecisionModel.ts +144 -0
- package/src/DecisionQuery.ts +56 -0
- package/src/DecisionSchema.ts +295 -0
- package/src/DecisionSet.ts +36 -0
- package/src/index.ts +4 -0
- package/src/internal/schema.ts +98 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
//#region src/DecisionSchema.ts
|
|
4
|
+
/**
|
|
5
|
+
* Request and response schemas for provider-neutral decision evaluations.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.1.0
|
|
8
|
+
*/
|
|
9
|
+
var DecisionSchema_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
+
Answer: () => Answer,
|
|
11
|
+
ChoiceAnswer: () => ChoiceAnswer,
|
|
12
|
+
ChoiceQuestion: () => ChoiceQuestion,
|
|
13
|
+
Content: () => Content,
|
|
14
|
+
EvaluateRequest: () => EvaluateRequest,
|
|
15
|
+
EvaluateResponse: () => EvaluateResponse,
|
|
16
|
+
Probability: () => Probability,
|
|
17
|
+
ProbabilityAnswer: () => ProbabilityAnswer,
|
|
18
|
+
ProbabilityQuestion: () => ProbabilityQuestion,
|
|
19
|
+
ProviderMetadata: () => ProviderMetadata,
|
|
20
|
+
Question: () => Question,
|
|
21
|
+
Questions: () => Questions,
|
|
22
|
+
ScoreAnswer: () => ScoreAnswer,
|
|
23
|
+
ScoreQuestion: () => ScoreQuestion,
|
|
24
|
+
Usage: () => Usage
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Text or JSON objects and arrays used as state and question instructions.
|
|
28
|
+
*
|
|
29
|
+
* @category schemas
|
|
30
|
+
* @since 0.1.0
|
|
31
|
+
*/
|
|
32
|
+
const Content = Schema.Union([
|
|
33
|
+
Schema.String,
|
|
34
|
+
Schema.JsonObject,
|
|
35
|
+
Schema.Array(Schema.Json)
|
|
36
|
+
]);
|
|
37
|
+
/**
|
|
38
|
+
* A choice between named options. A null rubric uses the option name alone.
|
|
39
|
+
*
|
|
40
|
+
* @category schemas
|
|
41
|
+
* @since 0.1.0
|
|
42
|
+
*/
|
|
43
|
+
const ChoiceQuestion = Schema.Struct({
|
|
44
|
+
type: Schema.Literal("choice"),
|
|
45
|
+
instructions: Content,
|
|
46
|
+
criteria: Schema.Record(Schema.String, Schema.NullOr(Schema.String)).check(Schema.isMinProperties(1))
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* A rating along at least two ordered, zero-indexed level descriptions.
|
|
50
|
+
*
|
|
51
|
+
* @category schemas
|
|
52
|
+
* @since 0.1.0
|
|
53
|
+
*/
|
|
54
|
+
const ScoreQuestion = Schema.Struct({
|
|
55
|
+
type: Schema.Literal("score"),
|
|
56
|
+
instructions: Content,
|
|
57
|
+
criteria: Schema.Array(Schema.String).check(Schema.isMinLength(2))
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* A yes/no judgment, with optional descriptions of either outcome.
|
|
61
|
+
*
|
|
62
|
+
* @category schemas
|
|
63
|
+
* @since 0.1.0
|
|
64
|
+
*/
|
|
65
|
+
const ProbabilityQuestion = Schema.Struct({
|
|
66
|
+
type: Schema.Literal("probability"),
|
|
67
|
+
instructions: Content,
|
|
68
|
+
criteria: Schema.optionalKey(Schema.Struct({
|
|
69
|
+
true: Schema.optionalKey(Schema.String),
|
|
70
|
+
false: Schema.optionalKey(Schema.String)
|
|
71
|
+
}))
|
|
72
|
+
});
|
|
73
|
+
/** @category schemas
|
|
74
|
+
* @since 0.1.0
|
|
75
|
+
*/
|
|
76
|
+
const Question = Schema.Union([
|
|
77
|
+
ChoiceQuestion,
|
|
78
|
+
ScoreQuestion,
|
|
79
|
+
ProbabilityQuestion
|
|
80
|
+
]);
|
|
81
|
+
/** @category schemas
|
|
82
|
+
* @since 0.1.0
|
|
83
|
+
*/
|
|
84
|
+
const Questions = Schema.Record(Schema.String, Question);
|
|
85
|
+
/** @category schemas
|
|
86
|
+
* @since 0.1.0
|
|
87
|
+
*/
|
|
88
|
+
const EvaluateRequest = Schema.Struct({
|
|
89
|
+
state: Content,
|
|
90
|
+
questions: Questions
|
|
91
|
+
});
|
|
92
|
+
/**
|
|
93
|
+
* A finite probability or confidence in the inclusive range [0, 1].
|
|
94
|
+
*
|
|
95
|
+
* @category schemas
|
|
96
|
+
* @since 0.1.0
|
|
97
|
+
*/
|
|
98
|
+
const Probability = Schema.Finite.check(Schema.isBetween({
|
|
99
|
+
minimum: 0,
|
|
100
|
+
maximum: 1
|
|
101
|
+
}));
|
|
102
|
+
/**
|
|
103
|
+
* A selected option and its full distribution. Provider-specific confidence
|
|
104
|
+
* statistics belong to evaluation metadata, not the shared answer contract.
|
|
105
|
+
* Probabilities retain the provider's reported precision and are not normalized.
|
|
106
|
+
*
|
|
107
|
+
* @category schemas
|
|
108
|
+
* @since 0.1.0
|
|
109
|
+
*/
|
|
110
|
+
const ChoiceAnswer = Schema.Struct({
|
|
111
|
+
type: Schema.Literal("choice"),
|
|
112
|
+
choice: Schema.String,
|
|
113
|
+
probabilities: Schema.Record(Schema.String, Probability)
|
|
114
|
+
});
|
|
115
|
+
/**
|
|
116
|
+
* A fractional, probability-weighted level, with the supplied rubric as legend.
|
|
117
|
+
*
|
|
118
|
+
* @category schemas
|
|
119
|
+
* @since 0.1.0
|
|
120
|
+
*/
|
|
121
|
+
const ScoreAnswer = Schema.Struct({
|
|
122
|
+
type: Schema.Literal("score"),
|
|
123
|
+
score: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
124
|
+
legend: Schema.Record(Schema.String, Schema.String),
|
|
125
|
+
probabilities: Schema.Record(Schema.String, Probability)
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* The probability of yes. A probability answer has no separate confidence field.
|
|
129
|
+
*
|
|
130
|
+
* @category schemas
|
|
131
|
+
* @since 0.1.0
|
|
132
|
+
*/
|
|
133
|
+
const ProbabilityAnswer = Schema.Struct({
|
|
134
|
+
type: Schema.Literal("probability"),
|
|
135
|
+
probability: Probability
|
|
136
|
+
});
|
|
137
|
+
/** @category schemas
|
|
138
|
+
* @since 0.1.0
|
|
139
|
+
*/
|
|
140
|
+
const Answer = Schema.Union([
|
|
141
|
+
ChoiceAnswer,
|
|
142
|
+
ScoreAnswer,
|
|
143
|
+
ProbabilityAnswer
|
|
144
|
+
]);
|
|
145
|
+
/** @category schemas
|
|
146
|
+
* @since 0.1.0
|
|
147
|
+
*/
|
|
148
|
+
const Usage = Schema.Struct({
|
|
149
|
+
inputTokens: Schema.NullOr(Schema.Natural),
|
|
150
|
+
outputTokens: Schema.NullOr(Schema.Natural)
|
|
151
|
+
});
|
|
152
|
+
/**
|
|
153
|
+
* Provider-namespaced evidence that has no shared interpretation. Consumers
|
|
154
|
+
* decode a namespace with its provider's schema before using its contents.
|
|
155
|
+
*
|
|
156
|
+
* @category schemas
|
|
157
|
+
* @since 0.1.0
|
|
158
|
+
*/
|
|
159
|
+
const ProviderMetadata = Schema.Record(Schema.String, Schema.JsonObject);
|
|
160
|
+
/**
|
|
161
|
+
* The wire response shape. `DecisionModel.evaluate` additionally validates
|
|
162
|
+
* answer IDs, question kinds, criteria, distributions, and score correlations.
|
|
163
|
+
*
|
|
164
|
+
* @category schemas
|
|
165
|
+
* @since 0.1.0
|
|
166
|
+
*/
|
|
167
|
+
const EvaluateResponse = Schema.Struct({
|
|
168
|
+
provider: Schema.NonEmptyString,
|
|
169
|
+
model: Schema.String,
|
|
170
|
+
answers: Schema.Record(Schema.String, Answer),
|
|
171
|
+
usage: Usage,
|
|
172
|
+
providerMetadata: Schema.optionalKey(ProviderMetadata)
|
|
173
|
+
});
|
|
174
|
+
//#endregion
|
|
175
|
+
export { Answer, ChoiceAnswer, ChoiceQuestion, Content, EvaluateRequest, EvaluateResponse, Probability, ProbabilityAnswer, ProbabilityQuestion, ProviderMetadata, Question, Questions, ScoreAnswer, ScoreQuestion, Usage, DecisionSchema_exports as t };
|
|
176
|
+
|
|
177
|
+
//# sourceMappingURL=DecisionSchema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DecisionSchema.mjs","names":[],"sources":["../src/DecisionSchema.ts"],"sourcesContent":["/**\n * Request and response schemas for provider-neutral decision evaluations.\n *\n * @since 0.1.0\n */\nimport * as Schema from \"effect/Schema\";\n\n/**\n * Text or JSON objects and arrays used as state and question instructions.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Content = Schema.Union([Schema.String, Schema.JsonObject, Schema.Array(Schema.Json)]);\n\n/** @category models\n * @since 0.1.0\n */\nexport type Content = typeof Content.Type;\n\n/**\n * A choice between named options. A null rubric uses the option name alone.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ChoiceQuestion = Schema.Struct({\n type: Schema.Literal(\"choice\"),\n instructions: Content,\n criteria: Schema.Record(Schema.String, Schema.NullOr(Schema.String)).check(\n Schema.isMinProperties(1),\n ),\n});\n\n/** @category models\n * @since 0.1.0\n */\nexport type ChoiceQuestion = typeof ChoiceQuestion.Type;\n\n/**\n * A rating along at least two ordered, zero-indexed level descriptions.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ScoreQuestion = Schema.Struct({\n type: Schema.Literal(\"score\"),\n instructions: Content,\n criteria: Schema.Array(Schema.String).check(Schema.isMinLength(2)),\n});\n\n/** @category models\n * @since 0.1.0\n */\nexport type ScoreQuestion = typeof ScoreQuestion.Type;\n\n/**\n * A yes/no judgment, with optional descriptions of either outcome.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ProbabilityQuestion = Schema.Struct({\n type: Schema.Literal(\"probability\"),\n instructions: Content,\n criteria: Schema.optionalKey(\n Schema.Struct({\n true: Schema.optionalKey(Schema.String),\n false: Schema.optionalKey(Schema.String),\n }),\n ),\n});\n\n/** @category models\n * @since 0.1.0\n */\nexport type ProbabilityQuestion = typeof ProbabilityQuestion.Type;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const Question = Schema.Union([ChoiceQuestion, ScoreQuestion, ProbabilityQuestion]);\n\n/** @category models\n * @since 0.1.0\n */\nexport type Question = typeof Question.Type;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const Questions = Schema.Record(Schema.String, Question);\n\n/** @category models\n * @since 0.1.0\n */\nexport type Questions = typeof Questions.Type;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const EvaluateRequest = Schema.Struct({\n state: Content,\n questions: Questions,\n});\n\n/**\n * Evaluation input. Keep question literals with `satisfies Questions` when\n * storing questions separately from the call to `evaluate`.\n *\n * @category models\n * @since 0.1.0\n */\nexport type EvaluateRequest<Q extends Questions = Questions> = Omit<\n typeof EvaluateRequest.Type,\n \"questions\"\n> & { readonly questions: Q };\n\n/**\n * A finite probability or confidence in the inclusive range [0, 1].\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const Probability = Schema.Finite.check(Schema.isBetween({ minimum: 0, maximum: 1 }));\n\n/**\n * A selected option and its full distribution. Provider-specific confidence\n * statistics belong to evaluation metadata, not the shared answer contract.\n * Probabilities retain the provider's reported precision and are not normalized.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ChoiceAnswer = Schema.Struct({\n type: Schema.Literal(\"choice\"),\n choice: Schema.String,\n probabilities: Schema.Record(Schema.String, Probability),\n});\n\n/**\n * Known option unions infer literal choices and required probability keys.\n * Open string or template-pattern option types allow absent dictionary entries.\n *\n * @category models\n * @since 0.1.0\n */\nexport type ChoiceAnswer<Choice extends string = string> = Omit<\n typeof ChoiceAnswer.Type,\n \"choice\" | \"probabilities\"\n> & {\n readonly choice: Choice;\n readonly probabilities: {\n readonly [K in Choice]: {} extends Pick<Record<Choice, unknown>, K>\n ? number | undefined\n : number;\n };\n};\n\n/**\n * A fractional, probability-weighted level, with the supplied rubric as legend.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ScoreAnswer = Schema.Struct({\n type: Schema.Literal(\"score\"),\n score: Schema.Finite.check(Schema.isGreaterThanOrEqualTo(0)),\n legend: Schema.Record(Schema.String, Schema.String),\n probabilities: Schema.Record(Schema.String, Probability),\n});\n\n/**\n * Score levels are keyed at runtime; an arbitrary legend or probability lookup\n * may be absent.\n *\n * @category models\n * @since 0.1.0\n */\nexport type ScoreAnswer = Omit<typeof ScoreAnswer.Type, \"legend\" | \"probabilities\"> & {\n readonly legend: { readonly [level: string]: string | undefined };\n readonly probabilities: { readonly [level: string]: number | undefined };\n};\n\n/**\n * The probability of yes. A probability answer has no separate confidence field.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ProbabilityAnswer = Schema.Struct({\n type: Schema.Literal(\"probability\"),\n probability: Probability,\n});\n\n/** @category models\n * @since 0.1.0\n */\nexport type ProbabilityAnswer = typeof ProbabilityAnswer.Type;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const Answer = Schema.Union([ChoiceAnswer, ScoreAnswer, ProbabilityAnswer]);\n\n/** @category models\n * @since 0.1.0\n */\nexport type Answer = ChoiceAnswer | ScoreAnswer | ProbabilityAnswer;\n\n/** @category schemas\n * @since 0.1.0\n */\nexport const Usage = Schema.Struct({\n inputTokens: Schema.NullOr(Schema.Natural),\n outputTokens: Schema.NullOr(Schema.Natural),\n});\n\n/** @category models\n * @since 0.1.0\n */\nexport type Usage = typeof Usage.Type;\n\n/**\n * Provider-namespaced evidence that has no shared interpretation. Consumers\n * decode a namespace with its provider's schema before using its contents.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const ProviderMetadata = Schema.Record(Schema.String, Schema.JsonObject);\n\n/** @category models\n * @since 0.1.0\n */\nexport type ProviderMetadata = typeof ProviderMetadata.Type;\n\n/**\n * The wire response shape. `DecisionModel.evaluate` additionally validates\n * answer IDs, question kinds, criteria, distributions, and score correlations.\n *\n * @category schemas\n * @since 0.1.0\n */\nexport const EvaluateResponse = Schema.Struct({\n provider: Schema.NonEmptyString,\n model: Schema.String,\n answers: Schema.Record(Schema.String, Answer),\n usage: Usage,\n providerMetadata: Schema.optionalKey(ProviderMetadata),\n});\n\ntype ChoiceAnswerFor<Criteria> = Criteria extends unknown\n ? Omit<typeof ChoiceAnswer.Type, \"choice\" | \"probabilities\"> & {\n readonly choice: `${Extract<keyof Criteria, string | number>}`;\n readonly probabilities: {\n readonly [\n K in keyof Criteria as K extends string | number ? `${K}` : never\n ]: {} extends Pick<Criteria, K> ? number | undefined : number;\n };\n }\n : never;\n\n/**\n * Infer a question's answer, preserving optional choice criteria in its probabilities.\n *\n * @category models\n * @since 0.1.0\n */\nexport type AnswerFor<Q extends Question> = Q extends ChoiceQuestion\n ? ChoiceAnswerFor<Q[\"criteria\"]>\n : Q extends ScoreQuestion\n ? ScoreAnswer\n : ProbabilityAnswer;\n\n/**\n * One answer for each required question. Optional properties and open string,\n * numeric, or template-pattern indexes require checking an entry for absence.\n *\n * @category models\n * @since 0.1.0\n */\nexport type Answers<Q extends Questions> = {\n readonly [K in keyof Q as K extends string | number ? `${K}` : never]: {} extends Pick<Q, K>\n ? AnswerFor<NonNullable<Q[K]>> | undefined\n : AnswerFor<Q[K]>;\n};\n\n/** @category models\n * @since 0.1.0\n */\nexport type EvaluateResponse<Q extends Questions = Questions> = Omit<\n typeof EvaluateResponse.Type,\n \"answers\"\n> & { readonly answers: Answers<Q> };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,MAAa,UAAU,OAAO,MAAM;CAAC,OAAO;CAAQ,OAAO;CAAY,OAAO,MAAM,OAAO,IAAI;AAAC,CAAC;;;;;;;AAajG,MAAa,iBAAiB,OAAO,OAAO;CAC1C,MAAM,OAAO,QAAQ,QAAQ;CAC7B,cAAc;CACd,UAAU,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC,CAAC,MACnE,OAAO,gBAAgB,CAAC,CAC1B;AACF,CAAC;;;;;;;AAaD,MAAa,gBAAgB,OAAO,OAAO;CACzC,MAAM,OAAO,QAAQ,OAAO;CAC5B,cAAc;CACd,UAAU,OAAO,MAAM,OAAO,MAAM,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AACnE,CAAC;;;;;;;AAaD,MAAa,sBAAsB,OAAO,OAAO;CAC/C,MAAM,OAAO,QAAQ,aAAa;CAClC,cAAc;CACd,UAAU,OAAO,YACf,OAAO,OAAO;EACZ,MAAM,OAAO,YAAY,OAAO,MAAM;EACtC,OAAO,OAAO,YAAY,OAAO,MAAM;CACzC,CAAC,CACH;AACF,CAAC;;;;AAUD,MAAa,WAAW,OAAO,MAAM;CAAC;CAAgB;CAAe;AAAmB,CAAC;;;;AAUzF,MAAa,YAAY,OAAO,OAAO,OAAO,QAAQ,QAAQ;;;;AAU9D,MAAa,kBAAkB,OAAO,OAAO;CAC3C,OAAO;CACP,WAAW;AACb,CAAC;;;;;;;AAoBD,MAAa,cAAc,OAAO,OAAO,MAAM,OAAO,UAAU;CAAE,SAAS;CAAG,SAAS;AAAE,CAAC,CAAC;;;;;;;;;AAU3F,MAAa,eAAe,OAAO,OAAO;CACxC,MAAM,OAAO,QAAQ,QAAQ;CAC7B,QAAQ,OAAO;CACf,eAAe,OAAO,OAAO,OAAO,QAAQ,WAAW;AACzD,CAAC;;;;;;;AA2BD,MAAa,cAAc,OAAO,OAAO;CACvC,MAAM,OAAO,QAAQ,OAAO;CAC5B,OAAO,OAAO,OAAO,MAAM,OAAO,uBAAuB,CAAC,CAAC;CAC3D,QAAQ,OAAO,OAAO,OAAO,QAAQ,OAAO,MAAM;CAClD,eAAe,OAAO,OAAO,OAAO,QAAQ,WAAW;AACzD,CAAC;;;;;;;AAoBD,MAAa,oBAAoB,OAAO,OAAO;CAC7C,MAAM,OAAO,QAAQ,aAAa;CAClC,aAAa;AACf,CAAC;;;;AAUD,MAAa,SAAS,OAAO,MAAM;CAAC;CAAc;CAAa;AAAiB,CAAC;;;;AAUjF,MAAa,QAAQ,OAAO,OAAO;CACjC,aAAa,OAAO,OAAO,OAAO,OAAO;CACzC,cAAc,OAAO,OAAO,OAAO,OAAO;AAC5C,CAAC;;;;;;;;AAcD,MAAa,mBAAmB,OAAO,OAAO,OAAO,QAAQ,OAAO,UAAU;;;;;;;;AAc9E,MAAa,mBAAmB,OAAO,OAAO;CAC5C,UAAU,OAAO;CACjB,OAAO,OAAO;CACd,SAAS,OAAO,OAAO,OAAO,QAAQ,MAAM;CAC5C,OAAO;CACP,kBAAkB,OAAO,YAAY,gBAAgB;AACvD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Questions, t as DecisionSchema_d_exports } from "./DecisionSchema.mjs";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
declare namespace DecisionSet_d_exports {
|
|
4
|
+
export { DecisionSet, make };
|
|
5
|
+
}
|
|
6
|
+
/** @category models
|
|
7
|
+
* @since 0.1.0
|
|
8
|
+
*/
|
|
9
|
+
export interface DecisionSet<Input extends Schema.Top, Questions$1 extends Questions> {
|
|
10
|
+
/** The encoded input becomes model-visible state: a string, JSON object, or JSON array. */
|
|
11
|
+
readonly input: Input;
|
|
12
|
+
/** Independent questions evaluated together against that state. */
|
|
13
|
+
readonly questions: Questions$1;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Describe a reusable assessment. Construction performs no encoding or model
|
|
17
|
+
* I/O. Input encoding and question validation occur inside model.evaluate.
|
|
18
|
+
* Treat nested instruction content as readonly; evaluation snapshots it before
|
|
19
|
+
* calling the provider. Dynamic question records are supported.
|
|
20
|
+
*
|
|
21
|
+
* @category constructors
|
|
22
|
+
* @since 0.1.0
|
|
23
|
+
*/
|
|
24
|
+
export declare const make: <Input extends Schema.Top, const Questions$2 extends Questions>(options: DecisionSet<Input, Questions$2>) => DecisionSet<Input, Questions$2>;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { DecisionSet_d_exports as t };
|
|
27
|
+
//# sourceMappingURL=DecisionSet.d.mts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
+
//#region src/DecisionSet.ts
|
|
3
|
+
var DecisionSet_exports = /* @__PURE__ */ __exportAll({ make: () => make });
|
|
4
|
+
/**
|
|
5
|
+
* Describe a reusable assessment. Construction performs no encoding or model
|
|
6
|
+
* I/O. Input encoding and question validation occur inside model.evaluate.
|
|
7
|
+
* Treat nested instruction content as readonly; evaluation snapshots it before
|
|
8
|
+
* calling the provider. Dynamic question records are supported.
|
|
9
|
+
*
|
|
10
|
+
* @category constructors
|
|
11
|
+
* @since 0.1.0
|
|
12
|
+
*/
|
|
13
|
+
const make = (options) => Object.freeze({
|
|
14
|
+
input: options.input,
|
|
15
|
+
questions: Object.freeze({ ...options.questions })
|
|
16
|
+
});
|
|
17
|
+
//#endregion
|
|
18
|
+
export { make, DecisionSet_exports as t };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=DecisionSet.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DecisionSet.mjs","names":[],"sources":["../src/DecisionSet.ts"],"sourcesContent":["/**\n * Reusable question collections with a schema-defined input. The set owns no\n * provider, live resources, routing policy, or execution state.\n *\n * @since 0.1.0\n */\nimport type * as Schema from \"effect/Schema\";\n\nimport type * as DecisionSchema from \"./DecisionSchema.ts\";\n\n/** @category models\n * @since 0.1.0\n */\nexport interface DecisionSet<Input extends Schema.Top, Questions extends DecisionSchema.Questions> {\n /** The encoded input becomes model-visible state: a string, JSON object, or JSON array. */\n readonly input: Input;\n /** Independent questions evaluated together against that state. */\n readonly questions: Questions;\n}\n\n/**\n * Describe a reusable assessment. Construction performs no encoding or model\n * I/O. Input encoding and question validation occur inside model.evaluate.\n * Treat nested instruction content as readonly; evaluation snapshots it before\n * calling the provider. Dynamic question records are supported.\n *\n * @category constructors\n * @since 0.1.0\n */\nexport const make = <Input extends Schema.Top, const Questions extends DecisionSchema.Questions>(\n options: DecisionSet<Input, Questions>,\n): DecisionSet<Input, Questions> =>\n Object.freeze({\n input: options.input,\n questions: Object.freeze({ ...options.questions }),\n });\n"],"mappings":";;;;;;;;;;;;AA6BA,MAAa,QACX,YAEA,OAAO,OAAO;CACZ,OAAO,QAAQ;CACf,WAAW,OAAO,OAAO,EAAE,GAAG,QAAQ,UAAU,CAAC;AACnD,CAAC"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { t as DecisionSchema_d_exports } from "./DecisionSchema.mjs";
|
|
2
|
+
import { t as DecisionSet_d_exports } from "./DecisionSet.mjs";
|
|
3
|
+
import { t as DecisionModel_d_exports } from "./DecisionModel.mjs";
|
|
4
|
+
import { t as DecisionQuery_d_exports } from "./DecisionQuery.mjs";
|
|
5
|
+
export { DecisionModel_d_exports as DecisionModel, DecisionQuery_d_exports as DecisionQuery, DecisionSchema_d_exports as DecisionSchema, DecisionSet_d_exports as DecisionSet };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { t as DecisionSchema_exports } from "./DecisionSchema.mjs";
|
|
2
|
+
import { n as DecisionModel_exports } from "./DecisionModel-BQpmPcHb.mjs";
|
|
3
|
+
import { t as DecisionQuery_exports } from "./DecisionQuery.mjs";
|
|
4
|
+
import { t as DecisionSet_exports } from "./DecisionSet.mjs";
|
|
5
|
+
export { DecisionModel_exports as DecisionModel, DecisionQuery_exports as DecisionQuery, DecisionSchema_exports as DecisionSchema, DecisionSet_exports as DecisionSet };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
package/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"@effect-agent/ai-decision","version":"0.1.0-beta.102","devDependencies":{"@effect/vitest":"4.0.0-rc.115","effect":"4.0.0-rc.115","typescript":"7.0.2","vite-plus":"0.3.2"},"peerDependencies":{"effect":"^4.0.0-rc.115"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./decision-model":{"types":"./dist/DecisionModel.d.mts","default":"./dist/DecisionModel.mjs"},"./decision-query":{"types":"./dist/DecisionQuery.d.mts","default":"./dist/DecisionQuery.mjs"},"./decision-schema":{"types":"./dist/DecisionSchema.d.mts","default":"./dist/DecisionSchema.mjs"},"./decision-set":{"types":"./dist/DecisionSet.d.mts","default":"./dist/DecisionSet.mjs"}},"description":"Provider-neutral choice, score, and probability evaluations with Effect.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/ai-decision"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test"}}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Context, Effect, Schema, type SchemaAST, type Scope } from "effect";
|
|
2
|
+
import { AiError } from "effect/unstable/ai";
|
|
3
|
+
|
|
4
|
+
import * as DecisionSchema from "./DecisionSchema.ts";
|
|
5
|
+
import type * as DecisionSet from "./DecisionSet.ts";
|
|
6
|
+
import { responseFor } from "./internal/schema.ts";
|
|
7
|
+
|
|
8
|
+
/** Typed semantic evaluations; the caller owns thresholds, transitions, and side effects. */
|
|
9
|
+
export interface Service {
|
|
10
|
+
readonly evaluate: {
|
|
11
|
+
<const Q extends DecisionSchema.Questions>(
|
|
12
|
+
request: DecisionSchema.EvaluateRequest<Q>,
|
|
13
|
+
): Effect.Effect<DecisionSchema.EvaluateResponse<Q>, AiError.AiError>;
|
|
14
|
+
/** Encode typed input as state, preserving the schema's encoding requirements. */
|
|
15
|
+
<Input extends Schema.Top, const Q extends DecisionSchema.Questions>(
|
|
16
|
+
set: DecisionSet.DecisionSet<Input, Q>,
|
|
17
|
+
input: NoInfer<Input["Type"]>,
|
|
18
|
+
): Effect.Effect<
|
|
19
|
+
DecisionSchema.EvaluateResponse<Q>,
|
|
20
|
+
AiError.AiError,
|
|
21
|
+
Input["EncodingServices"]
|
|
22
|
+
>;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** A decision provider, independent of the agent's generative LanguageModel. */
|
|
27
|
+
export class DecisionModel extends Context.Service<DecisionModel, Service>()(
|
|
28
|
+
"@effect-agent/ai-decision/DecisionModel",
|
|
29
|
+
) {}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Construct a provider with request-derived response validation. Capture dependencies once;
|
|
33
|
+
* resources acquired by evaluate close per call. Invalid data fails with native AiError.
|
|
34
|
+
* Defects and interruption propagate. There are no implicit retries, deadlines, confidence
|
|
35
|
+
* thresholds, or transitions. Usage is returned to the caller, not charged to an agent Run.
|
|
36
|
+
*/
|
|
37
|
+
export const make = Effect.fnUntraced(function* <R>(options: {
|
|
38
|
+
/**
|
|
39
|
+
* Provider-owned rounding check replacing only the Choice probability-sum check.
|
|
40
|
+
* Defaults to a sum of 1 within 1e-6. Exact keys, ranges, winning choices, and
|
|
41
|
+
* all Score checks remain enforced. This trusted construction option never
|
|
42
|
+
* comes from response metadata and must not normalize the supplied values.
|
|
43
|
+
*/
|
|
44
|
+
readonly choiceProbabilitySum?: SchemaAST.Check<Readonly<Record<string, number>>>;
|
|
45
|
+
readonly evaluate: (
|
|
46
|
+
request: DecisionSchema.EvaluateRequest,
|
|
47
|
+
) => Effect.Effect<unknown, AiError.AiError, R>;
|
|
48
|
+
}): Effect.fn.Return<Service, never, Exclude<R, Scope.Scope>> {
|
|
49
|
+
const services = yield* Effect.context<Exclude<R, Scope.Scope>>();
|
|
50
|
+
|
|
51
|
+
const evaluateRequest = Effect.fn("DecisionModel.evaluate")(function* <
|
|
52
|
+
const Q extends DecisionSchema.Questions,
|
|
53
|
+
>(
|
|
54
|
+
request: DecisionSchema.EvaluateRequest<Q>,
|
|
55
|
+
): Effect.fn.Return<DecisionSchema.EvaluateResponse<Q>, AiError.AiError> {
|
|
56
|
+
// Encode and decode once to snapshot caller-owned state and criteria before provider I/O.
|
|
57
|
+
const encoded = yield* Schema.encodeEffect(
|
|
58
|
+
Schema.fromJsonString(DecisionSchema.EvaluateRequest),
|
|
59
|
+
)(request).pipe(
|
|
60
|
+
Effect.mapError(
|
|
61
|
+
() =>
|
|
62
|
+
new AiError.AiError({
|
|
63
|
+
module: "DecisionModel",
|
|
64
|
+
method: "evaluate",
|
|
65
|
+
reason: new AiError.InvalidRequestError({
|
|
66
|
+
description: "Invalid decision evaluation request",
|
|
67
|
+
}),
|
|
68
|
+
}),
|
|
69
|
+
),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const snapshot = yield* Schema.decodeEffect(
|
|
73
|
+
Schema.fromJsonString(DecisionSchema.EvaluateRequest),
|
|
74
|
+
)(encoded).pipe(
|
|
75
|
+
Effect.mapError(
|
|
76
|
+
() =>
|
|
77
|
+
new AiError.AiError({
|
|
78
|
+
module: "DecisionModel",
|
|
79
|
+
method: "evaluate",
|
|
80
|
+
reason: new AiError.InvalidRequestError({
|
|
81
|
+
description: "Invalid decision evaluation request",
|
|
82
|
+
}),
|
|
83
|
+
}),
|
|
84
|
+
),
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const schema = responseFor(request.questions, options.choiceProbabilitySum);
|
|
88
|
+
|
|
89
|
+
const result = yield* Effect.scoped(options.evaluate(snapshot)).pipe(
|
|
90
|
+
Effect.provideContext(services),
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
return yield* Schema.decodeUnknownEffect(schema)(result, { onExcessProperty: "error" }).pipe(
|
|
94
|
+
Effect.mapError(
|
|
95
|
+
() =>
|
|
96
|
+
new AiError.AiError({
|
|
97
|
+
module: "DecisionModel",
|
|
98
|
+
method: "evaluate",
|
|
99
|
+
reason: new AiError.InvalidOutputError({
|
|
100
|
+
description: "Decision response disagrees with the submitted questions",
|
|
101
|
+
}),
|
|
102
|
+
}),
|
|
103
|
+
),
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const evaluateSet = Effect.fnUntraced(function* <
|
|
108
|
+
Input extends Schema.Top,
|
|
109
|
+
const Q extends DecisionSchema.Questions,
|
|
110
|
+
>(set: DecisionSet.DecisionSet<Input, Q>, input: Input["Type"]) {
|
|
111
|
+
const state = yield* Schema.encodeEffect(set.input)(input).pipe(
|
|
112
|
+
Effect.flatMap(Schema.decodeUnknownEffect(DecisionSchema.Content)),
|
|
113
|
+
Effect.mapError(
|
|
114
|
+
() =>
|
|
115
|
+
new AiError.AiError({
|
|
116
|
+
module: "DecisionModel",
|
|
117
|
+
method: "evaluate",
|
|
118
|
+
reason: new AiError.InvalidRequestError({
|
|
119
|
+
description: "Decision set input must encode to valid decision state",
|
|
120
|
+
}),
|
|
121
|
+
}),
|
|
122
|
+
),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return yield* evaluateRequest({ state, questions: set.questions });
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
function evaluate<const Q extends DecisionSchema.Questions>(
|
|
129
|
+
request: DecisionSchema.EvaluateRequest<Q>,
|
|
130
|
+
): Effect.Effect<DecisionSchema.EvaluateResponse<Q>, AiError.AiError>;
|
|
131
|
+
function evaluate<Input extends Schema.Top, const Q extends DecisionSchema.Questions>(
|
|
132
|
+
set: DecisionSet.DecisionSet<Input, Q>,
|
|
133
|
+
input: NoInfer<Input["Type"]>,
|
|
134
|
+
): Effect.Effect<DecisionSchema.EvaluateResponse<Q>, AiError.AiError, Input["EncodingServices"]>;
|
|
135
|
+
function evaluate<Input extends Schema.Top, const Q extends DecisionSchema.Questions>(
|
|
136
|
+
...args:
|
|
137
|
+
| [DecisionSchema.EvaluateRequest<Q>]
|
|
138
|
+
| [DecisionSet.DecisionSet<Input, Q>, Input["Type"]]
|
|
139
|
+
): Effect.Effect<DecisionSchema.EvaluateResponse<Q>, AiError.AiError, Input["EncodingServices"]> {
|
|
140
|
+
return args.length === 1 ? evaluateRequest(args[0]) : evaluateSet(args[0], args[1]);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return DecisionModel.of({ evaluate });
|
|
144
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure constructors for questions evaluated by a DecisionModel. Definitions
|
|
3
|
+
* are validated when evaluated; constructing a query performs no model I/O.
|
|
4
|
+
*
|
|
5
|
+
* @since 0.1.0
|
|
6
|
+
*/
|
|
7
|
+
import type * as DecisionSchema from "./DecisionSchema.ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Choose one named option and retain the complete categorical distribution.
|
|
11
|
+
* Option keys infer the answer's choice union. Supply at least one option;
|
|
12
|
+
* null descriptions use the option name alone.
|
|
13
|
+
*
|
|
14
|
+
* @category constructors
|
|
15
|
+
* @since 0.1.0
|
|
16
|
+
*/
|
|
17
|
+
export const choice = <const Options extends DecisionSchema.ChoiceQuestion["criteria"]>(options: {
|
|
18
|
+
readonly instructions: DecisionSchema.Content;
|
|
19
|
+
readonly options: Options;
|
|
20
|
+
}) =>
|
|
21
|
+
Object.freeze({
|
|
22
|
+
type: "choice" as const,
|
|
23
|
+
instructions: options.instructions,
|
|
24
|
+
criteria: Object.freeze({ ...options.options }),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Rate a state along at least two ordered descriptions. The answer is the
|
|
29
|
+
* probability-weighted, zero-indexed position and may fall between levels.
|
|
30
|
+
*
|
|
31
|
+
* @category constructors
|
|
32
|
+
* @since 0.1.0
|
|
33
|
+
*/
|
|
34
|
+
export const score = (options: {
|
|
35
|
+
readonly instructions: DecisionSchema.Content;
|
|
36
|
+
readonly levels: ReadonlyArray<string>;
|
|
37
|
+
}) =>
|
|
38
|
+
Object.freeze({
|
|
39
|
+
type: "score" as const,
|
|
40
|
+
instructions: options.instructions,
|
|
41
|
+
criteria: Object.freeze([...options.levels]),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Estimate the probability a proposition is true. Optional criteria clarify
|
|
46
|
+
* either outcome. No threshold or implicit boolean conversion is applied.
|
|
47
|
+
*
|
|
48
|
+
* @category constructors
|
|
49
|
+
* @since 0.1.0
|
|
50
|
+
*/
|
|
51
|
+
export const probability = (options: Omit<DecisionSchema.ProbabilityQuestion, "type">) =>
|
|
52
|
+
Object.freeze({
|
|
53
|
+
type: "probability" as const,
|
|
54
|
+
instructions: options.instructions,
|
|
55
|
+
...(options.criteria === undefined ? {} : { criteria: Object.freeze({ ...options.criteria }) }),
|
|
56
|
+
});
|