@providerprotocol/ai 0.0.39 → 0.0.40
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 +269 -34
- package/dist/anthropic/index.d.ts +3 -3
- package/dist/anthropic/index.js +7 -5
- package/dist/anthropic/index.js.map +1 -1
- package/dist/cerebras/index.d.ts +3 -3
- package/dist/cerebras/index.js +7 -5
- package/dist/cerebras/index.js.map +1 -1
- package/dist/{chunk-WU4U6IHF.js → chunk-6QCV4WXF.js} +4 -13
- package/dist/chunk-6QCV4WXF.js.map +1 -0
- package/dist/{chunk-5XPRVUOK.js → chunk-AC3VHSZJ.js} +2 -2
- package/dist/{chunk-5XPRVUOK.js.map → chunk-AC3VHSZJ.js.map} +1 -1
- package/dist/{chunk-ZDYEDI2A.js → chunk-CWGTARDE.js} +2 -2
- package/dist/{chunk-KNBODIQU.js → chunk-DI47UY2H.js} +2 -2
- package/dist/{chunk-KNBODIQU.js.map → chunk-DI47UY2H.js.map} +1 -1
- package/dist/{chunk-IDZR4ROP.js → chunk-EHR3LIPS.js} +2 -2
- package/dist/{chunk-IDZR4ROP.js.map → chunk-EHR3LIPS.js.map} +1 -1
- package/dist/chunk-EY2LLDGY.js +94 -0
- package/dist/chunk-EY2LLDGY.js.map +1 -0
- package/dist/{chunk-MJI74VEJ.js → chunk-F5ENANMJ.js} +18 -2
- package/dist/chunk-F5ENANMJ.js.map +1 -0
- package/dist/chunk-IKJH5ZSJ.js +1 -0
- package/dist/chunk-IKJH5ZSJ.js.map +1 -0
- package/dist/{chunk-IIMTP3XC.js → chunk-KBI45OXI.js} +2 -2
- package/dist/{chunk-SAMIK4WZ.js → chunk-KVUOTFYZ.js} +2 -2
- package/dist/{chunk-U6M3MXNI.js → chunk-L6QWKFGE.js} +3 -2
- package/dist/chunk-L6QWKFGE.js.map +1 -0
- package/dist/{chunk-RDC5GYST.js → chunk-N4LAFGLX.js} +7 -7
- package/dist/{chunk-ZKNPQBIE.js → chunk-R3T2IYOU.js} +5 -3
- package/dist/{chunk-ZKNPQBIE.js.map → chunk-R3T2IYOU.js.map} +1 -1
- package/dist/chunk-U2G5PHHL.js +25 -0
- package/dist/chunk-U2G5PHHL.js.map +1 -0
- package/dist/{chunk-SBGZJVTJ.js → chunk-VQZPADW6.js} +100 -33
- package/dist/chunk-VQZPADW6.js.map +1 -0
- package/dist/{chunk-O32SBS6S.js → chunk-XTWBAL42.js} +2 -2
- package/dist/{chunk-O32SBS6S.js.map → chunk-XTWBAL42.js.map} +1 -1
- package/dist/{chunk-WNB5PSY6.js → chunk-ZMESKGUY.js} +2 -2
- package/dist/{chunk-7ULSRWDH.js → chunk-ZSZVWLGE.js} +2 -2
- package/dist/{embedding-iNQCeXfk.d.ts → embedding-ts1npsDg.d.ts} +1 -1
- package/dist/google/index.d.ts +38 -4
- package/dist/google/index.js +5 -4
- package/dist/google/index.js.map +1 -1
- package/dist/groq/index.d.ts +3 -3
- package/dist/groq/index.js +7 -5
- package/dist/groq/index.js.map +1 -1
- package/dist/http/index.d.ts +5 -5
- package/dist/http/index.js +19 -22
- package/dist/{image-stream-ARno6XlS.d.ts → image-stream-BPml2YZZ.d.ts} +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.js +306 -112
- package/dist/index.js.map +1 -1
- package/dist/{llm-CZqlijjK.d.ts → llm-BWLaTzzY.d.ts} +75 -29
- package/dist/middleware/logging/index.d.ts +3 -3
- package/dist/middleware/logging/index.js +3 -0
- package/dist/middleware/logging/index.js.map +1 -1
- package/dist/middleware/parsed-object/index.d.ts +3 -3
- package/dist/middleware/parsed-object/index.js +5 -1
- package/dist/middleware/parsed-object/index.js.map +1 -1
- package/dist/middleware/persistence/index.d.ts +3 -3
- package/dist/middleware/persistence/index.js +3 -2
- package/dist/middleware/persistence/index.js.map +1 -1
- package/dist/middleware/pipeline/index.d.ts +195 -0
- package/dist/middleware/pipeline/index.js +61 -0
- package/dist/middleware/pipeline/index.js.map +1 -0
- package/dist/middleware/pubsub/index.d.ts +13 -11
- package/dist/middleware/pubsub/index.js +31 -5
- package/dist/middleware/pubsub/index.js.map +1 -1
- package/dist/middleware/pubsub/server/express/index.d.ts +3 -3
- package/dist/middleware/pubsub/server/express/index.js +2 -2
- package/dist/middleware/pubsub/server/fastify/index.d.ts +3 -3
- package/dist/middleware/pubsub/server/fastify/index.js +2 -2
- package/dist/middleware/pubsub/server/h3/index.d.ts +3 -3
- package/dist/middleware/pubsub/server/h3/index.js +2 -2
- package/dist/middleware/pubsub/server/index.d.ts +50 -9
- package/dist/middleware/pubsub/server/index.js +5 -5
- package/dist/middleware/pubsub/server/index.js.map +1 -1
- package/dist/middleware/pubsub/server/webapi/index.d.ts +3 -3
- package/dist/middleware/pubsub/server/webapi/index.js +2 -2
- package/dist/moonshot/index.d.ts +3 -3
- package/dist/moonshot/index.js +7 -5
- package/dist/moonshot/index.js.map +1 -1
- package/dist/ollama/index.d.ts +24 -4
- package/dist/ollama/index.js +5 -4
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +65 -4
- package/dist/openai/index.js +7 -5
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +4 -4
- package/dist/openrouter/index.js +7 -5
- package/dist/openrouter/index.js.map +1 -1
- package/dist/proxy/index.d.ts +5 -5
- package/dist/proxy/index.js +16 -15
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/server/express/index.d.ts +8 -9
- package/dist/proxy/server/express/index.js +4 -3
- package/dist/proxy/server/fastify/index.d.ts +8 -9
- package/dist/proxy/server/fastify/index.js +4 -3
- package/dist/proxy/server/h3/index.d.ts +8 -9
- package/dist/proxy/server/h3/index.js +4 -3
- package/dist/proxy/server/index.d.ts +5 -5
- package/dist/proxy/server/index.js +14 -13
- package/dist/proxy/server/webapi/index.d.ts +8 -9
- package/dist/proxy/server/webapi/index.js +4 -3
- package/dist/responses/index.d.ts +3 -3
- package/dist/responses/index.js +7 -5
- package/dist/responses/index.js.map +1 -1
- package/dist/retry-DVfdPLIB.d.ts +322 -0
- package/dist/{stream-DVVUIKpz.d.ts → stream-bBd_4Ipu.d.ts} +27 -4
- package/dist/{tool-D22EhP5F.d.ts → tool-BmAfKNBq.d.ts} +1 -1
- package/dist/{types-CyXF0J7C.d.ts → types-nTwlpyJE.d.ts} +13 -1
- package/dist/utils/index.d.ts +66 -2
- package/dist/utils/index.js +13 -0
- package/dist/xai/index.d.ts +3 -3
- package/dist/xai/index.js +7 -5
- package/dist/xai/index.js.map +1 -1
- package/package.json +6 -1
- package/dist/chunk-ARVM24K2.js +0 -128
- package/dist/chunk-ARVM24K2.js.map +0 -1
- package/dist/chunk-MJI74VEJ.js.map +0 -1
- package/dist/chunk-SBGZJVTJ.js.map +0 -1
- package/dist/chunk-U6M3MXNI.js.map +0 -1
- package/dist/chunk-WU4U6IHF.js.map +0 -1
- package/dist/chunk-Y5H7C5J4.js +0 -263
- package/dist/chunk-Y5H7C5J4.js.map +0 -1
- package/dist/retry-C1eJbEMV.d.ts +0 -531
- /package/dist/{chunk-ZDYEDI2A.js.map → chunk-CWGTARDE.js.map} +0 -0
- /package/dist/{chunk-IIMTP3XC.js.map → chunk-KBI45OXI.js.map} +0 -0
- /package/dist/{chunk-SAMIK4WZ.js.map → chunk-KVUOTFYZ.js.map} +0 -0
- /package/dist/{chunk-RDC5GYST.js.map → chunk-N4LAFGLX.js.map} +0 -0
- /package/dist/{chunk-WNB5PSY6.js.map → chunk-ZMESKGUY.js.map} +0 -0
- /package/dist/{chunk-7ULSRWDH.js.map → chunk-ZSZVWLGE.js.map} +0 -0
package/README.md
CHANGED
|
@@ -29,9 +29,10 @@ console.log(turn.response.text);
|
|
|
29
29
|
| OpenRouter | `@providerprotocol/ai/openrouter` | ✓ | ✓ | ✓ |
|
|
30
30
|
| Groq | `@providerprotocol/ai/groq` | ✓ | | |
|
|
31
31
|
| Cerebras | `@providerprotocol/ai/cerebras` | ✓ | | |
|
|
32
|
+
| Moonshot | `@providerprotocol/ai/moonshot` | ✓ | | |
|
|
32
33
|
| OpenResponses | `@providerprotocol/ai/responses` | ✓ | | |
|
|
33
34
|
|
|
34
|
-
API keys are loaded automatically from environment variables (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GROQ_API_KEY`, `CEREBRAS_API_KEY`, etc.).
|
|
35
|
+
API keys are loaded automatically from environment variables (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GROQ_API_KEY`, `CEREBRAS_API_KEY`, `MOONSHOT_API_KEY`, etc.).
|
|
35
36
|
|
|
36
37
|
## LLM
|
|
37
38
|
|
|
@@ -229,6 +230,9 @@ const videoTurn = await gemini.generate([video.toBlock(), 'Describe this video']
|
|
|
229
230
|
| OpenRouter | ✓ | PDF, Text | ✓ | ✓ |
|
|
230
231
|
| xAI | ✓ | | | |
|
|
231
232
|
| Groq | ✓ | | | |
|
|
233
|
+
| Moonshot | ✓ | | | ✓* |
|
|
234
|
+
|
|
235
|
+
\* Moonshot video input is experimental.
|
|
232
236
|
|
|
233
237
|
## Anthropic Beta Features
|
|
234
238
|
|
|
@@ -502,16 +506,15 @@ const result = await editor.edit({
|
|
|
502
506
|
## Configuration
|
|
503
507
|
|
|
504
508
|
```typescript
|
|
505
|
-
import { llm } from '@providerprotocol/ai';
|
|
509
|
+
import { llm, exponentialBackoff, roundRobinKeys } from '@providerprotocol/ai';
|
|
506
510
|
import { openai } from '@providerprotocol/ai/openai';
|
|
507
|
-
import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';
|
|
508
511
|
|
|
509
512
|
const instance = llm({
|
|
510
513
|
model: openai('gpt-4o'),
|
|
511
514
|
config: {
|
|
512
|
-
apiKey:
|
|
515
|
+
apiKey: roundRobinKeys(['sk-key1', 'sk-key2']),
|
|
513
516
|
timeout: 30000,
|
|
514
|
-
retryStrategy:
|
|
517
|
+
retryStrategy: exponentialBackoff({ maxAttempts: 3 }),
|
|
515
518
|
},
|
|
516
519
|
params: {
|
|
517
520
|
temperature: 0.7,
|
|
@@ -569,34 +572,33 @@ interface ProviderConfig {
|
|
|
569
572
|
### Key Strategies
|
|
570
573
|
|
|
571
574
|
```typescript
|
|
572
|
-
import {
|
|
575
|
+
import { roundRobinKeys, weightedKeys, dynamicKey } from '@providerprotocol/ai/http';
|
|
573
576
|
|
|
574
577
|
// Cycle through keys evenly
|
|
575
|
-
|
|
578
|
+
roundRobinKeys(['sk-1', 'sk-2', 'sk-3'])
|
|
576
579
|
|
|
577
580
|
// Weighted selection (70% key1, 30% key2)
|
|
578
|
-
|
|
581
|
+
weightedKeys([
|
|
579
582
|
{ key: 'sk-1', weight: 70 },
|
|
580
583
|
{ key: 'sk-2', weight: 30 },
|
|
581
584
|
])
|
|
582
585
|
|
|
583
586
|
// Dynamic fetching (secrets manager, etc.)
|
|
584
|
-
|
|
587
|
+
dynamicKey(async () => fetchKeyFromVault())
|
|
585
588
|
```
|
|
586
589
|
|
|
587
590
|
### Retry Strategies
|
|
588
591
|
|
|
589
592
|
```typescript
|
|
590
593
|
import {
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
} from '@providerprotocol/ai/http';
|
|
594
|
+
exponentialBackoff,
|
|
595
|
+
linearBackoff,
|
|
596
|
+
noRetry,
|
|
597
|
+
retryAfterStrategy,
|
|
598
|
+
} from '@providerprotocol/ai';
|
|
597
599
|
|
|
598
600
|
// Exponential: 1s, 2s, 4s...
|
|
599
|
-
|
|
601
|
+
exponentialBackoff({
|
|
600
602
|
maxAttempts: 5,
|
|
601
603
|
baseDelay: 1000,
|
|
602
604
|
maxDelay: 30000,
|
|
@@ -604,20 +606,19 @@ new ExponentialBackoff({
|
|
|
604
606
|
})
|
|
605
607
|
|
|
606
608
|
// Linear: 1s, 2s, 3s...
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
// Rate limiting with token bucket
|
|
610
|
-
new TokenBucket({ maxTokens: 10, refillRate: 1 })
|
|
609
|
+
linearBackoff({ maxAttempts: 3, delay: 1000 })
|
|
611
610
|
|
|
612
611
|
// Respect server Retry-After headers
|
|
613
|
-
|
|
612
|
+
retryAfterStrategy({ maxAttempts: 3, fallbackDelay: 5000 })
|
|
614
613
|
|
|
615
614
|
// No retries
|
|
616
|
-
|
|
615
|
+
noRetry()
|
|
617
616
|
```
|
|
618
617
|
|
|
619
618
|
**Retryable Errors:** `RATE_LIMITED`, `NETWORK_ERROR`, `TIMEOUT`, `PROVIDER_ERROR`
|
|
620
619
|
|
|
620
|
+
**Streaming Retry:** Retry strategies work with both `.generate()` and `.stream()`. During streaming, `stream_retry` events are emitted to notify consumers of retry attempts, and middleware can use the `onRetry` hook to reset accumulated state.
|
|
621
|
+
|
|
621
622
|
## Tool Execution Control
|
|
622
623
|
|
|
623
624
|
```typescript
|
|
@@ -786,22 +787,55 @@ Bun.serve({
|
|
|
786
787
|
```typescript
|
|
787
788
|
// Express
|
|
788
789
|
import { express } from '@providerprotocol/ai/middleware/pubsub/server';
|
|
789
|
-
|
|
790
|
-
|
|
790
|
+
|
|
791
|
+
app.post('/api/ai', async (req, res) => {
|
|
792
|
+
const { messages, streamId } = req.body;
|
|
793
|
+
|
|
794
|
+
// Guard: prevent duplicate generations on reconnect
|
|
795
|
+
if (!await adapter.exists(streamId)) {
|
|
796
|
+
const model = llm({
|
|
797
|
+
model: anthropic('claude-sonnet-4-20250514'),
|
|
798
|
+
middleware: [pubsubMiddleware({ adapter, streamId })],
|
|
799
|
+
});
|
|
800
|
+
model.stream(messages).then(turn => { /* save to DB */ });
|
|
801
|
+
}
|
|
802
|
+
|
|
791
803
|
express.streamSubscriber(streamId, adapter, res);
|
|
792
804
|
});
|
|
793
805
|
|
|
794
806
|
// Fastify
|
|
795
807
|
import { fastify } from '@providerprotocol/ai/middleware/pubsub/server';
|
|
796
|
-
|
|
797
|
-
|
|
808
|
+
|
|
809
|
+
app.post('/api/ai', async (request, reply) => {
|
|
810
|
+
const { messages, streamId } = request.body;
|
|
811
|
+
|
|
812
|
+
// Guard: prevent duplicate generations on reconnect
|
|
813
|
+
if (!await adapter.exists(streamId)) {
|
|
814
|
+
const model = llm({
|
|
815
|
+
model: anthropic('claude-sonnet-4-20250514'),
|
|
816
|
+
middleware: [pubsubMiddleware({ adapter, streamId })],
|
|
817
|
+
});
|
|
818
|
+
model.stream(messages).then(turn => { /* save to DB */ });
|
|
819
|
+
}
|
|
820
|
+
|
|
798
821
|
return fastify.streamSubscriber(streamId, adapter, reply);
|
|
799
822
|
});
|
|
800
823
|
|
|
801
824
|
// H3/Nuxt
|
|
802
825
|
import { h3 } from '@providerprotocol/ai/middleware/pubsub/server';
|
|
826
|
+
|
|
803
827
|
export default defineEventHandler(async (event) => {
|
|
804
|
-
const { streamId } = await readBody(event);
|
|
828
|
+
const { messages, streamId } = await readBody(event);
|
|
829
|
+
|
|
830
|
+
// Guard: prevent duplicate generations on reconnect
|
|
831
|
+
if (!await adapter.exists(streamId)) {
|
|
832
|
+
const model = llm({
|
|
833
|
+
model: anthropic('claude-sonnet-4-20250514'),
|
|
834
|
+
middleware: [pubsubMiddleware({ adapter, streamId })],
|
|
835
|
+
});
|
|
836
|
+
model.stream(messages).then(turn => { /* save to DB */ });
|
|
837
|
+
}
|
|
838
|
+
|
|
805
839
|
return h3.streamSubscriber(streamId, adapter, event);
|
|
806
840
|
});
|
|
807
841
|
```
|
|
@@ -842,6 +876,89 @@ const model = llm({
|
|
|
842
876
|
});
|
|
843
877
|
```
|
|
844
878
|
|
|
879
|
+
### Pipeline Middleware (Post-Turn Processing)
|
|
880
|
+
|
|
881
|
+
Run async tasks (image generation, embeddings, slug creation, etc.) after the LLM completes, with progress events streamed to connected clients:
|
|
882
|
+
|
|
883
|
+
```typescript
|
|
884
|
+
import { llm } from '@providerprotocol/ai';
|
|
885
|
+
import { anthropic } from '@providerprotocol/ai/anthropic';
|
|
886
|
+
import { pubsubMiddleware, memoryAdapter } from '@providerprotocol/ai/middleware/pubsub';
|
|
887
|
+
import { pipelineMiddleware, isPipelineStageEvent } from '@providerprotocol/ai/middleware/pipeline';
|
|
888
|
+
|
|
889
|
+
const adapter = memoryAdapter();
|
|
890
|
+
|
|
891
|
+
const model = llm({
|
|
892
|
+
model: anthropic('claude-sonnet-4-20250514'),
|
|
893
|
+
structure: BlogPostSchema,
|
|
894
|
+
middleware: [
|
|
895
|
+
pubsubMiddleware({ adapter, streamId: postId }),
|
|
896
|
+
pipelineMiddleware<BlogPost>({
|
|
897
|
+
stages: [
|
|
898
|
+
{
|
|
899
|
+
type: 'slug',
|
|
900
|
+
run: (turn, emit) => {
|
|
901
|
+
const slug = turn.data!.title.toLowerCase().replace(/\s+/g, '-');
|
|
902
|
+
(turn as { slug?: string }).slug = slug;
|
|
903
|
+
emit({ slug });
|
|
904
|
+
},
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
type: 'embedding',
|
|
908
|
+
run: async (turn, emit) => {
|
|
909
|
+
await vectorize(turn.data!);
|
|
910
|
+
emit({ embedded: true });
|
|
911
|
+
},
|
|
912
|
+
},
|
|
913
|
+
],
|
|
914
|
+
parallel: false, // Run stages sequentially (default)
|
|
915
|
+
continueOnError: false, // Stop on first error (default)
|
|
916
|
+
onStageError: ({ stage, error }) => {
|
|
917
|
+
console.error(`Stage ${stage.type} failed:`, error);
|
|
918
|
+
},
|
|
919
|
+
}),
|
|
920
|
+
],
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
// Stages run after streaming completes
|
|
924
|
+
model.stream(prompt).then(turn => {
|
|
925
|
+
const extended = turn as typeof turn & { slug?: string };
|
|
926
|
+
console.log(extended.slug);
|
|
927
|
+
});
|
|
928
|
+
```
|
|
929
|
+
|
|
930
|
+
**Consuming Pipeline Events:**
|
|
931
|
+
|
|
932
|
+
```typescript
|
|
933
|
+
for await (const event of model.stream(prompt)) {
|
|
934
|
+
if (isPipelineStageEvent(event)) {
|
|
935
|
+
console.log(event.delta.stage, event.delta.payload);
|
|
936
|
+
// 'slug' { slug: 'my-blog-post' }
|
|
937
|
+
// 'embedding' { embedded: true }
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
**Middleware Order:** Place `pipelineMiddleware` after `pubsubMiddleware` in the array:
|
|
943
|
+
|
|
944
|
+
```typescript
|
|
945
|
+
middleware: [
|
|
946
|
+
pubsubMiddleware({ ... }), // Setup runs first in onStart
|
|
947
|
+
pipelineMiddleware({ ... }), // Events run first in onTurn (reverse order)
|
|
948
|
+
]
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
This ensures pubsub sets up before pipeline stages execute, and pipeline events emit before pubsub cleanup.
|
|
952
|
+
|
|
953
|
+
**Pipeline Configuration:**
|
|
954
|
+
|
|
955
|
+
| Option | Type | Default | Description |
|
|
956
|
+
|--------|------|---------|-------------|
|
|
957
|
+
| `stages` | `PipelineStage[]` | required | Stages to run after turn completion |
|
|
958
|
+
| `parallel` | `boolean` | `false` | Run stages in parallel instead of sequential |
|
|
959
|
+
| `continueOnError` | `boolean` | `false` | Continue running subsequent stages if one fails |
|
|
960
|
+
| `onStageError` | `function` | - | Called when a stage throws an error |
|
|
961
|
+
|
|
845
962
|
## Error Handling
|
|
846
963
|
|
|
847
964
|
All errors are normalized to `UPPError` with consistent error codes:
|
|
@@ -888,17 +1005,16 @@ Build AI API gateways with your own authentication. Users authenticate with your
|
|
|
888
1005
|
### Server (Bun/Deno/Cloudflare Workers)
|
|
889
1006
|
|
|
890
1007
|
```typescript
|
|
891
|
-
import { llm } from '@providerprotocol/ai';
|
|
1008
|
+
import { llm, exponentialBackoff, roundRobinKeys } from '@providerprotocol/ai';
|
|
892
1009
|
import { anthropic } from '@providerprotocol/ai/anthropic';
|
|
893
|
-
import { ExponentialBackoff, RoundRobinKeys } from '@providerprotocol/ai/http';
|
|
894
1010
|
import { parseBody, toJSON, toSSE, toError } from '@providerprotocol/ai/proxy';
|
|
895
1011
|
|
|
896
1012
|
// Server manages AI provider keys - users never see them
|
|
897
1013
|
const claude = llm({
|
|
898
1014
|
model: anthropic('claude-sonnet-4-20250514'),
|
|
899
1015
|
config: {
|
|
900
|
-
apiKey:
|
|
901
|
-
retryStrategy:
|
|
1016
|
+
apiKey: roundRobinKeys([process.env.ANTHROPIC_KEY_1!, process.env.ANTHROPIC_KEY_2!]),
|
|
1017
|
+
retryStrategy: exponentialBackoff({ maxAttempts: 3 }),
|
|
902
1018
|
},
|
|
903
1019
|
});
|
|
904
1020
|
|
|
@@ -928,15 +1044,14 @@ Bun.serve({
|
|
|
928
1044
|
Clients authenticate with your platform token. They get automatic retry on network failures to your proxy.
|
|
929
1045
|
|
|
930
1046
|
```typescript
|
|
931
|
-
import { llm } from '@providerprotocol/ai';
|
|
1047
|
+
import { llm, exponentialBackoff } from '@providerprotocol/ai';
|
|
932
1048
|
import { proxy } from '@providerprotocol/ai/proxy';
|
|
933
|
-
import { ExponentialBackoff } from '@providerprotocol/ai/http';
|
|
934
1049
|
|
|
935
1050
|
const claude = llm({
|
|
936
1051
|
model: proxy('https://api.yourplatform.com/ai'),
|
|
937
1052
|
config: {
|
|
938
1053
|
headers: { 'Authorization': 'Bearer user-platform-token' },
|
|
939
|
-
retryStrategy:
|
|
1054
|
+
retryStrategy: exponentialBackoff({ maxAttempts: 3 }),
|
|
940
1055
|
timeout: 30000,
|
|
941
1056
|
},
|
|
942
1057
|
});
|
|
@@ -1153,6 +1268,85 @@ const model = llm({
|
|
|
1153
1268
|
|
|
1154
1269
|
**Environment:** `CEREBRAS_API_KEY`
|
|
1155
1270
|
|
|
1271
|
+
## Moonshot
|
|
1272
|
+
|
|
1273
|
+
Kimi K2.5 with 256K context, thinking mode, vision, and server-side builtin tools:
|
|
1274
|
+
|
|
1275
|
+
```typescript
|
|
1276
|
+
import { llm } from '@providerprotocol/ai';
|
|
1277
|
+
import { moonshot, tools } from '@providerprotocol/ai/moonshot';
|
|
1278
|
+
|
|
1279
|
+
const model = llm({
|
|
1280
|
+
model: moonshot('kimi-k2.5'),
|
|
1281
|
+
params: { max_tokens: 1000 },
|
|
1282
|
+
});
|
|
1283
|
+
|
|
1284
|
+
const turn = await model.generate('Hello!');
|
|
1285
|
+
```
|
|
1286
|
+
|
|
1287
|
+
**With thinking mode (default for K2.5):**
|
|
1288
|
+
|
|
1289
|
+
```typescript
|
|
1290
|
+
const model = llm({
|
|
1291
|
+
model: moonshot('kimi-k2.5'),
|
|
1292
|
+
params: {
|
|
1293
|
+
max_tokens: 2000,
|
|
1294
|
+
temperature: 1.0,
|
|
1295
|
+
thinking: { type: 'enabled' },
|
|
1296
|
+
},
|
|
1297
|
+
});
|
|
1298
|
+
|
|
1299
|
+
// Response includes reasoning in turn.response.reasoning
|
|
1300
|
+
const turn = await model.generate('Solve step by step: 2x + 5 = 13');
|
|
1301
|
+
```
|
|
1302
|
+
|
|
1303
|
+
**With instant mode (disabled thinking):**
|
|
1304
|
+
|
|
1305
|
+
```typescript
|
|
1306
|
+
const model = llm({
|
|
1307
|
+
model: moonshot('kimi-k2.5'),
|
|
1308
|
+
params: {
|
|
1309
|
+
temperature: 0.6,
|
|
1310
|
+
thinking: { type: 'disabled' },
|
|
1311
|
+
},
|
|
1312
|
+
});
|
|
1313
|
+
```
|
|
1314
|
+
|
|
1315
|
+
**With builtin tools:**
|
|
1316
|
+
|
|
1317
|
+
```typescript
|
|
1318
|
+
const model = llm({
|
|
1319
|
+
model: moonshot('kimi-k2.5'),
|
|
1320
|
+
params: {
|
|
1321
|
+
tools: [
|
|
1322
|
+
tools.webSearch(),
|
|
1323
|
+
tools.codeRunner(),
|
|
1324
|
+
tools.date(),
|
|
1325
|
+
],
|
|
1326
|
+
},
|
|
1327
|
+
});
|
|
1328
|
+
```
|
|
1329
|
+
|
|
1330
|
+
**Available Builtin Tools:**
|
|
1331
|
+
|
|
1332
|
+
| Tool | Description |
|
|
1333
|
+
|------|-------------|
|
|
1334
|
+
| `tools.webSearch()` | Real-time internet search |
|
|
1335
|
+
| `tools.codeRunner()` | Python code execution with matplotlib/pandas |
|
|
1336
|
+
| `tools.quickjs()` | JavaScript execution via QuickJS engine |
|
|
1337
|
+
| `tools.fetch()` | URL content fetching with markdown extraction |
|
|
1338
|
+
| `tools.convert()` | Unit conversion (length, mass, temperature, currency) |
|
|
1339
|
+
| `tools.date()` | Date/time processing and timezone conversion |
|
|
1340
|
+
| `tools.base64Encode()` | Base64 encoding |
|
|
1341
|
+
| `tools.base64Decode()` | Base64 decoding |
|
|
1342
|
+
| `tools.memory()` | Memory storage and retrieval system |
|
|
1343
|
+
| `tools.rethink()` | Intelligent reasoning/reflection tool |
|
|
1344
|
+
| `tools.randomChoice()` | Random selection with optional weights |
|
|
1345
|
+
|
|
1346
|
+
**Capabilities:** Streaming, tool calling, structured output, thinking mode, image input, video input (experimental).
|
|
1347
|
+
|
|
1348
|
+
**Environment:** `MOONSHOT_API_KEY` or `KIMI_API_KEY`
|
|
1349
|
+
|
|
1156
1350
|
## OpenResponses Provider
|
|
1157
1351
|
|
|
1158
1352
|
Connect to any server implementing the [OpenResponses specification](https://www.openresponses.org):
|
|
@@ -1209,8 +1403,10 @@ Full type safety with no `any` types. All provider parameters are typed:
|
|
|
1209
1403
|
import type {
|
|
1210
1404
|
// Core types
|
|
1211
1405
|
Turn,
|
|
1406
|
+
TurnJSON,
|
|
1212
1407
|
Message,
|
|
1213
1408
|
Tool,
|
|
1409
|
+
ToolInput,
|
|
1214
1410
|
TokenUsage,
|
|
1215
1411
|
|
|
1216
1412
|
// Streaming
|
|
@@ -1268,6 +1464,45 @@ if (isZodSchema(schema)) {
|
|
|
1268
1464
|
}
|
|
1269
1465
|
```
|
|
1270
1466
|
|
|
1467
|
+
**Error & ID Utilities:**
|
|
1468
|
+
|
|
1469
|
+
```typescript
|
|
1470
|
+
import {
|
|
1471
|
+
toError,
|
|
1472
|
+
isCancelledError,
|
|
1473
|
+
generateId,
|
|
1474
|
+
generateShortId,
|
|
1475
|
+
} from '@providerprotocol/ai/utils';
|
|
1476
|
+
|
|
1477
|
+
// Convert unknown thrown values to Error instances
|
|
1478
|
+
const error = toError(unknownValue);
|
|
1479
|
+
|
|
1480
|
+
// Check if an error is a cancellation/abort error
|
|
1481
|
+
if (isCancelledError(error)) {
|
|
1482
|
+
console.log('Request was cancelled');
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
// Generate IDs
|
|
1486
|
+
const uuid = generateId(); // UUID v4: "a1b2c3d4-..."
|
|
1487
|
+
const shortId = generateShortId('req'); // "req_abc123xyz789"
|
|
1488
|
+
```
|
|
1489
|
+
|
|
1490
|
+
**Provider-Specific Types:**
|
|
1491
|
+
|
|
1492
|
+
```typescript
|
|
1493
|
+
// OpenAI
|
|
1494
|
+
import type { OpenAIHeaders, OpenAIImageParams } from '@providerprotocol/ai/openai';
|
|
1495
|
+
|
|
1496
|
+
// Google
|
|
1497
|
+
import type { GoogleImagenParams } from '@providerprotocol/ai/google';
|
|
1498
|
+
|
|
1499
|
+
// Ollama
|
|
1500
|
+
import type { OllamaHeaders } from '@providerprotocol/ai/ollama';
|
|
1501
|
+
|
|
1502
|
+
// OpenRouter
|
|
1503
|
+
import type { OpenRouterProviderOptions } from '@providerprotocol/ai/openrouter';
|
|
1504
|
+
```
|
|
1505
|
+
|
|
1271
1506
|
**Type-Safe Enums:**
|
|
1272
1507
|
|
|
1273
1508
|
```typescript
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { e as Provider } from '../llm-
|
|
2
|
-
import '../stream-
|
|
3
|
-
import '../tool-
|
|
1
|
+
import { e as Provider } from '../llm-BWLaTzzY.js';
|
|
2
|
+
import '../stream-bBd_4Ipu.js';
|
|
3
|
+
import '../tool-BmAfKNBq.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @fileoverview Anthropic API type definitions.
|
package/dist/anthropic/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "../chunk-TUTYMOBL.js";
|
|
7
7
|
import {
|
|
8
8
|
resolveApiKey
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-EY2LLDGY.js";
|
|
10
10
|
import {
|
|
11
11
|
createProvider
|
|
12
12
|
} from "../chunk-JA3UZALR.js";
|
|
@@ -14,18 +14,20 @@ import {
|
|
|
14
14
|
doFetch,
|
|
15
15
|
doStreamFetch,
|
|
16
16
|
normalizeHttpError
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-VQZPADW6.js";
|
|
18
18
|
import {
|
|
19
19
|
StreamEventType,
|
|
20
20
|
objectDelta
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-F5ENANMJ.js";
|
|
22
22
|
import {
|
|
23
23
|
AssistantMessage,
|
|
24
|
-
generateId,
|
|
25
24
|
isAssistantMessage,
|
|
26
25
|
isToolResultMessage,
|
|
27
26
|
isUserMessage
|
|
28
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-6QCV4WXF.js";
|
|
28
|
+
import {
|
|
29
|
+
generateId
|
|
30
|
+
} from "../chunk-U2G5PHHL.js";
|
|
29
31
|
import {
|
|
30
32
|
toError
|
|
31
33
|
} from "../chunk-GIDT7C6I.js";
|