@inkdropapp/ai 0.1.1 → 0.1.2
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 +11 -11
- package/package.json +3 -1
- package/src/index.ts +2 -2
- package/src/registry.ts +8 -8
- package/src/settings.ts +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Headless TypeScript library for multi-provider AI integration. Designed to run
|
|
|
4
4
|
in the Inkdrop Electron main process.
|
|
5
5
|
|
|
6
6
|
- **Two-interface design** — `AIProvider` (auth + model catalogue) is separate from `AIModel` (capabilities + streaming).
|
|
7
|
-
- **
|
|
7
|
+
- **AIRegistry with task-slot routing** — slot binding plus fallback to per-provider defaults, so a single AI feature gets a sensible model without any user setup.
|
|
8
8
|
- **Two providers ship out of the box**:
|
|
9
9
|
- `AnthropicProvider` (Claude 4.x) — built-in model catalogue, prompt-cache configuration.
|
|
10
10
|
- `OpenAICompatibleProvider` — instantiated per user-named entry; covers OpenRouter, Together, Fireworks, Groq, vLLM, Ollama (`/v1`), LiteLLM, etc. with a single class.
|
|
@@ -31,7 +31,7 @@ The package is **ESM-only**. Use `import`, not `require`.
|
|
|
31
31
|
## Quickstart
|
|
32
32
|
|
|
33
33
|
```ts
|
|
34
|
-
import {
|
|
34
|
+
import { AIRegistry, type AISettings } from '@inkdropapp/ai'
|
|
35
35
|
|
|
36
36
|
const settings: AISettings = {
|
|
37
37
|
providers: {
|
|
@@ -48,7 +48,7 @@ const settings: AISettings = {
|
|
|
48
48
|
providerId: 'anthropic'
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const registry = new
|
|
51
|
+
const registry = new AIRegistry({ settings })
|
|
52
52
|
|
|
53
53
|
// Configure once — keys go to the system keyring (or env var).
|
|
54
54
|
const anthropic = registry.getProvider('anthropic')!
|
|
@@ -142,7 +142,7 @@ An `AIModelCatalog` is a per-provider override of that list, designed to be
|
|
|
142
142
|
distributed by a server endpoint and swapped in at runtime:
|
|
143
143
|
|
|
144
144
|
```ts
|
|
145
|
-
import {
|
|
145
|
+
import { AIRegistry, type AIModelCatalog } from '@inkdropapp/ai'
|
|
146
146
|
|
|
147
147
|
const catalog: AIModelCatalog = {
|
|
148
148
|
anthropic: {
|
|
@@ -170,14 +170,14 @@ const catalog: AIModelCatalog = {
|
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
const registry = new
|
|
173
|
+
const registry = new AIRegistry({ settings, catalog })
|
|
174
174
|
```
|
|
175
175
|
|
|
176
176
|
Resolution order, from highest to lowest priority:
|
|
177
177
|
|
|
178
178
|
1. **User-declared `config.models`** (`settings.providers.<name>.models`) — the
|
|
179
179
|
user's local overrides always win, regardless of where the catalogue came from.
|
|
180
|
-
2. **The catalogue passed to `
|
|
180
|
+
2. **The catalogue passed to `AIRegistry`** — overrides the provider's built-in list.
|
|
181
181
|
3. **The provider's compiled-in catalogue** (`ANTHROPIC_MODELS`, …) — fallback.
|
|
182
182
|
|
|
183
183
|
`defaultModelId` / `defaultFastModelId` override the provider's hard-coded
|
|
@@ -194,7 +194,7 @@ Typical flow: app starts with no catalogue (built-in defaults apply), fetches
|
|
|
194
194
|
one from the server in the background, then swaps it in:
|
|
195
195
|
|
|
196
196
|
```ts
|
|
197
|
-
const registry = new
|
|
197
|
+
const registry = new AIRegistry({ settings })
|
|
198
198
|
|
|
199
199
|
fetch('https://config.inkdrop.app/ai-catalog.json')
|
|
200
200
|
.then(r => r.json() as Promise<AIModelCatalog>)
|
|
@@ -269,10 +269,10 @@ hosts that want to predict the name (e.g. for an onboarding hint).
|
|
|
269
269
|
|
|
270
270
|
## API reference
|
|
271
271
|
|
|
272
|
-
### `
|
|
272
|
+
### `AIRegistry`
|
|
273
273
|
|
|
274
274
|
```ts
|
|
275
|
-
new
|
|
275
|
+
new AIRegistry({
|
|
276
276
|
settings: AISettings,
|
|
277
277
|
catalog?: AIModelCatalog, // server-distributed model lists; see "Model catalogues"
|
|
278
278
|
keyStore?: KeyStore
|
|
@@ -302,8 +302,8 @@ store.deleteKey(baseURL: string): Promise<void> // no-op if absent
|
|
|
302
302
|
store.invalidate(baseURL?: string): void // omit url to clear all
|
|
303
303
|
```
|
|
304
304
|
|
|
305
|
-
You generally don't construct a `KeyStore` yourself — `
|
|
306
|
-
Pass an existing instance via `
|
|
305
|
+
You generally don't construct a `KeyStore` yourself — `AIRegistry` creates one.
|
|
306
|
+
Pass an existing instance via `AIRegistryOptions.keyStore` if you want to share
|
|
307
307
|
its cache across registries.
|
|
308
308
|
|
|
309
309
|
### `AIProvider`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkdropapp/ai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "AI integration common module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -18,9 +18,11 @@
|
|
|
18
18
|
],
|
|
19
19
|
"author": "Takuya Matsuyama <t@inkdrop.app>",
|
|
20
20
|
"license": "UNLICENSED",
|
|
21
|
+
"packageManager": "pnpm@11.1.1",
|
|
21
22
|
"dependencies": {
|
|
22
23
|
"@ai-sdk/anthropic": "4.0.0-beta.42",
|
|
23
24
|
"@ai-sdk/openai-compatible": "3.0.0-beta.36",
|
|
25
|
+
"@ai-sdk/provider": "4.0.0-beta.14",
|
|
24
26
|
"@inkdropapp/ai-catalog": "^0.1.0",
|
|
25
27
|
"@napi-rs/keyring": "^1.2.0",
|
|
26
28
|
"ai": "7.0.0-beta.116"
|
package/src/index.ts
CHANGED
package/src/registry.ts
CHANGED
|
@@ -13,13 +13,13 @@ export type ResolvedSlot = {
|
|
|
13
13
|
model: AIModel
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export type
|
|
16
|
+
export type AIRegistryOptions = {
|
|
17
17
|
settings: AISettings
|
|
18
18
|
/**
|
|
19
19
|
* Optional server-distributed catalogue of supported models per provider.
|
|
20
20
|
* When omitted, each provider uses its compiled-in defaults (e.g. `ANTHROPIC_MODELS`).
|
|
21
21
|
* The host typically fetches this from an API and either passes it at
|
|
22
|
-
* construction time or swaps it in later via {@link
|
|
22
|
+
* construction time or swaps it in later via {@link AIRegistry.updateCatalog}.
|
|
23
23
|
*/
|
|
24
24
|
catalog?: AIModelCatalog
|
|
25
25
|
/** Pass an existing `KeyStore` to share its in-memory cache across registries. */
|
|
@@ -32,26 +32,26 @@ export type RegistryOptions = {
|
|
|
32
32
|
* Owns one instance of every configured provider, resolves task slots with
|
|
33
33
|
* fallback, and is the only place feature code calls to start a completion.
|
|
34
34
|
*
|
|
35
|
-
* The `
|
|
36
|
-
* settings on its own. Call {@link
|
|
35
|
+
* The `AIRegistry` is stateless beyond its provider list — it doesn't observe
|
|
36
|
+
* settings on its own. Call {@link AIRegistry.updateSettings} when settings
|
|
37
37
|
* change to rebuild providers.
|
|
38
38
|
*
|
|
39
39
|
* @example
|
|
40
40
|
* ```ts
|
|
41
|
-
* const registry = new
|
|
41
|
+
* const registry = new AIRegistry({ settings })
|
|
42
42
|
* const events = await registry.streamCompletion('default', { messages })
|
|
43
43
|
* for await (const event of events) {
|
|
44
44
|
* if (event.kind === 'text-delta') process.stdout.write(event.delta)
|
|
45
45
|
* }
|
|
46
46
|
* ```
|
|
47
47
|
*/
|
|
48
|
-
export class
|
|
48
|
+
export class AIRegistry {
|
|
49
49
|
readonly keyStore: KeyStore
|
|
50
50
|
private providers: Map<string, AIProvider> = new Map()
|
|
51
51
|
private settings: AISettings
|
|
52
52
|
private catalog: AIModelCatalog | undefined
|
|
53
53
|
|
|
54
|
-
constructor(options:
|
|
54
|
+
constructor(options: AIRegistryOptions) {
|
|
55
55
|
this.keyStore = options.keyStore ?? new KeyStore()
|
|
56
56
|
this.settings = options.settings
|
|
57
57
|
this.catalog = options.catalog
|
|
@@ -140,7 +140,7 @@ export class Registry {
|
|
|
140
140
|
/**
|
|
141
141
|
* Streams a completion for a task slot.
|
|
142
142
|
*
|
|
143
|
-
* Resolves the slot via {@link
|
|
143
|
+
* Resolves the slot via {@link AIRegistry.resolveSlot}; throws {@link NoApiKey}
|
|
144
144
|
* if no provider can satisfy it (no slot binding, and no authenticated
|
|
145
145
|
* provider available for the implicit fallback). Otherwise returns the
|
|
146
146
|
* model's stream — note that *upstream* errors (auth, rate limit, etc.)
|
package/src/settings.ts
CHANGED
|
@@ -88,7 +88,7 @@ export type AnthropicProviderConfig = CommonProviderConfig & {
|
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Top-level AI configuration. The host (Inkdrop main process) constructs this
|
|
91
|
-
* from whichever persistence layer it uses and passes it to `
|
|
91
|
+
* from whichever persistence layer it uses and passes it to `AIRegistry`.
|
|
92
92
|
*
|
|
93
93
|
* The library never reads or writes settings to disk itself.
|
|
94
94
|
*/
|