@agent-cards/commerce-sdk 0.16.0 → 0.18.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 CHANGED
@@ -242,29 +242,30 @@ Every list in the reply comes as bullet lines that start with `• `, the choice
242
242
 
243
243
  An answer that asks the shopper to choose, such as a sandwich's bread, a shirt's size or a store's own size question, carries `result.choice`: each group with every value, its option id and its extra price in `price_delta_cents`. The reply shown as written lists each value on its own `• ` line under the question, with its extra price, and so does one more `onText` message when the streamed reply named the values inside a sentence. `withChoice(text, result.choice)` lists them under any text of your own.
244
244
 
245
- ### Send a clear shopping message straight to Agentcard
245
+ ### Let Agentcard answer shopping first
246
246
 
247
- Your model's first call on most messages only decides to call the buy tool. Pass `direct: true` to `buyTool`, and each turn reads its message by rule, with no model, and sets `turn.direct` when the message goes straight to Agentcard: a request to buy or book something (`find me usb-c cables under $20`, `aa batteries on amazon`), a pick of what Agentcard just showed (a card's tap, `the first one`, `1 and 3`), or the answer to the question Agentcard just asked (the address, a code, `medium`, or a plain yes to the total it asked the shopper to confirm). Send the call yourself, and with `replyAsWritten` the turn makes no model call at all:
247
+ Send the shopper's message to Agentcard before your model runs, and run your model only when the message is yours:
248
248
 
249
249
  ```ts
250
- const turn = buy.turn(message, { onMessage: (text) => sendText(shopper.id, text) });
251
- let messages = turn.messages(history);
252
- if (turn.direct) {
253
- const id = `toolu_direct_${crypto.randomUUID().replace(/-/g, '')}`;
254
- const content = await turn.run(turn.direct.input);
255
- messages = [...messages, { role: 'assistant', content: [{ type: 'tool_use', id, name: turn.name, input: turn.direct.input }] }, { role: 'user', content: [{ type: 'tool_result', tool_use_id: id, content }] }];
256
- if (turn.replyAsWritten !== null) {
257
- await turn.say(turn.replyAsWritten);
258
- history = [...messages, { role: 'assistant', content: turn.replyAsWritten }];
259
- return;
260
- }
250
+ const turn = buy.turn(message, {
251
+ onItem: (item) => (item.kind === 'text' ? sendText(shopper.id, item.text) : sendCard(shopper.id, item.link)), // your code
252
+ });
253
+ if (await turn.handled()) {
254
+ // Agentcard answered the shopper: keep the exchange, so your model reads it on the next message.
255
+ const said = turn.items.flatMap((item) => (item.kind === 'text' ? [item.text] : [])).join('\n\n');
256
+ history = [...turn.messages(history), { role: 'assistant', content: said }];
257
+ return;
261
258
  }
262
- // Otherwise run your model on `messages` as before: it words the answer to the call already made, or decides the call itself.
259
+ // Otherwise run your model on turn.messages(history), as before.
263
260
  ```
264
261
 
265
- A turn `buy.nextStep` opens carries `turn.direct` too, with the reason `next_step`: its call reads where the purchase stands whatever the model would write, so send it the same way. With `replyAsWritten`, a step whose answer is a link, such as the approval link once the shopper saved their card, then reaches the shopper with no model call at all.
262
+ Agentcard answers a request to buy or book, with or without a verb (`Printer paper, one ream`), a pick of what it just showed (a card's tap, `the second one`, `1 and 3`), an answer to its question (the address, a code, `medium`) and a yes to a total. When its reply only asks the shopper something, the turn sends it through `onItem`, after the cards and the card, sign-in or approval link it handed over, and `handled()` resolves `true`: no model call before the search, and none after it.
263
+
264
+ Every other message comes back from Agentcard as yours in about 0.1 to 0.2 seconds, with no search, and `handled()` resolves `false`: small talk, a question, a change of mind such as `no` or `wait`, and anything about the account or an order. An answer your model has to word, such as an order placed or a refusal, resolves `false` too, and `turn.messages(history)` hands your model that answer with the shopper's message, so it words it and calls the tool no second time.
265
+
266
+ `handled()` sends one call, once, and a second call resolves as the first did. A turn `buy.nextStep` opened resolves `false` and sends nothing: take it as "Take the next step once the shopper finishes one outside the chat" shows.
266
267
 
267
- Everything else leaves `turn.direct` null for your model: a question, small talk, a change of mind such as `no` or `wait`, a command to the cart, and anything about the account or an order. A pick or an answer goes straight only when the shopper's last turn ended on Agentcard's answer, so a reply to something your model said reaches your model. `directCall(text, context)` applies the same rule to one message, for an app that keeps its own state. The option is off by default, because it moves the decision of when to call Agentcard from your model into the tool.
268
+ You no longer need `direct` or `replyAsWritten` for this. They still work as they did: `direct: true` sets `turn.direct` to the call the tool's own rule reads in a message (`directCall(text, context)`), and `replyAsWritten: true` sets `turn.replyAsWritten`, for an app that sends the call itself. An app that never calls `handled()` sends nothing until its model calls the tool.
268
269
 
269
270
  ### Hand the app the turn in order
270
271
 
@@ -409,7 +410,7 @@ A reaction is the default acknowledgement. It names nothing the shopper said, so
409
410
 
410
411
  - A message that starts a search gets it the moment `buy.turn` opens, before your model runs.
411
412
  - A pick of a product or a store the shopper saw, an address or other details, an answer to a question such as `yes`, `2` or a code, a step toward checkout such as `ok lets checkout`, and an acknowledgement such as `its ok` get none when the turn opens, because Agentcard answers them fast.
412
- - A call that Agentcard has not answered within 1.5 seconds puts the 👀 on a message that has none yet: a slow `yes`, a pick, or a confirm that is still placing the order. It sends no text.
413
+ - A call that Agentcard has not answered within 1 second puts the 👀 on a message that has none yet: a slow `yes`, a pick, or a confirm that is still placing the order. It sends no text.
413
414
  - A turn that runs long, even past a minute, still gets no text line. A search often takes 10 to 40 seconds, so a line at any wait short enough to help would land on most searches and bring back the chatter the reaction replaces. To show a long wait, pass `onProgress` and show its stage, such as `checking_out`, as a status line or a typing indicator.
414
415
 
415
416
  With `onItem` on `buy.turn`, the 👀 still goes to `onReaction` and never joins the turn's items, because it sits on the shopper's bubble rather than in the agent's sequence. Without an `onReaction`, the text instant reply is the turn's first `text` item, as before.
@@ -431,9 +432,9 @@ const buy = buyTool({
431
432
 
432
433
  `ack` takes `'reaction'`, `'text'` or `'none'`. Left out, the tool reacts when the tool or the turn has an `onReaction`, and sends text through `onWorking` otherwise, so an app built on 0.9 with only `onWorking` keeps its text replies. With both callbacks, the shopper gets the 👀 and never the text too. `'none'`, or `false`, sends nothing.
433
434
 
434
- In text mode, the tool sends the reply when Agentcard has not answered a new request within 1.5 seconds, so a quick answer arrives alone. It sends one for the calls the model makes in one turn, where a call that starts within 15 seconds of the last one ending counts as the same turn. A slow confirm or pick never hears `looking for`: a pick of a product the shopper saw hears `adding it now`, a pick of a store or a place in a list, such as `the first one`, hears `got it, one moment`, and a confirm hears `on it, one moment`. None of them names anything the shopper said, and a code hears nothing. The words rotate through six templates, and one tool never sends the same template twice in a row. A short paraphrase of the request goes in when the tool can read one: it stops before any link, email address, phone number, street address or long number, and a request that starts with one gets a reply that names nothing, such as `looking for that now`. The call waits for `onWorking`, so the shopper reads the reply before any link and before the model answers. An `onWorking` that throws costs only the instant reply.
435
+ In text mode, a streamed search's reply is Agentcard's own line, written from the conversation while it searches, such as `one sec, checking target for la croix`, and it reaches `onWorking` before the cards or not at all. A search `buy.turn` sends straight that has shown the shopper nothing by twice `ackDelayMs`, because Agentcard wrote no line or its line was dropped, sends `one moment` once, and a line of Agentcard's that comes after it is dropped. When your model's run fails before it wrote or called anything, call `turn.end()` before you show your error, so no wait line follows it. With `stream: false`, the tool sends its own reply when Agentcard has not answered a new request within `ackDelayMs`, 1 second by default, so a quick answer arrives alone. It sends one for the calls the model makes in one turn, where a call that starts within 15 seconds of the last one ending counts as the same turn. A slow confirm or pick never hears `looking for`: a pick, of a product, a store or a place in a list such as `the first one`, hears `got it, one moment`, a confirm hears `on it, one moment`, and any other answer hears `one moment`. A turn opened with `buy.turn` that has shown the shopper nothing, no line and no card, after the delay sends that line once. None of them names anything the shopper said, and a code hears nothing. The words rotate through six templates, and one tool never sends the same template twice in a row. A short paraphrase of the request goes in when the tool can read one: it stops before any link, email address, phone number, street address or long number, and a request that starts with one gets a reply that names nothing, such as `looking for that now`. The call waits for `onWorking`, so the shopper reads the reply before any link and before the model answers. An `onWorking` that throws costs only the instant reply.
435
436
 
436
- Pass `ack: (ask) => text` to write your own text from the shopper's words, where an empty answer sends none, and `ackDelayMs` to change the 1.5 seconds for either mode.
437
+ Pass `ack: (ask) => text` to write your own text from the shopper's words, where an empty answer sends none, and `ackDelayMs` to change the 1 second for either mode.
437
438
 
438
439
  The model takes several seconds to call the tool after the shopper's message arrives. Without `buy.turn`, react sooner by calling `buy.instantReaction(message)` the moment the message arrives, before your model runs, and put the emoji it returns on the message. In text mode, call `buy.instantAck(message)` and send the text it returns:
439
440
 
@@ -447,7 +448,7 @@ if (ack) await textShopper(shopper.id, ack);
447
448
 
448
449
  With `buy.turn`, pass `onReaction` or `onWorking` to the turn instead: it acknowledges the moment the turn opens, and calls `instantReaction` or `instantAck` for you. When either returns a 👀 or a reply, the tool sends none of its own for that turn.
449
450
 
450
- `instantReaction` and `instantAck` return null for a message that starts no search: a confirmation or a short answer such as `yes`, `1` or `ok`, a step toward paying for the cart such as `ok lets checkout`, `place the order` or `pay`, an acknowledgement such as `its ok`, `thats fine` or `sounds good`, a pick of a product the shopper already saw, such as `the first one`, `#2`, `I want the blue one` or a card's title with its price, a pick of a store, such as `order here` or a store card's `Order from Tacos El Grullense`, a code, small talk such as `hi` or `how are you`, a message that carries the shopper's own details, such as a name with a phone number, an email address, a street address, a bare house number and street such as `1801 wedemeyer`, or a zip code, any message that answers the last answer's request for an address, shipping or guest details or a code, and a short reply right after any other question the last answer asked, such as `im a 37` after `what size do you want?`, or `carne asada` after `which meat?`. A reply that opens a new request, such as `find me black running shoes`, or that runs past four words is still a search. The reply never reads those details back, never repeats the shopper's own first-person words, and names the request only when it reads as a short, whole phrase; otherwise it says `on it, give me a moment` or another reply that names nothing. The tool also reads a message that quotes the name of a product its last answer showed, or names one of the stores its last answer listed and nothing else to buy, as a pick of it. A request for a store the shopper did not see, such as `order from chipotle`, reads back as `looking for chipotle`, never `looking for from chipotle`. When it returns a reply, the tool sends none of its own through `onWorking` for that turn, and the model reads `shopper_already_told_looking: true`, so the shopper hears one acknowledgement. When it returns null for a message that picks nothing, such as `yes`, a call that runs past `ackDelayMs` still acknowledges: with a 👀 in reaction mode, and in text mode with an `onWorking` reply that names nothing and never says it is looking for anything, such as `working on it` or `one moment`, and when it returns null for a pick, such a call sends `adding it now` or `got it, one moment`.
451
+ `instantReaction` and `instantAck` return null for a message that starts no search: a confirmation or a short answer such as `yes`, `1` or `ok`, a step toward paying for the cart such as `ok lets checkout`, `place the order` or `pay`, an acknowledgement such as `its ok`, `thats fine` or `sounds good`, a pick of a product the shopper already saw, such as `the first one`, `#2`, `I want the blue one` or a card's title with its price, a pick of a store, such as `order here` or a store card's `Order from Tacos El Grullense`, a code, small talk such as `hi` or `how are you`, a message that carries the shopper's own details, such as a name with a phone number, an email address, a street address, a bare house number and street such as `1801 wedemeyer`, or a zip code, any message that answers the last answer's request for an address, shipping or guest details or a code, and a short reply right after any other question the last answer asked, such as `im a 37` after `what size do you want?`, or `carne asada` after `which meat?`. A reply that opens a new request, such as `find me black running shoes`, or that runs past four words is still a search. The reply never reads those details back, never repeats the shopper's own first-person words, and names the request only when it reads as a short, whole phrase; otherwise it says `on it, give me a moment` or another reply that names nothing. The tool also reads a message that quotes the name of a product its last answer showed, or names one of the stores its last answer listed and nothing else to buy, as a pick of it. A request for a store the shopper did not see, such as `order from chipotle`, reads back as `looking for chipotle`, never `looking for from chipotle`. When it returns a reply, the tool sends none of its own through `onWorking` for that turn, and the model reads `shopper_already_told_looking: true`, so the shopper hears one acknowledgement. When it returns null for a message that picks nothing, such as `yes`, a call that runs past `ackDelayMs` still acknowledges: with a 👀 in reaction mode, and in text mode with an `onWorking` reply that names nothing and never says it is looking for anything, such as `one moment`, and when it returns null for a pick, such a call sends `got it, one moment`.
451
452
 
452
453
  Without a buy tool, `instantReaction(message, { nextAction, asked, stores })` and `instantAck(message, { previous, nextAction, asked, stores })` from the package root decide the same way, and `ACK_REACTION` is the `👀` `instantReaction` returns: `previous` is the reply you sent last, so the next one comes from another template, `nextAction` is the last answer's `next_action`, `asked` is the last message the shopper read, so an answer to its question for an address, a name or a code, or a short answer to any other question it asked, gets none, and `stores` holds the names of the stores the last answer listed, so a message that picks one gets none. Pass `ack: 'none'` to the tool when you acknowledge yourself. `ackFor` is the earlier name of the same function.
453
454
 
package/dist/ack.d.ts CHANGED
@@ -43,13 +43,23 @@ export declare function paraphrase(text: string): string | null;
43
43
  export declare function ackAt(index: number, text: string): string;
44
44
  /** The reply at `index` for a message that is no search: it says Agentcard is working, and never that it is looking for anything. */
45
45
  export declare function waitAt(index: number): string;
46
- /** What a slow call that is not a new request is doing: adding a product the shopper picked, choosing a store, or going through with a cart. */
47
- export type SlowStep = 'product' | 'pick' | 'confirm';
48
46
  /**
49
- * The reply a slow pick or confirm sends once Agentcard takes longer than the delay: fixed words that
50
- * name nothing the shopper said and never say `looking for`, because the shopper already chose.
47
+ * What a slow call that is not a new request is doing: adding a product the shopper picked, choosing a store, going
48
+ * through with a cart, or answering anything else, such as `yes` or an address.
49
+ */
50
+ export type SlowStep = 'product' | 'pick' | 'confirm' | 'wait';
51
+ /**
52
+ * The reply a slow pick, confirm or answer sends once Agentcard takes longer than the delay: fixed words that
53
+ * name nothing the shopper said and never say `looking for`, because the shopper already chose. A pick never
54
+ * says it is adding anything: a sandwich's bread can still hold the cart line up.
51
55
  */
52
56
  export declare function slowStepLine(step: SlowStep): string;
57
+ /**
58
+ * Whether a model's message reads as an acknowledgement, such as `on it, looking for a dryer under $20`: one short line
59
+ * that opens with acknowledging words, says the turn is working, asks nothing and says nothing of what a search or a
60
+ * cart came to. A question, an answer such as `i can only help with shopping.`, or anything longer is not.
61
+ */
62
+ export declare function readsAsAckLine(message: string): boolean;
53
63
  /** A template other than `avoid`, picked at random. */
54
64
  export declare function nextTemplate(avoid: number, random?: () => number): number;
55
65
  export interface AckForOptions {
package/dist/ack.js CHANGED
@@ -298,11 +298,37 @@ export function waitAt(index) {
298
298
  return WAITS[((index % WAITS.length) + WAITS.length) % WAITS.length];
299
299
  }
300
300
  /**
301
- * The reply a slow pick or confirm sends once Agentcard takes longer than the delay: fixed words that
302
- * name nothing the shopper said and never say `looking for`, because the shopper already chose.
301
+ * The reply a slow pick, confirm or answer sends once Agentcard takes longer than the delay: fixed words that
302
+ * name nothing the shopper said and never say `looking for`, because the shopper already chose. A pick never
303
+ * says it is adding anything: a sandwich's bread can still hold the cart line up.
303
304
  */
304
305
  export function slowStepLine(step) {
305
- return step === 'product' ? 'adding it now' : step === 'confirm' ? 'on it, one moment' : 'got it, one moment';
306
+ return step === 'confirm' ? 'on it, one moment' : step === 'wait' ? 'one moment' : 'got it, one moment';
307
+ }
308
+ /** Words that say what a search or a cart came to, which no acknowledgement can know yet. */
309
+ const RESULT_CLAIM = /\b(found|finds?|added|adding|placed|total|totals|price[sd]?|pricing|in stock|out of stock|sold out|ordered|paid|charged|cart|costs?|here (?:are|is|'s))\b/i;
310
+ /** The most characters a model's acknowledgement line runs to, such as `on it, looking for a dryer under $20`. */
311
+ const ACK_LINE_MAX = 90;
312
+ /** Words an acknowledgement opens with, such as `on it,` in `on it, looking for a dryer under $20`. */
313
+ const ACK_OPENER = /^(?:(?:ok|okay|sure(?: thing)?|alright|all right|yes|yeah|yep|got it|on it|will do|of course|no problem|happy to help|absolutely)\b[\s,.!-]*)+/;
314
+ /** What is left of an acknowledgement after its opening words: it says the turn is working, and nothing else. */
315
+ const ACK_WORK = /^(?:(?:i'?ll|i'?m going to|i'?m gonna|i'?m|i am|let me|lemme|let'?s|just|now|gonna|going to)\s+)*(?:look|looking|check|checking|search|searching|finding|see what|seeing what|pull(?:ing)? up|work(?:ing)? on|dig(?:ging)?|hunt(?:ing)?|browse|browsing|start(?:ing)?)\b|^(?:one (?:moment|sec|second|minute)|a (?:moment|sec|second)|just a (?:moment|sec|second|minute)|give me a (?:moment|sec|second|minute)|hang tight|hold (?:on|tight)|two secs?|moment)\b/;
316
+ /**
317
+ * Whether a model's message reads as an acknowledgement, such as `on it, looking for a dryer under $20`: one short line
318
+ * that opens with acknowledging words, says the turn is working, asks nothing and says nothing of what a search or a
319
+ * cart came to. A question, an answer such as `i can only help with shopping.`, or anything longer is not.
320
+ */
321
+ export function readsAsAckLine(message) {
322
+ const line = String(message ?? '').trim();
323
+ if (line === '' || line.length > ACK_LINE_MAX || /[\r\n]/.test(line))
324
+ return false;
325
+ if (line.includes('?'))
326
+ return false;
327
+ if (RESULT_CLAIM.test(line))
328
+ return false;
329
+ // `on it` or `got it` is the whole acknowledgement; whatever follows those words has to say the turn is working.
330
+ const rest = line.toLowerCase().replace(ACK_OPENER, '').replace(/[\s,.!-]+$/, '');
331
+ return rest === '' ? ACK_OPENER.test(line.toLowerCase()) : ACK_WORK.test(rest);
306
332
  }
307
333
  /** A template other than `avoid`, picked at random. */
308
334
  export function nextTemplate(avoid, random = Math.random) {
@@ -315,12 +315,14 @@ export interface BuyToolOptions {
315
315
  */
316
316
  onReaction?: (emoji: string) => void | Promise<void>;
317
317
  /**
318
- * Sends the shopper an instant reply, such as `on it, looking for usb-c cables under $20`, while
319
- * Agentcard works on a new request, when the tool acknowledges in text: with `ack: 'text'`, or with
320
- * no `onReaction`. It goes out when Agentcard has not answered within
321
- * `ackDelayMs`, once for the calls the model makes in one turn. A slow pick gets `adding it now`
322
- * for a product or `got it, one moment` for a store or a place in a list. A slow confirm gets
323
- * `on it, one moment`. These replies name nothing the shopper said. A code gets no reply.
318
+ * Sends the shopper an instant reply, when the tool acknowledges in text: with `ack: 'text'`, or with
319
+ * no `onReaction`. A streamed search's reply is Agentcard's own line, such as `one sec, checking target
320
+ * for la croix`, written while it searches and sent before the cards or not at all; a search `buy.turn` sends
321
+ * straight that has shown nothing by twice `ackDelayMs` gets `one moment` instead; with `stream: false`
322
+ * it is the tool's template, once Agentcard has not answered within `ackDelayMs`. A pick, a confirm or
323
+ * any other answer that has shown nothing for `ackDelayMs` gets `got it, one moment`, `on it, one
324
+ * moment` or `one moment`, once for the calls the model makes in one turn. These replies name nothing
325
+ * the shopper said. A code gets no reply.
324
326
  * The call waits for it before it returns, so the shopper reads it before any link or the model's
325
327
  * answer. One that throws costs nothing but the instant reply.
326
328
  */
@@ -334,7 +336,7 @@ export interface BuyToolOptions {
334
336
  * names nothing.
335
337
  */
336
338
  ack?: BuyAckMode | false | ((ask: string) => string | null | undefined);
337
- /** How long Agentcard has to answer before the instant reply or the reaction goes out. Default 1500. */
339
+ /** How long a turn shows the shopper nothing before the instant reply or the reaction goes out. Default 1000. */
338
340
  ackDelayMs?: number;
339
341
  /**
340
342
  * Called with the whole answer once per call, after its links went out and before the model reads
@@ -620,6 +622,13 @@ export interface BuyToolTurn extends Omit<BuyTool, 'instantAck' | 'instantReacti
620
622
  * `buy.nextStep` for the same event opens a turn again, as on a webhook's redelivery. Does nothing on another turn.
621
623
  */
622
624
  release(): void;
625
+ /**
626
+ * Ends the turn: call it once your agent is done with the message, and above all when your model's run failed before
627
+ * it wrote or called anything. No wait line, such as `one moment`, and no 👀 goes out after it, not even for a call
628
+ * still running, so the shopper never reads that the turn is still working after your app showed its error. Calling it
629
+ * again does nothing.
630
+ */
631
+ end(): void;
623
632
  /** The instant reply this turn sent to `onWorking` when it opened, or null when it sent none, as with a reaction. */
624
633
  readonly ack: string | null;
625
634
  /** The reaction this turn put on the shopper's message, `👀`, when it opened or once a call ran slow, or null while it put none or when `onReaction` threw. */
@@ -668,6 +677,16 @@ export interface BuyToolTurn extends Omit<BuyTool, 'instantAck' | 'instantReacti
668
677
  * is set; when it is null, hand your model the call and its result, and its words answer the shopper.
669
678
  */
670
679
  readonly direct: DirectCall | null;
680
+ /**
681
+ * Sends the shopper's message to Agentcard and resolves `true` when Agentcard answered the shopper: a request to buy, a
682
+ * pick of what it showed, an answer to its question or a yes to a total, whose reply only asks the shopper something
683
+ * and went out with `say()`. Resolves `false` when your model answers: Agentcard read the message as yours, such as
684
+ * small talk or a question about an order, in well under a second and with no model call, or it answered with an order
685
+ * placed or a refusal for your model to word, which `messages(history)` then hands it. Call it once, before your model
686
+ * runs; a second call resolves as the first did. A turn `buy.nextStep` opened, or one opened while a call still runs,
687
+ * resolves `false` and sends nothing.
688
+ */
689
+ handled(): Promise<boolean>;
671
690
  /**
672
691
  * Every message and link the turn handed over, in the order they went out: the instant reply, each
673
692
  * link, each message of Agentcard's that `onText` took, and each message written through `messageStream()`
@@ -703,6 +722,8 @@ export type BuyToolTurnMessage = {
703
722
  * or an OpenAI Responses item, they come as an assistant message of their own.
704
723
  */
705
724
  export declare function turnMessages<M extends object>(history: readonly M[] | null | undefined, told: readonly string[], shopperText: string): Array<M | BuyToolTurnMessage>;
725
+ /** The note a message carries to the model when Agentcard already answered it and left the words to the model (`handled()`). */
726
+ export declare function handedNote(answer: string): string;
706
727
  /**
707
728
  * The words a `nextStep` turn hands the model as the user's message: the event, marked as no one's
708
729
  * typing, and the instruction to take the next step now in one short message, without the filler of