@alexkroman1/aai 0.8.8 → 0.9.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/{sdk/_internal_types.d.ts → _internal-types.d.ts} +0 -3
- package/dist/_internal-types.js +19 -0
- package/dist/{sdk/_mock_ws.d.ts → _mock-ws.d.ts} +16 -5
- package/dist/_mock-ws.js +158 -0
- package/dist/{sdk/_utils.d.ts → _utils.d.ts} +1 -2
- package/dist/_utils.js +8 -0
- package/dist/{sdk/builtin_tools.d.ts → builtin-tools.d.ts} +5 -8
- package/dist/builtin-tools.js +270 -0
- package/dist/{sdk/direct_executor.d.ts → direct-executor.d.ts} +3 -7
- package/dist/direct-executor.js +125 -0
- package/dist/{sdk/mod.d.ts → index.d.ts} +0 -4
- package/dist/index.js +2 -0
- package/dist/{sdk/kv.d.ts → kv.d.ts} +23 -20
- package/dist/kv.js +99 -0
- package/dist/{sdk/protocol.d.ts → protocol.d.ts} +65 -29
- package/dist/protocol.js +142 -0
- package/dist/runtime.d.ts +18 -0
- package/dist/runtime.js +16 -0
- package/dist/s2s.d.ts +110 -0
- package/dist/s2s.js +242 -0
- package/dist/{sdk/server.d.ts → server.d.ts} +3 -23
- package/dist/server.js +105 -0
- package/dist/{sdk/session.d.ts → session.d.ts} +4 -11
- package/dist/session.js +312 -0
- package/dist/tsdown.config.d.ts +2 -0
- package/dist/{sdk/types.d.ts → types.d.ts} +41 -25
- package/dist/types.js +139 -0
- package/dist/{sdk/vector.d.ts → vector.d.ts} +14 -15
- package/dist/vector.js +56 -0
- package/dist/{sdk/worker_entry.d.ts → worker-entry.d.ts} +2 -5
- package/dist/worker-entry.js +59 -0
- package/dist/{sdk/ws_handler.d.ts → ws-handler.d.ts} +10 -8
- package/dist/ws-handler.js +155 -0
- package/package.json +66 -149
- package/README.md +0 -34
- package/dist/aai.js +0 -3
- package/dist/cli/tsconfig.tsbuildinfo +0 -1
- package/dist/cli.js +0 -2811
- package/dist/sdk/_internal_types.d.ts.map +0 -1
- package/dist/sdk/_internal_types.js +0 -25
- package/dist/sdk/_internal_types.js.map +0 -1
- package/dist/sdk/_mock_ws.d.ts.map +0 -1
- package/dist/sdk/_mock_ws.js +0 -154
- package/dist/sdk/_mock_ws.js.map +0 -1
- package/dist/sdk/_render_check.d.ts +0 -10
- package/dist/sdk/_render_check.d.ts.map +0 -1
- package/dist/sdk/_render_check.js +0 -72
- package/dist/sdk/_render_check.js.map +0 -1
- package/dist/sdk/_utils.d.ts.map +0 -1
- package/dist/sdk/_utils.js +0 -7
- package/dist/sdk/_utils.js.map +0 -1
- package/dist/sdk/builtin_tools.d.ts.map +0 -1
- package/dist/sdk/builtin_tools.js +0 -309
- package/dist/sdk/builtin_tools.js.map +0 -1
- package/dist/sdk/capnweb.d.ts +0 -102
- package/dist/sdk/capnweb.d.ts.map +0 -1
- package/dist/sdk/capnweb.js +0 -219
- package/dist/sdk/capnweb.js.map +0 -1
- package/dist/sdk/define_agent.d.ts +0 -36
- package/dist/sdk/define_agent.d.ts.map +0 -1
- package/dist/sdk/define_agent.js +0 -71
- package/dist/sdk/define_agent.js.map +0 -1
- package/dist/sdk/direct_executor.d.ts.map +0 -1
- package/dist/sdk/direct_executor.js +0 -145
- package/dist/sdk/direct_executor.js.map +0 -1
- package/dist/sdk/host.d.ts +0 -59
- package/dist/sdk/host.d.ts.map +0 -1
- package/dist/sdk/host.js +0 -131
- package/dist/sdk/host.js.map +0 -1
- package/dist/sdk/kv.d.ts.map +0 -1
- package/dist/sdk/kv.js +0 -94
- package/dist/sdk/kv.js.map +0 -1
- package/dist/sdk/memory_tools.d.ts +0 -38
- package/dist/sdk/memory_tools.d.ts.map +0 -1
- package/dist/sdk/memory_tools.js +0 -77
- package/dist/sdk/memory_tools.js.map +0 -1
- package/dist/sdk/mod.d.ts.map +0 -1
- package/dist/sdk/mod.js +0 -27
- package/dist/sdk/mod.js.map +0 -1
- package/dist/sdk/protocol.d.ts.map +0 -1
- package/dist/sdk/protocol.js +0 -133
- package/dist/sdk/protocol.js.map +0 -1
- package/dist/sdk/runtime.d.ts +0 -36
- package/dist/sdk/runtime.d.ts.map +0 -1
- package/dist/sdk/runtime.js +0 -27
- package/dist/sdk/runtime.js.map +0 -1
- package/dist/sdk/s2s.d.ts +0 -74
- package/dist/sdk/s2s.d.ts.map +0 -1
- package/dist/sdk/s2s.js +0 -218
- package/dist/sdk/s2s.js.map +0 -1
- package/dist/sdk/server.d.ts.map +0 -1
- package/dist/sdk/server.js +0 -144
- package/dist/sdk/server.js.map +0 -1
- package/dist/sdk/session.d.ts.map +0 -1
- package/dist/sdk/session.js +0 -303
- package/dist/sdk/session.js.map +0 -1
- package/dist/sdk/system_prompt.d.ts +0 -6
- package/dist/sdk/system_prompt.d.ts.map +0 -1
- package/dist/sdk/system_prompt.js +0 -35
- package/dist/sdk/system_prompt.js.map +0 -1
- package/dist/sdk/tsconfig.tsbuildinfo +0 -1
- package/dist/sdk/types.d.ts.map +0 -1
- package/dist/sdk/types.js +0 -96
- package/dist/sdk/types.js.map +0 -1
- package/dist/sdk/vector.d.ts.map +0 -1
- package/dist/sdk/vector.js +0 -63
- package/dist/sdk/vector.js.map +0 -1
- package/dist/sdk/winterc_server.d.ts +0 -56
- package/dist/sdk/winterc_server.d.ts.map +0 -1
- package/dist/sdk/winterc_server.js +0 -77
- package/dist/sdk/winterc_server.js.map +0 -1
- package/dist/sdk/worker_entry.d.ts.map +0 -1
- package/dist/sdk/worker_entry.js +0 -68
- package/dist/sdk/worker_entry.js.map +0 -1
- package/dist/sdk/worker_shim.d.ts +0 -19
- package/dist/sdk/worker_shim.d.ts.map +0 -1
- package/dist/sdk/worker_shim.js +0 -141
- package/dist/sdk/worker_shim.js.map +0 -1
- package/dist/sdk/ws_handler.d.ts.map +0 -1
- package/dist/sdk/ws_handler.js +0 -158
- package/dist/sdk/ws_handler.js.map +0 -1
- package/dist/ui/_cn.d.ts +0 -5
- package/dist/ui/_cn.d.ts.map +0 -1
- package/dist/ui/_cn.js +0 -22
- package/dist/ui/_cn.js.map +0 -1
- package/dist/ui/_components/app.d.ts +0 -5
- package/dist/ui/_components/app.d.ts.map +0 -1
- package/dist/ui/_components/app.js +0 -12
- package/dist/ui/_components/app.js.map +0 -1
- package/dist/ui/_components/button.d.ts +0 -11
- package/dist/ui/_components/button.d.ts.map +0 -1
- package/dist/ui/_components/button.js +0 -17
- package/dist/ui/_components/button.js.map +0 -1
- package/dist/ui/_components/chat_view.d.ts +0 -5
- package/dist/ui/_components/chat_view.d.ts.map +0 -1
- package/dist/ui/_components/chat_view.js +0 -15
- package/dist/ui/_components/chat_view.js.map +0 -1
- package/dist/ui/_components/controls.d.ts +0 -4
- package/dist/ui/_components/controls.d.ts.map +0 -1
- package/dist/ui/_components/controls.js +0 -10
- package/dist/ui/_components/controls.js.map +0 -1
- package/dist/ui/_components/error_banner.d.ts +0 -8
- package/dist/ui/_components/error_banner.d.ts.map +0 -1
- package/dist/ui/_components/error_banner.js +0 -8
- package/dist/ui/_components/error_banner.js.map +0 -1
- package/dist/ui/_components/message_bubble.d.ts +0 -7
- package/dist/ui/_components/message_bubble.d.ts.map +0 -1
- package/dist/ui/_components/message_bubble.js +0 -11
- package/dist/ui/_components/message_bubble.js.map +0 -1
- package/dist/ui/_components/message_list.d.ts +0 -4
- package/dist/ui/_components/message_list.d.ts.map +0 -1
- package/dist/ui/_components/message_list.js +0 -45
- package/dist/ui/_components/message_list.js.map +0 -1
- package/dist/ui/_components/sidebar_layout.d.ts +0 -20
- package/dist/ui/_components/sidebar_layout.d.ts.map +0 -1
- package/dist/ui/_components/sidebar_layout.js +0 -19
- package/dist/ui/_components/sidebar_layout.js.map +0 -1
- package/dist/ui/_components/start_screen.d.ts +0 -25
- package/dist/ui/_components/start_screen.d.ts.map +0 -1
- package/dist/ui/_components/start_screen.js +0 -28
- package/dist/ui/_components/start_screen.js.map +0 -1
- package/dist/ui/_components/state_indicator.d.ts +0 -8
- package/dist/ui/_components/state_indicator.d.ts.map +0 -1
- package/dist/ui/_components/state_indicator.js +0 -6
- package/dist/ui/_components/state_indicator.js.map +0 -1
- package/dist/ui/_components/thinking_indicator.d.ts +0 -5
- package/dist/ui/_components/thinking_indicator.d.ts.map +0 -1
- package/dist/ui/_components/thinking_indicator.js +0 -10
- package/dist/ui/_components/thinking_indicator.js.map +0 -1
- package/dist/ui/_components/tool_call_block.d.ts +0 -7
- package/dist/ui/_components/tool_call_block.d.ts.map +0 -1
- package/dist/ui/_components/tool_call_block.js +0 -46
- package/dist/ui/_components/tool_call_block.js.map +0 -1
- package/dist/ui/_components/tool_icons.d.ts +0 -18
- package/dist/ui/_components/tool_icons.d.ts.map +0 -1
- package/dist/ui/_components/tool_icons.js +0 -26
- package/dist/ui/_components/tool_icons.js.map +0 -1
- package/dist/ui/_components/transcript.d.ts +0 -7
- package/dist/ui/_components/transcript.d.ts.map +0 -1
- package/dist/ui/_components/transcript.js +0 -9
- package/dist/ui/_components/transcript.js.map +0 -1
- package/dist/ui/_dom_shim.d.ts +0 -7
- package/dist/ui/_dom_shim.d.ts.map +0 -1
- package/dist/ui/_dom_shim.js +0 -21
- package/dist/ui/_dom_shim.js.map +0 -1
- package/dist/ui/_hooks.d.ts +0 -21
- package/dist/ui/_hooks.d.ts.map +0 -1
- package/dist/ui/_hooks.js +0 -35
- package/dist/ui/_hooks.js.map +0 -1
- package/dist/ui/_jsdom_setup.d.ts +0 -1
- package/dist/ui/_jsdom_setup.d.ts.map +0 -1
- package/dist/ui/_jsdom_setup.js +0 -6
- package/dist/ui/_jsdom_setup.js.map +0 -1
- package/dist/ui/_render_check.d.ts +0 -10
- package/dist/ui/_render_check.d.ts.map +0 -1
- package/dist/ui/_render_check.js +0 -72
- package/dist/ui/_render_check.js.map +0 -1
- package/dist/ui/_test_utils.js +0 -272
- package/dist/ui/_test_utils.js.map +0 -1
- package/dist/ui/audio.d.ts +0 -46
- package/dist/ui/audio.d.ts.map +0 -1
- package/dist/ui/audio.js +0 -130
- package/dist/ui/audio.js.map +0 -1
- package/dist/ui/components.d.ts +0 -14
- package/dist/ui/components.d.ts.map +0 -1
- package/dist/ui/components.js +0 -15
- package/dist/ui/components.js.map +0 -1
- package/dist/ui/components_mod.d.ts +0 -34
- package/dist/ui/components_mod.d.ts.map +0 -1
- package/dist/ui/components_mod.js +0 -32
- package/dist/ui/components_mod.js.map +0 -1
- package/dist/ui/mod.d.ts +0 -23
- package/dist/ui/mod.d.ts.map +0 -1
- package/dist/ui/mod.js +0 -22
- package/dist/ui/mod.js.map +0 -1
- package/dist/ui/mount.d.ts +0 -44
- package/dist/ui/mount.d.ts.map +0 -1
- package/dist/ui/mount.js +0 -61
- package/dist/ui/mount.js.map +0 -1
- package/dist/ui/mount_context.d.ts +0 -22
- package/dist/ui/mount_context.d.ts.map +0 -1
- package/dist/ui/mount_context.js +0 -10
- package/dist/ui/mount_context.js.map +0 -1
- package/dist/ui/session.d.ts +0 -96
- package/dist/ui/session.d.ts.map +0 -1
- package/dist/ui/session.js +0 -379
- package/dist/ui/session.js.map +0 -1
- package/dist/ui/session_mod.d.ts +0 -19
- package/dist/ui/session_mod.d.ts.map +0 -1
- package/dist/ui/session_mod.js +0 -18
- package/dist/ui/session_mod.js.map +0 -1
- package/dist/ui/signals.d.ts +0 -80
- package/dist/ui/signals.d.ts.map +0 -1
- package/dist/ui/signals.js +0 -137
- package/dist/ui/signals.js.map +0 -1
- package/dist/ui/tsconfig.tsbuildinfo +0 -1
- package/dist/ui/types.d.ts +0 -36
- package/dist/ui/types.d.ts.map +0 -1
- package/dist/ui/types.js +0 -4
- package/dist/ui/types.js.map +0 -1
- package/dist/ui/worklets/capture-processor.d.ts +0 -3
- package/dist/ui/worklets/capture-processor.d.ts.map +0 -1
- package/dist/ui/worklets/capture-processor.js +0 -61
- package/dist/ui/worklets/capture-processor.js.map +0 -1
- package/dist/ui/worklets/playback-processor.d.ts +0 -3
- package/dist/ui/worklets/playback-processor.d.ts.map +0 -1
- package/dist/ui/worklets/playback-processor.js +0 -109
- package/dist/ui/worklets/playback-processor.js.map +0 -1
- package/templates/.env +0 -1
- package/templates/_shared/.env.example +0 -5
- package/templates/_shared/CLAUDE.md +0 -1073
- package/templates/_shared/biome.json +0 -32
- package/templates/_shared/global.d.ts +0 -1
- package/templates/_shared/index.html +0 -16
- package/templates/_shared/package.json +0 -22
- package/templates/_shared/tsconfig.json +0 -16
- package/templates/code-interpreter/agent.ts +0 -27
- package/templates/code-interpreter/client.tsx +0 -3
- package/templates/dispatch-center/agent.ts +0 -1223
- package/templates/dispatch-center/client.tsx +0 -505
- package/templates/embedded-assets/agent.ts +0 -48
- package/templates/embedded-assets/client.tsx +0 -3
- package/templates/embedded-assets/knowledge.json +0 -20
- package/templates/health-assistant/agent.ts +0 -160
- package/templates/health-assistant/client.tsx +0 -3
- package/templates/infocom-adventure/agent.ts +0 -164
- package/templates/infocom-adventure/client.tsx +0 -300
- package/templates/math-buddy/agent.ts +0 -21
- package/templates/math-buddy/client.tsx +0 -3
- package/templates/memory-agent/agent.ts +0 -20
- package/templates/memory-agent/client.tsx +0 -3
- package/templates/night-owl/agent.ts +0 -98
- package/templates/night-owl/client.tsx +0 -12
- package/templates/personal-finance/agent.ts +0 -26
- package/templates/personal-finance/client.tsx +0 -3
- package/templates/pizza-ordering/agent.ts +0 -214
- package/templates/pizza-ordering/client.tsx +0 -264
- package/templates/simple/agent.ts +0 -6
- package/templates/simple/client.tsx +0 -3
- package/templates/smart-research/agent.ts +0 -164
- package/templates/smart-research/client.tsx +0 -3
- package/templates/solo-rpg/agent.ts +0 -1240
- package/templates/solo-rpg/client.tsx +0 -698
- package/templates/support/README.md +0 -62
- package/templates/support/agent.ts +0 -19
- package/templates/support/client.tsx +0 -3
- package/templates/travel-concierge/agent.ts +0 -29
- package/templates/travel-concierge/client.tsx +0 -3
- package/templates/tsconfig.json +0 -1
- package/templates/web-researcher/agent.ts +0 -17
- package/templates/web-researcher/client.tsx +0 -3
- package/ui/styles.css +0 -74
package/dist/cli.js
DELETED
|
@@ -1,2811 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __esm = (fn, res) => function __init() {
|
|
5
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
-
};
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
// sdk/_utils.ts
|
|
13
|
-
function errorMessage(err) {
|
|
14
|
-
return err instanceof Error ? err.message : String(err);
|
|
15
|
-
}
|
|
16
|
-
var init_utils = __esm({
|
|
17
|
-
"sdk/_utils.ts"() {
|
|
18
|
-
"use strict";
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
// cli/_ink.tsx
|
|
23
|
-
import { Spinner, StatusMessage } from "@inkjs/ui";
|
|
24
|
-
import chalk from "chalk";
|
|
25
|
-
import { Box, render, Static, Text, useApp } from "ink";
|
|
26
|
-
import React, { useRef, useState } from "react";
|
|
27
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
28
|
-
function primary(s) {
|
|
29
|
-
return chalk.hex(COLORS.primary)(s);
|
|
30
|
-
}
|
|
31
|
-
function interactive(s) {
|
|
32
|
-
return chalk.hex(COLORS.interactive)(s);
|
|
33
|
-
}
|
|
34
|
-
function StepBase({ action, msg, color }) {
|
|
35
|
-
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
36
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color, children: action }),
|
|
37
|
-
/* @__PURE__ */ jsxs(Text, { children: [
|
|
38
|
-
" ",
|
|
39
|
-
msg
|
|
40
|
-
] })
|
|
41
|
-
] });
|
|
42
|
-
}
|
|
43
|
-
function Step({ action, msg }) {
|
|
44
|
-
return /* @__PURE__ */ jsx(StepBase, { action, msg, color: COLORS.primary });
|
|
45
|
-
}
|
|
46
|
-
function StepInfo({ action, msg }) {
|
|
47
|
-
return /* @__PURE__ */ jsx(StepBase, { action, msg, color: COLORS.interactive });
|
|
48
|
-
}
|
|
49
|
-
function Info({ msg }) {
|
|
50
|
-
return /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
51
|
-
" ",
|
|
52
|
-
msg
|
|
53
|
-
] });
|
|
54
|
-
}
|
|
55
|
-
function Detail({ msg }) {
|
|
56
|
-
return /* @__PURE__ */ jsxs(Text, { children: [
|
|
57
|
-
" ",
|
|
58
|
-
msg
|
|
59
|
-
] });
|
|
60
|
-
}
|
|
61
|
-
function Warn({ msg }) {
|
|
62
|
-
return /* @__PURE__ */ jsx(StatusMessage, { variant: "warning", children: msg });
|
|
63
|
-
}
|
|
64
|
-
function ErrorLine({ msg }) {
|
|
65
|
-
return /* @__PURE__ */ jsx(StatusMessage, { variant: "error", children: msg });
|
|
66
|
-
}
|
|
67
|
-
function StepLog({ items }) {
|
|
68
|
-
return /* @__PURE__ */ jsx(Static, { items, children: (item) => /* @__PURE__ */ jsx(Box, { children: item.node }, item.id) });
|
|
69
|
-
}
|
|
70
|
-
function useStepLog() {
|
|
71
|
-
const [items, setItems] = useState([]);
|
|
72
|
-
const nextId = useRef(0);
|
|
73
|
-
const log = (node) => {
|
|
74
|
-
const id = nextId.current++;
|
|
75
|
-
setItems((prev) => [...prev, { id, node }]);
|
|
76
|
-
};
|
|
77
|
-
return { items, log };
|
|
78
|
-
}
|
|
79
|
-
function CommandRunner({
|
|
80
|
-
run,
|
|
81
|
-
onError
|
|
82
|
-
}) {
|
|
83
|
-
const { exit } = useApp();
|
|
84
|
-
const { items, log } = useStepLog();
|
|
85
|
-
const [spinning, setSpinning] = useState(true);
|
|
86
|
-
const [currentStep, setCurrentStep] = useState(null);
|
|
87
|
-
const [statusLine, setStatusLine] = useState(null);
|
|
88
|
-
const [err, setErr] = useState(null);
|
|
89
|
-
const currentStepRef = useRef(null);
|
|
90
|
-
const wrappedLog = (node) => {
|
|
91
|
-
if (currentStepRef.current) {
|
|
92
|
-
log(currentStepRef.current);
|
|
93
|
-
}
|
|
94
|
-
currentStepRef.current = node;
|
|
95
|
-
setCurrentStep(node);
|
|
96
|
-
};
|
|
97
|
-
const started = useRef(false);
|
|
98
|
-
React.useEffect(() => {
|
|
99
|
-
if (started.current) return;
|
|
100
|
-
started.current = true;
|
|
101
|
-
(async () => {
|
|
102
|
-
try {
|
|
103
|
-
await run({ log: wrappedLog, setStatus: setStatusLine });
|
|
104
|
-
} catch (e) {
|
|
105
|
-
const error = e instanceof Error ? e : new Error(String(e));
|
|
106
|
-
setErr(error.message);
|
|
107
|
-
onError?.(error);
|
|
108
|
-
}
|
|
109
|
-
if (currentStepRef.current) {
|
|
110
|
-
log(currentStepRef.current);
|
|
111
|
-
currentStepRef.current = null;
|
|
112
|
-
}
|
|
113
|
-
setCurrentStep(null);
|
|
114
|
-
setStatusLine(null);
|
|
115
|
-
setSpinning(false);
|
|
116
|
-
setTimeout(() => exit(), 0);
|
|
117
|
-
})();
|
|
118
|
-
});
|
|
119
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
120
|
-
/* @__PURE__ */ jsx(StepLog, { items }),
|
|
121
|
-
err && /* @__PURE__ */ jsx(ErrorLine, { msg: err }),
|
|
122
|
-
spinning && currentStep && /* @__PURE__ */ jsxs(Box, { children: [
|
|
123
|
-
/* @__PURE__ */ jsx(Spinner, {}),
|
|
124
|
-
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
125
|
-
currentStep
|
|
126
|
-
] }),
|
|
127
|
-
spinning && statusLine && /* @__PURE__ */ jsx(Box, { children: statusLine })
|
|
128
|
-
] });
|
|
129
|
-
}
|
|
130
|
-
async function runWithInk(fn) {
|
|
131
|
-
let thrownError;
|
|
132
|
-
const app = render(
|
|
133
|
-
/* @__PURE__ */ jsx(
|
|
134
|
-
CommandRunner,
|
|
135
|
-
{
|
|
136
|
-
onError: (e) => {
|
|
137
|
-
thrownError = e;
|
|
138
|
-
},
|
|
139
|
-
run: fn
|
|
140
|
-
}
|
|
141
|
-
)
|
|
142
|
-
);
|
|
143
|
-
await app.waitUntilExit();
|
|
144
|
-
if (thrownError) throw thrownError;
|
|
145
|
-
}
|
|
146
|
-
var COLORS;
|
|
147
|
-
var init_ink = __esm({
|
|
148
|
-
"cli/_ink.tsx"() {
|
|
149
|
-
"use strict";
|
|
150
|
-
if (chalk.level === 0 && !process.env.NO_COLOR) {
|
|
151
|
-
const ct = process.env.COLORTERM;
|
|
152
|
-
if (ct === "truecolor" || ct === "24bit") {
|
|
153
|
-
chalk.level = 3;
|
|
154
|
-
} else if (ct || /-256(color)?$/i.test(process.env.TERM ?? "")) {
|
|
155
|
-
chalk.level = 2;
|
|
156
|
-
} else if (process.env.TERM_PROGRAM) {
|
|
157
|
-
chalk.level = 1;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
COLORS = {
|
|
161
|
-
primary: "#fab283",
|
|
162
|
-
interactive: "#56b6c2",
|
|
163
|
-
error: "#e06c75",
|
|
164
|
-
warning: "#f5a742",
|
|
165
|
-
success: "#7fd88f",
|
|
166
|
-
accent: "#9d7cd8",
|
|
167
|
-
muted: "#808080"
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// cli/_prompts.tsx
|
|
173
|
-
import { ConfirmInput, PasswordInput, Select, TextInput } from "@inkjs/ui";
|
|
174
|
-
import { Box as Box2, render as render2, Text as Text2 } from "ink";
|
|
175
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
176
|
-
function inkPrompt(ui) {
|
|
177
|
-
return new Promise((resolve) => {
|
|
178
|
-
const app = render2(
|
|
179
|
-
ui((value) => {
|
|
180
|
-
resolve(value);
|
|
181
|
-
app.unmount();
|
|
182
|
-
})
|
|
183
|
-
);
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
function askPassword(message) {
|
|
187
|
-
return inkPrompt((done) => /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
188
|
-
/* @__PURE__ */ jsxs2(Text2, { children: [
|
|
189
|
-
message,
|
|
190
|
-
": "
|
|
191
|
-
] }),
|
|
192
|
-
/* @__PURE__ */ jsx2(PasswordInput, { onSubmit: done })
|
|
193
|
-
] }));
|
|
194
|
-
}
|
|
195
|
-
function askText(message, defaultValue) {
|
|
196
|
-
return inkPrompt((done) => /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
197
|
-
/* @__PURE__ */ jsxs2(Text2, { color: COLORS.interactive, children: [
|
|
198
|
-
message,
|
|
199
|
-
" \u203A "
|
|
200
|
-
] }),
|
|
201
|
-
/* @__PURE__ */ jsx2(TextInput, { placeholder: defaultValue, onSubmit: (value) => done(value || defaultValue) })
|
|
202
|
-
] }));
|
|
203
|
-
}
|
|
204
|
-
var init_prompts = __esm({
|
|
205
|
-
"cli/_prompts.tsx"() {
|
|
206
|
-
"use strict";
|
|
207
|
-
init_ink();
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
// cli/_discover.ts
|
|
212
|
-
import fs from "node:fs/promises";
|
|
213
|
-
import path from "node:path";
|
|
214
|
-
import { humanId } from "human-id";
|
|
215
|
-
function resolveCwd() {
|
|
216
|
-
return process.env.INIT_CWD || process.cwd();
|
|
217
|
-
}
|
|
218
|
-
function isDevMode(script) {
|
|
219
|
-
script ??= process.argv[1] ?? "";
|
|
220
|
-
return script.endsWith(".ts") || script.endsWith(".tsx");
|
|
221
|
-
}
|
|
222
|
-
function generateSlug() {
|
|
223
|
-
return humanId({ separator: "-", capitalize: false });
|
|
224
|
-
}
|
|
225
|
-
async function readAuthConfig() {
|
|
226
|
-
try {
|
|
227
|
-
return JSON.parse(await fs.readFile(CONFIG_FILE, "utf-8"));
|
|
228
|
-
} catch {
|
|
229
|
-
return {};
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
async function writeAuthConfig(config) {
|
|
233
|
-
await fs.mkdir(CONFIG_DIR, { recursive: true });
|
|
234
|
-
await fs.writeFile(CONFIG_FILE, `${JSON.stringify(config, null, 2)}
|
|
235
|
-
`);
|
|
236
|
-
if (process.platform !== "win32") {
|
|
237
|
-
await fs.chmod(CONFIG_FILE, 384);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
async function getApiKey() {
|
|
241
|
-
const config = await readAuthConfig();
|
|
242
|
-
if (config.assemblyai_api_key) {
|
|
243
|
-
process.env.ASSEMBLYAI_API_KEY = config.assemblyai_api_key;
|
|
244
|
-
return config.assemblyai_api_key;
|
|
245
|
-
}
|
|
246
|
-
let key;
|
|
247
|
-
while (!key) {
|
|
248
|
-
key = await askPassword("ASSEMBLYAI_API_KEY");
|
|
249
|
-
}
|
|
250
|
-
config.assemblyai_api_key = key;
|
|
251
|
-
process.env.ASSEMBLYAI_API_KEY = key;
|
|
252
|
-
await writeAuthConfig(config);
|
|
253
|
-
return key;
|
|
254
|
-
}
|
|
255
|
-
async function readProjectConfig(agentDir) {
|
|
256
|
-
try {
|
|
257
|
-
return JSON.parse(await fs.readFile(path.join(agentDir, ".aai", "project.json"), "utf-8"));
|
|
258
|
-
} catch {
|
|
259
|
-
return null;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
async function writeProjectConfig(agentDir, data) {
|
|
263
|
-
const aaiDir = path.join(agentDir, ".aai");
|
|
264
|
-
await fs.mkdir(aaiDir, { recursive: true });
|
|
265
|
-
await fs.writeFile(path.join(aaiDir, "project.json"), `${JSON.stringify(data, null, 2)}
|
|
266
|
-
`);
|
|
267
|
-
}
|
|
268
|
-
async function getServerInfo(cwd, explicitServer, explicitApiKey) {
|
|
269
|
-
const config = await readProjectConfig(cwd);
|
|
270
|
-
if (!config) {
|
|
271
|
-
throw new Error("No .aai/project.json found \u2014 deploy first with `aai deploy`");
|
|
272
|
-
}
|
|
273
|
-
const apiKey = explicitApiKey ?? await getApiKey();
|
|
274
|
-
const serverUrl = resolveServerUrl(explicitServer, config.serverUrl);
|
|
275
|
-
return { serverUrl, slug: config.slug, apiKey };
|
|
276
|
-
}
|
|
277
|
-
function resolveServerUrl(explicit, configUrl) {
|
|
278
|
-
return explicit || configUrl || (isDevMode() ? "http://localhost:3100" : DEFAULT_SERVER);
|
|
279
|
-
}
|
|
280
|
-
async function fileExists(p) {
|
|
281
|
-
try {
|
|
282
|
-
await fs.access(p);
|
|
283
|
-
return true;
|
|
284
|
-
} catch {
|
|
285
|
-
return false;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
async function loadAgent(dir) {
|
|
289
|
-
const hasAgentTs = await fileExists(path.join(dir, "agent.ts"));
|
|
290
|
-
if (!hasAgentTs) return null;
|
|
291
|
-
const config = await readProjectConfig(dir);
|
|
292
|
-
const slug = config?.slug ?? generateSlug();
|
|
293
|
-
const clientEntry = await fileExists(path.join(dir, "client.tsx")) ? path.join(dir, "client.tsx") : "";
|
|
294
|
-
return {
|
|
295
|
-
slug,
|
|
296
|
-
dir,
|
|
297
|
-
entryPoint: path.join(dir, "agent.ts"),
|
|
298
|
-
clientEntry
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
var CONFIG_DIR, CONFIG_FILE, DEFAULT_SERVER;
|
|
302
|
-
var init_discover = __esm({
|
|
303
|
-
"cli/_discover.ts"() {
|
|
304
|
-
"use strict";
|
|
305
|
-
init_prompts();
|
|
306
|
-
CONFIG_DIR = path.join(process.env.HOME ?? process.env.USERPROFILE ?? ".", ".config", "aai");
|
|
307
|
-
CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
308
|
-
DEFAULT_SERVER = "https://aai-agent.fly.dev";
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
// cli/_init.ts
|
|
313
|
-
var init_exports = {};
|
|
314
|
-
__export(init_exports, {
|
|
315
|
-
listTemplates: () => listTemplates,
|
|
316
|
-
runInit: () => runInit
|
|
317
|
-
});
|
|
318
|
-
import fs2 from "node:fs/promises";
|
|
319
|
-
import path2 from "node:path";
|
|
320
|
-
async function listTemplates(dir) {
|
|
321
|
-
const templates = [];
|
|
322
|
-
const entries = await fs2.readdir(dir, { withFileTypes: true });
|
|
323
|
-
for (const entry of entries) {
|
|
324
|
-
if (entry.isDirectory() && !entry.name.startsWith("_")) {
|
|
325
|
-
templates.push(entry.name);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
return templates.sort();
|
|
329
|
-
}
|
|
330
|
-
async function copyDirNoOverwrite(src, dest) {
|
|
331
|
-
const entries = await fs2.readdir(src, { recursive: true, withFileTypes: true });
|
|
332
|
-
for (const entry of entries) {
|
|
333
|
-
if (!entry.isFile()) continue;
|
|
334
|
-
const rel = path2.relative(src, path2.join(entry.parentPath, entry.name));
|
|
335
|
-
const destPath = path2.join(dest, rel);
|
|
336
|
-
await fs2.mkdir(path2.dirname(destPath), { recursive: true });
|
|
337
|
-
try {
|
|
338
|
-
await fs2.copyFile(path2.join(src, rel), destPath, fs2.constants.COPYFILE_EXCL);
|
|
339
|
-
} catch (err) {
|
|
340
|
-
if (err.code !== "EEXIST") throw err;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
async function runInit(opts) {
|
|
345
|
-
const { targetDir, template, templatesDir } = opts;
|
|
346
|
-
const available = await listTemplates(templatesDir);
|
|
347
|
-
if (!available.includes(template)) {
|
|
348
|
-
throw new Error(`unknown template '${template}' -- available: ${available.join(", ")}`);
|
|
349
|
-
}
|
|
350
|
-
await fs2.cp(path2.join(templatesDir, template), targetDir, { recursive: true, force: true });
|
|
351
|
-
await copyDirNoOverwrite(path2.join(templatesDir, "_shared"), targetDir);
|
|
352
|
-
try {
|
|
353
|
-
await fs2.copyFile(path2.join(targetDir, ".env.example"), path2.join(targetDir, ".env"));
|
|
354
|
-
} catch {
|
|
355
|
-
}
|
|
356
|
-
const readmePath = path2.join(targetDir, "README.md");
|
|
357
|
-
const slug = path2.basename(path2.resolve(targetDir));
|
|
358
|
-
const readme = `# ${slug}
|
|
359
|
-
|
|
360
|
-
A voice agent built with [aai](https://github.com/anthropics/aai).
|
|
361
|
-
|
|
362
|
-
## Getting started
|
|
363
|
-
|
|
364
|
-
\`\`\`sh
|
|
365
|
-
npm install # Install dependencies
|
|
366
|
-
npm run dev # Run locally (opens browser)
|
|
367
|
-
npm run deploy # Deploy to production
|
|
368
|
-
\`\`\`
|
|
369
|
-
|
|
370
|
-
## Environment variables
|
|
371
|
-
|
|
372
|
-
Secrets are managed on the server, not in local files:
|
|
373
|
-
|
|
374
|
-
\`\`\`sh
|
|
375
|
-
aai env add MY_KEY # Set a secret (prompts for value)
|
|
376
|
-
aai env ls # List secret names
|
|
377
|
-
aai env pull # Pull names into .env for reference
|
|
378
|
-
aai env rm MY_KEY # Remove a secret
|
|
379
|
-
\`\`\`
|
|
380
|
-
|
|
381
|
-
Access secrets in your agent via \`ctx.env.MY_KEY\`.
|
|
382
|
-
|
|
383
|
-
## Learn more
|
|
384
|
-
|
|
385
|
-
See \`CLAUDE.md\` for the full agent API reference.
|
|
386
|
-
`;
|
|
387
|
-
try {
|
|
388
|
-
await fs2.writeFile(readmePath, readme, { flag: "wx" });
|
|
389
|
-
} catch (err) {
|
|
390
|
-
if (err.code !== "EEXIST") throw err;
|
|
391
|
-
}
|
|
392
|
-
return targetDir;
|
|
393
|
-
}
|
|
394
|
-
var init_init = __esm({
|
|
395
|
-
"cli/_init.ts"() {
|
|
396
|
-
"use strict";
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
// cli/_bundler.ts
|
|
401
|
-
import fs3 from "node:fs/promises";
|
|
402
|
-
import path3 from "node:path";
|
|
403
|
-
import preact from "@preact/preset-vite";
|
|
404
|
-
import tailwindcss from "@tailwindcss/vite";
|
|
405
|
-
import { build } from "vite";
|
|
406
|
-
function workerEntryPlugin() {
|
|
407
|
-
const virtualId = "virtual:worker-entry";
|
|
408
|
-
const resolvedId = `\0${virtualId}`;
|
|
409
|
-
return {
|
|
410
|
-
name: "aai-worker-entry",
|
|
411
|
-
resolveId(source) {
|
|
412
|
-
return source === virtualId ? resolvedId : null;
|
|
413
|
-
},
|
|
414
|
-
load(id) {
|
|
415
|
-
if (id !== resolvedId) return null;
|
|
416
|
-
return [
|
|
417
|
-
`import agent from "./agent.ts";`,
|
|
418
|
-
`import { initWorker } from "@alexkroman1/aai/worker-shim";`,
|
|
419
|
-
`initWorker(agent);`
|
|
420
|
-
].join("\n");
|
|
421
|
-
}
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
async function readDirFiles(dir) {
|
|
425
|
-
let entries;
|
|
426
|
-
try {
|
|
427
|
-
entries = await fs3.readdir(dir, { recursive: true, withFileTypes: true });
|
|
428
|
-
} catch {
|
|
429
|
-
return {};
|
|
430
|
-
}
|
|
431
|
-
const files = {};
|
|
432
|
-
await Promise.all(
|
|
433
|
-
entries.filter((e) => e.isFile()).map(async (e) => {
|
|
434
|
-
const full = path3.join(e.parentPath, e.name);
|
|
435
|
-
files[path3.relative(dir, full)] = await fs3.readFile(full, "utf-8");
|
|
436
|
-
})
|
|
437
|
-
);
|
|
438
|
-
return files;
|
|
439
|
-
}
|
|
440
|
-
async function bundleAgent(agent, opts) {
|
|
441
|
-
const aaiDir = path3.join(agent.dir, ".aai");
|
|
442
|
-
const buildDir = path3.join(aaiDir, "build");
|
|
443
|
-
const clientDir = path3.join(aaiDir, "client");
|
|
444
|
-
const devMode = isDevMode();
|
|
445
|
-
const devResolve = devMode ? { conditions: ["source"] } : {};
|
|
446
|
-
try {
|
|
447
|
-
await build({
|
|
448
|
-
configFile: false,
|
|
449
|
-
root: agent.dir,
|
|
450
|
-
logLevel: "warn",
|
|
451
|
-
plugins: [workerEntryPlugin()],
|
|
452
|
-
resolve: devResolve,
|
|
453
|
-
build: {
|
|
454
|
-
rollupOptions: {
|
|
455
|
-
input: "virtual:worker-entry",
|
|
456
|
-
output: { format: "es", entryFileNames: "worker.js" }
|
|
457
|
-
},
|
|
458
|
-
outDir: buildDir,
|
|
459
|
-
emptyOutDir: true,
|
|
460
|
-
minify: true,
|
|
461
|
-
target: "es2022"
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
} catch (err) {
|
|
465
|
-
throw new BundleError(errorMessage(err));
|
|
466
|
-
}
|
|
467
|
-
const skipClient = opts?.skipClient || !agent.clientEntry;
|
|
468
|
-
if (!skipClient) {
|
|
469
|
-
try {
|
|
470
|
-
await build({
|
|
471
|
-
root: agent.dir,
|
|
472
|
-
base: "./",
|
|
473
|
-
logLevel: "warn",
|
|
474
|
-
plugins: [preact(), tailwindcss()],
|
|
475
|
-
resolve: {
|
|
476
|
-
...devResolve,
|
|
477
|
-
...devMode && { dedupe: ["preact", "@preact/signals"] }
|
|
478
|
-
},
|
|
479
|
-
build: {
|
|
480
|
-
outDir: clientDir,
|
|
481
|
-
emptyOutDir: true,
|
|
482
|
-
minify: true,
|
|
483
|
-
target: "es2022"
|
|
484
|
-
}
|
|
485
|
-
});
|
|
486
|
-
} catch (err) {
|
|
487
|
-
throw new BundleError(errorMessage(err));
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
const worker = await fs3.readFile(path3.join(buildDir, "worker.js"), "utf-8");
|
|
491
|
-
const clientFiles = await readDirFiles(clientDir);
|
|
492
|
-
return {
|
|
493
|
-
worker,
|
|
494
|
-
clientFiles,
|
|
495
|
-
clientDir,
|
|
496
|
-
workerBytes: Buffer.byteLength(worker)
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
var BundleError;
|
|
500
|
-
var init_bundler = __esm({
|
|
501
|
-
"cli/_bundler.ts"() {
|
|
502
|
-
"use strict";
|
|
503
|
-
init_utils();
|
|
504
|
-
init_discover();
|
|
505
|
-
BundleError = class extends Error {
|
|
506
|
-
constructor(message) {
|
|
507
|
-
super(message);
|
|
508
|
-
this.name = "BundleError";
|
|
509
|
-
}
|
|
510
|
-
};
|
|
511
|
-
}
|
|
512
|
-
});
|
|
513
|
-
|
|
514
|
-
// cli/_build.tsx
|
|
515
|
-
var build_exports = {};
|
|
516
|
-
__export(build_exports, {
|
|
517
|
-
buildAgentBundle: () => buildAgentBundle,
|
|
518
|
-
runBuildCommand: () => runBuildCommand
|
|
519
|
-
});
|
|
520
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
521
|
-
async function buildAgentBundle(cwd, log, opts) {
|
|
522
|
-
const agent = await loadAgent(cwd);
|
|
523
|
-
if (!agent) {
|
|
524
|
-
throw new Error("No agent found \u2014 run `aai init` first");
|
|
525
|
-
}
|
|
526
|
-
log(/* @__PURE__ */ jsx3(Step, { action: "Bundle", msg: agent.slug }));
|
|
527
|
-
let bundle;
|
|
528
|
-
try {
|
|
529
|
-
bundle = await bundleAgent(agent);
|
|
530
|
-
} catch (err) {
|
|
531
|
-
if (err instanceof BundleError) {
|
|
532
|
-
throw new Error(`Bundle failed: ${err.message}`);
|
|
533
|
-
}
|
|
534
|
-
throw err;
|
|
535
|
-
}
|
|
536
|
-
const kb = (bundle.workerBytes / 1024).toFixed(1);
|
|
537
|
-
const clientCount = Object.keys(bundle.clientFiles).length;
|
|
538
|
-
log(/* @__PURE__ */ jsx3(Info, { msg: `worker: ${kb} KB, client: ${clientCount} file(s)` }));
|
|
539
|
-
if (agent.clientEntry && !opts?.skipRenderCheck) {
|
|
540
|
-
const renderCheckPath = "../ui/_render_check.ts";
|
|
541
|
-
const mod = await import(
|
|
542
|
-
/* @vite-ignore */
|
|
543
|
-
renderCheckPath
|
|
544
|
-
).catch(() => null);
|
|
545
|
-
if (mod) {
|
|
546
|
-
log(/* @__PURE__ */ jsx3(Step, { action: "Render", msg: "check" }));
|
|
547
|
-
try {
|
|
548
|
-
await mod.renderCheck(agent.clientEntry, cwd);
|
|
549
|
-
} catch (err) {
|
|
550
|
-
throw new Error(`Render check failed: ${errorMessage(err)}`);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
return bundle;
|
|
555
|
-
}
|
|
556
|
-
async function runBuildCommand(cwd) {
|
|
557
|
-
await runWithInk(async ({ log }) => {
|
|
558
|
-
await buildAgentBundle(cwd, log);
|
|
559
|
-
log(/* @__PURE__ */ jsx3(Step, { action: "Build", msg: "ok" }));
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
var init_build = __esm({
|
|
563
|
-
"cli/_build.tsx"() {
|
|
564
|
-
"use strict";
|
|
565
|
-
init_utils();
|
|
566
|
-
init_bundler();
|
|
567
|
-
init_discover();
|
|
568
|
-
init_ink();
|
|
569
|
-
}
|
|
570
|
-
});
|
|
571
|
-
|
|
572
|
-
// cli/_deploy.ts
|
|
573
|
-
async function attemptDeploy(fetchFn, url, slug, apiKey, env, worker, clientFiles) {
|
|
574
|
-
try {
|
|
575
|
-
return await fetchFn(`${url}/${slug}/deploy`, {
|
|
576
|
-
method: "POST",
|
|
577
|
-
headers: {
|
|
578
|
-
"Content-Type": "application/json",
|
|
579
|
-
Authorization: `Bearer ${apiKey}`
|
|
580
|
-
},
|
|
581
|
-
body: JSON.stringify({
|
|
582
|
-
env,
|
|
583
|
-
worker,
|
|
584
|
-
clientFiles
|
|
585
|
-
})
|
|
586
|
-
});
|
|
587
|
-
} catch {
|
|
588
|
-
throw new Error(`deployment failed: could not reach ${url}`);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
async function runDeploy(opts) {
|
|
592
|
-
const { worker, clientFiles } = opts.bundle;
|
|
593
|
-
const fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
594
|
-
let slug = opts.slug;
|
|
595
|
-
for (let i = 0; i < MAX_RETRIES; i++) {
|
|
596
|
-
const resp = await attemptDeploy(
|
|
597
|
-
fetchFn,
|
|
598
|
-
opts.url,
|
|
599
|
-
slug,
|
|
600
|
-
opts.apiKey,
|
|
601
|
-
opts.env,
|
|
602
|
-
worker,
|
|
603
|
-
clientFiles
|
|
604
|
-
);
|
|
605
|
-
if (resp.ok) {
|
|
606
|
-
return { slug };
|
|
607
|
-
}
|
|
608
|
-
const text = await resp.text();
|
|
609
|
-
if (resp.status === 403 && text.includes("Slug")) {
|
|
610
|
-
slug = generateSlug();
|
|
611
|
-
continue;
|
|
612
|
-
}
|
|
613
|
-
throw new Error(`deploy failed (${resp.status}): ${text}`);
|
|
614
|
-
}
|
|
615
|
-
throw new Error(`deploy failed: could not find available slug after ${MAX_RETRIES} attempts`);
|
|
616
|
-
}
|
|
617
|
-
var MAX_RETRIES;
|
|
618
|
-
var init_deploy = __esm({
|
|
619
|
-
"cli/_deploy.ts"() {
|
|
620
|
-
"use strict";
|
|
621
|
-
init_discover();
|
|
622
|
-
MAX_RETRIES = 20;
|
|
623
|
-
}
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
// cli/deploy.tsx
|
|
627
|
-
var deploy_exports = {};
|
|
628
|
-
__export(deploy_exports, {
|
|
629
|
-
runDeployCommand: () => runDeployCommand
|
|
630
|
-
});
|
|
631
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
632
|
-
async function deployBundle(opts) {
|
|
633
|
-
const { bundle, serverUrl, apiKey, cwd, log } = opts;
|
|
634
|
-
let { slug } = opts;
|
|
635
|
-
log(/* @__PURE__ */ jsx4(Step, { action: "Deploy", msg: slug }));
|
|
636
|
-
const deployed = await runDeploy({
|
|
637
|
-
url: serverUrl,
|
|
638
|
-
bundle,
|
|
639
|
-
env: { ASSEMBLYAI_API_KEY: apiKey },
|
|
640
|
-
slug,
|
|
641
|
-
apiKey
|
|
642
|
-
});
|
|
643
|
-
slug = deployed.slug;
|
|
644
|
-
await writeProjectConfig(cwd, { slug, serverUrl });
|
|
645
|
-
const agentUrl = `${serverUrl}/${slug}`;
|
|
646
|
-
log(/* @__PURE__ */ jsx4(Step, { action: "Ready", msg: agentUrl }));
|
|
647
|
-
return agentUrl;
|
|
648
|
-
}
|
|
649
|
-
async function runDeployCommand(opts) {
|
|
650
|
-
const { cwd } = opts;
|
|
651
|
-
const dryRun = opts.dryRun ?? false;
|
|
652
|
-
const apiKey = dryRun ? "" : await getApiKey();
|
|
653
|
-
const projectConfig = await readProjectConfig(cwd);
|
|
654
|
-
const serverUrl = resolveServerUrl(opts.server, projectConfig?.serverUrl);
|
|
655
|
-
const slug = projectConfig?.slug ?? generateSlug();
|
|
656
|
-
await runWithInk(async ({ log }) => {
|
|
657
|
-
const bundle = await buildAgentBundle(cwd, log);
|
|
658
|
-
if (dryRun) {
|
|
659
|
-
log(/* @__PURE__ */ jsx4(StepInfo, { action: "Dry run", msg: `would deploy as ${slug}` }));
|
|
660
|
-
return;
|
|
661
|
-
}
|
|
662
|
-
await deployBundle({ bundle, serverUrl, apiKey, slug, cwd, log });
|
|
663
|
-
});
|
|
664
|
-
}
|
|
665
|
-
var init_deploy2 = __esm({
|
|
666
|
-
"cli/deploy.tsx"() {
|
|
667
|
-
"use strict";
|
|
668
|
-
init_build();
|
|
669
|
-
init_deploy();
|
|
670
|
-
init_discover();
|
|
671
|
-
init_ink();
|
|
672
|
-
}
|
|
673
|
-
});
|
|
674
|
-
|
|
675
|
-
// cli/init.tsx
|
|
676
|
-
var init_exports2 = {};
|
|
677
|
-
__export(init_exports2, {
|
|
678
|
-
runInitCommand: () => runInitCommand
|
|
679
|
-
});
|
|
680
|
-
import { execFile } from "node:child_process";
|
|
681
|
-
import fs4 from "node:fs/promises";
|
|
682
|
-
import path4 from "node:path";
|
|
683
|
-
import { fileURLToPath } from "node:url";
|
|
684
|
-
import { promisify } from "node:util";
|
|
685
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
686
|
-
async function rewriteDevDeps(cwd, cliDir2) {
|
|
687
|
-
const monorepoRoot = path4.join(cliDir2, "..");
|
|
688
|
-
const pkgJsonPath2 = path4.join(cwd, "package.json");
|
|
689
|
-
const pkgJson2 = JSON.parse(await fs4.readFile(pkgJsonPath2, "utf-8"));
|
|
690
|
-
const rootPkg = JSON.parse(await fs4.readFile(path4.join(monorepoRoot, "package.json"), "utf-8"));
|
|
691
|
-
const rootPkgName = rootPkg.name;
|
|
692
|
-
if (pkgJson2.dependencies[rootPkgName]) {
|
|
693
|
-
pkgJson2.dependencies[rootPkgName] = `file:${monorepoRoot}`;
|
|
694
|
-
}
|
|
695
|
-
await fs4.writeFile(pkgJsonPath2, `${JSON.stringify(pkgJson2, null, 2)}
|
|
696
|
-
`);
|
|
697
|
-
}
|
|
698
|
-
async function installDeps(cwd, log) {
|
|
699
|
-
if (await fileExists(path4.join(cwd, "node_modules"))) return;
|
|
700
|
-
let pkgJson2;
|
|
701
|
-
try {
|
|
702
|
-
pkgJson2 = JSON.parse(await fs4.readFile(path4.join(cwd, "package.json"), "utf-8"));
|
|
703
|
-
} catch {
|
|
704
|
-
pkgJson2 = {};
|
|
705
|
-
}
|
|
706
|
-
const deps = Object.keys(pkgJson2.dependencies ?? {});
|
|
707
|
-
const devDeps = Object.keys(pkgJson2.devDependencies ?? {});
|
|
708
|
-
if (deps.length > 0) {
|
|
709
|
-
log(/* @__PURE__ */ jsx5(Step, { action: "Install", msg: deps.join(", ") }));
|
|
710
|
-
}
|
|
711
|
-
if (devDeps.length > 0) {
|
|
712
|
-
log(/* @__PURE__ */ jsx5(Step, { action: "Install", msg: `dev: ${devDeps.join(", ")}` }));
|
|
713
|
-
}
|
|
714
|
-
try {
|
|
715
|
-
await execFileAsync("npm", ["install"], { cwd });
|
|
716
|
-
} catch {
|
|
717
|
-
log(/* @__PURE__ */ jsx5(Warn, { msg: "npm install failed" }));
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
async function runInitCommand(opts, extra) {
|
|
721
|
-
await getApiKey();
|
|
722
|
-
let dir = opts.dir;
|
|
723
|
-
if (!dir) {
|
|
724
|
-
dir = await askText("What is your project named?", "my-voice-agent");
|
|
725
|
-
}
|
|
726
|
-
const cwd = path4.resolve(resolveCwd(), dir);
|
|
727
|
-
if (!opts.force && await fileExists(path4.join(cwd, "agent.ts"))) {
|
|
728
|
-
throw new Error(
|
|
729
|
-
`agent.ts already exists in this directory. Use ${interactive("--force")} to overwrite.`
|
|
730
|
-
);
|
|
731
|
-
}
|
|
732
|
-
const cliDir2 = path4.dirname(fileURLToPath(import.meta.url));
|
|
733
|
-
const templatesDir = path4.join(cliDir2, "..", "templates");
|
|
734
|
-
const { runInit: runInit2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
735
|
-
const template = opts.template || "simple";
|
|
736
|
-
await runWithInk(async ({ log }) => {
|
|
737
|
-
log(/* @__PURE__ */ jsx5(Step, { action: "Create", msg: dir }));
|
|
738
|
-
await runInit2({ targetDir: cwd, template, templatesDir });
|
|
739
|
-
if (isDevMode()) {
|
|
740
|
-
await rewriteDevDeps(cwd, cliDir2);
|
|
741
|
-
}
|
|
742
|
-
await installDeps(cwd, log);
|
|
743
|
-
});
|
|
744
|
-
process.chdir(cwd);
|
|
745
|
-
delete process.env.INIT_CWD;
|
|
746
|
-
if (!extra?.quiet) {
|
|
747
|
-
const { runDeployCommand: runDeployCommand2 } = await Promise.resolve().then(() => (init_deploy2(), deploy_exports));
|
|
748
|
-
await runDeployCommand2({ cwd });
|
|
749
|
-
}
|
|
750
|
-
return cwd;
|
|
751
|
-
}
|
|
752
|
-
var execFileAsync;
|
|
753
|
-
var init_init2 = __esm({
|
|
754
|
-
"cli/init.tsx"() {
|
|
755
|
-
"use strict";
|
|
756
|
-
init_discover();
|
|
757
|
-
init_ink();
|
|
758
|
-
init_prompts();
|
|
759
|
-
execFileAsync = promisify(execFile);
|
|
760
|
-
}
|
|
761
|
-
});
|
|
762
|
-
|
|
763
|
-
// sdk/protocol.ts
|
|
764
|
-
import { z } from "zod";
|
|
765
|
-
var DEFAULT_TTS_SAMPLE_RATE, AUDIO_FORMAT, KvRequestSchema, VectorRequestSchema, HOOK_TIMEOUT_MS, TOOL_EXECUTION_TIMEOUT_MS, SessionErrorCodeSchema, ev, textEv, turnOrder, ClientEventSchema, ClientMessageSchema;
|
|
766
|
-
var init_protocol = __esm({
|
|
767
|
-
"sdk/protocol.ts"() {
|
|
768
|
-
"use strict";
|
|
769
|
-
DEFAULT_TTS_SAMPLE_RATE = 24e3;
|
|
770
|
-
AUDIO_FORMAT = "pcm16";
|
|
771
|
-
KvRequestSchema = z.discriminatedUnion("op", [
|
|
772
|
-
z.object({ op: z.literal("get"), key: z.string().min(1) }),
|
|
773
|
-
z.object({
|
|
774
|
-
op: z.literal("set"),
|
|
775
|
-
key: z.string().min(1),
|
|
776
|
-
value: z.string(),
|
|
777
|
-
ttl: z.number().int().positive().optional()
|
|
778
|
-
}),
|
|
779
|
-
z.object({ op: z.literal("del"), key: z.string().min(1) }),
|
|
780
|
-
z.object({
|
|
781
|
-
op: z.literal("list"),
|
|
782
|
-
prefix: z.string(),
|
|
783
|
-
limit: z.number().int().positive().optional(),
|
|
784
|
-
reverse: z.boolean().optional()
|
|
785
|
-
}),
|
|
786
|
-
z.object({ op: z.literal("keys"), pattern: z.string().optional() })
|
|
787
|
-
]);
|
|
788
|
-
VectorRequestSchema = z.discriminatedUnion("op", [
|
|
789
|
-
z.object({
|
|
790
|
-
op: z.literal("upsert"),
|
|
791
|
-
id: z.string().min(1),
|
|
792
|
-
data: z.string().min(1),
|
|
793
|
-
metadata: z.record(z.string(), z.unknown()).optional()
|
|
794
|
-
}),
|
|
795
|
-
z.object({
|
|
796
|
-
op: z.literal("query"),
|
|
797
|
-
text: z.string().min(1),
|
|
798
|
-
topK: z.number().int().positive().max(100).optional(),
|
|
799
|
-
filter: z.string().optional()
|
|
800
|
-
}),
|
|
801
|
-
z.object({
|
|
802
|
-
op: z.literal("remove"),
|
|
803
|
-
ids: z.array(z.string().min(1)).min(1)
|
|
804
|
-
})
|
|
805
|
-
]);
|
|
806
|
-
HOOK_TIMEOUT_MS = 5e3;
|
|
807
|
-
TOOL_EXECUTION_TIMEOUT_MS = 3e4;
|
|
808
|
-
SessionErrorCodeSchema = z.enum([
|
|
809
|
-
"stt",
|
|
810
|
-
"llm",
|
|
811
|
-
"tts",
|
|
812
|
-
"tool",
|
|
813
|
-
"protocol",
|
|
814
|
-
"connection",
|
|
815
|
-
"audio",
|
|
816
|
-
"internal"
|
|
817
|
-
]);
|
|
818
|
-
ev = (t) => z.object({ type: z.literal(t) });
|
|
819
|
-
textEv = (t) => z.object({ type: z.literal(t), text: z.string() });
|
|
820
|
-
turnOrder = z.number().int().nonnegative().optional();
|
|
821
|
-
ClientEventSchema = z.discriminatedUnion("type", [
|
|
822
|
-
ev("speech_started"),
|
|
823
|
-
ev("speech_stopped"),
|
|
824
|
-
z.object({ type: z.literal("transcript"), text: z.string(), isFinal: z.boolean(), turnOrder }),
|
|
825
|
-
textEv("turn").extend({ turnOrder }),
|
|
826
|
-
textEv("chat"),
|
|
827
|
-
textEv("chat_delta"),
|
|
828
|
-
z.object({
|
|
829
|
-
type: z.literal("tool_call_start"),
|
|
830
|
-
toolCallId: z.string(),
|
|
831
|
-
toolName: z.string(),
|
|
832
|
-
args: z.record(z.string(), z.unknown())
|
|
833
|
-
}),
|
|
834
|
-
z.object({
|
|
835
|
-
type: z.literal("tool_call_done"),
|
|
836
|
-
toolCallId: z.string(),
|
|
837
|
-
result: z.string().max(4e3)
|
|
838
|
-
}),
|
|
839
|
-
ev("tts_done"),
|
|
840
|
-
ev("cancelled"),
|
|
841
|
-
ev("reset"),
|
|
842
|
-
z.object({ type: z.literal("error"), code: SessionErrorCodeSchema, message: z.string() })
|
|
843
|
-
]);
|
|
844
|
-
ClientMessageSchema = z.discriminatedUnion("type", [
|
|
845
|
-
ev("audio_ready"),
|
|
846
|
-
ev("cancel"),
|
|
847
|
-
ev("reset"),
|
|
848
|
-
z.object({
|
|
849
|
-
type: z.literal("history"),
|
|
850
|
-
messages: z.array(z.object({ role: z.enum(["user", "assistant"]), text: z.string().max(1e5) })).max(200)
|
|
851
|
-
})
|
|
852
|
-
]);
|
|
853
|
-
}
|
|
854
|
-
});
|
|
855
|
-
|
|
856
|
-
// sdk/runtime.ts
|
|
857
|
-
var _log, consoleLogger, noopMetrics, DEFAULT_S2S_CONFIG;
|
|
858
|
-
var init_runtime = __esm({
|
|
859
|
-
"sdk/runtime.ts"() {
|
|
860
|
-
"use strict";
|
|
861
|
-
init_protocol();
|
|
862
|
-
_log = (m) => (msg, ctx) => console[m](msg, ...ctx ? [ctx] : []);
|
|
863
|
-
consoleLogger = {
|
|
864
|
-
info: _log("log"),
|
|
865
|
-
warn: _log("warn"),
|
|
866
|
-
error: _log("error"),
|
|
867
|
-
debug: _log("debug")
|
|
868
|
-
};
|
|
869
|
-
noopMetrics = {
|
|
870
|
-
sessionsTotal: { inc() {
|
|
871
|
-
} },
|
|
872
|
-
sessionsActive: { inc() {
|
|
873
|
-
}, dec() {
|
|
874
|
-
} }
|
|
875
|
-
};
|
|
876
|
-
DEFAULT_S2S_CONFIG = {
|
|
877
|
-
wssUrl: "wss://speech-to-speech.us.assemblyai.com/v1/realtime",
|
|
878
|
-
inputSampleRate: DEFAULT_TTS_SAMPLE_RATE,
|
|
879
|
-
outputSampleRate: DEFAULT_TTS_SAMPLE_RATE
|
|
880
|
-
};
|
|
881
|
-
}
|
|
882
|
-
});
|
|
883
|
-
|
|
884
|
-
// sdk/s2s.ts
|
|
885
|
-
var s2s_exports = {};
|
|
886
|
-
__export(s2s_exports, {
|
|
887
|
-
connectS2s: () => connectS2s,
|
|
888
|
-
wrapOnStyleWebSocket: () => wrapOnStyleWebSocket
|
|
889
|
-
});
|
|
890
|
-
import { z as z2 } from "zod";
|
|
891
|
-
function uint8ToBase64(bytes) {
|
|
892
|
-
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
|
|
893
|
-
}
|
|
894
|
-
function base64ToUint8(base64) {
|
|
895
|
-
const buf = Buffer.from(base64, "base64");
|
|
896
|
-
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
897
|
-
}
|
|
898
|
-
function wrapOnStyleWebSocket(ws) {
|
|
899
|
-
const target = new EventTarget();
|
|
900
|
-
ws.on("open", () => target.dispatchEvent(new Event("open")));
|
|
901
|
-
ws.on("message", (data) => target.dispatchEvent(new MessageEvent("message", { data })));
|
|
902
|
-
ws.on("close", (code, reason) => {
|
|
903
|
-
const init = { reason: String(reason ?? "") };
|
|
904
|
-
if (typeof code === "number") init.code = code;
|
|
905
|
-
target.dispatchEvent(new CloseEvent("close", init));
|
|
906
|
-
});
|
|
907
|
-
ws.on(
|
|
908
|
-
"error",
|
|
909
|
-
(err) => target.dispatchEvent(
|
|
910
|
-
new ErrorEvent("error", {
|
|
911
|
-
message: errorMessage(err)
|
|
912
|
-
})
|
|
913
|
-
)
|
|
914
|
-
);
|
|
915
|
-
Object.defineProperties(target, {
|
|
916
|
-
readyState: { get: () => ws.readyState, enumerable: true },
|
|
917
|
-
send: { value: (data) => ws.send(data), enumerable: true },
|
|
918
|
-
close: { value: () => ws.close(), enumerable: true }
|
|
919
|
-
});
|
|
920
|
-
return target;
|
|
921
|
-
}
|
|
922
|
-
function dispatchS2sMessage(target, msg) {
|
|
923
|
-
const entry = S2S_DISPATCH[msg.type]?.(msg);
|
|
924
|
-
if (entry) target.dispatchEvent(new CustomEvent(entry[0], { detail: entry[1] }));
|
|
925
|
-
}
|
|
926
|
-
function connectS2s(opts) {
|
|
927
|
-
const { apiKey, config, createWebSocket, logger: log = consoleLogger } = opts;
|
|
928
|
-
return new Promise((resolve, reject) => {
|
|
929
|
-
log.info("S2S connecting", { url: config.wssUrl });
|
|
930
|
-
const ws = createWebSocket(config.wssUrl, {
|
|
931
|
-
headers: { Authorization: `Bearer ${apiKey}` }
|
|
932
|
-
});
|
|
933
|
-
const target = new EventTarget();
|
|
934
|
-
let opened = false;
|
|
935
|
-
function send(msg) {
|
|
936
|
-
if (ws.readyState !== WS_OPEN) return;
|
|
937
|
-
const json = JSON.stringify(msg);
|
|
938
|
-
if (msg.type !== "input.audio") {
|
|
939
|
-
log.info(
|
|
940
|
-
`S2S >> ${msg.type}`,
|
|
941
|
-
msg.type === "session.update" ? { payload: json } : void 0
|
|
942
|
-
);
|
|
943
|
-
}
|
|
944
|
-
ws.send(json);
|
|
945
|
-
}
|
|
946
|
-
const handle = Object.assign(target, {
|
|
947
|
-
sendAudio(audio) {
|
|
948
|
-
if (ws.readyState !== WS_OPEN) return;
|
|
949
|
-
ws.send(`{"type":"input.audio","audio":"${uint8ToBase64(audio)}"}`);
|
|
950
|
-
},
|
|
951
|
-
sendToolResult(callId, result) {
|
|
952
|
-
const msg = { type: "tool.result", call_id: callId, result };
|
|
953
|
-
log.info("S2S >> tool.result", { call_id: callId, resultLength: result.length });
|
|
954
|
-
send(msg);
|
|
955
|
-
},
|
|
956
|
-
updateSession(sessionConfig) {
|
|
957
|
-
send({ type: "session.update", session: sessionConfig });
|
|
958
|
-
},
|
|
959
|
-
resumeSession(sessionId) {
|
|
960
|
-
send({ type: "session.resume", session_id: sessionId });
|
|
961
|
-
},
|
|
962
|
-
close() {
|
|
963
|
-
log.info("S2S closing");
|
|
964
|
-
ws.close();
|
|
965
|
-
}
|
|
966
|
-
});
|
|
967
|
-
ws.addEventListener("open", () => {
|
|
968
|
-
opened = true;
|
|
969
|
-
log.info("S2S WebSocket open");
|
|
970
|
-
resolve(handle);
|
|
971
|
-
});
|
|
972
|
-
function tryParseJson(data) {
|
|
973
|
-
try {
|
|
974
|
-
return JSON.parse(String(data));
|
|
975
|
-
} catch {
|
|
976
|
-
log.warn("S2S << invalid JSON", { data: String(data).slice(0, 200) });
|
|
977
|
-
return void 0;
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
function handleAudioFastPath(obj) {
|
|
981
|
-
if (obj.type === "reply.audio" && typeof obj.data === "string") {
|
|
982
|
-
const audioBytes = base64ToUint8(obj.data);
|
|
983
|
-
target.dispatchEvent(new CustomEvent("audio", { detail: { audio: audioBytes } }));
|
|
984
|
-
return true;
|
|
985
|
-
}
|
|
986
|
-
return false;
|
|
987
|
-
}
|
|
988
|
-
function logIncoming(obj) {
|
|
989
|
-
if (obj.type === "reply.audio" || obj.type === "input.audio") return;
|
|
990
|
-
log.info(
|
|
991
|
-
`S2S << ${obj.type}`,
|
|
992
|
-
obj.type === "transcript.agent.delta" ? { delta: obj.delta } : void 0
|
|
993
|
-
);
|
|
994
|
-
}
|
|
995
|
-
function handleS2sMessage(ev2) {
|
|
996
|
-
const raw = tryParseJson(ev2.data);
|
|
997
|
-
if (raw === void 0) return;
|
|
998
|
-
const obj = raw;
|
|
999
|
-
logIncoming(obj);
|
|
1000
|
-
if (handleAudioFastPath(obj)) return;
|
|
1001
|
-
const parsed = S2sServerMessageSchema.safeParse(raw);
|
|
1002
|
-
if (!parsed.success) {
|
|
1003
|
-
log.warn(
|
|
1004
|
-
`S2S << unrecognised message type: ${obj.type ?? JSON.stringify(raw).slice(0, 200)}`
|
|
1005
|
-
);
|
|
1006
|
-
return;
|
|
1007
|
-
}
|
|
1008
|
-
dispatchS2sMessage(target, parsed.data);
|
|
1009
|
-
}
|
|
1010
|
-
ws.addEventListener("message", handleS2sMessage);
|
|
1011
|
-
ws.addEventListener("close", ((ev2) => {
|
|
1012
|
-
log.info("S2S WebSocket closed", {
|
|
1013
|
-
code: ev2.code ?? 0,
|
|
1014
|
-
reason: ev2.reason ?? ""
|
|
1015
|
-
});
|
|
1016
|
-
target.dispatchEvent(new CustomEvent("close"));
|
|
1017
|
-
}));
|
|
1018
|
-
ws.addEventListener("error", ((ev2) => {
|
|
1019
|
-
const message = ev2 instanceof ErrorEvent ? ev2.message : "WebSocket error";
|
|
1020
|
-
const errObj = new Error(message);
|
|
1021
|
-
log.error("S2S WebSocket error", { error: errObj.message });
|
|
1022
|
-
if (!opened) {
|
|
1023
|
-
reject(errObj);
|
|
1024
|
-
} else {
|
|
1025
|
-
target.dispatchEvent(
|
|
1026
|
-
new CustomEvent("error", {
|
|
1027
|
-
detail: { code: "ws_error", message: errObj.message }
|
|
1028
|
-
})
|
|
1029
|
-
);
|
|
1030
|
-
}
|
|
1031
|
-
}));
|
|
1032
|
-
});
|
|
1033
|
-
}
|
|
1034
|
-
var WS_OPEN, S2sServerMessageSchema, S2S_DISPATCH;
|
|
1035
|
-
var init_s2s = __esm({
|
|
1036
|
-
"sdk/s2s.ts"() {
|
|
1037
|
-
"use strict";
|
|
1038
|
-
init_utils();
|
|
1039
|
-
init_runtime();
|
|
1040
|
-
WS_OPEN = 1;
|
|
1041
|
-
S2sServerMessageSchema = z2.discriminatedUnion("type", [
|
|
1042
|
-
z2.object({ type: z2.literal("session.ready"), session_id: z2.string() }),
|
|
1043
|
-
z2.object({ type: z2.literal("session.updated") }).passthrough(),
|
|
1044
|
-
z2.object({ type: z2.literal("input.speech.started") }),
|
|
1045
|
-
z2.object({ type: z2.literal("input.speech.stopped") }),
|
|
1046
|
-
z2.object({ type: z2.literal("transcript.user.delta"), text: z2.string() }),
|
|
1047
|
-
z2.object({
|
|
1048
|
-
type: z2.literal("transcript.user"),
|
|
1049
|
-
item_id: z2.string(),
|
|
1050
|
-
text: z2.string()
|
|
1051
|
-
}),
|
|
1052
|
-
z2.object({ type: z2.literal("reply.started"), reply_id: z2.string() }),
|
|
1053
|
-
// reply.audio is handled on the fast path before Zod.
|
|
1054
|
-
z2.object({ type: z2.literal("transcript.agent.delta"), delta: z2.string() }).passthrough(),
|
|
1055
|
-
z2.object({ type: z2.literal("transcript.agent"), text: z2.string() }),
|
|
1056
|
-
z2.object({ type: z2.literal("reply.content_part.started") }).passthrough(),
|
|
1057
|
-
z2.object({ type: z2.literal("reply.content_part.done") }).passthrough(),
|
|
1058
|
-
z2.object({
|
|
1059
|
-
type: z2.literal("tool.call"),
|
|
1060
|
-
call_id: z2.string(),
|
|
1061
|
-
name: z2.string(),
|
|
1062
|
-
args: z2.record(z2.string(), z2.unknown()).optional().default({})
|
|
1063
|
-
}),
|
|
1064
|
-
z2.object({
|
|
1065
|
-
type: z2.literal("reply.done"),
|
|
1066
|
-
status: z2.string().optional()
|
|
1067
|
-
}),
|
|
1068
|
-
z2.object({
|
|
1069
|
-
type: z2.literal("session.error"),
|
|
1070
|
-
code: z2.string(),
|
|
1071
|
-
message: z2.string()
|
|
1072
|
-
}),
|
|
1073
|
-
// Connection-level error (bare "error" without "session." prefix).
|
|
1074
|
-
z2.object({
|
|
1075
|
-
type: z2.literal("error"),
|
|
1076
|
-
message: z2.string()
|
|
1077
|
-
})
|
|
1078
|
-
]);
|
|
1079
|
-
S2S_DISPATCH = {
|
|
1080
|
-
"session.ready": (m) => ["ready", { session_id: m.session_id }],
|
|
1081
|
-
"session.updated": (m) => ["session_updated", m],
|
|
1082
|
-
"input.speech.started": () => ["speech_started", void 0],
|
|
1083
|
-
"input.speech.stopped": () => ["speech_stopped", void 0],
|
|
1084
|
-
"transcript.user.delta": (m) => ["user_transcript_delta", { text: m.text }],
|
|
1085
|
-
"transcript.user": (m) => ["user_transcript", { item_id: m.item_id, text: m.text }],
|
|
1086
|
-
"reply.started": (m) => ["reply_started", { reply_id: m.reply_id }],
|
|
1087
|
-
"transcript.agent.delta": (m) => ["agent_transcript_delta", { text: m.delta }],
|
|
1088
|
-
"transcript.agent": (m) => ["agent_transcript", { text: m.text }],
|
|
1089
|
-
"tool.call": (m) => ["tool_call", { call_id: m.call_id, name: m.name, args: m.args }],
|
|
1090
|
-
"reply.done": (m) => ["reply_done", { status: m.status }],
|
|
1091
|
-
"session.error": (m) => [
|
|
1092
|
-
m.code === "session_not_found" || m.code === "session_forbidden" ? "session_expired" : "error",
|
|
1093
|
-
{ code: m.code, message: m.message }
|
|
1094
|
-
],
|
|
1095
|
-
error: (m) => ["error", { code: "connection", message: m.message }],
|
|
1096
|
-
"reply.content_part.started": () => void 0,
|
|
1097
|
-
"reply.content_part.done": () => void 0
|
|
1098
|
-
};
|
|
1099
|
-
}
|
|
1100
|
-
});
|
|
1101
|
-
|
|
1102
|
-
// sdk/_internal_types.ts
|
|
1103
|
-
import { z as z3 } from "zod";
|
|
1104
|
-
function agentToolsToSchemas(tools) {
|
|
1105
|
-
return Object.entries(tools).map(([name, def]) => ({
|
|
1106
|
-
name,
|
|
1107
|
-
description: def.description,
|
|
1108
|
-
parameters: z3.toJSONSchema(def.parameters ?? EMPTY_PARAMS)
|
|
1109
|
-
}));
|
|
1110
|
-
}
|
|
1111
|
-
var EMPTY_PARAMS;
|
|
1112
|
-
var init_internal_types = __esm({
|
|
1113
|
-
"sdk/_internal_types.ts"() {
|
|
1114
|
-
"use strict";
|
|
1115
|
-
EMPTY_PARAMS = z3.object({});
|
|
1116
|
-
}
|
|
1117
|
-
});
|
|
1118
|
-
|
|
1119
|
-
// sdk/types.ts
|
|
1120
|
-
function tool(def) {
|
|
1121
|
-
return def;
|
|
1122
|
-
}
|
|
1123
|
-
var DEFAULT_INSTRUCTIONS;
|
|
1124
|
-
var init_types = __esm({
|
|
1125
|
-
"sdk/types.ts"() {
|
|
1126
|
-
"use strict";
|
|
1127
|
-
DEFAULT_INSTRUCTIONS = `You are AAI, a helpful AI assistant.
|
|
1128
|
-
|
|
1129
|
-
Voice-First Rules:
|
|
1130
|
-
- Optimize for natural speech. Avoid jargon unless central to the answer. Use short, punchy sentences.
|
|
1131
|
-
- Never mention "search results," "sources," or "the provided text." Speak as if the knowledge is your own.
|
|
1132
|
-
- No visual formatting. Do not say "bullet point," "bold," or "bracketed one." If you need to list items, say "First," "Next," and "Finally."
|
|
1133
|
-
- Start with the most important information. No introductory filler.
|
|
1134
|
-
- Be concise. Keep answers to 1-3 sentences. For complex topics, provide a high-level summary.
|
|
1135
|
-
- Be confident. Avoid hedging phrases like "It seems that" or "I believe."
|
|
1136
|
-
- If you don't have enough information, say so directly rather than guessing.
|
|
1137
|
-
- Never use exclamation points. Keep your tone calm and conversational.`;
|
|
1138
|
-
}
|
|
1139
|
-
});
|
|
1140
|
-
|
|
1141
|
-
// sdk/builtin_tools.ts
|
|
1142
|
-
import { convert } from "html-to-text";
|
|
1143
|
-
import { z as z4 } from "zod";
|
|
1144
|
-
function fetchSignal(toolSignal) {
|
|
1145
|
-
return AbortSignal.any([toolSignal, AbortSignal.timeout(FETCH_TIMEOUT_MS)]);
|
|
1146
|
-
}
|
|
1147
|
-
function htmlToText(html) {
|
|
1148
|
-
return convert(html, { wordwrap: false });
|
|
1149
|
-
}
|
|
1150
|
-
function createWebSearch(fetchFn = globalThis.fetch) {
|
|
1151
|
-
return {
|
|
1152
|
-
description: "Search the web for current information, facts, news, or answers to questions. Returns a list of results with title, URL, and description. Use this when the user asks about something you don't know, need up-to-date information, or want to verify facts.",
|
|
1153
|
-
parameters: webSearchParams,
|
|
1154
|
-
async execute(args, ctx) {
|
|
1155
|
-
const { query, max_results: maxResults = 5 } = args;
|
|
1156
|
-
const apiKey = ctx.env.BRAVE_API_KEY ?? "";
|
|
1157
|
-
if (!apiKey) {
|
|
1158
|
-
return { error: "BRAVE_API_KEY is not set \u2014 web search unavailable" };
|
|
1159
|
-
}
|
|
1160
|
-
const url = `${BRAVE_SEARCH_URL}?${new URLSearchParams({
|
|
1161
|
-
q: query,
|
|
1162
|
-
count: String(maxResults),
|
|
1163
|
-
text_decorations: "false"
|
|
1164
|
-
})}`;
|
|
1165
|
-
const resp = await fetchFn(url, {
|
|
1166
|
-
headers: { "X-Subscription-Token": apiKey },
|
|
1167
|
-
signal: fetchSignal(ctx.abortSignal)
|
|
1168
|
-
});
|
|
1169
|
-
if (!resp.ok) return [];
|
|
1170
|
-
const raw = await resp.json();
|
|
1171
|
-
const data = BraveSearchResponseSchema.safeParse(raw);
|
|
1172
|
-
if (!data.success) return [];
|
|
1173
|
-
return (data.data.web?.results ?? []).slice(0, maxResults).map((r) => ({
|
|
1174
|
-
title: r.title,
|
|
1175
|
-
url: r.url,
|
|
1176
|
-
description: r.description
|
|
1177
|
-
}));
|
|
1178
|
-
}
|
|
1179
|
-
};
|
|
1180
|
-
}
|
|
1181
|
-
function createVisitWebpage(fetchFn = globalThis.fetch) {
|
|
1182
|
-
return {
|
|
1183
|
-
description: "Fetch a webpage and return its content as clean text. Use this to read the full content of a URL found via web_search, or any link the user shares. Good for reading articles, documentation, blog posts, or product pages.",
|
|
1184
|
-
parameters: visitWebpageParams,
|
|
1185
|
-
async execute(args, ctx) {
|
|
1186
|
-
const { url } = args;
|
|
1187
|
-
const resp = await fetchFn(url, {
|
|
1188
|
-
headers: {
|
|
1189
|
-
"User-Agent": "Mozilla/5.0 (compatible; VoiceAgent/1.0; +https://github.com/AssemblyAI/aai)",
|
|
1190
|
-
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
|
1191
|
-
},
|
|
1192
|
-
redirect: "follow",
|
|
1193
|
-
signal: fetchSignal(ctx.abortSignal)
|
|
1194
|
-
});
|
|
1195
|
-
if (!resp.ok) {
|
|
1196
|
-
return { error: `Failed to fetch: ${resp.status} ${resp.statusText}`, url };
|
|
1197
|
-
}
|
|
1198
|
-
const htmlContent = await resp.text();
|
|
1199
|
-
const trimmedHtml = htmlContent.length > MAX_HTML_BYTES ? htmlContent.slice(0, MAX_HTML_BYTES) : htmlContent;
|
|
1200
|
-
const text = htmlToText(trimmedHtml);
|
|
1201
|
-
const truncated = text.length > MAX_PAGE_CHARS;
|
|
1202
|
-
const content = truncated ? text.slice(0, MAX_PAGE_CHARS) : text;
|
|
1203
|
-
return {
|
|
1204
|
-
url,
|
|
1205
|
-
content,
|
|
1206
|
-
...truncated ? { truncated: true, totalChars: text.length } : {}
|
|
1207
|
-
};
|
|
1208
|
-
}
|
|
1209
|
-
};
|
|
1210
|
-
}
|
|
1211
|
-
function createFetchJson(fetchFn = globalThis.fetch) {
|
|
1212
|
-
return {
|
|
1213
|
-
description: "Call a REST API endpoint via HTTP GET and return the JSON response. Use this to fetch structured data from APIs \u2014 for example, weather data, stock prices, exchange rates, or any public JSON API. Supports custom headers for authenticated APIs.",
|
|
1214
|
-
parameters: fetchJsonParams,
|
|
1215
|
-
async execute(args, ctx) {
|
|
1216
|
-
const { url, headers } = args;
|
|
1217
|
-
const resp = await fetchFn(url, {
|
|
1218
|
-
...headers && { headers },
|
|
1219
|
-
signal: fetchSignal(ctx.abortSignal)
|
|
1220
|
-
});
|
|
1221
|
-
if (!resp.ok) {
|
|
1222
|
-
return { error: `HTTP ${resp.status} ${resp.statusText}`, url };
|
|
1223
|
-
}
|
|
1224
|
-
try {
|
|
1225
|
-
return await resp.json();
|
|
1226
|
-
} catch {
|
|
1227
|
-
return { error: "Response was not valid JSON", url };
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
};
|
|
1231
|
-
}
|
|
1232
|
-
function createRunCode() {
|
|
1233
|
-
return {
|
|
1234
|
-
description: "Execute JavaScript code in a secure sandbox and return the output. Use this for calculations, data transformations, string manipulation, or any task that benefits from running code. Output is captured from console.log(). No network or filesystem access.",
|
|
1235
|
-
parameters: runCodeParams,
|
|
1236
|
-
async execute(args) {
|
|
1237
|
-
const { code } = args;
|
|
1238
|
-
const output = [];
|
|
1239
|
-
function capture(...captureArgs) {
|
|
1240
|
-
output.push(captureArgs.map(String).join(" "));
|
|
1241
|
-
}
|
|
1242
|
-
const fakeConsole = {
|
|
1243
|
-
log: capture,
|
|
1244
|
-
info: capture,
|
|
1245
|
-
warn: capture,
|
|
1246
|
-
error: capture,
|
|
1247
|
-
debug: capture
|
|
1248
|
-
};
|
|
1249
|
-
const AsyncFunction = Object.getPrototypeOf(async () => {
|
|
1250
|
-
}).constructor;
|
|
1251
|
-
try {
|
|
1252
|
-
const fn = new AsyncFunction("console", code);
|
|
1253
|
-
await Promise.race([
|
|
1254
|
-
fn(fakeConsole),
|
|
1255
|
-
new Promise(
|
|
1256
|
-
(_, reject) => setTimeout(() => reject(new Error("Code execution timed out")), RUN_CODE_TIMEOUT)
|
|
1257
|
-
)
|
|
1258
|
-
]);
|
|
1259
|
-
const result = output.join("\n").trim();
|
|
1260
|
-
return result || "Code ran successfully (no output)";
|
|
1261
|
-
} catch (err) {
|
|
1262
|
-
return { error: errorMessage(err) };
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
};
|
|
1266
|
-
}
|
|
1267
|
-
function createVectorSearch(vectorSearchFn) {
|
|
1268
|
-
return {
|
|
1269
|
-
description: "Search the agent's knowledge base for relevant information. Use this when the user asks a question that might be answered by previously ingested documents or data. Returns the most relevant matches ranked by similarity.",
|
|
1270
|
-
parameters: vectorSearchParams,
|
|
1271
|
-
async execute(args) {
|
|
1272
|
-
const { query, topK = 5 } = args;
|
|
1273
|
-
return vectorSearchFn(query, topK);
|
|
1274
|
-
}
|
|
1275
|
-
};
|
|
1276
|
-
}
|
|
1277
|
-
function resolveBuiltin(name, opts) {
|
|
1278
|
-
const entry = TOOL_REGISTRY[name];
|
|
1279
|
-
if (!entry) return [];
|
|
1280
|
-
if ("multi" in entry) return Object.entries(entry.multi());
|
|
1281
|
-
if (name === "vector_search" && !opts?.vectorSearch) return [];
|
|
1282
|
-
return [[name, entry.create(opts)]];
|
|
1283
|
-
}
|
|
1284
|
-
function getBuiltinToolDefs(names, opts) {
|
|
1285
|
-
const defs = {};
|
|
1286
|
-
for (const name of names) {
|
|
1287
|
-
for (const [k, v] of resolveBuiltin(name, opts)) defs[k] = v;
|
|
1288
|
-
}
|
|
1289
|
-
return defs;
|
|
1290
|
-
}
|
|
1291
|
-
function getBuiltinToolSchemas(names) {
|
|
1292
|
-
return names.flatMap(
|
|
1293
|
-
(name) => resolveBuiltin(name, { vectorSearch: async () => "" }).map(([toolName, def]) => ({
|
|
1294
|
-
name: toolName,
|
|
1295
|
-
description: def.description,
|
|
1296
|
-
parameters: z4.toJSONSchema(def.parameters ?? EMPTY_PARAMS)
|
|
1297
|
-
}))
|
|
1298
|
-
);
|
|
1299
|
-
}
|
|
1300
|
-
function memoryTools() {
|
|
1301
|
-
return {
|
|
1302
|
-
save_memory: tool({
|
|
1303
|
-
description: "Save a piece of information to persistent memory. Use a descriptive key like 'user:name' or 'project:status'.",
|
|
1304
|
-
parameters: z4.object({
|
|
1305
|
-
key: z4.string().describe("A descriptive key for this memory (e.g. 'user:name', 'preference:color')"),
|
|
1306
|
-
value: z4.string().describe("The information to remember")
|
|
1307
|
-
}),
|
|
1308
|
-
execute: async ({ key, value }, ctx) => {
|
|
1309
|
-
await ctx.kv.set(key, value);
|
|
1310
|
-
return { saved: key };
|
|
1311
|
-
}
|
|
1312
|
-
}),
|
|
1313
|
-
recall_memory: tool({
|
|
1314
|
-
description: "Retrieve a previously saved memory by its key.",
|
|
1315
|
-
parameters: z4.object({
|
|
1316
|
-
key: z4.string().describe("The key to look up")
|
|
1317
|
-
}),
|
|
1318
|
-
execute: async ({ key }, ctx) => {
|
|
1319
|
-
const value = await ctx.kv.get(key);
|
|
1320
|
-
if (value === null) return { found: false, key };
|
|
1321
|
-
return { found: true, key, value };
|
|
1322
|
-
}
|
|
1323
|
-
}),
|
|
1324
|
-
list_memories: tool({
|
|
1325
|
-
description: "List all saved memory keys, optionally filtered by a prefix (e.g. 'user:').",
|
|
1326
|
-
parameters: z4.object({
|
|
1327
|
-
prefix: z4.string().describe("Prefix to filter keys (e.g. 'user:'). Use empty string for all.").optional()
|
|
1328
|
-
}),
|
|
1329
|
-
execute: async ({ prefix }, ctx) => {
|
|
1330
|
-
const entries = await ctx.kv.list(prefix ?? "");
|
|
1331
|
-
return { count: entries.length, keys: entries.map((e) => e.key) };
|
|
1332
|
-
}
|
|
1333
|
-
}),
|
|
1334
|
-
forget_memory: tool({
|
|
1335
|
-
description: "Delete a previously saved memory by its key.",
|
|
1336
|
-
parameters: z4.object({
|
|
1337
|
-
key: z4.string().describe("The key to delete")
|
|
1338
|
-
}),
|
|
1339
|
-
execute: async ({ key }, ctx) => {
|
|
1340
|
-
await ctx.kv.delete(key);
|
|
1341
|
-
return { deleted: key };
|
|
1342
|
-
}
|
|
1343
|
-
})
|
|
1344
|
-
};
|
|
1345
|
-
}
|
|
1346
|
-
var FETCH_TIMEOUT_MS, RUN_CODE_TIMEOUT, webSearchParams, BRAVE_SEARCH_URL, BraveSearchResponseSchema, MAX_PAGE_CHARS, MAX_HTML_BYTES, visitWebpageParams, fetchJsonParams, runCodeParams, vectorSearchParams, TOOL_REGISTRY;
|
|
1347
|
-
var init_builtin_tools = __esm({
|
|
1348
|
-
"sdk/builtin_tools.ts"() {
|
|
1349
|
-
"use strict";
|
|
1350
|
-
init_internal_types();
|
|
1351
|
-
init_utils();
|
|
1352
|
-
init_types();
|
|
1353
|
-
FETCH_TIMEOUT_MS = 15e3;
|
|
1354
|
-
RUN_CODE_TIMEOUT = 5e3;
|
|
1355
|
-
webSearchParams = z4.object({
|
|
1356
|
-
query: z4.string().describe("The search query"),
|
|
1357
|
-
max_results: z4.number().describe("Maximum number of results to return (default 5)").optional()
|
|
1358
|
-
});
|
|
1359
|
-
BRAVE_SEARCH_URL = "https://api.search.brave.com/res/v1/web/search";
|
|
1360
|
-
BraveSearchResponseSchema = z4.object({
|
|
1361
|
-
web: z4.object({
|
|
1362
|
-
results: z4.array(
|
|
1363
|
-
z4.object({
|
|
1364
|
-
title: z4.string(),
|
|
1365
|
-
url: z4.string(),
|
|
1366
|
-
description: z4.string()
|
|
1367
|
-
})
|
|
1368
|
-
)
|
|
1369
|
-
}).optional()
|
|
1370
|
-
});
|
|
1371
|
-
MAX_PAGE_CHARS = 1e4;
|
|
1372
|
-
MAX_HTML_BYTES = 2e5;
|
|
1373
|
-
visitWebpageParams = z4.object({
|
|
1374
|
-
url: z4.string().describe("The full URL to fetch (e.g., 'https://example.com/page')")
|
|
1375
|
-
});
|
|
1376
|
-
fetchJsonParams = z4.object({
|
|
1377
|
-
url: z4.string().describe("The URL to fetch JSON from"),
|
|
1378
|
-
headers: z4.record(z4.string(), z4.string()).describe("Optional HTTP headers to include in the request").optional()
|
|
1379
|
-
});
|
|
1380
|
-
runCodeParams = z4.object({
|
|
1381
|
-
code: z4.string().describe("JavaScript code to execute. Use console.log() for output.")
|
|
1382
|
-
});
|
|
1383
|
-
vectorSearchParams = z4.object({
|
|
1384
|
-
query: z4.string().describe(
|
|
1385
|
-
'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".'
|
|
1386
|
-
),
|
|
1387
|
-
topK: z4.number().describe("Maximum results to return (default: 5)").optional()
|
|
1388
|
-
});
|
|
1389
|
-
TOOL_REGISTRY = {
|
|
1390
|
-
web_search: { create: (opts) => createWebSearch(opts?.fetch) },
|
|
1391
|
-
visit_webpage: { create: (opts) => createVisitWebpage(opts?.fetch) },
|
|
1392
|
-
fetch_json: { create: (opts) => createFetchJson(opts?.fetch) },
|
|
1393
|
-
run_code: { create: createRunCode },
|
|
1394
|
-
vector_search: { create: (opts) => createVectorSearch(opts?.vectorSearch ?? (async () => "")) },
|
|
1395
|
-
memory: { multi: memoryTools }
|
|
1396
|
-
};
|
|
1397
|
-
}
|
|
1398
|
-
});
|
|
1399
|
-
|
|
1400
|
-
// sdk/kv.ts
|
|
1401
|
-
function sortAndPaginate(entries, options) {
|
|
1402
|
-
entries.sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
|
|
1403
|
-
if (options?.reverse) entries.reverse();
|
|
1404
|
-
if (options?.limit && options.limit > 0) {
|
|
1405
|
-
entries.length = Math.min(entries.length, options.limit);
|
|
1406
|
-
}
|
|
1407
|
-
return entries;
|
|
1408
|
-
}
|
|
1409
|
-
function createMemoryKv() {
|
|
1410
|
-
const store = /* @__PURE__ */ new Map();
|
|
1411
|
-
function isExpired(entry) {
|
|
1412
|
-
return entry.expiresAt !== void 0 && entry.expiresAt <= Date.now();
|
|
1413
|
-
}
|
|
1414
|
-
return {
|
|
1415
|
-
get(key) {
|
|
1416
|
-
const entry = store.get(key);
|
|
1417
|
-
if (!entry || isExpired(entry)) {
|
|
1418
|
-
if (entry) store.delete(key);
|
|
1419
|
-
return Promise.resolve(null);
|
|
1420
|
-
}
|
|
1421
|
-
return Promise.resolve(JSON.parse(entry.raw));
|
|
1422
|
-
},
|
|
1423
|
-
set(key, value, options) {
|
|
1424
|
-
const raw = JSON.stringify(value);
|
|
1425
|
-
if (raw.length > MAX_VALUE_SIZE) {
|
|
1426
|
-
throw new Error(`Value exceeds max size of ${MAX_VALUE_SIZE} bytes`);
|
|
1427
|
-
}
|
|
1428
|
-
const expireIn = options?.expireIn;
|
|
1429
|
-
const entry = { raw };
|
|
1430
|
-
if (expireIn && expireIn > 0) {
|
|
1431
|
-
entry.expiresAt = Date.now() + expireIn;
|
|
1432
|
-
}
|
|
1433
|
-
store.set(key, entry);
|
|
1434
|
-
return Promise.resolve();
|
|
1435
|
-
},
|
|
1436
|
-
delete(key) {
|
|
1437
|
-
store.delete(key);
|
|
1438
|
-
return Promise.resolve();
|
|
1439
|
-
},
|
|
1440
|
-
async list(prefix, options) {
|
|
1441
|
-
const now = Date.now();
|
|
1442
|
-
const entries = [];
|
|
1443
|
-
let i = 0;
|
|
1444
|
-
for (const [key, entry] of store) {
|
|
1445
|
-
if (++i % 500 === 0) await new Promise((r) => setTimeout(r, 0));
|
|
1446
|
-
if (entry.expiresAt && entry.expiresAt <= now) {
|
|
1447
|
-
store.delete(key);
|
|
1448
|
-
continue;
|
|
1449
|
-
}
|
|
1450
|
-
if (key.startsWith(prefix)) {
|
|
1451
|
-
entries.push({ key, value: JSON.parse(entry.raw) });
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
return sortAndPaginate(entries, options);
|
|
1455
|
-
}
|
|
1456
|
-
};
|
|
1457
|
-
}
|
|
1458
|
-
var MAX_VALUE_SIZE;
|
|
1459
|
-
var init_kv = __esm({
|
|
1460
|
-
"sdk/kv.ts"() {
|
|
1461
|
-
"use strict";
|
|
1462
|
-
MAX_VALUE_SIZE = 65536;
|
|
1463
|
-
}
|
|
1464
|
-
});
|
|
1465
|
-
|
|
1466
|
-
// sdk/session.ts
|
|
1467
|
-
function createS2sSession(opts) {
|
|
1468
|
-
const {
|
|
1469
|
-
id,
|
|
1470
|
-
agent,
|
|
1471
|
-
client,
|
|
1472
|
-
toolSchemas,
|
|
1473
|
-
apiKey,
|
|
1474
|
-
s2sConfig,
|
|
1475
|
-
executeTool,
|
|
1476
|
-
createWebSocket,
|
|
1477
|
-
hookInvoker,
|
|
1478
|
-
logger: log = consoleLogger,
|
|
1479
|
-
metrics = noopMetrics
|
|
1480
|
-
} = opts;
|
|
1481
|
-
const agentLabel = { agent };
|
|
1482
|
-
const agentConfig = opts.skipGreeting ? { ...opts.agentConfig, greeting: "" } : opts.agentConfig;
|
|
1483
|
-
const hasTools = toolSchemas.length > 0 || (agentConfig.builtinTools?.length ?? 0) > 0;
|
|
1484
|
-
const systemPrompt = buildSystemPrompt(agentConfig, {
|
|
1485
|
-
hasTools,
|
|
1486
|
-
voice: true
|
|
1487
|
-
});
|
|
1488
|
-
const s2sTools = toolSchemas.map((ts) => ({
|
|
1489
|
-
type: "function",
|
|
1490
|
-
name: ts.name,
|
|
1491
|
-
description: ts.description,
|
|
1492
|
-
parameters: ts.parameters
|
|
1493
|
-
}));
|
|
1494
|
-
let s2s = null;
|
|
1495
|
-
const sessionAbort = new AbortController();
|
|
1496
|
-
let toolCallCount = 0;
|
|
1497
|
-
let turnPromise = null;
|
|
1498
|
-
let conversationMessages = [];
|
|
1499
|
-
let pendingTools = [];
|
|
1500
|
-
async function resolveTurnConfig() {
|
|
1501
|
-
if (!hookInvoker) return null;
|
|
1502
|
-
try {
|
|
1503
|
-
return await hookInvoker.resolveTurnConfig(id, HOOK_TIMEOUT_MS);
|
|
1504
|
-
} catch (err) {
|
|
1505
|
-
log.warn("resolveTurnConfig hook failed", { err: errorMessage(err) });
|
|
1506
|
-
return null;
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
function invokeHook(hook, arg) {
|
|
1510
|
-
if (!hookInvoker) return;
|
|
1511
|
-
try {
|
|
1512
|
-
const h = hookInvoker[hook];
|
|
1513
|
-
Promise.resolve(h.call(hookInvoker, id, arg, HOOK_TIMEOUT_MS)).catch((err) => {
|
|
1514
|
-
log.warn(`${hook} hook failed`, { err: errorMessage(err) });
|
|
1515
|
-
});
|
|
1516
|
-
} catch (err) {
|
|
1517
|
-
log.warn(`${hook} hook failed`, { err: errorMessage(err) });
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
function checkTurnLimits(turnConfig, name) {
|
|
1521
|
-
const maxSteps = turnConfig?.maxSteps ?? agentConfig.maxSteps;
|
|
1522
|
-
toolCallCount++;
|
|
1523
|
-
if (maxSteps !== void 0 && toolCallCount > maxSteps) {
|
|
1524
|
-
log.info("maxSteps exceeded, refusing tool call", { toolCallCount, maxSteps });
|
|
1525
|
-
return "Maximum tool steps reached. Please respond to the user now.";
|
|
1526
|
-
}
|
|
1527
|
-
if (turnConfig?.activeTools && !turnConfig.activeTools.includes(name)) {
|
|
1528
|
-
log.info("Tool filtered by activeTools", { name });
|
|
1529
|
-
return JSON.stringify({ error: `Tool "${name}" is not available at this step.` });
|
|
1530
|
-
}
|
|
1531
|
-
return null;
|
|
1532
|
-
}
|
|
1533
|
-
async function handleToolCall(detail) {
|
|
1534
|
-
const { call_id, name, args: parsedArgs } = detail;
|
|
1535
|
-
client.event({
|
|
1536
|
-
type: "tool_call_start",
|
|
1537
|
-
toolCallId: call_id,
|
|
1538
|
-
toolName: name,
|
|
1539
|
-
args: parsedArgs
|
|
1540
|
-
});
|
|
1541
|
-
const turnConfig = await resolveTurnConfig();
|
|
1542
|
-
const refused = checkTurnLimits(turnConfig, name);
|
|
1543
|
-
if (refused !== null) {
|
|
1544
|
-
pendingTools.push({ call_id, result: refused });
|
|
1545
|
-
client.event({ type: "tool_call_done", toolCallId: call_id, result: refused });
|
|
1546
|
-
return;
|
|
1547
|
-
}
|
|
1548
|
-
invokeHook("onStep", {
|
|
1549
|
-
stepNumber: toolCallCount - 1,
|
|
1550
|
-
toolCalls: [{ toolName: name, args: parsedArgs }],
|
|
1551
|
-
text: ""
|
|
1552
|
-
});
|
|
1553
|
-
log.info("S2S tool call", { tool: name, call_id, args: parsedArgs, agent });
|
|
1554
|
-
let result;
|
|
1555
|
-
try {
|
|
1556
|
-
result = await executeTool(name, parsedArgs, id, conversationMessages);
|
|
1557
|
-
} catch (err) {
|
|
1558
|
-
const msg = errorMessage(err);
|
|
1559
|
-
log.error("Tool execution failed", { tool: name, error: msg });
|
|
1560
|
-
result = JSON.stringify({ error: msg });
|
|
1561
|
-
}
|
|
1562
|
-
log.info("S2S tool result", {
|
|
1563
|
-
tool: name,
|
|
1564
|
-
call_id,
|
|
1565
|
-
resultLength: result.length
|
|
1566
|
-
});
|
|
1567
|
-
pendingTools.push({ call_id, result });
|
|
1568
|
-
client.event({ type: "tool_call_done", toolCallId: call_id, result });
|
|
1569
|
-
}
|
|
1570
|
-
function on(target, event, handler) {
|
|
1571
|
-
target.addEventListener(event, handler);
|
|
1572
|
-
}
|
|
1573
|
-
function setupListeners(handle) {
|
|
1574
|
-
on(handle, "ready", (e) => {
|
|
1575
|
-
log.info("S2S session ready", { session_id: e.detail.session_id });
|
|
1576
|
-
});
|
|
1577
|
-
on(handle, "session_expired", () => {
|
|
1578
|
-
log.info("S2S session expired");
|
|
1579
|
-
handle.close();
|
|
1580
|
-
});
|
|
1581
|
-
for (const type of ["speech_started", "speech_stopped"]) {
|
|
1582
|
-
handle.addEventListener(type, () => client.event({ type }));
|
|
1583
|
-
}
|
|
1584
|
-
on(handle, "user_transcript_delta", (e) => {
|
|
1585
|
-
client.event({ type: "transcript", text: e.detail.text, isFinal: false });
|
|
1586
|
-
});
|
|
1587
|
-
on(handle, "user_transcript", (e) => {
|
|
1588
|
-
const { text } = e.detail;
|
|
1589
|
-
log.info("S2S user transcript", { text });
|
|
1590
|
-
client.event({ type: "transcript", text, isFinal: true });
|
|
1591
|
-
client.event({ type: "turn", text });
|
|
1592
|
-
conversationMessages.push({ role: "user", content: text });
|
|
1593
|
-
invokeHook("onTurn", text);
|
|
1594
|
-
});
|
|
1595
|
-
handle.addEventListener("reply_started", () => {
|
|
1596
|
-
toolCallCount = 0;
|
|
1597
|
-
});
|
|
1598
|
-
on(handle, "audio", (e) => {
|
|
1599
|
-
client.playAudioChunk(e.detail.audio);
|
|
1600
|
-
});
|
|
1601
|
-
on(handle, "agent_transcript_delta", (e) => {
|
|
1602
|
-
client.event({ type: "chat_delta", text: e.detail.text });
|
|
1603
|
-
});
|
|
1604
|
-
on(handle, "agent_transcript", (e) => {
|
|
1605
|
-
const { text } = e.detail;
|
|
1606
|
-
client.event({ type: "chat", text });
|
|
1607
|
-
conversationMessages.push({ role: "assistant", content: text });
|
|
1608
|
-
});
|
|
1609
|
-
on(handle, "tool_call", (e) => {
|
|
1610
|
-
const p = handleToolCall(e.detail).catch((err) => {
|
|
1611
|
-
log.error("Tool call handler failed", { err: errorMessage(err) });
|
|
1612
|
-
});
|
|
1613
|
-
turnPromise = (turnPromise ?? Promise.resolve()).then(() => p);
|
|
1614
|
-
});
|
|
1615
|
-
on(handle, "reply_done", (e) => {
|
|
1616
|
-
if (e.detail.status === "interrupted") {
|
|
1617
|
-
log.info("S2S reply interrupted (barge-in)");
|
|
1618
|
-
pendingTools = [];
|
|
1619
|
-
client.event({ type: "cancelled" });
|
|
1620
|
-
} else if (pendingTools.length > 0) {
|
|
1621
|
-
for (const tool2 of pendingTools) s2s?.sendToolResult(tool2.call_id, tool2.result);
|
|
1622
|
-
pendingTools = [];
|
|
1623
|
-
} else {
|
|
1624
|
-
client.playAudioDone();
|
|
1625
|
-
client.event({ type: "tts_done" });
|
|
1626
|
-
}
|
|
1627
|
-
});
|
|
1628
|
-
on(handle, "error", (e) => {
|
|
1629
|
-
log.error("S2S error", { code: e.detail.code, message: e.detail.message });
|
|
1630
|
-
client.event({ type: "error", code: "internal", message: e.detail.message });
|
|
1631
|
-
handle.close();
|
|
1632
|
-
});
|
|
1633
|
-
handle.addEventListener("close", () => {
|
|
1634
|
-
log.info("S2S closed");
|
|
1635
|
-
s2s = null;
|
|
1636
|
-
});
|
|
1637
|
-
}
|
|
1638
|
-
async function connectAndSetup() {
|
|
1639
|
-
try {
|
|
1640
|
-
const handle = await _internals.connectS2s({
|
|
1641
|
-
apiKey,
|
|
1642
|
-
config: s2sConfig,
|
|
1643
|
-
createWebSocket,
|
|
1644
|
-
logger: log
|
|
1645
|
-
});
|
|
1646
|
-
setupListeners(handle);
|
|
1647
|
-
handle.updateSession({
|
|
1648
|
-
system_prompt: systemPrompt,
|
|
1649
|
-
tools: s2sTools,
|
|
1650
|
-
...agentConfig.greeting ? { greeting: agentConfig.greeting } : {}
|
|
1651
|
-
});
|
|
1652
|
-
s2s = handle;
|
|
1653
|
-
} catch (err) {
|
|
1654
|
-
const msg = errorMessage(err);
|
|
1655
|
-
log.error("S2S connect failed", { error: msg });
|
|
1656
|
-
client.event({ type: "error", code: "internal", message: msg });
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
return {
|
|
1660
|
-
async start() {
|
|
1661
|
-
metrics.sessionsTotal.inc(agentLabel);
|
|
1662
|
-
metrics.sessionsActive.inc(agentLabel);
|
|
1663
|
-
invokeHook("onConnect");
|
|
1664
|
-
await connectAndSetup();
|
|
1665
|
-
},
|
|
1666
|
-
async stop() {
|
|
1667
|
-
if (sessionAbort.signal.aborted) return;
|
|
1668
|
-
sessionAbort.abort();
|
|
1669
|
-
metrics.sessionsActive.dec(agentLabel);
|
|
1670
|
-
if (turnPromise) await turnPromise;
|
|
1671
|
-
s2s?.close();
|
|
1672
|
-
invokeHook("onDisconnect");
|
|
1673
|
-
},
|
|
1674
|
-
onAudio(data) {
|
|
1675
|
-
s2s?.sendAudio(data);
|
|
1676
|
-
},
|
|
1677
|
-
onAudioReady() {
|
|
1678
|
-
},
|
|
1679
|
-
onCancel() {
|
|
1680
|
-
client.event({ type: "cancelled" });
|
|
1681
|
-
},
|
|
1682
|
-
onReset() {
|
|
1683
|
-
conversationMessages = [];
|
|
1684
|
-
toolCallCount = 0;
|
|
1685
|
-
turnPromise = null;
|
|
1686
|
-
pendingTools = [];
|
|
1687
|
-
s2s?.close();
|
|
1688
|
-
client.event({ type: "reset" });
|
|
1689
|
-
connectAndSetup().catch((err) => {
|
|
1690
|
-
log.error("S2S reset reconnect failed", { error: errorMessage(err) });
|
|
1691
|
-
});
|
|
1692
|
-
},
|
|
1693
|
-
onHistory(incoming) {
|
|
1694
|
-
for (const msg of incoming) {
|
|
1695
|
-
conversationMessages.push({ role: msg.role, content: msg.text });
|
|
1696
|
-
}
|
|
1697
|
-
},
|
|
1698
|
-
waitForTurn() {
|
|
1699
|
-
return turnPromise ?? Promise.resolve();
|
|
1700
|
-
}
|
|
1701
|
-
};
|
|
1702
|
-
}
|
|
1703
|
-
function buildSystemPrompt(config, opts) {
|
|
1704
|
-
const { hasTools } = opts;
|
|
1705
|
-
const agentInstructions = config.instructions && config.instructions !== DEFAULT_INSTRUCTIONS ? `
|
|
1706
|
-
|
|
1707
|
-
Agent-Specific Instructions:
|
|
1708
|
-
${config.instructions}` : "";
|
|
1709
|
-
const toolPreamble = hasTools ? '\n\nWhen you decide to use a tool, ALWAYS say a brief natural phrase BEFORE the tool call (e.g. "Let me look that up" or "One moment while I check"). This fills silence while the tool executes. Keep preambles to one short sentence.' : "";
|
|
1710
|
-
const today = (/* @__PURE__ */ new Date()).toLocaleDateString("en-US", {
|
|
1711
|
-
weekday: "long",
|
|
1712
|
-
year: "numeric",
|
|
1713
|
-
month: "long",
|
|
1714
|
-
day: "numeric"
|
|
1715
|
-
});
|
|
1716
|
-
return DEFAULT_INSTRUCTIONS + `
|
|
1717
|
-
|
|
1718
|
-
Today's date is ${today}.` + agentInstructions + toolPreamble + (opts.voice ? VOICE_RULES : "");
|
|
1719
|
-
}
|
|
1720
|
-
var _internals, VOICE_RULES;
|
|
1721
|
-
var init_session = __esm({
|
|
1722
|
-
"sdk/session.ts"() {
|
|
1723
|
-
"use strict";
|
|
1724
|
-
init_utils();
|
|
1725
|
-
init_protocol();
|
|
1726
|
-
init_runtime();
|
|
1727
|
-
init_s2s();
|
|
1728
|
-
init_types();
|
|
1729
|
-
_internals = {
|
|
1730
|
-
connectS2s
|
|
1731
|
-
};
|
|
1732
|
-
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';
|
|
1733
|
-
}
|
|
1734
|
-
});
|
|
1735
|
-
|
|
1736
|
-
// sdk/vector.ts
|
|
1737
|
-
function createMemoryVectorStore() {
|
|
1738
|
-
const store = /* @__PURE__ */ new Map();
|
|
1739
|
-
return {
|
|
1740
|
-
upsert(id, data, metadata) {
|
|
1741
|
-
store.set(id, { data, metadata });
|
|
1742
|
-
return Promise.resolve();
|
|
1743
|
-
},
|
|
1744
|
-
async query(text, options) {
|
|
1745
|
-
const topK = options?.topK ?? 10;
|
|
1746
|
-
const query = text.toLowerCase();
|
|
1747
|
-
const words = query.split(/\s+/).filter(Boolean);
|
|
1748
|
-
const results = [];
|
|
1749
|
-
let i = 0;
|
|
1750
|
-
for (const [id, entry] of store) {
|
|
1751
|
-
if (++i % 500 === 0) await new Promise((r) => setTimeout(r, 0));
|
|
1752
|
-
const data = entry.data.toLowerCase();
|
|
1753
|
-
const matches = words.filter((w) => data.includes(w)).length;
|
|
1754
|
-
if (matches > 0) {
|
|
1755
|
-
results.push({
|
|
1756
|
-
id,
|
|
1757
|
-
score: matches / Math.max(words.length, 1),
|
|
1758
|
-
data: entry.data,
|
|
1759
|
-
metadata: entry.metadata
|
|
1760
|
-
});
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
results.sort((a, b) => b.score - a.score);
|
|
1764
|
-
return results.slice(0, topK);
|
|
1765
|
-
},
|
|
1766
|
-
remove(ids) {
|
|
1767
|
-
const idArray = Array.isArray(ids) ? ids : [ids];
|
|
1768
|
-
for (const id of idArray) {
|
|
1769
|
-
store.delete(id);
|
|
1770
|
-
}
|
|
1771
|
-
return Promise.resolve();
|
|
1772
|
-
}
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
var init_vector = __esm({
|
|
1776
|
-
"sdk/vector.ts"() {
|
|
1777
|
-
"use strict";
|
|
1778
|
-
}
|
|
1779
|
-
});
|
|
1780
|
-
|
|
1781
|
-
// sdk/worker_entry.ts
|
|
1782
|
-
function buildToolContext(opts) {
|
|
1783
|
-
const { env, state, kv, vector, messages } = opts;
|
|
1784
|
-
return {
|
|
1785
|
-
env: { ...env },
|
|
1786
|
-
abortSignal: AbortSignal.timeout(TOOL_EXECUTION_TIMEOUT_MS),
|
|
1787
|
-
state: state ?? {},
|
|
1788
|
-
get kv() {
|
|
1789
|
-
if (!kv) throw new Error("KV not available");
|
|
1790
|
-
return kv;
|
|
1791
|
-
},
|
|
1792
|
-
get vector() {
|
|
1793
|
-
if (!vector) throw new Error("Vector store not available");
|
|
1794
|
-
return vector;
|
|
1795
|
-
},
|
|
1796
|
-
messages: messages ?? []
|
|
1797
|
-
};
|
|
1798
|
-
}
|
|
1799
|
-
async function executeToolCall(name, args, options) {
|
|
1800
|
-
const { tool: tool2 } = options;
|
|
1801
|
-
const schema = tool2.parameters ?? EMPTY_PARAMS;
|
|
1802
|
-
const parsed = schema.safeParse(args);
|
|
1803
|
-
if (!parsed.success) {
|
|
1804
|
-
const issues = (parsed.error?.issues ?? []).map((i) => `${i.path.map(String).join(".")}: ${i.message}`).join(", ");
|
|
1805
|
-
return `Error: Invalid arguments for tool "${name}": ${issues}`;
|
|
1806
|
-
}
|
|
1807
|
-
try {
|
|
1808
|
-
const ctx = buildToolContext(options);
|
|
1809
|
-
await yieldTick();
|
|
1810
|
-
const result = await Promise.resolve(tool2.execute(parsed.data, ctx));
|
|
1811
|
-
await yieldTick();
|
|
1812
|
-
if (result == null) return "null";
|
|
1813
|
-
return typeof result === "string" ? result : JSON.stringify(result);
|
|
1814
|
-
} catch (err) {
|
|
1815
|
-
console.warn(`[tool-executor] Tool execution failed: ${name}`, err);
|
|
1816
|
-
return `Error: ${errorMessage(err)}`;
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
var yieldTick;
|
|
1820
|
-
var init_worker_entry = __esm({
|
|
1821
|
-
"sdk/worker_entry.ts"() {
|
|
1822
|
-
"use strict";
|
|
1823
|
-
init_internal_types();
|
|
1824
|
-
init_utils();
|
|
1825
|
-
init_protocol();
|
|
1826
|
-
yieldTick = () => new Promise((r) => setTimeout(r, 0));
|
|
1827
|
-
}
|
|
1828
|
-
});
|
|
1829
|
-
|
|
1830
|
-
// sdk/direct_executor.ts
|
|
1831
|
-
function buildAgentConfig(agent) {
|
|
1832
|
-
const config = {
|
|
1833
|
-
name: agent.name,
|
|
1834
|
-
instructions: agent.instructions,
|
|
1835
|
-
greeting: agent.greeting
|
|
1836
|
-
};
|
|
1837
|
-
if (agent.sttPrompt !== void 0) config.sttPrompt = agent.sttPrompt;
|
|
1838
|
-
if (typeof agent.maxSteps !== "function") config.maxSteps = agent.maxSteps;
|
|
1839
|
-
if (agent.toolChoice !== void 0) config.toolChoice = agent.toolChoice;
|
|
1840
|
-
if (agent.builtinTools) config.builtinTools = [...agent.builtinTools];
|
|
1841
|
-
if (agent.activeTools) config.activeTools = [...agent.activeTools];
|
|
1842
|
-
return config;
|
|
1843
|
-
}
|
|
1844
|
-
function createDirectExecutor(opts) {
|
|
1845
|
-
const {
|
|
1846
|
-
agent,
|
|
1847
|
-
env,
|
|
1848
|
-
kv = createMemoryKv(),
|
|
1849
|
-
vector = createMemoryVectorStore(),
|
|
1850
|
-
vectorSearch,
|
|
1851
|
-
createWebSocket,
|
|
1852
|
-
logger = consoleLogger,
|
|
1853
|
-
metrics = noopMetrics,
|
|
1854
|
-
s2sConfig = DEFAULT_S2S_CONFIG
|
|
1855
|
-
} = opts;
|
|
1856
|
-
const agentConfig = buildAgentConfig(agent);
|
|
1857
|
-
const builtinDefs = getBuiltinToolDefs(
|
|
1858
|
-
agent.builtinTools ?? [],
|
|
1859
|
-
vectorSearch ? { vectorSearch } : void 0
|
|
1860
|
-
);
|
|
1861
|
-
const allTools = {
|
|
1862
|
-
...builtinDefs,
|
|
1863
|
-
...agent.tools
|
|
1864
|
-
};
|
|
1865
|
-
const customSchemas = agentToolsToSchemas(agent.tools ?? {});
|
|
1866
|
-
const builtinSchemas = getBuiltinToolSchemas(agent.builtinTools ?? []);
|
|
1867
|
-
const toolSchemas = [...customSchemas, ...builtinSchemas];
|
|
1868
|
-
const sessionState = /* @__PURE__ */ new Map();
|
|
1869
|
-
const frozenEnv = Object.freeze({ ...env });
|
|
1870
|
-
function getState(sessionId) {
|
|
1871
|
-
if (!sessionState.has(sessionId) && agent.state) {
|
|
1872
|
-
sessionState.set(sessionId, agent.state());
|
|
1873
|
-
}
|
|
1874
|
-
return sessionState.get(sessionId) ?? {};
|
|
1875
|
-
}
|
|
1876
|
-
function makeHookContext(sessionId) {
|
|
1877
|
-
return {
|
|
1878
|
-
env: frozenEnv,
|
|
1879
|
-
state: getState(sessionId),
|
|
1880
|
-
get kv() {
|
|
1881
|
-
return kv;
|
|
1882
|
-
},
|
|
1883
|
-
get vector() {
|
|
1884
|
-
return vector;
|
|
1885
|
-
}
|
|
1886
|
-
};
|
|
1887
|
-
}
|
|
1888
|
-
const executeTool = async (name, args, sessionId, messages) => {
|
|
1889
|
-
const tool2 = allTools[name];
|
|
1890
|
-
if (!tool2) return JSON.stringify({ error: `Unknown tool: ${name}` });
|
|
1891
|
-
return executeToolCall(name, args, {
|
|
1892
|
-
tool: tool2,
|
|
1893
|
-
env: frozenEnv,
|
|
1894
|
-
state: getState(sessionId ?? ""),
|
|
1895
|
-
kv,
|
|
1896
|
-
vector,
|
|
1897
|
-
messages
|
|
1898
|
-
});
|
|
1899
|
-
};
|
|
1900
|
-
const hookInvoker = {
|
|
1901
|
-
async onConnect(sessionId) {
|
|
1902
|
-
await agent.onConnect?.(makeHookContext(sessionId));
|
|
1903
|
-
},
|
|
1904
|
-
async onDisconnect(sessionId) {
|
|
1905
|
-
await agent.onDisconnect?.(makeHookContext(sessionId));
|
|
1906
|
-
sessionState.delete(sessionId);
|
|
1907
|
-
},
|
|
1908
|
-
async onTurn(sessionId, text) {
|
|
1909
|
-
await agent.onTurn?.(text, makeHookContext(sessionId));
|
|
1910
|
-
},
|
|
1911
|
-
async onError(sessionId, error) {
|
|
1912
|
-
await agent.onError?.(new Error(error.message), makeHookContext(sessionId));
|
|
1913
|
-
},
|
|
1914
|
-
async onStep(sessionId, step) {
|
|
1915
|
-
await agent.onStep?.(step, makeHookContext(sessionId));
|
|
1916
|
-
},
|
|
1917
|
-
async resolveTurnConfig(sessionId) {
|
|
1918
|
-
const ctx = makeHookContext(sessionId);
|
|
1919
|
-
let maxSteps;
|
|
1920
|
-
let activeTools;
|
|
1921
|
-
if (typeof agent.maxSteps === "function") {
|
|
1922
|
-
maxSteps = await agent.maxSteps(ctx) ?? void 0;
|
|
1923
|
-
}
|
|
1924
|
-
if (agent.onBeforeStep) {
|
|
1925
|
-
const result = await agent.onBeforeStep(0, ctx);
|
|
1926
|
-
activeTools = result?.activeTools;
|
|
1927
|
-
}
|
|
1928
|
-
if (maxSteps === void 0 && activeTools === void 0) return null;
|
|
1929
|
-
const config = {};
|
|
1930
|
-
if (maxSteps !== void 0) config.maxSteps = maxSteps;
|
|
1931
|
-
if (activeTools !== void 0) config.activeTools = activeTools;
|
|
1932
|
-
return config;
|
|
1933
|
-
}
|
|
1934
|
-
};
|
|
1935
|
-
function createSession(sessionOpts) {
|
|
1936
|
-
if (!createWebSocket) {
|
|
1937
|
-
throw new Error("createWebSocket not provided \u2014 pass it in DirectExecutorOptions");
|
|
1938
|
-
}
|
|
1939
|
-
const apiKey = frozenEnv.ASSEMBLYAI_API_KEY ?? "";
|
|
1940
|
-
return createS2sSession({
|
|
1941
|
-
id: sessionOpts.id,
|
|
1942
|
-
agent: sessionOpts.agent,
|
|
1943
|
-
client: sessionOpts.client,
|
|
1944
|
-
agentConfig,
|
|
1945
|
-
toolSchemas,
|
|
1946
|
-
apiKey,
|
|
1947
|
-
s2sConfig,
|
|
1948
|
-
executeTool,
|
|
1949
|
-
createWebSocket,
|
|
1950
|
-
hookInvoker,
|
|
1951
|
-
skipGreeting: sessionOpts.skipGreeting ?? false,
|
|
1952
|
-
logger,
|
|
1953
|
-
metrics
|
|
1954
|
-
});
|
|
1955
|
-
}
|
|
1956
|
-
return { executeTool, hookInvoker, toolSchemas, createSession };
|
|
1957
|
-
}
|
|
1958
|
-
var init_direct_executor = __esm({
|
|
1959
|
-
"sdk/direct_executor.ts"() {
|
|
1960
|
-
"use strict";
|
|
1961
|
-
init_internal_types();
|
|
1962
|
-
init_builtin_tools();
|
|
1963
|
-
init_kv();
|
|
1964
|
-
init_runtime();
|
|
1965
|
-
init_session();
|
|
1966
|
-
init_vector();
|
|
1967
|
-
init_worker_entry();
|
|
1968
|
-
}
|
|
1969
|
-
});
|
|
1970
|
-
|
|
1971
|
-
// sdk/ws_handler.ts
|
|
1972
|
-
function createClientSink(ws) {
|
|
1973
|
-
function safeSend(data) {
|
|
1974
|
-
try {
|
|
1975
|
-
if (ws.readyState === 1) ws.send(data);
|
|
1976
|
-
} catch {
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
return {
|
|
1980
|
-
get open() {
|
|
1981
|
-
return ws.readyState === 1;
|
|
1982
|
-
},
|
|
1983
|
-
event(e) {
|
|
1984
|
-
safeSend(JSON.stringify(e));
|
|
1985
|
-
},
|
|
1986
|
-
playAudioChunk(chunk) {
|
|
1987
|
-
safeSend(chunk);
|
|
1988
|
-
},
|
|
1989
|
-
playAudioDone() {
|
|
1990
|
-
safeSend(JSON.stringify({ type: "audio_done" }));
|
|
1991
|
-
}
|
|
1992
|
-
};
|
|
1993
|
-
}
|
|
1994
|
-
function isBinaryData(data) {
|
|
1995
|
-
return globalThis.Buffer?.isBuffer(data) || data instanceof ArrayBuffer || data instanceof Uint8Array;
|
|
1996
|
-
}
|
|
1997
|
-
function toUint8Array(data) {
|
|
1998
|
-
if (data instanceof Uint8Array) return data;
|
|
1999
|
-
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
2000
|
-
const buf = data;
|
|
2001
|
-
return new Uint8Array(buf.buffer ?? data, buf.byteOffset ?? 0, buf.byteLength);
|
|
2002
|
-
}
|
|
2003
|
-
function handleBinaryAudio(data, session) {
|
|
2004
|
-
if (!isBinaryData(data)) return false;
|
|
2005
|
-
session.onAudio(toUint8Array(data));
|
|
2006
|
-
return true;
|
|
2007
|
-
}
|
|
2008
|
-
function handleTextMessage(data, session, log, ctx, sid) {
|
|
2009
|
-
if (typeof data !== "string") return;
|
|
2010
|
-
let json;
|
|
2011
|
-
try {
|
|
2012
|
-
json = JSON.parse(data);
|
|
2013
|
-
} catch {
|
|
2014
|
-
log.warn("Invalid JSON from client", { ...ctx, sid });
|
|
2015
|
-
return;
|
|
2016
|
-
}
|
|
2017
|
-
const parsed = ClientMessageSchema.safeParse(json);
|
|
2018
|
-
if (!parsed.success) {
|
|
2019
|
-
log.warn("Invalid client message", { ...ctx, sid, error: parsed.error.message });
|
|
2020
|
-
return;
|
|
2021
|
-
}
|
|
2022
|
-
const msg = parsed.data;
|
|
2023
|
-
switch (msg.type) {
|
|
2024
|
-
case "audio_ready":
|
|
2025
|
-
session.onAudioReady();
|
|
2026
|
-
break;
|
|
2027
|
-
case "cancel":
|
|
2028
|
-
session.onCancel();
|
|
2029
|
-
break;
|
|
2030
|
-
case "reset":
|
|
2031
|
-
session.onReset();
|
|
2032
|
-
break;
|
|
2033
|
-
case "history":
|
|
2034
|
-
session.onHistory(msg.messages);
|
|
2035
|
-
break;
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2038
|
-
function wireSessionSocket(ws, opts) {
|
|
2039
|
-
const { sessions, logger: log = consoleLogger } = opts;
|
|
2040
|
-
const sessionId = crypto.randomUUID();
|
|
2041
|
-
const sid = sessionId.slice(0, 8);
|
|
2042
|
-
const ctx = opts.logContext ?? {};
|
|
2043
|
-
let session = null;
|
|
2044
|
-
function onOpen() {
|
|
2045
|
-
opts.onOpen?.();
|
|
2046
|
-
log.info("Session connected", { ...ctx, sid });
|
|
2047
|
-
const client = createClientSink(ws);
|
|
2048
|
-
session = opts.createSession(sessionId, client);
|
|
2049
|
-
sessions.set(sessionId, session);
|
|
2050
|
-
ws.send(JSON.stringify({ type: "config", ...opts.readyConfig }));
|
|
2051
|
-
session.start().then(() => {
|
|
2052
|
-
log.info("Session ready", { ...ctx, sid });
|
|
2053
|
-
}).catch((err) => {
|
|
2054
|
-
log.error("Session start failed", { ...ctx, sid, error: errorMessage(err) });
|
|
2055
|
-
});
|
|
2056
|
-
}
|
|
2057
|
-
if (ws.readyState === 1) {
|
|
2058
|
-
onOpen();
|
|
2059
|
-
} else {
|
|
2060
|
-
ws.addEventListener("open", onOpen);
|
|
2061
|
-
}
|
|
2062
|
-
ws.addEventListener("message", (event) => {
|
|
2063
|
-
if (!session) return;
|
|
2064
|
-
const { data } = event;
|
|
2065
|
-
if (handleBinaryAudio(data, session)) return;
|
|
2066
|
-
handleTextMessage(data, session, log, ctx, sid);
|
|
2067
|
-
});
|
|
2068
|
-
ws.addEventListener("close", () => {
|
|
2069
|
-
log.info("Session disconnected", { ...ctx, sid });
|
|
2070
|
-
if (session) {
|
|
2071
|
-
void session.stop().finally(() => {
|
|
2072
|
-
sessions.delete(sessionId);
|
|
2073
|
-
});
|
|
2074
|
-
}
|
|
2075
|
-
opts.onClose?.();
|
|
2076
|
-
});
|
|
2077
|
-
ws.addEventListener("error", (event) => {
|
|
2078
|
-
const msg = event instanceof ErrorEvent ? event.message : "WebSocket error";
|
|
2079
|
-
log.error("WebSocket error", { ...ctx, sid, error: msg });
|
|
2080
|
-
});
|
|
2081
|
-
}
|
|
2082
|
-
var init_ws_handler = __esm({
|
|
2083
|
-
"sdk/ws_handler.ts"() {
|
|
2084
|
-
"use strict";
|
|
2085
|
-
init_utils();
|
|
2086
|
-
init_protocol();
|
|
2087
|
-
init_runtime();
|
|
2088
|
-
}
|
|
2089
|
-
});
|
|
2090
|
-
|
|
2091
|
-
// sdk/winterc_server.ts
|
|
2092
|
-
import { Hono } from "hono";
|
|
2093
|
-
function createWintercServer(options) {
|
|
2094
|
-
const {
|
|
2095
|
-
agent,
|
|
2096
|
-
env,
|
|
2097
|
-
kv = createMemoryKv(),
|
|
2098
|
-
vector = createMemoryVectorStore(),
|
|
2099
|
-
vectorSearch,
|
|
2100
|
-
clientHtml,
|
|
2101
|
-
logger = consoleLogger,
|
|
2102
|
-
metrics = noopMetrics,
|
|
2103
|
-
s2sConfig = DEFAULT_S2S_CONFIG
|
|
2104
|
-
} = options;
|
|
2105
|
-
const executor = createDirectExecutor({
|
|
2106
|
-
agent,
|
|
2107
|
-
env,
|
|
2108
|
-
kv,
|
|
2109
|
-
vector,
|
|
2110
|
-
...vectorSearch ? { vectorSearch } : {},
|
|
2111
|
-
createWebSocket: options.createWebSocket,
|
|
2112
|
-
logger,
|
|
2113
|
-
metrics,
|
|
2114
|
-
s2sConfig
|
|
2115
|
-
});
|
|
2116
|
-
const sessions = /* @__PURE__ */ new Map();
|
|
2117
|
-
const readyConfig = {
|
|
2118
|
-
audioFormat: AUDIO_FORMAT,
|
|
2119
|
-
sampleRate: s2sConfig.inputSampleRate,
|
|
2120
|
-
ttsSampleRate: s2sConfig.outputSampleRate
|
|
2121
|
-
};
|
|
2122
|
-
const app = new Hono();
|
|
2123
|
-
app.get("/health", (c) => c.json({ status: "ok", name: agent.name }));
|
|
2124
|
-
app.get("/", (c) => {
|
|
2125
|
-
if (clientHtml) {
|
|
2126
|
-
return c.html(clientHtml);
|
|
2127
|
-
}
|
|
2128
|
-
return c.html(
|
|
2129
|
-
`<!DOCTYPE html><html><body><h1>${agent.name}</h1><p>Agent server running.</p></body></html>`
|
|
2130
|
-
);
|
|
2131
|
-
});
|
|
2132
|
-
return {
|
|
2133
|
-
async fetch(request) {
|
|
2134
|
-
return app.fetch(request);
|
|
2135
|
-
},
|
|
2136
|
-
handleWebSocket(ws, wsOpts) {
|
|
2137
|
-
wireSessionSocket(ws, {
|
|
2138
|
-
sessions,
|
|
2139
|
-
createSession: (sid, client) => executor.createSession({
|
|
2140
|
-
id: sid,
|
|
2141
|
-
agent: agent.name,
|
|
2142
|
-
client,
|
|
2143
|
-
skipGreeting: wsOpts?.skipGreeting ?? false
|
|
2144
|
-
}),
|
|
2145
|
-
readyConfig,
|
|
2146
|
-
logger
|
|
2147
|
-
});
|
|
2148
|
-
},
|
|
2149
|
-
async close() {
|
|
2150
|
-
for (const session of sessions.values()) {
|
|
2151
|
-
await session.stop();
|
|
2152
|
-
}
|
|
2153
|
-
sessions.clear();
|
|
2154
|
-
}
|
|
2155
|
-
};
|
|
2156
|
-
}
|
|
2157
|
-
var init_winterc_server = __esm({
|
|
2158
|
-
"sdk/winterc_server.ts"() {
|
|
2159
|
-
"use strict";
|
|
2160
|
-
init_direct_executor();
|
|
2161
|
-
init_kv();
|
|
2162
|
-
init_protocol();
|
|
2163
|
-
init_runtime();
|
|
2164
|
-
init_vector();
|
|
2165
|
-
init_ws_handler();
|
|
2166
|
-
}
|
|
2167
|
-
});
|
|
2168
|
-
|
|
2169
|
-
// sdk/server.ts
|
|
2170
|
-
var server_exports = {};
|
|
2171
|
-
__export(server_exports, {
|
|
2172
|
-
createServer: () => createServer
|
|
2173
|
-
});
|
|
2174
|
-
import { serve } from "@hono/node-server";
|
|
2175
|
-
import { serveStatic } from "@hono/node-server/serve-static";
|
|
2176
|
-
import { Hono as Hono2 } from "hono";
|
|
2177
|
-
async function loadWsFactory() {
|
|
2178
|
-
try {
|
|
2179
|
-
const mod = await import("ws");
|
|
2180
|
-
const WS = mod.default ?? mod;
|
|
2181
|
-
return (url, opts) => wrapOnStyleWebSocket(new WS(url, { headers: opts.headers }));
|
|
2182
|
-
} catch {
|
|
2183
|
-
throw new Error(
|
|
2184
|
-
"WebSocket factory not provided and `ws` package not found. Install `ws` (`npm install ws`) or pass `createWebSocket` option."
|
|
2185
|
-
);
|
|
2186
|
-
}
|
|
2187
|
-
}
|
|
2188
|
-
function resolveEnv(env) {
|
|
2189
|
-
return Object.fromEntries(Object.entries(env).filter(([, v]) => v !== void 0));
|
|
2190
|
-
}
|
|
2191
|
-
function createServer(options) {
|
|
2192
|
-
const {
|
|
2193
|
-
agent,
|
|
2194
|
-
kv,
|
|
2195
|
-
clientHtml,
|
|
2196
|
-
clientDir,
|
|
2197
|
-
logger = consoleLogger,
|
|
2198
|
-
s2sConfig = DEFAULT_S2S_CONFIG
|
|
2199
|
-
} = options;
|
|
2200
|
-
const env = resolveEnv(
|
|
2201
|
-
options.env ?? (typeof process !== "undefined" ? process.env : {})
|
|
2202
|
-
);
|
|
2203
|
-
let wsFactory = options.createWebSocket ?? null;
|
|
2204
|
-
async function getWsFactory() {
|
|
2205
|
-
if (!wsFactory) {
|
|
2206
|
-
wsFactory = await loadWsFactory();
|
|
2207
|
-
}
|
|
2208
|
-
return wsFactory;
|
|
2209
|
-
}
|
|
2210
|
-
let winterc = null;
|
|
2211
|
-
function getWinterc() {
|
|
2212
|
-
if (!winterc) {
|
|
2213
|
-
winterc = createWintercServer({
|
|
2214
|
-
agent,
|
|
2215
|
-
env,
|
|
2216
|
-
...kv ? { kv } : {},
|
|
2217
|
-
createWebSocket: wsFactory ?? (() => {
|
|
2218
|
-
throw new Error("WebSocket factory not loaded");
|
|
2219
|
-
}),
|
|
2220
|
-
...clientHtml !== void 0 ? { clientHtml } : {},
|
|
2221
|
-
logger,
|
|
2222
|
-
s2sConfig
|
|
2223
|
-
});
|
|
2224
|
-
}
|
|
2225
|
-
return winterc;
|
|
2226
|
-
}
|
|
2227
|
-
let serverHandle = null;
|
|
2228
|
-
return {
|
|
2229
|
-
fetch(request) {
|
|
2230
|
-
return getWinterc().fetch(request);
|
|
2231
|
-
},
|
|
2232
|
-
async listen(port = 3e3) {
|
|
2233
|
-
await getWsFactory();
|
|
2234
|
-
const wintercServer = getWinterc();
|
|
2235
|
-
const app = new Hono2();
|
|
2236
|
-
app.onError((err, c) => {
|
|
2237
|
-
logger.error(`${c.req.method} ${new URL(c.req.url).pathname} error: ${err.message}`);
|
|
2238
|
-
return c.json({ error: "Internal Server Error" }, 500);
|
|
2239
|
-
});
|
|
2240
|
-
app.use("/*", async (c, next) => {
|
|
2241
|
-
const start = Date.now();
|
|
2242
|
-
await next();
|
|
2243
|
-
const ms = Date.now() - start;
|
|
2244
|
-
const status = c.res.status;
|
|
2245
|
-
const method = c.req.method;
|
|
2246
|
-
const path8 = new URL(c.req.url).pathname;
|
|
2247
|
-
if (status >= 400) {
|
|
2248
|
-
logger.error(`${method} ${path8} ${status} ${ms}ms`);
|
|
2249
|
-
} else {
|
|
2250
|
-
logger.info(`${method} ${path8} ${status} ${ms}ms`);
|
|
2251
|
-
}
|
|
2252
|
-
});
|
|
2253
|
-
if (clientDir) {
|
|
2254
|
-
app.use("/*", serveStatic({ root: clientDir }));
|
|
2255
|
-
}
|
|
2256
|
-
app.all("/*", (c) => wintercServer.fetch(c.req.raw));
|
|
2257
|
-
const nodeServer = serve({ fetch: app.fetch, port });
|
|
2258
|
-
await new Promise((resolve) => {
|
|
2259
|
-
nodeServer.on("listening", resolve);
|
|
2260
|
-
});
|
|
2261
|
-
try {
|
|
2262
|
-
const wsMod = await import("ws");
|
|
2263
|
-
const wss = new wsMod.WebSocketServer({ noServer: true });
|
|
2264
|
-
nodeServer.on("upgrade", (req, socket, head) => {
|
|
2265
|
-
const reqUrl = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
2266
|
-
const resume = reqUrl.searchParams.has("resume");
|
|
2267
|
-
logger.info(`WS upgrade ${reqUrl.pathname}${resume ? " (resume)" : ""}`);
|
|
2268
|
-
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
2269
|
-
wintercServer.handleWebSocket(ws, {
|
|
2270
|
-
skipGreeting: resume
|
|
2271
|
-
});
|
|
2272
|
-
});
|
|
2273
|
-
});
|
|
2274
|
-
} catch {
|
|
2275
|
-
logger.warn("ws package not available for Node.js WebSocket upgrade");
|
|
2276
|
-
}
|
|
2277
|
-
serverHandle = {
|
|
2278
|
-
async shutdown() {
|
|
2279
|
-
await new Promise((resolve, reject) => {
|
|
2280
|
-
nodeServer.close((err) => err ? reject(err) : resolve());
|
|
2281
|
-
});
|
|
2282
|
-
}
|
|
2283
|
-
};
|
|
2284
|
-
},
|
|
2285
|
-
async close() {
|
|
2286
|
-
await winterc?.close();
|
|
2287
|
-
await serverHandle?.shutdown();
|
|
2288
|
-
}
|
|
2289
|
-
};
|
|
2290
|
-
}
|
|
2291
|
-
var init_server = __esm({
|
|
2292
|
-
"sdk/server.ts"() {
|
|
2293
|
-
"use strict";
|
|
2294
|
-
init_runtime();
|
|
2295
|
-
init_s2s();
|
|
2296
|
-
init_winterc_server();
|
|
2297
|
-
}
|
|
2298
|
-
});
|
|
2299
|
-
|
|
2300
|
-
// cli/_server_common.ts
|
|
2301
|
-
import fs5 from "node:fs/promises";
|
|
2302
|
-
import path5 from "node:path";
|
|
2303
|
-
import { tsImport } from "tsx/esm/api";
|
|
2304
|
-
async function loadAgentDef(cwd) {
|
|
2305
|
-
const agentPath = path5.resolve(cwd, "agent.ts");
|
|
2306
|
-
const agentModule = await tsImport(agentPath, cwd);
|
|
2307
|
-
let agentDef = agentModule.default;
|
|
2308
|
-
if (agentDef?.__esModule && agentDef.default) {
|
|
2309
|
-
agentDef = agentDef.default;
|
|
2310
|
-
}
|
|
2311
|
-
if (!agentDef || typeof agentDef !== "object" || !agentDef.name) {
|
|
2312
|
-
throw new Error("agent.ts must export a default agent definition (from defineAgent())");
|
|
2313
|
-
}
|
|
2314
|
-
return agentDef;
|
|
2315
|
-
}
|
|
2316
|
-
async function resolveServerEnv(baseEnv) {
|
|
2317
|
-
const env = Object.fromEntries(
|
|
2318
|
-
Object.entries(baseEnv ?? process.env).filter((e) => e[1] !== void 0)
|
|
2319
|
-
);
|
|
2320
|
-
if (!env.ASSEMBLYAI_API_KEY) {
|
|
2321
|
-
env.ASSEMBLYAI_API_KEY = await getApiKey();
|
|
2322
|
-
}
|
|
2323
|
-
return env;
|
|
2324
|
-
}
|
|
2325
|
-
async function bootServer(agentDef, clientDir, env, port) {
|
|
2326
|
-
const { wrapOnStyleWebSocket: wrapOnStyleWebSocket2 } = await Promise.resolve().then(() => (init_s2s(), s2s_exports));
|
|
2327
|
-
const wsMod = await import("ws");
|
|
2328
|
-
const WS = wsMod.default ?? wsMod;
|
|
2329
|
-
const createWebSocket = (url, opts) => wrapOnStyleWebSocket2(new WS(url, { headers: opts.headers }));
|
|
2330
|
-
const clientHtml = await fs5.readFile(path5.join(clientDir, "index.html"), "utf-8");
|
|
2331
|
-
const { createServer: createServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
2332
|
-
const server = createServer2({
|
|
2333
|
-
agent: agentDef,
|
|
2334
|
-
clientHtml,
|
|
2335
|
-
clientDir,
|
|
2336
|
-
env,
|
|
2337
|
-
createWebSocket
|
|
2338
|
-
});
|
|
2339
|
-
await server.listen(port);
|
|
2340
|
-
}
|
|
2341
|
-
var init_server_common = __esm({
|
|
2342
|
-
"cli/_server_common.ts"() {
|
|
2343
|
-
"use strict";
|
|
2344
|
-
init_discover();
|
|
2345
|
-
}
|
|
2346
|
-
});
|
|
2347
|
-
|
|
2348
|
-
// cli/dev.tsx
|
|
2349
|
-
var dev_exports = {};
|
|
2350
|
-
__export(dev_exports, {
|
|
2351
|
-
_startDevServer: () => _startDevServer,
|
|
2352
|
-
runDevCommand: () => runDevCommand
|
|
2353
|
-
});
|
|
2354
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
2355
|
-
async function _startDevServer(cwd, port, log) {
|
|
2356
|
-
const bundle = await buildAgentBundle(cwd, log, { skipRenderCheck: true });
|
|
2357
|
-
const agentDef = await loadAgentDef(cwd);
|
|
2358
|
-
const env = await resolveServerEnv();
|
|
2359
|
-
await bootServer(agentDef, bundle.clientDir, env, port);
|
|
2360
|
-
log(/* @__PURE__ */ jsx6(Step, { action: "Ready", msg: `http://localhost:${port}` }));
|
|
2361
|
-
}
|
|
2362
|
-
async function runDevCommand(opts) {
|
|
2363
|
-
const port = Number.parseInt(opts.port, 10);
|
|
2364
|
-
await runWithInk(async ({ log }) => {
|
|
2365
|
-
await _startDevServer(opts.cwd, port, log);
|
|
2366
|
-
});
|
|
2367
|
-
}
|
|
2368
|
-
var init_dev = __esm({
|
|
2369
|
-
"cli/dev.tsx"() {
|
|
2370
|
-
"use strict";
|
|
2371
|
-
init_build();
|
|
2372
|
-
init_ink();
|
|
2373
|
-
init_server_common();
|
|
2374
|
-
}
|
|
2375
|
-
});
|
|
2376
|
-
|
|
2377
|
-
// cli/start.tsx
|
|
2378
|
-
var start_exports = {};
|
|
2379
|
-
__export(start_exports, {
|
|
2380
|
-
_startProductionServer: () => _startProductionServer,
|
|
2381
|
-
runStartCommand: () => runStartCommand
|
|
2382
|
-
});
|
|
2383
|
-
import path6 from "node:path";
|
|
2384
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
2385
|
-
async function _startProductionServer(cwd, port, log) {
|
|
2386
|
-
const clientDir = path6.join(cwd, ".aai", "client");
|
|
2387
|
-
log(/* @__PURE__ */ jsx7(Step, { action: "Start", msg: "loading agent" }));
|
|
2388
|
-
const agentDef = await loadAgentDef(cwd);
|
|
2389
|
-
const env = await resolveServerEnv();
|
|
2390
|
-
await bootServer(agentDef, clientDir, env, port);
|
|
2391
|
-
log(/* @__PURE__ */ jsx7(Step, { action: "Ready", msg: `http://localhost:${port}` }));
|
|
2392
|
-
}
|
|
2393
|
-
async function runStartCommand(opts) {
|
|
2394
|
-
const port = Number.parseInt(opts.port, 10);
|
|
2395
|
-
const buildDir = path6.join(opts.cwd, ".aai", "build");
|
|
2396
|
-
if (!await fileExists(path6.join(buildDir, "worker.js"))) {
|
|
2397
|
-
throw new Error("No build found \u2014 run `aai build` first");
|
|
2398
|
-
}
|
|
2399
|
-
await runWithInk(async ({ log }) => {
|
|
2400
|
-
log(/* @__PURE__ */ jsx7(Step, { action: "Start", msg: `production server on port ${port}` }));
|
|
2401
|
-
await _startProductionServer(opts.cwd, port, log);
|
|
2402
|
-
});
|
|
2403
|
-
}
|
|
2404
|
-
var init_start = __esm({
|
|
2405
|
-
"cli/start.tsx"() {
|
|
2406
|
-
"use strict";
|
|
2407
|
-
init_discover();
|
|
2408
|
-
init_ink();
|
|
2409
|
-
init_server_common();
|
|
2410
|
-
}
|
|
2411
|
-
});
|
|
2412
|
-
|
|
2413
|
-
// cli/secret.tsx
|
|
2414
|
-
var secret_exports = {};
|
|
2415
|
-
__export(secret_exports, {
|
|
2416
|
-
runSecretDelete: () => runSecretDelete,
|
|
2417
|
-
runSecretList: () => runSecretList,
|
|
2418
|
-
runSecretPut: () => runSecretPut
|
|
2419
|
-
});
|
|
2420
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
2421
|
-
async function apiFetch(cwd, pathSuffix, init) {
|
|
2422
|
-
const { serverUrl, slug, apiKey } = await getServerInfo(cwd);
|
|
2423
|
-
const resp = await fetch(`${serverUrl}/${slug}/secret${pathSuffix}`, {
|
|
2424
|
-
...init,
|
|
2425
|
-
headers: { Authorization: `Bearer ${apiKey}`, ...init?.headers }
|
|
2426
|
-
});
|
|
2427
|
-
if (!resp.ok) {
|
|
2428
|
-
const text = await resp.text();
|
|
2429
|
-
throw new Error(`Secret operation failed: ${text}`);
|
|
2430
|
-
}
|
|
2431
|
-
return { resp, slug };
|
|
2432
|
-
}
|
|
2433
|
-
async function runSecretPut(cwd, name) {
|
|
2434
|
-
const value = await askPassword(`Enter value for ${name}`);
|
|
2435
|
-
if (!value) throw new Error("No value provided");
|
|
2436
|
-
await runWithInk(async ({ log }) => {
|
|
2437
|
-
const { slug } = await apiFetch(cwd, "", {
|
|
2438
|
-
method: "PUT",
|
|
2439
|
-
headers: { "Content-Type": "application/json" },
|
|
2440
|
-
body: JSON.stringify({ [name]: value })
|
|
2441
|
-
});
|
|
2442
|
-
log(/* @__PURE__ */ jsx8(Step, { action: "Set", msg: `${name} for ${slug}` }));
|
|
2443
|
-
});
|
|
2444
|
-
}
|
|
2445
|
-
async function runSecretDelete(cwd, name) {
|
|
2446
|
-
await runWithInk(async ({ log }) => {
|
|
2447
|
-
const { slug } = await apiFetch(cwd, `/${name}`, { method: "DELETE" });
|
|
2448
|
-
log(/* @__PURE__ */ jsx8(Step, { action: "Deleted", msg: `${name} from ${slug}` }));
|
|
2449
|
-
});
|
|
2450
|
-
}
|
|
2451
|
-
async function runSecretList(cwd) {
|
|
2452
|
-
await runWithInk(async ({ log }) => {
|
|
2453
|
-
const { resp } = await apiFetch(cwd, "");
|
|
2454
|
-
const { vars } = await resp.json();
|
|
2455
|
-
if (vars.length === 0) {
|
|
2456
|
-
log(/* @__PURE__ */ jsx8(StepInfo, { action: "Secrets", msg: "none set" }));
|
|
2457
|
-
} else {
|
|
2458
|
-
for (const name of vars) {
|
|
2459
|
-
log(/* @__PURE__ */ jsx8(Detail, { msg: name }));
|
|
2460
|
-
}
|
|
2461
|
-
}
|
|
2462
|
-
});
|
|
2463
|
-
}
|
|
2464
|
-
var init_secret = __esm({
|
|
2465
|
-
"cli/secret.tsx"() {
|
|
2466
|
-
"use strict";
|
|
2467
|
-
init_discover();
|
|
2468
|
-
init_ink();
|
|
2469
|
-
init_prompts();
|
|
2470
|
-
}
|
|
2471
|
-
});
|
|
2472
|
-
|
|
2473
|
-
// cli/rag.tsx
|
|
2474
|
-
var rag_exports = {};
|
|
2475
|
-
__export(rag_exports, {
|
|
2476
|
-
chunkPages: () => chunkPages,
|
|
2477
|
-
parsePage: () => parsePage,
|
|
2478
|
-
runRagCommand: () => runRagCommand,
|
|
2479
|
-
slugify: () => slugify,
|
|
2480
|
-
splitPages: () => splitPages,
|
|
2481
|
-
stripNoise: () => stripNoise,
|
|
2482
|
-
upsertChunks: () => upsertChunks
|
|
2483
|
-
});
|
|
2484
|
-
import { Text as Text3 } from "ink";
|
|
2485
|
-
import pLimit from "p-limit";
|
|
2486
|
-
import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2487
|
-
async function runRag(opts) {
|
|
2488
|
-
const { url, apiKey, serverUrl, slug, chunkSize, log, setStatus } = opts;
|
|
2489
|
-
log(/* @__PURE__ */ jsx9(Step, { action: "Fetch", msg: url }));
|
|
2490
|
-
const resp = await fetch(url, {
|
|
2491
|
-
headers: { "User-Agent": "aai-cli/1.0" },
|
|
2492
|
-
redirect: "follow",
|
|
2493
|
-
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
|
|
2494
|
-
});
|
|
2495
|
-
if (!resp.ok) {
|
|
2496
|
-
throw new Error(`Failed to fetch: ${resp.status} ${resp.statusText}`);
|
|
2497
|
-
}
|
|
2498
|
-
const content = await resp.text();
|
|
2499
|
-
if (content.length === 0) {
|
|
2500
|
-
log(/* @__PURE__ */ jsx9(Warn, { msg: "File is empty" }));
|
|
2501
|
-
return;
|
|
2502
|
-
}
|
|
2503
|
-
log(/* @__PURE__ */ jsx9(Info, { msg: `${(content.length / 1024).toFixed(0)} KB` }));
|
|
2504
|
-
const origin = new URL(url).origin;
|
|
2505
|
-
const pages = splitPages(content);
|
|
2506
|
-
log(/* @__PURE__ */ jsx9(Step, { action: "Parse", msg: `${pages.length} pages` }));
|
|
2507
|
-
const { RecursiveChunker } = await import("@chonkiejs/core");
|
|
2508
|
-
const chunker = await RecursiveChunker.create({ chunkSize });
|
|
2509
|
-
const siteSlug = slugify(origin);
|
|
2510
|
-
const allChunks = await chunkPages(pages, chunker, origin, siteSlug);
|
|
2511
|
-
log(/* @__PURE__ */ jsx9(Step, { action: "Chunk", msg: `${allChunks.length} chunks` }));
|
|
2512
|
-
const vectorUrl = `${serverUrl}/${slug}/vector`;
|
|
2513
|
-
log(/* @__PURE__ */ jsx9(Info, { msg: `target: ${vectorUrl}` }));
|
|
2514
|
-
const result = await upsertChunks(allChunks, vectorUrl, apiKey, setStatus);
|
|
2515
|
-
log(/* @__PURE__ */ jsx9(Step, { action: "Done", msg: `${result.upserted} chunks upserted` }));
|
|
2516
|
-
if (result.errors > 0) {
|
|
2517
|
-
log(/* @__PURE__ */ jsx9(Warn, { msg: `${result.errors} failed` }));
|
|
2518
|
-
if (result.lastError) log(/* @__PURE__ */ jsx9(Info, { msg: `last error: ${result.lastError}` }));
|
|
2519
|
-
}
|
|
2520
|
-
log(/* @__PURE__ */ jsx9(Detail, { msg: `Agent: ${slug}` }));
|
|
2521
|
-
}
|
|
2522
|
-
async function chunkPages(pages, chunker, origin, siteSlug) {
|
|
2523
|
-
const allChunks = [];
|
|
2524
|
-
for (const page of pages) {
|
|
2525
|
-
page.body = stripNoise(page.body);
|
|
2526
|
-
if (!page.body) continue;
|
|
2527
|
-
const raw = await chunker.chunk(page.body);
|
|
2528
|
-
for (const [i, c] of raw.entries()) {
|
|
2529
|
-
const data = page.title ? `${page.title}
|
|
2530
|
-
|
|
2531
|
-
${c.text}` : c.text;
|
|
2532
|
-
const id = `${siteSlug}:${slugify(page.title || "page")}:${i}`;
|
|
2533
|
-
allChunks.push({
|
|
2534
|
-
id,
|
|
2535
|
-
data,
|
|
2536
|
-
metadata: {
|
|
2537
|
-
source: origin,
|
|
2538
|
-
...page.title ? { title: page.title } : {},
|
|
2539
|
-
tokenCount: c.tokenCount
|
|
2540
|
-
}
|
|
2541
|
-
});
|
|
2542
|
-
}
|
|
2543
|
-
}
|
|
2544
|
-
return allChunks;
|
|
2545
|
-
}
|
|
2546
|
-
async function upsertChunks(chunks, vectorUrl, apiKey, setStatus, fetchFn = globalThis.fetch) {
|
|
2547
|
-
const total = chunks.length;
|
|
2548
|
-
let completed = 0;
|
|
2549
|
-
let upserted = 0;
|
|
2550
|
-
let errors = 0;
|
|
2551
|
-
let lastError = "";
|
|
2552
|
-
const updateStatus = () => {
|
|
2553
|
-
const pct = Math.round(completed / total * 100);
|
|
2554
|
-
setStatus(
|
|
2555
|
-
/* @__PURE__ */ jsxs3(Text3, { children: [
|
|
2556
|
-
" ",
|
|
2557
|
-
"Upsert ",
|
|
2558
|
-
completed,
|
|
2559
|
-
"/",
|
|
2560
|
-
total,
|
|
2561
|
-
" (",
|
|
2562
|
-
pct,
|
|
2563
|
-
"%)"
|
|
2564
|
-
] })
|
|
2565
|
-
);
|
|
2566
|
-
};
|
|
2567
|
-
updateStatus();
|
|
2568
|
-
const limit = pLimit(5);
|
|
2569
|
-
await Promise.all(
|
|
2570
|
-
chunks.map(
|
|
2571
|
-
(chunk) => limit(async () => {
|
|
2572
|
-
try {
|
|
2573
|
-
const r = await fetchFn(vectorUrl, {
|
|
2574
|
-
method: "POST",
|
|
2575
|
-
headers: {
|
|
2576
|
-
"Content-Type": "application/json",
|
|
2577
|
-
Authorization: `Bearer ${apiKey}`
|
|
2578
|
-
},
|
|
2579
|
-
body: JSON.stringify({
|
|
2580
|
-
op: "upsert",
|
|
2581
|
-
id: chunk.id,
|
|
2582
|
-
data: chunk.data,
|
|
2583
|
-
metadata: chunk.metadata
|
|
2584
|
-
})
|
|
2585
|
-
});
|
|
2586
|
-
if (!r.ok) {
|
|
2587
|
-
lastError = await r.text();
|
|
2588
|
-
errors++;
|
|
2589
|
-
} else {
|
|
2590
|
-
upserted++;
|
|
2591
|
-
}
|
|
2592
|
-
} catch (err) {
|
|
2593
|
-
lastError = errorMessage(err);
|
|
2594
|
-
errors++;
|
|
2595
|
-
}
|
|
2596
|
-
completed++;
|
|
2597
|
-
updateStatus();
|
|
2598
|
-
})
|
|
2599
|
-
)
|
|
2600
|
-
);
|
|
2601
|
-
setStatus(null);
|
|
2602
|
-
return { upserted, errors, lastError };
|
|
2603
|
-
}
|
|
2604
|
-
async function runRagCommand(opts) {
|
|
2605
|
-
const { url, cwd } = opts;
|
|
2606
|
-
try {
|
|
2607
|
-
new URL(url);
|
|
2608
|
-
} catch {
|
|
2609
|
-
throw new Error(`Invalid URL: ${url}`);
|
|
2610
|
-
}
|
|
2611
|
-
const { apiKey, serverUrl, slug } = await getServerInfo(cwd, opts.server);
|
|
2612
|
-
const chunkSize = Number.parseInt(opts.chunkSize ?? "512", 10);
|
|
2613
|
-
await runWithInk(async ({ log, setStatus }) => {
|
|
2614
|
-
await runRag({ url, apiKey, serverUrl, slug, chunkSize, log, setStatus });
|
|
2615
|
-
});
|
|
2616
|
-
}
|
|
2617
|
-
function splitPages(content) {
|
|
2618
|
-
const raw = content.split(/^\*{3,}$/m);
|
|
2619
|
-
const pages = [];
|
|
2620
|
-
for (const section of raw) {
|
|
2621
|
-
const trimmed = section.trim();
|
|
2622
|
-
if (!trimmed) continue;
|
|
2623
|
-
const page = parsePage(trimmed);
|
|
2624
|
-
if (page.body.length > 0) {
|
|
2625
|
-
pages.push(page);
|
|
2626
|
-
}
|
|
2627
|
-
}
|
|
2628
|
-
return pages;
|
|
2629
|
-
}
|
|
2630
|
-
function parsePage(trimmed) {
|
|
2631
|
-
let title = "";
|
|
2632
|
-
let body = trimmed;
|
|
2633
|
-
const dashIndex = trimmed.search(/^-{3,}$/m);
|
|
2634
|
-
if (dashIndex !== -1) {
|
|
2635
|
-
const frontmatter = trimmed.slice(0, dashIndex);
|
|
2636
|
-
body = trimmed.slice(dashIndex).replace(/^-+$/m, "").trim();
|
|
2637
|
-
const titleMatch = frontmatter.match(/^title:\s*(.+)$/m);
|
|
2638
|
-
if (titleMatch) {
|
|
2639
|
-
title = titleMatch[1]?.trim() ?? "";
|
|
2640
|
-
}
|
|
2641
|
-
}
|
|
2642
|
-
if (!title) {
|
|
2643
|
-
const titleLineMatch = body.match(/^#{1,2}\s+title:\s*(.+)$/m);
|
|
2644
|
-
if (titleLineMatch) {
|
|
2645
|
-
title = titleLineMatch[1]?.trim() ?? "";
|
|
2646
|
-
body = body.replace(/^#{1,2}\s+title:\s*.+\n?/m, "").trim();
|
|
2647
|
-
} else {
|
|
2648
|
-
const headingMatch = body.match(/^(#{1,3})\s+(.+)$/m);
|
|
2649
|
-
if (headingMatch) {
|
|
2650
|
-
title = headingMatch[2]?.trim() ?? "";
|
|
2651
|
-
}
|
|
2652
|
-
}
|
|
2653
|
-
}
|
|
2654
|
-
return { title, body };
|
|
2655
|
-
}
|
|
2656
|
-
function stripNoise(text) {
|
|
2657
|
-
return text.replace(/^(`{3,}|~{3,}).*[\s\S]*?^\1/gm, "").replace(/^(?:[ ]{4,}|\t).+$/gm, "").replace(/`[^`]+`/g, "").replace(/\{\/\*[\s\S]*?\*\/\}/g, "").replace(/<[^>]+>/g, "").replace(/^\s*\}[^}\n]*$/gm, "").replace(/^\s+$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
2658
|
-
}
|
|
2659
|
-
function slugify(s) {
|
|
2660
|
-
return s.replace(/^https?:\/\//, "").replace(/^#+\s*/, "").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase().slice(0, 80);
|
|
2661
|
-
}
|
|
2662
|
-
var FETCH_TIMEOUT_MS2;
|
|
2663
|
-
var init_rag = __esm({
|
|
2664
|
-
"cli/rag.tsx"() {
|
|
2665
|
-
"use strict";
|
|
2666
|
-
init_utils();
|
|
2667
|
-
init_discover();
|
|
2668
|
-
init_ink();
|
|
2669
|
-
FETCH_TIMEOUT_MS2 = 6e4;
|
|
2670
|
-
}
|
|
2671
|
-
});
|
|
2672
|
-
|
|
2673
|
-
// cli/cli.ts
|
|
2674
|
-
init_utils();
|
|
2675
|
-
init_discover();
|
|
2676
|
-
init_ink();
|
|
2677
|
-
import { readFileSync } from "node:fs";
|
|
2678
|
-
import path7 from "node:path";
|
|
2679
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2680
|
-
import chalk2 from "chalk";
|
|
2681
|
-
import { Command } from "commander";
|
|
2682
|
-
var cliDir = path7.dirname(fileURLToPath2(import.meta.url));
|
|
2683
|
-
var pkgJsonPath = path7.join(cliDir, "..", "package.json");
|
|
2684
|
-
var pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
|
|
2685
|
-
var VERSION = pkgJson.version;
|
|
2686
|
-
var banner = [
|
|
2687
|
-
"",
|
|
2688
|
-
` ${primary(chalk2.bold(" \u2584\u2580\u2588 \u2584\u2580\u2588 \u2588"))} ${chalk2.dim("Voice agent development kit")}`,
|
|
2689
|
-
` ${primary(chalk2.bold(" \u2588\u2580\u2588 \u2588\u2580\u2588 \u2588"))} ${primary(`v${VERSION}`)}`,
|
|
2690
|
-
""
|
|
2691
|
-
].join("\n");
|
|
2692
|
-
var gettingStarted = [
|
|
2693
|
-
"",
|
|
2694
|
-
` ${chalk2.bold(interactive("Getting started"))}`,
|
|
2695
|
-
"",
|
|
2696
|
-
` ${chalk2.dim("$")} ${primary("aai init")} ${interactive("my-agent")}`,
|
|
2697
|
-
` ${chalk2.dim("$")} ${primary("cd")} ${interactive("my-agent")}`,
|
|
2698
|
-
` ${chalk2.dim("$")} ${primary("aai dev")}`,
|
|
2699
|
-
""
|
|
2700
|
-
].join("\n");
|
|
2701
|
-
async function ensureAgent(cwd, yes) {
|
|
2702
|
-
if (!await fileExists(path7.join(cwd, "agent.ts"))) {
|
|
2703
|
-
const { runInitCommand: runInitCommand2 } = await Promise.resolve().then(() => (init_init2(), init_exports2));
|
|
2704
|
-
await runInitCommand2({ yes }, { quiet: true });
|
|
2705
|
-
}
|
|
2706
|
-
}
|
|
2707
|
-
function withCwd(cmd) {
|
|
2708
|
-
return cmd.hook("preAction", (thisCmd) => {
|
|
2709
|
-
thisCmd.setOptionValue("cwd", resolveCwd());
|
|
2710
|
-
});
|
|
2711
|
-
}
|
|
2712
|
-
function withAgentGuard(cmd) {
|
|
2713
|
-
return cmd.hook("preAction", async (thisCmd) => {
|
|
2714
|
-
await ensureAgent(thisCmd.getOptionValue("cwd"), thisCmd.opts().yes);
|
|
2715
|
-
});
|
|
2716
|
-
}
|
|
2717
|
-
function withApiKey(cmd) {
|
|
2718
|
-
return cmd.hook("preAction", async () => {
|
|
2719
|
-
await getApiKey();
|
|
2720
|
-
});
|
|
2721
|
-
}
|
|
2722
|
-
function createProgram() {
|
|
2723
|
-
const program = new Command();
|
|
2724
|
-
program.name("aai").version(VERSION, "-V, --version").addHelpText("before", banner).addHelpText("after", gettingStarted);
|
|
2725
|
-
program.command("init").description("Scaffold a new agent project").argument("[dir]", "Project directory").option("-t, --template <template>", "Template to use").option("-f, --force", "Overwrite existing agent.ts").option("-y, --yes", "Accept defaults (no prompts)").action(
|
|
2726
|
-
async (dir, opts) => {
|
|
2727
|
-
const { runInitCommand: runInitCommand2 } = await Promise.resolve().then(() => (init_init2(), init_exports2));
|
|
2728
|
-
await runInitCommand2({ dir, ...opts });
|
|
2729
|
-
}
|
|
2730
|
-
);
|
|
2731
|
-
withApiKey(
|
|
2732
|
-
withAgentGuard(
|
|
2733
|
-
withCwd(
|
|
2734
|
-
program.command("dev").description("Start a local development server").option("-p, --port <number>", "Port to listen on", "3000").option("-y, --yes", "Accept defaults (no prompts)").action(async (opts) => {
|
|
2735
|
-
const { runDevCommand: runDevCommand2 } = await Promise.resolve().then(() => (init_dev(), dev_exports));
|
|
2736
|
-
await runDevCommand2(opts);
|
|
2737
|
-
})
|
|
2738
|
-
)
|
|
2739
|
-
)
|
|
2740
|
-
);
|
|
2741
|
-
withAgentGuard(
|
|
2742
|
-
withCwd(
|
|
2743
|
-
program.command("build").description("Bundle and validate (no server or deploy)").option("-y, --yes", "Accept defaults (no prompts)").action(async (opts) => {
|
|
2744
|
-
const { runBuildCommand: runBuildCommand2 } = await Promise.resolve().then(() => (init_build(), build_exports));
|
|
2745
|
-
await runBuildCommand2(opts.cwd);
|
|
2746
|
-
})
|
|
2747
|
-
)
|
|
2748
|
-
);
|
|
2749
|
-
withAgentGuard(
|
|
2750
|
-
withCwd(
|
|
2751
|
-
program.command("deploy").description("Bundle and deploy to production").option("-s, --server <url>", "Server URL").option("--dry-run", "Validate and bundle without deploying").option("-y, --yes", "Accept defaults (no prompts)").action(async (opts) => {
|
|
2752
|
-
const { runDeployCommand: runDeployCommand2 } = await Promise.resolve().then(() => (init_deploy2(), deploy_exports));
|
|
2753
|
-
await runDeployCommand2(opts);
|
|
2754
|
-
})
|
|
2755
|
-
)
|
|
2756
|
-
);
|
|
2757
|
-
withApiKey(
|
|
2758
|
-
withCwd(
|
|
2759
|
-
program.command("start").description("Start production server from build").option("-p, --port <number>", "Port to listen on", "3000").option("-y, --yes", "Accept defaults (no prompts)").action(async (opts) => {
|
|
2760
|
-
const { runStartCommand: runStartCommand2 } = await Promise.resolve().then(() => (init_start(), start_exports));
|
|
2761
|
-
await runStartCommand2(opts);
|
|
2762
|
-
})
|
|
2763
|
-
)
|
|
2764
|
-
);
|
|
2765
|
-
const secret = program.command("secret").description("Manage secrets").action(() => secret.help());
|
|
2766
|
-
withApiKey(withCwd(secret));
|
|
2767
|
-
secret.command("put").description("Create or update a secret").argument("<name>", "Secret name").action(async (name, _opts, cmd) => {
|
|
2768
|
-
const cwd = cmd.parent?.getOptionValue("cwd");
|
|
2769
|
-
const { runSecretPut: runSecretPut2 } = await Promise.resolve().then(() => (init_secret(), secret_exports));
|
|
2770
|
-
await runSecretPut2(cwd, name);
|
|
2771
|
-
});
|
|
2772
|
-
secret.command("delete").description("Delete a secret").argument("<name>", "Secret name").action(async (name, _opts, cmd) => {
|
|
2773
|
-
const cwd = cmd.parent?.getOptionValue("cwd");
|
|
2774
|
-
const { runSecretDelete: runSecretDelete2 } = await Promise.resolve().then(() => (init_secret(), secret_exports));
|
|
2775
|
-
await runSecretDelete2(cwd, name);
|
|
2776
|
-
});
|
|
2777
|
-
secret.command("list").description("List secret names").action(async (_opts, cmd) => {
|
|
2778
|
-
const cwd = cmd.parent?.getOptionValue("cwd");
|
|
2779
|
-
const { runSecretList: runSecretList2 } = await Promise.resolve().then(() => (init_secret(), secret_exports));
|
|
2780
|
-
await runSecretList2(cwd);
|
|
2781
|
-
});
|
|
2782
|
-
withApiKey(
|
|
2783
|
-
withCwd(
|
|
2784
|
-
program.command("rag").description("Ingest a site's llms-full.txt into the vector store").argument("<url>", "URL to ingest").option("-s, --server <url>", "Server URL").option("--chunk-size <n>", "Max chunk size in tokens", "512").option("-y, --yes", "Accept defaults (no prompts)").action(async (url, opts) => {
|
|
2785
|
-
const { runRagCommand: runRagCommand2 } = await Promise.resolve().then(() => (init_rag(), rag_exports));
|
|
2786
|
-
await runRagCommand2({ url, ...opts });
|
|
2787
|
-
})
|
|
2788
|
-
)
|
|
2789
|
-
);
|
|
2790
|
-
return program;
|
|
2791
|
-
}
|
|
2792
|
-
async function main(args) {
|
|
2793
|
-
if (args.length === 0) {
|
|
2794
|
-
const { runInitCommand: runInitCommand2 } = await Promise.resolve().then(() => (init_init2(), init_exports2));
|
|
2795
|
-
await runInitCommand2({});
|
|
2796
|
-
return;
|
|
2797
|
-
}
|
|
2798
|
-
const program = createProgram();
|
|
2799
|
-
await program.parseAsync(args, { from: "user" });
|
|
2800
|
-
}
|
|
2801
|
-
if (process.env.VITEST !== "true") {
|
|
2802
|
-
process.on("SIGINT", () => process.exit(0));
|
|
2803
|
-
main(process.argv.slice(2)).catch((err) => {
|
|
2804
|
-
console.error(errorMessage(err));
|
|
2805
|
-
process.exit(1);
|
|
2806
|
-
});
|
|
2807
|
-
}
|
|
2808
|
-
export {
|
|
2809
|
-
createProgram,
|
|
2810
|
-
main
|
|
2811
|
-
};
|