@langchain/core 1.3.7 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/decisions.cjs +1 -0
- package/decisions.d.cts +1 -0
- package/decisions.d.ts +1 -0
- package/decisions.js +1 -0
- package/dist/decisions/base.cjs +98 -0
- package/dist/decisions/base.cjs.map +1 -0
- package/dist/decisions/base.d.cts +83 -0
- package/dist/decisions/base.d.cts.map +1 -0
- package/dist/decisions/base.d.ts +83 -0
- package/dist/decisions/base.d.ts.map +1 -0
- package/dist/decisions/base.js +98 -0
- package/dist/decisions/base.js.map +1 -0
- package/dist/decisions/index.cjs +21 -0
- package/dist/decisions/index.cjs.map +1 -0
- package/dist/decisions/index.d.cts +3 -0
- package/dist/decisions/index.d.ts +3 -0
- package/dist/decisions/index.js +12 -0
- package/dist/decisions/index.js.map +1 -0
- package/dist/decisions/types.cjs +176 -0
- package/dist/decisions/types.cjs.map +1 -0
- package/dist/decisions/types.d.cts +368 -0
- package/dist/decisions/types.d.cts.map +1 -0
- package/dist/decisions/types.d.ts +368 -0
- package/dist/decisions/types.d.ts.map +1 -0
- package/dist/decisions/types.js +173 -0
- package/dist/decisions/types.js.map +1 -0
- package/dist/language_models/base.cjs +1 -1
- package/dist/language_models/base.js +1 -1
- package/dist/load/import_map.cjs +8 -0
- package/dist/load/import_map.cjs.map +1 -1
- package/dist/load/import_map.js +3 -1
- package/dist/load/import_map.js.map +1 -1
- package/dist/messages/base.cjs +4 -1
- package/dist/messages/base.cjs.map +1 -1
- package/dist/messages/base.d.cts.map +1 -1
- package/dist/messages/base.d.ts.map +1 -1
- package/dist/messages/base.js +4 -1
- package/dist/messages/base.js.map +1 -1
- package/package.json +18 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @langchain/core
|
|
2
2
|
|
|
3
|
+
## 1.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#12230](https://github.com/langchain-ai/langchainjs/pull/12230) [`84e85cc`](https://github.com/langchain-ai/langchainjs/commit/84e85cc8657a6922c9db34ff7a2a1a692e83a503) Thanks [@thushanth-bengre-langchain](https://github.com/thushanth-bengre-langchain)! - Merge streamed `input_json_delta` blocks into the preceding `tool_use` / `server_tool_use` block at the same index
|
|
8
|
+
|
|
9
|
+
## 1.4.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#12178](https://github.com/langchain-ai/langchainjs/pull/12178) [`01e5f2d`](https://github.com/langchain-ai/langchainjs/commit/01e5f2dbbf30823045fc82c69bef7b2c032315f4) Thanks [@thushanth-bengre-langchain](https://github.com/thushanth-bengre-langchain)! - feat(core): add decision models
|
|
14
|
+
|
|
15
|
+
- Add `@langchain/core/decisions` with `BaseDecisionModel`, a `Runnable` that answers typed `Noul`, `Choice`, `Score`, and `Box` questions about text, messages, or JSON state
|
|
16
|
+
- Add question and answer types, `parseQuestions`, and `parseClassifierResponse` for providers
|
|
17
|
+
- Type `invoke` answers from the questions asked, including `Choice` labels, and reject provider responses that leave a question unanswered or answer it with the wrong type or label
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#12192](https://github.com/langchain-ai/langchainjs/pull/12192) [`9920d4b`](https://github.com/langchain-ai/langchainjs/commit/9920d4b33dee5bc0cfb33d859246edf8973c86eb) Thanks [@jkennedyvz](https://github.com/jkennedyvz)! - Require Zod 4.6.6 or newer for installed dependencies to exclude versions affected by GHSA-mrhx-c7xc-m3w5. Zod v3 schemas remain supported through the bundled `zod/v3` entry point.
|
|
22
|
+
|
|
3
23
|
## 1.3.7
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/decisions.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("./dist/decisions/index.cjs");
|
package/decisions.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./dist/decisions/index.js";
|
package/decisions.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./dist/decisions/index.js";
|
package/decisions.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./dist/decisions/index.js";
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const require_base = require("../runnables/base.cjs");
|
|
2
|
+
const require_config = require("../runnables/config.cjs");
|
|
3
|
+
const require_types = require("./types.cjs");
|
|
4
|
+
// src/decisions/base.ts
|
|
5
|
+
function assertAnswered(questions, response) {
|
|
6
|
+
for (const [id, question] of Object.entries(questions)) {
|
|
7
|
+
const answer = Object.hasOwn(response.answers, id) ? response.answers[id] : void 0;
|
|
8
|
+
if (answer === void 0) throw new Error(`Decision model returned no answer for question "${id}".`);
|
|
9
|
+
if (answer.type !== question.type) throw new Error(`Decision model returned a ${answer.type} answer for ${question.type} question "${id}".`);
|
|
10
|
+
if (answer.type === "choice" && question.type === "choice" && !Object.hasOwn(question.criteria, answer.choice)) throw new Error(`Decision model returned a choice for question "${id}" that is not one of its labels.`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Answer typed questions about text, messages, or structured state.
|
|
15
|
+
*
|
|
16
|
+
* A decision model evaluates shared state against one or more questions and
|
|
17
|
+
* returns typed answers: a probability for a `Noul`, a selected label for a
|
|
18
|
+
* `Choice`, an expected level for a `Score`, and a location for a `Box`.
|
|
19
|
+
* Answers keep their probability distributions and confidence so applications
|
|
20
|
+
* can choose their own thresholds.
|
|
21
|
+
*
|
|
22
|
+
* Subclasses implement `_classify` to call a provider. This class validates
|
|
23
|
+
* questions and handles callbacks, tracing metadata, and token-usage
|
|
24
|
+
* reporting.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import {
|
|
29
|
+
* BaseDecisionModel,
|
|
30
|
+
* parseClassifierResponse,
|
|
31
|
+
* } from "@langchain/core/decisions";
|
|
32
|
+
*
|
|
33
|
+
* class MyDecisionModel extends BaseDecisionModel {
|
|
34
|
+
* lc_namespace = ["my_provider", "decisions"];
|
|
35
|
+
*
|
|
36
|
+
* get _provider() {
|
|
37
|
+
* return "my_provider";
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* async _classify(
|
|
41
|
+
* state: State,
|
|
42
|
+
* questions: Record<string, Question>,
|
|
43
|
+
* config?: Partial<RunnableConfig>
|
|
44
|
+
* ) {
|
|
45
|
+
* const body = await myClient.classify(
|
|
46
|
+
* { model: this.model, state, questions },
|
|
47
|
+
* { signal: config?.signal }
|
|
48
|
+
* );
|
|
49
|
+
* return parseClassifierResponse(body);
|
|
50
|
+
* }
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
var BaseDecisionModel = class extends require_base.Runnable {
|
|
55
|
+
/** Provider model name used to answer questions. */
|
|
56
|
+
model;
|
|
57
|
+
constructor(fields) {
|
|
58
|
+
super(fields);
|
|
59
|
+
this.model = fields.model;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Classify one request.
|
|
63
|
+
*
|
|
64
|
+
* The run is traced as an LLM run with `ls_provider` and `ls_model_name`
|
|
65
|
+
* metadata, and its output carries `usage_metadata` when the provider reports
|
|
66
|
+
* usage.
|
|
67
|
+
*
|
|
68
|
+
* @param input State and questions to evaluate.
|
|
69
|
+
* @param options Callbacks, tags, metadata, and other runnable config.
|
|
70
|
+
* @returns Answers keyed by answer ID and typed from `questions`, with
|
|
71
|
+
* request metadata.
|
|
72
|
+
* @throws Error if a question is invalid, `questions` is empty, or the
|
|
73
|
+
* provider leaves a question unanswered or answers it with the wrong type
|
|
74
|
+
* or an unknown `Choice` label.
|
|
75
|
+
*/
|
|
76
|
+
async invoke(input, options) {
|
|
77
|
+
const config = require_config.ensureConfig(options);
|
|
78
|
+
return await this._callWithConfig(async (request, runConfig, runManager) => {
|
|
79
|
+
const { runType: _runType, ...childConfig } = runConfig ?? {};
|
|
80
|
+
const questions = require_types.parseQuestions(request.questions);
|
|
81
|
+
const answered = await this._classify(request.state, questions, require_config.patchConfig(childConfig, { callbacks: runManager?.getChild() }));
|
|
82
|
+
assertAnswered(questions, answered);
|
|
83
|
+
return answered;
|
|
84
|
+
}, input, {
|
|
85
|
+
...config,
|
|
86
|
+
runType: "llm",
|
|
87
|
+
metadata: {
|
|
88
|
+
...config.metadata,
|
|
89
|
+
ls_provider: this._provider,
|
|
90
|
+
ls_model_name: this.model,
|
|
91
|
+
ls_model_type: "chat"
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
exports.BaseDecisionModel = BaseDecisionModel;
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=base.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.cjs","names":["Runnable","ensureConfig","parseQuestions","patchConfig"],"sources":["../../src/decisions/base.ts"],"sourcesContent":["import type { CallbackManagerForChainRun } from \"../callbacks/manager.js\";\nimport { Runnable } from \"../runnables/base.js\";\nimport {\n ensureConfig,\n patchConfig,\n type RunnableConfig,\n} from \"../runnables/config.js\";\nimport {\n parseQuestions,\n type ClassifierRequest,\n type ClassifierResponse,\n type Question,\n type State,\n} from \"./types.js\";\n\n// Throws unless every question has an answer of its type, so the response\n// matches its typed answers. Names question IDs only, never answer values.\nfunction assertAnswered(\n questions: Record<string, Question>,\n response: ClassifierResponse\n): void {\n for (const [id, question] of Object.entries(questions)) {\n const answer = Object.hasOwn(response.answers, id)\n ? response.answers[id]\n : undefined;\n if (answer === undefined) {\n throw new Error(\n `Decision model returned no answer for question \"${id}\".`\n );\n }\n if (answer.type !== question.type) {\n throw new Error(\n `Decision model returned a ${answer.type} answer for ${question.type} question \"${id}\".`\n );\n }\n if (\n answer.type === \"choice\" &&\n question.type === \"choice\" &&\n !Object.hasOwn(question.criteria, answer.choice)\n ) {\n throw new Error(\n `Decision model returned a choice for question \"${id}\" that is not one of its labels.`\n );\n }\n }\n}\n\n/** Fields shared by every decision model. */\nexport interface BaseDecisionModelFields {\n /** Provider model name used to answer questions. */\n model: string;\n}\n\n/**\n * Answer typed questions about text, messages, or structured state.\n *\n * A decision model evaluates shared state against one or more questions and\n * returns typed answers: a probability for a `Noul`, a selected label for a\n * `Choice`, an expected level for a `Score`, and a location for a `Box`.\n * Answers keep their probability distributions and confidence so applications\n * can choose their own thresholds.\n *\n * Subclasses implement `_classify` to call a provider. This class validates\n * questions and handles callbacks, tracing metadata, and token-usage\n * reporting.\n *\n * @example\n * ```ts\n * import {\n * BaseDecisionModel,\n * parseClassifierResponse,\n * } from \"@langchain/core/decisions\";\n *\n * class MyDecisionModel extends BaseDecisionModel {\n * lc_namespace = [\"my_provider\", \"decisions\"];\n *\n * get _provider() {\n * return \"my_provider\";\n * }\n *\n * async _classify(\n * state: State,\n * questions: Record<string, Question>,\n * config?: Partial<RunnableConfig>\n * ) {\n * const body = await myClient.classify(\n * { model: this.model, state, questions },\n * { signal: config?.signal }\n * );\n * return parseClassifierResponse(body);\n * }\n * }\n * ```\n */\nexport abstract class BaseDecisionModel extends Runnable<\n ClassifierRequest,\n ClassifierResponse\n> {\n /** Provider model name used to answer questions. */\n readonly model: string;\n\n constructor(fields: BaseDecisionModelFields) {\n super(fields);\n this.model = fields.model;\n }\n\n /** Provider name reported to LangSmith as `ls_provider`. */\n abstract get _provider(): string;\n\n /**\n * Answer one request.\n *\n * @param state State to evaluate.\n * @param questions Validated questions keyed by answer ID.\n * @param config Runnable config, including the abort `signal`.\n * @returns Typed answers keyed by answer ID, with request metadata.\n */\n abstract _classify(\n state: State,\n questions: Record<string, Question>,\n config?: Partial<RunnableConfig>\n ): Promise<ClassifierResponse>;\n\n /**\n * Classify one request.\n *\n * The run is traced as an LLM run with `ls_provider` and `ls_model_name`\n * metadata, and its output carries `usage_metadata` when the provider reports\n * usage.\n *\n * @param input State and questions to evaluate.\n * @param options Callbacks, tags, metadata, and other runnable config.\n * @returns Answers keyed by answer ID and typed from `questions`, with\n * request metadata.\n * @throws Error if a question is invalid, `questions` is empty, or the\n * provider leaves a question unanswered or answers it with the wrong type\n * or an unknown `Choice` label.\n */\n async invoke<const Q extends Record<string, Question>>(\n input: ClassifierRequest<Q>,\n options?: Partial<RunnableConfig>\n ): Promise<ClassifierResponse<Q>> {\n const config = ensureConfig(options);\n const response = await this._callWithConfig(\n async (\n request: ClassifierRequest,\n runConfig?: Partial<RunnableConfig & { runType: string }>,\n runManager?: CallbackManagerForChainRun\n ) => {\n const { runType: _runType, ...childConfig } = runConfig ?? {};\n const questions = parseQuestions(request.questions);\n const answered = await this._classify(\n request.state,\n questions,\n patchConfig(childConfig, { callbacks: runManager?.getChild() })\n );\n assertAnswered(questions, answered);\n return answered;\n },\n input,\n {\n ...config,\n runType: \"llm\",\n metadata: {\n ...config.metadata,\n ls_provider: this._provider,\n ls_model_name: this.model,\n ls_model_type: \"chat\",\n },\n }\n );\n return response as ClassifierResponse<Q>;\n }\n}\n"],"mappings":";;;;AAiBA,SAAS,eACP,WACA,UACM;CACN,KAAK,MAAM,CAAC,IAAI,aAAa,OAAO,QAAQ,SAAS,GAAG;EACtD,MAAM,SAAS,OAAO,OAAO,SAAS,SAAS,EAAE,IAC7C,SAAS,QAAQ,MACjB,KAAA;EACJ,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,MACR,mDAAmD,GAAG,GACxD;EAEF,IAAI,OAAO,SAAS,SAAS,MAC3B,MAAM,IAAI,MACR,6BAA6B,OAAO,KAAK,cAAc,SAAS,KAAK,aAAa,GAAG,GACvF;EAEF,IACE,OAAO,SAAS,YAChB,SAAS,SAAS,YAClB,CAAC,OAAO,OAAO,SAAS,UAAU,OAAO,MAAM,GAE/C,MAAM,IAAI,MACR,kDAAkD,GAAG,iCACvD;CAEJ;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,IAAsB,oBAAtB,cAAgDA,aAAAA,SAG9C;;CAEA;CAEA,YAAY,QAAiC;EAC3C,MAAM,MAAM;EACZ,KAAK,QAAQ,OAAO;CACtB;;;;;;;;;;;;;;;;CAkCA,MAAM,OACJ,OACA,SACgC;EAChC,MAAM,SAASC,eAAAA,aAAa,OAAO;EA6BnC,OAAO,MA5BgB,KAAK,gBAC1B,OACE,SACA,WACA,eACG;GACH,MAAM,EAAE,SAAS,UAAU,GAAG,gBAAgB,aAAa,CAAC;GAC5D,MAAM,YAAYC,cAAAA,eAAe,QAAQ,SAAS;GAClD,MAAM,WAAW,MAAM,KAAK,UAC1B,QAAQ,OACR,WACAC,eAAAA,YAAY,aAAa,EAAE,WAAW,YAAY,SAAS,EAAE,CAAC,CAChE;GACA,eAAe,WAAW,QAAQ;GAClC,OAAO;EACT,GACA,OACA;GACE,GAAG;GACH,SAAS;GACT,UAAU;IACR,GAAG,OAAO;IACV,aAAa,KAAK;IAClB,eAAe,KAAK;IACpB,eAAe;GACjB;EACF,CACF;CAEF;AACF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { RunnableConfig } from "../runnables/types.cjs";
|
|
2
|
+
import { Runnable } from "../runnables/base.cjs";
|
|
3
|
+
import "../runnables/config.cjs";
|
|
4
|
+
import { ClassifierRequest, ClassifierResponse, Question, State } from "./types.cjs";
|
|
5
|
+
/** Fields shared by every decision model. */
|
|
6
|
+
export interface BaseDecisionModelFields {
|
|
7
|
+
/** Provider model name used to answer questions. */
|
|
8
|
+
model: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Answer typed questions about text, messages, or structured state.
|
|
12
|
+
*
|
|
13
|
+
* A decision model evaluates shared state against one or more questions and
|
|
14
|
+
* returns typed answers: a probability for a `Noul`, a selected label for a
|
|
15
|
+
* `Choice`, an expected level for a `Score`, and a location for a `Box`.
|
|
16
|
+
* Answers keep their probability distributions and confidence so applications
|
|
17
|
+
* can choose their own thresholds.
|
|
18
|
+
*
|
|
19
|
+
* Subclasses implement `_classify` to call a provider. This class validates
|
|
20
|
+
* questions and handles callbacks, tracing metadata, and token-usage
|
|
21
|
+
* reporting.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import {
|
|
26
|
+
* BaseDecisionModel,
|
|
27
|
+
* parseClassifierResponse,
|
|
28
|
+
* } from "@langchain/core/decisions";
|
|
29
|
+
*
|
|
30
|
+
* class MyDecisionModel extends BaseDecisionModel {
|
|
31
|
+
* lc_namespace = ["my_provider", "decisions"];
|
|
32
|
+
*
|
|
33
|
+
* get _provider() {
|
|
34
|
+
* return "my_provider";
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* async _classify(
|
|
38
|
+
* state: State,
|
|
39
|
+
* questions: Record<string, Question>,
|
|
40
|
+
* config?: Partial<RunnableConfig>
|
|
41
|
+
* ) {
|
|
42
|
+
* const body = await myClient.classify(
|
|
43
|
+
* { model: this.model, state, questions },
|
|
44
|
+
* { signal: config?.signal }
|
|
45
|
+
* );
|
|
46
|
+
* return parseClassifierResponse(body);
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare abstract class BaseDecisionModel extends Runnable<ClassifierRequest, ClassifierResponse> {
|
|
52
|
+
/** Provider model name used to answer questions. */
|
|
53
|
+
readonly model: string;
|
|
54
|
+
constructor(fields: BaseDecisionModelFields);
|
|
55
|
+
/** Provider name reported to LangSmith as `ls_provider`. */
|
|
56
|
+
abstract get _provider(): string;
|
|
57
|
+
/**
|
|
58
|
+
* Answer one request.
|
|
59
|
+
*
|
|
60
|
+
* @param state State to evaluate.
|
|
61
|
+
* @param questions Validated questions keyed by answer ID.
|
|
62
|
+
* @param config Runnable config, including the abort `signal`.
|
|
63
|
+
* @returns Typed answers keyed by answer ID, with request metadata.
|
|
64
|
+
*/
|
|
65
|
+
abstract _classify(state: State, questions: Record<string, Question>, config?: Partial<RunnableConfig>): Promise<ClassifierResponse>;
|
|
66
|
+
/**
|
|
67
|
+
* Classify one request.
|
|
68
|
+
*
|
|
69
|
+
* The run is traced as an LLM run with `ls_provider` and `ls_model_name`
|
|
70
|
+
* metadata, and its output carries `usage_metadata` when the provider reports
|
|
71
|
+
* usage.
|
|
72
|
+
*
|
|
73
|
+
* @param input State and questions to evaluate.
|
|
74
|
+
* @param options Callbacks, tags, metadata, and other runnable config.
|
|
75
|
+
* @returns Answers keyed by answer ID and typed from `questions`, with
|
|
76
|
+
* request metadata.
|
|
77
|
+
* @throws Error if a question is invalid, `questions` is empty, or the
|
|
78
|
+
* provider leaves a question unanswered or answers it with the wrong type
|
|
79
|
+
* or an unknown `Choice` label.
|
|
80
|
+
*/
|
|
81
|
+
invoke<const Q extends Record<string, Question>>(input: ClassifierRequest<Q>, options?: Partial<RunnableConfig>): Promise<ClassifierResponse<Q>>;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=base.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.cts","names":[],"sources":["../../src/decisions/base.ts"],"mappings":";;;;;iBAgDiB;;EAEf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA4CoB,0BAA0B,SAC9C,mBACA;;WAGS;EAET,YAAY,QAAQ;;eAMP;;;;;;;;;WAUJ,UACP,OAAO,OACP,WAAW,eAAe,WAC1B,SAAS,QAAQ,kBAChB,QAAQ;;;;;;;;;;;;;;;;EAiBL,aAAa,UAAU,eAAe,WAC1C,OAAO,kBAAkB,IACzB,UAAU,QAAQ,kBACjB,QAAQ,mBAAmB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { RunnableConfig } from "../runnables/types.js";
|
|
2
|
+
import { Runnable } from "../runnables/base.js";
|
|
3
|
+
import "../runnables/config.js";
|
|
4
|
+
import { ClassifierRequest, ClassifierResponse, Question, State } from "./types.js";
|
|
5
|
+
/** Fields shared by every decision model. */
|
|
6
|
+
export interface BaseDecisionModelFields {
|
|
7
|
+
/** Provider model name used to answer questions. */
|
|
8
|
+
model: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Answer typed questions about text, messages, or structured state.
|
|
12
|
+
*
|
|
13
|
+
* A decision model evaluates shared state against one or more questions and
|
|
14
|
+
* returns typed answers: a probability for a `Noul`, a selected label for a
|
|
15
|
+
* `Choice`, an expected level for a `Score`, and a location for a `Box`.
|
|
16
|
+
* Answers keep their probability distributions and confidence so applications
|
|
17
|
+
* can choose their own thresholds.
|
|
18
|
+
*
|
|
19
|
+
* Subclasses implement `_classify` to call a provider. This class validates
|
|
20
|
+
* questions and handles callbacks, tracing metadata, and token-usage
|
|
21
|
+
* reporting.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import {
|
|
26
|
+
* BaseDecisionModel,
|
|
27
|
+
* parseClassifierResponse,
|
|
28
|
+
* } from "@langchain/core/decisions";
|
|
29
|
+
*
|
|
30
|
+
* class MyDecisionModel extends BaseDecisionModel {
|
|
31
|
+
* lc_namespace = ["my_provider", "decisions"];
|
|
32
|
+
*
|
|
33
|
+
* get _provider() {
|
|
34
|
+
* return "my_provider";
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* async _classify(
|
|
38
|
+
* state: State,
|
|
39
|
+
* questions: Record<string, Question>,
|
|
40
|
+
* config?: Partial<RunnableConfig>
|
|
41
|
+
* ) {
|
|
42
|
+
* const body = await myClient.classify(
|
|
43
|
+
* { model: this.model, state, questions },
|
|
44
|
+
* { signal: config?.signal }
|
|
45
|
+
* );
|
|
46
|
+
* return parseClassifierResponse(body);
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare abstract class BaseDecisionModel extends Runnable<ClassifierRequest, ClassifierResponse> {
|
|
52
|
+
/** Provider model name used to answer questions. */
|
|
53
|
+
readonly model: string;
|
|
54
|
+
constructor(fields: BaseDecisionModelFields);
|
|
55
|
+
/** Provider name reported to LangSmith as `ls_provider`. */
|
|
56
|
+
abstract get _provider(): string;
|
|
57
|
+
/**
|
|
58
|
+
* Answer one request.
|
|
59
|
+
*
|
|
60
|
+
* @param state State to evaluate.
|
|
61
|
+
* @param questions Validated questions keyed by answer ID.
|
|
62
|
+
* @param config Runnable config, including the abort `signal`.
|
|
63
|
+
* @returns Typed answers keyed by answer ID, with request metadata.
|
|
64
|
+
*/
|
|
65
|
+
abstract _classify(state: State, questions: Record<string, Question>, config?: Partial<RunnableConfig>): Promise<ClassifierResponse>;
|
|
66
|
+
/**
|
|
67
|
+
* Classify one request.
|
|
68
|
+
*
|
|
69
|
+
* The run is traced as an LLM run with `ls_provider` and `ls_model_name`
|
|
70
|
+
* metadata, and its output carries `usage_metadata` when the provider reports
|
|
71
|
+
* usage.
|
|
72
|
+
*
|
|
73
|
+
* @param input State and questions to evaluate.
|
|
74
|
+
* @param options Callbacks, tags, metadata, and other runnable config.
|
|
75
|
+
* @returns Answers keyed by answer ID and typed from `questions`, with
|
|
76
|
+
* request metadata.
|
|
77
|
+
* @throws Error if a question is invalid, `questions` is empty, or the
|
|
78
|
+
* provider leaves a question unanswered or answers it with the wrong type
|
|
79
|
+
* or an unknown `Choice` label.
|
|
80
|
+
*/
|
|
81
|
+
invoke<const Q extends Record<string, Question>>(input: ClassifierRequest<Q>, options?: Partial<RunnableConfig>): Promise<ClassifierResponse<Q>>;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","names":[],"sources":["../../src/decisions/base.ts"],"mappings":";;;;;iBAgDiB;;EAEf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA4CoB,0BAA0B,SAC9C,mBACA;;WAGS;EAET,YAAY,QAAQ;;eAMP;;;;;;;;;WAUJ,UACP,OAAO,OACP,WAAW,eAAe,WAC1B,SAAS,QAAQ,kBAChB,QAAQ;;;;;;;;;;;;;;;;EAiBL,aAAa,UAAU,eAAe,WAC1C,OAAO,kBAAkB,IACzB,UAAU,QAAQ,kBACjB,QAAQ,mBAAmB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Runnable } from "../runnables/base.js";
|
|
2
|
+
import { ensureConfig, patchConfig } from "../runnables/config.js";
|
|
3
|
+
import { parseQuestions } from "./types.js";
|
|
4
|
+
// src/decisions/base.ts
|
|
5
|
+
function assertAnswered(questions, response) {
|
|
6
|
+
for (const [id, question] of Object.entries(questions)) {
|
|
7
|
+
const answer = Object.hasOwn(response.answers, id) ? response.answers[id] : void 0;
|
|
8
|
+
if (answer === void 0) throw new Error(`Decision model returned no answer for question "${id}".`);
|
|
9
|
+
if (answer.type !== question.type) throw new Error(`Decision model returned a ${answer.type} answer for ${question.type} question "${id}".`);
|
|
10
|
+
if (answer.type === "choice" && question.type === "choice" && !Object.hasOwn(question.criteria, answer.choice)) throw new Error(`Decision model returned a choice for question "${id}" that is not one of its labels.`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Answer typed questions about text, messages, or structured state.
|
|
15
|
+
*
|
|
16
|
+
* A decision model evaluates shared state against one or more questions and
|
|
17
|
+
* returns typed answers: a probability for a `Noul`, a selected label for a
|
|
18
|
+
* `Choice`, an expected level for a `Score`, and a location for a `Box`.
|
|
19
|
+
* Answers keep their probability distributions and confidence so applications
|
|
20
|
+
* can choose their own thresholds.
|
|
21
|
+
*
|
|
22
|
+
* Subclasses implement `_classify` to call a provider. This class validates
|
|
23
|
+
* questions and handles callbacks, tracing metadata, and token-usage
|
|
24
|
+
* reporting.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import {
|
|
29
|
+
* BaseDecisionModel,
|
|
30
|
+
* parseClassifierResponse,
|
|
31
|
+
* } from "@langchain/core/decisions";
|
|
32
|
+
*
|
|
33
|
+
* class MyDecisionModel extends BaseDecisionModel {
|
|
34
|
+
* lc_namespace = ["my_provider", "decisions"];
|
|
35
|
+
*
|
|
36
|
+
* get _provider() {
|
|
37
|
+
* return "my_provider";
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* async _classify(
|
|
41
|
+
* state: State,
|
|
42
|
+
* questions: Record<string, Question>,
|
|
43
|
+
* config?: Partial<RunnableConfig>
|
|
44
|
+
* ) {
|
|
45
|
+
* const body = await myClient.classify(
|
|
46
|
+
* { model: this.model, state, questions },
|
|
47
|
+
* { signal: config?.signal }
|
|
48
|
+
* );
|
|
49
|
+
* return parseClassifierResponse(body);
|
|
50
|
+
* }
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
var BaseDecisionModel = class extends Runnable {
|
|
55
|
+
/** Provider model name used to answer questions. */
|
|
56
|
+
model;
|
|
57
|
+
constructor(fields) {
|
|
58
|
+
super(fields);
|
|
59
|
+
this.model = fields.model;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Classify one request.
|
|
63
|
+
*
|
|
64
|
+
* The run is traced as an LLM run with `ls_provider` and `ls_model_name`
|
|
65
|
+
* metadata, and its output carries `usage_metadata` when the provider reports
|
|
66
|
+
* usage.
|
|
67
|
+
*
|
|
68
|
+
* @param input State and questions to evaluate.
|
|
69
|
+
* @param options Callbacks, tags, metadata, and other runnable config.
|
|
70
|
+
* @returns Answers keyed by answer ID and typed from `questions`, with
|
|
71
|
+
* request metadata.
|
|
72
|
+
* @throws Error if a question is invalid, `questions` is empty, or the
|
|
73
|
+
* provider leaves a question unanswered or answers it with the wrong type
|
|
74
|
+
* or an unknown `Choice` label.
|
|
75
|
+
*/
|
|
76
|
+
async invoke(input, options) {
|
|
77
|
+
const config = ensureConfig(options);
|
|
78
|
+
return await this._callWithConfig(async (request, runConfig, runManager) => {
|
|
79
|
+
const { runType: _runType, ...childConfig } = runConfig ?? {};
|
|
80
|
+
const questions = parseQuestions(request.questions);
|
|
81
|
+
const answered = await this._classify(request.state, questions, patchConfig(childConfig, { callbacks: runManager?.getChild() }));
|
|
82
|
+
assertAnswered(questions, answered);
|
|
83
|
+
return answered;
|
|
84
|
+
}, input, {
|
|
85
|
+
...config,
|
|
86
|
+
runType: "llm",
|
|
87
|
+
metadata: {
|
|
88
|
+
...config.metadata,
|
|
89
|
+
ls_provider: this._provider,
|
|
90
|
+
ls_model_name: this.model,
|
|
91
|
+
ls_model_type: "chat"
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
export { BaseDecisionModel };
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"sources":["../../src/decisions/base.ts"],"sourcesContent":["import type { CallbackManagerForChainRun } from \"../callbacks/manager.js\";\nimport { Runnable } from \"../runnables/base.js\";\nimport {\n ensureConfig,\n patchConfig,\n type RunnableConfig,\n} from \"../runnables/config.js\";\nimport {\n parseQuestions,\n type ClassifierRequest,\n type ClassifierResponse,\n type Question,\n type State,\n} from \"./types.js\";\n\n// Throws unless every question has an answer of its type, so the response\n// matches its typed answers. Names question IDs only, never answer values.\nfunction assertAnswered(\n questions: Record<string, Question>,\n response: ClassifierResponse\n): void {\n for (const [id, question] of Object.entries(questions)) {\n const answer = Object.hasOwn(response.answers, id)\n ? response.answers[id]\n : undefined;\n if (answer === undefined) {\n throw new Error(\n `Decision model returned no answer for question \"${id}\".`\n );\n }\n if (answer.type !== question.type) {\n throw new Error(\n `Decision model returned a ${answer.type} answer for ${question.type} question \"${id}\".`\n );\n }\n if (\n answer.type === \"choice\" &&\n question.type === \"choice\" &&\n !Object.hasOwn(question.criteria, answer.choice)\n ) {\n throw new Error(\n `Decision model returned a choice for question \"${id}\" that is not one of its labels.`\n );\n }\n }\n}\n\n/** Fields shared by every decision model. */\nexport interface BaseDecisionModelFields {\n /** Provider model name used to answer questions. */\n model: string;\n}\n\n/**\n * Answer typed questions about text, messages, or structured state.\n *\n * A decision model evaluates shared state against one or more questions and\n * returns typed answers: a probability for a `Noul`, a selected label for a\n * `Choice`, an expected level for a `Score`, and a location for a `Box`.\n * Answers keep their probability distributions and confidence so applications\n * can choose their own thresholds.\n *\n * Subclasses implement `_classify` to call a provider. This class validates\n * questions and handles callbacks, tracing metadata, and token-usage\n * reporting.\n *\n * @example\n * ```ts\n * import {\n * BaseDecisionModel,\n * parseClassifierResponse,\n * } from \"@langchain/core/decisions\";\n *\n * class MyDecisionModel extends BaseDecisionModel {\n * lc_namespace = [\"my_provider\", \"decisions\"];\n *\n * get _provider() {\n * return \"my_provider\";\n * }\n *\n * async _classify(\n * state: State,\n * questions: Record<string, Question>,\n * config?: Partial<RunnableConfig>\n * ) {\n * const body = await myClient.classify(\n * { model: this.model, state, questions },\n * { signal: config?.signal }\n * );\n * return parseClassifierResponse(body);\n * }\n * }\n * ```\n */\nexport abstract class BaseDecisionModel extends Runnable<\n ClassifierRequest,\n ClassifierResponse\n> {\n /** Provider model name used to answer questions. */\n readonly model: string;\n\n constructor(fields: BaseDecisionModelFields) {\n super(fields);\n this.model = fields.model;\n }\n\n /** Provider name reported to LangSmith as `ls_provider`. */\n abstract get _provider(): string;\n\n /**\n * Answer one request.\n *\n * @param state State to evaluate.\n * @param questions Validated questions keyed by answer ID.\n * @param config Runnable config, including the abort `signal`.\n * @returns Typed answers keyed by answer ID, with request metadata.\n */\n abstract _classify(\n state: State,\n questions: Record<string, Question>,\n config?: Partial<RunnableConfig>\n ): Promise<ClassifierResponse>;\n\n /**\n * Classify one request.\n *\n * The run is traced as an LLM run with `ls_provider` and `ls_model_name`\n * metadata, and its output carries `usage_metadata` when the provider reports\n * usage.\n *\n * @param input State and questions to evaluate.\n * @param options Callbacks, tags, metadata, and other runnable config.\n * @returns Answers keyed by answer ID and typed from `questions`, with\n * request metadata.\n * @throws Error if a question is invalid, `questions` is empty, or the\n * provider leaves a question unanswered or answers it with the wrong type\n * or an unknown `Choice` label.\n */\n async invoke<const Q extends Record<string, Question>>(\n input: ClassifierRequest<Q>,\n options?: Partial<RunnableConfig>\n ): Promise<ClassifierResponse<Q>> {\n const config = ensureConfig(options);\n const response = await this._callWithConfig(\n async (\n request: ClassifierRequest,\n runConfig?: Partial<RunnableConfig & { runType: string }>,\n runManager?: CallbackManagerForChainRun\n ) => {\n const { runType: _runType, ...childConfig } = runConfig ?? {};\n const questions = parseQuestions(request.questions);\n const answered = await this._classify(\n request.state,\n questions,\n patchConfig(childConfig, { callbacks: runManager?.getChild() })\n );\n assertAnswered(questions, answered);\n return answered;\n },\n input,\n {\n ...config,\n runType: \"llm\",\n metadata: {\n ...config.metadata,\n ls_provider: this._provider,\n ls_model_name: this.model,\n ls_model_type: \"chat\",\n },\n }\n );\n return response as ClassifierResponse<Q>;\n }\n}\n"],"mappings":";;;;AAiBA,SAAS,eACP,WACA,UACM;CACN,KAAK,MAAM,CAAC,IAAI,aAAa,OAAO,QAAQ,SAAS,GAAG;EACtD,MAAM,SAAS,OAAO,OAAO,SAAS,SAAS,EAAE,IAC7C,SAAS,QAAQ,MACjB,KAAA;EACJ,IAAI,WAAW,KAAA,GACb,MAAM,IAAI,MACR,mDAAmD,GAAG,GACxD;EAEF,IAAI,OAAO,SAAS,SAAS,MAC3B,MAAM,IAAI,MACR,6BAA6B,OAAO,KAAK,cAAc,SAAS,KAAK,aAAa,GAAG,GACvF;EAEF,IACE,OAAO,SAAS,YAChB,SAAS,SAAS,YAClB,CAAC,OAAO,OAAO,SAAS,UAAU,OAAO,MAAM,GAE/C,MAAM,IAAI,MACR,kDAAkD,GAAG,iCACvD;CAEJ;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,IAAsB,oBAAtB,cAAgD,SAG9C;;CAEA;CAEA,YAAY,QAAiC;EAC3C,MAAM,MAAM;EACZ,KAAK,QAAQ,OAAO;CACtB;;;;;;;;;;;;;;;;CAkCA,MAAM,OACJ,OACA,SACgC;EAChC,MAAM,SAAS,aAAa,OAAO;EA6BnC,OAAO,MA5BgB,KAAK,gBAC1B,OACE,SACA,WACA,eACG;GACH,MAAM,EAAE,SAAS,UAAU,GAAG,gBAAgB,aAAa,CAAC;GAC5D,MAAM,YAAY,eAAe,QAAQ,SAAS;GAClD,MAAM,WAAW,MAAM,KAAK,UAC1B,QAAQ,OACR,WACA,YAAY,aAAa,EAAE,WAAW,YAAY,SAAS,EAAE,CAAC,CAChE;GACA,eAAe,WAAW,QAAQ;GAClC,OAAO;EACT,GACA,OACA;GACE,GAAG;GACH,SAAS;GACT,UAAU;IACR,GAAG,OAAO;IACV,aAAa,KAAK;IAClB,eAAe,KAAK;IACpB,eAAe;GACjB;EACF,CACF;CAEF;AACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_base = require("./base.cjs");
|
|
4
|
+
const require_types = require("./types.cjs");
|
|
5
|
+
// src/decisions/index.ts
|
|
6
|
+
var decisions_exports = /* @__PURE__ */ require_runtime.__exportAll({
|
|
7
|
+
BaseDecisionModel: () => require_base.BaseDecisionModel,
|
|
8
|
+
parseClassifierResponse: () => require_types.parseClassifierResponse,
|
|
9
|
+
parseQuestions: () => require_types.parseQuestions
|
|
10
|
+
});
|
|
11
|
+
exports.BaseDecisionModel = require_base.BaseDecisionModel;
|
|
12
|
+
Object.defineProperty(exports, "decisions_exports", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function() {
|
|
15
|
+
return decisions_exports;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
exports.parseClassifierResponse = require_types.parseClassifierResponse;
|
|
19
|
+
exports.parseQuestions = require_types.parseQuestions;
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/decisions/index.ts"],"sourcesContent":["export { BaseDecisionModel, type BaseDecisionModelFields } from \"./base.js\";\nexport {\n parseClassifierResponse,\n parseQuestions,\n type Answer,\n type AnswerFor,\n type Answers,\n type Box,\n type BoxAnswer,\n type BoxCoordinates,\n type Choice,\n type ChoiceAnswer,\n type ClassifierRequest,\n type ClassifierResponse,\n type ClassifierResponseFields,\n type Content,\n type JsonValue,\n type Noul,\n type NoulAnswer,\n type NoulCriteria,\n type Question,\n type Score,\n type ScoreAnswer,\n type State,\n type StateValue,\n} from \"./types.js\";\n"],"mappings":""}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { BaseDecisionModel, BaseDecisionModelFields } from "./base.cjs";
|
|
2
|
+
import { Answer, AnswerFor, Answers, Box, BoxAnswer, BoxCoordinates, Choice, ChoiceAnswer, ClassifierRequest, ClassifierResponse, ClassifierResponseFields, Content, JsonValue, Noul, NoulAnswer, NoulCriteria, Question, Score, ScoreAnswer, State, StateValue, parseClassifierResponse, parseQuestions } from "./types.cjs";
|
|
3
|
+
export { type Answer, type AnswerFor, type Answers, BaseDecisionModel, type BaseDecisionModelFields, type Box, type BoxAnswer, type BoxCoordinates, type Choice, type ChoiceAnswer, type ClassifierRequest, type ClassifierResponse, type ClassifierResponseFields, type Content, type JsonValue, type Noul, type NoulAnswer, type NoulCriteria, type Question, type Score, type ScoreAnswer, type State, type StateValue, parseClassifierResponse, parseQuestions };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { BaseDecisionModel, BaseDecisionModelFields } from "./base.js";
|
|
2
|
+
import { Answer, AnswerFor, Answers, Box, BoxAnswer, BoxCoordinates, Choice, ChoiceAnswer, ClassifierRequest, ClassifierResponse, ClassifierResponseFields, Content, JsonValue, Noul, NoulAnswer, NoulCriteria, Question, Score, ScoreAnswer, State, StateValue, parseClassifierResponse, parseQuestions } from "./types.js";
|
|
3
|
+
export { type Answer, type AnswerFor, type Answers, BaseDecisionModel, type BaseDecisionModelFields, type Box, type BoxAnswer, type BoxCoordinates, type Choice, type ChoiceAnswer, type ClassifierRequest, type ClassifierResponse, type ClassifierResponseFields, type Content, type JsonValue, type Noul, type NoulAnswer, type NoulCriteria, type Question, type Score, type ScoreAnswer, type State, type StateValue, parseClassifierResponse, parseQuestions };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { BaseDecisionModel } from "./base.js";
|
|
3
|
+
import { parseClassifierResponse, parseQuestions } from "./types.js";
|
|
4
|
+
// src/decisions/index.ts
|
|
5
|
+
var decisions_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
+
BaseDecisionModel: () => BaseDecisionModel,
|
|
7
|
+
parseClassifierResponse: () => parseClassifierResponse,
|
|
8
|
+
parseQuestions: () => parseQuestions
|
|
9
|
+
});
|
|
10
|
+
export { BaseDecisionModel, decisions_exports, parseClassifierResponse, parseQuestions };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/decisions/index.ts"],"sourcesContent":["export { BaseDecisionModel, type BaseDecisionModelFields } from \"./base.js\";\nexport {\n parseClassifierResponse,\n parseQuestions,\n type Answer,\n type AnswerFor,\n type Answers,\n type Box,\n type BoxAnswer,\n type BoxCoordinates,\n type Choice,\n type ChoiceAnswer,\n type ClassifierRequest,\n type ClassifierResponse,\n type ClassifierResponseFields,\n type Content,\n type JsonValue,\n type Noul,\n type NoulAnswer,\n type NoulCriteria,\n type Question,\n type Score,\n type ScoreAnswer,\n type State,\n type StateValue,\n} from \"./types.js\";\n"],"mappings":""}
|