@ai-chans/sdk-react 0.2.2 → 0.3.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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ChansState } from "@ai-chans/sdk-js";
2
- export type { ChansState } from "@ai-chans/sdk-js";
2
+ export type { ChansState, AgentInfo, SessionInfo } from "@ai-chans/sdk-js";
3
3
  export interface ChansVoiceProps {
4
4
  /**
5
5
  * Agent token from chans.ai dashboard
@@ -41,6 +41,22 @@ export interface ChansVoiceProps {
41
41
  * Called when disconnected
42
42
  */
43
43
  onDisconnected?: () => void;
44
+ /**
45
+ * Called when agent joins the room
46
+ */
47
+ onAgentConnected?: (agent: import("@ai-chans/sdk-js").AgentInfo) => void;
48
+ /**
49
+ * Called when agent leaves the room
50
+ */
51
+ onAgentDisconnected?: () => void;
52
+ /**
53
+ * Called when user finishes speaking (final transcript)
54
+ */
55
+ onUserTurnComplete?: (transcript: string) => void;
56
+ /**
57
+ * Called when session is created
58
+ */
59
+ onSessionCreated?: (session: import("@ai-chans/sdk-js").SessionInfo) => void;
44
60
  /**
45
61
  * Custom render function for the voice UI
46
62
  */
@@ -86,6 +102,6 @@ export declare function useChans(): ChansContextValue;
86
102
  * </ChansVoice>
87
103
  * ```
88
104
  */
89
- export declare function ChansVoice({ agentToken, userId, apiUrl, autoConnect, onTranscript, onResponse, onStateChange, onError, onConnected, onDisconnected, children, className, }: ChansVoiceProps): import("react/jsx-runtime").JSX.Element;
105
+ export declare function ChansVoice({ agentToken, userId, apiUrl, autoConnect, onTranscript, onResponse, onStateChange, onError, onConnected, onDisconnected, onAgentConnected, onAgentDisconnected, onUserTurnComplete, onSessionCreated, children, className, }: ChansVoiceProps): import("react/jsx-runtime").JSX.Element;
90
106
  export default ChansVoice;
91
107
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAe,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG1D,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAErC;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAEnC;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAE3C;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAEhC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IAExB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;IAE3B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,KAAK,CAAC,SAAS,CAAA;IAE5D;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,UAAU,CAAA;IACjB,WAAW,EAAE,OAAO,CAAA;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CACpB;AAGD,KAAK,iBAAiB,GAAG,qBAAqB,CAAA;AAI9C;;GAEG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,MAAM,EACN,MAAM,EACN,WAAkB,EAClB,YAAY,EACZ,UAAU,EACV,aAAa,EACb,OAAO,EACP,WAAW,EACX,cAAc,EACd,QAAQ,EACR,SAAS,GACV,EAAE,eAAe,2CA4GjB;AA8ID,eAAe,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAe,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAG1D,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE1E,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAErC;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAEnC;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAE3C;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAEhC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IAExB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;IAE3B;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,kBAAkB,EAAE,SAAS,KAAK,IAAI,CAAA;IAExE;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAA;IAEhC;;OAEG;IACH,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAA;IAEjD;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,kBAAkB,EAAE,WAAW,KAAK,IAAI,CAAA;IAE5E;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,KAAK,CAAC,SAAS,CAAA;IAE5D;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,UAAU,CAAA;IACjB,WAAW,EAAE,OAAO,CAAA;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CACpB;AAGD,KAAK,iBAAiB,GAAG,qBAAqB,CAAA;AAI9C;;GAEG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,MAAM,EACN,MAAM,EACN,WAAkB,EAClB,YAAY,EACZ,UAAU,EACV,aAAa,EACb,OAAO,EACP,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACR,SAAS,GACV,EAAE,eAAe,2CAgIjB;AA+ID,eAAe,UAAU,CAAA"}
package/dist/index.js CHANGED
@@ -37,7 +37,7 @@ export function useChans() {
37
37
  * </ChansVoice>
38
38
  * ```
39
39
  */
40
- export function ChansVoice({ agentToken, userId, apiUrl, autoConnect = true, onTranscript, onResponse, onStateChange, onError, onConnected, onDisconnected, children, className, }) {
40
+ export function ChansVoice({ agentToken, userId, apiUrl, autoConnect = true, onTranscript, onResponse, onStateChange, onError, onConnected, onDisconnected, onAgentConnected, onAgentDisconnected, onUserTurnComplete, onSessionCreated, children, className, }) {
41
41
  const [state, setState] = useState("idle");
42
42
  const [error, setError] = useState(null);
43
43
  const clientRef = useRef(null);
@@ -67,6 +67,18 @@ export function ChansVoice({ agentToken, userId, apiUrl, autoConnect = true, onT
67
67
  const unsubDisconnected = client.on("disconnected", () => {
68
68
  onDisconnected?.();
69
69
  });
70
+ const unsubAgentConnected = client.on("agentConnected", (agent) => {
71
+ onAgentConnected?.(agent);
72
+ });
73
+ const unsubAgentDisconnected = client.on("agentDisconnected", () => {
74
+ onAgentDisconnected?.();
75
+ });
76
+ const unsubUserTurnComplete = client.on("userTurnComplete", (transcript) => {
77
+ onUserTurnComplete?.(transcript);
78
+ });
79
+ const unsubSessionCreated = client.on("sessionCreated", (session) => {
80
+ onSessionCreated?.(session);
81
+ });
70
82
  return () => {
71
83
  unsubState();
72
84
  unsubTranscript();
@@ -74,9 +86,13 @@ export function ChansVoice({ agentToken, userId, apiUrl, autoConnect = true, onT
74
86
  unsubError();
75
87
  unsubConnected();
76
88
  unsubDisconnected();
89
+ unsubAgentConnected();
90
+ unsubAgentDisconnected();
91
+ unsubUserTurnComplete();
92
+ unsubSessionCreated();
77
93
  client.disconnect();
78
94
  };
79
- }, [agentToken, apiUrl, onStateChange, onTranscript, onResponse, onError, onConnected, onDisconnected]);
95
+ }, [agentToken, apiUrl, onStateChange, onTranscript, onResponse, onError, onConnected, onDisconnected, onAgentConnected, onAgentDisconnected, onUserTurnComplete, onSessionCreated]);
80
96
  // Auto-connect
81
97
  useEffect(() => {
82
98
  if (autoConnect && clientRef.current && state === "idle") {
@@ -149,7 +165,7 @@ function DefaultVoiceUI({ state, isConnected, connect, disconnect, error, }) {
149
165
  marginTop: "0.5rem",
150
166
  fontSize: "0.75rem",
151
167
  color: "#9ca3af",
152
- }, children: [state === "idle" && "Click to start", state === "connecting" && "Connecting...", state === "connected" && "Connected", state === "listening" && "Listening...", state === "speaking" && "Agent speaking", state === "error" && "Error"] })] }));
168
+ }, children: [state === "idle" && "Click to start", state === "connecting" && "Connecting...", state === "waiting" && "Waiting for agent...", state === "ready" && "Listening...", state === "processing" && "Processing...", state === "speaking" && "Agent speaking", state === "error" && "Error"] })] }));
153
169
  }
154
170
  function MicIcon() {
155
171
  return (_jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" }), _jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }), _jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }), _jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })] }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-chans/sdk-react",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -416,11 +416,11 @@ describe("ChansVoice", () => {
416
416
  expect(screen.getByText("Connecting...")).toBeInTheDocument()
417
417
  })
418
418
 
419
- it("should show 'Listening...' in listening state", () => {
419
+ it("should show 'Listening...' in ready state", () => {
420
420
  render(<ChansVoice agentToken="agt_test" autoConnect={false} />)
421
421
 
422
422
  act(() => {
423
- mockClient._emit("stateChange", "listening")
423
+ mockClient._emit("stateChange", "ready")
424
424
  })
425
425
 
426
426
  expect(screen.getByText("Listening...")).toBeInTheDocument()
package/src/index.tsx CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  import { ChansClient, ChansState } from "@ai-chans/sdk-js"
13
13
 
14
14
  // Re-export client types
15
- export type { ChansState } from "@ai-chans/sdk-js"
15
+ export type { ChansState, AgentInfo, SessionInfo } from "@ai-chans/sdk-js"
16
16
 
17
17
  export interface ChansVoiceProps {
18
18
  /**
@@ -65,6 +65,26 @@ export interface ChansVoiceProps {
65
65
  */
66
66
  onDisconnected?: () => void
67
67
 
68
+ /**
69
+ * Called when agent joins the room
70
+ */
71
+ onAgentConnected?: (agent: import("@ai-chans/sdk-js").AgentInfo) => void
72
+
73
+ /**
74
+ * Called when agent leaves the room
75
+ */
76
+ onAgentDisconnected?: () => void
77
+
78
+ /**
79
+ * Called when user finishes speaking (final transcript)
80
+ */
81
+ onUserTurnComplete?: (transcript: string) => void
82
+
83
+ /**
84
+ * Called when session is created
85
+ */
86
+ onSessionCreated?: (session: import("@ai-chans/sdk-js").SessionInfo) => void
87
+
68
88
  /**
69
89
  * Custom render function for the voice UI
70
90
  */
@@ -135,6 +155,10 @@ export function ChansVoice({
135
155
  onError,
136
156
  onConnected,
137
157
  onDisconnected,
158
+ onAgentConnected,
159
+ onAgentDisconnected,
160
+ onUserTurnComplete,
161
+ onSessionCreated,
138
162
  children,
139
163
  className,
140
164
  }: ChansVoiceProps) {
@@ -176,6 +200,22 @@ export function ChansVoice({
176
200
  onDisconnected?.()
177
201
  })
178
202
 
203
+ const unsubAgentConnected = client.on("agentConnected", (agent) => {
204
+ onAgentConnected?.(agent)
205
+ })
206
+
207
+ const unsubAgentDisconnected = client.on("agentDisconnected", () => {
208
+ onAgentDisconnected?.()
209
+ })
210
+
211
+ const unsubUserTurnComplete = client.on("userTurnComplete", (transcript) => {
212
+ onUserTurnComplete?.(transcript)
213
+ })
214
+
215
+ const unsubSessionCreated = client.on("sessionCreated", (session) => {
216
+ onSessionCreated?.(session)
217
+ })
218
+
179
219
  return () => {
180
220
  unsubState()
181
221
  unsubTranscript()
@@ -183,9 +223,13 @@ export function ChansVoice({
183
223
  unsubError()
184
224
  unsubConnected()
185
225
  unsubDisconnected()
226
+ unsubAgentConnected()
227
+ unsubAgentDisconnected()
228
+ unsubUserTurnComplete()
229
+ unsubSessionCreated()
186
230
  client.disconnect()
187
231
  }
188
- }, [agentToken, apiUrl, onStateChange, onTranscript, onResponse, onError, onConnected, onDisconnected])
232
+ }, [agentToken, apiUrl, onStateChange, onTranscript, onResponse, onError, onConnected, onDisconnected, onAgentConnected, onAgentDisconnected, onUserTurnComplete, onSessionCreated])
189
233
 
190
234
  // Auto-connect
191
235
  useEffect(() => {
@@ -322,8 +366,9 @@ function DefaultVoiceUI({
322
366
  >
323
367
  {state === "idle" && "Click to start"}
324
368
  {state === "connecting" && "Connecting..."}
325
- {state === "connected" && "Connected"}
326
- {state === "listening" && "Listening..."}
369
+ {state === "waiting" && "Waiting for agent..."}
370
+ {state === "ready" && "Listening..."}
371
+ {state === "processing" && "Processing..."}
327
372
  {state === "speaking" && "Agent speaking"}
328
373
  {state === "error" && "Error"}
329
374
  </div>