From c212be801fb4719741a9d9c9559f22ccbdee279d Mon Sep 17 00:00:00 2001 From: mjalalimanesh Date: Tue, 17 Feb 2026 13:48:15 +0330 Subject: [PATCH 1/2] feat: add OpenAI-first provider selection with OpenRouter fallback --- dash/agents.py | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/dash/agents.py b/dash/agents.py index 76eec7a..6e40567 100644 --- a/dash/agents.py +++ b/dash/agents.py @@ -7,6 +7,12 @@ from os import getenv +OPENAI_API_KEY = getenv("OPENAI_API_KEY", "") +OPENROUTER_API_KEY = getenv("OPENROUTER_API_KEY", "") +OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1" +USE_OPENAI_PROVIDER = bool(OPENAI_API_KEY) +USE_OPENROUTER_PROVIDER = not USE_OPENAI_PROVIDER and bool(OPENROUTER_API_KEY) + from agno.agent import Agent from agno.knowledge import Knowledge from agno.knowledge.embedder.openai import OpenAIEmbedder @@ -18,6 +24,7 @@ UserProfileConfig, ) from agno.models.openai import OpenAIResponses +from agno.models.openrouter import OpenRouter from agno.tools.mcp import MCPTools from agno.tools.reasoning import ReasoningTools from agno.tools.sql import SQLTools @@ -32,6 +39,31 @@ # Database & Knowledge # ============================================================================ + +def _build_embedder() -> OpenAIEmbedder: + """Build embedder using OpenAI first; OpenRouter only as fallback.""" + if USE_OPENROUTER_PROVIDER: + return OpenAIEmbedder( + id="openai/text-embedding-3-small", + api_key=OPENROUTER_API_KEY, + base_url=OPENROUTER_BASE_URL, + ) + return OpenAIEmbedder(id="text-embedding-3-small") + + +def _build_model(): + """Build model using OpenAI first; OpenRouter only as fallback.""" + if USE_OPENROUTER_PROVIDER: + return OpenRouter( + id=getenv("DASH_MODEL", "openai/gpt-4o"), + default_headers={ + "HTTP-Referer": "https://github.com/agno-agi/dash", + "X-Title": "dash", + }, + ) + return OpenAIResponses(id="gpt-5.2") + + agent_db = get_postgres_db() # KNOWLEDGE: Static, curated (table schemas, validated queries, business rules) @@ -41,7 +73,7 @@ db_url=db_url, table_name="dash_knowledge", search_type=SearchType.hybrid, - embedder=OpenAIEmbedder(id="text-embedding-3-small"), + embedder=_build_embedder(), ), contents_db=get_postgres_db(contents_table="dash_knowledge_contents"), ) @@ -53,7 +85,7 @@ db_url=db_url, table_name="dash_learnings", search_type=SearchType.hybrid, - embedder=OpenAIEmbedder(id="text-embedding-3-small"), + embedder=_build_embedder(), ), contents_db=get_postgres_db(contents_table="dash_learnings_contents"), ) @@ -165,7 +197,7 @@ dash = Agent( name="Dash", - model=OpenAIResponses(id="gpt-5.2"), + model=_build_model(), db=agent_db, instructions=INSTRUCTIONS, # Knowledge (static) From 11aa22e92853eab6528487dbf5b7ae5b9456c338 Mon Sep 17 00:00:00 2001 From: mjalalimanesh Date: Tue, 17 Feb 2026 13:48:29 +0330 Subject: [PATCH 2/2] docs: clarify OpenAI/OpenRouter key priority --- README.md | 8 ++++++-- example.env | 12 +++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bcfe19b..c7eefed 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Inspired by [OpenAI's in-house data agent](https://openai.com/index/inside-our-i ```sh # Clone this repo git clone https://github.com/agno-agi/dash.git && cd dash -# Add OPENAI_API_KEY by adding to .env file or export OPENAI_API_KEY=sk-*** +# Add OPENAI_API_KEY (preferred) or OPENROUTER_API_KEY (fallback) to .env cp example.env .env # Start the application @@ -234,10 +234,14 @@ python -m dash # CLI mode | Variable | Required | Description | |----------|----------|-------------| -| `OPENAI_API_KEY` | Yes | OpenAI API key | +| `OPENAI_API_KEY` | Preferred | OpenAI API key (original behavior, highest priority) | +| `OPENROUTER_API_KEY` | Fallback | Used only when `OPENAI_API_KEY` is not set | +| `DASH_MODEL` | No | Model override for OpenRouter path (default: `openai/gpt-4o`) | | `EXA_API_KEY` | No | Web search for external knowledge | | `DB_*` | No | Database config (defaults to localhost) | +Provider priority: Dash uses OpenAI when `OPENAI_API_KEY` is set. If it is not set and `OPENROUTER_API_KEY` is set, Dash uses OpenRouter. + ## Further Reading - [OpenAI's In-House Data Agent](https://openai.com/index/inside-our-in-house-data-agent/) — the inspiration diff --git a/example.env b/example.env index bd84ef8..854dc80 100644 --- a/example.env +++ b/example.env @@ -1,9 +1,11 @@ -# Required (default configured for OpenAI) +# Preferred (original behavior): OpenAI key OPENAI_API_KEY=sk-*** -# Optional: Use a different model provider -# ANTHROPIC_API_KEY=sk-ant-*** -# GOOGLE_API_KEY=*** +# Optional fallback provider: used only when OPENAI_API_KEY is not set +# OPENROUTER_API_KEY=sk-or-v1-*** + +# Optional model override (OpenRouter path only, default: openai/gpt-4o) +# DASH_MODEL=openai/gpt-4o # Exa API key for web research # EXA_API_KEY=*** @@ -11,4 +13,4 @@ OPENAI_API_KEY=sk-*** # Database (defaults work out of the box) # DB_USER=ai # DB_PASS=ai -# DB_DATABASE=ai \ No newline at end of file +# DB_DATABASE=ai