@alexkroman1/aai 0.8.7 → 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} +67 -31
- 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/_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/session.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { DEFAULT_INSTRUCTIONS } from "./types.js";
|
|
2
|
+
import { errorMessage } from "./_utils.js";
|
|
3
|
+
import { HOOK_TIMEOUT_MS } from "./protocol.js";
|
|
4
|
+
import { consoleLogger } from "./runtime.js";
|
|
5
|
+
import { connectS2s, defaultCreateS2sWebSocket } from "./s2s.js";
|
|
6
|
+
//#region session.ts
|
|
7
|
+
const _internals = { connectS2s };
|
|
8
|
+
/** Create an S2S-backed session with the same interface as the STT+LLM+TTS session. */
|
|
9
|
+
function createS2sSession(opts) {
|
|
10
|
+
const { id, agent, client, toolSchemas, apiKey, s2sConfig, executeTool, createWebSocket = defaultCreateS2sWebSocket, hookInvoker, logger: log = consoleLogger } = opts;
|
|
11
|
+
const agentConfig = opts.skipGreeting ? {
|
|
12
|
+
...opts.agentConfig,
|
|
13
|
+
greeting: ""
|
|
14
|
+
} : opts.agentConfig;
|
|
15
|
+
const systemPrompt = buildSystemPrompt(agentConfig, {
|
|
16
|
+
hasTools: toolSchemas.length > 0 || (agentConfig.builtinTools?.length ?? 0) > 0,
|
|
17
|
+
voice: true
|
|
18
|
+
});
|
|
19
|
+
const s2sTools = toolSchemas.map((ts) => ({
|
|
20
|
+
type: "function",
|
|
21
|
+
name: ts.name,
|
|
22
|
+
description: ts.description,
|
|
23
|
+
parameters: ts.parameters
|
|
24
|
+
}));
|
|
25
|
+
let s2s = null;
|
|
26
|
+
const sessionAbort = new AbortController();
|
|
27
|
+
let toolCallCount = 0;
|
|
28
|
+
let turnPromise = null;
|
|
29
|
+
let conversationMessages = [];
|
|
30
|
+
let pendingTools = [];
|
|
31
|
+
async function resolveTurnConfig() {
|
|
32
|
+
if (!hookInvoker) return null;
|
|
33
|
+
return await hookInvoker.resolveTurnConfig(id, HOOK_TIMEOUT_MS);
|
|
34
|
+
}
|
|
35
|
+
function fireHook(name, fn) {
|
|
36
|
+
if (!hookInvoker) return;
|
|
37
|
+
try {
|
|
38
|
+
fn(hookInvoker).catch((err) => {
|
|
39
|
+
log.warn(`${name} hook failed`, { err: errorMessage(err) });
|
|
40
|
+
});
|
|
41
|
+
} catch (err) {
|
|
42
|
+
log.warn(`${name} hook failed`, { err: errorMessage(err) });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Check if a tool call should be refused due to turn config limits. Returns a result string to short-circuit, or null. */
|
|
46
|
+
function checkTurnLimits(turnConfig, name) {
|
|
47
|
+
const maxSteps = turnConfig?.maxSteps ?? agentConfig.maxSteps;
|
|
48
|
+
toolCallCount++;
|
|
49
|
+
if (maxSteps !== void 0 && toolCallCount > maxSteps) {
|
|
50
|
+
log.info("maxSteps exceeded, refusing tool call", {
|
|
51
|
+
toolCallCount,
|
|
52
|
+
maxSteps
|
|
53
|
+
});
|
|
54
|
+
return "Maximum tool steps reached. Please respond to the user now.";
|
|
55
|
+
}
|
|
56
|
+
if (turnConfig?.activeTools && !turnConfig.activeTools.includes(name)) {
|
|
57
|
+
log.info("Tool filtered by activeTools", { name });
|
|
58
|
+
return JSON.stringify({ error: `Tool "${name}" is not available at this step.` });
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
async function handleToolCall(detail) {
|
|
63
|
+
const { call_id, name, args: parsedArgs } = detail;
|
|
64
|
+
client.event({
|
|
65
|
+
type: "tool_call_start",
|
|
66
|
+
toolCallId: call_id,
|
|
67
|
+
toolName: name,
|
|
68
|
+
args: parsedArgs
|
|
69
|
+
});
|
|
70
|
+
let turnConfig;
|
|
71
|
+
try {
|
|
72
|
+
turnConfig = await resolveTurnConfig();
|
|
73
|
+
} catch (err) {
|
|
74
|
+
const msg = `resolveTurnConfig hook error: ${errorMessage(err)}`;
|
|
75
|
+
log.error(msg);
|
|
76
|
+
pendingTools.push({
|
|
77
|
+
call_id,
|
|
78
|
+
result: msg
|
|
79
|
+
});
|
|
80
|
+
client.event({
|
|
81
|
+
type: "tool_call_done",
|
|
82
|
+
toolCallId: call_id,
|
|
83
|
+
result: msg
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const refused = checkTurnLimits(turnConfig, name);
|
|
88
|
+
if (refused !== null) {
|
|
89
|
+
pendingTools.push({
|
|
90
|
+
call_id,
|
|
91
|
+
result: refused
|
|
92
|
+
});
|
|
93
|
+
client.event({
|
|
94
|
+
type: "tool_call_done",
|
|
95
|
+
toolCallId: call_id,
|
|
96
|
+
result: refused
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
fireHook("onStep", (h) => h.onStep(id, {
|
|
101
|
+
stepNumber: toolCallCount - 1,
|
|
102
|
+
toolCalls: [{
|
|
103
|
+
toolName: name,
|
|
104
|
+
args: parsedArgs
|
|
105
|
+
}],
|
|
106
|
+
text: ""
|
|
107
|
+
}, HOOK_TIMEOUT_MS));
|
|
108
|
+
log.info("S2S tool call", {
|
|
109
|
+
tool: name,
|
|
110
|
+
call_id,
|
|
111
|
+
args: parsedArgs,
|
|
112
|
+
agent
|
|
113
|
+
});
|
|
114
|
+
let result;
|
|
115
|
+
try {
|
|
116
|
+
result = await executeTool(name, parsedArgs, id, conversationMessages);
|
|
117
|
+
} catch (err) {
|
|
118
|
+
const msg = errorMessage(err);
|
|
119
|
+
log.error("Tool execution failed", {
|
|
120
|
+
tool: name,
|
|
121
|
+
error: msg
|
|
122
|
+
});
|
|
123
|
+
result = JSON.stringify({ error: msg });
|
|
124
|
+
}
|
|
125
|
+
log.info("S2S tool result", {
|
|
126
|
+
tool: name,
|
|
127
|
+
call_id,
|
|
128
|
+
resultLength: result.length
|
|
129
|
+
});
|
|
130
|
+
pendingTools.push({
|
|
131
|
+
call_id,
|
|
132
|
+
result
|
|
133
|
+
});
|
|
134
|
+
client.event({
|
|
135
|
+
type: "tool_call_done",
|
|
136
|
+
toolCallId: call_id,
|
|
137
|
+
result
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** Wire all S2S events to the client sink, hooks, and session state. */
|
|
141
|
+
function setupListeners(handle) {
|
|
142
|
+
handle.on("ready", ({ session_id }) => {
|
|
143
|
+
log.info("S2S session ready", { session_id });
|
|
144
|
+
});
|
|
145
|
+
handle.on("session_expired", () => {
|
|
146
|
+
log.info("S2S session expired");
|
|
147
|
+
handle.close();
|
|
148
|
+
});
|
|
149
|
+
handle.on("speech_started", () => client.event({ type: "speech_started" }));
|
|
150
|
+
handle.on("speech_stopped", () => client.event({ type: "speech_stopped" }));
|
|
151
|
+
handle.on("user_transcript_delta", ({ text }) => {
|
|
152
|
+
client.event({
|
|
153
|
+
type: "transcript",
|
|
154
|
+
text,
|
|
155
|
+
isFinal: false
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
handle.on("user_transcript", ({ text }) => {
|
|
159
|
+
log.info("S2S user transcript", { text });
|
|
160
|
+
client.event({
|
|
161
|
+
type: "transcript",
|
|
162
|
+
text,
|
|
163
|
+
isFinal: true
|
|
164
|
+
});
|
|
165
|
+
client.event({
|
|
166
|
+
type: "turn",
|
|
167
|
+
text
|
|
168
|
+
});
|
|
169
|
+
conversationMessages.push({
|
|
170
|
+
role: "user",
|
|
171
|
+
content: text
|
|
172
|
+
});
|
|
173
|
+
fireHook("onTurn", (h) => h.onTurn(id, text, HOOK_TIMEOUT_MS));
|
|
174
|
+
});
|
|
175
|
+
handle.on("reply_started", () => {
|
|
176
|
+
toolCallCount = 0;
|
|
177
|
+
});
|
|
178
|
+
handle.on("audio", ({ audio }) => {
|
|
179
|
+
client.playAudioChunk(audio);
|
|
180
|
+
});
|
|
181
|
+
handle.on("agent_transcript_delta", ({ text }) => {
|
|
182
|
+
client.event({
|
|
183
|
+
type: "chat_delta",
|
|
184
|
+
text
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
handle.on("agent_transcript", ({ text }) => {
|
|
188
|
+
client.event({
|
|
189
|
+
type: "chat",
|
|
190
|
+
text
|
|
191
|
+
});
|
|
192
|
+
conversationMessages.push({
|
|
193
|
+
role: "assistant",
|
|
194
|
+
content: text
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
handle.on("tool_call", (detail) => {
|
|
198
|
+
const p = handleToolCall(detail).catch((err) => {
|
|
199
|
+
log.error("Tool call handler failed", { err: errorMessage(err) });
|
|
200
|
+
});
|
|
201
|
+
turnPromise = (turnPromise ?? Promise.resolve()).then(() => p);
|
|
202
|
+
});
|
|
203
|
+
handle.on("reply_done", ({ status }) => {
|
|
204
|
+
if (status === "interrupted") {
|
|
205
|
+
log.info("S2S reply interrupted (barge-in)");
|
|
206
|
+
pendingTools = [];
|
|
207
|
+
client.event({ type: "cancelled" });
|
|
208
|
+
} else if (pendingTools.length > 0) {
|
|
209
|
+
for (const tool of pendingTools) s2s?.sendToolResult(tool.call_id, tool.result);
|
|
210
|
+
pendingTools = [];
|
|
211
|
+
} else {
|
|
212
|
+
client.playAudioDone();
|
|
213
|
+
client.event({ type: "tts_done" });
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
handle.on("error", ({ code, message }) => {
|
|
217
|
+
log.error("S2S error", {
|
|
218
|
+
code,
|
|
219
|
+
message
|
|
220
|
+
});
|
|
221
|
+
client.event({
|
|
222
|
+
type: "error",
|
|
223
|
+
code: "internal",
|
|
224
|
+
message
|
|
225
|
+
});
|
|
226
|
+
handle.close();
|
|
227
|
+
});
|
|
228
|
+
handle.on("close", () => {
|
|
229
|
+
log.info("S2S closed");
|
|
230
|
+
s2s = null;
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
async function connectAndSetup() {
|
|
234
|
+
try {
|
|
235
|
+
const handle = await _internals.connectS2s({
|
|
236
|
+
apiKey,
|
|
237
|
+
config: s2sConfig,
|
|
238
|
+
createWebSocket,
|
|
239
|
+
logger: log
|
|
240
|
+
});
|
|
241
|
+
setupListeners(handle);
|
|
242
|
+
handle.updateSession({
|
|
243
|
+
system_prompt: systemPrompt,
|
|
244
|
+
tools: s2sTools,
|
|
245
|
+
...agentConfig.greeting ? { greeting: agentConfig.greeting } : {}
|
|
246
|
+
});
|
|
247
|
+
s2s = handle;
|
|
248
|
+
} catch (err) {
|
|
249
|
+
const msg = errorMessage(err);
|
|
250
|
+
log.error("S2S connect failed", { error: msg });
|
|
251
|
+
client.event({
|
|
252
|
+
type: "error",
|
|
253
|
+
code: "internal",
|
|
254
|
+
message: msg
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
async start() {
|
|
260
|
+
fireHook("onConnect", (h) => h.onConnect(id, HOOK_TIMEOUT_MS));
|
|
261
|
+
await connectAndSetup();
|
|
262
|
+
},
|
|
263
|
+
async stop() {
|
|
264
|
+
if (sessionAbort.signal.aborted) return;
|
|
265
|
+
sessionAbort.abort();
|
|
266
|
+
if (turnPromise) await turnPromise;
|
|
267
|
+
s2s?.close();
|
|
268
|
+
fireHook("onDisconnect", (h) => h.onDisconnect(id, HOOK_TIMEOUT_MS));
|
|
269
|
+
},
|
|
270
|
+
onAudio(data) {
|
|
271
|
+
s2s?.sendAudio(data);
|
|
272
|
+
},
|
|
273
|
+
onAudioReady() {},
|
|
274
|
+
onCancel() {
|
|
275
|
+
client.event({ type: "cancelled" });
|
|
276
|
+
},
|
|
277
|
+
onReset() {
|
|
278
|
+
conversationMessages = [];
|
|
279
|
+
toolCallCount = 0;
|
|
280
|
+
turnPromise = null;
|
|
281
|
+
pendingTools = [];
|
|
282
|
+
s2s?.close();
|
|
283
|
+
client.event({ type: "reset" });
|
|
284
|
+
connectAndSetup().catch((err) => {
|
|
285
|
+
log.error("S2S reset reconnect failed", { error: errorMessage(err) });
|
|
286
|
+
});
|
|
287
|
+
},
|
|
288
|
+
onHistory(incoming) {
|
|
289
|
+
for (const msg of incoming) conversationMessages.push({
|
|
290
|
+
role: msg.role,
|
|
291
|
+
content: msg.text
|
|
292
|
+
});
|
|
293
|
+
},
|
|
294
|
+
waitForTurn() {
|
|
295
|
+
return turnPromise ?? Promise.resolve();
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
const VOICE_RULES = "\n\nCRITICAL OUTPUT RULES — 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 (-, *, •) 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 — 1 to 3 sentences max";
|
|
300
|
+
function buildSystemPrompt(config, opts) {
|
|
301
|
+
const { hasTools } = opts;
|
|
302
|
+
const agentInstructions = config.instructions && config.instructions !== DEFAULT_INSTRUCTIONS ? `\n\nAgent-Specific Instructions:\n${config.instructions}` : "";
|
|
303
|
+
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." : "";
|
|
304
|
+
return DEFAULT_INSTRUCTIONS + `\n\nToday's date is ${(/* @__PURE__ */ new Date()).toLocaleDateString("en-US", {
|
|
305
|
+
weekday: "long",
|
|
306
|
+
year: "numeric",
|
|
307
|
+
month: "long",
|
|
308
|
+
day: "numeric"
|
|
309
|
+
})}.` + agentInstructions + toolPreamble + (opts.voice ? VOICE_RULES : "");
|
|
310
|
+
}
|
|
311
|
+
//#endregion
|
|
312
|
+
export { _internals, buildSystemPrompt, createS2sSession };
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core type definitions for the AAI agent SDK.
|
|
3
|
-
*
|
|
4
|
-
* @module
|
|
5
3
|
*/
|
|
6
|
-
import
|
|
4
|
+
import { z } from "zod";
|
|
7
5
|
import type { Kv } from "./kv.ts";
|
|
8
6
|
import type { VectorStore } from "./vector.ts";
|
|
9
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Result of the {@link AgentOptions.onBeforeStep} hook.
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
10
11
|
export type BeforeStepResult = {
|
|
11
12
|
activeTools?: string[];
|
|
12
13
|
} | undefined;
|
|
@@ -22,6 +23,8 @@ export type BeforeStepResult = {
|
|
|
22
23
|
* - `"run_code"` — Execute JavaScript in a sandbox for calculations and data processing.
|
|
23
24
|
* - `"vector_search"` — Search the agent's RAG knowledge base for relevant documents.
|
|
24
25
|
* - `"memory"` — Persistent KV memory: save_memory, recall_memory, list_memories, forget_memory.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
25
28
|
*/
|
|
26
29
|
export type BuiltinTool = "web_search" | "visit_webpage" | "fetch_json" | "run_code" | "vector_search" | "memory";
|
|
27
30
|
/**
|
|
@@ -40,7 +43,9 @@ export type ToolChoice = "auto" | "required" | "none" | {
|
|
|
40
43
|
* A single message in the conversation history.
|
|
41
44
|
*
|
|
42
45
|
* Messages are passed to tool `execute` functions via
|
|
43
|
-
* {@
|
|
46
|
+
* {@link ToolContext.messages} to provide conversation context.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
44
49
|
*/
|
|
45
50
|
export type Message = {
|
|
46
51
|
/** The role of the message sender. */
|
|
@@ -54,7 +59,7 @@ export type Message = {
|
|
|
54
59
|
* Provides access to the session environment, state, KV store, and
|
|
55
60
|
* conversation history from within a tool's execute handler.
|
|
56
61
|
*
|
|
57
|
-
* @typeParam S The shape of per-session state created by the agent's
|
|
62
|
+
* @typeParam S - The shape of per-session state created by the agent's
|
|
58
63
|
* `state` factory. Defaults to `Record<string, unknown>`.
|
|
59
64
|
*
|
|
60
65
|
* @example
|
|
@@ -71,12 +76,12 @@ export type Message = {
|
|
|
71
76
|
* },
|
|
72
77
|
* };
|
|
73
78
|
* ```
|
|
79
|
+
*
|
|
80
|
+
* @public
|
|
74
81
|
*/
|
|
75
82
|
export type ToolContext<S = Record<string, unknown>> = {
|
|
76
83
|
/** Environment variables declared in the agent config. */
|
|
77
84
|
env: Readonly<Record<string, string>>;
|
|
78
|
-
/** Signal that aborts when the tool execution times out. */
|
|
79
|
-
abortSignal: AbortSignal;
|
|
80
85
|
/** Mutable per-session state created by the agent's `state` factory. */
|
|
81
86
|
state: S;
|
|
82
87
|
/** Key-value store scoped to this agent deployment. */
|
|
@@ -89,13 +94,15 @@ export type ToolContext<S = Record<string, unknown>> = {
|
|
|
89
94
|
/**
|
|
90
95
|
* Context passed to lifecycle hooks (`onConnect`, `onTurn`, etc.).
|
|
91
96
|
*
|
|
92
|
-
* Same as {@
|
|
93
|
-
*
|
|
97
|
+
* Same as {@link ToolContext} but without `messages`, since hooks
|
|
98
|
+
* run outside the tool execution flow.
|
|
94
99
|
*
|
|
95
|
-
* @typeParam S The shape of per-session state created by the agent's
|
|
100
|
+
* @typeParam S - The shape of per-session state created by the agent's
|
|
96
101
|
* `state` factory. Defaults to `Record<string, unknown>`.
|
|
102
|
+
*
|
|
103
|
+
* @public
|
|
97
104
|
*/
|
|
98
|
-
export type HookContext<S = Record<string, unknown>> = Omit<ToolContext<S>, "
|
|
105
|
+
export type HookContext<S = Record<string, unknown>> = Omit<ToolContext<S>, "messages">;
|
|
99
106
|
/**
|
|
100
107
|
* Definition of a custom tool that the agent can invoke.
|
|
101
108
|
*
|
|
@@ -103,8 +110,8 @@ export type HookContext<S = Record<string, unknown>> = Omit<ToolContext<S>, "abo
|
|
|
103
110
|
* description (shown to the LLM), optional Zod parameters schema, and an
|
|
104
111
|
* `execute` function that runs inside the sandboxed worker.
|
|
105
112
|
*
|
|
106
|
-
* @typeParam P A Zod object schema describing the tool's parameters.
|
|
107
|
-
* Defaults to `
|
|
113
|
+
* @typeParam P - A Zod object schema describing the tool's parameters.
|
|
114
|
+
* Defaults to `ZodObject<ZodRawShape>` so tools without parameters don't need an explicit
|
|
108
115
|
* type argument.
|
|
109
116
|
*
|
|
110
117
|
* @example
|
|
@@ -125,6 +132,8 @@ export type HookContext<S = Record<string, unknown>> = Omit<ToolContext<S>, "abo
|
|
|
125
132
|
*
|
|
126
133
|
* const params = z.object({ city: z.string() });
|
|
127
134
|
* ```
|
|
135
|
+
*
|
|
136
|
+
* @public
|
|
128
137
|
*/
|
|
129
138
|
export type ToolDef<P extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawShape>, S = Record<string, unknown>> = {
|
|
130
139
|
/** Human-readable description shown to the LLM. */
|
|
@@ -158,13 +167,17 @@ export type ToolDef<P extends z.ZodObject<z.ZodRawShape> = z.ZodObject<z.ZodRawS
|
|
|
158
167
|
* },
|
|
159
168
|
* });
|
|
160
169
|
* ```
|
|
170
|
+
*
|
|
171
|
+
* @public
|
|
161
172
|
*/
|
|
162
|
-
export declare function tool<P extends z.ZodObject<z.ZodRawShape>, S =
|
|
173
|
+
export declare function tool<P extends z.ZodObject<z.ZodRawShape>, S = Record<string, unknown>>(def: ToolDef<P, S>): ToolDef<P, S>;
|
|
163
174
|
/**
|
|
164
175
|
* Information about a completed agentic step, passed to the `onStep` hook.
|
|
165
176
|
*
|
|
166
177
|
* Each turn may consist of multiple steps (up to `maxSteps`). A step
|
|
167
178
|
* represents one LLM invocation that may include tool calls and text output.
|
|
179
|
+
*
|
|
180
|
+
* @public
|
|
168
181
|
*/
|
|
169
182
|
export type StepInfo = {
|
|
170
183
|
/** 1-based step index within the current turn. */
|
|
@@ -178,12 +191,12 @@ export type StepInfo = {
|
|
|
178
191
|
text: string;
|
|
179
192
|
};
|
|
180
193
|
/**
|
|
181
|
-
* Options passed to {@
|
|
194
|
+
* Options passed to {@link defineAgent} to configure an agent.
|
|
182
195
|
*
|
|
183
196
|
* Only `name` is required; all other fields have sensible defaults.
|
|
184
197
|
*
|
|
185
|
-
* @typeParam S The shape of per-session state returned by the `state`
|
|
186
|
-
* factory. Defaults to `
|
|
198
|
+
* @typeParam S - The shape of per-session state returned by the `state`
|
|
199
|
+
* factory. Defaults to `Record<string, unknown>`.
|
|
187
200
|
*
|
|
188
201
|
* @example
|
|
189
202
|
* ```ts
|
|
@@ -204,6 +217,8 @@ export type StepInfo = {
|
|
|
204
217
|
* },
|
|
205
218
|
* });
|
|
206
219
|
* ```
|
|
220
|
+
*
|
|
221
|
+
* @public
|
|
207
222
|
*/
|
|
208
223
|
export type AgentOptions<S = Record<string, unknown>> = {
|
|
209
224
|
/** Display name for the agent. */
|
|
@@ -218,7 +233,7 @@ export type AgentOptions<S = Record<string, unknown>> = {
|
|
|
218
233
|
* Maximum agentic loop iterations per turn. Can be a static number or
|
|
219
234
|
* a function that receives the hook context and returns a number.
|
|
220
235
|
*
|
|
221
|
-
* @
|
|
236
|
+
* @defaultValue 5
|
|
222
237
|
*/
|
|
223
238
|
maxSteps?: number | ((ctx: HookContext<S>) => number);
|
|
224
239
|
/** How the LLM should choose tools. */
|
|
@@ -265,9 +280,9 @@ export declare const DEFAULT_INSTRUCTIONS: string;
|
|
|
265
280
|
export declare const DEFAULT_GREETING: string;
|
|
266
281
|
/**
|
|
267
282
|
* Agent definition with all defaults applied, returned by
|
|
268
|
-
* {@
|
|
283
|
+
* {@link defineAgent}.
|
|
269
284
|
*
|
|
270
|
-
* Unlike {@
|
|
285
|
+
* Unlike {@link AgentOptions}, every field here is resolved to its
|
|
271
286
|
* final value — no optional fields with implicit defaults remain.
|
|
272
287
|
*/
|
|
273
288
|
export type AgentDef = {
|
|
@@ -280,7 +295,7 @@ export type AgentDef = {
|
|
|
280
295
|
builtinTools?: readonly BuiltinTool[];
|
|
281
296
|
activeTools?: readonly string[];
|
|
282
297
|
tools: Readonly<Record<string, ToolDef>>;
|
|
283
|
-
state?: () => unknown
|
|
298
|
+
state?: () => Record<string, unknown>;
|
|
284
299
|
onConnect?: AgentOptions["onConnect"];
|
|
285
300
|
onDisconnect?: AgentOptions["onDisconnect"];
|
|
286
301
|
onError?: AgentOptions["onError"];
|
|
@@ -292,12 +307,14 @@ export type AgentDef = {
|
|
|
292
307
|
* Create an agent definition from the given options, applying sensible defaults.
|
|
293
308
|
*
|
|
294
309
|
* This is the main entry point for defining a voice agent. The returned
|
|
295
|
-
*
|
|
310
|
+
* `AgentDef` is consumed by the AAI server at deploy time.
|
|
296
311
|
*
|
|
297
|
-
* @param options Configuration for the agent including name, instructions,
|
|
312
|
+
* @param options - Configuration for the agent including name, instructions,
|
|
298
313
|
* tools, hooks, and other settings.
|
|
299
314
|
* @returns A fully resolved agent definition with all defaults applied.
|
|
300
315
|
*
|
|
316
|
+
* @public
|
|
317
|
+
*
|
|
301
318
|
* @example Basic agent with a custom tool
|
|
302
319
|
* ```ts
|
|
303
320
|
* import { defineAgent } from "aai";
|
|
@@ -317,4 +334,3 @@ export type AgentDef = {
|
|
|
317
334
|
* ```
|
|
318
335
|
*/
|
|
319
336
|
export declare function defineAgent<S>(options: AgentOptions<S>): AgentDef;
|
|
320
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region types.ts
|
|
3
|
+
/**
|
|
4
|
+
* Core type definitions for the AAI agent SDK.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Identity helper that preserves the Zod schema generic for type inference.
|
|
8
|
+
*
|
|
9
|
+
* When tools are defined inline in `defineAgent({ tools: { ... } })`, the
|
|
10
|
+
* generic `P` gets widened to the base `ZodObject` type, so `args` in
|
|
11
|
+
* `execute` loses its specific shape. Wrapping a tool definition in `tool()`
|
|
12
|
+
* lets TypeScript infer `P` from `parameters` and type `args` correctly.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { defineAgent, tool } from "aai";
|
|
17
|
+
* import { z } from "zod";
|
|
18
|
+
*
|
|
19
|
+
* export default defineAgent({
|
|
20
|
+
* name: "my-agent",
|
|
21
|
+
* tools: {
|
|
22
|
+
* greet: tool({
|
|
23
|
+
* description: "Greet the user",
|
|
24
|
+
* parameters: z.object({ name: z.string() }),
|
|
25
|
+
* execute: ({ name }) => `Hello, ${name}!`, // name is string
|
|
26
|
+
* }),
|
|
27
|
+
* },
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
function tool(def) {
|
|
34
|
+
return def;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Default system prompt used when `instructions` is not provided.
|
|
38
|
+
*
|
|
39
|
+
* Optimized for voice-first interactions: short sentences, no visual
|
|
40
|
+
* formatting, confident tone, and concise answers.
|
|
41
|
+
*/
|
|
42
|
+
const DEFAULT_INSTRUCTIONS = `\
|
|
43
|
+
You are AAI, a helpful AI assistant.
|
|
44
|
+
|
|
45
|
+
Voice-First Rules:
|
|
46
|
+
- Optimize for natural speech. Avoid jargon unless central to the answer. \
|
|
47
|
+
Use short, punchy sentences.
|
|
48
|
+
- Never mention "search results," "sources," or "the provided text." \
|
|
49
|
+
Speak as if the knowledge is your own.
|
|
50
|
+
- No visual formatting. Do not say "bullet point," "bold," or "bracketed one." \
|
|
51
|
+
If you need to list items, say "First," "Next," and "Finally."
|
|
52
|
+
- Start with the most important information. No introductory filler.
|
|
53
|
+
- Be concise. Keep answers to 1-3 sentences. For complex topics, provide a high-level summary.
|
|
54
|
+
- Be confident. Avoid hedging phrases like "It seems that" or "I believe."
|
|
55
|
+
- If you don't have enough information, say so directly rather than guessing.
|
|
56
|
+
- Never use exclamation points. Keep your tone calm and conversational.`;
|
|
57
|
+
/** Default greeting spoken when a session starts. */
|
|
58
|
+
const DEFAULT_GREETING = "Hey there. I'm a voice assistant. What can I help you with?";
|
|
59
|
+
const BuiltinToolSchema = z.enum([
|
|
60
|
+
"web_search",
|
|
61
|
+
"visit_webpage",
|
|
62
|
+
"fetch_json",
|
|
63
|
+
"run_code",
|
|
64
|
+
"vector_search",
|
|
65
|
+
"memory"
|
|
66
|
+
]);
|
|
67
|
+
const ToolChoiceSchema = z.union([z.enum([
|
|
68
|
+
"auto",
|
|
69
|
+
"required",
|
|
70
|
+
"none"
|
|
71
|
+
]), z.object({
|
|
72
|
+
type: z.literal("tool"),
|
|
73
|
+
toolName: z.string().min(1)
|
|
74
|
+
})]);
|
|
75
|
+
const ToolDefSchema = z.object({
|
|
76
|
+
description: z.string().min(1, "Tool description must be non-empty"),
|
|
77
|
+
parameters: z.custom((val) => val === void 0 || val instanceof z.ZodType, "Expected a Zod schema").optional(),
|
|
78
|
+
execute: z.function()
|
|
79
|
+
});
|
|
80
|
+
const AgentOptionsSchema = z.object({
|
|
81
|
+
name: z.string().min(1, "Agent name must be non-empty"),
|
|
82
|
+
instructions: z.string().optional(),
|
|
83
|
+
greeting: z.string().optional(),
|
|
84
|
+
sttPrompt: z.string().optional(),
|
|
85
|
+
maxSteps: z.union([z.number().int().positive(), z.function()]).optional(),
|
|
86
|
+
toolChoice: ToolChoiceSchema.optional(),
|
|
87
|
+
builtinTools: z.array(BuiltinToolSchema).optional(),
|
|
88
|
+
activeTools: z.array(z.string().min(1)).optional(),
|
|
89
|
+
tools: z.record(z.string(), ToolDefSchema).optional(),
|
|
90
|
+
state: z.function().optional(),
|
|
91
|
+
onConnect: z.function().optional(),
|
|
92
|
+
onDisconnect: z.function().optional(),
|
|
93
|
+
onError: z.function().optional(),
|
|
94
|
+
onTurn: z.function().optional(),
|
|
95
|
+
onStep: z.function().optional(),
|
|
96
|
+
onBeforeStep: z.function().optional()
|
|
97
|
+
});
|
|
98
|
+
/**
|
|
99
|
+
* Create an agent definition from the given options, applying sensible defaults.
|
|
100
|
+
*
|
|
101
|
+
* This is the main entry point for defining a voice agent. The returned
|
|
102
|
+
* `AgentDef` is consumed by the AAI server at deploy time.
|
|
103
|
+
*
|
|
104
|
+
* @param options - Configuration for the agent including name, instructions,
|
|
105
|
+
* tools, hooks, and other settings.
|
|
106
|
+
* @returns A fully resolved agent definition with all defaults applied.
|
|
107
|
+
*
|
|
108
|
+
* @public
|
|
109
|
+
*
|
|
110
|
+
* @example Basic agent with a custom tool
|
|
111
|
+
* ```ts
|
|
112
|
+
* import { defineAgent } from "aai";
|
|
113
|
+
* import { z } from "zod";
|
|
114
|
+
*
|
|
115
|
+
* export default defineAgent({
|
|
116
|
+
* name: "greeter",
|
|
117
|
+
* instructions: "You greet people warmly.",
|
|
118
|
+
* tools: {
|
|
119
|
+
* greet: {
|
|
120
|
+
* description: "Greet a user by name",
|
|
121
|
+
* parameters: z.object({ name: z.string() }),
|
|
122
|
+
* execute: ({ name }) => `Hello, ${name}!`,
|
|
123
|
+
* },
|
|
124
|
+
* },
|
|
125
|
+
* });
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
function defineAgent(options) {
|
|
129
|
+
AgentOptionsSchema.parse(options);
|
|
130
|
+
return {
|
|
131
|
+
...options,
|
|
132
|
+
instructions: options.instructions ?? DEFAULT_INSTRUCTIONS,
|
|
133
|
+
greeting: options.greeting ?? "Hey there. I'm a voice assistant. What can I help you with?",
|
|
134
|
+
maxSteps: options.maxSteps ?? 5,
|
|
135
|
+
tools: options.tools ?? {}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
export { DEFAULT_GREETING, DEFAULT_INSTRUCTIONS, defineAgent, tool };
|