Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/ardurai_ardur-agent.json
T

1 line
6.9 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "ardurai/ardur-agent", "files": {"crates/provider-openrouter/README.md": {"34b4b7d65e8efc7ef704dc1d72786861cd8d1fe5": {"t": 1785746528.624872, "n": 3259, "h": "14007e932f94c10e", "c": "# ardur-provider-openrouter (§3.2)\n\nA [`Provider`](../provider-runtime) backend for [OpenRouter](https://openrouter.ai) —\na multi-model gateway that exposes a single **OpenAI-compatible**\n`POST /chat/completions` endpoint routing to many upstream providers behind one\nAPI key.\n\n## Why\n\nOpenRouter unblocks dogfooding ardur-agent against cheap or free models without\nwiring a separate backend per vendor. One API key, one endpoint, dozens of\nmodels — selected per request by passing the model slug through the request's\n`ModelId`.\n\n## Usage\n\n```rust\nuse std::sync::Arc;\nuse ardur_provider_openrouter::{OpenRouterConfig, OpenRouterProvider};\nuse ardur_provider_runtime::{ModelId, Provider, ProviderRegistry};\n\n// From the OPENROUTER_API_KEY environment variable:\nlet provider = OpenRouterProvider::from_env(ModelId::new(\"anthropic/claude-3.5-sonnet\"))?;\n\n// …or from an explicit config (overridable base URL + attribution headers):\nlet provider = OpenRouterProvider::new(\n OpenRouterConfig::new(\"sk-or-...\")\n .referer(\"https://github.com/ArdurAI/ardur-agent\")\n .title(\"Ardur Agent\"),\n ModelId::new(\"openai/gpt-4o\"),\n);\n\n// It plugs into the generic registry like any other provider:\nlet mut registry = ProviderRegistry::new();\nregistry.register(Arc::new(provider)); // registered under id \"openrouter\"\n```\n\nThe model on each `CompletionRequest` selects which upstream model OpenRouter\nroutes to — the `model_id` passed at construction is only the runtime's default.\n\n## Supported models\n\nThe model string is **opaque** and passes through unchanged; OpenRouter\nvalidates it against its catalog. Any slug from\n<https://openrouter.ai/models> works. Representative examples:\n\n| Slug | Notes |\n|---|---|\n| `anthropic/claude-3.5-sonnet` | Anthropic via the gateway |\n| `openai/gpt-4o` | OpenAI |\n| `google/gemini-flash-1.5` | Google |\n| `meta-llama/llama-3.1-8b-instruct:free` | free tier (`:free` suffix) |\n| `mistralai/mistral-7b-instruct` | Mistral |\n| `deepseek/deepseek-chat` | DeepSeek |\n\n## Auth & headers\n\nEvery request sends:\n\n- `Authorization: Bearer <api-key>`\n- `HTTP-Referer: https://github.com/ArdurAI/ardur-agent` (default; OpenRouter's\n recommended attribution header, overridable)\n- `X-Title: Ardur Agent` (default, overridable)\n\n## Cost reporting\n\nOpenRouter returns `usage: { prompt_tokens, completion_tokens, total_tokens,\ncost }`. Token counts populate the billed `CostTuple`, and the dollar `cost` is\nmapped to whole US cents (`round(cost × 100)`). When `cost` is absent the call\nis billed `0` cents — Phase 1 does not reconstruct cost from a rate card.\n\n## Error mapping\n\n| HTTP | `ProviderError` |\n|---|---|\n| 401 / 403 | `Unauthorized` |\n| 429 | `RateLimited { retry_after_ms }` (from `Retry-After`) |\n| 400 | `InvalidRequest(message)` |\n| 404 | `ModelNotAvailable(model)` |\n| other | `Upstream(\"HTTP <code>: <message> (code: …)\")` |\n\nOpenRouter's `{ \"error\": { \"message\", \"code\" } }` body is parsed and its message\n+ code surfaced in the mapped error.\n\n## Not in Phase 1\n\n- **Streaming** — every request sends `stream: false`;\n `supports_streaming()` is `false`. (Phase 2.)\n- **Tool-call parsing** — a `tool_calls` finish reason surfaces as\n `FinishReason::ToolUse(vec![])`; the blocks are not decoded yet. (Phase 2.)\n"}, "e2011096735fdeba04690cf557708248b506b9e2": {"t": 1785765351.515097, "n": 3259, "h": "14007e932f94c10e", "c": "# ardur-provider-openrouter (§3.2)\n\nA [`Provider`](../provider-runtime) backend for [OpenRouter](https://openrouter.ai) —\na multi-model gateway that exposes a single **OpenAI-compatible**\n`POST /chat/completions` endpoint routing to many upstream providers behind one\nAPI key.\n\n## Why\n\nOpenRouter unblocks dogfooding ardur-agent against cheap or free models without\nwiring a separate backend per vendor. One API key, one endpoint, dozens of\nmodels — selected per request by passing the model slug through the request's\n`ModelId`.\n\n## Usage\n\n```rust\nuse std::sync::Arc;\nuse ardur_provider_openrouter::{OpenRouterConfig, OpenRouterProvider};\nuse ardur_provider_runtime::{ModelId, Provider, ProviderRegistry};\n\n// From the OPENROUTER_API_KEY environment variable:\nlet provider = OpenRouterProvider::from_env(ModelId::new(\"anthropic/claude-3.5-sonnet\"))?;\n\n// …or from an explicit config (overridable base URL + attribution headers):\nlet provider = OpenRouterProvider::new(\n OpenRouterConfig::new(\"sk-or-...\")\n .referer(\"https://github.com/ArdurAI/ardur-agent\")\n .title(\"Ardur Agent\"),\n ModelId::new(\"openai/gpt-4o\"),\n);\n\n// It plugs into the generic registry like any other provider:\nlet mut registry = ProviderRegistry::new();\nregistry.register(Arc::new(provider)); // registered under id \"openrouter\"\n```\n\nThe model on each `CompletionRequest` selects which upstream model OpenRouter\nroutes to — the `model_id` passed at construction is only the runtime's default.\n\n## Supported models\n\nThe model string is **opaque** and passes through unchanged; OpenRouter\nvalidates it against its catalog. Any slug from\n<https://openrouter.ai/models> works. Representative examples:\n\n| Slug | Notes |\n|---|---|\n| `anthropic/claude-3.5-sonnet` | Anthropic via the gateway |\n| `openai/gpt-4o` | OpenAI |\n| `google/gemini-flash-1.5` | Google |\n| `meta-llama/llama-3.1-8b-instruct:free` | free tier (`:free` suffix) |\n| `mistralai/mistral-7b-instruct` | Mistral |\n| `deepseek/deepseek-chat` | DeepSeek |\n\n## Auth & headers\n\nEvery request sends:\n\n- `Authorization: Bearer <api-key>`\n- `HTTP-Referer: https://github.com/ArdurAI/ardur-agent` (default; OpenRouter's\n recommended attribution header, overridable)\n- `X-Title: Ardur Agent` (default, overridable)\n\n## Cost reporting\n\nOpenRouter returns `usage: { prompt_tokens, completion_tokens, total_tokens,\ncost }`. Token counts populate the billed `CostTuple`, and the dollar `cost` is\nmapped to whole US cents (`round(cost × 100)`). When `cost` is absent the call\nis billed `0` cents — Phase 1 does not reconstruct cost from a rate card.\n\n## Error mapping\n\n| HTTP | `ProviderError` |\n|---|---|\n| 401 / 403 | `Unauthorized` |\n| 429 | `RateLimited { retry_after_ms }` (from `Retry-After`) |\n| 400 | `InvalidRequest(message)` |\n| 404 | `ModelNotAvailable(model)` |\n| other | `Upstream(\"HTTP <code>: <message> (code: …)\")` |\n\nOpenRouter's `{ \"error\": { \"message\", \"code\" } }` body is parsed and its message\n+ code surfaced in the mapped error.\n\n## Not in Phase 1\n\n- **Streaming** — every request sends `stream: false`;\n `supports_streaming()` is `false`. (Phase 2.)\n- **Tool-call parsing** — a `tool_calls` finish reason surfaces as\n `FinishReason::ToolUse(vec![])`; the blocks are not decoded yet. (Phase 2.)\n"}}}}