@alexkroman1/aai-cli 6.11.0 → 8.0.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 +1 -0
- package/dist/{_agent-DpH2pBJd.mjs → _agent-BTwZJu4P.mjs} +2 -2
- package/dist/{_bundler-C2BDwU7r.mjs → _bundler-CDuYl5Gb.mjs} +2 -2
- package/dist/_dev-env.d.ts +22 -2
- package/dist/{_dev-server-LLLWnFBs.mjs → _dev-server-Me06wgeF.mjs} +38 -47
- package/dist/_dev-server.d.ts +0 -17
- package/dist/{_init-C57bWAQ8.mjs → _init-BhEfQ6Yi.mjs} +3 -2
- package/dist/{_preflight-BtfaYtbE.mjs → _preflight-Co1G9Jww.mjs} +1 -1
- package/dist/_preflight.d.ts +1 -1
- package/dist/_resource-commands.d.ts +23 -0
- package/dist/{_slug-api-BxrsJXVI.mjs → _slug-api-z-USxPtL.mjs} +16 -12
- package/dist/_slug-api.d.ts +5 -2
- package/dist/{_studio-U3jhKlA3.mjs → _studio-DR5yzZ1T.mjs} +2 -1
- package/dist/{_templates-Dxb_P2Wz.mjs → _templates-4WcKOjS5.mjs} +5 -6
- package/dist/_templates.d.ts +3 -4
- package/dist/_workflow-scan.d.ts +108 -0
- package/dist/{build-Dfza2pRI.mjs → build-BBxf8vom.mjs} +6 -3
- package/dist/cli.mjs +346 -349
- package/dist/{client-bundler-BEIqgOtd.mjs → client-bundler-CWnG42cU.mjs} +2 -1
- package/dist/client-bundler.mjs +1 -1
- package/dist/{delete-vbpjGzqs.mjs → delete-Dl_LSfvI.mjs} +3 -3
- package/dist/{deploy-B8lubiRT.mjs → deploy-DRC8jWr8.mjs} +5 -5
- package/dist/{dev-Uq5ujP8a.mjs → dev-BvcctCn2.mjs} +1 -1
- package/dist/eval-DfQ8cm5p.mjs +56 -0
- package/dist/eval.d.ts +43 -0
- package/dist/{init-l6xfU4xX.mjs → init-CUo87gcI.mjs} +3 -3
- package/dist/{login-C71-qz8F.mjs → login-BBuM1sxH.mjs} +3 -4
- package/dist/{logs-BWVGSjLR.mjs → logs-CQ2T46dr.mjs} +2 -2
- package/dist/project-config.mjs +1 -1
- package/dist/scaffold/CLAUDE.md +442 -80
- package/dist/scaffold/package.json +6 -3
- package/dist/scaffold/server.mjs +11 -4
- package/dist/scaffold/tsconfig.json +0 -1
- package/dist/{secret-BuMuFR4B.mjs → secret-Ct34kdgU.mjs} +2 -2
- package/dist/{storage-DzRZ-eCw.mjs → storage-i_79ZwAR.mjs} +2 -2
- package/dist/{studio-BCNUpDgP.mjs → studio-CzTzPqe1.mjs} +4 -4
- package/dist/templates/briefing-desk/agent.test.ts +350 -0
- package/dist/templates/briefing-desk/agent.ts +30 -0
- package/dist/templates/briefing-desk/shared.ts +200 -0
- package/dist/templates/briefing-desk/system-prompt.md +39 -0
- package/dist/templates/briefing-desk/tools/briefing_so_far.ts +35 -0
- package/dist/templates/briefing-desk/tools/research_topic.ts +88 -0
- package/dist/templates/briefing-desk/tools/verify_claim.ts +77 -0
- package/dist/templates/call-audit/agent.eval.test.ts +474 -0
- package/dist/templates/call-audit/agent.test.ts +57 -204
- package/dist/templates/call-audit/agent.ts +32 -19
- package/dist/templates/call-audit/client.tsx +17 -54
- package/dist/templates/call-audit/workflows/audit.ts +11 -18
- package/dist/templates/call-audit/workflows/ingest.ts +106 -114
- package/dist/templates/call-audit/workflows/media.ts +2 -12
- package/dist/templates/call-audit/workflows/summarize.ts +47 -52
- package/dist/templates/call-audit/workflows/sync-api.ts +7 -7
- package/dist/templates/code-interpreter/agent.eval.test.ts +165 -0
- package/dist/templates/dispatch-center/agent.eval.test.ts +349 -0
- package/dist/templates/dispatch-center/agent.test.ts +149 -25
- package/dist/templates/dispatch-center/client.tsx +239 -129
- package/dist/templates/dispatch-center/shared.ts +99 -1
- package/dist/templates/dispatch-center/system-prompt.md +3 -1
- package/dist/templates/dispatch-center/tools/incident_add_note.ts +16 -13
- package/dist/templates/dispatch-center/tools/incident_create.ts +19 -1
- package/dist/templates/dispatch-center/tools/incident_escalate.ts +68 -59
- package/dist/templates/dispatch-center/tools/incident_triage.ts +57 -43
- package/dist/templates/dispatch-center/tools/incident_update_status.ts +49 -40
- package/dist/templates/dispatch-center/tools/ops_run_scenario.ts +8 -2
- package/dist/templates/dispatch-center/tools/resources_dispatch.ts +69 -52
- package/dist/templates/dispatch-center/tools/resources_update_status.ts +45 -41
- package/dist/templates/embedded-assets/agent.eval.test.ts +138 -0
- package/dist/templates/embedded-assets/agent.test.ts +17 -14
- package/dist/templates/health-assistant/agent.eval.test.ts +167 -0
- package/dist/templates/health-assistant/agent.test.ts +22 -4
- package/dist/templates/infocom-adventure/agent.eval.test.ts +158 -0
- package/dist/templates/infocom-adventure/agent.test.ts +53 -24
- package/dist/templates/infocom-adventure/agent.ts +21 -0
- package/dist/templates/infocom-adventure/client.tsx +246 -164
- package/dist/templates/infocom-adventure/shared.ts +20 -9
- package/dist/templates/infocom-adventure/system-prompt.md +1 -1
- package/dist/templates/infocom-adventure/tools/game_state_move.ts +3 -2
- package/dist/templates/link-digest/agent.eval.test.ts +195 -0
- package/dist/templates/link-digest/agent.test.ts +24 -19
- package/dist/templates/link-digest/client.tsx +47 -61
- package/dist/templates/link-digest/workflows/digest.ts +19 -31
- package/dist/templates/math-buddy/agent.eval.test.ts +146 -0
- package/dist/templates/night-owl/agent.eval.test.ts +272 -0
- package/dist/templates/night-owl/agent.test.ts +70 -19
- package/dist/templates/night-owl/agent.ts +5 -0
- package/dist/templates/night-owl/client.tsx +56 -56
- package/dist/templates/night-owl/shared.ts +24 -0
- package/dist/templates/night-owl/tools/recommend.ts +18 -6
- package/dist/templates/personal-finance/agent.eval.test.ts +168 -0
- package/dist/templates/personal-finance/system-prompt.md +4 -0
- package/dist/templates/pipeline-simple/agent.eval.test.ts +78 -0
- package/dist/templates/pipeline-simple/agent.ts +2 -2
- package/dist/templates/pizza-ordering/agent.eval.test.ts +171 -0
- package/dist/templates/pizza-ordering/agent.test.ts +42 -27
- package/dist/templates/pizza-ordering/client.tsx +9 -26
- package/dist/templates/pizza-ordering/shared.ts +20 -1
- package/dist/templates/pizza-ordering/system-prompt.md +6 -0
- package/dist/templates/plan-and-execute/agent.eval.test.ts +209 -0
- package/dist/templates/plan-and-execute/agent.test.ts +99 -58
- package/dist/templates/plan-and-execute/agent.ts +1 -1
- package/dist/templates/plan-and-execute/client.tsx +12 -15
- package/dist/templates/plan-and-execute/shared.ts +71 -2
- package/dist/templates/plan-and-execute/tools/plan_status.ts +18 -6
- package/dist/templates/plan-and-execute/tools/revise_plan.ts +18 -10
- package/dist/templates/plan-and-execute/tools/start_plan.ts +13 -2
- package/dist/templates/plan-and-execute/tools/work_next_step.ts +70 -22
- package/dist/templates/podcast-digest/agent.eval.test.ts +411 -0
- package/dist/templates/podcast-digest/agent.test.ts +717 -0
- package/dist/templates/podcast-digest/agent.ts +139 -0
- package/dist/templates/podcast-digest/client.tsx +154 -0
- package/dist/templates/podcast-digest/workflows/digest.ts +444 -0
- package/dist/templates/podcast-digest/workflows/feeds.ts +507 -0
- package/dist/templates/podcast-digest/workflows/slack.ts +88 -0
- package/dist/templates/recap-workflow/agent.eval.test.ts +366 -0
- package/dist/templates/recap-workflow/agent.test.ts +97 -94
- package/dist/templates/recap-workflow/tools/recap_progress.ts +9 -12
- package/dist/templates/recap-workflow/tools/recap_status.ts +8 -9
- package/dist/templates/recap-workflow/tools/request_recap.ts +2 -1
- package/dist/templates/recap-workflow/workflows/recap.ts +36 -40
- package/dist/templates/redline/agent.eval.test.ts +209 -0
- package/dist/templates/redline/agent.test.ts +17 -15
- package/dist/templates/redline/client.tsx +12 -12
- package/dist/templates/redline/workflows/redline.ts +19 -31
- package/dist/templates/research-workflow/agent.eval.test.ts +329 -0
- package/dist/templates/research-workflow/agent.test.ts +60 -59
- package/dist/templates/research-workflow/tools/research_progress.ts +9 -12
- package/dist/templates/research-workflow/tools/research_status.ts +9 -11
- package/dist/templates/research-workflow/workflows/research.ts +44 -61
- package/dist/templates/retail/address.ts +87 -1
- package/dist/templates/retail/agent.eval.test.ts +314 -0
- package/dist/templates/retail/agent.test.ts +195 -112
- package/dist/templates/retail/agent.ts +35 -1
- package/dist/templates/retail/cancel.ts +116 -0
- package/dist/templates/retail/client.tsx +265 -117
- package/dist/templates/retail/payment.ts +107 -0
- package/dist/templates/retail/pending.test.ts +196 -0
- package/dist/templates/retail/pending.ts +137 -0
- package/dist/templates/retail/registry.test.ts +150 -7
- package/dist/templates/retail/returns.ts +102 -0
- package/dist/templates/retail/shared.test.ts +42 -0
- package/dist/templates/retail/shared.ts +35 -0
- package/dist/templates/retail/store.test.ts +84 -15
- package/dist/templates/retail/store.ts +231 -48
- package/dist/templates/retail/swap.test.ts +4 -4
- package/dist/templates/retail/swap.ts +248 -15
- package/dist/templates/retail/system-prompt.md +69 -28
- package/dist/templates/retail/tools/cancel_change.ts +33 -0
- package/dist/templates/retail/tools/cancel_pending_order.ts +16 -60
- package/dist/templates/retail/tools/confirm_change.ts +42 -0
- package/dist/templates/retail/tools/exchange_delivered_order_items.ts +22 -67
- package/dist/templates/retail/tools/find_user_id_by_email.ts +8 -5
- package/dist/templates/retail/tools/find_user_id_by_name_zip.ts +4 -5
- package/dist/templates/retail/tools/get_item_details.ts +3 -4
- package/dist/templates/retail/tools/get_order_details.ts +3 -4
- package/dist/templates/retail/tools/get_product_details.ts +3 -4
- package/dist/templates/retail/tools/get_user_details.ts +2 -2
- package/dist/templates/retail/tools/list_all_product_types.ts +5 -5
- package/dist/templates/retail/tools/modify_pending_order_address.ts +13 -25
- package/dist/templates/retail/tools/modify_pending_order_items.ts +23 -62
- package/dist/templates/retail/tools/modify_pending_order_payment.ts +16 -78
- package/dist/templates/retail/tools/modify_user_address.ts +13 -16
- package/dist/templates/retail/tools/return_delivered_order_items.ts +17 -72
- package/dist/templates/retail/tools/transfer_to_human_agents.ts +12 -6
- package/dist/templates/simple/agent.eval.test.ts +54 -0
- package/dist/templates/solo-rpg/agent.eval.test.ts +320 -0
- package/dist/templates/solo-rpg/agent.test.ts +227 -48
- package/dist/templates/solo-rpg/client.tsx +38 -37
- package/dist/templates/solo-rpg/shared.ts +145 -19
- package/dist/templates/solo-rpg/system-prompt.md +3 -2
- package/dist/templates/solo-rpg/tools/action_roll.ts +82 -63
- package/dist/templates/solo-rpg/tools/burn_momentum.ts +85 -50
- package/dist/templates/solo-rpg/tools/check_state.ts +24 -7
- package/dist/templates/solo-rpg/tools/load_game.ts +13 -1
- package/dist/templates/solo-rpg/tools/save_game.ts +16 -7
- package/dist/templates/solo-rpg/tools/setup_character.ts +22 -2
- package/dist/templates/solo-rpg/tools/update_state.ts +113 -100
- package/dist/templates/spoken-summary/agent.eval.test.ts +342 -0
- package/dist/templates/spoken-summary/agent.test.ts +68 -97
- package/dist/templates/spoken-summary/agent.ts +30 -17
- package/dist/templates/spoken-summary/client.tsx +10 -50
- package/dist/templates/spoken-summary/workflows/summarize.ts +17 -22
- package/dist/templates/spoken-summary/workflows/transcribe.ts +19 -26
- package/dist/templates/support-line/agent.eval.test.ts +273 -0
- package/dist/templates/support-line/agent.test.ts +11 -16
- package/dist/templates/support-line/agent.ts +1 -1
- package/dist/templates/support-line/client.tsx +9 -9
- package/dist/templates/support-line/nodes.ts +100 -0
- package/dist/templates/support-line/procedure.ts +407 -0
- package/dist/templates/support-line/system-prompt.md +2 -1
- package/dist/templates/support-line/tools/answer_question.ts +66 -4
- package/dist/templates/transcription-workflow/agent.eval.test.ts +234 -0
- package/dist/templates/transcription-workflow/agent.test.ts +94 -194
- package/dist/templates/transcription-workflow/agent.ts +1 -1
- package/dist/templates/transcription-workflow/client.tsx +17 -42
- package/dist/templates/transcription-workflow/workflows/batch.ts +19 -22
- package/dist/templates/transcription-workflow/workflows/normalize.ts +90 -186
- package/dist/templates/transcription-workflow/workflows/stitch.ts +0 -11
- package/dist/templates/transcription-workflow/workflows/stream.ts +4 -5
- package/dist/templates/transcription-workflow/workflows/sync-api.ts +6 -6
- package/dist/templates/transcription-workflow/workflows/transcribe.ts +32 -26
- package/dist/templates/transcription-workflow/workflows/wav.ts +0 -31
- package/dist/templates/travel-concierge/agent.eval.test.ts +323 -0
- package/dist/templates/travel-concierge/agent.test.ts +174 -43
- package/dist/templates/travel-concierge/agent.ts +18 -9
- package/dist/templates/travel-concierge/client.tsx +11 -23
- package/dist/templates/travel-concierge/routing.ts +34 -15
- package/dist/templates/travel-concierge/shared.ts +180 -12
- package/dist/templates/travel-concierge/system-prompt.md +7 -1
- package/dist/templates/travel-concierge/tools/book_car_rental.ts +8 -5
- package/dist/templates/travel-concierge/tools/book_excursion.ts +8 -5
- package/dist/templates/travel-concierge/tools/book_hotel.ts +8 -5
- package/dist/templates/travel-concierge/tools/cancel_ticket.ts +8 -5
- package/dist/templates/travel-concierge/tools/search_car_rentals.ts +9 -5
- package/dist/templates/travel-concierge/tools/search_excursions.ts +9 -5
- package/dist/templates/travel-concierge/tools/search_flights.ts +9 -6
- package/dist/templates/travel-concierge/tools/search_hotels.ts +9 -5
- package/dist/templates/travel-concierge/tools/update_ticket.ts +8 -5
- package/dist/templates/web-researcher/agent.eval.test.ts +121 -0
- package/dist/templates/web-researcher/system-prompt.md +15 -4
- package/dist/{test-9kPKJI-w.mjs → test-BvyT6sAc.mjs} +24 -10
- package/dist/test.d.ts +29 -5
- package/dist/{worker-bundler-CGD4r8Kc.mjs → worker-bundler-CCVEDjm1.mjs} +241 -3
- package/dist/worker-bundler.mjs +1 -1
- package/dist/{workflow-CFpxOFfQ.mjs → workflow-BflATMmU.mjs} +47 -12
- package/dist/workflow-bundler.d.ts +6 -1
- package/dist/workflow.d.ts +1 -1
- package/package.json +5 -4
- package/dist/eject-31gjtaHF.mjs +0 -116
- package/dist/eject.d.ts +0 -60
- package/dist/templates/call-audit/workflows/temp-media.ts +0 -138
- package/dist/templates/infocom-adventure/tools/game_state_history.ts +0 -14
- package/dist/templates/support-line/graph.ts +0 -224
- package/dist/{_config-D_s09e7g.mjs → _config-CmJOFsAP.mjs} +1 -1
- /package/dist/templates/plan-and-execute/{graph.ts → procedure.ts} +0 -0
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { stageAction } from "../pending.ts";
|
|
4
|
+
import { OrderIdField } from "../resolve.ts";
|
|
5
|
+
import { retailTool, setFocus } from "../store.ts";
|
|
6
|
+
import { planExchange } from "../swap.ts";
|
|
6
7
|
|
|
7
8
|
export default retailTool({
|
|
8
9
|
name: "exchange_delivered_order_items",
|
|
10
|
+
when: "serving",
|
|
11
|
+
send: { type: "STAGED" },
|
|
9
12
|
description:
|
|
10
|
-
"
|
|
11
|
-
"Only a 'delivered' order can be exchanged, and only once
|
|
12
|
-
"item they want exchanged before you call this
|
|
13
|
-
"
|
|
14
|
-
"
|
|
13
|
+
"STAGE an exchange of items in a delivered order for different options of the SAME products — " +
|
|
14
|
+
"this does NOT request anything. Only a 'delivered' order can be exchanged, and only once, so " +
|
|
15
|
+
"remind the caller to name EVERY item they want exchanged before you call this. The whole " +
|
|
16
|
+
"list and the price difference come back as a sentence to read to them; nothing happens until " +
|
|
17
|
+
"you hear an explicit yes and call confirm_change. No new order is needed — the customer gets " +
|
|
18
|
+
"an email explaining how to send the originals back.",
|
|
15
19
|
inputSchema: z.object({
|
|
16
20
|
order_id: OrderIdField,
|
|
17
21
|
item_ids: z
|
|
@@ -28,65 +32,16 @@ export default retailTool({
|
|
|
28
32
|
.describe("Method to charge or refund the price difference"),
|
|
29
33
|
}),
|
|
30
34
|
execute: (args, state) => {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (order.status !== "delivered") {
|
|
39
|
-
return {
|
|
40
|
-
error: `Order ${order.order_id} is ${order.status}. Only a delivered order can be exchanged, and only once.`,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// requireDifferent is false: tau2 permits a same-item entry here, and a
|
|
45
|
-
// zero-difference exchange is harmless on a delivered order.
|
|
46
|
-
const plan = planItemSwap(state, order, args.item_ids, args.new_item_ids, {
|
|
47
|
-
requireDifferent: false,
|
|
48
|
-
});
|
|
35
|
+
const plan = planExchange(
|
|
36
|
+
state,
|
|
37
|
+
args.order_id,
|
|
38
|
+
args.item_ids,
|
|
39
|
+
args.new_item_ids,
|
|
40
|
+
args.payment_method_id,
|
|
41
|
+
);
|
|
49
42
|
if (isToolFailure(plan)) return plan;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (blocked) return blocked;
|
|
53
|
-
|
|
54
|
-
// No balance moves and no items change: this records a REQUEST. The money
|
|
55
|
-
// and the item swap settle when the originals come back.
|
|
56
|
-
order.status = "exchange requested";
|
|
57
|
-
// SORTED INDEPENDENTLY, verbatim from tau2 (`order.exchange_items =
|
|
58
|
-
// sorted(item_ids)` / `sorted(new_item_ids)`, the same shape
|
|
59
|
-
// `return_delivered_order_items` uses one list of) — kept because
|
|
60
|
-
// `seed.json` is tau2's data and these fields are what a tau2 task's
|
|
61
|
-
// expected end state is compared against. They are therefore two SETS of
|
|
62
|
-
// ids, not a pairing: sorting each list separately permutes the second
|
|
63
|
-
// against the first whenever the caller named more than one item.
|
|
64
|
-
//
|
|
65
|
-
// Which is why the ANSWER carries `exchanges` instead. `planItemSwap`
|
|
66
|
-
// priced this positionally, so returning the two sorted lists as if they
|
|
67
|
-
// lined up told the caller a pairing the quote was not for — the one thing
|
|
68
|
-
// this result must not do, since the model reads it back down a phone.
|
|
69
|
-
order.exchange_items = [...args.item_ids].sort();
|
|
70
|
-
order.exchange_new_items = [...args.new_item_ids].sort();
|
|
71
|
-
order.exchange_payment_method_id = args.payment_method_id;
|
|
72
|
-
order.exchange_price_difference = plan.diff;
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
order_id: order.order_id,
|
|
76
|
-
status: order.status,
|
|
77
|
-
price_difference: plan.diff,
|
|
78
|
-
// The pairing AS PRICED, per line, in the order the caller gave it.
|
|
79
|
-
exchanges: plan.pairs.map((pair) => ({
|
|
80
|
-
item_id: pair.item.item_id,
|
|
81
|
-
new_item_id: pair.newVariant.item_id,
|
|
82
|
-
price_difference: money(pair.newVariant.price - pair.item.price),
|
|
83
|
-
})),
|
|
84
|
-
message:
|
|
85
|
-
plan.diff > 0
|
|
86
|
-
? `Exchange requested on ${order.order_id}. $${plan.diff.toFixed(2)} will be charged to ${args.payment_method_id}. An email with return instructions is on its way.`
|
|
87
|
-
: `Exchange requested on ${order.order_id}. $${Math.abs(plan.diff).toFixed(2)} will be refunded to ${args.payment_method_id}. An email with return instructions is on its way.`,
|
|
88
|
-
};
|
|
43
|
+
setFocus(state, { orderId: plan.orderId });
|
|
44
|
+
return stageAction(state, { kind: "exchange_delivered_order_items", plan });
|
|
89
45
|
},
|
|
90
|
-
summary: (_args, result) =>
|
|
91
|
-
isToolFailure(result) ? "exchange failed" : `exchange requested on ${result.order_id}`,
|
|
46
|
+
summary: (_args, result) => `staged: ${result.read_back}`,
|
|
92
47
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { authenticateAs } from "../authenticate.ts";
|
|
4
|
-
import { retailTool } from "../store.ts";
|
|
3
|
+
import { BEFORE_TRANSFER, retailTool } from "../store.ts";
|
|
5
4
|
|
|
6
5
|
export default retailTool({
|
|
7
6
|
name: "find_user_id_by_email",
|
|
@@ -12,7 +11,12 @@ export default retailTool({
|
|
|
12
11
|
inputSchema: z.object({
|
|
13
12
|
email: z.string().max(200).describe("The customer's email, e.g. 'something@example.com'"),
|
|
14
13
|
}),
|
|
15
|
-
|
|
14
|
+
// Legal in `serving` too: a caller repeating their email must not hit an
|
|
15
|
+
// error, and `authenticateAs` is what refuses a switch to a DIFFERENT
|
|
16
|
+
// customer. The `IDENTIFIED` event is not sent on that refusal — a flow tool
|
|
17
|
+
// sends nothing when its body answers a `ToolFailure`.
|
|
18
|
+
when: BEFORE_TRANSFER,
|
|
19
|
+
send: { type: "IDENTIFIED" },
|
|
16
20
|
execute: (args, state) => {
|
|
17
21
|
const target = args.email.trim().toLowerCase();
|
|
18
22
|
const match = Object.values(state.store.users).find(
|
|
@@ -23,6 +27,5 @@ export default retailTool({
|
|
|
23
27
|
}
|
|
24
28
|
return authenticateAs(state, match);
|
|
25
29
|
},
|
|
26
|
-
summary: (_args, result) =>
|
|
27
|
-
isToolFailure(result) ? "lookup failed" : `identified ${result.user_id}`,
|
|
30
|
+
summary: (_args, result) => `identified ${result.user_id}`,
|
|
28
31
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { authenticateAs } from "../authenticate.ts";
|
|
4
|
-
import { retailTool } from "../store.ts";
|
|
3
|
+
import { BEFORE_TRANSFER, retailTool } from "../store.ts";
|
|
5
4
|
|
|
6
5
|
export default retailTool({
|
|
7
6
|
name: "find_user_id_by_name_zip",
|
|
@@ -13,7 +12,8 @@ export default retailTool({
|
|
|
13
12
|
last_name: z.string().max(100).describe("Last name, e.g. 'Doe'"),
|
|
14
13
|
zip: z.string().max(20).describe("Zip code, e.g. '12345'"),
|
|
15
14
|
}),
|
|
16
|
-
|
|
15
|
+
when: BEFORE_TRANSFER,
|
|
16
|
+
send: { type: "IDENTIFIED" },
|
|
17
17
|
execute: (args, state) => {
|
|
18
18
|
const first = args.first_name.trim().toLowerCase();
|
|
19
19
|
const last = args.last_name.trim().toLowerCase();
|
|
@@ -31,6 +31,5 @@ export default retailTool({
|
|
|
31
31
|
}
|
|
32
32
|
return authenticateAs(state, match);
|
|
33
33
|
},
|
|
34
|
-
summary: (_args, result) =>
|
|
35
|
-
isToolFailure(result) ? "lookup failed" : `identified ${result.user_id}`,
|
|
34
|
+
summary: (_args, result) => `identified ${result.user_id}`,
|
|
36
35
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { findItem, retailTool } from "../store.ts";
|
|
3
|
+
import { BEFORE_TRANSFER, findItem, retailTool } from "../store.ts";
|
|
4
4
|
|
|
5
5
|
export default retailTool({
|
|
6
6
|
name: "get_item_details",
|
|
@@ -10,7 +10,7 @@ export default retailTool({
|
|
|
10
10
|
inputSchema: z.object({
|
|
11
11
|
item_id: z.string().max(60).describe("The item id, e.g. '1008292230'"),
|
|
12
12
|
}),
|
|
13
|
-
|
|
13
|
+
when: BEFORE_TRANSFER,
|
|
14
14
|
execute: (args, state) => {
|
|
15
15
|
const found = findItem(state, args.item_id);
|
|
16
16
|
if (isToolFailure(found)) return found;
|
|
@@ -23,6 +23,5 @@ export default retailTool({
|
|
|
23
23
|
available: found.variant.available,
|
|
24
24
|
};
|
|
25
25
|
},
|
|
26
|
-
summary: (_args, result) =>
|
|
27
|
-
isToolFailure(result) ? "item read failed" : `read item ${result.item_id}`,
|
|
26
|
+
summary: (_args, result) => `read item ${result.item_id}`,
|
|
28
27
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
|
-
import { omitUndefined } from "@alexkroman1/aai/utils";
|
|
1
|
+
import { isToolFailure, omitUndefined } from "@alexkroman1/aai";
|
|
3
2
|
import { z } from "zod";
|
|
4
3
|
import { OrderIdField, resolveOrder } from "../resolve.ts";
|
|
5
4
|
import { retailTool, setFocus } from "../store.ts";
|
|
6
5
|
|
|
7
6
|
export default retailTool({
|
|
8
7
|
name: "get_order_details",
|
|
8
|
+
when: "serving",
|
|
9
9
|
description:
|
|
10
10
|
"Get the status and full details of one of the authenticated customer's orders. Accepts the " +
|
|
11
11
|
"order id (e.g. '#W0000000' — note the leading '#'), or a spoken reference such as " +
|
|
@@ -33,6 +33,5 @@ export default retailTool({
|
|
|
33
33
|
...(order.cancel_reason ? { cancel_reason: order.cancel_reason } : {}),
|
|
34
34
|
};
|
|
35
35
|
},
|
|
36
|
-
summary: (_args, result) =>
|
|
37
|
-
isToolFailure(result) ? "order read failed" : `read ${result.order_id}`,
|
|
36
|
+
summary: (_args, result) => `read ${result.order_id}`,
|
|
38
37
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { findProduct, retailTool, setFocus } from "../store.ts";
|
|
3
|
+
import { BEFORE_TRANSFER, findProduct, retailTool, setFocus } from "../store.ts";
|
|
4
4
|
|
|
5
5
|
export default retailTool({
|
|
6
6
|
name: "get_product_details",
|
|
@@ -10,7 +10,7 @@ export default retailTool({
|
|
|
10
10
|
inputSchema: z.object({
|
|
11
11
|
product_id: z.string().max(60).describe("The product id, e.g. '6086499569'"),
|
|
12
12
|
}),
|
|
13
|
-
|
|
13
|
+
when: BEFORE_TRANSFER,
|
|
14
14
|
execute: (args, state) => {
|
|
15
15
|
const product = findProduct(state, args.product_id);
|
|
16
16
|
if (isToolFailure(product)) return product;
|
|
@@ -26,6 +26,5 @@ export default retailTool({
|
|
|
26
26
|
})),
|
|
27
27
|
};
|
|
28
28
|
},
|
|
29
|
-
summary: (_args, result) =>
|
|
30
|
-
isToolFailure(result) ? "product read failed" : `read product ${result.name}`,
|
|
29
|
+
summary: (_args, result) => `read product ${result.name}`,
|
|
31
30
|
});
|
|
@@ -4,6 +4,7 @@ import { requireOwnUser, retailTool } from "../store.ts";
|
|
|
4
4
|
|
|
5
5
|
export default retailTool({
|
|
6
6
|
name: "get_user_details",
|
|
7
|
+
when: "serving",
|
|
7
8
|
description:
|
|
8
9
|
"Get the authenticated customer's profile: name, email, default address, payment methods " +
|
|
9
10
|
"(with gift-card balances) and their order ids with each order's status.",
|
|
@@ -32,6 +33,5 @@ export default retailTool({
|
|
|
32
33
|
})),
|
|
33
34
|
};
|
|
34
35
|
},
|
|
35
|
-
summary: (_args, result) =>
|
|
36
|
-
isToolFailure(result) ? "profile read failed" : `read profile ${result.user_id}`,
|
|
36
|
+
summary: (_args, result) => `read profile ${result.user_id}`,
|
|
37
37
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
1
|
import { z } from "zod";
|
|
3
|
-
import { retailTool } from "../store.ts";
|
|
2
|
+
import { BEFORE_TRANSFER, retailTool } from "../store.ts";
|
|
4
3
|
|
|
5
4
|
export default retailTool({
|
|
6
5
|
name: "list_all_product_types",
|
|
@@ -10,13 +9,14 @@ export default retailTool({
|
|
|
10
9
|
// Empty schema rather than omitting it: the wrapper has one code path, and
|
|
11
10
|
// that is where the per-call UI-update invariant lives.
|
|
12
11
|
inputSchema: z.object({}),
|
|
13
|
-
|
|
12
|
+
// The catalogue is not customer data, so it needs no identified caller — but
|
|
13
|
+
// it is still off limits once the call belongs to a human.
|
|
14
|
+
when: BEFORE_TRANSFER,
|
|
14
15
|
execute: (_args, state) => {
|
|
15
16
|
const entries = Object.values(state.store.products)
|
|
16
17
|
.map((product) => [product.name, product.product_id] as const)
|
|
17
18
|
.sort(([a], [b]) => a.localeCompare(b));
|
|
18
19
|
return { count: entries.length, products: Object.fromEntries(entries) };
|
|
19
20
|
},
|
|
20
|
-
summary: (_args, result) =>
|
|
21
|
-
isToolFailure(result) ? "catalog read failed" : `listed ${result.count} product types`,
|
|
21
|
+
summary: (_args, result) => `listed ${result.count} product types`,
|
|
22
22
|
});
|
|
@@ -1,39 +1,27 @@
|
|
|
1
1
|
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { AddressFields,
|
|
4
|
-
import {
|
|
3
|
+
import { AddressFields, planOrderAddress } from "../address.ts";
|
|
4
|
+
import { stageAction } from "../pending.ts";
|
|
5
|
+
import { OrderIdField } from "../resolve.ts";
|
|
5
6
|
import { retailTool, setFocus } from "../store.ts";
|
|
6
7
|
|
|
7
8
|
export default retailTool({
|
|
8
9
|
name: "modify_pending_order_address",
|
|
10
|
+
when: "serving",
|
|
11
|
+
send: { type: "STAGED" },
|
|
9
12
|
description:
|
|
10
|
-
"
|
|
11
|
-
"
|
|
13
|
+
"STAGE a change to a pending order's shipping address — this does NOT change it. The new " +
|
|
14
|
+
"address comes back as a sentence to read to the caller; nothing happens until you hear an " +
|
|
15
|
+
"explicit yes and call confirm_change. This does not touch the customer's default address.",
|
|
12
16
|
inputSchema: z.object({
|
|
13
17
|
order_id: OrderIdField,
|
|
14
18
|
...AddressFields,
|
|
15
19
|
}),
|
|
16
20
|
execute: (args, state) => {
|
|
17
|
-
const
|
|
18
|
-
if (isToolFailure(
|
|
19
|
-
setFocus(state, { orderId:
|
|
20
|
-
|
|
21
|
-
// Any pending variant is fine here — unlike cancel and modify-items, which
|
|
22
|
-
// require exactly 'pending'. Re-addressing a modified order is harmless.
|
|
23
|
-
if (!order.status.startsWith("pending")) {
|
|
24
|
-
return {
|
|
25
|
-
error: `Order ${order.order_id} is ${order.status}, and only a pending order's address can be changed.`,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
order.address = toAddress(args);
|
|
30
|
-
return {
|
|
31
|
-
order_id: order.order_id,
|
|
32
|
-
status: order.status,
|
|
33
|
-
address: order.address,
|
|
34
|
-
message: `Order ${order.order_id} now ships to ${formatAddress(order.address)}.`,
|
|
35
|
-
};
|
|
21
|
+
const plan = planOrderAddress(state, args.order_id, args);
|
|
22
|
+
if (isToolFailure(plan)) return plan;
|
|
23
|
+
setFocus(state, { orderId: plan.orderId });
|
|
24
|
+
return stageAction(state, { kind: "modify_pending_order_address", plan });
|
|
36
25
|
},
|
|
37
|
-
summary: (_args, result) =>
|
|
38
|
-
isToolFailure(result) ? "address change failed" : `re-addressed ${result.order_id}`,
|
|
26
|
+
summary: (_args, result) => `staged: ${result.read_back}`,
|
|
39
27
|
});
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { stageAction } from "../pending.ts";
|
|
4
|
+
import { OrderIdField } from "../resolve.ts";
|
|
5
|
+
import { retailTool, setFocus } from "../store.ts";
|
|
6
|
+
import { planModifyItems } from "../swap.ts";
|
|
6
7
|
|
|
7
8
|
export default retailTool({
|
|
8
9
|
name: "modify_pending_order_items",
|
|
10
|
+
when: "serving",
|
|
11
|
+
send: { type: "STAGED" },
|
|
9
12
|
description:
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
13
|
+
"STAGE a change of items in a pending order to different options of the SAME products — this " +
|
|
14
|
+
"does NOT change anything. It can only ever be done ONCE per order and is irreversible: " +
|
|
15
|
+
"afterwards the order can no longer be cancelled or modified at all. So collect EVERY item " +
|
|
16
|
+
"the caller wants changed into one call — ask them 'is that everything you want to change?' " +
|
|
17
|
+
"explicitly first. The whole list and the price difference come back as a sentence to read " +
|
|
18
|
+
"to them; nothing happens until you hear an explicit yes and call confirm_change. The item " +
|
|
19
|
+
"and replacement lists are positional and must be the same length.",
|
|
15
20
|
inputSchema: z.object({
|
|
16
21
|
order_id: OrderIdField,
|
|
17
22
|
item_ids: z
|
|
@@ -28,60 +33,16 @@ export default retailTool({
|
|
|
28
33
|
.describe("Method to charge or refund the price difference, e.g. 'gift_card_0000000'"),
|
|
29
34
|
}),
|
|
30
35
|
execute: (args, state) => {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// Exactly 'pending'. A 'pending (item modified)' order has already used its
|
|
39
|
-
// one modification, which is what makes this action terminal.
|
|
40
|
-
if (order.status !== "pending") {
|
|
41
|
-
return {
|
|
42
|
-
error: `Order ${order.order_id} is ${order.status}. Items can only be changed while an order is exactly 'pending', and only once.`,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const plan = planItemSwap(state, order, args.item_ids, args.new_item_ids, {
|
|
47
|
-
requireDifferent: true,
|
|
48
|
-
});
|
|
36
|
+
const plan = planModifyItems(
|
|
37
|
+
state,
|
|
38
|
+
args.order_id,
|
|
39
|
+
args.item_ids,
|
|
40
|
+
args.new_item_ids,
|
|
41
|
+
args.payment_method_id,
|
|
42
|
+
);
|
|
49
43
|
if (isToolFailure(plan)) return plan;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (blocked) return blocked;
|
|
53
|
-
|
|
54
|
-
const method = user.payment_methods[args.payment_method_id];
|
|
55
|
-
if (method && isGiftCard(method)) {
|
|
56
|
-
method.balance = money(method.balance - plan.diff);
|
|
57
|
-
}
|
|
58
|
-
order.payment_history.push({
|
|
59
|
-
transaction_type: plan.diff > 0 ? "payment" : "refund",
|
|
60
|
-
amount: money(Math.abs(plan.diff)),
|
|
61
|
-
payment_method_id: args.payment_method_id,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
applySwap(order, plan);
|
|
65
|
-
order.status = "pending (item modified)";
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
order_id: order.order_id,
|
|
69
|
-
status: order.status,
|
|
70
|
-
price_difference: plan.diff,
|
|
71
|
-
items: order.items.map((item) => ({
|
|
72
|
-
name: item.name,
|
|
73
|
-
item_id: item.item_id,
|
|
74
|
-
options: item.options,
|
|
75
|
-
price: item.price,
|
|
76
|
-
})),
|
|
77
|
-
message:
|
|
78
|
-
plan.diff > 0
|
|
79
|
-
? `Done. $${plan.diff.toFixed(2)} was charged to ${args.payment_method_id}. This order can no longer be modified or cancelled.`
|
|
80
|
-
: `Done. $${Math.abs(plan.diff).toFixed(2)} is being refunded to ${args.payment_method_id}. This order can no longer be modified or cancelled.`,
|
|
81
|
-
};
|
|
44
|
+
setFocus(state, { orderId: plan.orderId });
|
|
45
|
+
return stageAction(state, { kind: "modify_pending_order_items", plan });
|
|
82
46
|
},
|
|
83
|
-
summary: (_args, result) =>
|
|
84
|
-
isToolFailure(result)
|
|
85
|
-
? "item change failed"
|
|
86
|
-
: `modified ${result.order_id} (${result.price_difference >= 0 ? "+" : ""}${result.price_difference})`,
|
|
47
|
+
summary: (_args, result) => `staged: ${result.read_back}`,
|
|
87
48
|
});
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
isGiftCard,
|
|
8
|
-
money,
|
|
9
|
-
retailTool,
|
|
10
|
-
setFocus,
|
|
11
|
-
} from "../store.ts";
|
|
3
|
+
import { planPayment } from "../payment.ts";
|
|
4
|
+
import { stageAction } from "../pending.ts";
|
|
5
|
+
import { OrderIdField } from "../resolve.ts";
|
|
6
|
+
import { retailTool, setFocus } from "../store.ts";
|
|
12
7
|
|
|
13
8
|
export default retailTool({
|
|
14
9
|
name: "modify_pending_order_payment",
|
|
10
|
+
when: "serving",
|
|
11
|
+
send: { type: "STAGED" },
|
|
15
12
|
description:
|
|
16
|
-
"
|
|
17
|
-
"from the current one, and a gift card must hold enough
|
|
18
|
-
"
|
|
13
|
+
"STAGE a change to which payment method a pending order is charged to — this does NOT change " +
|
|
14
|
+
"it. The new method must be different from the current one, and a gift card must hold enough " +
|
|
15
|
+
"to cover the whole order; the original method is refunded. The change comes back as a " +
|
|
16
|
+
"sentence to read to the caller; nothing happens until you hear an explicit yes and call " +
|
|
17
|
+
"confirm_change.",
|
|
19
18
|
inputSchema: z.object({
|
|
20
19
|
order_id: OrderIdField,
|
|
21
20
|
payment_method_id: z
|
|
@@ -24,71 +23,10 @@ export default retailTool({
|
|
|
24
23
|
.describe("The new payment method id, e.g. 'gift_card_0000000'"),
|
|
25
24
|
}),
|
|
26
25
|
execute: (args, state) => {
|
|
27
|
-
const
|
|
28
|
-
if (isToolFailure(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (isToolFailure(order)) return order;
|
|
32
|
-
setFocus(state, { orderId: order.order_id });
|
|
33
|
-
|
|
34
|
-
if (!order.status.startsWith("pending")) {
|
|
35
|
-
return {
|
|
36
|
-
error: `Order ${order.order_id} is ${order.status}, and only a pending order's payment method can be changed.`,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const newMethod = findPaymentMethod(user, args.payment_method_id);
|
|
41
|
-
if (isToolFailure(newMethod)) return newMethod;
|
|
42
|
-
|
|
43
|
-
const original = order.payment_history[0];
|
|
44
|
-
if (order.payment_history.length !== 1 || original?.transaction_type !== "payment") {
|
|
45
|
-
return {
|
|
46
|
-
error: `Order ${order.order_id} does not have exactly one payment on record, so its payment method cannot be changed.`,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
if (original.payment_method_id === args.payment_method_id) {
|
|
50
|
-
return {
|
|
51
|
-
error: `Order ${order.order_id} is already paid with ${args.payment_method_id}. The new method must be different.`,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const amount = original.amount;
|
|
56
|
-
if (isGiftCard(newMethod) && newMethod.balance < amount) {
|
|
57
|
-
return {
|
|
58
|
-
error: `Gift card ${args.payment_method_id}'s balance ($${newMethod.balance.toFixed(2)}) does not cover the $${amount.toFixed(2)} order total.`,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
order.payment_history.push(
|
|
63
|
-
{
|
|
64
|
-
transaction_type: "payment",
|
|
65
|
-
amount,
|
|
66
|
-
payment_method_id: args.payment_method_id,
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
transaction_type: "refund",
|
|
70
|
-
amount,
|
|
71
|
-
payment_method_id: original.payment_method_id,
|
|
72
|
-
},
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
if (isGiftCard(newMethod)) {
|
|
76
|
-
newMethod.balance = money(newMethod.balance - amount);
|
|
77
|
-
}
|
|
78
|
-
const oldMethod = user.payment_methods[original.payment_method_id];
|
|
79
|
-
if (oldMethod && isGiftCard(oldMethod)) {
|
|
80
|
-
oldMethod.balance = money(oldMethod.balance + amount);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
order_id: order.order_id,
|
|
85
|
-
status: order.status,
|
|
86
|
-
amount,
|
|
87
|
-
paid_with: args.payment_method_id,
|
|
88
|
-
refunded_to: original.payment_method_id,
|
|
89
|
-
message: `Order ${order.order_id} is now charged to ${args.payment_method_id}, and $${amount.toFixed(2)} is going back to ${original.payment_method_id}.`,
|
|
90
|
-
};
|
|
26
|
+
const plan = planPayment(state, args.order_id, args.payment_method_id);
|
|
27
|
+
if (isToolFailure(plan)) return plan;
|
|
28
|
+
setFocus(state, { orderId: plan.orderId });
|
|
29
|
+
return stageAction(state, { kind: "modify_pending_order_payment", plan });
|
|
91
30
|
},
|
|
92
|
-
summary: (_args, result) =>
|
|
93
|
-
isToolFailure(result) ? "payment change failed" : `re-paid ${result.order_id}`,
|
|
31
|
+
summary: (_args, result) => `staged: ${result.read_back}`,
|
|
94
32
|
});
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
import { isToolFailure } from "@alexkroman1/aai";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { AddressFields,
|
|
4
|
-
import {
|
|
3
|
+
import { AddressFields, planUserAddress } from "../address.ts";
|
|
4
|
+
import { stageAction } from "../pending.ts";
|
|
5
|
+
import { retailTool } from "../store.ts";
|
|
5
6
|
|
|
6
7
|
export default retailTool({
|
|
7
8
|
name: "modify_user_address",
|
|
9
|
+
when: "serving",
|
|
10
|
+
send: { type: "STAGED" },
|
|
8
11
|
description:
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
+
"STAGE a change to the customer's default address, used for future orders — this does NOT " +
|
|
13
|
+
"change it. The new address comes back as a sentence to read to the caller; nothing happens " +
|
|
14
|
+
"until you hear an explicit yes and call confirm_change. This does not change the address on " +
|
|
15
|
+
"any existing order — use modify_pending_order_address for that.",
|
|
12
16
|
inputSchema: z.object({
|
|
13
17
|
user_id: z.string().max(100).describe("The user id, e.g. 'sara_doe_496'"),
|
|
14
18
|
...AddressFields,
|
|
15
19
|
}),
|
|
16
20
|
execute: (args, state) => {
|
|
17
|
-
const
|
|
18
|
-
if (isToolFailure(
|
|
19
|
-
|
|
20
|
-
user.address = toAddress(args);
|
|
21
|
-
return {
|
|
22
|
-
user_id: user.user_id,
|
|
23
|
-
address: user.address,
|
|
24
|
-
message: `Default address updated to ${formatAddress(user.address)}. Existing orders keep their own shipping addresses.`,
|
|
25
|
-
};
|
|
21
|
+
const plan = planUserAddress(state, args.user_id, args);
|
|
22
|
+
if (isToolFailure(plan)) return plan;
|
|
23
|
+
return stageAction(state, { kind: "modify_user_address", plan });
|
|
26
24
|
},
|
|
27
|
-
summary: (_args, result) =>
|
|
28
|
-
isToolFailure(result) ? "profile address change failed" : `re-addressed ${result.user_id}`,
|
|
25
|
+
summary: (_args, result) => `staged: ${result.read_back}`,
|
|
29
26
|
});
|