Skip to content

Make the AI provider a manual choice and Amazee.ai strictly opt-in - #50

Merged
jeremyandrews merged 1 commit into
mainfrom
feature/manual-provider-and-amazee-opt-in
Aug 4, 2026
Merged

jeremyandrews merged 1 commit into
mainfrom
feature/manual-provider-and-amazee-opt-in

Conversation

@jeremyandrews

Copy link
Copy Markdown
Member

What changed here

AutoProvisioner.ensure_ai_available() constructed an AmazeeTrialProvisioner and minted a free trial whenever it found an empty credential store, so any request, cron or install path that called it enrolled a site that had never opted in. That branch is deleted; the method now matches the PHP core exactly — it self-heals credentials that are already stored and establishes nothing. Its return value is consequently always False (there is no success left to report); the signature is unchanged so callers keep working, and a caller that branched on True should move that branch to its own explicit provision() call.

Alongside: ScoltaConfig.ai_provider defaults to "", HealthChecker no longer coalesces it and gains ai_provider_selected, AiClient rejects an absent provider instead of quietly becoming Anthropic, and AiServiceAdapter._get_client() refuses to build a client with no provider — raising the ApiKeyMissingException callers already degrade on. New AmazeeConnectionSource and ProvenanceAwareConfigStorage mirror the PHP core.

The policy

A — no default provider. Selection is always manual. Nothing ships with an AI provider selected, and while none is selected AI features are simply off: search still works, no provider is assumed, and Anthropic in particular is not silently assumed.

B — Amazee.ai is never auto-enabled. No credential is provisioned and no outbound Amazee call is made on a request, cron, install or activation path for a site that has not opted in. The only automatic Amazee activity permitted is re-resolving gateway model names against a key already on disk, which only a site that already connected can reach.

Migration is going-forward only. A provider already persisted by a site is read as-is — nothing rewrites, clears or re-defaults it, and there is no update hook that turns AI off on a working install.

Amazee is email-only

Connecting is two explicit actions, mirroring amazee.ai's own ai_provider_amazeeio module:

  • Try the demo — no email, no account, no card. One-time per site; when its credit is spent the surface points at the account path rather than failing opaquely.
  • Enter your Amazee credentials — the email → verification code → region flow, which creates or attaches a real account and persists the credentials it returns.

There is deliberately no paste-your-API-key path. amazee.ai issues and manages the keys; a second credential scheme would have nothing behind it.

Provenance

Which of the two actions established a connection is recorded when it happens, so surfaces report a stored fact instead of a guess. scolta-php#273 collapsed the two Amazee source cases because nothing recorded which had run — recording it is the fix, rather than guessing or giving up. Credentials connected before this release report the origin-free Amazee source and claim nothing.

Dependency

Requires the core changes in scolta-php#275, already merged to main. CI resolves tag1/scolta-php from dev-main, so this is testable now. The committed composer.lock stays pinned at the stable release — bumping it is release-time work, not part of this PR.

Tests

822 tests, ruff clean. New tests/ai/amazee/test_manual_provider_and_opt_in.py uses a transport that fails the test if it is called at all, so an unexpected outbound Amazee request names the endpoint rather than being swallowed. Two tests that asserted the old first-use mint behaviour are replaced by tests asserting its absence; the self-heal test now drives an explicit provision() for its setup, since ensure_ai_available() no longer establishes anything.

ensure_ai_available() constructed a trial provisioner and minted a free trial
whenever it found an empty credential store, so any request, cron or install
path that called it enrolled a site that had never opted in. That branch is
gone; the method now matches the PHP core exactly, self-healing credentials that
are already stored and establishing nothing.

The provider default of 'anthropic' and the two coalescings that restored it are
gone too. Empty means AI is off rather than Anthropic: the service adapter
refuses to build a client, AiClient rejects an absent provider, and health
reports ai_provider_selected: False. Sites keep any provider they already saved.

Which action established an Amazee connection is now recorded through a new
ProvenanceAwareConfigStorage, so a demo and an operator's own account are
distinguishable from a stored fact rather than from a guess.
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Summary

Removes AI provider auto-selection and Amazee.ai auto-enrollment: ai_provider now defaults to empty (no more silent "anthropic" default) meaning AI is off until explicitly configured, and AutoProvisioner.ensure_ai_available() no longer mints a free trial for empty credential stores—it only self-heals model resolution for already-stored credentials. A new ProvenanceAwareConfigStorage sub-interface records whether a stored connection came from the demo trial or an operator's own account.

Type: refactor
Effort: 3/5 — Behavioral policy change spanning ~10 source files plus substantial new/updated tests (~550 lines), but logic changes per file are moderate and mostly subtractive (removing defaults/auto-provision paths) or additive (new enum/interface).

Walkthrough

File Change Summary
Core Policy Changes
src/scolta/ai/amazee/auto_provisioner.py Modified Removes trial-minting branch; ensure_ai_available() now only self-heals stored credentials' model resolution, always returns False
src/scolta/config.py Modified ai_provider default changed from "anthropic" to ""
src/scolta/health.py Modified No longer coalesces empty provider to "anthropic"; adds ai_provider_selected field, ai_usable requires provider selected
src/scolta/ai/client.py Modified AiClient raises ValueError if no provider is set instead of defaulting to "anthropic"
src/scolta/ai/service.py Modified _get_client() raises ApiKeyMissingException when no provider selected, rather than building a default client
Provenance Tracking
src/scolta/ai/amazee/connection_source.py Added New AmazeeConnectionSource enum (DEMO/ACCOUNT) with label() method
src/scolta/ai/amazee/storage.py Modified Adds ProvenanceAwareConfigStorage abstract sub-interface for optional connection-source persistence
src/scolta/ai/amazee/trial_provisioner.py Modified Records DEMO connection source when storage supports it
src/scolta/ai/amazee/account_upgrader.py Modified Records ACCOUNT connection source when storage supports it
src/scolta/ai/amazee/key_expiry_recovery.py Modified Doc/comment updates clarifying opt-in nature of Amazee path
src/scolta/ai/amazee/init.py Modified Exports AmazeeConnectionSource and ProvenanceAwareConfigStorage
Tests
tests/ai/amazee/test_manual_provider_and_opt_in.py Added New comprehensive test suite asserting no-default-provider and no-auto-enrollment invariants, plus provenance recording
tests/ai/amazee/test_amazee.py Modified Replaces trial-minting assertions with no-op/no-outbound-call assertions
tests/ai/test_client.py Modified Test helper now supplies explicit provider in config
tests/ai/test_service.py Modified Tests updated to pass explicit ai_provider since default removed
tests/test_config.py Modified Updated default assertion to ""
tests/test_health.py Modified Tests updated to pass explicit ai_provider
Docs
CHANGELOG.md Modified Documents the two policy changes and removed auto-provision behavior
README.md Modified Adds "Selecting an AI provider is always manual" section
docs/CONFIG_REFERENCE.md Modified Updates ai_provider default/description

Related Issues & PRs

No related issues identified.


AI Review Summary — generated by ai-pr-review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Review: Approved

No findings above the confidence threshold. The changes look good.

Token usage by agent
Agent Model Input Output Cache Write Cache Read Total Est. Cost
code-reviewer Sonnet 5 1 448 / 16384 41332 0 41781 $0.1617
silent-failure-hunter Sonnet 5 1 777 / 16384 39844 0 40622 $0.1610
Total 2 1225 81176 0 82403 $0.3227
Context enrichment (context) 8204
Language profiles (profile) 1021

AI Review — generated by ai-pr-review

@jeremyandrews
jeremyandrews merged commit dffa41e into main Aug 4, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant