@botbotgo/better-call 0.1.46 → 0.1.48

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/scripts/demo.mjs +36 -19
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/better-call",
3
- "version": "0.1.46",
3
+ "version": "0.1.48",
4
4
  "description": "Small-model tool-call reliability layer for LangChain and custom agent runtimes.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/scripts/demo.mjs CHANGED
@@ -52,6 +52,19 @@ function displayValue(value) {
52
52
  return value == null ? "(none)" : String(value);
53
53
  }
54
54
 
55
+ function hasUsableArgsShape(value) {
56
+ return (
57
+ typeof value === "object" &&
58
+ value != null &&
59
+ !Array.isArray(value) &&
60
+ ("ticker" in value || "symbol" in value || "market" in value)
61
+ );
62
+ }
63
+
64
+ function createDemoMalformedInput() {
65
+ return { symbol: "Apple", market: "NASDAQ" };
66
+ }
67
+
55
68
  function exitWithError(step, error) {
56
69
  const message = errorMessage(error);
57
70
 
@@ -98,13 +111,12 @@ const stockQuote = {
98
111
  },
99
112
  };
100
113
 
101
- // Intentionally malformed repair input: "symbol" should be "ticker", and
102
- // "NASDAQ" is not one of the schema-valid markets ("US", "HK", or "CN").
103
- const intentionallyMalformedArgs = { symbol: "Apple", market: "NASDAQ" };
104
-
105
114
  /**
106
115
  * Repairs malformed stock quote tool-call input into one schema-valid call.
107
116
  *
117
+ * Diagnostics, when present, come from the surrounding reliableToolCalls run
118
+ * and explain validation/repair decisions such as fallback ticker or market values.
119
+ *
108
120
  * @param {object} [repairInput={}] Optional repair payload that may include
109
121
  * `calls[0].args`.
110
122
  * @returns {{ tool: string, args: { ticker: string, market: "US" | "HK" | "CN" } }[]}
@@ -113,18 +125,12 @@ const intentionallyMalformedArgs = { symbol: "Apple", market: "NASDAQ" };
113
125
  * AAPL, and unsupported markets fall back to US.
114
126
  */
115
127
  function repairDemoStockCall(repairInput = {}) {
116
- const hasUsableArgsShape = (value) =>
117
- typeof value === "object" &&
118
- value != null &&
119
- !Array.isArray(value) &&
120
- ("ticker" in value || "symbol" in value || "market" in value);
121
-
122
128
  const attemptedArgs =
123
129
  Array.isArray(repairInput?.calls) &&
124
130
  repairInput.calls.length > 0 &&
125
131
  hasUsableArgsShape(repairInput.calls[0]?.args)
126
132
  ? repairInput.calls[0].args
127
- : intentionallyMalformedArgs;
133
+ : createDemoMalformedInput();
128
134
 
129
135
  const attemptedTicker =
130
136
  typeof attemptedArgs.ticker === "string"
@@ -133,7 +139,7 @@ function repairDemoStockCall(repairInput = {}) {
133
139
  ? attemptedArgs.symbol
134
140
  : "AAPL";
135
141
  const normalizedTicker = attemptedTicker.trim().toLowerCase();
136
- // This demo falls back to AAPL when no ticker-like value is available.
142
+ // This demo maps empty input and the "apple" alias to AAPL.
137
143
  const ticker =
138
144
  normalizedTicker === ""
139
145
  ? "AAPL"
@@ -162,13 +168,23 @@ if (!Array.isArray(wrappedTools) || wrappedTools.length === 0) {
162
168
  );
163
169
  }
164
170
 
165
- const wrappedStockQuote = wrappedTools[0];
171
+ const wrappedStockQuote = wrappedTools.find((tool) => tool?.name === "stock_quote");
172
+ if (wrappedStockQuote == null) {
173
+ exitWithError(
174
+ "tool wrapping",
175
+ new Error("betterTools did not return a wrapped stock_quote tool")
176
+ );
177
+ }
178
+
179
+ // Intentionally malformed demo input: "symbol" should be "ticker", and
180
+ // "NASDAQ" is not one of the schema-valid markets ("US", "HK", or "CN").
181
+ const demoMalformedInput = createDemoMalformedInput();
166
182
 
167
183
  let wrappedOutput;
168
184
  try {
169
- wrappedOutput = await wrappedStockQuote.invoke(intentionallyMalformedArgs);
185
+ wrappedOutput = await wrappedStockQuote.invoke(demoMalformedInput);
170
186
  } catch (error) {
171
- const context = `tool=stock_quote args=${JSON.stringify(intentionallyMalformedArgs)}`;
187
+ const context = `tool=stock_quote args=${JSON.stringify(demoMalformedInput)}`;
172
188
  const message = `${errorMessage(error)} (${context})`;
173
189
  const contextualError =
174
190
  error instanceof Error ? new Error(message, { cause: error }) : new Error(message);
@@ -181,9 +197,9 @@ try {
181
197
  userInput: "Get Apple stock in the US market.",
182
198
  tools: [stockQuote],
183
199
  // Both the tool name and args are intentionally wrong to demonstrate repair:
184
- // "stock_price" should be "stock_quote"; intentionallyMalformedArgs uses
200
+ // "stock_price" should be "stock_quote"; demoMalformedInput uses
185
201
  // "symbol"/"NASDAQ" instead of schema-valid stock_quote args.
186
- calls: [{ tool: "stock_price", args: intentionallyMalformedArgs }],
202
+ calls: [{ tool: "stock_price", args: demoMalformedInput }],
187
203
  repair: repairDemoStockCall,
188
204
  });
189
205
  } catch (error) {
@@ -240,12 +256,13 @@ const repairedCall =
240
256
 
241
257
  const report = {
242
258
  wrappedTool: {
243
- before: intentionallyMalformedArgs,
259
+ before: demoMalformedInput,
244
260
  after: wrappedOutput,
245
261
  },
246
262
  reliableToolCalls: {
247
- before: { tool: "stock_price", args: intentionallyMalformedArgs },
263
+ before: { tool: "stock_price", args: demoMalformedInput },
248
264
  repaired: repairedCall,
265
+ // Optional validation/repair metadata; null means this run returned none.
249
266
  diagnostics: reliableResult?.diagnostics ?? null,
250
267
  },
251
268
  gatewayRepair: gatewayRepairResult,