Files
tracer-cloud--opensre/core/llm/AGENTS.md
T
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

92 lines
6.0 KiB
Markdown

# Hosted LLM Runtime
This package owns hosted LLM provider clients and runtime helpers used by the
agent loop. Subprocess-backed LLM CLIs live under `integrations/llm_cli/`.
## Where provider wiring lives
| File | Role |
| --- | --- |
| `config/config.py` | Declares `LLMProvider`, provider env vars, defaults, and validation requirements. |
| `config/llm_auth/provider_catalog.py` | Canonical `ProviderSpec` metadata shared by wizard, auth, and runtime checks. |
| `core/llm/factory.py` | Single routing entrypoint: `resolve_llm_route()`, `get_llm(role)`, `reset_llm_clients()`. |
| `core/llm/client_builders.py` | Construct the client for a resolved route: `build_agent_client()`, `build_reasoning_client()`. |
| `core/llm/providers/provider_registry.py` | `FIRST_PARTY_PROVIDERS` table (models, max_tokens, LiteLLM prefix, api-key env) the builders read. |
| `core/llm/transport_mode.py` | `OPENSRE_LLM_TRANSPORT` (`sdk` vs `litellm`) and `use_litellm_for_provider()`. |
| `core/llm/internal/client_cache_key.py` | Singleton cache invalidation key `(transport, runtime_provider)`. |
| `core/llm/providers/openai_compat_providers.py` | OpenAI-compatible provider catalog and model/base-URL resolution. |
| `core/llm/providers/azure_openai.py` | Azure OpenAI helpers: endpoint normalization, deployment selection, LiteLLM kwargs. |
| `core/llm/transports/litellm/routing.py` | Per-provider LiteLLM client construction (model prefix, `api_base`, `api_version`). |
| `core/llm/transports/litellm/clients.py` | `LiteLLMAgentClient` / `LiteLLMLLMClient` wrappers around `litellm.completion`. |
| `core/llm/transports/sdk/agent_clients.py` | Native SDK tool-calling clients (Anthropic, OpenAI, Bedrock, CLI-backed). |
| `core/llm/transports/sdk/llm_clients.py` | Native SDK non-agent clients. |
| `core/llm/shared/tool_schema_normalize.py` | JSON Schema normalization shared by strict tool-calling adapters. |
| `surfaces/cli/wizard/config.py` | Onboarding metadata (`SUPPORTED_PROVIDERS`) and model choices. |
| `surfaces/cli/wizard/env_sync.py` | `.env` synchronization when provider/model choices change. |
User-facing setup and env var tables: [`docs/llm-providers.mdx`](../../docs/llm-providers.mdx).
## Transport: native SDK vs LiteLLM
Default path is **native vendor SDKs** (`OPENSRE_LLM_TRANSPORT` unset or `sdk`).
**LiteLLM path** (`OPENSRE_LLM_TRANSPORT=litellm`): routes hosted API providers through
`core/llm/transports/litellm/routing.py` instead of `core/llm/transports/sdk/*`.
**Azure OpenAI** (`LLM_PROVIDER=azure-openai`) **always** uses LiteLLM — even when
`OPENSRE_LLM_TRANSPORT` is unset. Onboarding writes `OPENSRE_LLM_TRANSPORT=litellm` to
`.env`; switching away from Azure removes that key so other providers return to SDK routing.
Dispatch entrypoints — all routing lives in **one** place, `core/llm/factory.py`;
construction lives in `core/llm/client_builders.py`:
```text
get_llm(role) # role ∈ {AGENT, REASONING, CLASSIFICATION, TOOLCALL} # factory.py
→ resolve_llm_route() # the single provider/transport decision # factory.py
→ client_builders.build_agent_client(route) / build_reasoning_client(route, model_type)
cli_provider_registration? → CLI-backed subprocess client
use_litellm_for_provider? → build_litellm_*_client(settings, provider) # transports/litellm/routing.py
else → native SDK client in transports/sdk/agent_clients.py or transports/sdk/llm_clients.py
```
When changing routing, edit only `resolve_llm_route` in `factory.py`; when changing how a
provider's client is built, edit the builders in `client_builders.py` — there is no second
copy to keep in sync.
One cache in `factory.py` keyed by `(role, transport, runtime_provider)`, invalidated
together on `(transport, runtime_provider)` change (not transport alone). REPL `/model`
and wizard env sync call `reset_llm_clients()` directly.
## Adding a Hosted API Provider
1. Add the provider literal to `LLMProvider` and normalization/validation paths in `config/config.py`.
2. Add `ProviderSpec` in `config/llm_auth/provider_catalog.py` and matching `ProviderOption` in
`surfaces/cli/wizard/config.py` (model env vars, defaults, `endpoint_env` if needed).
3. Add runtime construction (routing itself stays in `core/llm/factory.py`; clients are built in `core/llm/client_builders.py`):
- **First-party provider** (its own SDK models + a LiteLLM prefix): add **one row** to
`FIRST_PARTY_PROVIDERS` in `core/llm/providers/provider_registry.py` — the SDK and LiteLLM
builders read the table, so no per-provider branch is needed unless the client class is new.
- **SDK path:** add the client class in `core/llm/transports/sdk/llm_clients.py` and/or
`core/llm/transports/sdk/agent_clients.py`; the builders in `client_builders.py` select it.
- **LiteLLM path (optional or required):** covered by the registry row; only add a branch in
`core/llm/transports/litellm/routing.py` for a non-standard case (e.g. Azure).
- **OpenAI-compatible:** register in `providers/openai_compat_providers.py` (SDK compat path) and/or
`transports/litellm/routing.py` (LiteLLM path).
4. Update `surfaces/cli/wizard/env_sync.py` if you introduce new non-secret env keys; keep endpoint
keys in `active_non_secret` when the provider needs persisted URL/version settings.
5. Add or update tests under `tests/core/runtime/llm/` and wizard tests if onboarding changes.
### Azure OpenAI (`azure-openai`)
Azure uses **deployment names** (not public OpenAI model IDs) and a resource **base URL**:
- `AZURE_OPENAI_BASE_URL`, `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_API_VERSION` (default applied when unset)
- `AZURE_OPENAI_*_MODEL` env vars hold deployment names in the user's Azure resource
- LiteLLM model string: `azure/<deployment>` via `azure_openai_litellm_model()`
Do not add a separate Azure client class — extend `transports/litellm/routing.py` and helpers in
`providers/azure_openai.py`.
For investigation tool calling details, see
[`docs/investigation-tool-calling.md`](../../docs/investigation-tool-calling.md).