Provider presets and factory #44

5 Commits
Author SHA1 Message Date
dev_agentandClaude Opus 5.5 08be8891da Reject API keys that are not valid header values at construction
Independent review Codex gpt-6-sol high: APPROVED (0 findings)
CI / ci (push) Successful in 1m30s
CI / ci (pull_request) Successful in 1m29s
FromSettings now fails with llm.ErrInvalidKey for a key with a control
character such as CR or LF, for every preset that sends a key, and
openai.New rejects such a key too, so neither defers the failure to the
first request. anthropic.New already rejected it. No error quotes the key.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 09:08:46 -04:00
dev_agentandClaude Opus 5.5 31322f239e Redact the API key from preset configuration and validation errors
CI / ci (push) Successful in 1m32s
CI / ci (pull_request) Successful in 1m30s
FromSettings errors and the configured provider's request-validation
errors now pass through a presets redactedError: its text has the key
removed with llm.Redact, it does not unwrap to the unredacted layers,
and Is still matches the llm sentinels. A key that equals a request
value (temperature -0.5) or a setting no longer appears in the error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 09:03:12 -04:00
dev_agentandClaude Opus 5.5 cb93134f3e Fix reasoning-model temperature quirk matching and validation
CI / ci (push) Successful in 1m38s
CI / ci (pull_request) Successful in 1m30s
- Omit temperature for OpenRouter's namespaced OpenAI reasoning models
  (openai/o1, openai/o1-mini, openai/o3-mini, openai/o1:online).
- Match o1/o3 only as the bare family name or with a "-" variant, so
  o123 and o3custom keep their temperature.
- Validate the caller's request before clearing temperature, so a
  negative temperature is still a validation error, not a sent request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 08:58:43 -04:00
dev_agentandClaude Opus 5.5 b6e433cc98 Allow openai and openrouter AI providers in the schema
CI / ci (push) Successful in 1m32s
CI / ci (pull_request) Successful in 1m30s
0001 limited ai_settings.provider and ai_runs.provider to
openai_compatible, anthropic and ollama, so the openai and openrouter
presets could not be stored. Migration 0004 rebuilds both tables with the
wider CHECK, keeping the three existing values and every row.

ai_runs is referenced by suggestion_batches and week_plans, so it is
rebuilt by copying rows aside and recreating the table under its own name
with foreign keys deferred; the create-then-rename rebuild from 0003 leaves
the dropped table's references counted as violations at commit.

Tests cover upgrading a database with ai_settings, ai_runs and referencing
rows, and storing every preset provider in both tables.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 08:54:03 -04:00
dev_agentandClaude Opus 5.5 61c767ea32 Add provider presets and FromSettings factory
internal/ai/llm/presets defines the anthropic, openai, openrouter, ollama
and openai_compatible presets (base URL, adapter, key policy, headers,
structured output modes and model quirks) and FromSettings, which turns
llm.Settings plus the decrypted key into a ready llm.Provider or a typed
configuration error from package llm.

Temperature is omitted for model ids matching ^o1 or ^o3, listed once in
TemperatureRejectingModels.

Maestro task: 4d90a725-5a7c-4bee-bbe4-d036cfb69c5b

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 08:51:19 -04:00