llmist 0.8.0 → 1.0.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/{chunk-4IMGADVY.js → chunk-53MM55JS.js} +40 -5
- package/dist/chunk-53MM55JS.js.map +1 -0
- package/dist/{chunk-62M4TDAK.js → chunk-T24KLXY4.js} +326 -536
- package/dist/chunk-T24KLXY4.js.map +1 -0
- package/dist/cli.cjs +500 -605
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +169 -63
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +362 -539
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -8
- package/dist/index.d.ts +66 -8
- package/dist/index.js +2 -2
- package/dist/{mock-stream-CjmvWDc3.d.cts → mock-stream-DKF5yatf.d.cts} +41 -102
- package/dist/{mock-stream-CjmvWDc3.d.ts → mock-stream-DKF5yatf.d.ts} +41 -102
- package/dist/testing/index.cjs +362 -539
- 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 +1 -1
- package/dist/chunk-4IMGADVY.js.map +0 -1
- package/dist/chunk-62M4TDAK.js.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -32,12 +32,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
32
32
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
33
|
|
|
34
34
|
// src/core/constants.ts
|
|
35
|
-
var GADGET_START_PREFIX, GADGET_END_PREFIX, DEFAULT_GADGET_OUTPUT_LIMIT, DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT, CHARS_PER_TOKEN, FALLBACK_CONTEXT_WINDOW;
|
|
35
|
+
var GADGET_START_PREFIX, GADGET_END_PREFIX, GADGET_ARG_PREFIX, DEFAULT_GADGET_OUTPUT_LIMIT, DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT, CHARS_PER_TOKEN, FALLBACK_CONTEXT_WINDOW;
|
|
36
36
|
var init_constants = __esm({
|
|
37
37
|
"src/core/constants.ts"() {
|
|
38
38
|
"use strict";
|
|
39
39
|
GADGET_START_PREFIX = "!!!GADGET_START:";
|
|
40
40
|
GADGET_END_PREFIX = "!!!GADGET_END";
|
|
41
|
+
GADGET_ARG_PREFIX = "!!!ARG:";
|
|
41
42
|
DEFAULT_GADGET_OUTPUT_LIMIT = true;
|
|
42
43
|
DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT = 15;
|
|
43
44
|
CHARS_PER_TOKEN = 4;
|
|
@@ -370,17 +371,12 @@ var init_prompt_config = __esm({
|
|
|
370
371
|
"EACH MARKER MUST START WITH A NEWLINE."
|
|
371
372
|
].join("\n"),
|
|
372
373
|
criticalUsage: "INVOKE gadgets using the markers - do not describe what you want to do.",
|
|
373
|
-
|
|
374
|
-
formatDescriptionJson: "Parameters in JSON format (valid JSON object)",
|
|
375
|
-
formatDescriptionToml: "Parameters in TOML format (key = value pairs, use heredoc for multiline: key = <<<EOF ... EOF)",
|
|
374
|
+
formatDescription: (ctx) => `Parameters using ${ctx.argPrefix}name markers (value on next line(s), no escaping needed)`,
|
|
376
375
|
rules: () => [
|
|
377
376
|
"Output ONLY plain text with the exact markers - never use function/tool calling",
|
|
378
377
|
"You can invoke multiple gadgets in a single response",
|
|
379
378
|
"For dependent gadgets, invoke the first one and wait for the result"
|
|
380
379
|
],
|
|
381
|
-
schemaLabelJson: "\n\nInput Schema (JSON):",
|
|
382
|
-
schemaLabelYaml: "\n\nInput Schema (YAML):",
|
|
383
|
-
schemaLabelToml: "\n\nInput Schema (TOML):",
|
|
384
380
|
customExamples: null
|
|
385
381
|
};
|
|
386
382
|
}
|
|
@@ -397,6 +393,7 @@ var init_messages = __esm({
|
|
|
397
393
|
messages = [];
|
|
398
394
|
startPrefix = GADGET_START_PREFIX;
|
|
399
395
|
endPrefix = GADGET_END_PREFIX;
|
|
396
|
+
argPrefix = GADGET_ARG_PREFIX;
|
|
400
397
|
promptConfig;
|
|
401
398
|
constructor(promptConfig) {
|
|
402
399
|
this.promptConfig = promptConfig ?? {};
|
|
@@ -405,26 +402,32 @@ var init_messages = __esm({
|
|
|
405
402
|
* Set custom prefixes for gadget markers.
|
|
406
403
|
* Used to configure history builder to match system prompt markers.
|
|
407
404
|
*/
|
|
408
|
-
withPrefixes(startPrefix, endPrefix) {
|
|
405
|
+
withPrefixes(startPrefix, endPrefix, argPrefix) {
|
|
409
406
|
this.startPrefix = startPrefix;
|
|
410
407
|
this.endPrefix = endPrefix;
|
|
408
|
+
if (argPrefix) {
|
|
409
|
+
this.argPrefix = argPrefix;
|
|
410
|
+
}
|
|
411
411
|
return this;
|
|
412
412
|
}
|
|
413
413
|
addSystem(content, metadata) {
|
|
414
414
|
this.messages.push({ role: "system", content, metadata });
|
|
415
415
|
return this;
|
|
416
416
|
}
|
|
417
|
-
addGadgets(gadgets,
|
|
417
|
+
addGadgets(gadgets, options) {
|
|
418
418
|
if (options?.startPrefix) {
|
|
419
419
|
this.startPrefix = options.startPrefix;
|
|
420
420
|
}
|
|
421
421
|
if (options?.endPrefix) {
|
|
422
422
|
this.endPrefix = options.endPrefix;
|
|
423
423
|
}
|
|
424
|
+
if (options?.argPrefix) {
|
|
425
|
+
this.argPrefix = options.argPrefix;
|
|
426
|
+
}
|
|
424
427
|
const context = {
|
|
425
|
-
parameterFormat,
|
|
426
428
|
startPrefix: this.startPrefix,
|
|
427
429
|
endPrefix: this.endPrefix,
|
|
430
|
+
argPrefix: this.argPrefix,
|
|
428
431
|
gadgetCount: gadgets.length,
|
|
429
432
|
gadgetNames: gadgets.map((g) => g.name ?? g.constructor.name)
|
|
430
433
|
};
|
|
@@ -435,26 +438,19 @@ var init_messages = __esm({
|
|
|
435
438
|
context
|
|
436
439
|
);
|
|
437
440
|
parts.push(mainInstruction);
|
|
438
|
-
parts.push(this.buildGadgetsSection(gadgets
|
|
439
|
-
parts.push(this.buildUsageSection(
|
|
441
|
+
parts.push(this.buildGadgetsSection(gadgets));
|
|
442
|
+
parts.push(this.buildUsageSection(context));
|
|
440
443
|
this.messages.push({ role: "system", content: parts.join("") });
|
|
441
444
|
return this;
|
|
442
445
|
}
|
|
443
|
-
buildGadgetsSection(gadgets
|
|
446
|
+
buildGadgetsSection(gadgets) {
|
|
444
447
|
const parts = [];
|
|
445
448
|
parts.push("\n\nAVAILABLE GADGETS");
|
|
446
449
|
parts.push("\n=================\n");
|
|
447
450
|
for (const gadget of gadgets) {
|
|
448
451
|
const gadgetName = gadget.name ?? gadget.constructor.name;
|
|
449
|
-
const instruction = gadget.getInstruction(
|
|
450
|
-
const
|
|
451
|
-
yaml: "\n\nInput Schema (YAML):",
|
|
452
|
-
json: "\n\nInput Schema (JSON):",
|
|
453
|
-
toml: "\n\nInput Schema (TOML):",
|
|
454
|
-
auto: "\n\nInput Schema (JSON):"
|
|
455
|
-
// auto defaults to JSON schema display
|
|
456
|
-
};
|
|
457
|
-
const schemaMarker = schemaMarkers[parameterFormat];
|
|
452
|
+
const instruction = gadget.getInstruction(this.argPrefix);
|
|
453
|
+
const schemaMarker = "\n\nInput Schema (BLOCK):";
|
|
458
454
|
const schemaIndex = instruction.indexOf(schemaMarker);
|
|
459
455
|
const description = (schemaIndex !== -1 ? instruction.substring(0, schemaIndex) : instruction).trim();
|
|
460
456
|
const schema = schemaIndex !== -1 ? instruction.substring(schemaIndex + schemaMarker.length).trim() : "";
|
|
@@ -465,35 +461,20 @@ ${description}`);
|
|
|
465
461
|
if (schema) {
|
|
466
462
|
parts.push(`
|
|
467
463
|
|
|
468
|
-
PARAMETERS (
|
|
464
|
+
PARAMETERS (BLOCK):
|
|
469
465
|
${schema}`);
|
|
470
466
|
}
|
|
471
467
|
parts.push("\n\n---");
|
|
472
468
|
}
|
|
473
469
|
return parts.join("");
|
|
474
470
|
}
|
|
475
|
-
buildUsageSection(
|
|
471
|
+
buildUsageSection(context) {
|
|
476
472
|
const parts = [];
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
json: {
|
|
483
|
-
config: this.promptConfig.formatDescriptionJson,
|
|
484
|
-
defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
|
|
485
|
-
},
|
|
486
|
-
toml: {
|
|
487
|
-
config: this.promptConfig.formatDescriptionToml,
|
|
488
|
-
defaultValue: DEFAULT_PROMPTS.formatDescriptionToml
|
|
489
|
-
},
|
|
490
|
-
auto: {
|
|
491
|
-
config: this.promptConfig.formatDescriptionJson,
|
|
492
|
-
defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
const { config, defaultValue } = formatDescriptionMap[parameterFormat];
|
|
496
|
-
const formatDescription = resolvePromptTemplate(config, defaultValue, context);
|
|
473
|
+
const formatDescription = resolvePromptTemplate(
|
|
474
|
+
this.promptConfig.formatDescription,
|
|
475
|
+
DEFAULT_PROMPTS.formatDescription,
|
|
476
|
+
context
|
|
477
|
+
);
|
|
497
478
|
parts.push("\n\nHOW TO INVOKE GADGETS");
|
|
498
479
|
parts.push("\n=====================\n");
|
|
499
480
|
const criticalUsage = resolvePromptTemplate(
|
|
@@ -511,124 +492,90 @@ CRITICAL: ${criticalUsage}
|
|
|
511
492
|
2. ${formatDescription}`);
|
|
512
493
|
parts.push(`
|
|
513
494
|
3. End marker: ${this.endPrefix}`);
|
|
514
|
-
parts.push(this.buildExamplesSection(
|
|
495
|
+
parts.push(this.buildExamplesSection(context));
|
|
515
496
|
parts.push(this.buildRulesSection(context));
|
|
516
497
|
parts.push("\n");
|
|
517
498
|
return parts.join("");
|
|
518
499
|
}
|
|
519
|
-
buildExamplesSection(
|
|
500
|
+
buildExamplesSection(context) {
|
|
520
501
|
if (this.promptConfig.customExamples) {
|
|
521
502
|
return this.promptConfig.customExamples(context);
|
|
522
503
|
}
|
|
523
504
|
const parts = [];
|
|
524
|
-
const
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
to
|
|
528
|
-
|
|
529
|
-
${this.
|
|
530
|
-
|
|
531
|
-
{
|
|
532
|
-
${this.endPrefix}`,
|
|
533
|
-
toml: `${this.startPrefix}translate
|
|
534
|
-
from = "English"
|
|
535
|
-
to = "Polish"
|
|
536
|
-
content = "Paris is the capital of France: a beautiful city."
|
|
537
|
-
${this.endPrefix}`,
|
|
538
|
-
auto: `${this.startPrefix}translate
|
|
539
|
-
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
540
|
-
${this.endPrefix}`
|
|
541
|
-
};
|
|
505
|
+
const singleExample = `${this.startPrefix}translate
|
|
506
|
+
${this.argPrefix}from
|
|
507
|
+
English
|
|
508
|
+
${this.argPrefix}to
|
|
509
|
+
Polish
|
|
510
|
+
${this.argPrefix}content
|
|
511
|
+
Paris is the capital of France: a beautiful city.
|
|
512
|
+
${this.endPrefix}`;
|
|
542
513
|
parts.push(`
|
|
543
514
|
|
|
544
515
|
EXAMPLE (Single Gadget):
|
|
545
516
|
|
|
546
|
-
${
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
to
|
|
551
|
-
|
|
552
|
-
${this.
|
|
553
|
-
|
|
554
|
-
type: economic_analysis
|
|
555
|
-
matter: "Polish Economy"
|
|
556
|
-
question: <<<EOF
|
|
557
|
-
Analyze the following:
|
|
558
|
-
- Polish arms exports 2025
|
|
559
|
-
- Economic implications
|
|
560
|
-
EOF
|
|
561
|
-
${this.endPrefix}`,
|
|
562
|
-
json: `${this.startPrefix}translate
|
|
563
|
-
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
564
|
-
${this.endPrefix}
|
|
565
|
-
${this.startPrefix}analyze
|
|
566
|
-
{"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
|
|
567
|
-
${this.endPrefix}`,
|
|
568
|
-
toml: `${this.startPrefix}translate
|
|
569
|
-
from = "English"
|
|
570
|
-
to = "Polish"
|
|
571
|
-
content = "Paris is the capital of France: a beautiful city."
|
|
517
|
+
${singleExample}`);
|
|
518
|
+
const multipleExample = `${this.startPrefix}translate
|
|
519
|
+
${this.argPrefix}from
|
|
520
|
+
English
|
|
521
|
+
${this.argPrefix}to
|
|
522
|
+
Polish
|
|
523
|
+
${this.argPrefix}content
|
|
524
|
+
Paris is the capital of France: a beautiful city.
|
|
572
525
|
${this.endPrefix}
|
|
573
526
|
${this.startPrefix}analyze
|
|
574
|
-
type
|
|
575
|
-
|
|
576
|
-
|
|
527
|
+
${this.argPrefix}type
|
|
528
|
+
economic_analysis
|
|
529
|
+
${this.argPrefix}matter
|
|
530
|
+
Polish Economy
|
|
531
|
+
${this.argPrefix}question
|
|
577
532
|
Analyze the following:
|
|
578
533
|
- Polish arms exports 2025
|
|
579
534
|
- Economic implications
|
|
580
|
-
|
|
581
|
-
${this.endPrefix}`,
|
|
582
|
-
auto: `${this.startPrefix}translate
|
|
583
|
-
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
584
|
-
${this.endPrefix}
|
|
585
|
-
${this.startPrefix}analyze
|
|
586
|
-
{"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
|
|
587
|
-
${this.endPrefix}`
|
|
588
|
-
};
|
|
535
|
+
${this.endPrefix}`;
|
|
589
536
|
parts.push(`
|
|
590
537
|
|
|
591
538
|
EXAMPLE (Multiple Gadgets):
|
|
592
539
|
|
|
593
|
-
${
|
|
594
|
-
|
|
595
|
-
parts.push(`
|
|
596
|
-
|
|
597
|
-
YAML HEREDOC SYNTAX:
|
|
598
|
-
For string values with multiple lines, use heredoc syntax (<<<DELIMITER...DELIMITER):
|
|
540
|
+
${multipleExample}`);
|
|
541
|
+
parts.push(`
|
|
599
542
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
# Project Title
|
|
543
|
+
BLOCK FORMAT SYNTAX:
|
|
544
|
+
Block format uses ${this.argPrefix}name markers. Values are captured verbatim until the next marker.
|
|
603
545
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
546
|
+
${this.argPrefix}filename
|
|
547
|
+
calculator.ts
|
|
548
|
+
${this.argPrefix}code
|
|
549
|
+
class Calculator {
|
|
550
|
+
private history: string[] = [];
|
|
609
551
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
For string values with multiple lines, use heredoc syntax (<<<DELIMITER...DELIMITER):
|
|
552
|
+
add(a: number, b: number): number {
|
|
553
|
+
const result = a + b;
|
|
554
|
+
this.history.push(\`\${a} + \${b} = \${result}\`);
|
|
555
|
+
return result;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
617
558
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
559
|
+
BLOCK FORMAT RULES:
|
|
560
|
+
- Each parameter starts with ${this.argPrefix}parameterName on its own line
|
|
561
|
+
- The value starts on the NEXT line after the marker
|
|
562
|
+
- Value ends when the next ${this.argPrefix} or ${this.endPrefix} appears
|
|
563
|
+
- NO escaping needed - write values exactly as they should appear
|
|
564
|
+
- Perfect for code, JSON, markdown, or any content with special characters
|
|
621
565
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
566
|
+
NESTED OBJECTS (use / separator):
|
|
567
|
+
${this.argPrefix}config/timeout
|
|
568
|
+
30
|
|
569
|
+
${this.argPrefix}config/retries
|
|
570
|
+
3
|
|
571
|
+
Produces: { "config": { "timeout": "30", "retries": "3" } }
|
|
627
572
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
573
|
+
ARRAYS (use numeric indices):
|
|
574
|
+
${this.argPrefix}items/0
|
|
575
|
+
first
|
|
576
|
+
${this.argPrefix}items/1
|
|
577
|
+
second
|
|
578
|
+
Produces: { "items": ["first", "second"] }`);
|
|
632
579
|
return parts.join("");
|
|
633
580
|
}
|
|
634
581
|
buildRulesSection(context) {
|
|
@@ -649,8 +596,8 @@ NEVER use TOML triple-quote strings ("""). ALWAYS use heredoc syntax (<<<EOF...E
|
|
|
649
596
|
this.messages.push({ role: "assistant", content, metadata });
|
|
650
597
|
return this;
|
|
651
598
|
}
|
|
652
|
-
addGadgetCall(gadget, parameters, result
|
|
653
|
-
const paramStr = this.
|
|
599
|
+
addGadgetCall(gadget, parameters, result) {
|
|
600
|
+
const paramStr = this.formatBlockParameters(parameters, "");
|
|
654
601
|
this.messages.push({
|
|
655
602
|
role: "assistant",
|
|
656
603
|
content: `${this.startPrefix}${gadget}
|
|
@@ -663,26 +610,32 @@ ${this.endPrefix}`
|
|
|
663
610
|
});
|
|
664
611
|
return this;
|
|
665
612
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
613
|
+
/**
|
|
614
|
+
* Format parameters as Block format with JSON Pointer paths.
|
|
615
|
+
* Uses the configured argPrefix for consistency with system prompt.
|
|
616
|
+
*/
|
|
617
|
+
formatBlockParameters(params, prefix) {
|
|
618
|
+
const lines = [];
|
|
619
|
+
for (const [key, value] of Object.entries(params)) {
|
|
620
|
+
const fullPath = prefix ? `${prefix}/${key}` : key;
|
|
621
|
+
if (Array.isArray(value)) {
|
|
622
|
+
value.forEach((item, index) => {
|
|
623
|
+
const itemPath = `${fullPath}/${index}`;
|
|
624
|
+
if (typeof item === "object" && item !== null) {
|
|
625
|
+
lines.push(this.formatBlockParameters(item, itemPath));
|
|
626
|
+
} else {
|
|
627
|
+
lines.push(`${this.argPrefix}${itemPath}`);
|
|
628
|
+
lines.push(String(item));
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
} else if (typeof value === "object" && value !== null) {
|
|
632
|
+
lines.push(this.formatBlockParameters(value, fullPath));
|
|
633
|
+
} else {
|
|
634
|
+
lines.push(`${this.argPrefix}${fullPath}`);
|
|
635
|
+
lines.push(String(value));
|
|
636
|
+
}
|
|
684
637
|
}
|
|
685
|
-
return
|
|
638
|
+
return lines.join("\n");
|
|
686
639
|
}
|
|
687
640
|
build() {
|
|
688
641
|
return [...this.messages];
|
|
@@ -854,134 +807,72 @@ var init_schema_to_json = __esm({
|
|
|
854
807
|
});
|
|
855
808
|
|
|
856
809
|
// src/gadgets/gadget.ts
|
|
857
|
-
function
|
|
858
|
-
const lines = content.split("\n");
|
|
859
|
-
for (const delimiter of HEREDOC_DELIMITERS) {
|
|
860
|
-
const regex = new RegExp(`^${delimiter}\\s*$`);
|
|
861
|
-
const isUsed = lines.some((line) => regex.test(line));
|
|
862
|
-
if (!isUsed) {
|
|
863
|
-
return delimiter;
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
let counter = 1;
|
|
867
|
-
while (counter < 1e3) {
|
|
868
|
-
const delimiter = `__GADGET_PARAM_${counter}__`;
|
|
869
|
-
const regex = new RegExp(`^${delimiter}\\s*$`);
|
|
870
|
-
const isUsed = lines.some((line) => regex.test(line));
|
|
871
|
-
if (!isUsed) {
|
|
872
|
-
return delimiter;
|
|
873
|
-
}
|
|
874
|
-
counter++;
|
|
875
|
-
}
|
|
876
|
-
return "HEREDOC_FALLBACK";
|
|
877
|
-
}
|
|
878
|
-
function formatYamlValue(value, indent = "") {
|
|
879
|
-
if (typeof value === "string") {
|
|
880
|
-
const lines = value.split("\n");
|
|
881
|
-
if (lines.length === 1 && !value.includes(":") && !value.startsWith("-")) {
|
|
882
|
-
return value;
|
|
883
|
-
}
|
|
884
|
-
const delimiter = findSafeDelimiter(value);
|
|
885
|
-
return `<<<${delimiter}
|
|
886
|
-
${value}
|
|
887
|
-
${delimiter}`;
|
|
888
|
-
}
|
|
889
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
890
|
-
return String(value);
|
|
891
|
-
}
|
|
892
|
-
if (value === null || value === void 0) {
|
|
893
|
-
return "null";
|
|
894
|
-
}
|
|
895
|
-
if (Array.isArray(value)) {
|
|
896
|
-
if (value.length === 0) return "[]";
|
|
897
|
-
const items = value.map((item) => `${indent}- ${formatYamlValue(item, indent + " ")}`);
|
|
898
|
-
return "\n" + items.join("\n");
|
|
899
|
-
}
|
|
900
|
-
if (typeof value === "object") {
|
|
901
|
-
const entries = Object.entries(value);
|
|
902
|
-
if (entries.length === 0) return "{}";
|
|
903
|
-
const lines = entries.map(([k, v]) => {
|
|
904
|
-
const formattedValue = formatYamlValue(v, indent + " ");
|
|
905
|
-
if (formattedValue.startsWith("\n") || formattedValue.startsWith("|")) {
|
|
906
|
-
return `${indent}${k}: ${formattedValue}`;
|
|
907
|
-
}
|
|
908
|
-
return `${indent}${k}: ${formattedValue}`;
|
|
909
|
-
});
|
|
910
|
-
return "\n" + lines.join("\n");
|
|
911
|
-
}
|
|
912
|
-
return yaml.dump(value).trimEnd();
|
|
913
|
-
}
|
|
914
|
-
function formatParamsAsYaml(params) {
|
|
810
|
+
function formatParamsAsBlock(params, prefix = "", argPrefix = GADGET_ARG_PREFIX) {
|
|
915
811
|
const lines = [];
|
|
916
812
|
for (const [key, value] of Object.entries(params)) {
|
|
917
|
-
const
|
|
918
|
-
if (
|
|
919
|
-
|
|
813
|
+
const fullPath = prefix ? `${prefix}/${key}` : key;
|
|
814
|
+
if (Array.isArray(value)) {
|
|
815
|
+
value.forEach((item, index) => {
|
|
816
|
+
const itemPath = `${fullPath}/${index}`;
|
|
817
|
+
if (typeof item === "object" && item !== null) {
|
|
818
|
+
lines.push(formatParamsAsBlock(item, itemPath, argPrefix));
|
|
819
|
+
} else {
|
|
820
|
+
lines.push(`${argPrefix}${itemPath}`);
|
|
821
|
+
lines.push(String(item));
|
|
822
|
+
}
|
|
823
|
+
});
|
|
824
|
+
} else if (typeof value === "object" && value !== null) {
|
|
825
|
+
lines.push(formatParamsAsBlock(value, fullPath, argPrefix));
|
|
920
826
|
} else {
|
|
921
|
-
lines.push(`${
|
|
827
|
+
lines.push(`${argPrefix}${fullPath}`);
|
|
828
|
+
lines.push(String(value));
|
|
922
829
|
}
|
|
923
830
|
}
|
|
924
831
|
return lines.join("\n");
|
|
925
832
|
}
|
|
926
|
-
function
|
|
927
|
-
const entries = Object.entries(obj).map(([k, v]) => `${k} = ${formatTomlValue(v)}`);
|
|
928
|
-
return `{ ${entries.join(", ")} }`;
|
|
929
|
-
}
|
|
930
|
-
function formatTomlValue(value) {
|
|
931
|
-
if (typeof value === "string") {
|
|
932
|
-
if (value.includes("\n")) {
|
|
933
|
-
const delimiter = findSafeDelimiter(value);
|
|
934
|
-
return `<<<${delimiter}
|
|
935
|
-
${value}
|
|
936
|
-
${delimiter}`;
|
|
937
|
-
}
|
|
938
|
-
return JSON.stringify(value);
|
|
939
|
-
}
|
|
940
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
941
|
-
return String(value);
|
|
942
|
-
}
|
|
943
|
-
if (value === null || value === void 0) {
|
|
944
|
-
return '""';
|
|
945
|
-
}
|
|
946
|
-
if (Array.isArray(value)) {
|
|
947
|
-
if (value.length === 0) return "[]";
|
|
948
|
-
const items = value.map((item) => {
|
|
949
|
-
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
950
|
-
return formatTomlInlineTable(item);
|
|
951
|
-
}
|
|
952
|
-
return formatTomlValue(item);
|
|
953
|
-
});
|
|
954
|
-
return `[${items.join(", ")}]`;
|
|
955
|
-
}
|
|
956
|
-
if (typeof value === "object") {
|
|
957
|
-
return formatTomlInlineTable(value);
|
|
958
|
-
}
|
|
959
|
-
return JSON.stringify(value);
|
|
960
|
-
}
|
|
961
|
-
function formatParamsAsToml(params) {
|
|
833
|
+
function formatSchemaAsPlainText(schema, indent = "") {
|
|
962
834
|
const lines = [];
|
|
963
|
-
|
|
964
|
-
|
|
835
|
+
const properties = schema.properties || {};
|
|
836
|
+
const required = schema.required || [];
|
|
837
|
+
for (const [key, prop] of Object.entries(properties)) {
|
|
838
|
+
const propObj = prop;
|
|
839
|
+
const type = propObj.type;
|
|
840
|
+
const description = propObj.description;
|
|
841
|
+
const isRequired = required.includes(key);
|
|
842
|
+
const enumValues = propObj.enum;
|
|
843
|
+
let line = `${indent}- ${key}`;
|
|
844
|
+
if (type === "array") {
|
|
845
|
+
const items = propObj.items;
|
|
846
|
+
const itemType = items?.type || "any";
|
|
847
|
+
line += ` (array of ${itemType})`;
|
|
848
|
+
} else if (type === "object" && propObj.properties) {
|
|
849
|
+
line += " (object)";
|
|
850
|
+
} else {
|
|
851
|
+
line += ` (${type})`;
|
|
852
|
+
}
|
|
853
|
+
if (isRequired) {
|
|
854
|
+
line += " [required]";
|
|
855
|
+
}
|
|
856
|
+
if (description) {
|
|
857
|
+
line += `: ${description}`;
|
|
858
|
+
}
|
|
859
|
+
if (enumValues) {
|
|
860
|
+
line += ` - one of: ${enumValues.map((v) => `"${v}"`).join(", ")}`;
|
|
861
|
+
}
|
|
862
|
+
lines.push(line);
|
|
863
|
+
if (type === "object" && propObj.properties) {
|
|
864
|
+
lines.push(formatSchemaAsPlainText(propObj, indent + " "));
|
|
865
|
+
}
|
|
965
866
|
}
|
|
966
867
|
return lines.join("\n");
|
|
967
868
|
}
|
|
968
|
-
var
|
|
869
|
+
var BaseGadget;
|
|
969
870
|
var init_gadget = __esm({
|
|
970
871
|
"src/gadgets/gadget.ts"() {
|
|
971
872
|
"use strict";
|
|
972
|
-
|
|
873
|
+
init_constants();
|
|
973
874
|
init_schema_to_json();
|
|
974
875
|
init_schema_validator();
|
|
975
|
-
HEREDOC_DELIMITERS = [
|
|
976
|
-
"__GADGET_PARAM_EOF__",
|
|
977
|
-
"__GADGET_PARAM_END__",
|
|
978
|
-
"__GADGET_PARAM_DOC__",
|
|
979
|
-
"__GADGET_PARAM_CONTENT__",
|
|
980
|
-
"__GADGET_PARAM_TEXT__",
|
|
981
|
-
"__GADGET_PARAM_HEREDOC__",
|
|
982
|
-
"__GADGET_PARAM_DATA__",
|
|
983
|
-
"__GADGET_PARAM_BLOCK__"
|
|
984
|
-
];
|
|
985
876
|
BaseGadget = class {
|
|
986
877
|
/**
|
|
987
878
|
* The name of the gadget. Used for identification when LLM calls it.
|
|
@@ -1012,19 +903,19 @@ var init_gadget = __esm({
|
|
|
1012
903
|
/**
|
|
1013
904
|
* Auto-generated instruction text for the LLM.
|
|
1014
905
|
* Combines name, description, and parameter schema into a formatted instruction.
|
|
1015
|
-
* @deprecated Use getInstruction(
|
|
906
|
+
* @deprecated Use getInstruction() instead
|
|
1016
907
|
*/
|
|
1017
908
|
get instruction() {
|
|
1018
|
-
return this.getInstruction(
|
|
909
|
+
return this.getInstruction();
|
|
1019
910
|
}
|
|
1020
911
|
/**
|
|
1021
|
-
* Generate instruction text for the LLM
|
|
912
|
+
* Generate instruction text for the LLM.
|
|
1022
913
|
* Combines name, description, and parameter schema into a formatted instruction.
|
|
1023
914
|
*
|
|
1024
|
-
* @param
|
|
915
|
+
* @param argPrefix - Optional custom argument prefix for block format examples
|
|
1025
916
|
* @returns Formatted instruction string
|
|
1026
917
|
*/
|
|
1027
|
-
getInstruction(
|
|
918
|
+
getInstruction(argPrefix) {
|
|
1028
919
|
const parts = [];
|
|
1029
920
|
parts.push(this.description);
|
|
1030
921
|
if (this.parameterSchema) {
|
|
@@ -1033,20 +924,12 @@ var init_gadget = __esm({
|
|
|
1033
924
|
const jsonSchema = schemaToJSONSchema(this.parameterSchema, {
|
|
1034
925
|
target: "draft-7"
|
|
1035
926
|
});
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
parts.push(JSON.stringify(jsonSchema, null, 2));
|
|
1039
|
-
} else if (format === "toml") {
|
|
1040
|
-
parts.push("\n\nInput Schema (TOML):");
|
|
1041
|
-
parts.push(JSON.stringify(jsonSchema, null, 2));
|
|
1042
|
-
} else {
|
|
1043
|
-
const yamlSchema = yaml.dump(jsonSchema).trimEnd();
|
|
1044
|
-
parts.push("\n\nInput Schema (YAML):");
|
|
1045
|
-
parts.push(yamlSchema);
|
|
1046
|
-
}
|
|
927
|
+
parts.push("\n\nParameters:");
|
|
928
|
+
parts.push(formatSchemaAsPlainText(jsonSchema));
|
|
1047
929
|
}
|
|
1048
930
|
if (this.examples && this.examples.length > 0) {
|
|
1049
931
|
parts.push("\n\nExamples:");
|
|
932
|
+
const effectiveArgPrefix = argPrefix ?? GADGET_ARG_PREFIX;
|
|
1050
933
|
this.examples.forEach((example, index) => {
|
|
1051
934
|
if (index > 0) {
|
|
1052
935
|
parts.push("");
|
|
@@ -1055,13 +938,7 @@ var init_gadget = __esm({
|
|
|
1055
938
|
parts.push(`# ${example.comment}`);
|
|
1056
939
|
}
|
|
1057
940
|
parts.push("Input:");
|
|
1058
|
-
|
|
1059
|
-
parts.push(JSON.stringify(example.params, null, 2));
|
|
1060
|
-
} else if (format === "toml") {
|
|
1061
|
-
parts.push(formatParamsAsToml(example.params));
|
|
1062
|
-
} else {
|
|
1063
|
-
parts.push(formatParamsAsYaml(example.params));
|
|
1064
|
-
}
|
|
941
|
+
parts.push(formatParamsAsBlock(example.params, "", effectiveArgPrefix));
|
|
1065
942
|
if (example.output !== void 0) {
|
|
1066
943
|
parts.push("Output:");
|
|
1067
944
|
parts.push(example.output);
|
|
@@ -1338,14 +1215,12 @@ var init_conversation_manager = __esm({
|
|
|
1338
1215
|
baseMessages;
|
|
1339
1216
|
initialMessages;
|
|
1340
1217
|
historyBuilder;
|
|
1341
|
-
parameterFormat;
|
|
1342
1218
|
constructor(baseMessages, initialMessages, options = {}) {
|
|
1343
1219
|
this.baseMessages = baseMessages;
|
|
1344
1220
|
this.initialMessages = initialMessages;
|
|
1345
|
-
this.parameterFormat = options.parameterFormat ?? "json";
|
|
1346
1221
|
this.historyBuilder = new LLMMessageBuilder();
|
|
1347
1222
|
if (options.startPrefix && options.endPrefix) {
|
|
1348
|
-
this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix);
|
|
1223
|
+
this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix, options.argPrefix);
|
|
1349
1224
|
}
|
|
1350
1225
|
}
|
|
1351
1226
|
addUserMessage(content) {
|
|
@@ -1355,7 +1230,7 @@ var init_conversation_manager = __esm({
|
|
|
1355
1230
|
this.historyBuilder.addAssistant(content);
|
|
1356
1231
|
}
|
|
1357
1232
|
addGadgetCall(gadgetName, parameters, result) {
|
|
1358
|
-
this.historyBuilder.addGadgetCall(gadgetName, parameters, result
|
|
1233
|
+
this.historyBuilder.addGadgetCall(gadgetName, parameters, result);
|
|
1359
1234
|
}
|
|
1360
1235
|
getMessages() {
|
|
1361
1236
|
return [...this.baseMessages, ...this.initialMessages, ...this.historyBuilder.build()];
|
|
@@ -1378,7 +1253,7 @@ async function runWithHandlers(agentGenerator, handlers) {
|
|
|
1378
1253
|
await handlers.onGadgetCall({
|
|
1379
1254
|
gadgetName: event.call.gadgetName,
|
|
1380
1255
|
parameters: event.call.parameters,
|
|
1381
|
-
|
|
1256
|
+
parametersRaw: event.call.parametersRaw
|
|
1382
1257
|
});
|
|
1383
1258
|
}
|
|
1384
1259
|
break;
|
|
@@ -1655,7 +1530,7 @@ var init_executor = __esm({
|
|
|
1655
1530
|
this.logger.error("Gadget parameter parse error", {
|
|
1656
1531
|
gadgetName: call.gadgetName,
|
|
1657
1532
|
parseError: call.parseError,
|
|
1658
|
-
rawParameters: call.
|
|
1533
|
+
rawParameters: call.parametersRaw
|
|
1659
1534
|
});
|
|
1660
1535
|
return {
|
|
1661
1536
|
gadgetName: call.gadgetName,
|
|
@@ -1817,168 +1692,107 @@ var init_executor = __esm({
|
|
|
1817
1692
|
}
|
|
1818
1693
|
});
|
|
1819
1694
|
|
|
1820
|
-
// src/gadgets/
|
|
1821
|
-
function
|
|
1822
|
-
const
|
|
1823
|
-
const result =
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
const
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
const
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
if (i < lines.length) {
|
|
1838
|
-
i++;
|
|
1839
|
-
}
|
|
1840
|
-
result.push(`${indent}${key}: |`);
|
|
1841
|
-
for (const bodyLine of bodyLines) {
|
|
1842
|
-
result.push(`${indent} ${bodyLine}`);
|
|
1695
|
+
// src/gadgets/block-params.ts
|
|
1696
|
+
function parseBlockParams(content, options) {
|
|
1697
|
+
const argPrefix = options?.argPrefix ?? GADGET_ARG_PREFIX;
|
|
1698
|
+
const result = {};
|
|
1699
|
+
const seenPointers = /* @__PURE__ */ new Set();
|
|
1700
|
+
const parts = content.split(argPrefix);
|
|
1701
|
+
for (let i = 1; i < parts.length; i++) {
|
|
1702
|
+
const part = parts[i];
|
|
1703
|
+
const newlineIndex = part.indexOf("\n");
|
|
1704
|
+
if (newlineIndex === -1) {
|
|
1705
|
+
const pointer2 = part.trim();
|
|
1706
|
+
if (pointer2) {
|
|
1707
|
+
if (seenPointers.has(pointer2)) {
|
|
1708
|
+
throw new Error(`Duplicate pointer: ${pointer2}`);
|
|
1709
|
+
}
|
|
1710
|
+
seenPointers.add(pointer2);
|
|
1711
|
+
setByPointer(result, pointer2, "");
|
|
1843
1712
|
}
|
|
1844
1713
|
continue;
|
|
1845
1714
|
}
|
|
1846
|
-
const
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
const blockLine = lines[i];
|
|
1857
|
-
const blockIndentMatch = blockLine.match(/^(\s*)/);
|
|
1858
|
-
const blockIndentLen = blockIndentMatch ? blockIndentMatch[1].length : 0;
|
|
1859
|
-
if (blockLine.trim() === "") {
|
|
1860
|
-
blockLines.push({ content: "", originalIndent: 0 });
|
|
1861
|
-
i++;
|
|
1862
|
-
continue;
|
|
1863
|
-
}
|
|
1864
|
-
if (blockIndentLen > keyIndentLen2) {
|
|
1865
|
-
const content = blockLine.substring(blockIndentLen);
|
|
1866
|
-
blockLines.push({ content, originalIndent: blockIndentLen });
|
|
1867
|
-
if (content.trim().length > 0) {
|
|
1868
|
-
minContentIndent = Math.min(minContentIndent, blockIndentLen);
|
|
1869
|
-
}
|
|
1870
|
-
i++;
|
|
1871
|
-
} else {
|
|
1872
|
-
break;
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
const targetIndent = keyIndentLen2 + 2;
|
|
1876
|
-
for (const blockLine of blockLines) {
|
|
1877
|
-
if (blockLine.content === "") {
|
|
1878
|
-
result.push("");
|
|
1879
|
-
} else {
|
|
1880
|
-
result.push(" ".repeat(targetIndent) + blockLine.content);
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
continue;
|
|
1884
|
-
}
|
|
1885
|
-
if (value.startsWith('"') || value.startsWith("'") || value === "true" || value === "false" || /^-?\d+(\.\d+)?$/.test(value)) {
|
|
1886
|
-
result.push(line);
|
|
1887
|
-
i++;
|
|
1888
|
-
continue;
|
|
1889
|
-
}
|
|
1890
|
-
const keyIndentLen = indent.length;
|
|
1891
|
-
const continuationLines = [];
|
|
1892
|
-
let j = i + 1;
|
|
1893
|
-
while (j < lines.length) {
|
|
1894
|
-
const nextLine = lines[j];
|
|
1895
|
-
if (nextLine.trim() === "") {
|
|
1896
|
-
continuationLines.push(nextLine);
|
|
1897
|
-
j++;
|
|
1898
|
-
continue;
|
|
1899
|
-
}
|
|
1900
|
-
const nextIndentMatch = nextLine.match(/^(\s*)/);
|
|
1901
|
-
const nextIndentLen = nextIndentMatch ? nextIndentMatch[1].length : 0;
|
|
1902
|
-
if (nextIndentLen > keyIndentLen) {
|
|
1903
|
-
continuationLines.push(nextLine);
|
|
1904
|
-
j++;
|
|
1905
|
-
} else {
|
|
1906
|
-
break;
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
|
-
if (continuationLines.length > 0 && continuationLines.some((l) => l.trim().length > 0)) {
|
|
1910
|
-
result.push(`${indent}${key}: |`);
|
|
1911
|
-
result.push(`${indent} ${value}`);
|
|
1912
|
-
for (const contLine of continuationLines) {
|
|
1913
|
-
if (contLine.trim() === "") {
|
|
1914
|
-
result.push("");
|
|
1915
|
-
} else {
|
|
1916
|
-
const contIndentMatch = contLine.match(/^(\s*)/);
|
|
1917
|
-
const contIndent = contIndentMatch ? contIndentMatch[1] : "";
|
|
1918
|
-
const contContent = contLine.substring(contIndent.length);
|
|
1919
|
-
result.push(`${indent} ${contContent}`);
|
|
1920
|
-
}
|
|
1921
|
-
}
|
|
1922
|
-
i = j;
|
|
1923
|
-
continue;
|
|
1924
|
-
}
|
|
1925
|
-
if (value.includes(": ") || value.endsWith(":")) {
|
|
1926
|
-
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
1927
|
-
result.push(`${indent}${key}: "${escaped}"`);
|
|
1928
|
-
i++;
|
|
1929
|
-
continue;
|
|
1930
|
-
}
|
|
1715
|
+
const pointer = part.substring(0, newlineIndex).trim();
|
|
1716
|
+
let value = part.substring(newlineIndex + 1);
|
|
1717
|
+
if (value.endsWith("\n")) {
|
|
1718
|
+
value = value.slice(0, -1);
|
|
1719
|
+
}
|
|
1720
|
+
if (!pointer) {
|
|
1721
|
+
continue;
|
|
1722
|
+
}
|
|
1723
|
+
if (seenPointers.has(pointer)) {
|
|
1724
|
+
throw new Error(`Duplicate pointer: ${pointer}`);
|
|
1931
1725
|
}
|
|
1932
|
-
|
|
1933
|
-
|
|
1726
|
+
seenPointers.add(pointer);
|
|
1727
|
+
setByPointer(result, pointer, value);
|
|
1934
1728
|
}
|
|
1935
|
-
return result
|
|
1729
|
+
return result;
|
|
1936
1730
|
}
|
|
1937
|
-
function
|
|
1938
|
-
|
|
1731
|
+
function coerceValue(value) {
|
|
1732
|
+
if (value.includes("\n")) {
|
|
1733
|
+
return value;
|
|
1734
|
+
}
|
|
1735
|
+
const trimmed = value.trim();
|
|
1736
|
+
if (trimmed === "true") return true;
|
|
1737
|
+
if (trimmed === "false") return false;
|
|
1738
|
+
if (trimmed !== "" && /^-?\d+(\.\d+)?$/.test(trimmed)) {
|
|
1739
|
+
const num = Number(trimmed);
|
|
1740
|
+
if (!isNaN(num) && isFinite(num)) {
|
|
1741
|
+
return num;
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
return value;
|
|
1939
1745
|
}
|
|
1940
|
-
function
|
|
1941
|
-
const
|
|
1942
|
-
|
|
1943
|
-
let i = 0;
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
const
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
}
|
|
1964
|
-
if (bodyLines.length === 0) {
|
|
1965
|
-
result.push(`${indent}${key} = ''''''`);
|
|
1966
|
-
} else {
|
|
1967
|
-
result.push(`${indent}${key} = '''`);
|
|
1968
|
-
for (let j = 0; j < bodyLines.length - 1; j++) {
|
|
1969
|
-
result.push(unescapeHeredocContent(bodyLines[j]));
|
|
1970
|
-
}
|
|
1971
|
-
result.push(`${unescapeHeredocContent(bodyLines[bodyLines.length - 1])}'''`);
|
|
1972
|
-
}
|
|
1973
|
-
if (!foundClosing) {
|
|
1746
|
+
function setByPointer(obj, pointer, value) {
|
|
1747
|
+
const segments = pointer.split("/");
|
|
1748
|
+
let current = obj;
|
|
1749
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
1750
|
+
const segment = segments[i];
|
|
1751
|
+
const nextSegment = segments[i + 1];
|
|
1752
|
+
const nextIsArrayIndex = /^\d+$/.test(nextSegment);
|
|
1753
|
+
if (Array.isArray(current)) {
|
|
1754
|
+
const index = parseInt(segment, 10);
|
|
1755
|
+
if (isNaN(index) || index < 0) {
|
|
1756
|
+
throw new Error(`Invalid array index: ${segment}`);
|
|
1757
|
+
}
|
|
1758
|
+
if (index > current.length) {
|
|
1759
|
+
throw new Error(`Array index gap: expected ${current.length}, got ${index}`);
|
|
1760
|
+
}
|
|
1761
|
+
if (current[index] === void 0) {
|
|
1762
|
+
current[index] = nextIsArrayIndex ? [] : {};
|
|
1763
|
+
}
|
|
1764
|
+
current = current[index];
|
|
1765
|
+
} else {
|
|
1766
|
+
const rec = current;
|
|
1767
|
+
if (rec[segment] === void 0) {
|
|
1768
|
+
rec[segment] = nextIsArrayIndex ? [] : {};
|
|
1974
1769
|
}
|
|
1975
|
-
|
|
1770
|
+
current = rec[segment];
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
const lastSegment = segments[segments.length - 1];
|
|
1774
|
+
const coercedValue = coerceValue(value);
|
|
1775
|
+
if (Array.isArray(current)) {
|
|
1776
|
+
const index = parseInt(lastSegment, 10);
|
|
1777
|
+
if (isNaN(index) || index < 0) {
|
|
1778
|
+
throw new Error(`Invalid array index: ${lastSegment}`);
|
|
1779
|
+
}
|
|
1780
|
+
if (index > current.length) {
|
|
1781
|
+
throw new Error(`Array index gap: expected ${current.length}, got ${index}`);
|
|
1976
1782
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1783
|
+
current[index] = coercedValue;
|
|
1784
|
+
} else {
|
|
1785
|
+
current[lastSegment] = coercedValue;
|
|
1979
1786
|
}
|
|
1980
|
-
return result.join("\n");
|
|
1981
1787
|
}
|
|
1788
|
+
var init_block_params = __esm({
|
|
1789
|
+
"src/gadgets/block-params.ts"() {
|
|
1790
|
+
"use strict";
|
|
1791
|
+
init_constants();
|
|
1792
|
+
}
|
|
1793
|
+
});
|
|
1794
|
+
|
|
1795
|
+
// src/gadgets/parser.ts
|
|
1982
1796
|
function stripMarkdownFences(content) {
|
|
1983
1797
|
let cleaned = content.trim();
|
|
1984
1798
|
const openingFence = /^```(?:toml|yaml|json)?\s*\n/i;
|
|
@@ -1987,24 +1801,23 @@ function stripMarkdownFences(content) {
|
|
|
1987
1801
|
cleaned = cleaned.replace(closingFence, "");
|
|
1988
1802
|
return cleaned.trim();
|
|
1989
1803
|
}
|
|
1990
|
-
var
|
|
1804
|
+
var globalInvocationCounter, StreamParser;
|
|
1991
1805
|
var init_parser = __esm({
|
|
1992
1806
|
"src/gadgets/parser.ts"() {
|
|
1993
1807
|
"use strict";
|
|
1994
|
-
yaml2 = __toESM(require("js-yaml"), 1);
|
|
1995
|
-
import_js_toml = require("js-toml");
|
|
1996
1808
|
init_constants();
|
|
1809
|
+
init_block_params();
|
|
1997
1810
|
globalInvocationCounter = 0;
|
|
1998
1811
|
StreamParser = class {
|
|
1999
1812
|
buffer = "";
|
|
2000
1813
|
lastReportedTextLength = 0;
|
|
2001
1814
|
startPrefix;
|
|
2002
1815
|
endPrefix;
|
|
2003
|
-
|
|
1816
|
+
argPrefix;
|
|
2004
1817
|
constructor(options = {}) {
|
|
2005
1818
|
this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
|
|
2006
1819
|
this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
|
|
2007
|
-
this.
|
|
1820
|
+
this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
|
|
2008
1821
|
}
|
|
2009
1822
|
takeTextUntil(index) {
|
|
2010
1823
|
if (index <= this.lastReportedTextLength) {
|
|
@@ -2039,43 +1852,14 @@ var init_parser = __esm({
|
|
|
2039
1852
|
return `${firstLine.slice(0, maxLen)}... (${message.length} chars total)`;
|
|
2040
1853
|
}
|
|
2041
1854
|
/**
|
|
2042
|
-
* Parse parameter string
|
|
1855
|
+
* Parse parameter string using block format
|
|
2043
1856
|
*/
|
|
2044
1857
|
parseParameters(raw) {
|
|
2045
1858
|
const cleaned = stripMarkdownFences(raw);
|
|
2046
|
-
if (this.parameterFormat === "json") {
|
|
2047
|
-
try {
|
|
2048
|
-
return { parameters: JSON.parse(cleaned) };
|
|
2049
|
-
} catch (error) {
|
|
2050
|
-
return { parseError: this.truncateParseError(error, "JSON") };
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
if (this.parameterFormat === "yaml") {
|
|
2054
|
-
try {
|
|
2055
|
-
return { parameters: yaml2.load(preprocessYaml(cleaned)) };
|
|
2056
|
-
} catch (error) {
|
|
2057
|
-
return { parseError: this.truncateParseError(error, "YAML") };
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
2060
|
-
if (this.parameterFormat === "toml") {
|
|
2061
|
-
try {
|
|
2062
|
-
return { parameters: (0, import_js_toml.load)(preprocessTomlHeredoc(cleaned)) };
|
|
2063
|
-
} catch (error) {
|
|
2064
|
-
return { parseError: this.truncateParseError(error, "TOML") };
|
|
2065
|
-
}
|
|
2066
|
-
}
|
|
2067
1859
|
try {
|
|
2068
|
-
return { parameters:
|
|
2069
|
-
} catch {
|
|
2070
|
-
|
|
2071
|
-
return { parameters: (0, import_js_toml.load)(preprocessTomlHeredoc(cleaned)) };
|
|
2072
|
-
} catch {
|
|
2073
|
-
try {
|
|
2074
|
-
return { parameters: yaml2.load(preprocessYaml(cleaned)) };
|
|
2075
|
-
} catch (error) {
|
|
2076
|
-
return { parseError: this.truncateParseError(error, "auto") };
|
|
2077
|
-
}
|
|
2078
|
-
}
|
|
1860
|
+
return { parameters: parseBlockParams(cleaned, { argPrefix: this.argPrefix }) };
|
|
1861
|
+
} catch (error) {
|
|
1862
|
+
return { parseError: this.truncateParseError(error, "block") };
|
|
2079
1863
|
}
|
|
2080
1864
|
}
|
|
2081
1865
|
// Feed a chunk of text and get parsed events
|
|
@@ -2134,8 +1918,7 @@ var init_parser = __esm({
|
|
|
2134
1918
|
call: {
|
|
2135
1919
|
gadgetName: actualGadgetName,
|
|
2136
1920
|
invocationId,
|
|
2137
|
-
|
|
2138
|
-
// Keep property name for backward compatibility
|
|
1921
|
+
parametersRaw,
|
|
2139
1922
|
parameters,
|
|
2140
1923
|
parseError
|
|
2141
1924
|
}
|
|
@@ -2169,7 +1952,7 @@ var init_parser = __esm({
|
|
|
2169
1952
|
call: {
|
|
2170
1953
|
gadgetName: actualGadgetName,
|
|
2171
1954
|
invocationId,
|
|
2172
|
-
|
|
1955
|
+
parametersRaw,
|
|
2173
1956
|
parameters,
|
|
2174
1957
|
parseError
|
|
2175
1958
|
}
|
|
@@ -2220,9 +2003,9 @@ var init_stream_processor = __esm({
|
|
|
2220
2003
|
this.stopOnGadgetError = options.stopOnGadgetError ?? true;
|
|
2221
2004
|
this.shouldContinueAfterError = options.shouldContinueAfterError;
|
|
2222
2005
|
this.parser = new StreamParser({
|
|
2223
|
-
parameterFormat: options.parameterFormat,
|
|
2224
2006
|
startPrefix: options.gadgetStartPrefix,
|
|
2225
|
-
endPrefix: options.gadgetEndPrefix
|
|
2007
|
+
endPrefix: options.gadgetEndPrefix,
|
|
2008
|
+
argPrefix: options.gadgetArgPrefix
|
|
2226
2009
|
});
|
|
2227
2010
|
this.executor = new GadgetExecutor(
|
|
2228
2011
|
options.registry,
|
|
@@ -2376,7 +2159,7 @@ var init_stream_processor = __esm({
|
|
|
2376
2159
|
this.logger.warn("Gadget has parse error", {
|
|
2377
2160
|
gadgetName: call.gadgetName,
|
|
2378
2161
|
error: call.parseError,
|
|
2379
|
-
rawParameters: call.
|
|
2162
|
+
rawParameters: call.parametersRaw
|
|
2380
2163
|
});
|
|
2381
2164
|
const shouldContinue = await this.checkContinueAfterError(
|
|
2382
2165
|
call.parseError,
|
|
@@ -2612,9 +2395,9 @@ var init_agent = __esm({
|
|
|
2612
2395
|
hooks;
|
|
2613
2396
|
conversation;
|
|
2614
2397
|
registry;
|
|
2615
|
-
parameterFormat;
|
|
2616
2398
|
gadgetStartPrefix;
|
|
2617
2399
|
gadgetEndPrefix;
|
|
2400
|
+
gadgetArgPrefix;
|
|
2618
2401
|
onHumanInputRequired;
|
|
2619
2402
|
textOnlyHandler;
|
|
2620
2403
|
textWithGadgetsHandler;
|
|
@@ -2643,9 +2426,9 @@ var init_agent = __esm({
|
|
|
2643
2426
|
this.temperature = options.temperature;
|
|
2644
2427
|
this.logger = options.logger ?? createLogger({ name: "llmist:agent" });
|
|
2645
2428
|
this.registry = options.registry;
|
|
2646
|
-
this.parameterFormat = options.parameterFormat ?? "json";
|
|
2647
2429
|
this.gadgetStartPrefix = options.gadgetStartPrefix;
|
|
2648
2430
|
this.gadgetEndPrefix = options.gadgetEndPrefix;
|
|
2431
|
+
this.gadgetArgPrefix = options.gadgetArgPrefix;
|
|
2649
2432
|
this.onHumanInputRequired = options.onHumanInputRequired;
|
|
2650
2433
|
this.textOnlyHandler = options.textOnlyHandler ?? "terminate";
|
|
2651
2434
|
this.textWithGadgetsHandler = options.textWithGadgetsHandler;
|
|
@@ -2667,9 +2450,10 @@ var init_agent = __esm({
|
|
|
2667
2450
|
if (options.systemPrompt) {
|
|
2668
2451
|
baseBuilder.addSystem(options.systemPrompt);
|
|
2669
2452
|
}
|
|
2670
|
-
baseBuilder.addGadgets(this.registry.getAll(),
|
|
2453
|
+
baseBuilder.addGadgets(this.registry.getAll(), {
|
|
2671
2454
|
startPrefix: options.gadgetStartPrefix,
|
|
2672
|
-
endPrefix: options.gadgetEndPrefix
|
|
2455
|
+
endPrefix: options.gadgetEndPrefix,
|
|
2456
|
+
argPrefix: options.gadgetArgPrefix
|
|
2673
2457
|
});
|
|
2674
2458
|
const baseMessages = baseBuilder.build();
|
|
2675
2459
|
const initialMessages = (options.initialMessages ?? []).map((message) => ({
|
|
@@ -2677,9 +2461,9 @@ var init_agent = __esm({
|
|
|
2677
2461
|
content: message.content
|
|
2678
2462
|
}));
|
|
2679
2463
|
this.conversation = new ConversationManager(baseMessages, initialMessages, {
|
|
2680
|
-
parameterFormat: this.parameterFormat,
|
|
2681
2464
|
startPrefix: options.gadgetStartPrefix,
|
|
2682
|
-
endPrefix: options.gadgetEndPrefix
|
|
2465
|
+
endPrefix: options.gadgetEndPrefix,
|
|
2466
|
+
argPrefix: options.gadgetArgPrefix
|
|
2683
2467
|
});
|
|
2684
2468
|
this.userPromptProvided = !!options.userPrompt;
|
|
2685
2469
|
if (options.userPrompt) {
|
|
@@ -2772,9 +2556,9 @@ var init_agent = __esm({
|
|
|
2772
2556
|
const processor = new StreamProcessor({
|
|
2773
2557
|
iteration: currentIteration,
|
|
2774
2558
|
registry: this.registry,
|
|
2775
|
-
parameterFormat: this.parameterFormat,
|
|
2776
2559
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
2777
2560
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
2561
|
+
gadgetArgPrefix: this.gadgetArgPrefix,
|
|
2778
2562
|
hooks: this.hooks,
|
|
2779
2563
|
logger: this.logger.getSubLogger({ name: "stream-processor" }),
|
|
2780
2564
|
onHumanInputRequired: this.onHumanInputRequired,
|
|
@@ -5040,9 +4824,9 @@ var init_builder = __esm({
|
|
|
5040
4824
|
gadgets = [];
|
|
5041
4825
|
initialMessages = [];
|
|
5042
4826
|
onHumanInputRequired;
|
|
5043
|
-
parameterFormat;
|
|
5044
4827
|
gadgetStartPrefix;
|
|
5045
4828
|
gadgetEndPrefix;
|
|
4829
|
+
gadgetArgPrefix;
|
|
5046
4830
|
textOnlyHandler;
|
|
5047
4831
|
textWithGadgetsHandler;
|
|
5048
4832
|
stopOnGadgetError;
|
|
@@ -5229,21 +5013,6 @@ var init_builder = __esm({
|
|
|
5229
5013
|
this.onHumanInputRequired = handler;
|
|
5230
5014
|
return this;
|
|
5231
5015
|
}
|
|
5232
|
-
/**
|
|
5233
|
-
* Set the parameter format for gadget calls.
|
|
5234
|
-
*
|
|
5235
|
-
* @param format - Parameter format ("json" or "xml")
|
|
5236
|
-
* @returns This builder for chaining
|
|
5237
|
-
*
|
|
5238
|
-
* @example
|
|
5239
|
-
* ```typescript
|
|
5240
|
-
* .withParameterFormat("xml")
|
|
5241
|
-
* ```
|
|
5242
|
-
*/
|
|
5243
|
-
withParameterFormat(format) {
|
|
5244
|
-
this.parameterFormat = format;
|
|
5245
|
-
return this;
|
|
5246
|
-
}
|
|
5247
5016
|
/**
|
|
5248
5017
|
* Set custom gadget marker prefix.
|
|
5249
5018
|
*
|
|
@@ -5274,6 +5043,21 @@ var init_builder = __esm({
|
|
|
5274
5043
|
this.gadgetEndPrefix = suffix;
|
|
5275
5044
|
return this;
|
|
5276
5045
|
}
|
|
5046
|
+
/**
|
|
5047
|
+
* Set custom argument prefix for block format parameters.
|
|
5048
|
+
*
|
|
5049
|
+
* @param prefix - Custom prefix for argument markers (default: "!!!ARG:")
|
|
5050
|
+
* @returns This builder for chaining
|
|
5051
|
+
*
|
|
5052
|
+
* @example
|
|
5053
|
+
* ```typescript
|
|
5054
|
+
* .withGadgetArgPrefix("<<ARG>>")
|
|
5055
|
+
* ```
|
|
5056
|
+
*/
|
|
5057
|
+
withGadgetArgPrefix(prefix) {
|
|
5058
|
+
this.gadgetArgPrefix = prefix;
|
|
5059
|
+
return this;
|
|
5060
|
+
}
|
|
5277
5061
|
/**
|
|
5278
5062
|
* Set the text-only handler strategy.
|
|
5279
5063
|
*
|
|
@@ -5473,8 +5257,7 @@ var init_builder = __esm({
|
|
|
5473
5257
|
withSyntheticGadgetCall(gadgetName, parameters, result) {
|
|
5474
5258
|
const startPrefix = this.gadgetStartPrefix ?? GADGET_START_PREFIX;
|
|
5475
5259
|
const endPrefix = this.gadgetEndPrefix ?? GADGET_END_PREFIX;
|
|
5476
|
-
const
|
|
5477
|
-
const paramStr = this.formatSyntheticParameters(parameters, format);
|
|
5260
|
+
const paramStr = this.formatBlockParameters(parameters, "");
|
|
5478
5261
|
this.initialMessages.push({
|
|
5479
5262
|
role: "assistant",
|
|
5480
5263
|
content: `${startPrefix}${gadgetName}
|
|
@@ -5488,25 +5271,31 @@ ${endPrefix}`
|
|
|
5488
5271
|
return this;
|
|
5489
5272
|
}
|
|
5490
5273
|
/**
|
|
5491
|
-
* Format parameters
|
|
5492
|
-
* Uses heredoc for multiline string values.
|
|
5274
|
+
* Format parameters as block format with JSON Pointer paths.
|
|
5493
5275
|
*/
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
if (
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5276
|
+
formatBlockParameters(params, prefix) {
|
|
5277
|
+
const lines = [];
|
|
5278
|
+
const argPrefix = this.gadgetArgPrefix ?? GADGET_ARG_PREFIX;
|
|
5279
|
+
for (const [key, value] of Object.entries(params)) {
|
|
5280
|
+
const fullPath = prefix ? `${prefix}/${key}` : key;
|
|
5281
|
+
if (Array.isArray(value)) {
|
|
5282
|
+
value.forEach((item, index) => {
|
|
5283
|
+
const itemPath = `${fullPath}/${index}`;
|
|
5284
|
+
if (typeof item === "object" && item !== null) {
|
|
5285
|
+
lines.push(this.formatBlockParameters(item, itemPath));
|
|
5286
|
+
} else {
|
|
5287
|
+
lines.push(`${argPrefix}${itemPath}`);
|
|
5288
|
+
lines.push(String(item));
|
|
5289
|
+
}
|
|
5290
|
+
});
|
|
5291
|
+
} else if (typeof value === "object" && value !== null) {
|
|
5292
|
+
lines.push(this.formatBlockParameters(value, fullPath));
|
|
5293
|
+
} else {
|
|
5294
|
+
lines.push(`${argPrefix}${fullPath}`);
|
|
5295
|
+
lines.push(String(value));
|
|
5507
5296
|
}
|
|
5508
|
-
|
|
5509
|
-
|
|
5297
|
+
}
|
|
5298
|
+
return lines.join("\n");
|
|
5510
5299
|
}
|
|
5511
5300
|
/**
|
|
5512
5301
|
* Build and create the agent with the given user prompt.
|
|
@@ -5546,9 +5335,9 @@ EOF`;
|
|
|
5546
5335
|
promptConfig: this.promptConfig,
|
|
5547
5336
|
initialMessages: this.initialMessages,
|
|
5548
5337
|
onHumanInputRequired: this.onHumanInputRequired,
|
|
5549
|
-
parameterFormat: this.parameterFormat,
|
|
5550
5338
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
5551
5339
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
5340
|
+
gadgetArgPrefix: this.gadgetArgPrefix,
|
|
5552
5341
|
textOnlyHandler: this.textOnlyHandler,
|
|
5553
5342
|
textWithGadgetsHandler: this.textWithGadgetsHandler,
|
|
5554
5343
|
stopOnGadgetError: this.stopOnGadgetError,
|
|
@@ -5648,9 +5437,9 @@ EOF`;
|
|
|
5648
5437
|
promptConfig: this.promptConfig,
|
|
5649
5438
|
initialMessages: this.initialMessages,
|
|
5650
5439
|
onHumanInputRequired: this.onHumanInputRequired,
|
|
5651
|
-
parameterFormat: this.parameterFormat,
|
|
5652
5440
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
5653
5441
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
5442
|
+
gadgetArgPrefix: this.gadgetArgPrefix,
|
|
5654
5443
|
textOnlyHandler: this.textOnlyHandler,
|
|
5655
5444
|
textWithGadgetsHandler: this.textWithGadgetsHandler,
|
|
5656
5445
|
stopOnGadgetError: this.stopOnGadgetError,
|
|
@@ -5675,7 +5464,6 @@ var COMMANDS = {
|
|
|
5675
5464
|
};
|
|
5676
5465
|
var LOG_LEVELS = ["silly", "trace", "debug", "info", "warn", "error", "fatal"];
|
|
5677
5466
|
var DEFAULT_MODEL = "openai:gpt-5-nano";
|
|
5678
|
-
var DEFAULT_PARAMETER_FORMAT = "toml";
|
|
5679
5467
|
var OPTION_FLAGS = {
|
|
5680
5468
|
model: "-m, --model <identifier>",
|
|
5681
5469
|
systemPrompt: "-s, --system <prompt>",
|
|
@@ -5683,10 +5471,11 @@ var OPTION_FLAGS = {
|
|
|
5683
5471
|
maxTokens: "--max-tokens <count>",
|
|
5684
5472
|
maxIterations: "-i, --max-iterations <count>",
|
|
5685
5473
|
gadgetModule: "-g, --gadget <module>",
|
|
5686
|
-
parameterFormat: "--parameter-format <format>",
|
|
5687
5474
|
logLevel: "--log-level <level>",
|
|
5688
5475
|
logFile: "--log-file <path>",
|
|
5689
5476
|
logReset: "--log-reset",
|
|
5477
|
+
logLlmRequests: "--log-llm-requests [dir]",
|
|
5478
|
+
logLlmResponses: "--log-llm-responses [dir]",
|
|
5690
5479
|
noBuiltins: "--no-builtins",
|
|
5691
5480
|
noBuiltinInteraction: "--no-builtin-interaction",
|
|
5692
5481
|
quiet: "-q, --quiet"
|
|
@@ -5698,10 +5487,11 @@ var OPTION_DESCRIPTIONS = {
|
|
|
5698
5487
|
maxTokens: "Maximum number of output tokens requested from the model.",
|
|
5699
5488
|
maxIterations: "Maximum number of agent loop iterations before exiting.",
|
|
5700
5489
|
gadgetModule: "Path or module specifier for a gadget export. Repeat to register multiple gadgets.",
|
|
5701
|
-
parameterFormat: "Format for gadget parameter schemas: 'json', 'yaml', 'toml', or 'auto'.",
|
|
5702
5490
|
logLevel: "Log level: silly, trace, debug, info, warn, error, fatal.",
|
|
5703
5491
|
logFile: "Path to log file. When set, logs are written to file instead of stderr.",
|
|
5704
5492
|
logReset: "Reset (truncate) the log file at session start instead of appending.",
|
|
5493
|
+
logLlmRequests: "Save raw LLM requests as plain text. Optional dir, defaults to ~/.llmist/logs/requests/",
|
|
5494
|
+
logLlmResponses: "Save raw LLM responses as plain text. Optional dir, defaults to ~/.llmist/logs/responses/",
|
|
5705
5495
|
noBuiltins: "Disable built-in gadgets (AskUser, TellUser).",
|
|
5706
5496
|
noBuiltinInteraction: "Disable interactive gadgets (AskUser) while keeping TellUser.",
|
|
5707
5497
|
quiet: "Suppress all output except content (text and TellUser messages)."
|
|
@@ -5709,12 +5499,12 @@ var OPTION_DESCRIPTIONS = {
|
|
|
5709
5499
|
var SUMMARY_PREFIX = "[llmist]";
|
|
5710
5500
|
|
|
5711
5501
|
// src/cli/program.ts
|
|
5712
|
-
var
|
|
5502
|
+
var import_commander2 = require("commander");
|
|
5713
5503
|
|
|
5714
5504
|
// package.json
|
|
5715
5505
|
var package_default = {
|
|
5716
5506
|
name: "llmist",
|
|
5717
|
-
version: "0.
|
|
5507
|
+
version: "0.8.0",
|
|
5718
5508
|
description: "Universal TypeScript LLM client with streaming-first agent framework. Works with any model - no structured outputs or native tool calling required. Implements its own flexible grammar for function calling.",
|
|
5719
5509
|
type: "module",
|
|
5720
5510
|
main: "dist/index.cjs",
|
|
@@ -5827,7 +5617,7 @@ var package_default = {
|
|
|
5827
5617
|
};
|
|
5828
5618
|
|
|
5829
5619
|
// src/cli/agent-command.ts
|
|
5830
|
-
var
|
|
5620
|
+
var import_promises2 = require("readline/promises");
|
|
5831
5621
|
var import_chalk3 = __toESM(require("chalk"), 1);
|
|
5832
5622
|
init_builder();
|
|
5833
5623
|
init_registry();
|
|
@@ -6016,8 +5806,33 @@ async function loadGadgets(specifiers, cwd, importer = (specifier) => import(spe
|
|
|
6016
5806
|
return gadgets;
|
|
6017
5807
|
}
|
|
6018
5808
|
|
|
6019
|
-
// src/cli/
|
|
6020
|
-
var
|
|
5809
|
+
// src/cli/llm-logging.ts
|
|
5810
|
+
var import_promises = require("fs/promises");
|
|
5811
|
+
var import_node_os = require("os");
|
|
5812
|
+
var import_node_path3 = require("path");
|
|
5813
|
+
var DEFAULT_LLM_LOG_DIR = (0, import_node_path3.join)((0, import_node_os.homedir)(), ".llmist", "logs");
|
|
5814
|
+
function resolveLogDir(option, subdir) {
|
|
5815
|
+
if (option === true) {
|
|
5816
|
+
return (0, import_node_path3.join)(DEFAULT_LLM_LOG_DIR, subdir);
|
|
5817
|
+
}
|
|
5818
|
+
if (typeof option === "string") {
|
|
5819
|
+
return option;
|
|
5820
|
+
}
|
|
5821
|
+
return void 0;
|
|
5822
|
+
}
|
|
5823
|
+
function formatLlmRequest(messages) {
|
|
5824
|
+
const lines = [];
|
|
5825
|
+
for (const msg of messages) {
|
|
5826
|
+
lines.push(`=== ${msg.role.toUpperCase()} ===`);
|
|
5827
|
+
lines.push(msg.content ?? "");
|
|
5828
|
+
lines.push("");
|
|
5829
|
+
}
|
|
5830
|
+
return lines.join("\n");
|
|
5831
|
+
}
|
|
5832
|
+
async function writeLogFile(dir, filename, content) {
|
|
5833
|
+
await (0, import_promises.mkdir)(dir, { recursive: true });
|
|
5834
|
+
await (0, import_promises.writeFile)((0, import_node_path3.join)(dir, filename), content, "utf-8");
|
|
5835
|
+
}
|
|
6021
5836
|
|
|
6022
5837
|
// src/cli/utils.ts
|
|
6023
5838
|
var import_chalk2 = __toESM(require("chalk"), 1);
|
|
@@ -6061,9 +5876,29 @@ function ensureMarkedConfigured() {
|
|
|
6061
5876
|
}
|
|
6062
5877
|
function renderMarkdown(text) {
|
|
6063
5878
|
ensureMarkedConfigured();
|
|
6064
|
-
|
|
5879
|
+
let rendered = import_marked.marked.parse(text);
|
|
5880
|
+
rendered = rendered.replace(/\*\*(.+?)\*\*/g, (_, content) => import_chalk.default.bold(content)).replace(/(?<!\*)\*(\S[^*]*)\*(?!\*)/g, (_, content) => import_chalk.default.italic(content));
|
|
6065
5881
|
return rendered.trimEnd();
|
|
6066
5882
|
}
|
|
5883
|
+
function createRainbowSeparator() {
|
|
5884
|
+
const colors = [import_chalk.default.red, import_chalk.default.yellow, import_chalk.default.green, import_chalk.default.cyan, import_chalk.default.blue, import_chalk.default.magenta];
|
|
5885
|
+
const char = "\u2500";
|
|
5886
|
+
const width = process.stdout.columns || 80;
|
|
5887
|
+
let result = "";
|
|
5888
|
+
for (let i = 0; i < width; i++) {
|
|
5889
|
+
result += colors[i % colors.length](char);
|
|
5890
|
+
}
|
|
5891
|
+
return result;
|
|
5892
|
+
}
|
|
5893
|
+
function renderMarkdownWithSeparators(text) {
|
|
5894
|
+
const rendered = renderMarkdown(text);
|
|
5895
|
+
const separator = createRainbowSeparator();
|
|
5896
|
+
return `
|
|
5897
|
+
${separator}
|
|
5898
|
+
${rendered}
|
|
5899
|
+
${separator}
|
|
5900
|
+
`;
|
|
5901
|
+
}
|
|
6067
5902
|
function formatTokens(tokens) {
|
|
6068
5903
|
return tokens >= 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : `${tokens}`;
|
|
6069
5904
|
}
|
|
@@ -6183,7 +6018,7 @@ function formatGadgetSummary(result) {
|
|
|
6183
6018
|
const summaryLine = `${icon} ${gadgetLabel}${paramsLabel} ${import_chalk.default.dim("\u2192")} ${outputLabel} ${timeLabel}`;
|
|
6184
6019
|
if (result.gadgetName === "TellUser" && result.parameters?.message) {
|
|
6185
6020
|
const message = String(result.parameters.message);
|
|
6186
|
-
const rendered =
|
|
6021
|
+
const rendered = renderMarkdownWithSeparators(message);
|
|
6187
6022
|
return `${summaryLine}
|
|
6188
6023
|
${rendered}`;
|
|
6189
6024
|
}
|
|
@@ -6490,7 +6325,7 @@ var StreamProgress = class {
|
|
|
6490
6325
|
}
|
|
6491
6326
|
this.isRunning = false;
|
|
6492
6327
|
if (this.hasRendered) {
|
|
6493
|
-
this.target.write("\r\x1B[K");
|
|
6328
|
+
this.target.write("\r\x1B[K\x1B[0G");
|
|
6494
6329
|
this.hasRendered = false;
|
|
6495
6330
|
}
|
|
6496
6331
|
}
|
|
@@ -6583,16 +6418,6 @@ async function executeAction(action, env) {
|
|
|
6583
6418
|
}
|
|
6584
6419
|
|
|
6585
6420
|
// src/cli/option-helpers.ts
|
|
6586
|
-
var PARAMETER_FORMAT_VALUES = ["json", "yaml", "toml", "auto"];
|
|
6587
|
-
function parseParameterFormat(value) {
|
|
6588
|
-
const normalized = value.toLowerCase();
|
|
6589
|
-
if (!PARAMETER_FORMAT_VALUES.includes(normalized)) {
|
|
6590
|
-
throw new import_commander2.InvalidArgumentError(
|
|
6591
|
-
`Parameter format must be one of: ${PARAMETER_FORMAT_VALUES.join(", ")}`
|
|
6592
|
-
);
|
|
6593
|
-
}
|
|
6594
|
-
return normalized;
|
|
6595
|
-
}
|
|
6596
6421
|
function addCompleteOptions(cmd, defaults) {
|
|
6597
6422
|
return cmd.option(OPTION_FLAGS.model, OPTION_DESCRIPTIONS.model, defaults?.model ?? DEFAULT_MODEL).option(OPTION_FLAGS.systemPrompt, OPTION_DESCRIPTIONS.systemPrompt, defaults?.system).option(
|
|
6598
6423
|
OPTION_FLAGS.temperature,
|
|
@@ -6604,7 +6429,7 @@ function addCompleteOptions(cmd, defaults) {
|
|
|
6604
6429
|
OPTION_DESCRIPTIONS.maxTokens,
|
|
6605
6430
|
createNumericParser({ label: "Max tokens", integer: true, min: 1 }),
|
|
6606
6431
|
defaults?.["max-tokens"]
|
|
6607
|
-
).option(OPTION_FLAGS.quiet, OPTION_DESCRIPTIONS.quiet, defaults?.quiet);
|
|
6432
|
+
).option(OPTION_FLAGS.quiet, OPTION_DESCRIPTIONS.quiet, defaults?.quiet).option(OPTION_FLAGS.logLlmRequests, OPTION_DESCRIPTIONS.logLlmRequests, defaults?.["log-llm-requests"]).option(OPTION_FLAGS.logLlmResponses, OPTION_DESCRIPTIONS.logLlmResponses, defaults?.["log-llm-responses"]);
|
|
6608
6433
|
}
|
|
6609
6434
|
function addAgentOptions(cmd, defaults) {
|
|
6610
6435
|
const gadgetAccumulator = (value, previous = []) => [
|
|
@@ -6624,16 +6449,11 @@ function addAgentOptions(cmd, defaults) {
|
|
|
6624
6449
|
defaults?.["max-iterations"]
|
|
6625
6450
|
).option(OPTION_FLAGS.gadgetModule, OPTION_DESCRIPTIONS.gadgetModule, gadgetAccumulator, [
|
|
6626
6451
|
...defaultGadgets
|
|
6627
|
-
]).option(
|
|
6628
|
-
OPTION_FLAGS.parameterFormat,
|
|
6629
|
-
OPTION_DESCRIPTIONS.parameterFormat,
|
|
6630
|
-
parseParameterFormat,
|
|
6631
|
-
defaults?.["parameter-format"] ?? DEFAULT_PARAMETER_FORMAT
|
|
6632
|
-
).option(OPTION_FLAGS.noBuiltins, OPTION_DESCRIPTIONS.noBuiltins, defaults?.builtins !== false).option(
|
|
6452
|
+
]).option(OPTION_FLAGS.noBuiltins, OPTION_DESCRIPTIONS.noBuiltins, defaults?.builtins !== false).option(
|
|
6633
6453
|
OPTION_FLAGS.noBuiltinInteraction,
|
|
6634
6454
|
OPTION_DESCRIPTIONS.noBuiltinInteraction,
|
|
6635
6455
|
defaults?.["builtin-interaction"] !== false
|
|
6636
|
-
).option(OPTION_FLAGS.quiet, OPTION_DESCRIPTIONS.quiet, defaults?.quiet);
|
|
6456
|
+
).option(OPTION_FLAGS.quiet, OPTION_DESCRIPTIONS.quiet, defaults?.quiet).option(OPTION_FLAGS.logLlmRequests, OPTION_DESCRIPTIONS.logLlmRequests, defaults?.["log-llm-requests"]).option(OPTION_FLAGS.logLlmResponses, OPTION_DESCRIPTIONS.logLlmResponses, defaults?.["log-llm-responses"]);
|
|
6637
6457
|
}
|
|
6638
6458
|
function configToCompleteOptions(config) {
|
|
6639
6459
|
const result = {};
|
|
@@ -6642,6 +6462,8 @@ function configToCompleteOptions(config) {
|
|
|
6642
6462
|
if (config.temperature !== void 0) result.temperature = config.temperature;
|
|
6643
6463
|
if (config["max-tokens"] !== void 0) result.maxTokens = config["max-tokens"];
|
|
6644
6464
|
if (config.quiet !== void 0) result.quiet = config.quiet;
|
|
6465
|
+
if (config["log-llm-requests"] !== void 0) result.logLlmRequests = config["log-llm-requests"];
|
|
6466
|
+
if (config["log-llm-responses"] !== void 0) result.logLlmResponses = config["log-llm-responses"];
|
|
6645
6467
|
return result;
|
|
6646
6468
|
}
|
|
6647
6469
|
function configToAgentOptions(config) {
|
|
@@ -6651,7 +6473,6 @@ function configToAgentOptions(config) {
|
|
|
6651
6473
|
if (config.temperature !== void 0) result.temperature = config.temperature;
|
|
6652
6474
|
if (config["max-iterations"] !== void 0) result.maxIterations = config["max-iterations"];
|
|
6653
6475
|
if (config.gadget !== void 0) result.gadget = config.gadget;
|
|
6654
|
-
if (config["parameter-format"] !== void 0) result.parameterFormat = config["parameter-format"];
|
|
6655
6476
|
if (config.builtins !== void 0) result.builtins = config.builtins;
|
|
6656
6477
|
if (config["builtin-interaction"] !== void 0)
|
|
6657
6478
|
result.builtinInteraction = config["builtin-interaction"];
|
|
@@ -6659,13 +6480,17 @@ function configToAgentOptions(config) {
|
|
|
6659
6480
|
result.gadgetStartPrefix = config["gadget-start-prefix"];
|
|
6660
6481
|
if (config["gadget-end-prefix"] !== void 0)
|
|
6661
6482
|
result.gadgetEndPrefix = config["gadget-end-prefix"];
|
|
6483
|
+
if (config["gadget-arg-prefix"] !== void 0)
|
|
6484
|
+
result.gadgetArgPrefix = config["gadget-arg-prefix"];
|
|
6662
6485
|
if (config.quiet !== void 0) result.quiet = config.quiet;
|
|
6486
|
+
if (config["log-llm-requests"] !== void 0) result.logLlmRequests = config["log-llm-requests"];
|
|
6487
|
+
if (config["log-llm-responses"] !== void 0) result.logLlmResponses = config["log-llm-responses"];
|
|
6663
6488
|
return result;
|
|
6664
6489
|
}
|
|
6665
6490
|
|
|
6666
6491
|
// src/cli/agent-command.ts
|
|
6667
6492
|
async function promptApproval(env, prompt) {
|
|
6668
|
-
const rl = (0,
|
|
6493
|
+
const rl = (0, import_promises2.createInterface)({ input: env.stdin, output: env.stderr });
|
|
6669
6494
|
try {
|
|
6670
6495
|
const answer = await rl.question(prompt);
|
|
6671
6496
|
return answer.trim();
|
|
@@ -6680,10 +6505,10 @@ function createHumanInputHandler(env, progress) {
|
|
|
6680
6505
|
}
|
|
6681
6506
|
return async (question) => {
|
|
6682
6507
|
progress.pause();
|
|
6683
|
-
const rl = (0,
|
|
6508
|
+
const rl = (0, import_promises2.createInterface)({ input: env.stdin, output: env.stdout });
|
|
6684
6509
|
try {
|
|
6685
6510
|
const questionLine = question.trim() ? `
|
|
6686
|
-
${
|
|
6511
|
+
${renderMarkdownWithSeparators(question.trim())}` : "";
|
|
6687
6512
|
let isFirst = true;
|
|
6688
6513
|
while (true) {
|
|
6689
6514
|
const statsPrompt = progress.formatPrompt();
|
|
@@ -6726,6 +6551,9 @@ async function executeAgent(promptArg, options, env) {
|
|
|
6726
6551
|
const progress = new StreamProgress(env.stderr, stderrTTY, client.modelRegistry);
|
|
6727
6552
|
let usage;
|
|
6728
6553
|
let iterations = 0;
|
|
6554
|
+
const llmRequestsDir = resolveLogDir(options.logLlmRequests, "requests");
|
|
6555
|
+
const llmResponsesDir = resolveLogDir(options.logLlmResponses, "responses");
|
|
6556
|
+
let llmCallCounter = 0;
|
|
6729
6557
|
const countMessagesTokens = async (model, messages) => {
|
|
6730
6558
|
try {
|
|
6731
6559
|
return await client.countTokens(model, messages);
|
|
@@ -6748,12 +6576,18 @@ async function executeAgent(promptArg, options, env) {
|
|
|
6748
6576
|
// onLLMCallStart: Start progress indicator for each LLM call
|
|
6749
6577
|
// This showcases how to react to agent lifecycle events
|
|
6750
6578
|
onLLMCallStart: async (context) => {
|
|
6579
|
+
llmCallCounter++;
|
|
6751
6580
|
const inputTokens = await countMessagesTokens(
|
|
6752
6581
|
context.options.model,
|
|
6753
6582
|
context.options.messages
|
|
6754
6583
|
);
|
|
6755
6584
|
progress.startCall(context.options.model, inputTokens);
|
|
6756
6585
|
progress.setInputTokens(inputTokens, false);
|
|
6586
|
+
if (llmRequestsDir) {
|
|
6587
|
+
const filename = `${Date.now()}_call_${llmCallCounter}.request.txt`;
|
|
6588
|
+
const content = formatLlmRequest(context.options.messages);
|
|
6589
|
+
await writeLogFile(llmRequestsDir, filename, content);
|
|
6590
|
+
}
|
|
6757
6591
|
},
|
|
6758
6592
|
// onStreamChunk: Real-time updates as LLM generates tokens
|
|
6759
6593
|
// This enables responsive UIs that show progress during generation
|
|
@@ -6816,6 +6650,10 @@ async function executeAgent(promptArg, options, env) {
|
|
|
6816
6650
|
`);
|
|
6817
6651
|
}
|
|
6818
6652
|
}
|
|
6653
|
+
if (llmResponsesDir) {
|
|
6654
|
+
const filename = `${Date.now()}_call_${llmCallCounter}.response.txt`;
|
|
6655
|
+
await writeLogFile(llmResponsesDir, filename, context.rawResponse);
|
|
6656
|
+
}
|
|
6819
6657
|
}
|
|
6820
6658
|
},
|
|
6821
6659
|
// SHOWCASE: Controller-based approval gating for dangerous gadgets
|
|
@@ -6880,13 +6718,15 @@ Command rejected by user with message: "${response}"`
|
|
|
6880
6718
|
if (gadgets.length > 0) {
|
|
6881
6719
|
builder.withGadgets(...gadgets);
|
|
6882
6720
|
}
|
|
6883
|
-
builder.withParameterFormat(options.parameterFormat);
|
|
6884
6721
|
if (options.gadgetStartPrefix) {
|
|
6885
6722
|
builder.withGadgetStartPrefix(options.gadgetStartPrefix);
|
|
6886
6723
|
}
|
|
6887
6724
|
if (options.gadgetEndPrefix) {
|
|
6888
6725
|
builder.withGadgetEndPrefix(options.gadgetEndPrefix);
|
|
6889
6726
|
}
|
|
6727
|
+
if (options.gadgetArgPrefix) {
|
|
6728
|
+
builder.withGadgetArgPrefix(options.gadgetArgPrefix);
|
|
6729
|
+
}
|
|
6890
6730
|
builder.withSyntheticGadgetCall(
|
|
6891
6731
|
"TellUser",
|
|
6892
6732
|
{
|
|
@@ -6903,17 +6743,25 @@ Command rejected by user with message: "${response}"`
|
|
|
6903
6743
|
resultMapping: (text) => `\u2139\uFE0F ${text}`
|
|
6904
6744
|
});
|
|
6905
6745
|
const agent = builder.ask(prompt);
|
|
6746
|
+
let textBuffer = "";
|
|
6747
|
+
const flushTextBuffer = () => {
|
|
6748
|
+
if (textBuffer) {
|
|
6749
|
+
const output = options.quiet ? textBuffer : renderMarkdownWithSeparators(textBuffer);
|
|
6750
|
+
printer.write(output);
|
|
6751
|
+
textBuffer = "";
|
|
6752
|
+
}
|
|
6753
|
+
};
|
|
6906
6754
|
for await (const event of agent.run()) {
|
|
6907
6755
|
if (event.type === "text") {
|
|
6908
6756
|
progress.pause();
|
|
6909
|
-
|
|
6757
|
+
textBuffer += event.content;
|
|
6910
6758
|
} else if (event.type === "gadget_result") {
|
|
6759
|
+
flushTextBuffer();
|
|
6911
6760
|
progress.pause();
|
|
6912
6761
|
if (options.quiet) {
|
|
6913
6762
|
if (event.result.gadgetName === "TellUser" && event.result.parameters?.message) {
|
|
6914
6763
|
const message = String(event.result.parameters.message);
|
|
6915
|
-
|
|
6916
|
-
env.stdout.write(`${rendered}
|
|
6764
|
+
env.stdout.write(`${message}
|
|
6917
6765
|
`);
|
|
6918
6766
|
}
|
|
6919
6767
|
} else {
|
|
@@ -6923,6 +6771,7 @@ Command rejected by user with message: "${response}"`
|
|
|
6923
6771
|
}
|
|
6924
6772
|
}
|
|
6925
6773
|
}
|
|
6774
|
+
flushTextBuffer();
|
|
6926
6775
|
progress.complete();
|
|
6927
6776
|
printer.ensureNewline();
|
|
6928
6777
|
if (!options.quiet && iterations > 1) {
|
|
@@ -6961,9 +6810,18 @@ async function executeComplete(promptArg, options, env) {
|
|
|
6961
6810
|
builder.addSystem(options.system);
|
|
6962
6811
|
}
|
|
6963
6812
|
builder.addUser(prompt);
|
|
6813
|
+
const messages = builder.build();
|
|
6814
|
+
const llmRequestsDir = resolveLogDir(options.logLlmRequests, "requests");
|
|
6815
|
+
const llmResponsesDir = resolveLogDir(options.logLlmResponses, "responses");
|
|
6816
|
+
const timestamp = Date.now();
|
|
6817
|
+
if (llmRequestsDir) {
|
|
6818
|
+
const filename = `${timestamp}_complete.request.txt`;
|
|
6819
|
+
const content = formatLlmRequest(messages);
|
|
6820
|
+
await writeLogFile(llmRequestsDir, filename, content);
|
|
6821
|
+
}
|
|
6964
6822
|
const stream2 = client.stream({
|
|
6965
6823
|
model,
|
|
6966
|
-
messages
|
|
6824
|
+
messages,
|
|
6967
6825
|
temperature: options.temperature,
|
|
6968
6826
|
maxTokens: options.maxTokens
|
|
6969
6827
|
});
|
|
@@ -6974,7 +6832,7 @@ async function executeComplete(promptArg, options, env) {
|
|
|
6974
6832
|
progress.startCall(model, estimatedInputTokens);
|
|
6975
6833
|
let finishReason;
|
|
6976
6834
|
let usage;
|
|
6977
|
-
let
|
|
6835
|
+
let accumulatedResponse = "";
|
|
6978
6836
|
for await (const chunk of stream2) {
|
|
6979
6837
|
if (chunk.usage) {
|
|
6980
6838
|
usage = chunk.usage;
|
|
@@ -6987,8 +6845,8 @@ async function executeComplete(promptArg, options, env) {
|
|
|
6987
6845
|
}
|
|
6988
6846
|
if (chunk.text) {
|
|
6989
6847
|
progress.pause();
|
|
6990
|
-
|
|
6991
|
-
progress.update(
|
|
6848
|
+
accumulatedResponse += chunk.text;
|
|
6849
|
+
progress.update(accumulatedResponse.length);
|
|
6992
6850
|
printer.write(chunk.text);
|
|
6993
6851
|
}
|
|
6994
6852
|
if (chunk.finishReason !== void 0) {
|
|
@@ -6998,6 +6856,10 @@ async function executeComplete(promptArg, options, env) {
|
|
|
6998
6856
|
progress.endCall(usage);
|
|
6999
6857
|
progress.complete();
|
|
7000
6858
|
printer.ensureNewline();
|
|
6859
|
+
if (llmResponsesDir) {
|
|
6860
|
+
const filename = `${timestamp}_complete.response.txt`;
|
|
6861
|
+
await writeLogFile(llmResponsesDir, filename, accumulatedResponse);
|
|
6862
|
+
}
|
|
7001
6863
|
if (stderrTTY && !options.quiet) {
|
|
7002
6864
|
const summary = renderSummary({ finishReason, usage, cost: progress.getTotalCost() });
|
|
7003
6865
|
if (summary) {
|
|
@@ -7016,9 +6878,9 @@ function registerCompleteCommand(program, env, config) {
|
|
|
7016
6878
|
|
|
7017
6879
|
// src/cli/config.ts
|
|
7018
6880
|
var import_node_fs3 = require("fs");
|
|
7019
|
-
var
|
|
7020
|
-
var
|
|
7021
|
-
var
|
|
6881
|
+
var import_node_os2 = require("os");
|
|
6882
|
+
var import_node_path4 = require("path");
|
|
6883
|
+
var import_js_toml = require("js-toml");
|
|
7022
6884
|
|
|
7023
6885
|
// src/cli/templates.ts
|
|
7024
6886
|
var import_eta = require("eta");
|
|
@@ -7112,6 +6974,8 @@ var COMPLETE_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
7112
6974
|
"log-level",
|
|
7113
6975
|
"log-file",
|
|
7114
6976
|
"log-reset",
|
|
6977
|
+
"log-llm-requests",
|
|
6978
|
+
"log-llm-responses",
|
|
7115
6979
|
"type"
|
|
7116
6980
|
// Allowed for inheritance compatibility, ignored for built-in commands
|
|
7117
6981
|
]);
|
|
@@ -7121,16 +6985,18 @@ var AGENT_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
7121
6985
|
"temperature",
|
|
7122
6986
|
"max-iterations",
|
|
7123
6987
|
"gadget",
|
|
7124
|
-
"parameter-format",
|
|
7125
6988
|
"builtins",
|
|
7126
6989
|
"builtin-interaction",
|
|
7127
6990
|
"gadget-start-prefix",
|
|
7128
6991
|
"gadget-end-prefix",
|
|
6992
|
+
"gadget-arg-prefix",
|
|
7129
6993
|
"quiet",
|
|
7130
6994
|
"inherits",
|
|
7131
6995
|
"log-level",
|
|
7132
6996
|
"log-file",
|
|
7133
6997
|
"log-reset",
|
|
6998
|
+
"log-llm-requests",
|
|
6999
|
+
"log-llm-responses",
|
|
7134
7000
|
"type"
|
|
7135
7001
|
// Allowed for inheritance compatibility, ignored for built-in commands
|
|
7136
7002
|
]);
|
|
@@ -7140,9 +7006,8 @@ var CUSTOM_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
7140
7006
|
"type",
|
|
7141
7007
|
"description"
|
|
7142
7008
|
]);
|
|
7143
|
-
var VALID_PARAMETER_FORMATS = ["json", "yaml", "toml", "auto"];
|
|
7144
7009
|
function getConfigPath() {
|
|
7145
|
-
return (0,
|
|
7010
|
+
return (0, import_node_path4.join)((0, import_node_os2.homedir)(), ".llmist", "cli.toml");
|
|
7146
7011
|
}
|
|
7147
7012
|
var ConfigError = class extends Error {
|
|
7148
7013
|
constructor(message, path2) {
|
|
@@ -7276,6 +7141,20 @@ function validateCompleteConfig(raw, section) {
|
|
|
7276
7141
|
if ("quiet" in rawObj) {
|
|
7277
7142
|
result.quiet = validateBoolean(rawObj.quiet, "quiet", section);
|
|
7278
7143
|
}
|
|
7144
|
+
if ("log-llm-requests" in rawObj) {
|
|
7145
|
+
result["log-llm-requests"] = validateStringOrBoolean(
|
|
7146
|
+
rawObj["log-llm-requests"],
|
|
7147
|
+
"log-llm-requests",
|
|
7148
|
+
section
|
|
7149
|
+
);
|
|
7150
|
+
}
|
|
7151
|
+
if ("log-llm-responses" in rawObj) {
|
|
7152
|
+
result["log-llm-responses"] = validateStringOrBoolean(
|
|
7153
|
+
rawObj["log-llm-responses"],
|
|
7154
|
+
"log-llm-responses",
|
|
7155
|
+
section
|
|
7156
|
+
);
|
|
7157
|
+
}
|
|
7279
7158
|
return result;
|
|
7280
7159
|
}
|
|
7281
7160
|
function validateAgentConfig(raw, section) {
|
|
@@ -7301,15 +7180,6 @@ function validateAgentConfig(raw, section) {
|
|
|
7301
7180
|
if ("gadget" in rawObj) {
|
|
7302
7181
|
result.gadget = validateStringArray(rawObj.gadget, "gadget", section);
|
|
7303
7182
|
}
|
|
7304
|
-
if ("parameter-format" in rawObj) {
|
|
7305
|
-
const format = validateString(rawObj["parameter-format"], "parameter-format", section);
|
|
7306
|
-
if (!VALID_PARAMETER_FORMATS.includes(format)) {
|
|
7307
|
-
throw new ConfigError(
|
|
7308
|
-
`[${section}].parameter-format must be one of: ${VALID_PARAMETER_FORMATS.join(", ")}`
|
|
7309
|
-
);
|
|
7310
|
-
}
|
|
7311
|
-
result["parameter-format"] = format;
|
|
7312
|
-
}
|
|
7313
7183
|
if ("builtins" in rawObj) {
|
|
7314
7184
|
result.builtins = validateBoolean(rawObj.builtins, "builtins", section);
|
|
7315
7185
|
}
|
|
@@ -7334,11 +7204,38 @@ function validateAgentConfig(raw, section) {
|
|
|
7334
7204
|
section
|
|
7335
7205
|
);
|
|
7336
7206
|
}
|
|
7207
|
+
if ("gadget-arg-prefix" in rawObj) {
|
|
7208
|
+
result["gadget-arg-prefix"] = validateString(
|
|
7209
|
+
rawObj["gadget-arg-prefix"],
|
|
7210
|
+
"gadget-arg-prefix",
|
|
7211
|
+
section
|
|
7212
|
+
);
|
|
7213
|
+
}
|
|
7337
7214
|
if ("quiet" in rawObj) {
|
|
7338
7215
|
result.quiet = validateBoolean(rawObj.quiet, "quiet", section);
|
|
7339
7216
|
}
|
|
7217
|
+
if ("log-llm-requests" in rawObj) {
|
|
7218
|
+
result["log-llm-requests"] = validateStringOrBoolean(
|
|
7219
|
+
rawObj["log-llm-requests"],
|
|
7220
|
+
"log-llm-requests",
|
|
7221
|
+
section
|
|
7222
|
+
);
|
|
7223
|
+
}
|
|
7224
|
+
if ("log-llm-responses" in rawObj) {
|
|
7225
|
+
result["log-llm-responses"] = validateStringOrBoolean(
|
|
7226
|
+
rawObj["log-llm-responses"],
|
|
7227
|
+
"log-llm-responses",
|
|
7228
|
+
section
|
|
7229
|
+
);
|
|
7230
|
+
}
|
|
7340
7231
|
return result;
|
|
7341
7232
|
}
|
|
7233
|
+
function validateStringOrBoolean(value, field, section) {
|
|
7234
|
+
if (typeof value === "string" || typeof value === "boolean") {
|
|
7235
|
+
return value;
|
|
7236
|
+
}
|
|
7237
|
+
throw new ConfigError(`[${section}].${field} must be a string or boolean`);
|
|
7238
|
+
}
|
|
7342
7239
|
function validateCustomConfig(raw, section) {
|
|
7343
7240
|
if (typeof raw !== "object" || raw === null) {
|
|
7344
7241
|
throw new ConfigError(`[${section}] must be a table`);
|
|
@@ -7373,15 +7270,6 @@ function validateCustomConfig(raw, section) {
|
|
|
7373
7270
|
if ("gadget" in rawObj) {
|
|
7374
7271
|
result.gadget = validateStringArray(rawObj.gadget, "gadget", section);
|
|
7375
7272
|
}
|
|
7376
|
-
if ("parameter-format" in rawObj) {
|
|
7377
|
-
const format = validateString(rawObj["parameter-format"], "parameter-format", section);
|
|
7378
|
-
if (!VALID_PARAMETER_FORMATS.includes(format)) {
|
|
7379
|
-
throw new ConfigError(
|
|
7380
|
-
`[${section}].parameter-format must be one of: ${VALID_PARAMETER_FORMATS.join(", ")}`
|
|
7381
|
-
);
|
|
7382
|
-
}
|
|
7383
|
-
result["parameter-format"] = format;
|
|
7384
|
-
}
|
|
7385
7273
|
if ("builtins" in rawObj) {
|
|
7386
7274
|
result.builtins = validateBoolean(rawObj.builtins, "builtins", section);
|
|
7387
7275
|
}
|
|
@@ -7406,6 +7294,13 @@ function validateCustomConfig(raw, section) {
|
|
|
7406
7294
|
section
|
|
7407
7295
|
);
|
|
7408
7296
|
}
|
|
7297
|
+
if ("gadget-arg-prefix" in rawObj) {
|
|
7298
|
+
result["gadget-arg-prefix"] = validateString(
|
|
7299
|
+
rawObj["gadget-arg-prefix"],
|
|
7300
|
+
"gadget-arg-prefix",
|
|
7301
|
+
section
|
|
7302
|
+
);
|
|
7303
|
+
}
|
|
7409
7304
|
if ("max-tokens" in rawObj) {
|
|
7410
7305
|
result["max-tokens"] = validateNumber(rawObj["max-tokens"], "max-tokens", section, {
|
|
7411
7306
|
integer: true,
|
|
@@ -7475,7 +7370,7 @@ function loadConfig() {
|
|
|
7475
7370
|
}
|
|
7476
7371
|
let raw;
|
|
7477
7372
|
try {
|
|
7478
|
-
raw = (0,
|
|
7373
|
+
raw = (0, import_js_toml.load)(content);
|
|
7479
7374
|
} catch (error) {
|
|
7480
7375
|
throw new ConfigError(
|
|
7481
7376
|
`Invalid TOML syntax: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
@@ -7891,12 +7786,12 @@ function registerCustomCommand(program, name, config, env) {
|
|
|
7891
7786
|
function parseLogLevel2(value) {
|
|
7892
7787
|
const normalized = value.toLowerCase();
|
|
7893
7788
|
if (!LOG_LEVELS.includes(normalized)) {
|
|
7894
|
-
throw new
|
|
7789
|
+
throw new import_commander2.InvalidArgumentError(`Log level must be one of: ${LOG_LEVELS.join(", ")}`);
|
|
7895
7790
|
}
|
|
7896
7791
|
return normalized;
|
|
7897
7792
|
}
|
|
7898
7793
|
function createProgram(env, config) {
|
|
7899
|
-
const program = new
|
|
7794
|
+
const program = new import_commander2.Command();
|
|
7900
7795
|
program.name(CLI_NAME).description(CLI_DESCRIPTION).version(package_default.version).option(OPTION_FLAGS.logLevel, OPTION_DESCRIPTIONS.logLevel, parseLogLevel2).option(OPTION_FLAGS.logFile, OPTION_DESCRIPTIONS.logFile).option(OPTION_FLAGS.logReset, OPTION_DESCRIPTIONS.logReset).configureOutput({
|
|
7901
7796
|
writeOut: (str) => env.stdout.write(str),
|
|
7902
7797
|
writeErr: (str) => env.stderr.write(str)
|
|
@@ -7917,7 +7812,7 @@ async function runCLI(overrides = {}) {
|
|
|
7917
7812
|
const opts = "env" in overrides || "config" in overrides ? overrides : { env: overrides };
|
|
7918
7813
|
const config = opts.config !== void 0 ? opts.config : loadConfig();
|
|
7919
7814
|
const envOverrides = opts.env ?? {};
|
|
7920
|
-
const preParser = new
|
|
7815
|
+
const preParser = new import_commander2.Command();
|
|
7921
7816
|
preParser.option(OPTION_FLAGS.logLevel, OPTION_DESCRIPTIONS.logLevel, parseLogLevel2).option(OPTION_FLAGS.logFile, OPTION_DESCRIPTIONS.logFile).option(OPTION_FLAGS.logReset, OPTION_DESCRIPTIONS.logReset).allowUnknownOption().allowExcessArguments().helpOption(false);
|
|
7922
7817
|
preParser.parse(process.argv);
|
|
7923
7818
|
const globalOpts = preParser.opts();
|