@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/s2s.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Speech-to-Speech WebSocket client for AssemblyAI's S2S API.
|
|
3
|
+
*/
|
|
4
|
+
import type { JSONSchema7 } from "json-schema";
|
|
5
|
+
import { type Unsubscribe } from "nanoevents";
|
|
6
|
+
import type { Logger, S2SConfig } from "./runtime.ts";
|
|
7
|
+
/** Minimal WebSocket interface for the S2S client. */
|
|
8
|
+
export type S2sWebSocket = {
|
|
9
|
+
readonly readyState: number;
|
|
10
|
+
send(data: string): void;
|
|
11
|
+
close(): void;
|
|
12
|
+
addEventListener(type: "open", listener: () => void): void;
|
|
13
|
+
addEventListener(type: "message", listener: (event: {
|
|
14
|
+
data: unknown;
|
|
15
|
+
}) => void): void;
|
|
16
|
+
addEventListener(type: "close", listener: (event: {
|
|
17
|
+
code?: number;
|
|
18
|
+
reason?: string;
|
|
19
|
+
}) => void): void;
|
|
20
|
+
addEventListener(type: "error", listener: (event: {
|
|
21
|
+
message?: string;
|
|
22
|
+
}) => void): void;
|
|
23
|
+
};
|
|
24
|
+
/** Factory for creating WebSocket connections (e.g. the `ws` package). */
|
|
25
|
+
export type CreateS2sWebSocket = (url: string, opts: {
|
|
26
|
+
headers: Record<string, string>;
|
|
27
|
+
}) => S2sWebSocket;
|
|
28
|
+
/** Default S2S WebSocket factory using the `ws` package (Node-only). */
|
|
29
|
+
export declare const defaultCreateS2sWebSocket: CreateS2sWebSocket;
|
|
30
|
+
export type S2sSessionConfig = {
|
|
31
|
+
system_prompt: string;
|
|
32
|
+
tools: S2sToolSchema[];
|
|
33
|
+
greeting?: string;
|
|
34
|
+
};
|
|
35
|
+
export type S2sToolSchema = {
|
|
36
|
+
type: "function";
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
parameters: JSONSchema7;
|
|
40
|
+
};
|
|
41
|
+
export type S2sToolCall = {
|
|
42
|
+
call_id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
args: Record<string, unknown>;
|
|
45
|
+
};
|
|
46
|
+
/** Typed event map for S2S handle events. */
|
|
47
|
+
export type S2sEvents = {
|
|
48
|
+
ready: (detail: {
|
|
49
|
+
session_id: string;
|
|
50
|
+
}) => void;
|
|
51
|
+
session_updated: (detail: Record<string, unknown>) => void;
|
|
52
|
+
session_expired: (detail: {
|
|
53
|
+
code: string;
|
|
54
|
+
message: string;
|
|
55
|
+
}) => void;
|
|
56
|
+
speech_started: () => void;
|
|
57
|
+
speech_stopped: () => void;
|
|
58
|
+
user_transcript_delta: (detail: {
|
|
59
|
+
text: string;
|
|
60
|
+
}) => void;
|
|
61
|
+
user_transcript: (detail: {
|
|
62
|
+
item_id: string;
|
|
63
|
+
text: string;
|
|
64
|
+
}) => void;
|
|
65
|
+
reply_started: (detail: {
|
|
66
|
+
reply_id: string;
|
|
67
|
+
}) => void;
|
|
68
|
+
agent_transcript_delta: (detail: {
|
|
69
|
+
text: string;
|
|
70
|
+
}) => void;
|
|
71
|
+
agent_transcript: (detail: {
|
|
72
|
+
text: string;
|
|
73
|
+
}) => void;
|
|
74
|
+
tool_call: (detail: S2sToolCall) => void;
|
|
75
|
+
reply_done: (detail: {
|
|
76
|
+
status?: string;
|
|
77
|
+
}) => void;
|
|
78
|
+
audio: (detail: {
|
|
79
|
+
audio: Uint8Array;
|
|
80
|
+
}) => void;
|
|
81
|
+
error: (detail: {
|
|
82
|
+
code: string;
|
|
83
|
+
message: string;
|
|
84
|
+
}) => void;
|
|
85
|
+
close: () => void;
|
|
86
|
+
};
|
|
87
|
+
export type S2sHandle = {
|
|
88
|
+
on<K extends keyof S2sEvents>(event: K, cb: S2sEvents[K]): Unsubscribe;
|
|
89
|
+
sendAudio(audio: Uint8Array): void;
|
|
90
|
+
sendToolResult(callId: string, result: string): void;
|
|
91
|
+
updateSession(config: S2sSessionConfig): void;
|
|
92
|
+
resumeSession(sessionId: string): void;
|
|
93
|
+
close(): void;
|
|
94
|
+
};
|
|
95
|
+
export type ConnectS2sOptions = {
|
|
96
|
+
apiKey: string;
|
|
97
|
+
config: S2SConfig;
|
|
98
|
+
createWebSocket: CreateS2sWebSocket;
|
|
99
|
+
logger?: Logger;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Connect to AssemblyAI's Speech-to-Speech WebSocket API.
|
|
103
|
+
*
|
|
104
|
+
* Returns an {@link S2sHandle} with a typed `on()` method.
|
|
105
|
+
* Consumers listen for events: `ready`, `speech_started`, `speech_stopped`,
|
|
106
|
+
* `user_transcript_delta`, `user_transcript`, `reply_started`,
|
|
107
|
+
* `reply_done`, `audio`, `agent_transcript`, `tool_call`,
|
|
108
|
+
* `session_expired`, `error`, `close`.
|
|
109
|
+
*/
|
|
110
|
+
export declare function connectS2s(opts: ConnectS2sOptions): Promise<S2sHandle>;
|
package/dist/s2s.js
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { consoleLogger } from "./runtime.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { WebSocket } from "ws";
|
|
4
|
+
import { createNanoEvents } from "nanoevents";
|
|
5
|
+
//#region s2s.ts
|
|
6
|
+
const uint8ToBase64 = (bytes) => Buffer.from(bytes).toString("base64");
|
|
7
|
+
const base64ToUint8 = (base64) => new Uint8Array(Buffer.from(base64, "base64"));
|
|
8
|
+
/** WebSocket readyState constant for OPEN. */
|
|
9
|
+
const WS_OPEN = 1;
|
|
10
|
+
/** Default S2S WebSocket factory using the `ws` package (Node-only). */
|
|
11
|
+
const defaultCreateS2sWebSocket = (url, opts) => new WebSocket(url, { headers: opts.headers });
|
|
12
|
+
const S2sServerMessageSchema = z.discriminatedUnion("type", [
|
|
13
|
+
z.object({
|
|
14
|
+
type: z.literal("session.ready"),
|
|
15
|
+
session_id: z.string()
|
|
16
|
+
}),
|
|
17
|
+
z.object({ type: z.literal("session.updated") }).passthrough(),
|
|
18
|
+
z.object({ type: z.literal("input.speech.started") }),
|
|
19
|
+
z.object({ type: z.literal("input.speech.stopped") }),
|
|
20
|
+
z.object({
|
|
21
|
+
type: z.literal("transcript.user.delta"),
|
|
22
|
+
text: z.string()
|
|
23
|
+
}),
|
|
24
|
+
z.object({
|
|
25
|
+
type: z.literal("transcript.user"),
|
|
26
|
+
item_id: z.string(),
|
|
27
|
+
text: z.string()
|
|
28
|
+
}),
|
|
29
|
+
z.object({
|
|
30
|
+
type: z.literal("reply.started"),
|
|
31
|
+
reply_id: z.string()
|
|
32
|
+
}),
|
|
33
|
+
z.object({
|
|
34
|
+
type: z.literal("transcript.agent.delta"),
|
|
35
|
+
delta: z.string()
|
|
36
|
+
}).passthrough(),
|
|
37
|
+
z.object({
|
|
38
|
+
type: z.literal("transcript.agent"),
|
|
39
|
+
text: z.string()
|
|
40
|
+
}),
|
|
41
|
+
z.object({ type: z.literal("reply.content_part.started") }).passthrough(),
|
|
42
|
+
z.object({ type: z.literal("reply.content_part.done") }).passthrough(),
|
|
43
|
+
z.object({
|
|
44
|
+
type: z.literal("tool.call"),
|
|
45
|
+
call_id: z.string(),
|
|
46
|
+
name: z.string(),
|
|
47
|
+
args: z.record(z.string(), z.unknown()).optional().default({})
|
|
48
|
+
}),
|
|
49
|
+
z.object({
|
|
50
|
+
type: z.literal("reply.done"),
|
|
51
|
+
status: z.string().optional()
|
|
52
|
+
}),
|
|
53
|
+
z.object({
|
|
54
|
+
type: z.literal("session.error"),
|
|
55
|
+
code: z.string(),
|
|
56
|
+
message: z.string()
|
|
57
|
+
}),
|
|
58
|
+
z.object({
|
|
59
|
+
type: z.literal("error"),
|
|
60
|
+
message: z.string()
|
|
61
|
+
})
|
|
62
|
+
]);
|
|
63
|
+
/** Dispatch a parsed S2S server message to the emitter. */
|
|
64
|
+
function dispatchS2sMessage(emitter, msg) {
|
|
65
|
+
switch (msg.type) {
|
|
66
|
+
case "session.ready":
|
|
67
|
+
emitter.emit("ready", { session_id: msg.session_id });
|
|
68
|
+
break;
|
|
69
|
+
case "session.updated":
|
|
70
|
+
emitter.emit("session_updated", msg);
|
|
71
|
+
break;
|
|
72
|
+
case "input.speech.started":
|
|
73
|
+
emitter.emit("speech_started");
|
|
74
|
+
break;
|
|
75
|
+
case "input.speech.stopped":
|
|
76
|
+
emitter.emit("speech_stopped");
|
|
77
|
+
break;
|
|
78
|
+
case "transcript.user.delta":
|
|
79
|
+
emitter.emit("user_transcript_delta", { text: msg.text });
|
|
80
|
+
break;
|
|
81
|
+
case "transcript.user":
|
|
82
|
+
emitter.emit("user_transcript", {
|
|
83
|
+
item_id: msg.item_id,
|
|
84
|
+
text: msg.text
|
|
85
|
+
});
|
|
86
|
+
break;
|
|
87
|
+
case "reply.started":
|
|
88
|
+
emitter.emit("reply_started", { reply_id: msg.reply_id });
|
|
89
|
+
break;
|
|
90
|
+
case "transcript.agent.delta":
|
|
91
|
+
emitter.emit("agent_transcript_delta", { text: msg.delta });
|
|
92
|
+
break;
|
|
93
|
+
case "transcript.agent":
|
|
94
|
+
emitter.emit("agent_transcript", { text: msg.text });
|
|
95
|
+
break;
|
|
96
|
+
case "tool.call":
|
|
97
|
+
emitter.emit("tool_call", {
|
|
98
|
+
call_id: msg.call_id,
|
|
99
|
+
name: msg.name,
|
|
100
|
+
args: msg.args
|
|
101
|
+
});
|
|
102
|
+
break;
|
|
103
|
+
case "reply.done":
|
|
104
|
+
emitter.emit("reply_done", { ...msg.status ? { status: msg.status } : {} });
|
|
105
|
+
break;
|
|
106
|
+
case "session.error":
|
|
107
|
+
if (msg.code === "session_not_found" || msg.code === "session_forbidden") emitter.emit("session_expired", {
|
|
108
|
+
code: msg.code,
|
|
109
|
+
message: msg.message
|
|
110
|
+
});
|
|
111
|
+
else emitter.emit("error", {
|
|
112
|
+
code: msg.code,
|
|
113
|
+
message: msg.message
|
|
114
|
+
});
|
|
115
|
+
break;
|
|
116
|
+
case "error":
|
|
117
|
+
emitter.emit("error", {
|
|
118
|
+
code: "connection",
|
|
119
|
+
message: msg.message
|
|
120
|
+
});
|
|
121
|
+
break;
|
|
122
|
+
case "reply.content_part.started":
|
|
123
|
+
case "reply.content_part.done": break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Connect to AssemblyAI's Speech-to-Speech WebSocket API.
|
|
128
|
+
*
|
|
129
|
+
* Returns an {@link S2sHandle} with a typed `on()` method.
|
|
130
|
+
* Consumers listen for events: `ready`, `speech_started`, `speech_stopped`,
|
|
131
|
+
* `user_transcript_delta`, `user_transcript`, `reply_started`,
|
|
132
|
+
* `reply_done`, `audio`, `agent_transcript`, `tool_call`,
|
|
133
|
+
* `session_expired`, `error`, `close`.
|
|
134
|
+
*/
|
|
135
|
+
function connectS2s(opts) {
|
|
136
|
+
const { apiKey, config, createWebSocket, logger: log = consoleLogger } = opts;
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
log.info("S2S connecting", { url: config.wssUrl });
|
|
139
|
+
const ws = createWebSocket(config.wssUrl, { headers: { Authorization: `Bearer ${apiKey}` } });
|
|
140
|
+
const emitter = createNanoEvents();
|
|
141
|
+
let opened = false;
|
|
142
|
+
function send(msg) {
|
|
143
|
+
if (ws.readyState !== WS_OPEN) return;
|
|
144
|
+
const json = JSON.stringify(msg);
|
|
145
|
+
if (msg.type !== "input.audio") log.info(`S2S >> ${msg.type}`, msg.type === "session.update" ? { payload: json } : void 0);
|
|
146
|
+
ws.send(json);
|
|
147
|
+
}
|
|
148
|
+
const handle = {
|
|
149
|
+
on: emitter.on.bind(emitter),
|
|
150
|
+
sendAudio(audio) {
|
|
151
|
+
if (ws.readyState !== WS_OPEN) return;
|
|
152
|
+
ws.send(`{"type":"input.audio","audio":"${uint8ToBase64(audio)}"}`);
|
|
153
|
+
},
|
|
154
|
+
sendToolResult(callId, result) {
|
|
155
|
+
const msg = {
|
|
156
|
+
type: "tool.result",
|
|
157
|
+
call_id: callId,
|
|
158
|
+
result
|
|
159
|
+
};
|
|
160
|
+
log.info("S2S >> tool.result", {
|
|
161
|
+
call_id: callId,
|
|
162
|
+
resultLength: result.length
|
|
163
|
+
});
|
|
164
|
+
send(msg);
|
|
165
|
+
},
|
|
166
|
+
updateSession(sessionConfig) {
|
|
167
|
+
send({
|
|
168
|
+
type: "session.update",
|
|
169
|
+
session: sessionConfig
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
resumeSession(sessionId) {
|
|
173
|
+
send({
|
|
174
|
+
type: "session.resume",
|
|
175
|
+
session_id: sessionId
|
|
176
|
+
});
|
|
177
|
+
},
|
|
178
|
+
close() {
|
|
179
|
+
log.info("S2S closing");
|
|
180
|
+
ws.close();
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
ws.addEventListener("open", () => {
|
|
184
|
+
opened = true;
|
|
185
|
+
log.info("S2S WebSocket open");
|
|
186
|
+
resolve(handle);
|
|
187
|
+
});
|
|
188
|
+
function tryParseJson(data) {
|
|
189
|
+
try {
|
|
190
|
+
return JSON.parse(String(data));
|
|
191
|
+
} catch {
|
|
192
|
+
log.warn("S2S << invalid JSON", { data: String(data).slice(0, 200) });
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function handleAudioFastPath(obj) {
|
|
197
|
+
if (obj.type === "reply.audio" && typeof obj.data === "string") {
|
|
198
|
+
const audioBytes = base64ToUint8(obj.data);
|
|
199
|
+
emitter.emit("audio", { audio: audioBytes });
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
function logIncoming(obj) {
|
|
205
|
+
if (obj.type === "reply.audio" || obj.type === "input.audio") return;
|
|
206
|
+
log.info(`S2S << ${obj.type}`, obj.type === "transcript.agent.delta" ? { delta: obj.delta } : void 0);
|
|
207
|
+
}
|
|
208
|
+
function handleS2sMessage(ev) {
|
|
209
|
+
const raw = tryParseJson(ev.data);
|
|
210
|
+
if (raw === void 0) return;
|
|
211
|
+
const obj = raw;
|
|
212
|
+
logIncoming(obj);
|
|
213
|
+
if (handleAudioFastPath(obj)) return;
|
|
214
|
+
const parsed = S2sServerMessageSchema.safeParse(raw);
|
|
215
|
+
if (!parsed.success) {
|
|
216
|
+
log.warn(`S2S << unrecognised message type: ${obj.type ?? JSON.stringify(raw).slice(0, 200)}`);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
dispatchS2sMessage(emitter, parsed.data);
|
|
220
|
+
}
|
|
221
|
+
ws.addEventListener("message", handleS2sMessage);
|
|
222
|
+
ws.addEventListener("close", (ev) => {
|
|
223
|
+
log.info("S2S WebSocket closed", {
|
|
224
|
+
code: ev.code ?? 0,
|
|
225
|
+
reason: ev.reason ?? ""
|
|
226
|
+
});
|
|
227
|
+
emitter.emit("close");
|
|
228
|
+
});
|
|
229
|
+
ws.addEventListener("error", (ev) => {
|
|
230
|
+
const message = typeof ev.message === "string" ? ev.message : "WebSocket error";
|
|
231
|
+
const errObj = new Error(message);
|
|
232
|
+
log.error("S2S WebSocket error", { error: errObj.message });
|
|
233
|
+
if (!opened) reject(errObj);
|
|
234
|
+
else emitter.emit("error", {
|
|
235
|
+
code: "ws_error",
|
|
236
|
+
message: errObj.message
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
//#endregion
|
|
242
|
+
export { connectS2s, defaultCreateS2sWebSocket };
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Self-hostable agent server.
|
|
3
3
|
*
|
|
4
|
-
* `createServer()` returns a server with
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @module
|
|
4
|
+
* `createServer()` returns a server with `listen()` for HTTP + WebSocket.
|
|
5
|
+
* Calls `createDirectExecutor` + `wireSessionSocket` directly — no
|
|
6
|
+
* intermediate WintercServer layer.
|
|
8
7
|
*/
|
|
9
8
|
import type { Kv } from "./kv.ts";
|
|
10
9
|
import type { Logger, S2SConfig } from "./runtime.ts";
|
|
11
|
-
import { type CreateS2sWebSocket } from "./s2s.ts";
|
|
12
10
|
import type { AgentDef } from "./types.ts";
|
|
13
11
|
export type ServerOptions = {
|
|
14
12
|
/** The agent definition returned by `defineAgent()`. */
|
|
@@ -25,29 +23,11 @@ export type ServerOptions = {
|
|
|
25
23
|
logger?: Logger;
|
|
26
24
|
/** S2S configuration. Defaults to AssemblyAI production. */
|
|
27
25
|
s2sConfig?: S2SConfig;
|
|
28
|
-
/** WebSocket factory for S2S connections. Auto-detected if not provided. */
|
|
29
|
-
createWebSocket?: CreateS2sWebSocket;
|
|
30
26
|
};
|
|
31
27
|
export type AgentServer = {
|
|
32
|
-
/** Standard fetch handler using web `Request`/`Response` types. */
|
|
33
|
-
fetch(request: Request): Promise<Response>;
|
|
34
28
|
/** Start listening on the given port. */
|
|
35
29
|
listen(port?: number): Promise<void>;
|
|
36
30
|
/** Stop the server. */
|
|
37
31
|
close(): Promise<void>;
|
|
38
32
|
};
|
|
39
|
-
/**
|
|
40
|
-
* Create a self-hostable agent server.
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```ts
|
|
44
|
-
* import { defineAgent } from "aai";
|
|
45
|
-
* import { createServer } from "aai/server";
|
|
46
|
-
*
|
|
47
|
-
* const agent = defineAgent({ name: "my-agent" });
|
|
48
|
-
* const server = createServer({ agent });
|
|
49
|
-
* await server.listen(3000);
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
33
|
export declare function createServer(options: ServerOptions): AgentServer;
|
|
53
|
-
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { AUDIO_FORMAT } from "./protocol.js";
|
|
2
|
+
import { DEFAULT_S2S_CONFIG, consoleLogger } from "./runtime.js";
|
|
3
|
+
import { createDirectExecutor } from "./direct-executor.js";
|
|
4
|
+
import { wireSessionSocket } from "./ws-handler.js";
|
|
5
|
+
import { serve } from "@hono/node-server";
|
|
6
|
+
import { serveStatic } from "@hono/node-server/serve-static";
|
|
7
|
+
import { Hono } from "hono";
|
|
8
|
+
import { WebSocketServer } from "ws";
|
|
9
|
+
//#region server.ts
|
|
10
|
+
/**
|
|
11
|
+
* Self-hostable agent server.
|
|
12
|
+
*
|
|
13
|
+
* `createServer()` returns a server with `listen()` for HTTP + WebSocket.
|
|
14
|
+
* Calls `createDirectExecutor` + `wireSessionSocket` directly — no
|
|
15
|
+
* intermediate WintercServer layer.
|
|
16
|
+
*/
|
|
17
|
+
function resolveEnv(env) {
|
|
18
|
+
return Object.fromEntries(Object.entries(env).filter(([, v]) => v !== void 0));
|
|
19
|
+
}
|
|
20
|
+
function createServer(options) {
|
|
21
|
+
const { agent, kv, clientHtml, clientDir, logger = consoleLogger, s2sConfig = DEFAULT_S2S_CONFIG } = options;
|
|
22
|
+
const executor = createDirectExecutor({
|
|
23
|
+
agent,
|
|
24
|
+
env: resolveEnv(options.env ?? (typeof process !== "undefined" ? process.env : {})),
|
|
25
|
+
...kv ? { kv } : {},
|
|
26
|
+
logger,
|
|
27
|
+
s2sConfig
|
|
28
|
+
});
|
|
29
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
30
|
+
const readyConfig = {
|
|
31
|
+
audioFormat: AUDIO_FORMAT,
|
|
32
|
+
sampleRate: s2sConfig.inputSampleRate,
|
|
33
|
+
ttsSampleRate: s2sConfig.outputSampleRate
|
|
34
|
+
};
|
|
35
|
+
function handleWs(ws, skipGreeting) {
|
|
36
|
+
wireSessionSocket(ws, {
|
|
37
|
+
sessions,
|
|
38
|
+
createSession: (sid, client) => executor.createSession({
|
|
39
|
+
id: sid,
|
|
40
|
+
agent: agent.name,
|
|
41
|
+
client,
|
|
42
|
+
skipGreeting
|
|
43
|
+
}),
|
|
44
|
+
readyConfig,
|
|
45
|
+
logger
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
let serverHandle = null;
|
|
49
|
+
return {
|
|
50
|
+
async listen(port = 3e3) {
|
|
51
|
+
const app = new Hono();
|
|
52
|
+
app.onError((err, c) => {
|
|
53
|
+
logger.error(`${c.req.method} ${new URL(c.req.url).pathname} error: ${err.message}`);
|
|
54
|
+
return c.json({ error: "Internal Server Error" }, 500);
|
|
55
|
+
});
|
|
56
|
+
app.use("/*", async (c, next) => {
|
|
57
|
+
const start = Date.now();
|
|
58
|
+
await next();
|
|
59
|
+
const ms = Date.now() - start;
|
|
60
|
+
const { status } = c.res;
|
|
61
|
+
const method = c.req.method;
|
|
62
|
+
const path = new URL(c.req.url).pathname;
|
|
63
|
+
if (status >= 400) logger.error(`${method} ${path} ${status} ${ms}ms`);
|
|
64
|
+
else logger.info(`${method} ${path} ${status} ${ms}ms`);
|
|
65
|
+
});
|
|
66
|
+
app.get("/health", (c) => c.json({
|
|
67
|
+
status: "ok",
|
|
68
|
+
name: agent.name
|
|
69
|
+
}));
|
|
70
|
+
if (clientDir) app.use("/*", serveStatic({ root: clientDir }));
|
|
71
|
+
app.get("/", (c) => {
|
|
72
|
+
if (clientHtml) return c.html(clientHtml);
|
|
73
|
+
return c.html(`<!DOCTYPE html><html><body><h1>${agent.name}</h1><p>Agent server running.</p></body></html>`);
|
|
74
|
+
});
|
|
75
|
+
const nodeServer = serve({
|
|
76
|
+
fetch: app.fetch,
|
|
77
|
+
port
|
|
78
|
+
});
|
|
79
|
+
await new Promise((resolve) => {
|
|
80
|
+
nodeServer.on("listening", resolve);
|
|
81
|
+
});
|
|
82
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
83
|
+
nodeServer.on("upgrade", (req, socket, head) => {
|
|
84
|
+
const reqUrl = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
85
|
+
const resume = reqUrl.searchParams.has("resume");
|
|
86
|
+
logger.info(`WS upgrade ${reqUrl.pathname}${resume ? " (resume)" : ""}`);
|
|
87
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
88
|
+
handleWs(ws, resume);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
serverHandle = { async shutdown() {
|
|
92
|
+
await new Promise((resolve, reject) => {
|
|
93
|
+
nodeServer.close((err) => err ? reject(err) : resolve());
|
|
94
|
+
});
|
|
95
|
+
} };
|
|
96
|
+
},
|
|
97
|
+
async close() {
|
|
98
|
+
for (const session of sessions.values()) await session.stop();
|
|
99
|
+
sessions.clear();
|
|
100
|
+
await serverHandle?.shutdown();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
export { createServer };
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* S2S session — relays audio between the client and AssemblyAI's
|
|
3
3
|
* Speech-to-Speech API, intercepting only tool calls for local execution.
|
|
4
|
-
*
|
|
5
|
-
* Cross-runtime: accepts Logger, Metrics, and a WebSocket factory via
|
|
6
|
-
* dependency injection.
|
|
7
|
-
*
|
|
8
|
-
* @module
|
|
9
4
|
*/
|
|
10
|
-
import type { AgentConfig, ToolSchema } from "./
|
|
5
|
+
import type { AgentConfig, ToolSchema } from "./_internal-types.ts";
|
|
11
6
|
import type { ClientSink } from "./protocol.ts";
|
|
12
|
-
import type { Logger,
|
|
7
|
+
import type { Logger, S2SConfig } from "./runtime.ts";
|
|
13
8
|
import { type CreateS2sWebSocket, connectS2s } from "./s2s.ts";
|
|
14
9
|
import { type StepInfo } from "./types.ts";
|
|
15
|
-
import type { ExecuteTool } from "./
|
|
10
|
+
import type { ExecuteTool } from "./worker-entry.ts";
|
|
16
11
|
/** A voice session managing the S2S connection for one client. */
|
|
17
12
|
export type Session = {
|
|
18
13
|
start(): Promise<void>;
|
|
@@ -51,12 +46,11 @@ export type SessionOptions = {
|
|
|
51
46
|
apiKey: string;
|
|
52
47
|
s2sConfig: S2SConfig;
|
|
53
48
|
executeTool: ExecuteTool;
|
|
54
|
-
createWebSocket
|
|
49
|
+
createWebSocket?: CreateS2sWebSocket;
|
|
55
50
|
env?: Record<string, string | undefined>;
|
|
56
51
|
hookInvoker?: HookInvoker;
|
|
57
52
|
skipGreeting?: boolean;
|
|
58
53
|
logger?: Logger;
|
|
59
|
-
metrics?: Metrics;
|
|
60
54
|
};
|
|
61
55
|
export declare const _internals: {
|
|
62
56
|
connectS2s: typeof connectS2s;
|
|
@@ -67,4 +61,3 @@ export declare function buildSystemPrompt(config: AgentConfig, opts: {
|
|
|
67
61
|
hasTools: boolean;
|
|
68
62
|
voice?: boolean;
|
|
69
63
|
}): string;
|
|
70
|
-
//# sourceMappingURL=session.d.ts.map
|