@botbotgo/better-call 0.1.47 → 0.1.49

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 +44 -25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/better-call",
3
- "version": "0.1.47",
3
+ "version": "0.1.49",
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
@@ -3,6 +3,8 @@ import { betterTools, repairToolCall, reliableToolCalls } from "../dist/index.js
3
3
 
4
4
  const json = process.argv.includes("--json");
5
5
  const VALID_MARKETS = ["US", "HK", "CN"];
6
+ // Intentionally incorrect tool name used to demonstrate tool-call repair behavior.
7
+ const DEMO_INVALID_TOOL_NAME = "stock_price";
6
8
 
7
9
  function errorMessage(error) {
8
10
  return error instanceof Error ? error.message : String(error);
@@ -52,6 +54,19 @@ function displayValue(value) {
52
54
  return value == null ? "(none)" : String(value);
53
55
  }
54
56
 
57
+ function hasUsableArgsShape(value) {
58
+ return (
59
+ typeof value === "object" &&
60
+ value != null &&
61
+ !Array.isArray(value) &&
62
+ ("ticker" in value || "symbol" in value || "market" in value)
63
+ );
64
+ }
65
+
66
+ function createDemoMalformedInput() {
67
+ return { symbol: "Apple", market: "NASDAQ" };
68
+ }
69
+
55
70
  function exitWithError(step, error) {
56
71
  const message = errorMessage(error);
57
72
 
@@ -98,10 +113,6 @@ const stockQuote = {
98
113
  },
99
114
  };
100
115
 
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 DEMO_MALFORMED_INPUT = { symbol: "Apple", market: "NASDAQ" };
104
-
105
116
  /**
106
117
  * Repairs malformed stock quote tool-call input into one schema-valid call.
107
118
  *
@@ -116,33 +127,31 @@ const DEMO_MALFORMED_INPUT = { symbol: "Apple", market: "NASDAQ" };
116
127
  * AAPL, and unsupported markets fall back to US.
117
128
  */
118
129
  function repairDemoStockCall(repairInput = {}) {
119
- const hasUsableArgsShape = (value) =>
120
- typeof value === "object" &&
121
- value != null &&
122
- !Array.isArray(value) &&
123
- ("ticker" in value || "symbol" in value || "market" in value);
124
-
125
130
  const attemptedArgs =
126
131
  Array.isArray(repairInput?.calls) &&
127
132
  repairInput.calls.length > 0 &&
128
133
  hasUsableArgsShape(repairInput.calls[0]?.args)
129
134
  ? repairInput.calls[0].args
130
- : DEMO_MALFORMED_INPUT;
135
+ : createDemoMalformedInput();
131
136
 
132
- const attemptedTicker =
137
+ const rawAttemptedTicker =
133
138
  typeof attemptedArgs.ticker === "string"
134
139
  ? attemptedArgs.ticker
135
140
  : typeof attemptedArgs.symbol === "string"
136
141
  ? attemptedArgs.symbol
137
142
  : "AAPL";
143
+ const attemptedTicker =
144
+ typeof rawAttemptedTicker === "string" ? rawAttemptedTicker : "AAPL";
138
145
  const normalizedTicker = attemptedTicker.trim().toLowerCase();
139
146
  // This demo maps empty input and the "apple" alias to AAPL.
140
- const ticker =
141
- normalizedTicker === ""
142
- ? "AAPL"
143
- : normalizedTicker === "apple"
144
- ? "AAPL"
145
- : normalizedTicker.toUpperCase();
147
+ let ticker;
148
+ if (normalizedTicker === "") {
149
+ ticker = "AAPL";
150
+ } else if (normalizedTicker === "apple") {
151
+ ticker = "AAPL";
152
+ } else {
153
+ ticker = normalizedTicker.toUpperCase();
154
+ }
146
155
 
147
156
  const attemptedMarket = typeof attemptedArgs.market === "string" ? attemptedArgs.market : null;
148
157
  const market =
@@ -165,13 +174,23 @@ if (!Array.isArray(wrappedTools) || wrappedTools.length === 0) {
165
174
  );
166
175
  }
167
176
 
168
- const wrappedStockQuote = wrappedTools[0];
177
+ const wrappedStockQuote = wrappedTools.find((tool) => tool?.name === "stock_quote");
178
+ if (wrappedStockQuote == null) {
179
+ exitWithError(
180
+ "tool wrapping",
181
+ new Error("betterTools did not return a wrapped stock_quote tool")
182
+ );
183
+ }
184
+
185
+ // Intentionally malformed demo input: "symbol" should be "ticker", and
186
+ // "NASDAQ" is not one of the schema-valid markets ("US", "HK", or "CN").
187
+ const demoMalformedInput = createDemoMalformedInput();
169
188
 
170
189
  let wrappedOutput;
171
190
  try {
172
- wrappedOutput = await wrappedStockQuote.invoke(DEMO_MALFORMED_INPUT);
191
+ wrappedOutput = await wrappedStockQuote.invoke(demoMalformedInput);
173
192
  } catch (error) {
174
- const context = `tool=stock_quote args=${JSON.stringify(DEMO_MALFORMED_INPUT)}`;
193
+ const context = `tool=stock_quote args=${JSON.stringify(demoMalformedInput)}`;
175
194
  const message = `${errorMessage(error)} (${context})`;
176
195
  const contextualError =
177
196
  error instanceof Error ? new Error(message, { cause: error }) : new Error(message);
@@ -184,9 +203,9 @@ try {
184
203
  userInput: "Get Apple stock in the US market.",
185
204
  tools: [stockQuote],
186
205
  // Both the tool name and args are intentionally wrong to demonstrate repair:
187
- // "stock_price" should be "stock_quote"; DEMO_MALFORMED_INPUT uses
206
+ // DEMO_INVALID_TOOL_NAME should be "stock_quote"; demoMalformedInput uses
188
207
  // "symbol"/"NASDAQ" instead of schema-valid stock_quote args.
189
- calls: [{ tool: "stock_price", args: DEMO_MALFORMED_INPUT }],
208
+ calls: [{ tool: DEMO_INVALID_TOOL_NAME, args: demoMalformedInput }],
190
209
  repair: repairDemoStockCall,
191
210
  });
192
211
  } catch (error) {
@@ -243,11 +262,11 @@ const repairedCall =
243
262
 
244
263
  const report = {
245
264
  wrappedTool: {
246
- before: DEMO_MALFORMED_INPUT,
265
+ before: demoMalformedInput,
247
266
  after: wrappedOutput,
248
267
  },
249
268
  reliableToolCalls: {
250
- before: { tool: "stock_price", args: DEMO_MALFORMED_INPUT },
269
+ before: { tool: DEMO_INVALID_TOOL_NAME, args: demoMalformedInput },
251
270
  repaired: repairedCall,
252
271
  // Optional validation/repair metadata; null means this run returned none.
253
272
  diagnostics: reliableResult?.diagnostics ?? null,