-
-
Save SaseQ/c2a20a38b11276537ec5332d1f7a5e53 to your computer and use it in GitHub Desktop.
| { | |
| "transformers": [ | |
| { | |
| "path": "$HOME/.claude-code-router/plugins/rovo-cli.js", | |
| "options": { | |
| "email": "ROVO_DEV_EMAIL", | |
| "api_token": "ROVO_DEV_API_TOKEN" | |
| } | |
| } | |
| ], | |
| "Providers": [ | |
| { | |
| "name": "rovo-cli", | |
| "api_base_url": "https://api.atlassian.com/rovodev/v2/proxy/ai/v1/openai/v1/chat/completions", | |
| "api_key": "sk-xxx", | |
| "models": ["gpt-5-2025-08-07"], | |
| "transformer": { | |
| "use": ["rovo-cli"] | |
| } | |
| } | |
| ], | |
| "Router": { | |
| "default": "rovo-cli,gpt-5-2025-08-07" | |
| } | |
| } |
| const os = require("os"); | |
| const path = require("path"); | |
| const fs = require("fs/promises"); | |
| class RovoCLITransformer { | |
| name = "rovo-cli"; | |
| constructor(options) { | |
| this.options = options; | |
| } | |
| async transformRequestIn(request, provider) { | |
| const body = typeof request === "string" ? JSON.parse(request) : { ...request }; | |
| if (Object.prototype.hasOwnProperty.call(body, "max_tokens")) { | |
| if (!Object.prototype.hasOwnProperty.call(body, "max_completion_tokens")) { | |
| body.max_completion_tokens = body.max_tokens; | |
| } | |
| delete body.max_tokens; | |
| } | |
| if (body.params && typeof body.params === "object") { | |
| if (Object.prototype.hasOwnProperty.call(body.params, "max_tokens")) { | |
| if (!Object.prototype.hasOwnProperty.call(body.params, "max_completion_tokens")) { | |
| body.params.max_completion_tokens = body.params.max_tokens; | |
| } | |
| delete body.params.max_tokens; | |
| } | |
| } | |
| const toolsToAdd = await this.getDefaultRovoTools(); | |
| const existingTools = Array.isArray(body.tools) ? body.tools : []; | |
| const byName = new Map(); | |
| for (const t of existingTools) { | |
| const key = t?.function?.name || JSON.stringify(t); | |
| byName.set(key, t); | |
| } | |
| for (const t of toolsToAdd) { | |
| const key = t?.function?.name || JSON.stringify(t); | |
| if (!byName.has(key)) byName.set(key, t); | |
| } | |
| body.tools = Array.from(byName.values()); | |
| const email = this.options?.email; | |
| const api_token = this.options?.api_token; | |
| const basicToken = Buffer.from(`${email}:${api_token}`, "utf-8").toString("base64"); | |
| return { | |
| body, | |
| config: { | |
| headers: { | |
| Authorization: `Basic ${basicToken}`, | |
| }, | |
| }, | |
| }; | |
| } | |
| getDefaultRovoTools() { | |
| return [ | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "open_files_legacy", | |
| "description": "IGNORE THE TOOL. Kept for legacy. Open one or more files in the workspace. Supports text, image, and PDF documents.\n", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "file_paths": { | |
| "type": "array", | |
| "items": {"type": "string"}, | |
| "description": "A list of file paths to open." | |
| } | |
| }, | |
| "required": ["file_paths"] | |
| } | |
| } | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "create_file_legacy", | |
| "description": "IGNORE THE TOOL. Kept for legacy. Create a file in the workspace.\n", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "file_path": {"type": "string"} | |
| }, | |
| "required": ["file_path"] | |
| } | |
| } | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "expand_code_chunks_legacy", | |
| "description": "IGNORE THE TOOL. Kept for legacy. Expand line ranges or code chunks within a file and return the expanded content.\n\nCode can be expanded by specifying line ranges or by searching for code symbols in the code, separating levels of\nhierarchy with slashes.\n\nExample patterns:\n- \"MyClass\": Selects the class definition and any references to MyClass.\n- \"my_function\": Selects the function definition and any uses of my_function.\n- \"def my_function\": Selects only the function definition for my_function.\n- \"MyClass/my_method\": Selects the method my_method within MyClass using slash separator.", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "file_path": {"type": "string"} | |
| }, | |
| "required": ["file_path"] | |
| } | |
| } | |
| } | |
| ]; | |
| } | |
| } | |
| module.exports = RovoCLITransformer; |
@dav1lex Just fill in the email and api_token, leave the api_key as it is.
Go to your Atlassian profile, select Create API token, and create an unscoped API token.
@SaseQ Jestem na windowsie,config tak wygląda ale nie działa, czy widzisz gdzie jest błąd? Tak samo z googlem, nie działa. Pobrałem nowy gemini-cli z repo, ale coś po prostu tu nie gra. config:
{ "LOG": false, "LOG_LEVEL": "info", "CLAUDE_PATH": "", "HOST": "127.0.0.1", "PORT": 3456, "APIKEY": "", "API_TIMEOUT_MS": "600000", "PROXY_URL": "", "transformers": [ { "name": "rovo-cli", "path": "C:\\Users\\admin\\.claude-code-router\\plugins\\rovo-cli.js", "options": { "email": "[email protected]", "api_token": "token without scope" } } ], "Providers": [ { "name": "rovo-cli", "api_base_url": "https://api.atlassian.com/rovodev/v2/proxy/ai/v1/openai/v1/chat/completions", "api_key": "api key", "models": [ "gpt-5-2025-08-07" ], "transformer": { "use": [ "rovo-cli" ], "gpt-5-2025-08-07": { "use": [ "rovo-cli" ] } } } ], "StatusLine": { "enabled": false, "currentStyle": "default", "default": { "modules": [] }, "powerline": { "modules": [] } }, "Router": { "default": "rovo-cli,gpt-5-2025-08-07", "background": "", "think": "", "longContext": "", "longContextThreshold": 60000, "webSearch": "" }, "stream": false }
@dav1lex Napisze po angielsku jakby ktoś kiedyś miał ten sam problem.
Copy configuration from top of this page, change only the transformers: path, email, and api_token sections, do not change anything else, and try testing it this way.
@SaseQ OK figured it out and works well, thank you
@SaseQ If I want to use the Claude4 ,what should I change the api_base_url to?
似乎还是不行,目前根据你提供的方案我测试了一下,还是401
似乎还是不行,目前根据你提供的方案我测试了一下,还是401
What model, what are your settings?
I get the same question, and I do the same as you, but it doesn't work.
I am %99 percent sure that your "path" is wrong. I litearlly have same settings with you, and I changed path to a wrong one, and it returned same error. You must check path, in my case , on windows C:\\Users\\admin\\.claude-code-router\\plugins\\rovo-cli.js. On linux just right click copy the path from rovo-cli.js
@SaseQ I just copy pasted the config.json and changed email, path and api token, I get this error "API Error: 400 {"error":"Missing model in request body"}"
Its not work via Cline
yeah its broken i have actually dmed the owner on dc and he didnt replied so i made a proxy of my own (didnt made it open source ) . you can check my qwen proxy there i have the dc server link . im allowing free usage but also safeguarding against mass usage
https://github.com/aptdnfapt/qwen-code-oai-proxy
I ran into 429. I think rovo dev might disable this API soon, cuz this involves business competition, so no more integration into claude code router.
yeah same for me :(




⎿ API Error (401 {"error":{"message":"Error from provider(401): {"code":401,"message":"Unauthorized"}Error: Error from provider(401): {"code":401,"message":"Unauthorized"}\n at bt (C:\****npm\node_modules\@musistudio\claude-code-router\dist\cli.js:74721:11)\n at u0 (C:\****npm\node_modules\@musistudio\claude-code-router\dist\cli.js:74779:11)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async o0 (C:\****npm\node_modules\@musistudio\claude-code-router\dist\cli.js:74746:84)","type":"api_error","code":"provider_response_error"}}) · Retrying in 1 seconds… (attempt 1/10)
Hi, api_token and api_key, I put the same val since I don't know what would be api token. pls correct me if i do wrong
``