llmist 0.6.2 → 0.7.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.
@@ -8,7 +8,7 @@ import {
8
8
  init_constants,
9
9
  init_gadget,
10
10
  init_logger
11
- } from "./chunk-DVK6ZQOV.js";
11
+ } from "./chunk-ZFHFBEQ5.js";
12
12
 
13
13
  // src/gadgets/validation.ts
14
14
  function validateAndApplyDefaults(schema, params) {
@@ -900,4 +900,4 @@ export {
900
900
  MockGadgetBuilder,
901
901
  mockGadget
902
902
  };
903
- //# sourceMappingURL=chunk-TSR25DAY.js.map
903
+ //# sourceMappingURL=chunk-CTC2WJZA.js.map
@@ -927,6 +927,10 @@ function formatParamsAsYaml(params) {
927
927
  }
928
928
  return lines.join("\n");
929
929
  }
930
+ function formatTomlInlineTable(obj) {
931
+ const entries = Object.entries(obj).map(([k, v]) => `${k} = ${formatTomlValue(v)}`);
932
+ return `{ ${entries.join(", ")} }`;
933
+ }
930
934
  function formatTomlValue(value) {
931
935
  if (typeof value === "string") {
932
936
  if (value.includes("\n")) {
@@ -944,10 +948,17 @@ ${delimiter}`;
944
948
  return '""';
945
949
  }
946
950
  if (Array.isArray(value)) {
947
- return JSON.stringify(value);
951
+ if (value.length === 0) return "[]";
952
+ const items = value.map((item) => {
953
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
954
+ return formatTomlInlineTable(item);
955
+ }
956
+ return formatTomlValue(item);
957
+ });
958
+ return `[${items.join(", ")}]`;
948
959
  }
949
960
  if (typeof value === "object") {
950
- return JSON.stringify(value);
961
+ return formatTomlInlineTable(value);
951
962
  }
952
963
  return JSON.stringify(value);
953
964
  }
@@ -1828,6 +1839,14 @@ function preprocessTomlHeredoc(tomlStr) {
1828
1839
  }
1829
1840
  return result.join("\n");
1830
1841
  }
1842
+ function stripMarkdownFences(content) {
1843
+ let cleaned = content.trim();
1844
+ const openingFence = /^```(?:toml|yaml|json)?\s*\n/i;
1845
+ const closingFence = /\n?```\s*$/;
1846
+ cleaned = cleaned.replace(openingFence, "");
1847
+ cleaned = cleaned.replace(closingFence, "");
1848
+ return cleaned.trim();
1849
+ }
1831
1850
  var globalInvocationCounter, StreamParser;
1832
1851
  var init_parser = __esm({
1833
1852
  "src/gadgets/parser.ts"() {
@@ -1881,35 +1900,36 @@ var init_parser = __esm({
1881
1900
  * Parse parameter string according to configured format
1882
1901
  */
1883
1902
  parseParameters(raw) {
1903
+ const cleaned = stripMarkdownFences(raw);
1884
1904
  if (this.parameterFormat === "json") {
1885
1905
  try {
1886
- return { parameters: JSON.parse(raw) };
1906
+ return { parameters: JSON.parse(cleaned) };
1887
1907
  } catch (error) {
1888
1908
  return { parseError: this.truncateParseError(error, "JSON") };
1889
1909
  }
1890
1910
  }
1891
1911
  if (this.parameterFormat === "yaml") {
1892
1912
  try {
1893
- return { parameters: yaml2.load(preprocessYaml(raw)) };
1913
+ return { parameters: yaml2.load(preprocessYaml(cleaned)) };
1894
1914
  } catch (error) {
1895
1915
  return { parseError: this.truncateParseError(error, "YAML") };
1896
1916
  }
1897
1917
  }
1898
1918
  if (this.parameterFormat === "toml") {
1899
1919
  try {
1900
- return { parameters: parseToml(preprocessTomlHeredoc(raw)) };
1920
+ return { parameters: parseToml(preprocessTomlHeredoc(cleaned)) };
1901
1921
  } catch (error) {
1902
1922
  return { parseError: this.truncateParseError(error, "TOML") };
1903
1923
  }
1904
1924
  }
1905
1925
  try {
1906
- return { parameters: JSON.parse(raw) };
1926
+ return { parameters: JSON.parse(cleaned) };
1907
1927
  } catch {
1908
1928
  try {
1909
- return { parameters: parseToml(preprocessTomlHeredoc(raw)) };
1929
+ return { parameters: parseToml(preprocessTomlHeredoc(cleaned)) };
1910
1930
  } catch {
1911
1931
  try {
1912
- return { parameters: yaml2.load(preprocessYaml(raw)) };
1932
+ return { parameters: yaml2.load(preprocessYaml(cleaned)) };
1913
1933
  } catch (error) {
1914
1934
  return { parseError: this.truncateParseError(error, "auto") };
1915
1935
  }
@@ -4068,6 +4088,7 @@ var init_agent = __esm({
4068
4088
  gadgetEndPrefix;
4069
4089
  onHumanInputRequired;
4070
4090
  textOnlyHandler;
4091
+ textWithGadgetsHandler;
4071
4092
  stopOnGadgetError;
4072
4093
  shouldContinueAfterError;
4073
4094
  defaultGadgetTimeoutMs;
@@ -4098,6 +4119,7 @@ var init_agent = __esm({
4098
4119
  this.gadgetEndPrefix = options.gadgetEndPrefix;
4099
4120
  this.onHumanInputRequired = options.onHumanInputRequired;
4100
4121
  this.textOnlyHandler = options.textOnlyHandler ?? "terminate";
4122
+ this.textWithGadgetsHandler = options.textWithGadgetsHandler;
4101
4123
  this.stopOnGadgetError = options.stopOnGadgetError ?? true;
4102
4124
  this.shouldContinueAfterError = options.shouldContinueAfterError;
4103
4125
  this.defaultGadgetTimeoutMs = options.defaultGadgetTimeoutMs;
@@ -4285,6 +4307,17 @@ var init_agent = __esm({
4285
4307
  }
4286
4308
  }
4287
4309
  if (result.didExecuteGadgets) {
4310
+ if (this.textWithGadgetsHandler) {
4311
+ const textContent = result.outputs.filter((output) => output.type === "text").map((output) => output.content).join("");
4312
+ if (textContent.trim()) {
4313
+ const { gadgetName, parameterMapping, resultMapping } = this.textWithGadgetsHandler;
4314
+ this.conversation.addGadgetCall(
4315
+ gadgetName,
4316
+ parameterMapping(textContent),
4317
+ resultMapping ? resultMapping(textContent) : textContent
4318
+ );
4319
+ }
4320
+ }
4288
4321
  for (const output of result.outputs) {
4289
4322
  if (output.type === "gadget_result") {
4290
4323
  const gadgetResult = output.result;
@@ -4296,7 +4329,13 @@ var init_agent = __esm({
4296
4329
  }
4297
4330
  }
4298
4331
  } else {
4299
- this.conversation.addAssistantMessage(finalMessage);
4332
+ if (finalMessage.trim()) {
4333
+ this.conversation.addGadgetCall(
4334
+ "TellUser",
4335
+ { message: finalMessage, done: false, type: "info" },
4336
+ `\u2139\uFE0F ${finalMessage}`
4337
+ );
4338
+ }
4300
4339
  const shouldBreak = await this.handleTextOnlyResponse(finalMessage);
4301
4340
  if (shouldBreak) {
4302
4341
  break;
@@ -4481,6 +4520,7 @@ var AgentBuilder;
4481
4520
  var init_builder = __esm({
4482
4521
  "src/agent/builder.ts"() {
4483
4522
  "use strict";
4523
+ init_constants();
4484
4524
  init_model_shortcuts();
4485
4525
  init_registry();
4486
4526
  init_agent();
@@ -4502,6 +4542,7 @@ var init_builder = __esm({
4502
4542
  gadgetStartPrefix;
4503
4543
  gadgetEndPrefix;
4504
4544
  textOnlyHandler;
4545
+ textWithGadgetsHandler;
4505
4546
  stopOnGadgetError;
4506
4547
  shouldContinueAfterError;
4507
4548
  defaultGadgetTimeoutMs;
@@ -4764,6 +4805,30 @@ var init_builder = __esm({
4764
4805
  this.textOnlyHandler = handler;
4765
4806
  return this;
4766
4807
  }
4808
+ /**
4809
+ * Set the handler for text content that appears alongside gadget calls.
4810
+ *
4811
+ * When set, text accompanying gadget responses will be wrapped as a
4812
+ * synthetic gadget call before the actual gadget results in the
4813
+ * conversation history.
4814
+ *
4815
+ * @param handler - Configuration for wrapping text
4816
+ * @returns This builder for chaining
4817
+ *
4818
+ * @example
4819
+ * ```typescript
4820
+ * // Wrap text as TellUser gadget
4821
+ * .withTextWithGadgetsHandler({
4822
+ * gadgetName: "TellUser",
4823
+ * parameterMapping: (text) => ({ message: text, done: false, type: "info" }),
4824
+ * resultMapping: (text) => `ℹ️ ${text}`,
4825
+ * })
4826
+ * ```
4827
+ */
4828
+ withTextWithGadgetsHandler(handler) {
4829
+ this.textWithGadgetsHandler = handler;
4830
+ return this;
4831
+ }
4767
4832
  /**
4768
4833
  * Set whether to stop gadget execution on first error.
4769
4834
  *
@@ -4878,6 +4943,69 @@ var init_builder = __esm({
4878
4943
  this.gadgetOutputLimitPercent = percent;
4879
4944
  return this;
4880
4945
  }
4946
+ /**
4947
+ * Add a synthetic gadget call to the conversation history.
4948
+ *
4949
+ * This is useful for in-context learning - showing the LLM what "past self"
4950
+ * did correctly so it mimics the pattern. The call is formatted with proper
4951
+ * markers and parameter format.
4952
+ *
4953
+ * @param gadgetName - Name of the gadget
4954
+ * @param parameters - Parameters passed to the gadget
4955
+ * @param result - Result returned by the gadget
4956
+ * @returns This builder for chaining
4957
+ *
4958
+ * @example
4959
+ * ```typescript
4960
+ * .withSyntheticGadgetCall(
4961
+ * 'TellUser',
4962
+ * {
4963
+ * message: '👋 Hello!\n\nHere\'s what I can do:\n- Analyze code\n- Run commands',
4964
+ * done: false,
4965
+ * type: 'info'
4966
+ * },
4967
+ * 'ℹ️ 👋 Hello!\n\nHere\'s what I can do:\n- Analyze code\n- Run commands'
4968
+ * )
4969
+ * ```
4970
+ */
4971
+ withSyntheticGadgetCall(gadgetName, parameters, result) {
4972
+ const startPrefix = this.gadgetStartPrefix ?? GADGET_START_PREFIX;
4973
+ const endPrefix = this.gadgetEndPrefix ?? GADGET_END_PREFIX;
4974
+ const format = this.parameterFormat ?? "yaml";
4975
+ const paramStr = this.formatSyntheticParameters(parameters, format);
4976
+ this.initialMessages.push({
4977
+ role: "assistant",
4978
+ content: `${startPrefix}${gadgetName}
4979
+ ${paramStr}
4980
+ ${endPrefix}`
4981
+ });
4982
+ this.initialMessages.push({
4983
+ role: "user",
4984
+ content: `Result: ${result}`
4985
+ });
4986
+ return this;
4987
+ }
4988
+ /**
4989
+ * Format parameters for synthetic gadget calls.
4990
+ * Uses heredoc for multiline string values.
4991
+ */
4992
+ formatSyntheticParameters(parameters, format) {
4993
+ if (format === "json" || format === "auto") {
4994
+ return JSON.stringify(parameters);
4995
+ }
4996
+ return Object.entries(parameters).map(([key, value]) => {
4997
+ if (typeof value === "string" && value.includes("\n")) {
4998
+ const separator = format === "yaml" ? ":" : " =";
4999
+ return `${key}${separator} <<<EOF
5000
+ ${value}
5001
+ EOF`;
5002
+ }
5003
+ if (format === "yaml") {
5004
+ return typeof value === "string" ? `${key}: ${value}` : `${key}: ${JSON.stringify(value)}`;
5005
+ }
5006
+ return `${key} = ${JSON.stringify(value)}`;
5007
+ }).join("\n");
5008
+ }
4881
5009
  /**
4882
5010
  * Build and create the agent with the given user prompt.
4883
5011
  * Returns the Agent instance ready to run.
@@ -4920,6 +5048,7 @@ var init_builder = __esm({
4920
5048
  gadgetStartPrefix: this.gadgetStartPrefix,
4921
5049
  gadgetEndPrefix: this.gadgetEndPrefix,
4922
5050
  textOnlyHandler: this.textOnlyHandler,
5051
+ textWithGadgetsHandler: this.textWithGadgetsHandler,
4923
5052
  stopOnGadgetError: this.stopOnGadgetError,
4924
5053
  shouldContinueAfterError: this.shouldContinueAfterError,
4925
5054
  defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
@@ -5021,6 +5150,7 @@ var init_builder = __esm({
5021
5150
  gadgetStartPrefix: this.gadgetStartPrefix,
5022
5151
  gadgetEndPrefix: this.gadgetEndPrefix,
5023
5152
  textOnlyHandler: this.textOnlyHandler,
5153
+ textWithGadgetsHandler: this.textWithGadgetsHandler,
5024
5154
  stopOnGadgetError: this.stopOnGadgetError,
5025
5155
  shouldContinueAfterError: this.shouldContinueAfterError,
5026
5156
  defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
@@ -5276,6 +5406,9 @@ var init_client = __esm({
5276
5406
  });
5277
5407
 
5278
5408
  export {
5409
+ GADGET_START_PREFIX,
5410
+ GADGET_END_PREFIX,
5411
+ init_constants,
5279
5412
  MODEL_ALIASES,
5280
5413
  resolveModel,
5281
5414
  hasProviderPrefix,
@@ -5284,9 +5417,6 @@ export {
5284
5417
  init_model_shortcuts,
5285
5418
  GadgetRegistry,
5286
5419
  init_registry,
5287
- GADGET_START_PREFIX,
5288
- GADGET_END_PREFIX,
5289
- init_constants,
5290
5420
  DEFAULT_PROMPTS,
5291
5421
  resolvePromptTemplate,
5292
5422
  resolveRulesTemplate,
@@ -5344,4 +5474,4 @@ export {
5344
5474
  AgentBuilder,
5345
5475
  init_builder
5346
5476
  };
5347
- //# sourceMappingURL=chunk-DVK6ZQOV.js.map
5477
+ //# sourceMappingURL=chunk-ZFHFBEQ5.js.map