@alexkroman1/aai-cli 5.13.2 → 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 +32 -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 +21 -30
- package/dist/templates/dispatch-center/agent.ts +4 -31
- package/dist/templates/dispatch-center/client.tsx +41 -28
- package/dist/templates/dispatch-center/shared.ts +73 -66
- package/dist/templates/dispatch-center/tools/incident_add_note.ts +13 -15
- package/dist/templates/dispatch-center/tools/incident_create.ts +42 -45
- package/dist/templates/dispatch-center/tools/incident_escalate.ts +60 -62
- package/dist/templates/dispatch-center/tools/incident_get.ts +10 -6
- package/dist/templates/dispatch-center/tools/incident_triage.ts +44 -46
- package/dist/templates/dispatch-center/tools/incident_update_status.ts +40 -42
- package/dist/templates/dispatch-center/tools/ops_dashboard.ts +3 -6
- package/dist/templates/dispatch-center/tools/ops_protocols.ts +1 -1
- package/dist/templates/dispatch-center/tools/ops_run_scenario.ts +21 -24
- package/dist/templates/dispatch-center/tools/resources_dispatch.ts +53 -55
- package/dist/templates/dispatch-center/tools/resources_get_available.ts +3 -5
- package/dist/templates/dispatch-center/tools/resources_update_status.ts +40 -43
- 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 +32 -28
- package/dist/templates/infocom-adventure/shared.ts +36 -16
- 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 +59 -58
- package/dist/templates/pizza-ordering/agent.ts +10 -159
- package/dist/templates/pizza-ordering/client.tsx +4 -4
- package/dist/templates/pizza-ordering/shared.ts +44 -27
- 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 +319 -256
- package/dist/templates/retail/agent.ts +6 -46
- package/dist/templates/retail/authenticate.ts +2 -2
- package/dist/templates/retail/client.tsx +45 -24
- package/dist/templates/retail/registry.test.ts +40 -25
- package/dist/templates/retail/resolve.test.ts +17 -16
- package/dist/templates/retail/resolve.ts +32 -67
- package/dist/templates/retail/shared.test.ts +21 -19
- package/dist/templates/retail/shared.ts +61 -23
- package/dist/templates/retail/store.test.ts +47 -52
- package/dist/templates/retail/store.ts +92 -79
- package/dist/templates/retail/swap.test.ts +20 -17
- package/dist/templates/retail/swap.ts +7 -14
- package/dist/templates/retail/tools/cancel_pending_order.ts +7 -11
- package/dist/templates/retail/tools/exchange_delivered_order_items.ts +26 -14
- 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 +7 -8
- package/dist/templates/retail/tools/get_order_details.ts +7 -8
- package/dist/templates/retail/tools/get_product_details.ts +6 -8
- package/dist/templates/retail/tools/get_user_details.ts +6 -8
- package/dist/templates/retail/tools/list_all_product_types.ts +5 -7
- package/dist/templates/retail/tools/modify_pending_order_address.ts +6 -10
- package/dist/templates/retail/tools/modify_pending_order_items.ts +8 -20
- package/dist/templates/retail/tools/modify_pending_order_payment.ts +7 -13
- package/dist/templates/retail/tools/modify_user_address.ts +6 -10
- package/dist/templates/retail/tools/return_delivered_order_items.ts +7 -13
- package/dist/templates/retail/tools/transfer_to_human_agents.ts +1 -1
- package/dist/templates/solo-rpg/agent.test.ts +169 -54
- package/dist/templates/solo-rpg/agent.ts +4 -22
- package/dist/templates/solo-rpg/client.tsx +19 -6
- package/dist/templates/solo-rpg/shared.ts +20 -20
- package/dist/templates/solo-rpg/tools/action_roll.ts +3 -5
- package/dist/templates/solo-rpg/tools/burn_momentum.ts +3 -5
- package/dist/templates/solo-rpg/tools/check_state.ts +7 -7
- package/dist/templates/solo-rpg/tools/load_game.ts +3 -3
- package/dist/templates/solo-rpg/tools/oracle.ts +19 -12
- package/dist/templates/solo-rpg/tools/save_game.ts +11 -8
- package/dist/templates/solo-rpg/tools/setup_character.ts +3 -3
- package/dist/templates/solo-rpg/tools/update_state.ts +13 -13
- 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
|
@@ -6,28 +6,31 @@
|
|
|
6
6
|
},
|
|
7
7
|
"scripts": {
|
|
8
8
|
"dev": "aai dev",
|
|
9
|
+
"prestart": "aai build --skip-tests",
|
|
9
10
|
"start": "node server.mjs",
|
|
10
11
|
"build": "aai build",
|
|
11
12
|
"test": "aai test",
|
|
12
13
|
"publish:agent": "aai publish"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|
|
15
|
-
"@alexkroman1/aai": "^
|
|
16
|
-
"@alexkroman1/aai-ui": "^
|
|
16
|
+
"@alexkroman1/aai": "^6.1.0",
|
|
17
|
+
"@alexkroman1/aai-ui": "^6.1.0",
|
|
18
|
+
"@workflow/world-postgres": "4.3.3",
|
|
17
19
|
"react": "^19.2.8",
|
|
18
20
|
"react-dom": "^19.2.8",
|
|
19
21
|
"tailwindcss": "^4.0.0",
|
|
22
|
+
"workflow": "4.8.2",
|
|
20
23
|
"zod": "^4.4.3"
|
|
21
24
|
},
|
|
22
25
|
"devDependencies": {
|
|
23
|
-
"@alexkroman1/aai-cli": "^
|
|
26
|
+
"@alexkroman1/aai-cli": "^6.1.0",
|
|
24
27
|
"@tailwindcss/vite": "^4.3.3",
|
|
25
|
-
"@types/node": "^26.
|
|
26
|
-
"@types/react": "^19.2.
|
|
27
|
-
"@types/react-dom": "^19.2.
|
|
28
|
-
"@vitejs/plugin-react": "^6.0.
|
|
28
|
+
"@types/node": "^26.2.0",
|
|
29
|
+
"@types/react": "^19.2.18",
|
|
30
|
+
"@types/react-dom": "^19.2.4",
|
|
31
|
+
"@vitejs/plugin-react": "^6.0.5",
|
|
29
32
|
"typescript": "^7.0.2",
|
|
30
|
-
"vite": "^8.1
|
|
33
|
+
"vite": "^8.2.1",
|
|
31
34
|
"vitest": "^4.1.10"
|
|
32
35
|
}
|
|
33
36
|
}
|
|
@@ -7,7 +7,39 @@
|
|
|
7
7
|
# build script without this entry. pnpm 10 reads `onlyBuiltDependencies`;
|
|
8
8
|
# pnpm 11 renamed it to `allowBuilds` and ignores the old key, so both are
|
|
9
9
|
# declared. This file also marks the project as its own pnpm workspace root.
|
|
10
|
+
# `@swc/core` and `cbor-extract` arrive TRANSITIVELY, through the `workflow`
|
|
11
|
+
# dependency the DevKit templates need. pnpm 11 makes an undeclared build script
|
|
12
|
+
# a hard error (`ERR_PNPM_IGNORED_BUILDS`), so leaving them out fails the install
|
|
13
|
+
# — which is the very first thing `aai init` does after writing these files.
|
|
10
14
|
onlyBuiltDependencies:
|
|
15
|
+
- "@swc/core"
|
|
16
|
+
- cbor-extract
|
|
11
17
|
- esbuild
|
|
12
18
|
allowBuilds:
|
|
19
|
+
"@swc/core": true
|
|
20
|
+
cbor-extract: true
|
|
13
21
|
esbuild: true
|
|
22
|
+
|
|
23
|
+
# Exempt our own packages from pnpm's release-age quarantine, and ONLY ours.
|
|
24
|
+
# `minimumReleaseAge` holds a version back until it has been on the registry
|
|
25
|
+
# for N minutes (pnpm 11 turns it on by default; an org .npmrc or a corporate
|
|
26
|
+
# config can set it far higher). The scaffold pins `^<newest>` — see
|
|
27
|
+
# scripts/sync-scaffold-versions.mjs, which resyncs it on every `changeset
|
|
28
|
+
# version` — and this repo publishes several times a day, so EVERY version
|
|
29
|
+
# satisfying that range is younger than the window and resolution fails
|
|
30
|
+
# outright:
|
|
31
|
+
#
|
|
32
|
+
# ERR_PNPM_NO_MATURE_MATCHING_VERSION Version 5.13.2 (released 2 hours ago)
|
|
33
|
+
# of @alexkroman1/aai-cli does not meet the minimumReleaseAge constraint
|
|
34
|
+
#
|
|
35
|
+
# There is no version to fall back to, so a freshly scaffolded project cannot
|
|
36
|
+
# install at all — `aai init` fails at its own install step. Lowering the pin
|
|
37
|
+
# would not help: the floor has to admit the SDK the templates are written
|
|
38
|
+
# against, and that build is by definition new.
|
|
39
|
+
#
|
|
40
|
+
# Quarantine exists to blunt a compromised-release window, so this stays a
|
|
41
|
+
# per-package exemption rather than `minimumReleaseAge: 0` — every third-party
|
|
42
|
+
# dependency keeps whatever window the user has configured. We are the one
|
|
43
|
+
# publisher whose freshness the user is opting into by running `aai init`.
|
|
44
|
+
minimumReleaseAgeExclude:
|
|
45
|
+
- "@alexkroman1/*"
|
package/dist/scaffold/server.mjs
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
// Self-hosted entrypoint — this is what `npm start` runs.
|
|
2
2
|
//
|
|
3
3
|
// It serves the agent over HTTP + WebSocket from your own Node process: no
|
|
4
|
-
// platform account, no
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// platform account, no managed anything. `aai dev` is the development
|
|
5
|
+
// counterpart (file watching, Vite, a browser that opens itself); this file is
|
|
6
|
+
// the deployment.
|
|
7
7
|
//
|
|
8
8
|
// npm start # http://127.0.0.1:3000
|
|
9
9
|
// PORT=8080 HOST=0.0.0.0 npm start # bind every interface, e.g. in a container
|
|
10
10
|
//
|
|
11
11
|
// Anything that can run Node can host it: copy the project, install
|
|
12
|
-
// dependencies, provide the secrets, run
|
|
13
|
-
// — `aai dev`, `aai publish` and the managed platform never read it.
|
|
12
|
+
// dependencies, provide the secrets, run `npm start`. Deleting this file costs
|
|
13
|
+
// nothing — `aai dev`, `aai publish` and the managed platform never read it.
|
|
14
14
|
|
|
15
|
-
import { existsSync
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
16
|
import { readFile } from "node:fs/promises";
|
|
17
|
-
import { registerHooks } from "node:module";
|
|
18
17
|
import path from "node:path";
|
|
19
|
-
import { fileURLToPath } from "node:url";
|
|
18
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
20
19
|
import { parseEnv } from "node:util";
|
|
21
20
|
import { createAgentServer, withHostCredentialFallback } from "@alexkroman1/aai/runtime";
|
|
22
21
|
import { defaultClientDir } from "@alexkroman1/aai-ui/client-dir";
|
|
@@ -24,56 +23,38 @@ import { defaultClientDir } from "@alexkroman1/aai-ui/client-dir";
|
|
|
24
23
|
const root = path.dirname(fileURLToPath(import.meta.url));
|
|
25
24
|
|
|
26
25
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* The built agent — `.aai/worker.mjs`, produced by `aai build`, which the
|
|
27
|
+
* `prestart` script runs for you. It is the SAME artifact `aai publish` uploads
|
|
28
|
+
* and the managed platform runs, so a self-hosted agent and a deployed one
|
|
29
|
+
* cannot behave differently.
|
|
29
30
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
31
|
+
* Loading the build rather than `agent.ts` directly is what makes `tools/`
|
|
32
|
+
* work. A tool is registered by EXISTING — its file name is the name the model
|
|
33
|
+
* calls, and nothing anywhere lists them — and the only place a directory can
|
|
34
|
+
* be turned into modules is where the bundle is assembled: a deployed agent is
|
|
35
|
+
* handed one ESM string and has no filesystem to scan. So the bundler
|
|
36
|
+
* enumerates `tools/` and emits the imports, and every loader that skips it
|
|
37
|
+
* would serve an agent with no tools at all.
|
|
36
38
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
39
|
+
* It also settles two things the bundler already resolves, and this file used
|
|
40
|
+
* to re-implement with `node:module` hooks: `import prompt from
|
|
41
|
+
* "./system-prompt.md?raw"` (a Vite convention — Node looks for a file
|
|
42
|
+
* literally named `system-prompt.md?raw`) and `import data from "./data.json"`
|
|
43
|
+
* with no import attribute (TypeScript's `resolveJsonModule` allows it, Node
|
|
44
|
+
* requires `with { type: "json" }`). Both are inlined into the bundle, so
|
|
45
|
+
* there is nothing left to teach Node.
|
|
41
46
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return nextResolve(specifier, context);
|
|
54
|
-
},
|
|
55
|
-
load(url, context, nextLoad) {
|
|
56
|
-
const asRaw = url.endsWith("?raw");
|
|
57
|
-
const asBareJson = url.endsWith(".json") && context.importAttributes?.type !== "json";
|
|
58
|
-
if (!(asRaw || asBareJson)) return nextLoad(url, context);
|
|
59
|
-
const text = readFileSync(fileURLToPath(asRaw ? url.slice(0, -"?raw".length) : url), "utf-8");
|
|
60
|
-
return {
|
|
61
|
-
format: "module",
|
|
62
|
-
// `export default <literal>` for both: a JSON document is already a
|
|
63
|
-
// valid JS expression, and JSON.stringify makes any file safe to embed
|
|
64
|
-
// as a string. Emitting `format: "json"` instead would put the import
|
|
65
|
-
// back under the attribute check this exists to satisfy.
|
|
66
|
-
source: `export default ${asRaw ? JSON.stringify(text) : text};`,
|
|
67
|
-
shortCircuit: true,
|
|
68
|
-
};
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// Imported dynamically, and this is load-bearing: static `import` statements
|
|
73
|
-
// are hoisted and evaluated BEFORE any statement in this file, so an
|
|
74
|
-
// `import agent from "./agent.ts"` at the top would load the agent — and every
|
|
75
|
-
// `?raw` import inside it — before the hooks above were ever registered.
|
|
76
|
-
const { default: agent } = await import("./agent.ts");
|
|
47
|
+
const workerPath = path.join(root, ".aai", "worker.mjs");
|
|
48
|
+
if (!existsSync(workerPath)) {
|
|
49
|
+
console.error(
|
|
50
|
+
`No built agent at ${path.relative(root, workerPath)}.\n` +
|
|
51
|
+
"Run `npm run build` (or `aai build`) first — `npm start` normally does it for you.",
|
|
52
|
+
);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
// A file: URL rather than a relative specifier, so the path is correct on
|
|
56
|
+
// Windows, where a bare POSIX-looking path is not a valid module specifier.
|
|
57
|
+
const { default: agent } = await import(pathToFileURL(workerPath).href);
|
|
77
58
|
|
|
78
59
|
/** Parse a dotenv-syntax file into a record; `{}` when it does not exist. */
|
|
79
60
|
async function readEnvFile(file) {
|
|
@@ -116,8 +97,8 @@ async function resolveAgentEnv() {
|
|
|
116
97
|
|
|
117
98
|
/**
|
|
118
99
|
* Static assets served at `/`: this project's own UI once `client.tsx` has been
|
|
119
|
-
* built (`
|
|
120
|
-
* default client that ships inside @alexkroman1/aai-ui.
|
|
100
|
+
* built (the same `aai build` leaves it in `.aai/client`), otherwise the
|
|
101
|
+
* prebuilt default client that ships inside @alexkroman1/aai-ui.
|
|
121
102
|
*/
|
|
122
103
|
function resolveClientDir() {
|
|
123
104
|
const built = path.join(root, ".aai", "client");
|
|
@@ -130,6 +111,20 @@ function resolveClientDir() {
|
|
|
130
111
|
|
|
131
112
|
const env = await resolveAgentEnv();
|
|
132
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Where THIS server is reachable from outside — `PUBLIC_URL`, e.g.
|
|
116
|
+
* `https://agent.example.com`. Set it whenever a durable workflow has to hand a
|
|
117
|
+
* URL to somebody else: `ctx.workflows.publicWebhookUrl(token)` is built from it,
|
|
118
|
+
* and without it that call throws rather than minting a `http://localhost:3000`
|
|
119
|
+
* URL that a payment provider will try, days later, and fail.
|
|
120
|
+
*
|
|
121
|
+
* Nothing else reads it, so it is not a startup requirement: an agent with no
|
|
122
|
+
* webhooks needs no value here. It is deliberately NOT derived from `PORT`/`HOST`
|
|
123
|
+
* — those describe the socket this process binds, which behind a reverse proxy is
|
|
124
|
+
* not what the outside world dials.
|
|
125
|
+
*/
|
|
126
|
+
const publicUrl = process.env.PUBLIC_URL?.trim();
|
|
127
|
+
|
|
133
128
|
const server = createAgentServer({
|
|
134
129
|
agent,
|
|
135
130
|
env,
|
|
@@ -138,6 +133,7 @@ const server = createAgentServer({
|
|
|
138
133
|
// ASSEMBLYAI_API_KEY to a container. Anything in `env` still wins.
|
|
139
134
|
providerEnv: withHostCredentialFallback(env),
|
|
140
135
|
clientDir: resolveClientDir(),
|
|
136
|
+
...(publicUrl ? { publicUrl } : {}),
|
|
141
137
|
});
|
|
142
138
|
|
|
143
139
|
// Loopback by default: this server has no request authentication of its own,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as ok, n as fail } from "./_output-
|
|
2
|
+
import { a as ok, n as fail } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log, s as unwrapCancel } from "./_ui-u7T4YooX.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { a as isStringArray, i as checkedResponse } from "./_api-client-LgLksMhN.mjs";
|
|
5
|
+
import { t as secretRequest } from "./_slug-api-D2heILuC.mjs";
|
|
6
|
+
import { isRecord } from "@alexkroman1/aai/utils";
|
|
5
7
|
import * as p from "@clack/prompts";
|
|
6
8
|
import { text } from "node:stream/consumers";
|
|
7
9
|
//#region secret.ts
|
|
@@ -46,7 +48,8 @@ async function executeSecretDelete(cwd, name, server) {
|
|
|
46
48
|
return ok({ name });
|
|
47
49
|
}
|
|
48
50
|
async function executeSecretList(cwd, server) {
|
|
49
|
-
const { data
|
|
51
|
+
const { data, target } = await secretRequest(cwd, "", { action: "secret" }, server);
|
|
52
|
+
const { vars } = checkedResponse(data, (value) => isRecord(value) && isStringArray(value.vars), `the secret list for ${target}`);
|
|
50
53
|
if (vars.length === 0) log.info("No secrets set. Use `aai secret put <name>` to add one.");
|
|
51
54
|
else {
|
|
52
55
|
log.message(`${vars.length} secret${vars.length === 1 ? "" : "s"}:`);
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as ok, n as fail } from "./_output-
|
|
2
|
+
import { a as ok, n as fail } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { i as checkedResponse } from "./_api-client-LgLksMhN.mjs";
|
|
5
|
+
import { n as slugRequest } from "./_slug-api-D2heILuC.mjs";
|
|
6
|
+
import { isRecord } from "@alexkroman1/aai/utils";
|
|
5
7
|
import * as p from "@clack/prompts";
|
|
6
8
|
//#region storage.ts
|
|
9
|
+
/**
|
|
10
|
+
* The storage route's answer, CHECKED — every caller here reads `enabled` and
|
|
11
|
+
* a body without it reported "Storage is disabled for <slug>" (and returned
|
|
12
|
+
* `enabled: undefined` to a script) for a server that never said so. See
|
|
13
|
+
* `checkedResponse`.
|
|
14
|
+
*/
|
|
7
15
|
async function storageRequest(cwd, init, server) {
|
|
8
|
-
|
|
16
|
+
const { data, slug } = await slugRequest(cwd, "/storage", {
|
|
9
17
|
...init,
|
|
10
18
|
action: "storage"
|
|
11
19
|
}, server);
|
|
20
|
+
return {
|
|
21
|
+
enabled: checkedResponse(data, (value) => isRecord(value) && typeof value.enabled === "boolean", `the storage route for ${slug}`).enabled,
|
|
22
|
+
slug
|
|
23
|
+
};
|
|
12
24
|
}
|
|
13
25
|
async function executeStorageStatus(cwd, server) {
|
|
14
|
-
const {
|
|
26
|
+
const { enabled, slug } = await storageRequest(cwd, void 0, server);
|
|
15
27
|
if (enabled) log.info(`Storage is enabled for ${slug}`);
|
|
16
28
|
else log.info(`Storage is disabled for ${slug}. Use \`aai storage enable\` to turn it on.`);
|
|
17
29
|
return ok({
|
|
@@ -20,7 +32,7 @@ async function executeStorageStatus(cwd, server) {
|
|
|
20
32
|
});
|
|
21
33
|
}
|
|
22
34
|
async function executeStorageEnable(cwd, server) {
|
|
23
|
-
const {
|
|
35
|
+
const { enabled, slug } = await storageRequest(cwd, { method: "POST" }, server);
|
|
24
36
|
log.success(`Storage enabled for ${slug}`);
|
|
25
37
|
log.info("Tool code can now use ctx.db.query(sql, params).");
|
|
26
38
|
return ok({
|
|
@@ -43,7 +55,7 @@ async function executeStorageDisable(cwd, opts = {}) {
|
|
|
43
55
|
return fail("cancelled", "Disable cancelled");
|
|
44
56
|
}
|
|
45
57
|
}
|
|
46
|
-
const {
|
|
58
|
+
const { enabled, slug } = await storageRequest(cwd, { method: "DELETE" }, opts.server);
|
|
47
59
|
log.success(`Storage disabled for ${slug} — database schema and data dropped`);
|
|
48
60
|
return ok({
|
|
49
61
|
slug,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as ok, t as CliError } from "./_output-
|
|
2
|
+
import { a as ok, t as CliError } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log, t as fmtUrl } from "./_ui-u7T4YooX.mjs";
|
|
4
|
-
import { s as updateProjectConfig } from "./_config-
|
|
5
|
-
import { t as resolveServerEnv } from "./_server-common-
|
|
6
|
-
import {
|
|
7
|
-
import { layerScaffold } from "./_templates-
|
|
8
|
-
import { n as apiRequest } from "./_api-client-
|
|
9
|
-
import { a as publishStudioProject, i as projectNameFromDir, n as fetchStudioProject, o as pushStudioSource, r as listStudioProjects, s as studioProjectUrl, t as collectSourceFiles } from "./_studio-
|
|
4
|
+
import { s as updateProjectConfig } from "./_config-D_s09e7g.mjs";
|
|
5
|
+
import { t as resolveServerEnv } from "./_server-common-6e0QI4mq.mjs";
|
|
6
|
+
import { a as resolveDeployTarget } from "./_agent-vGW5SBnX.mjs";
|
|
7
|
+
import { layerScaffold } from "./_templates-iDGjGiPf.mjs";
|
|
8
|
+
import { i as checkedResponse, n as apiRequest } from "./_api-client-LgLksMhN.mjs";
|
|
9
|
+
import { a as publishStudioProject, i as projectNameFromDir, n as fetchStudioProject, o as pushStudioSource, r as listStudioProjects, s as studioProjectUrl, t as collectSourceFiles } from "./_studio-zAJycZ8j.mjs";
|
|
10
10
|
import path from "node:path";
|
|
11
|
+
import { isRecord } from "@alexkroman1/aai/utils";
|
|
11
12
|
import { mkdir, readdir, writeFile } from "node:fs/promises";
|
|
12
13
|
//#region studio.ts
|
|
13
14
|
/**
|
|
@@ -158,7 +159,7 @@ async function syncEnvSecrets(cwd, serverUrl, apiKey, project) {
|
|
|
158
159
|
}
|
|
159
160
|
async function executePublish(opts) {
|
|
160
161
|
if (!opts.skipTypecheck) {
|
|
161
|
-
const { assertTypechecks } = await import("./_typecheck-gate-
|
|
162
|
+
const { assertTypechecks } = await import("./_typecheck-gate-BXvUNnfs.mjs");
|
|
162
163
|
await assertTypechecks(opts.cwd);
|
|
163
164
|
}
|
|
164
165
|
const pushed = await pushProject(opts);
|
|
@@ -166,8 +167,7 @@ async function executePublish(opts) {
|
|
|
166
167
|
const hadSlug = pushed.slug !== void 0;
|
|
167
168
|
if (pushed.slug) await syncEnvSecrets(opts.cwd, serverUrl, apiKey, project);
|
|
168
169
|
log.step(`Publishing ${project} (builds in the project's sandbox)…`);
|
|
169
|
-
const result = await publishStudioProject(serverUrl, apiKey, project);
|
|
170
|
-
if (typeof result?.slug !== "string" || typeof result?.output !== "string") throw new CliError("bad_publish_response", `Unexpected response from the publish route at ${serverUrl}.`, "Check that --server points at an aai platform server, then try again.");
|
|
170
|
+
const result = checkedResponse(await publishStudioProject(serverUrl, apiKey, project), (value) => isRecord(value) && typeof value.slug === "string" && typeof value.output === "string", `the publish route at ${serverUrl}`);
|
|
171
171
|
if (result.output.trim()) log.message(result.output.trim());
|
|
172
172
|
await updateProjectConfig(opts.cwd, {
|
|
173
173
|
serverUrl,
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { agent } from "@alexkroman1/aai";
|
|
2
|
-
import systemPrompt from "./system-prompt.md?raw";
|
|
3
2
|
|
|
4
3
|
export default agent({
|
|
5
4
|
name: "Coda",
|
|
6
|
-
systemPrompt,
|
|
7
5
|
greeting:
|
|
8
6
|
"Hey, I'm Coda. I solve problems by writing and running code. Try asking me something like, what's the 50th fibonacci number, or what day of the week was January 1st 2000.",
|
|
9
7
|
builtinTools: ["run_code"],
|
|
@@ -1,27 +1,18 @@
|
|
|
1
1
|
import type { ToolContext } from "@alexkroman1/aai";
|
|
2
|
+
import { createToolContext } from "@alexkroman1/aai/testing";
|
|
2
3
|
import { describe, expect, test } from "vitest";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const sessionId = `test-session-${++sessionCounter}`;
|
|
16
|
-
const ctx = {
|
|
17
|
-
sessionId,
|
|
18
|
-
send: () => {},
|
|
19
|
-
env: {},
|
|
20
|
-
state: {},
|
|
21
|
-
messages: [],
|
|
22
|
-
} as unknown as ToolContext;
|
|
23
|
-
return { ctx };
|
|
24
|
-
}
|
|
4
|
+
import { dispatchSlot } from "./shared.ts";
|
|
5
|
+
import incidentCreate from "./tools/incident_create.ts";
|
|
6
|
+
import incidentEscalate from "./tools/incident_escalate.ts";
|
|
7
|
+
import incidentTriage from "./tools/incident_triage.ts";
|
|
8
|
+
import incidentUpdateStatus from "./tools/incident_update_status.ts";
|
|
9
|
+
import resourcesDispatch from "./tools/resources_dispatch.ts";
|
|
10
|
+
import resourcesUpdateStatus from "./tools/resources_update_status.ts";
|
|
11
|
+
|
|
12
|
+
/** The dispatch board lives in a session slot, and `createToolContext` gives
|
|
13
|
+
* each call its own slot store — so two contexts are two boards by
|
|
14
|
+
* construction. */
|
|
15
|
+
const makeCtx = (): ToolContext => createToolContext();
|
|
25
16
|
|
|
26
17
|
async function createIncidentFor(
|
|
27
18
|
ctx: ToolContext,
|
|
@@ -36,7 +27,7 @@ async function createIncidentFor(
|
|
|
36
27
|
|
|
37
28
|
describe("dispatch-center template", () => {
|
|
38
29
|
test("resolving an incident does not yank a reassigned unit off its new incident", async () => {
|
|
39
|
-
const
|
|
30
|
+
const ctx = makeCtx();
|
|
40
31
|
|
|
41
32
|
const inc1 = await createIncidentFor(ctx);
|
|
42
33
|
await resourcesDispatch.execute({ incidentId: inc1, callsigns: ["Medic-1"] }, ctx);
|
|
@@ -49,7 +40,7 @@ describe("dispatch-center template", () => {
|
|
|
49
40
|
// Resolving the first incident must not touch Medic-1 anymore.
|
|
50
41
|
await incidentUpdateStatus.execute({ incidentId: inc1, status: "resolved" }, ctx);
|
|
51
42
|
|
|
52
|
-
const state =
|
|
43
|
+
const state = dispatchSlot.get(ctx);
|
|
53
44
|
const medic1 = state.resources.find((r) => r.callsign === "Medic-1");
|
|
54
45
|
expect(medic1?.status).toBe("dispatched");
|
|
55
46
|
expect(medic1?.assignedIncident).toBe(inc2);
|
|
@@ -58,7 +49,7 @@ describe("dispatch-center template", () => {
|
|
|
58
49
|
});
|
|
59
50
|
|
|
60
51
|
test("callsigns: ['auto'] triggers auto-dispatch as the description promises", async () => {
|
|
61
|
-
const
|
|
52
|
+
const ctx = makeCtx();
|
|
62
53
|
const incidentId = await createIncidentFor(ctx, "cardiac arrest, patient not breathing");
|
|
63
54
|
|
|
64
55
|
const result = (await resourcesDispatch.execute({ incidentId, callsigns: ["auto"] }, ctx)) as {
|
|
@@ -71,7 +62,7 @@ describe("dispatch-center template", () => {
|
|
|
71
62
|
});
|
|
72
63
|
|
|
73
64
|
test("concurrent tool calls are serialized — no lost updates", async () => {
|
|
74
|
-
const
|
|
65
|
+
const ctx = makeCtx();
|
|
75
66
|
|
|
76
67
|
// Parallel tool calls in one LLM turn run concurrently. The per-session
|
|
77
68
|
// mutex in updateState makes each one run against the previous one's
|
|
@@ -82,7 +73,7 @@ describe("dispatch-center template", () => {
|
|
|
82
73
|
incidentCreate.execute({ location: "2 Second St", description: "vehicle crash" }, ctx),
|
|
83
74
|
])) as { incidentId: string }[];
|
|
84
75
|
|
|
85
|
-
const state =
|
|
76
|
+
const state = dispatchSlot.get(ctx);
|
|
86
77
|
expect(a?.incidentId).not.toBe(b?.incidentId);
|
|
87
78
|
expect(state.incidentCounter).toBe(2);
|
|
88
79
|
expect(Object.keys(state.incidents)).toHaveLength(2);
|
|
@@ -109,7 +100,7 @@ describe("dispatch-center template", () => {
|
|
|
109
100
|
});
|
|
110
101
|
|
|
111
102
|
test("mutual-aid units get unique ids and callsigns across escalations", async () => {
|
|
112
|
-
const
|
|
103
|
+
const ctx = makeCtx();
|
|
113
104
|
const incidentId = await createIncidentFor(ctx);
|
|
114
105
|
|
|
115
106
|
await incidentEscalate.execute(
|
|
@@ -121,7 +112,7 @@ describe("dispatch-center template", () => {
|
|
|
121
112
|
ctx,
|
|
122
113
|
);
|
|
123
114
|
|
|
124
|
-
const state =
|
|
115
|
+
const state = dispatchSlot.get(ctx);
|
|
125
116
|
const mutualAid = state.resources.filter((r) => r.id.startsWith("MA-"));
|
|
126
117
|
expect(mutualAid).toHaveLength(4);
|
|
127
118
|
expect(new Set(mutualAid.map((r) => r.id)).size).toBe(4);
|
|
@@ -129,7 +120,7 @@ describe("dispatch-center template", () => {
|
|
|
129
120
|
});
|
|
130
121
|
|
|
131
122
|
test("resolved is terminal: no escalation, re-resolution, or dispatch", async () => {
|
|
132
|
-
const
|
|
123
|
+
const ctx = makeCtx();
|
|
133
124
|
const incidentId = await createIncidentFor(ctx);
|
|
134
125
|
await incidentUpdateStatus.execute({ incidentId, status: "resolved" }, ctx);
|
|
135
126
|
|
|
@@ -1,48 +1,21 @@
|
|
|
1
1
|
import { agent } from "@alexkroman1/aai";
|
|
2
|
-
import { dashboardView } from "./shared.ts";
|
|
3
|
-
import systemPrompt from "./system-prompt.md?raw";
|
|
4
|
-
import { incidentAddNote } from "./tools/incident_add_note.ts";
|
|
5
|
-
import { incidentCreate } from "./tools/incident_create.ts";
|
|
6
|
-
import { incidentEscalate } from "./tools/incident_escalate.ts";
|
|
7
|
-
import { incidentGet } from "./tools/incident_get.ts";
|
|
8
|
-
import { incidentTriage } from "./tools/incident_triage.ts";
|
|
9
|
-
import { incidentUpdateStatus } from "./tools/incident_update_status.ts";
|
|
10
|
-
import { opsDashboard } from "./tools/ops_dashboard.ts";
|
|
11
|
-
import { opsProtocols } from "./tools/ops_protocols.ts";
|
|
12
|
-
import { opsRunScenario } from "./tools/ops_run_scenario.ts";
|
|
13
|
-
import { resourcesDispatch } from "./tools/resources_dispatch.ts";
|
|
14
|
-
import { resourcesGetAvailable } from "./tools/resources_get_available.ts";
|
|
15
|
-
import { resourcesUpdateStatus } from "./tools/resources_update_status.ts";
|
|
2
|
+
import { dashboardView, dispatchSlot } from "./shared.ts";
|
|
16
3
|
|
|
17
4
|
export default agent({
|
|
18
5
|
name: "Dispatch Command Center",
|
|
6
|
+
// The board exists before the first tool call, so a resumed connection has
|
|
7
|
+
// something to project rather than an empty state object.
|
|
19
8
|
// One projection replaces eleven `ctx.send("incidents", ...)` calls, and
|
|
20
9
|
// is the single place that decides caller PII stays server-side.
|
|
21
|
-
syncState: dashboardView,
|
|
10
|
+
syncState: dispatchSlot.projection(dashboardView),
|
|
22
11
|
// A dispatcher reads addresses and unit numbers in bursts with pauses inside
|
|
23
12
|
// one message ("unit twelve … respond to"). The default pipeline's
|
|
24
13
|
// `max_turn_silence` already tolerates that; reach for
|
|
25
14
|
// `assemblyAIStt({ maxTurnSilenceMs })` only if your callers pause longer.
|
|
26
|
-
systemPrompt,
|
|
27
15
|
greeting:
|
|
28
16
|
"Dispatch Command Center online. Restoring operational state. I'm ready to take incoming calls, manage active incidents, or run dispatch operations. Say 'dashboard' for a full status report. What do we have.",
|
|
29
17
|
|
|
30
18
|
// The system prompt instructs the model to use web_search and run_code, so
|
|
31
19
|
// they must be enabled here — the default builtin set does not include them.
|
|
32
20
|
builtinTools: ["think", "remember", "recall", "calculate", "web_search", "run_code"],
|
|
33
|
-
|
|
34
|
-
tools: {
|
|
35
|
-
incident_add_note: incidentAddNote,
|
|
36
|
-
incident_create: incidentCreate,
|
|
37
|
-
incident_escalate: incidentEscalate,
|
|
38
|
-
incident_get: incidentGet,
|
|
39
|
-
incident_triage: incidentTriage,
|
|
40
|
-
incident_update_status: incidentUpdateStatus,
|
|
41
|
-
ops_dashboard: opsDashboard,
|
|
42
|
-
ops_protocols: opsProtocols,
|
|
43
|
-
ops_run_scenario: opsRunScenario,
|
|
44
|
-
resources_dispatch: resourcesDispatch,
|
|
45
|
-
resources_get_available: resourcesGetAvailable,
|
|
46
|
-
resources_update_status: resourcesUpdateStatus,
|
|
47
|
-
},
|
|
48
21
|
});
|