@alexkroman1/aai-cli 5.11.0 → 5.13.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-DS2PUJcl.mjs → _agent-C8Jk-ZcP.mjs} +3 -2
- package/dist/_agent.d.ts +1 -0
- package/dist/{_api-client-B-upMGkc.mjs → _api-client-BX8Qv51n.mjs} +2 -1
- package/dist/{_bundler-DC17suWN.mjs → _bundler-BuIyDdvs.mjs} +30 -11
- package/dist/_bundler.d.ts +16 -2
- package/dist/{_config-DMyolIk9.mjs → _config-CzwAWOWr.mjs} +3 -3
- package/dist/_deploy.d.ts +0 -10
- package/dist/_dev-restart.d.ts +59 -0
- package/dist/{_dev-server-B3ivqyEd.mjs → _dev-server-Ch7K8e8i.mjs} +181 -92
- package/dist/_dev-server.d.ts +17 -0
- package/dist/{_init-5hHkHe-V.mjs → _init-CbkrE2wq.mjs} +3 -3
- package/dist/_preflight-BtfaYtbE.mjs +46 -0
- package/dist/_preflight.d.ts +57 -0
- package/dist/{_server-common-DX8Bfrf5.mjs → _server-common-61fL__39.mjs} +1 -1
- package/dist/_slug-api-D30zPmsn.mjs +50 -0
- package/dist/_slug-api.d.ts +16 -0
- package/dist/_studio-D2ciIhbi.mjs +94 -0
- package/dist/_studio.d.ts +19 -16
- package/dist/{_templates-DmdG-voA.mjs → _templates-B1kt3BGt.mjs} +2 -2
- package/dist/{_typecheck-gate-DB-PY0A3.mjs → _typecheck-gate-4v9UBZHh.mjs} +1 -1
- package/dist/{_ui-DfwfDbT-.mjs → _ui-u7T4YooX.mjs} +5 -1
- package/dist/_ui.d.ts +2 -0
- package/dist/{_utils-8KKw-bzi.mjs → _utils-0DHbcqUb.mjs} +2 -2
- package/dist/{build-CACFbdQ4.mjs → build-DQJ1ZSm9.mjs} +4 -4
- package/dist/cli.d.ts +2 -1
- package/dist/cli.mjs +70 -34
- package/dist/{client-bundler-DONm-khu.mjs → client-bundler-C9qXL8A2.mjs} +1 -1
- package/dist/client-bundler.mjs +1 -1
- package/dist/{delete-DEZ7u3u4.mjs → delete-DCRX3d96.mjs} +4 -4
- package/dist/{deploy-Ch0d_jje.mjs → deploy-DjsEV-40.mjs} +27 -26
- package/dist/deploy.d.ts +0 -2
- package/dist/{dev-CdeRcYiQ.mjs → dev-CvPH5dbF.mjs} +3 -3
- package/dist/{eject-DSrAp8PL.mjs → eject-LgBRfnbH.mjs} +3 -3
- package/dist/{init-BBAoRI_f.mjs → init-BppxMR8r.mjs} +5 -5
- package/dist/{login-BeFUiU6M.mjs → login-BQQaxJhL.mjs} +4 -15
- package/dist/login.d.ts +0 -9
- package/dist/project-config.d.ts +23 -0
- package/dist/project-config.mjs +3 -0
- package/dist/scaffold/CLAUDE.md +60 -10
- package/dist/scaffold/package.json +3 -3
- package/dist/{secret-4_dYyrpA.mjs → secret-Ds9dvqAj.mjs} +7 -7
- package/dist/{storage-BTfErOOW.mjs → storage-DbrQSHFk.mjs} +2 -2
- package/dist/{studio-DPDFKZ9i.mjs → studio-GSFd4s5O.mjs} +12 -179
- package/dist/templates/dispatch-center/shared.ts +13 -15
- package/dist/templates/pizza-ordering/agent.test.ts +3 -0
- package/dist/templates/retail/store.ts +11 -17
- package/dist/templates/solo-rpg/agent.test.ts +3 -0
- package/dist/{test-C-V98oC-.mjs → test-2LWBcXvY.mjs} +2 -2
- package/dist/typecheck.mjs +1 -1
- package/package.json +8 -3
- package/dist/_slug-api-fRNNR8tz.mjs +0 -27
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log } from "./_ui-
|
|
4
|
-
import {
|
|
5
|
-
import { i as resolveDeployTarget, n as getServerInfo } from "./_agent-
|
|
6
|
-
import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-
|
|
3
|
+
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
+
import { l as writeProjectConfig } from "./_config-CzwAWOWr.mjs";
|
|
5
|
+
import { i as resolveDeployTarget, n as getServerInfo } from "./_agent-C8Jk-ZcP.mjs";
|
|
6
|
+
import { n as apiRequest, t as HINT_NOT_DEPLOYED } from "./_api-client-BX8Qv51n.mjs";
|
|
7
7
|
//#region delete.ts
|
|
8
8
|
async function runDelete(opts) {
|
|
9
9
|
await apiRequest(`${opts.url}/${opts.slug}`, {
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log, t as fmtUrl } from "./_ui-
|
|
4
|
-
import { a as errorMessage } from "./_utils-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { t as resolveServerEnv } from "./_server-common-
|
|
8
|
-
import { i as resolveDeployTarget } from "./_agent-
|
|
9
|
-
import { assertTypechecks } from "./_typecheck-gate-
|
|
10
|
-
import { n as apiRequest } from "./_api-client-
|
|
3
|
+
import { n as log, r as notify, t as fmtUrl } from "./_ui-u7T4YooX.mjs";
|
|
4
|
+
import { a as errorMessage$1 } from "./_utils-0DHbcqUb.mjs";
|
|
5
|
+
import { s as updateProjectConfig } from "./_config-CzwAWOWr.mjs";
|
|
6
|
+
import { i as evalWorkerConfig, t as buildAgentBundle } from "./_bundler-BuIyDdvs.mjs";
|
|
7
|
+
import { t as resolveServerEnv } from "./_server-common-61fL__39.mjs";
|
|
8
|
+
import { i as resolveDeployTarget } from "./_agent-C8Jk-ZcP.mjs";
|
|
9
|
+
import { assertTypechecks } from "./_typecheck-gate-4v9UBZHh.mjs";
|
|
10
|
+
import { n as apiRequest } from "./_api-client-BX8Qv51n.mjs";
|
|
11
|
+
import { i as projectNameFromDir } from "./_studio-D2ciIhbi.mjs";
|
|
12
|
+
import { omitUndefined } from "@alexkroman1/aai/utils";
|
|
11
13
|
import { gzipSync } from "node:zlib";
|
|
12
14
|
//#region _deploy.ts
|
|
13
15
|
async function runDeploy(opts) {
|
|
14
16
|
const body = gzipSync(JSON.stringify({
|
|
15
17
|
...opts.slug ? { slug: opts.slug } : {},
|
|
16
|
-
...opts.allowMissingSecrets ? { credentialPolicy: "warn" } : {},
|
|
17
18
|
...opts.allowPreviewSlug ? { allowPreviewSlug: true } : {},
|
|
18
19
|
env: opts.env,
|
|
19
20
|
worker: opts.bundle.worker,
|
|
20
21
|
clientFiles: opts.bundle.clientFiles
|
|
21
22
|
}));
|
|
22
|
-
|
|
23
|
+
return { slug: (await apiRequest(`${opts.url}/deploy`, {
|
|
23
24
|
method: "POST",
|
|
24
25
|
body,
|
|
25
26
|
headers: {
|
|
@@ -30,13 +31,9 @@ async function runDeploy(opts) {
|
|
|
30
31
|
action: "deploy",
|
|
31
32
|
hints: { 413: "Your bundle is too large. Try reducing dependencies or splitting your agent." },
|
|
32
33
|
...opts.slug ? {} : { retry: 0 },
|
|
33
|
-
...
|
|
34
|
+
...omitUndefined({ retryDelay: opts.retryDelay }),
|
|
34
35
|
...opts.fetch ? { fetch: opts.fetch } : {}
|
|
35
|
-
});
|
|
36
|
-
return {
|
|
37
|
-
slug: data.slug,
|
|
38
|
-
...data.warnings ? { warnings: data.warnings } : {}
|
|
39
|
-
};
|
|
36
|
+
})).slug };
|
|
40
37
|
}
|
|
41
38
|
//#endregion
|
|
42
39
|
//#region deploy.ts
|
|
@@ -44,19 +41,24 @@ async function executeDeploy(opts) {
|
|
|
44
41
|
const { cwd } = opts;
|
|
45
42
|
const { config: projectConfig, serverUrl, apiKey } = await resolveDeployTarget(cwd, opts.server);
|
|
46
43
|
if (!opts.skipTypecheck) await assertTypechecks(cwd);
|
|
44
|
+
const preflightModule = import("./_preflight-BtfaYtbE.mjs");
|
|
47
45
|
const bundle = await buildAgentBundle(cwd, { minify: true });
|
|
48
|
-
const slug = projectConfig?.slug;
|
|
49
|
-
const
|
|
46
|
+
const slug = projectConfig?.slug ?? projectNameFromDir(cwd) ?? void 0;
|
|
47
|
+
const uploadEnv = {
|
|
48
|
+
ASSEMBLYAI_API_KEY: apiKey,
|
|
49
|
+
...await resolveServerEnv(cwd)
|
|
50
|
+
};
|
|
51
|
+
const { missingCredentialMessage, missingCredentials } = await preflightModule;
|
|
52
|
+
const config = await evalWorkerConfig(bundle.worker);
|
|
53
|
+
const missing = config ? missingCredentials(config, uploadEnv) : [];
|
|
54
|
+
const warnings = missing.length > 0 ? [missingCredentialMessage(missing)] : [];
|
|
55
|
+
for (const warning of warnings) notify("warn", warning);
|
|
50
56
|
log.step(`Deploying${slug ? ` ${slug}` : ""}…`);
|
|
51
57
|
const deployed = await runDeploy({
|
|
52
58
|
url: serverUrl,
|
|
53
59
|
bundle,
|
|
54
|
-
env:
|
|
55
|
-
ASSEMBLYAI_API_KEY: apiKey,
|
|
56
|
-
...env
|
|
57
|
-
},
|
|
60
|
+
env: uploadEnv,
|
|
58
61
|
...slug ? { slug } : {},
|
|
59
|
-
...opts.allowMissingSecrets ? { allowMissingSecrets: true } : {},
|
|
60
62
|
...opts.allowPreviewSlug ? { allowPreviewSlug: true } : {},
|
|
61
63
|
apiKey
|
|
62
64
|
});
|
|
@@ -67,18 +69,17 @@ async function executeDeploy(opts) {
|
|
|
67
69
|
serverUrl
|
|
68
70
|
});
|
|
69
71
|
} catch (err) {
|
|
70
|
-
log.warn(`Deployed as ${deployed.slug}, but couldn't save .aai/project.json: ${errorMessage(err)}\n Write it manually so future deploys reuse this slug:
|
|
72
|
+
log.warn(`Deployed as ${deployed.slug}, but couldn't save .aai/project.json: ${errorMessage$1(err)}\n Write it manually so future deploys reuse this slug:
|
|
71
73
|
${JSON.stringify({
|
|
72
74
|
slug: deployed.slug,
|
|
73
75
|
serverUrl
|
|
74
76
|
})}`);
|
|
75
77
|
}
|
|
76
|
-
for (const warning of deployed.warnings ?? []) log.warn(warning);
|
|
77
78
|
log.success(`Deployed ${fmtUrl(agentUrl)}`);
|
|
78
79
|
return ok({
|
|
79
80
|
slug: deployed.slug,
|
|
80
81
|
url: agentUrl,
|
|
81
|
-
...
|
|
82
|
+
...warnings.length > 0 ? { warnings } : {}
|
|
82
83
|
});
|
|
83
84
|
}
|
|
84
85
|
//#endregion
|
package/dist/deploy.d.ts
CHANGED
|
@@ -7,8 +7,6 @@ type DeployData = {
|
|
|
7
7
|
export declare function executeDeploy(opts: {
|
|
8
8
|
cwd: string;
|
|
9
9
|
server?: string | undefined;
|
|
10
|
-
/** See DeployOpts.allowMissingSecrets (`--allow-missing-secrets`). */
|
|
11
|
-
allowMissingSecrets?: boolean | undefined;
|
|
12
10
|
/** See DeployOpts.allowPreviewSlug (`--allow-preview-slug`; studio-internal). */
|
|
13
11
|
allowPreviewSlug?: boolean | undefined;
|
|
14
12
|
/** `--skipTypecheck`: deploy without the tsc gate. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import { i as errorDetail } from "./_utils-
|
|
3
|
+
import { a as parsePort, n as log, r as notify, t as fmtUrl } from "./_ui-u7T4YooX.mjs";
|
|
4
|
+
import { i as errorDetail } from "./_utils-0DHbcqUb.mjs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { styleText } from "node:util";
|
|
7
7
|
//#region dev.ts
|
|
@@ -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-Ch7K8e8i.mjs");
|
|
16
16
|
let cleanup;
|
|
17
17
|
let shuttingDown = false;
|
|
18
18
|
const onSignal = () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok, t as CliError } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log } from "./_ui-
|
|
4
|
-
import { a as errorMessage, c as readJson, d as writeJson, o as fileExists } from "./_utils-
|
|
5
|
-
import { scaffoldDir } from "./_templates-
|
|
3
|
+
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
+
import { a as errorMessage, c as readJson, d as writeJson, o as fileExists } from "./_utils-0DHbcqUb.mjs";
|
|
5
|
+
import { scaffoldDir } from "./_templates-B1kt3BGt.mjs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import fs from "node:fs/promises";
|
|
8
8
|
//#region eject.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log,
|
|
4
|
-
import { a as errorMessage, c as readJson, l as resolveCwd, o as fileExists, t as AGENT_ENTRY } from "./_utils-
|
|
5
|
-
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-
|
|
3
|
+
import { n as log, s as unwrapCancel } from "./_ui-u7T4YooX.mjs";
|
|
4
|
+
import { a as errorMessage, c as readJson, l as resolveCwd, o as fileExists, t as AGENT_ENTRY } from "./_utils-0DHbcqUb.mjs";
|
|
5
|
+
import { r as isDevMode, t as getMonorepoRoot } from "./_agent-C8Jk-ZcP.mjs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { styleText } from "node:util";
|
|
8
8
|
import * as p from "@clack/prompts";
|
|
@@ -75,7 +75,7 @@ function resolveTargetDir(dir) {
|
|
|
75
75
|
}
|
|
76
76
|
/** Publish after init and return deploy metadata if successful. */
|
|
77
77
|
async function tryPublish(cwd, server) {
|
|
78
|
-
const { executePublish } = await import("./studio-
|
|
78
|
+
const { executePublish } = await import("./studio-GSFd4s5O.mjs");
|
|
79
79
|
try {
|
|
80
80
|
const result = await executePublish({
|
|
81
81
|
cwd,
|
|
@@ -94,7 +94,7 @@ async function tryPublish(cwd, server) {
|
|
|
94
94
|
}
|
|
95
95
|
/** Scaffold the project, optionally showing a spinner. */
|
|
96
96
|
async function scaffoldProject(dir, cwd, template, silent) {
|
|
97
|
-
const { runInit } = await import("./_init-
|
|
97
|
+
const { runInit } = await import("./_init-CbkrE2wq.mjs");
|
|
98
98
|
const s = silent ? void 0 : p.spinner();
|
|
99
99
|
s?.start(`Creating ${dir}`);
|
|
100
100
|
await runInit({
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok, t as CliError } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log } from "./_ui-
|
|
4
|
-
import { o as updateGlobalConfig, r as readGlobalConfig, t as approveServer } from "./_config-
|
|
5
|
-
import { a as resolveServerUrl } from "./_agent-
|
|
3
|
+
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
+
import { o as updateGlobalConfig, r as readGlobalConfig, t as approveServer } from "./_config-CzwAWOWr.mjs";
|
|
5
|
+
import { a as resolveServerUrl } from "./_agent-C8Jk-ZcP.mjs";
|
|
6
|
+
import { linkConfirmationCode } from "@alexkroman1/aai/utils";
|
|
6
7
|
import { spawn } from "node:child_process";
|
|
7
8
|
import { setTimeout } from "node:timers/promises";
|
|
8
9
|
import { randomBytes } from "node:crypto";
|
|
@@ -115,18 +116,6 @@ function openerFor(platform) {
|
|
|
115
116
|
]];
|
|
116
117
|
return ["xdg-open", []];
|
|
117
118
|
}
|
|
118
|
-
/**
|
|
119
|
-
* Human-matchable confirmation derived from the link code — printed in the
|
|
120
|
-
* terminal AND shown on the browser approval gate (aai-studio-client's
|
|
121
|
-
* cli-link.ts derives the same value; keep the two in lockstep). Not a
|
|
122
|
-
* secret: both ends already hold the full code. It exists so someone who
|
|
123
|
-
* lands on an approval page they didn't cause has a concrete mismatch to
|
|
124
|
-
* notice ("what terminal?") instead of a bare Approve button.
|
|
125
|
-
*/
|
|
126
|
-
function linkConfirmationCode(code) {
|
|
127
|
-
const head = code.slice(0, 8).toUpperCase();
|
|
128
|
-
return `${head.slice(0, 4)}-${head.slice(4)}`;
|
|
129
|
-
}
|
|
130
119
|
/** Best-effort: the link URL is always printed, so a failure is fine. */
|
|
131
120
|
function defaultOpenBrowser(url) {
|
|
132
121
|
const [cmd, args] = openerFor(process.platform);
|
package/dist/login.d.ts
CHANGED
|
@@ -30,15 +30,6 @@ export type LoginDeps = {
|
|
|
30
30
|
/** Test seam — never set outside tests. */
|
|
31
31
|
timeoutMs?: number;
|
|
32
32
|
};
|
|
33
|
-
/**
|
|
34
|
-
* Human-matchable confirmation derived from the link code — printed in the
|
|
35
|
-
* terminal AND shown on the browser approval gate (aai-studio-client's
|
|
36
|
-
* cli-link.ts derives the same value; keep the two in lockstep). Not a
|
|
37
|
-
* secret: both ends already hold the full code. It exists so someone who
|
|
38
|
-
* lands on an approval page they didn't cause has a concrete mismatch to
|
|
39
|
-
* notice ("what terminal?") instead of a bare Approve button.
|
|
40
|
-
*/
|
|
41
|
-
export declare function linkConfirmationCode(code: string): string;
|
|
42
33
|
export declare function executeLogin(opts: {
|
|
43
34
|
server?: string | undefined;
|
|
44
35
|
}, deps?: LoginDeps): Promise<CommandResult<{
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two on-disk formats a CLI invocation reads, as WRITERS other packages
|
|
3
|
+
* can call — the config home (`config.json`, which holds the API key) and a
|
|
4
|
+
* project's `.aai/project.json` pin.
|
|
5
|
+
*
|
|
6
|
+
* It exists for the studio guest. Publish materializes a workspace into a
|
|
7
|
+
* real project and then spawns this CLI against it
|
|
8
|
+
* (`aai-guest/studio-publish.ts`), which means writing both files first; it
|
|
9
|
+
* used to do that with `JSON.stringify`, so the shapes agreed by coincidence
|
|
10
|
+
* and nothing tied them to the schemas the CLI parses them back with. Two of
|
|
11
|
+
* this file's properties are not obvious from the JSON and were absent from
|
|
12
|
+
* the hand-written copies' successors-in-waiting: the config home is written
|
|
13
|
+
* 0600 through an atomic rename (so an older world-readable file is
|
|
14
|
+
* TIGHTENED rather than left), and the project pin is MERGED, never
|
|
15
|
+
* replaced — `.aai/project.json` also carries the studio link fields, and a
|
|
16
|
+
* writer that replaces the document drops them.
|
|
17
|
+
*
|
|
18
|
+
* Deliberately a thin re-export of `_config.ts` rather than a second
|
|
19
|
+
* implementation: the point is that there is one writer per format, not that
|
|
20
|
+
* there is a nicer one here.
|
|
21
|
+
*/
|
|
22
|
+
export type { GlobalConfig, ProjectConfig } from "./_config.ts";
|
|
23
|
+
export { updateProjectConfig, writeGlobalConfig as writeConfigHome } from "./_config.ts";
|
package/dist/scaffold/CLAUDE.md
CHANGED
|
@@ -205,9 +205,9 @@ that stage — the rest keep the default.
|
|
|
205
205
|
from `@alexkroman1/aai`, next to `agent()`) selects AssemblyAI's
|
|
206
206
|
speech-to-speech Voice Agent API: STT, the LLM loop, and TTS run
|
|
207
207
|
service-side in one socket. Fewer moving parts, but you cannot choose the
|
|
208
|
-
model
|
|
209
|
-
|
|
210
|
-
|
|
208
|
+
model or swap a provider. There is no way to reach S2S by omission — only
|
|
209
|
+
the `s2s` field selects it, and it is mutually exclusive with the
|
|
210
|
+
`stt`/`llm`/`tts` triple.
|
|
211
211
|
|
|
212
212
|
```ts
|
|
213
213
|
import { agent, assemblyAIS2s } from "@alexkroman1/aai";
|
|
@@ -218,6 +218,33 @@ export default agent({
|
|
|
218
218
|
});
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
+
The descriptor takes three optional knobs, all forwarded only when set:
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
import { agent, assemblyAIS2s } from "@alexkroman1/aai";
|
|
225
|
+
|
|
226
|
+
export default agent({
|
|
227
|
+
name: "My Agent",
|
|
228
|
+
sttPrompt: "Callers spell order numbers one character at a time.",
|
|
229
|
+
s2s: assemblyAIS2s({
|
|
230
|
+
voice: "michael",
|
|
231
|
+
languages: ["en"],
|
|
232
|
+
keyterms: ["Acme Rewards", "SKU"],
|
|
233
|
+
}),
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
- `voice` — the agent's voice. Unset uses the service default.
|
|
238
|
+
- `languages` — **leave it unset for multilingual calls**: unset means
|
|
239
|
+
"detect per turn", so pinning `["en"]` on a line that takes other
|
|
240
|
+
languages disables detection for every caller. Pin it when the line
|
|
241
|
+
really is monolingual — on a benchmark run that plus a transcription
|
|
242
|
+
prompt took a caller's spelled first name from 1 of 6 attempts correct
|
|
243
|
+
to 6 of 6.
|
|
244
|
+
- `keyterms` — product names and proper nouns to bias transcription
|
|
245
|
+
toward. Use `sttPrompt` (above, and honoured in **both** modes) for
|
|
246
|
+
prose guidance and `keyterms` for a term list.
|
|
247
|
+
|
|
221
248
|
**Prefer pipeline mode** — the default — unless the user specifically
|
|
222
249
|
asks for the speech-to-speech API. Nearly every template ships this way, and
|
|
223
250
|
it is what AssemblyAI Build defaults to. The host runs the LLM loop locally
|
|
@@ -444,6 +471,28 @@ ctx.messages: readonly Message[] // conversation history [{role, c
|
|
|
444
471
|
ctx.sessionId: string // unique session ID
|
|
445
472
|
ctx.send(event: string, data: unknown): void // push custom event to browser client (silently dropped over 64 KB JSON)
|
|
446
473
|
ctx.generate(opts): Promise<{ text, object? }> // one-shot LLM call (host-side)
|
|
474
|
+
// with a `schema`, `object` is REQUIRED and typed by it
|
|
475
|
+
ctx.signal: AbortSignal // aborts on barge-in, reset, session stop, or this call's timeout
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
**Pass `ctx.signal` to anything slow.** It is always present — no `?.`
|
|
479
|
+
needed — and forwarding it is what makes a tool stop work the caller has
|
|
480
|
+
already interrupted:
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
import { tool } from "@alexkroman1/aai";
|
|
484
|
+
import { z } from "zod";
|
|
485
|
+
|
|
486
|
+
export const lookup = tool({
|
|
487
|
+
description: "Look up an order",
|
|
488
|
+
inputSchema: z.object({ id: z.string() }),
|
|
489
|
+
execute: async ({ id }, ctx) => {
|
|
490
|
+
const res = await fetch(`https://api.example.com/orders/${id}`, {
|
|
491
|
+
signal: ctx.signal,
|
|
492
|
+
});
|
|
493
|
+
return await res.json();
|
|
494
|
+
},
|
|
495
|
+
});
|
|
447
496
|
```
|
|
448
497
|
|
|
449
498
|
**Typing `ctx.state` is optional.** `ctx.state` is untyped by default, and
|
|
@@ -632,9 +681,10 @@ export default agent({
|
|
|
632
681
|
|
|
633
682
|
## Built-in tools
|
|
634
683
|
|
|
635
|
-
Enable via `builtinTools` in `agent()`. When `builtinTools` is omitted,
|
|
636
|
-
|
|
637
|
-
|
|
684
|
+
Enable via `builtinTools` in `agent()`. **When `builtinTools` is omitted, none
|
|
685
|
+
are enabled** — omitting the field and passing `[]` mean the same thing. Name
|
|
686
|
+
the ones you want; a built-in is something an agent asks for rather than
|
|
687
|
+
something it has to notice and switch off.
|
|
638
688
|
|
|
639
689
|
| Tool | Description | Params |
|
|
640
690
|
| --- | --- | --- |
|
|
@@ -643,10 +693,10 @@ set `builtinTools` explicitly (including `[]`) to override.
|
|
|
643
693
|
| `get_page_design` | Fetch URL's raw HTML + CSS (style blocks and linked stylesheets) to study/mimic a site's design | `url` |
|
|
644
694
|
| `fetch_json` | HTTP GET a JSON API | `url`, `headers?` |
|
|
645
695
|
| `run_code` | Execute JS in the agent's sandbox — same authority as the agent's own tool code, output is what it logs (5s timeout) | `code` |
|
|
646
|
-
| `think` | Private reasoning scratchpad, no side effects
|
|
647
|
-
| `remember` | Save a confirmed fact to session notes
|
|
648
|
-
| `recall` | Read session notes saved with `remember`
|
|
649
|
-
| `calculate` | Safe arithmetic evaluator, no code execution
|
|
696
|
+
| `think` | Private reasoning scratchpad, no side effects | `thought` |
|
|
697
|
+
| `remember` | Save a confirmed fact to session notes | `key`, `value` |
|
|
698
|
+
| `recall` | Read session notes saved with `remember` | `key?` |
|
|
699
|
+
| `calculate` | Safe arithmetic evaluator, no code execution | `expression` |
|
|
650
700
|
|
|
651
701
|
**Every builtin in this table is a tool the MODEL calls — not a function
|
|
652
702
|
your code can call.** Listing one in `builtinTools` adds it to the model's
|
|
@@ -12,15 +12,15 @@
|
|
|
12
12
|
"publish:agent": "aai publish"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@alexkroman1/aai": "^5.
|
|
16
|
-
"@alexkroman1/aai-ui": "^5.
|
|
15
|
+
"@alexkroman1/aai": "^5.13.0",
|
|
16
|
+
"@alexkroman1/aai-ui": "^5.13.0",
|
|
17
17
|
"react": "^19.2.8",
|
|
18
18
|
"react-dom": "^19.2.8",
|
|
19
19
|
"tailwindcss": "^4.0.0",
|
|
20
20
|
"zod": "^4.4.3"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@alexkroman1/aai-cli": "^5.
|
|
23
|
+
"@alexkroman1/aai-cli": "^5.13.0",
|
|
24
24
|
"@tailwindcss/vite": "^4.3.3",
|
|
25
25
|
"@types/node": "^26.1.1",
|
|
26
26
|
"@types/react": "^19.2.17",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok, n as fail } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log,
|
|
4
|
-
import { t as
|
|
3
|
+
import { n as log, s as unwrapCancel } from "./_ui-u7T4YooX.mjs";
|
|
4
|
+
import { t as secretRequest } from "./_slug-api-D30zPmsn.mjs";
|
|
5
5
|
import * as p from "@clack/prompts";
|
|
6
6
|
import { text } from "node:stream/consumers";
|
|
7
7
|
//#region secret.ts
|
|
@@ -29,24 +29,24 @@ async function executeSecretPut(cwd, name, value, server) {
|
|
|
29
29
|
if (!result) return fail(...NO_INPUT);
|
|
30
30
|
secretValue = result;
|
|
31
31
|
}
|
|
32
|
-
const {
|
|
32
|
+
const { target } = await secretRequest(cwd, "", {
|
|
33
33
|
method: "PUT",
|
|
34
34
|
body: { [name]: secretValue },
|
|
35
35
|
action: "secret"
|
|
36
36
|
}, server);
|
|
37
|
-
log.success(`Set ${name} for ${
|
|
37
|
+
log.success(`Set ${name} for ${target}`);
|
|
38
38
|
return ok({ name });
|
|
39
39
|
}
|
|
40
40
|
async function executeSecretDelete(cwd, name, server) {
|
|
41
|
-
const {
|
|
41
|
+
const { target } = await secretRequest(cwd, `/${encodeURIComponent(name)}`, {
|
|
42
42
|
method: "DELETE",
|
|
43
43
|
action: "secret"
|
|
44
44
|
}, server);
|
|
45
|
-
log.success(`Deleted ${name} from ${
|
|
45
|
+
log.success(`Deleted ${name} from ${target}`);
|
|
46
46
|
return ok({ name });
|
|
47
47
|
}
|
|
48
48
|
async function executeSecretList(cwd, server) {
|
|
49
|
-
const { data: { vars } } = await
|
|
49
|
+
const { data: { vars } } = await secretRequest(cwd, "", { action: "secret" }, server);
|
|
50
50
|
if (vars.length === 0) log.info("No secrets set. Use `aai secret put <name>` to add one.");
|
|
51
51
|
else {
|
|
52
52
|
log.message(`${vars.length} secret${vars.length === 1 ? "" : "s"}:`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { a as ok, n as fail } from "./_output-CC300DzW.mjs";
|
|
3
|
-
import { n as log } from "./_ui-
|
|
4
|
-
import {
|
|
3
|
+
import { n as log } from "./_ui-u7T4YooX.mjs";
|
|
4
|
+
import { n as slugRequest } from "./_slug-api-D30zPmsn.mjs";
|
|
5
5
|
import * as p from "@clack/prompts";
|
|
6
6
|
//#region storage.ts
|
|
7
7
|
async function storageRequest(cwd, init, server) {
|