langchain
Version:
Typescript bindings for langchain
71 lines (70 loc) • 2.59 kB
JavaScript
const require_errors = require("../errors.cjs");
const require_middleware = require("../middleware.cjs");
let _langchain_core_messages = require("@langchain/core/messages");
let _langchain_core_errors = require("@langchain/core/errors");
// src/agents/middleware/modelRefusal.ts
function throwIfRefused(message) {
if (!message) return;
for (const block of message.contentBlocks) if (block.type === "refusal") throw _langchain_core_errors.ModelRefusalError.fromRefusal(block, message);
}
/**
* The `StructuredOutputParsingError` behind `error`, if any.
*
* Middleware listed after this one wraps errors in `MiddlewareError`, so the
* parsing error can sit further down the `cause` chain.
*/
function parsingError(error) {
let current = error;
while (require_errors.MiddlewareError.isInstance(current)) current = current.cause;
return current instanceof require_errors.StructuredOutputParsingError ? current : void 0;
}
/**
* Middleware that throws {@link ModelRefusalError} when the model refuses.
*
* Providers report a refusal, such as a safety-policy refusal, as a successful
* response, so without this middleware the agent run ends as if it succeeded.
* The middleware checks each model response for a `refusal` content block,
* including refusals that fail to parse under a structured `responseFormat`.
* It does not detect refusals the model writes as ordinary text.
*
* List it after {@link modelFallbackMiddleware} so the fallback catches the
* error and retries the request on the next model. `modelRetryMiddleware` does
* not retry refusals.
*
* @example
* ```ts
* import {
* createAgent,
* modelFallbackMiddleware,
* modelRefusalMiddleware,
* } from "langchain";
*
* const agent = createAgent({
* model: "anthropic:claude-sonnet-5-5",
* tools: [],
* middleware: [
* modelFallbackMiddleware("openai:gpt-6.1-sol"),
* modelRefusalMiddleware(),
* ],
* });
* ```
*/
function modelRefusalMiddleware() {
return require_middleware.createMiddleware({
name: "modelRefusalMiddleware",
wrapModelCall: async (request, handler) => {
let response;
try {
response = await handler(request);
} catch (error) {
throwIfRefused(parsingError(error)?.aiMessage);
throw error;
}
const messages = _langchain_core_messages.AIMessage.isInstance(response) ? [response] : response.messages ?? [];
for (const message of messages) if (_langchain_core_messages.AIMessage.isInstance(message)) throwIfRefused(message);
return response;
}
});
}
exports.modelRefusalMiddleware = modelRefusalMiddleware;
//# sourceMappingURL=modelRefusal.cjs.map