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.
@@ -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
- formatDescriptionYaml: "Parameters in YAML format (one per line)",
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, parameterFormat = "json", options) {
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, parameterFormat));
517
- parts.push(this.buildUsageSection(parameterFormat, context));
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, parameterFormat) {
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(parameterFormat);
528
- const schemaMarkers = {
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 (${parameterFormat.toUpperCase()}):
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(parameterFormat, context) {
549
+ buildUsageSection(context) {
554
550
  const parts = [];
555
- const formatDescriptionMap = {
556
- yaml: {
557
- config: this.promptConfig.formatDescriptionYaml,
558
- defaultValue: DEFAULT_PROMPTS.formatDescriptionYaml
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(parameterFormat, context));
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(parameterFormat, context) {
578
+ buildExamplesSection(context) {
598
579
  if (this.promptConfig.customExamples) {
599
580
  return this.promptConfig.customExamples(context);
600
581
  }
601
582
  const parts = [];
602
- const singleExamples = {
603
- yaml: `${this.startPrefix}translate
604
- from: English
605
- to: Polish
606
- content: "Paris is the capital of France: a beautiful city."
607
- ${this.endPrefix}`,
608
- json: `${this.startPrefix}translate
609
- {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
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
- ${singleExamples[parameterFormat]}`);
625
- const multipleExamples = {
626
- yaml: `${this.startPrefix}translate
627
- from: English
628
- to: Polish
629
- content: "Paris is the capital of France: a beautiful city."
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: economic_analysis
633
- matter: "Polish Economy"
634
- question: <<<EOF
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
- EOF
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
- ${multipleExamples[parameterFormat]}`);
672
- if (parameterFormat === "yaml") {
673
- parts.push(`
674
-
675
- YAML HEREDOC SYNTAX:
676
- For string values with multiple lines, use heredoc syntax (<<<DELIMITER...DELIMITER):
677
-
678
- filePath: "README.md"
679
- content: <<<EOF
680
- # Project Title
618
+ ${multipleExample}`);
619
+ parts.push(`
681
620
 
682
- This content can contain:
683
- - Markdown lists
684
- - Special characters: # : -
685
- - Multiple paragraphs
686
- EOF
621
+ BLOCK FORMAT SYNTAX:
622
+ Block format uses ${this.argPrefix}name markers. Values are captured verbatim until the next marker.
687
623
 
688
- The delimiter (EOF) can be any identifier. The closing delimiter must be on its own line.
689
- No indentation is required for the content.`);
690
- } else if (parameterFormat === "toml") {
691
- parts.push(`
624
+ ${this.argPrefix}filename
625
+ calculator.ts
626
+ ${this.argPrefix}code
627
+ class Calculator {
628
+ private history: string[] = [];
692
629
 
693
- TOML HEREDOC SYNTAX:
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
- filePath = "README.md"
697
- content = <<<EOF
698
- # Project Title
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
- This content can contain:
701
- - Markdown lists
702
- - Special characters: # : -
703
- - Multiple paragraphs
704
- EOF
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
- The delimiter (EOF) can be any identifier. The closing delimiter must be on its own line.
707
- IMPORTANT: Content inside heredoc is LITERAL - do NOT escape backticks, dollar signs, or any characters.
708
- NEVER use TOML triple-quote strings ("""). ALWAYS use heredoc syntax (<<<EOF...EOF) for multiline content.`);
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, parameterFormat = "json") {
731
- const paramStr = this.formatParameters(parameters, parameterFormat);
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
- formatParameters(parameters, format) {
745
- if (format === "yaml") {
746
- return Object.entries(parameters).map(([key, value]) => {
747
- if (typeof value === "string") {
748
- return `${key}: ${value}`;
749
- }
750
- return `${key}: ${JSON.stringify(value)}`;
751
- }).join("\n");
752
- }
753
- if (format === "toml") {
754
- return Object.entries(parameters).map(([key, value]) => {
755
- if (typeof value === "string" && value.includes("\n")) {
756
- return `${key} = <<<EOF
757
- ${value}
758
- EOF`;
759
- }
760
- return `${key} = ${JSON.stringify(value)}`;
761
- }).join("\n");
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 JSON.stringify(parameters);
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 findSafeDelimiter(content) {
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 formattedValue = formatYamlValue(value, "");
917
- if (formattedValue.startsWith("\n")) {
918
- lines.push(`${key}:${formattedValue}`);
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(`${key}: ${formattedValue}`);
826
+ lines.push(`${argPrefix}${fullPath}`);
827
+ lines.push(String(value));
921
828
  }
922
829
  }
923
830
  return lines.join("\n");
924
831
  }
925
- function formatTomlInlineTable(obj) {
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
- for (const [key, value] of Object.entries(params)) {
963
- lines.push(`${key} = ${formatTomlValue(value)}`);
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 yaml, HEREDOC_DELIMITERS, BaseGadget;
868
+ var BaseGadget;
968
869
  var init_gadget = __esm({
969
870
  "src/gadgets/gadget.ts"() {
970
871
  "use strict";
971
- yaml = __toESM(require("js-yaml"), 1);
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(format) instead for format-specific schemas
905
+ * @deprecated Use getInstruction() instead
1015
906
  */
1016
907
  get instruction() {
1017
- return this.getInstruction("yaml");
908
+ return this.getInstruction();
1018
909
  }
1019
910
  /**
1020
- * Generate instruction text for the LLM with format-specific schema.
911
+ * Generate instruction text for the LLM.
1021
912
  * Combines name, description, and parameter schema into a formatted instruction.
1022
913
  *
1023
- * @param format - Format for the schema representation ('json' | 'yaml' | 'toml' | 'auto')
914
+ * @param argPrefix - Optional custom argument prefix for block format examples
1024
915
  * @returns Formatted instruction string
1025
916
  */
1026
- getInstruction(format = "json") {
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
- if (format === "json" || format === "auto") {
1036
- parts.push("\n\nInput Schema (JSON):");
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
- if (format === "json" || format === "auto") {
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, this.parameterFormat);
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
- parametersYaml: event.call.parametersYaml
1255
+ parametersRaw: event.call.parametersRaw
1381
1256
  });
1382
1257
  }
1383
1258
  break;
@@ -1654,7 +1529,7 @@ var init_executor = __esm({
1654
1529
  this.logger.error("Gadget parameter parse error", {
1655
1530
  gadgetName: call.gadgetName,
1656
1531
  parseError: call.parseError,
1657
- rawParameters: call.parametersYaml
1532
+ rawParameters: call.parametersRaw
1658
1533
  });
1659
1534
  return {
1660
1535
  gadgetName: call.gadgetName,
@@ -1816,168 +1691,107 @@ var init_executor = __esm({
1816
1691
  }
1817
1692
  });
1818
1693
 
1819
- // src/gadgets/parser.ts
1820
- function preprocessYaml(yamlStr) {
1821
- const lines = yamlStr.split("\n");
1822
- const result = [];
1823
- let i = 0;
1824
- while (i < lines.length) {
1825
- const line = lines[i];
1826
- const heredocMatch = line.match(/^(\s*)([\w-]+):\s*<<<([A-Za-z_][A-Za-z0-9_]*)\s*$/);
1827
- if (heredocMatch) {
1828
- const [, indent, key, delimiter] = heredocMatch;
1829
- const bodyLines = [];
1830
- i++;
1831
- const closingRegex = new RegExp(`^${delimiter}\\s*$`);
1832
- while (i < lines.length && !closingRegex.test(lines[i])) {
1833
- bodyLines.push(lines[i]);
1834
- i++;
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}`);
1694
+ // src/gadgets/block-params.ts
1695
+ function parseBlockParams(content, options) {
1696
+ const argPrefix = options?.argPrefix ?? GADGET_ARG_PREFIX;
1697
+ const result = {};
1698
+ const seenPointers = /* @__PURE__ */ new Set();
1699
+ const parts = content.split(argPrefix);
1700
+ for (let i = 1; i < parts.length; i++) {
1701
+ const part = parts[i];
1702
+ const newlineIndex = part.indexOf("\n");
1703
+ if (newlineIndex === -1) {
1704
+ const pointer2 = part.trim();
1705
+ if (pointer2) {
1706
+ if (seenPointers.has(pointer2)) {
1707
+ throw new Error(`Duplicate pointer: ${pointer2}`);
1708
+ }
1709
+ seenPointers.add(pointer2);
1710
+ setByPointer(result, pointer2, "");
1842
1711
  }
1843
1712
  continue;
1844
1713
  }
1845
- const match = line.match(/^(\s*)([\w-]+):\s+(.+)$/);
1846
- if (match) {
1847
- const [, indent, key, value] = match;
1848
- if (value === "|" || value === ">" || value === "|-" || value === ">-") {
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
- }
1714
+ const pointer = part.substring(0, newlineIndex).trim();
1715
+ let value = part.substring(newlineIndex + 1);
1716
+ if (value.endsWith("\n")) {
1717
+ value = value.slice(0, -1);
1718
+ }
1719
+ if (!pointer) {
1720
+ continue;
1721
+ }
1722
+ if (seenPointers.has(pointer)) {
1723
+ throw new Error(`Duplicate pointer: ${pointer}`);
1930
1724
  }
1931
- result.push(line);
1932
- i++;
1725
+ seenPointers.add(pointer);
1726
+ setByPointer(result, pointer, value);
1933
1727
  }
1934
- return result.join("\n");
1728
+ return result;
1935
1729
  }
1936
- function unescapeHeredocContent(content) {
1937
- return content.replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\{/g, "{").replace(/\\}/g, "}");
1730
+ function coerceValue(value) {
1731
+ if (value.includes("\n")) {
1732
+ return value;
1733
+ }
1734
+ const trimmed = value.trim();
1735
+ if (trimmed === "true") return true;
1736
+ if (trimmed === "false") return false;
1737
+ if (trimmed !== "" && /^-?\d+(\.\d+)?$/.test(trimmed)) {
1738
+ const num = Number(trimmed);
1739
+ if (!isNaN(num) && isFinite(num)) {
1740
+ return num;
1741
+ }
1742
+ }
1743
+ return value;
1938
1744
  }
1939
- function preprocessTomlHeredoc(tomlStr) {
1940
- const lines = tomlStr.split("\n");
1941
- const result = [];
1942
- let i = 0;
1943
- const heredocStartRegex = /^(\s*)([\w-]+)\s*=\s*<<<([A-Za-z_][A-Za-z0-9_]*)\s*$/;
1944
- while (i < lines.length) {
1945
- const line = lines[i];
1946
- const match = line.match(heredocStartRegex);
1947
- if (match) {
1948
- const [, indent, key, delimiter] = match;
1949
- const bodyLines = [];
1950
- i++;
1951
- const closingRegex = new RegExp(`^${delimiter}\\s*$`);
1952
- let foundClosing = false;
1953
- while (i < lines.length) {
1954
- const bodyLine = lines[i];
1955
- if (closingRegex.test(bodyLine)) {
1956
- foundClosing = true;
1957
- i++;
1958
- break;
1959
- }
1960
- bodyLines.push(bodyLine);
1961
- i++;
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) {
1745
+ function setByPointer(obj, pointer, value) {
1746
+ const segments = pointer.split("/");
1747
+ let current = obj;
1748
+ for (let i = 0; i < segments.length - 1; i++) {
1749
+ const segment = segments[i];
1750
+ const nextSegment = segments[i + 1];
1751
+ const nextIsArrayIndex = /^\d+$/.test(nextSegment);
1752
+ if (Array.isArray(current)) {
1753
+ const index = parseInt(segment, 10);
1754
+ if (isNaN(index) || index < 0) {
1755
+ throw new Error(`Invalid array index: ${segment}`);
1756
+ }
1757
+ if (index > current.length) {
1758
+ throw new Error(`Array index gap: expected ${current.length}, got ${index}`);
1759
+ }
1760
+ if (current[index] === void 0) {
1761
+ current[index] = nextIsArrayIndex ? [] : {};
1762
+ }
1763
+ current = current[index];
1764
+ } else {
1765
+ const rec = current;
1766
+ if (rec[segment] === void 0) {
1767
+ rec[segment] = nextIsArrayIndex ? [] : {};
1973
1768
  }
1974
- continue;
1769
+ current = rec[segment];
1770
+ }
1771
+ }
1772
+ const lastSegment = segments[segments.length - 1];
1773
+ const coercedValue = coerceValue(value);
1774
+ if (Array.isArray(current)) {
1775
+ const index = parseInt(lastSegment, 10);
1776
+ if (isNaN(index) || index < 0) {
1777
+ throw new Error(`Invalid array index: ${lastSegment}`);
1778
+ }
1779
+ if (index > current.length) {
1780
+ throw new Error(`Array index gap: expected ${current.length}, got ${index}`);
1975
1781
  }
1976
- result.push(line);
1977
- i++;
1782
+ current[index] = coercedValue;
1783
+ } else {
1784
+ current[lastSegment] = coercedValue;
1978
1785
  }
1979
- return result.join("\n");
1980
1786
  }
1787
+ var init_block_params = __esm({
1788
+ "src/gadgets/block-params.ts"() {
1789
+ "use strict";
1790
+ init_constants();
1791
+ }
1792
+ });
1793
+
1794
+ // src/gadgets/parser.ts
1981
1795
  function stripMarkdownFences(content) {
1982
1796
  let cleaned = content.trim();
1983
1797
  const openingFence = /^```(?:toml|yaml|json)?\s*\n/i;
@@ -1986,24 +1800,23 @@ function stripMarkdownFences(content) {
1986
1800
  cleaned = cleaned.replace(closingFence, "");
1987
1801
  return cleaned.trim();
1988
1802
  }
1989
- var yaml2, import_js_toml, globalInvocationCounter, StreamParser;
1803
+ var globalInvocationCounter, StreamParser;
1990
1804
  var init_parser = __esm({
1991
1805
  "src/gadgets/parser.ts"() {
1992
1806
  "use strict";
1993
- yaml2 = __toESM(require("js-yaml"), 1);
1994
- import_js_toml = require("js-toml");
1995
1807
  init_constants();
1808
+ init_block_params();
1996
1809
  globalInvocationCounter = 0;
1997
1810
  StreamParser = class {
1998
1811
  buffer = "";
1999
1812
  lastReportedTextLength = 0;
2000
1813
  startPrefix;
2001
1814
  endPrefix;
2002
- parameterFormat;
1815
+ argPrefix;
2003
1816
  constructor(options = {}) {
2004
1817
  this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
2005
1818
  this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
2006
- this.parameterFormat = options.parameterFormat ?? "json";
1819
+ this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
2007
1820
  }
2008
1821
  takeTextUntil(index) {
2009
1822
  if (index <= this.lastReportedTextLength) {
@@ -2038,43 +1851,14 @@ var init_parser = __esm({
2038
1851
  return `${firstLine.slice(0, maxLen)}... (${message.length} chars total)`;
2039
1852
  }
2040
1853
  /**
2041
- * Parse parameter string according to configured format
1854
+ * Parse parameter string using block format
2042
1855
  */
2043
1856
  parseParameters(raw) {
2044
1857
  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
1858
  try {
2067
- return { parameters: JSON.parse(cleaned) };
2068
- } catch {
2069
- try {
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
- }
1859
+ return { parameters: parseBlockParams(cleaned, { argPrefix: this.argPrefix }) };
1860
+ } catch (error) {
1861
+ return { parseError: this.truncateParseError(error, "block") };
2078
1862
  }
2079
1863
  }
2080
1864
  // Feed a chunk of text and get parsed events
@@ -2133,8 +1917,7 @@ var init_parser = __esm({
2133
1917
  call: {
2134
1918
  gadgetName: actualGadgetName,
2135
1919
  invocationId,
2136
- parametersYaml: parametersRaw,
2137
- // Keep property name for backward compatibility
1920
+ parametersRaw,
2138
1921
  parameters,
2139
1922
  parseError
2140
1923
  }
@@ -2168,7 +1951,7 @@ var init_parser = __esm({
2168
1951
  call: {
2169
1952
  gadgetName: actualGadgetName,
2170
1953
  invocationId,
2171
- parametersYaml: parametersRaw,
1954
+ parametersRaw,
2172
1955
  parameters,
2173
1956
  parseError
2174
1957
  }
@@ -2219,9 +2002,9 @@ var init_stream_processor = __esm({
2219
2002
  this.stopOnGadgetError = options.stopOnGadgetError ?? true;
2220
2003
  this.shouldContinueAfterError = options.shouldContinueAfterError;
2221
2004
  this.parser = new StreamParser({
2222
- parameterFormat: options.parameterFormat,
2223
2005
  startPrefix: options.gadgetStartPrefix,
2224
- endPrefix: options.gadgetEndPrefix
2006
+ endPrefix: options.gadgetEndPrefix,
2007
+ argPrefix: options.gadgetArgPrefix
2225
2008
  });
2226
2009
  this.executor = new GadgetExecutor(
2227
2010
  options.registry,
@@ -2375,7 +2158,7 @@ var init_stream_processor = __esm({
2375
2158
  this.logger.warn("Gadget has parse error", {
2376
2159
  gadgetName: call.gadgetName,
2377
2160
  error: call.parseError,
2378
- rawParameters: call.parametersYaml
2161
+ rawParameters: call.parametersRaw
2379
2162
  });
2380
2163
  const shouldContinue = await this.checkContinueAfterError(
2381
2164
  call.parseError,
@@ -2611,9 +2394,9 @@ var init_agent = __esm({
2611
2394
  hooks;
2612
2395
  conversation;
2613
2396
  registry;
2614
- parameterFormat;
2615
2397
  gadgetStartPrefix;
2616
2398
  gadgetEndPrefix;
2399
+ gadgetArgPrefix;
2617
2400
  onHumanInputRequired;
2618
2401
  textOnlyHandler;
2619
2402
  textWithGadgetsHandler;
@@ -2642,9 +2425,9 @@ var init_agent = __esm({
2642
2425
  this.temperature = options.temperature;
2643
2426
  this.logger = options.logger ?? createLogger({ name: "llmist:agent" });
2644
2427
  this.registry = options.registry;
2645
- this.parameterFormat = options.parameterFormat ?? "json";
2646
2428
  this.gadgetStartPrefix = options.gadgetStartPrefix;
2647
2429
  this.gadgetEndPrefix = options.gadgetEndPrefix;
2430
+ this.gadgetArgPrefix = options.gadgetArgPrefix;
2648
2431
  this.onHumanInputRequired = options.onHumanInputRequired;
2649
2432
  this.textOnlyHandler = options.textOnlyHandler ?? "terminate";
2650
2433
  this.textWithGadgetsHandler = options.textWithGadgetsHandler;
@@ -2666,9 +2449,10 @@ var init_agent = __esm({
2666
2449
  if (options.systemPrompt) {
2667
2450
  baseBuilder.addSystem(options.systemPrompt);
2668
2451
  }
2669
- baseBuilder.addGadgets(this.registry.getAll(), this.parameterFormat, {
2452
+ baseBuilder.addGadgets(this.registry.getAll(), {
2670
2453
  startPrefix: options.gadgetStartPrefix,
2671
- endPrefix: options.gadgetEndPrefix
2454
+ endPrefix: options.gadgetEndPrefix,
2455
+ argPrefix: options.gadgetArgPrefix
2672
2456
  });
2673
2457
  const baseMessages = baseBuilder.build();
2674
2458
  const initialMessages = (options.initialMessages ?? []).map((message) => ({
@@ -2676,9 +2460,9 @@ var init_agent = __esm({
2676
2460
  content: message.content
2677
2461
  }));
2678
2462
  this.conversation = new ConversationManager(baseMessages, initialMessages, {
2679
- parameterFormat: this.parameterFormat,
2680
2463
  startPrefix: options.gadgetStartPrefix,
2681
- endPrefix: options.gadgetEndPrefix
2464
+ endPrefix: options.gadgetEndPrefix,
2465
+ argPrefix: options.gadgetArgPrefix
2682
2466
  });
2683
2467
  this.userPromptProvided = !!options.userPrompt;
2684
2468
  if (options.userPrompt) {
@@ -2771,9 +2555,9 @@ var init_agent = __esm({
2771
2555
  const processor = new StreamProcessor({
2772
2556
  iteration: currentIteration,
2773
2557
  registry: this.registry,
2774
- parameterFormat: this.parameterFormat,
2775
2558
  gadgetStartPrefix: this.gadgetStartPrefix,
2776
2559
  gadgetEndPrefix: this.gadgetEndPrefix,
2560
+ gadgetArgPrefix: this.gadgetArgPrefix,
2777
2561
  hooks: this.hooks,
2778
2562
  logger: this.logger.getSubLogger({ name: "stream-processor" }),
2779
2563
  onHumanInputRequired: this.onHumanInputRequired,
@@ -3066,9 +2850,9 @@ var init_builder = __esm({
3066
2850
  gadgets = [];
3067
2851
  initialMessages = [];
3068
2852
  onHumanInputRequired;
3069
- parameterFormat;
3070
2853
  gadgetStartPrefix;
3071
2854
  gadgetEndPrefix;
2855
+ gadgetArgPrefix;
3072
2856
  textOnlyHandler;
3073
2857
  textWithGadgetsHandler;
3074
2858
  stopOnGadgetError;
@@ -3255,21 +3039,6 @@ var init_builder = __esm({
3255
3039
  this.onHumanInputRequired = handler;
3256
3040
  return this;
3257
3041
  }
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
3042
  /**
3274
3043
  * Set custom gadget marker prefix.
3275
3044
  *
@@ -3300,6 +3069,21 @@ var init_builder = __esm({
3300
3069
  this.gadgetEndPrefix = suffix;
3301
3070
  return this;
3302
3071
  }
3072
+ /**
3073
+ * Set custom argument prefix for block format parameters.
3074
+ *
3075
+ * @param prefix - Custom prefix for argument markers (default: "!!!ARG:")
3076
+ * @returns This builder for chaining
3077
+ *
3078
+ * @example
3079
+ * ```typescript
3080
+ * .withGadgetArgPrefix("<<ARG>>")
3081
+ * ```
3082
+ */
3083
+ withGadgetArgPrefix(prefix) {
3084
+ this.gadgetArgPrefix = prefix;
3085
+ return this;
3086
+ }
3303
3087
  /**
3304
3088
  * Set the text-only handler strategy.
3305
3089
  *
@@ -3499,8 +3283,7 @@ var init_builder = __esm({
3499
3283
  withSyntheticGadgetCall(gadgetName, parameters, result) {
3500
3284
  const startPrefix = this.gadgetStartPrefix ?? GADGET_START_PREFIX;
3501
3285
  const endPrefix = this.gadgetEndPrefix ?? GADGET_END_PREFIX;
3502
- const format = this.parameterFormat ?? "yaml";
3503
- const paramStr = this.formatSyntheticParameters(parameters, format);
3286
+ const paramStr = this.formatBlockParameters(parameters, "");
3504
3287
  this.initialMessages.push({
3505
3288
  role: "assistant",
3506
3289
  content: `${startPrefix}${gadgetName}
@@ -3514,25 +3297,31 @@ ${endPrefix}`
3514
3297
  return this;
3515
3298
  }
3516
3299
  /**
3517
- * Format parameters for synthetic gadget calls.
3518
- * Uses heredoc for multiline string values.
3300
+ * Format parameters as block format with JSON Pointer paths.
3519
3301
  */
3520
- formatSyntheticParameters(parameters, format) {
3521
- if (format === "json" || format === "auto") {
3522
- return JSON.stringify(parameters);
3523
- }
3524
- return Object.entries(parameters).map(([key, value]) => {
3525
- if (typeof value === "string" && value.includes("\n")) {
3526
- const separator = format === "yaml" ? ":" : " =";
3527
- return `${key}${separator} <<<EOF
3528
- ${value}
3529
- EOF`;
3530
- }
3531
- if (format === "yaml") {
3532
- return typeof value === "string" ? `${key}: ${value}` : `${key}: ${JSON.stringify(value)}`;
3302
+ formatBlockParameters(params, prefix) {
3303
+ const lines = [];
3304
+ const argPrefix = this.gadgetArgPrefix ?? GADGET_ARG_PREFIX;
3305
+ for (const [key, value] of Object.entries(params)) {
3306
+ const fullPath = prefix ? `${prefix}/${key}` : key;
3307
+ if (Array.isArray(value)) {
3308
+ value.forEach((item, index) => {
3309
+ const itemPath = `${fullPath}/${index}`;
3310
+ if (typeof item === "object" && item !== null) {
3311
+ lines.push(this.formatBlockParameters(item, itemPath));
3312
+ } else {
3313
+ lines.push(`${argPrefix}${itemPath}`);
3314
+ lines.push(String(item));
3315
+ }
3316
+ });
3317
+ } else if (typeof value === "object" && value !== null) {
3318
+ lines.push(this.formatBlockParameters(value, fullPath));
3319
+ } else {
3320
+ lines.push(`${argPrefix}${fullPath}`);
3321
+ lines.push(String(value));
3533
3322
  }
3534
- return `${key} = ${JSON.stringify(value)}`;
3535
- }).join("\n");
3323
+ }
3324
+ return lines.join("\n");
3536
3325
  }
3537
3326
  /**
3538
3327
  * Build and create the agent with the given user prompt.
@@ -3572,9 +3361,9 @@ EOF`;
3572
3361
  promptConfig: this.promptConfig,
3573
3362
  initialMessages: this.initialMessages,
3574
3363
  onHumanInputRequired: this.onHumanInputRequired,
3575
- parameterFormat: this.parameterFormat,
3576
3364
  gadgetStartPrefix: this.gadgetStartPrefix,
3577
3365
  gadgetEndPrefix: this.gadgetEndPrefix,
3366
+ gadgetArgPrefix: this.gadgetArgPrefix,
3578
3367
  textOnlyHandler: this.textOnlyHandler,
3579
3368
  textWithGadgetsHandler: this.textWithGadgetsHandler,
3580
3369
  stopOnGadgetError: this.stopOnGadgetError,
@@ -3674,9 +3463,9 @@ EOF`;
3674
3463
  promptConfig: this.promptConfig,
3675
3464
  initialMessages: this.initialMessages,
3676
3465
  onHumanInputRequired: this.onHumanInputRequired,
3677
- parameterFormat: this.parameterFormat,
3678
3466
  gadgetStartPrefix: this.gadgetStartPrefix,
3679
3467
  gadgetEndPrefix: this.gadgetEndPrefix,
3468
+ gadgetArgPrefix: this.gadgetArgPrefix,
3680
3469
  textOnlyHandler: this.textOnlyHandler,
3681
3470
  textWithGadgetsHandler: this.textWithGadgetsHandler,
3682
3471
  stopOnGadgetError: this.stopOnGadgetError,
@@ -5944,17 +5733,51 @@ function splitIntoChunks(text, minChunkSize = 5, maxChunkSize = 30) {
5944
5733
  }
5945
5734
  return chunks;
5946
5735
  }
5736
+ function serializeToBlockFormat(obj, prefix = "") {
5737
+ let result = "";
5738
+ for (const [key, value] of Object.entries(obj)) {
5739
+ const pointer = prefix ? `${prefix}/${key}` : key;
5740
+ if (value === null || value === void 0) {
5741
+ continue;
5742
+ }
5743
+ if (Array.isArray(value)) {
5744
+ for (let i = 0; i < value.length; i++) {
5745
+ const item = value[i];
5746
+ const itemPointer = `${pointer}/${i}`;
5747
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
5748
+ result += serializeToBlockFormat(item, itemPointer);
5749
+ } else if (Array.isArray(item)) {
5750
+ for (let j = 0; j < item.length; j++) {
5751
+ result += `${GADGET_ARG_PREFIX}${itemPointer}/${j}
5752
+ ${String(item[j])}
5753
+ `;
5754
+ }
5755
+ } else {
5756
+ result += `${GADGET_ARG_PREFIX}${itemPointer}
5757
+ ${String(item)}
5758
+ `;
5759
+ }
5760
+ }
5761
+ } else if (typeof value === "object") {
5762
+ result += serializeToBlockFormat(value, pointer);
5763
+ } else {
5764
+ result += `${GADGET_ARG_PREFIX}${pointer}
5765
+ ${String(value)}
5766
+ `;
5767
+ }
5768
+ }
5769
+ return result;
5770
+ }
5947
5771
  function formatGadgetCalls(gadgetCalls) {
5948
5772
  let text = "";
5949
5773
  const calls = [];
5950
5774
  for (const call of gadgetCalls) {
5951
5775
  const invocationId = call.invocationId ?? generateInvocationId();
5952
5776
  calls.push({ name: call.gadgetName, invocationId });
5953
- const paramsJson = JSON.stringify(call.parameters);
5777
+ const blockParams = serializeToBlockFormat(call.parameters);
5954
5778
  text += `
5955
5779
  ${GADGET_START_PREFIX}${call.gadgetName}
5956
- ${paramsJson}
5957
- ${GADGET_END_PREFIX}`;
5780
+ ${blockParams}${GADGET_END_PREFIX}`;
5958
5781
  }
5959
5782
  return { text, calls };
5960
5783
  }