@octavus/react 0.0.9 → 0.0.10
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 +65 -2
- package/dist/index.js +31 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OctavusChatOptions, UIMessage, ChatStatus, UserMessageInput } from '@octavus/client-sdk';
|
|
1
|
+
import { OctavusChatOptions, UIMessage, ChatStatus, ConnectionState, UserMessageInput } from '@octavus/client-sdk';
|
|
2
2
|
export * from '@octavus/client-sdk';
|
|
3
3
|
export { ChatStatus, OctavusChatOptions, UserMessageInput } from '@octavus/client-sdk';
|
|
4
4
|
|
|
@@ -9,6 +9,20 @@ interface UseOctavusChatReturn {
|
|
|
9
9
|
status: ChatStatus;
|
|
10
10
|
/** Error if status is 'error' */
|
|
11
11
|
error: Error | null;
|
|
12
|
+
/**
|
|
13
|
+
* Socket connection state (socket transport only).
|
|
14
|
+
* For HTTP transport, this is always `undefined`.
|
|
15
|
+
*
|
|
16
|
+
* - `disconnected`: Not connected (initial state before first send)
|
|
17
|
+
* - `connecting`: Connection attempt in progress
|
|
18
|
+
* - `connected`: Successfully connected
|
|
19
|
+
* - `error`: Connection failed (check `connectionError`)
|
|
20
|
+
*/
|
|
21
|
+
connectionState: ConnectionState | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Connection error if `connectionState` is 'error'.
|
|
24
|
+
*/
|
|
25
|
+
connectionError: Error | undefined;
|
|
12
26
|
/**
|
|
13
27
|
* Trigger the agent and optionally add a user message to the chat.
|
|
14
28
|
*
|
|
@@ -21,6 +35,21 @@ interface UseOctavusChatReturn {
|
|
|
21
35
|
}) => Promise<void>;
|
|
22
36
|
/** Stop the current streaming and finalize any partial message */
|
|
23
37
|
stop: () => void;
|
|
38
|
+
/**
|
|
39
|
+
* Eagerly connect to the socket (socket transport only).
|
|
40
|
+
* Returns a promise that resolves when connected or rejects on error.
|
|
41
|
+
* Safe to call multiple times - subsequent calls resolve immediately if already connected.
|
|
42
|
+
*
|
|
43
|
+
* For HTTP transport, this is `undefined`.
|
|
44
|
+
*/
|
|
45
|
+
connect: (() => Promise<void>) | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Disconnect the socket (socket transport only).
|
|
48
|
+
* The transport will reconnect automatically on next send().
|
|
49
|
+
*
|
|
50
|
+
* For HTTP transport, this is `undefined`.
|
|
51
|
+
*/
|
|
52
|
+
disconnect: (() => void) | undefined;
|
|
24
53
|
}
|
|
25
54
|
/**
|
|
26
55
|
* React hook for interacting with Octavus agents.
|
|
@@ -30,7 +59,7 @@ interface UseOctavusChatReturn {
|
|
|
30
59
|
* reinitializes with a fresh chat instance. Use `initialMessages` if you need
|
|
31
60
|
* to preserve messages across transport changes.
|
|
32
61
|
*
|
|
33
|
-
* @example
|
|
62
|
+
* @example Basic usage with HTTP transport
|
|
34
63
|
* ```tsx
|
|
35
64
|
* import { useOctavusChat, createHttpTransport } from '@octavus/react';
|
|
36
65
|
*
|
|
@@ -61,6 +90,40 @@ interface UseOctavusChatReturn {
|
|
|
61
90
|
* );
|
|
62
91
|
* }
|
|
63
92
|
* ```
|
|
93
|
+
*
|
|
94
|
+
* @example Socket transport with eager connection
|
|
95
|
+
* ```tsx
|
|
96
|
+
* import { useOctavusChat, createSocketTransport } from '@octavus/react';
|
|
97
|
+
*
|
|
98
|
+
* function Chat() {
|
|
99
|
+
* const transport = useMemo(
|
|
100
|
+
* () => createSocketTransport({
|
|
101
|
+
* connect: () => new Promise((resolve, reject) => {
|
|
102
|
+
* const sock = new SockJS('/octavus');
|
|
103
|
+
* sock.onopen = () => resolve(sock);
|
|
104
|
+
* sock.onerror = () => reject(new Error('Connection failed'));
|
|
105
|
+
* }),
|
|
106
|
+
* }),
|
|
107
|
+
* [],
|
|
108
|
+
* );
|
|
109
|
+
*
|
|
110
|
+
* const { messages, status, send, connectionState, connect, disconnect } =
|
|
111
|
+
* useOctavusChat({ transport });
|
|
112
|
+
*
|
|
113
|
+
* // Eager connection on mount
|
|
114
|
+
* useEffect(() => {
|
|
115
|
+
* connect?.();
|
|
116
|
+
* return () => disconnect?.();
|
|
117
|
+
* }, [connect, disconnect]);
|
|
118
|
+
*
|
|
119
|
+
* return (
|
|
120
|
+
* <div>
|
|
121
|
+
* <StatusIndicator state={connectionState} />
|
|
122
|
+
* {messages.map((msg) => <Message key={msg.id} message={msg} />)}
|
|
123
|
+
* </div>
|
|
124
|
+
* );
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
64
127
|
*/
|
|
65
128
|
declare function useOctavusChat(options: OctavusChatOptions): UseOctavusChatReturn;
|
|
66
129
|
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// src/hooks/use-octavus-chat.ts
|
|
2
|
-
import { useRef, useCallback, useSyncExternalStore } from "react";
|
|
2
|
+
import { useRef, useCallback, useSyncExternalStore, useState, useEffect } from "react";
|
|
3
3
|
import {
|
|
4
|
-
OctavusChat
|
|
4
|
+
OctavusChat,
|
|
5
|
+
isSocketTransport
|
|
5
6
|
} from "@octavus/client-sdk";
|
|
6
7
|
function useOctavusChat(options) {
|
|
7
8
|
const chatRef = useRef(null);
|
|
@@ -12,6 +13,7 @@ function useOctavusChat(options) {
|
|
|
12
13
|
transportRef.current = options.transport;
|
|
13
14
|
}
|
|
14
15
|
const chat = chatRef.current;
|
|
16
|
+
const transport = options.transport;
|
|
15
17
|
const subscribe = useCallback((callback) => chat.subscribe(callback), [chat]);
|
|
16
18
|
const getMessagesSnapshot = useCallback(() => chat.messages, [chat]);
|
|
17
19
|
const getStatusSnapshot = useCallback(() => chat.status, [chat]);
|
|
@@ -19,17 +21,43 @@ function useOctavusChat(options) {
|
|
|
19
21
|
const messages = useSyncExternalStore(subscribe, getMessagesSnapshot, getMessagesSnapshot);
|
|
20
22
|
const status = useSyncExternalStore(subscribe, getStatusSnapshot, getStatusSnapshot);
|
|
21
23
|
const error = useSyncExternalStore(subscribe, getErrorSnapshot, getErrorSnapshot);
|
|
24
|
+
const socketTransport = isSocketTransport(transport) ? transport : null;
|
|
25
|
+
const [connectionState, setConnectionState] = useState(
|
|
26
|
+
socketTransport?.connectionState
|
|
27
|
+
);
|
|
28
|
+
const [connectionError, setConnectionError] = useState(void 0);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!socketTransport) {
|
|
31
|
+
setConnectionState(void 0);
|
|
32
|
+
setConnectionError(void 0);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const unsubscribe = socketTransport.onConnectionStateChange((state, err) => {
|
|
36
|
+
setConnectionState(state);
|
|
37
|
+
setConnectionError(err);
|
|
38
|
+
});
|
|
39
|
+
return unsubscribe;
|
|
40
|
+
}, [socketTransport]);
|
|
22
41
|
const send = useCallback(
|
|
23
42
|
(triggerName, input, sendOptions) => chat.send(triggerName, input, sendOptions),
|
|
24
43
|
[chat]
|
|
25
44
|
);
|
|
26
45
|
const stop = useCallback(() => chat.stop(), [chat]);
|
|
46
|
+
const connect = useCallback(
|
|
47
|
+
() => socketTransport?.connect() ?? Promise.resolve(),
|
|
48
|
+
[socketTransport]
|
|
49
|
+
);
|
|
50
|
+
const disconnect = useCallback(() => socketTransport?.disconnect(), [socketTransport]);
|
|
27
51
|
return {
|
|
28
52
|
messages,
|
|
29
53
|
status,
|
|
30
54
|
error,
|
|
55
|
+
connectionState,
|
|
56
|
+
connectionError,
|
|
31
57
|
send,
|
|
32
|
-
stop
|
|
58
|
+
stop,
|
|
59
|
+
connect: socketTransport ? connect : void 0,
|
|
60
|
+
disconnect: socketTransport ? disconnect : void 0
|
|
33
61
|
};
|
|
34
62
|
}
|
|
35
63
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-octavus-chat.ts","../src/index.ts"],"sourcesContent":["'use client';\n\nimport { useRef, useCallback, useSyncExternalStore } from 'react';\nimport {\n OctavusChat,\n type OctavusChatOptions,\n type ChatStatus,\n type UserMessageInput,\n type UIMessage,\n type Transport,\n} from '@octavus/client-sdk';\n\nexport type { OctavusChatOptions, ChatStatus, UserMessageInput };\n\nexport interface UseOctavusChatReturn {\n /** All messages including the currently streaming one */\n messages: UIMessage[];\n /** Current status of the chat */\n status: ChatStatus;\n /** Error if status is 'error' */\n error: Error | null;\n /**\n * Trigger the agent and optionally add a user message to the chat.\n *\n * @param triggerName - The trigger name defined in the agent's protocol.yaml\n * @param input - Input parameters for the trigger (variable substitutions)\n * @param options.userMessage - If provided, adds a user message to the chat before triggering\n */\n send: (\n triggerName: string,\n input?: Record<string, unknown>,\n options?: { userMessage?: UserMessageInput },\n ) => Promise<void>;\n /** Stop the current streaming and finalize any partial message */\n stop: () => void;\n}\n\n/**\n * React hook for interacting with Octavus agents.\n * Provides chat state management and streaming support.\n *\n * When the transport changes (e.g., sessionId changes), the hook automatically\n * reinitializes with a fresh chat instance. Use `initialMessages` if you need\n * to preserve messages across transport changes.\n *\n * @example\n * ```tsx\n * import { useOctavusChat, createHttpTransport } from '@octavus/react';\n *\n * function Chat({ sessionId }) {\n * const transport = useMemo(\n * () => createHttpTransport({\n * triggerRequest: (triggerName, input) =>\n * fetch('/api/trigger', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ sessionId, triggerName, input }),\n * }),\n * }),\n * [sessionId],\n * );\n *\n * const { messages, status, send } = useOctavusChat({ transport });\n *\n * return (\n * <div>\n * {messages.map((msg) => (\n * <Message key={msg.id} message={msg} />\n * ))}\n * <button onClick={() => send('user-message', { USER_MESSAGE: 'Hello' })}>\n * Send\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useOctavusChat(options: OctavusChatOptions): UseOctavusChatReturn {\n const chatRef = useRef<OctavusChat | null>(null);\n const transportRef = useRef<Transport | null>(null);\n\n if (transportRef.current !== options.transport) {\n chatRef.current?.stop();\n chatRef.current = new OctavusChat(options);\n transportRef.current = options.transport;\n }\n\n const chat = chatRef.current!;\n
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-octavus-chat.ts","../src/index.ts"],"sourcesContent":["'use client';\n\nimport { useRef, useCallback, useSyncExternalStore, useState, useEffect } from 'react';\nimport {\n OctavusChat,\n isSocketTransport,\n type OctavusChatOptions,\n type ChatStatus,\n type UserMessageInput,\n type UIMessage,\n type Transport,\n type ConnectionState,\n} from '@octavus/client-sdk';\n\nexport type { OctavusChatOptions, ChatStatus, UserMessageInput };\n\nexport interface UseOctavusChatReturn {\n /** All messages including the currently streaming one */\n messages: UIMessage[];\n /** Current status of the chat */\n status: ChatStatus;\n /** Error if status is 'error' */\n error: Error | null;\n /**\n * Socket connection state (socket transport only).\n * For HTTP transport, this is always `undefined`.\n *\n * - `disconnected`: Not connected (initial state before first send)\n * - `connecting`: Connection attempt in progress\n * - `connected`: Successfully connected\n * - `error`: Connection failed (check `connectionError`)\n */\n connectionState: ConnectionState | undefined;\n /**\n * Connection error if `connectionState` is 'error'.\n */\n connectionError: Error | undefined;\n /**\n * Trigger the agent and optionally add a user message to the chat.\n *\n * @param triggerName - The trigger name defined in the agent's protocol.yaml\n * @param input - Input parameters for the trigger (variable substitutions)\n * @param options.userMessage - If provided, adds a user message to the chat before triggering\n */\n send: (\n triggerName: string,\n input?: Record<string, unknown>,\n options?: { userMessage?: UserMessageInput },\n ) => Promise<void>;\n /** Stop the current streaming and finalize any partial message */\n stop: () => void;\n /**\n * Eagerly connect to the socket (socket transport only).\n * Returns a promise that resolves when connected or rejects on error.\n * Safe to call multiple times - subsequent calls resolve immediately if already connected.\n *\n * For HTTP transport, this is `undefined`.\n */\n connect: (() => Promise<void>) | undefined;\n /**\n * Disconnect the socket (socket transport only).\n * The transport will reconnect automatically on next send().\n *\n * For HTTP transport, this is `undefined`.\n */\n disconnect: (() => void) | undefined;\n}\n\n/**\n * React hook for interacting with Octavus agents.\n * Provides chat state management and streaming support.\n *\n * When the transport changes (e.g., sessionId changes), the hook automatically\n * reinitializes with a fresh chat instance. Use `initialMessages` if you need\n * to preserve messages across transport changes.\n *\n * @example Basic usage with HTTP transport\n * ```tsx\n * import { useOctavusChat, createHttpTransport } from '@octavus/react';\n *\n * function Chat({ sessionId }) {\n * const transport = useMemo(\n * () => createHttpTransport({\n * triggerRequest: (triggerName, input) =>\n * fetch('/api/trigger', {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ sessionId, triggerName, input }),\n * }),\n * }),\n * [sessionId],\n * );\n *\n * const { messages, status, send } = useOctavusChat({ transport });\n *\n * return (\n * <div>\n * {messages.map((msg) => (\n * <Message key={msg.id} message={msg} />\n * ))}\n * <button onClick={() => send('user-message', { USER_MESSAGE: 'Hello' })}>\n * Send\n * </button>\n * </div>\n * );\n * }\n * ```\n *\n * @example Socket transport with eager connection\n * ```tsx\n * import { useOctavusChat, createSocketTransport } from '@octavus/react';\n *\n * function Chat() {\n * const transport = useMemo(\n * () => createSocketTransport({\n * connect: () => new Promise((resolve, reject) => {\n * const sock = new SockJS('/octavus');\n * sock.onopen = () => resolve(sock);\n * sock.onerror = () => reject(new Error('Connection failed'));\n * }),\n * }),\n * [],\n * );\n *\n * const { messages, status, send, connectionState, connect, disconnect } =\n * useOctavusChat({ transport });\n *\n * // Eager connection on mount\n * useEffect(() => {\n * connect?.();\n * return () => disconnect?.();\n * }, [connect, disconnect]);\n *\n * return (\n * <div>\n * <StatusIndicator state={connectionState} />\n * {messages.map((msg) => <Message key={msg.id} message={msg} />)}\n * </div>\n * );\n * }\n * ```\n */\nexport function useOctavusChat(options: OctavusChatOptions): UseOctavusChatReturn {\n const chatRef = useRef<OctavusChat | null>(null);\n const transportRef = useRef<Transport | null>(null);\n\n if (transportRef.current !== options.transport) {\n chatRef.current?.stop();\n chatRef.current = new OctavusChat(options);\n transportRef.current = options.transport;\n }\n\n const chat = chatRef.current!;\n const transport = options.transport;\n\n const subscribe = useCallback((callback: () => void) => chat.subscribe(callback), [chat]);\n const getMessagesSnapshot = useCallback(() => chat.messages, [chat]);\n const getStatusSnapshot = useCallback(() => chat.status, [chat]);\n const getErrorSnapshot = useCallback(() => chat.error, [chat]);\n\n const messages = useSyncExternalStore(subscribe, getMessagesSnapshot, getMessagesSnapshot);\n const status = useSyncExternalStore(subscribe, getStatusSnapshot, getStatusSnapshot);\n const error = useSyncExternalStore(subscribe, getErrorSnapshot, getErrorSnapshot);\n\n const socketTransport = isSocketTransport(transport) ? transport : null;\n const [connectionState, setConnectionState] = useState<ConnectionState | undefined>(\n socketTransport?.connectionState,\n );\n const [connectionError, setConnectionError] = useState<Error | undefined>(undefined);\n\n useEffect(() => {\n if (!socketTransport) {\n setConnectionState(undefined);\n setConnectionError(undefined);\n return;\n }\n\n const unsubscribe = socketTransport.onConnectionStateChange((state, err) => {\n setConnectionState(state);\n setConnectionError(err);\n });\n\n return unsubscribe;\n }, [socketTransport]);\n\n const send = useCallback(\n (\n triggerName: string,\n input?: Record<string, unknown>,\n sendOptions?: { userMessage?: UserMessageInput },\n ) => chat.send(triggerName, input, sendOptions),\n [chat],\n );\n\n const stop = useCallback(() => chat.stop(), [chat]);\n\n // Stable references for connect/disconnect (socket transport only)\n const connect = useCallback(\n () => socketTransport?.connect() ?? Promise.resolve(),\n [socketTransport],\n );\n const disconnect = useCallback(() => socketTransport?.disconnect(), [socketTransport]);\n\n return {\n messages,\n status,\n error,\n connectionState,\n connectionError,\n send,\n stop,\n connect: socketTransport ? connect : undefined,\n disconnect: socketTransport ? disconnect : undefined,\n };\n}\n","export {\n useOctavusChat,\n type UseOctavusChatReturn,\n type OctavusChatOptions,\n type ChatStatus,\n type UserMessageInput,\n} from './hooks/use-octavus-chat';\n\n// Re-export everything from client-sdk so consumers only need @octavus/react\nexport * from '@octavus/client-sdk';\n"],"mappings":";AAEA,SAAS,QAAQ,aAAa,sBAAsB,UAAU,iBAAiB;AAC/E;AAAA,EACE;AAAA,EACA;AAAA,OAOK;AAkIA,SAAS,eAAe,SAAmD;AAChF,QAAM,UAAU,OAA2B,IAAI;AAC/C,QAAM,eAAe,OAAyB,IAAI;AAElD,MAAI,aAAa,YAAY,QAAQ,WAAW;AAC9C,YAAQ,SAAS,KAAK;AACtB,YAAQ,UAAU,IAAI,YAAY,OAAO;AACzC,iBAAa,UAAU,QAAQ;AAAA,EACjC;AAEA,QAAM,OAAO,QAAQ;AACrB,QAAM,YAAY,QAAQ;AAE1B,QAAM,YAAY,YAAY,CAAC,aAAyB,KAAK,UAAU,QAAQ,GAAG,CAAC,IAAI,CAAC;AACxF,QAAM,sBAAsB,YAAY,MAAM,KAAK,UAAU,CAAC,IAAI,CAAC;AACnE,QAAM,oBAAoB,YAAY,MAAM,KAAK,QAAQ,CAAC,IAAI,CAAC;AAC/D,QAAM,mBAAmB,YAAY,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;AAE7D,QAAM,WAAW,qBAAqB,WAAW,qBAAqB,mBAAmB;AACzF,QAAM,SAAS,qBAAqB,WAAW,mBAAmB,iBAAiB;AACnF,QAAM,QAAQ,qBAAqB,WAAW,kBAAkB,gBAAgB;AAEhF,QAAM,kBAAkB,kBAAkB,SAAS,IAAI,YAAY;AACnE,QAAM,CAAC,iBAAiB,kBAAkB,IAAI;AAAA,IAC5C,iBAAiB;AAAA,EACnB;AACA,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAA4B,MAAS;AAEnF,YAAU,MAAM;AACd,QAAI,CAAC,iBAAiB;AACpB,yBAAmB,MAAS;AAC5B,yBAAmB,MAAS;AAC5B;AAAA,IACF;AAEA,UAAM,cAAc,gBAAgB,wBAAwB,CAAC,OAAO,QAAQ;AAC1E,yBAAmB,KAAK;AACxB,yBAAmB,GAAG;AAAA,IACxB,CAAC;AAED,WAAO;AAAA,EACT,GAAG,CAAC,eAAe,CAAC;AAEpB,QAAM,OAAO;AAAA,IACX,CACE,aACA,OACA,gBACG,KAAK,KAAK,aAAa,OAAO,WAAW;AAAA,IAC9C,CAAC,IAAI;AAAA,EACP;AAEA,QAAM,OAAO,YAAY,MAAM,KAAK,KAAK,GAAG,CAAC,IAAI,CAAC;AAGlD,QAAM,UAAU;AAAA,IACd,MAAM,iBAAiB,QAAQ,KAAK,QAAQ,QAAQ;AAAA,IACpD,CAAC,eAAe;AAAA,EAClB;AACA,QAAM,aAAa,YAAY,MAAM,iBAAiB,WAAW,GAAG,CAAC,eAAe,CAAC;AAErF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,kBAAkB,UAAU;AAAA,IACrC,YAAY,kBAAkB,aAAa;AAAA,EAC7C;AACF;;;AC7MA,cAAc;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octavus/react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "React bindings for Octavus agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Octavus AI <dev@octavus.ai>",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@octavus/client-sdk": "^0.0.
|
|
32
|
+
"@octavus/client-sdk": "^0.0.10"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": ">=18.0.0"
|