@node-llm/core 1.17.1 → 1.18.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/README.md +1 -0
- package/dist/agent/Agent.d.ts +24 -11
- package/dist/agent/Agent.d.ts.map +1 -1
- package/dist/agent/Agent.js +1 -3
- package/dist/aliases.d.ts +341 -172
- package/dist/aliases.d.ts.map +1 -1
- package/dist/aliases.js +409 -240
- package/dist/chat/Chat.d.ts +13 -10
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +15 -4
- package/dist/chat/ChatOptions.d.ts +11 -11
- package/dist/chat/ChatOptions.d.ts.map +1 -1
- package/dist/chat/Tool.d.ts +26 -5
- package/dist/chat/Tool.d.ts.map +1 -1
- package/dist/chat/Tool.js +25 -3
- package/dist/chat/ToolCallOutcome.d.ts +6 -6
- package/dist/chat/ToolCallOutcome.d.ts.map +1 -1
- package/dist/chat/ToolHandler.d.ts +2 -2
- package/dist/chat/ToolHandler.d.ts.map +1 -1
- package/dist/config.d.ts +12 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -1
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/judge/Judge.d.ts +107 -0
- package/dist/judge/Judge.d.ts.map +1 -0
- package/dist/judge/Judge.js +104 -0
- package/dist/judge/Judgment.d.ts +116 -0
- package/dist/judge/Judgment.d.ts.map +1 -0
- package/dist/judge/Judgment.js +159 -0
- package/dist/judge/Question.d.ts +91 -0
- package/dist/judge/Question.d.ts.map +1 -0
- package/dist/judge/Question.js +180 -0
- package/dist/llm.d.ts +46 -0
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +105 -5
- package/dist/models/ModelRegistry.d.ts +11 -18
- package/dist/models/ModelRegistry.d.ts.map +1 -1
- package/dist/models/ModelRegistry.js +6 -0
- package/dist/models/models.json +5181 -2145
- package/dist/providers/BaseProvider.d.ts +2 -1
- package/dist/providers/BaseProvider.d.ts.map +1 -1
- package/dist/providers/BaseProvider.js +3 -0
- package/dist/providers/Provider.d.ts +37 -0
- package/dist/providers/Provider.d.ts.map +1 -1
- package/dist/providers/registry.d.ts +2 -1
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +2 -1
- package/dist/providers/typesafe/SystemOne.d.ts +11 -0
- package/dist/providers/typesafe/SystemOne.d.ts.map +1 -0
- package/dist/providers/typesafe/SystemOne.js +171 -0
- package/dist/providers/typesafe/TypeSafeProvider.d.ts +27 -0
- package/dist/providers/typesafe/TypeSafeProvider.d.ts.map +1 -0
- package/dist/providers/typesafe/TypeSafeProvider.js +76 -0
- package/dist/providers/typesafe/index.d.ts +4 -0
- package/dist/providers/typesafe/index.d.ts.map +1 -0
- package/dist/providers/typesafe/index.js +19 -0
- package/dist/types/Middleware.d.ts +9 -0
- package/dist/types/Middleware.d.ts.map +1 -1
- package/package.json +13 -10
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { NodeLLMCore } from "../llm.js";
|
|
2
|
+
import { JudgmentInput } from "../providers/Provider.js";
|
|
3
|
+
import { LazyValue } from "../agent/Agent.js";
|
|
4
|
+
import { QuestionMap } from "./Question.js";
|
|
5
|
+
import { JudgmentResult } from "./Judgment.js";
|
|
6
|
+
/** The questions a Judge class declares, once resolved. */
|
|
7
|
+
export type QuestionsOf<T> = T extends {
|
|
8
|
+
questions: infer Q;
|
|
9
|
+
} ? Q extends (...args: never[]) => infer R ? R extends QuestionMap ? R : never : Q extends QuestionMap ? Q : never : never;
|
|
10
|
+
export interface JudgeCallOptions<I = Record<string, unknown>> {
|
|
11
|
+
/** Values for the inputs the judge declares; available to lazy settings. */
|
|
12
|
+
inputs?: I;
|
|
13
|
+
/** Overrides the judge's model for this call. */
|
|
14
|
+
model?: string;
|
|
15
|
+
/** Overrides the judge's provider for this call. */
|
|
16
|
+
provider?: string;
|
|
17
|
+
/** Merged over the judge's own providerOptions. */
|
|
18
|
+
providerOptions?: Record<string, unknown>;
|
|
19
|
+
requestTimeout?: number;
|
|
20
|
+
/** The NodeLLM instance to judge with. Defaults to the global NodeLLM. */
|
|
21
|
+
llm?: NodeLLMCore;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A reusable set of typed questions about your application data.
|
|
25
|
+
*
|
|
26
|
+
* Subclass it and declare `questions`; call `judge` with the input. Answers are
|
|
27
|
+
* typed from the declaration, so a choice's answer is a union of its options.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* class TicketTriage extends Judge {
|
|
31
|
+
* static questions = {
|
|
32
|
+
* urgent: probability("Does this need attention today?"),
|
|
33
|
+
* department: choice("Which team should handle this?", {
|
|
34
|
+
* billing: "Payments and refunds",
|
|
35
|
+
* technical: "Bugs and integrations",
|
|
36
|
+
* other: null
|
|
37
|
+
* }),
|
|
38
|
+
* frustration: score("How frustrated is the customer?", ["Calm", "Frustrated", "Angry"])
|
|
39
|
+
* };
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* const judgment = await TicketTriage.judge("Please refund the duplicate charge today.");
|
|
43
|
+
* judgment.urgent.probability; // number
|
|
44
|
+
* judgment.department.choice; // "billing" | "technical" | "other"
|
|
45
|
+
*
|
|
46
|
+
* Settings can depend on runtime data. Declare the inputs a judge needs and
|
|
47
|
+
* pass them to `judge`; `questions`, `model` and `providerOptions` may be
|
|
48
|
+
* functions of those inputs, resolved once per judgment.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* class TeamRouter extends Judge {
|
|
52
|
+
* static inputs = ["teams"] as const;
|
|
53
|
+
* static questions = ({ teams }: { teams: Team[] }) => ({
|
|
54
|
+
* team: choice("Which team should handle this?",
|
|
55
|
+
* Object.fromEntries(teams.map((t) => [t.slug, t.description])))
|
|
56
|
+
* });
|
|
57
|
+
* }
|
|
58
|
+
* await TeamRouter.judge(ticket.body, { inputs: { teams } });
|
|
59
|
+
*/
|
|
60
|
+
export declare abstract class Judge {
|
|
61
|
+
/** The judgment model. Defaults to the instance default, then `jev-latest`. */
|
|
62
|
+
static model?: LazyValue<string, never>;
|
|
63
|
+
/** Routes to a specific provider; normally inferred from the model. */
|
|
64
|
+
static provider?: string;
|
|
65
|
+
/** Names of the inputs `judge` must be given. */
|
|
66
|
+
static inputs?: readonly string[];
|
|
67
|
+
/** The questions, or a function of the declared inputs returning them. */
|
|
68
|
+
static questions: LazyValue<QuestionMap, never>;
|
|
69
|
+
/** Provider-specific request fields, or a function of the inputs. */
|
|
70
|
+
static providerOptions?: LazyValue<Record<string, unknown>, never>;
|
|
71
|
+
/**
|
|
72
|
+
* Judges the input and returns typed answers. The input is text, an object,
|
|
73
|
+
* or an array of JSON-compatible values - or a function of the inputs that
|
|
74
|
+
* returns one.
|
|
75
|
+
*/
|
|
76
|
+
static judge<T extends typeof Judge, I extends Record<string, unknown> = Record<string, unknown>>(this: T, input: LazyValue<JudgmentInput, I>, options?: JudgeCallOptions<I>): Promise<JudgmentResult<QuestionsOf<T>>>;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Defines a judge without a class, mirroring `defineAgent`.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const Urgency = defineJudge({
|
|
83
|
+
* questions: { urgent: probability("Does this need attention today?") }
|
|
84
|
+
* });
|
|
85
|
+
* (await Urgency.judge("The site is down")).urgent.probability;
|
|
86
|
+
*/
|
|
87
|
+
export declare function defineJudge<const Q extends QuestionMap>(definition: {
|
|
88
|
+
questions: LazyValue<Q, never>;
|
|
89
|
+
model?: LazyValue<string, never>;
|
|
90
|
+
provider?: string;
|
|
91
|
+
inputs?: readonly string[];
|
|
92
|
+
providerOptions?: LazyValue<Record<string, unknown>, never>;
|
|
93
|
+
}): {
|
|
94
|
+
new (): {};
|
|
95
|
+
questions: LazyValue<Q, never>;
|
|
96
|
+
model: LazyValue<string, never> | undefined;
|
|
97
|
+
provider: string | undefined;
|
|
98
|
+
inputs: readonly string[] | undefined;
|
|
99
|
+
providerOptions: LazyValue<Record<string, unknown>, never> | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* Judges the input and returns typed answers. The input is text, an object,
|
|
102
|
+
* or an array of JSON-compatible values - or a function of the inputs that
|
|
103
|
+
* returns one.
|
|
104
|
+
*/
|
|
105
|
+
judge<T extends typeof Judge, I extends Record<string, unknown> = Record<string, unknown>>(this: T, input: LazyValue<JudgmentInput, I>, options?: JudgeCallOptions<I>): Promise<JudgmentResult<QuestionsOf<T>>>;
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=Judge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Judge.d.ts","sourceRoot":"","sources":["../../src/judge/Judge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { NodeLLM } from "../llm.js";
|
|
2
|
+
/**
|
|
3
|
+
* A reusable set of typed questions about your application data.
|
|
4
|
+
*
|
|
5
|
+
* Subclass it and declare `questions`; call `judge` with the input. Answers are
|
|
6
|
+
* typed from the declaration, so a choice's answer is a union of its options.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* class TicketTriage extends Judge {
|
|
10
|
+
* static questions = {
|
|
11
|
+
* urgent: probability("Does this need attention today?"),
|
|
12
|
+
* department: choice("Which team should handle this?", {
|
|
13
|
+
* billing: "Payments and refunds",
|
|
14
|
+
* technical: "Bugs and integrations",
|
|
15
|
+
* other: null
|
|
16
|
+
* }),
|
|
17
|
+
* frustration: score("How frustrated is the customer?", ["Calm", "Frustrated", "Angry"])
|
|
18
|
+
* };
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* const judgment = await TicketTriage.judge("Please refund the duplicate charge today.");
|
|
22
|
+
* judgment.urgent.probability; // number
|
|
23
|
+
* judgment.department.choice; // "billing" | "technical" | "other"
|
|
24
|
+
*
|
|
25
|
+
* Settings can depend on runtime data. Declare the inputs a judge needs and
|
|
26
|
+
* pass them to `judge`; `questions`, `model` and `providerOptions` may be
|
|
27
|
+
* functions of those inputs, resolved once per judgment.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* class TeamRouter extends Judge {
|
|
31
|
+
* static inputs = ["teams"] as const;
|
|
32
|
+
* static questions = ({ teams }: { teams: Team[] }) => ({
|
|
33
|
+
* team: choice("Which team should handle this?",
|
|
34
|
+
* Object.fromEntries(teams.map((t) => [t.slug, t.description])))
|
|
35
|
+
* });
|
|
36
|
+
* }
|
|
37
|
+
* await TeamRouter.judge(ticket.body, { inputs: { teams } });
|
|
38
|
+
*/
|
|
39
|
+
export class Judge {
|
|
40
|
+
/** The judgment model. Defaults to the instance default, then `jev-latest`. */
|
|
41
|
+
static model;
|
|
42
|
+
/** Routes to a specific provider; normally inferred from the model. */
|
|
43
|
+
static provider;
|
|
44
|
+
/** Names of the inputs `judge` must be given. */
|
|
45
|
+
static inputs;
|
|
46
|
+
/** The questions, or a function of the declared inputs returning them. */
|
|
47
|
+
static questions;
|
|
48
|
+
/** Provider-specific request fields, or a function of the inputs. */
|
|
49
|
+
static providerOptions;
|
|
50
|
+
/**
|
|
51
|
+
* Judges the input and returns typed answers. The input is text, an object,
|
|
52
|
+
* or an array of JSON-compatible values - or a function of the inputs that
|
|
53
|
+
* returns one.
|
|
54
|
+
*/
|
|
55
|
+
static async judge(input, options = {}) {
|
|
56
|
+
const inputs = (options.inputs ?? {});
|
|
57
|
+
checkInputs(this, inputs);
|
|
58
|
+
const resolve = (value) => typeof value === "function" ? value(inputs) : value;
|
|
59
|
+
const questions = resolve(this.questions);
|
|
60
|
+
if (!questions) {
|
|
61
|
+
throw new Error(`${this.name} declares no questions`);
|
|
62
|
+
}
|
|
63
|
+
const declaredOptions = resolve(this.providerOptions);
|
|
64
|
+
const providerOptions = declaredOptions || options.providerOptions
|
|
65
|
+
? { ...declaredOptions, ...options.providerOptions }
|
|
66
|
+
: undefined;
|
|
67
|
+
const llm = options.llm ?? NodeLLM;
|
|
68
|
+
return llm.judge(resolve(input), {
|
|
69
|
+
questions: questions,
|
|
70
|
+
model: options.model ?? resolve(this.model),
|
|
71
|
+
provider: options.provider ?? this.provider,
|
|
72
|
+
providerOptions,
|
|
73
|
+
requestTimeout: options.requestTimeout
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function checkInputs(judge, inputs) {
|
|
78
|
+
const declared = judge.inputs ?? [];
|
|
79
|
+
const given = Object.keys(inputs);
|
|
80
|
+
const missing = declared.filter((name) => !(name in inputs));
|
|
81
|
+
const unknown = given.filter((name) => !declared.includes(name));
|
|
82
|
+
if (missing.length > 0)
|
|
83
|
+
throw new Error(`${judge.name} is missing inputs: ${missing.join(", ")}`);
|
|
84
|
+
if (unknown.length > 0)
|
|
85
|
+
throw new Error(`${judge.name} does not declare inputs: ${unknown.join(", ")}`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Defines a judge without a class, mirroring `defineAgent`.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* const Urgency = defineJudge({
|
|
92
|
+
* questions: { urgent: probability("Does this need attention today?") }
|
|
93
|
+
* });
|
|
94
|
+
* (await Urgency.judge("The site is down")).urgent.probability;
|
|
95
|
+
*/
|
|
96
|
+
export function defineJudge(definition) {
|
|
97
|
+
return class extends Judge {
|
|
98
|
+
static questions = definition.questions;
|
|
99
|
+
static model = definition.model;
|
|
100
|
+
static provider = definition.provider;
|
|
101
|
+
static inputs = definition.inputs;
|
|
102
|
+
static providerOptions = definition.providerOptions;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { JudgmentResponse, Usage } from "../providers/Provider.js";
|
|
2
|
+
import { ChoiceQuestion, Description, ProbabilityQuestion, NamedQuestion, QuestionDefinition, QuestionMap, ScoreQuestion } from "./Question.js";
|
|
3
|
+
/** The probability that a yes/no statement holds, between 0 and 1. */
|
|
4
|
+
export declare class ProbabilityAnswer {
|
|
5
|
+
readonly probability: number;
|
|
6
|
+
readonly type: "probability";
|
|
7
|
+
constructor(probability: number);
|
|
8
|
+
toJSON(): {
|
|
9
|
+
type: "probability";
|
|
10
|
+
probability: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The selected option, with a probability for every option. `confidence`
|
|
15
|
+
* describes how concentrated the distribution is; it is not a guarantee that
|
|
16
|
+
* the choice is correct.
|
|
17
|
+
*/
|
|
18
|
+
export declare class ChoiceAnswer<K extends string = string> {
|
|
19
|
+
readonly choice: K;
|
|
20
|
+
readonly probabilities: Readonly<Record<K, number>>;
|
|
21
|
+
readonly confidence: number;
|
|
22
|
+
readonly type: "choice";
|
|
23
|
+
constructor(choice: K, probabilities: Readonly<Record<K, number>>, confidence: number);
|
|
24
|
+
toJSON(): {
|
|
25
|
+
type: "choice";
|
|
26
|
+
choice: K;
|
|
27
|
+
probabilities: Readonly<Record<K, number>>;
|
|
28
|
+
confidence: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A probability-weighted position on an ordered scale. Level 0 is the first
|
|
33
|
+
* level, so with three levels the score runs from 0 to 2 and can fall between
|
|
34
|
+
* them. `probabilities` is keyed by level index.
|
|
35
|
+
*/
|
|
36
|
+
export declare class ScoreAnswer {
|
|
37
|
+
readonly score: number;
|
|
38
|
+
readonly levels: readonly Description[];
|
|
39
|
+
readonly probabilities: Readonly<Record<number, number>>;
|
|
40
|
+
readonly confidence: number;
|
|
41
|
+
readonly type: "score";
|
|
42
|
+
constructor(score: number, levels: readonly Description[], probabilities: Readonly<Record<number, number>>, confidence: number);
|
|
43
|
+
toJSON(): {
|
|
44
|
+
type: "score";
|
|
45
|
+
score: number;
|
|
46
|
+
levels: readonly Description[];
|
|
47
|
+
probabilities: Readonly<Record<number, number>>;
|
|
48
|
+
confidence: number;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export type Answer = ProbabilityAnswer | ChoiceAnswer | ScoreAnswer;
|
|
52
|
+
/** The answer type a question produces. */
|
|
53
|
+
export type AnswerFor<D extends QuestionDefinition> = D extends ProbabilityQuestion ? ProbabilityAnswer : D extends ChoiceQuestion<infer K> ? ChoiceAnswer<K> : D extends ScoreQuestion ? ScoreAnswer : never;
|
|
54
|
+
/** Answers keyed by question name, typed from the questions asked. */
|
|
55
|
+
export type AnswersOf<Q extends QuestionMap> = {
|
|
56
|
+
readonly [N in keyof Q]: AnswerFor<Q[N]>;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* The typed answers to a set of questions, with the model that answered them
|
|
60
|
+
* and the tokens it used.
|
|
61
|
+
*
|
|
62
|
+
* Answers are available by name - `judgment.urgent.probability` - and through
|
|
63
|
+
* `judgment.answers`. A question named like one of Judgment's own members
|
|
64
|
+
* (`model`, `usage`, `get`, ...) is only reachable through `answers` or `get`.
|
|
65
|
+
*/
|
|
66
|
+
export declare class Judgment<Q extends QuestionMap = QuestionMap> {
|
|
67
|
+
readonly answers: AnswersOf<Q>;
|
|
68
|
+
/** The model that answered, as reported by the provider. */
|
|
69
|
+
readonly model: string;
|
|
70
|
+
/** Token usage. `cost` is present only when the model has known pricing. */
|
|
71
|
+
readonly usage: Usage;
|
|
72
|
+
/** The provider's raw response. */
|
|
73
|
+
readonly raw?: unknown | undefined;
|
|
74
|
+
constructor(answers: AnswersOf<Q>,
|
|
75
|
+
/** The model that answered, as reported by the provider. */
|
|
76
|
+
model: string,
|
|
77
|
+
/** Token usage. `cost` is present only when the model has known pricing. */
|
|
78
|
+
usage: Usage,
|
|
79
|
+
/** The provider's raw response. */
|
|
80
|
+
raw?: unknown | undefined);
|
|
81
|
+
/** Returns the named answer, or undefined when there is none. */
|
|
82
|
+
get<N extends keyof Q & string>(name: N): AnswersOf<Q>[N] | undefined;
|
|
83
|
+
/** Returns the named answer, throwing when there is none. */
|
|
84
|
+
fetch<N extends keyof Q & string>(name: N): AnswersOf<Q>[N];
|
|
85
|
+
[Symbol.iterator](): IterableIterator<[keyof Q & string, Answer]>;
|
|
86
|
+
toJSON(): {
|
|
87
|
+
model: string;
|
|
88
|
+
answers: {
|
|
89
|
+
[k: string]: {
|
|
90
|
+
type: "probability";
|
|
91
|
+
probability: number;
|
|
92
|
+
} | {
|
|
93
|
+
type: "score";
|
|
94
|
+
score: number;
|
|
95
|
+
levels: readonly Description[];
|
|
96
|
+
probabilities: Readonly<Record<number, number>>;
|
|
97
|
+
confidence: number;
|
|
98
|
+
} | {
|
|
99
|
+
type: "choice";
|
|
100
|
+
choice: string;
|
|
101
|
+
probabilities: Readonly<Record<string, number>>;
|
|
102
|
+
confidence: number;
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
usage: Usage;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/** A Judgment whose answers can also be read directly by question name. */
|
|
109
|
+
export type JudgmentResult<Q extends QuestionMap = QuestionMap> = Judgment<Q> & Omit<AnswersOf<Q>, keyof Judgment<Q>>;
|
|
110
|
+
/**
|
|
111
|
+
* Wraps a provider's answers in typed, frozen answer objects. Every question
|
|
112
|
+
* must come back answered with the type it was asked as; anything else means
|
|
113
|
+
* the provider and the request disagree, and is reported rather than guessed.
|
|
114
|
+
*/
|
|
115
|
+
export declare function buildJudgment<Q extends QuestionMap>(response: JudgmentResponse, questions: NamedQuestion[]): JudgmentResult<Q>;
|
|
116
|
+
//# sourceMappingURL=Judgment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Judgment.d.ts","sourceRoot":"","sources":["../../src/judge/Judgment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/** The probability that a yes/no statement holds, between 0 and 1. */
|
|
2
|
+
export class ProbabilityAnswer {
|
|
3
|
+
probability;
|
|
4
|
+
type = "probability";
|
|
5
|
+
constructor(probability) {
|
|
6
|
+
this.probability = probability;
|
|
7
|
+
Object.freeze(this);
|
|
8
|
+
}
|
|
9
|
+
toJSON() {
|
|
10
|
+
return { type: this.type, probability: this.probability };
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The selected option, with a probability for every option. `confidence`
|
|
15
|
+
* describes how concentrated the distribution is; it is not a guarantee that
|
|
16
|
+
* the choice is correct.
|
|
17
|
+
*/
|
|
18
|
+
export class ChoiceAnswer {
|
|
19
|
+
choice;
|
|
20
|
+
probabilities;
|
|
21
|
+
confidence;
|
|
22
|
+
type = "choice";
|
|
23
|
+
constructor(choice, probabilities, confidence) {
|
|
24
|
+
this.choice = choice;
|
|
25
|
+
this.probabilities = probabilities;
|
|
26
|
+
this.confidence = confidence;
|
|
27
|
+
Object.freeze(this.probabilities);
|
|
28
|
+
Object.freeze(this);
|
|
29
|
+
}
|
|
30
|
+
toJSON() {
|
|
31
|
+
return {
|
|
32
|
+
type: this.type,
|
|
33
|
+
choice: this.choice,
|
|
34
|
+
probabilities: this.probabilities,
|
|
35
|
+
confidence: this.confidence
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A probability-weighted position on an ordered scale. Level 0 is the first
|
|
41
|
+
* level, so with three levels the score runs from 0 to 2 and can fall between
|
|
42
|
+
* them. `probabilities` is keyed by level index.
|
|
43
|
+
*/
|
|
44
|
+
export class ScoreAnswer {
|
|
45
|
+
score;
|
|
46
|
+
levels;
|
|
47
|
+
probabilities;
|
|
48
|
+
confidence;
|
|
49
|
+
type = "score";
|
|
50
|
+
constructor(score, levels, probabilities, confidence) {
|
|
51
|
+
this.score = score;
|
|
52
|
+
this.levels = levels;
|
|
53
|
+
this.probabilities = probabilities;
|
|
54
|
+
this.confidence = confidence;
|
|
55
|
+
Object.freeze(this.levels);
|
|
56
|
+
Object.freeze(this.probabilities);
|
|
57
|
+
Object.freeze(this);
|
|
58
|
+
}
|
|
59
|
+
toJSON() {
|
|
60
|
+
return {
|
|
61
|
+
type: this.type,
|
|
62
|
+
score: this.score,
|
|
63
|
+
levels: this.levels,
|
|
64
|
+
probabilities: this.probabilities,
|
|
65
|
+
confidence: this.confidence
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The typed answers to a set of questions, with the model that answered them
|
|
71
|
+
* and the tokens it used.
|
|
72
|
+
*
|
|
73
|
+
* Answers are available by name - `judgment.urgent.probability` - and through
|
|
74
|
+
* `judgment.answers`. A question named like one of Judgment's own members
|
|
75
|
+
* (`model`, `usage`, `get`, ...) is only reachable through `answers` or `get`.
|
|
76
|
+
*/
|
|
77
|
+
export class Judgment {
|
|
78
|
+
answers;
|
|
79
|
+
model;
|
|
80
|
+
usage;
|
|
81
|
+
raw;
|
|
82
|
+
constructor(answers,
|
|
83
|
+
/** The model that answered, as reported by the provider. */
|
|
84
|
+
model,
|
|
85
|
+
/** Token usage. `cost` is present only when the model has known pricing. */
|
|
86
|
+
usage,
|
|
87
|
+
/** The provider's raw response. */
|
|
88
|
+
raw) {
|
|
89
|
+
this.answers = answers;
|
|
90
|
+
this.model = model;
|
|
91
|
+
this.usage = usage;
|
|
92
|
+
this.raw = raw;
|
|
93
|
+
Object.freeze(this.answers);
|
|
94
|
+
for (const name of Object.keys(answers)) {
|
|
95
|
+
if (name in this)
|
|
96
|
+
continue;
|
|
97
|
+
Object.defineProperty(this, name, {
|
|
98
|
+
value: answers[name],
|
|
99
|
+
enumerable: false
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
Object.freeze(this);
|
|
103
|
+
}
|
|
104
|
+
/** Returns the named answer, or undefined when there is none. */
|
|
105
|
+
get(name) {
|
|
106
|
+
return Object.prototype.hasOwnProperty.call(this.answers, name)
|
|
107
|
+
? this.answers[name]
|
|
108
|
+
: undefined;
|
|
109
|
+
}
|
|
110
|
+
/** Returns the named answer, throwing when there is none. */
|
|
111
|
+
fetch(name) {
|
|
112
|
+
const answer = this.get(name);
|
|
113
|
+
if (answer === undefined)
|
|
114
|
+
throw new Error(`No answer named '${name}' in this judgment`);
|
|
115
|
+
return answer;
|
|
116
|
+
}
|
|
117
|
+
*[Symbol.iterator]() {
|
|
118
|
+
for (const [name, answer] of Object.entries(this.answers)) {
|
|
119
|
+
yield [name, answer];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
toJSON() {
|
|
123
|
+
return {
|
|
124
|
+
model: this.model,
|
|
125
|
+
answers: Object.fromEntries(Object.entries(this.answers).map(([name, answer]) => [name, answer.toJSON()])),
|
|
126
|
+
usage: this.usage
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Wraps a provider's answers in typed, frozen answer objects. Every question
|
|
132
|
+
* must come back answered with the type it was asked as; anything else means
|
|
133
|
+
* the provider and the request disagree, and is reported rather than guessed.
|
|
134
|
+
*/
|
|
135
|
+
export function buildJudgment(response, questions) {
|
|
136
|
+
const answers = {};
|
|
137
|
+
for (const question of questions) {
|
|
138
|
+
const data = response.answers[question.name];
|
|
139
|
+
if (!data)
|
|
140
|
+
throw new Error(`The provider returned no answer for '${question.name}'`);
|
|
141
|
+
if (data.type !== question.type) {
|
|
142
|
+
throw new Error(`The provider answered '${question.name}' as a ${data.type}, but it was asked as a ${question.type}`);
|
|
143
|
+
}
|
|
144
|
+
switch (data.type) {
|
|
145
|
+
case "probability":
|
|
146
|
+
answers[question.name] = new ProbabilityAnswer(data.probability);
|
|
147
|
+
break;
|
|
148
|
+
case "choice":
|
|
149
|
+
answers[question.name] = new ChoiceAnswer(data.choice, { ...data.probabilities }, data.confidence);
|
|
150
|
+
break;
|
|
151
|
+
case "score":
|
|
152
|
+
// Copy the levels: the answer is frozen, and freezing the caller's own
|
|
153
|
+
// question definition would be a surprising side effect.
|
|
154
|
+
answers[question.name] = new ScoreAnswer(data.score, structuredClone(question.levels), { ...data.probabilities }, data.confidence);
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return new Judgment(answers, response.model, response.usage, response.raw);
|
|
159
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed questions for judgments.
|
|
3
|
+
*
|
|
4
|
+
* A judgment asks a set of named questions about one input and returns a typed
|
|
5
|
+
* answer for each: the probability that a statement holds, a choice among named
|
|
6
|
+
* options, or a score on an ordered scale. Questions are plain data, so they
|
|
7
|
+
* can be declared on a Judge class, passed to NodeLLM.judge, or built at
|
|
8
|
+
* runtime from application data.
|
|
9
|
+
*/
|
|
10
|
+
/** A JSON-compatible value, used for descriptions and structured input. */
|
|
11
|
+
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
12
|
+
[key: string]: JsonValue;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Describes a question, an option, or a level. Text is usual; an object or
|
|
16
|
+
* array carries structured instructions, and null means "no description".
|
|
17
|
+
*/
|
|
18
|
+
export type Description = string | null | JsonValue[] | {
|
|
19
|
+
[key: string]: JsonValue;
|
|
20
|
+
};
|
|
21
|
+
/** The yes/no boundary of a probability question. Either side is optional. */
|
|
22
|
+
export interface ProbabilityCriteria {
|
|
23
|
+
yes?: Description;
|
|
24
|
+
no?: Description;
|
|
25
|
+
}
|
|
26
|
+
export interface ProbabilityQuestion {
|
|
27
|
+
type: "probability";
|
|
28
|
+
instructions?: Description;
|
|
29
|
+
criteria?: ProbabilityCriteria;
|
|
30
|
+
}
|
|
31
|
+
export interface ChoiceQuestion<K extends string = string> {
|
|
32
|
+
type: "choice";
|
|
33
|
+
instructions?: Description;
|
|
34
|
+
options: Record<K, Description>;
|
|
35
|
+
}
|
|
36
|
+
export interface ScoreQuestion {
|
|
37
|
+
type: "score";
|
|
38
|
+
instructions?: Description;
|
|
39
|
+
levels: Description[];
|
|
40
|
+
}
|
|
41
|
+
export type QuestionDefinition = ProbabilityQuestion | ChoiceQuestion | ScoreQuestion;
|
|
42
|
+
/** Questions keyed by the name your code reads the answer from. */
|
|
43
|
+
export type QuestionMap = Record<string, QuestionDefinition>;
|
|
44
|
+
/** A question after validation, carrying its name for the provider. */
|
|
45
|
+
export type NamedQuestion = QuestionDefinition & {
|
|
46
|
+
name: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Declares a yes/no question whose answer is the probability of yes. A value
|
|
50
|
+
* near 0.5 means yes and no are about equally likely, not "medium"; use a
|
|
51
|
+
* score to measure degree.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* probability("Does this need attention today?", {
|
|
55
|
+
* yes: "An explicit deadline today or an ongoing outage",
|
|
56
|
+
* no: "A general question with no time pressure"
|
|
57
|
+
* })
|
|
58
|
+
*/
|
|
59
|
+
export declare function probability(instructions?: Description, criteria?: ProbabilityCriteria): ProbabilityQuestion;
|
|
60
|
+
/**
|
|
61
|
+
* Declares a question that selects one named option and returns a probability
|
|
62
|
+
* for every option. Include a catch-all such as `other` when none of the
|
|
63
|
+
* specific options may fit. Use null for an option that needs no description.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* choice("Which team should handle this?", {
|
|
67
|
+
* billing: "Payments and refunds",
|
|
68
|
+
* technical: "Bugs and integrations",
|
|
69
|
+
* other: null
|
|
70
|
+
* })
|
|
71
|
+
*/
|
|
72
|
+
export declare function choice<const O extends Record<string, Description>>(instructions: Description | undefined, options: O): ChoiceQuestion<Extract<keyof O, string>>;
|
|
73
|
+
/**
|
|
74
|
+
* Declares a question scored against ordered levels. The first level is 0, the
|
|
75
|
+
* second 1, and so on; the answer is probability-weighted and can fall between
|
|
76
|
+
* levels. Describe each level concretely.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* score("How frustrated is the customer?", ["Calm", "Frustrated", "Angry"])
|
|
80
|
+
*/
|
|
81
|
+
export declare function score(instructions: Description | undefined, levels: Description[]): ScoreQuestion;
|
|
82
|
+
/**
|
|
83
|
+
* Validates every question and returns them in declaration order with their
|
|
84
|
+
* names attached. Rejects the problems a provider would otherwise report as an
|
|
85
|
+
* opaque 400: unknown types, empty choices or scales, and probability criteria
|
|
86
|
+
* that describe anything other than yes and no.
|
|
87
|
+
*/
|
|
88
|
+
export declare function normalizeQuestions(questions: QuestionMap): NamedQuestion[];
|
|
89
|
+
/** True when the value can be sent as judgment input. */
|
|
90
|
+
export declare function isJudgmentInput(value: unknown): boolean;
|
|
91
|
+
//# sourceMappingURL=Question.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Question.d.ts","sourceRoot":"","sources":["../../src/judge/Question.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAErF,8EAA8E;AAC9E,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,EAAE,CAAC,EAAE,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CAChC;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACvD,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG,cAAc,GAAG,aAAa,CAAC;AAEtF,mEAAmE;AACnE,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAE7D,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG,kBAAkB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,YAAY,CAAC,EAAE,WAAW,EAC1B,QAAQ,CAAC,EAAE,mBAAmB,GAC7B,mBAAmB,CAErB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAChE,YAAY,EAAE,WAAW,GAAG,SAAS,EACrC,OAAO,EAAE,CAAC,GACT,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAE1C;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,YAAY,EAAE,WAAW,GAAG,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,aAAa,CAEjG;AAyCD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,WAAW,GAAG,aAAa,EAAE,CAmC1E;AAuDD,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKvD"}
|