subllm
subllm is the single Python source of truth for Subactor LLM providers,
models, application/function routes and their priorities. The repository name
and import package are subllm; the distribution is named
subactor-subllm because the unscoped subllm distribution name is already in
use.
The repository never tracks credentials. For local development, all SubLLM
consumers in one sibling-project workspace can read provider keys from the
single ignored subllm/.env file. In CI and deployments, process environment
variables or a credential vault remain the source and override that file.
Policy
LLM strategies are assigned by API-key source (ADOPT
wellmanifest/policy-dsl profile llm-credential and
wellmanifest/env-dsl subllm-credential-strategies.env):
| Credential | Provider | Transport | Default model |
|---|---|---|---|
CURSOR_API_KEY |
cursor |
Cursor SDK | gpt-5.6-sol |
ZAI_API_KEY |
zai |
OpenAI-compatible | glm-5.2 |
OPENROUTER_API_KEY |
openrouter |
OpenAI-compatible | glm-5.2 |
gpt-5.6-sol is Cursor-only. OpenRouter never claims Sol as
openai/gpt-5.6-sol. Missing keys fail closed for that strategy; routes then
continue with later candidates.
Koru is intentionally stricter than the shared default route. Its
planning-assistant and queue-executor routes allow only Cursor
grok-4.6 with effort=xhigh and fast=false; they do not fall back to
OpenRouter, Z.AI, Sol, or a different Cursor preset.
Gemini 3.1 Pro Preview is blocked in the catalog. Provider, model, application
and route definitions live in src/subllm/policy.py. See
docs/credential-strategies.md.
The two Validator routes are intentionally narrower than the shared provider
default: validator-agent/patch-review and
validator-agent/direct-pr-review pin direct Z.AI to glm-5.3, while their
OpenRouter fallback remains z-ai/glm-5.2. This keeps the GLM 5.3 rollout
bounded to Validator until the newer model is qualified for other consumers.
Application identity in provider logs
Every application has one stable ID plus an operator-controlled display name
and public attribution URL in subllm.toml:
[applications.doctor-agent]
name = "doctor-agent"
url = "https://github.com/subactor/doctor-agent"
OpenRouter requests carry the URL in HTTP-Referer, the configured name in
X-OpenRouter-Title, and the stable application ID in user. Z.AI requests
carry the stable ID in user_id. Native HTTP and SubLLM-managed LiteLLM calls
also carry a unique request_id prefixed with the application and function.
These values contain no credential or end-user personal data.
ResolvedRoute.litellm_kwargs() adds the provider-specific fields for
OpenAI-compatible transports. Cursor routes use cursor_sdk_kwargs() instead.
Provider priority and default models
Edit the tracked subllm.toml file:
[providers.cursor]
enabled = true
priority = 0
default_model = "gpt-5.6-sol"
[providers.zai]
enabled = true
priority = 10
default_model = "glm-5.2"
[providers.openrouter]
enabled = true
priority = 20
default_model = "glm-5.2"
Lower priority wins. Set enabled = false to remove a provider from every
route. Sibling projects discover this file automatically. Set
SUBLLM_POLICY_FILE for another layout.
Fallback chain
SUBLLM_PROVIDER_ORDER is a comma-separated allowlist:
cursor, zai, openrouter. Empty or unset uses the default:
cursor,zai,openrouterwhenCURSOR_API_KEYis set,zai,openrouterwhen it is absent.
Unknown names fail closed. resolve() returns cursor when that candidate
wins and the Cursor key is valid.
One local credential file
cp .env.example .env
chmod 600 .env
ZAI_API_KEY=YOUR_API_KEY_ID.YOUR_SIGNATURE_SECRET
OPENROUTER_API_KEY=
CURSOR_API_KEY=
SUBLLM_PROVIDER_ORDER=
Python API
from subllm import resolve
route = resolve("repair-agent", "repair-plan")
# wellmanifest/webpage site UX judgment:
# route = resolve("platform", "site-audit")
if route.provider == "cursor":
sdk = route.cursor_sdk_kwargs()
else:
result = completion(**route.litellm_kwargs(), messages=[...])
CLI
subllm check
subllm providers
subllm resolve doctor-agent repair-proposal --configured
subllm resolve onedev-agent code-edit --provider openrouter --field litellm-model
subllm poa inspect poa://subactor.subllm/process/list-routes/v1
subllm serve --host 127.0.0.1 --port 8788
CLI, shell and HTTP share one POA CQRS/ES bus. See docs/poa-api.md.
Development
python -m venv .venv
. .venv/bin/activate
python -m pip install -e '.[test]'
./scripts/verify
See docs/architecture.md and docs/operations.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file subactor_subllm-1.4.1.tar.gz.
File metadata
- Download URL: subactor_subllm-1.4.1.tar.gz
- Upload date:
- Size: 36.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac4ea8334cb66861d4db489669119bfae70e2825255ab37430653460c8f60a0e
|
|
| MD5 |
0d1a7ed5fcfbdb8318e49aa04943eb01
|
|
| BLAKE2b-256 |
d0ad23ed8890c015ce99d6d5b5aabfa546800b1b87b49103e3005dc733a80c02
|
File details
Details for the file subactor_subllm-1.4.1-py3-none-any.whl.
File metadata
- Download URL: subactor_subllm-1.4.1-py3-none-any.whl
- Upload date:
- Size: 33.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8fca3f91402ebb8f492ae185f7931883518ba3d7081a019b526a8ce5ac8f8f4
|
|
| MD5 |
55e27ef67de8d5257f5f0afab93a6f1a
|
|
| BLAKE2b-256 |
a80eb9f821e47c31d601b543a05530fc85559b3d594b4d0da820c58b05f34d6b
|