Skip to content

[Epic] Enhance Custom Model Support for Multiple Providers (Azure, Gemini, OpenRouter)Β #56

@andai0731

Description

@andai0731

πŸ§‘β€πŸ’» Maintainer's Note

A big thanks to @[Original-Poster-Username] for providing the detailed logs!

After analysis, we have confirmed the root cause:
The current "Add Custom Model" feature was designed to support only the "OpenAI" provider type. When a user attempts to configure an Azure OpenAI endpoint, the system does not know how to parse the Azure-specific fields (e.g., Endpoint, API Version, Deployment ID).

This leads directly to the TypeError: Invalid URL ... input: 'undefined/...' error seen in the logs, as the backend logic fails to find the expected configuration values when building the request.

This is not a bug in a specific provider's logic, but rather a core feature (multi-provider support) that is missing.

This issue will now serve as an [Epic] to track the work required to:

  1. Add a "Provider Type" selector to the UI.
  2. Implement full (UI + Backend) support for new providers.

🎯 Task Breakdown (Tasks for Contribution)

We have broken this epic into the following independent tasks. Contributions are welcome!


Original User Report & Logs

When trying to add the api there is a db error
Or error on accessing the url

These are the logs

I have removed the api key from logs

--> GET /api/conversation?mode_type=task&agent_id=null 200 6ms 35b
config { channel: 'provider', service: 'Azure', model: 'DeepSeek-V3.1' }
options: {
model_info: {
model_name: 'DeepSeek-V3.1',
platform_name: 'Azure',
api_key: '',
api_url: 'https://schou-m6cjy710-francecentral.services.ai.azure.com/models/chat/completions?api-version=2024-05-01-preview#/chat/completions',
base_url: 'https://schou-m6cjy710-francecentral.services.ai.azure.com/models/chat/completions?api-version=2024-05-01-preview#',
is_subscribe: false
}
}
azure.options {
messages: [],
model: 'DeepSeek-V3.1',
prompt: '\n' +
' You are a helpful assistant that generates concise, descriptive titles for conversations with Lemon. Your name is Lemon. Lemon is a helpful AI agent that can interact with a computer to solve tasks using bash terminal, file editor, and browser. Given a user message (which may be truncated), generate a concise, descriptive title for the conversation. Return only the title, with no additional text, quotes, or explanations.\n' +
' Reply in the language used in the message\n' +
' Generate a title for a conversation that starts with this message:\n' +
' \n' +
' hello\n' +
' ',
streaming: true,
temperature: 0
}
config {
"method": "post",
"maxBodyLength": null,
"url": "undefined/openai/responses?api-version=undefined",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer undefined"
},
"data": {
"model": "DeepSeek-V3.1",
"input": [
{
"role": "user",
"content": "\n You are a helpful assistant that generates concise, descriptive titles for conversations with Lemon. Your name is Lemon. Lemon is a helpful AI agent that can interact with a computer to solve tasks using bash terminal, file editor, and browser. Given a user message (which may be truncated), generate a concise, descriptive title for the conversation. Return only the title, with no additional text, quotes, or explanations.\n Reply in the language used in the message\n Generate a title for a conversation that starts with this message:\n \n hello\n "
}
],
"stream": true
}
}
TypeError: Invalid URL
at new URL (node:internal/url:825:25)
at dispatchHttpRequest (/app/node_modules/axios/dist/node/axios.cjs:2925:20)
at /app/node_modules/axios/dist/node/axios.cjs:2845:5
at new Promise ()
at wrapAsync (/app/node_modules/axios/dist/node/axios.cjs:2825:10)
at http (/app/node_modules/axios/dist/node/axios.cjs:2863:10)
at Axios.dispatchRequest (/app/node_modules/axios/dist/node/axios.cjs:4323:10)
at Axios._request (/app/node_modules/axios/dist/node/axios.cjs:4621:33)
at Axios.request (/app/node_modules/axios/dist/node/axios.cjs:4478:25)
at Function.wrap [as request] (/app/node_modules/axios/dist/node/axios.cjs:31:15)
at Axios.request (/app/node_modules/axios/dist/node/axios.cjs:4483:41)
at async chatCompletion (/app/src/completion/llm.azure.openai.js:73:18)
at async Azure.call (/app/src/completion/llm.azure.openai.js:108:22)
at async Azure.start (/app/src/completion/llm.base.js:40:22)
at async Azure.completion (/app/src/completion/llm.base.js:29:21)
at async call (/app/src/utils/llm.js:45:19)
at async generate_title_local (/app/src/agent/generate-title/index.js:35:21)
at async generate_title (/app/src/agent/generate-title/index.js:18:18)
at async /app/src/routers/conversation/conversation.js:310:15
at async /app/src/middlewares/auth.js:17:5 {
code: 'ERR_INVALID_URL',
input: 'undefined/openai/responses?api-version=undefined'
}
PUT /api/conversation/b4a56f88-f49f-4904-8797-689db3a3db25 - 72ms
--> PUT /api/conversation/b4a56f88-f49f-4904-8797-689db3a3db25 200 74ms 70b
<-- GET /api/conversation/b4a56f88-f49f-4904-8797-689db3a3db25
Request URL: /api/conversation/b4a56f88-f49f-4904-8797-689db3a3db25
modelIds [ 50 ]
GET /api/conversation/b4a56f88-f49f-4904-8797-689db3a3db25 - 7ms
--> GET /api/conversation/b4a56f88-f49f-4904-8797-689db3a3db25 404 9ms -
<-- POST /api/agent/generate
Request URL: /api/agent/generate
config { channel: 'provider', service: 'Azure', model: 'DeepSeek-V3.1' }
options: {
model_info: {
model_name: 'DeepSeek-V3.1',
platform_name: 'Azure',
api_key: '',
api_url: 'https://schou-m6cjy710-francecentral.services.ai.azure.com/models/chat/completions?api-version=2024-05-01-preview#/chat/completions',
base_url: 'https://schou-m6cjy710-francecentral.services.ai.azure.com/models/chat/completions?api-version=2024-05-01-preview#',
is_subscribe: false
}
}
azure.options {
messages: [],
model: 'DeepSeek-V3.1',
prompt: "You are an expert in defining AI Agent product requirements. Based on the user's request, abstract the core name (name) of the Agent they want to build and a detailed functional description (describe) of that Agent. Return the result in the same language as the user's input.\n" +
'\n' +
'When defining "name":\n' +
* **Extract the Agent's most core, abstract purpose, removing specific modifiers and qualifiers to make it concise and general.** For example, if the user wants to plan a trip, the name should be "Travel Assistant" instead of "Trip Planning Assistant."\n +
"* The name should accurately reflect the Agent's primary role.\n" +
'\n' +
'When defining "describe":\n' +
"* Explain in as much detail as possible the Agent's main responsibilities, processing flow, expected output, or problems solved.\n" +
"* If the user's request is unclear, make reasonable inferences and additions based on common sense or typical Agent functionalities.\n" +
'\n' +
'Please return the output in JSON format, with fields "name" and "describe".\n' +
'\n' +
'User Request: hello\n' +
' ',
streaming: true
}
config {
"method": "post",
"maxBodyLength": null,
"url": "undefined/openai/responses?api-version=undefined",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer undefined"
},
"data": {
"model": "DeepSeek-V3.1",
"input": [
{
"role": "user",
"content": "You are an expert in defining AI Agent product requirements. Based on the user's request, abstract the core name (name) of the Agent they want to build and a detailed functional description (describe) of that Agent. Return the result in the same language as the user's input.\n\nWhen defining "name":\n* Extract the Agent's most core, abstract purpose, removing specific modifiers and qualifiers to make it concise and general. For example, if the user wants to plan a trip, the name should be "Travel Assistant" instead of "Trip Planning Assistant."\n* The name should accurately reflect the Agent's primary role.\n\nWhen defining "describe":\n* Explain in as much detail as possible the Agent's main responsibilities, processing flow, expected output, or problems solved.\n* If the user's request is unclear, make reasonable inferences and additions based on common sense or typical Agent functionalities.\n\nPlease return the output in JSON format, with fields "name" and "describe".\n\nUser Request: hello\n "
}
],
"stream": true
}
}
TypeError: Invalid URL
at new URL (node:internal/url:825:25)
at dispatchHttpRequest (/app/node_modules/axios/dist/node/axios.cjs:2925:20)
at /app/node_modules/axios/dist/node/axios.cjs:2845:5
at new Promise ()
at wrapAsync (/app/node_modules/axios/dist/node/axios.cjs:2825:10)
at http (/app/node_modules/axios/dist/node/axios.cjs:2863:10)
at Axios.dispatchRequest (/app/node_modules/axios/dist/node/axios.cjs:4323:10)
at Axios._request (/app/node_modules/axios/dist/node/axios.cjs:4621:33)
at Axios.request (/app/node_modules/axios/dist/node/axios.cjs:4478:25)
at Function.wrap [as request] (/app/node_modules/axios/dist/node/axios.cjs:31:15)
at Axios.request (/app/node_modules/axios/dist/node/axios.cjs:4483:41)
at async chatCompletion (/app/src/completion/llm.azure.openai.js:73:18)
at async Azure.call (/app/src/completion/llm.azure.openai.js:108:22)
at async Azure.start (/app/src/completion/llm.base.js:40:22)
at async Azure.completion (/app/src/completion/llm.base.js:29:21)
at async call (/app/src/utils/llm.js:45:19)
at async generate_agent_local (/app/src/agent/generate-agent/index.js:32:19)
at async generate_agent (/app/src/agent/generate-agent/index.js:17:16)
at async /app/src/routers/agent/agent.js:35:32
at async /app/src/middlewares/auth.js:17:5 {
code: 'ERR_INVALID_URL',
input: 'undefined/openai/responses?api-version=undefined'
}
POST /api/agent/generate - 15ms
--> POST /api/agent/generate 200 15ms 63b
<-- POST /api/agent/run
Request URL: /api/agent/run
<-- GET /api/agent
Request URL: /api/agent
xxx POST /api/agent/run 500 6ms -
server error Error: WHERE parameter "id" has invalid "undefined" value
at SQLiteQueryGenerator.whereItemQuery (/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1746:13)
at /app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1737:25
at Array.forEach ()
at SQLiteQueryGenerator.whereItemsQuery (/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1735:35)
at SQLiteQueryGenerator.whereQuery (/app/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1717:24)
at SQLiteQueryGenerator.updateQuery (/app/node_modules/sequelize/lib/dialects/sqlite/query-generator.js:185:84)
at SQLiteQueryInterface.bulkUpdate (/app/node_modules/sequelize/lib/dialects/abstract/query-interface.js:361:37)
at agent.update (/app/node_modules/sequelize/lib/model.js:2010:54)
at async /app/src/routers/agent/run.js:92:3
at async /app/src/middlewares/auth.js:17:5 {
request: {
method: 'POST',
url: '/api/agent/run',
header: {
host: '127.0.0.1:3000',
'node-token': '',
accept: 'text/event-stream',
'sec-fetch-site': 'same-origin',
'accept-language': 'en-IN,en-GB;q=0.9,en;q=0.8',
'accept-encoding': 'gzip, deflate',
'sec-fetch-mode': 'cors',
'content-type': 'application/json',
origin: 'http://localhost:5005',
'content-length': '138',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15',
referer: 'http://localhost:5005/lemon',
connection: 'close',
'sec-fetch-dest': 'empty'
}
},
response: {
status: 404,
message: 'Not Found',
header: [Object: null prototype] {}
},
app: { subdomainOffset: 2, proxy: false, env: 'development' },
originalUrl: '/api/agent/run',
req: '',
res: '',
socket: ''
}
GET /api/agent - 6ms
--> GET /api/agent 200 15ms 35b
<-- GET /api/conversation?mode_type=task&agent_id=null
Request URL: /api/conversation?mode_type=task&agent_id=null
get conversations [Object: null prototype] { mode_type: 'task', agent_id: 'null' }
get conversations: 1.329ms
GET /api/conversation?mode_type=task&agent_id=null - 2ms
--> GET /api/conversation?mode_type=task&agent_id=null 200 2ms 35b
<-- GET /api/model/enabled
Request URL: /api/model/enabled
<-- GET /api/recharge_product/list
Request URL: /api/recharge_product/list
GET /api/model/enabled - 17ms
--> GET /api/model/enabled 200 31ms 198.81kb
<-- GET /api/mcp_server/active
Request URL: /api/mcp_server/active
GET /api/mcp_server/active - 2ms
--> GET /api/mcp_server/active 200 3ms 35b
GET /api/recharge_product/list - 200ms

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions