llmist 0.7.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."
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.
556
529
  ${this.endPrefix}
557
530
  ${this.startPrefix}analyze
558
- type: economic_analysis
559
- matter: "Polish Economy"
560
- question: <<<EOF
531
+ ${this.argPrefix}type
532
+ economic_analysis
533
+ ${this.argPrefix}matter
534
+ Polish Economy
535
+ ${this.argPrefix}question
561
536
  Analyze the following:
562
537
  - Polish arms exports 2025
563
538
  - 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."}
568
- ${this.endPrefix}
569
- ${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
581
- Analyze the following:
582
- - Polish arms exports 2025
583
- - 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,125 +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 = `HEREDOC_${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 = ["EOF", "END", "DOC", "CONTENT", "TEXT", "HEREDOC", "DATA", "BLOCK"];
979
879
  BaseGadget = class {
980
880
  /**
981
881
  * The name of the gadget. Used for identification when LLM calls it.
@@ -1006,19 +906,19 @@ var init_gadget = __esm({
1006
906
  /**
1007
907
  * Auto-generated instruction text for the LLM.
1008
908
  * Combines name, description, and parameter schema into a formatted instruction.
1009
- * @deprecated Use getInstruction(format) instead for format-specific schemas
909
+ * @deprecated Use getInstruction() instead
1010
910
  */
1011
911
  get instruction() {
1012
- return this.getInstruction("yaml");
912
+ return this.getInstruction();
1013
913
  }
1014
914
  /**
1015
- * Generate instruction text for the LLM with format-specific schema.
915
+ * Generate instruction text for the LLM.
1016
916
  * Combines name, description, and parameter schema into a formatted instruction.
1017
917
  *
1018
- * @param format - Format for the schema representation ('json' | 'yaml' | 'toml' | 'auto')
918
+ * @param argPrefix - Optional custom argument prefix for block format examples
1019
919
  * @returns Formatted instruction string
1020
920
  */
1021
- getInstruction(format = "json") {
921
+ getInstruction(argPrefix) {
1022
922
  const parts = [];
1023
923
  parts.push(this.description);
1024
924
  if (this.parameterSchema) {
@@ -1027,20 +927,12 @@ var init_gadget = __esm({
1027
927
  const jsonSchema = schemaToJSONSchema(this.parameterSchema, {
1028
928
  target: "draft-7"
1029
929
  });
1030
- if (format === "json" || format === "auto") {
1031
- parts.push("\n\nInput Schema (JSON):");
1032
- parts.push(JSON.stringify(jsonSchema, null, 2));
1033
- } else if (format === "toml") {
1034
- parts.push("\n\nInput Schema (TOML):");
1035
- parts.push(JSON.stringify(jsonSchema, null, 2));
1036
- } else {
1037
- const yamlSchema = yaml.dump(jsonSchema).trimEnd();
1038
- parts.push("\n\nInput Schema (YAML):");
1039
- parts.push(yamlSchema);
1040
- }
930
+ parts.push("\n\nParameters:");
931
+ parts.push(formatSchemaAsPlainText(jsonSchema));
1041
932
  }
1042
933
  if (this.examples && this.examples.length > 0) {
1043
934
  parts.push("\n\nExamples:");
935
+ const effectiveArgPrefix = argPrefix ?? GADGET_ARG_PREFIX;
1044
936
  this.examples.forEach((example, index) => {
1045
937
  if (index > 0) {
1046
938
  parts.push("");
@@ -1049,13 +941,7 @@ var init_gadget = __esm({
1049
941
  parts.push(`# ${example.comment}`);
1050
942
  }
1051
943
  parts.push("Input:");
1052
- if (format === "json" || format === "auto") {
1053
- parts.push(JSON.stringify(example.params, null, 2));
1054
- } else if (format === "toml") {
1055
- parts.push(formatParamsAsToml(example.params));
1056
- } else {
1057
- parts.push(formatParamsAsYaml(example.params));
1058
- }
944
+ parts.push(formatParamsAsBlock(example.params, "", effectiveArgPrefix));
1059
945
  if (example.output !== void 0) {
1060
946
  parts.push("Output:");
1061
947
  parts.push(example.output);
@@ -1320,14 +1206,12 @@ var init_conversation_manager = __esm({
1320
1206
  baseMessages;
1321
1207
  initialMessages;
1322
1208
  historyBuilder;
1323
- parameterFormat;
1324
1209
  constructor(baseMessages, initialMessages, options = {}) {
1325
1210
  this.baseMessages = baseMessages;
1326
1211
  this.initialMessages = initialMessages;
1327
- this.parameterFormat = options.parameterFormat ?? "json";
1328
1212
  this.historyBuilder = new LLMMessageBuilder();
1329
1213
  if (options.startPrefix && options.endPrefix) {
1330
- this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix);
1214
+ this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix, options.argPrefix);
1331
1215
  }
1332
1216
  }
1333
1217
  addUserMessage(content) {
@@ -1337,7 +1221,7 @@ var init_conversation_manager = __esm({
1337
1221
  this.historyBuilder.addAssistant(content);
1338
1222
  }
1339
1223
  addGadgetCall(gadgetName, parameters, result) {
1340
- this.historyBuilder.addGadgetCall(gadgetName, parameters, result, this.parameterFormat);
1224
+ this.historyBuilder.addGadgetCall(gadgetName, parameters, result);
1341
1225
  }
1342
1226
  getMessages() {
1343
1227
  return [...this.baseMessages, ...this.initialMessages, ...this.historyBuilder.build()];
@@ -1360,7 +1244,7 @@ async function runWithHandlers(agentGenerator, handlers) {
1360
1244
  await handlers.onGadgetCall({
1361
1245
  gadgetName: event.call.gadgetName,
1362
1246
  parameters: event.call.parameters,
1363
- parametersYaml: event.call.parametersYaml
1247
+ parametersRaw: event.call.parametersRaw
1364
1248
  });
1365
1249
  }
1366
1250
  break;
@@ -1513,7 +1397,7 @@ var init_executor = __esm({
1513
1397
  this.logger.error("Gadget parameter parse error", {
1514
1398
  gadgetName: call.gadgetName,
1515
1399
  parseError: call.parseError,
1516
- rawParameters: call.parametersYaml
1400
+ rawParameters: call.parametersRaw
1517
1401
  });
1518
1402
  return {
1519
1403
  gadgetName: call.gadgetName,
@@ -1675,170 +1559,107 @@ var init_executor = __esm({
1675
1559
  }
1676
1560
  });
1677
1561
 
1678
- // src/gadgets/parser.ts
1679
- import * as yaml2 from "js-yaml";
1680
- import { load as parseToml } from "js-toml";
1681
- function preprocessYaml(yamlStr) {
1682
- const lines = yamlStr.split("\n");
1683
- const result = [];
1684
- let i = 0;
1685
- while (i < lines.length) {
1686
- const line = lines[i];
1687
- const heredocMatch = line.match(/^(\s*)([\w-]+):\s*<<<([A-Za-z_][A-Za-z0-9_]*)\s*$/);
1688
- if (heredocMatch) {
1689
- const [, indent, key, delimiter] = heredocMatch;
1690
- const bodyLines = [];
1691
- i++;
1692
- const closingRegex = new RegExp(`^${delimiter}\\s*$`);
1693
- while (i < lines.length && !closingRegex.test(lines[i])) {
1694
- bodyLines.push(lines[i]);
1695
- i++;
1696
- }
1697
- if (i < lines.length) {
1698
- i++;
1699
- }
1700
- result.push(`${indent}${key}: |`);
1701
- for (const bodyLine of bodyLines) {
1702
- 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, "");
1703
1579
  }
1704
1580
  continue;
1705
1581
  }
1706
- const match = line.match(/^(\s*)([\w-]+):\s+(.+)$/);
1707
- if (match) {
1708
- const [, indent, key, value] = match;
1709
- if (value === "|" || value === ">" || value === "|-" || value === ">-") {
1710
- result.push(line);
1711
- i++;
1712
- const keyIndentLen2 = indent.length;
1713
- const blockLines = [];
1714
- let minContentIndent = Infinity;
1715
- while (i < lines.length) {
1716
- const blockLine = lines[i];
1717
- const blockIndentMatch = blockLine.match(/^(\s*)/);
1718
- const blockIndentLen = blockIndentMatch ? blockIndentMatch[1].length : 0;
1719
- if (blockLine.trim() === "") {
1720
- blockLines.push({ content: "", originalIndent: 0 });
1721
- i++;
1722
- continue;
1723
- }
1724
- if (blockIndentLen > keyIndentLen2) {
1725
- const content = blockLine.substring(blockIndentLen);
1726
- blockLines.push({ content, originalIndent: blockIndentLen });
1727
- if (content.trim().length > 0) {
1728
- minContentIndent = Math.min(minContentIndent, blockIndentLen);
1729
- }
1730
- i++;
1731
- } else {
1732
- break;
1733
- }
1734
- }
1735
- const targetIndent = keyIndentLen2 + 2;
1736
- for (const blockLine of blockLines) {
1737
- if (blockLine.content === "") {
1738
- result.push("");
1739
- } else {
1740
- result.push(" ".repeat(targetIndent) + blockLine.content);
1741
- }
1742
- }
1743
- continue;
1744
- }
1745
- if (value.startsWith('"') || value.startsWith("'") || value === "true" || value === "false" || /^-?\d+(\.\d+)?$/.test(value)) {
1746
- result.push(line);
1747
- i++;
1748
- continue;
1749
- }
1750
- const keyIndentLen = indent.length;
1751
- const continuationLines = [];
1752
- let j = i + 1;
1753
- while (j < lines.length) {
1754
- const nextLine = lines[j];
1755
- if (nextLine.trim() === "") {
1756
- continuationLines.push(nextLine);
1757
- j++;
1758
- continue;
1759
- }
1760
- const nextIndentMatch = nextLine.match(/^(\s*)/);
1761
- const nextIndentLen = nextIndentMatch ? nextIndentMatch[1].length : 0;
1762
- if (nextIndentLen > keyIndentLen) {
1763
- continuationLines.push(nextLine);
1764
- j++;
1765
- } else {
1766
- break;
1767
- }
1768
- }
1769
- if (continuationLines.length > 0 && continuationLines.some((l) => l.trim().length > 0)) {
1770
- result.push(`${indent}${key}: |`);
1771
- result.push(`${indent} ${value}`);
1772
- for (const contLine of continuationLines) {
1773
- if (contLine.trim() === "") {
1774
- result.push("");
1775
- } else {
1776
- const contIndentMatch = contLine.match(/^(\s*)/);
1777
- const contIndent = contIndentMatch ? contIndentMatch[1] : "";
1778
- const contContent = contLine.substring(contIndent.length);
1779
- result.push(`${indent} ${contContent}`);
1780
- }
1781
- }
1782
- i = j;
1783
- continue;
1784
- }
1785
- if (value.includes(": ") || value.endsWith(":")) {
1786
- const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1787
- result.push(`${indent}${key}: "${escaped}"`);
1788
- i++;
1789
- continue;
1790
- }
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;
1791
1589
  }
1792
- result.push(line);
1793
- i++;
1590
+ if (seenPointers.has(pointer)) {
1591
+ throw new Error(`Duplicate pointer: ${pointer}`);
1592
+ }
1593
+ seenPointers.add(pointer);
1594
+ setByPointer(result, pointer, value);
1794
1595
  }
1795
- return result.join("\n");
1596
+ return result;
1796
1597
  }
1797
- function unescapeHeredocContent(content) {
1798
- 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;
1799
1612
  }
1800
- function preprocessTomlHeredoc(tomlStr) {
1801
- const lines = tomlStr.split("\n");
1802
- const result = [];
1803
- let i = 0;
1804
- const heredocStartRegex = /^(\s*)([\w-]+)\s*=\s*<<<([A-Za-z_][A-Za-z0-9_]*)\s*$/;
1805
- while (i < lines.length) {
1806
- const line = lines[i];
1807
- const match = line.match(heredocStartRegex);
1808
- if (match) {
1809
- const [, indent, key, delimiter] = match;
1810
- const bodyLines = [];
1811
- i++;
1812
- const closingRegex = new RegExp(`^${delimiter}\\s*$`);
1813
- let foundClosing = false;
1814
- while (i < lines.length) {
1815
- const bodyLine = lines[i];
1816
- if (closingRegex.test(bodyLine)) {
1817
- foundClosing = true;
1818
- i++;
1819
- break;
1820
- }
1821
- bodyLines.push(bodyLine);
1822
- i++;
1823
- }
1824
- if (bodyLines.length === 0) {
1825
- result.push(`${indent}${key} = ''''''`);
1826
- } else {
1827
- result.push(`${indent}${key} = '''`);
1828
- for (let j = 0; j < bodyLines.length - 1; j++) {
1829
- result.push(unescapeHeredocContent(bodyLines[j]));
1830
- }
1831
- result.push(`${unescapeHeredocContent(bodyLines[bodyLines.length - 1])}'''`);
1832
- }
1833
- 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 ? [] : {};
1834
1636
  }
1835
- 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}`);
1836
1646
  }
1837
- result.push(line);
1838
- i++;
1647
+ if (index > current.length) {
1648
+ throw new Error(`Array index gap: expected ${current.length}, got ${index}`);
1649
+ }
1650
+ current[index] = coercedValue;
1651
+ } else {
1652
+ current[lastSegment] = coercedValue;
1839
1653
  }
1840
- return result.join("\n");
1841
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
1842
1663
  function stripMarkdownFences(content) {
1843
1664
  let cleaned = content.trim();
1844
1665
  const openingFence = /^```(?:toml|yaml|json)?\s*\n/i;
@@ -1852,17 +1673,18 @@ var init_parser = __esm({
1852
1673
  "src/gadgets/parser.ts"() {
1853
1674
  "use strict";
1854
1675
  init_constants();
1676
+ init_block_params();
1855
1677
  globalInvocationCounter = 0;
1856
1678
  StreamParser = class {
1857
1679
  buffer = "";
1858
1680
  lastReportedTextLength = 0;
1859
1681
  startPrefix;
1860
1682
  endPrefix;
1861
- parameterFormat;
1683
+ argPrefix;
1862
1684
  constructor(options = {}) {
1863
1685
  this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
1864
1686
  this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
1865
- this.parameterFormat = options.parameterFormat ?? "json";
1687
+ this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
1866
1688
  }
1867
1689
  takeTextUntil(index) {
1868
1690
  if (index <= this.lastReportedTextLength) {
@@ -1897,43 +1719,14 @@ var init_parser = __esm({
1897
1719
  return `${firstLine.slice(0, maxLen)}... (${message.length} chars total)`;
1898
1720
  }
1899
1721
  /**
1900
- * Parse parameter string according to configured format
1722
+ * Parse parameter string using block format
1901
1723
  */
1902
1724
  parseParameters(raw) {
1903
1725
  const cleaned = stripMarkdownFences(raw);
1904
- if (this.parameterFormat === "json") {
1905
- try {
1906
- return { parameters: JSON.parse(cleaned) };
1907
- } catch (error) {
1908
- return { parseError: this.truncateParseError(error, "JSON") };
1909
- }
1910
- }
1911
- if (this.parameterFormat === "yaml") {
1912
- try {
1913
- return { parameters: yaml2.load(preprocessYaml(cleaned)) };
1914
- } catch (error) {
1915
- return { parseError: this.truncateParseError(error, "YAML") };
1916
- }
1917
- }
1918
- if (this.parameterFormat === "toml") {
1919
- try {
1920
- return { parameters: parseToml(preprocessTomlHeredoc(cleaned)) };
1921
- } catch (error) {
1922
- return { parseError: this.truncateParseError(error, "TOML") };
1923
- }
1924
- }
1925
1726
  try {
1926
- return { parameters: JSON.parse(cleaned) };
1927
- } catch {
1928
- try {
1929
- return { parameters: parseToml(preprocessTomlHeredoc(cleaned)) };
1930
- } catch {
1931
- try {
1932
- return { parameters: yaml2.load(preprocessYaml(cleaned)) };
1933
- } catch (error) {
1934
- return { parseError: this.truncateParseError(error, "auto") };
1935
- }
1936
- }
1727
+ return { parameters: parseBlockParams(cleaned, { argPrefix: this.argPrefix }) };
1728
+ } catch (error) {
1729
+ return { parseError: this.truncateParseError(error, "block") };
1937
1730
  }
1938
1731
  }
1939
1732
  // Feed a chunk of text and get parsed events
@@ -1992,8 +1785,7 @@ var init_parser = __esm({
1992
1785
  call: {
1993
1786
  gadgetName: actualGadgetName,
1994
1787
  invocationId,
1995
- parametersYaml: parametersRaw,
1996
- // Keep property name for backward compatibility
1788
+ parametersRaw,
1997
1789
  parameters,
1998
1790
  parseError
1999
1791
  }
@@ -2027,7 +1819,7 @@ var init_parser = __esm({
2027
1819
  call: {
2028
1820
  gadgetName: actualGadgetName,
2029
1821
  invocationId,
2030
- parametersYaml: parametersRaw,
1822
+ parametersRaw,
2031
1823
  parameters,
2032
1824
  parseError
2033
1825
  }
@@ -2232,9 +2024,9 @@ var init_stream_processor = __esm({
2232
2024
  this.stopOnGadgetError = options.stopOnGadgetError ?? true;
2233
2025
  this.shouldContinueAfterError = options.shouldContinueAfterError;
2234
2026
  this.parser = new StreamParser({
2235
- parameterFormat: options.parameterFormat,
2236
2027
  startPrefix: options.gadgetStartPrefix,
2237
- endPrefix: options.gadgetEndPrefix
2028
+ endPrefix: options.gadgetEndPrefix,
2029
+ argPrefix: options.gadgetArgPrefix
2238
2030
  });
2239
2031
  this.executor = new GadgetExecutor(
2240
2032
  options.registry,
@@ -2388,7 +2180,7 @@ var init_stream_processor = __esm({
2388
2180
  this.logger.warn("Gadget has parse error", {
2389
2181
  gadgetName: call.gadgetName,
2390
2182
  error: call.parseError,
2391
- rawParameters: call.parametersYaml
2183
+ rawParameters: call.parametersRaw
2392
2184
  });
2393
2185
  const shouldContinue = await this.checkContinueAfterError(
2394
2186
  call.parseError,
@@ -2614,7 +2406,8 @@ var init_anthropic_models = __esm({
2614
2406
  pricing: {
2615
2407
  input: 3,
2616
2408
  output: 15,
2617
- cachedInput: 0.3
2409
+ cachedInput: 0.3,
2410
+ cacheWriteInput: 3.75
2618
2411
  },
2619
2412
  knowledgeCutoff: "2025-01",
2620
2413
  features: {
@@ -2638,7 +2431,8 @@ var init_anthropic_models = __esm({
2638
2431
  pricing: {
2639
2432
  input: 1,
2640
2433
  output: 5,
2641
- cachedInput: 0.1
2434
+ cachedInput: 0.1,
2435
+ cacheWriteInput: 1.25
2642
2436
  },
2643
2437
  knowledgeCutoff: "2025-02",
2644
2438
  features: {
@@ -2662,7 +2456,8 @@ var init_anthropic_models = __esm({
2662
2456
  pricing: {
2663
2457
  input: 3,
2664
2458
  output: 15,
2665
- cachedInput: 0.3
2459
+ cachedInput: 0.3,
2460
+ cacheWriteInput: 3.75
2666
2461
  },
2667
2462
  knowledgeCutoff: "2025-03",
2668
2463
  features: {
@@ -2686,7 +2481,8 @@ var init_anthropic_models = __esm({
2686
2481
  pricing: {
2687
2482
  input: 3,
2688
2483
  output: 15,
2689
- cachedInput: 0.3
2484
+ cachedInput: 0.3,
2485
+ cacheWriteInput: 3.75
2690
2486
  },
2691
2487
  knowledgeCutoff: "2024-11",
2692
2488
  features: {
@@ -2710,7 +2506,8 @@ var init_anthropic_models = __esm({
2710
2506
  pricing: {
2711
2507
  input: 15,
2712
2508
  output: 75,
2713
- cachedInput: 1.5
2509
+ cachedInput: 1.5,
2510
+ cacheWriteInput: 18.75
2714
2511
  },
2715
2512
  knowledgeCutoff: "2025-01",
2716
2513
  features: {
@@ -2734,7 +2531,8 @@ var init_anthropic_models = __esm({
2734
2531
  pricing: {
2735
2532
  input: 15,
2736
2533
  output: 75,
2737
- cachedInput: 1.5
2534
+ cachedInput: 1.5,
2535
+ cacheWriteInput: 18.75
2738
2536
  },
2739
2537
  knowledgeCutoff: "2025-03",
2740
2538
  features: {
@@ -2757,7 +2555,8 @@ var init_anthropic_models = __esm({
2757
2555
  pricing: {
2758
2556
  input: 0.8,
2759
2557
  output: 4,
2760
- cachedInput: 0.08
2558
+ cachedInput: 0.08,
2559
+ cacheWriteInput: 1
2761
2560
  },
2762
2561
  knowledgeCutoff: "2024-07",
2763
2562
  features: {
@@ -2780,7 +2579,8 @@ var init_anthropic_models = __esm({
2780
2579
  pricing: {
2781
2580
  input: 0.25,
2782
2581
  output: 1.25,
2783
- cachedInput: 0.025
2582
+ cachedInput: 0.025,
2583
+ cacheWriteInput: 0.3125
2784
2584
  },
2785
2585
  knowledgeCutoff: "2023-08",
2786
2586
  features: {
@@ -2804,7 +2604,8 @@ var init_anthropic_models = __esm({
2804
2604
  pricing: {
2805
2605
  input: 1,
2806
2606
  output: 5,
2807
- cachedInput: 0.1
2607
+ cachedInput: 0.1,
2608
+ cacheWriteInput: 1.25
2808
2609
  },
2809
2610
  knowledgeCutoff: "2025-02",
2810
2611
  features: {
@@ -2828,7 +2629,8 @@ var init_anthropic_models = __esm({
2828
2629
  pricing: {
2829
2630
  input: 3,
2830
2631
  output: 15,
2831
- cachedInput: 0.3
2632
+ cachedInput: 0.3,
2633
+ cacheWriteInput: 3.75
2832
2634
  },
2833
2635
  knowledgeCutoff: "2025-01",
2834
2636
  features: {
@@ -2852,7 +2654,8 @@ var init_anthropic_models = __esm({
2852
2654
  pricing: {
2853
2655
  input: 5,
2854
2656
  output: 25,
2855
- cachedInput: 0.5
2657
+ cachedInput: 0.5,
2658
+ cacheWriteInput: 6.25
2856
2659
  },
2857
2660
  knowledgeCutoff: "2025-03",
2858
2661
  features: {
@@ -2967,15 +2770,27 @@ var init_anthropic = __esm({
2967
2770
  }
2968
2771
  buildRequestPayload(options, descriptor, spec, messages) {
2969
2772
  const systemMessages = messages.filter((message) => message.role === "system");
2970
- const system = systemMessages.length > 0 ? systemMessages.map((m) => m.content).join("\n\n") : void 0;
2971
- const conversation = messages.filter(
2773
+ const system = systemMessages.length > 0 ? systemMessages.map((m, index) => ({
2774
+ type: "text",
2775
+ text: m.content,
2776
+ // Add cache_control to the LAST system message block
2777
+ ...index === systemMessages.length - 1 ? { cache_control: { type: "ephemeral" } } : {}
2778
+ })) : void 0;
2779
+ const nonSystemMessages = messages.filter(
2972
2780
  (message) => message.role !== "system"
2973
- ).map((message) => ({
2781
+ );
2782
+ const lastUserIndex = nonSystemMessages.reduce(
2783
+ (lastIdx, msg, idx) => msg.role === "user" ? idx : lastIdx,
2784
+ -1
2785
+ );
2786
+ const conversation = nonSystemMessages.map((message, index) => ({
2974
2787
  role: message.role,
2975
2788
  content: [
2976
2789
  {
2977
2790
  type: "text",
2978
- text: message.content
2791
+ text: message.content,
2792
+ // Add cache_control to the LAST user message
2793
+ ...message.role === "user" && index === lastUserIndex ? { cache_control: { type: "ephemeral" } } : {}
2979
2794
  }
2980
2795
  ]
2981
2796
  }));
@@ -3001,15 +2816,22 @@ var init_anthropic = __esm({
3001
2816
  async *wrapStream(iterable) {
3002
2817
  const stream2 = iterable;
3003
2818
  let inputTokens = 0;
2819
+ let cachedInputTokens = 0;
2820
+ let cacheCreationInputTokens = 0;
3004
2821
  for await (const event of stream2) {
3005
2822
  if (event.type === "message_start") {
3006
- inputTokens = event.message.usage.input_tokens;
2823
+ const usage = event.message.usage;
2824
+ cachedInputTokens = usage.cache_read_input_tokens ?? 0;
2825
+ cacheCreationInputTokens = usage.cache_creation_input_tokens ?? 0;
2826
+ inputTokens = usage.input_tokens + cachedInputTokens + cacheCreationInputTokens;
3007
2827
  yield {
3008
2828
  text: "",
3009
2829
  usage: {
3010
2830
  inputTokens,
3011
2831
  outputTokens: 0,
3012
- totalTokens: inputTokens
2832
+ totalTokens: inputTokens,
2833
+ cachedInputTokens,
2834
+ cacheCreationInputTokens
3013
2835
  },
3014
2836
  rawEvent: event
3015
2837
  };
@@ -3023,7 +2845,9 @@ var init_anthropic = __esm({
3023
2845
  const usage = event.usage ? {
3024
2846
  inputTokens,
3025
2847
  outputTokens: event.usage.output_tokens,
3026
- totalTokens: inputTokens + event.usage.output_tokens
2848
+ totalTokens: inputTokens + event.usage.output_tokens,
2849
+ cachedInputTokens,
2850
+ cacheCreationInputTokens
3027
2851
  } : void 0;
3028
2852
  if (event.delta.stop_reason || usage) {
3029
2853
  yield {
@@ -3104,6 +2928,7 @@ var init_gemini_models = __esm({
3104
2928
  "src/providers/gemini-models.ts"() {
3105
2929
  "use strict";
3106
2930
  GEMINI_MODELS = [
2931
+ // Gemini 3 Pro (Preview)
3107
2932
  {
3108
2933
  provider: "gemini",
3109
2934
  modelId: "gemini-3-pro-preview",
@@ -3112,8 +2937,11 @@ var init_gemini_models = __esm({
3112
2937
  maxOutputTokens: 65536,
3113
2938
  pricing: {
3114
2939
  input: 2,
2940
+ // $2.00 for prompts <= 200k, $4.00 for > 200k (using lower tier)
3115
2941
  output: 12,
2942
+ // $12.00 for prompts <= 200k, $18.00 for > 200k
3116
2943
  cachedInput: 0.2
2944
+ // $0.20 for prompts <= 200k
3117
2945
  },
3118
2946
  knowledgeCutoff: "2025-01",
3119
2947
  features: {
@@ -3126,9 +2954,10 @@ var init_gemini_models = __esm({
3126
2954
  metadata: {
3127
2955
  family: "Gemini 3",
3128
2956
  releaseDate: "2025-11-18",
3129
- notes: "Most advanced model. 1501 Elo LMArena, 91.9% GPQA Diamond, 76.2% SWE-bench. Deep Think mode available."
2957
+ notes: "Best model for multimodal understanding, agentic and vibe-coding. Deep Think mode available."
3130
2958
  }
3131
2959
  },
2960
+ // Gemini 2.5 Pro
3132
2961
  {
3133
2962
  provider: "gemini",
3134
2963
  modelId: "gemini-2.5-pro",
@@ -3137,8 +2966,11 @@ var init_gemini_models = __esm({
3137
2966
  maxOutputTokens: 65536,
3138
2967
  pricing: {
3139
2968
  input: 1.25,
2969
+ // $1.25 for prompts <= 200k, $2.50 for > 200k
3140
2970
  output: 10,
2971
+ // $10.00 for prompts <= 200k, $15.00 for > 200k
3141
2972
  cachedInput: 0.125
2973
+ // $0.125 for prompts <= 200k
3142
2974
  },
3143
2975
  knowledgeCutoff: "2025-01",
3144
2976
  features: {
@@ -3151,9 +2983,10 @@ var init_gemini_models = __esm({
3151
2983
  metadata: {
3152
2984
  family: "Gemini 2.5",
3153
2985
  releaseDate: "2025-06",
3154
- notes: "Balanced multimodal model with 1M context. Best for complex agents and reasoning."
2986
+ notes: "State-of-the-art multipurpose model. Excels at coding and complex reasoning."
3155
2987
  }
3156
2988
  },
2989
+ // Gemini 2.5 Flash
3157
2990
  {
3158
2991
  provider: "gemini",
3159
2992
  modelId: "gemini-2.5-flash",
@@ -3162,8 +2995,10 @@ var init_gemini_models = __esm({
3162
2995
  maxOutputTokens: 65536,
3163
2996
  pricing: {
3164
2997
  input: 0.3,
2998
+ // $0.30 for text/image/video, $1.00 for audio
3165
2999
  output: 2.5,
3166
3000
  cachedInput: 0.03
3001
+ // $0.03 for text/image/video
3167
3002
  },
3168
3003
  knowledgeCutoff: "2025-01",
3169
3004
  features: {
@@ -3176,9 +3011,10 @@ var init_gemini_models = __esm({
3176
3011
  metadata: {
3177
3012
  family: "Gemini 2.5",
3178
3013
  releaseDate: "2025-06",
3179
- notes: "Best price-performance ratio with thinking enabled by default"
3014
+ notes: "First hybrid reasoning model with 1M context and thinking budgets."
3180
3015
  }
3181
3016
  },
3017
+ // Gemini 2.5 Flash-Lite
3182
3018
  {
3183
3019
  provider: "gemini",
3184
3020
  modelId: "gemini-2.5-flash-lite",
@@ -3187,8 +3023,10 @@ var init_gemini_models = __esm({
3187
3023
  maxOutputTokens: 65536,
3188
3024
  pricing: {
3189
3025
  input: 0.1,
3026
+ // $0.10 for text/image/video, $0.30 for audio
3190
3027
  output: 0.4,
3191
3028
  cachedInput: 0.01
3029
+ // $0.01 for text/image/video
3192
3030
  },
3193
3031
  knowledgeCutoff: "2025-01",
3194
3032
  features: {
@@ -3200,9 +3038,10 @@ var init_gemini_models = __esm({
3200
3038
  metadata: {
3201
3039
  family: "Gemini 2.5",
3202
3040
  releaseDate: "2025-06",
3203
- notes: "Fastest and most cost-efficient model for high-volume, low-latency tasks"
3041
+ notes: "Smallest and most cost effective model, built for at scale usage."
3204
3042
  }
3205
3043
  },
3044
+ // Gemini 2.0 Flash
3206
3045
  {
3207
3046
  provider: "gemini",
3208
3047
  modelId: "gemini-2.0-flash",
@@ -3211,8 +3050,10 @@ var init_gemini_models = __esm({
3211
3050
  maxOutputTokens: 8192,
3212
3051
  pricing: {
3213
3052
  input: 0.1,
3053
+ // $0.10 for text/image/video, $0.70 for audio
3214
3054
  output: 0.4,
3215
- cachedInput: 0.01
3055
+ cachedInput: 0.025
3056
+ // $0.025 for text/image/video
3216
3057
  },
3217
3058
  knowledgeCutoff: "2024-08",
3218
3059
  features: {
@@ -3223,9 +3064,10 @@ var init_gemini_models = __esm({
3223
3064
  },
3224
3065
  metadata: {
3225
3066
  family: "Gemini 2.0",
3226
- notes: "Previous generation with 1M context and multimodal capabilities"
3067
+ notes: "Balanced multimodal model with 1M context, built for the era of Agents."
3227
3068
  }
3228
3069
  },
3070
+ // Gemini 2.0 Flash-Lite
3229
3071
  {
3230
3072
  provider: "gemini",
3231
3073
  modelId: "gemini-2.0-flash-lite",
@@ -3234,8 +3076,8 @@ var init_gemini_models = __esm({
3234
3076
  maxOutputTokens: 8192,
3235
3077
  pricing: {
3236
3078
  input: 0.075,
3237
- output: 0.3,
3238
- cachedInput: 75e-4
3079
+ output: 0.3
3080
+ // No context caching available for 2.0-flash-lite
3239
3081
  },
3240
3082
  knowledgeCutoff: "2024-08",
3241
3083
  features: {
@@ -3246,7 +3088,7 @@ var init_gemini_models = __esm({
3246
3088
  },
3247
3089
  metadata: {
3248
3090
  family: "Gemini 2.0",
3249
- notes: "Lightweight previous generation model for cost-sensitive applications"
3091
+ notes: "Smallest and most cost effective 2.0 model for at scale usage."
3250
3092
  }
3251
3093
  }
3252
3094
  ];
@@ -3416,7 +3258,9 @@ var init_gemini = __esm({
3416
3258
  return {
3417
3259
  inputTokens: usageMetadata.promptTokenCount ?? 0,
3418
3260
  outputTokens: usageMetadata.candidatesTokenCount ?? 0,
3419
- totalTokens: usageMetadata.totalTokenCount ?? 0
3261
+ totalTokens: usageMetadata.totalTokenCount ?? 0,
3262
+ // Gemini returns cached token count in cachedContentTokenCount
3263
+ cachedInputTokens: usageMetadata.cachedContentTokenCount ?? 0
3420
3264
  };
3421
3265
  }
3422
3266
  /**
@@ -3472,10 +3316,11 @@ var init_openai_models = __esm({
3472
3316
  "src/providers/openai-models.ts"() {
3473
3317
  "use strict";
3474
3318
  OPENAI_MODELS = [
3319
+ // GPT-5 Family
3475
3320
  {
3476
3321
  provider: "openai",
3477
3322
  modelId: "gpt-5.1",
3478
- displayName: "GPT-5.1 Instant",
3323
+ displayName: "GPT-5.1",
3479
3324
  contextWindow: 128e3,
3480
3325
  maxOutputTokens: 32768,
3481
3326
  pricing: {
@@ -3495,34 +3340,7 @@ var init_openai_models = __esm({
3495
3340
  metadata: {
3496
3341
  family: "GPT-5",
3497
3342
  releaseDate: "2025-11-12",
3498
- notes: "Warmer, more intelligent, better instruction following. 2-3x faster than GPT-5.",
3499
- supportsTemperature: false
3500
- }
3501
- },
3502
- {
3503
- provider: "openai",
3504
- modelId: "gpt-5.1-thinking",
3505
- displayName: "GPT-5.1 Thinking",
3506
- contextWindow: 196e3,
3507
- maxOutputTokens: 32768,
3508
- pricing: {
3509
- input: 1.25,
3510
- output: 10,
3511
- cachedInput: 0.125
3512
- },
3513
- knowledgeCutoff: "2024-09-30",
3514
- features: {
3515
- streaming: true,
3516
- functionCalling: true,
3517
- vision: true,
3518
- reasoning: true,
3519
- structuredOutputs: true,
3520
- fineTuning: true
3521
- },
3522
- metadata: {
3523
- family: "GPT-5",
3524
- releaseDate: "2025-11-12",
3525
- notes: "Advanced reasoning with thinking levels: Light, Standard, Extended, Heavy. Best for complex tasks.",
3343
+ notes: "Latest GPT-5 with improved instruction following. 2-3x faster than GPT-5.",
3526
3344
  supportsTemperature: false
3527
3345
  }
3528
3346
  },
@@ -3602,6 +3420,255 @@ var init_openai_models = __esm({
3602
3420
  notes: "Fastest, most cost-efficient version for well-defined tasks",
3603
3421
  supportsTemperature: false
3604
3422
  }
3423
+ },
3424
+ {
3425
+ provider: "openai",
3426
+ modelId: "gpt-5-pro",
3427
+ displayName: "GPT-5 Pro",
3428
+ contextWindow: 272e3,
3429
+ maxOutputTokens: 128e3,
3430
+ pricing: {
3431
+ input: 15,
3432
+ output: 120
3433
+ // No cached input pricing for gpt-5-pro
3434
+ },
3435
+ knowledgeCutoff: "2024-09-30",
3436
+ features: {
3437
+ streaming: true,
3438
+ functionCalling: true,
3439
+ vision: true,
3440
+ reasoning: true,
3441
+ structuredOutputs: true
3442
+ },
3443
+ metadata: {
3444
+ family: "GPT-5",
3445
+ notes: "Premium tier with enhanced capabilities. Does not support prompt caching.",
3446
+ supportsTemperature: false
3447
+ }
3448
+ },
3449
+ // GPT-4.1 Family
3450
+ {
3451
+ provider: "openai",
3452
+ modelId: "gpt-4.1",
3453
+ displayName: "GPT-4.1",
3454
+ contextWindow: 128e3,
3455
+ maxOutputTokens: 32768,
3456
+ pricing: {
3457
+ input: 2,
3458
+ output: 8,
3459
+ cachedInput: 0.5
3460
+ },
3461
+ knowledgeCutoff: "2024-04-01",
3462
+ features: {
3463
+ streaming: true,
3464
+ functionCalling: true,
3465
+ vision: true,
3466
+ structuredOutputs: true,
3467
+ fineTuning: true
3468
+ },
3469
+ metadata: {
3470
+ family: "GPT-4.1",
3471
+ notes: "Improved GPT-4 with better instruction following"
3472
+ }
3473
+ },
3474
+ {
3475
+ provider: "openai",
3476
+ modelId: "gpt-4.1-mini",
3477
+ displayName: "GPT-4.1 Mini",
3478
+ contextWindow: 128e3,
3479
+ maxOutputTokens: 32768,
3480
+ pricing: {
3481
+ input: 0.4,
3482
+ output: 1.6,
3483
+ cachedInput: 0.1
3484
+ },
3485
+ knowledgeCutoff: "2024-04-01",
3486
+ features: {
3487
+ streaming: true,
3488
+ functionCalling: true,
3489
+ vision: true,
3490
+ structuredOutputs: true,
3491
+ fineTuning: true
3492
+ },
3493
+ metadata: {
3494
+ family: "GPT-4.1",
3495
+ notes: "Cost-efficient GPT-4.1 variant"
3496
+ }
3497
+ },
3498
+ {
3499
+ provider: "openai",
3500
+ modelId: "gpt-4.1-nano",
3501
+ displayName: "GPT-4.1 Nano",
3502
+ contextWindow: 128e3,
3503
+ maxOutputTokens: 32768,
3504
+ pricing: {
3505
+ input: 0.1,
3506
+ output: 0.4,
3507
+ cachedInput: 0.025
3508
+ },
3509
+ knowledgeCutoff: "2024-04-01",
3510
+ features: {
3511
+ streaming: true,
3512
+ functionCalling: true,
3513
+ vision: true,
3514
+ structuredOutputs: true,
3515
+ fineTuning: true
3516
+ },
3517
+ metadata: {
3518
+ family: "GPT-4.1",
3519
+ notes: "Fastest GPT-4.1 variant for simple tasks"
3520
+ }
3521
+ },
3522
+ // GPT-4o Family
3523
+ {
3524
+ provider: "openai",
3525
+ modelId: "gpt-4o",
3526
+ displayName: "GPT-4o",
3527
+ contextWindow: 128e3,
3528
+ maxOutputTokens: 16384,
3529
+ pricing: {
3530
+ input: 2.5,
3531
+ output: 10,
3532
+ cachedInput: 1.25
3533
+ },
3534
+ knowledgeCutoff: "2024-04-01",
3535
+ features: {
3536
+ streaming: true,
3537
+ functionCalling: true,
3538
+ vision: true,
3539
+ structuredOutputs: true,
3540
+ fineTuning: true
3541
+ },
3542
+ metadata: {
3543
+ family: "GPT-4o",
3544
+ notes: "Multimodal model optimized for speed"
3545
+ }
3546
+ },
3547
+ {
3548
+ provider: "openai",
3549
+ modelId: "gpt-4o-mini",
3550
+ displayName: "GPT-4o Mini",
3551
+ contextWindow: 128e3,
3552
+ maxOutputTokens: 16384,
3553
+ pricing: {
3554
+ input: 0.15,
3555
+ output: 0.6,
3556
+ cachedInput: 0.075
3557
+ },
3558
+ knowledgeCutoff: "2024-04-01",
3559
+ features: {
3560
+ streaming: true,
3561
+ functionCalling: true,
3562
+ vision: true,
3563
+ structuredOutputs: true,
3564
+ fineTuning: true
3565
+ },
3566
+ metadata: {
3567
+ family: "GPT-4o",
3568
+ notes: "Fast and affordable multimodal model"
3569
+ }
3570
+ },
3571
+ // o-series (Reasoning models)
3572
+ {
3573
+ provider: "openai",
3574
+ modelId: "o1",
3575
+ displayName: "o1",
3576
+ contextWindow: 2e5,
3577
+ maxOutputTokens: 1e5,
3578
+ pricing: {
3579
+ input: 15,
3580
+ output: 60,
3581
+ cachedInput: 7.5
3582
+ },
3583
+ knowledgeCutoff: "2024-12-01",
3584
+ features: {
3585
+ streaming: true,
3586
+ functionCalling: true,
3587
+ vision: true,
3588
+ reasoning: true,
3589
+ structuredOutputs: true
3590
+ },
3591
+ metadata: {
3592
+ family: "o-series",
3593
+ notes: "Advanced reasoning model with chain-of-thought",
3594
+ supportsTemperature: false
3595
+ }
3596
+ },
3597
+ {
3598
+ provider: "openai",
3599
+ modelId: "o3",
3600
+ displayName: "o3",
3601
+ contextWindow: 2e5,
3602
+ maxOutputTokens: 1e5,
3603
+ pricing: {
3604
+ input: 2,
3605
+ output: 8,
3606
+ cachedInput: 0.5
3607
+ },
3608
+ knowledgeCutoff: "2025-01-01",
3609
+ features: {
3610
+ streaming: true,
3611
+ functionCalling: true,
3612
+ vision: true,
3613
+ reasoning: true,
3614
+ structuredOutputs: true
3615
+ },
3616
+ metadata: {
3617
+ family: "o-series",
3618
+ notes: "Next-gen reasoning model, more efficient than o1",
3619
+ supportsTemperature: false
3620
+ }
3621
+ },
3622
+ {
3623
+ provider: "openai",
3624
+ modelId: "o4-mini",
3625
+ displayName: "o4 Mini",
3626
+ contextWindow: 2e5,
3627
+ maxOutputTokens: 1e5,
3628
+ pricing: {
3629
+ input: 1.1,
3630
+ output: 4.4,
3631
+ cachedInput: 0.275
3632
+ },
3633
+ knowledgeCutoff: "2025-04-01",
3634
+ features: {
3635
+ streaming: true,
3636
+ functionCalling: true,
3637
+ vision: true,
3638
+ reasoning: true,
3639
+ structuredOutputs: true,
3640
+ fineTuning: true
3641
+ },
3642
+ metadata: {
3643
+ family: "o-series",
3644
+ notes: "Cost-efficient reasoning model",
3645
+ supportsTemperature: false
3646
+ }
3647
+ },
3648
+ {
3649
+ provider: "openai",
3650
+ modelId: "o3-mini",
3651
+ displayName: "o3 Mini",
3652
+ contextWindow: 2e5,
3653
+ maxOutputTokens: 1e5,
3654
+ pricing: {
3655
+ input: 1.1,
3656
+ output: 4.4,
3657
+ cachedInput: 0.55
3658
+ },
3659
+ knowledgeCutoff: "2025-01-01",
3660
+ features: {
3661
+ streaming: true,
3662
+ functionCalling: true,
3663
+ vision: true,
3664
+ reasoning: true,
3665
+ structuredOutputs: true
3666
+ },
3667
+ metadata: {
3668
+ family: "o-series",
3669
+ notes: "Compact reasoning model for cost-sensitive applications",
3670
+ supportsTemperature: false
3671
+ }
3605
3672
  }
3606
3673
  ];
3607
3674
  }
@@ -3682,7 +3749,8 @@ var init_openai = __esm({
3682
3749
  const usage = chunk.usage ? {
3683
3750
  inputTokens: chunk.usage.prompt_tokens,
3684
3751
  outputTokens: chunk.usage.completion_tokens,
3685
- totalTokens: chunk.usage.total_tokens
3752
+ totalTokens: chunk.usage.total_tokens,
3753
+ cachedInputTokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0
3686
3754
  } : void 0;
3687
3755
  if (finishReason || usage) {
3688
3756
  yield { text: "", finishReason, usage, rawEvent: chunk };
@@ -3899,20 +3967,28 @@ var init_model_registry = __esm({
3899
3967
  /**
3900
3968
  * Estimate API cost for a given model and token usage
3901
3969
  * @param modelId - Full model identifier
3902
- * @param inputTokens - Number of input tokens
3970
+ * @param inputTokens - Number of input tokens (total, including cached and cache creation)
3903
3971
  * @param outputTokens - Number of output tokens
3904
- * @param useCachedInput - Whether to use cached input pricing (if supported by provider)
3972
+ * @param cachedInputTokens - Number of cached input tokens (subset of inputTokens)
3973
+ * @param cacheCreationInputTokens - Number of cache creation tokens (subset of inputTokens, Anthropic only)
3905
3974
  * @returns CostEstimate if model found, undefined otherwise
3906
3975
  */
3907
- estimateCost(modelId, inputTokens, outputTokens, useCachedInput = false) {
3976
+ estimateCost(modelId, inputTokens, outputTokens, cachedInputTokens = 0, cacheCreationInputTokens = 0) {
3908
3977
  const spec = this.getModelSpec(modelId);
3909
3978
  if (!spec) return void 0;
3910
- const inputRate = useCachedInput && spec.pricing.cachedInput !== void 0 ? spec.pricing.cachedInput : spec.pricing.input;
3911
- const inputCost = inputTokens / 1e6 * inputRate;
3979
+ const cachedRate = spec.pricing.cachedInput ?? spec.pricing.input;
3980
+ const cacheWriteRate = spec.pricing.cacheWriteInput ?? spec.pricing.input;
3981
+ const uncachedInputTokens = inputTokens - cachedInputTokens - cacheCreationInputTokens;
3982
+ const uncachedInputCost = uncachedInputTokens / 1e6 * spec.pricing.input;
3983
+ const cachedInputCost = cachedInputTokens / 1e6 * cachedRate;
3984
+ const cacheCreationCost = cacheCreationInputTokens / 1e6 * cacheWriteRate;
3985
+ const inputCost = uncachedInputCost + cachedInputCost + cacheCreationCost;
3912
3986
  const outputCost = outputTokens / 1e6 * spec.pricing.output;
3913
3987
  const totalCost = inputCost + outputCost;
3914
3988
  return {
3915
3989
  inputCost,
3990
+ cachedInputCost,
3991
+ cacheCreationCost,
3916
3992
  outputCost,
3917
3993
  totalCost,
3918
3994
  currency: "USD"
@@ -4083,9 +4159,9 @@ var init_agent = __esm({
4083
4159
  hooks;
4084
4160
  conversation;
4085
4161
  registry;
4086
- parameterFormat;
4087
4162
  gadgetStartPrefix;
4088
4163
  gadgetEndPrefix;
4164
+ gadgetArgPrefix;
4089
4165
  onHumanInputRequired;
4090
4166
  textOnlyHandler;
4091
4167
  textWithGadgetsHandler;
@@ -4114,9 +4190,9 @@ var init_agent = __esm({
4114
4190
  this.temperature = options.temperature;
4115
4191
  this.logger = options.logger ?? createLogger({ name: "llmist:agent" });
4116
4192
  this.registry = options.registry;
4117
- this.parameterFormat = options.parameterFormat ?? "json";
4118
4193
  this.gadgetStartPrefix = options.gadgetStartPrefix;
4119
4194
  this.gadgetEndPrefix = options.gadgetEndPrefix;
4195
+ this.gadgetArgPrefix = options.gadgetArgPrefix;
4120
4196
  this.onHumanInputRequired = options.onHumanInputRequired;
4121
4197
  this.textOnlyHandler = options.textOnlyHandler ?? "terminate";
4122
4198
  this.textWithGadgetsHandler = options.textWithGadgetsHandler;
@@ -4138,9 +4214,10 @@ var init_agent = __esm({
4138
4214
  if (options.systemPrompt) {
4139
4215
  baseBuilder.addSystem(options.systemPrompt);
4140
4216
  }
4141
- baseBuilder.addGadgets(this.registry.getAll(), this.parameterFormat, {
4217
+ baseBuilder.addGadgets(this.registry.getAll(), {
4142
4218
  startPrefix: options.gadgetStartPrefix,
4143
- endPrefix: options.gadgetEndPrefix
4219
+ endPrefix: options.gadgetEndPrefix,
4220
+ argPrefix: options.gadgetArgPrefix
4144
4221
  });
4145
4222
  const baseMessages = baseBuilder.build();
4146
4223
  const initialMessages = (options.initialMessages ?? []).map((message) => ({
@@ -4148,9 +4225,9 @@ var init_agent = __esm({
4148
4225
  content: message.content
4149
4226
  }));
4150
4227
  this.conversation = new ConversationManager(baseMessages, initialMessages, {
4151
- parameterFormat: this.parameterFormat,
4152
4228
  startPrefix: options.gadgetStartPrefix,
4153
- endPrefix: options.gadgetEndPrefix
4229
+ endPrefix: options.gadgetEndPrefix,
4230
+ argPrefix: options.gadgetArgPrefix
4154
4231
  });
4155
4232
  this.userPromptProvided = !!options.userPrompt;
4156
4233
  if (options.userPrompt) {
@@ -4243,9 +4320,9 @@ var init_agent = __esm({
4243
4320
  const processor = new StreamProcessor({
4244
4321
  iteration: currentIteration,
4245
4322
  registry: this.registry,
4246
- parameterFormat: this.parameterFormat,
4247
4323
  gadgetStartPrefix: this.gadgetStartPrefix,
4248
4324
  gadgetEndPrefix: this.gadgetEndPrefix,
4325
+ gadgetArgPrefix: this.gadgetArgPrefix,
4249
4326
  hooks: this.hooks,
4250
4327
  logger: this.logger.getSubLogger({ name: "stream-processor" }),
4251
4328
  onHumanInputRequired: this.onHumanInputRequired,
@@ -4538,9 +4615,9 @@ var init_builder = __esm({
4538
4615
  gadgets = [];
4539
4616
  initialMessages = [];
4540
4617
  onHumanInputRequired;
4541
- parameterFormat;
4542
4618
  gadgetStartPrefix;
4543
4619
  gadgetEndPrefix;
4620
+ gadgetArgPrefix;
4544
4621
  textOnlyHandler;
4545
4622
  textWithGadgetsHandler;
4546
4623
  stopOnGadgetError;
@@ -4727,21 +4804,6 @@ var init_builder = __esm({
4727
4804
  this.onHumanInputRequired = handler;
4728
4805
  return this;
4729
4806
  }
4730
- /**
4731
- * Set the parameter format for gadget calls.
4732
- *
4733
- * @param format - Parameter format ("json" or "xml")
4734
- * @returns This builder for chaining
4735
- *
4736
- * @example
4737
- * ```typescript
4738
- * .withParameterFormat("xml")
4739
- * ```
4740
- */
4741
- withParameterFormat(format) {
4742
- this.parameterFormat = format;
4743
- return this;
4744
- }
4745
4807
  /**
4746
4808
  * Set custom gadget marker prefix.
4747
4809
  *
@@ -4772,6 +4834,21 @@ var init_builder = __esm({
4772
4834
  this.gadgetEndPrefix = suffix;
4773
4835
  return this;
4774
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
+ }
4775
4852
  /**
4776
4853
  * Set the text-only handler strategy.
4777
4854
  *
@@ -4971,8 +5048,7 @@ var init_builder = __esm({
4971
5048
  withSyntheticGadgetCall(gadgetName, parameters, result) {
4972
5049
  const startPrefix = this.gadgetStartPrefix ?? GADGET_START_PREFIX;
4973
5050
  const endPrefix = this.gadgetEndPrefix ?? GADGET_END_PREFIX;
4974
- const format = this.parameterFormat ?? "yaml";
4975
- const paramStr = this.formatSyntheticParameters(parameters, format);
5051
+ const paramStr = this.formatBlockParameters(parameters, "");
4976
5052
  this.initialMessages.push({
4977
5053
  role: "assistant",
4978
5054
  content: `${startPrefix}${gadgetName}
@@ -4986,25 +5062,31 @@ ${endPrefix}`
4986
5062
  return this;
4987
5063
  }
4988
5064
  /**
4989
- * Format parameters for synthetic gadget calls.
4990
- * Uses heredoc for multiline string values.
5065
+ * Format parameters as block format with JSON Pointer paths.
4991
5066
  */
4992
- formatSyntheticParameters(parameters, format) {
4993
- if (format === "json" || format === "auto") {
4994
- return JSON.stringify(parameters);
4995
- }
4996
- return Object.entries(parameters).map(([key, value]) => {
4997
- if (typeof value === "string" && value.includes("\n")) {
4998
- const separator = format === "yaml" ? ":" : " =";
4999
- return `${key}${separator} <<<EOF
5000
- ${value}
5001
- EOF`;
5002
- }
5003
- if (format === "yaml") {
5004
- 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));
5005
5087
  }
5006
- return `${key} = ${JSON.stringify(value)}`;
5007
- }).join("\n");
5088
+ }
5089
+ return lines.join("\n");
5008
5090
  }
5009
5091
  /**
5010
5092
  * Build and create the agent with the given user prompt.
@@ -5044,9 +5126,9 @@ EOF`;
5044
5126
  promptConfig: this.promptConfig,
5045
5127
  initialMessages: this.initialMessages,
5046
5128
  onHumanInputRequired: this.onHumanInputRequired,
5047
- parameterFormat: this.parameterFormat,
5048
5129
  gadgetStartPrefix: this.gadgetStartPrefix,
5049
5130
  gadgetEndPrefix: this.gadgetEndPrefix,
5131
+ gadgetArgPrefix: this.gadgetArgPrefix,
5050
5132
  textOnlyHandler: this.textOnlyHandler,
5051
5133
  textWithGadgetsHandler: this.textWithGadgetsHandler,
5052
5134
  stopOnGadgetError: this.stopOnGadgetError,
@@ -5146,9 +5228,9 @@ EOF`;
5146
5228
  promptConfig: this.promptConfig,
5147
5229
  initialMessages: this.initialMessages,
5148
5230
  onHumanInputRequired: this.onHumanInputRequired,
5149
- parameterFormat: this.parameterFormat,
5150
5231
  gadgetStartPrefix: this.gadgetStartPrefix,
5151
5232
  gadgetEndPrefix: this.gadgetEndPrefix,
5233
+ gadgetArgPrefix: this.gadgetArgPrefix,
5152
5234
  textOnlyHandler: this.textOnlyHandler,
5153
5235
  textWithGadgetsHandler: this.textWithGadgetsHandler,
5154
5236
  stopOnGadgetError: this.stopOnGadgetError,
@@ -5408,6 +5490,7 @@ var init_client = __esm({
5408
5490
  export {
5409
5491
  GADGET_START_PREFIX,
5410
5492
  GADGET_END_PREFIX,
5493
+ GADGET_ARG_PREFIX,
5411
5494
  init_constants,
5412
5495
  MODEL_ALIASES,
5413
5496
  resolveModel,
@@ -5474,4 +5557,4 @@ export {
5474
5557
  AgentBuilder,
5475
5558
  init_builder
5476
5559
  };
5477
- //# sourceMappingURL=chunk-ZFHFBEQ5.js.map
5560
+ //# sourceMappingURL=chunk-T24KLXY4.js.map