@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.
- package/dist/{_agent-C8Jk-ZcP.mjs → _agent-vGW5SBnX.mjs} +23 -5
- package/dist/_agent.d.ts +18 -0
- package/dist/{_api-client-BX8Qv51n.mjs → _api-client-LgLksMhN.mjs} +45 -8
- package/dist/_api-client.d.ts +39 -0
- package/dist/{_bundler-BuIyDdvs.mjs → _bundler-BapCUUJN.mjs} +42 -14
- package/dist/_bundler.d.ts +43 -5
- package/dist/_cli-common.d.ts +67 -3
- package/dist/{_config-CzwAWOWr.mjs → _config-D_s09e7g.mjs} +36 -18
- package/dist/_deploy.d.ts +2 -5
- package/dist/_dev-restart.d.ts +6 -1
- package/dist/{_dev-server-Ch7K8e8i.mjs → _dev-server-DQ1t9sbw.mjs} +94 -38
- package/dist/_dev-server.d.ts +30 -2
- package/dist/_e2e-test-utils.d.ts +80 -0
- package/dist/_fault-mode.d.ts +175 -0
- package/dist/{_init-CbkrE2wq.mjs → _init-CpISqoR8.mjs} +3 -3
- package/dist/{_output-CC300DzW.mjs → _output-CKkmWs7i.mjs} +8 -1
- package/dist/_output.d.ts +9 -2
- package/dist/{_server-common-61fL__39.mjs → _server-common-6e0QI4mq.mjs} +1 -1
- package/dist/{_slug-api-D30zPmsn.mjs → _slug-api-D2heILuC.mjs} +2 -2
- package/dist/{_studio-D2ciIhbi.mjs → _studio-zAJycZ8j.mjs} +3 -3
- package/dist/{_templates-B1kt3BGt.mjs → _templates-iDGjGiPf.mjs} +4 -6
- package/dist/{_typecheck-gate-4v9UBZHh.mjs → _typecheck-gate-BXvUNnfs.mjs} +1 -1
- package/dist/{_utils-0DHbcqUb.mjs → _utils-B8QmtFhK.mjs} +21 -7
- package/dist/_utils.d.ts +18 -2
- package/dist/{_vite-env-Dg_QlVv0.mjs → _vite-env-BNveawd1.mjs} +31 -1
- package/dist/_vite-env.d.ts +30 -0
- package/dist/build-BO1Ni6oJ.mjs +62 -0
- package/dist/build.d.ts +19 -0
- package/dist/cli-workflow.d.ts +10 -0
- package/dist/cli.d.ts +1 -2
- package/dist/cli.mjs +406 -224
- package/dist/{client-bundler-C9qXL8A2.mjs → client-bundler-B8Q9F8gJ.mjs} +3 -22
- package/dist/client-bundler.mjs +1 -1
- package/dist/{delete-DCRX3d96.mjs → delete-4I0uNR4a.mjs} +6 -7
- package/dist/delete.d.ts +2 -8
- package/dist/{deploy-DjsEV-40.mjs → deploy-DJ3HRcia.mjs} +13 -14
- package/dist/{dev-CvPH5dbF.mjs → dev-C6SWaAZP.mjs} +3 -3
- package/dist/{eject-LgBRfnbH.mjs → eject-Zrzk5KV3.mjs} +41 -15
- package/dist/eject.d.ts +30 -3
- package/dist/{init-BppxMR8r.mjs → init-BTRGiPQr.mjs} +61 -26
- package/dist/init.d.ts +11 -0
- package/dist/{login-BQQaxJhL.mjs → login-k0Z3VQu9.mjs} +5 -5
- package/dist/project-config.mjs +1 -1
- package/dist/scaffold/CLAUDE.md +498 -91
- package/dist/scaffold/package.json +11 -8
- package/dist/scaffold/pnpm-workspace.yaml +8 -0
- package/dist/scaffold/server.mjs +53 -57
- package/dist/{secret-Ds9dvqAj.mjs → secret-DzSQx1Ds.mjs} +6 -3
- package/dist/{storage-DbrQSHFk.mjs → storage-C-Do0mIA.mjs} +18 -6
- package/dist/{studio-GSFd4s5O.mjs → studio-BGVmCA2G.mjs} +10 -10
- package/dist/templates/code-interpreter/agent.ts +0 -2
- package/dist/templates/dispatch-center/agent.test.ts +17 -19
- package/dist/templates/dispatch-center/agent.ts +2 -29
- package/dist/templates/dispatch-center/client.tsx +33 -16
- package/dist/templates/dispatch-center/shared.ts +53 -19
- package/dist/templates/dispatch-center/tools/incident_add_note.ts +12 -14
- package/dist/templates/dispatch-center/tools/incident_create.ts +41 -44
- package/dist/templates/dispatch-center/tools/incident_escalate.ts +59 -61
- package/dist/templates/dispatch-center/tools/incident_get.ts +3 -4
- package/dist/templates/dispatch-center/tools/incident_triage.ts +43 -45
- package/dist/templates/dispatch-center/tools/incident_update_status.ts +39 -41
- package/dist/templates/dispatch-center/tools/ops_dashboard.ts +2 -5
- package/dist/templates/dispatch-center/tools/ops_protocols.ts +1 -1
- package/dist/templates/dispatch-center/tools/ops_run_scenario.ts +20 -23
- package/dist/templates/dispatch-center/tools/resources_dispatch.ts +52 -54
- package/dist/templates/dispatch-center/tools/resources_get_available.ts +2 -4
- package/dist/templates/dispatch-center/tools/resources_update_status.ts +39 -42
- package/dist/templates/embedded-assets/agent.test.ts +83 -0
- package/dist/templates/embedded-assets/agent.ts +1 -48
- package/dist/templates/embedded-assets/shared.ts +17 -0
- package/dist/templates/embedded-assets/system-prompt.md +13 -0
- package/dist/templates/embedded-assets/tools/list_topics.ts +9 -0
- package/dist/templates/embedded-assets/tools/search_knowledge.ts +26 -0
- package/dist/templates/health-assistant/agent.test.ts +169 -0
- package/dist/templates/health-assistant/agent.ts +1 -166
- package/dist/templates/health-assistant/fda.ts +100 -0
- package/dist/templates/health-assistant/tools/check_drug_interaction.ts +59 -0
- package/dist/templates/health-assistant/tools/medication_lookup.ts +31 -0
- package/dist/templates/infocom-adventure/agent.test.ts +205 -0
- package/dist/templates/infocom-adventure/agent.ts +3 -106
- package/dist/templates/infocom-adventure/client.tsx +28 -12
- package/dist/templates/infocom-adventure/shared.ts +28 -11
- package/dist/templates/infocom-adventure/tools/game_state_drop.ts +13 -0
- package/dist/templates/infocom-adventure/tools/game_state_flag.ts +13 -0
- package/dist/templates/infocom-adventure/tools/game_state_get.ts +16 -0
- package/dist/templates/infocom-adventure/tools/game_state_history.ts +14 -0
- package/dist/templates/infocom-adventure/tools/game_state_move.ts +14 -0
- package/dist/templates/infocom-adventure/tools/game_state_restart.ts +13 -0
- package/dist/templates/infocom-adventure/tools/game_state_score.ts +13 -0
- package/dist/templates/infocom-adventure/tools/game_state_take.ts +13 -0
- package/dist/templates/link-digest/agent.test.ts +223 -0
- package/dist/templates/link-digest/agent.ts +79 -0
- package/dist/templates/link-digest/client.tsx +146 -0
- package/dist/templates/link-digest/workflows/digest.ts +248 -0
- package/dist/templates/math-buddy/agent.ts +0 -2
- package/dist/templates/night-owl/agent.test.ts +80 -0
- package/dist/templates/night-owl/agent.ts +1 -68
- package/dist/templates/night-owl/system-prompt.md +10 -0
- package/dist/templates/night-owl/tools/recommend.ts +64 -0
- package/dist/templates/personal-finance/agent.ts +0 -2
- package/dist/templates/pizza-ordering/agent.test.ts +52 -47
- package/dist/templates/pizza-ordering/agent.ts +9 -158
- package/dist/templates/pizza-ordering/shared.ts +35 -12
- package/dist/templates/pizza-ordering/tools/add_pizza.ts +31 -0
- package/dist/templates/pizza-ordering/tools/place_order.ts +22 -0
- package/dist/templates/pizza-ordering/tools/remove_pizza.ts +22 -0
- package/dist/templates/pizza-ordering/tools/set_customer_name.ts +13 -0
- package/dist/templates/pizza-ordering/tools/update_pizza.ts +28 -0
- package/dist/templates/pizza-ordering/tools/view_order.ts +21 -0
- package/dist/templates/plan-and-execute/agent.test.ts +411 -0
- package/dist/templates/plan-and-execute/agent.ts +23 -0
- package/dist/templates/plan-and-execute/client.tsx +115 -0
- package/dist/templates/plan-and-execute/graph.ts +178 -0
- package/dist/templates/plan-and-execute/prompts.ts +110 -0
- package/dist/templates/plan-and-execute/shared.ts +161 -0
- package/dist/templates/plan-and-execute/system-prompt.md +18 -0
- package/dist/templates/plan-and-execute/tools/plan_status.ts +20 -0
- package/dist/templates/plan-and-execute/tools/revise_plan.ts +63 -0
- package/dist/templates/plan-and-execute/tools/start_plan.ts +51 -0
- package/dist/templates/plan-and-execute/tools/work_next_step.ts +101 -0
- package/dist/templates/recap-workflow/agent.test.ts +762 -0
- package/dist/templates/recap-workflow/agent.ts +95 -0
- package/dist/templates/recap-workflow/shared.ts +43 -0
- package/dist/templates/recap-workflow/tools/cancel_recap.ts +23 -0
- package/dist/templates/recap-workflow/tools/keep_transcript.ts +31 -0
- package/dist/templates/recap-workflow/tools/recap_progress.ts +27 -0
- package/dist/templates/recap-workflow/tools/recap_status.ts +46 -0
- package/dist/templates/recap-workflow/tools/request_recap.ts +43 -0
- package/dist/templates/recap-workflow/workflows/recap.ts +544 -0
- package/dist/templates/recap-workflow/workflows/tokens.ts +26 -0
- package/dist/templates/redline/agent.test.ts +222 -0
- package/dist/templates/redline/agent.ts +89 -0
- package/dist/templates/redline/client.tsx +184 -0
- package/dist/templates/redline/workflows/prompts.ts +68 -0
- package/dist/templates/redline/workflows/redline.ts +258 -0
- package/dist/templates/research-workflow/agent.test.ts +525 -0
- package/dist/templates/research-workflow/agent.ts +94 -0
- package/dist/templates/research-workflow/shared.ts +35 -0
- package/dist/templates/research-workflow/tools/file_it_now.ts +22 -0
- package/dist/templates/research-workflow/tools/request_research.ts +33 -0
- package/dist/templates/research-workflow/tools/research_progress.ts +26 -0
- package/dist/templates/research-workflow/tools/research_status.ts +40 -0
- package/dist/templates/research-workflow/workflows/prompts.ts +143 -0
- package/dist/templates/research-workflow/workflows/research.ts +558 -0
- package/dist/templates/retail/agent.test.ts +236 -172
- package/dist/templates/retail/agent.ts +5 -42
- package/dist/templates/retail/client.tsx +33 -11
- package/dist/templates/retail/registry.test.ts +31 -16
- package/dist/templates/retail/resolve.ts +28 -64
- package/dist/templates/retail/shared.test.ts +4 -3
- package/dist/templates/retail/shared.ts +24 -7
- package/dist/templates/retail/store.test.ts +12 -10
- package/dist/templates/retail/store.ts +69 -30
- package/dist/templates/retail/tools/cancel_pending_order.ts +4 -9
- package/dist/templates/retail/tools/exchange_delivered_order_items.ts +22 -11
- package/dist/templates/retail/tools/find_user_id_by_email.ts +5 -9
- package/dist/templates/retail/tools/find_user_id_by_name_zip.ts +5 -7
- package/dist/templates/retail/tools/get_item_details.ts +5 -7
- package/dist/templates/retail/tools/get_order_details.ts +5 -7
- package/dist/templates/retail/tools/get_product_details.ts +4 -7
- package/dist/templates/retail/tools/get_user_details.ts +4 -7
- package/dist/templates/retail/tools/list_all_product_types.ts +5 -7
- package/dist/templates/retail/tools/modify_pending_order_address.ts +4 -9
- package/dist/templates/retail/tools/modify_pending_order_items.ts +4 -16
- package/dist/templates/retail/tools/modify_pending_order_payment.ts +3 -9
- package/dist/templates/retail/tools/modify_user_address.ts +4 -9
- package/dist/templates/retail/tools/return_delivered_order_items.ts +3 -9
- package/dist/templates/retail/tools/transfer_to_human_agents.ts +1 -1
- package/dist/templates/solo-rpg/agent.test.ts +152 -29
- package/dist/templates/solo-rpg/agent.ts +3 -21
- package/dist/templates/solo-rpg/client.tsx +19 -6
- package/dist/templates/solo-rpg/shared.ts +19 -11
- package/dist/templates/solo-rpg/tools/action_roll.ts +2 -4
- package/dist/templates/solo-rpg/tools/burn_momentum.ts +2 -4
- package/dist/templates/solo-rpg/tools/check_state.ts +6 -6
- package/dist/templates/solo-rpg/tools/load_game.ts +1 -1
- package/dist/templates/solo-rpg/tools/oracle.ts +18 -11
- package/dist/templates/solo-rpg/tools/save_game.ts +10 -7
- package/dist/templates/solo-rpg/tools/setup_character.ts +1 -1
- package/dist/templates/solo-rpg/tools/update_state.ts +3 -4
- package/dist/templates/support-line/agent.test.ts +343 -0
- package/dist/templates/support-line/agent.ts +27 -0
- package/dist/templates/support-line/client.tsx +122 -0
- package/dist/templates/support-line/graph.ts +224 -0
- package/dist/templates/support-line/knowledge.json +65 -0
- package/dist/templates/support-line/prompts.ts +95 -0
- package/dist/templates/support-line/shared.ts +240 -0
- package/dist/templates/support-line/system-prompt.md +17 -0
- package/dist/templates/support-line/tools/answer_question.ts +72 -0
- package/dist/templates/support-line/tools/list_topics.ts +22 -0
- package/dist/templates/support-line/tools/log_ticket.ts +30 -0
- package/dist/templates/transcription-workflow/agent.test.ts +563 -0
- package/dist/templates/transcription-workflow/agent.ts +92 -0
- package/dist/templates/transcription-workflow/client.tsx +234 -0
- package/dist/templates/transcription-workflow/workflows/transcribe.ts +416 -0
- package/dist/templates/transcription-workflow/workflows/wav.ts +314 -0
- package/dist/templates/travel-concierge/agent.test.ts +338 -0
- package/dist/templates/travel-concierge/agent.ts +29 -0
- package/dist/templates/travel-concierge/client.tsx +161 -0
- package/dist/templates/travel-concierge/routing.ts +138 -0
- package/dist/templates/travel-concierge/shared.ts +547 -0
- package/dist/templates/travel-concierge/system-prompt.md +24 -0
- package/dist/templates/travel-concierge/tools/book_car_rental.ts +20 -0
- package/dist/templates/travel-concierge/tools/book_excursion.ts +18 -0
- package/dist/templates/travel-concierge/tools/book_hotel.ts +20 -0
- package/dist/templates/travel-concierge/tools/cancel_action.ts +7 -0
- package/dist/templates/travel-concierge/tools/cancel_ticket.ts +16 -0
- package/dist/templates/travel-concierge/tools/complete_or_escalate.ts +7 -0
- package/dist/templates/travel-concierge/tools/confirm_action.ts +7 -0
- package/dist/templates/travel-concierge/tools/lookup_booking.ts +35 -0
- package/dist/templates/travel-concierge/tools/search_car_rentals.ts +33 -0
- package/dist/templates/travel-concierge/tools/search_excursions.ts +37 -0
- package/dist/templates/travel-concierge/tools/search_flights.ts +43 -0
- package/dist/templates/travel-concierge/tools/search_hotels.ts +36 -0
- package/dist/templates/travel-concierge/tools/to_car_rental_assistant.ts +11 -0
- package/dist/templates/travel-concierge/tools/to_excursion_assistant.ts +11 -0
- package/dist/templates/travel-concierge/tools/to_flight_assistant.ts +11 -0
- package/dist/templates/travel-concierge/tools/to_hotel_assistant.ts +11 -0
- package/dist/templates/travel-concierge/tools/update_ticket.ts +22 -0
- package/dist/templates/web-researcher/agent.ts +0 -2
- package/dist/templates/web-researcher/system-prompt.md +10 -0
- package/dist/{test-2LWBcXvY.mjs → test-B6ZBxSpk.mjs} +2 -2
- package/dist/typecheck.mjs +17 -15
- package/dist/worker-bundler-CIdDhZ0c.mjs +398 -0
- package/dist/worker-bundler.d.ts +14 -0
- package/dist/worker-bundler.mjs +1 -108
- package/dist/workflow-B-O97AqI.mjs +125 -0
- package/dist/workflow-bundler.d.ts +133 -0
- package/dist/workflow.d.ts +67 -0
- package/package.json +13 -9
- 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
|
+
});
|