@simfinity/constellation-client 1.0.7 → 1.0.9

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/index.cjs CHANGED
@@ -31,26 +31,62 @@ var WebClient = class {
31
31
  this.sessionId = null;
32
32
  this.config = config;
33
33
  }
34
+ /**
35
+ * Retrieve the list of available tools:
36
+ * Tools, or functions, can be exposed to & added to the model's context, allowing it
37
+ * to use them during the session as part of its response creation process. In order to add
38
+ * a tool to the session context, it must be listed (by name) at session creation time
39
+ * (see startSession(...) function)
40
+ *
41
+ * @remarks
42
+ * Tools are remote functions exposed by MCP servers and integrated by the constellation server
43
+ *
44
+ * @exception
45
+ * This method throws new Error(...) if unable to execute successfully for any reason.
46
+ */
47
+ async fetchAvailableTools() {
48
+ const response = await fetch(`${this.config.sessionEndpoint}/available_tools`, {
49
+ method: "GET",
50
+ headers: {
51
+ "Authorization": `Bearer ${this.config.key}`,
52
+ "Content-Type": "application/json",
53
+ "Accept": "application/json"
54
+ }
55
+ });
56
+ if (!response.ok) {
57
+ throw new Error(`Could not fetch the list of available tools
58
+ [${response.status}:${response.statusText}]`);
59
+ }
60
+ try {
61
+ const result = await response.json();
62
+ return result != null ? result : [];
63
+ } catch (error) {
64
+ throw `Failed to read session create response: ${error}`;
65
+ }
66
+ }
34
67
  /**
35
68
  * Start a persistent chat room on the server, allowing for re-connection,
36
69
  * when the streaming connection is lost. Once a session was started it must
37
70
  * be closed to release the context on server side. See endSession().
38
71
  *
39
72
  * @remarks
40
- * A session MUST exist to connect the stream.
73
+ * A session MUST exist first in order to connect the stream next.
41
74
  *
42
- * @param instructions to the model, added to its context. This is the "system" input instructions.
43
- * @param audio whether to allow audio streaming or text-only
75
+ * @param audioEnabled whether this session can receive & produce audio as well as text
76
+ * @param voiceName LLM specific voice name e.g. with OpenAI this could be 'alloy'
77
+ * @param tools a list of tool names to be included in this session. These must be matching the
78
+ * names returned by 'fetchAvailableTools()'.
44
79
  *
45
80
  * @exception
46
81
  * This method throws new Error(...) if unable to execute successfully for any reason.
47
- *
48
- * @example
49
- * ```TypeScript
50
- * await startSession("You are useful assistant", true)
51
- * ```
52
82
  */
53
- async startSession(instructions = "", audio = false) {
83
+ async startSession(audioEnabled, voiceName, tools = []) {
84
+ const prepareBody = {
85
+ llmProvider: this.config.llm,
86
+ audioEnabled,
87
+ voiceName,
88
+ includeTools: tools
89
+ };
54
90
  const response = await fetch(`${this.config.sessionEndpoint}/prepare_session`, {
55
91
  method: "POST",
56
92
  headers: {
@@ -58,11 +94,7 @@ var WebClient = class {
58
94
  "Content-Type": "application/json",
59
95
  "Accept": "application/json"
60
96
  },
61
- body: JSON.stringify({
62
- llmProvider: this.config.llm,
63
- systemPrompt: instructions,
64
- audio
65
- })
97
+ body: JSON.stringify(prepareBody)
66
98
  });
67
99
  if (!response.ok) {
68
100
  throw new Error(`Could not create a new chat session
@@ -116,7 +148,7 @@ var WebClient = class {
116
148
  * This method not only opens a websocket connection with the server but also initiates a
117
149
  * handshake, where the server explicitly acknowledges and accepts the client connection.
118
150
  *
119
- * @param audio for a session that created with audio capabilities, allows this streaming to include audio
151
+ * @param audio for an audio-enabled session, request this streaming connection to include audio events
120
152
  * @param handlers callback functions to handle every possible communication events coming from the server
121
153
  *
122
154
  * @exception
@@ -125,7 +157,7 @@ var WebClient = class {
125
157
  * @example
126
158
  * ```TypeScript
127
159
  * // Open an audio connection: in this example we choose to handle only audio data, and ignore text.
128
- * await connect(true, {
160
+ * await joinSession(true, {
129
161
  * onStreamClosed: (reason: string) => { console.log("Stream connection lost"); },
130
162
  * onAudioResponseStart: () => { console.log("The model is talking"); },
131
163
  * onAudioResponseChunk: (audioChunk: string) => { audioPlayer.enqueue(audioChunk); },
@@ -187,7 +219,7 @@ var WebClient = class {
187
219
  this.ws = ws;
188
220
  }
189
221
  /**
190
- * With an opened streaming connection: send a "system" update of the session settings.
222
+ * Once a session is joined: send a "system" update of the session settings.
191
223
  * Allows to change some behavioral parameters like the temperature or system instructions.
192
224
  * This does not trigger a model response.
193
225
  *
@@ -195,16 +227,16 @@ var WebClient = class {
195
227
  * With openai for example, this triggers (pseudo-code):
196
228
  * webSocket.send({ type: "session.update", session: { ... }})
197
229
  *
198
- * @param settings complete definition of the settings. Same values must be re-provided for unchanged parameters.
230
+ * @param settings new system settings to apply. Omitted values will remain unchanged
199
231
  *
200
232
  * @exception
201
233
  * This method throws new Error(...) if unable to execute successfully for any reason.
202
234
  */
203
- async configureSession(settings) {
235
+ configureSession(settings) {
204
236
  this.send("session.configure", settings);
205
237
  }
206
238
  /**
207
- * With an opened streaming connection: send a text input message to the LLM. This will trigger a
239
+ * Once a session is joined: send a text input message to the LLM. This will trigger a
208
240
  * text response as well as an audio response if the session was opened with audio mode active.
209
241
  *
210
242
  * @remarks
@@ -221,7 +253,7 @@ var WebClient = class {
221
253
  this.send("text.input.message", { text });
222
254
  }
223
255
  /**
224
- * With an opened streaming connection: send a chunk of raw audio data to the LLM.
256
+ * Once a session is joined: send a chunk of raw audio data to the LLM.
225
257
  * Audio data chunks do not systematically & immediately trigger a model response:
226
258
  * They get accumulated by the model to form a single input message, until:
227
259
  * - commitAudioChunksSent is called, which flushes the accumulated audio and triggers a response
@@ -240,8 +272,8 @@ var WebClient = class {
240
272
  this.send("audio.input.append", { audioData: chunk });
241
273
  }
242
274
  /**
243
- * With an opened streaming connection: triggers the processing of the accumulated audio data since
244
- * the last model response. This effectively flushes the audio buffer and triggers a new model response.
275
+ * Once a session is joined: triggers the processing of the accumulated audio data since
276
+ * the last model response. This effectively flushes the audio buffer and triggers a model response.
245
277
  *
246
278
  * @remarks
247
279
  * With openai for example, this triggers (pseudo-code):
@@ -279,14 +311,22 @@ var WebClient = class {
279
311
  ws.onopen = () => {
280
312
  const eventSubs = audio ? [0 /* Text */, 1 /* Audio */] : [0 /* Text */];
281
313
  ws.send(JSON.stringify({
282
- type: "connection.request",
283
- data: { subscription: eventSubs }
314
+ type: "connection.initiate",
315
+ data: {
316
+ subscription: eventSubs,
317
+ settings: {
318
+ audio: true,
319
+ voice: "alloy",
320
+ temperature: 0.8,
321
+ instructions: ""
322
+ }
323
+ }
284
324
  }));
285
325
  };
286
326
  ws.onmessage = (event) => {
287
327
  try {
288
328
  const data = JSON.parse(event.data);
289
- if (data.type === "connection.accepted")
329
+ if (data.type === "connection.initiated")
290
330
  resolve(true);
291
331
  else
292
332
  reject(new Error(`Received unexpected event: ${data.type}`));
package/dist/index.d.cts CHANGED
@@ -31,17 +31,13 @@ interface WebClientConfig {
31
31
  }
32
32
  /**
33
33
  * System settings influencing the model behavior:
34
- * @audio: to activate voice conversation
35
- * @voice: depending on the LLM solution, this is the voice name to be used in audio
36
34
  * @temperature: LLM creativity factor in 0-1 range
37
35
  * @instructions: system instructions giving context, rules and directions to guide the LLM behavior
38
36
  * @maxResponseToken: 1-4096 value, maximum number of token used for a single response. Undefined means unlimited.
39
37
  */
40
- interface SessionSettings {
41
- audio: boolean;
42
- voice: string;
43
- temperature: number;
44
- instructions: string;
38
+ interface SessionConfig {
39
+ temperature?: number;
40
+ instructions?: string;
45
41
  maxResponseToken?: number;
46
42
  }
47
43
  /**
@@ -66,7 +62,7 @@ interface SessionSettings {
66
62
  */
67
63
  interface EventHandlers {
68
64
  onStreamClosed: (reason: string) => void;
69
- onSessionConfigured?: (settings: SessionSettings) => void;
65
+ onSessionConfigured?: (settings: SessionConfig) => void;
70
66
  onAudioResponseStart?: () => void;
71
67
  onAudioResponseChunk?: (audioChunk: string) => void;
72
68
  onAudioResponseEnd?: () => void;
@@ -74,6 +70,16 @@ interface EventHandlers {
74
70
  onTranscriptResponse?: (transcript: string) => void;
75
71
  onTechnicalError?: (error: string) => void;
76
72
  }
73
+ /**
74
+ * Description of an available tool that can be added to a session context.
75
+ * Tools included in the session context can be used by the AI model during the session.
76
+ * Tools (or functions) can be many things, for example a calendar manager, allowing
77
+ * the model to manage the user's schedule.
78
+ */
79
+ interface ToolDescription {
80
+ name: string;
81
+ description: string;
82
+ }
77
83
  /**
78
84
  * This class is a code wrapper to integrate the Simfinity constellation server.
79
85
  * The constellation server is a proxy managing streaming sessions with third party LLMs.
@@ -87,26 +93,37 @@ declare class WebClient {
87
93
  private ws;
88
94
  private sessionId;
89
95
  constructor(config: WebClientConfig);
96
+ /**
97
+ * Retrieve the list of available tools:
98
+ * Tools, or functions, can be exposed to & added to the model's context, allowing it
99
+ * to use them during the session as part of its response creation process. In order to add
100
+ * a tool to the session context, it must be listed (by name) at session creation time
101
+ * (see startSession(...) function)
102
+ *
103
+ * @remarks
104
+ * Tools are remote functions exposed by MCP servers and integrated by the constellation server
105
+ *
106
+ * @exception
107
+ * This method throws new Error(...) if unable to execute successfully for any reason.
108
+ */
109
+ fetchAvailableTools(): Promise<ToolDescription[]>;
90
110
  /**
91
111
  * Start a persistent chat room on the server, allowing for re-connection,
92
112
  * when the streaming connection is lost. Once a session was started it must
93
113
  * be closed to release the context on server side. See endSession().
94
114
  *
95
115
  * @remarks
96
- * A session MUST exist to connect the stream.
116
+ * A session MUST exist first in order to connect the stream next.
97
117
  *
98
- * @param instructions to the model, added to its context. This is the "system" input instructions.
99
- * @param audio whether to allow audio streaming or text-only
118
+ * @param audioEnabled whether this session can receive & produce audio as well as text
119
+ * @param voiceName LLM specific voice name e.g. with OpenAI this could be 'alloy'
120
+ * @param tools a list of tool names to be included in this session. These must be matching the
121
+ * names returned by 'fetchAvailableTools()'.
100
122
  *
101
123
  * @exception
102
124
  * This method throws new Error(...) if unable to execute successfully for any reason.
103
- *
104
- * @example
105
- * ```TypeScript
106
- * await startSession("You are useful assistant", true)
107
- * ```
108
125
  */
109
- startSession(instructions?: string, audio?: boolean): Promise<void>;
126
+ startSession(audioEnabled: boolean, voiceName?: string, tools?: string[]): Promise<void>;
110
127
  /**
111
128
  * Close an opened, persistent chat room, effectively killing the streaming as well if still opened.
112
129
  * If there is no active session, this method does nothing.
@@ -128,7 +145,7 @@ declare class WebClient {
128
145
  * This method not only opens a websocket connection with the server but also initiates a
129
146
  * handshake, where the server explicitly acknowledges and accepts the client connection.
130
147
  *
131
- * @param audio for a session that created with audio capabilities, allows this streaming to include audio
148
+ * @param audio for an audio-enabled session, request this streaming connection to include audio events
132
149
  * @param handlers callback functions to handle every possible communication events coming from the server
133
150
  *
134
151
  * @exception
@@ -137,7 +154,7 @@ declare class WebClient {
137
154
  * @example
138
155
  * ```TypeScript
139
156
  * // Open an audio connection: in this example we choose to handle only audio data, and ignore text.
140
- * await connect(true, {
157
+ * await joinSession(true, {
141
158
  * onStreamClosed: (reason: string) => { console.log("Stream connection lost"); },
142
159
  * onAudioResponseStart: () => { console.log("The model is talking"); },
143
160
  * onAudioResponseChunk: (audioChunk: string) => { audioPlayer.enqueue(audioChunk); },
@@ -147,7 +164,7 @@ declare class WebClient {
147
164
  */
148
165
  joinSession(audio: boolean | undefined, handlers: EventHandlers): Promise<void>;
149
166
  /**
150
- * With an opened streaming connection: send a "system" update of the session settings.
167
+ * Once a session is joined: send a "system" update of the session settings.
151
168
  * Allows to change some behavioral parameters like the temperature or system instructions.
152
169
  * This does not trigger a model response.
153
170
  *
@@ -155,14 +172,14 @@ declare class WebClient {
155
172
  * With openai for example, this triggers (pseudo-code):
156
173
  * webSocket.send({ type: "session.update", session: { ... }})
157
174
  *
158
- * @param settings complete definition of the settings. Same values must be re-provided for unchanged parameters.
175
+ * @param settings new system settings to apply. Omitted values will remain unchanged
159
176
  *
160
177
  * @exception
161
178
  * This method throws new Error(...) if unable to execute successfully for any reason.
162
179
  */
163
- configureSession(settings: SessionSettings): Promise<void>;
180
+ configureSession(settings: SessionConfig): void;
164
181
  /**
165
- * With an opened streaming connection: send a text input message to the LLM. This will trigger a
182
+ * Once a session is joined: send a text input message to the LLM. This will trigger a
166
183
  * text response as well as an audio response if the session was opened with audio mode active.
167
184
  *
168
185
  * @remarks
@@ -177,7 +194,7 @@ declare class WebClient {
177
194
  */
178
195
  sendText(text: string): void;
179
196
  /**
180
- * With an opened streaming connection: send a chunk of raw audio data to the LLM.
197
+ * Once a session is joined: send a chunk of raw audio data to the LLM.
181
198
  * Audio data chunks do not systematically & immediately trigger a model response:
182
199
  * They get accumulated by the model to form a single input message, until:
183
200
  * - commitAudioChunksSent is called, which flushes the accumulated audio and triggers a response
@@ -194,8 +211,8 @@ declare class WebClient {
194
211
  */
195
212
  sendAudioChunk(chunk: string): void;
196
213
  /**
197
- * With an opened streaming connection: triggers the processing of the accumulated audio data since
198
- * the last model response. This effectively flushes the audio buffer and triggers a new model response.
214
+ * Once a session is joined: triggers the processing of the accumulated audio data since
215
+ * the last model response. This effectively flushes the audio buffer and triggers a model response.
199
216
  *
200
217
  * @remarks
201
218
  * With openai for example, this triggers (pseudo-code):
@@ -215,4 +232,4 @@ declare class WebClient {
215
232
  private send;
216
233
  }
217
234
 
218
- export { type EventHandlers, type LlmType, type SessionSettings, WebClient, type WebClientConfig };
235
+ export { type EventHandlers, type LlmType, type SessionConfig, type ToolDescription, WebClient, type WebClientConfig };
package/dist/index.d.ts CHANGED
@@ -31,17 +31,13 @@ interface WebClientConfig {
31
31
  }
32
32
  /**
33
33
  * System settings influencing the model behavior:
34
- * @audio: to activate voice conversation
35
- * @voice: depending on the LLM solution, this is the voice name to be used in audio
36
34
  * @temperature: LLM creativity factor in 0-1 range
37
35
  * @instructions: system instructions giving context, rules and directions to guide the LLM behavior
38
36
  * @maxResponseToken: 1-4096 value, maximum number of token used for a single response. Undefined means unlimited.
39
37
  */
40
- interface SessionSettings {
41
- audio: boolean;
42
- voice: string;
43
- temperature: number;
44
- instructions: string;
38
+ interface SessionConfig {
39
+ temperature?: number;
40
+ instructions?: string;
45
41
  maxResponseToken?: number;
46
42
  }
47
43
  /**
@@ -66,7 +62,7 @@ interface SessionSettings {
66
62
  */
67
63
  interface EventHandlers {
68
64
  onStreamClosed: (reason: string) => void;
69
- onSessionConfigured?: (settings: SessionSettings) => void;
65
+ onSessionConfigured?: (settings: SessionConfig) => void;
70
66
  onAudioResponseStart?: () => void;
71
67
  onAudioResponseChunk?: (audioChunk: string) => void;
72
68
  onAudioResponseEnd?: () => void;
@@ -74,6 +70,16 @@ interface EventHandlers {
74
70
  onTranscriptResponse?: (transcript: string) => void;
75
71
  onTechnicalError?: (error: string) => void;
76
72
  }
73
+ /**
74
+ * Description of an available tool that can be added to a session context.
75
+ * Tools included in the session context can be used by the AI model during the session.
76
+ * Tools (or functions) can be many things, for example a calendar manager, allowing
77
+ * the model to manage the user's schedule.
78
+ */
79
+ interface ToolDescription {
80
+ name: string;
81
+ description: string;
82
+ }
77
83
  /**
78
84
  * This class is a code wrapper to integrate the Simfinity constellation server.
79
85
  * The constellation server is a proxy managing streaming sessions with third party LLMs.
@@ -87,26 +93,37 @@ declare class WebClient {
87
93
  private ws;
88
94
  private sessionId;
89
95
  constructor(config: WebClientConfig);
96
+ /**
97
+ * Retrieve the list of available tools:
98
+ * Tools, or functions, can be exposed to & added to the model's context, allowing it
99
+ * to use them during the session as part of its response creation process. In order to add
100
+ * a tool to the session context, it must be listed (by name) at session creation time
101
+ * (see startSession(...) function)
102
+ *
103
+ * @remarks
104
+ * Tools are remote functions exposed by MCP servers and integrated by the constellation server
105
+ *
106
+ * @exception
107
+ * This method throws new Error(...) if unable to execute successfully for any reason.
108
+ */
109
+ fetchAvailableTools(): Promise<ToolDescription[]>;
90
110
  /**
91
111
  * Start a persistent chat room on the server, allowing for re-connection,
92
112
  * when the streaming connection is lost. Once a session was started it must
93
113
  * be closed to release the context on server side. See endSession().
94
114
  *
95
115
  * @remarks
96
- * A session MUST exist to connect the stream.
116
+ * A session MUST exist first in order to connect the stream next.
97
117
  *
98
- * @param instructions to the model, added to its context. This is the "system" input instructions.
99
- * @param audio whether to allow audio streaming or text-only
118
+ * @param audioEnabled whether this session can receive & produce audio as well as text
119
+ * @param voiceName LLM specific voice name e.g. with OpenAI this could be 'alloy'
120
+ * @param tools a list of tool names to be included in this session. These must be matching the
121
+ * names returned by 'fetchAvailableTools()'.
100
122
  *
101
123
  * @exception
102
124
  * This method throws new Error(...) if unable to execute successfully for any reason.
103
- *
104
- * @example
105
- * ```TypeScript
106
- * await startSession("You are useful assistant", true)
107
- * ```
108
125
  */
109
- startSession(instructions?: string, audio?: boolean): Promise<void>;
126
+ startSession(audioEnabled: boolean, voiceName?: string, tools?: string[]): Promise<void>;
110
127
  /**
111
128
  * Close an opened, persistent chat room, effectively killing the streaming as well if still opened.
112
129
  * If there is no active session, this method does nothing.
@@ -128,7 +145,7 @@ declare class WebClient {
128
145
  * This method not only opens a websocket connection with the server but also initiates a
129
146
  * handshake, where the server explicitly acknowledges and accepts the client connection.
130
147
  *
131
- * @param audio for a session that created with audio capabilities, allows this streaming to include audio
148
+ * @param audio for an audio-enabled session, request this streaming connection to include audio events
132
149
  * @param handlers callback functions to handle every possible communication events coming from the server
133
150
  *
134
151
  * @exception
@@ -137,7 +154,7 @@ declare class WebClient {
137
154
  * @example
138
155
  * ```TypeScript
139
156
  * // Open an audio connection: in this example we choose to handle only audio data, and ignore text.
140
- * await connect(true, {
157
+ * await joinSession(true, {
141
158
  * onStreamClosed: (reason: string) => { console.log("Stream connection lost"); },
142
159
  * onAudioResponseStart: () => { console.log("The model is talking"); },
143
160
  * onAudioResponseChunk: (audioChunk: string) => { audioPlayer.enqueue(audioChunk); },
@@ -147,7 +164,7 @@ declare class WebClient {
147
164
  */
148
165
  joinSession(audio: boolean | undefined, handlers: EventHandlers): Promise<void>;
149
166
  /**
150
- * With an opened streaming connection: send a "system" update of the session settings.
167
+ * Once a session is joined: send a "system" update of the session settings.
151
168
  * Allows to change some behavioral parameters like the temperature or system instructions.
152
169
  * This does not trigger a model response.
153
170
  *
@@ -155,14 +172,14 @@ declare class WebClient {
155
172
  * With openai for example, this triggers (pseudo-code):
156
173
  * webSocket.send({ type: "session.update", session: { ... }})
157
174
  *
158
- * @param settings complete definition of the settings. Same values must be re-provided for unchanged parameters.
175
+ * @param settings new system settings to apply. Omitted values will remain unchanged
159
176
  *
160
177
  * @exception
161
178
  * This method throws new Error(...) if unable to execute successfully for any reason.
162
179
  */
163
- configureSession(settings: SessionSettings): Promise<void>;
180
+ configureSession(settings: SessionConfig): void;
164
181
  /**
165
- * With an opened streaming connection: send a text input message to the LLM. This will trigger a
182
+ * Once a session is joined: send a text input message to the LLM. This will trigger a
166
183
  * text response as well as an audio response if the session was opened with audio mode active.
167
184
  *
168
185
  * @remarks
@@ -177,7 +194,7 @@ declare class WebClient {
177
194
  */
178
195
  sendText(text: string): void;
179
196
  /**
180
- * With an opened streaming connection: send a chunk of raw audio data to the LLM.
197
+ * Once a session is joined: send a chunk of raw audio data to the LLM.
181
198
  * Audio data chunks do not systematically & immediately trigger a model response:
182
199
  * They get accumulated by the model to form a single input message, until:
183
200
  * - commitAudioChunksSent is called, which flushes the accumulated audio and triggers a response
@@ -194,8 +211,8 @@ declare class WebClient {
194
211
  */
195
212
  sendAudioChunk(chunk: string): void;
196
213
  /**
197
- * With an opened streaming connection: triggers the processing of the accumulated audio data since
198
- * the last model response. This effectively flushes the audio buffer and triggers a new model response.
214
+ * Once a session is joined: triggers the processing of the accumulated audio data since
215
+ * the last model response. This effectively flushes the audio buffer and triggers a model response.
199
216
  *
200
217
  * @remarks
201
218
  * With openai for example, this triggers (pseudo-code):
@@ -215,4 +232,4 @@ declare class WebClient {
215
232
  private send;
216
233
  }
217
234
 
218
- export { type EventHandlers, type LlmType, type SessionSettings, WebClient, type WebClientConfig };
235
+ export { type EventHandlers, type LlmType, type SessionConfig, type ToolDescription, WebClient, type WebClientConfig };
package/dist/index.js CHANGED
@@ -5,26 +5,62 @@ var WebClient = class {
5
5
  this.sessionId = null;
6
6
  this.config = config;
7
7
  }
8
+ /**
9
+ * Retrieve the list of available tools:
10
+ * Tools, or functions, can be exposed to & added to the model's context, allowing it
11
+ * to use them during the session as part of its response creation process. In order to add
12
+ * a tool to the session context, it must be listed (by name) at session creation time
13
+ * (see startSession(...) function)
14
+ *
15
+ * @remarks
16
+ * Tools are remote functions exposed by MCP servers and integrated by the constellation server
17
+ *
18
+ * @exception
19
+ * This method throws new Error(...) if unable to execute successfully for any reason.
20
+ */
21
+ async fetchAvailableTools() {
22
+ const response = await fetch(`${this.config.sessionEndpoint}/available_tools`, {
23
+ method: "GET",
24
+ headers: {
25
+ "Authorization": `Bearer ${this.config.key}`,
26
+ "Content-Type": "application/json",
27
+ "Accept": "application/json"
28
+ }
29
+ });
30
+ if (!response.ok) {
31
+ throw new Error(`Could not fetch the list of available tools
32
+ [${response.status}:${response.statusText}]`);
33
+ }
34
+ try {
35
+ const result = await response.json();
36
+ return result != null ? result : [];
37
+ } catch (error) {
38
+ throw `Failed to read session create response: ${error}`;
39
+ }
40
+ }
8
41
  /**
9
42
  * Start a persistent chat room on the server, allowing for re-connection,
10
43
  * when the streaming connection is lost. Once a session was started it must
11
44
  * be closed to release the context on server side. See endSession().
12
45
  *
13
46
  * @remarks
14
- * A session MUST exist to connect the stream.
47
+ * A session MUST exist first in order to connect the stream next.
15
48
  *
16
- * @param instructions to the model, added to its context. This is the "system" input instructions.
17
- * @param audio whether to allow audio streaming or text-only
49
+ * @param audioEnabled whether this session can receive & produce audio as well as text
50
+ * @param voiceName LLM specific voice name e.g. with OpenAI this could be 'alloy'
51
+ * @param tools a list of tool names to be included in this session. These must be matching the
52
+ * names returned by 'fetchAvailableTools()'.
18
53
  *
19
54
  * @exception
20
55
  * This method throws new Error(...) if unable to execute successfully for any reason.
21
- *
22
- * @example
23
- * ```TypeScript
24
- * await startSession("You are useful assistant", true)
25
- * ```
26
56
  */
27
- async startSession(instructions = "", audio = false) {
57
+ async startSession(audioEnabled, voiceName, tools = []) {
58
+ const prepareBody = {
59
+ llmProvider: this.config.llm,
60
+ audioEnabled,
61
+ voiceName,
62
+ includeTools: tools
63
+ };
28
64
  const response = await fetch(`${this.config.sessionEndpoint}/prepare_session`, {
29
65
  method: "POST",
30
66
  headers: {
@@ -32,11 +68,7 @@ var WebClient = class {
32
68
  "Content-Type": "application/json",
33
69
  "Accept": "application/json"
34
70
  },
35
- body: JSON.stringify({
36
- llmProvider: this.config.llm,
37
- systemPrompt: instructions,
38
- audio
39
- })
71
+ body: JSON.stringify(prepareBody)
40
72
  });
41
73
  if (!response.ok) {
42
74
  throw new Error(`Could not create a new chat session
@@ -90,7 +122,7 @@ var WebClient = class {
90
122
  * This method not only opens a websocket connection with the server but also initiates a
91
123
  * handshake, where the server explicitly acknowledges and accepts the client connection.
92
124
  *
93
- * @param audio for a session that created with audio capabilities, allows this streaming to include audio
125
+ * @param audio for an audio-enabled session, request this streaming connection to include audio events
94
126
  * @param handlers callback functions to handle every possible communication events coming from the server
95
127
  *
96
128
  * @exception
@@ -99,7 +131,7 @@ var WebClient = class {
99
131
  * @example
100
132
  * ```TypeScript
101
133
  * // Open an audio connection: in this example we choose to handle only audio data, and ignore text.
102
- * await connect(true, {
134
+ * await joinSession(true, {
103
135
  * onStreamClosed: (reason: string) => { console.log("Stream connection lost"); },
104
136
  * onAudioResponseStart: () => { console.log("The model is talking"); },
105
137
  * onAudioResponseChunk: (audioChunk: string) => { audioPlayer.enqueue(audioChunk); },
@@ -161,7 +193,7 @@ var WebClient = class {
161
193
  this.ws = ws;
162
194
  }
163
195
  /**
164
- * With an opened streaming connection: send a "system" update of the session settings.
196
+ * Once a session is joined: send a "system" update of the session settings.
165
197
  * Allows to change some behavioral parameters like the temperature or system instructions.
166
198
  * This does not trigger a model response.
167
199
  *
@@ -169,16 +201,16 @@ var WebClient = class {
169
201
  * With openai for example, this triggers (pseudo-code):
170
202
  * webSocket.send({ type: "session.update", session: { ... }})
171
203
  *
172
- * @param settings complete definition of the settings. Same values must be re-provided for unchanged parameters.
204
+ * @param settings new system settings to apply. Omitted values will remain unchanged
173
205
  *
174
206
  * @exception
175
207
  * This method throws new Error(...) if unable to execute successfully for any reason.
176
208
  */
177
- async configureSession(settings) {
209
+ configureSession(settings) {
178
210
  this.send("session.configure", settings);
179
211
  }
180
212
  /**
181
- * With an opened streaming connection: send a text input message to the LLM. This will trigger a
213
+ * Once a session is joined: send a text input message to the LLM. This will trigger a
182
214
  * text response as well as an audio response if the session was opened with audio mode active.
183
215
  *
184
216
  * @remarks
@@ -195,7 +227,7 @@ var WebClient = class {
195
227
  this.send("text.input.message", { text });
196
228
  }
197
229
  /**
198
- * With an opened streaming connection: send a chunk of raw audio data to the LLM.
230
+ * Once a session is joined: send a chunk of raw audio data to the LLM.
199
231
  * Audio data chunks do not systematically & immediately trigger a model response:
200
232
  * They get accumulated by the model to form a single input message, until:
201
233
  * - commitAudioChunksSent is called, which flushes the accumulated audio and triggers a response
@@ -214,8 +246,8 @@ var WebClient = class {
214
246
  this.send("audio.input.append", { audioData: chunk });
215
247
  }
216
248
  /**
217
- * With an opened streaming connection: triggers the processing of the accumulated audio data since
218
- * the last model response. This effectively flushes the audio buffer and triggers a new model response.
249
+ * Once a session is joined: triggers the processing of the accumulated audio data since
250
+ * the last model response. This effectively flushes the audio buffer and triggers a model response.
219
251
  *
220
252
  * @remarks
221
253
  * With openai for example, this triggers (pseudo-code):
@@ -253,14 +285,22 @@ var WebClient = class {
253
285
  ws.onopen = () => {
254
286
  const eventSubs = audio ? [0 /* Text */, 1 /* Audio */] : [0 /* Text */];
255
287
  ws.send(JSON.stringify({
256
- type: "connection.request",
257
- data: { subscription: eventSubs }
288
+ type: "connection.initiate",
289
+ data: {
290
+ subscription: eventSubs,
291
+ settings: {
292
+ audio: true,
293
+ voice: "alloy",
294
+ temperature: 0.8,
295
+ instructions: ""
296
+ }
297
+ }
258
298
  }));
259
299
  };
260
300
  ws.onmessage = (event) => {
261
301
  try {
262
302
  const data = JSON.parse(event.data);
263
- if (data.type === "connection.accepted")
303
+ if (data.type === "connection.initiated")
264
304
  resolve(true);
265
305
  else
266
306
  reject(new Error(`Received unexpected event: ${data.type}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simfinity/constellation-client",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {