feat: add Requesty as an OpenAI-compatible provider#978
Conversation
|
This PR was auto-closed. Only contributors approved with Maintainers review auto-closed issues daily. Issues that do not meet the quality bar in CONTRIBUTING.md will not be reopened or receive a reply. If a maintainer replies See CONTRIBUTING.md. |
|
Hello @Thibaultjaigu, thank you for this. If the ts backend implementation is not done it's a bit useless because all the agentic stuff is done there. So the best would be to support it there as well. |
There was a problem hiding this comment.
Hi, thanks a lot for your contribution! However it remains a lot of changes so that we can merge this add as is, I'll let you know which points is missing :
Functional
apps/backend/src/agents/provider-meta.ts— invalide model IDswrong values on related fields (see inline comments).cli/nao_core/commands/debug.py—_check_available_modelsdoesn't handlerequesty→ returns "Unknown provider: requesty". Add anelif provider == "requesty":branch withbase_url="https://router.requesty.ai/v1"(copy of the openrouter branch).cli/nao_core/templates/engine.py— (a) addREQUESTYto the OpenAI-compatible set (l.120), otherwiseai_summaryraises "Unsupported LLM provider". (b) add the Requesty base_url fallback (l.157), otherwise the call hits the default OpenAI endpoint.
Consistency
cli/nao_core/deps.py— add"requesty": "openai"to_PROVIDER_ALIASES, otherwise theopenaiextra is never detected/installed for Requesty.apps/frontend/src/components/ui/llm-provider-icon.tsx— addcase 'requesty'+ theicons/requesty.svgasset. The SVG must be monochrome and usefill="currentColor"(no hardcoded colors, no fixed width/height — only aviewBox) so it inherits the theme color like the other provider icons (text-foreground opacity-50).
Quality / docs
apps/backend/src/agents/provider-meta.ts— addcostPerMto Requesty models (see inline comments).cli/tests/nao_core/commands/test_debug.py— add Requesty tests (mirroringtest_openrouter_*).cli/README.md— (l.89) add Requesty to the providers list.- Verify the model IDs actually exist on
router.requesty.ai(especiallyanthropic/claude-haiku-4.5andopenai/gpt-4o-mini).
| id: 'openai/gpt-4o-mini', | ||
| name: 'GPT-4o mini', | ||
| default: true, | ||
| contextWindow: 128_000, |
There was a problem hiding this comment.
The costPerM variable must be implemented in order to continue tracking costs in the cost setting section and also for the budget setting section that can be set by admins.
| contextWindow: 128_000, | |
| contextWindow: 128_000, | |
| costPerM: { inputNoCache: 0.15, inputCacheRead: 0.075, inputCacheWrite: 0, output: 0.6 }, |
| extractorModelId: 'anthropic/claude-haiku-4.5', | ||
| summaryModelId: 'anthropic/claude-haiku-4.5', |
There was a problem hiding this comment.
These 2 models anthropic/claude-haiku-4.5 and anthropic/claude-sonnet-4.5 don't exist in https://router.requesty.ai/v1/models.
| extractorModelId: 'anthropic/claude-haiku-4.5', | |
| summaryModelId: 'anthropic/claude-haiku-4.5', | |
| extractorModelId: 'anthropic/claude-haiku-4-5', | |
| summaryModelId: 'anthropic/claude-haiku-4-5', |
| { | ||
| id: 'deepseek/deepseek-chat', | ||
| name: 'DeepSeek Chat', | ||
| contextWindow: 128_000, |
There was a problem hiding this comment.
It was not the correct amount for contextWindow.
| contextWindow: 128_000, | |
| contextWindow: 1_000_000, | |
| costPerM: { inputNoCache: 0.14, inputCacheRead: 0.028, inputCacheWrite: 0, output: 0.28 }, |
| contextWindow: 128_000, | ||
| }, | ||
| { | ||
| id: 'anthropic/claude-sonnet-4.5', |
There was a problem hiding this comment.
| id: 'anthropic/claude-sonnet-4.5', | |
| id: 'anthropic/claude-sonnet-4-5, |
| { | ||
| id: 'anthropic/claude-sonnet-4.5', | ||
| name: 'Claude Sonnet 4.5 (Requesty)', | ||
| contextWindow: 1_000_000, |
There was a problem hiding this comment.
| contextWindow: 1_000_000, | |
| contextWindow: 1_000_000, | |
| costPerM: { inputNoCache: 3, inputCacheRead: 0.3, inputCacheWrite: 0, output: 15 }, |
|
Thanks for the careful review. I pushed a commit addressing all of it:
Live values used for
On the backend point: the agentic path is wired in |
|
@Thibaultjaigu Thanks for the update, and I appreciate the changes you've made so far! The backend model IDs and metadata look much better now. However, there are still several of the points from my previous review that haven't been addressed yet, including the CLI changes, provider aliases, frontend icon, tests, and documentation updates. Could you please go through the remaining items from my original review and address those as well? Once those are covered, we should be much closer to being able to merge this PR. Thanks again for your work! P.S. The |
Signed-off-by: Thibault Jaigu <thibault.jaigu@gmail.com>
|
Thanks, I pushed another commit covering the remaining items:
On the backend client: Requesty reuses the On the P.S.: the For tests: I did not find an existing test that enumerates providers or covers OpenRouter specifically (the CLI |
There was a problem hiding this comment.
1 issue found across 4 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="cli/README.md">
<violation number="1" location="cli/README.md:89">
P3: Requesty is documented as a selectable LLM provider but the README installation section does not indicate which extra is required. Since `pyproject.toml` has no `requesty` extra and `deps.py` maps Requesty to the `openai` extra, users may try to install a non-existent extra or be unsure how to enable the provider.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| - **Database connections** (BigQuery, DuckDB, Databricks, Snowflake, PostgreSQL, Redshift, MSSQL, Trino, StarRocks) | ||
| - **Git repositories** to sync | ||
| - **LLM provider** (OpenAI, Anthropic, Mistral, Gemini, OpenRouter, Ollama) | ||
| - **LLM provider** (OpenAI, Anthropic, Mistral, Gemini, OpenRouter, Requesty, Ollama) |
There was a problem hiding this comment.
P3: Requesty is documented as a selectable LLM provider but the README installation section does not indicate which extra is required. Since pyproject.toml has no requesty extra and deps.py maps Requesty to the openai extra, users may try to install a non-existent extra or be unsure how to enable the provider.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At cli/README.md, line 89:
<comment>Requesty is documented as a selectable LLM provider but the README installation section does not indicate which extra is required. Since `pyproject.toml` has no `requesty` extra and `deps.py` maps Requesty to the `openai` extra, users may try to install a non-existent extra or be unsure how to enable the provider.</comment>
<file context>
@@ -86,7 +86,7 @@ This will create a new nao project in the current directory. It will prompt you
- **Database connections** (BigQuery, DuckDB, Databricks, Snowflake, PostgreSQL, Redshift, MSSQL, Trino, StarRocks)
- **Git repositories** to sync
-- **LLM provider** (OpenAI, Anthropic, Mistral, Gemini, OpenRouter, Ollama)
+- **LLM provider** (OpenAI, Anthropic, Mistral, Gemini, OpenRouter, Requesty, Ollama)
- **`ai_summary` template + model** (prompted only when you enable `ai_summary` for databases)
- **Slack integration**
</file context>
socallmebertille
left a comment
There was a problem hiding this comment.
I checked again your changes and it's almost there !
A few points :
- cubic comment's isn't particularly relevant this time, you can skip it
cli/nao_core/commands/debug.pystill misses theelif provider == "requesty":branch so thedebugCLI command handles the new providercli/nao_core/templates/engine.pystill misses the provider wiring : addLLMProvider.REQUESTYto the set at l.120 —if self.llm_config.provider in {LLMProvider.OPENAI, LLMProvider.OPENROUTER, LLMProvider.REQUESTY}:— and the base_url fallback at l.157 :elif self.llm_config and self.llm_config.provider == LLMProvider.REQUESTY: kwargs["base_url"] = "https://router.requesty.ai/v1"
- for the tests, the file is located at the following path
cli/tests/nao_core/commands/test_debug.py, I was referring the 2def test_openrouter_connection_success(self)anddef test_openrouter_exception_returns_failure(self)(1 that succeed and 1 that fail) that I encourage you to follow for the requesty one (I will cover the 3 providers tests's missing in another PR)
My bad on the P.S., you were right !
What
Adds Requesty as a named LLM provider in the CLI configuration, mirroring the existing OpenRouter wiring 1:1.
Requesty is an OpenAI-compatible LLM gateway. It uses the same
provider/modelnaming convention as OpenRouter (e.g.openai/gpt-4o-mini), so it slots into the existing provider machinery without special handling.Changes
In
cli/nao_core/config/llm/__init__.py:LLMProviderenum: addREQUESTY = "requesty"PROVIDER_AUTH: addProviderAuthConfig(env_var="REQUESTY_API_KEY", api_key="required", base_url_env_var="REQUESTY_BASE_URL")DEFAULT_ANNOTATION_MODELS: addLLMProvider.REQUESTY: "openai/gpt-4o-mini"promptConfigpicker: addquestionary.Choice("Requesty", value="requesty")Each entry is placed directly alongside the corresponding OpenRouter entry.
Tested
https://router.requesty.ai/v1/chat/completionswith modelopenai/gpt-4o-mini→ HTTP 200.LLMProvider("requesty"),PROVIDER_AUTH,DEFAULT_ANNOTATION_MODELS, and aLLMConfig(provider=REQUESTY, api_key=...)round-trip all resolve correctly (default annotation model applied,requires_api_key=True).The TypeScript backend provider (
apps/backend) can be wired the same way using the official@requesty/ai-sdk(createRequesty) provider; I kept this PR scoped to the self-contained CLI surface and am happy to follow up with the backend wiring in a separate PR.I work at Requesty. This mirrors the existing OpenRouter provider as closely as possible. Happy to adjust wording/placement or close it if it's not a fit.