From b2470e9037daab2ab623312a62bdba73d1908c55 Mon Sep 17 00:00:00 2001 From: "Huabing (Robin) Zhao" Date: Tue, 28 Jul 2026 19:18:53 -0700 Subject: [PATCH 1/2] feat(providers): add TARS (Tetrate Agent Router Service) as a built-in inference provider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adds `tars` as a built-in Providers v2 profile (`providers/tars.yaml`) with inference category, Bearer auth, and TARS_API_KEY / AGENTROUTER_API_KEY discovery - Adds `TARS_PROFILE` to inference routing so `inference.local` works with the `tars` provider type. TARS serves OpenAI-compatible endpoints and the Anthropic Messages API on the same host, so the profile advertises both protocol families on a single route (precedent: google-vertex-ai) — OpenAI-SDK tools and Anthropic clients work in the same sandbox with one configured provider - Default base URL is the Tetrate-hosted SaaS gateway (https://api.router.tetrate.ai/v1); enterprise deployments override it with `--config TARS_BASE_URL` (precedent: deepinfra's vendor default) - Passes through anthropic-version, anthropic-beta, openai-organization, and x-model-id client headers - Registers a tars provider plugin (discovery, known_types(), TUI), a Tars telemetry bucket, and normalize aliases (tars, agentrouter, tetrate-agent-router) - Updates providers-v2.mdx, manage-providers.mdx, and architecture/gateway.md provider lists Signed-off-by: Huabing (Robin) Zhao --- architecture/gateway.md | 2 +- crates/openshell-core/src/inference.rs | 81 ++++++++++++++++++- crates/openshell-core/src/telemetry.rs | 3 + crates/openshell-providers/src/lib.rs | 1 + crates/openshell-providers/src/profiles.rs | 1 + .../openshell-providers/src/providers/mod.rs | 1 + .../openshell-providers/src/providers/tars.rs | 15 ++++ crates/openshell-server/src/grpc/provider.rs | 4 +- crates/openshell-server/src/inference.rs | 2 +- docs/sandboxes/manage-providers.mdx | 2 + docs/sandboxes/providers-v2.mdx | 1 + providers/tars.yaml | 27 +++++++ 12 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 crates/openshell-providers/src/providers/tars.rs create mode 100644 providers/tars.yaml diff --git a/architecture/gateway.md b/architecture/gateway.md index c8b323ea13..89ed4da73c 100644 --- a/architecture/gateway.md +++ b/architecture/gateway.md @@ -406,7 +406,7 @@ Cluster inference routes store only `provider_name`, `model_id`, and optional timeout. The gateway resolves endpoint URLs, protocols, credentials, auth style, and route-shaping metadata from the provider record when supervisors call `GetInferenceBundle`. Supported provider types for cluster inference are -`openai`, `anthropic`, `nvidia`, `deepinfra`, and `google-vertex-ai`. +`openai`, `anthropic`, `nvidia`, `deepinfra`, `tars`, and `google-vertex-ai`. The bundle carries enough information for sandbox-local routers to construct upstream URLs without re-deriving provider-specific routing logic. Each resolved diff --git a/crates/openshell-core/src/inference.rs b/crates/openshell-core/src/inference.rs index 2be79d45ee..09adf5e3d5 100644 --- a/crates/openshell-core/src/inference.rs +++ b/crates/openshell-core/src/inference.rs @@ -78,6 +78,20 @@ const ANTHROPIC_PROTOCOLS: &[&str] = &["anthropic_messages", "model_discovery"]; /// base-URL-override escape hatch path. const VERTEX_AI_PROTOCOLS: &[&str] = &["anthropic_messages", "model_discovery"]; +/// Protocol set for the TARS (Tetrate Agent Router Service) profile. TARS is an +/// LLM traffic router that serves both OpenAI-compatible endpoints and the +/// Anthropic Messages API on the same host, so a single route advertises both +/// protocol families and `inference.local` serves OpenAI-style and +/// Anthropic-style clients simultaneously. +const TARS_PROTOCOLS: &[&str] = &[ + "openai_chat_completions", + "openai_completions", + "openai_responses", + "openai_embeddings", + "anthropic_messages", + "model_discovery", +]; + // `aws_bedrock_invoke_stream` (`/model/{id}/invoke-with-response-stream`) is // deferred to a follow-up alongside protocol-aware AWS event-stream error // handling: the shared streaming relay's truncation/timeout path injects @@ -177,6 +191,27 @@ static DEEPINFRA_PROFILE: InferenceProviderProfile = InferenceProviderProfile { passthrough_headers: &["x-model-id"], }; +// TARS (Tetrate Agent Router Service) — a multi-tenant LLM traffic router. +// The default base URL is the Tetrate-hosted SaaS gateway; enterprise +// deployments override it with `TARS_BASE_URL` (customer-specific hostname). +// TARS accepts `Authorization: Bearer sk-` on both its OpenAI-compatible +// and Anthropic Messages routes, so `Bearer` covers the whole protocol set. +static TARS_PROFILE: InferenceProviderProfile = InferenceProviderProfile { + provider_type: "tars", + default_base_url: "https://api.router.tetrate.ai/v1", + protocols: TARS_PROTOCOLS, + credential_key_names: &["TARS_API_KEY", "AGENTROUTER_API_KEY"], + base_url_config_keys: &["TARS_BASE_URL", "AGENTROUTER_BASE_URL"], + auth: AuthHeader::Bearer, + default_headers: &[], + passthrough_headers: &[ + "anthropic-version", + "anthropic-beta", + "openai-organization", + "x-model-id", + ], +}; + // AWS Bedrock — registered as bridge-fronted (no router-side auth // injection). Real AWS Bedrock requires `SigV4` signing of every request, // which is deferred to a follow-up PR (see #1704 thread). Until then, @@ -222,6 +257,7 @@ pub fn normalize_inference_provider_type(input: &str) -> Option<&'static str> { "anthropic" => Some("anthropic"), "nvidia" => Some("nvidia"), "deepinfra" => Some("deepinfra"), + "tars" | "agentrouter" | "tetrate-agent-router" => Some("tars"), "aws-bedrock" => Some("aws-bedrock"), "google-vertex-ai" | "vertex" | "vertex-ai" | "google-vertex" | "gcp-vertex" => { Some("google-vertex-ai") @@ -240,6 +276,7 @@ pub fn profile_for(provider_type: &str) -> Option<&'static InferenceProviderProf "anthropic" => Some(&ANTHROPIC_PROFILE), "nvidia" => Some(&NVIDIA_PROFILE), "deepinfra" => Some(&DEEPINFRA_PROFILE), + "tars" => Some(&TARS_PROFILE), "google-vertex-ai" => Some(&VERTEX_AI_PROFILE), "aws-bedrock" => Some(&AWS_BEDROCK_PROFILE), _ => None, @@ -403,9 +440,51 @@ mod tests { assert_eq!(profile.auth, AuthHeader::Bearer); } + #[test] + fn profile_for_tars_types() { + for key in &["tars", "agentrouter", "tetrate-agent-router", "TARS"] { + let profile = profile_for(key).expect("tars profile should be Some"); + assert_eq!(profile.provider_type, "tars"); + } + } + + #[test] + fn tars_profile_advertises_both_protocol_families() { + let profile = profile_for("tars").expect("tars profile should exist"); + assert_eq!(profile.default_base_url, "https://api.router.tetrate.ai/v1"); + assert_eq!(profile.auth, AuthHeader::Bearer); + // TARS serves OpenAI-compatible and Anthropic Messages routes on the + // same host, so one route covers both client families. + for protocol in [ + "openai_chat_completions", + "openai_responses", + "openai_embeddings", + "anthropic_messages", + "model_discovery", + ] { + assert!( + profile.protocols.contains(&protocol), + "tars should route {protocol}" + ); + } + } + + #[test] + fn route_headers_for_tars_include_both_families_passthrough() { + let (auth, headers, passthrough_headers) = route_headers_for_provider_type("tars"); + assert_eq!(auth, AuthHeader::Bearer); + assert!(headers.is_empty()); + for name in ["anthropic-version", "anthropic-beta", "openai-organization"] { + assert!( + passthrough_headers.iter().any(|h| h == name), + "tars should pass through {name}" + ); + } + } + #[test] fn openai_compatible_profiles_include_embeddings() { - for provider_type in ["openai", "nvidia", "deepinfra"] { + for provider_type in ["openai", "nvidia", "deepinfra", "tars"] { let profile = profile_for(provider_type).expect("provider profile should exist"); assert!( profile.protocols.contains(&"openai_embeddings"), diff --git a/crates/openshell-core/src/telemetry.rs b/crates/openshell-core/src/telemetry.rs index 49ce620f4f..e9518adbe9 100644 --- a/crates/openshell-core/src/telemetry.rs +++ b/crates/openshell-core/src/telemetry.rs @@ -212,6 +212,7 @@ pub enum ProviderProfile { Openai, Opencode, Outlook, + Tars, Custom, } @@ -230,6 +231,7 @@ impl ProviderProfile { Self::Openai => "openai", Self::Opencode => "opencode", Self::Outlook => "outlook", + Self::Tars => "tars", Self::Custom => "custom", } } @@ -248,6 +250,7 @@ impl ProviderProfile { "openai" => Self::Openai, "opencode" => Self::Opencode, "outlook" => Self::Outlook, + "tars" | "agentrouter" | "tetrate-agent-router" => Self::Tars, _ => Self::Custom, } } diff --git a/crates/openshell-providers/src/lib.rs b/crates/openshell-providers/src/lib.rs index fabe1a5bed..a97dffb956 100644 --- a/crates/openshell-providers/src/lib.rs +++ b/crates/openshell-providers/src/lib.rs @@ -116,6 +116,7 @@ impl ProviderRegistry { registry.register(providers::anthropic::SPEC); registry.register(providers::nvidia::SPEC); registry.register(providers::deepinfra::SPEC); + registry.register(providers::tars::SPEC); registry.register(providers::github::SPEC); registry.register(providers::gitlab::SPEC); registry.register(providers::google_cloud::GoogleCloudProvider); diff --git a/crates/openshell-providers/src/profiles.rs b/crates/openshell-providers/src/profiles.rs index 2ba071db16..29f3c30c9c 100644 --- a/crates/openshell-providers/src/profiles.rs +++ b/crates/openshell-providers/src/profiles.rs @@ -36,6 +36,7 @@ const BUILT_IN_PROFILE_YAMLS: &[&str] = &[ include_str!("../../../providers/google-vertex-ai.yaml"), include_str!("../../../providers/nvidia.yaml"), include_str!("../../../providers/pypi.yaml"), + include_str!("../../../providers/tars.yaml"), ]; #[derive(Debug, thiserror::Error)] diff --git a/crates/openshell-providers/src/providers/mod.rs b/crates/openshell-providers/src/providers/mod.rs index 2770210318..0f5aba0828 100644 --- a/crates/openshell-providers/src/providers/mod.rs +++ b/crates/openshell-providers/src/providers/mod.rs @@ -43,4 +43,5 @@ pub mod nvidia; pub mod openai; pub mod opencode; pub mod outlook; +pub mod tars; pub mod vertex; diff --git a/crates/openshell-providers/src/providers/tars.rs b/crates/openshell-providers/src/providers/tars.rs new file mode 100644 index 0000000000..9f6a8bc67b --- /dev/null +++ b/crates/openshell-providers/src/providers/tars.rs @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +use crate::ProviderDiscoverySpec; + +pub const SPEC: ProviderDiscoverySpec = ProviderDiscoverySpec { + id: "tars", + credential_env_vars: &["TARS_API_KEY", "AGENTROUTER_API_KEY"], +}; + +test_discovers_env_credential!( + discovers_tars_env_credentials, + "TARS_API_KEY", + "sk-tars-test-123" +); diff --git a/crates/openshell-server/src/grpc/provider.rs b/crates/openshell-server/src/grpc/provider.rs index 46d3a31cd4..ed572a42a6 100644 --- a/crates/openshell-server/src/grpc/provider.rs +++ b/crates/openshell-server/src/grpc/provider.rs @@ -2902,6 +2902,7 @@ fn telemetry_provider_profile(provider_type: &str) -> TelemetryProviderProfile { Some("openai") => TelemetryProviderProfile::Openai, Some("opencode") => TelemetryProviderProfile::Opencode, Some("outlook") => TelemetryProviderProfile::Outlook, + Some("tars") => TelemetryProviderProfile::Tars, _ => TelemetryProviderProfile::Custom, } } @@ -3770,7 +3771,8 @@ mod tests { "google-cloud", "google-vertex-ai", "nvidia", - "pypi" + "pypi", + "tars" ] ); diff --git a/crates/openshell-server/src/inference.rs b/crates/openshell-server/src/inference.rs index 39d6afe2fd..746c787d5b 100644 --- a/crates/openshell-server/src/inference.rs +++ b/crates/openshell-server/src/inference.rs @@ -718,7 +718,7 @@ fn resolve_provider_route( let profile = openshell_core::inference::profile_for(&provider_type).ok_or_else(|| { Status::invalid_argument(format!( "provider '{name}' has unsupported type '{raw_provider_type}' for cluster inference \ - (supported: openai, anthropic, nvidia, deepinfra, google-vertex-ai, aws-bedrock)", + (supported: openai, anthropic, nvidia, deepinfra, tars, google-vertex-ai, aws-bedrock)", name = provider.object_name() )) })?; diff --git a/docs/sandboxes/manage-providers.mdx b/docs/sandboxes/manage-providers.mdx index d639c37acb..ee67f49497 100644 --- a/docs/sandboxes/manage-providers.mdx +++ b/docs/sandboxes/manage-providers.mdx @@ -339,6 +339,7 @@ The following provider types are supported. | `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | | `openai` | `OPENAI_API_KEY` | Any OpenAI-compatible endpoint. Set `--config OPENAI_BASE_URL` to point to the provider. Refer to [Inference Routing](/sandboxes/inference-routing). | | `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | OpenCode | +| `tars` | `TARS_API_KEY`, `AGENTROUTER_API_KEY` | Tetrate Agent Router Service (TARS). Serves OpenAI-compatible and Anthropic Messages clients through one provider. Set `--config TARS_BASE_URL` for enterprise (self-hosted) gateways. | `ANTHROPIC_API_KEY` is an API key from [console.anthropic.com](https://console.anthropic.com), not a subscription token. Subscription users must generate a separate API key from the Anthropic Console. @@ -366,6 +367,7 @@ The following providers have been tested with `inference.local`. Any provider th | Groq | `groq` | `openai` | `https://api.groq.com/openai/v1` | `OPENAI_API_KEY` | | Ollama (local) | `ollama` | `openai` | `http://host.openshell.internal:11434/v1` | `OPENAI_API_KEY` | | LM Studio (local) | `lmstudio` | `openai` | `http://host.openshell.internal:1234/v1` | `OPENAI_API_KEY` | +| Tetrate Agent Router Service | `tars` | `tars` | `https://api.router.tetrate.ai/v1` (SaaS) or enterprise `TARS_BASE_URL` | `TARS_API_KEY` | Refer to your provider's documentation for the correct base URL, available models, and API key setup. For the Vertex-specific auth flows and config keys, refer to [Google Vertex AI](/providers/google-vertex-ai). To configure inference routing, refer to [Inference Routing](/sandboxes/inference-routing). diff --git a/docs/sandboxes/providers-v2.mdx b/docs/sandboxes/providers-v2.mdx index fbb8e404fa..2658a364af 100644 --- a/docs/sandboxes/providers-v2.mdx +++ b/docs/sandboxes/providers-v2.mdx @@ -110,6 +110,7 @@ Built-in Providers v2 profiles currently include: | `google-vertex-ai` | `inference` | `GOOGLE_SERVICE_ACCOUNT_KEY`, `GOOGLE_VERTEX_AI_SERVICE_ACCOUNT_TOKEN`, `VERTEX_AI_SERVICE_ACCOUNT_TOKEN`, `GOOGLE_VERTEX_AI_TOKEN`, `VERTEX_AI_TOKEN` | | `nvidia` | `inference` | `NVIDIA_API_KEY` | | `pypi` | `data` | None | +| `tars` | `inference` | `TARS_API_KEY`, `AGENTROUTER_API_KEY` | Export a built-in profile as YAML: diff --git a/providers/tars.yaml b/providers/tars.yaml new file mode 100644 index 0000000000..0694bf6aae --- /dev/null +++ b/providers/tars.yaml @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +id: tars +display_name: Tetrate Agent Router Service +description: Tetrate Agent Router Service (TARS) LLM traffic router +category: inference +inference_capable: true +credentials: + - name: api_key + description: TARS inference API key + env_vars: [TARS_API_KEY, AGENTROUTER_API_KEY] + required: true + auth_style: bearer + header_name: authorization +discovery: + credentials: [api_key] +endpoints: + # Tetrate-hosted SaaS gateway. Enterprise deployments use a + # customer-specific hostname: override the provider base URL with + # `TARS_BASE_URL` and add the gateway host to the sandbox policy. + - host: api.router.tetrate.ai + port: 443 + protocol: rest + access: read-write + enforcement: enforce +binaries: [/usr/bin/curl, /usr/local/bin/curl] From 9c6f7e8d0978649a37bb20741b2081061682c26d Mon Sep 17 00:00:00 2001 From: "Huabing (Robin) Zhao" Date: Wed, 29 Jul 2026 01:41:45 -0700 Subject: [PATCH 2/2] fix(providers): correct TARS protocol set and document aliases Verified each protocol the TARS profile advertises against the live endpoint. `POST /v1/completions` answers "Unsupported endpoint", so drop `openai_completions` from the profile; chat completions, responses, embeddings, and Anthropic messages all serve. Record why `default_headers` stays empty on a dual-family profile: route default headers apply to every request on the route regardless of protocol, so injecting `anthropic-version` would also stamp it onto the OpenAI-family paths TARS serves from the same base URL. Add the `tars` row to the debug-inference skill, the TARS passthrough set to the inference-routing header table, and the `agentrouter` / `tetrate-agent-router` aliases to the provider table, with a normalize_provider_type test pinning them. Signed-off-by: Huabing (Robin) Zhao --- .agents/skills/debug-inference/SKILL.md | 1 + crates/openshell-core/src/inference.rs | 30 ++++++++++++++++++++++++- crates/openshell-providers/src/lib.rs | 6 +++++ docs/sandboxes/inference-routing.mdx | 2 +- docs/sandboxes/manage-providers.mdx | 2 +- 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/.agents/skills/debug-inference/SKILL.md b/.agents/skills/debug-inference/SKILL.md index 3cb08b5861..70b7dc5f8c 100644 --- a/.agents/skills/debug-inference/SKILL.md +++ b/.agents/skills/debug-inference/SKILL.md @@ -131,6 +131,7 @@ Check: - `anthropic` for Anthropic Messages API - `nvidia` for NVIDIA-hosted OpenAI-compatible endpoints - `deepinfra` for DeepInfra's OpenAI-compatible endpoint + - `tars` for Tetrate Agent Router Service; serves OpenAI Chat Completions, Responses, Embeddings, and Anthropic Messages from one base URL - `google-vertex-ai` for Vertex AI; Claude models use Anthropic Messages and other models use OpenAI Chat Completions - `aws-bedrock` only through a configured Bedrock-compatible bridge today - Required credential key exists diff --git a/crates/openshell-core/src/inference.rs b/crates/openshell-core/src/inference.rs index 09adf5e3d5..9acb0f6ebb 100644 --- a/crates/openshell-core/src/inference.rs +++ b/crates/openshell-core/src/inference.rs @@ -85,7 +85,6 @@ const VERTEX_AI_PROTOCOLS: &[&str] = &["anthropic_messages", "model_discovery"]; /// Anthropic-style clients simultaneously. const TARS_PROTOCOLS: &[&str] = &[ "openai_chat_completions", - "openai_completions", "openai_responses", "openai_embeddings", "anthropic_messages", @@ -196,6 +195,15 @@ static DEEPINFRA_PROFILE: InferenceProviderProfile = InferenceProviderProfile { // deployments override it with `TARS_BASE_URL` (customer-specific hostname). // TARS accepts `Authorization: Bearer sk-` on both its OpenAI-compatible // and Anthropic Messages routes, so `Bearer` covers the whole protocol set. +// +// `default_headers` is intentionally empty even though this profile serves +// `anthropic_messages`, where `ANTHROPIC_PROFILE` injects `anthropic-version`. +// Route default headers are applied to every request on the route regardless +// of the request's protocol (there is no per-protocol hook — see +// `route_headers_for_route`), so injecting `anthropic-version` here would also +// stamp it onto `/v1/chat/completions` and `/v1/embeddings`, where a +// translating gateway may read it as a protocol-family hint. Anthropic clients +// send the header themselves and it is on the passthrough allowlist below. static TARS_PROFILE: InferenceProviderProfile = InferenceProviderProfile { provider_type: "tars", default_base_url: "https://api.router.tetrate.ai/v1", @@ -469,6 +477,26 @@ mod tests { } } + #[test] + fn tars_profile_omits_legacy_completions() { + let profile = profile_for("tars").expect("tars profile should exist"); + assert!(!profile.protocols.contains(&"openai_completions")); + } + + /// Unlike `ANTHROPIC_PROFILE`, the dual-family TARS profile must not inject + /// `anthropic-version` as a route default: route default headers apply to + /// every request on the route, so it would also land on the OpenAI-family + /// paths TARS serves from the same base URL. + #[test] + fn tars_profile_injects_no_default_headers() { + let profile = profile_for("tars").expect("tars profile should exist"); + assert!(profile.default_headers.is_empty()); + assert!( + profile.passthrough_headers.contains(&"anthropic-version"), + "anthropic clients must still be able to send anthropic-version" + ); + } + #[test] fn route_headers_for_tars_include_both_families_passthrough() { let (auth, headers, passthrough_headers) = route_headers_for_provider_type("tars"); diff --git a/crates/openshell-providers/src/lib.rs b/crates/openshell-providers/src/lib.rs index a97dffb956..83254fa77b 100644 --- a/crates/openshell-providers/src/lib.rs +++ b/crates/openshell-providers/src/lib.rs @@ -242,6 +242,12 @@ mod tests { normalize_provider_type("vertex-ai"), Some("google-vertex-ai") ); + assert_eq!(normalize_provider_type("tars"), Some("tars")); + assert_eq!(normalize_provider_type("agentrouter"), Some("tars")); + assert_eq!( + normalize_provider_type("tetrate-agent-router"), + Some("tars") + ); assert_eq!(normalize_provider_type("unknown"), None); } diff --git a/docs/sandboxes/inference-routing.mdx b/docs/sandboxes/inference-routing.mdx index 0a92800086..bab2d61532 100644 --- a/docs/sandboxes/inference-routing.mdx +++ b/docs/sandboxes/inference-routing.mdx @@ -24,7 +24,7 @@ If code calls an external inference host directly, OpenShell evaluates that traf | Property | Detail | |---|---| | Credentials | No sandbox API keys needed. Credentials come from the configured provider record. The router strips caller-supplied `Authorization` before forwarding the request. | -| Header forwarding | `inference.local` forwards only a per-provider header allowlist. OpenAI routes allow `openai-organization` and `x-model-id`. Anthropic routes allow `anthropic-version` and `anthropic-beta`. Vertex Claude rawPredict routes strip `anthropic-beta` and do not forward `anthropic-version` as a header because the router injects `anthropic_version` into the Vertex request body. NVIDIA routes allow `x-model-id`. AWS Bedrock routes have no passthrough headers today. All other caller headers are stripped. | +| Header forwarding | `inference.local` forwards only a per-provider header allowlist. OpenAI routes allow `openai-organization` and `x-model-id`. Anthropic routes allow `anthropic-version` and `anthropic-beta`. Vertex Claude rawPredict routes strip `anthropic-beta` and do not forward `anthropic-version` as a header because the router injects `anthropic_version` into the Vertex request body. NVIDIA routes allow `x-model-id`. TARS routes serve both families from one base URL, so they allow `anthropic-version`, `anthropic-beta`, `openai-organization`, and `x-model-id`. AWS Bedrock routes have no passthrough headers today. All other caller headers are stripped. | | Configuration | One provider and one model define sandbox inference for the active gateway. Every sandbox on that gateway sees the same `inference.local` backend. | | Provider support | NVIDIA, Anthropic, Google Vertex AI, AWS Bedrock (via a translating bridge — direct AWS with SigV4 signing is a separate follow-up), and any OpenAI-compatible provider all work through the same endpoint. Vertex routes Claude models through `/v1/messages` and non-Anthropic models through `/v1/chat/completions`. The gateway resolves the upstream Vertex host from the provider config, including regional, global, and supported multi-region endpoints. | | Streaming reliability | The router tolerates idle gaps of up to 120 seconds between streamed chunks so long reasoning responses are not cut off mid-stream. | diff --git a/docs/sandboxes/manage-providers.mdx b/docs/sandboxes/manage-providers.mdx index ee67f49497..6240f037be 100644 --- a/docs/sandboxes/manage-providers.mdx +++ b/docs/sandboxes/manage-providers.mdx @@ -339,7 +339,7 @@ The following provider types are supported. | `nvidia` | `NVIDIA_API_KEY` | NVIDIA API Catalog | | `openai` | `OPENAI_API_KEY` | Any OpenAI-compatible endpoint. Set `--config OPENAI_BASE_URL` to point to the provider. Refer to [Inference Routing](/sandboxes/inference-routing). | | `opencode` | `OPENCODE_API_KEY`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY` | OpenCode | -| `tars` | `TARS_API_KEY`, `AGENTROUTER_API_KEY` | Tetrate Agent Router Service (TARS). Serves OpenAI-compatible and Anthropic Messages clients through one provider. Set `--config TARS_BASE_URL` for enterprise (self-hosted) gateways. | +| `tars` | `TARS_API_KEY`, `AGENTROUTER_API_KEY` | Tetrate Agent Router Service (TARS). Aliases: `agentrouter`, `tetrate-agent-router`. Serves OpenAI-compatible and Anthropic Messages clients through one provider. Set `--config TARS_BASE_URL` for enterprise (self-hosted) gateways. | `ANTHROPIC_API_KEY` is an API key from [console.anthropic.com](https://console.anthropic.com), not a subscription token. Subscription users must generate a separate API key from the Anthropic Console.