llmist 0.1.3 → 0.1.5
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 +67 -12
- package/dist/{chunk-TP7HE3MN.js → chunk-J3NCIWMY.js} +34 -36
- package/dist/chunk-J3NCIWMY.js.map +1 -0
- package/dist/{chunk-JEBGLCDW.js → chunk-MO5ONHPZ.js} +2 -2
- package/dist/{chunk-DCW33WV7.js → chunk-PVHHXDCV.js} +2 -2
- package/dist/cli.cjs +161 -92
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +130 -59
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +368 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +376 -50
- package/dist/index.d.ts +376 -50
- package/dist/index.js +338 -43
- package/dist/index.js.map +1 -1
- package/dist/{mock-stream-D4erlo7B.d.cts → mock-stream-C2sBQlvc.d.cts} +1 -2
- package/dist/{mock-stream-D4erlo7B.d.ts → mock-stream-C2sBQlvc.d.ts} +1 -2
- package/dist/testing/index.cjs +33 -35
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +2 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +2 -2
- package/package.json +2 -2
- package/dist/chunk-TP7HE3MN.js.map +0 -1
- /package/dist/{chunk-JEBGLCDW.js.map → chunk-MO5ONHPZ.js.map} +0 -0
- /package/dist/{chunk-DCW33WV7.js.map → chunk-PVHHXDCV.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -436,14 +436,15 @@ var init_messages = __esm({
|
|
|
436
436
|
context
|
|
437
437
|
);
|
|
438
438
|
parts.push(mainInstruction);
|
|
439
|
-
parts.push(this.
|
|
439
|
+
parts.push(this.buildGadgetsSection(gadgets, parameterFormat));
|
|
440
440
|
parts.push(this.buildUsageSection(parameterFormat, context));
|
|
441
441
|
this.messages.push({ role: "system", content: parts.join("") });
|
|
442
442
|
return this;
|
|
443
443
|
}
|
|
444
|
-
|
|
444
|
+
buildGadgetsSection(gadgets, parameterFormat) {
|
|
445
445
|
const parts = [];
|
|
446
|
-
parts.push("
|
|
446
|
+
parts.push("\n\nAVAILABLE GADGETS");
|
|
447
|
+
parts.push("\n=================\n");
|
|
447
448
|
for (const gadget of gadgets) {
|
|
448
449
|
const gadgetName = gadget.name ?? gadget.constructor.name;
|
|
449
450
|
const instruction = gadget.getInstruction(parameterFormat);
|
|
@@ -451,18 +452,17 @@ var init_messages = __esm({
|
|
|
451
452
|
const schemaIndex = instruction.indexOf(schemaMarker);
|
|
452
453
|
const description = (schemaIndex !== -1 ? instruction.substring(0, schemaIndex) : instruction).trim();
|
|
453
454
|
const schema = schemaIndex !== -1 ? instruction.substring(schemaIndex + schemaMarker.length).trim() : "";
|
|
454
|
-
parts.push("\n <gadget>");
|
|
455
455
|
parts.push(`
|
|
456
|
-
|
|
456
|
+
GADGET: ${gadgetName}`);
|
|
457
457
|
parts.push(`
|
|
458
|
-
|
|
458
|
+
${description}`);
|
|
459
459
|
if (schema) {
|
|
460
460
|
parts.push(`
|
|
461
|
-
|
|
462
|
-
${
|
|
463
|
-
|
|
461
|
+
|
|
462
|
+
PARAMETERS (${parameterFormat.toUpperCase()}):
|
|
463
|
+
${schema}`);
|
|
464
464
|
}
|
|
465
|
-
parts.push("\n
|
|
465
|
+
parts.push("\n\n---");
|
|
466
466
|
}
|
|
467
467
|
return parts.join("");
|
|
468
468
|
}
|
|
@@ -477,26 +477,26 @@ ${schema}
|
|
|
477
477
|
DEFAULT_PROMPTS.formatDescriptionJson,
|
|
478
478
|
context
|
|
479
479
|
);
|
|
480
|
-
parts.push("
|
|
480
|
+
parts.push("\n\nHOW TO INVOKE GADGETS");
|
|
481
|
+
parts.push("\n=====================\n");
|
|
481
482
|
const criticalUsage = resolvePromptTemplate(
|
|
482
483
|
this.promptConfig.criticalUsage,
|
|
483
484
|
DEFAULT_PROMPTS.criticalUsage,
|
|
484
485
|
context
|
|
485
486
|
);
|
|
486
487
|
parts.push(`
|
|
487
|
-
|
|
488
|
-
|
|
488
|
+
CRITICAL: ${criticalUsage}
|
|
489
|
+
`);
|
|
490
|
+
parts.push("\nFORMAT:");
|
|
489
491
|
parts.push(`
|
|
490
|
-
|
|
492
|
+
1. Start marker: ${this.startPrefix}gadget_name`);
|
|
491
493
|
parts.push(`
|
|
492
|
-
|
|
494
|
+
2. ${formatDescription}`);
|
|
493
495
|
parts.push(`
|
|
494
|
-
|
|
495
|
-
parts.push("\n </format>");
|
|
496
|
+
3. End marker: ${this.endPrefix}`);
|
|
496
497
|
parts.push(this.buildExamplesSection(parameterFormat, context));
|
|
497
498
|
parts.push(this.buildRulesSection(context));
|
|
498
|
-
parts.push("\n
|
|
499
|
-
parts.push("\n</GADGETS>\n\n");
|
|
499
|
+
parts.push("\n");
|
|
500
500
|
return parts.join("");
|
|
501
501
|
}
|
|
502
502
|
buildExamplesSection(parameterFormat, context) {
|
|
@@ -504,7 +504,6 @@ ${schema}
|
|
|
504
504
|
return this.promptConfig.customExamples(context);
|
|
505
505
|
}
|
|
506
506
|
const parts = [];
|
|
507
|
-
parts.push("\n <examples>");
|
|
508
507
|
const singleExample = parameterFormat === "yaml" ? `${this.startPrefix}translate
|
|
509
508
|
from: English
|
|
510
509
|
to: Polish
|
|
@@ -513,9 +512,10 @@ ${this.endPrefix}` : `${this.startPrefix}translate
|
|
|
513
512
|
{"from": "English", "to": "Polish", "content": "Paris is the capital of France."}
|
|
514
513
|
${this.endPrefix}`;
|
|
515
514
|
parts.push(`
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
515
|
+
|
|
516
|
+
EXAMPLE (Single Gadget):
|
|
517
|
+
|
|
518
|
+
${singleExample}`);
|
|
519
519
|
const multipleExample = parameterFormat === "yaml" ? `${this.startPrefix}translate
|
|
520
520
|
from: English
|
|
521
521
|
to: Polish
|
|
@@ -532,21 +532,20 @@ ${this.startPrefix}analyze
|
|
|
532
532
|
{"type": "economic_analysis", "matter": "Polish Economy", "question": "Polish arms exports 2025."}
|
|
533
533
|
${this.endPrefix}`;
|
|
534
534
|
parts.push(`
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
535
|
+
|
|
536
|
+
EXAMPLE (Multiple Gadgets):
|
|
537
|
+
|
|
538
|
+
${multipleExample}`);
|
|
539
539
|
return parts.join("");
|
|
540
540
|
}
|
|
541
541
|
buildRulesSection(context) {
|
|
542
542
|
const parts = [];
|
|
543
|
-
parts.push("\n
|
|
543
|
+
parts.push("\n\nRULES:");
|
|
544
544
|
const rules = resolveRulesTemplate(this.promptConfig.rules, context);
|
|
545
545
|
for (const rule of rules) {
|
|
546
546
|
parts.push(`
|
|
547
|
-
|
|
547
|
+
- ${rule}`);
|
|
548
548
|
}
|
|
549
|
-
parts.push("\n </rules>");
|
|
550
549
|
return parts.join("");
|
|
551
550
|
}
|
|
552
551
|
addUser(content, metadata) {
|
|
@@ -1186,19 +1185,19 @@ var init_executor = __esm({
|
|
|
1186
1185
|
});
|
|
1187
1186
|
|
|
1188
1187
|
// src/gadgets/parser.ts
|
|
1189
|
-
var yaml, StreamParser;
|
|
1188
|
+
var yaml, globalInvocationCounter, StreamParser;
|
|
1190
1189
|
var init_parser = __esm({
|
|
1191
1190
|
"src/gadgets/parser.ts"() {
|
|
1192
1191
|
"use strict";
|
|
1193
1192
|
yaml = __toESM(require("js-yaml"), 1);
|
|
1194
1193
|
init_constants();
|
|
1194
|
+
globalInvocationCounter = 0;
|
|
1195
1195
|
StreamParser = class {
|
|
1196
1196
|
buffer = "";
|
|
1197
1197
|
lastReportedTextLength = 0;
|
|
1198
1198
|
startPrefix;
|
|
1199
1199
|
endPrefix;
|
|
1200
1200
|
parameterFormat;
|
|
1201
|
-
invocationCounter = 0;
|
|
1202
1201
|
constructor(options = {}) {
|
|
1203
1202
|
this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
|
|
1204
1203
|
this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
|
|
@@ -1265,7 +1264,7 @@ var init_parser = __esm({
|
|
|
1265
1264
|
invocationId = parts[1];
|
|
1266
1265
|
} else {
|
|
1267
1266
|
actualGadgetName = gadgetName;
|
|
1268
|
-
invocationId = `
|
|
1267
|
+
invocationId = `gadget_${++globalInvocationCounter}`;
|
|
1269
1268
|
}
|
|
1270
1269
|
const contentStartIndex = metadataEndIndex + 1;
|
|
1271
1270
|
let partEndIndex;
|
|
@@ -1322,11 +1321,10 @@ var init_parser = __esm({
|
|
|
1322
1321
|
yield { type: "text", content: remainingText };
|
|
1323
1322
|
}
|
|
1324
1323
|
}
|
|
1325
|
-
// Reset parser state
|
|
1324
|
+
// Reset parser state (note: global invocation counter is NOT reset to ensure unique IDs)
|
|
1326
1325
|
reset() {
|
|
1327
1326
|
this.buffer = "";
|
|
1328
1327
|
this.lastReportedTextLength = 0;
|
|
1329
|
-
this.invocationCounter = 0;
|
|
1330
1328
|
}
|
|
1331
1329
|
};
|
|
1332
1330
|
}
|
|
@@ -4321,18 +4319,59 @@ init_event_handlers();
|
|
|
4321
4319
|
// src/agent/hook-presets.ts
|
|
4322
4320
|
var HookPresets = class _HookPresets {
|
|
4323
4321
|
/**
|
|
4324
|
-
*
|
|
4322
|
+
* Logs LLM calls and gadget execution to console with optional verbosity.
|
|
4323
|
+
*
|
|
4324
|
+
* **Output (basic mode):**
|
|
4325
|
+
* - LLM call start/complete events with iteration numbers
|
|
4326
|
+
* - Gadget execution start/complete with gadget names
|
|
4327
|
+
* - Token counts when available
|
|
4328
|
+
*
|
|
4329
|
+
* **Output (verbose mode):**
|
|
4330
|
+
* - All basic mode output
|
|
4331
|
+
* - Full gadget parameters (formatted JSON)
|
|
4332
|
+
* - Full gadget results
|
|
4333
|
+
* - Complete LLM response text
|
|
4325
4334
|
*
|
|
4326
|
-
*
|
|
4335
|
+
* **Use cases:**
|
|
4336
|
+
* - Basic development debugging and execution flow visibility
|
|
4337
|
+
* - Understanding agent decision-making and tool usage
|
|
4338
|
+
* - Troubleshooting gadget invocations
|
|
4339
|
+
*
|
|
4340
|
+
* **Performance:** Minimal overhead. Console writes are synchronous but fast.
|
|
4327
4341
|
*
|
|
4328
4342
|
* @param options - Logging options
|
|
4329
|
-
* @
|
|
4343
|
+
* @param options.verbose - Include full parameters and results. Default: false
|
|
4344
|
+
* @returns Hook configuration that can be passed to .withHooks()
|
|
4345
|
+
*
|
|
4346
|
+
* @example
|
|
4347
|
+
* ```typescript
|
|
4348
|
+
* // Basic logging
|
|
4349
|
+
* await LLMist.createAgent()
|
|
4350
|
+
* .withHooks(HookPresets.logging())
|
|
4351
|
+
* .ask("Calculate 15 * 23");
|
|
4352
|
+
* // Output: [LLM] Starting call (iteration 0)
|
|
4353
|
+
* // [GADGET] Executing Calculator
|
|
4354
|
+
* // [GADGET] Completed Calculator
|
|
4355
|
+
* // [LLM] Completed (tokens: 245)
|
|
4356
|
+
* ```
|
|
4357
|
+
*
|
|
4358
|
+
* @example
|
|
4359
|
+
* ```typescript
|
|
4360
|
+
* // Verbose logging with full details
|
|
4361
|
+
* await LLMist.createAgent()
|
|
4362
|
+
* .withHooks(HookPresets.logging({ verbose: true }))
|
|
4363
|
+
* .ask("Calculate 15 * 23");
|
|
4364
|
+
* // Output includes: parameters, results, and full responses
|
|
4365
|
+
* ```
|
|
4330
4366
|
*
|
|
4331
4367
|
* @example
|
|
4332
4368
|
* ```typescript
|
|
4333
|
-
*
|
|
4334
|
-
* .
|
|
4369
|
+
* // Environment-based verbosity
|
|
4370
|
+
* const isDev = process.env.NODE_ENV === 'development';
|
|
4371
|
+
* .withHooks(HookPresets.logging({ verbose: isDev }))
|
|
4335
4372
|
* ```
|
|
4373
|
+
*
|
|
4374
|
+
* @see {@link https://github.com/zbigniewsobiecki/llmist/blob/main/docs/HOOKS.md#hookpresetsloggingoptions | Full documentation}
|
|
4336
4375
|
*/
|
|
4337
4376
|
static logging(options = {}) {
|
|
4338
4377
|
return {
|
|
@@ -4364,16 +4403,54 @@ var HookPresets = class _HookPresets {
|
|
|
4364
4403
|
};
|
|
4365
4404
|
}
|
|
4366
4405
|
/**
|
|
4367
|
-
* Preset: Performance timing for all operations.
|
|
4368
|
-
*
|
|
4369
4406
|
* Measures and logs execution time for LLM calls and gadgets.
|
|
4370
4407
|
*
|
|
4371
|
-
*
|
|
4408
|
+
* **Output:**
|
|
4409
|
+
* - Duration in milliseconds with ⏱️ emoji for each operation
|
|
4410
|
+
* - Separate timing for each LLM iteration
|
|
4411
|
+
* - Separate timing for each gadget execution
|
|
4412
|
+
*
|
|
4413
|
+
* **Use cases:**
|
|
4414
|
+
* - Performance profiling and optimization
|
|
4415
|
+
* - Identifying slow operations (LLM calls vs gadget execution)
|
|
4416
|
+
* - Monitoring response times in production
|
|
4417
|
+
* - Capacity planning and SLA tracking
|
|
4418
|
+
*
|
|
4419
|
+
* **Performance:** Negligible overhead. Uses Date.now() for timing measurements.
|
|
4420
|
+
*
|
|
4421
|
+
* @returns Hook configuration that can be passed to .withHooks()
|
|
4372
4422
|
*
|
|
4373
4423
|
* @example
|
|
4374
4424
|
* ```typescript
|
|
4375
|
-
*
|
|
4425
|
+
* // Basic timing
|
|
4426
|
+
* await LLMist.createAgent()
|
|
4427
|
+
* .withHooks(HookPresets.timing())
|
|
4428
|
+
* .withGadgets(Weather, Database)
|
|
4429
|
+
* .ask("What's the weather in NYC?");
|
|
4430
|
+
* // Output: ⏱️ LLM call took 1234ms
|
|
4431
|
+
* // ⏱️ Gadget Weather took 567ms
|
|
4432
|
+
* // ⏱️ LLM call took 890ms
|
|
4376
4433
|
* ```
|
|
4434
|
+
*
|
|
4435
|
+
* @example
|
|
4436
|
+
* ```typescript
|
|
4437
|
+
* // Combined with logging for full context
|
|
4438
|
+
* .withHooks(HookPresets.merge(
|
|
4439
|
+
* HookPresets.logging(),
|
|
4440
|
+
* HookPresets.timing()
|
|
4441
|
+
* ))
|
|
4442
|
+
* ```
|
|
4443
|
+
*
|
|
4444
|
+
* @example
|
|
4445
|
+
* ```typescript
|
|
4446
|
+
* // Correlate performance with cost
|
|
4447
|
+
* .withHooks(HookPresets.merge(
|
|
4448
|
+
* HookPresets.timing(),
|
|
4449
|
+
* HookPresets.tokenTracking()
|
|
4450
|
+
* ))
|
|
4451
|
+
* ```
|
|
4452
|
+
*
|
|
4453
|
+
* @see {@link https://github.com/zbigniewsobiecki/llmist/blob/main/docs/HOOKS.md#hookpresetstiming | Full documentation}
|
|
4377
4454
|
*/
|
|
4378
4455
|
static timing() {
|
|
4379
4456
|
const timings = /* @__PURE__ */ new Map();
|
|
@@ -4410,16 +4487,57 @@ var HookPresets = class _HookPresets {
|
|
|
4410
4487
|
};
|
|
4411
4488
|
}
|
|
4412
4489
|
/**
|
|
4413
|
-
*
|
|
4490
|
+
* Tracks cumulative token usage across all LLM calls.
|
|
4491
|
+
*
|
|
4492
|
+
* **Output:**
|
|
4493
|
+
* - Per-call token count with 📊 emoji
|
|
4494
|
+
* - Cumulative total across all calls
|
|
4495
|
+
* - Call count for average calculations
|
|
4496
|
+
*
|
|
4497
|
+
* **Use cases:**
|
|
4498
|
+
* - Cost monitoring and budget tracking
|
|
4499
|
+
* - Optimizing prompts to reduce token usage
|
|
4500
|
+
* - Comparing token efficiency across different approaches
|
|
4501
|
+
* - Real-time cost estimation
|
|
4414
4502
|
*
|
|
4415
|
-
*
|
|
4503
|
+
* **Performance:** Minimal overhead. Simple counter increments.
|
|
4416
4504
|
*
|
|
4417
|
-
*
|
|
4505
|
+
* **Note:** Token counts depend on the provider's response. Some providers
|
|
4506
|
+
* may not include usage data, in which case counts won't be logged.
|
|
4507
|
+
*
|
|
4508
|
+
* @returns Hook configuration that can be passed to .withHooks()
|
|
4418
4509
|
*
|
|
4419
4510
|
* @example
|
|
4420
4511
|
* ```typescript
|
|
4421
|
-
*
|
|
4512
|
+
* // Basic token tracking
|
|
4513
|
+
* await LLMist.createAgent()
|
|
4514
|
+
* .withHooks(HookPresets.tokenTracking())
|
|
4515
|
+
* .ask("Summarize this document...");
|
|
4516
|
+
* // Output: 📊 Tokens this call: 1,234
|
|
4517
|
+
* // 📊 Total tokens: 1,234 (across 1 calls)
|
|
4518
|
+
* // 📊 Tokens this call: 567
|
|
4519
|
+
* // 📊 Total tokens: 1,801 (across 2 calls)
|
|
4422
4520
|
* ```
|
|
4521
|
+
*
|
|
4522
|
+
* @example
|
|
4523
|
+
* ```typescript
|
|
4524
|
+
* // Cost calculation with custom hook
|
|
4525
|
+
* let totalTokens = 0;
|
|
4526
|
+
* .withHooks(HookPresets.merge(
|
|
4527
|
+
* HookPresets.tokenTracking(),
|
|
4528
|
+
* {
|
|
4529
|
+
* observers: {
|
|
4530
|
+
* onLLMCallComplete: async (ctx) => {
|
|
4531
|
+
* totalTokens += ctx.usage?.totalTokens ?? 0;
|
|
4532
|
+
* const cost = (totalTokens / 1_000_000) * 3.0; // $3 per 1M tokens
|
|
4533
|
+
* console.log(`💰 Estimated cost: $${cost.toFixed(4)}`);
|
|
4534
|
+
* },
|
|
4535
|
+
* },
|
|
4536
|
+
* }
|
|
4537
|
+
* ))
|
|
4538
|
+
* ```
|
|
4539
|
+
*
|
|
4540
|
+
* @see {@link https://github.com/zbigniewsobiecki/llmist/blob/main/docs/HOOKS.md#hookpresetstokentracking | Full documentation}
|
|
4423
4541
|
*/
|
|
4424
4542
|
static tokenTracking() {
|
|
4425
4543
|
let totalTokens = 0;
|
|
@@ -4438,16 +4556,64 @@ var HookPresets = class _HookPresets {
|
|
|
4438
4556
|
};
|
|
4439
4557
|
}
|
|
4440
4558
|
/**
|
|
4441
|
-
*
|
|
4559
|
+
* Logs detailed error information for debugging and troubleshooting.
|
|
4560
|
+
*
|
|
4561
|
+
* **Output:**
|
|
4562
|
+
* - LLM errors with ❌ emoji, including model and recovery status
|
|
4563
|
+
* - Gadget errors with full context (parameters, error message)
|
|
4564
|
+
* - Separate logging for LLM and gadget failures
|
|
4442
4565
|
*
|
|
4443
|
-
*
|
|
4566
|
+
* **Use cases:**
|
|
4567
|
+
* - Troubleshooting production issues
|
|
4568
|
+
* - Understanding error patterns and frequency
|
|
4569
|
+
* - Debugging error recovery behavior
|
|
4570
|
+
* - Collecting error metrics for monitoring
|
|
4444
4571
|
*
|
|
4445
|
-
*
|
|
4572
|
+
* **Performance:** Minimal overhead. Only logs when errors occur.
|
|
4573
|
+
*
|
|
4574
|
+
* @returns Hook configuration that can be passed to .withHooks()
|
|
4575
|
+
*
|
|
4576
|
+
* @example
|
|
4577
|
+
* ```typescript
|
|
4578
|
+
* // Basic error logging
|
|
4579
|
+
* await LLMist.createAgent()
|
|
4580
|
+
* .withHooks(HookPresets.errorLogging())
|
|
4581
|
+
* .withGadgets(Database)
|
|
4582
|
+
* .ask("Fetch user data");
|
|
4583
|
+
* // Output (on LLM error): ❌ LLM Error (iteration 1): Rate limit exceeded
|
|
4584
|
+
* // Model: gpt-5-nano
|
|
4585
|
+
* // Recovered: true
|
|
4586
|
+
* // Output (on gadget error): ❌ Gadget Error: Database
|
|
4587
|
+
* // Error: Connection timeout
|
|
4588
|
+
* // Parameters: {...}
|
|
4589
|
+
* ```
|
|
4590
|
+
*
|
|
4591
|
+
* @example
|
|
4592
|
+
* ```typescript
|
|
4593
|
+
* // Combine with monitoring for full context
|
|
4594
|
+
* .withHooks(HookPresets.merge(
|
|
4595
|
+
* HookPresets.monitoring(), // Includes errorLogging
|
|
4596
|
+
* customErrorAnalytics
|
|
4597
|
+
* ))
|
|
4598
|
+
* ```
|
|
4446
4599
|
*
|
|
4447
4600
|
* @example
|
|
4448
4601
|
* ```typescript
|
|
4449
|
-
*
|
|
4602
|
+
* // Error analytics collection
|
|
4603
|
+
* const errors: any[] = [];
|
|
4604
|
+
* .withHooks(HookPresets.merge(
|
|
4605
|
+
* HookPresets.errorLogging(),
|
|
4606
|
+
* {
|
|
4607
|
+
* observers: {
|
|
4608
|
+
* onLLMCallError: async (ctx) => {
|
|
4609
|
+
* errors.push({ type: 'llm', error: ctx.error, recovered: ctx.recovered });
|
|
4610
|
+
* },
|
|
4611
|
+
* },
|
|
4612
|
+
* }
|
|
4613
|
+
* ))
|
|
4450
4614
|
* ```
|
|
4615
|
+
*
|
|
4616
|
+
* @see {@link https://github.com/zbigniewsobiecki/llmist/blob/main/docs/HOOKS.md#hookpresetserrorlogging | Full documentation}
|
|
4451
4617
|
*/
|
|
4452
4618
|
static errorLogging() {
|
|
4453
4619
|
return {
|
|
@@ -4468,48 +4634,131 @@ var HookPresets = class _HookPresets {
|
|
|
4468
4634
|
};
|
|
4469
4635
|
}
|
|
4470
4636
|
/**
|
|
4471
|
-
*
|
|
4637
|
+
* Returns empty hook configuration for clean output without any logging.
|
|
4638
|
+
*
|
|
4639
|
+
* **Output:**
|
|
4640
|
+
* - None. Returns {} (empty object).
|
|
4641
|
+
*
|
|
4642
|
+
* **Use cases:**
|
|
4643
|
+
* - Clean test output without console noise
|
|
4644
|
+
* - Production environments where logging is handled externally
|
|
4645
|
+
* - Baseline for custom hook development
|
|
4646
|
+
* - Temporary disable of all hook output
|
|
4472
4647
|
*
|
|
4473
|
-
*
|
|
4648
|
+
* **Performance:** Zero overhead. No-op hook configuration.
|
|
4474
4649
|
*
|
|
4475
4650
|
* @returns Empty hook configuration
|
|
4476
4651
|
*
|
|
4477
4652
|
* @example
|
|
4478
4653
|
* ```typescript
|
|
4479
|
-
*
|
|
4654
|
+
* // Clean test output
|
|
4655
|
+
* describe('Agent tests', () => {
|
|
4656
|
+
* it('should calculate correctly', async () => {
|
|
4657
|
+
* const result = await LLMist.createAgent()
|
|
4658
|
+
* .withHooks(HookPresets.silent()) // No console output
|
|
4659
|
+
* .withGadgets(Calculator)
|
|
4660
|
+
* .askAndCollect("What is 15 times 23?");
|
|
4661
|
+
*
|
|
4662
|
+
* expect(result).toContain("345");
|
|
4663
|
+
* });
|
|
4664
|
+
* });
|
|
4665
|
+
* ```
|
|
4666
|
+
*
|
|
4667
|
+
* @example
|
|
4668
|
+
* ```typescript
|
|
4669
|
+
* // Conditional silence based on environment
|
|
4670
|
+
* const isTesting = process.env.NODE_ENV === 'test';
|
|
4671
|
+
* .withHooks(isTesting ? HookPresets.silent() : HookPresets.monitoring())
|
|
4480
4672
|
* ```
|
|
4673
|
+
*
|
|
4674
|
+
* @see {@link https://github.com/zbigniewsobiecki/llmist/blob/main/docs/HOOKS.md#hookpresetssilent | Full documentation}
|
|
4481
4675
|
*/
|
|
4482
4676
|
static silent() {
|
|
4483
4677
|
return {};
|
|
4484
4678
|
}
|
|
4485
4679
|
/**
|
|
4486
|
-
*
|
|
4680
|
+
* Combines multiple hook configurations into one.
|
|
4681
|
+
*
|
|
4682
|
+
* Merge allows you to compose preset and custom hooks for modular monitoring
|
|
4683
|
+
* configurations. Understanding merge behavior is crucial for proper composition.
|
|
4684
|
+
*
|
|
4685
|
+
* **Merge behavior:**
|
|
4686
|
+
* - **Observers:** Composed - all handlers run sequentially in order
|
|
4687
|
+
* - **Interceptors:** Last one wins - only the last interceptor applies
|
|
4688
|
+
* - **Controllers:** Last one wins - only the last controller applies
|
|
4689
|
+
*
|
|
4690
|
+
* **Why interceptors/controllers don't compose:**
|
|
4691
|
+
* - Interceptors have different signatures per method, making composition impractical
|
|
4692
|
+
* - Controllers return specific actions that can't be meaningfully combined
|
|
4693
|
+
* - Only observers support composition because they're read-only and independent
|
|
4694
|
+
*
|
|
4695
|
+
* **Use cases:**
|
|
4696
|
+
* - Combining multiple presets (logging + timing + tokens)
|
|
4697
|
+
* - Adding custom hooks to presets
|
|
4698
|
+
* - Building modular, reusable monitoring configurations
|
|
4699
|
+
* - Environment-specific hook composition
|
|
4487
4700
|
*
|
|
4488
|
-
*
|
|
4489
|
-
* When multiple hooks target the same lifecycle event, they are composed
|
|
4490
|
-
* to run sequentially (all handlers will execute).
|
|
4701
|
+
* **Performance:** Minimal overhead for merging. Runtime performance depends on merged hooks.
|
|
4491
4702
|
*
|
|
4492
|
-
* @param hookSets -
|
|
4493
|
-
* @returns
|
|
4703
|
+
* @param hookSets - Variable number of hook configurations to merge
|
|
4704
|
+
* @returns Single merged hook configuration with composed/overridden handlers
|
|
4494
4705
|
*
|
|
4495
4706
|
* @example
|
|
4496
4707
|
* ```typescript
|
|
4708
|
+
* // Combine multiple presets
|
|
4709
|
+
* .withHooks(HookPresets.merge(
|
|
4710
|
+
* HookPresets.logging(),
|
|
4711
|
+
* HookPresets.timing(),
|
|
4712
|
+
* HookPresets.tokenTracking()
|
|
4713
|
+
* ))
|
|
4714
|
+
* // All observers from all three presets will run
|
|
4715
|
+
* ```
|
|
4716
|
+
*
|
|
4717
|
+
* @example
|
|
4718
|
+
* ```typescript
|
|
4719
|
+
* // Add custom observer to preset (both run)
|
|
4497
4720
|
* .withHooks(HookPresets.merge(
|
|
4498
|
-
* HookPresets.logging({ verbose: true }),
|
|
4499
4721
|
* HookPresets.timing(),
|
|
4500
|
-
* HookPresets.tokenTracking(),
|
|
4501
4722
|
* {
|
|
4502
|
-
* // Custom hook
|
|
4503
4723
|
* observers: {
|
|
4504
4724
|
* onLLMCallComplete: async (ctx) => {
|
|
4505
|
-
*
|
|
4506
|
-
* }
|
|
4507
|
-
* }
|
|
4725
|
+
* await saveMetrics({ tokens: ctx.usage?.totalTokens });
|
|
4726
|
+
* },
|
|
4727
|
+
* },
|
|
4508
4728
|
* }
|
|
4509
4729
|
* ))
|
|
4510
|
-
* // All onLLMCallComplete handlers from logging, timing, tokenTracking,
|
|
4511
|
-
* // and the custom hook will execute in order
|
|
4512
4730
|
* ```
|
|
4731
|
+
*
|
|
4732
|
+
* @example
|
|
4733
|
+
* ```typescript
|
|
4734
|
+
* // Multiple interceptors (last wins!)
|
|
4735
|
+
* .withHooks(HookPresets.merge(
|
|
4736
|
+
* {
|
|
4737
|
+
* interceptors: {
|
|
4738
|
+
* interceptTextChunk: (chunk) => chunk.toUpperCase(), // Ignored
|
|
4739
|
+
* },
|
|
4740
|
+
* },
|
|
4741
|
+
* {
|
|
4742
|
+
* interceptors: {
|
|
4743
|
+
* interceptTextChunk: (chunk) => chunk.toLowerCase(), // This wins
|
|
4744
|
+
* },
|
|
4745
|
+
* }
|
|
4746
|
+
* ))
|
|
4747
|
+
* // Result: text will be lowercase
|
|
4748
|
+
* ```
|
|
4749
|
+
*
|
|
4750
|
+
* @example
|
|
4751
|
+
* ```typescript
|
|
4752
|
+
* // Modular environment-based configuration
|
|
4753
|
+
* const baseHooks = HookPresets.errorLogging();
|
|
4754
|
+
* const devHooks = HookPresets.merge(baseHooks, HookPresets.monitoring({ verbose: true }));
|
|
4755
|
+
* const prodHooks = HookPresets.merge(baseHooks, HookPresets.tokenTracking());
|
|
4756
|
+
*
|
|
4757
|
+
* const hooks = process.env.NODE_ENV === 'production' ? prodHooks : devHooks;
|
|
4758
|
+
* .withHooks(hooks)
|
|
4759
|
+
* ```
|
|
4760
|
+
*
|
|
4761
|
+
* @see {@link https://github.com/zbigniewsobiecki/llmist/blob/main/docs/HOOKS.md#hookpresetsmergehooksets | Full documentation}
|
|
4513
4762
|
*/
|
|
4514
4763
|
static merge(...hookSets) {
|
|
4515
4764
|
const merged = {
|
|
@@ -4542,18 +4791,62 @@ var HookPresets = class _HookPresets {
|
|
|
4542
4791
|
return merged;
|
|
4543
4792
|
}
|
|
4544
4793
|
/**
|
|
4545
|
-
*
|
|
4794
|
+
* Composite preset combining logging, timing, tokenTracking, and errorLogging.
|
|
4795
|
+
*
|
|
4796
|
+
* This is the recommended preset for development and initial production deployments,
|
|
4797
|
+
* providing comprehensive observability with a single method call.
|
|
4798
|
+
*
|
|
4799
|
+
* **Includes:**
|
|
4800
|
+
* - All output from `logging()` preset (with optional verbosity)
|
|
4801
|
+
* - All output from `timing()` preset (execution times)
|
|
4802
|
+
* - All output from `tokenTracking()` preset (token usage)
|
|
4803
|
+
* - All output from `errorLogging()` preset (error details)
|
|
4804
|
+
*
|
|
4805
|
+
* **Output format:**
|
|
4806
|
+
* - Event logging: [LLM]/[GADGET] messages
|
|
4807
|
+
* - Timing: ⏱️ emoji with milliseconds
|
|
4808
|
+
* - Tokens: 📊 emoji with per-call and cumulative counts
|
|
4809
|
+
* - Errors: ❌ emoji with full error details
|
|
4810
|
+
*
|
|
4811
|
+
* **Use cases:**
|
|
4812
|
+
* - Full observability during development
|
|
4813
|
+
* - Comprehensive monitoring in production
|
|
4814
|
+
* - One-liner for complete agent visibility
|
|
4815
|
+
* - Troubleshooting and debugging with full context
|
|
4816
|
+
*
|
|
4817
|
+
* **Performance:** Combined overhead of all four presets, but still minimal in practice.
|
|
4818
|
+
*
|
|
4819
|
+
* @param options - Monitoring options
|
|
4820
|
+
* @param options.verbose - Passed to logging() preset for detailed output. Default: false
|
|
4821
|
+
* @returns Merged hook configuration combining all monitoring presets
|
|
4546
4822
|
*
|
|
4547
|
-
*
|
|
4823
|
+
* @example
|
|
4824
|
+
* ```typescript
|
|
4825
|
+
* // Basic monitoring (recommended for development)
|
|
4826
|
+
* await LLMist.createAgent()
|
|
4827
|
+
* .withHooks(HookPresets.monitoring())
|
|
4828
|
+
* .withGadgets(Calculator, Weather)
|
|
4829
|
+
* .ask("What is 15 times 23, and what's the weather in NYC?");
|
|
4830
|
+
* // Output: All events, timing, tokens, and errors in one place
|
|
4831
|
+
* ```
|
|
4548
4832
|
*
|
|
4549
|
-
* @
|
|
4550
|
-
*
|
|
4833
|
+
* @example
|
|
4834
|
+
* ```typescript
|
|
4835
|
+
* // Verbose monitoring with full details
|
|
4836
|
+
* await LLMist.createAgent()
|
|
4837
|
+
* .withHooks(HookPresets.monitoring({ verbose: true }))
|
|
4838
|
+
* .ask("Your prompt");
|
|
4839
|
+
* // Output includes: parameters, results, and complete responses
|
|
4840
|
+
* ```
|
|
4551
4841
|
*
|
|
4552
4842
|
* @example
|
|
4553
4843
|
* ```typescript
|
|
4554
|
-
*
|
|
4555
|
-
* .
|
|
4844
|
+
* // Environment-based monitoring
|
|
4845
|
+
* const isDev = process.env.NODE_ENV === 'development';
|
|
4846
|
+
* .withHooks(HookPresets.monitoring({ verbose: isDev }))
|
|
4556
4847
|
* ```
|
|
4848
|
+
*
|
|
4849
|
+
* @see {@link https://github.com/zbigniewsobiecki/llmist/blob/main/docs/HOOKS.md#hookpresetsmonitoringoptions | Full documentation}
|
|
4557
4850
|
*/
|
|
4558
4851
|
static monitoring(options = {}) {
|
|
4559
4852
|
return _HookPresets.merge(
|