feat(v2): add Parse() and extensible Registry #5

Merged
steve merged 5 commits from feat/parse-registry into main 2026-05-24 15:14:45 +00:00
Owner

Summary

  • llm.Parse(spec) resolves model strings into ready-to-use *Model objects in one call. Supports "openai/gpt-4o", "openai/gpt-4o:high" (with reasoning suffix), Ollama-style tags like "ollama/qwen3:30b", static aliases, dynamic resolvers, and named targets via LLM_X env var DSNs.
  • Extensible Registry type with RegisterProvider, RegisterAlias, and RegisterResolver methods. A DefaultRegistry is pre-populated with all built-in providers (including the new foreman entry). Package-level convenience functions delegate to DefaultRegistry.
  • Foreman constructor for targeting foreman daemons (private authenticated Ollama endpoints with queuing/observability).
  • LLM_X DSN env vars enable named multi-instance targets without code changes: LLM_M5=foreman://token@host lets callers write llm.Parse("m5/qwen3:30b").

Spec format

spec     = alias | provider "/" model | envname "/" model
alias    = registered name (e.g., "fast", "thinking")
provider = registered provider (e.g., "openai", "foreman")
envname  = name resolved via LLM_{UPPER(name)} env var DSN
model    = everything after the first "/"

Optional ":low"/":medium"/":high" reasoning suffix on any spec.
Ollama tags like ":30b" are preserved (not consumed as reasoning).

DSN format (for LLM_X env vars)

scheme://[token@]host[/path]

Examples:

  • LLM_M5=foreman://my-token@foreman-m5.local
  • LLM_LOCAL=ollama://localhost:11434

Extension points

Method Purpose
RegisterProvider(info) Add or replace a provider factory
RegisterAlias(name, spec) Static alias ("fast" -> "openai/gpt-4o-mini")
RegisterResolver(res) Dynamic resolver (DB-backed tiers, remote config)

Follow-up

mort migration (registering tier aliases as resolvers, lane-wrapped factories via RegisterProvider) is a separate PR.

Test plan

  • go build ./... passes
  • go vet ./... clean
  • go test -race -count=1 ./... all pass (18 new test cases in parse_test.go)
  • go mod tidy + no diff on go.mod/go.sum
  • Backward compat: Providers() and ProviderByName() still work, now include foreman
## Summary - **`llm.Parse(spec)`** resolves model strings into ready-to-use `*Model` objects in one call. Supports `"openai/gpt-4o"`, `"openai/gpt-4o:high"` (with reasoning suffix), Ollama-style tags like `"ollama/qwen3:30b"`, static aliases, dynamic resolvers, and named targets via `LLM_X` env var DSNs. - **Extensible `Registry`** type with `RegisterProvider`, `RegisterAlias`, and `RegisterResolver` methods. A `DefaultRegistry` is pre-populated with all built-in providers (including the new `foreman` entry). Package-level convenience functions delegate to `DefaultRegistry`. - **`Foreman` constructor** for targeting foreman daemons (private authenticated Ollama endpoints with queuing/observability). - **`LLM_X` DSN env vars** enable named multi-instance targets without code changes: `LLM_M5=foreman://token@host` lets callers write `llm.Parse("m5/qwen3:30b")`. ## Spec format ``` spec = alias | provider "/" model | envname "/" model alias = registered name (e.g., "fast", "thinking") provider = registered provider (e.g., "openai", "foreman") envname = name resolved via LLM_{UPPER(name)} env var DSN model = everything after the first "/" Optional ":low"/":medium"/":high" reasoning suffix on any spec. Ollama tags like ":30b" are preserved (not consumed as reasoning). ``` ## DSN format (for `LLM_X` env vars) ``` scheme://[token@]host[/path] ``` Examples: - `LLM_M5=foreman://my-token@foreman-m5.local` - `LLM_LOCAL=ollama://localhost:11434` ## Extension points | Method | Purpose | |---|---| | `RegisterProvider(info)` | Add or replace a provider factory | | `RegisterAlias(name, spec)` | Static alias ("fast" -> "openai/gpt-4o-mini") | | `RegisterResolver(res)` | Dynamic resolver (DB-backed tiers, remote config) | ## Follow-up mort migration (registering tier aliases as resolvers, lane-wrapped factories via RegisterProvider) is a separate PR. ## Test plan - [x] `go build ./...` passes - [x] `go vet ./...` clean - [x] `go test -race -count=1 ./...` all pass (18 new test cases in parse_test.go) - [x] `go mod tidy` + no diff on go.mod/go.sum - [x] Backward compat: `Providers()` and `ProviderByName()` still work, now include foreman
steve added 1 commit 2026-05-24 02:58:49 +00:00
feat(v2): add Parse() function and extensible Registry for model string resolution
CI / Root Module (pull_request) Failing after 3s
CI / Lint (pull_request) Failing after 3s
CI / V2 Module (pull_request) Successful in 1m25s
4522310f5a
Introduces llm.Parse(spec) backed by an extensible Registry that resolves
model strings like "openai/gpt-4o", aliases like "fast", and named targets
like "m5/qwen3:30b" (via LLM_M5 env var DSNs) into ready-to-use *Model
objects. Extension points: RegisterProvider, RegisterAlias, RegisterResolver.
Adds Foreman constructor and sentinel errors ErrAliasLoop, ErrUnknownProvider,
ErrInvalidDSN.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
steve added 1 commit 2026-05-24 03:02:57 +00:00
steve added 1 commit 2026-05-24 03:24:23 +00:00
fix(ci): write correct YAML workflow (was double-encoded as base64)
CI / Lint (pull_request) Successful in 9s
CI / V2 Module (pull_request) Successful in 1m50s
db03e8d4ed
The previous CI fix commits stored the workflow file as a literal base64
string instead of decoded YAML, so Gitea could not parse it as a valid
workflow and no CI runs triggered. This writes the correct YAML content.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
steve added 1 commit 2026-05-24 03:28:26 +00:00
ci: optimize workflow by merging jobs and adding module cache
CI / Build, Test & Lint (pull_request) Successful in 11m33s
72e281f82b
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
steve added 1 commit 2026-05-24 15:14:18 +00:00
Merge branch 'main' into feat/parse-registry
CI / Build, Test & Lint (pull_request) Successful in 12m0s
a1f405de74
steve merged commit 6bac4cb3ed into main 2026-05-24 15:14:45 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: steve/go-llm#5