amal66 is making Mike's AI connections easier to extend

The closed proposal would replace a tangle of provider-specific handling with a single, reusable way to add AI services.

integrationinfrastructure

Rather than changing several parts of the product whenever a new model provider is added, amal66's approach puts those connections in one shared register. Existing behaviour would stay the same: the same three built-in providers, model selection, and key-status checks.

  • OpenAI-compatible services could be added through a self-contained setup.
  • Local models via Ollama were planned as a follow-on.
  • Vertex AI and a demo mode were also intended to build on this foundation.

The branch passed the upstream test suite and build checks, but the proposal closed without merging.

So what Legal teams weighing a broader mix of AI providers should watch this fork: it points toward less friction when connecting Mike to their preferred model infrastructure.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

1 commit from amal66/mike, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
f98c2092 refactor: provider registry, storage adapter, table-driven api-key lookup Amal 2026-05-24 ↗ GitHub
commit body
Implements three open-source extensibility primitives so adding a new LLM
provider, storage backend, or law-library integration is a single-file
operation with no edits to core dispatch logic.

**LLM provider registry** (lib/llm/registry.ts)
- LLMProviderAdapter interface: id, matchesModel, stream, complete, models
- registerProvider() / findProviderForModel() / allRegisteredModels()
- Built-in providers (Claude, Gemini, OpenAI) self-register in index.ts on
  load; Vitest mock hoisting still captures them so retryCircuit tests pass
- providerForModel() checks registry first, then falls back to prefix
  heuristics - external providers override routing with zero core edits
- resolveModel() checks live registry union then static ALL_MODELS fallback
  (derived from *_MODELS spreads, not hand-maintained)
- Dispatch in streamChatWithTools / completeText: registry lookup + explicit
  throw on missing adapter - no silent fallthrough
- registerProvider() re-exported from lib/llm for consumer convenience
- Example: lib/llm/providers/ollama.ts shows full third-party integration

**Storage adapter pattern** (lib/storage/adapter.ts + r2.ts)
- StorageAdapter interface: upload, download, delete, getSignedUrl, checkReady
- R2StorageAdapter implements the interface with singleton S3Client
- lib/storage.ts gains setStorageAdapter() - swap to Supabase Storage, local
  filesystem, AWS S3, or MinIO with zero changes to any route or middleware
- All original function exports preserved with identical signatures

**Table-driven API-key lookup** (core/apiKeyProviders.ts)
- Provider env-var names live in a Map, not in a switch statement
- registerApiKeyProvider() lets new providers declare their env vars once
- getUserApiKeyStatus() and getUserApiKeys() iterate getRegisteredProviders()
  so a fourth provider appears in both automatically - no literal-object edits
- UserApiKeys index signature extended so third-party keys flow through
  without type changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-1394.md from inside the repo you want the changes in.

⬇ Download capture-thread-1394.md