llmist 0.4.0 → 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-I55AV3WV.js → chunk-LKIBXQ5I.js} +3 -2
- package/dist/chunk-LKIBXQ5I.js.map +1 -0
- package/dist/{chunk-VYBRYR2S.js → chunk-MH4TQ5AD.js} +471 -97
- package/dist/chunk-MH4TQ5AD.js.map +1 -0
- package/dist/{chunk-VRTKJK2X.js → chunk-VF2WOCHM.js} +2 -2
- package/dist/cli.cjs +1243 -202
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +773 -107
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +473 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -7
- package/dist/index.d.ts +36 -7
- 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 +471 -97
- 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-I55AV3WV.js.map +0 -1
- package/dist/chunk-VYBRYR2S.js.map +0 -1
- /package/dist/{chunk-VRTKJK2X.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."
|
|
583
|
+
${this.endPrefix}
|
|
584
|
+
${this.startPrefix}analyze
|
|
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."}
|
|
530
595
|
${this.endPrefix}
|
|
531
596
|
${this.startPrefix}analyze
|
|
532
|
-
{"type": "economic_analysis", "matter": "Polish Economy", "question": "Polish arms exports 2025
|
|
533
|
-
${this.endPrefix}
|
|
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);
|
|
@@ -2791,10 +3049,11 @@ var init_gemini = __esm({
|
|
|
2791
3049
|
return GEMINI_MODELS;
|
|
2792
3050
|
}
|
|
2793
3051
|
buildRequestPayload(options, descriptor, _spec, messages) {
|
|
2794
|
-
const
|
|
3052
|
+
const contents = this.convertMessagesToContents(messages);
|
|
2795
3053
|
const generationConfig = this.buildGenerationConfig(options);
|
|
2796
3054
|
const config = {
|
|
2797
|
-
|
|
3055
|
+
// Note: systemInstruction removed - it doesn't work with countTokens()
|
|
3056
|
+
// System messages are now included in contents as user+model exchanges
|
|
2798
3057
|
...generationConfig ? { ...generationConfig } : {},
|
|
2799
3058
|
// Explicitly disable function calling to prevent UNEXPECTED_TOOL_CALL errors
|
|
2800
3059
|
toolConfig: {
|
|
@@ -2815,31 +3074,37 @@ var init_gemini = __esm({
|
|
|
2815
3074
|
const streamResponse = await client.models.generateContentStream(payload);
|
|
2816
3075
|
return streamResponse;
|
|
2817
3076
|
}
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
3077
|
+
/**
|
|
3078
|
+
* Convert LLM messages to Gemini contents format.
|
|
3079
|
+
*
|
|
3080
|
+
* For Gemini, we convert system messages to user+model exchanges instead of
|
|
3081
|
+
* using systemInstruction, because:
|
|
3082
|
+
* 1. systemInstruction doesn't work with countTokens() API
|
|
3083
|
+
* 2. This approach gives perfect token counting accuracy (0% error)
|
|
3084
|
+
* 3. The model receives and follows system instructions identically
|
|
3085
|
+
*
|
|
3086
|
+
* System message: "You are a helpful assistant"
|
|
3087
|
+
* Becomes:
|
|
3088
|
+
* - User: "You are a helpful assistant"
|
|
3089
|
+
* - Model: "Understood."
|
|
3090
|
+
*/
|
|
3091
|
+
convertMessagesToContents(messages) {
|
|
3092
|
+
const expandedMessages = [];
|
|
3093
|
+
for (const message of messages) {
|
|
3094
|
+
if (message.role === "system") {
|
|
3095
|
+
expandedMessages.push({
|
|
3096
|
+
role: "user",
|
|
3097
|
+
content: message.content
|
|
3098
|
+
});
|
|
3099
|
+
expandedMessages.push({
|
|
3100
|
+
role: "assistant",
|
|
3101
|
+
content: "Understood."
|
|
3102
|
+
});
|
|
3103
|
+
} else {
|
|
3104
|
+
expandedMessages.push(message);
|
|
3105
|
+
}
|
|
2825
3106
|
}
|
|
2826
|
-
|
|
2827
|
-
while (systemBlockEnd < messages.length && messages[systemBlockEnd].role === "system") {
|
|
2828
|
-
systemBlockEnd++;
|
|
2829
|
-
}
|
|
2830
|
-
const systemMessages = messages.slice(firstSystemIndex, systemBlockEnd);
|
|
2831
|
-
const nonSystemMessages = [
|
|
2832
|
-
...messages.slice(0, firstSystemIndex),
|
|
2833
|
-
...messages.slice(systemBlockEnd)
|
|
2834
|
-
];
|
|
2835
|
-
const systemInstruction = {
|
|
2836
|
-
role: "system",
|
|
2837
|
-
parts: systemMessages.map((message) => ({ text: message.content }))
|
|
2838
|
-
};
|
|
2839
|
-
return {
|
|
2840
|
-
systemInstruction,
|
|
2841
|
-
contents: this.mergeConsecutiveMessages(nonSystemMessages)
|
|
2842
|
-
};
|
|
3107
|
+
return this.mergeConsecutiveMessages(expandedMessages);
|
|
2843
3108
|
}
|
|
2844
3109
|
mergeConsecutiveMessages(messages) {
|
|
2845
3110
|
if (messages.length === 0) {
|
|
@@ -2928,8 +3193,8 @@ var init_gemini = __esm({
|
|
|
2928
3193
|
*
|
|
2929
3194
|
* This method provides accurate token estimation for Gemini models by:
|
|
2930
3195
|
* - Using the SDK's countTokens() method
|
|
2931
|
-
* -
|
|
2932
|
-
* -
|
|
3196
|
+
* - Converting system messages to user+model exchanges (same as in generation)
|
|
3197
|
+
* - This gives perfect token counting accuracy (0% error vs actual usage)
|
|
2933
3198
|
*
|
|
2934
3199
|
* @param messages - The messages to count tokens for
|
|
2935
3200
|
* @param descriptor - Model descriptor containing the model name
|
|
@@ -2948,16 +3213,14 @@ var init_gemini = __esm({
|
|
|
2948
3213
|
*/
|
|
2949
3214
|
async countTokens(messages, descriptor, _spec) {
|
|
2950
3215
|
const client = this.client;
|
|
2951
|
-
const
|
|
2952
|
-
const request = {
|
|
2953
|
-
model: descriptor.name,
|
|
2954
|
-
contents: this.convertContentsForNewSDK(contents)
|
|
2955
|
-
};
|
|
2956
|
-
if (systemInstruction) {
|
|
2957
|
-
request.systemInstruction = systemInstruction.parts.map((p) => p.text).join("\n");
|
|
2958
|
-
}
|
|
3216
|
+
const contents = this.convertMessagesToContents(messages);
|
|
2959
3217
|
try {
|
|
2960
|
-
const response = await client.models.countTokens(
|
|
3218
|
+
const response = await client.models.countTokens({
|
|
3219
|
+
model: descriptor.name,
|
|
3220
|
+
contents: this.convertContentsForNewSDK(contents)
|
|
3221
|
+
// Note: systemInstruction not used - it's not supported by countTokens()
|
|
3222
|
+
// and would cause a 2100% token counting error
|
|
3223
|
+
});
|
|
2961
3224
|
return response.totalTokens ?? 0;
|
|
2962
3225
|
} catch (error) {
|
|
2963
3226
|
console.warn(
|
|
@@ -5185,6 +5448,83 @@ function mergeDescriptions(schema, jsonSchema) {
|
|
|
5185
5448
|
|
|
5186
5449
|
// src/gadgets/gadget.ts
|
|
5187
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
|
+
}
|
|
5188
5528
|
var BaseGadget = class {
|
|
5189
5529
|
/**
|
|
5190
5530
|
* The name of the gadget. Used for identification when LLM calls it.
|
|
@@ -5204,6 +5544,14 @@ var BaseGadget = class {
|
|
|
5204
5544
|
* Set to 0 or undefined to disable timeout for this gadget.
|
|
5205
5545
|
*/
|
|
5206
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;
|
|
5207
5555
|
/**
|
|
5208
5556
|
* Auto-generated instruction text for the LLM.
|
|
5209
5557
|
* Combines name, description, and parameter schema into a formatted instruction.
|
|
@@ -5216,7 +5564,7 @@ var BaseGadget = class {
|
|
|
5216
5564
|
* Generate instruction text for the LLM with format-specific schema.
|
|
5217
5565
|
* Combines name, description, and parameter schema into a formatted instruction.
|
|
5218
5566
|
*
|
|
5219
|
-
* @param format - Format for the schema representation ('json' | 'yaml' | 'auto')
|
|
5567
|
+
* @param format - Format for the schema representation ('json' | 'yaml' | 'toml' | 'auto')
|
|
5220
5568
|
* @returns Formatted instruction string
|
|
5221
5569
|
*/
|
|
5222
5570
|
getInstruction(format = "json") {
|
|
@@ -5231,12 +5579,38 @@ var BaseGadget = class {
|
|
|
5231
5579
|
if (format === "json" || format === "auto") {
|
|
5232
5580
|
parts.push("\n\nInput Schema (JSON):");
|
|
5233
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));
|
|
5234
5585
|
} else {
|
|
5235
5586
|
const yamlSchema = yaml2.dump(jsonSchema).trimEnd();
|
|
5236
5587
|
parts.push("\n\nInput Schema (YAML):");
|
|
5237
5588
|
parts.push(yamlSchema);
|
|
5238
5589
|
}
|
|
5239
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
|
+
}
|
|
5240
5614
|
return parts.join("\n");
|
|
5241
5615
|
}
|
|
5242
5616
|
};
|
|
@@ -5248,6 +5622,7 @@ function createGadget(config) {
|
|
|
5248
5622
|
description = config.description;
|
|
5249
5623
|
parameterSchema = config.schema;
|
|
5250
5624
|
timeoutMs = config.timeoutMs;
|
|
5625
|
+
examples = config.examples;
|
|
5251
5626
|
execute(params) {
|
|
5252
5627
|
return config.execute(params);
|
|
5253
5628
|
}
|
|
@@ -5268,6 +5643,7 @@ function Gadget(config) {
|
|
|
5268
5643
|
parameterSchema = config.schema;
|
|
5269
5644
|
name = config.name;
|
|
5270
5645
|
timeoutMs = config.timeoutMs;
|
|
5646
|
+
examples = config.examples;
|
|
5271
5647
|
/**
|
|
5272
5648
|
* Type helper property for accessing inferred parameter type.
|
|
5273
5649
|
* This is used in the execute method signature: `execute(params: this['params'])`
|