llmist 0.4.1 → 0.5.1

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.
@@ -436,6 +436,7 @@ var init_prompt_config = __esm({
436
436
  criticalUsage: "INVOKE gadgets using the markers - do not describe what you want to do.",
437
437
  formatDescriptionYaml: "Parameters in YAML format (one per line)",
438
438
  formatDescriptionJson: "Parameters in JSON format (valid JSON object)",
439
+ formatDescriptionToml: "Parameters in TOML format (key = value pairs, use triple-quotes for multiline)",
439
440
  rules: () => [
440
441
  "Output ONLY plain text with the exact markers - never use function/tool calling",
441
442
  "You can invoke multiple gadgets in a single response",
@@ -443,6 +444,7 @@ var init_prompt_config = __esm({
443
444
  ],
444
445
  schemaLabelJson: "\n\nInput Schema (JSON):",
445
446
  schemaLabelYaml: "\n\nInput Schema (YAML):",
447
+ schemaLabelToml: "\n\nInput Schema (TOML):",
446
448
  customExamples: null
447
449
  };
448
450
  }
@@ -463,6 +465,15 @@ var init_messages = __esm({
463
465
  constructor(promptConfig) {
464
466
  this.promptConfig = promptConfig ?? {};
465
467
  }
468
+ /**
469
+ * Set custom prefixes for gadget markers.
470
+ * Used to configure history builder to match system prompt markers.
471
+ */
472
+ withPrefixes(startPrefix, endPrefix) {
473
+ this.startPrefix = startPrefix;
474
+ this.endPrefix = endPrefix;
475
+ return this;
476
+ }
466
477
  addSystem(content, metadata) {
467
478
  this.messages.push({ role: "system", content, metadata });
468
479
  return this;
@@ -500,7 +511,14 @@ var init_messages = __esm({
500
511
  for (const gadget of gadgets) {
501
512
  const gadgetName = gadget.name ?? gadget.constructor.name;
502
513
  const instruction = gadget.getInstruction(parameterFormat);
503
- const schemaMarker = parameterFormat === "yaml" ? "\n\nInput Schema (YAML):" : "\n\nInput Schema (JSON):";
514
+ const schemaMarkers = {
515
+ yaml: "\n\nInput Schema (YAML):",
516
+ json: "\n\nInput Schema (JSON):",
517
+ toml: "\n\nInput Schema (TOML):",
518
+ auto: "\n\nInput Schema (JSON):"
519
+ // auto defaults to JSON schema display
520
+ };
521
+ const schemaMarker = schemaMarkers[parameterFormat];
504
522
  const schemaIndex = instruction.indexOf(schemaMarker);
505
523
  const description = (schemaIndex !== -1 ? instruction.substring(0, schemaIndex) : instruction).trim();
506
524
  const schema = schemaIndex !== -1 ? instruction.substring(schemaIndex + schemaMarker.length).trim() : "";
@@ -520,15 +538,26 @@ ${schema}`);
520
538
  }
521
539
  buildUsageSection(parameterFormat, context) {
522
540
  const parts = [];
523
- const formatDescription = parameterFormat === "yaml" ? resolvePromptTemplate(
524
- this.promptConfig.formatDescriptionYaml,
525
- DEFAULT_PROMPTS.formatDescriptionYaml,
526
- context
527
- ) : resolvePromptTemplate(
528
- this.promptConfig.formatDescriptionJson,
529
- DEFAULT_PROMPTS.formatDescriptionJson,
530
- context
531
- );
541
+ const formatDescriptionMap = {
542
+ yaml: {
543
+ config: this.promptConfig.formatDescriptionYaml,
544
+ defaultValue: DEFAULT_PROMPTS.formatDescriptionYaml
545
+ },
546
+ json: {
547
+ config: this.promptConfig.formatDescriptionJson,
548
+ defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
549
+ },
550
+ toml: {
551
+ config: this.promptConfig.formatDescriptionToml,
552
+ defaultValue: DEFAULT_PROMPTS.formatDescriptionToml
553
+ },
554
+ auto: {
555
+ config: this.promptConfig.formatDescriptionJson,
556
+ defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
557
+ }
558
+ };
559
+ const { config, defaultValue } = formatDescriptionMap[parameterFormat];
560
+ const formatDescription = resolvePromptTemplate(config, defaultValue, context);
532
561
  parts.push("\n\nHOW TO INVOKE GADGETS");
533
562
  parts.push("\n=====================\n");
534
563
  const criticalUsage = resolvePromptTemplate(
@@ -556,38 +585,110 @@ CRITICAL: ${criticalUsage}
556
585
  return this.promptConfig.customExamples(context);
557
586
  }
558
587
  const parts = [];
559
- const singleExample = parameterFormat === "yaml" ? `${this.startPrefix}translate
588
+ const singleExamples = {
589
+ yaml: `${this.startPrefix}translate
560
590
  from: English
561
591
  to: Polish
562
- content: Paris is the capital of France.
563
- ${this.endPrefix}` : `${this.startPrefix}translate
564
- {"from": "English", "to": "Polish", "content": "Paris is the capital of France."}
565
- ${this.endPrefix}`;
592
+ content: "Paris is the capital of France: a beautiful city."
593
+ ${this.endPrefix}`,
594
+ json: `${this.startPrefix}translate
595
+ {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
596
+ ${this.endPrefix}`,
597
+ toml: `${this.startPrefix}translate
598
+ from = "English"
599
+ to = "Polish"
600
+ content = "Paris is the capital of France: a beautiful city."
601
+ ${this.endPrefix}`,
602
+ auto: `${this.startPrefix}translate
603
+ {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
604
+ ${this.endPrefix}`
605
+ };
566
606
  parts.push(`
567
607
 
568
608
  EXAMPLE (Single Gadget):
569
609
 
570
- ${singleExample}`);
571
- const multipleExample = parameterFormat === "yaml" ? `${this.startPrefix}translate
610
+ ${singleExamples[parameterFormat]}`);
611
+ const multipleExamples = {
612
+ yaml: `${this.startPrefix}translate
572
613
  from: English
573
614
  to: Polish
574
- content: Paris is the capital of France.
615
+ content: "Paris is the capital of France: a beautiful city."
575
616
  ${this.endPrefix}
576
617
  ${this.startPrefix}analyze
577
618
  type: economic_analysis
578
619
  matter: "Polish Economy"
579
- question: Polish arms exports 2025.
580
- ${this.endPrefix}` : `${this.startPrefix}translate
581
- {"from": "English", "to": "Polish", "content": "Paris is the capital of France."}
620
+ question: |
621
+ Analyze the following:
622
+ - Polish arms exports 2025
623
+ - Economic implications
624
+ ${this.endPrefix}`,
625
+ json: `${this.startPrefix}translate
626
+ {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
627
+ ${this.endPrefix}
628
+ ${this.startPrefix}analyze
629
+ {"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
630
+ ${this.endPrefix}`,
631
+ toml: `${this.startPrefix}translate
632
+ from = "English"
633
+ to = "Polish"
634
+ content = "Paris is the capital of France: a beautiful city."
582
635
  ${this.endPrefix}
583
636
  ${this.startPrefix}analyze
584
- {"type": "economic_analysis", "matter": "Polish Economy", "question": "Polish arms exports 2025."}
585
- ${this.endPrefix}`;
637
+ type = "economic_analysis"
638
+ matter = "Polish Economy"
639
+ question = """
640
+ Analyze the following:
641
+ - Polish arms exports 2025
642
+ - Economic implications
643
+ """
644
+ ${this.endPrefix}`,
645
+ auto: `${this.startPrefix}translate
646
+ {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
647
+ ${this.endPrefix}
648
+ ${this.startPrefix}analyze
649
+ {"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
650
+ ${this.endPrefix}`
651
+ };
586
652
  parts.push(`
587
653
 
588
654
  EXAMPLE (Multiple Gadgets):
589
655
 
590
- ${multipleExample}`);
656
+ ${multipleExamples[parameterFormat]}`);
657
+ if (parameterFormat === "yaml") {
658
+ parts.push(`
659
+
660
+ YAML MULTILINE SYNTAX:
661
+ For string values with special characters (colons, dashes, quotes) or multiple lines,
662
+ use the pipe (|) syntax. ALL content lines MUST be indented with 2 spaces:
663
+
664
+ CORRECT - all lines indented:
665
+ question: |
666
+ Which option do you prefer?
667
+ - Option A: fast processing
668
+ - Option B: thorough analysis
669
+ Please choose one.
670
+
671
+ WRONG - inconsistent indentation breaks YAML:
672
+ question: |
673
+ Which option do you prefer?
674
+ - Option A: fast
675
+ Please choose one. <-- ERROR: not indented, breaks out of the block`);
676
+ } else if (parameterFormat === "toml") {
677
+ parts.push(`
678
+
679
+ TOML MULTILINE SYNTAX:
680
+ For string values with multiple lines or special characters, use triple-quotes ("""):
681
+
682
+ filePath = "README.md"
683
+ content = """
684
+ # Project Title
685
+
686
+ This content can contain:
687
+ - Markdown lists
688
+ - Special characters: # : -
689
+ - Multiple paragraphs
690
+ """`);
691
+ }
591
692
  return parts.join("");
592
693
  }
593
694
  buildRulesSection(context) {
@@ -631,6 +732,16 @@ ${this.endPrefix}`
631
732
  return `${key}: ${JSON.stringify(value)}`;
632
733
  }).join("\n");
633
734
  }
735
+ if (format === "toml") {
736
+ return Object.entries(parameters).map(([key, value]) => {
737
+ if (typeof value === "string" && value.includes("\n")) {
738
+ return `${key} = """
739
+ ${value}
740
+ """`;
741
+ }
742
+ return `${key} = ${JSON.stringify(value)}`;
743
+ }).join("\n");
744
+ }
634
745
  return JSON.stringify(parameters);
635
746
  }
636
747
  build() {
@@ -663,11 +774,14 @@ var init_conversation_manager = __esm({
663
774
  initialMessages;
664
775
  historyBuilder;
665
776
  parameterFormat;
666
- constructor(baseMessages, initialMessages, parameterFormat = "json") {
777
+ constructor(baseMessages, initialMessages, options = {}) {
667
778
  this.baseMessages = baseMessages;
668
779
  this.initialMessages = initialMessages;
669
- this.parameterFormat = parameterFormat;
780
+ this.parameterFormat = options.parameterFormat ?? "json";
670
781
  this.historyBuilder = new LLMMessageBuilder();
782
+ if (options.startPrefix && options.endPrefix) {
783
+ this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix);
784
+ }
671
785
  }
672
786
  addUserMessage(content) {
673
787
  this.historyBuilder.addUser(content);
@@ -1138,11 +1252,109 @@ var init_executor = __esm({
1138
1252
  });
1139
1253
 
1140
1254
  // src/gadgets/parser.ts
1141
- var yaml, globalInvocationCounter, StreamParser;
1255
+ function preprocessYaml(yamlStr) {
1256
+ const lines = yamlStr.split("\n");
1257
+ const result = [];
1258
+ let i = 0;
1259
+ while (i < lines.length) {
1260
+ const line = lines[i];
1261
+ const match = line.match(/^(\s*)([\w-]+):\s+(.+)$/);
1262
+ if (match) {
1263
+ const [, indent, key, value] = match;
1264
+ if (value === "|" || value === ">" || value === "|-" || value === ">-") {
1265
+ result.push(line);
1266
+ i++;
1267
+ const keyIndentLen2 = indent.length;
1268
+ const blockLines = [];
1269
+ let minContentIndent = Infinity;
1270
+ while (i < lines.length) {
1271
+ const blockLine = lines[i];
1272
+ const blockIndentMatch = blockLine.match(/^(\s*)/);
1273
+ const blockIndentLen = blockIndentMatch ? blockIndentMatch[1].length : 0;
1274
+ if (blockLine.trim() === "") {
1275
+ blockLines.push({ content: "", originalIndent: 0 });
1276
+ i++;
1277
+ continue;
1278
+ }
1279
+ if (blockIndentLen > keyIndentLen2) {
1280
+ const content = blockLine.substring(blockIndentLen);
1281
+ blockLines.push({ content, originalIndent: blockIndentLen });
1282
+ if (content.trim().length > 0) {
1283
+ minContentIndent = Math.min(minContentIndent, blockIndentLen);
1284
+ }
1285
+ i++;
1286
+ } else {
1287
+ break;
1288
+ }
1289
+ }
1290
+ const targetIndent = keyIndentLen2 + 2;
1291
+ for (const blockLine of blockLines) {
1292
+ if (blockLine.content === "") {
1293
+ result.push("");
1294
+ } else {
1295
+ result.push(" ".repeat(targetIndent) + blockLine.content);
1296
+ }
1297
+ }
1298
+ continue;
1299
+ }
1300
+ if (value.startsWith('"') || value.startsWith("'") || value === "true" || value === "false" || /^-?\d+(\.\d+)?$/.test(value)) {
1301
+ result.push(line);
1302
+ i++;
1303
+ continue;
1304
+ }
1305
+ const keyIndentLen = indent.length;
1306
+ const continuationLines = [];
1307
+ let j = i + 1;
1308
+ while (j < lines.length) {
1309
+ const nextLine = lines[j];
1310
+ if (nextLine.trim() === "") {
1311
+ continuationLines.push(nextLine);
1312
+ j++;
1313
+ continue;
1314
+ }
1315
+ const nextIndentMatch = nextLine.match(/^(\s*)/);
1316
+ const nextIndentLen = nextIndentMatch ? nextIndentMatch[1].length : 0;
1317
+ if (nextIndentLen > keyIndentLen) {
1318
+ continuationLines.push(nextLine);
1319
+ j++;
1320
+ } else {
1321
+ break;
1322
+ }
1323
+ }
1324
+ if (continuationLines.length > 0 && continuationLines.some((l) => l.trim().length > 0)) {
1325
+ result.push(`${indent}${key}: |`);
1326
+ result.push(`${indent} ${value}`);
1327
+ for (const contLine of continuationLines) {
1328
+ if (contLine.trim() === "") {
1329
+ result.push("");
1330
+ } else {
1331
+ const contIndentMatch = contLine.match(/^(\s*)/);
1332
+ const contIndent = contIndentMatch ? contIndentMatch[1] : "";
1333
+ const contContent = contLine.substring(contIndent.length);
1334
+ result.push(`${indent} ${contContent}`);
1335
+ }
1336
+ }
1337
+ i = j;
1338
+ continue;
1339
+ }
1340
+ if (value.includes(": ") || value.endsWith(":")) {
1341
+ const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1342
+ result.push(`${indent}${key}: "${escaped}"`);
1343
+ i++;
1344
+ continue;
1345
+ }
1346
+ }
1347
+ result.push(line);
1348
+ i++;
1349
+ }
1350
+ return result.join("\n");
1351
+ }
1352
+ var yaml, import_js_toml, globalInvocationCounter, StreamParser;
1142
1353
  var init_parser = __esm({
1143
1354
  "src/gadgets/parser.ts"() {
1144
1355
  "use strict";
1145
1356
  yaml = __toESM(require("js-yaml"), 1);
1357
+ import_js_toml = require("js-toml");
1146
1358
  init_constants();
1147
1359
  globalInvocationCounter = 0;
1148
1360
  StreamParser = class {
@@ -1164,6 +1376,17 @@ var init_parser = __esm({
1164
1376
  this.lastReportedTextLength = index;
1165
1377
  return segment.trim().length > 0 ? segment : void 0;
1166
1378
  }
1379
+ /**
1380
+ * Parse gadget name, handling both old format (name:invocationId) and new format (just name).
1381
+ * For new format, generates a unique invocation ID.
1382
+ */
1383
+ parseGadgetName(gadgetName) {
1384
+ if (gadgetName.includes(":")) {
1385
+ const parts = gadgetName.split(":");
1386
+ return { actualName: parts[0], invocationId: parts[1] };
1387
+ }
1388
+ return { actualName: gadgetName, invocationId: `gadget_${++globalInvocationCounter}` };
1389
+ }
1167
1390
  /**
1168
1391
  * Parse parameter string according to configured format
1169
1392
  */
@@ -1177,20 +1400,31 @@ var init_parser = __esm({
1177
1400
  }
1178
1401
  if (this.parameterFormat === "yaml") {
1179
1402
  try {
1180
- return { parameters: yaml.load(raw) };
1403
+ return { parameters: yaml.load(preprocessYaml(raw)) };
1181
1404
  } catch (error) {
1182
1405
  return { parseError: error instanceof Error ? error.message : "Failed to parse YAML" };
1183
1406
  }
1184
1407
  }
1408
+ if (this.parameterFormat === "toml") {
1409
+ try {
1410
+ return { parameters: (0, import_js_toml.load)(raw) };
1411
+ } catch (error) {
1412
+ return { parseError: error instanceof Error ? error.message : "Failed to parse TOML" };
1413
+ }
1414
+ }
1185
1415
  try {
1186
1416
  return { parameters: JSON.parse(raw) };
1187
1417
  } catch {
1188
1418
  try {
1189
- return { parameters: yaml.load(raw) };
1190
- } catch (error) {
1191
- return {
1192
- parseError: error instanceof Error ? error.message : "Failed to parse as JSON or YAML"
1193
- };
1419
+ return { parameters: (0, import_js_toml.load)(raw) };
1420
+ } catch {
1421
+ try {
1422
+ return { parameters: yaml.load(preprocessYaml(raw)) };
1423
+ } catch (error) {
1424
+ return {
1425
+ parseError: error instanceof Error ? error.message : "Failed to parse as JSON, TOML, or YAML"
1426
+ };
1427
+ }
1194
1428
  }
1195
1429
  }
1196
1430
  }
@@ -1209,16 +1443,7 @@ var init_parser = __esm({
1209
1443
  const metadataEndIndex = this.buffer.indexOf("\n", metadataStartIndex);
1210
1444
  if (metadataEndIndex === -1) break;
1211
1445
  const gadgetName = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();
1212
- let invocationId;
1213
- let actualGadgetName;
1214
- if (gadgetName.includes(":")) {
1215
- const parts = gadgetName.split(":");
1216
- actualGadgetName = parts[0];
1217
- invocationId = parts[1];
1218
- } else {
1219
- actualGadgetName = gadgetName;
1220
- invocationId = `gadget_${++globalInvocationCounter}`;
1221
- }
1446
+ const { actualName: actualGadgetName, invocationId } = this.parseGadgetName(gadgetName);
1222
1447
  const contentStartIndex = metadataEndIndex + 1;
1223
1448
  let partEndIndex;
1224
1449
  let endMarkerLength = 0;
@@ -1228,23 +1453,29 @@ var init_parser = __esm({
1228
1453
  if (partEndIndex === -1) break;
1229
1454
  endMarkerLength = oldEndMarker.length;
1230
1455
  } else {
1231
- partEndIndex = contentStartIndex;
1456
+ const nextStartPos = this.buffer.indexOf(this.startPrefix, contentStartIndex);
1457
+ let validEndPos = -1;
1458
+ let searchPos = contentStartIndex;
1232
1459
  while (true) {
1233
- const endPos = this.buffer.indexOf(this.endPrefix, partEndIndex);
1234
- if (endPos === -1) {
1235
- partEndIndex = -1;
1236
- break;
1237
- }
1460
+ const endPos = this.buffer.indexOf(this.endPrefix, searchPos);
1461
+ if (endPos === -1) break;
1238
1462
  const afterEnd = this.buffer.substring(endPos + this.endPrefix.length);
1239
1463
  if (afterEnd.startsWith("\n") || afterEnd.startsWith("\r") || afterEnd.startsWith(this.startPrefix) || afterEnd.length === 0) {
1240
- partEndIndex = endPos;
1241
- endMarkerLength = this.endPrefix.length;
1464
+ validEndPos = endPos;
1242
1465
  break;
1243
1466
  } else {
1244
- partEndIndex = endPos + this.endPrefix.length;
1467
+ searchPos = endPos + this.endPrefix.length;
1245
1468
  }
1246
1469
  }
1247
- if (partEndIndex === -1) break;
1470
+ if (nextStartPos !== -1 && (validEndPos === -1 || nextStartPos < validEndPos)) {
1471
+ partEndIndex = nextStartPos;
1472
+ endMarkerLength = 0;
1473
+ } else if (validEndPos !== -1) {
1474
+ partEndIndex = validEndPos;
1475
+ endMarkerLength = this.endPrefix.length;
1476
+ } else {
1477
+ break;
1478
+ }
1248
1479
  }
1249
1480
  const parametersRaw = this.buffer.substring(contentStartIndex, partEndIndex).trim();
1250
1481
  const { parameters, parseError } = this.parseParameters(parametersRaw);
@@ -1267,8 +1498,35 @@ var init_parser = __esm({
1267
1498
  this.lastReportedTextLength = 0;
1268
1499
  }
1269
1500
  }
1270
- // Finalize parsing and return remaining text
1501
+ // Finalize parsing and return remaining text or incomplete gadgets
1271
1502
  *finalize() {
1503
+ const startIndex = this.buffer.indexOf(this.startPrefix, this.lastReportedTextLength);
1504
+ if (startIndex !== -1) {
1505
+ const textBefore = this.takeTextUntil(startIndex);
1506
+ if (textBefore !== void 0) {
1507
+ yield { type: "text", content: textBefore };
1508
+ }
1509
+ const metadataStartIndex = startIndex + this.startPrefix.length;
1510
+ const metadataEndIndex = this.buffer.indexOf("\n", metadataStartIndex);
1511
+ if (metadataEndIndex !== -1) {
1512
+ const gadgetName = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();
1513
+ const { actualName: actualGadgetName, invocationId } = this.parseGadgetName(gadgetName);
1514
+ const contentStartIndex = metadataEndIndex + 1;
1515
+ const parametersRaw = this.buffer.substring(contentStartIndex).trim();
1516
+ const { parameters, parseError } = this.parseParameters(parametersRaw);
1517
+ yield {
1518
+ type: "gadget_call",
1519
+ call: {
1520
+ gadgetName: actualGadgetName,
1521
+ invocationId,
1522
+ parametersYaml: parametersRaw,
1523
+ parameters,
1524
+ parseError
1525
+ }
1526
+ };
1527
+ return;
1528
+ }
1529
+ }
1272
1530
  const remainingText = this.takeTextUntil(this.buffer.length);
1273
1531
  if (remainingText !== void 0) {
1274
1532
  yield { type: "text", content: remainingText };
@@ -1749,11 +2007,11 @@ var init_agent = __esm({
1749
2007
  role: message.role,
1750
2008
  content: message.content
1751
2009
  }));
1752
- this.conversation = new ConversationManager(
1753
- baseMessages,
1754
- initialMessages,
1755
- this.parameterFormat
1756
- );
2010
+ this.conversation = new ConversationManager(baseMessages, initialMessages, {
2011
+ parameterFormat: this.parameterFormat,
2012
+ startPrefix: options.gadgetStartPrefix,
2013
+ endPrefix: options.gadgetEndPrefix
2014
+ });
1757
2015
  this.userPromptProvided = !!options.userPrompt;
1758
2016
  if (options.userPrompt) {
1759
2017
  this.conversation.addUserMessage(options.userPrompt);
@@ -5090,6 +5348,83 @@ function mergeDescriptions(schema, jsonSchema) {
5090
5348
 
5091
5349
  // src/gadgets/gadget.ts
5092
5350
  init_schema_validator();
5351
+ function formatYamlValue(value, indent = "") {
5352
+ if (typeof value === "string") {
5353
+ const lines = value.split("\n");
5354
+ if (lines.length === 1 && !value.includes(":") && !value.startsWith("-")) {
5355
+ return value;
5356
+ }
5357
+ const indentedLines = lines.map((line) => `${indent} ${line}`).join("\n");
5358
+ return `|
5359
+ ${indentedLines}`;
5360
+ }
5361
+ if (typeof value === "number" || typeof value === "boolean") {
5362
+ return String(value);
5363
+ }
5364
+ if (value === null || value === void 0) {
5365
+ return "null";
5366
+ }
5367
+ if (Array.isArray(value)) {
5368
+ if (value.length === 0) return "[]";
5369
+ const items = value.map((item) => `${indent}- ${formatYamlValue(item, indent + " ")}`);
5370
+ return "\n" + items.join("\n");
5371
+ }
5372
+ if (typeof value === "object") {
5373
+ const entries = Object.entries(value);
5374
+ if (entries.length === 0) return "{}";
5375
+ const lines = entries.map(([k, v]) => {
5376
+ const formattedValue = formatYamlValue(v, indent + " ");
5377
+ if (formattedValue.startsWith("\n") || formattedValue.startsWith("|")) {
5378
+ return `${indent}${k}: ${formattedValue}`;
5379
+ }
5380
+ return `${indent}${k}: ${formattedValue}`;
5381
+ });
5382
+ return "\n" + lines.join("\n");
5383
+ }
5384
+ return yaml2.dump(value).trimEnd();
5385
+ }
5386
+ function formatParamsAsYaml(params) {
5387
+ const lines = [];
5388
+ for (const [key, value] of Object.entries(params)) {
5389
+ const formattedValue = formatYamlValue(value, "");
5390
+ if (formattedValue.startsWith("\n")) {
5391
+ lines.push(`${key}:${formattedValue}`);
5392
+ } else {
5393
+ lines.push(`${key}: ${formattedValue}`);
5394
+ }
5395
+ }
5396
+ return lines.join("\n");
5397
+ }
5398
+ function formatTomlValue(value) {
5399
+ if (typeof value === "string") {
5400
+ if (value.includes("\n")) {
5401
+ return `"""
5402
+ ${value}
5403
+ """`;
5404
+ }
5405
+ return JSON.stringify(value);
5406
+ }
5407
+ if (typeof value === "number" || typeof value === "boolean") {
5408
+ return String(value);
5409
+ }
5410
+ if (value === null || value === void 0) {
5411
+ return '""';
5412
+ }
5413
+ if (Array.isArray(value)) {
5414
+ return JSON.stringify(value);
5415
+ }
5416
+ if (typeof value === "object") {
5417
+ return JSON.stringify(value);
5418
+ }
5419
+ return JSON.stringify(value);
5420
+ }
5421
+ function formatParamsAsToml(params) {
5422
+ const lines = [];
5423
+ for (const [key, value] of Object.entries(params)) {
5424
+ lines.push(`${key} = ${formatTomlValue(value)}`);
5425
+ }
5426
+ return lines.join("\n");
5427
+ }
5093
5428
  var BaseGadget = class {
5094
5429
  /**
5095
5430
  * The name of the gadget. Used for identification when LLM calls it.
@@ -5109,6 +5444,14 @@ var BaseGadget = class {
5109
5444
  * Set to 0 or undefined to disable timeout for this gadget.
5110
5445
  */
5111
5446
  timeoutMs;
5447
+ /**
5448
+ * Optional usage examples to help LLMs understand proper invocation.
5449
+ * Examples are rendered in getInstruction() alongside the schema.
5450
+ *
5451
+ * Note: Uses broader `unknown` type to allow typed examples from subclasses
5452
+ * while maintaining runtime compatibility.
5453
+ */
5454
+ examples;
5112
5455
  /**
5113
5456
  * Auto-generated instruction text for the LLM.
5114
5457
  * Combines name, description, and parameter schema into a formatted instruction.
@@ -5121,7 +5464,7 @@ var BaseGadget = class {
5121
5464
  * Generate instruction text for the LLM with format-specific schema.
5122
5465
  * Combines name, description, and parameter schema into a formatted instruction.
5123
5466
  *
5124
- * @param format - Format for the schema representation ('json' | 'yaml' | 'auto')
5467
+ * @param format - Format for the schema representation ('json' | 'yaml' | 'toml' | 'auto')
5125
5468
  * @returns Formatted instruction string
5126
5469
  */
5127
5470
  getInstruction(format = "json") {
@@ -5136,12 +5479,38 @@ var BaseGadget = class {
5136
5479
  if (format === "json" || format === "auto") {
5137
5480
  parts.push("\n\nInput Schema (JSON):");
5138
5481
  parts.push(JSON.stringify(jsonSchema, null, 2));
5482
+ } else if (format === "toml") {
5483
+ parts.push("\n\nInput Schema (TOML):");
5484
+ parts.push(JSON.stringify(jsonSchema, null, 2));
5139
5485
  } else {
5140
5486
  const yamlSchema = yaml2.dump(jsonSchema).trimEnd();
5141
5487
  parts.push("\n\nInput Schema (YAML):");
5142
5488
  parts.push(yamlSchema);
5143
5489
  }
5144
5490
  }
5491
+ if (this.examples && this.examples.length > 0) {
5492
+ parts.push("\n\nExamples:");
5493
+ this.examples.forEach((example, index) => {
5494
+ if (index > 0) {
5495
+ parts.push("");
5496
+ }
5497
+ if (example.comment) {
5498
+ parts.push(`# ${example.comment}`);
5499
+ }
5500
+ parts.push("Input:");
5501
+ if (format === "json" || format === "auto") {
5502
+ parts.push(JSON.stringify(example.params, null, 2));
5503
+ } else if (format === "toml") {
5504
+ parts.push(formatParamsAsToml(example.params));
5505
+ } else {
5506
+ parts.push(formatParamsAsYaml(example.params));
5507
+ }
5508
+ if (example.output !== void 0) {
5509
+ parts.push("Output:");
5510
+ parts.push(example.output);
5511
+ }
5512
+ });
5513
+ }
5145
5514
  return parts.join("\n");
5146
5515
  }
5147
5516
  };