UNPKG

@langchain/core

Version:
98 lines (97 loc) • 3.62 kB
const require_base = require("../runnables/base.cjs"); const require_config = require("../runnables/config.cjs"); const require_types = require("./types.cjs"); // src/decisions/base.ts function assertAnswered(questions, response) { for (const [id, question] of Object.entries(questions)) { const answer = Object.hasOwn(response.answers, id) ? response.answers[id] : void 0; if (answer === void 0) throw new Error(`Decision model returned no answer for question "${id}".`); if (answer.type !== question.type) throw new Error(`Decision model returned a ${answer.type} answer for ${question.type} question "${id}".`); 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.`); } } /** * Answer typed questions about text, messages, or structured state. * * A decision model evaluates shared state against one or more questions and * returns typed answers: a probability for a `Noul`, a selected label for a * `Choice`, an expected level for a `Score`, and a location for a `Box`. * Answers keep their probability distributions and confidence so applications * can choose their own thresholds. * * Subclasses implement `_classify` to call a provider. This class validates * questions and handles callbacks, tracing metadata, and token-usage * reporting. * * @example * ```ts * import { * BaseDecisionModel, * parseClassifierResponse, * } from "@langchain/core/decisions"; * * class MyDecisionModel extends BaseDecisionModel { * lc_namespace = ["my_provider", "decisions"]; * * get _provider() { * return "my_provider"; * } * * async _classify( * state: State, * questions: Record<string, Question>, * config?: Partial<RunnableConfig> * ) { * const body = await myClient.classify( * { model: this.model, state, questions }, * { signal: config?.signal } * ); * return parseClassifierResponse(body); * } * } * ``` */ var BaseDecisionModel = class extends require_base.Runnable { /** Provider model name used to answer questions. */ model; constructor(fields) { super(fields); this.model = fields.model; } /** * Classify one request. * * The run is traced as an LLM run with `ls_provider` and `ls_model_name` * metadata, and its output carries `usage_metadata` when the provider reports * usage. * * @param input State and questions to evaluate. * @param options Callbacks, tags, metadata, and other runnable config. * @returns Answers keyed by answer ID and typed from `questions`, with * request metadata. * @throws Error if a question is invalid, `questions` is empty, or the * provider leaves a question unanswered or answers it with the wrong type * or an unknown `Choice` label. */ async invoke(input, options) { const config = require_config.ensureConfig(options); return await this._callWithConfig(async (request, runConfig, runManager) => { const { runType: _runType, ...childConfig } = runConfig ?? {}; const questions = require_types.parseQuestions(request.questions); const answered = await this._classify(request.state, questions, require_config.patchConfig(childConfig, { callbacks: runManager?.getChild() })); assertAnswered(questions, answered); return answered; }, input, { ...config, runType: "llm", metadata: { ...config.metadata, ls_provider: this._provider, ls_model_name: this.model, ls_model_type: "chat" } }); } }; exports.BaseDecisionModel = BaseDecisionModel; //# sourceMappingURL=base.cjs.map