@simfinity/constellation-react 0.0.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/README.md ADDED
@@ -0,0 +1,241 @@
1
+ # @simfinity/constellation-ui
2
+
3
+ React bindings for Simfinity Constellation Client — persistent real-time LLM chat rooms (text + audio).
4
+
5
+ ## Overview
6
+
7
+ Constellation provides:
8
+ * An abstraction layer to interact with different LLMs
9
+ * Persistent server-side sessions
10
+ * WebSocket real-time streaming
11
+ * Text + audio conversations
12
+ * Configurable system instructions & session settings
13
+ * Reconnectable chat rooms
14
+
15
+ This package is a React wrapper around:
16
+
17
+ @simfinity/constellation-client
18
+
19
+ It provides context + hooks for lifecycle management.
20
+
21
+ ## Installation
22
+ ```bash
23
+ npm install @simfinity/constellation-ui
24
+ # or
25
+ yarn add @simfinity/constellation-ui
26
+
27
+ # Dependency:
28
+ npm install @simfinity/constellation-client
29
+ # or
30
+ yarn add @simfinity/constellation-client
31
+ ```
32
+
33
+ ## Architecture
34
+
35
+ Session lifecycle:
36
+ ```
37
+ startSession() → REST call
38
+ joinSession() → WebSocket connection
39
+
40
+ configureSession() (optional) → WebSocket messages
41
+ sendText() / sendAudioChunk() + commitAudio() → WebSocket messages
42
+
43
+ endSession() → REST call
44
+ ```
45
+
46
+ ⚠️ A session MUST be started before it can be joined.
47
+
48
+ ⚠️ A session SHOULD be ended when finished.
49
+
50
+ ## Minimal Working Example (Text-Only)
51
+
52
+ ```Typescript
53
+ import React, { useEffect } from "react";
54
+ import WebClient from "@simfinity/constellation-client";
55
+ import {
56
+ ConstellationProvider,
57
+ useConstellationClient
58
+ } from "@simfinity/constellation-ui";
59
+
60
+ const client = new WebClient({
61
+ sessionEndpoint: "https://your-api",
62
+ streamingEndpoint: "wss://your-stream",
63
+ key: "YOUR_SECRET_KEY",
64
+ });
65
+
66
+ function Chat() {
67
+ const client = useConstellationClient();
68
+
69
+ useEffect(() => {
70
+ async function init() {
71
+ const params: SessionStartParameters = {
72
+ llmProvider: "openai",
73
+ voiceEnabled: false,
74
+ behaviour: {
75
+ temperature: 0.9,
76
+ instructions: "Just have a nice and casual conversation.",
77
+ }
78
+ }
79
+
80
+ await client.startSession(params);
81
+
82
+ await client.joinSession(false, {
83
+ onStreamClosed: console.log,
84
+ onTranscriptResponse: (msg) => {
85
+ console.log("Model:", msg);
86
+ }
87
+ });
88
+
89
+ client.sendText("Hello!");
90
+ }
91
+
92
+ init();
93
+
94
+ return () => {
95
+ client.endSession();
96
+ };
97
+ }, []);
98
+
99
+ return <div>Chat running...</div>;
100
+ }
101
+
102
+ export default function App() {
103
+ return (
104
+ <ConstellationProvider client={client}>
105
+ <Chat />
106
+ </ConstellationProvider>
107
+ );
108
+ }
109
+ ```
110
+
111
+ ## Audio Mode
112
+
113
+ To enable audio:
114
+
115
+ ```Typescript
116
+ // Create a audio-enabled session
117
+ const params: SessionStartParameters = {
118
+ llmProvider: "openai",
119
+ voiceEnabled: true,
120
+ voiceName: "alloy",
121
+ behaviour: {
122
+ temperature: 0.9,
123
+ instructions: "Just have a nice and casual conversation.",
124
+ }
125
+ }
126
+ await startSession(params);
127
+
128
+ // Join a stream subscribing to audio events
129
+ await joinSession(true, {
130
+ onStreamClosed: console.log,
131
+ onAudioResponseStart: () => console.log("Speaking..."),
132
+ onAudioResponseChunk: (chunk) => audioPlayer.enqueue(chunk),
133
+ onAudioResponseEnd: () => console.log("Done")
134
+ });
135
+ ```
136
+
137
+ Audio requirements:
138
+
139
+ ### Input:
140
+ * Format: PCM, 16k Hertz
141
+ * Encoding: Base64
142
+ * Transcription: handled server-side
143
+
144
+ Send audio:
145
+
146
+ ```Typescript
147
+ sendAudioChunk(base64PcmChunk);
148
+ commitAudio();
149
+ ```
150
+
151
+ commitAudio() is MANDATORY: server-side VAD (voice activation detection) is not provided.
152
+
153
+ ⚠️ Client should always implement audio-input noise detection and explicit commits:
154
+ * Current constellation version does not provide it server-side
155
+ * Avoids continuously streaming audio data which reduces network and token consumption
156
+ * Allows to provide a more responsive experience as VAD introduces a constant delay and is potentially less stable
157
+
158
+ ### Output:
159
+ Audio responses are:
160
+ * Format: PCM, 24k Hertz
161
+ * Encoding: Base64
162
+
163
+
164
+ ## Text and Transcript
165
+
166
+ Text is always enabled in a session. However, the client must provide the appropriate handlers to receive events:
167
+ ```Typescript
168
+ interface EventHandlers {
169
+ // ...
170
+ onTranscriptInput?: (transcript: string) => void;
171
+ onTranscriptResponse?: (transcript: string) => void;
172
+ }
173
+ ```
174
+ ⚠️ These events serve both the text exchanges AND transcript of audio exchanges:
175
+
176
+ ```Typescript
177
+ // Pseudo-code:
178
+
179
+ // Text:
180
+ constellationClient.sendText("Hello");
181
+
182
+ // Triggers:
183
+ // 1) onTranscriptInput(transcript) -> transcript is "Hello"
184
+ // 2) onTranscriptResponse(transcript) -> transcript is the response from the LLM
185
+
186
+ // Audio:
187
+ constellationClient.sendAudioChunk("... PCM16 audio data for 'Hello'...");
188
+ constellationClient.commitAudio();
189
+
190
+ // Triggers:
191
+ // 1) onTranscriptInput(transcript) -> transcript is "Hello"
192
+ // 2) onTranscriptResponse(transcript) -> transcript is the response from the LLM
193
+ ```
194
+
195
+ Partial text events are provided as well through ```onTranscriptInputPart``` and ```onTranscriptResponsePart``` events.
196
+ Partial text events are fired when a new piece of text is available, they allow for a more reactive/realtime, temporary display of
197
+ incoming text, but cannot be trusted to build the final message: always rely on the final "non-part" event as the final source of truth.
198
+
199
+ ## Session Configuration
200
+
201
+ System behavior can be updated dynamically, mid-session:
202
+
203
+ ```Typescript
204
+ configureSession({
205
+ temperature: 0.2,
206
+ instructions: "You are a helpful coding assistant.",
207
+ maxResponseToken: 500
208
+ });
209
+ ```
210
+
211
+ This does NOT trigger a response.
212
+
213
+ ## Event Handlers
214
+
215
+ The event handlers are client-provided hooks to receive all the server events discussed above
216
+ Provided at join session time.
217
+
218
+ joinSession() requires at least:
219
+
220
+ ```Typescript
221
+ {
222
+ onStreamClosed: (reason: string) => void
223
+ }
224
+ ```
225
+
226
+ Optional handlers:
227
+
228
+ * onSessionConfigured: acknowledgment of configureSession call
229
+ * onAudioResponseChunk: audio data chunk of a model audio response
230
+ * onAudioResponseEnd: model has finished streaming an audio response
231
+ * onResponseEnd: model has finished generating and streaming a response
232
+ * onTranscriptInput: the echo of a user text input or transcript of a user audio input
233
+ * onTranscriptInputPart: the echo of a user text input or a piece of transcript of a user audio input
234
+ * onTranscriptResponse: model text response or transcript of model audio response
235
+ * onTranscriptResponsePart: piece of model text response or transcript of model audio response
236
+ * onAgentResponse: in a session agents configured, this is the event carry an agent-feedback
237
+ * onClientAction: in a session with client action defined, this event is fired when a named action is called by the model
238
+ * onTechnicalError
239
+ * onLatencyUpdate: fired regularly with the last computed latency between the client and constellation
240
+
241
+ If omitted, events are ignored silently & safely.