@agent-cards/commerce-sdk 0.16.0 → 0.17.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 +4 -4
- package/dist/ack.d.ts +14 -4
- package/dist/ack.js +29 -3
- package/dist/buy-tool.d.ts +16 -7
- package/dist/buy-tool.js +270 -21
- package/dist/client.d.ts +8 -0
- package/dist/client.js +4 -1
- package/dist/definition.js +1 -0
- package/dist/direct.d.ts +11 -1
- package/dist/direct.js +34 -7
- package/dist/messages.d.ts +27 -6
- package/dist/messages.js +68 -8
- package/dist/model-view.d.ts +5 -2
- package/dist/model-view.js +192 -23
- package/dist/sentences.d.ts +13 -0
- package/dist/sentences.js +28 -0
- package/dist/texting.d.ts +2 -0
- package/dist/texting.js +6 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -409,7 +409,7 @@ A reaction is the default acknowledgement. It names nothing the shopper said, so
|
|
|
409
409
|
|
|
410
410
|
- A message that starts a search gets it the moment `buy.turn` opens, before your model runs.
|
|
411
411
|
- 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
|
|
412
|
+
- 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
413
|
- 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
414
|
|
|
415
415
|
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 +431,9 @@ const buy = buyTool({
|
|
|
431
431
|
|
|
432
432
|
`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
433
|
|
|
434
|
-
In text mode, the
|
|
434
|
+
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
435
|
|
|
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
|
|
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 second for either mode.
|
|
437
437
|
|
|
438
438
|
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
439
|
|
|
@@ -447,7 +447,7 @@ if (ack) await textShopper(shopper.id, ack);
|
|
|
447
447
|
|
|
448
448
|
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
449
|
|
|
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 `
|
|
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 `one moment`, and when it returns null for a pick, such a call sends `got it, one moment`.
|
|
451
451
|
|
|
452
452
|
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
453
|
|
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
|
-
*
|
|
50
|
-
*
|
|
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
|
|
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 === '
|
|
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) {
|
package/dist/buy-tool.d.ts
CHANGED
|
@@ -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,
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
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
|
|
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. */
|