@alexkroman1/aai 0.7.9 → 0.7.10
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/aai.js +1 -1
- package/dist/cli.js +393 -372
- package/dist/sdk/s2s.d.ts.map +1 -1
- package/dist/sdk/s2s.js +13 -1
- package/dist/sdk/s2s.js.map +1 -1
- package/dist/sdk/server.d.ts.map +1 -1
- package/dist/sdk/server.js +1 -4
- package/dist/sdk/server.js.map +1 -1
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -12,17 +12,24 @@ var __export = (target, all) => {
|
|
|
12
12
|
// cli/_colors.ts
|
|
13
13
|
import chalk from "chalk";
|
|
14
14
|
function primary(s) {
|
|
15
|
-
return chalk.hex(
|
|
15
|
+
return chalk.hex(COLORS.primary)(s);
|
|
16
16
|
}
|
|
17
17
|
function interactive(s) {
|
|
18
|
-
return chalk.hex(
|
|
19
|
-
}
|
|
20
|
-
function error(s) {
|
|
21
|
-
return chalk.hex("#e06c75")(s);
|
|
18
|
+
return chalk.hex(COLORS.interactive)(s);
|
|
22
19
|
}
|
|
20
|
+
var COLORS;
|
|
23
21
|
var init_colors = __esm({
|
|
24
22
|
"cli/_colors.ts"() {
|
|
25
23
|
"use strict";
|
|
24
|
+
COLORS = {
|
|
25
|
+
primary: "#fab283",
|
|
26
|
+
interactive: "#56b6c2",
|
|
27
|
+
error: "#e06c75",
|
|
28
|
+
warning: "#f5a742",
|
|
29
|
+
success: "#7fd88f",
|
|
30
|
+
accent: "#9d7cd8",
|
|
31
|
+
muted: "#808080"
|
|
32
|
+
};
|
|
26
33
|
}
|
|
27
34
|
});
|
|
28
35
|
|
|
@@ -121,46 +128,37 @@ var init_help = __esm({
|
|
|
121
128
|
}
|
|
122
129
|
});
|
|
123
130
|
|
|
124
|
-
// cli/_output.ts
|
|
125
|
-
import chalk3 from "chalk";
|
|
126
|
-
function fmt(action, color, msg) {
|
|
127
|
-
return `${color(chalk3.bold(action))} ${msg}`;
|
|
128
|
-
}
|
|
129
|
-
function step(action, msg) {
|
|
130
|
-
console.log(fmt(action, primary, msg));
|
|
131
|
-
}
|
|
132
|
-
function error2(msg) {
|
|
133
|
-
console.error(`${error(chalk3.bold("error"))}: ${msg}`);
|
|
134
|
-
}
|
|
135
|
-
var init_output = __esm({
|
|
136
|
-
"cli/_output.ts"() {
|
|
137
|
-
"use strict";
|
|
138
|
-
init_colors();
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
|
|
142
131
|
// cli/_bundler.ts
|
|
143
132
|
import fs from "node:fs/promises";
|
|
144
133
|
import path from "node:path";
|
|
145
134
|
import preact from "@preact/preset-vite";
|
|
146
135
|
import tailwindcss from "@tailwindcss/vite";
|
|
147
136
|
import { build } from "vite";
|
|
148
|
-
function
|
|
149
|
-
const outputs = Array.isArray(result) ? result : [result];
|
|
137
|
+
async function readDirRecursive(dir, base = dir) {
|
|
150
138
|
const files = {};
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
139
|
+
let names;
|
|
140
|
+
try {
|
|
141
|
+
names = await fs.readdir(dir);
|
|
142
|
+
} catch {
|
|
143
|
+
return files;
|
|
144
|
+
}
|
|
145
|
+
for (const name of names) {
|
|
146
|
+
const full = path.join(dir, name);
|
|
147
|
+
const stat = await fs.stat(full);
|
|
148
|
+
const entry = { name, isDirectory: () => stat.isDirectory() };
|
|
149
|
+
if (entry.isDirectory()) {
|
|
150
|
+
Object.assign(files, await readDirRecursive(full, base));
|
|
151
|
+
} else {
|
|
152
|
+
const rel = path.relative(base, full);
|
|
153
|
+
files[rel] = await fs.readFile(full, "utf-8");
|
|
158
154
|
}
|
|
159
155
|
}
|
|
160
156
|
return files;
|
|
161
157
|
}
|
|
162
158
|
async function bundleAgent(agent, opts) {
|
|
163
159
|
const aaiDir = path.join(agent.dir, ".aai");
|
|
160
|
+
const buildDir = path.join(aaiDir, "build");
|
|
161
|
+
const clientDir = path.join(aaiDir, "client");
|
|
164
162
|
await fs.mkdir(aaiDir, { recursive: true });
|
|
165
163
|
const workerEntry = path.join(aaiDir, "_worker_entry.ts");
|
|
166
164
|
await fs.writeFile(
|
|
@@ -171,14 +169,14 @@ async function bundleAgent(agent, opts) {
|
|
|
171
169
|
`initWorker(agent);`
|
|
172
170
|
].join("\n")
|
|
173
171
|
);
|
|
174
|
-
let workerResult;
|
|
175
172
|
try {
|
|
176
|
-
|
|
173
|
+
await build({
|
|
177
174
|
configFile: false,
|
|
178
175
|
root: agent.dir,
|
|
179
176
|
logLevel: "warn",
|
|
180
177
|
build: {
|
|
181
|
-
|
|
178
|
+
outDir: buildDir,
|
|
179
|
+
emptyOutDir: true,
|
|
182
180
|
minify: true,
|
|
183
181
|
target: "es2022",
|
|
184
182
|
rollupOptions: {
|
|
@@ -194,20 +192,17 @@ async function bundleAgent(agent, opts) {
|
|
|
194
192
|
} catch (err) {
|
|
195
193
|
throw new BundleError(err instanceof Error ? err.message : String(err));
|
|
196
194
|
}
|
|
197
|
-
const workerFiles = extractFiles(workerResult);
|
|
198
|
-
const worker = workerFiles["worker.js"] ?? "";
|
|
199
195
|
const skipClient = opts?.skipClient || !agent.clientEntry;
|
|
200
|
-
let clientFiles = {};
|
|
201
196
|
if (!skipClient) {
|
|
202
|
-
let clientResult;
|
|
203
197
|
try {
|
|
204
|
-
|
|
198
|
+
await build({
|
|
205
199
|
root: agent.dir,
|
|
206
200
|
base: "./",
|
|
207
201
|
logLevel: "warn",
|
|
208
202
|
plugins: [preact(), tailwindcss()],
|
|
209
203
|
build: {
|
|
210
|
-
|
|
204
|
+
outDir: clientDir,
|
|
205
|
+
emptyOutDir: true,
|
|
211
206
|
minify: true,
|
|
212
207
|
target: "es2022"
|
|
213
208
|
}
|
|
@@ -215,11 +210,13 @@ async function bundleAgent(agent, opts) {
|
|
|
215
210
|
} catch (err) {
|
|
216
211
|
throw new BundleError(err instanceof Error ? err.message : String(err));
|
|
217
212
|
}
|
|
218
|
-
clientFiles = extractFiles(clientResult);
|
|
219
213
|
}
|
|
214
|
+
const worker = await fs.readFile(path.join(buildDir, "worker.js"), "utf-8");
|
|
215
|
+
const clientFiles = await readDirRecursive(clientDir);
|
|
220
216
|
return {
|
|
221
217
|
worker,
|
|
222
218
|
clientFiles,
|
|
219
|
+
clientDir,
|
|
223
220
|
workerBytes: Buffer.byteLength(worker)
|
|
224
221
|
};
|
|
225
222
|
}
|
|
@@ -261,23 +258,20 @@ async function askPassword(message) {
|
|
|
261
258
|
);
|
|
262
259
|
});
|
|
263
260
|
}
|
|
264
|
-
async function
|
|
261
|
+
async function askText(message, defaultValue) {
|
|
265
262
|
return new Promise((resolve) => {
|
|
266
263
|
const app = render(
|
|
267
264
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
268
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
265
|
+
/* @__PURE__ */ jsxs(Text, { color: COLORS.interactive, children: [
|
|
269
266
|
message,
|
|
270
|
-
" "
|
|
267
|
+
" \u203A "
|
|
271
268
|
] }),
|
|
272
269
|
/* @__PURE__ */ jsx(
|
|
273
|
-
|
|
270
|
+
TextInput,
|
|
274
271
|
{
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
},
|
|
279
|
-
onCancel: () => {
|
|
280
|
-
resolve(false);
|
|
272
|
+
placeholder: defaultValue,
|
|
273
|
+
onSubmit: (value) => {
|
|
274
|
+
resolve(value || defaultValue);
|
|
281
275
|
app.unmount();
|
|
282
276
|
}
|
|
283
277
|
}
|
|
@@ -286,20 +280,17 @@ async function askConfirm(message) {
|
|
|
286
280
|
);
|
|
287
281
|
});
|
|
288
282
|
}
|
|
289
|
-
async function
|
|
283
|
+
async function askEnter(message) {
|
|
290
284
|
return new Promise((resolve) => {
|
|
291
285
|
const app = render(
|
|
292
286
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
293
|
-
/* @__PURE__ */
|
|
294
|
-
message,
|
|
295
|
-
" \u203A "
|
|
296
|
-
] }),
|
|
287
|
+
/* @__PURE__ */ jsx(Text, { color: COLORS.interactive, children: message }),
|
|
297
288
|
/* @__PURE__ */ jsx(
|
|
298
289
|
TextInput,
|
|
299
290
|
{
|
|
300
|
-
placeholder:
|
|
301
|
-
onSubmit: (
|
|
302
|
-
resolve(
|
|
291
|
+
placeholder: "",
|
|
292
|
+
onSubmit: () => {
|
|
293
|
+
resolve();
|
|
303
294
|
app.unmount();
|
|
304
295
|
}
|
|
305
296
|
}
|
|
@@ -311,10 +302,22 @@ async function askText(message, defaultValue) {
|
|
|
311
302
|
var init_prompts = __esm({
|
|
312
303
|
"cli/_prompts.tsx"() {
|
|
313
304
|
"use strict";
|
|
305
|
+
init_colors();
|
|
314
306
|
}
|
|
315
307
|
});
|
|
316
308
|
|
|
317
309
|
// cli/_discover.ts
|
|
310
|
+
var discover_exports = {};
|
|
311
|
+
__export(discover_exports, {
|
|
312
|
+
DEFAULT_SERVER: () => DEFAULT_SERVER,
|
|
313
|
+
fileExists: () => fileExists,
|
|
314
|
+
generateSlug: () => generateSlug,
|
|
315
|
+
getApiKey: () => getApiKey,
|
|
316
|
+
isDevMode: () => isDevMode,
|
|
317
|
+
loadAgent: () => loadAgent,
|
|
318
|
+
readProjectConfig: () => readProjectConfig,
|
|
319
|
+
writeProjectConfig: () => writeProjectConfig
|
|
320
|
+
});
|
|
318
321
|
import { accessSync } from "node:fs";
|
|
319
322
|
import fs2 from "node:fs/promises";
|
|
320
323
|
import path2 from "node:path";
|
|
@@ -358,8 +361,6 @@ async function getApiKey() {
|
|
|
358
361
|
process.env.ASSEMBLYAI_API_KEY = config.assemblyai_api_key;
|
|
359
362
|
return config.assemblyai_api_key;
|
|
360
363
|
}
|
|
361
|
-
step("Setup", "AssemblyAI API key required for speech-to-text");
|
|
362
|
-
console.log("Get one at https://www.assemblyai.com/dashboard/signup\n");
|
|
363
364
|
let key;
|
|
364
365
|
while (!key) {
|
|
365
366
|
key = await askPassword("ASSEMBLYAI_API_KEY");
|
|
@@ -367,7 +368,6 @@ async function getApiKey() {
|
|
|
367
368
|
config.assemblyai_api_key = key;
|
|
368
369
|
process.env.ASSEMBLYAI_API_KEY = key;
|
|
369
370
|
await writeAuthConfig(config);
|
|
370
|
-
step("Saved", CONFIG_FILE);
|
|
371
371
|
return key;
|
|
372
372
|
}
|
|
373
373
|
async function readProjectConfig(agentDir) {
|
|
@@ -408,7 +408,6 @@ var CONFIG_DIR, CONFIG_FILE, DEFAULT_SERVER;
|
|
|
408
408
|
var init_discover = __esm({
|
|
409
409
|
"cli/_discover.ts"() {
|
|
410
410
|
"use strict";
|
|
411
|
-
init_output();
|
|
412
411
|
init_prompts();
|
|
413
412
|
CONFIG_DIR = path2.join(process.env.HOME ?? process.env.USERPROFILE ?? ".", ".config", "aai");
|
|
414
413
|
CONFIG_FILE = path2.join(CONFIG_DIR, "config.json");
|
|
@@ -474,7 +473,7 @@ import React, { useRef, useState } from "react";
|
|
|
474
473
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
475
474
|
function Step({ action, msg }) {
|
|
476
475
|
return /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
477
|
-
/* @__PURE__ */ jsx2(Text2, { bold: true, color:
|
|
476
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, color: COLORS.primary, children: action }),
|
|
478
477
|
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
479
478
|
" ",
|
|
480
479
|
msg
|
|
@@ -483,7 +482,7 @@ function Step({ action, msg }) {
|
|
|
483
482
|
}
|
|
484
483
|
function StepInfo({ action, msg }) {
|
|
485
484
|
return /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
486
|
-
/* @__PURE__ */ jsx2(Text2, { bold: true, color:
|
|
485
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, color: COLORS.interactive, children: action }),
|
|
487
486
|
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
488
487
|
" ",
|
|
489
488
|
msg
|
|
@@ -498,7 +497,7 @@ function Detail({ msg }) {
|
|
|
498
497
|
}
|
|
499
498
|
function Warn({ msg }) {
|
|
500
499
|
return /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
501
|
-
/* @__PURE__ */ jsx2(Text2, { bold: true, color:
|
|
500
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, color: COLORS.warning, children: "warning" }),
|
|
502
501
|
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
503
502
|
" ",
|
|
504
503
|
msg
|
|
@@ -507,7 +506,7 @@ function Warn({ msg }) {
|
|
|
507
506
|
}
|
|
508
507
|
function ErrorLine({ msg }) {
|
|
509
508
|
return /* @__PURE__ */ jsxs2(Text2, { children: [
|
|
510
|
-
/* @__PURE__ */ jsx2(Text2, { bold: true, color:
|
|
509
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, color: COLORS.error, children: "error" }),
|
|
511
510
|
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
512
511
|
": ",
|
|
513
512
|
msg
|
|
@@ -551,9 +550,9 @@ function CommandRunner({
|
|
|
551
550
|
try {
|
|
552
551
|
await run(wrappedLog);
|
|
553
552
|
} catch (e) {
|
|
554
|
-
const
|
|
555
|
-
setErr(
|
|
556
|
-
onError?.(
|
|
553
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
554
|
+
setErr(error.message);
|
|
555
|
+
onError?.(error);
|
|
557
556
|
}
|
|
558
557
|
if (currentStepRef.current) {
|
|
559
558
|
log(currentStepRef.current);
|
|
@@ -590,14 +589,10 @@ async function runWithInk(fn) {
|
|
|
590
589
|
await app.waitUntilExit();
|
|
591
590
|
if (thrownError) throw thrownError;
|
|
592
591
|
}
|
|
593
|
-
var PRIMARY, INTERACTIVE, ERROR_COLOR, WARNING_COLOR;
|
|
594
592
|
var init_ink = __esm({
|
|
595
593
|
"cli/_ink.tsx"() {
|
|
596
594
|
"use strict";
|
|
597
|
-
|
|
598
|
-
INTERACTIVE = "#56b6c2";
|
|
599
|
-
ERROR_COLOR = "#e06c75";
|
|
600
|
-
WARNING_COLOR = "#f5a742";
|
|
595
|
+
init_colors();
|
|
601
596
|
}
|
|
602
597
|
});
|
|
603
598
|
|
|
@@ -741,6 +736,8 @@ async function runInitCommand(args, version, opts) {
|
|
|
741
736
|
console.log(subcommandHelp(initCommandDef, version));
|
|
742
737
|
return "";
|
|
743
738
|
}
|
|
739
|
+
const { getApiKey: getApiKey2 } = await Promise.resolve().then(() => (init_discover(), discover_exports));
|
|
740
|
+
await getApiKey2();
|
|
744
741
|
let dir = parsed._[0];
|
|
745
742
|
if (!dir) {
|
|
746
743
|
dir = await askText("What is your project named?", "my-voice-agent");
|
|
@@ -802,21 +799,9 @@ var deploy_exports = {};
|
|
|
802
799
|
__export(deploy_exports, {
|
|
803
800
|
runDeployCommand: () => runDeployCommand
|
|
804
801
|
});
|
|
805
|
-
import fs5 from "node:fs/promises";
|
|
806
802
|
import path5 from "node:path";
|
|
807
803
|
import minimist2 from "minimist";
|
|
808
804
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
809
|
-
async function writeBuildOutput(agentDir, bundle) {
|
|
810
|
-
const buildDir = path5.join(agentDir, ".aai", "build");
|
|
811
|
-
await fs5.mkdir(buildDir, { recursive: true });
|
|
812
|
-
const writes = [fs5.writeFile(path5.join(buildDir, "worker.js"), bundle.worker)];
|
|
813
|
-
for (const [relPath, content] of Object.entries(bundle.clientFiles)) {
|
|
814
|
-
const fullPath = path5.join(buildDir, "client", relPath);
|
|
815
|
-
await fs5.mkdir(path5.dirname(fullPath), { recursive: true });
|
|
816
|
-
writes.push(fs5.writeFile(fullPath, content));
|
|
817
|
-
}
|
|
818
|
-
await Promise.all(writes);
|
|
819
|
-
}
|
|
820
805
|
function resolveServerUrl(parsed) {
|
|
821
806
|
return parsed.server || (isDevMode() ? "http://localhost:3100" : DEFAULT_SERVER);
|
|
822
807
|
}
|
|
@@ -835,7 +820,6 @@ async function buildAgent(cwd, log) {
|
|
|
835
820
|
}
|
|
836
821
|
throw err;
|
|
837
822
|
}
|
|
838
|
-
await writeBuildOutput(cwd, bundle);
|
|
839
823
|
return bundle;
|
|
840
824
|
}
|
|
841
825
|
async function deployBundle(opts) {
|
|
@@ -844,11 +828,7 @@ async function deployBundle(opts) {
|
|
|
844
828
|
log(/* @__PURE__ */ jsx4(Step, { action: "Deploy", msg: slug }));
|
|
845
829
|
const deployed = await runDeploy({
|
|
846
830
|
url: serverUrl,
|
|
847
|
-
bundle
|
|
848
|
-
worker: bundle.worker,
|
|
849
|
-
clientFiles: bundle.clientFiles,
|
|
850
|
-
workerBytes: bundle.workerBytes
|
|
851
|
-
},
|
|
831
|
+
bundle,
|
|
852
832
|
env: { ASSEMBLYAI_API_KEY: apiKey },
|
|
853
833
|
slug,
|
|
854
834
|
dryRun: false,
|
|
@@ -889,11 +869,9 @@ async function runDeployCommand(args, version) {
|
|
|
889
869
|
agentUrl = await deployBundle({ bundle, serverUrl, apiKey, slug, cwd, log });
|
|
890
870
|
});
|
|
891
871
|
if (agentUrl && !dryRun) {
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
exec(`open "${agentUrl}"`);
|
|
896
|
-
}
|
|
872
|
+
await askEnter("Press enter to open in browser");
|
|
873
|
+
const { exec } = await import("node:child_process");
|
|
874
|
+
exec(`open "${agentUrl}"`);
|
|
897
875
|
}
|
|
898
876
|
}
|
|
899
877
|
var deployCommandDef;
|
|
@@ -922,11 +900,11 @@ var init_deploy2 = __esm({
|
|
|
922
900
|
}
|
|
923
901
|
});
|
|
924
902
|
|
|
925
|
-
//
|
|
903
|
+
// sdk/protocol.ts
|
|
926
904
|
import { z } from "zod";
|
|
927
905
|
var DEFAULT_TTS_SAMPLE_RATE, AUDIO_FORMAT, _bitsPerSample, _channels, AudioFrameSpec, KvRequestBaseSchema, HOOK_TIMEOUT_MS, SessionErrorCodeSchema, TranscriptEventSchema, ClientEventSchema, ClientMessageSchema;
|
|
928
906
|
var init_protocol = __esm({
|
|
929
|
-
"
|
|
907
|
+
"sdk/protocol.ts"() {
|
|
930
908
|
"use strict";
|
|
931
909
|
DEFAULT_TTS_SAMPLE_RATE = 24e3;
|
|
932
910
|
AUDIO_FORMAT = "pcm16";
|
|
@@ -1013,45 +991,39 @@ var init_protocol = __esm({
|
|
|
1013
991
|
z.object({ type: z.literal("reset") }),
|
|
1014
992
|
z.object({
|
|
1015
993
|
type: z.literal("history"),
|
|
1016
|
-
messages: z.array(
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
994
|
+
messages: z.array(
|
|
995
|
+
z.object({
|
|
996
|
+
role: z.enum(["user", "assistant"]),
|
|
997
|
+
text: z.string().max(1e5)
|
|
998
|
+
})
|
|
999
|
+
).max(200)
|
|
1020
1000
|
})
|
|
1021
1001
|
]);
|
|
1022
1002
|
}
|
|
1023
1003
|
});
|
|
1024
1004
|
|
|
1025
|
-
//
|
|
1005
|
+
// sdk/runtime.ts
|
|
1026
1006
|
var consoleLogger, noopMetrics, DEFAULT_S2S_CONFIG;
|
|
1027
1007
|
var init_runtime = __esm({
|
|
1028
|
-
"
|
|
1008
|
+
"sdk/runtime.ts"() {
|
|
1029
1009
|
"use strict";
|
|
1030
1010
|
init_protocol();
|
|
1031
1011
|
consoleLogger = {
|
|
1032
1012
|
info(msg, ctx) {
|
|
1033
|
-
if (ctx)
|
|
1034
|
-
|
|
1035
|
-
else
|
|
1036
|
-
console.log(msg);
|
|
1013
|
+
if (ctx) console.log(msg, ctx);
|
|
1014
|
+
else console.log(msg);
|
|
1037
1015
|
},
|
|
1038
1016
|
warn(msg, ctx) {
|
|
1039
|
-
if (ctx)
|
|
1040
|
-
|
|
1041
|
-
else
|
|
1042
|
-
console.warn(msg);
|
|
1017
|
+
if (ctx) console.warn(msg, ctx);
|
|
1018
|
+
else console.warn(msg);
|
|
1043
1019
|
},
|
|
1044
1020
|
error(msg, ctx) {
|
|
1045
|
-
if (ctx)
|
|
1046
|
-
|
|
1047
|
-
else
|
|
1048
|
-
console.error(msg);
|
|
1021
|
+
if (ctx) console.error(msg, ctx);
|
|
1022
|
+
else console.error(msg);
|
|
1049
1023
|
},
|
|
1050
1024
|
debug(msg, ctx) {
|
|
1051
|
-
if (ctx)
|
|
1052
|
-
|
|
1053
|
-
else
|
|
1054
|
-
console.debug(msg);
|
|
1025
|
+
if (ctx) console.debug(msg, ctx);
|
|
1026
|
+
else console.debug(msg);
|
|
1055
1027
|
}
|
|
1056
1028
|
};
|
|
1057
1029
|
noopMetrics = {
|
|
@@ -1069,7 +1041,7 @@ var init_runtime = __esm({
|
|
|
1069
1041
|
}
|
|
1070
1042
|
});
|
|
1071
1043
|
|
|
1072
|
-
//
|
|
1044
|
+
// sdk/_internal_types.ts
|
|
1073
1045
|
import { z as z2 } from "zod";
|
|
1074
1046
|
function agentToolsToSchemas(tools) {
|
|
1075
1047
|
return Object.entries(tools).map(([name, def]) => ({
|
|
@@ -1080,13 +1052,13 @@ function agentToolsToSchemas(tools) {
|
|
|
1080
1052
|
}
|
|
1081
1053
|
var EMPTY_PARAMS;
|
|
1082
1054
|
var init_internal_types = __esm({
|
|
1083
|
-
"
|
|
1055
|
+
"sdk/_internal_types.ts"() {
|
|
1084
1056
|
"use strict";
|
|
1085
1057
|
EMPTY_PARAMS = z2.object({});
|
|
1086
1058
|
}
|
|
1087
1059
|
});
|
|
1088
1060
|
|
|
1089
|
-
//
|
|
1061
|
+
// sdk/builtin_tools.ts
|
|
1090
1062
|
import { convert } from "html-to-text";
|
|
1091
1063
|
import { z as z3 } from "zod";
|
|
1092
1064
|
function htmlToText(html) {
|
|
@@ -1111,12 +1083,10 @@ function createWebSearch() {
|
|
|
1111
1083
|
headers: { "X-Subscription-Token": apiKey },
|
|
1112
1084
|
signal: ctx.abortSignal ?? AbortSignal.timeout(15e3)
|
|
1113
1085
|
});
|
|
1114
|
-
if (!resp.ok)
|
|
1115
|
-
return [];
|
|
1086
|
+
if (!resp.ok) return [];
|
|
1116
1087
|
const raw = await resp.json();
|
|
1117
1088
|
const data = BraveSearchResponseSchema.safeParse(raw);
|
|
1118
|
-
if (!data.success)
|
|
1119
|
-
return [];
|
|
1089
|
+
if (!data.success) return [];
|
|
1120
1090
|
return (data.data.web?.results ?? []).slice(0, maxResults).map((r) => ({
|
|
1121
1091
|
title: r.title,
|
|
1122
1092
|
url: r.url,
|
|
@@ -1200,7 +1170,9 @@ function createRunCode() {
|
|
|
1200
1170
|
const fn = new AsyncFunction("console", code);
|
|
1201
1171
|
await Promise.race([
|
|
1202
1172
|
fn(fakeConsole),
|
|
1203
|
-
new Promise(
|
|
1173
|
+
new Promise(
|
|
1174
|
+
(_, reject) => setTimeout(() => reject(new Error("Code execution timed out")), RUN_CODE_TIMEOUT)
|
|
1175
|
+
)
|
|
1204
1176
|
]);
|
|
1205
1177
|
const result = output.join("\n").trim();
|
|
1206
1178
|
return result || "Code ran successfully (no output)";
|
|
@@ -1248,8 +1220,7 @@ function getBuiltinToolDefs(names, opts) {
|
|
|
1248
1220
|
function getBuiltinToolSchemas(names) {
|
|
1249
1221
|
return names.flatMap((name) => {
|
|
1250
1222
|
const creator = TOOL_CREATORS[name];
|
|
1251
|
-
if (!creator)
|
|
1252
|
-
return [];
|
|
1223
|
+
if (!creator) return [];
|
|
1253
1224
|
const def = creator();
|
|
1254
1225
|
return [
|
|
1255
1226
|
{
|
|
@@ -1262,7 +1233,7 @@ function getBuiltinToolSchemas(names) {
|
|
|
1262
1233
|
}
|
|
1263
1234
|
var webSearchParams, BRAVE_SEARCH_URL, BraveSearchResponseSchema, MAX_PAGE_CHARS, MAX_HTML_BYTES, visitWebpageParams, fetchJsonParams, runCodeParams, vectorSearchParams, TOOL_CREATORS;
|
|
1264
1235
|
var init_builtin_tools = __esm({
|
|
1265
|
-
"
|
|
1236
|
+
"sdk/builtin_tools.ts"() {
|
|
1266
1237
|
"use strict";
|
|
1267
1238
|
init_internal_types();
|
|
1268
1239
|
webSearchParams = z3.object({
|
|
@@ -1272,11 +1243,13 @@ var init_builtin_tools = __esm({
|
|
|
1272
1243
|
BRAVE_SEARCH_URL = "https://api.search.brave.com/res/v1/web/search";
|
|
1273
1244
|
BraveSearchResponseSchema = z3.object({
|
|
1274
1245
|
web: z3.object({
|
|
1275
|
-
results: z3.array(
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1246
|
+
results: z3.array(
|
|
1247
|
+
z3.object({
|
|
1248
|
+
title: z3.string(),
|
|
1249
|
+
url: z3.string(),
|
|
1250
|
+
description: z3.string()
|
|
1251
|
+
})
|
|
1252
|
+
)
|
|
1280
1253
|
}).optional()
|
|
1281
1254
|
});
|
|
1282
1255
|
MAX_PAGE_CHARS = 1e4;
|
|
@@ -1292,7 +1265,9 @@ var init_builtin_tools = __esm({
|
|
|
1292
1265
|
code: z3.string().describe("JavaScript code to execute. Use console.log() for output.")
|
|
1293
1266
|
});
|
|
1294
1267
|
vectorSearchParams = z3.object({
|
|
1295
|
-
query: z3.string().describe(
|
|
1268
|
+
query: z3.string().describe(
|
|
1269
|
+
'Short keyword query to search the knowledge base. Use specific topic terms, not full sentences. Do NOT include the company or product name since all documents are from the same source. For example, if the user asks "how much does Acme cost", search for "pricing plans rates".'
|
|
1270
|
+
),
|
|
1296
1271
|
topK: z3.number().describe("Maximum results to return (default: 5)").optional()
|
|
1297
1272
|
});
|
|
1298
1273
|
TOOL_CREATORS = {
|
|
@@ -1306,11 +1281,10 @@ var init_builtin_tools = __esm({
|
|
|
1306
1281
|
}
|
|
1307
1282
|
});
|
|
1308
1283
|
|
|
1309
|
-
//
|
|
1284
|
+
// sdk/kv.ts
|
|
1310
1285
|
function sortAndPaginate(entries, options) {
|
|
1311
1286
|
entries.sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
|
|
1312
|
-
if (options?.reverse)
|
|
1313
|
-
entries.reverse();
|
|
1287
|
+
if (options?.reverse) entries.reverse();
|
|
1314
1288
|
if (options?.limit && options.limit > 0) {
|
|
1315
1289
|
entries.length = Math.min(entries.length, options.limit);
|
|
1316
1290
|
}
|
|
@@ -1325,8 +1299,7 @@ function createMemoryKv() {
|
|
|
1325
1299
|
get(key) {
|
|
1326
1300
|
const entry = store.get(key);
|
|
1327
1301
|
if (!entry || isExpired(entry)) {
|
|
1328
|
-
if (entry)
|
|
1329
|
-
store.delete(key);
|
|
1302
|
+
if (entry) store.delete(key);
|
|
1330
1303
|
return Promise.resolve(null);
|
|
1331
1304
|
}
|
|
1332
1305
|
return Promise.resolve(JSON.parse(entry.raw));
|
|
@@ -1353,8 +1326,7 @@ function createMemoryKv() {
|
|
|
1353
1326
|
const entries = [];
|
|
1354
1327
|
let i = 0;
|
|
1355
1328
|
for (const [key, entry] of store) {
|
|
1356
|
-
if (++i % 500 === 0)
|
|
1357
|
-
await new Promise((r) => setTimeout(r, 0));
|
|
1329
|
+
if (++i % 500 === 0) await new Promise((r) => setTimeout(r, 0));
|
|
1358
1330
|
if (entry.expiresAt && entry.expiresAt <= now) {
|
|
1359
1331
|
store.delete(key);
|
|
1360
1332
|
continue;
|
|
@@ -1369,13 +1341,13 @@ function createMemoryKv() {
|
|
|
1369
1341
|
}
|
|
1370
1342
|
var MAX_VALUE_SIZE;
|
|
1371
1343
|
var init_kv = __esm({
|
|
1372
|
-
"
|
|
1344
|
+
"sdk/kv.ts"() {
|
|
1373
1345
|
"use strict";
|
|
1374
1346
|
MAX_VALUE_SIZE = 65536;
|
|
1375
1347
|
}
|
|
1376
1348
|
});
|
|
1377
1349
|
|
|
1378
|
-
//
|
|
1350
|
+
// sdk/s2s.ts
|
|
1379
1351
|
import { z as z4 } from "zod";
|
|
1380
1352
|
function uint8ToBase64(bytes) {
|
|
1381
1353
|
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
|
|
@@ -1387,9 +1359,11 @@ function base64ToUint8(base64) {
|
|
|
1387
1359
|
function dispatchS2sMessage(target, msg) {
|
|
1388
1360
|
switch (msg.type) {
|
|
1389
1361
|
case "session.ready":
|
|
1390
|
-
target.dispatchEvent(
|
|
1391
|
-
|
|
1392
|
-
|
|
1362
|
+
target.dispatchEvent(
|
|
1363
|
+
new CustomEvent("ready", {
|
|
1364
|
+
detail: { session_id: msg.session_id }
|
|
1365
|
+
})
|
|
1366
|
+
);
|
|
1393
1367
|
break;
|
|
1394
1368
|
case "session.updated":
|
|
1395
1369
|
target.dispatchEvent(new CustomEvent("session_updated", { detail: msg }));
|
|
@@ -1401,54 +1375,80 @@ function dispatchS2sMessage(target, msg) {
|
|
|
1401
1375
|
target.dispatchEvent(new CustomEvent("speech_stopped"));
|
|
1402
1376
|
break;
|
|
1403
1377
|
case "transcript.user.delta":
|
|
1404
|
-
target.dispatchEvent(
|
|
1405
|
-
|
|
1406
|
-
|
|
1378
|
+
target.dispatchEvent(
|
|
1379
|
+
new CustomEvent("user_transcript_delta", {
|
|
1380
|
+
detail: { text: msg.text }
|
|
1381
|
+
})
|
|
1382
|
+
);
|
|
1407
1383
|
break;
|
|
1408
1384
|
case "transcript.user":
|
|
1409
|
-
target.dispatchEvent(
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1385
|
+
target.dispatchEvent(
|
|
1386
|
+
new CustomEvent("user_transcript", {
|
|
1387
|
+
detail: {
|
|
1388
|
+
item_id: msg.item_id,
|
|
1389
|
+
text: msg.text
|
|
1390
|
+
}
|
|
1391
|
+
})
|
|
1392
|
+
);
|
|
1415
1393
|
break;
|
|
1416
1394
|
case "reply.started":
|
|
1417
|
-
target.dispatchEvent(
|
|
1418
|
-
|
|
1419
|
-
|
|
1395
|
+
target.dispatchEvent(
|
|
1396
|
+
new CustomEvent("reply_started", {
|
|
1397
|
+
detail: { reply_id: msg.reply_id }
|
|
1398
|
+
})
|
|
1399
|
+
);
|
|
1420
1400
|
break;
|
|
1421
1401
|
// reply.audio handled on the fast path — never reaches dispatch.
|
|
1402
|
+
case "transcript.agent.delta":
|
|
1403
|
+
target.dispatchEvent(
|
|
1404
|
+
new CustomEvent("agent_transcript_delta", {
|
|
1405
|
+
detail: { text: msg.delta }
|
|
1406
|
+
})
|
|
1407
|
+
);
|
|
1408
|
+
break;
|
|
1422
1409
|
case "transcript.agent":
|
|
1423
|
-
target.dispatchEvent(
|
|
1424
|
-
|
|
1425
|
-
|
|
1410
|
+
target.dispatchEvent(
|
|
1411
|
+
new CustomEvent("agent_transcript", {
|
|
1412
|
+
detail: { text: msg.text }
|
|
1413
|
+
})
|
|
1414
|
+
);
|
|
1426
1415
|
break;
|
|
1427
1416
|
case "tool.call":
|
|
1428
|
-
target.dispatchEvent(
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1417
|
+
target.dispatchEvent(
|
|
1418
|
+
new CustomEvent("tool_call", {
|
|
1419
|
+
detail: {
|
|
1420
|
+
call_id: msg.call_id,
|
|
1421
|
+
name: msg.name,
|
|
1422
|
+
args: msg.args
|
|
1423
|
+
}
|
|
1424
|
+
})
|
|
1425
|
+
);
|
|
1435
1426
|
break;
|
|
1436
1427
|
case "reply.done":
|
|
1437
|
-
target.dispatchEvent(
|
|
1438
|
-
|
|
1439
|
-
|
|
1428
|
+
target.dispatchEvent(
|
|
1429
|
+
new CustomEvent("reply_done", {
|
|
1430
|
+
detail: { status: msg.status }
|
|
1431
|
+
})
|
|
1432
|
+
);
|
|
1440
1433
|
break;
|
|
1441
1434
|
case "session.error": {
|
|
1442
1435
|
const isExpired = msg.code === "session_not_found" || msg.code === "session_forbidden";
|
|
1443
|
-
target.dispatchEvent(
|
|
1444
|
-
|
|
1445
|
-
|
|
1436
|
+
target.dispatchEvent(
|
|
1437
|
+
new CustomEvent(isExpired ? "session_expired" : "error", {
|
|
1438
|
+
detail: { code: msg.code, message: msg.message }
|
|
1439
|
+
})
|
|
1440
|
+
);
|
|
1446
1441
|
break;
|
|
1447
1442
|
}
|
|
1443
|
+
case "reply.content_part.started":
|
|
1444
|
+
case "reply.content_part.done":
|
|
1445
|
+
break;
|
|
1448
1446
|
case "error":
|
|
1449
|
-
target.dispatchEvent(
|
|
1450
|
-
|
|
1451
|
-
|
|
1447
|
+
target.dispatchEvent(
|
|
1448
|
+
new CustomEvent("error", {
|
|
1449
|
+
detail: { code: "connection", message: msg.message }
|
|
1450
|
+
})
|
|
1451
|
+
);
|
|
1452
1452
|
break;
|
|
1453
1453
|
}
|
|
1454
1454
|
}
|
|
@@ -1462,20 +1462,24 @@ function connectS2s(opts) {
|
|
|
1462
1462
|
const target = new EventTarget();
|
|
1463
1463
|
let opened = false;
|
|
1464
1464
|
function send(msg) {
|
|
1465
|
-
if (ws.readyState !== WS_OPEN)
|
|
1466
|
-
return;
|
|
1465
|
+
if (ws.readyState !== WS_OPEN) return;
|
|
1467
1466
|
const json = JSON.stringify(msg);
|
|
1468
1467
|
if (msg.type !== "input.audio") {
|
|
1469
|
-
log.debug(
|
|
1468
|
+
log.debug(
|
|
1469
|
+
`S2S >> ${msg.type}`,
|
|
1470
|
+
msg.type === "session.update" ? { payload: json } : void 0
|
|
1471
|
+
);
|
|
1470
1472
|
}
|
|
1471
1473
|
ws.send(json);
|
|
1472
1474
|
}
|
|
1473
1475
|
const handle = Object.assign(target, {
|
|
1474
1476
|
sendAudio(audio) {
|
|
1475
|
-
if (ws.readyState !== WS_OPEN)
|
|
1476
|
-
return;
|
|
1477
|
+
if (ws.readyState !== WS_OPEN) return;
|
|
1477
1478
|
if (ws.sendBinary) {
|
|
1478
|
-
const ab = audio.buffer.slice(
|
|
1479
|
+
const ab = audio.buffer.slice(
|
|
1480
|
+
audio.byteOffset,
|
|
1481
|
+
audio.byteOffset + audio.byteLength
|
|
1482
|
+
);
|
|
1479
1483
|
ws.sendBinary(ab);
|
|
1480
1484
|
} else {
|
|
1481
1485
|
ws.send(`{"type":"input.audio","audio":"${uint8ToBase64(audio)}"}`);
|
|
@@ -1519,7 +1523,9 @@ function connectS2s(opts) {
|
|
|
1519
1523
|
}
|
|
1520
1524
|
const parsed = S2sServerMessageSchema.safeParse(raw);
|
|
1521
1525
|
if (!parsed.success) {
|
|
1522
|
-
log.debug(
|
|
1526
|
+
log.debug(
|
|
1527
|
+
`S2S << unrecognised message type: ${obj.type ?? JSON.stringify(raw).slice(0, 100)}`
|
|
1528
|
+
);
|
|
1523
1529
|
return;
|
|
1524
1530
|
}
|
|
1525
1531
|
const msg = parsed.data;
|
|
@@ -1539,16 +1545,18 @@ function connectS2s(opts) {
|
|
|
1539
1545
|
if (!opened) {
|
|
1540
1546
|
reject(errObj);
|
|
1541
1547
|
} else {
|
|
1542
|
-
target.dispatchEvent(
|
|
1543
|
-
|
|
1544
|
-
|
|
1548
|
+
target.dispatchEvent(
|
|
1549
|
+
new CustomEvent("error", {
|
|
1550
|
+
detail: { code: "ws_error", message: errObj.message }
|
|
1551
|
+
})
|
|
1552
|
+
);
|
|
1545
1553
|
}
|
|
1546
1554
|
});
|
|
1547
1555
|
});
|
|
1548
1556
|
}
|
|
1549
1557
|
var WS_OPEN, S2sServerMessageSchema;
|
|
1550
1558
|
var init_s2s = __esm({
|
|
1551
|
-
"
|
|
1559
|
+
"sdk/s2s.ts"() {
|
|
1552
1560
|
"use strict";
|
|
1553
1561
|
init_runtime();
|
|
1554
1562
|
WS_OPEN = 1;
|
|
@@ -1565,7 +1573,10 @@ var init_s2s = __esm({
|
|
|
1565
1573
|
}),
|
|
1566
1574
|
z4.object({ type: z4.literal("reply.started"), reply_id: z4.string() }),
|
|
1567
1575
|
// reply.audio is handled on the fast path before Zod — see message handler.
|
|
1576
|
+
z4.object({ type: z4.literal("transcript.agent.delta"), delta: z4.string() }).passthrough(),
|
|
1568
1577
|
z4.object({ type: z4.literal("transcript.agent"), text: z4.string() }),
|
|
1578
|
+
z4.object({ type: z4.literal("reply.content_part.started") }).passthrough(),
|
|
1579
|
+
z4.object({ type: z4.literal("reply.content_part.done") }).passthrough(),
|
|
1569
1580
|
z4.object({
|
|
1570
1581
|
type: z4.literal("tool.call"),
|
|
1571
1582
|
call_id: z4.string(),
|
|
@@ -1590,10 +1601,10 @@ var init_s2s = __esm({
|
|
|
1590
1601
|
}
|
|
1591
1602
|
});
|
|
1592
1603
|
|
|
1593
|
-
//
|
|
1604
|
+
// sdk/types.ts
|
|
1594
1605
|
var DEFAULT_INSTRUCTIONS;
|
|
1595
1606
|
var init_types = __esm({
|
|
1596
|
-
"
|
|
1607
|
+
"sdk/types.ts"() {
|
|
1597
1608
|
"use strict";
|
|
1598
1609
|
DEFAULT_INSTRUCTIONS = `You are AAI, a helpful AI assistant.
|
|
1599
1610
|
|
|
@@ -1609,7 +1620,7 @@ Voice-First Rules:
|
|
|
1609
1620
|
}
|
|
1610
1621
|
});
|
|
1611
1622
|
|
|
1612
|
-
//
|
|
1623
|
+
// sdk/system_prompt.ts
|
|
1613
1624
|
function buildSystemPrompt(config, opts) {
|
|
1614
1625
|
const { hasTools } = opts;
|
|
1615
1626
|
const agentInstructions = config.instructions && config.instructions !== DEFAULT_INSTRUCTIONS ? `
|
|
@@ -1629,16 +1640,28 @@ Today's date is ${today}.` + agentInstructions + toolPreamble + (opts?.voice ? V
|
|
|
1629
1640
|
}
|
|
1630
1641
|
var VOICE_RULES;
|
|
1631
1642
|
var init_system_prompt = __esm({
|
|
1632
|
-
"
|
|
1643
|
+
"sdk/system_prompt.ts"() {
|
|
1633
1644
|
"use strict";
|
|
1634
1645
|
init_types();
|
|
1635
1646
|
VOICE_RULES = '\n\nCRITICAL OUTPUT RULES \u2014 you MUST follow these for EVERY response:\nYour response will be spoken aloud by a TTS system and displayed as plain text.\n- NEVER use markdown: no **, no *, no _, no #, no `, no [](), no ---\n- NEVER use bullet points (-, *, \u2022) or numbered lists (1., 2.)\n- NEVER use code blocks or inline code\n- NEVER mention tools, search, APIs, or technical failures to the user. If a tool returns no results, just answer naturally without explaining why.\n- Write exactly as you would say it out loud to a friend\n- Use short conversational sentences. To list things, say "First," "Next," "Finally,"\n- Keep responses concise \u2014 1 to 3 sentences max';
|
|
1636
1647
|
}
|
|
1637
1648
|
});
|
|
1638
1649
|
|
|
1639
|
-
//
|
|
1650
|
+
// sdk/session.ts
|
|
1640
1651
|
function createS2sSession(opts) {
|
|
1641
|
-
const {
|
|
1652
|
+
const {
|
|
1653
|
+
id,
|
|
1654
|
+
agent,
|
|
1655
|
+
client,
|
|
1656
|
+
toolSchemas,
|
|
1657
|
+
apiKey,
|
|
1658
|
+
s2sConfig,
|
|
1659
|
+
executeTool,
|
|
1660
|
+
createWebSocket,
|
|
1661
|
+
hookInvoker,
|
|
1662
|
+
logger: log = consoleLogger,
|
|
1663
|
+
metrics = noopMetrics
|
|
1664
|
+
} = opts;
|
|
1642
1665
|
const agentLabel = { agent };
|
|
1643
1666
|
const agentConfig = opts.skipGreeting ? { ...opts.agentConfig, greeting: "" } : opts.agentConfig;
|
|
1644
1667
|
const hasTools = toolSchemas.length > 0 || (agentConfig.builtinTools?.length ?? 0) > 0;
|
|
@@ -1663,8 +1686,7 @@ function createS2sSession(opts) {
|
|
|
1663
1686
|
let pendingReconnect = false;
|
|
1664
1687
|
let pendingTools = [];
|
|
1665
1688
|
async function resolveTurnConfig() {
|
|
1666
|
-
if (!hookInvoker)
|
|
1667
|
-
return null;
|
|
1689
|
+
if (!hookInvoker) return null;
|
|
1668
1690
|
try {
|
|
1669
1691
|
return await hookInvoker.resolveTurnConfig(id, HOOK_TIMEOUT_MS);
|
|
1670
1692
|
} catch {
|
|
@@ -1672,8 +1694,7 @@ function createS2sSession(opts) {
|
|
|
1672
1694
|
}
|
|
1673
1695
|
}
|
|
1674
1696
|
function invokeHook(hook, arg) {
|
|
1675
|
-
if (!hookInvoker)
|
|
1676
|
-
return;
|
|
1697
|
+
if (!hookInvoker) return;
|
|
1677
1698
|
const run = async () => {
|
|
1678
1699
|
switch (hook) {
|
|
1679
1700
|
case "onConnect":
|
|
@@ -1887,12 +1908,10 @@ function createS2sSession(opts) {
|
|
|
1887
1908
|
await connectAndSetup();
|
|
1888
1909
|
},
|
|
1889
1910
|
async stop() {
|
|
1890
|
-
if (sessionAbort.signal.aborted)
|
|
1891
|
-
return;
|
|
1911
|
+
if (sessionAbort.signal.aborted) return;
|
|
1892
1912
|
sessionAbort.abort();
|
|
1893
1913
|
metrics.sessionsActive.dec(agentLabel);
|
|
1894
|
-
if (turnPromise)
|
|
1895
|
-
await turnPromise;
|
|
1914
|
+
if (turnPromise) await turnPromise;
|
|
1896
1915
|
s2s?.close();
|
|
1897
1916
|
invokeHook("onDisconnect");
|
|
1898
1917
|
},
|
|
@@ -1900,8 +1919,7 @@ function createS2sSession(opts) {
|
|
|
1900
1919
|
s2s?.sendAudio(data);
|
|
1901
1920
|
},
|
|
1902
1921
|
onAudioReady() {
|
|
1903
|
-
if (audioReady)
|
|
1904
|
-
return;
|
|
1922
|
+
if (audioReady) return;
|
|
1905
1923
|
audioReady = true;
|
|
1906
1924
|
},
|
|
1907
1925
|
onCancel() {
|
|
@@ -1928,7 +1946,7 @@ function createS2sSession(opts) {
|
|
|
1928
1946
|
}
|
|
1929
1947
|
var _internals2;
|
|
1930
1948
|
var init_session = __esm({
|
|
1931
|
-
"
|
|
1949
|
+
"sdk/session.ts"() {
|
|
1932
1950
|
"use strict";
|
|
1933
1951
|
init_protocol();
|
|
1934
1952
|
init_runtime();
|
|
@@ -1940,7 +1958,7 @@ var init_session = __esm({
|
|
|
1940
1958
|
}
|
|
1941
1959
|
});
|
|
1942
1960
|
|
|
1943
|
-
//
|
|
1961
|
+
// sdk/vector.ts
|
|
1944
1962
|
function createMemoryVectorStore() {
|
|
1945
1963
|
const store = /* @__PURE__ */ new Map();
|
|
1946
1964
|
return {
|
|
@@ -1955,8 +1973,7 @@ function createMemoryVectorStore() {
|
|
|
1955
1973
|
const results = [];
|
|
1956
1974
|
let i = 0;
|
|
1957
1975
|
for (const [id, entry] of store) {
|
|
1958
|
-
if (++i % 500 === 0)
|
|
1959
|
-
await new Promise((r) => setTimeout(r, 0));
|
|
1976
|
+
if (++i % 500 === 0) await new Promise((r) => setTimeout(r, 0));
|
|
1960
1977
|
const data = entry.data.toLowerCase();
|
|
1961
1978
|
const matches = words.filter((w) => data.includes(w)).length;
|
|
1962
1979
|
if (matches > 0) {
|
|
@@ -1981,12 +1998,12 @@ function createMemoryVectorStore() {
|
|
|
1981
1998
|
};
|
|
1982
1999
|
}
|
|
1983
2000
|
var init_vector = __esm({
|
|
1984
|
-
"
|
|
2001
|
+
"sdk/vector.ts"() {
|
|
1985
2002
|
"use strict";
|
|
1986
2003
|
}
|
|
1987
2004
|
});
|
|
1988
2005
|
|
|
1989
|
-
//
|
|
2006
|
+
// sdk/worker_entry.ts
|
|
1990
2007
|
function buildToolContext(opts) {
|
|
1991
2008
|
const { env, sessionId, state, kv, vector, messages } = opts;
|
|
1992
2009
|
return {
|
|
@@ -1995,13 +2012,11 @@ function buildToolContext(opts) {
|
|
|
1995
2012
|
abortSignal: AbortSignal.timeout(TOOL_HANDLER_TIMEOUT),
|
|
1996
2013
|
state: state ?? {},
|
|
1997
2014
|
get kv() {
|
|
1998
|
-
if (!kv)
|
|
1999
|
-
throw new Error("KV not available");
|
|
2015
|
+
if (!kv) throw new Error("KV not available");
|
|
2000
2016
|
return kv;
|
|
2001
2017
|
},
|
|
2002
2018
|
get vector() {
|
|
2003
|
-
if (!vector)
|
|
2004
|
-
throw new Error("Vector store not available");
|
|
2019
|
+
if (!vector) throw new Error("Vector store not available");
|
|
2005
2020
|
return vector;
|
|
2006
2021
|
},
|
|
2007
2022
|
messages: messages ?? []
|
|
@@ -2020,8 +2035,7 @@ async function executeToolCall(name, args, options) {
|
|
|
2020
2035
|
await yieldTick();
|
|
2021
2036
|
const result = await Promise.resolve(tool.execute(parsed.data, ctx));
|
|
2022
2037
|
await yieldTick();
|
|
2023
|
-
if (result == null)
|
|
2024
|
-
return "null";
|
|
2038
|
+
if (result == null) return "null";
|
|
2025
2039
|
return typeof result === "string" ? result : JSON.stringify(result);
|
|
2026
2040
|
} catch (err) {
|
|
2027
2041
|
if (err instanceof DOMException && err.name === "TimeoutError") {
|
|
@@ -2034,7 +2048,7 @@ async function executeToolCall(name, args, options) {
|
|
|
2034
2048
|
}
|
|
2035
2049
|
var yieldTick, TOOL_HANDLER_TIMEOUT;
|
|
2036
2050
|
var init_worker_entry = __esm({
|
|
2037
|
-
"
|
|
2051
|
+
"sdk/worker_entry.ts"() {
|
|
2038
2052
|
"use strict";
|
|
2039
2053
|
init_internal_types();
|
|
2040
2054
|
yieldTick = () => new Promise((r) => setTimeout(r, 0));
|
|
@@ -2042,7 +2056,7 @@ var init_worker_entry = __esm({
|
|
|
2042
2056
|
}
|
|
2043
2057
|
});
|
|
2044
2058
|
|
|
2045
|
-
//
|
|
2059
|
+
// sdk/direct_executor.ts
|
|
2046
2060
|
function buildAgentConfig(agent) {
|
|
2047
2061
|
const config = {
|
|
2048
2062
|
name: agent.name,
|
|
@@ -2050,22 +2064,30 @@ function buildAgentConfig(agent) {
|
|
|
2050
2064
|
greeting: agent.greeting,
|
|
2051
2065
|
voice: agent.voice
|
|
2052
2066
|
};
|
|
2053
|
-
if (agent.sttPrompt !== void 0)
|
|
2054
|
-
|
|
2055
|
-
if (
|
|
2056
|
-
|
|
2057
|
-
if (agent.
|
|
2058
|
-
config.toolChoice = agent.toolChoice;
|
|
2059
|
-
if (agent.builtinTools)
|
|
2060
|
-
config.builtinTools = [...agent.builtinTools];
|
|
2061
|
-
if (agent.activeTools)
|
|
2062
|
-
config.activeTools = [...agent.activeTools];
|
|
2067
|
+
if (agent.sttPrompt !== void 0) config.sttPrompt = agent.sttPrompt;
|
|
2068
|
+
if (typeof agent.maxSteps !== "function") config.maxSteps = agent.maxSteps;
|
|
2069
|
+
if (agent.toolChoice !== void 0) config.toolChoice = agent.toolChoice;
|
|
2070
|
+
if (agent.builtinTools) config.builtinTools = [...agent.builtinTools];
|
|
2071
|
+
if (agent.activeTools) config.activeTools = [...agent.activeTools];
|
|
2063
2072
|
return config;
|
|
2064
2073
|
}
|
|
2065
2074
|
function createDirectExecutor(opts) {
|
|
2066
|
-
const {
|
|
2075
|
+
const {
|
|
2076
|
+
agent,
|
|
2077
|
+
env,
|
|
2078
|
+
kv = createMemoryKv(),
|
|
2079
|
+
vector = createMemoryVectorStore(),
|
|
2080
|
+
vectorSearch,
|
|
2081
|
+
createWebSocket,
|
|
2082
|
+
logger = consoleLogger,
|
|
2083
|
+
metrics = noopMetrics,
|
|
2084
|
+
s2sConfig = DEFAULT_S2S_CONFIG
|
|
2085
|
+
} = opts;
|
|
2067
2086
|
const agentConfig = buildAgentConfig(agent);
|
|
2068
|
-
const builtinDefs = getBuiltinToolDefs(
|
|
2087
|
+
const builtinDefs = getBuiltinToolDefs(
|
|
2088
|
+
agent.builtinTools ?? [],
|
|
2089
|
+
vectorSearch ? { vectorSearch } : void 0
|
|
2090
|
+
);
|
|
2069
2091
|
const allTools = {
|
|
2070
2092
|
...builtinDefs,
|
|
2071
2093
|
...agent.tools
|
|
@@ -2096,8 +2118,7 @@ function createDirectExecutor(opts) {
|
|
|
2096
2118
|
}
|
|
2097
2119
|
const executeTool = async (name, args, sessionId, messages) => {
|
|
2098
2120
|
const tool = allTools[name];
|
|
2099
|
-
if (!tool)
|
|
2100
|
-
return JSON.stringify({ error: `Unknown tool: ${name}` });
|
|
2121
|
+
if (!tool) return JSON.stringify({ error: `Unknown tool: ${name}` });
|
|
2101
2122
|
return executeToolCall(name, args, {
|
|
2102
2123
|
tool,
|
|
2103
2124
|
env: frozenEnv,
|
|
@@ -2119,11 +2140,11 @@ function createDirectExecutor(opts) {
|
|
|
2119
2140
|
async onTurn(sessionId, text) {
|
|
2120
2141
|
await agent.onTurn?.(text, makeHookContext(sessionId));
|
|
2121
2142
|
},
|
|
2122
|
-
async onError(sessionId,
|
|
2123
|
-
await agent.onError?.(new Error(
|
|
2143
|
+
async onError(sessionId, error) {
|
|
2144
|
+
await agent.onError?.(new Error(error.message), makeHookContext(sessionId));
|
|
2124
2145
|
},
|
|
2125
|
-
async onStep(sessionId,
|
|
2126
|
-
await agent.onStep?.(
|
|
2146
|
+
async onStep(sessionId, step) {
|
|
2147
|
+
await agent.onStep?.(step, makeHookContext(sessionId));
|
|
2127
2148
|
},
|
|
2128
2149
|
async resolveTurnConfig(sessionId) {
|
|
2129
2150
|
const ctx = makeHookContext(sessionId);
|
|
@@ -2136,13 +2157,10 @@ function createDirectExecutor(opts) {
|
|
|
2136
2157
|
const result = await agent.onBeforeStep(0, ctx);
|
|
2137
2158
|
activeTools = result?.activeTools;
|
|
2138
2159
|
}
|
|
2139
|
-
if (maxSteps === void 0 && activeTools === void 0)
|
|
2140
|
-
return null;
|
|
2160
|
+
if (maxSteps === void 0 && activeTools === void 0) return null;
|
|
2141
2161
|
const config = {};
|
|
2142
|
-
if (maxSteps !== void 0)
|
|
2143
|
-
|
|
2144
|
-
if (activeTools !== void 0)
|
|
2145
|
-
config.activeTools = activeTools;
|
|
2162
|
+
if (maxSteps !== void 0) config.maxSteps = maxSteps;
|
|
2163
|
+
if (activeTools !== void 0) config.activeTools = activeTools;
|
|
2146
2164
|
return config;
|
|
2147
2165
|
}
|
|
2148
2166
|
};
|
|
@@ -2170,7 +2188,7 @@ function createDirectExecutor(opts) {
|
|
|
2170
2188
|
return { executeTool, hookInvoker, toolSchemas, createSession };
|
|
2171
2189
|
}
|
|
2172
2190
|
var init_direct_executor = __esm({
|
|
2173
|
-
"
|
|
2191
|
+
"sdk/direct_executor.ts"() {
|
|
2174
2192
|
"use strict";
|
|
2175
2193
|
init_internal_types();
|
|
2176
2194
|
init_builtin_tools();
|
|
@@ -2182,15 +2200,14 @@ var init_direct_executor = __esm({
|
|
|
2182
2200
|
}
|
|
2183
2201
|
});
|
|
2184
2202
|
|
|
2185
|
-
//
|
|
2203
|
+
// sdk/ws_handler.ts
|
|
2186
2204
|
function isValidAudioChunk(data) {
|
|
2187
2205
|
return data.byteLength > 0 && data.byteLength <= MAX_AUDIO_CHUNK_BYTES && data.byteLength % 2 === 0;
|
|
2188
2206
|
}
|
|
2189
2207
|
function createClientSink(ws) {
|
|
2190
2208
|
function safeSend(data) {
|
|
2191
2209
|
try {
|
|
2192
|
-
if (ws.readyState === 1)
|
|
2193
|
-
ws.send(data);
|
|
2210
|
+
if (ws.readyState === 1) ws.send(data);
|
|
2194
2211
|
} catch {
|
|
2195
2212
|
}
|
|
2196
2213
|
}
|
|
@@ -2213,16 +2230,13 @@ function isBinaryData(data) {
|
|
|
2213
2230
|
return globalThis.Buffer?.isBuffer(data) || data instanceof ArrayBuffer || data instanceof Uint8Array;
|
|
2214
2231
|
}
|
|
2215
2232
|
function toUint8Array(data) {
|
|
2216
|
-
if (data instanceof Uint8Array)
|
|
2217
|
-
|
|
2218
|
-
if (data instanceof ArrayBuffer)
|
|
2219
|
-
return new Uint8Array(data);
|
|
2233
|
+
if (data instanceof Uint8Array) return data;
|
|
2234
|
+
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
2220
2235
|
const buf = data;
|
|
2221
2236
|
return new Uint8Array(buf.buffer ?? data, buf.byteOffset ?? 0, buf.byteLength);
|
|
2222
2237
|
}
|
|
2223
2238
|
function handleBinaryAudio(data, session, log, ctx, sid) {
|
|
2224
|
-
if (!isBinaryData(data))
|
|
2225
|
-
return false;
|
|
2239
|
+
if (!isBinaryData(data)) return false;
|
|
2226
2240
|
const chunk = toUint8Array(data);
|
|
2227
2241
|
if (!isValidAudioChunk(chunk)) {
|
|
2228
2242
|
log.warn("Invalid audio chunk, dropping", {
|
|
@@ -2237,8 +2251,7 @@ function handleBinaryAudio(data, session, log, ctx, sid) {
|
|
|
2237
2251
|
return true;
|
|
2238
2252
|
}
|
|
2239
2253
|
function handleTextMessage(data, session, log, ctx, sid) {
|
|
2240
|
-
if (typeof data !== "string")
|
|
2241
|
-
return;
|
|
2254
|
+
if (typeof data !== "string") return;
|
|
2242
2255
|
let json;
|
|
2243
2256
|
try {
|
|
2244
2257
|
json = JSON.parse(data);
|
|
@@ -2289,11 +2302,9 @@ function wireSessionSocket(ws, opts) {
|
|
|
2289
2302
|
ws.addEventListener("open", onOpen);
|
|
2290
2303
|
}
|
|
2291
2304
|
ws.addEventListener("message", (event) => {
|
|
2292
|
-
if (!session)
|
|
2293
|
-
return;
|
|
2305
|
+
if (!session) return;
|
|
2294
2306
|
const { data } = event;
|
|
2295
|
-
if (handleBinaryAudio(data, session, log, ctx, sid))
|
|
2296
|
-
return;
|
|
2307
|
+
if (handleBinaryAudio(data, session, log, ctx, sid)) return;
|
|
2297
2308
|
handleTextMessage(data, session, log, ctx, sid);
|
|
2298
2309
|
});
|
|
2299
2310
|
ws.addEventListener("close", () => {
|
|
@@ -2312,7 +2323,7 @@ function wireSessionSocket(ws, opts) {
|
|
|
2312
2323
|
}
|
|
2313
2324
|
var MAX_AUDIO_CHUNK_BYTES;
|
|
2314
2325
|
var init_ws_handler = __esm({
|
|
2315
|
-
"
|
|
2326
|
+
"sdk/ws_handler.ts"() {
|
|
2316
2327
|
"use strict";
|
|
2317
2328
|
init_protocol();
|
|
2318
2329
|
init_runtime();
|
|
@@ -2320,9 +2331,19 @@ var init_ws_handler = __esm({
|
|
|
2320
2331
|
}
|
|
2321
2332
|
});
|
|
2322
2333
|
|
|
2323
|
-
//
|
|
2334
|
+
// sdk/winterc_server.ts
|
|
2324
2335
|
function createWintercServer(options) {
|
|
2325
|
-
const {
|
|
2336
|
+
const {
|
|
2337
|
+
agent,
|
|
2338
|
+
env,
|
|
2339
|
+
kv = createMemoryKv(),
|
|
2340
|
+
vector = createMemoryVectorStore(),
|
|
2341
|
+
vectorSearch,
|
|
2342
|
+
clientHtml,
|
|
2343
|
+
logger = consoleLogger,
|
|
2344
|
+
metrics = noopMetrics,
|
|
2345
|
+
s2sConfig = DEFAULT_S2S_CONFIG
|
|
2346
|
+
} = options;
|
|
2326
2347
|
const executor = createDirectExecutor({
|
|
2327
2348
|
agent,
|
|
2328
2349
|
env,
|
|
@@ -2354,7 +2375,10 @@ function createWintercServer(options) {
|
|
|
2354
2375
|
});
|
|
2355
2376
|
}
|
|
2356
2377
|
if (url.pathname === "/") {
|
|
2357
|
-
return new Response(
|
|
2378
|
+
return new Response(
|
|
2379
|
+
`<!DOCTYPE html><html><body><h1>${agent.name}</h1><p>Agent server running.</p></body></html>`,
|
|
2380
|
+
{ headers: { "Content-Type": "text/html" } }
|
|
2381
|
+
);
|
|
2358
2382
|
}
|
|
2359
2383
|
return new Response("Not Found", { status: 404 });
|
|
2360
2384
|
},
|
|
@@ -2380,7 +2404,7 @@ function createWintercServer(options) {
|
|
|
2380
2404
|
};
|
|
2381
2405
|
}
|
|
2382
2406
|
var init_winterc_server = __esm({
|
|
2383
|
-
"
|
|
2407
|
+
"sdk/winterc_server.ts"() {
|
|
2384
2408
|
"use strict";
|
|
2385
2409
|
init_direct_executor();
|
|
2386
2410
|
init_kv();
|
|
@@ -2391,7 +2415,7 @@ var init_winterc_server = __esm({
|
|
|
2391
2415
|
}
|
|
2392
2416
|
});
|
|
2393
2417
|
|
|
2394
|
-
//
|
|
2418
|
+
// sdk/server.ts
|
|
2395
2419
|
var server_exports = {};
|
|
2396
2420
|
__export(server_exports, {
|
|
2397
2421
|
createServer: () => createServer
|
|
@@ -2402,20 +2426,30 @@ async function loadWsFactory() {
|
|
|
2402
2426
|
const WS = mod.default ?? mod;
|
|
2403
2427
|
return (url, opts) => new WS(url, { headers: opts.headers });
|
|
2404
2428
|
} catch {
|
|
2405
|
-
throw new Error(
|
|
2429
|
+
throw new Error(
|
|
2430
|
+
"WebSocket factory not provided and `ws` package not found. Install `ws` (`npm install ws`) or pass `createWebSocket` option."
|
|
2431
|
+
);
|
|
2406
2432
|
}
|
|
2407
2433
|
}
|
|
2408
2434
|
function resolveEnv(env) {
|
|
2409
2435
|
const resolved = {};
|
|
2410
2436
|
for (const [key, value] of Object.entries(env)) {
|
|
2411
|
-
if (value !== void 0)
|
|
2412
|
-
resolved[key] = value;
|
|
2437
|
+
if (value !== void 0) resolved[key] = value;
|
|
2413
2438
|
}
|
|
2414
2439
|
return resolved;
|
|
2415
2440
|
}
|
|
2416
2441
|
function createServer(options) {
|
|
2417
|
-
const {
|
|
2418
|
-
|
|
2442
|
+
const {
|
|
2443
|
+
agent,
|
|
2444
|
+
kv,
|
|
2445
|
+
clientHtml,
|
|
2446
|
+
clientDir,
|
|
2447
|
+
logger = consoleLogger,
|
|
2448
|
+
s2sConfig = DEFAULT_S2S_CONFIG
|
|
2449
|
+
} = options;
|
|
2450
|
+
const env = resolveEnv(
|
|
2451
|
+
options.env ?? (typeof process !== "undefined" ? process.env : {})
|
|
2452
|
+
);
|
|
2419
2453
|
let wsFactory = options.createWebSocket ?? null;
|
|
2420
2454
|
async function getWsFactory() {
|
|
2421
2455
|
if (!wsFactory) {
|
|
@@ -2451,17 +2485,13 @@ function createServer(options) {
|
|
|
2451
2485
|
const nodeServer = http.createServer(async (req, res) => {
|
|
2452
2486
|
if (clientDir && req.url) {
|
|
2453
2487
|
const served = await serveStaticFile(req.url, clientDir, res);
|
|
2454
|
-
if (served)
|
|
2455
|
-
return;
|
|
2488
|
+
if (served) return;
|
|
2456
2489
|
}
|
|
2457
2490
|
await nodeHttpHandler(req, res, port, getWinterc);
|
|
2458
2491
|
});
|
|
2459
2492
|
attachWsUpgrade(nodeServer, port, getWinterc, logger);
|
|
2460
2493
|
await new Promise((resolve) => {
|
|
2461
|
-
nodeServer.listen(port, () =>
|
|
2462
|
-
logger.info(`Agent "${agent.name}" listening on http://localhost:${port}`);
|
|
2463
|
-
resolve();
|
|
2464
|
-
});
|
|
2494
|
+
nodeServer.listen(port, () => resolve());
|
|
2465
2495
|
});
|
|
2466
2496
|
serverHandle = {
|
|
2467
2497
|
async shutdown() {
|
|
@@ -2483,8 +2513,7 @@ async function serveStaticFile(reqUrl, clientDir, res) {
|
|
|
2483
2513
|
const urlPath = new URL(reqUrl, "http://localhost").pathname;
|
|
2484
2514
|
const relPath = urlPath === "/" ? "index.html" : urlPath.slice(1);
|
|
2485
2515
|
const filePath = normalize(join(clientDir, relPath));
|
|
2486
|
-
if (!filePath.startsWith(clientDir))
|
|
2487
|
-
return false;
|
|
2516
|
+
if (!filePath.startsWith(clientDir)) return false;
|
|
2488
2517
|
try {
|
|
2489
2518
|
const content = await readFile(filePath);
|
|
2490
2519
|
const ext = extname(filePath);
|
|
@@ -2503,8 +2532,7 @@ async function nodeHttpHandler(req, res, port, getWinterc) {
|
|
|
2503
2532
|
const url = new URL(req.url ?? "/", `${protocol}://${host}`);
|
|
2504
2533
|
const headers = new Headers();
|
|
2505
2534
|
for (const [key, val] of Object.entries(req.headers)) {
|
|
2506
|
-
if (val)
|
|
2507
|
-
headers.set(key, Array.isArray(val) ? val[0] ?? "" : val);
|
|
2535
|
+
if (val) headers.set(key, Array.isArray(val) ? val[0] ?? "" : val);
|
|
2508
2536
|
}
|
|
2509
2537
|
const request = new Request(url, { method: req.method ?? "GET", headers });
|
|
2510
2538
|
const response = await getWinterc().fetch(request);
|
|
@@ -2518,16 +2546,23 @@ async function nodeHttpHandler(req, res, port, getWinterc) {
|
|
|
2518
2546
|
function attachWsUpgrade(nodeServer, port, getWinterc, logger) {
|
|
2519
2547
|
import("ws").then((wsMod) => {
|
|
2520
2548
|
const WSServer = wsMod.WebSocketServer;
|
|
2521
|
-
if (!WSServer)
|
|
2522
|
-
return;
|
|
2549
|
+
if (!WSServer) return;
|
|
2523
2550
|
const wss = new WSServer({ noServer: true });
|
|
2524
2551
|
nodeServer.on("upgrade", (req, socket, head) => {
|
|
2525
|
-
wss.handleUpgrade(
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2552
|
+
wss.handleUpgrade(
|
|
2553
|
+
req,
|
|
2554
|
+
socket,
|
|
2555
|
+
head,
|
|
2556
|
+
(ws) => {
|
|
2557
|
+
const reqUrl = new URL(
|
|
2558
|
+
req.url ?? "/",
|
|
2559
|
+
`http://localhost:${port}`
|
|
2560
|
+
);
|
|
2561
|
+
getWinterc().handleWebSocket(ws, {
|
|
2562
|
+
skipGreeting: reqUrl.searchParams.has("resume")
|
|
2563
|
+
});
|
|
2564
|
+
}
|
|
2565
|
+
);
|
|
2531
2566
|
});
|
|
2532
2567
|
}).catch(() => {
|
|
2533
2568
|
logger.warn("ws package not available for Node.js WebSocket upgrade");
|
|
@@ -2535,7 +2570,8 @@ function attachWsUpgrade(nodeServer, port, getWinterc, logger) {
|
|
|
2535
2570
|
}
|
|
2536
2571
|
var MIME_TYPES;
|
|
2537
2572
|
var init_server = __esm({
|
|
2538
|
-
"
|
|
2573
|
+
"sdk/server.ts"() {
|
|
2574
|
+
"use strict";
|
|
2539
2575
|
init_runtime();
|
|
2540
2576
|
init_winterc_server();
|
|
2541
2577
|
MIME_TYPES = {
|
|
@@ -2554,27 +2590,25 @@ var init_server = __esm({
|
|
|
2554
2590
|
|
|
2555
2591
|
// cli/cli.ts
|
|
2556
2592
|
init_help();
|
|
2557
|
-
init_output();
|
|
2558
2593
|
init_deploy2();
|
|
2559
2594
|
import { readFileSync } from "node:fs";
|
|
2560
|
-
import
|
|
2595
|
+
import path10 from "node:path";
|
|
2561
2596
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2562
2597
|
import minimist7 from "minimist";
|
|
2563
2598
|
|
|
2564
2599
|
// cli/dev.tsx
|
|
2565
|
-
import
|
|
2600
|
+
import path7 from "node:path";
|
|
2566
2601
|
import minimist3 from "minimist";
|
|
2567
2602
|
|
|
2568
2603
|
// cli/_dev.ts
|
|
2569
2604
|
init_bundler();
|
|
2570
2605
|
init_discover();
|
|
2571
|
-
|
|
2572
|
-
import
|
|
2606
|
+
init_ink();
|
|
2607
|
+
import React2 from "react";
|
|
2573
2608
|
|
|
2574
2609
|
// cli/_server_common.ts
|
|
2575
2610
|
init_discover();
|
|
2576
|
-
|
|
2577
|
-
import fs6 from "node:fs/promises";
|
|
2611
|
+
import fs5 from "node:fs/promises";
|
|
2578
2612
|
import path6 from "node:path";
|
|
2579
2613
|
import { createServer as createViteServer } from "vite";
|
|
2580
2614
|
async function loadAgentDef(cwd) {
|
|
@@ -2600,25 +2634,15 @@ async function resolveServerEnv() {
|
|
|
2600
2634
|
Object.entries(process.env).filter((e) => e[1] !== void 0)
|
|
2601
2635
|
);
|
|
2602
2636
|
if (!env.ASSEMBLYAI_API_KEY) {
|
|
2603
|
-
|
|
2604
|
-
env.ASSEMBLYAI_API_KEY = await getApiKey();
|
|
2605
|
-
} catch {
|
|
2606
|
-
error2("ASSEMBLYAI_API_KEY not set. Set it in your environment or run `aai env add`.");
|
|
2607
|
-
throw new Error("ASSEMBLYAI_API_KEY is required");
|
|
2608
|
-
}
|
|
2637
|
+
env.ASSEMBLYAI_API_KEY = await getApiKey();
|
|
2609
2638
|
}
|
|
2610
2639
|
return env;
|
|
2611
2640
|
}
|
|
2612
|
-
async function
|
|
2613
|
-
const
|
|
2614
|
-
const
|
|
2615
|
-
const
|
|
2616
|
-
|
|
2617
|
-
}
|
|
2618
|
-
async function bootServer(agentDef, clientDir, env, port, cwd) {
|
|
2619
|
-
step("Start", `http://localhost:${port}`);
|
|
2620
|
-
const createWebSocket = await loadWsFromProject(cwd);
|
|
2621
|
-
const clientHtml = await fs6.readFile(path6.join(clientDir, "index.html"), "utf-8");
|
|
2641
|
+
async function bootServer(agentDef, clientDir, env, port) {
|
|
2642
|
+
const wsMod = await import("ws");
|
|
2643
|
+
const WS = wsMod.default ?? wsMod;
|
|
2644
|
+
const createWebSocket = (url, opts) => new WS(url, { headers: opts.headers });
|
|
2645
|
+
const clientHtml = await fs5.readFile(path6.join(clientDir, "index.html"), "utf-8");
|
|
2622
2646
|
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
2623
2647
|
const server = createServer2({
|
|
2624
2648
|
agent: agentDef,
|
|
@@ -2628,31 +2652,29 @@ async function bootServer(agentDef, clientDir, env, port, cwd) {
|
|
|
2628
2652
|
createWebSocket
|
|
2629
2653
|
});
|
|
2630
2654
|
await server.listen(port);
|
|
2631
|
-
step("Ready", `http://localhost:${port}`);
|
|
2632
2655
|
}
|
|
2633
2656
|
|
|
2634
2657
|
// cli/_dev.ts
|
|
2635
|
-
async function _startDevServer(cwd, port) {
|
|
2658
|
+
async function _startDevServer(cwd, port, log) {
|
|
2636
2659
|
const agent = await loadAgent(cwd);
|
|
2637
2660
|
if (!agent) {
|
|
2638
2661
|
throw new Error("No agent found \u2014 run `aai init` first");
|
|
2639
2662
|
}
|
|
2640
|
-
|
|
2663
|
+
log(React2.createElement(Step, { action: "Build", msg: agent.slug }));
|
|
2641
2664
|
let clientDir;
|
|
2642
2665
|
try {
|
|
2643
|
-
await bundleAgent(agent);
|
|
2644
|
-
clientDir =
|
|
2666
|
+
const bundle = await bundleAgent(agent);
|
|
2667
|
+
clientDir = bundle.clientDir;
|
|
2645
2668
|
} catch (err) {
|
|
2646
2669
|
if (err instanceof BundleError) {
|
|
2647
|
-
|
|
2648
|
-
throw new Error("Bundle failed \u2014 fix the errors above");
|
|
2670
|
+
throw new Error(`Bundle failed: ${err.message}`);
|
|
2649
2671
|
}
|
|
2650
2672
|
throw err;
|
|
2651
2673
|
}
|
|
2652
|
-
step("Load", "agent.ts");
|
|
2653
2674
|
const agentDef = await loadAgentDef(cwd);
|
|
2654
2675
|
const env = await resolveServerEnv();
|
|
2655
|
-
await bootServer(agentDef, clientDir, env, port
|
|
2676
|
+
await bootServer(agentDef, clientDir, env, port);
|
|
2677
|
+
log(React2.createElement(Step, { action: "Ready", msg: `http://localhost:${port}` }));
|
|
2656
2678
|
}
|
|
2657
2679
|
|
|
2658
2680
|
// cli/dev.tsx
|
|
@@ -2660,7 +2682,6 @@ init_discover();
|
|
|
2660
2682
|
init_help();
|
|
2661
2683
|
init_ink();
|
|
2662
2684
|
init_init2();
|
|
2663
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
2664
2685
|
var devCommandDef = {
|
|
2665
2686
|
name: "dev",
|
|
2666
2687
|
description: "Start a local development server",
|
|
@@ -2684,13 +2705,12 @@ async function runDevCommand(args, version) {
|
|
|
2684
2705
|
}
|
|
2685
2706
|
const cwd = process.env.INIT_CWD || process.cwd();
|
|
2686
2707
|
const port = Number.parseInt(parsed.port ?? "3000", 10);
|
|
2687
|
-
if (!await fileExists(
|
|
2708
|
+
if (!await fileExists(path7.join(cwd, "agent.ts"))) {
|
|
2688
2709
|
await runInitCommand(parsed.yes ? ["-y"] : [], version, { quiet: true });
|
|
2689
2710
|
}
|
|
2690
2711
|
await getApiKey();
|
|
2691
2712
|
await runWithInk(async (log) => {
|
|
2692
|
-
|
|
2693
|
-
await _startDevServer(cwd, port);
|
|
2713
|
+
await _startDevServer(cwd, port, log);
|
|
2694
2714
|
});
|
|
2695
2715
|
}
|
|
2696
2716
|
|
|
@@ -2705,7 +2725,7 @@ import { render as render3, Text as Text3, useApp as useApp2 } from "ink";
|
|
|
2705
2725
|
import minimist4 from "minimist";
|
|
2706
2726
|
import pLimit from "p-limit";
|
|
2707
2727
|
import { useEffect, useState as useState2 } from "react";
|
|
2708
|
-
import { Fragment as Fragment2, jsx as
|
|
2728
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2709
2729
|
var ragCommandDef = {
|
|
2710
2730
|
name: "rag",
|
|
2711
2731
|
description: "Ingest a site's llms-full.txt into the vector store",
|
|
@@ -2739,17 +2759,17 @@ function RagUI({ url, apiKey, serverUrl, slug, chunkSize, onError }) {
|
|
|
2739
2759
|
setProgress
|
|
2740
2760
|
});
|
|
2741
2761
|
} catch (e) {
|
|
2742
|
-
const
|
|
2743
|
-
setErr(
|
|
2744
|
-
onError?.(
|
|
2762
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
2763
|
+
setErr(error.message);
|
|
2764
|
+
onError?.(error);
|
|
2745
2765
|
}
|
|
2746
2766
|
setProgress(null);
|
|
2747
2767
|
exit();
|
|
2748
2768
|
})();
|
|
2749
2769
|
}, [apiKey, chunkSize, exit, log, onError, serverUrl, slug, url]);
|
|
2750
2770
|
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
2751
|
-
/* @__PURE__ */
|
|
2752
|
-
err && /* @__PURE__ */
|
|
2771
|
+
/* @__PURE__ */ jsx5(StepLog, { items }),
|
|
2772
|
+
err && /* @__PURE__ */ jsx5(ErrorLine, { msg: err }),
|
|
2753
2773
|
progress && /* @__PURE__ */ jsxs3(Text3, { children: [
|
|
2754
2774
|
" ".repeat(PAD + 1),
|
|
2755
2775
|
"Upsert ",
|
|
@@ -2764,7 +2784,7 @@ function RagUI({ url, apiKey, serverUrl, slug, chunkSize, onError }) {
|
|
|
2764
2784
|
}
|
|
2765
2785
|
async function runRag(opts) {
|
|
2766
2786
|
const { url, apiKey, serverUrl, slug, chunkSize, log, setProgress } = opts;
|
|
2767
|
-
log(/* @__PURE__ */
|
|
2787
|
+
log(/* @__PURE__ */ jsx5(Step, { action: "Fetch", msg: url }));
|
|
2768
2788
|
const resp = await fetch(url, {
|
|
2769
2789
|
headers: { "User-Agent": "aai-cli/1.0" },
|
|
2770
2790
|
redirect: "follow",
|
|
@@ -2775,27 +2795,27 @@ async function runRag(opts) {
|
|
|
2775
2795
|
}
|
|
2776
2796
|
const content = await resp.text();
|
|
2777
2797
|
if (content.length === 0) {
|
|
2778
|
-
log(/* @__PURE__ */
|
|
2798
|
+
log(/* @__PURE__ */ jsx5(Warn, { msg: "File is empty" }));
|
|
2779
2799
|
return;
|
|
2780
2800
|
}
|
|
2781
|
-
log(/* @__PURE__ */
|
|
2801
|
+
log(/* @__PURE__ */ jsx5(Info, { msg: `${(content.length / 1024).toFixed(0)} KB` }));
|
|
2782
2802
|
const origin = new URL(url).origin;
|
|
2783
2803
|
const pages = splitPages(content);
|
|
2784
|
-
log(/* @__PURE__ */
|
|
2804
|
+
log(/* @__PURE__ */ jsx5(Step, { action: "Parsed", msg: `${pages.length} pages` }));
|
|
2785
2805
|
const { RecursiveChunker } = await import("@chonkiejs/core");
|
|
2786
2806
|
const chunker = await RecursiveChunker.create({ chunkSize });
|
|
2787
2807
|
const siteSlug = slugify(origin);
|
|
2788
2808
|
const allChunks = await chunkPages(pages, chunker, origin, siteSlug);
|
|
2789
|
-
log(/* @__PURE__ */
|
|
2809
|
+
log(/* @__PURE__ */ jsx5(Step, { action: "Chunked", msg: `${allChunks.length} chunks` }));
|
|
2790
2810
|
const vectorUrl = `${serverUrl}/${slug}/vector`;
|
|
2791
|
-
log(/* @__PURE__ */
|
|
2811
|
+
log(/* @__PURE__ */ jsx5(Info, { msg: `target: ${vectorUrl}` }));
|
|
2792
2812
|
const result = await upsertChunks(allChunks, vectorUrl, apiKey, setProgress);
|
|
2793
|
-
log(/* @__PURE__ */
|
|
2813
|
+
log(/* @__PURE__ */ jsx5(Step, { action: "Done", msg: `${result.upserted} chunks upserted` }));
|
|
2794
2814
|
if (result.errors > 0) {
|
|
2795
|
-
log(/* @__PURE__ */
|
|
2796
|
-
if (result.lastError) log(/* @__PURE__ */
|
|
2815
|
+
log(/* @__PURE__ */ jsx5(Warn, { msg: `${result.errors} failed` }));
|
|
2816
|
+
if (result.lastError) log(/* @__PURE__ */ jsx5(Info, { msg: `last error: ${result.lastError}` }));
|
|
2797
2817
|
}
|
|
2798
|
-
log(/* @__PURE__ */
|
|
2818
|
+
log(/* @__PURE__ */ jsx5(Detail, { msg: `Agent: ${slug}` }));
|
|
2799
2819
|
}
|
|
2800
2820
|
async function chunkPages(pages, chunker, origin, siteSlug) {
|
|
2801
2821
|
const allChunks = [];
|
|
@@ -2896,7 +2916,7 @@ async function runRagCommand(args, version) {
|
|
|
2896
2916
|
const chunkSize = Number.parseInt(parsed["chunk-size"] ?? "512", 10);
|
|
2897
2917
|
let thrownError;
|
|
2898
2918
|
const app = render3(
|
|
2899
|
-
/* @__PURE__ */
|
|
2919
|
+
/* @__PURE__ */ jsx5(
|
|
2900
2920
|
RagUI,
|
|
2901
2921
|
{
|
|
2902
2922
|
url,
|
|
@@ -2965,7 +2985,7 @@ init_help();
|
|
|
2965
2985
|
init_ink();
|
|
2966
2986
|
init_prompts();
|
|
2967
2987
|
import minimist5 from "minimist";
|
|
2968
|
-
import { jsx as
|
|
2988
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
2969
2989
|
var secretCommandDef = {
|
|
2970
2990
|
name: "secret",
|
|
2971
2991
|
description: "Manage secrets",
|
|
@@ -3038,7 +3058,7 @@ async function secretPut(cwd, name, value) {
|
|
|
3038
3058
|
const text = await resp.text();
|
|
3039
3059
|
throw new Error(`Failed to set secret: ${text}`);
|
|
3040
3060
|
}
|
|
3041
|
-
log(/* @__PURE__ */
|
|
3061
|
+
log(/* @__PURE__ */ jsx6(Step, { action: "Set", msg: `${name} for ${slug}` }));
|
|
3042
3062
|
});
|
|
3043
3063
|
}
|
|
3044
3064
|
async function secretDelete(cwd, name) {
|
|
@@ -3053,7 +3073,7 @@ async function secretDelete(cwd, name) {
|
|
|
3053
3073
|
const text = await resp.text();
|
|
3054
3074
|
throw new Error(`Failed to delete secret: ${text}`);
|
|
3055
3075
|
}
|
|
3056
|
-
log(/* @__PURE__ */
|
|
3076
|
+
log(/* @__PURE__ */ jsx6(Step, { action: "Deleted", msg: `${name} from ${slug}` }));
|
|
3057
3077
|
});
|
|
3058
3078
|
}
|
|
3059
3079
|
async function secretList(cwd) {
|
|
@@ -3068,10 +3088,10 @@ async function secretList(cwd) {
|
|
|
3068
3088
|
}
|
|
3069
3089
|
const { vars } = await resp.json();
|
|
3070
3090
|
if (vars.length === 0) {
|
|
3071
|
-
log(/* @__PURE__ */
|
|
3091
|
+
log(/* @__PURE__ */ jsx6(StepInfo, { action: "Secrets", msg: "No secrets set" }));
|
|
3072
3092
|
} else {
|
|
3073
3093
|
for (const name of vars) {
|
|
3074
|
-
log(/* @__PURE__ */
|
|
3094
|
+
log(/* @__PURE__ */ jsx6(Detail, { msg: name }));
|
|
3075
3095
|
}
|
|
3076
3096
|
}
|
|
3077
3097
|
});
|
|
@@ -3081,22 +3101,25 @@ async function secretList(cwd) {
|
|
|
3081
3101
|
init_discover();
|
|
3082
3102
|
init_help();
|
|
3083
3103
|
init_ink();
|
|
3084
|
-
import
|
|
3104
|
+
import path9 from "node:path";
|
|
3085
3105
|
import minimist6 from "minimist";
|
|
3086
3106
|
|
|
3087
3107
|
// cli/_start.ts
|
|
3088
|
-
|
|
3089
|
-
import
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3108
|
+
init_ink();
|
|
3109
|
+
import path8 from "node:path";
|
|
3110
|
+
import React3 from "react";
|
|
3111
|
+
async function _startProductionServer(cwd, port, log) {
|
|
3112
|
+
const clientDir = path8.join(cwd, ".aai", "client");
|
|
3113
|
+
log(React3.createElement(Step, { action: "Load", msg: "agent" }));
|
|
3093
3114
|
const agentDef = await loadAgentDef(cwd);
|
|
3094
3115
|
const env = await resolveServerEnv();
|
|
3095
|
-
|
|
3116
|
+
log(React3.createElement(Step, { action: "Start", msg: `http://localhost:${port}` }));
|
|
3117
|
+
await bootServer(agentDef, clientDir, env, port);
|
|
3118
|
+
log(React3.createElement(Step, { action: "Ready", msg: `http://localhost:${port}` }));
|
|
3096
3119
|
}
|
|
3097
3120
|
|
|
3098
3121
|
// cli/start.tsx
|
|
3099
|
-
import { jsx as
|
|
3122
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
3100
3123
|
var startCommandDef = {
|
|
3101
3124
|
name: "start",
|
|
3102
3125
|
description: "Start the production server from a build",
|
|
@@ -3120,20 +3143,20 @@ async function runStartCommand(args, version) {
|
|
|
3120
3143
|
}
|
|
3121
3144
|
const cwd = process.env.INIT_CWD || process.cwd();
|
|
3122
3145
|
const port = Number.parseInt(parsed.port ?? "3000", 10);
|
|
3123
|
-
const buildDir =
|
|
3124
|
-
if (!await fileExists(
|
|
3146
|
+
const buildDir = path9.join(cwd, ".aai", "build");
|
|
3147
|
+
if (!await fileExists(path9.join(buildDir, "worker.js"))) {
|
|
3125
3148
|
throw new Error("No build found \u2014 run `aai build` first");
|
|
3126
3149
|
}
|
|
3127
3150
|
await getApiKey();
|
|
3128
3151
|
await runWithInk(async (log) => {
|
|
3129
|
-
log(/* @__PURE__ */
|
|
3130
|
-
await _startProductionServer(cwd, port);
|
|
3152
|
+
log(/* @__PURE__ */ jsx7(Step, { action: "Start", msg: `production server on port ${port}` }));
|
|
3153
|
+
await _startProductionServer(cwd, port, log);
|
|
3131
3154
|
});
|
|
3132
3155
|
}
|
|
3133
3156
|
|
|
3134
3157
|
// cli/cli.ts
|
|
3135
|
-
var cliDir =
|
|
3136
|
-
var pkgJsonPath =
|
|
3158
|
+
var cliDir = path10.dirname(fileURLToPath2(import.meta.url));
|
|
3159
|
+
var pkgJsonPath = path10.join(cliDir, "..", "package.json");
|
|
3137
3160
|
var pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
|
|
3138
3161
|
var VERSION = pkgJson.version;
|
|
3139
3162
|
async function main(args) {
|
|
@@ -3178,19 +3201,17 @@ async function main(args) {
|
|
|
3178
3201
|
await runInitCommand(subArgs, VERSION);
|
|
3179
3202
|
return;
|
|
3180
3203
|
default:
|
|
3181
|
-
|
|
3204
|
+
console.error(`Unknown command: ${subcommand}`);
|
|
3182
3205
|
console.log(rootHelp(VERSION));
|
|
3183
3206
|
process.exit(1);
|
|
3184
3207
|
}
|
|
3185
3208
|
}
|
|
3186
3209
|
if (process.env.VITEST !== "true") {
|
|
3187
3210
|
process.on("SIGINT", () => process.exit(0));
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
} catch (err) {
|
|
3191
|
-
error2(err instanceof Error ? err.message : String(err));
|
|
3211
|
+
main(process.argv.slice(2)).catch((err) => {
|
|
3212
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
3192
3213
|
process.exit(1);
|
|
3193
|
-
}
|
|
3214
|
+
});
|
|
3194
3215
|
}
|
|
3195
3216
|
export {
|
|
3196
3217
|
main
|