@alexkroman1/aai-cli 6.10.1 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{_agent-DpH2pBJd.mjs → _agent-BTwZJu4P.mjs} +2 -2
- package/dist/{_bundler-C2BDwU7r.mjs → _bundler-B4RqNF5Z.mjs} +2 -2
- package/dist/_dev-env.d.ts +22 -2
- package/dist/{_dev-server-LLLWnFBs.mjs → _dev-server-CiKFH9qw.mjs} +38 -47
- package/dist/_dev-server.d.ts +0 -17
- package/dist/{_init-C57bWAQ8.mjs → _init-CE4HKdgV.mjs} +3 -2
- package/dist/{_preflight-BtfaYtbE.mjs → _preflight-Co1G9Jww.mjs} +1 -1
- package/dist/_preflight.d.ts +1 -1
- package/dist/{_slug-api-BxrsJXVI.mjs → _slug-api-nRFaBEPJ.mjs} +2 -2
- package/dist/{_studio-U3jhKlA3.mjs → _studio-DR5yzZ1T.mjs} +2 -1
- package/dist/{_templates-Dxb_P2Wz.mjs → _templates-FI3xPEMj.mjs} +1 -1
- package/dist/_workflow-scan.d.ts +108 -0
- package/dist/{build-Dfza2pRI.mjs → build-6jfaakgc.mjs} +5 -2
- package/dist/cli.mjs +30 -25
- package/dist/{client-bundler-BEIqgOtd.mjs → client-bundler-CWnG42cU.mjs} +2 -1
- package/dist/client-bundler.mjs +1 -1
- package/dist/{delete-vbpjGzqs.mjs → delete-Dl_LSfvI.mjs} +3 -3
- package/dist/{deploy-B8lubiRT.mjs → deploy-DvYeD8ia.mjs} +5 -5
- package/dist/{dev-Uq5ujP8a.mjs → dev-B59JIfWO.mjs} +1 -1
- package/dist/{eject-31gjtaHF.mjs → eject-C9WJyyr2.mjs} +1 -1
- package/dist/{init-l6xfU4xX.mjs → init-CpJVjEg0.mjs} +3 -3
- package/dist/{login-C71-qz8F.mjs → login-BBuM1sxH.mjs} +3 -4
- package/dist/{logs-BWVGSjLR.mjs → logs-9q-psa4q.mjs} +2 -2
- package/dist/project-config.mjs +1 -1
- package/dist/scaffold/CLAUDE.md +93 -14
- package/dist/scaffold/package.json +5 -3
- package/dist/scaffold/server.mjs +13 -4
- package/dist/scaffold/vite.config.ts +1 -1
- package/dist/{secret-BuMuFR4B.mjs → secret-CVvSLIDV.mjs} +2 -2
- package/dist/{storage-DzRZ-eCw.mjs → storage-BvUrnvM3.mjs} +2 -2
- package/dist/{studio-BCNUpDgP.mjs → studio--MUV0cid.mjs} +4 -4
- package/dist/templates/call-audit/agent.test.ts +818 -0
- package/dist/templates/call-audit/agent.ts +171 -0
- package/dist/templates/call-audit/client.tsx +198 -0
- package/dist/templates/call-audit/workflows/audit.ts +298 -0
- package/dist/templates/call-audit/workflows/ingest.ts +251 -0
- package/dist/templates/call-audit/workflows/media.ts +637 -0
- package/dist/templates/call-audit/workflows/summarize.ts +201 -0
- package/dist/templates/call-audit/workflows/sync-api.ts +44 -0
- package/dist/templates/dispatch-center/agent.test.ts +149 -25
- package/dist/templates/dispatch-center/client.tsx +239 -129
- package/dist/templates/dispatch-center/shared.ts +99 -1
- package/dist/templates/dispatch-center/system-prompt.md +3 -1
- package/dist/templates/dispatch-center/tools/incident_add_note.ts +16 -13
- package/dist/templates/dispatch-center/tools/incident_create.ts +19 -1
- package/dist/templates/dispatch-center/tools/incident_escalate.ts +68 -59
- package/dist/templates/dispatch-center/tools/incident_triage.ts +57 -43
- package/dist/templates/dispatch-center/tools/incident_update_status.ts +49 -40
- package/dist/templates/dispatch-center/tools/ops_run_scenario.ts +8 -2
- package/dist/templates/dispatch-center/tools/resources_dispatch.ts +69 -52
- package/dist/templates/dispatch-center/tools/resources_update_status.ts +45 -41
- package/dist/templates/embedded-assets/agent.test.ts +17 -14
- package/dist/templates/health-assistant/agent.test.ts +22 -4
- package/dist/templates/infocom-adventure/agent.test.ts +4 -6
- package/dist/templates/infocom-adventure/client.tsx +246 -164
- package/dist/templates/link-digest/agent.test.ts +24 -19
- package/dist/templates/link-digest/client.tsx +47 -61
- package/dist/templates/link-digest/workflows/digest.ts +19 -31
- package/dist/templates/night-owl/agent.test.ts +70 -19
- package/dist/templates/night-owl/agent.ts +5 -0
- package/dist/templates/night-owl/client.tsx +56 -56
- package/dist/templates/night-owl/shared.ts +24 -0
- package/dist/templates/night-owl/tools/recommend.ts +18 -6
- package/dist/templates/pizza-ordering/agent.test.ts +27 -27
- package/dist/templates/pizza-ordering/client.tsx +9 -26
- package/dist/templates/plan-and-execute/agent.test.ts +99 -58
- package/dist/templates/plan-and-execute/agent.ts +1 -1
- package/dist/templates/plan-and-execute/client.tsx +12 -15
- package/dist/templates/plan-and-execute/shared.ts +71 -2
- package/dist/templates/plan-and-execute/tools/plan_status.ts +18 -6
- package/dist/templates/plan-and-execute/tools/revise_plan.ts +18 -10
- package/dist/templates/plan-and-execute/tools/start_plan.ts +13 -2
- package/dist/templates/plan-and-execute/tools/work_next_step.ts +70 -22
- package/dist/templates/podcast-digest/agent.test.ts +746 -0
- package/dist/templates/podcast-digest/agent.ts +139 -0
- package/dist/templates/podcast-digest/client.tsx +154 -0
- package/dist/templates/podcast-digest/workflows/digest.ts +411 -0
- package/dist/templates/podcast-digest/workflows/feeds.ts +507 -0
- package/dist/templates/podcast-digest/workflows/slack.ts +209 -0
- package/dist/templates/recap-workflow/agent.test.ts +107 -96
- package/dist/templates/recap-workflow/tools/recap_progress.ts +9 -12
- package/dist/templates/recap-workflow/tools/recap_status.ts +8 -9
- package/dist/templates/recap-workflow/tools/request_recap.ts +2 -1
- package/dist/templates/recap-workflow/workflows/recap.ts +48 -41
- package/dist/templates/redline/agent.test.ts +17 -15
- package/dist/templates/redline/client.tsx +12 -12
- package/dist/templates/redline/workflows/redline.ts +19 -31
- package/dist/templates/research-workflow/agent.test.ts +60 -59
- package/dist/templates/research-workflow/tools/research_progress.ts +9 -12
- package/dist/templates/research-workflow/tools/research_status.ts +9 -11
- package/dist/templates/research-workflow/workflows/research.ts +44 -61
- package/dist/templates/retail/agent.test.ts +26 -23
- package/dist/templates/retail/client.tsx +226 -117
- package/dist/templates/retail/registry.test.ts +38 -6
- package/dist/templates/retail/store.test.ts +82 -15
- package/dist/templates/retail/store.ts +174 -47
- package/dist/templates/retail/system-prompt.md +11 -2
- package/dist/templates/retail/tools/cancel_pending_order.ts +2 -2
- package/dist/templates/retail/tools/exchange_delivered_order_items.ts +2 -2
- package/dist/templates/retail/tools/find_user_id_by_email.ts +8 -5
- package/dist/templates/retail/tools/find_user_id_by_name_zip.ts +4 -5
- package/dist/templates/retail/tools/get_item_details.ts +3 -4
- package/dist/templates/retail/tools/get_order_details.ts +3 -4
- package/dist/templates/retail/tools/get_product_details.ts +3 -4
- package/dist/templates/retail/tools/get_user_details.ts +2 -2
- package/dist/templates/retail/tools/list_all_product_types.ts +5 -5
- package/dist/templates/retail/tools/modify_pending_order_address.ts +2 -2
- package/dist/templates/retail/tools/modify_pending_order_items.ts +2 -3
- package/dist/templates/retail/tools/modify_pending_order_payment.ts +2 -2
- package/dist/templates/retail/tools/modify_user_address.ts +2 -2
- package/dist/templates/retail/tools/return_delivered_order_items.ts +2 -2
- package/dist/templates/retail/tools/transfer_to_human_agents.ts +8 -4
- package/dist/templates/solo-rpg/agent.test.ts +227 -48
- package/dist/templates/solo-rpg/client.tsx +38 -37
- package/dist/templates/solo-rpg/shared.ts +145 -19
- package/dist/templates/solo-rpg/system-prompt.md +3 -2
- package/dist/templates/solo-rpg/tools/action_roll.ts +82 -63
- package/dist/templates/solo-rpg/tools/burn_momentum.ts +85 -50
- package/dist/templates/solo-rpg/tools/check_state.ts +24 -7
- package/dist/templates/solo-rpg/tools/load_game.ts +13 -1
- package/dist/templates/solo-rpg/tools/save_game.ts +16 -7
- package/dist/templates/solo-rpg/tools/setup_character.ts +22 -2
- package/dist/templates/solo-rpg/tools/update_state.ts +113 -100
- package/dist/templates/spoken-summary/agent.test.ts +314 -0
- package/dist/templates/spoken-summary/agent.ts +155 -0
- package/dist/templates/spoken-summary/client.tsx +185 -0
- package/dist/templates/spoken-summary/workflows/summarize.ts +237 -0
- package/dist/templates/spoken-summary/workflows/transcribe.ts +138 -0
- package/dist/templates/support-line/agent.test.ts +11 -16
- package/dist/templates/support-line/agent.ts +1 -1
- package/dist/templates/support-line/client.tsx +9 -9
- package/dist/templates/support-line/nodes.ts +100 -0
- package/dist/templates/support-line/procedure.ts +407 -0
- package/dist/templates/support-line/tools/answer_question.ts +17 -4
- package/dist/templates/transcription-workflow/agent.test.ts +246 -123
- package/dist/templates/transcription-workflow/agent.ts +21 -7
- package/dist/templates/transcription-workflow/client.tsx +17 -42
- package/dist/templates/transcription-workflow/workflows/batch.ts +79 -180
- package/dist/templates/transcription-workflow/workflows/normalize.ts +247 -0
- package/dist/templates/transcription-workflow/workflows/stitch.ts +0 -11
- package/dist/templates/transcription-workflow/workflows/stream.ts +10 -9
- package/dist/templates/transcription-workflow/workflows/sync-api.ts +26 -94
- package/dist/templates/transcription-workflow/workflows/transcribe.ts +55 -40
- package/dist/templates/transcription-workflow/workflows/wav.ts +31 -31
- package/dist/templates/travel-concierge/agent.test.ts +64 -33
- package/dist/templates/travel-concierge/client.tsx +11 -23
- package/dist/templates/travel-concierge/routing.ts +34 -15
- package/dist/templates/travel-concierge/shared.ts +70 -3
- package/dist/templates/travel-concierge/tools/book_car_rental.ts +2 -2
- package/dist/templates/travel-concierge/tools/book_excursion.ts +2 -2
- package/dist/templates/travel-concierge/tools/book_hotel.ts +2 -2
- package/dist/templates/travel-concierge/tools/cancel_ticket.ts +2 -2
- package/dist/templates/travel-concierge/tools/update_ticket.ts +2 -2
- package/dist/{worker-bundler-CGD4r8Kc.mjs → worker-bundler-COxnqstQ.mjs} +221 -3
- package/dist/worker-bundler.mjs +1 -1
- package/dist/{workflow-CFpxOFfQ.mjs → workflow-D2AQf2Pl.mjs} +28 -1
- package/dist/workflow-bundler.d.ts +6 -1
- package/dist/workflow.d.ts +1 -1
- package/package.json +5 -4
- package/dist/templates/support-line/graph.ts +0 -224
- package/dist/{_config-D_s09e7g.mjs → _config-CmJOFsAP.mjs} +1 -1
- /package/dist/templates/plan-and-execute/{graph.ts → procedure.ts} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
-
import { l as writeProjectConfig } from "./_config-
|
|
5
|
-
import { a as resolveDeployTarget, i as requireDeployedSlug } from "./_agent-
|
|
6
|
-
import { d as apiTestSeam, l as HINT_NOT_DEPLOYED, s as studioProjectApiUrl, u as apiRequest } from "./_studio-
|
|
4
|
+
import { l as writeProjectConfig } from "./_config-CmJOFsAP.mjs";
|
|
5
|
+
import { a as resolveDeployTarget, i as requireDeployedSlug } from "./_agent-BTwZJu4P.mjs";
|
|
6
|
+
import { d as apiTestSeam, l as HINT_NOT_DEPLOYED, s as studioProjectApiUrl, u as apiRequest } from "./_studio-DR5yzZ1T.mjs";
|
|
7
7
|
//#region delete.ts
|
|
8
8
|
async function runDelete(opts) {
|
|
9
9
|
await apiRequest(`${opts.url}/${opts.slug}`, {
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import { a as ok } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log, r as notify, t as fmtUrl } from "./_ui-u7T4YooX.mjs";
|
|
4
4
|
import { o as errorMessage$1 } from "./_utils-B8QmtFhK.mjs";
|
|
5
|
-
import { s as updateProjectConfig } from "./_config-
|
|
6
|
-
import { i as evalWorkerConfig, t as buildAgentBundle } from "./_bundler-
|
|
5
|
+
import { s as updateProjectConfig } from "./_config-CmJOFsAP.mjs";
|
|
6
|
+
import { i as evalWorkerConfig, t as buildAgentBundle } from "./_bundler-B4RqNF5Z.mjs";
|
|
7
7
|
import { t as resolveServerEnv } from "./_server-common-6e0QI4mq.mjs";
|
|
8
|
-
import { a as resolveDeployTarget } from "./_agent-
|
|
8
|
+
import { a as resolveDeployTarget } from "./_agent-BTwZJu4P.mjs";
|
|
9
9
|
import { assertTypechecks } from "./_typecheck-gate-BXvUNnfs.mjs";
|
|
10
|
-
import { d as apiTestSeam, f as checkedResponse, i as projectNameFromDir, u as apiRequest } from "./_studio-
|
|
10
|
+
import { d as apiTestSeam, f as checkedResponse, i as projectNameFromDir, u as apiRequest } from "./_studio-DR5yzZ1T.mjs";
|
|
11
11
|
import { isRecord } from "@alexkroman1/aai/utils";
|
|
12
12
|
import { gzipSync } from "node:zlib";
|
|
13
13
|
//#region _deploy.ts
|
|
@@ -39,7 +39,7 @@ async function executeDeploy(opts) {
|
|
|
39
39
|
const { cwd } = opts;
|
|
40
40
|
const { config: projectConfig, serverUrl, apiKey } = await resolveDeployTarget(cwd, opts.server);
|
|
41
41
|
if (!opts.skipTypecheck) await assertTypechecks(cwd);
|
|
42
|
-
const preflightModule = import("./_preflight-
|
|
42
|
+
const preflightModule = import("./_preflight-Co1G9Jww.mjs");
|
|
43
43
|
const bundle = await buildAgentBundle(cwd, { minify: true });
|
|
44
44
|
const slug = projectConfig?.slug ?? projectNameFromDir(cwd) ?? void 0;
|
|
45
45
|
const uploadEnv = {
|
|
@@ -12,7 +12,7 @@ import { styleText } from "node:util";
|
|
|
12
12
|
async function executeDev(opts) {
|
|
13
13
|
const port = parsePort(opts.port);
|
|
14
14
|
const agentName = path.basename(path.resolve(opts.cwd));
|
|
15
|
-
const { startDevServer } = await import("./_dev-server-
|
|
15
|
+
const { startDevServer } = await import("./_dev-server-CiKFH9qw.mjs");
|
|
16
16
|
let cleanup;
|
|
17
17
|
let shuttingDown = false;
|
|
18
18
|
const onSignal = () => {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { a as ok, t as CliError } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
4
|
import { l as readJson, o as errorMessage, p as writeJson, s as fileExists } from "./_utils-B8QmtFhK.mjs";
|
|
5
|
-
import { scaffoldDir } from "./_templates-
|
|
5
|
+
import { scaffoldDir } from "./_templates-FI3xPEMj.mjs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import fs from "node:fs/promises";
|
|
8
8
|
//#region eject.ts
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { a as ok } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log, s as unwrapCancel } from "./_ui-u7T4YooX.mjs";
|
|
4
4
|
import { d as resolveCwd, l as readJson, o as errorMessage, s as fileExists, t as AGENT_ENTRY } from "./_utils-B8QmtFhK.mjs";
|
|
5
|
-
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-
|
|
5
|
+
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-BTwZJu4P.mjs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { styleText } from "node:util";
|
|
8
8
|
import * as p from "@clack/prompts";
|
|
@@ -105,7 +105,7 @@ function collectWarnings() {
|
|
|
105
105
|
}
|
|
106
106
|
/** Publish after init and return deploy metadata if successful. */
|
|
107
107
|
async function tryPublish(cwd, server, warn) {
|
|
108
|
-
const { executePublish } = await import("./studio
|
|
108
|
+
const { executePublish } = await import("./studio--MUV0cid.mjs");
|
|
109
109
|
try {
|
|
110
110
|
const result = await executePublish({
|
|
111
111
|
cwd,
|
|
@@ -126,7 +126,7 @@ async function tryPublish(cwd, server, warn) {
|
|
|
126
126
|
}
|
|
127
127
|
/** Scaffold the project, optionally showing a spinner. */
|
|
128
128
|
async function scaffoldProject(dir, cwd, template, silent) {
|
|
129
|
-
const { runInit } = await import("./_init-
|
|
129
|
+
const { runInit } = await import("./_init-CE4HKdgV.mjs");
|
|
130
130
|
await withSpinner(silent, {
|
|
131
131
|
start: `Creating ${dir}`,
|
|
132
132
|
done: "Project created",
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok, t as CliError } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
-
import { o as updateGlobalConfig, r as readGlobalConfig, t as approveServer } from "./_config-
|
|
5
|
-
import { o as resolveServerUrl } from "./_agent-
|
|
6
|
-
import { linkConfirmationCode } from "@alexkroman1/aai/
|
|
4
|
+
import { o as updateGlobalConfig, r as readGlobalConfig, t as approveServer } from "./_config-CmJOFsAP.mjs";
|
|
5
|
+
import { o as resolveServerUrl } from "./_agent-BTwZJu4P.mjs";
|
|
6
|
+
import { linkConfirmationCode, sleep } from "@alexkroman1/aai/internal";
|
|
7
7
|
import { spawn } from "node:child_process";
|
|
8
|
-
import { sleep } from "@alexkroman1/aai/internal";
|
|
9
8
|
import { randomBytes } from "node:crypto";
|
|
10
9
|
//#region login.ts
|
|
11
10
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
-
import { f as checkedResponse } from "./_studio-
|
|
5
|
-
import { n as slugRequest } from "./_slug-api-
|
|
4
|
+
import { f as checkedResponse } from "./_studio-DR5yzZ1T.mjs";
|
|
5
|
+
import { n as slugRequest } from "./_slug-api-nRFaBEPJ.mjs";
|
|
6
6
|
import { isRecord, omitUndefined } from "@alexkroman1/aai/utils";
|
|
7
7
|
import { sleep } from "@alexkroman1/aai/internal";
|
|
8
8
|
function isLogsPage(value) {
|
package/dist/project-config.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { c as writeGlobalConfig, s as updateProjectConfig } from "./_config-
|
|
2
|
+
import { c as writeGlobalConfig, s as updateProjectConfig } from "./_config-CmJOFsAP.mjs";
|
|
3
3
|
export { updateProjectConfig, writeGlobalConfig as writeConfigHome };
|
package/dist/scaffold/CLAUDE.md
CHANGED
|
@@ -127,6 +127,8 @@ export default agent({
|
|
|
127
127
|
llm?: LlmProvider | string; // unset stages default to AssemblyAI
|
|
128
128
|
tts?: TtsProvider; // (llm also takes a model-id string)
|
|
129
129
|
s2s?: S2sProvider; // explicit opt-in to speech-to-speech mode
|
|
130
|
+
// all four types are on "@alexkroman1/aai",
|
|
131
|
+
// and on their own stage subpath
|
|
130
132
|
sttPrompt?: string; // STT guidance for jargon/acronyms
|
|
131
133
|
builtinTools?: BuiltinTool[]; // see built-in tools table
|
|
132
134
|
// (there is no `tools` field — a tool is a FILE;
|
|
@@ -344,12 +346,15 @@ async function file(digest: { url: string }) {
|
|
|
344
346
|
}
|
|
345
347
|
```
|
|
346
348
|
|
|
347
|
-
Three rules
|
|
349
|
+
Three rules. The second and third fail silently if broken; the first is
|
|
350
|
+
warned about by `aai build` and `aai dev`, naming the file and the call:
|
|
348
351
|
|
|
349
352
|
- **The body replays from the top on every resume**, so it holds no live handle
|
|
350
353
|
and makes no undurable decision — no `Date.now()`, no `Math.random()`, no
|
|
351
|
-
`fetch`. Those belong in a step, whose result is
|
|
352
|
-
unchanged on replay.
|
|
354
|
+
`crypto.randomUUID()`, no `fetch`. Those belong in a step, whose result is
|
|
355
|
+
journaled and returned unchanged on replay. (The warning reads the built
|
|
356
|
+
workflow bundle, where step bodies have already been removed, so a step doing
|
|
357
|
+
any of this is not flagged — that is what a step is FOR.)
|
|
353
358
|
- **A step's arguments and return value cross a queue**, so they must be
|
|
354
359
|
JSON-shaped and small. Put bytes in storage and pass the key.
|
|
355
360
|
- **A step gets no tool context.** It is bundled and dispatched separately from
|
|
@@ -359,12 +364,12 @@ Three rules, all of which fail silently if broken:
|
|
|
359
364
|
### A step's env, and calling a model from one
|
|
360
365
|
|
|
361
366
|
A step has no `ctx`, so the two things tool code takes for granted come from
|
|
362
|
-
`@alexkroman1/aai/
|
|
367
|
+
`@alexkroman1/aai/step` instead. Import them from THERE and not from
|
|
363
368
|
`@alexkroman1/aai` — a `workflows/*.ts` module is bundled separately, and the
|
|
364
369
|
root barrel would drag the whole SDK into that bundle.
|
|
365
370
|
|
|
366
371
|
```ts no-check
|
|
367
|
-
import { requireStepEnv, stepEnv, StepGenerateError, stepGenerate } from "@alexkroman1/aai/
|
|
372
|
+
import { requireStepEnv, stepEnv, StepGenerateError, stepGenerate } from "@alexkroman1/aai/step";
|
|
368
373
|
import { FatalError } from "workflow";
|
|
369
374
|
|
|
370
375
|
async function summarize(url: string, text: string) {
|
|
@@ -399,11 +404,11 @@ deploy. Ask it for JSON and parse the reply if you need a shape.
|
|
|
399
404
|
### A step's HTTP: use `stepFetch`, not `fetch`
|
|
400
405
|
|
|
401
406
|
Any outbound request from a step goes through `stepFetch` (also
|
|
402
|
-
`@alexkroman1/aai/
|
|
407
|
+
`@alexkroman1/aai/step`). It is not a style preference — `fetch` is the wrong
|
|
403
408
|
call to make from a step, for a reason nothing at the call site shows:
|
|
404
409
|
|
|
405
410
|
```ts no-check
|
|
406
|
-
import { multipartBody, stepFetch, StepTransportError } from "@alexkroman1/aai/
|
|
411
|
+
import { multipartBody, stepFetch, StepTransportError } from "@alexkroman1/aai/step";
|
|
407
412
|
|
|
408
413
|
async function transcribeChunk(key: string, bytes: Uint8Array, index: number) {
|
|
409
414
|
"use step";
|
|
@@ -433,7 +438,7 @@ async function transcribeChunk(key: string, bytes: Uint8Array, index: number) {
|
|
|
433
438
|
global `fetch` offers `h2` in ALPN and the far side decides; a server that takes
|
|
434
439
|
it gets every concurrent request from your process multiplexed onto ONE TCP
|
|
435
440
|
connection, sharing one flow-control window. That is fine for small JSON calls
|
|
436
|
-
and pathological for `
|
|
441
|
+
and pathological for `mapConcurrent` over large bodies. Measured on 8 concurrent
|
|
437
442
|
17.66 MB uploads: `fetch` landed 14 of 16 at p50 8094ms, HTTP/1.1 landed 16 of
|
|
438
443
|
16 at p50 3037ms.
|
|
439
444
|
|
|
@@ -466,6 +471,66 @@ Three rules come with it:
|
|
|
466
471
|
`stepGenerate` already goes through this, so a step that only calls a model gets
|
|
467
472
|
it for free.
|
|
468
473
|
|
|
474
|
+
### A step can SPEAK, and store the file it made
|
|
475
|
+
|
|
476
|
+
A workflow whose answer is a FILE — a summary read aloud, a rendered image, a
|
|
477
|
+
generated PDF — needs two things a first draft reaches for and does not find.
|
|
478
|
+
Both are on `@alexkroman1/aai/step`, and `spoken-summary` is the template that
|
|
479
|
+
shows the whole round trip.
|
|
480
|
+
|
|
481
|
+
```ts no-check
|
|
482
|
+
import { stepSpeak, writeUpload } from "@alexkroman1/aai/step";
|
|
483
|
+
|
|
484
|
+
export async function narrate(script: string) {
|
|
485
|
+
"use step";
|
|
486
|
+
|
|
487
|
+
const spoken = await stepSpeak(script, { voice: "jane" });
|
|
488
|
+
const stored = await writeUpload(spoken.audio, { name: "summary.wav", type: "audio/wav" });
|
|
489
|
+
return { audio: stored.id, durationMs: spoken.durationMs };
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**`stepSpeak` is `stepGenerate` for the voice.** A step is handed no
|
|
494
|
+
`ToolContext`, so the provider stack your `agent()` declares is not in scope —
|
|
495
|
+
and the session TTS surface would not help anyway: it is an event stream wired
|
|
496
|
+
into a live pipeline's playback, and a step has no turn to be part of and has to
|
|
497
|
+
return a value. So this is the smaller thing: text in, the whole utterance out
|
|
498
|
+
as a WAV, on the same `ASSEMBLYAI_API_KEY` everything else uses. Voices come
|
|
499
|
+
from `ASSEMBLYAI_TTS_VOICES` (`@alexkroman1/aai`, or `/tts`) — read that list
|
|
500
|
+
rather than typing an id, because a wrong one is refused *after* the socket
|
|
501
|
+
opens and produces silence rather than an error. The `AssemblyAITtsVoice` type
|
|
502
|
+
gives you autocomplete over it and nothing more: it accepts any string, so that
|
|
503
|
+
a voice the service adds after this release still compiles.
|
|
504
|
+
|
|
505
|
+
**`writeUpload` is `readUpload`'s other direction, and you need it.** A run's
|
|
506
|
+
output is read back as JSON, so audio cannot travel in one — the same rule that
|
|
507
|
+
keeps an uploaded recording's bytes out of a run's INPUT, arriving at the other
|
|
508
|
+
end of the run. Store the bytes, return the **id**, and let the page fetch it
|
|
509
|
+
with `api.download(id)`.
|
|
510
|
+
|
|
511
|
+
Three rules come with it:
|
|
512
|
+
|
|
513
|
+
- **Speak and store in ONE step.** A step is journaled by its return value, so
|
|
514
|
+
an id is replayed on a resume and bytes are not. Split in two, the audio
|
|
515
|
+
crosses the queue between them every time the run resumes.
|
|
516
|
+
- **A retried step writes a SECOND upload** and abandons the first — the store
|
|
517
|
+
cannot know two calls meant one file. That is the price of the step being
|
|
518
|
+
retryable at all, and it is the right trade.
|
|
519
|
+
- **Name and TYPE what you store.** The byte route serves the `type` it was
|
|
520
|
+
given, and a browser will not play inline a file it was handed as
|
|
521
|
+
`application/octet-stream`.
|
|
522
|
+
|
|
523
|
+
On the page, `api.download(id)` answers a `Blob`, not a URL — the byte route
|
|
524
|
+
takes the same bearer every other route does, and neither `<audio src>` nor
|
|
525
|
+
`<a href>` can send one, so a page built on a URL works in `aai dev` and 401s
|
|
526
|
+
once the agent has a token. `URL.createObjectURL(blob)` is what those elements
|
|
527
|
+
take; revoke it when the id changes.
|
|
528
|
+
|
|
529
|
+
Test both with `stubSpeech()` and `stubUploads(files, { writable: true })`
|
|
530
|
+
(`@alexkroman1/aai/testing`). The write half is opt-in on purpose: a store that
|
|
531
|
+
silently accepted writes could not fail a spec whose step stored a file nobody
|
|
532
|
+
meant it to.
|
|
533
|
+
|
|
469
534
|
### A builtin's failure is its RESULT, so narrow it
|
|
470
535
|
|
|
471
536
|
`webSearch`, `visitWebpage` and `fetchJson` (`@alexkroman1/aai/tools`) answer
|
|
@@ -502,7 +567,7 @@ request. Everything else is the same file, React and Tailwind included.
|
|
|
502
567
|
```tsx no-check
|
|
503
568
|
import { createWorkflowApi, page, useWorkflowRun } from "@alexkroman1/aai-ui";
|
|
504
569
|
import "@alexkroman1/aai-ui/styles.css";
|
|
505
|
-
import type { WorkflowOutputOf } from "@alexkroman1/aai";
|
|
570
|
+
import type { WorkflowOutputOf } from "@alexkroman1/aai/workflow-api";
|
|
506
571
|
import { useState } from "react";
|
|
507
572
|
import type { digest } from "./agent.ts";
|
|
508
573
|
|
|
@@ -689,11 +754,18 @@ for the providers you actually use.
|
|
|
689
754
|
| --------------- | ---------------------- | -------------------- |
|
|
690
755
|
| `assemblyAIStt` | `"universal-3-5-pro"` | `ASSEMBLYAI_API_KEY` |
|
|
691
756
|
| `deepgram` | `"nova-3"` | `DEEPGRAM_API_KEY` |
|
|
692
|
-
| `
|
|
757
|
+
| `elevenLabsStt` | `"scribe_v2_realtime"` | `ELEVENLABS_API_KEY` |
|
|
693
758
|
| `soniox` | `"stt-rt-v3"` | `SONIOX_API_KEY` |
|
|
694
759
|
|
|
695
760
|
All STT factories accept `{ model?: string, ... }`. Bare calls
|
|
696
|
-
(`deepgram()`, `soniox()`, etc.) use the default model.
|
|
761
|
+
(`deepgram()`, `soniox()`, etc.) use the default model. Language is spelled
|
|
762
|
+
`language` where the vendor takes one code (`deepgram`, `elevenLabsStt`) and
|
|
763
|
+
`languages` where it takes a list (`assemblyAIStt`, `soniox`) — and only
|
|
764
|
+
`deepgram`'s unset value means English; the other three auto-detect.
|
|
765
|
+
|
|
766
|
+
`elevenLabsStt` carries the stage in its name because ElevenLabs is
|
|
767
|
+
better known for TTS: when that stage arrives, `elevenLabs` is the name it
|
|
768
|
+
should get.
|
|
697
769
|
|
|
698
770
|
`assemblyAIStt` accepts an optional `region: "eu"` for EU data residency —
|
|
699
771
|
it routes streaming transcription to AssemblyAI's EU endpoints. EU-region
|
|
@@ -714,8 +786,11 @@ API keys require it; the US endpoints reject them. Example:
|
|
|
714
786
|
| `gateway` | `ai` (built in) | `AI_GATEWAY_API_KEY` |
|
|
715
787
|
| `assemblyAILlm` | `@ai-sdk/openai` | `ASSEMBLYAI_API_KEY` |
|
|
716
788
|
|
|
717
|
-
LLM factories require `{ model: string }
|
|
718
|
-
|
|
789
|
+
LLM factories require `{ model: string }` — the `ModelOptions` interface,
|
|
790
|
+
shared by all of them except `assemblyAILlm`. Example:
|
|
791
|
+
`anthropic({ model: "claude-haiku-4-5" })`. The argument is required because a
|
|
792
|
+
third-party vendor's catalog is not this SDK's to default from;
|
|
793
|
+
`assemblyAILlm()` is the one bare call, since it has a default model.
|
|
719
794
|
|
|
720
795
|
`openrouter` routes through [OpenRouter](https://openrouter.ai) — an
|
|
721
796
|
OpenAI-compatible endpoint fronting hundreds of models addressed as
|
|
@@ -793,7 +868,11 @@ Set
|
|
|
793
868
|
`language` only alongside a voice that speaks it, as an ISO 639-1 code —
|
|
794
869
|
`"en"`, `"fr"`, `"de"`, `"it"`, `"pt"`, `"es"` are the six the catalog
|
|
795
870
|
covers, and the SDK translates each to the full name the service wants.
|
|
796
|
-
|
|
871
|
+
An unsupported code, and a code the declared voice does not speak, are both
|
|
872
|
+
build errors naming the voices that do speak it — including the one you get by
|
|
873
|
+
setting `language` alone, since the descriptor then fills in the default
|
|
874
|
+
English voice. (A voice this release's catalog does not list is passed through:
|
|
875
|
+
the catalog is the service's, so a voice it ships later still works.)
|
|
797
876
|
|
|
798
877
|
**Rime quirk:** language uses ISO 639-3 three-letter codes (e.g. `"eng"`
|
|
799
878
|
not `"en"`).
|
|
@@ -13,17 +13,19 @@
|
|
|
13
13
|
"publish:agent": "aai publish"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@alexkroman1/aai": "^
|
|
17
|
-
"@alexkroman1/aai-
|
|
16
|
+
"@alexkroman1/aai": "^7.0.0",
|
|
17
|
+
"@alexkroman1/aai-runtime": "^7.0.0",
|
|
18
|
+
"@alexkroman1/aai-ui": "^7.0.0",
|
|
18
19
|
"@workflow/world-postgres": "4.3.3",
|
|
19
20
|
"react": "^19.2.8",
|
|
20
21
|
"react-dom": "^19.2.8",
|
|
21
22
|
"tailwindcss": "^4.0.0",
|
|
22
23
|
"workflow": "4.8.2",
|
|
24
|
+
"xstate": "^5.32.5",
|
|
23
25
|
"zod": "^4.4.3"
|
|
24
26
|
},
|
|
25
27
|
"devDependencies": {
|
|
26
|
-
"@alexkroman1/aai-cli": "^
|
|
28
|
+
"@alexkroman1/aai-cli": "^7.0.0",
|
|
27
29
|
"@tailwindcss/vite": "^4.3.3",
|
|
28
30
|
"@types/node": "^26.2.0",
|
|
29
31
|
"@types/react": "^19.2.18",
|
package/dist/scaffold/server.mjs
CHANGED
|
@@ -17,7 +17,7 @@ import { readFile } from "node:fs/promises";
|
|
|
17
17
|
import path from "node:path";
|
|
18
18
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
19
19
|
import { parseEnv } from "node:util";
|
|
20
|
-
import { createAgentServer, withHostCredentialFallback } from "@alexkroman1/aai
|
|
20
|
+
import { createAgentServer, withHostCredentialFallback } from "@alexkroman1/aai-runtime";
|
|
21
21
|
import { defaultClientDir } from "@alexkroman1/aai-ui/client-dir";
|
|
22
22
|
|
|
23
23
|
const root = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -144,9 +144,18 @@ await server.listen(Number(process.env.PORT ?? 3000), host);
|
|
|
144
144
|
console.log(`${agent.name} listening on http://${host ?? "127.0.0.1"}:${server.port}`);
|
|
145
145
|
|
|
146
146
|
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
147
|
-
|
|
147
|
+
// A SYNCHRONOUS listener. An `async` one hands its promise to `process`,
|
|
148
|
+
// which discards what a listener returns — so a `close()` that rejects would
|
|
149
|
+
// surface as an unhandled rejection, i.e. a crash with a stack trace on
|
|
150
|
+
// Ctrl-C, instead of the non-zero exit a failed shutdown should be.
|
|
151
|
+
process.once(signal, () => {
|
|
148
152
|
// close() shuts the runtime down too — no separate runtime.shutdown().
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
server.close().then(
|
|
154
|
+
() => process.exit(0),
|
|
155
|
+
(error) => {
|
|
156
|
+
console.error(`shutdown failed: ${error?.message ?? error}`);
|
|
157
|
+
process.exit(1);
|
|
158
|
+
},
|
|
159
|
+
);
|
|
151
160
|
});
|
|
152
161
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
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 { f as checkedResponse, p as isStringArray } from "./_studio-
|
|
5
|
-
import { t as secretRequest } from "./_slug-api-
|
|
4
|
+
import { f as checkedResponse, p as isStringArray } from "./_studio-DR5yzZ1T.mjs";
|
|
5
|
+
import { t as secretRequest } from "./_slug-api-nRFaBEPJ.mjs";
|
|
6
6
|
import { isRecord } from "@alexkroman1/aai/utils";
|
|
7
7
|
import * as p from "@clack/prompts";
|
|
8
8
|
import { text } from "node:stream/consumers";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok, n as fail } from "./_output-CKkmWs7i.mjs";
|
|
3
3
|
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
-
import { f as checkedResponse } from "./_studio-
|
|
5
|
-
import { n as slugRequest } from "./_slug-api-
|
|
4
|
+
import { f as checkedResponse } from "./_studio-DR5yzZ1T.mjs";
|
|
5
|
+
import { n as slugRequest } from "./_slug-api-nRFaBEPJ.mjs";
|
|
6
6
|
import { isRecord } from "@alexkroman1/aai/utils";
|
|
7
7
|
import * as p from "@clack/prompts";
|
|
8
8
|
//#region storage.ts
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
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-
|
|
4
|
+
import { s as updateProjectConfig } from "./_config-CmJOFsAP.mjs";
|
|
5
5
|
import { t as resolveServerEnv } from "./_server-common-6e0QI4mq.mjs";
|
|
6
|
-
import { a as resolveDeployTarget } from "./_agent-
|
|
7
|
-
import { layerScaffold } from "./_templates-
|
|
8
|
-
import { a as publishStudioProject, c as studioProjectUrl, f as checkedResponse, i as projectNameFromDir, n as fetchStudioProject, o as pushStudioSource, r as listStudioProjects, s as studioProjectApiUrl, t as collectSourceFiles, u as apiRequest } from "./_studio-
|
|
6
|
+
import { a as resolveDeployTarget } from "./_agent-BTwZJu4P.mjs";
|
|
7
|
+
import { layerScaffold } from "./_templates-FI3xPEMj.mjs";
|
|
8
|
+
import { a as publishStudioProject, c as studioProjectUrl, f as checkedResponse, i as projectNameFromDir, n as fetchStudioProject, o as pushStudioSource, r as listStudioProjects, s as studioProjectApiUrl, t as collectSourceFiles, u as apiRequest } from "./_studio-DR5yzZ1T.mjs";
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { isRecord } from "@alexkroman1/aai/utils";
|
|
11
11
|
import { mkdir, readdir, writeFile } from "node:fs/promises";
|