vern-llm 0.0.0-canary-8b7fc47
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 +105 -0
- package/dist/chunk-BtT13l48.cjs +40 -0
- package/dist/dist-cjs-Bg-V7ltA.js +26661 -0
- package/dist/dist-cjs-Bg-V7ltA.js.map +1 -0
- package/dist/dist-cjs-BnuaUbRC.cjs +26657 -0
- package/dist/dist-cjs-BnuaUbRC.cjs.map +1 -0
- package/dist/index.cjs +4825 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2988 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +2988 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4760 -0
- package/dist/index.js.map +1 -0
- package/package.json +94 -0
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/LakBud/vernLLM/main/apps/docs/public/logo.png" alt="vern-llm logo" width="96" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">vern-llm</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://github.com/LakBud/vernLLM">GitHub</a> ·
|
|
9
|
+
<a href="https://vernllm.vercel.app">Documentation</a> ·
|
|
10
|
+
<a href="https://www.npmjs.com/package/vern-llm">npm</a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://www.npmjs.com/package/vern-llm"><img src="https://img.shields.io/npm/v/vern-llm.svg" alt="npm version" /></a>
|
|
15
|
+
<a href="https://www.npmjs.com/package/vern-llm"><img src="https://img.shields.io/npm/dm/vern-llm.svg" alt="npm downloads" /></a>
|
|
16
|
+
<a href="https://github.com/LakBud/vernLLM/actions/workflows/build-checks.yml"><img src="https://github.com/LakBud/vernLLM/actions/workflows/build-checks.yml/badge.svg" alt="build checks status" /></a>
|
|
17
|
+
<a href="https://github.com/LakBud/vernLLM/actions/workflows/typecheck.yml"><img src="https://github.com/LakBud/vernLLM/actions/workflows/typecheck.yml/badge.svg" alt="typecheck status" /></a>
|
|
18
|
+
<a href="https://github.com/LakBud/vernLLM/actions/workflows/test-unit.yml"><img src="https://github.com/LakBud/vernLLM/actions/workflows/test-unit.yml/badge.svg" alt="unit test status" /></a>
|
|
19
|
+
<a href="https://github.com/LakBud/vernLLM/actions/workflows/test-integration.yml"><img src="https://github.com/LakBud/vernLLM/actions/workflows/test-integration.yml/badge.svg" alt="integration test status" /></a>
|
|
20
|
+
<a href="https://github.com/LakBud/vernLLM/actions/workflows/lint.yml"><img src="https://github.com/LakBud/vernLLM/actions/workflows/lint.yml/badge.svg" alt="lint status" /></a>
|
|
21
|
+
<a href="https://github.com/LakBud/vernLLM/blob/main/LICENSE.md"><img src="https://img.shields.io/npm/l/vern-llm.svg" alt="license" /></a>
|
|
22
|
+
<img src="https://img.shields.io/node/v/vern-llm.svg" alt="node version" />
|
|
23
|
+
<img src="https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=white" alt="TypeScript" />
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<p align="center">The LLM call framework. Resilience, observability, and control for every call.</p>
|
|
27
|
+
|
|
28
|
+
Retries, timeouts, caching, circuit breaking, provider fallback, and client-side rate limiting behind one typed interface, with adapters for OpenAI-compatible APIs, Anthropic, Gemini, and Bedrock.
|
|
29
|
+
|
|
30
|
+
**Full documentation: [vernllm.vercel.app](https://vernllm.vercel.app)** — installation, structured output, caching, circuit breaker, provider fallback, rate limiting, observability, every adapter, and the complete API reference all live there and are kept up to date. This README is a quick pitch, not the manual.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add vern-llm
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick start
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
42
|
+
import OpenAI from 'openai';
|
|
43
|
+
import { fromAnthropic, fromOpenAI, VernLLM } from 'vern-llm';
|
|
44
|
+
|
|
45
|
+
const llm = new VernLLM({
|
|
46
|
+
client: fromOpenAI(new OpenAI({ apiKey: process.env.OPENAI_API_KEY })),
|
|
47
|
+
model: 'gpt-4o',
|
|
48
|
+
maxRetries: 3,
|
|
49
|
+
timeoutMs: 10_000,
|
|
50
|
+
circuitBreaker: true,
|
|
51
|
+
rateLimit: { requestsPerMinute: 500, maxConcurrent: 20 },
|
|
52
|
+
fallback: {
|
|
53
|
+
client: fromAnthropic(new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })),
|
|
54
|
+
model: 'claude-sonnet-5',
|
|
55
|
+
circuitBreaker: true,
|
|
56
|
+
},
|
|
57
|
+
onEvent: (event) => {
|
|
58
|
+
if (event.kind === 'fallback') console.warn(`falling over ${event.from} -> ${event.to}`);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const getWeather = {
|
|
63
|
+
name: 'get_weather',
|
|
64
|
+
description: 'Gets the current weather for a city',
|
|
65
|
+
parameters: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'] },
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const { chunks, finalResult } = await llm.cachedCall({
|
|
69
|
+
cacheKey: 'weather-demo-001',
|
|
70
|
+
ttl: 60,
|
|
71
|
+
call: {
|
|
72
|
+
userContent: "What's the weather in New York?",
|
|
73
|
+
tools: [getWeather],
|
|
74
|
+
stream: true,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
for await (const chunk of chunks) {
|
|
79
|
+
if (chunk.type === 'text-delta') process.stdout.write(chunk.delta);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const result = await finalResult; // cached, retried, and streamed, tool calls included
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Why vern-llm?
|
|
86
|
+
|
|
87
|
+
- **Retries with backoff**: transient failures retry automatically; validation errors and non-retryable status codes fail fast instead
|
|
88
|
+
- **Provider fallback**: declare an ordered list of backup targets, tried in order after the primary, with no scoring or health-checking, `fallback` on the same constructor
|
|
89
|
+
- **Client-side rate limiting**: queue locally against requests-per-minute, tokens-per-minute, and concurrency ceilings instead of letting the provider reject the call
|
|
90
|
+
- **Structured output**: pass a Zod schema, get a typed, validated result back
|
|
91
|
+
- **Tool calling**: pass `tools`, vern-llm handles retries and validation around them the same as any other call; you run the tools and continue the conversation
|
|
92
|
+
- **Streaming**: set `stream: true` on any call and get live chunks alongside the same validated result the call would otherwise resolve to
|
|
93
|
+
- **Provider-native JSON Schema mode**: constrain generation itself, not just validate after the fact
|
|
94
|
+
- **Caching**: wrap any LLM call with `cachedCall`, bring your own cache adapter
|
|
95
|
+
- **Circuit breaker**: trips after repeated failures, recovers automatically once the provider's back, independent per fallback target too
|
|
96
|
+
- **Observability**: one `onEvent` stream reports retries, fallovers, circuit transitions, and rate-limit waits
|
|
97
|
+
- **Usage tracking**: `onUsage` and `onUsageFailure` report token spend on success and on failure, so nothing goes unaccounted for when a call fails after the provider already responded
|
|
98
|
+
- **One interface, every provider**: OpenAI, Groq, Mistral, DeepSeek, Cerebras, Together, Fireworks, Ollama, Anthropic, Gemini, Bedrock, or raw HTTP via `fromFetch`
|
|
99
|
+
- **Zero runtime dependencies**: `zod` and provider SDKs are not required dependencies; vern-llm relies on compatible interfaces rather than specific implementations.
|
|
100
|
+
|
|
101
|
+
See the [docs](https://vernllm.vercel.app) for adapter setup, caching, the circuit breaker, provider fallback, rate limiting, and structured output in depth.
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
[MIT](https://github.com/LakBud/vernLLM/blob/main/LICENSE.md) © LakBud
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//#region rolldown:runtime
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __commonJS = (cb, mod) => function() {
|
|
10
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
14
|
+
key = keys[i];
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
16
|
+
get: ((k) => from[k]).bind(null, key),
|
|
17
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
|
|
29
|
+
Object.defineProperty(exports, '__commonJS', {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
get: function () {
|
|
32
|
+
return __commonJS;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(exports, '__toESM', {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
get: function () {
|
|
38
|
+
return __toESM;
|
|
39
|
+
}
|
|
40
|
+
});
|