llmist 1.0.0 → 1.1.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/dist/index.cjs CHANGED
@@ -1493,6 +1493,89 @@ var init_hook_validators = __esm({
1493
1493
  }
1494
1494
  });
1495
1495
 
1496
+ // src/gadgets/error-formatter.ts
1497
+ var GadgetErrorFormatter;
1498
+ var init_error_formatter = __esm({
1499
+ "src/gadgets/error-formatter.ts"() {
1500
+ "use strict";
1501
+ init_constants();
1502
+ GadgetErrorFormatter = class {
1503
+ argPrefix;
1504
+ startPrefix;
1505
+ endPrefix;
1506
+ constructor(options = {}) {
1507
+ this.argPrefix = options.argPrefix ?? GADGET_ARG_PREFIX;
1508
+ this.startPrefix = options.startPrefix ?? GADGET_START_PREFIX;
1509
+ this.endPrefix = options.endPrefix ?? GADGET_END_PREFIX;
1510
+ }
1511
+ /**
1512
+ * Format a Zod validation error with full gadget instructions.
1513
+ *
1514
+ * @param gadgetName - Name of the gadget that was called
1515
+ * @param zodError - The Zod validation error
1516
+ * @param gadget - The gadget instance (for generating instructions)
1517
+ * @returns Formatted error message with usage instructions
1518
+ */
1519
+ formatValidationError(gadgetName, zodError, gadget) {
1520
+ const parts = [];
1521
+ parts.push(`Error: Invalid parameters for '${gadgetName}':`);
1522
+ for (const issue of zodError.issues) {
1523
+ const path = issue.path.join(".") || "root";
1524
+ parts.push(` - ${path}: ${issue.message}`);
1525
+ }
1526
+ parts.push("");
1527
+ parts.push("Gadget Usage:");
1528
+ parts.push(gadget.getInstruction(this.argPrefix));
1529
+ return parts.join("\n");
1530
+ }
1531
+ /**
1532
+ * Format a parse error with block format reference.
1533
+ *
1534
+ * @param gadgetName - Name of the gadget that was called
1535
+ * @param parseError - The parse error message
1536
+ * @param gadget - The gadget instance if found (for generating instructions)
1537
+ * @returns Formatted error message with format reference
1538
+ */
1539
+ formatParseError(gadgetName, parseError, gadget) {
1540
+ const parts = [];
1541
+ parts.push(`Error: Failed to parse parameters for '${gadgetName}':`);
1542
+ parts.push(` ${parseError}`);
1543
+ if (gadget) {
1544
+ parts.push("");
1545
+ parts.push("Gadget Usage:");
1546
+ parts.push(gadget.getInstruction(this.argPrefix));
1547
+ }
1548
+ parts.push("");
1549
+ parts.push("Block Format Reference:");
1550
+ parts.push(` ${this.startPrefix}${gadgetName}`);
1551
+ parts.push(` ${this.argPrefix}parameterName`);
1552
+ parts.push(" parameter value here");
1553
+ parts.push(` ${this.endPrefix}`);
1554
+ return parts.join("\n");
1555
+ }
1556
+ /**
1557
+ * Format a registry error (gadget not found) with available gadgets list.
1558
+ *
1559
+ * @param gadgetName - Name of the gadget that was not found
1560
+ * @param availableGadgets - List of available gadget names
1561
+ * @returns Formatted error message with available gadgets
1562
+ */
1563
+ formatRegistryError(gadgetName, availableGadgets) {
1564
+ const parts = [];
1565
+ parts.push(`Error: Gadget '${gadgetName}' not found.`);
1566
+ if (availableGadgets.length > 0) {
1567
+ parts.push("");
1568
+ parts.push(`Available gadgets: ${availableGadgets.join(", ")}`);
1569
+ } else {
1570
+ parts.push("");
1571
+ parts.push("No gadgets are currently registered.");
1572
+ }
1573
+ return parts.join("\n");
1574
+ }
1575
+ };
1576
+ }
1577
+ });
1578
+
1496
1579
  // src/gadgets/exceptions.ts
1497
1580
  var BreakLoopException, HumanInputException, TimeoutException;
1498
1581
  var init_exceptions = __esm({
@@ -1531,15 +1614,18 @@ var init_executor = __esm({
1531
1614
  "src/gadgets/executor.ts"() {
1532
1615
  "use strict";
1533
1616
  init_logger();
1617
+ init_error_formatter();
1534
1618
  init_exceptions();
1535
1619
  GadgetExecutor = class {
1536
- constructor(registry, onHumanInputRequired, logger, defaultGadgetTimeoutMs) {
1620
+ constructor(registry, onHumanInputRequired, logger, defaultGadgetTimeoutMs, errorFormatterOptions) {
1537
1621
  this.registry = registry;
1538
1622
  this.onHumanInputRequired = onHumanInputRequired;
1539
1623
  this.defaultGadgetTimeoutMs = defaultGadgetTimeoutMs;
1540
1624
  this.logger = logger ?? createLogger({ name: "llmist:executor" });
1625
+ this.errorFormatter = new GadgetErrorFormatter(errorFormatterOptions);
1541
1626
  }
1542
1627
  logger;
1628
+ errorFormatter;
1543
1629
  /**
1544
1630
  * Creates a promise that rejects with a TimeoutException after the specified timeout.
1545
1631
  */
@@ -1564,11 +1650,12 @@ var init_executor = __esm({
1564
1650
  const gadget = this.registry.get(call.gadgetName);
1565
1651
  if (!gadget) {
1566
1652
  this.logger.error("Gadget not found", { gadgetName: call.gadgetName });
1653
+ const availableGadgets = this.registry.getNames();
1567
1654
  return {
1568
1655
  gadgetName: call.gadgetName,
1569
1656
  invocationId: call.invocationId,
1570
1657
  parameters: call.parameters ?? {},
1571
- error: `Gadget '${call.gadgetName}' not found in registry`,
1658
+ error: this.errorFormatter.formatRegistryError(call.gadgetName, availableGadgets),
1572
1659
  executionTimeMs: Date.now() - startTime
1573
1660
  };
1574
1661
  }
@@ -1578,25 +1665,26 @@ var init_executor = __esm({
1578
1665
  parseError: call.parseError,
1579
1666
  rawParameters: call.parametersRaw
1580
1667
  });
1668
+ const parseErrorMessage = call.parseError ?? "Failed to parse parameters";
1581
1669
  return {
1582
1670
  gadgetName: call.gadgetName,
1583
1671
  invocationId: call.invocationId,
1584
1672
  parameters: {},
1585
- error: call.parseError ?? "Failed to parse parameters",
1673
+ error: this.errorFormatter.formatParseError(call.gadgetName, parseErrorMessage, gadget),
1586
1674
  executionTimeMs: Date.now() - startTime
1587
1675
  };
1588
1676
  }
1589
1677
  if (gadget.parameterSchema) {
1590
1678
  const validationResult = gadget.parameterSchema.safeParse(rawParameters);
1591
1679
  if (!validationResult.success) {
1592
- const formattedIssues = validationResult.error.issues.map((issue) => {
1593
- const path = issue.path.join(".") || "root";
1594
- return `${path}: ${issue.message}`;
1595
- }).join("; ");
1596
- const validationError = `Invalid parameters: ${formattedIssues}`;
1680
+ const validationError = this.errorFormatter.formatValidationError(
1681
+ call.gadgetName,
1682
+ validationResult.error,
1683
+ gadget
1684
+ );
1597
1685
  this.logger.error("Gadget parameter validation failed", {
1598
1686
  gadgetName: call.gadgetName,
1599
- error: validationError
1687
+ issueCount: validationResult.error.issues.length
1600
1688
  });
1601
1689
  return {
1602
1690
  gadgetName: call.gadgetName,
@@ -1885,17 +1973,12 @@ var init_parser = __esm({
1885
1973
  return { actualName: gadgetName, invocationId: `gadget_${++globalInvocationCounter}` };
1886
1974
  }
1887
1975
  /**
1888
- * Truncate verbose parse errors to avoid context overflow.
1889
- * Keeps first meaningful line and limits total length.
1976
+ * Extract the error message from a parse error.
1977
+ * Preserves full message since the error formatter adds contextual help
1978
+ * that benefits from precise, detailed error information.
1890
1979
  */
1891
- truncateParseError(error, format) {
1892
- const message = error instanceof Error ? error.message : String(error);
1893
- const firstLine = message.split("\n")[0];
1894
- const maxLen = 200;
1895
- if (firstLine.length <= maxLen) {
1896
- return firstLine;
1897
- }
1898
- return `${firstLine.slice(0, maxLen)}... (${message.length} chars total)`;
1980
+ extractParseError(error) {
1981
+ return error instanceof Error ? error.message : String(error);
1899
1982
  }
1900
1983
  /**
1901
1984
  * Parse parameter string using block format
@@ -1905,7 +1988,7 @@ var init_parser = __esm({
1905
1988
  try {
1906
1989
  return { parameters: parseBlockParams(cleaned, { argPrefix: this.argPrefix }) };
1907
1990
  } catch (error) {
1908
- return { parseError: this.truncateParseError(error, "block") };
1991
+ return { parseError: this.extractParseError(error) };
1909
1992
  }
1910
1993
  }
1911
1994
  // Feed a chunk of text and get parsed events