llmist 7.0.0 β 8.1.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/dist/index.cjs +410 -1038
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6073 -4
- package/dist/index.d.ts +6073 -4
- package/dist/index.js +11955 -115
- package/dist/index.js.map +1 -1
- package/package.json +8 -36
- package/LICENSE +0 -21
- package/README.md +0 -511
- package/dist/chunk-5KEZ7SQX.js +0 -1182
- package/dist/chunk-5KEZ7SQX.js.map +0 -1
- package/dist/chunk-SFZIL2VR.js +0 -12214
- package/dist/chunk-SFZIL2VR.js.map +0 -1
- package/dist/cli.cjs +0 -18226
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.d.cts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -7819
- package/dist/cli.js.map +0 -1
- package/dist/mock-stream-r5vjy2Iq.d.cts +0 -6397
- package/dist/mock-stream-r5vjy2Iq.d.ts +0 -6397
- package/dist/testing/index.cjs +0 -12088
- package/dist/testing/index.cjs.map +0 -1
- package/dist/testing/index.d.cts +0 -710
- package/dist/testing/index.d.ts +0 -710
- package/dist/testing/index.js +0 -83
- package/dist/testing/index.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llmist",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.1.0",
|
|
4
4
|
"description": "TypeScript LLM client with streaming tool execution. Tools fire mid-stream. Built-in function calling works with any modelβno structured outputs or native tool support required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -16,42 +16,20 @@
|
|
|
16
16
|
"types": "./dist/index.d.cts",
|
|
17
17
|
"default": "./dist/index.cjs"
|
|
18
18
|
}
|
|
19
|
-
},
|
|
20
|
-
"./testing": {
|
|
21
|
-
"import": {
|
|
22
|
-
"types": "./dist/testing/index.d.ts",
|
|
23
|
-
"default": "./dist/testing/index.js"
|
|
24
|
-
},
|
|
25
|
-
"require": {
|
|
26
|
-
"types": "./dist/testing/index.d.cts",
|
|
27
|
-
"default": "./dist/testing/index.cjs"
|
|
28
|
-
}
|
|
29
19
|
}
|
|
30
20
|
},
|
|
31
21
|
"scripts": {
|
|
32
|
-
"cli": "bun run scripts/cli-runner.ts",
|
|
33
22
|
"build": "tsup",
|
|
34
23
|
"typecheck": "tsc --noEmit",
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"check": "biome check --write .",
|
|
38
|
-
"test": "bun test",
|
|
39
|
-
"test:unit": "bun test src/agent src/core src/gadgets src/providers src/testing",
|
|
40
|
-
"test:watch": "bun test --watch",
|
|
24
|
+
"test": "bun test src --ignore-pattern='**/e2e/**'",
|
|
25
|
+
"test:unit": "bun test src/agent src/core src/gadgets src/providers",
|
|
41
26
|
"test:e2e": "bun test src/e2e --timeout 60000 --bail 1",
|
|
42
|
-
"
|
|
43
|
-
"test:all": "bun run test && bun run test:e2e",
|
|
44
|
-
"clean": "rimraf dist",
|
|
45
|
-
"prepare": "node scripts/install-hooks.js || true",
|
|
46
|
-
"release:dry": "bunx semantic-release --dry-run",
|
|
47
|
-
"release:publish": "test \"$(git branch --show-current)\" = \"main\" && git pull origin main && bun run build && npm publish"
|
|
48
|
-
},
|
|
49
|
-
"bin": {
|
|
50
|
-
"llmist": "dist/cli.js"
|
|
27
|
+
"clean": "rimraf dist"
|
|
51
28
|
},
|
|
52
29
|
"repository": {
|
|
53
30
|
"type": "git",
|
|
54
|
-
"url": "https://github.com/zbigniewsobiecki/llmist.git"
|
|
31
|
+
"url": "https://github.com/zbigniewsobiecki/llmist.git",
|
|
32
|
+
"directory": "packages/llmist"
|
|
55
33
|
},
|
|
56
34
|
"publishConfig": {
|
|
57
35
|
"access": "public"
|
|
@@ -87,12 +65,11 @@
|
|
|
87
65
|
],
|
|
88
66
|
"author": "Zbigniew Sobiecki <zbigniew@sobiecki.name>",
|
|
89
67
|
"license": "MIT",
|
|
68
|
+
"sideEffects": false,
|
|
90
69
|
"dependencies": {
|
|
91
70
|
"@anthropic-ai/sdk": "^0.69.0",
|
|
92
71
|
"@google/genai": "^1.27.0",
|
|
93
|
-
"@unblessed/node": "^1.0.0-alpha.23",
|
|
94
72
|
"chalk": "^5.6.2",
|
|
95
|
-
"commander": "^12.1.0",
|
|
96
73
|
"diff": "^8.0.2",
|
|
97
74
|
"eta": "^4.4.1",
|
|
98
75
|
"fast-deep-equal": "^3.1.3",
|
|
@@ -101,16 +78,12 @@
|
|
|
101
78
|
"marked": "^15.0.12",
|
|
102
79
|
"marked-terminal": "^7.3.0",
|
|
103
80
|
"openai": "^6.0.0",
|
|
81
|
+
"p-retry": "^7.1.1",
|
|
104
82
|
"tiktoken": "^1.0.22",
|
|
105
83
|
"tslog": "^4.10.2",
|
|
106
84
|
"zod": "^4.1.12"
|
|
107
85
|
},
|
|
108
86
|
"devDependencies": {
|
|
109
|
-
"@biomejs/biome": "^2.3.2",
|
|
110
|
-
"@commitlint/cli": "^20.1.0",
|
|
111
|
-
"@commitlint/config-conventional": "^20.0.0",
|
|
112
|
-
"@semantic-release/changelog": "^6.0.3",
|
|
113
|
-
"@semantic-release/git": "^10.0.1",
|
|
114
87
|
"@types/diff": "^8.0.0",
|
|
115
88
|
"@types/js-yaml": "^4.0.9",
|
|
116
89
|
"@types/marked-terminal": "^6.1.1",
|
|
@@ -118,7 +91,6 @@
|
|
|
118
91
|
"bun-types": "^1.3.2",
|
|
119
92
|
"dotenv": "^17.2.3",
|
|
120
93
|
"rimraf": "^5.0.5",
|
|
121
|
-
"semantic-release": "^25.0.2",
|
|
122
94
|
"tsup": "^8.3.5",
|
|
123
95
|
"typescript": "^5.4.5"
|
|
124
96
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Zbigniew Sobiecki
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/README.md
DELETED
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
# llmist
|
|
2
|
-
|
|
3
|
-
[](https://github.com/zbigniewsobiecki/llmist/actions/workflows/ci.yml)
|
|
4
|
-
[](https://codecov.io/gh/zbigniewsobiecki/llmist)
|
|
5
|
-
[](https://www.npmjs.com/package/llmist)
|
|
6
|
-
[](https://opensource.org/licenses/MIT)
|
|
7
|
-
|
|
8
|
-
> **Tools execute while the LLM streams. Any model. Clean API.**
|
|
9
|
-
|
|
10
|
-
> **β οΈ EARLY WORK IN PROGRESS** - This library is under active development. APIs may change without notice. Use in production at your own risk.
|
|
11
|
-
|
|
12
|
-
Most LLM libraries buffer the entire response before parsing tool calls. **llmist parses incrementally.**
|
|
13
|
-
|
|
14
|
-
Your gadgets (tools) fire the instant they're complete in the streamβgiving your users immediate feedback. llmist implements its own function calling mechanism via a simple text-based block format. No JSON mode required. No native tool support needed. Works with OpenAI, Anthropic, and Gemini out of the boxβextensible to any provider.
|
|
15
|
-
|
|
16
|
-
A fluent, async-first API lets you plug into any part of the agent loop. Fully typed. Composable. Your code stays clean.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## π― Why llmist?
|
|
21
|
-
|
|
22
|
-
<table>
|
|
23
|
-
<tr>
|
|
24
|
-
<td width="33%" valign="top">
|
|
25
|
-
|
|
26
|
-
### β‘ Streaming Tool Execution
|
|
27
|
-
Gadgets execute the moment their block is parsedβnot after the response completes. Real-time UX without buffering.
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
// Tool fires mid-stream
|
|
31
|
-
for await (const event of agent.run()) {
|
|
32
|
-
if (event.type === 'gadget_result')
|
|
33
|
-
updateUI(event.result); // Immediate
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
</td>
|
|
38
|
-
<td width="33%" valign="top">
|
|
39
|
-
|
|
40
|
-
### π§© Built-in Function Calling
|
|
41
|
-
llmist implements its own tool calling via a simple block format. No `response_format: json`. No native tool support needed. Works with any model from supported providers.
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
!!!GADGET_START[Calculator]
|
|
45
|
-
!!!ARG[operation] add
|
|
46
|
-
!!!ARG[a] 15
|
|
47
|
-
!!!ARG[b] 23
|
|
48
|
-
!!!GADGET_END
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
*Markers are fully [configurable](./docs/BLOCK_FORMAT.md).*
|
|
52
|
-
|
|
53
|
-
</td>
|
|
54
|
-
<td width="33%" valign="top">
|
|
55
|
-
|
|
56
|
-
### π Composable Agent API
|
|
57
|
-
Fluent builder, async iterators, full TypeScript inference. Hook into any lifecycle point. Your code stays readable.
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
const answer = await LLMist.createAgent()
|
|
61
|
-
.withModel('sonnet')
|
|
62
|
-
.withGadgets(Calculator, Weather)
|
|
63
|
-
.withHooks(HookPresets.monitoring())
|
|
64
|
-
.askAndCollect('What is 15 + 23?');
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
</td>
|
|
68
|
-
</tr>
|
|
69
|
-
</table>
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## π Quick Start
|
|
74
|
-
|
|
75
|
-
### Installation
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
npm install llmist
|
|
79
|
-
# or
|
|
80
|
-
bun add llmist
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## π₯οΈ Command Line Interface
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
# Initialize config (creates ~/.llmist/cli.toml)
|
|
89
|
-
bunx llmist init
|
|
90
|
-
|
|
91
|
-
# Quick completion
|
|
92
|
-
bunx llmist complete "Explain TypeScript generics" --model haiku
|
|
93
|
-
|
|
94
|
-
# Agent with tools
|
|
95
|
-
bunx llmist agent "Calculate 15 * 23" --gadget ./calculator.ts --model sonnet
|
|
96
|
-
|
|
97
|
-
# External gadgets (npm/git - auto-installed)
|
|
98
|
-
bunx llmist agent "Browse apple.com" --gadget webasto --model sonnet
|
|
99
|
-
bunx llmist agent "Screenshot google.com" --gadget webasto:minimal
|
|
100
|
-
bunx llmist agent "Navigate to site" --gadget git+https://github.com/user/gadgets.git
|
|
101
|
-
|
|
102
|
-
# Pipe input
|
|
103
|
-
cat document.txt | llmist complete "Summarize" --model gpt-5-nano
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
π **[CLI Reference](./docs/CLI.md)** | **[CLI Gadgets Guide](./docs/CLI_GADGETS.md)**
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
### Your First Agent
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
import { LLMist, Gadget, z } from 'llmist';
|
|
113
|
-
|
|
114
|
-
// Define a tool (called "gadget" in llmist)
|
|
115
|
-
class Calculator extends Gadget({
|
|
116
|
-
description: 'Performs arithmetic operations',
|
|
117
|
-
schema: z.object({
|
|
118
|
-
operation: z.enum(['add', 'multiply', 'subtract', 'divide']),
|
|
119
|
-
a: z.number(),
|
|
120
|
-
b: z.number(),
|
|
121
|
-
}),
|
|
122
|
-
}) {
|
|
123
|
-
execute(params: this['params']): string {
|
|
124
|
-
const { operation, a, b } = params; // Automatically typed!
|
|
125
|
-
switch (operation) {
|
|
126
|
-
case 'add': return `${a + b}`;
|
|
127
|
-
case 'multiply': return `${a * b}`;
|
|
128
|
-
case 'subtract': return `${a - b}`;
|
|
129
|
-
case 'divide': return `${a / b}`;
|
|
130
|
-
default: throw new Error('Unknown operation');
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Create and run agent with fluent API
|
|
136
|
-
const answer = await LLMist.createAgent()
|
|
137
|
-
.withModel('gpt-5-nano') // Model shortcuts: sonnet, haiku, etc.
|
|
138
|
-
.withSystem('You are a helpful math assistant')
|
|
139
|
-
.withGadgets(Calculator)
|
|
140
|
-
.askAndCollect('What is 15 times 23?');
|
|
141
|
-
|
|
142
|
-
console.log(answer); // "15 times 23 equals 345"
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
**That's it!**
|
|
146
|
-
|
|
147
|
-
π **[Getting Started Guide](./docs/GETTING_STARTED.md)** - Learn more in 5 minutes
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## β¨ Key Features
|
|
152
|
-
|
|
153
|
-
### π Multi-Provider Support
|
|
154
|
-
|
|
155
|
-
```typescript
|
|
156
|
-
// Use model shortcuts
|
|
157
|
-
.withModel('gpt-5-nano') // OpenAI gpt-5-nano
|
|
158
|
-
.withModel('sonnet') // Claude Sonnet 4.5
|
|
159
|
-
.withModel('haiku') // Claude Haiku 4.5
|
|
160
|
-
.withModel('flash') // Gemini 2.0 Flash
|
|
161
|
-
|
|
162
|
-
// Or full names
|
|
163
|
-
.withModel('openai:gpt-5-nano')
|
|
164
|
-
.withModel('anthropic:claude-sonnet-4-5')
|
|
165
|
-
.withModel('gemini:gemini-2.0-flash')
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
**Automatic provider discovery** - Just set API keys as env vars (`OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`)
|
|
169
|
-
|
|
170
|
-
π **[Providers Guide](./docs/PROVIDERS.md)** | **[Model Catalog](./docs/MODEL_CATALOG.md)**
|
|
171
|
-
|
|
172
|
-
### π οΈ Flexible Gadgets (Tools)
|
|
173
|
-
|
|
174
|
-
Two ways to create tools:
|
|
175
|
-
|
|
176
|
-
```typescript
|
|
177
|
-
// 1. Class-based with type safety
|
|
178
|
-
class Weather extends Gadget({
|
|
179
|
-
description: 'Get weather for a city',
|
|
180
|
-
schema: z.object({ city: z.string() }),
|
|
181
|
-
}) {
|
|
182
|
-
async execute(params: this['params']) {
|
|
183
|
-
// params is auto-typed!
|
|
184
|
-
const data = await fetch(`https://api.weather.com/${params.city}`);
|
|
185
|
-
return `Weather: ${data.temp}Β°C`;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// 2. Functional for simplicity
|
|
190
|
-
const calculator = createGadget({
|
|
191
|
-
description: 'Arithmetic operations',
|
|
192
|
-
schema: z.object({ operation: z.enum(['add']), a: z.number(), b: z.number() }),
|
|
193
|
-
execute: ({ operation, a, b }) => `${a + b}`,
|
|
194
|
-
});
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
π **[Gadgets Guide](./docs/GADGETS.md)** | **[Examples](./examples/02-custom-gadgets.ts)**
|
|
198
|
-
|
|
199
|
-
### πͺ Lifecycle Hooks
|
|
200
|
-
|
|
201
|
-
Monitor, transform, and control agent execution with ready-to-use presets or custom hooks:
|
|
202
|
-
|
|
203
|
-
**Quick start with presets:**
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
import { LLMist, HookPresets } from 'llmist';
|
|
207
|
-
|
|
208
|
-
// Full monitoring suite (recommended for development)
|
|
209
|
-
await LLMist.createAgent()
|
|
210
|
-
.withHooks(HookPresets.monitoring())
|
|
211
|
-
.ask('Your prompt');
|
|
212
|
-
// Output: Logs + timing + token tracking + error logging
|
|
213
|
-
|
|
214
|
-
// Combine specific presets for focused monitoring
|
|
215
|
-
await LLMist.createAgent()
|
|
216
|
-
.withHooks(HookPresets.merge(
|
|
217
|
-
HookPresets.timing(),
|
|
218
|
-
HookPresets.tokenTracking()
|
|
219
|
-
))
|
|
220
|
-
.ask('Your prompt');
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
**Available presets:**
|
|
224
|
-
- `logging()` / `logging({ verbose: true })` - Event logging with optional details
|
|
225
|
-
- `timing()` - Execution time measurements
|
|
226
|
-
- `tokenTracking()` - Cumulative token usage and cost tracking
|
|
227
|
-
- `errorLogging()` - Detailed error information
|
|
228
|
-
- `silent()` - No output (for testing)
|
|
229
|
-
- `monitoring()` - All-in-one preset combining logging, timing, tokens, and errors
|
|
230
|
-
- `merge()` - Combine multiple presets or add custom hooks
|
|
231
|
-
|
|
232
|
-
**Production vs Development patterns:**
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
// Environment-based configuration
|
|
236
|
-
const isDev = process.env.NODE_ENV === 'development';
|
|
237
|
-
const hooks = isDev
|
|
238
|
-
? HookPresets.monitoring({ verbose: true }) // Full visibility in dev
|
|
239
|
-
: HookPresets.merge(
|
|
240
|
-
HookPresets.errorLogging(), // Only errors in prod
|
|
241
|
-
HookPresets.tokenTracking() // Track costs
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
await LLMist.createAgent()
|
|
245
|
-
.withHooks(hooks)
|
|
246
|
-
.ask('Your prompt');
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
**Custom hooks for advanced control:**
|
|
250
|
-
|
|
251
|
-
```typescript
|
|
252
|
-
// Observers: read-only monitoring
|
|
253
|
-
.withHooks({
|
|
254
|
-
observers: {
|
|
255
|
-
onLLMCallComplete: async (ctx) => {
|
|
256
|
-
console.log(`Used ${ctx.usage?.totalTokens} tokens`);
|
|
257
|
-
await sendMetricsToDataDog(ctx);
|
|
258
|
-
},
|
|
259
|
-
},
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
// Interceptors: transform data in flight
|
|
263
|
-
.withHooks({
|
|
264
|
-
interceptors: {
|
|
265
|
-
interceptTextChunk: (chunk) => chunk.toUpperCase(),
|
|
266
|
-
},
|
|
267
|
-
})
|
|
268
|
-
|
|
269
|
-
// Controllers: control execution flow
|
|
270
|
-
.withHooks({
|
|
271
|
-
controllers: {
|
|
272
|
-
beforeLLMCall: async (ctx) => {
|
|
273
|
-
if (shouldCache(ctx)) {
|
|
274
|
-
return { action: 'skip', syntheticResponse: cachedResponse };
|
|
275
|
-
}
|
|
276
|
-
return { action: 'proceed' };
|
|
277
|
-
},
|
|
278
|
-
},
|
|
279
|
-
})
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
π **[Hooks Guide](./docs/HOOKS.md)** | **[Examples](./examples/03-hooks.ts)**
|
|
283
|
-
|
|
284
|
-
### π¬ Human-in-the-Loop
|
|
285
|
-
|
|
286
|
-
```typescript
|
|
287
|
-
class AskUser extends Gadget({
|
|
288
|
-
description: 'Ask the user a question',
|
|
289
|
-
schema: z.object({ question: z.string() }),
|
|
290
|
-
}) {
|
|
291
|
-
execute(params: this['params']) {
|
|
292
|
-
throw new HumanInputRequiredException(params.question);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
await LLMist.createAgent()
|
|
297
|
-
.withGadgets(AskUser)
|
|
298
|
-
.onHumanInput(async (question) => {
|
|
299
|
-
return await promptUser(question);
|
|
300
|
-
})
|
|
301
|
-
.ask('Help me plan my vacation');
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
π **[Human-in-the-Loop Guide](./docs/HUMAN_IN_LOOP.md)** | **[Examples](./examples/04-human-in-loop.ts)**
|
|
305
|
-
|
|
306
|
-
### β‘ Streaming & Event Handling
|
|
307
|
-
|
|
308
|
-
```typescript
|
|
309
|
-
// Collect all text
|
|
310
|
-
const answer = await LLMist.createAgent()
|
|
311
|
-
.withModel('haiku')
|
|
312
|
-
.askAndCollect('Tell me a joke');
|
|
313
|
-
|
|
314
|
-
// Handle specific events
|
|
315
|
-
await LLMist.createAgent()
|
|
316
|
-
.withModel('sonnet')
|
|
317
|
-
.withGadgets(Calculator)
|
|
318
|
-
.askWith('Calculate 2 + 2', {
|
|
319
|
-
onText: (text) => console.log('LLM:', text),
|
|
320
|
-
onGadgetCall: (call) => console.log('Calling:', call.gadgetName),
|
|
321
|
-
onGadgetResult: (result) => console.log('Result:', result.result),
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
// Manual control
|
|
325
|
-
const agent = LLMist.createAgent().withModel('gpt-5-nano').ask('Question');
|
|
326
|
-
for await (const event of agent.run()) {
|
|
327
|
-
if (event.type === 'text') console.log(event.content);
|
|
328
|
-
}
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
π **[Streaming Guide](./docs/STREAMING.md)** | **[Examples](./examples/05-streaming.ts)**
|
|
332
|
-
|
|
333
|
-
### π Gadget Dependencies (DAG Execution)
|
|
334
|
-
|
|
335
|
-
LLMs can specify execution order between gadgets. Independent gadgets run in parallel; dependent gadgets wait for their dependencies. Failed dependencies automatically skip downstream gadgets.
|
|
336
|
-
|
|
337
|
-
π **[Block Format](./docs/BLOCK_FORMAT.md#dependencies)** | **[Example](./examples/11-gadget-dependencies.ts)**
|
|
338
|
-
|
|
339
|
-
### π§ͺ Mock Testing
|
|
340
|
-
|
|
341
|
-
```typescript
|
|
342
|
-
import { LLMist, mockLLM, createMockClient } from 'llmist';
|
|
343
|
-
|
|
344
|
-
mockLLM()
|
|
345
|
-
.forModel('gpt-5')
|
|
346
|
-
.whenMessageContains('calculate')
|
|
347
|
-
.returns('The answer is 42')
|
|
348
|
-
.register();
|
|
349
|
-
|
|
350
|
-
const mockClient = createMockClient();
|
|
351
|
-
const answer = await mockClient.createAgent()
|
|
352
|
-
.withModel('gpt-5')
|
|
353
|
-
.askAndCollect('Calculate 2 + 2');
|
|
354
|
-
|
|
355
|
-
console.log(answer); // "The answer is 42" - no API call made!
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
π **[Testing Guide](./docs/TESTING.md)** | **[Examples](./examples/mock-testing-example.ts)**
|
|
359
|
-
|
|
360
|
-
### π Model Catalog & Cost Estimation
|
|
361
|
-
|
|
362
|
-
```typescript
|
|
363
|
-
const client = new LLMist();
|
|
364
|
-
|
|
365
|
-
// Get model specs
|
|
366
|
-
const gpt5 = client.modelRegistry.getModelSpec('gpt-5');
|
|
367
|
-
console.log(gpt5.contextWindow); // 272000
|
|
368
|
-
console.log(gpt5.pricing.input); // 1.25 per 1M tokens
|
|
369
|
-
|
|
370
|
-
// Estimate costs
|
|
371
|
-
const cost = client.modelRegistry.estimateCost('gpt-5', 10_000, 2_000);
|
|
372
|
-
console.log(`$${cost.totalCost.toFixed(4)}`);
|
|
373
|
-
|
|
374
|
-
// Find cheapest model
|
|
375
|
-
const cheapest = client.modelRegistry.getCheapestModel(10_000, 2_000);
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
π **[Model Catalog Guide](./docs/MODEL_CATALOG.md)** | **[Custom Models](./docs/CUSTOM_MODELS.md)**
|
|
379
|
-
|
|
380
|
-
### π’ Native Token Counting
|
|
381
|
-
|
|
382
|
-
```typescript
|
|
383
|
-
const messages = [
|
|
384
|
-
{ role: 'system', content: 'You are helpful' },
|
|
385
|
-
{ role: 'user', content: 'Explain quantum computing' }
|
|
386
|
-
];
|
|
387
|
-
|
|
388
|
-
const tokens = await client.countTokens('openai:gpt-5', messages);
|
|
389
|
-
const cost = client.modelRegistry.estimateCost('gpt-5', tokens, 1000);
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
Uses provider-specific methods (tiktoken for OpenAI, native APIs for Anthropic/Gemini).
|
|
393
|
-
|
|
394
|
-
---
|
|
395
|
-
|
|
396
|
-
## π Documentation
|
|
397
|
-
|
|
398
|
-
**Getting Started**
|
|
399
|
-
- **[Getting Started](./docs/GETTING_STARTED.md)** - Your first agent in 5 minutes
|
|
400
|
-
- **[Configuration](./docs/CONFIGURATION.md)** - All available options
|
|
401
|
-
- **[Quick Methods](./docs/QUICK_METHODS.md)** - Simple APIs for basic tasks
|
|
402
|
-
|
|
403
|
-
**Core Concepts**
|
|
404
|
-
- **[Gadgets (Tools)](./docs/GADGETS.md)** - Creating custom functions
|
|
405
|
-
- **[Block Format](./docs/BLOCK_FORMAT.md)** - Parameter syntax reference
|
|
406
|
-
- **[Hooks](./docs/HOOKS.md)** - Lifecycle monitoring and control
|
|
407
|
-
- **[Streaming](./docs/STREAMING.md)** - Real-time response handling
|
|
408
|
-
- **[Human-in-the-Loop](./docs/HUMAN_IN_LOOP.md)** - Interactive workflows
|
|
409
|
-
|
|
410
|
-
**Advanced**
|
|
411
|
-
- **[Providers](./docs/PROVIDERS.md)** - Multi-provider configuration
|
|
412
|
-
- **[Model Catalog](./docs/MODEL_CATALOG.md)** - Querying models and costs
|
|
413
|
-
- **[Custom Models](./docs/CUSTOM_MODELS.md)** - Register fine-tuned models
|
|
414
|
-
- **[Subagents](./docs/SUBAGENTS.md)** - Nested agents for complex tasks
|
|
415
|
-
- **[Execution Tree](./docs/EXECUTION_TREE.md)** - Tracking LLM calls and costs
|
|
416
|
-
- **[Error Handling](./docs/ERROR_HANDLING.md)** - Recovery strategies
|
|
417
|
-
- **[Testing](./docs/TESTING.md)** - Mocking and test strategies
|
|
418
|
-
|
|
419
|
-
**Reference**
|
|
420
|
-
- **[CLI Reference](./docs/CLI.md)** - Command-line interface
|
|
421
|
-
- **[Architecture](./docs/ARCHITECTURE.md)** - Technical deep-dive
|
|
422
|
-
- **[Debugging](./docs/DEBUGGING.md)** - Capture raw prompts/responses
|
|
423
|
-
- **[Troubleshooting](./docs/TROUBLESHOOTING.md)** - Common issues
|
|
424
|
-
|
|
425
|
-
---
|
|
426
|
-
|
|
427
|
-
## π Examples
|
|
428
|
-
|
|
429
|
-
Comprehensive examples are available in the **[examples/](./examples/)** directory:
|
|
430
|
-
|
|
431
|
-
| Example | Description |
|
|
432
|
-
|---------|-------------|
|
|
433
|
-
| **[01-basic-usage.ts](./examples/01-basic-usage.ts)** | Simple agent with calculator gadget |
|
|
434
|
-
| **[02-custom-gadgets.ts](./examples/02-custom-gadgets.ts)** | Async gadgets, validation, loop termination |
|
|
435
|
-
| **[03-hooks.ts](./examples/03-hooks.ts)** | Lifecycle hooks for monitoring |
|
|
436
|
-
| **[04-human-in-loop.ts](./examples/04-human-in-loop.ts)** | Interactive conversations |
|
|
437
|
-
| **[05-streaming.ts](./examples/05-streaming.ts)** | Real-time streaming |
|
|
438
|
-
| **[06-model-catalog.ts](./examples/06-model-catalog.ts)** | Model queries and cost estimation |
|
|
439
|
-
| **[07-logging.ts](./examples/07-logging.ts)** | Logging and debugging |
|
|
440
|
-
| **[11-gadget-dependencies.ts](./examples/11-gadget-dependencies.ts)** | Gadget dependencies (DAG execution) |
|
|
441
|
-
| **[13-syntactic-sugar.ts](./examples/13-syntactic-sugar.ts)** | Fluent API showcase |
|
|
442
|
-
| **[14-hints.ts](./examples/14-hints.ts)** | LLM assistance hints |
|
|
443
|
-
| **[16-image-generation.ts](./examples/16-image-generation.ts)** | Image generation with DALL-E |
|
|
444
|
-
| **[17-speech-generation.ts](./examples/17-speech-generation.ts)** | Text-to-speech generation |
|
|
445
|
-
| **[20-external-gadgets.ts](./examples/20-external-gadgets.ts)** | npm/git gadget packages |
|
|
446
|
-
|
|
447
|
-
**Run any example:**
|
|
448
|
-
```bash
|
|
449
|
-
bun install && bun run build
|
|
450
|
-
bunx tsx examples/01-basic-usage.ts
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
See **[examples/README.md](./examples/README.md)** for full list and details.
|
|
454
|
-
|
|
455
|
-
---
|
|
456
|
-
|
|
457
|
-
## ποΈ Architecture
|
|
458
|
-
|
|
459
|
-
llmist follows **SOLID principles** with a composable architecture.
|
|
460
|
-
|
|
461
|
-
**Key components:**
|
|
462
|
-
- **LLMist** - Provider-agnostic streaming client
|
|
463
|
-
- **Agent** - Full agent loop with automatic orchestration
|
|
464
|
-
- **StreamProcessor** - Process LLM streams with custom event loops
|
|
465
|
-
- **GadgetExecutor** - Execute tools with timeout and error handling
|
|
466
|
-
- **GadgetRegistry** - Registry for available tools
|
|
467
|
-
|
|
468
|
-
π **[Architecture Guide](./docs/ARCHITECTURE.md)** for detailed design documentation
|
|
469
|
-
|
|
470
|
-
---
|
|
471
|
-
|
|
472
|
-
## π§ͺ Development
|
|
473
|
-
|
|
474
|
-
```bash
|
|
475
|
-
bun install
|
|
476
|
-
|
|
477
|
-
# Run tests
|
|
478
|
-
bun test # All tests
|
|
479
|
-
bun run test:unit # Unit tests only
|
|
480
|
-
bun run test:e2e # E2E tests only
|
|
481
|
-
|
|
482
|
-
# Build and lint
|
|
483
|
-
bun run build
|
|
484
|
-
bun run lint
|
|
485
|
-
bun run format
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
---
|
|
489
|
-
|
|
490
|
-
## π€ Contributing
|
|
491
|
-
|
|
492
|
-
Contributions welcome! See **[CONTRIBUTING.md](./CONTRIBUTING.md)** for guidelines, commit conventions, and release process.
|
|
493
|
-
|
|
494
|
-
---
|
|
495
|
-
|
|
496
|
-
## π License
|
|
497
|
-
|
|
498
|
-
MIT - see [LICENSE](./LICENSE) for details.
|
|
499
|
-
|
|
500
|
-
---
|
|
501
|
-
|
|
502
|
-
## π Links
|
|
503
|
-
|
|
504
|
-
- π¦ [npm Package](https://www.npmjs.com/package/llmist)
|
|
505
|
-
- π [GitHub Repository](https://github.com/zbigniewsobiecki/llmist)
|
|
506
|
-
- π [Full Documentation](./docs/)
|
|
507
|
-
- π [Issue Tracker](https://github.com/zbigniewsobiecki/llmist/issues)
|
|
508
|
-
|
|
509
|
-
---
|
|
510
|
-
|
|
511
|
-
Made with π€ͺ by the llmist team
|