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.
@@ -360,29 +360,25 @@ var init_prompt_config = __esm({
360
360
  "EACH MARKER MUST START WITH A NEWLINE."
361
361
  ].join("\n"),
362
362
  criticalUsage: "INVOKE gadgets using the markers - do not describe what you want to do.",
363
- formatDescriptionYaml: "Parameters in YAML format (one per line)",
364
- formatDescriptionJson: "Parameters in JSON format (valid JSON object)",
365
- formatDescriptionToml: "Parameters in TOML format (key = value pairs, use heredoc for multiline: key = <<<EOF ... EOF)",
363
+ formatDescription: (ctx) => `Parameters using ${ctx.argPrefix}name markers (value on next line(s), no escaping needed)`,
366
364
  rules: () => [
367
365
  "Output ONLY plain text with the exact markers - never use function/tool calling",
368
366
  "You can invoke multiple gadgets in a single response",
369
367
  "For dependent gadgets, invoke the first one and wait for the result"
370
368
  ],
371
- schemaLabelJson: "\n\nInput Schema (JSON):",
372
- schemaLabelYaml: "\n\nInput Schema (YAML):",
373
- schemaLabelToml: "\n\nInput Schema (TOML):",
374
369
  customExamples: null
375
370
  };
376
371
  }
377
372
  });
378
373
 
379
374
  // src/core/constants.ts
380
- var GADGET_START_PREFIX, GADGET_END_PREFIX, DEFAULT_GADGET_OUTPUT_LIMIT, DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT, CHARS_PER_TOKEN, FALLBACK_CONTEXT_WINDOW;
375
+ 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;
381
376
  var init_constants = __esm({
382
377
  "src/core/constants.ts"() {
383
378
  "use strict";
384
379
  GADGET_START_PREFIX = "!!!GADGET_START:";
385
380
  GADGET_END_PREFIX = "!!!GADGET_END";
381
+ GADGET_ARG_PREFIX = "!!!ARG:";
386
382
  DEFAULT_GADGET_OUTPUT_LIMIT = true;
387
383
  DEFAULT_GADGET_OUTPUT_LIMIT_PERCENT = 15;
388
384
  CHARS_PER_TOKEN = 4;
@@ -401,6 +397,7 @@ var init_messages = __esm({
401
397
  messages = [];
402
398
  startPrefix = GADGET_START_PREFIX;
403
399
  endPrefix = GADGET_END_PREFIX;
400
+ argPrefix = GADGET_ARG_PREFIX;
404
401
  promptConfig;
405
402
  constructor(promptConfig) {
406
403
  this.promptConfig = promptConfig ?? {};
@@ -409,26 +406,32 @@ var init_messages = __esm({
409
406
  * Set custom prefixes for gadget markers.
410
407
  * Used to configure history builder to match system prompt markers.
411
408
  */
412
- withPrefixes(startPrefix, endPrefix) {
409
+ withPrefixes(startPrefix, endPrefix, argPrefix) {
413
410
  this.startPrefix = startPrefix;
414
411
  this.endPrefix = endPrefix;
412
+ if (argPrefix) {
413
+ this.argPrefix = argPrefix;
414
+ }
415
415
  return this;
416
416
  }
417
417
  addSystem(content, metadata) {
418
418
  this.messages.push({ role: "system", content, metadata });
419
419
  return this;
420
420
  }
421
- addGadgets(gadgets, parameterFormat = "json", options) {
421
+ addGadgets(gadgets, options) {
422
422
  if (options?.startPrefix) {
423
423
  this.startPrefix = options.startPrefix;
424
424
  }
425
425
  if (options?.endPrefix) {
426
426
  this.endPrefix = options.endPrefix;
427
427
  }
428
+ if (options?.argPrefix) {
429
+ this.argPrefix = options.argPrefix;
430
+ }
428
431
  const context = {
429
- parameterFormat,
430
432
  startPrefix: this.startPrefix,
431
433
  endPrefix: this.endPrefix,
434
+ argPrefix: this.argPrefix,
432
435
  gadgetCount: gadgets.length,
433
436
  gadgetNames: gadgets.map((g) => g.name ?? g.constructor.name)
434
437
  };
@@ -439,26 +442,19 @@ var init_messages = __esm({
439
442
  context
440
443
  );
441
444
  parts.push(mainInstruction);
442
- parts.push(this.buildGadgetsSection(gadgets, parameterFormat));
443
- parts.push(this.buildUsageSection(parameterFormat, context));
445
+ parts.push(this.buildGadgetsSection(gadgets));
446
+ parts.push(this.buildUsageSection(context));
444
447
  this.messages.push({ role: "system", content: parts.join("") });
445
448
  return this;
446
449
  }
447
- buildGadgetsSection(gadgets, parameterFormat) {
450
+ buildGadgetsSection(gadgets) {
448
451
  const parts = [];
449
452
  parts.push("\n\nAVAILABLE GADGETS");
450
453
  parts.push("\n=================\n");
451
454
  for (const gadget of gadgets) {
452
455
  const gadgetName = gadget.name ?? gadget.constructor.name;
453
- const instruction = gadget.getInstruction(parameterFormat);
454
- const schemaMarkers = {
455
- yaml: "\n\nInput Schema (YAML):",
456
- json: "\n\nInput Schema (JSON):",
457
- toml: "\n\nInput Schema (TOML):",
458
- auto: "\n\nInput Schema (JSON):"
459
- // auto defaults to JSON schema display
460
- };
461
- const schemaMarker = schemaMarkers[parameterFormat];
456
+ const instruction = gadget.getInstruction(this.argPrefix);
457
+ const schemaMarker = "\n\nInput Schema (BLOCK):";
462
458
  const schemaIndex = instruction.indexOf(schemaMarker);
463
459
  const description = (schemaIndex !== -1 ? instruction.substring(0, schemaIndex) : instruction).trim();
464
460
  const schema = schemaIndex !== -1 ? instruction.substring(schemaIndex + schemaMarker.length).trim() : "";
@@ -469,35 +465,20 @@ ${description}`);
469
465
  if (schema) {
470
466
  parts.push(`
471
467
 
472
- PARAMETERS (${parameterFormat.toUpperCase()}):
468
+ PARAMETERS (BLOCK):
473
469
  ${schema}`);
474
470
  }
475
471
  parts.push("\n\n---");
476
472
  }
477
473
  return parts.join("");
478
474
  }
479
- buildUsageSection(parameterFormat, context) {
475
+ buildUsageSection(context) {
480
476
  const parts = [];
481
- const formatDescriptionMap = {
482
- yaml: {
483
- config: this.promptConfig.formatDescriptionYaml,
484
- defaultValue: DEFAULT_PROMPTS.formatDescriptionYaml
485
- },
486
- json: {
487
- config: this.promptConfig.formatDescriptionJson,
488
- defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
489
- },
490
- toml: {
491
- config: this.promptConfig.formatDescriptionToml,
492
- defaultValue: DEFAULT_PROMPTS.formatDescriptionToml
493
- },
494
- auto: {
495
- config: this.promptConfig.formatDescriptionJson,
496
- defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
497
- }
498
- };
499
- const { config, defaultValue } = formatDescriptionMap[parameterFormat];
500
- const formatDescription = resolvePromptTemplate(config, defaultValue, context);
477
+ const formatDescription = resolvePromptTemplate(
478
+ this.promptConfig.formatDescription,
479
+ DEFAULT_PROMPTS.formatDescription,
480
+ context
481
+ );
501
482
  parts.push("\n\nHOW TO INVOKE GADGETS");
502
483
  parts.push("\n=====================\n");
503
484
  const criticalUsage = resolvePromptTemplate(
@@ -515,124 +496,90 @@ CRITICAL: ${criticalUsage}
515
496
  2. ${formatDescription}`);
516
497
  parts.push(`
517
498
  3. End marker: ${this.endPrefix}`);
518
- parts.push(this.buildExamplesSection(parameterFormat, context));
499
+ parts.push(this.buildExamplesSection(context));
519
500
  parts.push(this.buildRulesSection(context));
520
501
  parts.push("\n");
521
502
  return parts.join("");
522
503
  }
523
- buildExamplesSection(parameterFormat, context) {
504
+ buildExamplesSection(context) {
524
505
  if (this.promptConfig.customExamples) {
525
506
  return this.promptConfig.customExamples(context);
526
507
  }
527
508
  const parts = [];
528
- const singleExamples = {
529
- yaml: `${this.startPrefix}translate
530
- from: English
531
- to: Polish
532
- content: "Paris is the capital of France: a beautiful city."
533
- ${this.endPrefix}`,
534
- json: `${this.startPrefix}translate
535
- {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
536
- ${this.endPrefix}`,
537
- toml: `${this.startPrefix}translate
538
- from = "English"
539
- to = "Polish"
540
- content = "Paris is the capital of France: a beautiful city."
541
- ${this.endPrefix}`,
542
- auto: `${this.startPrefix}translate
543
- {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
544
- ${this.endPrefix}`
545
- };
509
+ const singleExample = `${this.startPrefix}translate
510
+ ${this.argPrefix}from
511
+ English
512
+ ${this.argPrefix}to
513
+ Polish
514
+ ${this.argPrefix}content
515
+ Paris is the capital of France: a beautiful city.
516
+ ${this.endPrefix}`;
546
517
  parts.push(`
547
518
 
548
519
  EXAMPLE (Single Gadget):
549
520
 
550
- ${singleExamples[parameterFormat]}`);
551
- const multipleExamples = {
552
- yaml: `${this.startPrefix}translate
553
- from: English
554
- to: Polish
555
- content: "Paris is the capital of France: a beautiful city."
556
- ${this.endPrefix}
557
- ${this.startPrefix}analyze
558
- type: economic_analysis
559
- matter: "Polish Economy"
560
- question: <<<EOF
561
- Analyze the following:
562
- - Polish arms exports 2025
563
- - Economic implications
564
- EOF
565
- ${this.endPrefix}`,
566
- json: `${this.startPrefix}translate
567
- {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
521
+ ${singleExample}`);
522
+ const multipleExample = `${this.startPrefix}translate
523
+ ${this.argPrefix}from
524
+ English
525
+ ${this.argPrefix}to
526
+ Polish
527
+ ${this.argPrefix}content
528
+ Paris is the capital of France: a beautiful city.
568
529
  ${this.endPrefix}
569
530
  ${this.startPrefix}analyze
570
- {"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
571
- ${this.endPrefix}`,
572
- toml: `${this.startPrefix}translate
573
- from = "English"
574
- to = "Polish"
575
- content = "Paris is the capital of France: a beautiful city."
576
- ${this.endPrefix}
577
- ${this.startPrefix}analyze
578
- type = "economic_analysis"
579
- matter = "Polish Economy"
580
- question = <<<EOF
531
+ ${this.argPrefix}type
532
+ economic_analysis
533
+ ${this.argPrefix}matter
534
+ Polish Economy
535
+ ${this.argPrefix}question
581
536
  Analyze the following:
582
537
  - Polish arms exports 2025
583
538
  - Economic implications
584
- EOF
585
- ${this.endPrefix}`,
586
- auto: `${this.startPrefix}translate
587
- {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
588
- ${this.endPrefix}
589
- ${this.startPrefix}analyze
590
- {"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
591
- ${this.endPrefix}`
592
- };
539
+ ${this.endPrefix}`;
593
540
  parts.push(`
594
541
 
595
542
  EXAMPLE (Multiple Gadgets):
596
543
 
597
- ${multipleExamples[parameterFormat]}`);
598
- if (parameterFormat === "yaml") {
599
- parts.push(`
600
-
601
- YAML HEREDOC SYNTAX:
602
- For string values with multiple lines, use heredoc syntax (<<<DELIMITER...DELIMITER):
603
-
604
- filePath: "README.md"
605
- content: <<<EOF
606
- # Project Title
544
+ ${multipleExample}`);
545
+ parts.push(`
607
546
 
608
- This content can contain:
609
- - Markdown lists
610
- - Special characters: # : -
611
- - Multiple paragraphs
612
- EOF
547
+ BLOCK FORMAT SYNTAX:
548
+ Block format uses ${this.argPrefix}name markers. Values are captured verbatim until the next marker.
613
549
 
614
- The delimiter (EOF) can be any identifier. The closing delimiter must be on its own line.
615
- No indentation is required for the content.`);
616
- } else if (parameterFormat === "toml") {
617
- parts.push(`
550
+ ${this.argPrefix}filename
551
+ calculator.ts
552
+ ${this.argPrefix}code
553
+ class Calculator {
554
+ private history: string[] = [];
618
555
 
619
- TOML HEREDOC SYNTAX:
620
- For string values with multiple lines, use heredoc syntax (<<<DELIMITER...DELIMITER):
556
+ add(a: number, b: number): number {
557
+ const result = a + b;
558
+ this.history.push(\`\${a} + \${b} = \${result}\`);
559
+ return result;
560
+ }
561
+ }
621
562
 
622
- filePath = "README.md"
623
- content = <<<EOF
624
- # Project Title
563
+ BLOCK FORMAT RULES:
564
+ - Each parameter starts with ${this.argPrefix}parameterName on its own line
565
+ - The value starts on the NEXT line after the marker
566
+ - Value ends when the next ${this.argPrefix} or ${this.endPrefix} appears
567
+ - NO escaping needed - write values exactly as they should appear
568
+ - Perfect for code, JSON, markdown, or any content with special characters
625
569
 
626
- This content can contain:
627
- - Markdown lists
628
- - Special characters: # : -
629
- - Multiple paragraphs
630
- EOF
570
+ NESTED OBJECTS (use / separator):
571
+ ${this.argPrefix}config/timeout
572
+ 30
573
+ ${this.argPrefix}config/retries
574
+ 3
575
+ Produces: { "config": { "timeout": "30", "retries": "3" } }
631
576
 
632
- The delimiter (EOF) can be any identifier. The closing delimiter must be on its own line.
633
- IMPORTANT: Content inside heredoc is LITERAL - do NOT escape backticks, dollar signs, or any characters.
634
- NEVER use TOML triple-quote strings ("""). ALWAYS use heredoc syntax (<<<EOF...EOF) for multiline content.`);
635
- }
577
+ ARRAYS (use numeric indices):
578
+ ${this.argPrefix}items/0
579
+ first
580
+ ${this.argPrefix}items/1
581
+ second
582
+ Produces: { "items": ["first", "second"] }`);
636
583
  return parts.join("");
637
584
  }
638
585
  buildRulesSection(context) {
@@ -653,8 +600,8 @@ NEVER use TOML triple-quote strings ("""). ALWAYS use heredoc syntax (<<<EOF...E
653
600
  this.messages.push({ role: "assistant", content, metadata });
654
601
  return this;
655
602
  }
656
- addGadgetCall(gadget, parameters, result, parameterFormat = "json") {
657
- const paramStr = this.formatParameters(parameters, parameterFormat);
603
+ addGadgetCall(gadget, parameters, result) {
604
+ const paramStr = this.formatBlockParameters(parameters, "");
658
605
  this.messages.push({
659
606
  role: "assistant",
660
607
  content: `${this.startPrefix}${gadget}
@@ -667,26 +614,32 @@ ${this.endPrefix}`
667
614
  });
668
615
  return this;
669
616
  }
670
- formatParameters(parameters, format) {
671
- if (format === "yaml") {
672
- return Object.entries(parameters).map(([key, value]) => {
673
- if (typeof value === "string") {
674
- return `${key}: ${value}`;
675
- }
676
- return `${key}: ${JSON.stringify(value)}`;
677
- }).join("\n");
678
- }
679
- if (format === "toml") {
680
- return Object.entries(parameters).map(([key, value]) => {
681
- if (typeof value === "string" && value.includes("\n")) {
682
- return `${key} = <<<EOF
683
- ${value}
684
- EOF`;
685
- }
686
- return `${key} = ${JSON.stringify(value)}`;
687
- }).join("\n");
617
+ /**
618
+ * Format parameters as Block format with JSON Pointer paths.
619
+ * Uses the configured argPrefix for consistency with system prompt.
620
+ */
621
+ formatBlockParameters(params, prefix) {
622
+ const lines = [];
623
+ for (const [key, value] of Object.entries(params)) {
624
+ const fullPath = prefix ? `${prefix}/${key}` : key;
625
+ if (Array.isArray(value)) {
626
+ value.forEach((item, index) => {
627
+ const itemPath = `${fullPath}/${index}`;
628
+ if (typeof item === "object" && item !== null) {
629
+ lines.push(this.formatBlockParameters(item, itemPath));
630
+ } else {
631
+ lines.push(`${this.argPrefix}${itemPath}`);
632
+ lines.push(String(item));
633
+ }
634
+ });
635
+ } else if (typeof value === "object" && value !== null) {
636
+ lines.push(this.formatBlockParameters(value, fullPath));
637
+ } else {
638
+ lines.push(`${this.argPrefix}${fullPath}`);
639
+ lines.push(String(value));
640
+ }
688
641
  }
689
- return JSON.stringify(parameters);
642
+ return lines.join("\n");
690
643
  }
691
644
  build() {
692
645
  return [...this.messages];
@@ -857,134 +810,72 @@ var init_schema_to_json = __esm({
857
810
  });
858
811
 
859
812
  // src/gadgets/gadget.ts
860
- import * as yaml from "js-yaml";
861
- function findSafeDelimiter(content) {
862
- const lines = content.split("\n");
863
- for (const delimiter of HEREDOC_DELIMITERS) {
864
- const regex = new RegExp(`^${delimiter}\\s*$`);
865
- const isUsed = lines.some((line) => regex.test(line));
866
- if (!isUsed) {
867
- return delimiter;
868
- }
869
- }
870
- let counter = 1;
871
- while (counter < 1e3) {
872
- const delimiter = `__GADGET_PARAM_${counter}__`;
873
- const regex = new RegExp(`^${delimiter}\\s*$`);
874
- const isUsed = lines.some((line) => regex.test(line));
875
- if (!isUsed) {
876
- return delimiter;
877
- }
878
- counter++;
879
- }
880
- return "HEREDOC_FALLBACK";
881
- }
882
- function formatYamlValue(value, indent = "") {
883
- if (typeof value === "string") {
884
- const lines = value.split("\n");
885
- if (lines.length === 1 && !value.includes(":") && !value.startsWith("-")) {
886
- return value;
887
- }
888
- const delimiter = findSafeDelimiter(value);
889
- return `<<<${delimiter}
890
- ${value}
891
- ${delimiter}`;
892
- }
893
- if (typeof value === "number" || typeof value === "boolean") {
894
- return String(value);
895
- }
896
- if (value === null || value === void 0) {
897
- return "null";
898
- }
899
- if (Array.isArray(value)) {
900
- if (value.length === 0) return "[]";
901
- const items = value.map((item) => `${indent}- ${formatYamlValue(item, indent + " ")}`);
902
- return "\n" + items.join("\n");
903
- }
904
- if (typeof value === "object") {
905
- const entries = Object.entries(value);
906
- if (entries.length === 0) return "{}";
907
- const lines = entries.map(([k, v]) => {
908
- const formattedValue = formatYamlValue(v, indent + " ");
909
- if (formattedValue.startsWith("\n") || formattedValue.startsWith("|")) {
910
- return `${indent}${k}: ${formattedValue}`;
911
- }
912
- return `${indent}${k}: ${formattedValue}`;
913
- });
914
- return "\n" + lines.join("\n");
915
- }
916
- return yaml.dump(value).trimEnd();
917
- }
918
- function formatParamsAsYaml(params) {
813
+ function formatParamsAsBlock(params, prefix = "", argPrefix = GADGET_ARG_PREFIX) {
919
814
  const lines = [];
920
815
  for (const [key, value] of Object.entries(params)) {
921
- const formattedValue = formatYamlValue(value, "");
922
- if (formattedValue.startsWith("\n")) {
923
- lines.push(`${key}:${formattedValue}`);
816
+ const fullPath = prefix ? `${prefix}/${key}` : key;
817
+ if (Array.isArray(value)) {
818
+ value.forEach((item, index) => {
819
+ const itemPath = `${fullPath}/${index}`;
820
+ if (typeof item === "object" && item !== null) {
821
+ lines.push(formatParamsAsBlock(item, itemPath, argPrefix));
822
+ } else {
823
+ lines.push(`${argPrefix}${itemPath}`);
824
+ lines.push(String(item));
825
+ }
826
+ });
827
+ } else if (typeof value === "object" && value !== null) {
828
+ lines.push(formatParamsAsBlock(value, fullPath, argPrefix));
924
829
  } else {
925
- lines.push(`${key}: ${formattedValue}`);
830
+ lines.push(`${argPrefix}${fullPath}`);
831
+ lines.push(String(value));
926
832
  }
927
833
  }
928
834
  return lines.join("\n");
929
835
  }
930
- function formatTomlInlineTable(obj) {
931
- const entries = Object.entries(obj).map(([k, v]) => `${k} = ${formatTomlValue(v)}`);
932
- return `{ ${entries.join(", ")} }`;
933
- }
934
- function formatTomlValue(value) {
935
- if (typeof value === "string") {
936
- if (value.includes("\n")) {
937
- const delimiter = findSafeDelimiter(value);
938
- return `<<<${delimiter}
939
- ${value}
940
- ${delimiter}`;
941
- }
942
- return JSON.stringify(value);
943
- }
944
- if (typeof value === "number" || typeof value === "boolean") {
945
- return String(value);
946
- }
947
- if (value === null || value === void 0) {
948
- return '""';
949
- }
950
- if (Array.isArray(value)) {
951
- if (value.length === 0) return "[]";
952
- const items = value.map((item) => {
953
- if (typeof item === "object" && item !== null && !Array.isArray(item)) {
954
- return formatTomlInlineTable(item);
955
- }
956
- return formatTomlValue(item);
957
- });
958
- return `[${items.join(", ")}]`;
959
- }
960
- if (typeof value === "object") {
961
- return formatTomlInlineTable(value);
962
- }
963
- return JSON.stringify(value);
964
- }
965
- function formatParamsAsToml(params) {
836
+ function formatSchemaAsPlainText(schema, indent = "") {
966
837
  const lines = [];
967
- for (const [key, value] of Object.entries(params)) {
968
- lines.push(`${key} = ${formatTomlValue(value)}`);
838
+ const properties = schema.properties || {};
839
+ const required = schema.required || [];
840
+ for (const [key, prop] of Object.entries(properties)) {
841
+ const propObj = prop;
842
+ const type = propObj.type;
843
+ const description = propObj.description;
844
+ const isRequired = required.includes(key);
845
+ const enumValues = propObj.enum;
846
+ let line = `${indent}- ${key}`;
847
+ if (type === "array") {
848
+ const items = propObj.items;
849
+ const itemType = items?.type || "any";
850
+ line += ` (array of ${itemType})`;
851
+ } else if (type === "object" && propObj.properties) {
852
+ line += " (object)";
853
+ } else {
854
+ line += ` (${type})`;
855
+ }
856
+ if (isRequired) {
857
+ line += " [required]";
858
+ }
859
+ if (description) {
860
+ line += `: ${description}`;
861
+ }
862
+ if (enumValues) {
863
+ line += ` - one of: ${enumValues.map((v) => `"${v}"`).join(", ")}`;
864
+ }
865
+ lines.push(line);
866
+ if (type === "object" && propObj.properties) {
867
+ lines.push(formatSchemaAsPlainText(propObj, indent + " "));
868
+ }
969
869
  }
970
870
  return lines.join("\n");
971
871
  }
972
- var HEREDOC_DELIMITERS, BaseGadget;
872
+ var BaseGadget;
973
873
  var init_gadget = __esm({
974
874
  "src/gadgets/gadget.ts"() {
975
875
  "use strict";
876
+ init_constants();
976
877
  init_schema_to_json();
977
878
  init_schema_validator();
978
- HEREDOC_DELIMITERS = [
979
- "__GADGET_PARAM_EOF__",
980
- "__GADGET_PARAM_END__",
981
- "__GADGET_PARAM_DOC__",
982
- "__GADGET_PARAM_CONTENT__",
983
- "__GADGET_PARAM_TEXT__",
984
- "__GADGET_PARAM_HEREDOC__",
985
- "__GADGET_PARAM_DATA__",
986
- "__GADGET_PARAM_BLOCK__"
987
- ];
988
879
  BaseGadget = class {
989
880
  /**
990
881
  * The name of the gadget. Used for identification when LLM calls it.
@@ -1015,19 +906,19 @@ var init_gadget = __esm({
1015
906
  /**
1016
907
  * Auto-generated instruction text for the LLM.
1017
908
  * Combines name, description, and parameter schema into a formatted instruction.
1018
- * @deprecated Use getInstruction(format) instead for format-specific schemas
909
+ * @deprecated Use getInstruction() instead
1019
910
  */
1020
911
  get instruction() {
1021
- return this.getInstruction("yaml");
912
+ return this.getInstruction();
1022
913
  }
1023
914
  /**
1024
- * Generate instruction text for the LLM with format-specific schema.
915
+ * Generate instruction text for the LLM.
1025
916
  * Combines name, description, and parameter schema into a formatted instruction.
1026
917
  *
1027
- * @param format - Format for the schema representation ('json' | 'yaml' | 'toml' | 'auto')
918
+ * @param argPrefix - Optional custom argument prefix for block format examples
1028
919
  * @returns Formatted instruction string
1029
920
  */
1030
- getInstruction(format = "json") {
921
+ getInstruction(argPrefix) {
1031
922
  const parts = [];
1032
923
  parts.push(this.description);
1033
924
  if (this.parameterSchema) {
@@ -1036,20 +927,12 @@ var init_gadget = __esm({
1036
927
  const jsonSchema = schemaToJSONSchema(this.parameterSchema, {
1037
928
  target: "draft-7"
1038
929
  });
1039
- if (format === "json" || format === "auto") {
1040
- parts.push("\n\nInput Schema (JSON):");
1041
- parts.push(JSON.stringify(jsonSchema, null, 2));
1042
- } else if (format === "toml") {
1043
- parts.push("\n\nInput Schema (TOML):");
1044
- parts.push(JSON.stringify(jsonSchema, null, 2));
1045
- } else {
1046
- const yamlSchema = yaml.dump(jsonSchema).trimEnd();
1047
- parts.push("\n\nInput Schema (YAML):");
1048
- parts.push(yamlSchema);
1049
- }
930
+ parts.push("\n\nParameters:");
931
+ parts.push(formatSchemaAsPlainText(jsonSchema));
1050
932
  }
1051
933
  if (this.examples && this.examples.length > 0) {
1052
934
  parts.push("\n\nExamples:");
935
+ const effectiveArgPrefix = argPrefix ?? GADGET_ARG_PREFIX;
1053
936
  this.examples.forEach((example, index) => {
1054
937
  if (index > 0) {
1055
938
  parts.push("");
@@ -1058,13 +941,7 @@ var init_gadget = __esm({
1058
941
  parts.push(`# ${example.comment}`);
1059
942
  }
1060
943
  parts.push("Input:");
1061
- if (format === "json" || format === "auto") {
1062
- parts.push(JSON.stringify(example.params, null, 2));
1063
- } else if (format === "toml") {
1064
- parts.push(formatParamsAsToml(example.params));
1065
- } else {
1066
- parts.push(formatParamsAsYaml(example.params));
1067
- }
944
+ parts.push(formatParamsAsBlock(example.params, "", effectiveArgPrefix));
1068
945
  if (example.output !== void 0) {
1069
946
  parts.push("Output:");
1070
947
  parts.push(example.output);
@@ -1329,14 +1206,12 @@ var init_conversation_manager = __esm({
1329
1206
  baseMessages;
1330
1207
  initialMessages;
1331
1208
  historyBuilder;
1332
- parameterFormat;
1333
1209
  constructor(baseMessages, initialMessages, options = {}) {
1334
1210
  this.baseMessages = baseMessages;
1335
1211
  this.initialMessages = initialMessages;
1336
- this.parameterFormat = options.parameterFormat ?? "json";
1337
1212
  this.historyBuilder = new LLMMessageBuilder();
1338
1213
  if (options.startPrefix && options.endPrefix) {
1339
- this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix);
1214
+ this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix, options.argPrefix);
1340
1215
  }
1341
1216
  }
1342
1217
  addUserMessage(content) {
@@ -1346,7 +1221,7 @@ var init_conversation_manager = __esm({
1346
1221
  this.historyBuilder.addAssistant(content);
1347
1222
  }
1348
1223
  addGadgetCall(gadgetName, parameters, result) {
1349
- this.historyBuilder.addGadgetCall(gadgetName, parameters, result, this.parameterFormat);
1224
+ this.historyBuilder.addGadgetCall(gadgetName, parameters, result);
1350
1225
  }
1351
1226
  getMessages() {
1352
1227
  return [...this.baseMessages, ...this.initialMessages, ...this.historyBuilder.build()];
@@ -1369,7 +1244,7 @@ async function runWithHandlers(agentGenerator, handlers) {
1369
1244
  await handlers.onGadgetCall({
1370
1245
  gadgetName: event.call.gadgetName,
1371
1246
  parameters: event.call.parameters,
1372
- parametersYaml: event.call.parametersYaml
1247
+ parametersRaw: event.call.parametersRaw
1373
1248
  });
1374
1249
  }
1375
1250
  break;
@@ -1522,7 +1397,7 @@ var init_executor = __esm({
1522
1397
  this.logger.error("Gadget parameter parse error", {
1523
1398
  gadgetName: call.gadgetName,
1524
1399
  parseError: call.parseError,
1525
- rawParameters: call.parametersYaml
1400
+ rawParameters: call.parametersRaw
1526
1401
  });
1527
1402
  return {
1528
1403
  gadgetName: call.gadgetName,
@@ -1684,170 +1559,107 @@ var init_executor = __esm({
1684
1559
  }
1685
1560
  });
1686
1561
 
1687
- // src/gadgets/parser.ts
1688
- import * as yaml2 from "js-yaml";
1689
- import { load as parseToml } from "js-toml";
1690
- function preprocessYaml(yamlStr) {
1691
- const lines = yamlStr.split("\n");
1692
- const result = [];
1693
- let i = 0;
1694
- while (i < lines.length) {
1695
- const line = lines[i];
1696
- const heredocMatch = line.match(/^(\s*)([\w-]+):\s*<<<([A-Za-z_][A-Za-z0-9_]*)\s*$/);
1697
- if (heredocMatch) {
1698
- const [, indent, key, delimiter] = heredocMatch;
1699
- const bodyLines = [];
1700
- i++;
1701
- const closingRegex = new RegExp(`^${delimiter}\\s*$`);
1702
- while (i < lines.length && !closingRegex.test(lines[i])) {
1703
- bodyLines.push(lines[i]);
1704
- i++;
1705
- }
1706
- if (i < lines.length) {
1707
- i++;
1708
- }
1709
- result.push(`${indent}${key}: |`);
1710
- for (const bodyLine of bodyLines) {
1711
- result.push(`${indent} ${bodyLine}`);
1562
+ // src/gadgets/block-params.ts
1563
+ function parseBlockParams(content, options) {
1564
+ const argPrefix = options?.argPrefix ?? GADGET_ARG_PREFIX;
1565
+ const result = {};
1566
+ const seenPointers = /* @__PURE__ */ new Set();
1567
+ const parts = content.split(argPrefix);
1568
+ for (let i = 1; i < parts.length; i++) {
1569
+ const part = parts[i];
1570
+ const newlineIndex = part.indexOf("\n");
1571
+ if (newlineIndex === -1) {
1572
+ const pointer2 = part.trim();
1573
+ if (pointer2) {
1574
+ if (seenPointers.has(pointer2)) {
1575
+ throw new Error(`Duplicate pointer: ${pointer2}`);
1576
+ }
1577
+ seenPointers.add(pointer2);
1578
+ setByPointer(result, pointer2, "");
1712
1579
  }
1713
1580
  continue;
1714
1581
  }
1715
- const match = line.match(/^(\s*)([\w-]+):\s+(.+)$/);
1716
- if (match) {
1717
- const [, indent, key, value] = match;
1718
- if (value === "|" || value === ">" || value === "|-" || value === ">-") {
1719
- result.push(line);
1720
- i++;
1721
- const keyIndentLen2 = indent.length;
1722
- const blockLines = [];
1723
- let minContentIndent = Infinity;
1724
- while (i < lines.length) {
1725
- const blockLine = lines[i];
1726
- const blockIndentMatch = blockLine.match(/^(\s*)/);
1727
- const blockIndentLen = blockIndentMatch ? blockIndentMatch[1].length : 0;
1728
- if (blockLine.trim() === "") {
1729
- blockLines.push({ content: "", originalIndent: 0 });
1730
- i++;
1731
- continue;
1732
- }
1733
- if (blockIndentLen > keyIndentLen2) {
1734
- const content = blockLine.substring(blockIndentLen);
1735
- blockLines.push({ content, originalIndent: blockIndentLen });
1736
- if (content.trim().length > 0) {
1737
- minContentIndent = Math.min(minContentIndent, blockIndentLen);
1738
- }
1739
- i++;
1740
- } else {
1741
- break;
1742
- }
1743
- }
1744
- const targetIndent = keyIndentLen2 + 2;
1745
- for (const blockLine of blockLines) {
1746
- if (blockLine.content === "") {
1747
- result.push("");
1748
- } else {
1749
- result.push(" ".repeat(targetIndent) + blockLine.content);
1750
- }
1751
- }
1752
- continue;
1753
- }
1754
- if (value.startsWith('"') || value.startsWith("'") || value === "true" || value === "false" || /^-?\d+(\.\d+)?$/.test(value)) {
1755
- result.push(line);
1756
- i++;
1757
- continue;
1758
- }
1759
- const keyIndentLen = indent.length;
1760
- const continuationLines = [];
1761
- let j = i + 1;
1762
- while (j < lines.length) {
1763
- const nextLine = lines[j];
1764
- if (nextLine.trim() === "") {
1765
- continuationLines.push(nextLine);
1766
- j++;
1767
- continue;
1768
- }
1769
- const nextIndentMatch = nextLine.match(/^(\s*)/);
1770
- const nextIndentLen = nextIndentMatch ? nextIndentMatch[1].length : 0;
1771
- if (nextIndentLen > keyIndentLen) {
1772
- continuationLines.push(nextLine);
1773
- j++;
1774
- } else {
1775
- break;
1776
- }
1777
- }
1778
- if (continuationLines.length > 0 && continuationLines.some((l) => l.trim().length > 0)) {
1779
- result.push(`${indent}${key}: |`);
1780
- result.push(`${indent} ${value}`);
1781
- for (const contLine of continuationLines) {
1782
- if (contLine.trim() === "") {
1783
- result.push("");
1784
- } else {
1785
- const contIndentMatch = contLine.match(/^(\s*)/);
1786
- const contIndent = contIndentMatch ? contIndentMatch[1] : "";
1787
- const contContent = contLine.substring(contIndent.length);
1788
- result.push(`${indent} ${contContent}`);
1789
- }
1790
- }
1791
- i = j;
1792
- continue;
1793
- }
1794
- if (value.includes(": ") || value.endsWith(":")) {
1795
- const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1796
- result.push(`${indent}${key}: "${escaped}"`);
1797
- i++;
1798
- continue;
1799
- }
1582
+ const pointer = part.substring(0, newlineIndex).trim();
1583
+ let value = part.substring(newlineIndex + 1);
1584
+ if (value.endsWith("\n")) {
1585
+ value = value.slice(0, -1);
1586
+ }
1587
+ if (!pointer) {
1588
+ continue;
1800
1589
  }
1801
- result.push(line);
1802
- i++;
1590
+ if (seenPointers.has(pointer)) {
1591
+ throw new Error(`Duplicate pointer: ${pointer}`);
1592
+ }
1593
+ seenPointers.add(pointer);
1594
+ setByPointer(result, pointer, value);
1803
1595
  }
1804
- return result.join("\n");
1596
+ return result;
1805
1597
  }
1806
- function unescapeHeredocContent(content) {
1807
- return content.replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\{/g, "{").replace(/\\}/g, "}");
1598
+ function coerceValue(value) {
1599
+ if (value.includes("\n")) {
1600
+ return value;
1601
+ }
1602
+ const trimmed = value.trim();
1603
+ if (trimmed === "true") return true;
1604
+ if (trimmed === "false") return false;
1605
+ if (trimmed !== "" && /^-?\d+(\.\d+)?$/.test(trimmed)) {
1606
+ const num = Number(trimmed);
1607
+ if (!isNaN(num) && isFinite(num)) {
1608
+ return num;
1609
+ }
1610
+ }
1611
+ return value;
1808
1612
  }
1809
- function preprocessTomlHeredoc(tomlStr) {
1810
- const lines = tomlStr.split("\n");
1811
- const result = [];
1812
- let i = 0;
1813
- const heredocStartRegex = /^(\s*)([\w-]+)\s*=\s*<<<([A-Za-z_][A-Za-z0-9_]*)\s*$/;
1814
- while (i < lines.length) {
1815
- const line = lines[i];
1816
- const match = line.match(heredocStartRegex);
1817
- if (match) {
1818
- const [, indent, key, delimiter] = match;
1819
- const bodyLines = [];
1820
- i++;
1821
- const closingRegex = new RegExp(`^${delimiter}\\s*$`);
1822
- let foundClosing = false;
1823
- while (i < lines.length) {
1824
- const bodyLine = lines[i];
1825
- if (closingRegex.test(bodyLine)) {
1826
- foundClosing = true;
1827
- i++;
1828
- break;
1829
- }
1830
- bodyLines.push(bodyLine);
1831
- i++;
1832
- }
1833
- if (bodyLines.length === 0) {
1834
- result.push(`${indent}${key} = ''''''`);
1835
- } else {
1836
- result.push(`${indent}${key} = '''`);
1837
- for (let j = 0; j < bodyLines.length - 1; j++) {
1838
- result.push(unescapeHeredocContent(bodyLines[j]));
1839
- }
1840
- result.push(`${unescapeHeredocContent(bodyLines[bodyLines.length - 1])}'''`);
1841
- }
1842
- if (!foundClosing) {
1613
+ function setByPointer(obj, pointer, value) {
1614
+ const segments = pointer.split("/");
1615
+ let current = obj;
1616
+ for (let i = 0; i < segments.length - 1; i++) {
1617
+ const segment = segments[i];
1618
+ const nextSegment = segments[i + 1];
1619
+ const nextIsArrayIndex = /^\d+$/.test(nextSegment);
1620
+ if (Array.isArray(current)) {
1621
+ const index = parseInt(segment, 10);
1622
+ if (isNaN(index) || index < 0) {
1623
+ throw new Error(`Invalid array index: ${segment}`);
1624
+ }
1625
+ if (index > current.length) {
1626
+ throw new Error(`Array index gap: expected ${current.length}, got ${index}`);
1627
+ }
1628
+ if (current[index] === void 0) {
1629
+ current[index] = nextIsArrayIndex ? [] : {};
1630
+ }
1631
+ current = current[index];
1632
+ } else {
1633
+ const rec = current;
1634
+ if (rec[segment] === void 0) {
1635
+ rec[segment] = nextIsArrayIndex ? [] : {};
1843
1636
  }
1844
- continue;
1637
+ current = rec[segment];
1638
+ }
1639
+ }
1640
+ const lastSegment = segments[segments.length - 1];
1641
+ const coercedValue = coerceValue(value);
1642
+ if (Array.isArray(current)) {
1643
+ const index = parseInt(lastSegment, 10);
1644
+ if (isNaN(index) || index < 0) {
1645
+ throw new Error(`Invalid array index: ${lastSegment}`);
1646
+ }
1647
+ if (index > current.length) {
1648
+ throw new Error(`Array index gap: expected ${current.length}, got ${index}`);
1845
1649
  }
1846
- result.push(line);
1847
- i++;
1650
+ current[index] = coercedValue;
1651
+ } else {
1652
+ current[lastSegment] = coercedValue;
1848
1653
  }
1849
- return result.join("\n");
1850
1654
  }
1655
+ var init_block_params = __esm({
1656
+ "src/gadgets/block-params.ts"() {
1657
+ "use strict";
1658
+ init_constants();
1659
+ }
1660
+ });
1661
+
1662
+ // src/gadgets/parser.ts
1851
1663
  function stripMarkdownFences(content) {
1852
1664
  let cleaned = content.trim();
1853
1665
  const openingFence = /^```(?:toml|yaml|json)?\s*\n/i;
@@ -1861,17 +1673,18 @@ var init_parser = __esm({
1861
1673
  "src/gadgets/parser.ts"() {
1862
1674
  "use strict";
1863
1675
  init_constants();
1676
+ init_block_params();
1864
1677
  globalInvocationCounter = 0;
1865
1678
  StreamParser = class {
1866
1679
  buffer = "";
1867
1680
  lastReportedTextLength = 0;
1868
1681
  startPrefix;
1869
1682
  endPrefix;
1870
- parameterFormat;
1683
+ argPrefix;
1871
1684
  constructor(options = {}) {
1872
1685
  this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
1873
1686
  this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
1874
- this.parameterFormat = options.parameterFormat ?? "json";
1687
+ this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
1875
1688
  }
1876
1689
  takeTextUntil(index) {
1877
1690
  if (index <= this.lastReportedTextLength) {
@@ -1906,43 +1719,14 @@ var init_parser = __esm({
1906
1719
  return `${firstLine.slice(0, maxLen)}... (${message.length} chars total)`;
1907
1720
  }
1908
1721
  /**
1909
- * Parse parameter string according to configured format
1722
+ * Parse parameter string using block format
1910
1723
  */
1911
1724
  parseParameters(raw) {
1912
1725
  const cleaned = stripMarkdownFences(raw);
1913
- if (this.parameterFormat === "json") {
1914
- try {
1915
- return { parameters: JSON.parse(cleaned) };
1916
- } catch (error) {
1917
- return { parseError: this.truncateParseError(error, "JSON") };
1918
- }
1919
- }
1920
- if (this.parameterFormat === "yaml") {
1921
- try {
1922
- return { parameters: yaml2.load(preprocessYaml(cleaned)) };
1923
- } catch (error) {
1924
- return { parseError: this.truncateParseError(error, "YAML") };
1925
- }
1926
- }
1927
- if (this.parameterFormat === "toml") {
1928
- try {
1929
- return { parameters: parseToml(preprocessTomlHeredoc(cleaned)) };
1930
- } catch (error) {
1931
- return { parseError: this.truncateParseError(error, "TOML") };
1932
- }
1933
- }
1934
1726
  try {
1935
- return { parameters: JSON.parse(cleaned) };
1936
- } catch {
1937
- try {
1938
- return { parameters: parseToml(preprocessTomlHeredoc(cleaned)) };
1939
- } catch {
1940
- try {
1941
- return { parameters: yaml2.load(preprocessYaml(cleaned)) };
1942
- } catch (error) {
1943
- return { parseError: this.truncateParseError(error, "auto") };
1944
- }
1945
- }
1727
+ return { parameters: parseBlockParams(cleaned, { argPrefix: this.argPrefix }) };
1728
+ } catch (error) {
1729
+ return { parseError: this.truncateParseError(error, "block") };
1946
1730
  }
1947
1731
  }
1948
1732
  // Feed a chunk of text and get parsed events
@@ -2001,8 +1785,7 @@ var init_parser = __esm({
2001
1785
  call: {
2002
1786
  gadgetName: actualGadgetName,
2003
1787
  invocationId,
2004
- parametersYaml: parametersRaw,
2005
- // Keep property name for backward compatibility
1788
+ parametersRaw,
2006
1789
  parameters,
2007
1790
  parseError
2008
1791
  }
@@ -2036,7 +1819,7 @@ var init_parser = __esm({
2036
1819
  call: {
2037
1820
  gadgetName: actualGadgetName,
2038
1821
  invocationId,
2039
- parametersYaml: parametersRaw,
1822
+ parametersRaw,
2040
1823
  parameters,
2041
1824
  parseError
2042
1825
  }
@@ -2241,9 +2024,9 @@ var init_stream_processor = __esm({
2241
2024
  this.stopOnGadgetError = options.stopOnGadgetError ?? true;
2242
2025
  this.shouldContinueAfterError = options.shouldContinueAfterError;
2243
2026
  this.parser = new StreamParser({
2244
- parameterFormat: options.parameterFormat,
2245
2027
  startPrefix: options.gadgetStartPrefix,
2246
- endPrefix: options.gadgetEndPrefix
2028
+ endPrefix: options.gadgetEndPrefix,
2029
+ argPrefix: options.gadgetArgPrefix
2247
2030
  });
2248
2031
  this.executor = new GadgetExecutor(
2249
2032
  options.registry,
@@ -2397,7 +2180,7 @@ var init_stream_processor = __esm({
2397
2180
  this.logger.warn("Gadget has parse error", {
2398
2181
  gadgetName: call.gadgetName,
2399
2182
  error: call.parseError,
2400
- rawParameters: call.parametersYaml
2183
+ rawParameters: call.parametersRaw
2401
2184
  });
2402
2185
  const shouldContinue = await this.checkContinueAfterError(
2403
2186
  call.parseError,
@@ -4376,9 +4159,9 @@ var init_agent = __esm({
4376
4159
  hooks;
4377
4160
  conversation;
4378
4161
  registry;
4379
- parameterFormat;
4380
4162
  gadgetStartPrefix;
4381
4163
  gadgetEndPrefix;
4164
+ gadgetArgPrefix;
4382
4165
  onHumanInputRequired;
4383
4166
  textOnlyHandler;
4384
4167
  textWithGadgetsHandler;
@@ -4407,9 +4190,9 @@ var init_agent = __esm({
4407
4190
  this.temperature = options.temperature;
4408
4191
  this.logger = options.logger ?? createLogger({ name: "llmist:agent" });
4409
4192
  this.registry = options.registry;
4410
- this.parameterFormat = options.parameterFormat ?? "json";
4411
4193
  this.gadgetStartPrefix = options.gadgetStartPrefix;
4412
4194
  this.gadgetEndPrefix = options.gadgetEndPrefix;
4195
+ this.gadgetArgPrefix = options.gadgetArgPrefix;
4413
4196
  this.onHumanInputRequired = options.onHumanInputRequired;
4414
4197
  this.textOnlyHandler = options.textOnlyHandler ?? "terminate";
4415
4198
  this.textWithGadgetsHandler = options.textWithGadgetsHandler;
@@ -4431,9 +4214,10 @@ var init_agent = __esm({
4431
4214
  if (options.systemPrompt) {
4432
4215
  baseBuilder.addSystem(options.systemPrompt);
4433
4216
  }
4434
- baseBuilder.addGadgets(this.registry.getAll(), this.parameterFormat, {
4217
+ baseBuilder.addGadgets(this.registry.getAll(), {
4435
4218
  startPrefix: options.gadgetStartPrefix,
4436
- endPrefix: options.gadgetEndPrefix
4219
+ endPrefix: options.gadgetEndPrefix,
4220
+ argPrefix: options.gadgetArgPrefix
4437
4221
  });
4438
4222
  const baseMessages = baseBuilder.build();
4439
4223
  const initialMessages = (options.initialMessages ?? []).map((message) => ({
@@ -4441,9 +4225,9 @@ var init_agent = __esm({
4441
4225
  content: message.content
4442
4226
  }));
4443
4227
  this.conversation = new ConversationManager(baseMessages, initialMessages, {
4444
- parameterFormat: this.parameterFormat,
4445
4228
  startPrefix: options.gadgetStartPrefix,
4446
- endPrefix: options.gadgetEndPrefix
4229
+ endPrefix: options.gadgetEndPrefix,
4230
+ argPrefix: options.gadgetArgPrefix
4447
4231
  });
4448
4232
  this.userPromptProvided = !!options.userPrompt;
4449
4233
  if (options.userPrompt) {
@@ -4536,9 +4320,9 @@ var init_agent = __esm({
4536
4320
  const processor = new StreamProcessor({
4537
4321
  iteration: currentIteration,
4538
4322
  registry: this.registry,
4539
- parameterFormat: this.parameterFormat,
4540
4323
  gadgetStartPrefix: this.gadgetStartPrefix,
4541
4324
  gadgetEndPrefix: this.gadgetEndPrefix,
4325
+ gadgetArgPrefix: this.gadgetArgPrefix,
4542
4326
  hooks: this.hooks,
4543
4327
  logger: this.logger.getSubLogger({ name: "stream-processor" }),
4544
4328
  onHumanInputRequired: this.onHumanInputRequired,
@@ -4831,9 +4615,9 @@ var init_builder = __esm({
4831
4615
  gadgets = [];
4832
4616
  initialMessages = [];
4833
4617
  onHumanInputRequired;
4834
- parameterFormat;
4835
4618
  gadgetStartPrefix;
4836
4619
  gadgetEndPrefix;
4620
+ gadgetArgPrefix;
4837
4621
  textOnlyHandler;
4838
4622
  textWithGadgetsHandler;
4839
4623
  stopOnGadgetError;
@@ -5020,21 +4804,6 @@ var init_builder = __esm({
5020
4804
  this.onHumanInputRequired = handler;
5021
4805
  return this;
5022
4806
  }
5023
- /**
5024
- * Set the parameter format for gadget calls.
5025
- *
5026
- * @param format - Parameter format ("json" or "xml")
5027
- * @returns This builder for chaining
5028
- *
5029
- * @example
5030
- * ```typescript
5031
- * .withParameterFormat("xml")
5032
- * ```
5033
- */
5034
- withParameterFormat(format) {
5035
- this.parameterFormat = format;
5036
- return this;
5037
- }
5038
4807
  /**
5039
4808
  * Set custom gadget marker prefix.
5040
4809
  *
@@ -5065,6 +4834,21 @@ var init_builder = __esm({
5065
4834
  this.gadgetEndPrefix = suffix;
5066
4835
  return this;
5067
4836
  }
4837
+ /**
4838
+ * Set custom argument prefix for block format parameters.
4839
+ *
4840
+ * @param prefix - Custom prefix for argument markers (default: "!!!ARG:")
4841
+ * @returns This builder for chaining
4842
+ *
4843
+ * @example
4844
+ * ```typescript
4845
+ * .withGadgetArgPrefix("<<ARG>>")
4846
+ * ```
4847
+ */
4848
+ withGadgetArgPrefix(prefix) {
4849
+ this.gadgetArgPrefix = prefix;
4850
+ return this;
4851
+ }
5068
4852
  /**
5069
4853
  * Set the text-only handler strategy.
5070
4854
  *
@@ -5264,8 +5048,7 @@ var init_builder = __esm({
5264
5048
  withSyntheticGadgetCall(gadgetName, parameters, result) {
5265
5049
  const startPrefix = this.gadgetStartPrefix ?? GADGET_START_PREFIX;
5266
5050
  const endPrefix = this.gadgetEndPrefix ?? GADGET_END_PREFIX;
5267
- const format = this.parameterFormat ?? "yaml";
5268
- const paramStr = this.formatSyntheticParameters(parameters, format);
5051
+ const paramStr = this.formatBlockParameters(parameters, "");
5269
5052
  this.initialMessages.push({
5270
5053
  role: "assistant",
5271
5054
  content: `${startPrefix}${gadgetName}
@@ -5279,25 +5062,31 @@ ${endPrefix}`
5279
5062
  return this;
5280
5063
  }
5281
5064
  /**
5282
- * Format parameters for synthetic gadget calls.
5283
- * Uses heredoc for multiline string values.
5065
+ * Format parameters as block format with JSON Pointer paths.
5284
5066
  */
5285
- formatSyntheticParameters(parameters, format) {
5286
- if (format === "json" || format === "auto") {
5287
- return JSON.stringify(parameters);
5288
- }
5289
- return Object.entries(parameters).map(([key, value]) => {
5290
- if (typeof value === "string" && value.includes("\n")) {
5291
- const separator = format === "yaml" ? ":" : " =";
5292
- return `${key}${separator} <<<EOF
5293
- ${value}
5294
- EOF`;
5295
- }
5296
- if (format === "yaml") {
5297
- return typeof value === "string" ? `${key}: ${value}` : `${key}: ${JSON.stringify(value)}`;
5067
+ formatBlockParameters(params, prefix) {
5068
+ const lines = [];
5069
+ const argPrefix = this.gadgetArgPrefix ?? GADGET_ARG_PREFIX;
5070
+ for (const [key, value] of Object.entries(params)) {
5071
+ const fullPath = prefix ? `${prefix}/${key}` : key;
5072
+ if (Array.isArray(value)) {
5073
+ value.forEach((item, index) => {
5074
+ const itemPath = `${fullPath}/${index}`;
5075
+ if (typeof item === "object" && item !== null) {
5076
+ lines.push(this.formatBlockParameters(item, itemPath));
5077
+ } else {
5078
+ lines.push(`${argPrefix}${itemPath}`);
5079
+ lines.push(String(item));
5080
+ }
5081
+ });
5082
+ } else if (typeof value === "object" && value !== null) {
5083
+ lines.push(this.formatBlockParameters(value, fullPath));
5084
+ } else {
5085
+ lines.push(`${argPrefix}${fullPath}`);
5086
+ lines.push(String(value));
5298
5087
  }
5299
- return `${key} = ${JSON.stringify(value)}`;
5300
- }).join("\n");
5088
+ }
5089
+ return lines.join("\n");
5301
5090
  }
5302
5091
  /**
5303
5092
  * Build and create the agent with the given user prompt.
@@ -5337,9 +5126,9 @@ EOF`;
5337
5126
  promptConfig: this.promptConfig,
5338
5127
  initialMessages: this.initialMessages,
5339
5128
  onHumanInputRequired: this.onHumanInputRequired,
5340
- parameterFormat: this.parameterFormat,
5341
5129
  gadgetStartPrefix: this.gadgetStartPrefix,
5342
5130
  gadgetEndPrefix: this.gadgetEndPrefix,
5131
+ gadgetArgPrefix: this.gadgetArgPrefix,
5343
5132
  textOnlyHandler: this.textOnlyHandler,
5344
5133
  textWithGadgetsHandler: this.textWithGadgetsHandler,
5345
5134
  stopOnGadgetError: this.stopOnGadgetError,
@@ -5439,9 +5228,9 @@ EOF`;
5439
5228
  promptConfig: this.promptConfig,
5440
5229
  initialMessages: this.initialMessages,
5441
5230
  onHumanInputRequired: this.onHumanInputRequired,
5442
- parameterFormat: this.parameterFormat,
5443
5231
  gadgetStartPrefix: this.gadgetStartPrefix,
5444
5232
  gadgetEndPrefix: this.gadgetEndPrefix,
5233
+ gadgetArgPrefix: this.gadgetArgPrefix,
5445
5234
  textOnlyHandler: this.textOnlyHandler,
5446
5235
  textWithGadgetsHandler: this.textWithGadgetsHandler,
5447
5236
  stopOnGadgetError: this.stopOnGadgetError,
@@ -5701,6 +5490,7 @@ var init_client = __esm({
5701
5490
  export {
5702
5491
  GADGET_START_PREFIX,
5703
5492
  GADGET_END_PREFIX,
5493
+ GADGET_ARG_PREFIX,
5704
5494
  init_constants,
5705
5495
  MODEL_ALIASES,
5706
5496
  resolveModel,
@@ -5767,4 +5557,4 @@ export {
5767
5557
  AgentBuilder,
5768
5558
  init_builder
5769
5559
  };
5770
- //# sourceMappingURL=chunk-62M4TDAK.js.map
5560
+ //# sourceMappingURL=chunk-T24KLXY4.js.map