@alexkroman1/aai-cli 5.14.0 → 6.1.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.
Files changed (231) hide show
  1. package/dist/{_agent-C8Jk-ZcP.mjs → _agent-vGW5SBnX.mjs} +23 -5
  2. package/dist/_agent.d.ts +18 -0
  3. package/dist/{_api-client-BX8Qv51n.mjs → _api-client-LgLksMhN.mjs} +45 -8
  4. package/dist/_api-client.d.ts +39 -0
  5. package/dist/{_bundler-BuIyDdvs.mjs → _bundler-BapCUUJN.mjs} +42 -14
  6. package/dist/_bundler.d.ts +43 -5
  7. package/dist/_cli-common.d.ts +67 -3
  8. package/dist/{_config-CzwAWOWr.mjs → _config-D_s09e7g.mjs} +36 -18
  9. package/dist/_deploy.d.ts +2 -5
  10. package/dist/_dev-restart.d.ts +6 -1
  11. package/dist/{_dev-server-Ch7K8e8i.mjs → _dev-server-DQ1t9sbw.mjs} +94 -38
  12. package/dist/_dev-server.d.ts +30 -2
  13. package/dist/_e2e-test-utils.d.ts +80 -0
  14. package/dist/_fault-mode.d.ts +175 -0
  15. package/dist/{_init-CbkrE2wq.mjs → _init-CpISqoR8.mjs} +3 -3
  16. package/dist/{_output-CC300DzW.mjs → _output-CKkmWs7i.mjs} +8 -1
  17. package/dist/_output.d.ts +9 -2
  18. package/dist/{_server-common-61fL__39.mjs → _server-common-6e0QI4mq.mjs} +1 -1
  19. package/dist/{_slug-api-D30zPmsn.mjs → _slug-api-D2heILuC.mjs} +2 -2
  20. package/dist/{_studio-D2ciIhbi.mjs → _studio-zAJycZ8j.mjs} +3 -3
  21. package/dist/{_templates-B1kt3BGt.mjs → _templates-iDGjGiPf.mjs} +4 -6
  22. package/dist/{_typecheck-gate-4v9UBZHh.mjs → _typecheck-gate-BXvUNnfs.mjs} +1 -1
  23. package/dist/{_utils-0DHbcqUb.mjs → _utils-B8QmtFhK.mjs} +21 -7
  24. package/dist/_utils.d.ts +18 -2
  25. package/dist/{_vite-env-Dg_QlVv0.mjs → _vite-env-BNveawd1.mjs} +31 -1
  26. package/dist/_vite-env.d.ts +30 -0
  27. package/dist/build-BO1Ni6oJ.mjs +62 -0
  28. package/dist/build.d.ts +19 -0
  29. package/dist/cli-workflow.d.ts +10 -0
  30. package/dist/cli.d.ts +1 -2
  31. package/dist/cli.mjs +406 -224
  32. package/dist/{client-bundler-C9qXL8A2.mjs → client-bundler-B8Q9F8gJ.mjs} +3 -22
  33. package/dist/client-bundler.mjs +1 -1
  34. package/dist/{delete-DCRX3d96.mjs → delete-4I0uNR4a.mjs} +6 -7
  35. package/dist/delete.d.ts +2 -8
  36. package/dist/{deploy-DjsEV-40.mjs → deploy-DJ3HRcia.mjs} +13 -14
  37. package/dist/{dev-CvPH5dbF.mjs → dev-C6SWaAZP.mjs} +3 -3
  38. package/dist/{eject-LgBRfnbH.mjs → eject-Zrzk5KV3.mjs} +41 -15
  39. package/dist/eject.d.ts +30 -3
  40. package/dist/{init-BppxMR8r.mjs → init-BTRGiPQr.mjs} +61 -26
  41. package/dist/init.d.ts +11 -0
  42. package/dist/{login-BQQaxJhL.mjs → login-k0Z3VQu9.mjs} +5 -5
  43. package/dist/project-config.mjs +1 -1
  44. package/dist/scaffold/CLAUDE.md +498 -91
  45. package/dist/scaffold/package.json +11 -8
  46. package/dist/scaffold/pnpm-workspace.yaml +8 -0
  47. package/dist/scaffold/server.mjs +53 -57
  48. package/dist/{secret-Ds9dvqAj.mjs → secret-DzSQx1Ds.mjs} +6 -3
  49. package/dist/{storage-DbrQSHFk.mjs → storage-C-Do0mIA.mjs} +18 -6
  50. package/dist/{studio-GSFd4s5O.mjs → studio-BGVmCA2G.mjs} +10 -10
  51. package/dist/templates/code-interpreter/agent.ts +0 -2
  52. package/dist/templates/dispatch-center/agent.test.ts +17 -19
  53. package/dist/templates/dispatch-center/agent.ts +2 -29
  54. package/dist/templates/dispatch-center/client.tsx +33 -16
  55. package/dist/templates/dispatch-center/shared.ts +53 -19
  56. package/dist/templates/dispatch-center/tools/incident_add_note.ts +12 -14
  57. package/dist/templates/dispatch-center/tools/incident_create.ts +41 -44
  58. package/dist/templates/dispatch-center/tools/incident_escalate.ts +59 -61
  59. package/dist/templates/dispatch-center/tools/incident_get.ts +3 -4
  60. package/dist/templates/dispatch-center/tools/incident_triage.ts +43 -45
  61. package/dist/templates/dispatch-center/tools/incident_update_status.ts +39 -41
  62. package/dist/templates/dispatch-center/tools/ops_dashboard.ts +2 -5
  63. package/dist/templates/dispatch-center/tools/ops_protocols.ts +1 -1
  64. package/dist/templates/dispatch-center/tools/ops_run_scenario.ts +20 -23
  65. package/dist/templates/dispatch-center/tools/resources_dispatch.ts +52 -54
  66. package/dist/templates/dispatch-center/tools/resources_get_available.ts +2 -4
  67. package/dist/templates/dispatch-center/tools/resources_update_status.ts +39 -42
  68. package/dist/templates/embedded-assets/agent.test.ts +83 -0
  69. package/dist/templates/embedded-assets/agent.ts +1 -48
  70. package/dist/templates/embedded-assets/shared.ts +17 -0
  71. package/dist/templates/embedded-assets/system-prompt.md +13 -0
  72. package/dist/templates/embedded-assets/tools/list_topics.ts +9 -0
  73. package/dist/templates/embedded-assets/tools/search_knowledge.ts +26 -0
  74. package/dist/templates/health-assistant/agent.test.ts +169 -0
  75. package/dist/templates/health-assistant/agent.ts +1 -166
  76. package/dist/templates/health-assistant/fda.ts +100 -0
  77. package/dist/templates/health-assistant/tools/check_drug_interaction.ts +59 -0
  78. package/dist/templates/health-assistant/tools/medication_lookup.ts +31 -0
  79. package/dist/templates/infocom-adventure/agent.test.ts +205 -0
  80. package/dist/templates/infocom-adventure/agent.ts +3 -106
  81. package/dist/templates/infocom-adventure/client.tsx +28 -12
  82. package/dist/templates/infocom-adventure/shared.ts +28 -11
  83. package/dist/templates/infocom-adventure/tools/game_state_drop.ts +13 -0
  84. package/dist/templates/infocom-adventure/tools/game_state_flag.ts +13 -0
  85. package/dist/templates/infocom-adventure/tools/game_state_get.ts +16 -0
  86. package/dist/templates/infocom-adventure/tools/game_state_history.ts +14 -0
  87. package/dist/templates/infocom-adventure/tools/game_state_move.ts +14 -0
  88. package/dist/templates/infocom-adventure/tools/game_state_restart.ts +13 -0
  89. package/dist/templates/infocom-adventure/tools/game_state_score.ts +13 -0
  90. package/dist/templates/infocom-adventure/tools/game_state_take.ts +13 -0
  91. package/dist/templates/link-digest/agent.test.ts +223 -0
  92. package/dist/templates/link-digest/agent.ts +79 -0
  93. package/dist/templates/link-digest/client.tsx +146 -0
  94. package/dist/templates/link-digest/workflows/digest.ts +248 -0
  95. package/dist/templates/math-buddy/agent.ts +0 -2
  96. package/dist/templates/night-owl/agent.test.ts +80 -0
  97. package/dist/templates/night-owl/agent.ts +1 -68
  98. package/dist/templates/night-owl/system-prompt.md +10 -0
  99. package/dist/templates/night-owl/tools/recommend.ts +64 -0
  100. package/dist/templates/personal-finance/agent.ts +0 -2
  101. package/dist/templates/pizza-ordering/agent.test.ts +52 -47
  102. package/dist/templates/pizza-ordering/agent.ts +9 -158
  103. package/dist/templates/pizza-ordering/shared.ts +35 -12
  104. package/dist/templates/pizza-ordering/tools/add_pizza.ts +31 -0
  105. package/dist/templates/pizza-ordering/tools/place_order.ts +22 -0
  106. package/dist/templates/pizza-ordering/tools/remove_pizza.ts +22 -0
  107. package/dist/templates/pizza-ordering/tools/set_customer_name.ts +13 -0
  108. package/dist/templates/pizza-ordering/tools/update_pizza.ts +28 -0
  109. package/dist/templates/pizza-ordering/tools/view_order.ts +21 -0
  110. package/dist/templates/plan-and-execute/agent.test.ts +411 -0
  111. package/dist/templates/plan-and-execute/agent.ts +23 -0
  112. package/dist/templates/plan-and-execute/client.tsx +115 -0
  113. package/dist/templates/plan-and-execute/graph.ts +178 -0
  114. package/dist/templates/plan-and-execute/prompts.ts +110 -0
  115. package/dist/templates/plan-and-execute/shared.ts +161 -0
  116. package/dist/templates/plan-and-execute/system-prompt.md +18 -0
  117. package/dist/templates/plan-and-execute/tools/plan_status.ts +20 -0
  118. package/dist/templates/plan-and-execute/tools/revise_plan.ts +63 -0
  119. package/dist/templates/plan-and-execute/tools/start_plan.ts +51 -0
  120. package/dist/templates/plan-and-execute/tools/work_next_step.ts +101 -0
  121. package/dist/templates/recap-workflow/agent.test.ts +762 -0
  122. package/dist/templates/recap-workflow/agent.ts +95 -0
  123. package/dist/templates/recap-workflow/shared.ts +43 -0
  124. package/dist/templates/recap-workflow/tools/cancel_recap.ts +23 -0
  125. package/dist/templates/recap-workflow/tools/keep_transcript.ts +31 -0
  126. package/dist/templates/recap-workflow/tools/recap_progress.ts +27 -0
  127. package/dist/templates/recap-workflow/tools/recap_status.ts +46 -0
  128. package/dist/templates/recap-workflow/tools/request_recap.ts +43 -0
  129. package/dist/templates/recap-workflow/workflows/recap.ts +544 -0
  130. package/dist/templates/recap-workflow/workflows/tokens.ts +26 -0
  131. package/dist/templates/redline/agent.test.ts +222 -0
  132. package/dist/templates/redline/agent.ts +89 -0
  133. package/dist/templates/redline/client.tsx +184 -0
  134. package/dist/templates/redline/workflows/prompts.ts +68 -0
  135. package/dist/templates/redline/workflows/redline.ts +258 -0
  136. package/dist/templates/research-workflow/agent.test.ts +525 -0
  137. package/dist/templates/research-workflow/agent.ts +94 -0
  138. package/dist/templates/research-workflow/shared.ts +35 -0
  139. package/dist/templates/research-workflow/tools/file_it_now.ts +22 -0
  140. package/dist/templates/research-workflow/tools/request_research.ts +33 -0
  141. package/dist/templates/research-workflow/tools/research_progress.ts +26 -0
  142. package/dist/templates/research-workflow/tools/research_status.ts +40 -0
  143. package/dist/templates/research-workflow/workflows/prompts.ts +143 -0
  144. package/dist/templates/research-workflow/workflows/research.ts +558 -0
  145. package/dist/templates/retail/agent.test.ts +236 -172
  146. package/dist/templates/retail/agent.ts +5 -42
  147. package/dist/templates/retail/client.tsx +33 -11
  148. package/dist/templates/retail/registry.test.ts +31 -16
  149. package/dist/templates/retail/resolve.ts +28 -64
  150. package/dist/templates/retail/shared.test.ts +4 -3
  151. package/dist/templates/retail/shared.ts +24 -7
  152. package/dist/templates/retail/store.test.ts +12 -10
  153. package/dist/templates/retail/store.ts +69 -30
  154. package/dist/templates/retail/tools/cancel_pending_order.ts +4 -9
  155. package/dist/templates/retail/tools/exchange_delivered_order_items.ts +22 -11
  156. package/dist/templates/retail/tools/find_user_id_by_email.ts +5 -9
  157. package/dist/templates/retail/tools/find_user_id_by_name_zip.ts +5 -7
  158. package/dist/templates/retail/tools/get_item_details.ts +5 -7
  159. package/dist/templates/retail/tools/get_order_details.ts +5 -7
  160. package/dist/templates/retail/tools/get_product_details.ts +4 -7
  161. package/dist/templates/retail/tools/get_user_details.ts +4 -7
  162. package/dist/templates/retail/tools/list_all_product_types.ts +5 -7
  163. package/dist/templates/retail/tools/modify_pending_order_address.ts +4 -9
  164. package/dist/templates/retail/tools/modify_pending_order_items.ts +4 -16
  165. package/dist/templates/retail/tools/modify_pending_order_payment.ts +3 -9
  166. package/dist/templates/retail/tools/modify_user_address.ts +4 -9
  167. package/dist/templates/retail/tools/return_delivered_order_items.ts +3 -9
  168. package/dist/templates/retail/tools/transfer_to_human_agents.ts +1 -1
  169. package/dist/templates/solo-rpg/agent.test.ts +152 -29
  170. package/dist/templates/solo-rpg/agent.ts +3 -21
  171. package/dist/templates/solo-rpg/client.tsx +19 -6
  172. package/dist/templates/solo-rpg/shared.ts +19 -11
  173. package/dist/templates/solo-rpg/tools/action_roll.ts +2 -4
  174. package/dist/templates/solo-rpg/tools/burn_momentum.ts +2 -4
  175. package/dist/templates/solo-rpg/tools/check_state.ts +6 -6
  176. package/dist/templates/solo-rpg/tools/load_game.ts +1 -1
  177. package/dist/templates/solo-rpg/tools/oracle.ts +18 -11
  178. package/dist/templates/solo-rpg/tools/save_game.ts +10 -7
  179. package/dist/templates/solo-rpg/tools/setup_character.ts +1 -1
  180. package/dist/templates/solo-rpg/tools/update_state.ts +3 -4
  181. package/dist/templates/support-line/agent.test.ts +343 -0
  182. package/dist/templates/support-line/agent.ts +27 -0
  183. package/dist/templates/support-line/client.tsx +122 -0
  184. package/dist/templates/support-line/graph.ts +224 -0
  185. package/dist/templates/support-line/knowledge.json +65 -0
  186. package/dist/templates/support-line/prompts.ts +95 -0
  187. package/dist/templates/support-line/shared.ts +240 -0
  188. package/dist/templates/support-line/system-prompt.md +17 -0
  189. package/dist/templates/support-line/tools/answer_question.ts +72 -0
  190. package/dist/templates/support-line/tools/list_topics.ts +22 -0
  191. package/dist/templates/support-line/tools/log_ticket.ts +30 -0
  192. package/dist/templates/transcription-workflow/agent.test.ts +563 -0
  193. package/dist/templates/transcription-workflow/agent.ts +92 -0
  194. package/dist/templates/transcription-workflow/client.tsx +234 -0
  195. package/dist/templates/transcription-workflow/workflows/transcribe.ts +416 -0
  196. package/dist/templates/transcription-workflow/workflows/wav.ts +314 -0
  197. package/dist/templates/travel-concierge/agent.test.ts +338 -0
  198. package/dist/templates/travel-concierge/agent.ts +29 -0
  199. package/dist/templates/travel-concierge/client.tsx +161 -0
  200. package/dist/templates/travel-concierge/routing.ts +138 -0
  201. package/dist/templates/travel-concierge/shared.ts +547 -0
  202. package/dist/templates/travel-concierge/system-prompt.md +24 -0
  203. package/dist/templates/travel-concierge/tools/book_car_rental.ts +20 -0
  204. package/dist/templates/travel-concierge/tools/book_excursion.ts +18 -0
  205. package/dist/templates/travel-concierge/tools/book_hotel.ts +20 -0
  206. package/dist/templates/travel-concierge/tools/cancel_action.ts +7 -0
  207. package/dist/templates/travel-concierge/tools/cancel_ticket.ts +16 -0
  208. package/dist/templates/travel-concierge/tools/complete_or_escalate.ts +7 -0
  209. package/dist/templates/travel-concierge/tools/confirm_action.ts +7 -0
  210. package/dist/templates/travel-concierge/tools/lookup_booking.ts +35 -0
  211. package/dist/templates/travel-concierge/tools/search_car_rentals.ts +33 -0
  212. package/dist/templates/travel-concierge/tools/search_excursions.ts +37 -0
  213. package/dist/templates/travel-concierge/tools/search_flights.ts +43 -0
  214. package/dist/templates/travel-concierge/tools/search_hotels.ts +36 -0
  215. package/dist/templates/travel-concierge/tools/to_car_rental_assistant.ts +11 -0
  216. package/dist/templates/travel-concierge/tools/to_excursion_assistant.ts +11 -0
  217. package/dist/templates/travel-concierge/tools/to_flight_assistant.ts +11 -0
  218. package/dist/templates/travel-concierge/tools/to_hotel_assistant.ts +11 -0
  219. package/dist/templates/travel-concierge/tools/update_ticket.ts +22 -0
  220. package/dist/templates/web-researcher/agent.ts +0 -2
  221. package/dist/templates/web-researcher/system-prompt.md +10 -0
  222. package/dist/{test-2LWBcXvY.mjs → test-B6ZBxSpk.mjs} +2 -2
  223. package/dist/typecheck.mjs +17 -15
  224. package/dist/worker-bundler-CIdDhZ0c.mjs +398 -0
  225. package/dist/worker-bundler.d.ts +14 -0
  226. package/dist/worker-bundler.mjs +1 -108
  227. package/dist/workflow-B-O97AqI.mjs +125 -0
  228. package/dist/workflow-bundler.d.ts +133 -0
  229. package/dist/workflow.d.ts +67 -0
  230. package/package.json +13 -9
  231. package/dist/build-DQJ1ZSm9.mjs +0 -39
@@ -0,0 +1,161 @@
1
+ import "@alexkroman1/aai-ui/styles.css";
2
+ import { AutoScroll, client, useAgentState, useTheme } from "@alexkroman1/aai-ui";
3
+ import type { TripView } from "./shared.ts";
4
+ import { SPECIALIST_IDS, SPECIALISTS, tripSlot, tripView } from "./shared.ts";
5
+
6
+ // Derived from the projection so a new TripView field cannot silently miss the
7
+ // pre-first-tool-call render.
8
+ const EMPTY_TRIP: TripView = tripSlot.projection(tripView)(undefined);
9
+
10
+ const DESKS = ["primary", ...SPECIALIST_IDS] as const;
11
+
12
+ function deskLabel(id: (typeof DESKS)[number]): string {
13
+ return id === "primary" ? "concierge" : SPECIALISTS[id].title;
14
+ }
15
+
16
+ /**
17
+ * The dialog stack, rendered. This is the panel that earns its place: the
18
+ * caller cannot see which desk is holding the call, and neither can a reader of
19
+ * the transcript — the whole delegation mechanism is otherwise invisible.
20
+ */
21
+ function DeskStrip({ active }: { active: TripView["assistant"] }) {
22
+ const theme = useTheme();
23
+ return (
24
+ <div className="flex flex-wrap gap-1.5">
25
+ {DESKS.map((id) => {
26
+ const on = id === active;
27
+ return (
28
+ <span
29
+ key={id}
30
+ className="rounded-full px-2.5 py-1 text-[11px] font-medium capitalize"
31
+ style={{
32
+ background: on ? theme.primary : theme.surface,
33
+ color: on ? theme.bg : theme.text,
34
+ opacity: on ? 1 : 0.55,
35
+ }}
36
+ >
37
+ {deskLabel(id)}
38
+ </span>
39
+ );
40
+ })}
41
+ </div>
42
+ );
43
+ }
44
+
45
+ function ItinerarySidebar() {
46
+ const theme = useTheme();
47
+ const trip = useAgentState<TripView>(EMPTY_TRIP);
48
+
49
+ return (
50
+ <div className="flex flex-col gap-4 p-4 h-full min-h-0" style={{ color: theme.text }}>
51
+ <div className="flex flex-col gap-2">
52
+ <h3 className="text-sm font-bold opacity-60 uppercase tracking-wide">{trip.passenger}</h3>
53
+ <DeskStrip active={trip.assistant} />
54
+ </div>
55
+
56
+ {/* The staged action — the browser half of the confirmation gate. What is
57
+ on screen is exactly what the concierge just asked out loud. */}
58
+ {trip.pending && (
59
+ <div
60
+ className="rounded-lg p-3 text-sm"
61
+ style={{ background: theme.surface, border: `1px solid ${theme.primary}` }}
62
+ >
63
+ <p className="text-[11px] font-bold uppercase tracking-wide opacity-60">
64
+ Waiting on your yes
65
+ </p>
66
+ <p className="mt-1 capitalize">{trip.pending}</p>
67
+ </div>
68
+ )}
69
+
70
+ <div className="flex flex-col gap-2">
71
+ <p className="text-[11px] font-bold uppercase tracking-wide opacity-60">Ticket</p>
72
+ {trip.ticket ? (
73
+ <div className="rounded-lg p-3" style={{ background: theme.surface }}>
74
+ <p className="text-sm font-medium">
75
+ {trip.ticket.flightId} · {trip.ticket.route}
76
+ </p>
77
+ <p className="text-xs opacity-60">
78
+ {trip.ticket.departs} · ref {trip.ticket.reference}
79
+ </p>
80
+ </div>
81
+ ) : (
82
+ <p className="text-sm opacity-50">No ticket — cancelled on this call.</p>
83
+ )}
84
+ </div>
85
+
86
+ {trip.bookings.length > 0 && (
87
+ <div className="flex flex-col gap-2">
88
+ <p className="text-[11px] font-bold uppercase tracking-wide opacity-60">Booked</p>
89
+ {trip.bookings.map((booking) => (
90
+ <div
91
+ key={booking.reference}
92
+ className="flex items-center justify-between gap-3 rounded-lg p-3"
93
+ style={{ background: theme.surface }}
94
+ >
95
+ <div className="min-w-0">
96
+ <p className="truncate text-sm">{booking.summary}</p>
97
+ <p className="text-xs opacity-60">{booking.reference}</p>
98
+ </div>
99
+ <span className="text-sm font-bold" style={{ color: theme.primary }}>
100
+ ${booking.price.toLocaleString("en-US")}
101
+ </span>
102
+ </div>
103
+ ))}
104
+ <div
105
+ className="flex justify-between border-t pt-2 text-sm font-bold"
106
+ style={{ borderColor: theme.border }}
107
+ >
108
+ <span>Total</span>
109
+ <span style={{ color: theme.primary }}>${trip.total.toLocaleString("en-US")}</span>
110
+ </div>
111
+ </div>
112
+ )}
113
+
114
+ <div className="flex min-h-0 flex-1 flex-col gap-2">
115
+ <p className="text-[11px] font-bold uppercase tracking-wide opacity-60">Call log</p>
116
+ <AutoScroll
117
+ scrollClassName="overflow-y-auto min-h-0"
118
+ contentClassName="flex flex-col gap-1 pr-1"
119
+ >
120
+ {trip.log.length === 0 ? (
121
+ <p className="text-xs opacity-40">Nothing yet.</p>
122
+ ) : (
123
+ trip.log.map((entry, index) => (
124
+ // The log is append-only and capped, so the index is stable for
125
+ // an entry's lifetime — there is no reorder to lose.
126
+ <p key={`${index}-${entry}`} className="text-xs opacity-70">
127
+ {entry}
128
+ </p>
129
+ ))
130
+ )}
131
+ </AutoScroll>
132
+ </div>
133
+ </div>
134
+ );
135
+ }
136
+
137
+ client({
138
+ name: "Swiss Air Concierge",
139
+ sidebar: ItinerarySidebar,
140
+ theme: {
141
+ bg: "#0d1117",
142
+ primary: "#e35d5b",
143
+ text: "#eef2f6",
144
+ surface: "#161d27",
145
+ border: "#232c38",
146
+ },
147
+ tools: {
148
+ to_flight_assistant: { icon: "\u{2708}", label: "Flight desk" },
149
+ to_hotel_assistant: { icon: "\u{1F3E8}", label: "Hotel desk" },
150
+ to_car_rental_assistant: { icon: "\u{1F697}", label: "Car desk" },
151
+ to_excursion_assistant: { icon: "\u{1F5FA}", label: "Excursions desk" },
152
+ complete_or_escalate: { icon: "\u{21A9}", label: "Back to concierge" },
153
+ confirm_action: { icon: "\u{2705}", label: "Applying change" },
154
+ cancel_action: { icon: "\u{274C}", label: "Discarding change" },
155
+ update_ticket: { icon: "\u{1F39F}", label: "Staging ticket change" },
156
+ cancel_ticket: { icon: "\u{1F5D1}", label: "Staging cancellation" },
157
+ book_hotel: { icon: "\u{1F6CF}", label: "Staging hotel" },
158
+ book_car_rental: { icon: "\u{1F511}", label: "Staging car" },
159
+ book_excursion: { icon: "\u{1F3AB}", label: "Staging excursion" },
160
+ },
161
+ });
@@ -0,0 +1,138 @@
1
+ /**
2
+ * The dialog-stack tools: delegate, escalate, confirm, cancel.
3
+ *
4
+ * These four shapes are the customer-support tutorial's control plane, and the
5
+ * DEFINITIONS live together here because they share this module's helpers —
6
+ * `activeAssistant`, `applyPending`, `note`. Each is NAMED by a file under
7
+ * `tools/`, which is what registers it: a tool's name is its file name, so
8
+ * `tools/to_flight_assistant.ts` is one line handing {@link delegationTool} an
9
+ * id, and `tools/confirm_action.ts` re-exports {@link confirmAction}.
10
+ *
11
+ * The delegation four are still generated rather than written out. The notebook
12
+ * declares `ToFlightBookingAssistant`, `ToHotelBookingAssistant`,
13
+ * `ToBookCarRental` and `ToBookExcursion` as four pydantic classes differing
14
+ * only in the docstring, and the whole content of one is an entry in
15
+ * {@link SPECIALISTS} — so the factory stays and the files name its instances,
16
+ * which is a different thing from four near-identical tool bodies. A domain tool
17
+ * — one that searches or books something — is written in its own file, because
18
+ * each of those really is different work.
19
+ */
20
+
21
+ import type { ToolDef } from "@alexkroman1/aai";
22
+ import { z } from "zod";
23
+ import {
24
+ activeAssistant,
25
+ applyPending,
26
+ describeAction,
27
+ note,
28
+ SPECIALISTS,
29
+ type SpecialistId,
30
+ tripSlot,
31
+ } from "./shared.ts";
32
+
33
+ /**
34
+ * `to_<specialist>_assistant` — push a desk onto the dialog stack.
35
+ *
36
+ * The result IS the specialist's brief. A voice session's system prompt is
37
+ * fixed at connect, so there is no swapping it the way their graph swaps the
38
+ * runnable; handing the brief back as the tool result puts it in the last thing
39
+ * the model reads before it speaks, which is the same effect by a route that
40
+ * works on a live call. `request` exists for the same reason theirs does: the
41
+ * specialist needs what the caller actually asked for, not just that they were
42
+ * transferred.
43
+ */
44
+ export function delegationTool(id: SpecialistId): ToolDef {
45
+ const specialist = SPECIALISTS[id];
46
+ return tripSlot.updateTool({
47
+ description:
48
+ `Hand the call to the ${specialist.title}. Use this as soon as the caller ` +
49
+ "raises something that desk owns — do not answer it yourself. Do not " +
50
+ "mention the transfer; the caller should hear one continuous conversation.",
51
+ inputSchema: z.object({
52
+ request: z
53
+ .string()
54
+ .max(500)
55
+ .describe("What the caller asked for, in their own words where possible"),
56
+ }),
57
+ execute(args, trip) {
58
+ // Re-entering a desk the call is already on would grow the stack without
59
+ // bound over a long call; the brief is still worth re-reading.
60
+ if (activeAssistant(trip) !== id) trip.dialogState.push(id);
61
+ note(trip, `→ ${specialist.title}: ${args.request}`);
62
+ return {
63
+ desk: specialist.title,
64
+ instructions: specialist.instructions,
65
+ request: args.request,
66
+ };
67
+ },
68
+ });
69
+ }
70
+
71
+ /**
72
+ * `complete_or_escalate` — pop back to the concierge.
73
+ *
74
+ * Kept under its original name because the name is load-bearing: it covers BOTH
75
+ * "this desk is finished" and "this desk cannot help", and a model offered only
76
+ * a `done` tool will keep trying to answer things the desk has no tools for.
77
+ * The `reason` is what the concierge is handed on the way back up.
78
+ */
79
+ export const completeOrEscalate = tripSlot.updateTool({
80
+ description:
81
+ "Hand the call back to the main concierge. Use this when the current desk's " +
82
+ "work is finished, when the caller changes the subject to something this " +
83
+ "desk does not handle, or when they change their mind.",
84
+ inputSchema: z.object({
85
+ reason: z
86
+ .string()
87
+ .max(300)
88
+ .describe("Why the call is going back — what is done, or what the caller now wants"),
89
+ }),
90
+ execute(args, trip) {
91
+ const left = activeAssistant(trip);
92
+ // `primary` stays at the bottom — the slot's `after` hook restores it if a
93
+ // pop ever empties the stack.
94
+ if (trip.dialogState.length > 1) trip.dialogState.pop();
95
+ note(trip, `← back to concierge: ${args.reason}`);
96
+ return {
97
+ returnedFrom: left === "primary" ? "concierge" : SPECIALISTS[left].title,
98
+ nowHandling: "concierge",
99
+ reason: args.reason,
100
+ instructions:
101
+ "You are the main concierge again. Pick up what the caller asked for; " +
102
+ "delegate again if it belongs to another desk.",
103
+ };
104
+ },
105
+ });
106
+
107
+ /**
108
+ * `confirm_action` — the caller said yes.
109
+ *
110
+ * This is the only tool in the template that changes a booking. Their graph
111
+ * halts before a sensitive tool and resumes on approval; the halt here is that
112
+ * every sensitive tool stages instead of acting, so the approval has somewhere
113
+ * to arrive.
114
+ */
115
+ export const confirmAction = tripSlot.updateTool({
116
+ description:
117
+ "Apply the change the caller has just confirmed out loud. Only call this " +
118
+ "after you have read the change back and heard a clear yes.",
119
+ execute(_args, trip) {
120
+ return applyPending(trip);
121
+ },
122
+ });
123
+
124
+ /** `cancel_action` — the caller said no. Drops the staged action, changes nothing. */
125
+ export const cancelAction = tripSlot.updateTool({
126
+ description:
127
+ "Discard the change the caller just declined. Call this when they say no, " +
128
+ "or when they want to change the details before confirming.",
129
+ execute(_args, trip) {
130
+ const action = trip.pending;
131
+ if (!action) return { message: "Nothing was waiting for confirmation." };
132
+ trip.pending = null;
133
+ const described = describeAction(action);
134
+ const summary = typeof described === "string" ? described : action.kind;
135
+ note(trip, `Declined: ${summary}`);
136
+ return { discarded: summary, message: "Nothing was changed." };
137
+ },
138
+ });