@inkdropapp/ai 0.1.0 → 0.1.1
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.
- package/README.md +14 -11
- package/package.json +4 -4
- package/src/provider.ts +4 -1
- package/src/registry.ts +19 -3
- package/src/settings.ts +11 -2
package/README.md
CHANGED
|
@@ -44,10 +44,8 @@ const settings: AISettings = {
|
|
|
44
44
|
}
|
|
45
45
|
]
|
|
46
46
|
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
fast: { providerId: 'anthropic', modelId: 'claude-haiku-4-5' }
|
|
50
|
-
}
|
|
47
|
+
// Pick one provider — slot models come from its catalogue defaults.
|
|
48
|
+
providerId: 'anthropic'
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
const registry = new Registry({ settings })
|
|
@@ -102,13 +100,18 @@ Inkdrop's AI features map onto two slots:
|
|
|
102
100
|
|
|
103
101
|
A slot resolves to `(provider, model)` via:
|
|
104
102
|
|
|
105
|
-
1. Explicit binding from `settings.slots[slot]`, if both the provider id and model id resolve.
|
|
106
|
-
2.
|
|
107
|
-
3. `
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
103
|
+
1. Explicit binding from `settings.slots[slot]`, if both the provider id and model id resolve. *(Advanced — pin a specific model per slot or mix providers across slots.)*
|
|
104
|
+
2. For `'fast'` only: fall back to `settings.slots.default` if that resolves.
|
|
105
|
+
3. Preferred provider from `settings.providerId`, if configured — takes its `defaultModel()` (for `default`) or `defaultFastModel()` (for `fast`). *(The simple UI knob — one provider dropdown drives every slot.)*
|
|
106
|
+
4. First **authenticated** registered provider in alphabetical id order, taking its `defaultModel()` / `defaultFastModel()`.
|
|
107
|
+
5. `undefined` if no provider can satisfy the slot.
|
|
108
|
+
|
|
109
|
+
Steps 1 and 3 do **not** check authentication — the user picked those
|
|
110
|
+
explicitly, so auth errors surface inline as `'error'` events at stream time
|
|
111
|
+
rather than silently swapping providers. Step 4 is a courtesy fallback for
|
|
112
|
+
hosts that don't wire any preference at all; it skips unauthenticated
|
|
113
|
+
providers. `streamCompletion` throws `NoApiKey` only when resolution returns
|
|
114
|
+
`undefined` (i.e. no provider is configured at all).
|
|
112
115
|
|
|
113
116
|
### Credential resolution
|
|
114
117
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkdropapp/ai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "AI integration common module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"author": "Takuya Matsuyama <t@inkdrop.app>",
|
|
20
20
|
"license": "UNLICENSED",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@ai-sdk/anthropic": "
|
|
23
|
-
"@ai-sdk/openai-compatible": "
|
|
22
|
+
"@ai-sdk/anthropic": "4.0.0-beta.42",
|
|
23
|
+
"@ai-sdk/openai-compatible": "3.0.0-beta.36",
|
|
24
24
|
"@inkdropapp/ai-catalog": "^0.1.0",
|
|
25
25
|
"@napi-rs/keyring": "^1.2.0",
|
|
26
|
-
"ai": "
|
|
26
|
+
"ai": "7.0.0-beta.116"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/jest": "^30.0.0",
|
package/src/provider.ts
CHANGED
|
@@ -52,7 +52,10 @@ export interface AIModel {
|
|
|
52
52
|
* OpenAI-compatible providers (OpenRouter, Together, Ollama, …) are modelled.
|
|
53
53
|
*/
|
|
54
54
|
export interface AIProvider {
|
|
55
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* Stable provider id; appears in both `AISettings.providerId` and
|
|
57
|
+
* `AISettings.slots[*].providerId`.
|
|
58
|
+
*/
|
|
56
59
|
readonly id: string
|
|
57
60
|
/** Human-readable label. */
|
|
58
61
|
readonly name: string
|
package/src/registry.ts
CHANGED
|
@@ -84,12 +84,17 @@ export class Registry {
|
|
|
84
84
|
* Order:
|
|
85
85
|
* 1. Explicit binding `settings.slots[slot]`, if both provider and model resolve.
|
|
86
86
|
* 2. For `'fast'` only: fall back to `settings.slots.default`.
|
|
87
|
-
* 3.
|
|
87
|
+
* 3. Preferred provider `settings.providerId`, if that provider is configured,
|
|
88
|
+
* taking its `defaultModel()` (or `defaultFastModel()` for the fast slot).
|
|
89
|
+
* Authentication is not gated here — the user explicitly picked this
|
|
90
|
+
* provider; auth errors surface at stream time rather than silently
|
|
91
|
+
* swapping providers.
|
|
92
|
+
* 4. First authenticated provider in alphabetical id order, taking that
|
|
88
93
|
* provider's `defaultModel()` (or `defaultFastModel()` for the fast slot).
|
|
89
94
|
* Mirrors Zed's `available_fallback_model` without the Zed-Cloud preference.
|
|
90
|
-
*
|
|
95
|
+
* 5. `undefined` if no provider can satisfy the slot.
|
|
91
96
|
*
|
|
92
|
-
* Async because the
|
|
97
|
+
* Async because the fourth step calls `provider.isAuthenticated()`, which may
|
|
93
98
|
* touch the keyring.
|
|
94
99
|
*/
|
|
95
100
|
async resolveSlot(slot: SlotName): Promise<ResolvedSlot | undefined> {
|
|
@@ -101,6 +106,17 @@ export class Registry {
|
|
|
101
106
|
if (fallback) return fallback
|
|
102
107
|
}
|
|
103
108
|
|
|
109
|
+
if (this.settings.providerId) {
|
|
110
|
+
const provider = this.providers.get(this.settings.providerId)
|
|
111
|
+
if (provider) {
|
|
112
|
+
const model =
|
|
113
|
+
slot === 'fast'
|
|
114
|
+
? provider.defaultFastModel()
|
|
115
|
+
: provider.defaultModel()
|
|
116
|
+
if (model) return { provider, model }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
104
120
|
for (const provider of this.providers.values()) {
|
|
105
121
|
if (!(await provider.isAuthenticated())) continue
|
|
106
122
|
const model =
|
package/src/settings.ts
CHANGED
|
@@ -98,8 +98,17 @@ export type AISettings = {
|
|
|
98
98
|
openaiCompatible?: OpenAICompatibleProviderConfig[]
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
101
|
+
* Preferred provider for every task slot. When set (and the per-slot
|
|
102
|
+
* `slots[slot]` override isn't), each slot resolves to this provider's
|
|
103
|
+
* `defaultModel` / `defaultFastModel`. This is the simple UI knob — bind it
|
|
104
|
+
* to a single "AI provider" dropdown.
|
|
105
|
+
*/
|
|
106
|
+
providerId?: string
|
|
107
|
+
/**
|
|
108
|
+
* Per-slot `(provider, model)` overrides. Wins over `providerId` when set.
|
|
109
|
+
* Useful for advanced configurations that pin a specific model per slot or
|
|
110
|
+
* mix providers across slots (e.g. Claude for `default`, a local model for
|
|
111
|
+
* `fast`).
|
|
103
112
|
*/
|
|
104
113
|
slots?: Partial<Record<SlotName, SlotConfig>>
|
|
105
114
|
}
|