@node-llm/core 1.17.0 → 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 +826 -467
- package/dist/aliases.d.ts.map +1 -1
- package/dist/aliases.js +881 -522
- package/dist/chat/Chat.d.ts +14 -10
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +20 -5
- package/dist/chat/ChatOptions.d.ts +12 -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/chat/ToolHandler.js +15 -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 +8 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +6 -1
- package/dist/errors/index.d.ts +3 -1
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +4 -1
- package/dist/executor/Executor.d.ts +6 -0
- package/dist/executor/Executor.d.ts.map +1 -1
- package/dist/executor/Executor.js +19 -2
- 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 +16534 -10534
- 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/anthropic/Models.d.ts.map +1 -1
- package/dist/providers/anthropic/Models.js +4 -2
- package/dist/providers/deepseek/Models.d.ts.map +1 -1
- package/dist/providers/deepseek/Models.js +4 -2
- package/dist/providers/gemini/Embeddings.d.ts.map +1 -1
- package/dist/providers/gemini/Embeddings.js +4 -2
- package/dist/providers/gemini/Image.d.ts.map +1 -1
- package/dist/providers/gemini/Image.js +4 -2
- package/dist/providers/gemini/Models.d.ts.map +1 -1
- package/dist/providers/gemini/Models.js +4 -2
- package/dist/providers/gemini/Transcription.d.ts.map +1 -1
- package/dist/providers/gemini/Transcription.js +4 -2
- package/dist/providers/mistral/Embedding.d.ts.map +1 -1
- package/dist/providers/mistral/Embedding.js +4 -2
- package/dist/providers/mistral/Models.d.ts.map +1 -1
- package/dist/providers/mistral/Models.js +4 -2
- package/dist/providers/openai/Models.d.ts.map +1 -1
- package/dist/providers/openai/Models.js +4 -2
- package/dist/providers/openrouter/Models.d.ts.map +1 -1
- package/dist/providers/openrouter/Models.js +4 -2
- 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/dist/utils/Binary.d.ts.map +1 -1
- package/dist/utils/Binary.js +11 -0
- package/dist/utils/FileLoader.d.ts.map +1 -1
- package/dist/utils/FileLoader.js +21 -2
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +8 -1
- package/package.json +1 -1
|
@@ -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"}
|
|
@@ -0,0 +1,180 @@
|
|
|
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
|
+
/**
|
|
11
|
+
* Declares a yes/no question whose answer is the probability of yes. A value
|
|
12
|
+
* near 0.5 means yes and no are about equally likely, not "medium"; use a
|
|
13
|
+
* score to measure degree.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* probability("Does this need attention today?", {
|
|
17
|
+
* yes: "An explicit deadline today or an ongoing outage",
|
|
18
|
+
* no: "A general question with no time pressure"
|
|
19
|
+
* })
|
|
20
|
+
*/
|
|
21
|
+
export function probability(instructions, criteria) {
|
|
22
|
+
return { type: "probability", instructions, ...(criteria ? { criteria } : {}) };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Declares a question that selects one named option and returns a probability
|
|
26
|
+
* for every option. Include a catch-all such as `other` when none of the
|
|
27
|
+
* specific options may fit. Use null for an option that needs no description.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* choice("Which team should handle this?", {
|
|
31
|
+
* billing: "Payments and refunds",
|
|
32
|
+
* technical: "Bugs and integrations",
|
|
33
|
+
* other: null
|
|
34
|
+
* })
|
|
35
|
+
*/
|
|
36
|
+
export function choice(instructions, options) {
|
|
37
|
+
return { type: "choice", instructions, options };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Declares a question scored against ordered levels. The first level is 0, the
|
|
41
|
+
* second 1, and so on; the answer is probability-weighted and can fall between
|
|
42
|
+
* levels. Describe each level concretely.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* score("How frustrated is the customer?", ["Calm", "Frustrated", "Angry"])
|
|
46
|
+
*/
|
|
47
|
+
export function score(instructions, levels) {
|
|
48
|
+
return { type: "score", instructions, levels };
|
|
49
|
+
}
|
|
50
|
+
function isDescription(value) {
|
|
51
|
+
if (value === null || typeof value === "string")
|
|
52
|
+
return true;
|
|
53
|
+
if (Array.isArray(value))
|
|
54
|
+
return value.every(isJson);
|
|
55
|
+
if (typeof value === "object")
|
|
56
|
+
return isJson(value);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
function isJson(value) {
|
|
60
|
+
if (value === null)
|
|
61
|
+
return true;
|
|
62
|
+
switch (typeof value) {
|
|
63
|
+
case "string":
|
|
64
|
+
case "boolean":
|
|
65
|
+
return true;
|
|
66
|
+
case "number":
|
|
67
|
+
return Number.isFinite(value);
|
|
68
|
+
case "object":
|
|
69
|
+
if (Array.isArray(value))
|
|
70
|
+
return value.every(isJson);
|
|
71
|
+
if (Object.getPrototypeOf(value) !== Object.prototype &&
|
|
72
|
+
Object.getPrototypeOf(value) !== null) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return Object.values(value).every(isJson);
|
|
76
|
+
default:
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function invalid(name, message) {
|
|
81
|
+
throw new Error(`Invalid judgment question '${name}': ${message}`);
|
|
82
|
+
}
|
|
83
|
+
function validateDescriptions(name, values) {
|
|
84
|
+
if (!values.every(isDescription)) {
|
|
85
|
+
invalid(name, "descriptions must be text, an object, an array, or null");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Validates every question and returns them in declaration order with their
|
|
90
|
+
* names attached. Rejects the problems a provider would otherwise report as an
|
|
91
|
+
* opaque 400: unknown types, empty choices or scales, and probability criteria
|
|
92
|
+
* that describe anything other than yes and no.
|
|
93
|
+
*/
|
|
94
|
+
export function normalizeQuestions(questions) {
|
|
95
|
+
if (!questions || typeof questions !== "object" || Array.isArray(questions)) {
|
|
96
|
+
throw new Error("Judgment questions must be an object keyed by question name");
|
|
97
|
+
}
|
|
98
|
+
const entries = Object.entries(questions);
|
|
99
|
+
if (entries.length === 0) {
|
|
100
|
+
throw new Error("A judgment needs at least one question");
|
|
101
|
+
}
|
|
102
|
+
return entries.map(([name, question]) => {
|
|
103
|
+
if (name.length === 0)
|
|
104
|
+
invalid(name, "a question name cannot be empty");
|
|
105
|
+
if (!question || typeof question !== "object")
|
|
106
|
+
invalid(name, "the definition must be an object");
|
|
107
|
+
if (question.instructions !== undefined && !isDescription(question.instructions)) {
|
|
108
|
+
invalid(name, "instructions must be text, an object, an array, or null");
|
|
109
|
+
}
|
|
110
|
+
switch (question.type) {
|
|
111
|
+
case "probability":
|
|
112
|
+
validateProbability(name, question);
|
|
113
|
+
break;
|
|
114
|
+
case "choice":
|
|
115
|
+
validateChoice(name, question);
|
|
116
|
+
break;
|
|
117
|
+
case "score":
|
|
118
|
+
validateScore(name, question);
|
|
119
|
+
break;
|
|
120
|
+
default:
|
|
121
|
+
invalid(name, `unknown type '${String(question.type)}'`);
|
|
122
|
+
}
|
|
123
|
+
return { ...question, name };
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function validateProbability(name, question) {
|
|
127
|
+
const extra = Object.keys(question).filter((k) => !["type", "instructions", "criteria"].includes(k));
|
|
128
|
+
if (extra.length > 0)
|
|
129
|
+
invalid(name, `unknown fields ${extra.join(", ")}`);
|
|
130
|
+
if (question.criteria === undefined)
|
|
131
|
+
return;
|
|
132
|
+
const criteria = question.criteria;
|
|
133
|
+
if (!criteria || typeof criteria !== "object" || Array.isArray(criteria)) {
|
|
134
|
+
invalid(name, "probability criteria must describe yes and no");
|
|
135
|
+
}
|
|
136
|
+
const keys = Object.keys(criteria);
|
|
137
|
+
const unknown = keys.filter((k) => !["yes", "no", "true", "false"].includes(k));
|
|
138
|
+
if (unknown.length > 0)
|
|
139
|
+
invalid(name, "probability criteria must describe yes and no");
|
|
140
|
+
// yes/true and no/false are the same outcome; describing one twice is ambiguous.
|
|
141
|
+
const positives = keys.filter((k) => k === "yes" || k === "true").length;
|
|
142
|
+
const negatives = keys.filter((k) => k === "no" || k === "false").length;
|
|
143
|
+
if (positives > 1 || negatives > 1)
|
|
144
|
+
invalid(name, "probability criteria contain duplicate outcomes");
|
|
145
|
+
validateDescriptions(name, Object.values(criteria));
|
|
146
|
+
}
|
|
147
|
+
function validateChoice(name, question) {
|
|
148
|
+
const extra = Object.keys(question).filter((k) => !["type", "instructions", "options"].includes(k));
|
|
149
|
+
if (extra.length > 0)
|
|
150
|
+
invalid(name, `unknown fields ${extra.join(", ")}`);
|
|
151
|
+
const options = question.options;
|
|
152
|
+
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
153
|
+
invalid(name, "a choice needs a non-empty object of options");
|
|
154
|
+
}
|
|
155
|
+
const keys = Object.keys(options);
|
|
156
|
+
if (keys.length === 0)
|
|
157
|
+
invalid(name, "a choice needs a non-empty object of options");
|
|
158
|
+
if (keys.some((k) => k.length === 0))
|
|
159
|
+
invalid(name, "choice options must have non-empty names");
|
|
160
|
+
validateDescriptions(name, Object.values(options));
|
|
161
|
+
}
|
|
162
|
+
function validateScore(name, question) {
|
|
163
|
+
const extra = Object.keys(question).filter((k) => !["type", "instructions", "levels"].includes(k));
|
|
164
|
+
if (extra.length > 0)
|
|
165
|
+
invalid(name, `unknown fields ${extra.join(", ")}`);
|
|
166
|
+
if (!Array.isArray(question.levels) || question.levels.length === 0) {
|
|
167
|
+
invalid(name, "a score needs a non-empty array of levels");
|
|
168
|
+
}
|
|
169
|
+
validateDescriptions(name, question.levels);
|
|
170
|
+
}
|
|
171
|
+
/** True when the value can be sent as judgment input. */
|
|
172
|
+
export function isJudgmentInput(value) {
|
|
173
|
+
if (typeof value === "string")
|
|
174
|
+
return true;
|
|
175
|
+
if (Array.isArray(value))
|
|
176
|
+
return isJson(value);
|
|
177
|
+
if (value !== null && typeof value === "object")
|
|
178
|
+
return isJson(value);
|
|
179
|
+
return false;
|
|
180
|
+
}
|
package/dist/llm.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ import { Moderation } from "./moderation/Moderation.js";
|
|
|
9
9
|
import { Embedding } from "./embedding/Embedding.js";
|
|
10
10
|
import { NodeLLMConfig } from "./config.js";
|
|
11
11
|
import { Middleware } from "./types/Middleware.js";
|
|
12
|
+
import { JudgmentInput } from "./providers/Provider.js";
|
|
13
|
+
import { QuestionMap } from "./judge/Question.js";
|
|
14
|
+
import { JudgmentResult } from "./judge/Judgment.js";
|
|
12
15
|
export interface RetryOptions {
|
|
13
16
|
attempts?: number;
|
|
14
17
|
delayMs?: number;
|
|
@@ -21,6 +24,7 @@ type LLMConfig = {
|
|
|
21
24
|
defaultTranscriptionModel?: string;
|
|
22
25
|
defaultModerationModel?: string;
|
|
23
26
|
defaultEmbeddingModel?: string;
|
|
27
|
+
defaultJudgmentModel?: string;
|
|
24
28
|
} & Omit<Partial<NodeLLMConfig>, "provider">;
|
|
25
29
|
export declare class NodeLLMCore {
|
|
26
30
|
readonly config: NodeLLMConfig;
|
|
@@ -35,11 +39,13 @@ export declare class NodeLLMCore {
|
|
|
35
39
|
transcription?: string;
|
|
36
40
|
moderation?: string;
|
|
37
41
|
embedding?: string;
|
|
42
|
+
judgment?: string;
|
|
38
43
|
});
|
|
39
44
|
get defaultChatModel(): string | undefined;
|
|
40
45
|
get defaultTranscriptionModel(): string | undefined;
|
|
41
46
|
get defaultModerationModel(): string | undefined;
|
|
42
47
|
get defaultEmbeddingModel(): string | undefined;
|
|
48
|
+
get defaultJudgmentModel(): string | undefined;
|
|
43
49
|
/**
|
|
44
50
|
* Returns a scoped LLM instance configured for a specific provider.
|
|
45
51
|
* This returns a NEW immutable instance.
|
|
@@ -72,6 +78,8 @@ export declare class NodeLLMCore {
|
|
|
72
78
|
language?: string;
|
|
73
79
|
speakerNames?: string[];
|
|
74
80
|
speakerReferences?: string[];
|
|
81
|
+
/** Word and/or segment timestamps, where the provider supports them. */
|
|
82
|
+
timestamp_granularities?: ("word" | "segment")[];
|
|
75
83
|
assumeModelExists?: boolean;
|
|
76
84
|
requestTimeout?: number;
|
|
77
85
|
middlewares?: Middleware[];
|
|
@@ -89,6 +97,44 @@ export declare class NodeLLMCore {
|
|
|
89
97
|
requestTimeout?: number;
|
|
90
98
|
middlewares?: Middleware[];
|
|
91
99
|
}): Promise<Embedding>;
|
|
100
|
+
/**
|
|
101
|
+
* Asks typed questions about one input and returns a typed answer for each:
|
|
102
|
+
* a probability, a choice among named options, or a score on a scale.
|
|
103
|
+
*
|
|
104
|
+
* The provider follows the model: `jev-latest` (the default) is answered by
|
|
105
|
+
* TypeSafe whichever provider this instance is scoped to. Pass `provider` to
|
|
106
|
+
* route explicitly, for example to a Jev-compatible local server configured
|
|
107
|
+
* through `typesafeApiBase`.
|
|
108
|
+
*
|
|
109
|
+
* Each call judges only the input given; it keeps no conversation history.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* const judgment = await NodeLLM.judge("Please refund the duplicate charge today.", {
|
|
113
|
+
* questions: {
|
|
114
|
+
* urgent: probability("Does this need attention today?"),
|
|
115
|
+
* team: choice("Which team should handle this?", { billing: "Payments", other: null })
|
|
116
|
+
* }
|
|
117
|
+
* });
|
|
118
|
+
* judgment.urgent.probability; // 0.91
|
|
119
|
+
* judgment.team.choice; // "billing"
|
|
120
|
+
*/
|
|
121
|
+
judge<const Q extends QuestionMap>(input: JudgmentInput, options: {
|
|
122
|
+
questions: Q;
|
|
123
|
+
model?: string;
|
|
124
|
+
provider?: string;
|
|
125
|
+
/** Provider-specific fields merged into the request body. */
|
|
126
|
+
providerOptions?: Record<string, unknown>;
|
|
127
|
+
requestTimeout?: number;
|
|
128
|
+
middlewares?: Middleware[];
|
|
129
|
+
}): Promise<JudgmentResult<Q>>;
|
|
130
|
+
/**
|
|
131
|
+
* Picks the provider that answers judgments for a model: an explicit choice
|
|
132
|
+
* first, then the registry's owner of a known judgment model, then this
|
|
133
|
+
* instance's own provider - which is how a model the registry does not know,
|
|
134
|
+
* such as one on a local Jev-compatible server, reaches the provider it was
|
|
135
|
+
* scoped to.
|
|
136
|
+
*/
|
|
137
|
+
private judgmentProvider;
|
|
92
138
|
}
|
|
93
139
|
export { Transcription, Moderation, Embedding, ModelRegistry, PricingRegistry };
|
|
94
140
|
/**
|
package/dist/llm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}
|
package/dist/llm.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { Chat } from "./chat/Chat.js";
|
|
2
|
-
import { providerRegistry, ensureOpenAIRegistered, registerAnthropicProvider, registerGeminiProvider, registerDeepSeekProvider, registerOllamaProvider, registerOpenRouterProvider, registerBedrockProvider, registerXAIProvider, registerMistralProvider } from "./providers/registry.js";
|
|
2
|
+
import { providerRegistry, ensureOpenAIRegistered, registerAnthropicProvider, registerGeminiProvider, registerDeepSeekProvider, registerOllamaProvider, registerOpenRouterProvider, registerBedrockProvider, registerXAIProvider, registerMistralProvider, registerTypeSafeProvider } from "./providers/registry.js";
|
|
3
3
|
import { GeneratedImage } from "./image/GeneratedImage.js";
|
|
4
4
|
import { ModelRegistry } from "./models/ModelRegistry.js";
|
|
5
5
|
import { PricingRegistry } from "./models/PricingRegistry.js";
|
|
6
6
|
import { Transcription } from "./transcription/Transcription.js";
|
|
7
7
|
import { Moderation } from "./moderation/Moderation.js";
|
|
8
8
|
import { Embedding } from "./embedding/Embedding.js";
|
|
9
|
-
import { ProviderNotConfiguredError, UnsupportedFeatureError, ModelCapabilityError } from "./errors/index.js";
|
|
9
|
+
import { ProviderNotConfiguredError, UnsupportedFeatureError, ModelCapabilityError, ConfigurationError } from "./errors/index.js";
|
|
10
10
|
import { resolveModelAlias } from "./model_aliases.js";
|
|
11
11
|
import { logger } from "./utils/logger.js";
|
|
12
12
|
import { config, Configuration } from "./config.js";
|
|
13
13
|
import { runMiddleware } from "./utils/middleware-runner.js";
|
|
14
|
+
import { normalizeQuestions, isJudgmentInput } from "./judge/Question.js";
|
|
15
|
+
import { buildJudgment } from "./judge/Judgment.js";
|
|
16
|
+
import { DEFAULT_MODELS } from "./constants.js";
|
|
14
17
|
import { randomUUID } from "node:crypto";
|
|
15
18
|
// Provider registration map
|
|
16
19
|
const PROVIDER_REGISTRARS = {
|
|
@@ -22,7 +25,8 @@ const PROVIDER_REGISTRARS = {
|
|
|
22
25
|
openrouter: registerOpenRouterProvider,
|
|
23
26
|
bedrock: registerBedrockProvider,
|
|
24
27
|
xai: registerXAIProvider,
|
|
25
|
-
mistral: registerMistralProvider
|
|
28
|
+
mistral: registerMistralProvider,
|
|
29
|
+
typesafe: registerTypeSafeProvider
|
|
26
30
|
};
|
|
27
31
|
export class NodeLLMCore {
|
|
28
32
|
config;
|
|
@@ -54,6 +58,9 @@ export class NodeLLMCore {
|
|
|
54
58
|
get defaultEmbeddingModel() {
|
|
55
59
|
return this.defaults.embedding;
|
|
56
60
|
}
|
|
61
|
+
get defaultJudgmentModel() {
|
|
62
|
+
return this.defaults.judgment;
|
|
63
|
+
}
|
|
57
64
|
/**
|
|
58
65
|
* Returns a scoped LLM instance configured for a specific provider.
|
|
59
66
|
* This returns a NEW immutable instance.
|
|
@@ -70,7 +77,8 @@ export class NodeLLMCore {
|
|
|
70
77
|
defaultChatModel: this.defaults.chat,
|
|
71
78
|
defaultTranscriptionModel: this.defaults.transcription,
|
|
72
79
|
defaultModerationModel: this.defaults.moderation,
|
|
73
|
-
defaultEmbeddingModel: this.defaults.embedding
|
|
80
|
+
defaultEmbeddingModel: this.defaults.embedding,
|
|
81
|
+
defaultJudgmentModel: this.defaults.judgment
|
|
74
82
|
});
|
|
75
83
|
}
|
|
76
84
|
/**
|
|
@@ -281,6 +289,97 @@ export class NodeLLMCore {
|
|
|
281
289
|
throw error;
|
|
282
290
|
}
|
|
283
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* Asks typed questions about one input and returns a typed answer for each:
|
|
294
|
+
* a probability, a choice among named options, or a score on a scale.
|
|
295
|
+
*
|
|
296
|
+
* The provider follows the model: `jev-latest` (the default) is answered by
|
|
297
|
+
* TypeSafe whichever provider this instance is scoped to. Pass `provider` to
|
|
298
|
+
* route explicitly, for example to a Jev-compatible local server configured
|
|
299
|
+
* through `typesafeApiBase`.
|
|
300
|
+
*
|
|
301
|
+
* Each call judges only the input given; it keeps no conversation history.
|
|
302
|
+
*
|
|
303
|
+
* @example
|
|
304
|
+
* const judgment = await NodeLLM.judge("Please refund the duplicate charge today.", {
|
|
305
|
+
* questions: {
|
|
306
|
+
* urgent: probability("Does this need attention today?"),
|
|
307
|
+
* team: choice("Which team should handle this?", { billing: "Payments", other: null })
|
|
308
|
+
* }
|
|
309
|
+
* });
|
|
310
|
+
* judgment.urgent.probability; // 0.91
|
|
311
|
+
* judgment.team.choice; // "billing"
|
|
312
|
+
*/
|
|
313
|
+
async judge(input, options) {
|
|
314
|
+
if (!isJudgmentInput(input)) {
|
|
315
|
+
throw new Error("Judgment input must be text, an object, or an array of JSON-compatible values");
|
|
316
|
+
}
|
|
317
|
+
const questions = normalizeQuestions(options.questions);
|
|
318
|
+
const model = options.model || this.defaults.judgment || DEFAULT_MODELS.JUDGMENT;
|
|
319
|
+
const provider = this.judgmentProvider(model, options.provider);
|
|
320
|
+
if (!provider.judge) {
|
|
321
|
+
throw new UnsupportedFeatureError(provider.id, "judge");
|
|
322
|
+
}
|
|
323
|
+
const context = {
|
|
324
|
+
requestId: randomUUID(),
|
|
325
|
+
provider: provider.id,
|
|
326
|
+
model,
|
|
327
|
+
judgmentInput: input,
|
|
328
|
+
judgmentOptions: options,
|
|
329
|
+
state: {}
|
|
330
|
+
};
|
|
331
|
+
const middlewares = [...this.middlewares, ...(options.middlewares || [])];
|
|
332
|
+
try {
|
|
333
|
+
await runMiddleware(middlewares, "onRequest", context);
|
|
334
|
+
const response = await provider.judge({
|
|
335
|
+
model,
|
|
336
|
+
input: context.judgmentInput ?? input,
|
|
337
|
+
questions,
|
|
338
|
+
providerOptions: options.providerOptions,
|
|
339
|
+
requestTimeout: options.requestTimeout ?? this.config.requestTimeout
|
|
340
|
+
});
|
|
341
|
+
// Priced by the requested model, which is what the registry knows; the
|
|
342
|
+
// response names the exact build that answered (jev-latest comes back as
|
|
343
|
+
// e.g. jev-1.13.0). An unpriced model leaves cost undefined rather than a
|
|
344
|
+
// guessed number.
|
|
345
|
+
const usage = ModelRegistry.calculateCost(response.usage, model, provider.id);
|
|
346
|
+
const judgment = buildJudgment({ ...response, usage }, questions);
|
|
347
|
+
await runMiddleware(middlewares, "onResponse", context, judgment);
|
|
348
|
+
return judgment;
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
await runMiddleware(middlewares, "onError", context, error);
|
|
352
|
+
throw error;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Picks the provider that answers judgments for a model: an explicit choice
|
|
357
|
+
* first, then the registry's owner of a known judgment model, then this
|
|
358
|
+
* instance's own provider - which is how a model the registry does not know,
|
|
359
|
+
* such as one on a local Jev-compatible server, reaches the provider it was
|
|
360
|
+
* scoped to.
|
|
361
|
+
*/
|
|
362
|
+
judgmentProvider(model, explicit) {
|
|
363
|
+
const known = ModelRegistry.find(model);
|
|
364
|
+
const owner = explicit ??
|
|
365
|
+
(known &&
|
|
366
|
+
known.id.toLowerCase() === model.toLowerCase() &&
|
|
367
|
+
known.capabilities?.includes("judgment")
|
|
368
|
+
? known.provider
|
|
369
|
+
: undefined);
|
|
370
|
+
if (!owner || owner === this.provider?.id) {
|
|
371
|
+
if (!this.provider) {
|
|
372
|
+
// Guessing a provider for an unknown model would send the request (and
|
|
373
|
+
// the credentials) somewhere the caller did not choose.
|
|
374
|
+
throw new ConfigurationError(`Unknown judgment model '${model}': no provider is known to serve it. ` +
|
|
375
|
+
`Pass \`provider\` (for example "typesafe"), or call judge on ` +
|
|
376
|
+
`NodeLLM.withProvider("typesafe").`);
|
|
377
|
+
}
|
|
378
|
+
return this.provider;
|
|
379
|
+
}
|
|
380
|
+
PROVIDER_REGISTRARS[owner]?.();
|
|
381
|
+
return providerRegistry.resolve(owner, this.config);
|
|
382
|
+
}
|
|
284
383
|
}
|
|
285
384
|
export { Transcription, Moderation, Embedding, ModelRegistry, PricingRegistry };
|
|
286
385
|
/**
|
|
@@ -330,7 +429,8 @@ export function createLLM(options = {}) {
|
|
|
330
429
|
chat: options.defaultChatModel,
|
|
331
430
|
transcription: options.defaultTranscriptionModel,
|
|
332
431
|
moderation: options.defaultModerationModel,
|
|
333
|
-
embedding: options.defaultEmbeddingModel
|
|
432
|
+
embedding: options.defaultEmbeddingModel,
|
|
433
|
+
judgment: options.defaultJudgmentModel
|
|
334
434
|
};
|
|
335
435
|
return new NodeLLMCore(baseConfig, providerInstance, retry, options.middlewares || [], defaults);
|
|
336
436
|
}
|
|
@@ -25,30 +25,23 @@ export declare class ModelRegistry {
|
|
|
25
25
|
/**
|
|
26
26
|
* Calculate cost for usage.
|
|
27
27
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}, modelId: string, provider: string): {
|
|
36
|
-
input_tokens: number;
|
|
37
|
-
output_tokens: number;
|
|
38
|
-
total_tokens: number;
|
|
39
|
-
cached_tokens?: number;
|
|
40
|
-
reasoning_tokens?: number;
|
|
41
|
-
image_tokens?: number;
|
|
42
|
-
} | {
|
|
43
|
-
input_cost: number;
|
|
44
|
-
output_cost: number;
|
|
45
|
-
cost: number;
|
|
28
|
+
/**
|
|
29
|
+
* Returns the usage with `input_cost`, `output_cost` and `cost` added when the
|
|
30
|
+
* model has known pricing. Without pricing the usage comes back unchanged and
|
|
31
|
+
* the cost fields are undefined - declared on the return type either way, so
|
|
32
|
+
* callers can read `.cost` without a cast.
|
|
33
|
+
*/
|
|
34
|
+
static calculateCost<U extends {
|
|
46
35
|
input_tokens: number;
|
|
47
36
|
output_tokens: number;
|
|
48
37
|
total_tokens: number;
|
|
49
38
|
cached_tokens?: number;
|
|
50
39
|
reasoning_tokens?: number;
|
|
51
40
|
image_tokens?: number;
|
|
41
|
+
}>(usage: U, modelId: string, provider: string): U & {
|
|
42
|
+
input_cost?: number;
|
|
43
|
+
output_cost?: number;
|
|
44
|
+
cost?: number;
|
|
52
45
|
};
|
|
53
46
|
}
|
|
54
47
|
//# sourceMappingURL=ModelRegistry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelRegistry.d.ts","sourceRoot":"","sources":["../../src/models/ModelRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA6C;IAElE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAmBlE;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,IAAI;IAe1C;;OAEG;IACH,MAAM,CAAC,GAAG,IAAI,KAAK,EAAE;IAIrB;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKhF;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAwB/E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAK9E;;OAEG;IACH,MAAM,CAAC,aAAa,CAClB,
|
|
1
|
+
{"version":3,"file":"ModelRegistry.d.ts","sourceRoot":"","sources":["../../src/models/ModelRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA6C;IAElE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAmBlE;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,IAAI;IAe1C;;OAEG;IACH,MAAM,CAAC,GAAG,IAAI,KAAK,EAAE;IAIrB;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKhF;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAwB/E;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAK9E;;OAEG;IACH;;;;;OAKG;IACH,MAAM,CAAC,aAAa,CAClB,CAAC,SAAS;QACR,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,EAED,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;CAgDpE"}
|
|
@@ -77,6 +77,12 @@ export class ModelRegistry {
|
|
|
77
77
|
/**
|
|
78
78
|
* Calculate cost for usage.
|
|
79
79
|
*/
|
|
80
|
+
/**
|
|
81
|
+
* Returns the usage with `input_cost`, `output_cost` and `cost` added when the
|
|
82
|
+
* model has known pricing. Without pricing the usage comes back unchanged and
|
|
83
|
+
* the cost fields are undefined - declared on the return type either way, so
|
|
84
|
+
* callers can read `.cost` without a cast.
|
|
85
|
+
*/
|
|
80
86
|
static calculateCost(usage, modelId, provider) {
|
|
81
87
|
const pricing = PricingRegistry.getPricing(modelId, provider);
|
|
82
88
|
if (!pricing) {
|