llmist 0.8.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-4IMGADVY.js → chunk-OIPLYP7M.js} +40 -5
- package/dist/chunk-OIPLYP7M.js.map +1 -0
- package/dist/{chunk-62M4TDAK.js → chunk-VXPZQZF5.js} +432 -555
- package/dist/chunk-VXPZQZF5.js.map +1 -0
- package/dist/cli.cjs +1069 -658
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +638 -95
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +464 -558
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -9
- package/dist/index.d.ts +78 -9
- 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 +464 -558
- 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/testing/index.cjs
CHANGED
|
@@ -110,12 +110,13 @@ var init_logger = __esm({
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
// src/core/constants.ts
|
|
113
|
-
var GADGET_START_PREFIX, GADGET_END_PREFIX, DEFAULT_GADGET_OUTPUT_LIMIT, DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT, CHARS_PER_TOKEN, FALLBACK_CONTEXT_WINDOW;
|
|
113
|
+
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;
|
|
114
114
|
var init_constants = __esm({
|
|
115
115
|
"src/core/constants.ts"() {
|
|
116
116
|
"use strict";
|
|
117
117
|
GADGET_START_PREFIX = "!!!GADGET_START:";
|
|
118
118
|
GADGET_END_PREFIX = "!!!GADGET_END";
|
|
119
|
+
GADGET_ARG_PREFIX = "!!!ARG:";
|
|
119
120
|
DEFAULT_GADGET_OUTPUT_LIMIT = true;
|
|
120
121
|
DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT = 15;
|
|
121
122
|
CHARS_PER_TOKEN = 4;
|
|
@@ -448,17 +449,12 @@ var init_prompt_config = __esm({
|
|
|
448
449
|
"EACH MARKER MUST START WITH A NEWLINE."
|
|
449
450
|
].join("\n"),
|
|
450
451
|
criticalUsage: "INVOKE gadgets using the markers - do not describe what you want to do.",
|
|
451
|
-
|
|
452
|
-
formatDescriptionJson: "Parameters in JSON format (valid JSON object)",
|
|
453
|
-
formatDescriptionToml: "Parameters in TOML format (key = value pairs, use heredoc for multiline: key = <<<EOF ... EOF)",
|
|
452
|
+
formatDescription: (ctx) => `Parameters using ${ctx.argPrefix}name markers (value on next line(s), no escaping needed)`,
|
|
454
453
|
rules: () => [
|
|
455
454
|
"Output ONLY plain text with the exact markers - never use function/tool calling",
|
|
456
455
|
"You can invoke multiple gadgets in a single response",
|
|
457
456
|
"For dependent gadgets, invoke the first one and wait for the result"
|
|
458
457
|
],
|
|
459
|
-
schemaLabelJson: "\n\nInput Schema (JSON):",
|
|
460
|
-
schemaLabelYaml: "\n\nInput Schema (YAML):",
|
|
461
|
-
schemaLabelToml: "\n\nInput Schema (TOML):",
|
|
462
458
|
customExamples: null
|
|
463
459
|
};
|
|
464
460
|
}
|
|
@@ -475,6 +471,7 @@ var init_messages = __esm({
|
|
|
475
471
|
messages = [];
|
|
476
472
|
startPrefix = GADGET_START_PREFIX;
|
|
477
473
|
endPrefix = GADGET_END_PREFIX;
|
|
474
|
+
argPrefix = GADGET_ARG_PREFIX;
|
|
478
475
|
promptConfig;
|
|
479
476
|
constructor(promptConfig) {
|
|
480
477
|
this.promptConfig = promptConfig ?? {};
|
|
@@ -483,26 +480,32 @@ var init_messages = __esm({
|
|
|
483
480
|
* Set custom prefixes for gadget markers.
|
|
484
481
|
* Used to configure history builder to match system prompt markers.
|
|
485
482
|
*/
|
|
486
|
-
withPrefixes(startPrefix, endPrefix) {
|
|
483
|
+
withPrefixes(startPrefix, endPrefix, argPrefix) {
|
|
487
484
|
this.startPrefix = startPrefix;
|
|
488
485
|
this.endPrefix = endPrefix;
|
|
486
|
+
if (argPrefix) {
|
|
487
|
+
this.argPrefix = argPrefix;
|
|
488
|
+
}
|
|
489
489
|
return this;
|
|
490
490
|
}
|
|
491
491
|
addSystem(content, metadata) {
|
|
492
492
|
this.messages.push({ role: "system", content, metadata });
|
|
493
493
|
return this;
|
|
494
494
|
}
|
|
495
|
-
addGadgets(gadgets,
|
|
495
|
+
addGadgets(gadgets, options) {
|
|
496
496
|
if (options?.startPrefix) {
|
|
497
497
|
this.startPrefix = options.startPrefix;
|
|
498
498
|
}
|
|
499
499
|
if (options?.endPrefix) {
|
|
500
500
|
this.endPrefix = options.endPrefix;
|
|
501
501
|
}
|
|
502
|
+
if (options?.argPrefix) {
|
|
503
|
+
this.argPrefix = options.argPrefix;
|
|
504
|
+
}
|
|
502
505
|
const context = {
|
|
503
|
-
parameterFormat,
|
|
504
506
|
startPrefix: this.startPrefix,
|
|
505
507
|
endPrefix: this.endPrefix,
|
|
508
|
+
argPrefix: this.argPrefix,
|
|
506
509
|
gadgetCount: gadgets.length,
|
|
507
510
|
gadgetNames: gadgets.map((g) => g.name ?? g.constructor.name)
|
|
508
511
|
};
|
|
@@ -513,26 +516,19 @@ var init_messages = __esm({
|
|
|
513
516
|
context
|
|
514
517
|
);
|
|
515
518
|
parts.push(mainInstruction);
|
|
516
|
-
parts.push(this.buildGadgetsSection(gadgets
|
|
517
|
-
parts.push(this.buildUsageSection(
|
|
519
|
+
parts.push(this.buildGadgetsSection(gadgets));
|
|
520
|
+
parts.push(this.buildUsageSection(context));
|
|
518
521
|
this.messages.push({ role: "system", content: parts.join("") });
|
|
519
522
|
return this;
|
|
520
523
|
}
|
|
521
|
-
buildGadgetsSection(gadgets
|
|
524
|
+
buildGadgetsSection(gadgets) {
|
|
522
525
|
const parts = [];
|
|
523
526
|
parts.push("\n\nAVAILABLE GADGETS");
|
|
524
527
|
parts.push("\n=================\n");
|
|
525
528
|
for (const gadget of gadgets) {
|
|
526
529
|
const gadgetName = gadget.name ?? gadget.constructor.name;
|
|
527
|
-
const instruction = gadget.getInstruction(
|
|
528
|
-
const
|
|
529
|
-
yaml: "\n\nInput Schema (YAML):",
|
|
530
|
-
json: "\n\nInput Schema (JSON):",
|
|
531
|
-
toml: "\n\nInput Schema (TOML):",
|
|
532
|
-
auto: "\n\nInput Schema (JSON):"
|
|
533
|
-
// auto defaults to JSON schema display
|
|
534
|
-
};
|
|
535
|
-
const schemaMarker = schemaMarkers[parameterFormat];
|
|
530
|
+
const instruction = gadget.getInstruction(this.argPrefix);
|
|
531
|
+
const schemaMarker = "\n\nInput Schema (BLOCK):";
|
|
536
532
|
const schemaIndex = instruction.indexOf(schemaMarker);
|
|
537
533
|
const description = (schemaIndex !== -1 ? instruction.substring(0, schemaIndex) : instruction).trim();
|
|
538
534
|
const schema = schemaIndex !== -1 ? instruction.substring(schemaIndex + schemaMarker.length).trim() : "";
|
|
@@ -543,35 +539,20 @@ ${description}`);
|
|
|
543
539
|
if (schema) {
|
|
544
540
|
parts.push(`
|
|
545
541
|
|
|
546
|
-
PARAMETERS (
|
|
542
|
+
PARAMETERS (BLOCK):
|
|
547
543
|
${schema}`);
|
|
548
544
|
}
|
|
549
545
|
parts.push("\n\n---");
|
|
550
546
|
}
|
|
551
547
|
return parts.join("");
|
|
552
548
|
}
|
|
553
|
-
buildUsageSection(
|
|
549
|
+
buildUsageSection(context) {
|
|
554
550
|
const parts = [];
|
|
555
|
-
const
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
json: {
|
|
561
|
-
config: this.promptConfig.formatDescriptionJson,
|
|
562
|
-
defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
|
|
563
|
-
},
|
|
564
|
-
toml: {
|
|
565
|
-
config: this.promptConfig.formatDescriptionToml,
|
|
566
|
-
defaultValue: DEFAULT_PROMPTS.formatDescriptionToml
|
|
567
|
-
},
|
|
568
|
-
auto: {
|
|
569
|
-
config: this.promptConfig.formatDescriptionJson,
|
|
570
|
-
defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
|
|
571
|
-
}
|
|
572
|
-
};
|
|
573
|
-
const { config, defaultValue } = formatDescriptionMap[parameterFormat];
|
|
574
|
-
const formatDescription = resolvePromptTemplate(config, defaultValue, context);
|
|
551
|
+
const formatDescription = resolvePromptTemplate(
|
|
552
|
+
this.promptConfig.formatDescription,
|
|
553
|
+
DEFAULT_PROMPTS.formatDescription,
|
|
554
|
+
context
|
|
555
|
+
);
|
|
575
556
|
parts.push("\n\nHOW TO INVOKE GADGETS");
|
|
576
557
|
parts.push("\n=====================\n");
|
|
577
558
|
const criticalUsage = resolvePromptTemplate(
|
|
@@ -589,124 +570,90 @@ CRITICAL: ${criticalUsage}
|
|
|
589
570
|
2. ${formatDescription}`);
|
|
590
571
|
parts.push(`
|
|
591
572
|
3. End marker: ${this.endPrefix}`);
|
|
592
|
-
parts.push(this.buildExamplesSection(
|
|
573
|
+
parts.push(this.buildExamplesSection(context));
|
|
593
574
|
parts.push(this.buildRulesSection(context));
|
|
594
575
|
parts.push("\n");
|
|
595
576
|
return parts.join("");
|
|
596
577
|
}
|
|
597
|
-
buildExamplesSection(
|
|
578
|
+
buildExamplesSection(context) {
|
|
598
579
|
if (this.promptConfig.customExamples) {
|
|
599
580
|
return this.promptConfig.customExamples(context);
|
|
600
581
|
}
|
|
601
582
|
const parts = [];
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
to
|
|
606
|
-
|
|
607
|
-
${this.
|
|
608
|
-
|
|
609
|
-
{
|
|
610
|
-
${this.endPrefix}`,
|
|
611
|
-
toml: `${this.startPrefix}translate
|
|
612
|
-
from = "English"
|
|
613
|
-
to = "Polish"
|
|
614
|
-
content = "Paris is the capital of France: a beautiful city."
|
|
615
|
-
${this.endPrefix}`,
|
|
616
|
-
auto: `${this.startPrefix}translate
|
|
617
|
-
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
618
|
-
${this.endPrefix}`
|
|
619
|
-
};
|
|
583
|
+
const singleExample = `${this.startPrefix}translate
|
|
584
|
+
${this.argPrefix}from
|
|
585
|
+
English
|
|
586
|
+
${this.argPrefix}to
|
|
587
|
+
Polish
|
|
588
|
+
${this.argPrefix}content
|
|
589
|
+
Paris is the capital of France: a beautiful city.
|
|
590
|
+
${this.endPrefix}`;
|
|
620
591
|
parts.push(`
|
|
621
592
|
|
|
622
593
|
EXAMPLE (Single Gadget):
|
|
623
594
|
|
|
624
|
-
${
|
|
625
|
-
const
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
to
|
|
629
|
-
|
|
595
|
+
${singleExample}`);
|
|
596
|
+
const multipleExample = `${this.startPrefix}translate
|
|
597
|
+
${this.argPrefix}from
|
|
598
|
+
English
|
|
599
|
+
${this.argPrefix}to
|
|
600
|
+
Polish
|
|
601
|
+
${this.argPrefix}content
|
|
602
|
+
Paris is the capital of France: a beautiful city.
|
|
630
603
|
${this.endPrefix}
|
|
631
604
|
${this.startPrefix}analyze
|
|
632
|
-
type
|
|
633
|
-
|
|
634
|
-
|
|
605
|
+
${this.argPrefix}type
|
|
606
|
+
economic_analysis
|
|
607
|
+
${this.argPrefix}matter
|
|
608
|
+
Polish Economy
|
|
609
|
+
${this.argPrefix}question
|
|
635
610
|
Analyze the following:
|
|
636
611
|
- Polish arms exports 2025
|
|
637
612
|
- Economic implications
|
|
638
|
-
|
|
639
|
-
${this.endPrefix}`,
|
|
640
|
-
json: `${this.startPrefix}translate
|
|
641
|
-
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
642
|
-
${this.endPrefix}
|
|
643
|
-
${this.startPrefix}analyze
|
|
644
|
-
{"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
|
|
645
|
-
${this.endPrefix}`,
|
|
646
|
-
toml: `${this.startPrefix}translate
|
|
647
|
-
from = "English"
|
|
648
|
-
to = "Polish"
|
|
649
|
-
content = "Paris is the capital of France: a beautiful city."
|
|
650
|
-
${this.endPrefix}
|
|
651
|
-
${this.startPrefix}analyze
|
|
652
|
-
type = "economic_analysis"
|
|
653
|
-
matter = "Polish Economy"
|
|
654
|
-
question = <<<EOF
|
|
655
|
-
Analyze the following:
|
|
656
|
-
- Polish arms exports 2025
|
|
657
|
-
- Economic implications
|
|
658
|
-
EOF
|
|
659
|
-
${this.endPrefix}`,
|
|
660
|
-
auto: `${this.startPrefix}translate
|
|
661
|
-
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
662
|
-
${this.endPrefix}
|
|
663
|
-
${this.startPrefix}analyze
|
|
664
|
-
{"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
|
|
665
|
-
${this.endPrefix}`
|
|
666
|
-
};
|
|
613
|
+
${this.endPrefix}`;
|
|
667
614
|
parts.push(`
|
|
668
615
|
|
|
669
616
|
EXAMPLE (Multiple Gadgets):
|
|
670
617
|
|
|
671
|
-
${
|
|
672
|
-
|
|
673
|
-
parts.push(`
|
|
674
|
-
|
|
675
|
-
YAML HEREDOC SYNTAX:
|
|
676
|
-
For string values with multiple lines, use heredoc syntax (<<<DELIMITER...DELIMITER):
|
|
618
|
+
${multipleExample}`);
|
|
619
|
+
parts.push(`
|
|
677
620
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
# Project Title
|
|
621
|
+
BLOCK FORMAT SYNTAX:
|
|
622
|
+
Block format uses ${this.argPrefix}name markers. Values are captured verbatim until the next marker.
|
|
681
623
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
624
|
+
${this.argPrefix}filename
|
|
625
|
+
calculator.ts
|
|
626
|
+
${this.argPrefix}code
|
|
627
|
+
class Calculator {
|
|
628
|
+
private history: string[] = [];
|
|
687
629
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
For string values with multiple lines, use heredoc syntax (<<<DELIMITER...DELIMITER):
|
|
630
|
+
add(a: number, b: number): number {
|
|
631
|
+
const result = a + b;
|
|
632
|
+
this.history.push(\`\${a} + \${b} = \${result}\`);
|
|
633
|
+
return result;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
695
636
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
637
|
+
BLOCK FORMAT RULES:
|
|
638
|
+
- Each parameter starts with ${this.argPrefix}parameterName on its own line
|
|
639
|
+
- The value starts on the NEXT line after the marker
|
|
640
|
+
- Value ends when the next ${this.argPrefix} or ${this.endPrefix} appears
|
|
641
|
+
- NO escaping needed - write values exactly as they should appear
|
|
642
|
+
- Perfect for code, JSON, markdown, or any content with special characters
|
|
699
643
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
644
|
+
NESTED OBJECTS (use / separator):
|
|
645
|
+
${this.argPrefix}config/timeout
|
|
646
|
+
30
|
|
647
|
+
${this.argPrefix}config/retries
|
|
648
|
+
3
|
|
649
|
+
Produces: { "config": { "timeout": "30", "retries": "3" } }
|
|
705
650
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
651
|
+
ARRAYS (use numeric indices):
|
|
652
|
+
${this.argPrefix}items/0
|
|
653
|
+
first
|
|
654
|
+
${this.argPrefix}items/1
|
|
655
|
+
second
|
|
656
|
+
Produces: { "items": ["first", "second"] }`);
|
|
710
657
|
return parts.join("");
|
|
711
658
|
}
|
|
712
659
|
buildRulesSection(context) {
|
|
@@ -727,8 +674,8 @@ NEVER use TOML triple-quote strings ("""). ALWAYS use heredoc syntax (<<<EOF...E
|
|
|
727
674
|
this.messages.push({ role: "assistant", content, metadata });
|
|
728
675
|
return this;
|
|
729
676
|
}
|
|
730
|
-
addGadgetCall(gadget, parameters, result
|
|
731
|
-
const paramStr = this.
|
|
677
|
+
addGadgetCall(gadget, parameters, result) {
|
|
678
|
+
const paramStr = this.formatBlockParameters(parameters, "");
|
|
732
679
|
this.messages.push({
|
|
733
680
|
role: "assistant",
|
|
734
681
|
content: `${this.startPrefix}${gadget}
|
|
@@ -741,26 +688,32 @@ ${this.endPrefix}`
|
|
|
741
688
|
});
|
|
742
689
|
return this;
|
|
743
690
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
691
|
+
/**
|
|
692
|
+
* Format parameters as Block format with JSON Pointer paths.
|
|
693
|
+
* Uses the configured argPrefix for consistency with system prompt.
|
|
694
|
+
*/
|
|
695
|
+
formatBlockParameters(params, prefix) {
|
|
696
|
+
const lines = [];
|
|
697
|
+
for (const [key, value] of Object.entries(params)) {
|
|
698
|
+
const fullPath = prefix ? `${prefix}/${key}` : key;
|
|
699
|
+
if (Array.isArray(value)) {
|
|
700
|
+
value.forEach((item, index) => {
|
|
701
|
+
const itemPath = `${fullPath}/${index}`;
|
|
702
|
+
if (typeof item === "object" && item !== null) {
|
|
703
|
+
lines.push(this.formatBlockParameters(item, itemPath));
|
|
704
|
+
} else {
|
|
705
|
+
lines.push(`${this.argPrefix}${itemPath}`);
|
|
706
|
+
lines.push(String(item));
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
} else if (typeof value === "object" && value !== null) {
|
|
710
|
+
lines.push(this.formatBlockParameters(value, fullPath));
|
|
711
|
+
} else {
|
|
712
|
+
lines.push(`${this.argPrefix}${fullPath}`);
|
|
713
|
+
lines.push(String(value));
|
|
714
|
+
}
|
|
762
715
|
}
|
|
763
|
-
return
|
|
716
|
+
return lines.join("\n");
|
|
764
717
|
}
|
|
765
718
|
build() {
|
|
766
719
|
return [...this.messages];
|
|
@@ -853,134 +806,72 @@ var init_schema_to_json = __esm({
|
|
|
853
806
|
});
|
|
854
807
|
|
|
855
808
|
// src/gadgets/gadget.ts
|
|
856
|
-
function
|
|
857
|
-
const lines = content.split("\n");
|
|
858
|
-
for (const delimiter of HEREDOC_DELIMITERS) {
|
|
859
|
-
const regex = new RegExp(`^${delimiter}\\s*$`);
|
|
860
|
-
const isUsed = lines.some((line) => regex.test(line));
|
|
861
|
-
if (!isUsed) {
|
|
862
|
-
return delimiter;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
let counter = 1;
|
|
866
|
-
while (counter < 1e3) {
|
|
867
|
-
const delimiter = `__GADGET_PARAM_${counter}__`;
|
|
868
|
-
const regex = new RegExp(`^${delimiter}\\s*$`);
|
|
869
|
-
const isUsed = lines.some((line) => regex.test(line));
|
|
870
|
-
if (!isUsed) {
|
|
871
|
-
return delimiter;
|
|
872
|
-
}
|
|
873
|
-
counter++;
|
|
874
|
-
}
|
|
875
|
-
return "HEREDOC_FALLBACK";
|
|
876
|
-
}
|
|
877
|
-
function formatYamlValue(value, indent = "") {
|
|
878
|
-
if (typeof value === "string") {
|
|
879
|
-
const lines = value.split("\n");
|
|
880
|
-
if (lines.length === 1 && !value.includes(":") && !value.startsWith("-")) {
|
|
881
|
-
return value;
|
|
882
|
-
}
|
|
883
|
-
const delimiter = findSafeDelimiter(value);
|
|
884
|
-
return `<<<${delimiter}
|
|
885
|
-
${value}
|
|
886
|
-
${delimiter}`;
|
|
887
|
-
}
|
|
888
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
889
|
-
return String(value);
|
|
890
|
-
}
|
|
891
|
-
if (value === null || value === void 0) {
|
|
892
|
-
return "null";
|
|
893
|
-
}
|
|
894
|
-
if (Array.isArray(value)) {
|
|
895
|
-
if (value.length === 0) return "[]";
|
|
896
|
-
const items = value.map((item) => `${indent}- ${formatYamlValue(item, indent + " ")}`);
|
|
897
|
-
return "\n" + items.join("\n");
|
|
898
|
-
}
|
|
899
|
-
if (typeof value === "object") {
|
|
900
|
-
const entries = Object.entries(value);
|
|
901
|
-
if (entries.length === 0) return "{}";
|
|
902
|
-
const lines = entries.map(([k, v]) => {
|
|
903
|
-
const formattedValue = formatYamlValue(v, indent + " ");
|
|
904
|
-
if (formattedValue.startsWith("\n") || formattedValue.startsWith("|")) {
|
|
905
|
-
return `${indent}${k}: ${formattedValue}`;
|
|
906
|
-
}
|
|
907
|
-
return `${indent}${k}: ${formattedValue}`;
|
|
908
|
-
});
|
|
909
|
-
return "\n" + lines.join("\n");
|
|
910
|
-
}
|
|
911
|
-
return yaml.dump(value).trimEnd();
|
|
912
|
-
}
|
|
913
|
-
function formatParamsAsYaml(params) {
|
|
809
|
+
function formatParamsAsBlock(params, prefix = "", argPrefix = GADGET_ARG_PREFIX) {
|
|
914
810
|
const lines = [];
|
|
915
811
|
for (const [key, value] of Object.entries(params)) {
|
|
916
|
-
const
|
|
917
|
-
if (
|
|
918
|
-
|
|
812
|
+
const fullPath = prefix ? `${prefix}/${key}` : key;
|
|
813
|
+
if (Array.isArray(value)) {
|
|
814
|
+
value.forEach((item, index) => {
|
|
815
|
+
const itemPath = `${fullPath}/${index}`;
|
|
816
|
+
if (typeof item === "object" && item !== null) {
|
|
817
|
+
lines.push(formatParamsAsBlock(item, itemPath, argPrefix));
|
|
818
|
+
} else {
|
|
819
|
+
lines.push(`${argPrefix}${itemPath}`);
|
|
820
|
+
lines.push(String(item));
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
} else if (typeof value === "object" && value !== null) {
|
|
824
|
+
lines.push(formatParamsAsBlock(value, fullPath, argPrefix));
|
|
919
825
|
} else {
|
|
920
|
-
lines.push(`${
|
|
826
|
+
lines.push(`${argPrefix}${fullPath}`);
|
|
827
|
+
lines.push(String(value));
|
|
921
828
|
}
|
|
922
829
|
}
|
|
923
830
|
return lines.join("\n");
|
|
924
831
|
}
|
|
925
|
-
function
|
|
926
|
-
const entries = Object.entries(obj).map(([k, v]) => `${k} = ${formatTomlValue(v)}`);
|
|
927
|
-
return `{ ${entries.join(", ")} }`;
|
|
928
|
-
}
|
|
929
|
-
function formatTomlValue(value) {
|
|
930
|
-
if (typeof value === "string") {
|
|
931
|
-
if (value.includes("\n")) {
|
|
932
|
-
const delimiter = findSafeDelimiter(value);
|
|
933
|
-
return `<<<${delimiter}
|
|
934
|
-
${value}
|
|
935
|
-
${delimiter}`;
|
|
936
|
-
}
|
|
937
|
-
return JSON.stringify(value);
|
|
938
|
-
}
|
|
939
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
940
|
-
return String(value);
|
|
941
|
-
}
|
|
942
|
-
if (value === null || value === void 0) {
|
|
943
|
-
return '""';
|
|
944
|
-
}
|
|
945
|
-
if (Array.isArray(value)) {
|
|
946
|
-
if (value.length === 0) return "[]";
|
|
947
|
-
const items = value.map((item) => {
|
|
948
|
-
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
949
|
-
return formatTomlInlineTable(item);
|
|
950
|
-
}
|
|
951
|
-
return formatTomlValue(item);
|
|
952
|
-
});
|
|
953
|
-
return `[${items.join(", ")}]`;
|
|
954
|
-
}
|
|
955
|
-
if (typeof value === "object") {
|
|
956
|
-
return formatTomlInlineTable(value);
|
|
957
|
-
}
|
|
958
|
-
return JSON.stringify(value);
|
|
959
|
-
}
|
|
960
|
-
function formatParamsAsToml(params) {
|
|
832
|
+
function formatSchemaAsPlainText(schema, indent = "") {
|
|
961
833
|
const lines = [];
|
|
962
|
-
|
|
963
|
-
|
|
834
|
+
const properties = schema.properties || {};
|
|
835
|
+
const required = schema.required || [];
|
|
836
|
+
for (const [key, prop] of Object.entries(properties)) {
|
|
837
|
+
const propObj = prop;
|
|
838
|
+
const type = propObj.type;
|
|
839
|
+
const description = propObj.description;
|
|
840
|
+
const isRequired = required.includes(key);
|
|
841
|
+
const enumValues = propObj.enum;
|
|
842
|
+
let line = `${indent}- ${key}`;
|
|
843
|
+
if (type === "array") {
|
|
844
|
+
const items = propObj.items;
|
|
845
|
+
const itemType = items?.type || "any";
|
|
846
|
+
line += ` (array of ${itemType})`;
|
|
847
|
+
} else if (type === "object" && propObj.properties) {
|
|
848
|
+
line += " (object)";
|
|
849
|
+
} else {
|
|
850
|
+
line += ` (${type})`;
|
|
851
|
+
}
|
|
852
|
+
if (isRequired) {
|
|
853
|
+
line += " [required]";
|
|
854
|
+
}
|
|
855
|
+
if (description) {
|
|
856
|
+
line += `: ${description}`;
|
|
857
|
+
}
|
|
858
|
+
if (enumValues) {
|
|
859
|
+
line += ` - one of: ${enumValues.map((v) => `"${v}"`).join(", ")}`;
|
|
860
|
+
}
|
|
861
|
+
lines.push(line);
|
|
862
|
+
if (type === "object" && propObj.properties) {
|
|
863
|
+
lines.push(formatSchemaAsPlainText(propObj, indent + " "));
|
|
864
|
+
}
|
|
964
865
|
}
|
|
965
866
|
return lines.join("\n");
|
|
966
867
|
}
|
|
967
|
-
var
|
|
868
|
+
var BaseGadget;
|
|
968
869
|
var init_gadget = __esm({
|
|
969
870
|
"src/gadgets/gadget.ts"() {
|
|
970
871
|
"use strict";
|
|
971
|
-
|
|
872
|
+
init_constants();
|
|
972
873
|
init_schema_to_json();
|
|
973
874
|
init_schema_validator();
|
|
974
|
-
HEREDOC_DELIMITERS = [
|
|
975
|
-
"__GADGET_PARAM_EOF__",
|
|
976
|
-
"__GADGET_PARAM_END__",
|
|
977
|
-
"__GADGET_PARAM_DOC__",
|
|
978
|
-
"__GADGET_PARAM_CONTENT__",
|
|
979
|
-
"__GADGET_PARAM_TEXT__",
|
|
980
|
-
"__GADGET_PARAM_HEREDOC__",
|
|
981
|
-
"__GADGET_PARAM_DATA__",
|
|
982
|
-
"__GADGET_PARAM_BLOCK__"
|
|
983
|
-
];
|
|
984
875
|
BaseGadget = class {
|
|
985
876
|
/**
|
|
986
877
|
* The name of the gadget. Used for identification when LLM calls it.
|
|
@@ -1011,19 +902,19 @@ var init_gadget = __esm({
|
|
|
1011
902
|
/**
|
|
1012
903
|
* Auto-generated instruction text for the LLM.
|
|
1013
904
|
* Combines name, description, and parameter schema into a formatted instruction.
|
|
1014
|
-
* @deprecated Use getInstruction(
|
|
905
|
+
* @deprecated Use getInstruction() instead
|
|
1015
906
|
*/
|
|
1016
907
|
get instruction() {
|
|
1017
|
-
return this.getInstruction(
|
|
908
|
+
return this.getInstruction();
|
|
1018
909
|
}
|
|
1019
910
|
/**
|
|
1020
|
-
* Generate instruction text for the LLM
|
|
911
|
+
* Generate instruction text for the LLM.
|
|
1021
912
|
* Combines name, description, and parameter schema into a formatted instruction.
|
|
1022
913
|
*
|
|
1023
|
-
* @param
|
|
914
|
+
* @param argPrefix - Optional custom argument prefix for block format examples
|
|
1024
915
|
* @returns Formatted instruction string
|
|
1025
916
|
*/
|
|
1026
|
-
getInstruction(
|
|
917
|
+
getInstruction(argPrefix) {
|
|
1027
918
|
const parts = [];
|
|
1028
919
|
parts.push(this.description);
|
|
1029
920
|
if (this.parameterSchema) {
|
|
@@ -1032,20 +923,12 @@ var init_gadget = __esm({
|
|
|
1032
923
|
const jsonSchema = schemaToJSONSchema(this.parameterSchema, {
|
|
1033
924
|
target: "draft-7"
|
|
1034
925
|
});
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
parts.push(JSON.stringify(jsonSchema, null, 2));
|
|
1038
|
-
} else if (format === "toml") {
|
|
1039
|
-
parts.push("\n\nInput Schema (TOML):");
|
|
1040
|
-
parts.push(JSON.stringify(jsonSchema, null, 2));
|
|
1041
|
-
} else {
|
|
1042
|
-
const yamlSchema = yaml.dump(jsonSchema).trimEnd();
|
|
1043
|
-
parts.push("\n\nInput Schema (YAML):");
|
|
1044
|
-
parts.push(yamlSchema);
|
|
1045
|
-
}
|
|
926
|
+
parts.push("\n\nParameters:");
|
|
927
|
+
parts.push(formatSchemaAsPlainText(jsonSchema));
|
|
1046
928
|
}
|
|
1047
929
|
if (this.examples && this.examples.length > 0) {
|
|
1048
930
|
parts.push("\n\nExamples:");
|
|
931
|
+
const effectiveArgPrefix = argPrefix ?? GADGET_ARG_PREFIX;
|
|
1049
932
|
this.examples.forEach((example, index) => {
|
|
1050
933
|
if (index > 0) {
|
|
1051
934
|
parts.push("");
|
|
@@ -1054,13 +937,7 @@ var init_gadget = __esm({
|
|
|
1054
937
|
parts.push(`# ${example.comment}`);
|
|
1055
938
|
}
|
|
1056
939
|
parts.push("Input:");
|
|
1057
|
-
|
|
1058
|
-
parts.push(JSON.stringify(example.params, null, 2));
|
|
1059
|
-
} else if (format === "toml") {
|
|
1060
|
-
parts.push(formatParamsAsToml(example.params));
|
|
1061
|
-
} else {
|
|
1062
|
-
parts.push(formatParamsAsYaml(example.params));
|
|
1063
|
-
}
|
|
940
|
+
parts.push(formatParamsAsBlock(example.params, "", effectiveArgPrefix));
|
|
1064
941
|
if (example.output !== void 0) {
|
|
1065
942
|
parts.push("Output:");
|
|
1066
943
|
parts.push(example.output);
|
|
@@ -1337,14 +1214,12 @@ var init_conversation_manager = __esm({
|
|
|
1337
1214
|
baseMessages;
|
|
1338
1215
|
initialMessages;
|
|
1339
1216
|
historyBuilder;
|
|
1340
|
-
parameterFormat;
|
|
1341
1217
|
constructor(baseMessages, initialMessages, options = {}) {
|
|
1342
1218
|
this.baseMessages = baseMessages;
|
|
1343
1219
|
this.initialMessages = initialMessages;
|
|
1344
|
-
this.parameterFormat = options.parameterFormat ?? "json";
|
|
1345
1220
|
this.historyBuilder = new LLMMessageBuilder();
|
|
1346
1221
|
if (options.startPrefix && options.endPrefix) {
|
|
1347
|
-
this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix);
|
|
1222
|
+
this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix, options.argPrefix);
|
|
1348
1223
|
}
|
|
1349
1224
|
}
|
|
1350
1225
|
addUserMessage(content) {
|
|
@@ -1354,7 +1229,7 @@ var init_conversation_manager = __esm({
|
|
|
1354
1229
|
this.historyBuilder.addAssistant(content);
|
|
1355
1230
|
}
|
|
1356
1231
|
addGadgetCall(gadgetName, parameters, result) {
|
|
1357
|
-
this.historyBuilder.addGadgetCall(gadgetName, parameters, result
|
|
1232
|
+
this.historyBuilder.addGadgetCall(gadgetName, parameters, result);
|
|
1358
1233
|
}
|
|
1359
1234
|
getMessages() {
|
|
1360
1235
|
return [...this.baseMessages, ...this.initialMessages, ...this.historyBuilder.build()];
|
|
@@ -1377,7 +1252,7 @@ async function runWithHandlers(agentGenerator, handlers) {
|
|
|
1377
1252
|
await handlers.onGadgetCall({
|
|
1378
1253
|
gadgetName: event.call.gadgetName,
|
|
1379
1254
|
parameters: event.call.parameters,
|
|
1380
|
-
|
|
1255
|
+
parametersRaw: event.call.parametersRaw
|
|
1381
1256
|
});
|
|
1382
1257
|
}
|
|
1383
1258
|
break;
|
|
@@ -1571,6 +1446,89 @@ var init_hook_validators = __esm({
|
|
|
1571
1446
|
}
|
|
1572
1447
|
});
|
|
1573
1448
|
|
|
1449
|
+
// src/gadgets/error-formatter.ts
|
|
1450
|
+
var GadgetErrorFormatter;
|
|
1451
|
+
var init_error_formatter = __esm({
|
|
1452
|
+
"src/gadgets/error-formatter.ts"() {
|
|
1453
|
+
"use strict";
|
|
1454
|
+
init_constants();
|
|
1455
|
+
GadgetErrorFormatter = class {
|
|
1456
|
+
argPrefix;
|
|
1457
|
+
startPrefix;
|
|
1458
|
+
endPrefix;
|
|
1459
|
+
constructor(options = {}) {
|
|
1460
|
+
this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
|
|
1461
|
+
this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
|
|
1462
|
+
this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
|
|
1463
|
+
}
|
|
1464
|
+
/**
|
|
1465
|
+
* Format a Zod validation error with full gadget instructions.
|
|
1466
|
+
*
|
|
1467
|
+
* @param gadgetName - Name of the gadget that was called
|
|
1468
|
+
* @param zodError - The Zod validation error
|
|
1469
|
+
* @param gadget - The gadget instance (for generating instructions)
|
|
1470
|
+
* @returns Formatted error message with usage instructions
|
|
1471
|
+
*/
|
|
1472
|
+
formatValidationError(gadgetName, zodError, gadget) {
|
|
1473
|
+
const parts = [];
|
|
1474
|
+
parts.push(`Error: Invalid parameters for '${gadgetName}':`);
|
|
1475
|
+
for (const issue of zodError.issues) {
|
|
1476
|
+
const path = issue.path.join(".") || "root";
|
|
1477
|
+
parts.push(` - ${path}: ${issue.message}`);
|
|
1478
|
+
}
|
|
1479
|
+
parts.push("");
|
|
1480
|
+
parts.push("Gadget Usage:");
|
|
1481
|
+
parts.push(gadget.getInstruction(this.argPrefix));
|
|
1482
|
+
return parts.join("\n");
|
|
1483
|
+
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Format a parse error with block format reference.
|
|
1486
|
+
*
|
|
1487
|
+
* @param gadgetName - Name of the gadget that was called
|
|
1488
|
+
* @param parseError - The parse error message
|
|
1489
|
+
* @param gadget - The gadget instance if found (for generating instructions)
|
|
1490
|
+
* @returns Formatted error message with format reference
|
|
1491
|
+
*/
|
|
1492
|
+
formatParseError(gadgetName, parseError, gadget) {
|
|
1493
|
+
const parts = [];
|
|
1494
|
+
parts.push(`Error: Failed to parse parameters for '${gadgetName}':`);
|
|
1495
|
+
parts.push(` ${parseError}`);
|
|
1496
|
+
if (gadget) {
|
|
1497
|
+
parts.push("");
|
|
1498
|
+
parts.push("Gadget Usage:");
|
|
1499
|
+
parts.push(gadget.getInstruction(this.argPrefix));
|
|
1500
|
+
}
|
|
1501
|
+
parts.push("");
|
|
1502
|
+
parts.push("Block Format Reference:");
|
|
1503
|
+
parts.push(` ${this.startPrefix}${gadgetName}`);
|
|
1504
|
+
parts.push(` ${this.argPrefix}parameterName`);
|
|
1505
|
+
parts.push(" parameter value here");
|
|
1506
|
+
parts.push(` ${this.endPrefix}`);
|
|
1507
|
+
return parts.join("\n");
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Format a registry error (gadget not found) with available gadgets list.
|
|
1511
|
+
*
|
|
1512
|
+
* @param gadgetName - Name of the gadget that was not found
|
|
1513
|
+
* @param availableGadgets - List of available gadget names
|
|
1514
|
+
* @returns Formatted error message with available gadgets
|
|
1515
|
+
*/
|
|
1516
|
+
formatRegistryError(gadgetName, availableGadgets) {
|
|
1517
|
+
const parts = [];
|
|
1518
|
+
parts.push(`Error: Gadget '${gadgetName}' not found.`);
|
|
1519
|
+
if (availableGadgets.length > 0) {
|
|
1520
|
+
parts.push("");
|
|
1521
|
+
parts.push(`Available gadgets: ${availableGadgets.join(", ")}`);
|
|
1522
|
+
} else {
|
|
1523
|
+
parts.push("");
|
|
1524
|
+
parts.push("No gadgets are currently registered.");
|
|
1525
|
+
}
|
|
1526
|
+
return parts.join("\n");
|
|
1527
|
+
}
|
|
1528
|
+
};
|
|
1529
|
+
}
|
|
1530
|
+
});
|
|
1531
|
+
|
|
1574
1532
|
// src/gadgets/exceptions.ts
|
|
1575
1533
|
var BreakLoopException, HumanInputException, TimeoutException;
|
|
1576
1534
|
var init_exceptions = __esm({
|
|
@@ -1609,15 +1567,18 @@ var init_executor = __esm({
|
|
|
1609
1567
|
"src/gadgets/executor.ts"() {
|
|
1610
1568
|
"use strict";
|
|
1611
1569
|
init_logger();
|
|
1570
|
+
init_error_formatter();
|
|
1612
1571
|
init_exceptions();
|
|
1613
1572
|
GadgetExecutor = class {
|
|
1614
|
-
constructor(registry, onHumanInputRequired, logger, defaultGadgetTimeoutMs) {
|
|
1573
|
+
constructor(registry, onHumanInputRequired, logger, defaultGadgetTimeoutMs, errorFormatterOptions) {
|
|
1615
1574
|
this.registry = registry;
|
|
1616
1575
|
this.onHumanInputRequired = onHumanInputRequired;
|
|
1617
1576
|
this.defaultGadgetTimeoutMs = defaultGadgetTimeoutMs;
|
|
1618
1577
|
this.logger = logger ?? createLogger({ name: "llmist:executor" });
|
|
1578
|
+
this.errorFormatter = new GadgetErrorFormatter(errorFormatterOptions);
|
|
1619
1579
|
}
|
|
1620
1580
|
logger;
|
|
1581
|
+
errorFormatter;
|
|
1621
1582
|
/**
|
|
1622
1583
|
* Creates a promise that rejects with a TimeoutException after the specified timeout.
|
|
1623
1584
|
*/
|
|
@@ -1642,11 +1603,12 @@ var init_executor = __esm({
|
|
|
1642
1603
|
const gadget = this.registry.get(call.gadgetName);
|
|
1643
1604
|
if (!gadget) {
|
|
1644
1605
|
this.logger.error("Gadget not found", { gadgetName: call.gadgetName });
|
|
1606
|
+
const availableGadgets = this.registry.getNames();
|
|
1645
1607
|
return {
|
|
1646
1608
|
gadgetName: call.gadgetName,
|
|
1647
1609
|
invocationId: call.invocationId,
|
|
1648
1610
|
parameters: call.parameters ?? {},
|
|
1649
|
-
error:
|
|
1611
|
+
error: this.errorFormatter.formatRegistryError(call.gadgetName, availableGadgets),
|
|
1650
1612
|
executionTimeMs: Date.now() - startTime
|
|
1651
1613
|
};
|
|
1652
1614
|
}
|
|
@@ -1654,27 +1616,28 @@ var init_executor = __esm({
|
|
|
1654
1616
|
this.logger.error("Gadget parameter parse error", {
|
|
1655
1617
|
gadgetName: call.gadgetName,
|
|
1656
1618
|
parseError: call.parseError,
|
|
1657
|
-
rawParameters: call.
|
|
1619
|
+
rawParameters: call.parametersRaw
|
|
1658
1620
|
});
|
|
1621
|
+
const parseErrorMessage = call.parseError ?? "Failed to parse parameters";
|
|
1659
1622
|
return {
|
|
1660
1623
|
gadgetName: call.gadgetName,
|
|
1661
1624
|
invocationId: call.invocationId,
|
|
1662
1625
|
parameters: {},
|
|
1663
|
-
error: call.
|
|
1626
|
+
error: this.errorFormatter.formatParseError(call.gadgetName, parseErrorMessage, gadget),
|
|
1664
1627
|
executionTimeMs: Date.now() - startTime
|
|
1665
1628
|
};
|
|
1666
1629
|
}
|
|
1667
1630
|
if (gadget.parameterSchema) {
|
|
1668
1631
|
const validationResult = gadget.parameterSchema.safeParse(rawParameters);
|
|
1669
1632
|
if (!validationResult.success) {
|
|
1670
|
-
const
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1633
|
+
const validationError = this.errorFormatter.formatValidationError(
|
|
1634
|
+
call.gadgetName,
|
|
1635
|
+
validationResult.error,
|
|
1636
|
+
gadget
|
|
1637
|
+
);
|
|
1675
1638
|
this.logger.error("Gadget parameter validation failed", {
|
|
1676
1639
|
gadgetName: call.gadgetName,
|
|
1677
|
-
|
|
1640
|
+
issueCount: validationResult.error.issues.length
|
|
1678
1641
|
});
|
|
1679
1642
|
return {
|
|
1680
1643
|
gadgetName: call.gadgetName,
|
|
@@ -1816,168 +1779,107 @@ var init_executor = __esm({
|
|
|
1816
1779
|
}
|
|
1817
1780
|
});
|
|
1818
1781
|
|
|
1819
|
-
// src/gadgets/
|
|
1820
|
-
function
|
|
1821
|
-
const
|
|
1822
|
-
const result =
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
const
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
const
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
if (i < lines.length) {
|
|
1837
|
-
i++;
|
|
1838
|
-
}
|
|
1839
|
-
result.push(`${indent}${key}: |`);
|
|
1840
|
-
for (const bodyLine of bodyLines) {
|
|
1841
|
-
result.push(`${indent} ${bodyLine}`);
|
|
1782
|
+
// src/gadgets/block-params.ts
|
|
1783
|
+
function parseBlockParams(content, options) {
|
|
1784
|
+
const argPrefix = options?.argPrefix ?? GADGET_ARG_PREFIX;
|
|
1785
|
+
const result = {};
|
|
1786
|
+
const seenPointers = /* @__PURE__ */ new Set();
|
|
1787
|
+
const parts = content.split(argPrefix);
|
|
1788
|
+
for (let i = 1; i < parts.length; i++) {
|
|
1789
|
+
const part = parts[i];
|
|
1790
|
+
const newlineIndex = part.indexOf("\n");
|
|
1791
|
+
if (newlineIndex === -1) {
|
|
1792
|
+
const pointer2 = part.trim();
|
|
1793
|
+
if (pointer2) {
|
|
1794
|
+
if (seenPointers.has(pointer2)) {
|
|
1795
|
+
throw new Error(`Duplicate pointer: ${pointer2}`);
|
|
1796
|
+
}
|
|
1797
|
+
seenPointers.add(pointer2);
|
|
1798
|
+
setByPointer(result, pointer2, "");
|
|
1842
1799
|
}
|
|
1843
1800
|
continue;
|
|
1844
1801
|
}
|
|
1845
|
-
const
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
result.push(line);
|
|
1850
|
-
i++;
|
|
1851
|
-
const keyIndentLen2 = indent.length;
|
|
1852
|
-
const blockLines = [];
|
|
1853
|
-
let minContentIndent = Infinity;
|
|
1854
|
-
while (i < lines.length) {
|
|
1855
|
-
const blockLine = lines[i];
|
|
1856
|
-
const blockIndentMatch = blockLine.match(/^(\s*)/);
|
|
1857
|
-
const blockIndentLen = blockIndentMatch ? blockIndentMatch[1].length : 0;
|
|
1858
|
-
if (blockLine.trim() === "") {
|
|
1859
|
-
blockLines.push({ content: "", originalIndent: 0 });
|
|
1860
|
-
i++;
|
|
1861
|
-
continue;
|
|
1862
|
-
}
|
|
1863
|
-
if (blockIndentLen > keyIndentLen2) {
|
|
1864
|
-
const content = blockLine.substring(blockIndentLen);
|
|
1865
|
-
blockLines.push({ content, originalIndent: blockIndentLen });
|
|
1866
|
-
if (content.trim().length > 0) {
|
|
1867
|
-
minContentIndent = Math.min(minContentIndent, blockIndentLen);
|
|
1868
|
-
}
|
|
1869
|
-
i++;
|
|
1870
|
-
} else {
|
|
1871
|
-
break;
|
|
1872
|
-
}
|
|
1873
|
-
}
|
|
1874
|
-
const targetIndent = keyIndentLen2 + 2;
|
|
1875
|
-
for (const blockLine of blockLines) {
|
|
1876
|
-
if (blockLine.content === "") {
|
|
1877
|
-
result.push("");
|
|
1878
|
-
} else {
|
|
1879
|
-
result.push(" ".repeat(targetIndent) + blockLine.content);
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
continue;
|
|
1883
|
-
}
|
|
1884
|
-
if (value.startsWith('"') || value.startsWith("'") || value === "true" || value === "false" || /^-?\d+(\.\d+)?$/.test(value)) {
|
|
1885
|
-
result.push(line);
|
|
1886
|
-
i++;
|
|
1887
|
-
continue;
|
|
1888
|
-
}
|
|
1889
|
-
const keyIndentLen = indent.length;
|
|
1890
|
-
const continuationLines = [];
|
|
1891
|
-
let j = i + 1;
|
|
1892
|
-
while (j < lines.length) {
|
|
1893
|
-
const nextLine = lines[j];
|
|
1894
|
-
if (nextLine.trim() === "") {
|
|
1895
|
-
continuationLines.push(nextLine);
|
|
1896
|
-
j++;
|
|
1897
|
-
continue;
|
|
1898
|
-
}
|
|
1899
|
-
const nextIndentMatch = nextLine.match(/^(\s*)/);
|
|
1900
|
-
const nextIndentLen = nextIndentMatch ? nextIndentMatch[1].length : 0;
|
|
1901
|
-
if (nextIndentLen > keyIndentLen) {
|
|
1902
|
-
continuationLines.push(nextLine);
|
|
1903
|
-
j++;
|
|
1904
|
-
} else {
|
|
1905
|
-
break;
|
|
1906
|
-
}
|
|
1907
|
-
}
|
|
1908
|
-
if (continuationLines.length > 0 && continuationLines.some((l) => l.trim().length > 0)) {
|
|
1909
|
-
result.push(`${indent}${key}: |`);
|
|
1910
|
-
result.push(`${indent} ${value}`);
|
|
1911
|
-
for (const contLine of continuationLines) {
|
|
1912
|
-
if (contLine.trim() === "") {
|
|
1913
|
-
result.push("");
|
|
1914
|
-
} else {
|
|
1915
|
-
const contIndentMatch = contLine.match(/^(\s*)/);
|
|
1916
|
-
const contIndent = contIndentMatch ? contIndentMatch[1] : "";
|
|
1917
|
-
const contContent = contLine.substring(contIndent.length);
|
|
1918
|
-
result.push(`${indent} ${contContent}`);
|
|
1919
|
-
}
|
|
1920
|
-
}
|
|
1921
|
-
i = j;
|
|
1922
|
-
continue;
|
|
1923
|
-
}
|
|
1924
|
-
if (value.includes(": ") || value.endsWith(":")) {
|
|
1925
|
-
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
1926
|
-
result.push(`${indent}${key}: "${escaped}"`);
|
|
1927
|
-
i++;
|
|
1928
|
-
continue;
|
|
1929
|
-
}
|
|
1802
|
+
const pointer = part.substring(0, newlineIndex).trim();
|
|
1803
|
+
let value = part.substring(newlineIndex + 1);
|
|
1804
|
+
if (value.endsWith("\n")) {
|
|
1805
|
+
value = value.slice(0, -1);
|
|
1930
1806
|
}
|
|
1931
|
-
|
|
1932
|
-
|
|
1807
|
+
if (!pointer) {
|
|
1808
|
+
continue;
|
|
1809
|
+
}
|
|
1810
|
+
if (seenPointers.has(pointer)) {
|
|
1811
|
+
throw new Error(`Duplicate pointer: ${pointer}`);
|
|
1812
|
+
}
|
|
1813
|
+
seenPointers.add(pointer);
|
|
1814
|
+
setByPointer(result, pointer, value);
|
|
1933
1815
|
}
|
|
1934
|
-
return result
|
|
1816
|
+
return result;
|
|
1935
1817
|
}
|
|
1936
|
-
function
|
|
1937
|
-
|
|
1818
|
+
function coerceValue(value) {
|
|
1819
|
+
if (value.includes("\n")) {
|
|
1820
|
+
return value;
|
|
1821
|
+
}
|
|
1822
|
+
const trimmed = value.trim();
|
|
1823
|
+
if (trimmed === "true") return true;
|
|
1824
|
+
if (trimmed === "false") return false;
|
|
1825
|
+
if (trimmed !== "" && /^-?\d+(\.\d+)?$/.test(trimmed)) {
|
|
1826
|
+
const num = Number(trimmed);
|
|
1827
|
+
if (!isNaN(num) && isFinite(num)) {
|
|
1828
|
+
return num;
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
return value;
|
|
1938
1832
|
}
|
|
1939
|
-
function
|
|
1940
|
-
const
|
|
1941
|
-
|
|
1942
|
-
let i = 0;
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
const
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
}
|
|
1963
|
-
if (bodyLines.length === 0) {
|
|
1964
|
-
result.push(`${indent}${key} = ''''''`);
|
|
1965
|
-
} else {
|
|
1966
|
-
result.push(`${indent}${key} = '''`);
|
|
1967
|
-
for (let j = 0; j < bodyLines.length - 1; j++) {
|
|
1968
|
-
result.push(unescapeHeredocContent(bodyLines[j]));
|
|
1969
|
-
}
|
|
1970
|
-
result.push(`${unescapeHeredocContent(bodyLines[bodyLines.length - 1])}'''`);
|
|
1971
|
-
}
|
|
1972
|
-
if (!foundClosing) {
|
|
1833
|
+
function setByPointer(obj, pointer, value) {
|
|
1834
|
+
const segments = pointer.split("/");
|
|
1835
|
+
let current = obj;
|
|
1836
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
1837
|
+
const segment = segments[i];
|
|
1838
|
+
const nextSegment = segments[i + 1];
|
|
1839
|
+
const nextIsArrayIndex = /^\d+$/.test(nextSegment);
|
|
1840
|
+
if (Array.isArray(current)) {
|
|
1841
|
+
const index = parseInt(segment, 10);
|
|
1842
|
+
if (isNaN(index) || index < 0) {
|
|
1843
|
+
throw new Error(`Invalid array index: ${segment}`);
|
|
1844
|
+
}
|
|
1845
|
+
if (index > current.length) {
|
|
1846
|
+
throw new Error(`Array index gap: expected ${current.length}, got ${index}`);
|
|
1847
|
+
}
|
|
1848
|
+
if (current[index] === void 0) {
|
|
1849
|
+
current[index] = nextIsArrayIndex ? [] : {};
|
|
1850
|
+
}
|
|
1851
|
+
current = current[index];
|
|
1852
|
+
} else {
|
|
1853
|
+
const rec = current;
|
|
1854
|
+
if (rec[segment] === void 0) {
|
|
1855
|
+
rec[segment] = nextIsArrayIndex ? [] : {};
|
|
1973
1856
|
}
|
|
1974
|
-
|
|
1857
|
+
current = rec[segment];
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
const lastSegment = segments[segments.length - 1];
|
|
1861
|
+
const coercedValue = coerceValue(value);
|
|
1862
|
+
if (Array.isArray(current)) {
|
|
1863
|
+
const index = parseInt(lastSegment, 10);
|
|
1864
|
+
if (isNaN(index) || index < 0) {
|
|
1865
|
+
throw new Error(`Invalid array index: ${lastSegment}`);
|
|
1866
|
+
}
|
|
1867
|
+
if (index > current.length) {
|
|
1868
|
+
throw new Error(`Array index gap: expected ${current.length}, got ${index}`);
|
|
1975
1869
|
}
|
|
1976
|
-
|
|
1977
|
-
|
|
1870
|
+
current[index] = coercedValue;
|
|
1871
|
+
} else {
|
|
1872
|
+
current[lastSegment] = coercedValue;
|
|
1978
1873
|
}
|
|
1979
|
-
return result.join("\n");
|
|
1980
1874
|
}
|
|
1875
|
+
var init_block_params = __esm({
|
|
1876
|
+
"src/gadgets/block-params.ts"() {
|
|
1877
|
+
"use strict";
|
|
1878
|
+
init_constants();
|
|
1879
|
+
}
|
|
1880
|
+
});
|
|
1881
|
+
|
|
1882
|
+
// src/gadgets/parser.ts
|
|
1981
1883
|
function stripMarkdownFences(content) {
|
|
1982
1884
|
let cleaned = content.trim();
|
|
1983
1885
|
const openingFence = /^```(?:toml|yaml|json)?\s*\n/i;
|
|
@@ -1986,24 +1888,23 @@ function stripMarkdownFences(content) {
|
|
|
1986
1888
|
cleaned = cleaned.replace(closingFence, "");
|
|
1987
1889
|
return cleaned.trim();
|
|
1988
1890
|
}
|
|
1989
|
-
var
|
|
1891
|
+
var globalInvocationCounter, StreamParser;
|
|
1990
1892
|
var init_parser = __esm({
|
|
1991
1893
|
"src/gadgets/parser.ts"() {
|
|
1992
1894
|
"use strict";
|
|
1993
|
-
yaml2 = __toESM(require("js-yaml"), 1);
|
|
1994
|
-
import_js_toml = require("js-toml");
|
|
1995
1895
|
init_constants();
|
|
1896
|
+
init_block_params();
|
|
1996
1897
|
globalInvocationCounter = 0;
|
|
1997
1898
|
StreamParser = class {
|
|
1998
1899
|
buffer = "";
|
|
1999
1900
|
lastReportedTextLength = 0;
|
|
2000
1901
|
startPrefix;
|
|
2001
1902
|
endPrefix;
|
|
2002
|
-
|
|
1903
|
+
argPrefix;
|
|
2003
1904
|
constructor(options = {}) {
|
|
2004
1905
|
this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
|
|
2005
1906
|
this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
|
|
2006
|
-
this.
|
|
1907
|
+
this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
|
|
2007
1908
|
}
|
|
2008
1909
|
takeTextUntil(index) {
|
|
2009
1910
|
if (index <= this.lastReportedTextLength) {
|
|
@@ -2025,56 +1926,22 @@ var init_parser = __esm({
|
|
|
2025
1926
|
return { actualName: gadgetName, invocationId: `gadget_${++globalInvocationCounter}` };
|
|
2026
1927
|
}
|
|
2027
1928
|
/**
|
|
2028
|
-
*
|
|
2029
|
-
*
|
|
1929
|
+
* Extract the error message from a parse error.
|
|
1930
|
+
* Preserves full message since the error formatter adds contextual help
|
|
1931
|
+
* that benefits from precise, detailed error information.
|
|
2030
1932
|
*/
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
const firstLine = message.split("\n")[0];
|
|
2034
|
-
const maxLen = 200;
|
|
2035
|
-
if (firstLine.length <= maxLen) {
|
|
2036
|
-
return firstLine;
|
|
2037
|
-
}
|
|
2038
|
-
return `${firstLine.slice(0, maxLen)}... (${message.length} chars total)`;
|
|
1933
|
+
extractParseError(error) {
|
|
1934
|
+
return error instanceof Error ? error.message : String(error);
|
|
2039
1935
|
}
|
|
2040
1936
|
/**
|
|
2041
|
-
* Parse parameter string
|
|
1937
|
+
* Parse parameter string using block format
|
|
2042
1938
|
*/
|
|
2043
1939
|
parseParameters(raw) {
|
|
2044
1940
|
const cleaned = stripMarkdownFences(raw);
|
|
2045
|
-
if (this.parameterFormat === "json") {
|
|
2046
|
-
try {
|
|
2047
|
-
return { parameters: JSON.parse(cleaned) };
|
|
2048
|
-
} catch (error) {
|
|
2049
|
-
return { parseError: this.truncateParseError(error, "JSON") };
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
if (this.parameterFormat === "yaml") {
|
|
2053
|
-
try {
|
|
2054
|
-
return { parameters: yaml2.load(preprocessYaml(cleaned)) };
|
|
2055
|
-
} catch (error) {
|
|
2056
|
-
return { parseError: this.truncateParseError(error, "YAML") };
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
if (this.parameterFormat === "toml") {
|
|
2060
|
-
try {
|
|
2061
|
-
return { parameters: (0, import_js_toml.load)(preprocessTomlHeredoc(cleaned)) };
|
|
2062
|
-
} catch (error) {
|
|
2063
|
-
return { parseError: this.truncateParseError(error, "TOML") };
|
|
2064
|
-
}
|
|
2065
|
-
}
|
|
2066
1941
|
try {
|
|
2067
|
-
return { parameters:
|
|
2068
|
-
} catch {
|
|
2069
|
-
|
|
2070
|
-
return { parameters: (0, import_js_toml.load)(preprocessTomlHeredoc(cleaned)) };
|
|
2071
|
-
} catch {
|
|
2072
|
-
try {
|
|
2073
|
-
return { parameters: yaml2.load(preprocessYaml(cleaned)) };
|
|
2074
|
-
} catch (error) {
|
|
2075
|
-
return { parseError: this.truncateParseError(error, "auto") };
|
|
2076
|
-
}
|
|
2077
|
-
}
|
|
1942
|
+
return { parameters: parseBlockParams(cleaned, { argPrefix: this.argPrefix }) };
|
|
1943
|
+
} catch (error) {
|
|
1944
|
+
return { parseError: this.extractParseError(error) };
|
|
2078
1945
|
}
|
|
2079
1946
|
}
|
|
2080
1947
|
// Feed a chunk of text and get parsed events
|
|
@@ -2133,8 +2000,7 @@ var init_parser = __esm({
|
|
|
2133
2000
|
call: {
|
|
2134
2001
|
gadgetName: actualGadgetName,
|
|
2135
2002
|
invocationId,
|
|
2136
|
-
|
|
2137
|
-
// Keep property name for backward compatibility
|
|
2003
|
+
parametersRaw,
|
|
2138
2004
|
parameters,
|
|
2139
2005
|
parseError
|
|
2140
2006
|
}
|
|
@@ -2168,7 +2034,7 @@ var init_parser = __esm({
|
|
|
2168
2034
|
call: {
|
|
2169
2035
|
gadgetName: actualGadgetName,
|
|
2170
2036
|
invocationId,
|
|
2171
|
-
|
|
2037
|
+
parametersRaw,
|
|
2172
2038
|
parameters,
|
|
2173
2039
|
parseError
|
|
2174
2040
|
}
|
|
@@ -2219,9 +2085,9 @@ var init_stream_processor = __esm({
|
|
|
2219
2085
|
this.stopOnGadgetError = options.stopOnGadgetError ?? true;
|
|
2220
2086
|
this.shouldContinueAfterError = options.shouldContinueAfterError;
|
|
2221
2087
|
this.parser = new StreamParser({
|
|
2222
|
-
parameterFormat: options.parameterFormat,
|
|
2223
2088
|
startPrefix: options.gadgetStartPrefix,
|
|
2224
|
-
endPrefix: options.gadgetEndPrefix
|
|
2089
|
+
endPrefix: options.gadgetEndPrefix,
|
|
2090
|
+
argPrefix: options.gadgetArgPrefix
|
|
2225
2091
|
});
|
|
2226
2092
|
this.executor = new GadgetExecutor(
|
|
2227
2093
|
options.registry,
|
|
@@ -2375,7 +2241,7 @@ var init_stream_processor = __esm({
|
|
|
2375
2241
|
this.logger.warn("Gadget has parse error", {
|
|
2376
2242
|
gadgetName: call.gadgetName,
|
|
2377
2243
|
error: call.parseError,
|
|
2378
|
-
rawParameters: call.
|
|
2244
|
+
rawParameters: call.parametersRaw
|
|
2379
2245
|
});
|
|
2380
2246
|
const shouldContinue = await this.checkContinueAfterError(
|
|
2381
2247
|
call.parseError,
|
|
@@ -2611,9 +2477,9 @@ var init_agent = __esm({
|
|
|
2611
2477
|
hooks;
|
|
2612
2478
|
conversation;
|
|
2613
2479
|
registry;
|
|
2614
|
-
parameterFormat;
|
|
2615
2480
|
gadgetStartPrefix;
|
|
2616
2481
|
gadgetEndPrefix;
|
|
2482
|
+
gadgetArgPrefix;
|
|
2617
2483
|
onHumanInputRequired;
|
|
2618
2484
|
textOnlyHandler;
|
|
2619
2485
|
textWithGadgetsHandler;
|
|
@@ -2642,9 +2508,9 @@ var init_agent = __esm({
|
|
|
2642
2508
|
this.temperature = options.temperature;
|
|
2643
2509
|
this.logger = options.logger ?? createLogger({ name: "llmist:agent" });
|
|
2644
2510
|
this.registry = options.registry;
|
|
2645
|
-
this.parameterFormat = options.parameterFormat ?? "json";
|
|
2646
2511
|
this.gadgetStartPrefix = options.gadgetStartPrefix;
|
|
2647
2512
|
this.gadgetEndPrefix = options.gadgetEndPrefix;
|
|
2513
|
+
this.gadgetArgPrefix = options.gadgetArgPrefix;
|
|
2648
2514
|
this.onHumanInputRequired = options.onHumanInputRequired;
|
|
2649
2515
|
this.textOnlyHandler = options.textOnlyHandler ?? "terminate";
|
|
2650
2516
|
this.textWithGadgetsHandler = options.textWithGadgetsHandler;
|
|
@@ -2666,9 +2532,10 @@ var init_agent = __esm({
|
|
|
2666
2532
|
if (options.systemPrompt) {
|
|
2667
2533
|
baseBuilder.addSystem(options.systemPrompt);
|
|
2668
2534
|
}
|
|
2669
|
-
baseBuilder.addGadgets(this.registry.getAll(),
|
|
2535
|
+
baseBuilder.addGadgets(this.registry.getAll(), {
|
|
2670
2536
|
startPrefix: options.gadgetStartPrefix,
|
|
2671
|
-
endPrefix: options.gadgetEndPrefix
|
|
2537
|
+
endPrefix: options.gadgetEndPrefix,
|
|
2538
|
+
argPrefix: options.gadgetArgPrefix
|
|
2672
2539
|
});
|
|
2673
2540
|
const baseMessages = baseBuilder.build();
|
|
2674
2541
|
const initialMessages = (options.initialMessages ?? []).map((message) => ({
|
|
@@ -2676,9 +2543,9 @@ var init_agent = __esm({
|
|
|
2676
2543
|
content: message.content
|
|
2677
2544
|
}));
|
|
2678
2545
|
this.conversation = new ConversationManager(baseMessages, initialMessages, {
|
|
2679
|
-
parameterFormat: this.parameterFormat,
|
|
2680
2546
|
startPrefix: options.gadgetStartPrefix,
|
|
2681
|
-
endPrefix: options.gadgetEndPrefix
|
|
2547
|
+
endPrefix: options.gadgetEndPrefix,
|
|
2548
|
+
argPrefix: options.gadgetArgPrefix
|
|
2682
2549
|
});
|
|
2683
2550
|
this.userPromptProvided = !!options.userPrompt;
|
|
2684
2551
|
if (options.userPrompt) {
|
|
@@ -2771,9 +2638,9 @@ var init_agent = __esm({
|
|
|
2771
2638
|
const processor = new StreamProcessor({
|
|
2772
2639
|
iteration: currentIteration,
|
|
2773
2640
|
registry: this.registry,
|
|
2774
|
-
parameterFormat: this.parameterFormat,
|
|
2775
2641
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
2776
2642
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
2643
|
+
gadgetArgPrefix: this.gadgetArgPrefix,
|
|
2777
2644
|
hooks: this.hooks,
|
|
2778
2645
|
logger: this.logger.getSubLogger({ name: "stream-processor" }),
|
|
2779
2646
|
onHumanInputRequired: this.onHumanInputRequired,
|
|
@@ -3066,9 +2933,9 @@ var init_builder = __esm({
|
|
|
3066
2933
|
gadgets = [];
|
|
3067
2934
|
initialMessages = [];
|
|
3068
2935
|
onHumanInputRequired;
|
|
3069
|
-
parameterFormat;
|
|
3070
2936
|
gadgetStartPrefix;
|
|
3071
2937
|
gadgetEndPrefix;
|
|
2938
|
+
gadgetArgPrefix;
|
|
3072
2939
|
textOnlyHandler;
|
|
3073
2940
|
textWithGadgetsHandler;
|
|
3074
2941
|
stopOnGadgetError;
|
|
@@ -3255,21 +3122,6 @@ var init_builder = __esm({
|
|
|
3255
3122
|
this.onHumanInputRequired = handler;
|
|
3256
3123
|
return this;
|
|
3257
3124
|
}
|
|
3258
|
-
/**
|
|
3259
|
-
* Set the parameter format for gadget calls.
|
|
3260
|
-
*
|
|
3261
|
-
* @param format - Parameter format ("json" or "xml")
|
|
3262
|
-
* @returns This builder for chaining
|
|
3263
|
-
*
|
|
3264
|
-
* @example
|
|
3265
|
-
* ```typescript
|
|
3266
|
-
* .withParameterFormat("xml")
|
|
3267
|
-
* ```
|
|
3268
|
-
*/
|
|
3269
|
-
withParameterFormat(format) {
|
|
3270
|
-
this.parameterFormat = format;
|
|
3271
|
-
return this;
|
|
3272
|
-
}
|
|
3273
3125
|
/**
|
|
3274
3126
|
* Set custom gadget marker prefix.
|
|
3275
3127
|
*
|
|
@@ -3300,6 +3152,21 @@ var init_builder = __esm({
|
|
|
3300
3152
|
this.gadgetEndPrefix = suffix;
|
|
3301
3153
|
return this;
|
|
3302
3154
|
}
|
|
3155
|
+
/**
|
|
3156
|
+
* Set custom argument prefix for block format parameters.
|
|
3157
|
+
*
|
|
3158
|
+
* @param prefix - Custom prefix for argument markers (default: "!!!ARG:")
|
|
3159
|
+
* @returns This builder for chaining
|
|
3160
|
+
*
|
|
3161
|
+
* @example
|
|
3162
|
+
* ```typescript
|
|
3163
|
+
* .withGadgetArgPrefix("<<ARG>>")
|
|
3164
|
+
* ```
|
|
3165
|
+
*/
|
|
3166
|
+
withGadgetArgPrefix(prefix) {
|
|
3167
|
+
this.gadgetArgPrefix = prefix;
|
|
3168
|
+
return this;
|
|
3169
|
+
}
|
|
3303
3170
|
/**
|
|
3304
3171
|
* Set the text-only handler strategy.
|
|
3305
3172
|
*
|
|
@@ -3499,8 +3366,7 @@ var init_builder = __esm({
|
|
|
3499
3366
|
withSyntheticGadgetCall(gadgetName, parameters, result) {
|
|
3500
3367
|
const startPrefix = this.gadgetStartPrefix ?? GADGET_START_PREFIX;
|
|
3501
3368
|
const endPrefix = this.gadgetEndPrefix ?? GADGET_END_PREFIX;
|
|
3502
|
-
const
|
|
3503
|
-
const paramStr = this.formatSyntheticParameters(parameters, format);
|
|
3369
|
+
const paramStr = this.formatBlockParameters(parameters, "");
|
|
3504
3370
|
this.initialMessages.push({
|
|
3505
3371
|
role: "assistant",
|
|
3506
3372
|
content: `${startPrefix}${gadgetName}
|
|
@@ -3514,25 +3380,31 @@ ${endPrefix}`
|
|
|
3514
3380
|
return this;
|
|
3515
3381
|
}
|
|
3516
3382
|
/**
|
|
3517
|
-
* Format parameters
|
|
3518
|
-
* Uses heredoc for multiline string values.
|
|
3383
|
+
* Format parameters as block format with JSON Pointer paths.
|
|
3519
3384
|
*/
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
if (
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3385
|
+
formatBlockParameters(params, prefix) {
|
|
3386
|
+
const lines = [];
|
|
3387
|
+
const argPrefix = this.gadgetArgPrefix ?? GADGET_ARG_PREFIX;
|
|
3388
|
+
for (const [key, value] of Object.entries(params)) {
|
|
3389
|
+
const fullPath = prefix ? `${prefix}/${key}` : key;
|
|
3390
|
+
if (Array.isArray(value)) {
|
|
3391
|
+
value.forEach((item, index) => {
|
|
3392
|
+
const itemPath = `${fullPath}/${index}`;
|
|
3393
|
+
if (typeof item === "object" && item !== null) {
|
|
3394
|
+
lines.push(this.formatBlockParameters(item, itemPath));
|
|
3395
|
+
} else {
|
|
3396
|
+
lines.push(`${argPrefix}${itemPath}`);
|
|
3397
|
+
lines.push(String(item));
|
|
3398
|
+
}
|
|
3399
|
+
});
|
|
3400
|
+
} else if (typeof value === "object" && value !== null) {
|
|
3401
|
+
lines.push(this.formatBlockParameters(value, fullPath));
|
|
3402
|
+
} else {
|
|
3403
|
+
lines.push(`${argPrefix}${fullPath}`);
|
|
3404
|
+
lines.push(String(value));
|
|
3533
3405
|
}
|
|
3534
|
-
|
|
3535
|
-
|
|
3406
|
+
}
|
|
3407
|
+
return lines.join("\n");
|
|
3536
3408
|
}
|
|
3537
3409
|
/**
|
|
3538
3410
|
* Build and create the agent with the given user prompt.
|
|
@@ -3572,9 +3444,9 @@ EOF`;
|
|
|
3572
3444
|
promptConfig: this.promptConfig,
|
|
3573
3445
|
initialMessages: this.initialMessages,
|
|
3574
3446
|
onHumanInputRequired: this.onHumanInputRequired,
|
|
3575
|
-
parameterFormat: this.parameterFormat,
|
|
3576
3447
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
3577
3448
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
3449
|
+
gadgetArgPrefix: this.gadgetArgPrefix,
|
|
3578
3450
|
textOnlyHandler: this.textOnlyHandler,
|
|
3579
3451
|
textWithGadgetsHandler: this.textWithGadgetsHandler,
|
|
3580
3452
|
stopOnGadgetError: this.stopOnGadgetError,
|
|
@@ -3674,9 +3546,9 @@ EOF`;
|
|
|
3674
3546
|
promptConfig: this.promptConfig,
|
|
3675
3547
|
initialMessages: this.initialMessages,
|
|
3676
3548
|
onHumanInputRequired: this.onHumanInputRequired,
|
|
3677
|
-
parameterFormat: this.parameterFormat,
|
|
3678
3549
|
gadgetStartPrefix: this.gadgetStartPrefix,
|
|
3679
3550
|
gadgetEndPrefix: this.gadgetEndPrefix,
|
|
3551
|
+
gadgetArgPrefix: this.gadgetArgPrefix,
|
|
3680
3552
|
textOnlyHandler: this.textOnlyHandler,
|
|
3681
3553
|
textWithGadgetsHandler: this.textWithGadgetsHandler,
|
|
3682
3554
|
stopOnGadgetError: this.stopOnGadgetError,
|
|
@@ -5944,17 +5816,51 @@ function splitIntoChunks(text, minChunkSize = 5, maxChunkSize = 30) {
|
|
|
5944
5816
|
}
|
|
5945
5817
|
return chunks;
|
|
5946
5818
|
}
|
|
5819
|
+
function serializeToBlockFormat(obj, prefix = "") {
|
|
5820
|
+
let result = "";
|
|
5821
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
5822
|
+
const pointer = prefix ? `${prefix}/${key}` : key;
|
|
5823
|
+
if (value === null || value === void 0) {
|
|
5824
|
+
continue;
|
|
5825
|
+
}
|
|
5826
|
+
if (Array.isArray(value)) {
|
|
5827
|
+
for (let i = 0; i < value.length; i++) {
|
|
5828
|
+
const item = value[i];
|
|
5829
|
+
const itemPointer = `${pointer}/${i}`;
|
|
5830
|
+
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
5831
|
+
result += serializeToBlockFormat(item, itemPointer);
|
|
5832
|
+
} else if (Array.isArray(item)) {
|
|
5833
|
+
for (let j = 0; j < item.length; j++) {
|
|
5834
|
+
result += `${GADGET_ARG_PREFIX}${itemPointer}/${j}
|
|
5835
|
+
${String(item[j])}
|
|
5836
|
+
`;
|
|
5837
|
+
}
|
|
5838
|
+
} else {
|
|
5839
|
+
result += `${GADGET_ARG_PREFIX}${itemPointer}
|
|
5840
|
+
${String(item)}
|
|
5841
|
+
`;
|
|
5842
|
+
}
|
|
5843
|
+
}
|
|
5844
|
+
} else if (typeof value === "object") {
|
|
5845
|
+
result += serializeToBlockFormat(value, pointer);
|
|
5846
|
+
} else {
|
|
5847
|
+
result += `${GADGET_ARG_PREFIX}${pointer}
|
|
5848
|
+
${String(value)}
|
|
5849
|
+
`;
|
|
5850
|
+
}
|
|
5851
|
+
}
|
|
5852
|
+
return result;
|
|
5853
|
+
}
|
|
5947
5854
|
function formatGadgetCalls(gadgetCalls) {
|
|
5948
5855
|
let text = "";
|
|
5949
5856
|
const calls = [];
|
|
5950
5857
|
for (const call of gadgetCalls) {
|
|
5951
5858
|
const invocationId = call.invocationId ?? generateInvocationId();
|
|
5952
5859
|
calls.push({ name: call.gadgetName, invocationId });
|
|
5953
|
-
const
|
|
5860
|
+
const blockParams = serializeToBlockFormat(call.parameters);
|
|
5954
5861
|
text += `
|
|
5955
5862
|
${GADGET_START_PREFIX}${call.gadgetName}
|
|
5956
|
-
${
|
|
5957
|
-
${GADGET_END_PREFIX}`;
|
|
5863
|
+
${blockParams}${GADGET_END_PREFIX}`;
|
|
5958
5864
|
}
|
|
5959
5865
|
return { text, calls };
|
|
5960
5866
|
}
|