@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 +241 -0
- package/dist/index.cjs +919 -0
- package/dist/index.d.cts +261 -0
- package/dist/index.d.ts +261 -0
- package/dist/index.js +880 -0
- package/package.json +38 -0
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.
|