llmist 9.1.2 → 9.3.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 +104 -0
- package/dist/index.cjs +386 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +875 -6
- package/dist/index.d.ts +875 -6
- package/dist/index.js +361 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# llmist
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://github.com/zbigniewsobiecki/llmist/actions/workflows/ci.yml"><img src="https://github.com/zbigniewsobiecki/llmist/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
5
|
+
<a href="https://codecov.io/gh/zbigniewsobiecki/llmist"><img src="https://codecov.io/gh/zbigniewsobiecki/llmist/graph/badge.svg?branch=dev" alt="codecov"></a>
|
|
6
|
+
<a href="https://www.npmjs.com/package/llmist"><img src="https://img.shields.io/npm/v/llmist.svg" alt="npm version"></a>
|
|
7
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License"></a>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
**Streaming-first multi-provider LLM client in TypeScript with home-made tool calling.**
|
|
11
|
+
|
|
12
|
+
llmist implements its own tool calling syntax called "gadgets" - tools execute the moment their block is parsed, not after the response completes. Works with any model that can follow instructions.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install llmist
|
|
18
|
+
# or
|
|
19
|
+
bun add llmist
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { Gadget, LLMist, z } from 'llmist';
|
|
26
|
+
|
|
27
|
+
// Define a gadget (tool) with Zod schema
|
|
28
|
+
class Calculator extends Gadget({
|
|
29
|
+
description: 'Performs arithmetic operations',
|
|
30
|
+
schema: z.object({
|
|
31
|
+
operation: z.enum(['add', 'subtract', 'multiply', 'divide']),
|
|
32
|
+
a: z.number(),
|
|
33
|
+
b: z.number(),
|
|
34
|
+
}),
|
|
35
|
+
}) {
|
|
36
|
+
execute(params: this['params']): string {
|
|
37
|
+
const { operation, a, b } = params;
|
|
38
|
+
switch (operation) {
|
|
39
|
+
case 'add': return String(a + b);
|
|
40
|
+
case 'subtract': return String(a - b);
|
|
41
|
+
case 'multiply': return String(a * b);
|
|
42
|
+
case 'divide': return String(a / b);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Run the agent
|
|
48
|
+
const answer = await LLMist.createAgent()
|
|
49
|
+
.withModel('sonnet')
|
|
50
|
+
.withGadgets(Calculator)
|
|
51
|
+
.askAndCollect('What is 15 times 23?');
|
|
52
|
+
|
|
53
|
+
console.log(answer);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Features
|
|
57
|
+
|
|
58
|
+
- **Streaming-first** - Tools execute mid-stream, not after response completes
|
|
59
|
+
- **Multi-provider** - OpenAI, Anthropic, Gemini with unified API
|
|
60
|
+
- **Type-safe** - Full TypeScript inference from Zod schemas
|
|
61
|
+
- **Flexible hooks** - Observers, interceptors, and controllers for deep integration
|
|
62
|
+
- **Built-in cost tracking** - Real-time token counting and cost estimation
|
|
63
|
+
- **Multimodal** - Vision and audio input support
|
|
64
|
+
|
|
65
|
+
## Providers
|
|
66
|
+
|
|
67
|
+
Set one of these environment variables:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
export OPENAI_API_KEY="sk-..."
|
|
71
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
72
|
+
export GEMINI_API_KEY="..."
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Use model aliases for convenience:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
.withModel('sonnet') // Claude 3.5 Sonnet
|
|
79
|
+
.withModel('opus') // Claude Opus 4
|
|
80
|
+
.withModel('gpt4o') // GPT-4o
|
|
81
|
+
.withModel('flash') // Gemini 2.0 Flash
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Documentation
|
|
85
|
+
|
|
86
|
+
Full documentation at [llmist.dev](https://llmist.dev)
|
|
87
|
+
|
|
88
|
+
- [Getting Started](https://llmist.dev/library/getting-started/introduction/)
|
|
89
|
+
- [Creating Gadgets](https://llmist.dev/library/guides/creating-gadgets/)
|
|
90
|
+
- [Hooks System](https://llmist.dev/library/guides/hooks/)
|
|
91
|
+
- [Provider Configuration](https://llmist.dev/library/providers/overview/)
|
|
92
|
+
|
|
93
|
+
## Examples
|
|
94
|
+
|
|
95
|
+
See the [examples directory](https://github.com/zbigniewsobiecki/llmist/tree/main/examples) for runnable examples covering all features.
|
|
96
|
+
|
|
97
|
+
## Related Packages
|
|
98
|
+
|
|
99
|
+
- [`@llmist/cli`](https://www.npmjs.com/package/@llmist/cli) - Command-line interface
|
|
100
|
+
- [`@llmist/testing`](https://www.npmjs.com/package/@llmist/testing) - Testing utilities and mocks
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -1272,7 +1272,11 @@ var init_messages = __esm({
|
|
|
1272
1272
|
parts.push("\n=================\n");
|
|
1273
1273
|
for (const gadget of gadgets) {
|
|
1274
1274
|
const gadgetName = gadget.name ?? gadget.constructor.name;
|
|
1275
|
-
const instruction = gadget.getInstruction(
|
|
1275
|
+
const instruction = gadget.getInstruction({
|
|
1276
|
+
argPrefix: this.argPrefix,
|
|
1277
|
+
startPrefix: this.startPrefix,
|
|
1278
|
+
endPrefix: this.endPrefix
|
|
1279
|
+
});
|
|
1276
1280
|
const schemaMarker = "\n\nInput Schema (BLOCK):";
|
|
1277
1281
|
const schemaIndex = instruction.indexOf(schemaMarker);
|
|
1278
1282
|
const description = (schemaIndex !== -1 ? instruction.substring(0, schemaIndex) : instruction).trim();
|
|
@@ -6017,13 +6021,13 @@ var init_openai = __esm({
|
|
|
6017
6021
|
async generateSpeech(options) {
|
|
6018
6022
|
const client = this.client;
|
|
6019
6023
|
const spec = getOpenAISpeechModelSpec(options.model);
|
|
6020
|
-
const
|
|
6024
|
+
const format2 = options.responseFormat ?? spec?.defaultFormat ?? "mp3";
|
|
6021
6025
|
const voice = options.voice ?? spec?.defaultVoice ?? "alloy";
|
|
6022
6026
|
const response = await client.audio.speech.create({
|
|
6023
6027
|
model: options.model,
|
|
6024
6028
|
input: options.input,
|
|
6025
6029
|
voice,
|
|
6026
|
-
response_format:
|
|
6030
|
+
response_format: format2,
|
|
6027
6031
|
speed: options.speed ?? 1
|
|
6028
6032
|
});
|
|
6029
6033
|
const audioBuffer = await response.arrayBuffer();
|
|
@@ -6035,7 +6039,7 @@ var init_openai = __esm({
|
|
|
6035
6039
|
characterCount: options.input.length
|
|
6036
6040
|
},
|
|
6037
6041
|
cost,
|
|
6038
|
-
format
|
|
6042
|
+
format: format2
|
|
6039
6043
|
};
|
|
6040
6044
|
}
|
|
6041
6045
|
buildApiRequest(options, descriptor, spec, messages) {
|
|
@@ -11074,6 +11078,7 @@ __export(index_exports, {
|
|
|
11074
11078
|
Agent: () => Agent,
|
|
11075
11079
|
AgentBuilder: () => AgentBuilder,
|
|
11076
11080
|
AnthropicMessagesProvider: () => AnthropicMessagesProvider,
|
|
11081
|
+
BaseSessionManager: () => BaseSessionManager,
|
|
11077
11082
|
CompactionManager: () => CompactionManager,
|
|
11078
11083
|
ConversationManager: () => ConversationManager,
|
|
11079
11084
|
DEFAULT_COMPACTION_CONFIG: () => DEFAULT_COMPACTION_CONFIG,
|
|
@@ -11102,6 +11107,7 @@ __export(index_exports, {
|
|
|
11102
11107
|
ModelIdentifierParser: () => ModelIdentifierParser,
|
|
11103
11108
|
ModelRegistry: () => ModelRegistry,
|
|
11104
11109
|
OpenAIChatProvider: () => OpenAIChatProvider,
|
|
11110
|
+
SimpleSessionManager: () => SimpleSessionManager,
|
|
11105
11111
|
SlidingWindowStrategy: () => SlidingWindowStrategy,
|
|
11106
11112
|
StreamProcessor: () => StreamProcessor,
|
|
11107
11113
|
SummarizationStrategy: () => SummarizationStrategy,
|
|
@@ -11120,6 +11126,7 @@ __export(index_exports, {
|
|
|
11120
11126
|
createLogger: () => createLogger,
|
|
11121
11127
|
createMediaOutput: () => createMediaOutput,
|
|
11122
11128
|
createOpenAIProviderFromEnv: () => createOpenAIProviderFromEnv,
|
|
11129
|
+
createSubagent: () => createSubagent,
|
|
11123
11130
|
defaultLogger: () => defaultLogger,
|
|
11124
11131
|
detectAudioMimeType: () => detectAudioMimeType,
|
|
11125
11132
|
detectImageMimeType: () => detectImageMimeType,
|
|
@@ -11128,12 +11135,25 @@ __export(index_exports, {
|
|
|
11128
11135
|
filterByDepth: () => filterByDepth,
|
|
11129
11136
|
filterByParent: () => filterByParent,
|
|
11130
11137
|
filterRootEvents: () => filterRootEvents,
|
|
11138
|
+
format: () => format,
|
|
11139
|
+
formatBytes: () => formatBytes,
|
|
11140
|
+
formatDate: () => formatDate,
|
|
11141
|
+
formatDuration: () => formatDuration,
|
|
11131
11142
|
formatLLMError: () => formatLLMError,
|
|
11132
|
-
|
|
11143
|
+
gadgetError: () => gadgetError,
|
|
11144
|
+
gadgetSuccess: () => gadgetSuccess,
|
|
11145
|
+
getErrorMessage: () => getErrorMessage,
|
|
11146
|
+
getHostExports: () => getHostExports2,
|
|
11133
11147
|
getModelId: () => getModelId,
|
|
11148
|
+
getPresetGadgets: () => getPresetGadgets,
|
|
11134
11149
|
getProvider: () => getProvider,
|
|
11150
|
+
getSubagent: () => getSubagent,
|
|
11135
11151
|
groupByParent: () => groupByParent,
|
|
11152
|
+
hasHostExports: () => hasHostExports,
|
|
11153
|
+
hasPreset: () => hasPreset,
|
|
11136
11154
|
hasProviderPrefix: () => hasProviderPrefix,
|
|
11155
|
+
hasSubagents: () => hasSubagents,
|
|
11156
|
+
humanDelay: () => humanDelay,
|
|
11137
11157
|
imageFromBase64: () => imageFromBase64,
|
|
11138
11158
|
imageFromBuffer: () => imageFromBuffer,
|
|
11139
11159
|
imageFromUrl: () => imageFromUrl,
|
|
@@ -11148,9 +11168,13 @@ __export(index_exports, {
|
|
|
11148
11168
|
isSubagentEvent: () => isSubagentEvent,
|
|
11149
11169
|
isTextPart: () => isTextPart,
|
|
11150
11170
|
iterationProgressHint: () => iterationProgressHint,
|
|
11171
|
+
listPresets: () => listPresets,
|
|
11172
|
+
listSubagents: () => listSubagents,
|
|
11151
11173
|
normalizeMessageContent: () => normalizeMessageContent,
|
|
11152
11174
|
parallelGadgetHint: () => parallelGadgetHint,
|
|
11153
11175
|
parseDataUrl: () => parseDataUrl,
|
|
11176
|
+
parseManifest: () => parseManifest,
|
|
11177
|
+
randomDelay: () => randomDelay,
|
|
11154
11178
|
resolveConfig: () => resolveConfig,
|
|
11155
11179
|
resolveHintTemplate: () => resolveHintTemplate,
|
|
11156
11180
|
resolveModel: () => resolveModel,
|
|
@@ -11168,10 +11192,15 @@ __export(index_exports, {
|
|
|
11168
11192
|
schemaToJSONSchema: () => schemaToJSONSchema,
|
|
11169
11193
|
stream: () => stream,
|
|
11170
11194
|
text: () => text,
|
|
11195
|
+
timing: () => timing,
|
|
11171
11196
|
toBase64: () => toBase64,
|
|
11197
|
+
truncate: () => truncate,
|
|
11172
11198
|
validateAndApplyDefaults: () => validateAndApplyDefaults,
|
|
11173
11199
|
validateGadgetParams: () => validateGadgetParams,
|
|
11174
11200
|
validateGadgetSchema: () => validateGadgetSchema,
|
|
11201
|
+
withErrorHandling: () => withErrorHandling,
|
|
11202
|
+
withRetry: () => withRetry,
|
|
11203
|
+
withTimeout: () => withTimeout,
|
|
11175
11204
|
z: () => import_zod3.z
|
|
11176
11205
|
});
|
|
11177
11206
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -11968,17 +11997,17 @@ init_gadget_output_store();
|
|
|
11968
11997
|
// src/agent/hints.ts
|
|
11969
11998
|
init_prompt_config();
|
|
11970
11999
|
function iterationProgressHint(options) {
|
|
11971
|
-
const { timing = "always", showUrgency = true, template } = options ?? {};
|
|
12000
|
+
const { timing: timing2 = "always", showUrgency = true, template } = options ?? {};
|
|
11972
12001
|
return {
|
|
11973
12002
|
controllers: {
|
|
11974
12003
|
beforeLLMCall: async (ctx) => {
|
|
11975
12004
|
const iteration = ctx.iteration + 1;
|
|
11976
12005
|
const maxIterations = ctx.maxIterations;
|
|
11977
12006
|
const progress = iteration / maxIterations;
|
|
11978
|
-
if (
|
|
12007
|
+
if (timing2 === "late" && progress < 0.5) {
|
|
11979
12008
|
return { action: "proceed" };
|
|
11980
12009
|
}
|
|
11981
|
-
if (
|
|
12010
|
+
if (timing2 === "urgent" && progress < 0.8) {
|
|
11982
12011
|
return { action: "proceed" };
|
|
11983
12012
|
}
|
|
11984
12013
|
const remaining = maxIterations - iteration;
|
|
@@ -12139,6 +12168,24 @@ init_typed_gadget();
|
|
|
12139
12168
|
|
|
12140
12169
|
// src/gadgets/helpers.ts
|
|
12141
12170
|
init_input_content();
|
|
12171
|
+
function gadgetSuccess(data = {}) {
|
|
12172
|
+
return JSON.stringify({ success: true, ...data });
|
|
12173
|
+
}
|
|
12174
|
+
function gadgetError(message, details) {
|
|
12175
|
+
return JSON.stringify({ error: message, ...details });
|
|
12176
|
+
}
|
|
12177
|
+
function getErrorMessage(error) {
|
|
12178
|
+
return error instanceof Error ? error.message : String(error);
|
|
12179
|
+
}
|
|
12180
|
+
function withErrorHandling(execute) {
|
|
12181
|
+
return async (params, ctx) => {
|
|
12182
|
+
try {
|
|
12183
|
+
return await execute(params, ctx);
|
|
12184
|
+
} catch (error) {
|
|
12185
|
+
return gadgetError(getErrorMessage(error));
|
|
12186
|
+
}
|
|
12187
|
+
};
|
|
12188
|
+
}
|
|
12142
12189
|
function createMediaOutput(kind, data, mimeType, options) {
|
|
12143
12190
|
const buffer = data instanceof Buffer ? data : Buffer.from(data);
|
|
12144
12191
|
return {
|
|
@@ -12334,7 +12381,313 @@ init_anthropic();
|
|
|
12334
12381
|
init_discovery();
|
|
12335
12382
|
init_gemini();
|
|
12336
12383
|
init_openai();
|
|
12384
|
+
|
|
12385
|
+
// src/utils/format.ts
|
|
12386
|
+
function truncate(text3, maxLength, suffix = "...") {
|
|
12387
|
+
if (text3.length <= maxLength) return text3;
|
|
12388
|
+
const truncateAt = maxLength - suffix.length;
|
|
12389
|
+
if (truncateAt <= 0) return suffix.slice(0, maxLength);
|
|
12390
|
+
return text3.slice(0, truncateAt) + suffix;
|
|
12391
|
+
}
|
|
12392
|
+
function formatBytes(bytes, decimals = 1) {
|
|
12393
|
+
if (bytes === 0) return "0 B";
|
|
12394
|
+
const k = 1024;
|
|
12395
|
+
const sizes = ["B", "KB", "MB", "GB", "TB", "PB"];
|
|
12396
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
12397
|
+
const size = bytes / Math.pow(k, i);
|
|
12398
|
+
const formatted = size % 1 === 0 ? size.toString() : size.toFixed(decimals);
|
|
12399
|
+
return `${formatted} ${sizes[i]}`;
|
|
12400
|
+
}
|
|
12401
|
+
function formatDate(isoDate, options = {
|
|
12402
|
+
year: "numeric",
|
|
12403
|
+
month: "short",
|
|
12404
|
+
day: "numeric",
|
|
12405
|
+
hour: "2-digit",
|
|
12406
|
+
minute: "2-digit"
|
|
12407
|
+
}) {
|
|
12408
|
+
try {
|
|
12409
|
+
const date = new Date(isoDate);
|
|
12410
|
+
return date.toLocaleString(void 0, options);
|
|
12411
|
+
} catch {
|
|
12412
|
+
return isoDate;
|
|
12413
|
+
}
|
|
12414
|
+
}
|
|
12415
|
+
function formatDuration(ms, options = {}) {
|
|
12416
|
+
if (ms < 1e3) {
|
|
12417
|
+
return `${Math.round(ms)}ms`;
|
|
12418
|
+
}
|
|
12419
|
+
const seconds = Math.floor(ms / 1e3);
|
|
12420
|
+
const minutes = Math.floor(seconds / 60);
|
|
12421
|
+
const hours = Math.floor(minutes / 60);
|
|
12422
|
+
if (hours > 0) {
|
|
12423
|
+
const remainingMinutes = minutes % 60;
|
|
12424
|
+
const remainingSeconds = seconds % 60;
|
|
12425
|
+
if (options.compact) {
|
|
12426
|
+
return `${hours}h ${remainingMinutes}m`;
|
|
12427
|
+
}
|
|
12428
|
+
return remainingSeconds > 0 ? `${hours}h ${remainingMinutes}m ${remainingSeconds}s` : `${hours}h ${remainingMinutes}m`;
|
|
12429
|
+
}
|
|
12430
|
+
if (minutes > 0) {
|
|
12431
|
+
const remainingSeconds = seconds % 60;
|
|
12432
|
+
return remainingSeconds > 0 ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
|
|
12433
|
+
}
|
|
12434
|
+
const secs = ms / 1e3;
|
|
12435
|
+
return secs % 1 === 0 ? `${secs}s` : `${secs.toFixed(1)}s`;
|
|
12436
|
+
}
|
|
12437
|
+
var format = {
|
|
12438
|
+
truncate,
|
|
12439
|
+
bytes: formatBytes,
|
|
12440
|
+
date: formatDate,
|
|
12441
|
+
duration: formatDuration
|
|
12442
|
+
};
|
|
12443
|
+
|
|
12444
|
+
// src/utils/timing.ts
|
|
12445
|
+
function randomDelay(min, max) {
|
|
12446
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
12447
|
+
}
|
|
12448
|
+
async function humanDelay(min = 50, max = 150) {
|
|
12449
|
+
const delay = randomDelay(min, max);
|
|
12450
|
+
return new Promise((resolve) => setTimeout(resolve, delay));
|
|
12451
|
+
}
|
|
12452
|
+
async function withTimeout(fn, timeoutMs, signal) {
|
|
12453
|
+
return new Promise((resolve, reject) => {
|
|
12454
|
+
if (signal?.aborted) {
|
|
12455
|
+
reject(new Error("Operation aborted"));
|
|
12456
|
+
return;
|
|
12457
|
+
}
|
|
12458
|
+
let settled = false;
|
|
12459
|
+
const timeoutId = setTimeout(() => {
|
|
12460
|
+
if (!settled) {
|
|
12461
|
+
settled = true;
|
|
12462
|
+
reject(new Error(`Operation timed out after ${timeoutMs}ms`));
|
|
12463
|
+
}
|
|
12464
|
+
}, timeoutMs);
|
|
12465
|
+
const abortHandler = () => {
|
|
12466
|
+
if (!settled) {
|
|
12467
|
+
settled = true;
|
|
12468
|
+
clearTimeout(timeoutId);
|
|
12469
|
+
reject(new Error("Operation aborted"));
|
|
12470
|
+
}
|
|
12471
|
+
};
|
|
12472
|
+
signal?.addEventListener("abort", abortHandler);
|
|
12473
|
+
fn().then((result) => {
|
|
12474
|
+
if (!settled) {
|
|
12475
|
+
settled = true;
|
|
12476
|
+
clearTimeout(timeoutId);
|
|
12477
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
12478
|
+
resolve(result);
|
|
12479
|
+
}
|
|
12480
|
+
}).catch((error) => {
|
|
12481
|
+
if (!settled) {
|
|
12482
|
+
settled = true;
|
|
12483
|
+
clearTimeout(timeoutId);
|
|
12484
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
12485
|
+
reject(error);
|
|
12486
|
+
}
|
|
12487
|
+
});
|
|
12488
|
+
});
|
|
12489
|
+
}
|
|
12490
|
+
async function withRetry(fn, options = {}) {
|
|
12491
|
+
const {
|
|
12492
|
+
maxRetries = 3,
|
|
12493
|
+
delay = 1e3,
|
|
12494
|
+
backoff = "exponential",
|
|
12495
|
+
maxDelay = 3e4,
|
|
12496
|
+
shouldRetry = () => true,
|
|
12497
|
+
onRetry
|
|
12498
|
+
} = options;
|
|
12499
|
+
let lastError;
|
|
12500
|
+
let currentDelay = delay;
|
|
12501
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
12502
|
+
try {
|
|
12503
|
+
return await fn();
|
|
12504
|
+
} catch (error) {
|
|
12505
|
+
lastError = error;
|
|
12506
|
+
if (attempt >= maxRetries || !shouldRetry(error, attempt)) {
|
|
12507
|
+
throw error;
|
|
12508
|
+
}
|
|
12509
|
+
const waitTime = Math.min(currentDelay, maxDelay);
|
|
12510
|
+
onRetry?.(error, attempt + 1, waitTime);
|
|
12511
|
+
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
12512
|
+
if (backoff === "exponential") {
|
|
12513
|
+
currentDelay *= 2;
|
|
12514
|
+
} else {
|
|
12515
|
+
currentDelay += delay;
|
|
12516
|
+
}
|
|
12517
|
+
}
|
|
12518
|
+
}
|
|
12519
|
+
throw lastError;
|
|
12520
|
+
}
|
|
12521
|
+
var timing = {
|
|
12522
|
+
randomDelay,
|
|
12523
|
+
humanDelay,
|
|
12524
|
+
withTimeout,
|
|
12525
|
+
withRetry
|
|
12526
|
+
};
|
|
12527
|
+
|
|
12528
|
+
// src/session/manager.ts
|
|
12529
|
+
var BaseSessionManager = class {
|
|
12530
|
+
/** Map of session ID to session object */
|
|
12531
|
+
sessions = /* @__PURE__ */ new Map();
|
|
12532
|
+
/** Counter for generating unique session IDs */
|
|
12533
|
+
idCounter = 0;
|
|
12534
|
+
/**
|
|
12535
|
+
* Generate a unique session ID with the given prefix.
|
|
12536
|
+
*
|
|
12537
|
+
* @param prefix - Prefix for the ID (e.g., "p" for pages, "b" for browsers)
|
|
12538
|
+
* @returns Unique ID like "p1", "p2", etc.
|
|
12539
|
+
*/
|
|
12540
|
+
generateId(prefix) {
|
|
12541
|
+
return `${prefix}${++this.idCounter}`;
|
|
12542
|
+
}
|
|
12543
|
+
/**
|
|
12544
|
+
* Get a session by ID.
|
|
12545
|
+
*/
|
|
12546
|
+
getSession(id) {
|
|
12547
|
+
return this.sessions.get(id);
|
|
12548
|
+
}
|
|
12549
|
+
/**
|
|
12550
|
+
* Get a session by ID, throwing if not found.
|
|
12551
|
+
*/
|
|
12552
|
+
requireSession(id) {
|
|
12553
|
+
const session = this.sessions.get(id);
|
|
12554
|
+
if (!session) {
|
|
12555
|
+
throw new Error(`Session not found: ${id}`);
|
|
12556
|
+
}
|
|
12557
|
+
return session;
|
|
12558
|
+
}
|
|
12559
|
+
/**
|
|
12560
|
+
* List all active session IDs.
|
|
12561
|
+
*/
|
|
12562
|
+
listSessions() {
|
|
12563
|
+
return Array.from(this.sessions.keys());
|
|
12564
|
+
}
|
|
12565
|
+
/**
|
|
12566
|
+
* Check if a session exists.
|
|
12567
|
+
*/
|
|
12568
|
+
hasSession(id) {
|
|
12569
|
+
return this.sessions.has(id);
|
|
12570
|
+
}
|
|
12571
|
+
/**
|
|
12572
|
+
* Close all sessions.
|
|
12573
|
+
* Closes sessions in reverse order (most recent first).
|
|
12574
|
+
*/
|
|
12575
|
+
async closeAll() {
|
|
12576
|
+
const ids = this.listSessions().reverse();
|
|
12577
|
+
for (const id of ids) {
|
|
12578
|
+
try {
|
|
12579
|
+
await this.closeSession(id);
|
|
12580
|
+
} catch {
|
|
12581
|
+
}
|
|
12582
|
+
}
|
|
12583
|
+
}
|
|
12584
|
+
};
|
|
12585
|
+
var SimpleSessionManager = class extends BaseSessionManager {
|
|
12586
|
+
/**
|
|
12587
|
+
* Create a session by storing the provided data.
|
|
12588
|
+
*/
|
|
12589
|
+
async createSession(data) {
|
|
12590
|
+
const id = this.generateId("s");
|
|
12591
|
+
if (data !== void 0) {
|
|
12592
|
+
this.sessions.set(id, data);
|
|
12593
|
+
}
|
|
12594
|
+
return id;
|
|
12595
|
+
}
|
|
12596
|
+
/**
|
|
12597
|
+
* Close a session by removing it from the map.
|
|
12598
|
+
*/
|
|
12599
|
+
async closeSession(id) {
|
|
12600
|
+
this.sessions.delete(id);
|
|
12601
|
+
}
|
|
12602
|
+
/**
|
|
12603
|
+
* Set session data directly.
|
|
12604
|
+
*/
|
|
12605
|
+
setSession(id, data) {
|
|
12606
|
+
this.sessions.set(id, data);
|
|
12607
|
+
}
|
|
12608
|
+
};
|
|
12609
|
+
|
|
12610
|
+
// src/agent/subagent.ts
|
|
12337
12611
|
function getHostExports(ctx) {
|
|
12612
|
+
if (!ctx?.hostExports) {
|
|
12613
|
+
throw new Error(
|
|
12614
|
+
"hostExports not available. Subagent gadgets must be run via llmist agent. Ensure you are using llmist >= 6.2.0 and running through the CLI or AgentBuilder."
|
|
12615
|
+
);
|
|
12616
|
+
}
|
|
12617
|
+
return ctx.hostExports;
|
|
12618
|
+
}
|
|
12619
|
+
function createSubagent(ctx, options) {
|
|
12620
|
+
const {
|
|
12621
|
+
name,
|
|
12622
|
+
gadgets,
|
|
12623
|
+
systemPrompt,
|
|
12624
|
+
model: runtimeModel,
|
|
12625
|
+
defaultModel = "sonnet",
|
|
12626
|
+
maxIterations: runtimeMaxIterations,
|
|
12627
|
+
defaultMaxIterations = 15,
|
|
12628
|
+
hooks,
|
|
12629
|
+
temperature
|
|
12630
|
+
} = options;
|
|
12631
|
+
const { AgentBuilder: AgentBuilder2, LLMist: LLMist2 } = getHostExports(ctx);
|
|
12632
|
+
const client = new LLMist2();
|
|
12633
|
+
const model = resolveSubagentModel(ctx, name, runtimeModel, defaultModel);
|
|
12634
|
+
const maxIterations = resolveValue(ctx, name, {
|
|
12635
|
+
runtime: runtimeMaxIterations,
|
|
12636
|
+
subagentKey: "maxIterations",
|
|
12637
|
+
defaultValue: defaultMaxIterations
|
|
12638
|
+
});
|
|
12639
|
+
let builder = new AgentBuilder2(client).withModel(model).withGadgets(...gadgets).withMaxIterations(maxIterations).withParentContext(ctx);
|
|
12640
|
+
if (systemPrompt) {
|
|
12641
|
+
builder = builder.withSystem(systemPrompt);
|
|
12642
|
+
}
|
|
12643
|
+
if (hooks) {
|
|
12644
|
+
builder = builder.withHooks(hooks);
|
|
12645
|
+
}
|
|
12646
|
+
if (temperature !== void 0) {
|
|
12647
|
+
builder = builder.withTemperature(temperature);
|
|
12648
|
+
}
|
|
12649
|
+
if (ctx.logger) {
|
|
12650
|
+
builder = builder.withLogger(ctx.logger);
|
|
12651
|
+
}
|
|
12652
|
+
return builder;
|
|
12653
|
+
}
|
|
12654
|
+
function hasHostExports(ctx) {
|
|
12655
|
+
return ctx?.hostExports !== void 0;
|
|
12656
|
+
}
|
|
12657
|
+
|
|
12658
|
+
// src/package/manifest.ts
|
|
12659
|
+
function parseManifest(packageJson) {
|
|
12660
|
+
const llmist = packageJson.llmist;
|
|
12661
|
+
if (!llmist || typeof llmist !== "object") {
|
|
12662
|
+
return void 0;
|
|
12663
|
+
}
|
|
12664
|
+
return llmist;
|
|
12665
|
+
}
|
|
12666
|
+
function hasPreset(manifest, presetName) {
|
|
12667
|
+
return manifest?.presets?.[presetName] !== void 0;
|
|
12668
|
+
}
|
|
12669
|
+
function getPresetGadgets(manifest, presetName) {
|
|
12670
|
+
const preset = manifest?.presets?.[presetName];
|
|
12671
|
+
if (preset === void 0) return void 0;
|
|
12672
|
+
return preset;
|
|
12673
|
+
}
|
|
12674
|
+
function hasSubagents(manifest) {
|
|
12675
|
+
return manifest?.subagents !== void 0 && Object.keys(manifest.subagents).length > 0;
|
|
12676
|
+
}
|
|
12677
|
+
function getSubagent(manifest, name) {
|
|
12678
|
+
return manifest?.subagents?.[name];
|
|
12679
|
+
}
|
|
12680
|
+
function listSubagents(manifest) {
|
|
12681
|
+
if (!manifest?.subagents) return [];
|
|
12682
|
+
return Object.keys(manifest.subagents);
|
|
12683
|
+
}
|
|
12684
|
+
function listPresets(manifest) {
|
|
12685
|
+
if (!manifest?.presets) return [];
|
|
12686
|
+
return Object.keys(manifest.presets);
|
|
12687
|
+
}
|
|
12688
|
+
|
|
12689
|
+
// src/index.ts
|
|
12690
|
+
function getHostExports2(ctx) {
|
|
12338
12691
|
if (!ctx?.hostExports) {
|
|
12339
12692
|
throw new Error(
|
|
12340
12693
|
"hostExports not available. Gadgets that create subagents must be run via llmist agent, not standalone. Ensure you are using llmist >= 6.2.0."
|
|
@@ -12349,6 +12702,7 @@ function getHostExports(ctx) {
|
|
|
12349
12702
|
Agent,
|
|
12350
12703
|
AgentBuilder,
|
|
12351
12704
|
AnthropicMessagesProvider,
|
|
12705
|
+
BaseSessionManager,
|
|
12352
12706
|
CompactionManager,
|
|
12353
12707
|
ConversationManager,
|
|
12354
12708
|
DEFAULT_COMPACTION_CONFIG,
|
|
@@ -12377,6 +12731,7 @@ function getHostExports(ctx) {
|
|
|
12377
12731
|
ModelIdentifierParser,
|
|
12378
12732
|
ModelRegistry,
|
|
12379
12733
|
OpenAIChatProvider,
|
|
12734
|
+
SimpleSessionManager,
|
|
12380
12735
|
SlidingWindowStrategy,
|
|
12381
12736
|
StreamProcessor,
|
|
12382
12737
|
SummarizationStrategy,
|
|
@@ -12395,6 +12750,7 @@ function getHostExports(ctx) {
|
|
|
12395
12750
|
createLogger,
|
|
12396
12751
|
createMediaOutput,
|
|
12397
12752
|
createOpenAIProviderFromEnv,
|
|
12753
|
+
createSubagent,
|
|
12398
12754
|
defaultLogger,
|
|
12399
12755
|
detectAudioMimeType,
|
|
12400
12756
|
detectImageMimeType,
|
|
@@ -12403,12 +12759,25 @@ function getHostExports(ctx) {
|
|
|
12403
12759
|
filterByDepth,
|
|
12404
12760
|
filterByParent,
|
|
12405
12761
|
filterRootEvents,
|
|
12762
|
+
format,
|
|
12763
|
+
formatBytes,
|
|
12764
|
+
formatDate,
|
|
12765
|
+
formatDuration,
|
|
12406
12766
|
formatLLMError,
|
|
12767
|
+
gadgetError,
|
|
12768
|
+
gadgetSuccess,
|
|
12769
|
+
getErrorMessage,
|
|
12407
12770
|
getHostExports,
|
|
12408
12771
|
getModelId,
|
|
12772
|
+
getPresetGadgets,
|
|
12409
12773
|
getProvider,
|
|
12774
|
+
getSubagent,
|
|
12410
12775
|
groupByParent,
|
|
12776
|
+
hasHostExports,
|
|
12777
|
+
hasPreset,
|
|
12411
12778
|
hasProviderPrefix,
|
|
12779
|
+
hasSubagents,
|
|
12780
|
+
humanDelay,
|
|
12412
12781
|
imageFromBase64,
|
|
12413
12782
|
imageFromBuffer,
|
|
12414
12783
|
imageFromUrl,
|
|
@@ -12423,9 +12792,13 @@ function getHostExports(ctx) {
|
|
|
12423
12792
|
isSubagentEvent,
|
|
12424
12793
|
isTextPart,
|
|
12425
12794
|
iterationProgressHint,
|
|
12795
|
+
listPresets,
|
|
12796
|
+
listSubagents,
|
|
12426
12797
|
normalizeMessageContent,
|
|
12427
12798
|
parallelGadgetHint,
|
|
12428
12799
|
parseDataUrl,
|
|
12800
|
+
parseManifest,
|
|
12801
|
+
randomDelay,
|
|
12429
12802
|
resolveConfig,
|
|
12430
12803
|
resolveHintTemplate,
|
|
12431
12804
|
resolveModel,
|
|
@@ -12443,10 +12816,15 @@ function getHostExports(ctx) {
|
|
|
12443
12816
|
schemaToJSONSchema,
|
|
12444
12817
|
stream,
|
|
12445
12818
|
text,
|
|
12819
|
+
timing,
|
|
12446
12820
|
toBase64,
|
|
12821
|
+
truncate,
|
|
12447
12822
|
validateAndApplyDefaults,
|
|
12448
12823
|
validateGadgetParams,
|
|
12449
12824
|
validateGadgetSchema,
|
|
12825
|
+
withErrorHandling,
|
|
12826
|
+
withRetry,
|
|
12827
|
+
withTimeout,
|
|
12450
12828
|
z
|
|
12451
12829
|
});
|
|
12452
12830
|
//# sourceMappingURL=index.cjs.map
|