@moss-tools/voice-server 1.0.0-beta.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to @moss-tools/voice-server will be documented in this file.
4
+
5
+ ## [1.0.0-beta.1] - 2026-02-11
6
+
7
+ Initial beta release.
8
+
9
+ ### Added
10
+ - `MossVoiceServer` class for managing voice agent connections
11
+ - `MossVoiceServer.create()` - Fetch and initialize credentials from Moss API
12
+ - `voiceServer.getServerUrl()` - Get voice agent server URL
13
+ - `voiceServer.createParticipantToken()` - Generate participant tokens
14
+ - `voiceServer.getAgentName()` - Get configured agent name
15
+ - Automatic credential caching
16
+ - Full TypeScript support with JSDoc
17
+
18
+ [1.0.0-beta.1]: https://github.com/InferEdge-Inc/moss/releases/tag/voice-server-v1.0.0-beta.1
package/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # @moss-tools/voice-server
2
+
3
+ Optimized server-side utilities for LiveKit-based Moss voice agents. Handles secure token generation and connection management.
4
+
5
+ ## Features
6
+
7
+ - **Token generation** - Create participant tokens with optimized permissions
8
+ - **Clean class-based API** - Simple, intuitive interface
9
+ - **Type-safe** - Full TypeScript support with detailed JSDoc comments
10
+
11
+ ## Requirements
12
+
13
+ - Node.js 18.0.0 or higher
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install @moss-tools/voice-server
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```ts
24
+ import { MossVoiceServer } from "@moss-tools/voice-server";
25
+
26
+ // Create and initialize (call once at app startup)
27
+ const voiceServer = await MossVoiceServer.create({
28
+ projectId: process.env.MOSS_PROJECT_ID!,
29
+ projectKey: process.env.MOSS_PROJECT_KEY!,
30
+ voiceAgentId: process.env.MOSS_VOICE_AGENT_ID!,
31
+ });
32
+
33
+ // Get voice agent server URL for clients
34
+ const serverUrl = voiceServer.getServerUrl();
35
+
36
+ // Create participant tokens
37
+ const token = await voiceServer.createParticipantToken(
38
+ { identity: "user_123", name: "John Doe" },
39
+ "support_room_456"
40
+ );
41
+ ```
42
+
43
+ The MossVoiceServer class securely fetches and caches your voice agent credentials, then uses them to generate participant tokens.
44
+
45
+ ## API
46
+
47
+ ### `MossVoiceServer.create(config): Promise<MossVoiceServer>`
48
+
49
+ Create and initialize a MossVoiceServer instance by fetching credentials from Moss API.
50
+
51
+ **Parameters:**
52
+ - `config.projectId` - Your Moss project ID
53
+ - `config.projectKey` - Your Moss project key
54
+ - `config.voiceAgentId` - Voice agent ID to use
55
+
56
+ **Returns:** Initialized `MossVoiceServer` instance
57
+
58
+ **Example:**
59
+ ```ts
60
+ const voiceServer = await MossVoiceServer.create({
61
+ projectId: "your-project-id",
62
+ projectKey: "your-project-key",
63
+ voiceAgentId: "your-voice-agent-id",
64
+ });
65
+ ```
66
+
67
+ ### `voiceServer.getServerUrl(): string`
68
+
69
+ Get the voice agent server URL for client connections.
70
+
71
+ **Returns:** Voice agent server URL (e.g., `wss://your-agent.livekit.cloud`)
72
+
73
+ **Note:** Credentials are kept secure on the server and never exposed.
74
+
75
+ ### `voiceServer.createParticipantToken(userInfo, roomName, agentName?): Promise<string>`
76
+
77
+ Create and sign a participant token for joining a voice session.
78
+
79
+ **Parameters:**
80
+ - `userInfo` - User identity and name
81
+ - `identity` - Unique user identifier
82
+ - `name` - Display name for the participant
83
+ - `roomName` - Room name to join
84
+ - `agentName` - (Optional) Override default voice agent name
85
+
86
+ **Returns:** Signed JWT token valid for 15 minutes
87
+
88
+ **Example:**
89
+ ```ts
90
+ const token = await voiceServer.createParticipantToken(
91
+ { identity: "user_123", name: "John Doe" },
92
+ "support_room_456"
93
+ );
94
+ ```
95
+
96
+ ### `voiceServer.getAgentName(): string`
97
+
98
+ Get the configured voice agent name.
99
+
100
+ **Returns:** Voice agent name
101
+
102
+ ## Environment Variables
103
+
104
+ Configure using environment variables:
105
+
106
+ ```bash
107
+ MOSS_PROJECT_ID=your-project-id
108
+ MOSS_PROJECT_KEY=your-project-key
109
+ MOSS_VOICE_AGENT_ID=your-voice-agent-id
110
+ ```
111
+
112
+ Then in your code:
113
+
114
+ ```ts
115
+ const voiceServer = await MossVoiceServer.create({
116
+ projectId: process.env.MOSS_PROJECT_ID!,
117
+ projectKey: process.env.MOSS_PROJECT_KEY!,
118
+ voiceAgentId: process.env.MOSS_VOICE_AGENT_ID!,
119
+ });
120
+ ```
121
+
122
+ ## Development
123
+
124
+ ```bash
125
+ npm install
126
+ npm run build
127
+ npm test
128
+ ```
129
+
130
+ Build output is emitted to `dist/`.
@@ -0,0 +1,84 @@
1
+ import { type AccessTokenOptions } from "livekit-server-sdk";
2
+ type MossVoiceServerConfig = {
3
+ projectId: string;
4
+ projectKey: string;
5
+ voiceAgentId: string;
6
+ };
7
+ /**
8
+ * Voice server client for managing voice agent connections and tokens.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const voiceServer = await MossVoiceServer.create({
13
+ * projectId: process.env.MOSS_PROJECT_ID!,
14
+ * projectKey: process.env.MOSS_PROJECT_KEY!,
15
+ * voiceAgentId: process.env.MOSS_VOICE_AGENT_ID!,
16
+ * });
17
+ *
18
+ * const url = voiceServer.getServerUrl();
19
+ * const token = await voiceServer.createParticipantToken(
20
+ * { identity: "user_123", name: "John" },
21
+ * "room_name"
22
+ * );
23
+ * ```
24
+ */
25
+ export declare class MossVoiceServer {
26
+ private config;
27
+ private credentials;
28
+ private constructor();
29
+ /**
30
+ * Create and initialize a MossVoiceServer instance.
31
+ *
32
+ * @param config - Configuration object
33
+ * @param config.projectId - Moss project ID
34
+ * @param config.projectKey - Moss project key
35
+ * @param config.voiceAgentId - Voice agent ID to use
36
+ * @returns Initialized MossVoiceServer instance
37
+ *
38
+ * @throws Error if credentials cannot be fetched
39
+ */
40
+ static create(config: MossVoiceServerConfig): Promise<MossVoiceServer>;
41
+ /**
42
+ * Initialize by fetching credentials from the Moss API.
43
+ * Called automatically by MossVoiceServer.create().
44
+ */
45
+ private initialize;
46
+ /**
47
+ * Get the voice agent server URL for client connections.
48
+ *
49
+ * @returns Voice agent server URL (e.g., "wss://your-agent.livekit.cloud")
50
+ * @throws Error if not initialized
51
+ */
52
+ getServerUrl(): string;
53
+ /**
54
+ * Create a participant token for joining a voice session.
55
+ *
56
+ * @param userInfo - LiveKit AccessTokenOptions (identity, name, metadata, etc.)
57
+ * @param roomName - Room name to join
58
+ * @param agentName - (Optional) Override default voice agent name
59
+ * @returns Signed JWT token valid for 15 minutes
60
+ *
61
+ * @throws Error if not initialized
62
+ *
63
+ * @remarks
64
+ * Token TTL is automatically set to 15 minutes. If userInfo.ttl is provided, it will be overridden.
65
+ * Commonly used userInfo fields: identity (required), name, metadata.
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * const token = await voiceServer.createParticipantToken(
70
+ * { identity: "user_123", name: "John Doe" },
71
+ * "support_room_456"
72
+ * );
73
+ * ```
74
+ */
75
+ createParticipantToken(userInfo: AccessTokenOptions, roomName: string, agentName?: string): Promise<string>;
76
+ /**
77
+ * Get the voice agent name from credentials.
78
+ *
79
+ * @returns Voice agent name
80
+ * @throws Error if not initialized
81
+ */
82
+ getAgentName(): string;
83
+ }
84
+ export {};
@@ -0,0 +1,151 @@
1
+ import { AccessToken, RoomConfiguration, } from "livekit-server-sdk";
2
+ const VOICE_AGENT_API_URL = "https://service.usemoss.dev/api/voice-agent-deploy/get-voice-agent";
3
+ /**
4
+ * Voice server client for managing voice agent connections and tokens.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const voiceServer = await MossVoiceServer.create({
9
+ * projectId: process.env.MOSS_PROJECT_ID!,
10
+ * projectKey: process.env.MOSS_PROJECT_KEY!,
11
+ * voiceAgentId: process.env.MOSS_VOICE_AGENT_ID!,
12
+ * });
13
+ *
14
+ * const url = voiceServer.getServerUrl();
15
+ * const token = await voiceServer.createParticipantToken(
16
+ * { identity: "user_123", name: "John" },
17
+ * "room_name"
18
+ * );
19
+ * ```
20
+ */
21
+ export class MossVoiceServer {
22
+ config;
23
+ credentials = null;
24
+ constructor(config) {
25
+ this.config = config;
26
+ }
27
+ /**
28
+ * Create and initialize a MossVoiceServer instance.
29
+ *
30
+ * @param config - Configuration object
31
+ * @param config.projectId - Moss project ID
32
+ * @param config.projectKey - Moss project key
33
+ * @param config.voiceAgentId - Voice agent ID to use
34
+ * @returns Initialized MossVoiceServer instance
35
+ *
36
+ * @throws Error if credentials cannot be fetched
37
+ */
38
+ static async create(config) {
39
+ const instance = new MossVoiceServer(config);
40
+ await instance.initialize();
41
+ return instance;
42
+ }
43
+ /**
44
+ * Initialize by fetching credentials from the Moss API.
45
+ * Called automatically by MossVoiceServer.create().
46
+ */
47
+ async initialize() {
48
+ const { projectId, projectKey, voiceAgentId } = this.config;
49
+ if (!projectId || !projectKey || !voiceAgentId) {
50
+ throw new Error("projectId, projectKey, and voiceAgentId are required");
51
+ }
52
+ try {
53
+ const url = `${VOICE_AGENT_API_URL}?voice_agent_id=${encodeURIComponent(voiceAgentId)}`;
54
+ // Add 10 second timeout to prevent indefinite hangs
55
+ const response = await fetch(url, {
56
+ method: "GET",
57
+ headers: {
58
+ "X-Project-Id": projectId,
59
+ "X-Project-Key": projectKey,
60
+ },
61
+ signal: AbortSignal.timeout(10000),
62
+ });
63
+ if (!response.ok) {
64
+ const errorText = await response.text().catch(() => "Unknown error");
65
+ throw new Error(`Failed to fetch credentials: ${response.status} ${errorText}`);
66
+ }
67
+ this.credentials = (await response.json());
68
+ }
69
+ catch (error) {
70
+ if (error instanceof Error) {
71
+ // Provide clear error message for timeout
72
+ if (error.name === "TimeoutError" || error.name === "AbortError") {
73
+ throw new Error("Failed to initialize MossVoiceServer: Request timed out after 10 seconds");
74
+ }
75
+ throw new Error(`Failed to initialize MossVoiceServer: ${error.message}`);
76
+ }
77
+ throw error;
78
+ }
79
+ }
80
+ /**
81
+ * Get the voice agent server URL for client connections.
82
+ *
83
+ * @returns Voice agent server URL (e.g., "wss://your-agent.livekit.cloud")
84
+ * @throws Error if not initialized
85
+ */
86
+ getServerUrl() {
87
+ if (!this.credentials) {
88
+ throw new Error("MossVoiceServer not initialized");
89
+ }
90
+ return this.credentials.voice_agent_url;
91
+ }
92
+ /**
93
+ * Create a participant token for joining a voice session.
94
+ *
95
+ * @param userInfo - LiveKit AccessTokenOptions (identity, name, metadata, etc.)
96
+ * @param roomName - Room name to join
97
+ * @param agentName - (Optional) Override default voice agent name
98
+ * @returns Signed JWT token valid for 15 minutes
99
+ *
100
+ * @throws Error if not initialized
101
+ *
102
+ * @remarks
103
+ * Token TTL is automatically set to 15 minutes. If userInfo.ttl is provided, it will be overridden.
104
+ * Commonly used userInfo fields: identity (required), name, metadata.
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * const token = await voiceServer.createParticipantToken(
109
+ * { identity: "user_123", name: "John Doe" },
110
+ * "support_room_456"
111
+ * );
112
+ * ```
113
+ */
114
+ async createParticipantToken(userInfo, roomName, agentName) {
115
+ if (!this.credentials) {
116
+ throw new Error("MossVoiceServer not initialized");
117
+ }
118
+ const { voice_agent_api_key, voice_agent_api_secret, voice_agent_name } = this.credentials;
119
+ const at = new AccessToken(voice_agent_api_key, voice_agent_api_secret, {
120
+ ...userInfo,
121
+ ttl: "15m",
122
+ });
123
+ const grant = {
124
+ room: roomName,
125
+ roomJoin: true,
126
+ canPublish: true,
127
+ canPublishData: true,
128
+ canSubscribe: true,
129
+ };
130
+ at.addGrant(grant);
131
+ const effectiveAgentName = agentName ?? voice_agent_name;
132
+ if (effectiveAgentName) {
133
+ at.roomConfig = new RoomConfiguration({
134
+ agents: [{ agentName: effectiveAgentName }],
135
+ });
136
+ }
137
+ return at.toJwt();
138
+ }
139
+ /**
140
+ * Get the voice agent name from credentials.
141
+ *
142
+ * @returns Voice agent name
143
+ * @throws Error if not initialized
144
+ */
145
+ getAgentName() {
146
+ if (!this.credentials) {
147
+ throw new Error("MossVoiceServer not initialized");
148
+ }
149
+ return this.credentials.voice_agent_name;
150
+ }
151
+ }
@@ -0,0 +1 @@
1
+ export { MossVoiceServer } from "./MossVoiceServer.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { MossVoiceServer } from "./MossVoiceServer.js";
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@moss-tools/voice-server",
3
+ "version": "1.0.0-beta.1",
4
+ "description": "Optimized server-side utilities for LiveKit-based Moss voice agents.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "CHANGELOG.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.json",
21
+ "test": "npm run build && tsx --test test/voice-server.test.ts"
22
+ },
23
+ "keywords": [
24
+ "moss",
25
+ "voice",
26
+ "agent",
27
+ "livekit",
28
+ "realtime",
29
+ "token",
30
+ "server"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/InferEdge-Inc/moss.git",
35
+ "directory": "javascript/voice-server"
36
+ },
37
+ "author": "Moss Team",
38
+ "license": "MIT",
39
+ "engines": {
40
+ "node": ">=18.0.0"
41
+ },
42
+ "dependencies": {
43
+ "livekit-server-sdk": "^2.15.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^24.3.0",
47
+ "tsx": "^4.21.0",
48
+ "typescript": "^5.9.3"
49
+ }
50
+ }