Skip to content

feat: add OrcaRouter as a named provider and target the chat-completions surface - #99

Open
XiaoHuo888-hue wants to merge 1 commit into
context-labs:mainfrom
XiaoHuo888-hue:add-orcarouter-provider
Open

feat: add OrcaRouter as a named provider and target the chat-completions surface#99
XiaoHuo888-hue wants to merge 1 commit into
context-labs:mainfrom
XiaoHuo888-hue:add-orcarouter-provider

Conversation

@XiaoHuo888-hue

@XiaoHuo888-hue XiaoHuo888-hue commented Aug 10, 2026

Copy link
Copy Markdown

Summary

Adds OrcaRouter as a named provider in the HALO desktop app, and fixes the engine so any OpenAI-compatible endpoint actually works.

Desktop app. The "Add provider" dialog now has an OrcaRouter preset alongside OpenAI and Anthropic — picking it fills in https://api.orcarouter.ai/v1 and a curated model list (orcarouter/auto, openai/gpt-5.5, anthropic/claude-sonnet-4.6, anthropic/claude-haiku-4.5, deepseek/deepseek-chat). The new provider type flows through HALO_PROVIDER_TYPES, the tRPC schema (built from that array in router.ts), and the model options in one place.

Engine (fixes #81). ModelProviderConfig documents that HALO "targets the OpenAI-compatible chat-completions surface", but OpenAIProvider was constructed without use_responses=False, so the SDK used OpenAI's Responses API (/v1/responses) — a surface only OpenAI serves. Every other endpoint — OpenRouter, OrcaRouter, Anthropic's compat layer, vLLM, Together, Groq, etc. — returned 404. Both call sites (engine/main.py for the root agent, engine/tools/subagent_tool_factory.py for subagents) now pass use_responses=False, so HALO runs end-to-end against any OpenAI-compatible endpoint.

Docs. The README's provider example now lists OrcaRouter alongside OpenRouter.

With one API key, users get 150+ models from OpenAI, Anthropic, Google, DeepSeek, Qwen, MiniMax and xAI behind a single endpoint. Because the provider is a thin base-URL swap, any HALO pipeline/agent that uses it also inherits OrcaRouter's gateway-level, zero-trust security controls for AI agents — with no application code changes. The gateway screens every prompt and response and governs every tool call on a default-deny basis, across four layers:

  • Scoped keys — bind a key to specific models, IPs, spend caps, and expiry.
  • Guardrails — screen for PII, secret leakage, prompt injection, and unsafe output.
  • Agent firewall — tool allow-lists with per-argument validation.
  • Audit trail — a record of every match, verdict, and approval decision.

I'm an engineer on the OrcaRouter team.

Verification

  • L3 live (real key, engine end-to-end): uv run halo demo/openai-agents-sdk-demo/sample-traces/traces.jsonl -p "How many traces are in this dataset?" --base-url https://api.orcarouter.ai/v1 --api-key <key> --model openai/gpt-5.5 --max-depth 1 --max-turns 8 exits 0; the root agent calls get_dataset_overview through OrcaRouter and returns a final answer. Previously this path 404'd on /v1/responses.
  • All 6 preset model IDs confirmed in the live /v1/models catalog (189 models).
  • POST /v1/chat/completions (openai/gpt-5.5) → 200; invalid key → 401.
  • App: tsc --noEmit exit 0.
  • Engine: tests/unit 463 passed; the 63 failures/errors are identical to clean main (Windows-only git-tool / trace-index / taxonomy-fixture issues in untouched files). tests/integration subset 13 passed; the 1 failure (test_call_subagent_through_sdk_adapter_live) needs a live API key and fails identically on clean main.
  • ruff check and ruff format --check clean on the edited files.

Note

Medium Risk
Touches core LLM routing for every engine run (root and subagents); the change is small but affects all non-OpenAI-compatible endpoints and is on the critical inference path.

Overview
OrcaRouter is added as a named provider in the HALO desktop app: the add-provider dialog preset, HALO_PROVIDER_TYPES, curated model IDs, and README examples alongside OpenRouter.

The engine fix is the behavioral change: root and subagent OpenAIProvider instances now pass use_responses=False, so the Agents SDK calls /v1/chat/completions instead of OpenAI-only /v1/responses. That aligns runtime behavior with ModelProviderConfig and unblocks OpenRouter, OrcaRouter, Anthropic compat, and other gateways that previously 404’d.

Reviewed by Cursor Bugbot for commit acbc6c0. Bugbot is set up for automated code reviews on this repo. Configure here.

…ons surface

Co-Authored-By: Claude <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit acbc6c0. Configure here.

export function defaultModelForProvider(providerType: HaloProviderType) {
if (providerType === "openai") return "gpt-5.2";
if (providerType === "anthropic_compat") return "claude-sonnet-4-5";
if (providerType === "orcarouter") return "openai/gpt-5.5";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefixed models skip reasoning defaults

Medium Severity

OrcaRouter presets use vendor-prefixed IDs like openai/gpt-5.5, but max_reasoning_effort_for_model only matches bare names such as gpt-5.5. The desktop default therefore never applies xhigh and falls through to the provider’s medium default, so OrcaRouter GPT runs analyze with weaker reasoning than the OpenAI preset path.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit acbc6c0. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Engine 404s on every non-OpenAI provider: OpenAIProvider defaults to the Responses API

1 participant