clew-code 0.4.5 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,107 @@
1
+ # Provider System
2
+
3
+ How Clew Code selects, configures, and talks to AI providers.
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ Clew core (claude.ts agent loop)
9
+ │ speaks Clew Internal Protocol v1
10
+
11
+ UnifiedAIProviderClient — client.beta.messages.create(...)
12
+
13
+ ├─ anthropic → native Anthropic SDK client (no adapter)
14
+ └─ everyone else
15
+
16
+ ProviderManager.createClient()
17
+ │ selection: session override → AI_PROVIDER → provider.json → legacy env → DEFAULT_PROVIDER
18
+
19
+ ProviderRegistry (built from providers.json)
20
+ │ provider classes: OpenAIProvider, GoogleProvider, OpenAICompatibleProvider, ...
21
+
22
+ AnthropicAdapter
23
+ converts requests/responses/stream events between the provider's
24
+ wire format and the Clew Internal Protocol
25
+ ```
26
+
27
+ ## Clew Internal Protocol v1
28
+
29
+ The core speaks the **Anthropic Messages format** end to end. This is a
30
+ deliberate, named decision — declared in `src/services/api/clewProtocol.ts` —
31
+ not an accident of history:
32
+
33
+ - `ClewProtocolRequest` = `BetaMessageStreamParams`
34
+ - `ClewProtocolMessage` = `BetaMessage`
35
+ - `ClewProtocolStreamEvent` = `BetaRawMessageStreamEvent`
36
+
37
+ Providers with other wire formats (OpenAI-compatible, Gemini, ...) are
38
+ converted at the system edge by adapters in `src/services/ai/adapter/`.
39
+ Changing these shapes is a protocol version bump.
40
+
41
+ ## Single source of truth
42
+
43
+ `src/services/ai/providers.json` is the only provider/model catalog. It feeds:
44
+
45
+ - `providerRegistry.ts` → `PROVIDER_REGISTRY`, `PROVIDER_IDS`, capabilities,
46
+ default models, prompt-caching support
47
+ - the `/providers` slash command (interactive picker)
48
+ - the `clew provider` CLI (`src/commands/provider-select-cli.ts`)
49
+ - dynamic model listing fallbacks (`providerModels.ts`)
50
+
51
+ Do **not** add hardcoded provider or model lists elsewhere. If a provider
52
+ needs a dedicated client class, register it in `createProvider()` in
53
+ `providerRegistry.ts`; anything OpenAI-compatible only needs a
54
+ `providers.json` entry (`envKey` + `defaultBaseUrl`) and falls back to
55
+ `OpenAICompatibleProvider` automatically.
56
+
57
+ `anthropic` is a first-class registry entry. Client creation still
58
+ special-cases it in `src/services/api/client.ts` (native SDK client, no
59
+ adapter), but selection, API-key resolution, model listing, and defaults all
60
+ go through the registry like every other provider.
61
+
62
+ ## Configuration
63
+
64
+ | Source | Precedence |
65
+ |---|---|
66
+ | Session override (`setSessionProvider` / `/providers set` without `--global`) | 1 (highest) |
67
+ | `AI_PROVIDER` env var | 2 |
68
+ | `<project>/.clew/provider.json`, else `~/.clew/provider.json` | 3 |
69
+ | Legacy env (`CLAUDE_CODE_USE_BEDROCK` / `VERTEX` / `FOUNDRY` → anthropic) | 4 |
70
+ | `DEFAULT_PROVIDER` (`openai`) | 5 |
71
+
72
+ ### Legacy IDs and migration
73
+
74
+ Older configs and CLIs wrote provider IDs that were never registered
75
+ (notably `gemini`). `normalizeProviderId()` in `providerRegistry.ts` maps
76
+ these aliases to canonical IDs (`gemini` → `google`) and is applied:
77
+
78
+ - when `provider.json` is loaded (`normalizeLegacyProviderConfig` — in-memory
79
+ only; the file on disk is not rewritten, and legacy `apiKeys` entries are
80
+ copied to the canonical ID rather than deleted, so older versions keep
81
+ working)
82
+ - to `AI_PROVIDER` and session-provider values
83
+ - to provider arguments of `/providers` and `clew provider --models`
84
+
85
+ Unknown provider IDs never throw at selection time — they fall through to
86
+ the next precedence level.
87
+
88
+ ### Selection-time validation
89
+
90
+ `src/services/ai/providerSelection.ts` validates provider/model choices when
91
+ the user changes them (`/providers set <provider> <model>`, `clew provider`):
92
+
93
+ - provider must resolve to a registry entry (aliases applied)
94
+ - model must appear in the registry catalog **or** the provider's live
95
+ `/models` listing; when neither yields any models (no API key, offline),
96
+ the model is accepted unverified
97
+ - `custom` provider models are never validated (arbitrary endpoints)
98
+
99
+ ## Known caveat: checked-in `.js` shadows
100
+
101
+ Several modules in `src/services/ai/` have a checked-in transpiled `.js`
102
+ sibling (`providerRegistry.js`, `ProviderManager.js`, `providers/*.js`,
103
+ `adapter/AnthropicAdapter.js`). Bun resolves an `import './x.js'` to the
104
+ `.js` file when it exists, so **the `.js` shadow is what actually runs** —
105
+ any change to a shadowed `.ts` file must be mirrored in its `.js` sibling or
106
+ it silently has no effect at runtime. Longer term these shadows should be
107
+ removed or generated by tooling.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clew-code",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "ClewCode — multi-provider AI coding agent CLI",
5
5
  "main": "./dist/main.js",
6
6
  "type": "module",