provider-kit 0.1.0 → 1.0.0

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 CHANGED
@@ -1,126 +1,144 @@
1
- # @openchat/provider-kit
2
-
3
- **One API for 42 LLM providers.** OpenAI, Anthropic, Ollama, OpenRouter, Google Gemini, Azure, AWS Bedrock, Cohere same interface, built-in retry and timeout.
4
-
5
- ```js
6
- import { createProvider } from '@openchat/provider-kit'
7
-
8
- const provider = await createProvider('openai', { apiKey: 'sk-...' })
9
- const reply = await provider.chat('gpt-4', [
10
- { role: 'user', content: 'Hello' }
11
- ])
12
- // { content: '...', model: 'gpt-4', usage: { prompt_tokens: 10, completion_tokens: 20 } }
13
- ```
14
-
15
- ## Install
16
-
17
- ```bash
18
- npm install @openchat/provider-kit
19
- ```
20
-
21
- ## Usage
22
-
23
- ### Basic chat
24
-
25
- ```js
26
- import { createProvider } from '@openchat/provider-kit'
27
-
28
- const provider = await createProvider('openai', { apiKey: process.env.OPENAI_API_KEY })
29
- const reply = await provider.chat('gpt-4o-mini', [
30
- { role: 'system', content: 'You are a poet' },
31
- { role: 'user', content: 'Write a haiku' },
32
- ])
33
- console.log(reply.content)
34
- ```
35
-
36
- ### With retry and timeout
37
-
38
- ```js
39
- import { safeProviderCall } from '@openchat/provider-kit'
40
-
41
- const reply = await safeProviderCall(
42
- () => provider.chat('gpt-4', messages),
43
- { provider: 'openai', retries: 3, timeout: 30000 }
44
- )
45
- ```
46
-
47
- ### Available providers
48
-
49
- | Provider | `type` | Requires |
50
- |----------|--------|----------|
51
- | OpenAI | `openai` | `OPENAI_API_KEY` |
52
- | Anthropic | `anthropic` | `ANTHROPIC_API_KEY` |
53
- | Ollama | `ollama` | local server at `http://localhost:11434` |
54
- | Azure OpenAI | `azure` | Azure credentials |
55
- | AWS Bedrock | `bedrock` | AWS credentials |
56
- | Cohere | `cohere` | `COHERE_API_KEY` |
57
- | Google Gemini | `gemini` | `GEMINI_API_KEY` |
58
- | OpenAI-compatible | `openai` with custom `baseUrl` | Any OpenAI-compatible API |
59
-
60
- ### Streaming
61
-
62
- ```js
63
- const stream = await provider.chatStream('gpt-4', messages)
64
- for await (const chunk of stream) {
65
- if (chunk.type === 'content') process.stdout.write(chunk.content)
66
- }
67
- ```
68
-
69
- ### Error handling
70
-
71
- `createProvider`, `.chat()`, `.chatStream()` all throw `ProviderError` with consistent fields:
72
-
73
- ```js
74
- import { ProviderError } from '@openchat/provider-kit'
75
-
76
- try { /* ... */ } catch (e) {
77
- if (e instanceof ProviderError) {
78
- console.log(e.provider, e.statusCode, e.retryable, e.type)
79
- // e.g. 'openai', 429, true, 'rate_limit'
80
- }
81
- }
82
- ```
83
-
84
- ### Function Calling
85
-
86
- ```js
87
- const reply = await provider.chat('gpt-4', messages, {
88
- tools: [{
89
- type: 'function',
90
- function: {
91
- name: 'get_weather',
92
- description: 'Get weather for a city',
93
- parameters: { type: 'object', properties: { city: { type: 'string' } } }
94
- }
95
- }]
96
- })
97
- if (reply.toolCalls) {
98
- // [{ id, name, arguments: { city: 'Tokyo' } }]
99
- }
100
- ```
101
-
102
- ## ProviderRegistry
103
-
104
- Manage multiple providers with a registry:
105
-
106
- ```js
107
- import { providerRegistry, createProvider } from '@openchat/provider-kit'
108
-
109
- await providerRegistry.configure('openai', { apiKey: 'sk-...' })
110
- await providerRegistry.configure('ollama', { baseUrl: 'http://localhost:11434' })
111
-
112
- const provider = providerRegistry.get('openai')
113
- const reply = await provider.chat('gpt-4', messages)
114
- ```
115
-
116
- ## Known Limitations (v0.1.0)
117
-
118
- - **No config persistence by default.** API keys must be passed on every `createProvider()` call. Use `createStore()` for persistent config.
119
- - **10 adapters implemented out of 42 presets.** The remaining 32 use OpenAI-compatible fallback. Contributions welcome.
120
- - **No TypeScript types.** Planned for v0.2.0.
121
- - **Not for production.** API keys are stored in memory. No OS keychain integration.
122
- - **`.provider-kit.json` should be added to `.gitignore`** if you choose to use file persistence via `createStore()`.
123
-
124
- ## Related
125
-
126
- - `@openchat/fairy-guardian` — self-healing process cluster for AI model servers
1
+ # provider-kit
2
+
3
+ **One API for 42 LLM providers.** OpenAI, Anthropic, Ollama, OpenRouter, Google Gemini, Azure, AWS Bedrock, Cohere �?same interface, built-in retry and timeout.
4
+
5
+ ```bash
6
+ npm install provider-kit
7
+ ```
8
+
9
+ ## Quickstart �?first response in under 60 seconds
10
+
11
+ ```js
12
+ import { createProvider } from 'provider-kit'
13
+
14
+ const client = await createProvider('openai', { apiKey: process.env.OPENAI_API_KEY })
15
+
16
+ const stream = client.chatStream('gpt-4o-mini', [
17
+ { role: 'user', content: 'Say hello in one sentence' },
18
+ ])
19
+
20
+ for await (const chunk of stream) {
21
+ if (chunk.type === 'content') process.stdout.write(chunk.content)
22
+ }
23
+ ```
24
+
25
+ Run it:
26
+
27
+ ```bash
28
+ export OPENAI_API_KEY=sk-...
29
+ node quickstart.mjs
30
+ # �?Hello! I'm an AI assistant ready to help you.
31
+ ```
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ npm install provider-kit
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ## Usage
42
+
43
+ ### Basic chat
44
+
45
+ ```js
46
+ import { createProvider } from 'provider-kit'
47
+
48
+ const provider = await createProvider('openai', { apiKey: process.env.OPENAI_API_KEY })
49
+ const reply = await provider.chat('gpt-4o-mini', [
50
+ { role: 'system', content: 'You are a poet' },
51
+ { role: 'user', content: 'Write a haiku' },
52
+ ])
53
+ console.log(reply.content)
54
+ ```
55
+
56
+ ### With retry and timeout
57
+
58
+ ```js
59
+ import { safeProviderCall } from 'provider-kit'
60
+
61
+ const reply = await safeProviderCall(
62
+ () => provider.chat('gpt-4', messages),
63
+ { provider: 'openai', retries: 3, timeout: 30000 }
64
+ )
65
+ ```
66
+
67
+ ### Available providers
68
+
69
+ | Provider | `type` | Requires |
70
+ |----------|--------|----------|
71
+ | OpenAI | `openai` | `OPENAI_API_KEY` |
72
+ | Anthropic | `anthropic` | `ANTHROPIC_API_KEY` |
73
+ | Ollama | `ollama` | local server at `http://localhost:11434` |
74
+ | Azure OpenAI | `azure` | Azure credentials |
75
+ | AWS Bedrock | `bedrock` | AWS credentials |
76
+ | Cohere | `cohere` | `COHERE_API_KEY` |
77
+ | Google Gemini | `gemini` | `GEMINI_API_KEY` |
78
+ | OpenAI-compatible | `openai` with custom `baseUrl` | Any OpenAI-compatible API |
79
+
80
+ ### Streaming
81
+
82
+ ```js
83
+ const stream = await provider.chatStream('gpt-4', messages)
84
+ for await (const chunk of stream) {
85
+ if (chunk.type === 'content') process.stdout.write(chunk.content)
86
+ }
87
+ ```
88
+
89
+ ### Error handling
90
+
91
+ `createProvider`, `.chat()`, `.chatStream()` �?all throw `ProviderError` with consistent fields:
92
+
93
+ ```js
94
+ import { ProviderError } from 'provider-kit'
95
+
96
+ try { /* ... */ } catch (e) {
97
+ if (e instanceof ProviderError) {
98
+ console.log(e.provider, e.statusCode, e.retryable, e.type)
99
+ // e.g. 'openai', 429, true, 'rate_limit'
100
+ }
101
+ }
102
+ ```
103
+
104
+ ### Function Calling
105
+
106
+ ```js
107
+ const reply = await provider.chat('gpt-4', messages, {
108
+ tools: [{
109
+ type: 'function',
110
+ function: {
111
+ name: 'get_weather',
112
+ description: 'Get weather for a city',
113
+ parameters: { type: 'object', properties: { city: { type: 'string' } } }
114
+ }
115
+ }]
116
+ })
117
+ if (reply.toolCalls) {
118
+ // [{ id, name, arguments: { city: 'Tokyo' } }]
119
+ }
120
+ ```
121
+
122
+ ## ProviderRegistry
123
+
124
+ Manage multiple providers with a registry:
125
+
126
+ ```js
127
+ import { providerRegistry, createProvider } from 'provider-kit'
128
+
129
+ await providerRegistry.configure('openai', { apiKey: 'sk-...' })
130
+ await providerRegistry.configure('ollama', { baseUrl: 'http://localhost:11434' })
131
+
132
+ const provider = providerRegistry.get('openai')
133
+ const reply = await provider.chat('gpt-4', messages)
134
+ ```
135
+
136
+ ## Known Limitations (v0.1.0)
137
+
138
+ - **10 adapters implemented out of 42 presets.** The remaining 32 use OpenAI-compatible fallback. Contributions welcome.
139
+ - **No TypeScript types.** Planned for v0.2.0.
140
+ - **Not for production.** API keys are stored in memory. No OS keychain integration.
141
+
142
+ ## Related
143
+
144
+ - `fairy-guardian` �?self-healing process cluster for AI model servers
package/package.json CHANGED
@@ -1,19 +1,36 @@
1
1
  {
2
2
  "name": "provider-kit",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "42 LLM provider unified API — one interface for OpenAI, Anthropic, Ollama, OpenRouter, and 38 more. Built-in retry, timeout, and error handling.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
- "exports": { ".": "./src/index.js" },
8
- "files": ["src/", "README.md"],
7
+ "exports": {
8
+ ".": "./src/index.js"
9
+ },
10
+ "files": [
11
+ "src/",
12
+ "README.md"
13
+ ],
9
14
  "scripts": {
10
15
  "test": "node --test test/*.test.js",
11
16
  "prepublishOnly": "npm test",
12
17
  "version": "git add -A src/ CHANGELOG.md",
13
18
  "postversion": "git push && git push --tags"
14
19
  },
15
- "keywords": ["llm", "openai", "anthropic", "ollama", "provider", "api"],
20
+ "keywords": [
21
+ "llm",
22
+ "openai",
23
+ "anthropic",
24
+ "ollama",
25
+ "provider",
26
+ "api"
27
+ ],
16
28
  "license": "MIT",
17
- "engines": { "node": ">=18" },
18
- "repository": { "type": "git", "url": "https://github.com/openchat-ai/openchat" }
29
+ "engines": {
30
+ "node": ">=18"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/openchat-ai/openchat"
35
+ }
19
36
  }
@@ -47,7 +47,10 @@ export async function withRetry(fn, { retries = 2, baseDelay = 1000, provider }
47
47
  if (i === retries) throw e;
48
48
  const isRetryable = e instanceof ProviderError ? e.retryable : true;
49
49
  if (!isRetryable) throw e;
50
- await new Promise(r => setTimeout(r, baseDelay * Math.pow(2, i)));
50
+ // Exponential backoff with jitter (±25%) to prevent thundering herd
51
+ const delay = baseDelay * Math.pow(2, i);
52
+ const jitter = delay * (0.75 + Math.random() * 0.5);
53
+ await new Promise(r => setTimeout(r, jitter));
51
54
  }
52
55
  }
53
56
  }