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.
- package/README.md +4 -1
- package/dist/{chunk-QVDGTUQN.js → chunk-LKIBXQ5I.js} +3 -2
- package/dist/chunk-LKIBXQ5I.js.map +1 -0
- package/dist/{chunk-LQE7TKKW.js → chunk-MH4TQ5AD.js} +429 -60
- package/dist/chunk-MH4TQ5AD.js.map +1 -0
- package/dist/{chunk-A4GRCCXF.js → chunk-VF2WOCHM.js} +2 -2
- package/dist/cli.cjs +1201 -165
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +773 -107
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +431 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -4
- package/dist/index.d.ts +19 -4
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/{mock-stream-C0vOqI3L.d.cts → mock-stream-C8mBXRzJ.d.cts} +58 -3
- package/dist/{mock-stream-C0vOqI3L.d.ts → mock-stream-C8mBXRzJ.d.ts} +58 -3
- package/dist/testing/index.cjs +429 -60
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +2 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +2 -2
- package/package.json +5 -1
- package/dist/chunk-LQE7TKKW.js.map +0 -1
- package/dist/chunk-QVDGTUQN.js.map +0 -1
- /package/dist/{chunk-A4GRCCXF.js.map → chunk-VF2WOCHM.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -384,6 +384,7 @@ var init_prompt_config = __esm({
|
|
|
384
384
|
criticalUsage: "INVOKE gadgets using the markers - do not describe what you want to do.",
|
|
385
385
|
formatDescriptionYaml: "Parameters in YAML format (one per line)",
|
|
386
386
|
formatDescriptionJson: "Parameters in JSON format (valid JSON object)",
|
|
387
|
+
formatDescriptionToml: "Parameters in TOML format (key = value pairs, use triple-quotes for multiline)",
|
|
387
388
|
rules: () => [
|
|
388
389
|
"Output ONLY plain text with the exact markers - never use function/tool calling",
|
|
389
390
|
"You can invoke multiple gadgets in a single response",
|
|
@@ -391,6 +392,7 @@ var init_prompt_config = __esm({
|
|
|
391
392
|
],
|
|
392
393
|
schemaLabelJson: "\n\nInput Schema (JSON):",
|
|
393
394
|
schemaLabelYaml: "\n\nInput Schema (YAML):",
|
|
395
|
+
schemaLabelToml: "\n\nInput Schema (TOML):",
|
|
394
396
|
customExamples: null
|
|
395
397
|
};
|
|
396
398
|
}
|
|
@@ -411,6 +413,15 @@ var init_messages = __esm({
|
|
|
411
413
|
constructor(promptConfig) {
|
|
412
414
|
this.promptConfig = promptConfig ?? {};
|
|
413
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* Set custom prefixes for gadget markers.
|
|
418
|
+
* Used to configure history builder to match system prompt markers.
|
|
419
|
+
*/
|
|
420
|
+
withPrefixes(startPrefix, endPrefix) {
|
|
421
|
+
this.startPrefix = startPrefix;
|
|
422
|
+
this.endPrefix = endPrefix;
|
|
423
|
+
return this;
|
|
424
|
+
}
|
|
414
425
|
addSystem(content, metadata) {
|
|
415
426
|
this.messages.push({ role: "system", content, metadata });
|
|
416
427
|
return this;
|
|
@@ -448,7 +459,14 @@ var init_messages = __esm({
|
|
|
448
459
|
for (const gadget of gadgets) {
|
|
449
460
|
const gadgetName = gadget.name ?? gadget.constructor.name;
|
|
450
461
|
const instruction = gadget.getInstruction(parameterFormat);
|
|
451
|
-
const
|
|
462
|
+
const schemaMarkers = {
|
|
463
|
+
yaml: "\n\nInput Schema (YAML):",
|
|
464
|
+
json: "\n\nInput Schema (JSON):",
|
|
465
|
+
toml: "\n\nInput Schema (TOML):",
|
|
466
|
+
auto: "\n\nInput Schema (JSON):"
|
|
467
|
+
// auto defaults to JSON schema display
|
|
468
|
+
};
|
|
469
|
+
const schemaMarker = schemaMarkers[parameterFormat];
|
|
452
470
|
const schemaIndex = instruction.indexOf(schemaMarker);
|
|
453
471
|
const description = (schemaIndex !== -1 ? instruction.substring(0, schemaIndex) : instruction).trim();
|
|
454
472
|
const schema = schemaIndex !== -1 ? instruction.substring(schemaIndex + schemaMarker.length).trim() : "";
|
|
@@ -468,15 +486,26 @@ ${schema}`);
|
|
|
468
486
|
}
|
|
469
487
|
buildUsageSection(parameterFormat, context) {
|
|
470
488
|
const parts = [];
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
489
|
+
const formatDescriptionMap = {
|
|
490
|
+
yaml: {
|
|
491
|
+
config: this.promptConfig.formatDescriptionYaml,
|
|
492
|
+
defaultValue: DEFAULT_PROMPTS.formatDescriptionYaml
|
|
493
|
+
},
|
|
494
|
+
json: {
|
|
495
|
+
config: this.promptConfig.formatDescriptionJson,
|
|
496
|
+
defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
|
|
497
|
+
},
|
|
498
|
+
toml: {
|
|
499
|
+
config: this.promptConfig.formatDescriptionToml,
|
|
500
|
+
defaultValue: DEFAULT_PROMPTS.formatDescriptionToml
|
|
501
|
+
},
|
|
502
|
+
auto: {
|
|
503
|
+
config: this.promptConfig.formatDescriptionJson,
|
|
504
|
+
defaultValue: DEFAULT_PROMPTS.formatDescriptionJson
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
const { config, defaultValue } = formatDescriptionMap[parameterFormat];
|
|
508
|
+
const formatDescription = resolvePromptTemplate(config, defaultValue, context);
|
|
480
509
|
parts.push("\n\nHOW TO INVOKE GADGETS");
|
|
481
510
|
parts.push("\n=====================\n");
|
|
482
511
|
const criticalUsage = resolvePromptTemplate(
|
|
@@ -504,38 +533,110 @@ CRITICAL: ${criticalUsage}
|
|
|
504
533
|
return this.promptConfig.customExamples(context);
|
|
505
534
|
}
|
|
506
535
|
const parts = [];
|
|
507
|
-
const
|
|
536
|
+
const singleExamples = {
|
|
537
|
+
yaml: `${this.startPrefix}translate
|
|
508
538
|
from: English
|
|
509
539
|
to: Polish
|
|
510
|
-
content: Paris is the capital of France.
|
|
511
|
-
${this.endPrefix}
|
|
512
|
-
|
|
513
|
-
|
|
540
|
+
content: "Paris is the capital of France: a beautiful city."
|
|
541
|
+
${this.endPrefix}`,
|
|
542
|
+
json: `${this.startPrefix}translate
|
|
543
|
+
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
544
|
+
${this.endPrefix}`,
|
|
545
|
+
toml: `${this.startPrefix}translate
|
|
546
|
+
from = "English"
|
|
547
|
+
to = "Polish"
|
|
548
|
+
content = "Paris is the capital of France: a beautiful city."
|
|
549
|
+
${this.endPrefix}`,
|
|
550
|
+
auto: `${this.startPrefix}translate
|
|
551
|
+
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
552
|
+
${this.endPrefix}`
|
|
553
|
+
};
|
|
514
554
|
parts.push(`
|
|
515
555
|
|
|
516
556
|
EXAMPLE (Single Gadget):
|
|
517
557
|
|
|
518
|
-
${
|
|
519
|
-
const
|
|
558
|
+
${singleExamples[parameterFormat]}`);
|
|
559
|
+
const multipleExamples = {
|
|
560
|
+
yaml: `${this.startPrefix}translate
|
|
520
561
|
from: English
|
|
521
562
|
to: Polish
|
|
522
|
-
content: Paris is the capital of France.
|
|
563
|
+
content: "Paris is the capital of France: a beautiful city."
|
|
523
564
|
${this.endPrefix}
|
|
524
565
|
${this.startPrefix}analyze
|
|
525
566
|
type: economic_analysis
|
|
526
567
|
matter: "Polish Economy"
|
|
527
|
-
question:
|
|
528
|
-
|
|
529
|
-
|
|
568
|
+
question: |
|
|
569
|
+
Analyze the following:
|
|
570
|
+
- Polish arms exports 2025
|
|
571
|
+
- Economic implications
|
|
572
|
+
${this.endPrefix}`,
|
|
573
|
+
json: `${this.startPrefix}translate
|
|
574
|
+
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
575
|
+
${this.endPrefix}
|
|
576
|
+
${this.startPrefix}analyze
|
|
577
|
+
{"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
|
|
578
|
+
${this.endPrefix}`,
|
|
579
|
+
toml: `${this.startPrefix}translate
|
|
580
|
+
from = "English"
|
|
581
|
+
to = "Polish"
|
|
582
|
+
content = "Paris is the capital of France: a beautiful city."
|
|
530
583
|
${this.endPrefix}
|
|
531
584
|
${this.startPrefix}analyze
|
|
532
|
-
|
|
533
|
-
|
|
585
|
+
type = "economic_analysis"
|
|
586
|
+
matter = "Polish Economy"
|
|
587
|
+
question = """
|
|
588
|
+
Analyze the following:
|
|
589
|
+
- Polish arms exports 2025
|
|
590
|
+
- Economic implications
|
|
591
|
+
"""
|
|
592
|
+
${this.endPrefix}`,
|
|
593
|
+
auto: `${this.startPrefix}translate
|
|
594
|
+
{"from": "English", "to": "Polish", "content": "Paris is the capital of France: a beautiful city."}
|
|
595
|
+
${this.endPrefix}
|
|
596
|
+
${this.startPrefix}analyze
|
|
597
|
+
{"type": "economic_analysis", "matter": "Polish Economy", "question": "Analyze the following: Polish arms exports 2025, economic implications"}
|
|
598
|
+
${this.endPrefix}`
|
|
599
|
+
};
|
|
534
600
|
parts.push(`
|
|
535
601
|
|
|
536
602
|
EXAMPLE (Multiple Gadgets):
|
|
537
603
|
|
|
538
|
-
${
|
|
604
|
+
${multipleExamples[parameterFormat]}`);
|
|
605
|
+
if (parameterFormat === "yaml") {
|
|
606
|
+
parts.push(`
|
|
607
|
+
|
|
608
|
+
YAML MULTILINE SYNTAX:
|
|
609
|
+
For string values with special characters (colons, dashes, quotes) or multiple lines,
|
|
610
|
+
use the pipe (|) syntax. ALL content lines MUST be indented with 2 spaces:
|
|
611
|
+
|
|
612
|
+
CORRECT - all lines indented:
|
|
613
|
+
question: |
|
|
614
|
+
Which option do you prefer?
|
|
615
|
+
- Option A: fast processing
|
|
616
|
+
- Option B: thorough analysis
|
|
617
|
+
Please choose one.
|
|
618
|
+
|
|
619
|
+
WRONG - inconsistent indentation breaks YAML:
|
|
620
|
+
question: |
|
|
621
|
+
Which option do you prefer?
|
|
622
|
+
- Option A: fast
|
|
623
|
+
Please choose one. <-- ERROR: not indented, breaks out of the block`);
|
|
624
|
+
} else if (parameterFormat === "toml") {
|
|
625
|
+
parts.push(`
|
|
626
|
+
|
|
627
|
+
TOML MULTILINE SYNTAX:
|
|
628
|
+
For string values with multiple lines or special characters, use triple-quotes ("""):
|
|
629
|
+
|
|
630
|
+
filePath = "README.md"
|
|
631
|
+
content = """
|
|
632
|
+
# Project Title
|
|
633
|
+
|
|
634
|
+
This content can contain:
|
|
635
|
+
- Markdown lists
|
|
636
|
+
- Special characters: # : -
|
|
637
|
+
- Multiple paragraphs
|
|
638
|
+
"""`);
|
|
639
|
+
}
|
|
539
640
|
return parts.join("");
|
|
540
641
|
}
|
|
541
642
|
buildRulesSection(context) {
|
|
@@ -579,6 +680,16 @@ ${this.endPrefix}`
|
|
|
579
680
|
return `${key}: ${JSON.stringify(value)}`;
|
|
580
681
|
}).join("\n");
|
|
581
682
|
}
|
|
683
|
+
if (format === "toml") {
|
|
684
|
+
return Object.entries(parameters).map(([key, value]) => {
|
|
685
|
+
if (typeof value === "string" && value.includes("\n")) {
|
|
686
|
+
return `${key} = """
|
|
687
|
+
${value}
|
|
688
|
+
"""`;
|
|
689
|
+
}
|
|
690
|
+
return `${key} = ${JSON.stringify(value)}`;
|
|
691
|
+
}).join("\n");
|
|
692
|
+
}
|
|
582
693
|
return JSON.stringify(parameters);
|
|
583
694
|
}
|
|
584
695
|
build() {
|
|
@@ -680,11 +791,14 @@ var init_conversation_manager = __esm({
|
|
|
680
791
|
initialMessages;
|
|
681
792
|
historyBuilder;
|
|
682
793
|
parameterFormat;
|
|
683
|
-
constructor(baseMessages, initialMessages,
|
|
794
|
+
constructor(baseMessages, initialMessages, options = {}) {
|
|
684
795
|
this.baseMessages = baseMessages;
|
|
685
796
|
this.initialMessages = initialMessages;
|
|
686
|
-
this.parameterFormat = parameterFormat;
|
|
797
|
+
this.parameterFormat = options.parameterFormat ?? "json";
|
|
687
798
|
this.historyBuilder = new LLMMessageBuilder();
|
|
799
|
+
if (options.startPrefix && options.endPrefix) {
|
|
800
|
+
this.historyBuilder.withPrefixes(options.startPrefix, options.endPrefix);
|
|
801
|
+
}
|
|
688
802
|
}
|
|
689
803
|
addUserMessage(content) {
|
|
690
804
|
this.historyBuilder.addUser(content);
|
|
@@ -1185,11 +1299,109 @@ var init_executor = __esm({
|
|
|
1185
1299
|
});
|
|
1186
1300
|
|
|
1187
1301
|
// src/gadgets/parser.ts
|
|
1188
|
-
|
|
1302
|
+
function preprocessYaml(yamlStr) {
|
|
1303
|
+
const lines = yamlStr.split("\n");
|
|
1304
|
+
const result = [];
|
|
1305
|
+
let i = 0;
|
|
1306
|
+
while (i < lines.length) {
|
|
1307
|
+
const line = lines[i];
|
|
1308
|
+
const match = line.match(/^(\s*)([\w-]+):\s+(.+)$/);
|
|
1309
|
+
if (match) {
|
|
1310
|
+
const [, indent, key, value] = match;
|
|
1311
|
+
if (value === "|" || value === ">" || value === "|-" || value === ">-") {
|
|
1312
|
+
result.push(line);
|
|
1313
|
+
i++;
|
|
1314
|
+
const keyIndentLen2 = indent.length;
|
|
1315
|
+
const blockLines = [];
|
|
1316
|
+
let minContentIndent = Infinity;
|
|
1317
|
+
while (i < lines.length) {
|
|
1318
|
+
const blockLine = lines[i];
|
|
1319
|
+
const blockIndentMatch = blockLine.match(/^(\s*)/);
|
|
1320
|
+
const blockIndentLen = blockIndentMatch ? blockIndentMatch[1].length : 0;
|
|
1321
|
+
if (blockLine.trim() === "") {
|
|
1322
|
+
blockLines.push({ content: "", originalIndent: 0 });
|
|
1323
|
+
i++;
|
|
1324
|
+
continue;
|
|
1325
|
+
}
|
|
1326
|
+
if (blockIndentLen > keyIndentLen2) {
|
|
1327
|
+
const content = blockLine.substring(blockIndentLen);
|
|
1328
|
+
blockLines.push({ content, originalIndent: blockIndentLen });
|
|
1329
|
+
if (content.trim().length > 0) {
|
|
1330
|
+
minContentIndent = Math.min(minContentIndent, blockIndentLen);
|
|
1331
|
+
}
|
|
1332
|
+
i++;
|
|
1333
|
+
} else {
|
|
1334
|
+
break;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
const targetIndent = keyIndentLen2 + 2;
|
|
1338
|
+
for (const blockLine of blockLines) {
|
|
1339
|
+
if (blockLine.content === "") {
|
|
1340
|
+
result.push("");
|
|
1341
|
+
} else {
|
|
1342
|
+
result.push(" ".repeat(targetIndent) + blockLine.content);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
continue;
|
|
1346
|
+
}
|
|
1347
|
+
if (value.startsWith('"') || value.startsWith("'") || value === "true" || value === "false" || /^-?\d+(\.\d+)?$/.test(value)) {
|
|
1348
|
+
result.push(line);
|
|
1349
|
+
i++;
|
|
1350
|
+
continue;
|
|
1351
|
+
}
|
|
1352
|
+
const keyIndentLen = indent.length;
|
|
1353
|
+
const continuationLines = [];
|
|
1354
|
+
let j = i + 1;
|
|
1355
|
+
while (j < lines.length) {
|
|
1356
|
+
const nextLine = lines[j];
|
|
1357
|
+
if (nextLine.trim() === "") {
|
|
1358
|
+
continuationLines.push(nextLine);
|
|
1359
|
+
j++;
|
|
1360
|
+
continue;
|
|
1361
|
+
}
|
|
1362
|
+
const nextIndentMatch = nextLine.match(/^(\s*)/);
|
|
1363
|
+
const nextIndentLen = nextIndentMatch ? nextIndentMatch[1].length : 0;
|
|
1364
|
+
if (nextIndentLen > keyIndentLen) {
|
|
1365
|
+
continuationLines.push(nextLine);
|
|
1366
|
+
j++;
|
|
1367
|
+
} else {
|
|
1368
|
+
break;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
if (continuationLines.length > 0 && continuationLines.some((l) => l.trim().length > 0)) {
|
|
1372
|
+
result.push(`${indent}${key}: |`);
|
|
1373
|
+
result.push(`${indent} ${value}`);
|
|
1374
|
+
for (const contLine of continuationLines) {
|
|
1375
|
+
if (contLine.trim() === "") {
|
|
1376
|
+
result.push("");
|
|
1377
|
+
} else {
|
|
1378
|
+
const contIndentMatch = contLine.match(/^(\s*)/);
|
|
1379
|
+
const contIndent = contIndentMatch ? contIndentMatch[1] : "";
|
|
1380
|
+
const contContent = contLine.substring(contIndent.length);
|
|
1381
|
+
result.push(`${indent} ${contContent}`);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
i = j;
|
|
1385
|
+
continue;
|
|
1386
|
+
}
|
|
1387
|
+
if (value.includes(": ") || value.endsWith(":")) {
|
|
1388
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
1389
|
+
result.push(`${indent}${key}: "${escaped}"`);
|
|
1390
|
+
i++;
|
|
1391
|
+
continue;
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
result.push(line);
|
|
1395
|
+
i++;
|
|
1396
|
+
}
|
|
1397
|
+
return result.join("\n");
|
|
1398
|
+
}
|
|
1399
|
+
var yaml, import_js_toml, globalInvocationCounter, StreamParser;
|
|
1189
1400
|
var init_parser = __esm({
|
|
1190
1401
|
"src/gadgets/parser.ts"() {
|
|
1191
1402
|
"use strict";
|
|
1192
1403
|
yaml = __toESM(require("js-yaml"), 1);
|
|
1404
|
+
import_js_toml = require("js-toml");
|
|
1193
1405
|
init_constants();
|
|
1194
1406
|
globalInvocationCounter = 0;
|
|
1195
1407
|
StreamParser = class {
|
|
@@ -1211,6 +1423,17 @@ var init_parser = __esm({
|
|
|
1211
1423
|
this.lastReportedTextLength = index;
|
|
1212
1424
|
return segment.trim().length > 0 ? segment : void 0;
|
|
1213
1425
|
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Parse gadget name, handling both old format (name:invocationId) and new format (just name).
|
|
1428
|
+
* For new format, generates a unique invocation ID.
|
|
1429
|
+
*/
|
|
1430
|
+
parseGadgetName(gadgetName) {
|
|
1431
|
+
if (gadgetName.includes(":")) {
|
|
1432
|
+
const parts = gadgetName.split(":");
|
|
1433
|
+
return { actualName: parts[0], invocationId: parts[1] };
|
|
1434
|
+
}
|
|
1435
|
+
return { actualName: gadgetName, invocationId: `gadget_${++globalInvocationCounter}` };
|
|
1436
|
+
}
|
|
1214
1437
|
/**
|
|
1215
1438
|
* Parse parameter string according to configured format
|
|
1216
1439
|
*/
|
|
@@ -1224,20 +1447,31 @@ var init_parser = __esm({
|
|
|
1224
1447
|
}
|
|
1225
1448
|
if (this.parameterFormat === "yaml") {
|
|
1226
1449
|
try {
|
|
1227
|
-
return { parameters: yaml.load(raw) };
|
|
1450
|
+
return { parameters: yaml.load(preprocessYaml(raw)) };
|
|
1228
1451
|
} catch (error) {
|
|
1229
1452
|
return { parseError: error instanceof Error ? error.message : "Failed to parse YAML" };
|
|
1230
1453
|
}
|
|
1231
1454
|
}
|
|
1455
|
+
if (this.parameterFormat === "toml") {
|
|
1456
|
+
try {
|
|
1457
|
+
return { parameters: (0, import_js_toml.load)(raw) };
|
|
1458
|
+
} catch (error) {
|
|
1459
|
+
return { parseError: error instanceof Error ? error.message : "Failed to parse TOML" };
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1232
1462
|
try {
|
|
1233
1463
|
return { parameters: JSON.parse(raw) };
|
|
1234
1464
|
} catch {
|
|
1235
1465
|
try {
|
|
1236
|
-
return { parameters:
|
|
1237
|
-
} catch
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
}
|
|
1466
|
+
return { parameters: (0, import_js_toml.load)(raw) };
|
|
1467
|
+
} catch {
|
|
1468
|
+
try {
|
|
1469
|
+
return { parameters: yaml.load(preprocessYaml(raw)) };
|
|
1470
|
+
} catch (error) {
|
|
1471
|
+
return {
|
|
1472
|
+
parseError: error instanceof Error ? error.message : "Failed to parse as JSON, TOML, or YAML"
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1241
1475
|
}
|
|
1242
1476
|
}
|
|
1243
1477
|
}
|
|
@@ -1256,16 +1490,7 @@ var init_parser = __esm({
|
|
|
1256
1490
|
const metadataEndIndex = this.buffer.indexOf("\n", metadataStartIndex);
|
|
1257
1491
|
if (metadataEndIndex === -1) break;
|
|
1258
1492
|
const gadgetName = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();
|
|
1259
|
-
|
|
1260
|
-
let actualGadgetName;
|
|
1261
|
-
if (gadgetName.includes(":")) {
|
|
1262
|
-
const parts = gadgetName.split(":");
|
|
1263
|
-
actualGadgetName = parts[0];
|
|
1264
|
-
invocationId = parts[1];
|
|
1265
|
-
} else {
|
|
1266
|
-
actualGadgetName = gadgetName;
|
|
1267
|
-
invocationId = `gadget_${++globalInvocationCounter}`;
|
|
1268
|
-
}
|
|
1493
|
+
const { actualName: actualGadgetName, invocationId } = this.parseGadgetName(gadgetName);
|
|
1269
1494
|
const contentStartIndex = metadataEndIndex + 1;
|
|
1270
1495
|
let partEndIndex;
|
|
1271
1496
|
let endMarkerLength = 0;
|
|
@@ -1275,23 +1500,29 @@ var init_parser = __esm({
|
|
|
1275
1500
|
if (partEndIndex === -1) break;
|
|
1276
1501
|
endMarkerLength = oldEndMarker.length;
|
|
1277
1502
|
} else {
|
|
1278
|
-
|
|
1503
|
+
const nextStartPos = this.buffer.indexOf(this.startPrefix, contentStartIndex);
|
|
1504
|
+
let validEndPos = -1;
|
|
1505
|
+
let searchPos = contentStartIndex;
|
|
1279
1506
|
while (true) {
|
|
1280
|
-
const endPos = this.buffer.indexOf(this.endPrefix,
|
|
1281
|
-
if (endPos === -1)
|
|
1282
|
-
partEndIndex = -1;
|
|
1283
|
-
break;
|
|
1284
|
-
}
|
|
1507
|
+
const endPos = this.buffer.indexOf(this.endPrefix, searchPos);
|
|
1508
|
+
if (endPos === -1) break;
|
|
1285
1509
|
const afterEnd = this.buffer.substring(endPos + this.endPrefix.length);
|
|
1286
1510
|
if (afterEnd.startsWith("\n") || afterEnd.startsWith("\r") || afterEnd.startsWith(this.startPrefix) || afterEnd.length === 0) {
|
|
1287
|
-
|
|
1288
|
-
endMarkerLength = this.endPrefix.length;
|
|
1511
|
+
validEndPos = endPos;
|
|
1289
1512
|
break;
|
|
1290
1513
|
} else {
|
|
1291
|
-
|
|
1514
|
+
searchPos = endPos + this.endPrefix.length;
|
|
1292
1515
|
}
|
|
1293
1516
|
}
|
|
1294
|
-
if (
|
|
1517
|
+
if (nextStartPos !== -1 && (validEndPos === -1 || nextStartPos < validEndPos)) {
|
|
1518
|
+
partEndIndex = nextStartPos;
|
|
1519
|
+
endMarkerLength = 0;
|
|
1520
|
+
} else if (validEndPos !== -1) {
|
|
1521
|
+
partEndIndex = validEndPos;
|
|
1522
|
+
endMarkerLength = this.endPrefix.length;
|
|
1523
|
+
} else {
|
|
1524
|
+
break;
|
|
1525
|
+
}
|
|
1295
1526
|
}
|
|
1296
1527
|
const parametersRaw = this.buffer.substring(contentStartIndex, partEndIndex).trim();
|
|
1297
1528
|
const { parameters, parseError } = this.parseParameters(parametersRaw);
|
|
@@ -1314,8 +1545,35 @@ var init_parser = __esm({
|
|
|
1314
1545
|
this.lastReportedTextLength = 0;
|
|
1315
1546
|
}
|
|
1316
1547
|
}
|
|
1317
|
-
// Finalize parsing and return remaining text
|
|
1548
|
+
// Finalize parsing and return remaining text or incomplete gadgets
|
|
1318
1549
|
*finalize() {
|
|
1550
|
+
const startIndex = this.buffer.indexOf(this.startPrefix, this.lastReportedTextLength);
|
|
1551
|
+
if (startIndex !== -1) {
|
|
1552
|
+
const textBefore = this.takeTextUntil(startIndex);
|
|
1553
|
+
if (textBefore !== void 0) {
|
|
1554
|
+
yield { type: "text", content: textBefore };
|
|
1555
|
+
}
|
|
1556
|
+
const metadataStartIndex = startIndex + this.startPrefix.length;
|
|
1557
|
+
const metadataEndIndex = this.buffer.indexOf("\n", metadataStartIndex);
|
|
1558
|
+
if (metadataEndIndex !== -1) {
|
|
1559
|
+
const gadgetName = this.buffer.substring(metadataStartIndex, metadataEndIndex).trim();
|
|
1560
|
+
const { actualName: actualGadgetName, invocationId } = this.parseGadgetName(gadgetName);
|
|
1561
|
+
const contentStartIndex = metadataEndIndex + 1;
|
|
1562
|
+
const parametersRaw = this.buffer.substring(contentStartIndex).trim();
|
|
1563
|
+
const { parameters, parseError } = this.parseParameters(parametersRaw);
|
|
1564
|
+
yield {
|
|
1565
|
+
type: "gadget_call",
|
|
1566
|
+
call: {
|
|
1567
|
+
gadgetName: actualGadgetName,
|
|
1568
|
+
invocationId,
|
|
1569
|
+
parametersYaml: parametersRaw,
|
|
1570
|
+
parameters,
|
|
1571
|
+
parseError
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
return;
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1319
1577
|
const remainingText = this.takeTextUntil(this.buffer.length);
|
|
1320
1578
|
if (remainingText !== void 0) {
|
|
1321
1579
|
yield { type: "text", content: remainingText };
|
|
@@ -1796,11 +2054,11 @@ var init_agent = __esm({
|
|
|
1796
2054
|
role: message.role,
|
|
1797
2055
|
content: message.content
|
|
1798
2056
|
}));
|
|
1799
|
-
this.conversation = new ConversationManager(
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
);
|
|
2057
|
+
this.conversation = new ConversationManager(baseMessages, initialMessages, {
|
|
2058
|
+
parameterFormat: this.parameterFormat,
|
|
2059
|
+
startPrefix: options.gadgetStartPrefix,
|
|
2060
|
+
endPrefix: options.gadgetEndPrefix
|
|
2061
|
+
});
|
|
1804
2062
|
this.userPromptProvided = !!options.userPrompt;
|
|
1805
2063
|
if (options.userPrompt) {
|
|
1806
2064
|
this.conversation.addUserMessage(options.userPrompt);
|
|
@@ -5190,6 +5448,83 @@ function mergeDescriptions(schema, jsonSchema) {
|
|
|
5190
5448
|
|
|
5191
5449
|
// src/gadgets/gadget.ts
|
|
5192
5450
|
init_schema_validator();
|
|
5451
|
+
function formatYamlValue(value, indent = "") {
|
|
5452
|
+
if (typeof value === "string") {
|
|
5453
|
+
const lines = value.split("\n");
|
|
5454
|
+
if (lines.length === 1 && !value.includes(":") && !value.startsWith("-")) {
|
|
5455
|
+
return value;
|
|
5456
|
+
}
|
|
5457
|
+
const indentedLines = lines.map((line) => `${indent} ${line}`).join("\n");
|
|
5458
|
+
return `|
|
|
5459
|
+
${indentedLines}`;
|
|
5460
|
+
}
|
|
5461
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
5462
|
+
return String(value);
|
|
5463
|
+
}
|
|
5464
|
+
if (value === null || value === void 0) {
|
|
5465
|
+
return "null";
|
|
5466
|
+
}
|
|
5467
|
+
if (Array.isArray(value)) {
|
|
5468
|
+
if (value.length === 0) return "[]";
|
|
5469
|
+
const items = value.map((item) => `${indent}- ${formatYamlValue(item, indent + " ")}`);
|
|
5470
|
+
return "\n" + items.join("\n");
|
|
5471
|
+
}
|
|
5472
|
+
if (typeof value === "object") {
|
|
5473
|
+
const entries = Object.entries(value);
|
|
5474
|
+
if (entries.length === 0) return "{}";
|
|
5475
|
+
const lines = entries.map(([k, v]) => {
|
|
5476
|
+
const formattedValue = formatYamlValue(v, indent + " ");
|
|
5477
|
+
if (formattedValue.startsWith("\n") || formattedValue.startsWith("|")) {
|
|
5478
|
+
return `${indent}${k}: ${formattedValue}`;
|
|
5479
|
+
}
|
|
5480
|
+
return `${indent}${k}: ${formattedValue}`;
|
|
5481
|
+
});
|
|
5482
|
+
return "\n" + lines.join("\n");
|
|
5483
|
+
}
|
|
5484
|
+
return yaml2.dump(value).trimEnd();
|
|
5485
|
+
}
|
|
5486
|
+
function formatParamsAsYaml(params) {
|
|
5487
|
+
const lines = [];
|
|
5488
|
+
for (const [key, value] of Object.entries(params)) {
|
|
5489
|
+
const formattedValue = formatYamlValue(value, "");
|
|
5490
|
+
if (formattedValue.startsWith("\n")) {
|
|
5491
|
+
lines.push(`${key}:${formattedValue}`);
|
|
5492
|
+
} else {
|
|
5493
|
+
lines.push(`${key}: ${formattedValue}`);
|
|
5494
|
+
}
|
|
5495
|
+
}
|
|
5496
|
+
return lines.join("\n");
|
|
5497
|
+
}
|
|
5498
|
+
function formatTomlValue(value) {
|
|
5499
|
+
if (typeof value === "string") {
|
|
5500
|
+
if (value.includes("\n")) {
|
|
5501
|
+
return `"""
|
|
5502
|
+
${value}
|
|
5503
|
+
"""`;
|
|
5504
|
+
}
|
|
5505
|
+
return JSON.stringify(value);
|
|
5506
|
+
}
|
|
5507
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
5508
|
+
return String(value);
|
|
5509
|
+
}
|
|
5510
|
+
if (value === null || value === void 0) {
|
|
5511
|
+
return '""';
|
|
5512
|
+
}
|
|
5513
|
+
if (Array.isArray(value)) {
|
|
5514
|
+
return JSON.stringify(value);
|
|
5515
|
+
}
|
|
5516
|
+
if (typeof value === "object") {
|
|
5517
|
+
return JSON.stringify(value);
|
|
5518
|
+
}
|
|
5519
|
+
return JSON.stringify(value);
|
|
5520
|
+
}
|
|
5521
|
+
function formatParamsAsToml(params) {
|
|
5522
|
+
const lines = [];
|
|
5523
|
+
for (const [key, value] of Object.entries(params)) {
|
|
5524
|
+
lines.push(`${key} = ${formatTomlValue(value)}`);
|
|
5525
|
+
}
|
|
5526
|
+
return lines.join("\n");
|
|
5527
|
+
}
|
|
5193
5528
|
var BaseGadget = class {
|
|
5194
5529
|
/**
|
|
5195
5530
|
* The name of the gadget. Used for identification when LLM calls it.
|
|
@@ -5209,6 +5544,14 @@ var BaseGadget = class {
|
|
|
5209
5544
|
* Set to 0 or undefined to disable timeout for this gadget.
|
|
5210
5545
|
*/
|
|
5211
5546
|
timeoutMs;
|
|
5547
|
+
/**
|
|
5548
|
+
* Optional usage examples to help LLMs understand proper invocation.
|
|
5549
|
+
* Examples are rendered in getInstruction() alongside the schema.
|
|
5550
|
+
*
|
|
5551
|
+
* Note: Uses broader `unknown` type to allow typed examples from subclasses
|
|
5552
|
+
* while maintaining runtime compatibility.
|
|
5553
|
+
*/
|
|
5554
|
+
examples;
|
|
5212
5555
|
/**
|
|
5213
5556
|
* Auto-generated instruction text for the LLM.
|
|
5214
5557
|
* Combines name, description, and parameter schema into a formatted instruction.
|
|
@@ -5221,7 +5564,7 @@ var BaseGadget = class {
|
|
|
5221
5564
|
* Generate instruction text for the LLM with format-specific schema.
|
|
5222
5565
|
* Combines name, description, and parameter schema into a formatted instruction.
|
|
5223
5566
|
*
|
|
5224
|
-
* @param format - Format for the schema representation ('json' | 'yaml' | 'auto')
|
|
5567
|
+
* @param format - Format for the schema representation ('json' | 'yaml' | 'toml' | 'auto')
|
|
5225
5568
|
* @returns Formatted instruction string
|
|
5226
5569
|
*/
|
|
5227
5570
|
getInstruction(format = "json") {
|
|
@@ -5236,12 +5579,38 @@ var BaseGadget = class {
|
|
|
5236
5579
|
if (format === "json" || format === "auto") {
|
|
5237
5580
|
parts.push("\n\nInput Schema (JSON):");
|
|
5238
5581
|
parts.push(JSON.stringify(jsonSchema, null, 2));
|
|
5582
|
+
} else if (format === "toml") {
|
|
5583
|
+
parts.push("\n\nInput Schema (TOML):");
|
|
5584
|
+
parts.push(JSON.stringify(jsonSchema, null, 2));
|
|
5239
5585
|
} else {
|
|
5240
5586
|
const yamlSchema = yaml2.dump(jsonSchema).trimEnd();
|
|
5241
5587
|
parts.push("\n\nInput Schema (YAML):");
|
|
5242
5588
|
parts.push(yamlSchema);
|
|
5243
5589
|
}
|
|
5244
5590
|
}
|
|
5591
|
+
if (this.examples && this.examples.length > 0) {
|
|
5592
|
+
parts.push("\n\nExamples:");
|
|
5593
|
+
this.examples.forEach((example, index) => {
|
|
5594
|
+
if (index > 0) {
|
|
5595
|
+
parts.push("");
|
|
5596
|
+
}
|
|
5597
|
+
if (example.comment) {
|
|
5598
|
+
parts.push(`# ${example.comment}`);
|
|
5599
|
+
}
|
|
5600
|
+
parts.push("Input:");
|
|
5601
|
+
if (format === "json" || format === "auto") {
|
|
5602
|
+
parts.push(JSON.stringify(example.params, null, 2));
|
|
5603
|
+
} else if (format === "toml") {
|
|
5604
|
+
parts.push(formatParamsAsToml(example.params));
|
|
5605
|
+
} else {
|
|
5606
|
+
parts.push(formatParamsAsYaml(example.params));
|
|
5607
|
+
}
|
|
5608
|
+
if (example.output !== void 0) {
|
|
5609
|
+
parts.push("Output:");
|
|
5610
|
+
parts.push(example.output);
|
|
5611
|
+
}
|
|
5612
|
+
});
|
|
5613
|
+
}
|
|
5245
5614
|
return parts.join("\n");
|
|
5246
5615
|
}
|
|
5247
5616
|
};
|
|
@@ -5253,6 +5622,7 @@ function createGadget(config) {
|
|
|
5253
5622
|
description = config.description;
|
|
5254
5623
|
parameterSchema = config.schema;
|
|
5255
5624
|
timeoutMs = config.timeoutMs;
|
|
5625
|
+
examples = config.examples;
|
|
5256
5626
|
execute(params) {
|
|
5257
5627
|
return config.execute(params);
|
|
5258
5628
|
}
|
|
@@ -5273,6 +5643,7 @@ function Gadget(config) {
|
|
|
5273
5643
|
parameterSchema = config.schema;
|
|
5274
5644
|
name = config.name;
|
|
5275
5645
|
timeoutMs = config.timeoutMs;
|
|
5646
|
+
examples = config.examples;
|
|
5276
5647
|
/**
|
|
5277
5648
|
* Type helper property for accessing inferred parameter type.
|
|
5278
5649
|
* This is used in the execute method signature: `execute(params: this['params'])`
|