llmist 0.4.1 → 0.5.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.
@@ -362,6 +362,7 @@ var init_prompt_config = __esm({
362
362
  criticalUsage: "INVOKE gadgets using the markers - do not describe what you want to do.",
363
363
  formatDescriptionYaml: "Parameters in YAML format (one per line)",
364
364
  formatDescriptionJson: "Parameters in JSON format (valid JSON object)",
365
+ formatDescriptionToml: "Parameters in TOML format (key = value pairs, use triple-quotes for multiline)",
365
366
  rules: () => [
366
367
  "Output ONLY plain text with the exact markers - never use function/tool calling",
367
368
  "You can invoke multiple gadgets in a single response",
@@ -369,6 +370,7 @@ var init_prompt_config = __esm({
369
370
  ],
370
371
  schemaLabelJson: "\n\nInput Schema (JSON):",
371
372
  schemaLabelYaml: "\n\nInput Schema (YAML):",
373
+ schemaLabelToml: "\n\nInput Schema (TOML):",
372
374
  customExamples: null
373
375
  };
374
376
  }
@@ -399,6 +401,15 @@ var init_messages = __esm({
399
401
  constructor(promptConfig) {
400
402
  this.promptConfig = promptConfig ?? {};
401
403
  }
404
+ /**
405
+ * Set custom prefixes for gadget markers.
406
+ * Used to configure history builder to match system prompt markers.
407
+ */
408
+ withPrefixes(startPrefix, endPrefix) {
409
+ this.startPrefix = startPrefix;
410
+ this.endPrefix = endPrefix;
411
+ return this;
412
+ }
402
413
  addSystem(content, metadata) {
403
414
  this.messages.push({ role: "system", content, metadata });
404
415
  return this;
@@ -436,7 +447,14 @@ var init_messages = __esm({
436
447
  for (const gadget of gadgets) {
437
448
  const gadgetName = gadget.name ?? gadget.constructor.name;
438
449
  const instruction = gadget.getInstruction(parameterFormat);
439
- const schemaMarker = parameterFormat === "yaml" ? "\n\nInput Schema (YAML):" : "\n\nInput Schema (JSON):";
450
+ const schemaMarkers = {
451
+ yaml: "\n\nInput Schema (YAML):",
452
+ json: "\n\nInput Schema (JSON):",
453
+ toml: "\n\nInput Schema (TOML):",
454
+ auto: "\n\nInput Schema (JSON):"
455
+ // auto defaults to JSON schema display
456
+ };
457
+ const schemaMarker = schemaMarkers[parameterFormat];
440
458
  const schemaIndex = instruction.indexOf(schemaMarker);
441
459
  const description = (schemaIndex !== -1 ? instruction.substring(0, schemaIndex) : instruction).trim();
442
460
  const schema = schemaIndex !== -1 ? instruction.substring(schemaIndex + schemaMarker.length).trim() : "";
@@ -456,15 +474,26 @@ ${schema}`);
456
474
  }
457
475
  buildUsageSection(parameterFormat, context) {
458
476
  const parts = [];
459
- const formatDescription = parameterFormat === "yaml" ? resolvePromptTemplate(
460
- this.promptConfig.formatDescriptionYaml,
461
- DEFAULT_PROMPTS.formatDescriptionYaml,
462
- context
463
- ) : resolvePromptTemplate(
464
- this.promptConfig.formatDescriptionJson,
465
- DEFAULT_PROMPTS.formatDescriptionJson,
466
- context
467
- );
477
+ const formatDescriptionMap = {
478
+ yaml: {
479
+ config: this.promptConfig.formatDescriptionYaml,
480
+ defaultValue: DEFAULT_PROMPTS.formatDescriptionYaml
481
+ },
482
+ json: {
483
+ config: this.promptConfig.formatDescriptionJson,
484
+ defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
485
+ },
486
+ toml: {
487
+ config: this.promptConfig.formatDescriptionToml,
488
+ defaultValue: DEFAULT_PROMPTS.formatDescriptionToml
489
+ },
490
+ auto: {
491
+ config: this.promptConfig.formatDescriptionJson,
492
+ defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
493
+ }
494
+ };
495
+ const { config, defaultValue } = formatDescriptionMap[parameterFormat];
496
+ const formatDescription = resolvePromptTemplate(config, defaultValue, context);
468
497
  parts.push("\n\nHOW TO INVOKE GADGETS");
469
498
  parts.push("\n=====================\n");
470
499
  const criticalUsage = resolvePromptTemplate(
@@ -492,38 +521,110 @@ CRITICAL: ${criticalUsage}
492
521
  return this.promptConfig.customExamples(context);
493
522
  }
494
523
  const parts = [];
495
- const singleExample = parameterFormat === "yaml" ? `${this.startPrefix}translate
524
+ const singleExamples = {
525
+ yaml: `${this.startPrefix}translate
496
526
  from: English
497
527
  to: Polish
498
- content: Paris is the capital of France.
499
- ${this.endPrefix}` : `${this.startPrefix}translate
500
- {"from": "English", "to": "Polish", "content": "Paris is the capital of France."}
501
- ${this.endPrefix}`;
528
+ content: "Paris is the capital of France: a beautiful city."
529
+ ${this.endPrefix}`,
530
+ json: `${this.startPrefix}translate
531
+ {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
532
+ ${this.endPrefix}`,
533
+ toml: `${this.startPrefix}translate
534
+ from = "English"
535
+ to = "Polish"
536
+ content = "Paris is the capital of France: a beautiful city."
537
+ ${this.endPrefix}`,
538
+ auto: `${this.startPrefix}translate
539
+ {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
540
+ ${this.endPrefix}`
541
+ };
502
542
  parts.push(`
503
543
 
504
544
  EXAMPLE (Single Gadget):
505
545
 
506
- ${singleExample}`);
507
- const multipleExample = parameterFormat === "yaml" ? `${this.startPrefix}translate
546
+ ${singleExamples[parameterFormat]}`);
547
+ const multipleExamples = {
548
+ yaml: `${this.startPrefix}translate
508
549
  from: English
509
550
  to: Polish
510
- content: Paris is the capital of France.
551
+ content: "Paris is the capital of France: a beautiful city."
511
552
  ${this.endPrefix}
512
553
  ${this.startPrefix}analyze
513
554
  type: economic_analysis
514
555
  matter: "Polish Economy"
515
- question: Polish arms exports 2025.
516
- ${this.endPrefix}` : `${this.startPrefix}translate
517
- {"from": "English", "to": "Polish", "content": "Paris is the capital of France."}
556
+ question: |
557
+ Analyze the following:
558
+ - Polish arms exports 2025
559
+ - Economic implications
560
+ ${this.endPrefix}`,
561
+ json: `${this.startPrefix}translate
562
+ {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
563
+ ${this.endPrefix}
564
+ ${this.startPrefix}analyze
565
+ {"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
566
+ ${this.endPrefix}`,
567
+ toml: `${this.startPrefix}translate
568
+ from = "English"
569
+ to = "Polish"
570
+ content = "Paris is the capital of France: a beautiful city."
571
+ ${this.endPrefix}
572
+ ${this.startPrefix}analyze
573
+ type = "economic_analysis"
574
+ matter = "Polish Economy"
575
+ question = """
576
+ Analyze the following:
577
+ - Polish arms exports 2025
578
+ - Economic implications
579
+ """
580
+ ${this.endPrefix}`,
581
+ auto: `${this.startPrefix}translate
582
+ {"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
518
583
  ${this.endPrefix}
519
584
  ${this.startPrefix}analyze
520
- {"type": "economic_analysis", "matter": "Polish Economy", "question": "Polish arms exports 2025."}
521
- ${this.endPrefix}`;
585
+ {"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
586
+ ${this.endPrefix}`
587
+ };
522
588
  parts.push(`
523
589
 
524
590
  EXAMPLE (Multiple Gadgets):
525
591
 
526
- ${multipleExample}`);
592
+ ${multipleExamples[parameterFormat]}`);
593
+ if (parameterFormat === "yaml") {
594
+ parts.push(`
595
+
596
+ YAML MULTILINE SYNTAX:
597
+ For string values with special characters (colons, dashes, quotes) or multiple lines,
598
+ use the pipe (|) syntax. ALL content lines MUST be indented with 2 spaces:
599
+
600
+ CORRECT - all lines indented:
601
+ question: |
602
+ Which option do you prefer?
603
+ - Option A: fast processing
604
+ - Option B: thorough analysis
605
+ Please choose one.
606
+
607
+ WRONG - inconsistent indentation breaks YAML:
608
+ question: |
609
+ Which option do you prefer?
610
+ - Option A: fast
611
+ Please choose one. <-- ERROR: not indented, breaks out of the block`);
612
+ } else if (parameterFormat === "toml") {
613
+ parts.push(`
614
+
615
+ TOML MULTILINE SYNTAX:
616
+ For string values with multiple lines or special characters, use triple-quotes ("""):
617
+
618
+ filePath = "README.md"
619
+ content = """
620
+ # Project Title
621
+
622
+ This content can contain:
623
+ - Markdown lists
624
+ - Special characters: # : -
625
+ - Multiple paragraphs
626
+ """`);
627
+ }
527
628
  return parts.join("");
528
629
  }
529
630
  buildRulesSection(context) {
@@ -567,6 +668,16 @@ ${this.endPrefix}`
567
668
  return `${key}: ${JSON.stringify(value)}`;
568
669
  }).join("\n");
569
670
  }
671
+ if (format === "toml") {
672
+ return Object.entries(parameters).map(([key, value]) => {
673
+ if (typeof value === "string" && value.includes("\n")) {
674
+ return `${key} = """
675
+ ${value}
676
+ """`;
677
+ }
678
+ return `${key} = ${JSON.stringify(value)}`;
679
+ }).join("\n");
680
+ }
570
681
  return JSON.stringify(parameters);
571
682
  }
572
683
  build() {
@@ -656,11 +767,14 @@ var init_conversation_manager = __esm({
656
767
  initialMessages;
657
768
  historyBuilder;
658
769
  parameterFormat;
659
- constructor(baseMessages, initialMessages, parameterFormat = "json") {
770
+ constructor(baseMessages, initialMessages, options = {}) {
660
771
  this.baseMessages = baseMessages;
661
772
  this.initialMessages = initialMessages;
662
- this.parameterFormat = parameterFormat;
773
+ this.parameterFormat = options.parameterFormat ?? "json";
663
774
  this.historyBuilder = new LLMMessageBuilder();
775
+ if (options.startPrefix && options.endPrefix) {
776
+ this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix);
777
+ }
664
778
  }
665
779
  addUserMessage(content) {
666
780
  this.historyBuilder.addUser(content);
@@ -1008,6 +1122,104 @@ var init_executor = __esm({
1008
1122
 
1009
1123
  // src/gadgets/parser.ts
1010
1124
  import * as yaml from "js-yaml";
1125
+ import { load as parseToml } from "js-toml";
1126
+ function preprocessYaml(yamlStr) {
1127
+ const lines = yamlStr.split("\n");
1128
+ const result = [];
1129
+ let i = 0;
1130
+ while (i < lines.length) {
1131
+ const line = lines[i];
1132
+ const match = line.match(/^(\s*)([\w-]+):\s+(.+)$/);
1133
+ if (match) {
1134
+ const [, indent, key, value] = match;
1135
+ if (value === "|" || value === ">" || value === "|-" || value === ">-") {
1136
+ result.push(line);
1137
+ i++;
1138
+ const keyIndentLen2 = indent.length;
1139
+ const blockLines = [];
1140
+ let minContentIndent = Infinity;
1141
+ while (i < lines.length) {
1142
+ const blockLine = lines[i];
1143
+ const blockIndentMatch = blockLine.match(/^(\s*)/);
1144
+ const blockIndentLen = blockIndentMatch ? blockIndentMatch[1].length : 0;
1145
+ if (blockLine.trim() === "") {
1146
+ blockLines.push({ content: "", originalIndent: 0 });
1147
+ i++;
1148
+ continue;
1149
+ }
1150
+ if (blockIndentLen > keyIndentLen2) {
1151
+ const content = blockLine.substring(blockIndentLen);
1152
+ blockLines.push({ content, originalIndent: blockIndentLen });
1153
+ if (content.trim().length > 0) {
1154
+ minContentIndent = Math.min(minContentIndent, blockIndentLen);
1155
+ }
1156
+ i++;
1157
+ } else {
1158
+ break;
1159
+ }
1160
+ }
1161
+ const targetIndent = keyIndentLen2 + 2;
1162
+ for (const blockLine of blockLines) {
1163
+ if (blockLine.content === "") {
1164
+ result.push("");
1165
+ } else {
1166
+ result.push(" ".repeat(targetIndent) + blockLine.content);
1167
+ }
1168
+ }
1169
+ continue;
1170
+ }
1171
+ if (value.startsWith('"') || value.startsWith("'") || value === "true" || value === "false" || /^-?\d+(\.\d+)?$/.test(value)) {
1172
+ result.push(line);
1173
+ i++;
1174
+ continue;
1175
+ }
1176
+ const keyIndentLen = indent.length;
1177
+ const continuationLines = [];
1178
+ let j = i + 1;
1179
+ while (j < lines.length) {
1180
+ const nextLine = lines[j];
1181
+ if (nextLine.trim() === "") {
1182
+ continuationLines.push(nextLine);
1183
+ j++;
1184
+ continue;
1185
+ }
1186
+ const nextIndentMatch = nextLine.match(/^(\s*)/);
1187
+ const nextIndentLen = nextIndentMatch ? nextIndentMatch[1].length : 0;
1188
+ if (nextIndentLen > keyIndentLen) {
1189
+ continuationLines.push(nextLine);
1190
+ j++;
1191
+ } else {
1192
+ break;
1193
+ }
1194
+ }
1195
+ if (continuationLines.length > 0 && continuationLines.some((l) => l.trim().length > 0)) {
1196
+ result.push(`${indent}${key}: |`);
1197
+ result.push(`${indent} ${value}`);
1198
+ for (const contLine of continuationLines) {
1199
+ if (contLine.trim() === "") {
1200
+ result.push("");
1201
+ } else {
1202
+ const contIndentMatch = contLine.match(/^(\s*)/);
1203
+ const contIndent = contIndentMatch ? contIndentMatch[1] : "";
1204
+ const contContent = contLine.substring(contIndent.length);
1205
+ result.push(`${indent} ${contContent}`);
1206
+ }
1207
+ }
1208
+ i = j;
1209
+ continue;
1210
+ }
1211
+ if (value.includes(": ") || value.endsWith(":")) {
1212
+ const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1213
+ result.push(`${indent}${key}: "${escaped}"`);
1214
+ i++;
1215
+ continue;
1216
+ }
1217
+ }
1218
+ result.push(line);
1219
+ i++;
1220
+ }
1221
+ return result.join("\n");
1222
+ }
1011
1223
  var globalInvocationCounter, StreamParser;
1012
1224
  var init_parser = __esm({
1013
1225
  "src/gadgets/parser.ts"() {
@@ -1033,6 +1245,17 @@ var init_parser = __esm({
1033
1245
  this.lastReportedTextLength = index;
1034
1246
  return segment.trim().length > 0 ? segment : void 0;
1035
1247
  }
1248
+ /**
1249
+ * Parse gadget name, handling both old format (name:invocationId) and new format (just name).
1250
+ * For new format, generates a unique invocation ID.
1251
+ */
1252
+ parseGadgetName(gadgetName) {
1253
+ if (gadgetName.includes(":")) {
1254
+ const parts = gadgetName.split(":");
1255
+ return { actualName: parts[0], invocationId: parts[1] };
1256
+ }
1257
+ return { actualName: gadgetName, invocationId: `gadget_${++globalInvocationCounter}` };
1258
+ }
1036
1259
  /**
1037
1260
  * Parse parameter string according to configured format
1038
1261
  */
@@ -1046,20 +1269,31 @@ var init_parser = __esm({
1046
1269
  }
1047
1270
  if (this.parameterFormat === "yaml") {
1048
1271
  try {
1049
- return { parameters: yaml.load(raw) };
1272
+ return { parameters: yaml.load(preprocessYaml(raw)) };
1050
1273
  } catch (error) {
1051
1274
  return { parseError: error instanceof Error ? error.message : "Failed to parse YAML" };
1052
1275
  }
1053
1276
  }
1277
+ if (this.parameterFormat === "toml") {
1278
+ try {
1279
+ return { parameters: parseToml(raw) };
1280
+ } catch (error) {
1281
+ return { parseError: error instanceof Error ? error.message : "Failed to parse TOML" };
1282
+ }
1283
+ }
1054
1284
  try {
1055
1285
  return { parameters: JSON.parse(raw) };
1056
1286
  } catch {
1057
1287
  try {
1058
- return { parameters: yaml.load(raw) };
1059
- } catch (error) {
1060
- return {
1061
- parseError: error instanceof Error ? error.message : "Failed to parse as JSON or YAML"
1062
- };
1288
+ return { parameters: parseToml(raw) };
1289
+ } catch {
1290
+ try {
1291
+ return { parameters: yaml.load(preprocessYaml(raw)) };
1292
+ } catch (error) {
1293
+ return {
1294
+ parseError: error instanceof Error ? error.message : "Failed to parse as JSON, TOML, or YAML"
1295
+ };
1296
+ }
1063
1297
  }
1064
1298
  }
1065
1299
  }
@@ -1078,16 +1312,7 @@ var init_parser = __esm({
1078
1312
  const metadataEndIndex = this.buffer.indexOf("\n", metadataStartIndex);
1079
1313
  if (metadataEndIndex === -1) break;
1080
1314
  const gadgetName = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();
1081
- let invocationId;
1082
- let actualGadgetName;
1083
- if (gadgetName.includes(":")) {
1084
- const parts = gadgetName.split(":");
1085
- actualGadgetName = parts[0];
1086
- invocationId = parts[1];
1087
- } else {
1088
- actualGadgetName = gadgetName;
1089
- invocationId = `gadget_${++globalInvocationCounter}`;
1090
- }
1315
+ const { actualName: actualGadgetName, invocationId } = this.parseGadgetName(gadgetName);
1091
1316
  const contentStartIndex = metadataEndIndex + 1;
1092
1317
  let partEndIndex;
1093
1318
  let endMarkerLength = 0;
@@ -1097,23 +1322,29 @@ var init_parser = __esm({
1097
1322
  if (partEndIndex === -1) break;
1098
1323
  endMarkerLength = oldEndMarker.length;
1099
1324
  } else {
1100
- partEndIndex = contentStartIndex;
1325
+ const nextStartPos = this.buffer.indexOf(this.startPrefix, contentStartIndex);
1326
+ let validEndPos = -1;
1327
+ let searchPos = contentStartIndex;
1101
1328
  while (true) {
1102
- const endPos = this.buffer.indexOf(this.endPrefix, partEndIndex);
1103
- if (endPos === -1) {
1104
- partEndIndex = -1;
1105
- break;
1106
- }
1329
+ const endPos = this.buffer.indexOf(this.endPrefix, searchPos);
1330
+ if (endPos === -1) break;
1107
1331
  const afterEnd = this.buffer.substring(endPos + this.endPrefix.length);
1108
1332
  if (afterEnd.startsWith("\n") || afterEnd.startsWith("\r") || afterEnd.startsWith(this.startPrefix) || afterEnd.length === 0) {
1109
- partEndIndex = endPos;
1110
- endMarkerLength = this.endPrefix.length;
1333
+ validEndPos = endPos;
1111
1334
  break;
1112
1335
  } else {
1113
- partEndIndex = endPos + this.endPrefix.length;
1336
+ searchPos = endPos + this.endPrefix.length;
1114
1337
  }
1115
1338
  }
1116
- if (partEndIndex === -1) break;
1339
+ if (nextStartPos !== -1 && (validEndPos === -1 || nextStartPos < validEndPos)) {
1340
+ partEndIndex = nextStartPos;
1341
+ endMarkerLength = 0;
1342
+ } else if (validEndPos !== -1) {
1343
+ partEndIndex = validEndPos;
1344
+ endMarkerLength = this.endPrefix.length;
1345
+ } else {
1346
+ break;
1347
+ }
1117
1348
  }
1118
1349
  const parametersRaw = this.buffer.substring(contentStartIndex, partEndIndex).trim();
1119
1350
  const { parameters, parseError } = this.parseParameters(parametersRaw);
@@ -1136,8 +1367,35 @@ var init_parser = __esm({
1136
1367
  this.lastReportedTextLength = 0;
1137
1368
  }
1138
1369
  }
1139
- // Finalize parsing and return remaining text
1370
+ // Finalize parsing and return remaining text or incomplete gadgets
1140
1371
  *finalize() {
1372
+ const startIndex = this.buffer.indexOf(this.startPrefix, this.lastReportedTextLength);
1373
+ if (startIndex !== -1) {
1374
+ const textBefore = this.takeTextUntil(startIndex);
1375
+ if (textBefore !== void 0) {
1376
+ yield { type: "text", content: textBefore };
1377
+ }
1378
+ const metadataStartIndex = startIndex + this.startPrefix.length;
1379
+ const metadataEndIndex = this.buffer.indexOf("\n", metadataStartIndex);
1380
+ if (metadataEndIndex !== -1) {
1381
+ const gadgetName = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();
1382
+ const { actualName: actualGadgetName, invocationId } = this.parseGadgetName(gadgetName);
1383
+ const contentStartIndex = metadataEndIndex + 1;
1384
+ const parametersRaw = this.buffer.substring(contentStartIndex).trim();
1385
+ const { parameters, parseError } = this.parseParameters(parametersRaw);
1386
+ yield {
1387
+ type: "gadget_call",
1388
+ call: {
1389
+ gadgetName: actualGadgetName,
1390
+ invocationId,
1391
+ parametersYaml: parametersRaw,
1392
+ parameters,
1393
+ parseError
1394
+ }
1395
+ };
1396
+ return;
1397
+ }
1398
+ }
1141
1399
  const remainingText = this.takeTextUntil(this.buffer.length);
1142
1400
  if (remainingText !== void 0) {
1143
1401
  yield { type: "text", content: remainingText };
@@ -3231,11 +3489,11 @@ var init_agent = __esm({
3231
3489
  role: message.role,
3232
3490
  content: message.content
3233
3491
  }));
3234
- this.conversation = new ConversationManager(
3235
- baseMessages,
3236
- initialMessages,
3237
- this.parameterFormat
3238
- );
3492
+ this.conversation = new ConversationManager(baseMessages, initialMessages, {
3493
+ parameterFormat: this.parameterFormat,
3494
+ startPrefix: options.gadgetStartPrefix,
3495
+ endPrefix: options.gadgetEndPrefix
3496
+ });
3239
3497
  this.userPromptProvided = !!options.userPrompt;
3240
3498
  if (options.userPrompt) {
3241
3499
  this.conversation.addUserMessage(options.userPrompt);
@@ -4381,6 +4639,83 @@ function mergeDescriptions(schema, jsonSchema) {
4381
4639
 
4382
4640
  // src/gadgets/gadget.ts
4383
4641
  init_schema_validator();
4642
+ function formatYamlValue(value, indent = "") {
4643
+ if (typeof value === "string") {
4644
+ const lines = value.split("\n");
4645
+ if (lines.length === 1 && !value.includes(":") && !value.startsWith("-")) {
4646
+ return value;
4647
+ }
4648
+ const indentedLines = lines.map((line) => `${indent} ${line}`).join("\n");
4649
+ return `|
4650
+ ${indentedLines}`;
4651
+ }
4652
+ if (typeof value === "number" || typeof value === "boolean") {
4653
+ return String(value);
4654
+ }
4655
+ if (value === null || value === void 0) {
4656
+ return "null";
4657
+ }
4658
+ if (Array.isArray(value)) {
4659
+ if (value.length === 0) return "[]";
4660
+ const items = value.map((item) => `${indent}- ${formatYamlValue(item, indent + " ")}`);
4661
+ return "\n" + items.join("\n");
4662
+ }
4663
+ if (typeof value === "object") {
4664
+ const entries = Object.entries(value);
4665
+ if (entries.length === 0) return "{}";
4666
+ const lines = entries.map(([k, v]) => {
4667
+ const formattedValue = formatYamlValue(v, indent + " ");
4668
+ if (formattedValue.startsWith("\n") || formattedValue.startsWith("|")) {
4669
+ return `${indent}${k}: ${formattedValue}`;
4670
+ }
4671
+ return `${indent}${k}: ${formattedValue}`;
4672
+ });
4673
+ return "\n" + lines.join("\n");
4674
+ }
4675
+ return yaml2.dump(value).trimEnd();
4676
+ }
4677
+ function formatParamsAsYaml(params) {
4678
+ const lines = [];
4679
+ for (const [key, value] of Object.entries(params)) {
4680
+ const formattedValue = formatYamlValue(value, "");
4681
+ if (formattedValue.startsWith("\n")) {
4682
+ lines.push(`${key}:${formattedValue}`);
4683
+ } else {
4684
+ lines.push(`${key}: ${formattedValue}`);
4685
+ }
4686
+ }
4687
+ return lines.join("\n");
4688
+ }
4689
+ function formatTomlValue(value) {
4690
+ if (typeof value === "string") {
4691
+ if (value.includes("\n")) {
4692
+ return `"""
4693
+ ${value}
4694
+ """`;
4695
+ }
4696
+ return JSON.stringify(value);
4697
+ }
4698
+ if (typeof value === "number" || typeof value === "boolean") {
4699
+ return String(value);
4700
+ }
4701
+ if (value === null || value === void 0) {
4702
+ return '""';
4703
+ }
4704
+ if (Array.isArray(value)) {
4705
+ return JSON.stringify(value);
4706
+ }
4707
+ if (typeof value === "object") {
4708
+ return JSON.stringify(value);
4709
+ }
4710
+ return JSON.stringify(value);
4711
+ }
4712
+ function formatParamsAsToml(params) {
4713
+ const lines = [];
4714
+ for (const [key, value] of Object.entries(params)) {
4715
+ lines.push(`${key} = ${formatTomlValue(value)}`);
4716
+ }
4717
+ return lines.join("\n");
4718
+ }
4384
4719
  var BaseGadget = class {
4385
4720
  /**
4386
4721
  * The name of the gadget. Used for identification when LLM calls it.
@@ -4400,6 +4735,14 @@ var BaseGadget = class {
4400
4735
  * Set to 0 or undefined to disable timeout for this gadget.
4401
4736
  */
4402
4737
  timeoutMs;
4738
+ /**
4739
+ * Optional usage examples to help LLMs understand proper invocation.
4740
+ * Examples are rendered in getInstruction() alongside the schema.
4741
+ *
4742
+ * Note: Uses broader `unknown` type to allow typed examples from subclasses
4743
+ * while maintaining runtime compatibility.
4744
+ */
4745
+ examples;
4403
4746
  /**
4404
4747
  * Auto-generated instruction text for the LLM.
4405
4748
  * Combines name, description, and parameter schema into a formatted instruction.
@@ -4412,7 +4755,7 @@ var BaseGadget = class {
4412
4755
  * Generate instruction text for the LLM with format-specific schema.
4413
4756
  * Combines name, description, and parameter schema into a formatted instruction.
4414
4757
  *
4415
- * @param format - Format for the schema representation ('json' | 'yaml' | 'auto')
4758
+ * @param format - Format for the schema representation ('json' | 'yaml' | 'toml' | 'auto')
4416
4759
  * @returns Formatted instruction string
4417
4760
  */
4418
4761
  getInstruction(format = "json") {
@@ -4427,12 +4770,38 @@ var BaseGadget = class {
4427
4770
  if (format === "json" || format === "auto") {
4428
4771
  parts.push("\n\nInput Schema (JSON):");
4429
4772
  parts.push(JSON.stringify(jsonSchema, null, 2));
4773
+ } else if (format === "toml") {
4774
+ parts.push("\n\nInput Schema (TOML):");
4775
+ parts.push(JSON.stringify(jsonSchema, null, 2));
4430
4776
  } else {
4431
4777
  const yamlSchema = yaml2.dump(jsonSchema).trimEnd();
4432
4778
  parts.push("\n\nInput Schema (YAML):");
4433
4779
  parts.push(yamlSchema);
4434
4780
  }
4435
4781
  }
4782
+ if (this.examples && this.examples.length > 0) {
4783
+ parts.push("\n\nExamples:");
4784
+ this.examples.forEach((example, index) => {
4785
+ if (index > 0) {
4786
+ parts.push("");
4787
+ }
4788
+ if (example.comment) {
4789
+ parts.push(`# ${example.comment}`);
4790
+ }
4791
+ parts.push("Input:");
4792
+ if (format === "json" || format === "auto") {
4793
+ parts.push(JSON.stringify(example.params, null, 2));
4794
+ } else if (format === "toml") {
4795
+ parts.push(formatParamsAsToml(example.params));
4796
+ } else {
4797
+ parts.push(formatParamsAsYaml(example.params));
4798
+ }
4799
+ if (example.output !== void 0) {
4800
+ parts.push("Output:");
4801
+ parts.push(example.output);
4802
+ }
4803
+ });
4804
+ }
4436
4805
  return parts.join("\n");
4437
4806
  }
4438
4807
  };
@@ -4499,4 +4868,4 @@ export {
4499
4868
  init_builder,
4500
4869
  BaseGadget
4501
4870
  };
4502
- //# sourceMappingURL=chunk-LQE7TKKW.js.map
4871
+ //# sourceMappingURL=chunk-MH4TQ5AD.js.map