Add reasoningTag param to openai compat config

This commit is contained in:
bkellam 2025-10-29 17:04:15 -07:00
parent 727a6da105
commit c1ebcb0960
9 changed files with 110 additions and 2 deletions

View file

@ -292,6 +292,7 @@ The OpenAI compatible provider allows you to use any model that is compatible wi
<Accordion title="Troubleshooting"> <Accordion title="Troubleshooting">
- When using [llama.cpp](https://github.com/ggml-org/llama.cpp), if you hit "Failed after 3 attempts. Last error: tools param requires --jinja flag", add the `--jinja` flag to your `llama-server` command. - When using [llama.cpp](https://github.com/ggml-org/llama.cpp), if you hit "Failed after 3 attempts. Last error: tools param requires --jinja flag", add the `--jinja` flag to your `llama-server` command.
- If you're seeing the LLM outputing reasoning tokens wrapped in XML tags (e.g., `<reasoning>`, `<thinking>`, etc.), you can configure the `reasoningTag` parameter to the name of the tag (without angle brackets). This parameter defaults to `think`.
</Accordion> </Accordion>
### OpenRouter ### OpenRouter

View file

@ -2633,6 +2633,16 @@
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"reasoningTag": {
"type": "string",
"description": "The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.",
"default": "think",
"examples": [
"think",
"thinking",
"reasoning"
]
} }
}, },
"required": [ "required": [
@ -4052,6 +4062,16 @@
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"reasoningTag": {
"type": "string",
"description": "The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.",
"default": "think",
"examples": [
"think",
"thinking",
"reasoning"
]
} }
}, },
"required": [ "required": [

View file

@ -1202,6 +1202,16 @@
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"reasoningTag": {
"type": "string",
"description": "The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.",
"default": "think",
"examples": [
"think",
"thinking",
"reasoning"
]
} }
}, },
"required": [ "required": [
@ -2621,6 +2631,16 @@
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"reasoningTag": {
"type": "string",
"description": "The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.",
"default": "think",
"examples": [
"think",
"thinking",
"reasoning"
]
} }
}, },
"required": [ "required": [

View file

@ -2632,6 +2632,16 @@ const schema = {
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"reasoningTag": {
"type": "string",
"description": "The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.",
"default": "think",
"examples": [
"think",
"thinking",
"reasoning"
]
} }
}, },
"required": [ "required": [
@ -4051,6 +4061,16 @@ const schema = {
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"reasoningTag": {
"type": "string",
"description": "The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.",
"default": "think",
"examples": [
"think",
"thinking",
"reasoning"
]
} }
}, },
"required": [ "required": [

View file

@ -974,6 +974,10 @@ export interface OpenAICompatibleLanguageModel {
baseUrl: string; baseUrl: string;
headers?: LanguageModelHeaders; headers?: LanguageModelHeaders;
queryParams?: LanguageModelQueryParams; queryParams?: LanguageModelQueryParams;
/**
* The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.
*/
reasoningTag?: string;
} }
/** /**
* Optional query parameters to include in the request url. * Optional query parameters to include in the request url.

View file

@ -1201,6 +1201,16 @@ const schema = {
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"reasoningTag": {
"type": "string",
"description": "The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.",
"default": "think",
"examples": [
"think",
"thinking",
"reasoning"
]
} }
}, },
"required": [ "required": [
@ -2620,6 +2630,16 @@ const schema = {
} }
}, },
"additionalProperties": false "additionalProperties": false
},
"reasoningTag": {
"type": "string",
"description": "The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.",
"default": "think",
"examples": [
"think",
"thinking",
"reasoning"
]
} }
}, },
"required": [ "required": [

View file

@ -453,6 +453,10 @@ export interface OpenAICompatibleLanguageModel {
baseUrl: string; baseUrl: string;
headers?: LanguageModelHeaders; headers?: LanguageModelHeaders;
queryParams?: LanguageModelQueryParams; queryParams?: LanguageModelQueryParams;
/**
* The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.
*/
reasoningTag?: string;
} }
/** /**
* Optional query parameters to include in the request url. * Optional query parameters to include in the request url.

View file

@ -25,7 +25,7 @@ import { ChatVisibility, OrgRole, Prisma, PrismaClient } from "@sourcebot/db";
import { LanguageModel } from "@sourcebot/schemas/v3/languageModel.type"; import { LanguageModel } from "@sourcebot/schemas/v3/languageModel.type";
import { Token } from "@sourcebot/schemas/v3/shared.type"; import { Token } from "@sourcebot/schemas/v3/shared.type";
import { loadConfig } from "@sourcebot/shared"; import { loadConfig } from "@sourcebot/shared";
import { generateText, JSONValue } from "ai"; import { generateText, JSONValue, extractReasoningMiddleware, wrapLanguageModel } from "ai";
import fs from 'fs'; import fs from 'fs';
import { StatusCodes } from "http-status-codes"; import { StatusCodes } from "http-status-codes";
import path from 'path'; import path from 'path';
@ -568,8 +568,17 @@ export const _getAISDKLanguageModelAndOptions = async (config: LanguageModel, or
: undefined, : undefined,
}); });
return { const model = wrapLanguageModel({
model: openai.chatModel(modelId), model: openai.chatModel(modelId),
middleware: [
extractReasoningMiddleware({
tagName: config.reasoningTag ?? 'think',
}),
]
});
return {
model,
} }
} }
case 'openrouter': { case 'openrouter': {

View file

@ -425,6 +425,16 @@
}, },
"queryParams": { "queryParams": {
"$ref": "./shared.json#/definitions/LanguageModelQueryParams" "$ref": "./shared.json#/definitions/LanguageModelQueryParams"
},
"reasoningTag": {
"type": "string",
"description": "The name of the XML tag to extract reasoning from (without angle brackets). Defaults to `think`.",
"default": "think",
"examples": [
"think",
"thinking",
"reasoning"
]
} }
}, },
"required": [ "required": [