@arbidocs/react 0.3.16 → 0.3.18

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 CHANGED
@@ -1,16 +1,14 @@
1
1
  # @arbidocs/react
2
2
 
3
- React hooks and provider for the ARBI SDK. Built on `@arbidocs/sdk` and `@tanstack/react-query`.
3
+ React hooks and provider for building ARBI-powered apps. Includes `@arbidocs/sdk` and `@tanstack/react-query` — one install gets you everything.
4
4
 
5
- ## Install
5
+ ## Quickstart
6
6
 
7
7
  ```bash
8
8
  npm install @arbidocs/react
9
9
  ```
10
10
 
11
- ## Quick Start
12
-
13
- Wrap your app with `ArbiProvider` and a React Query `QueryClientProvider`:
11
+ ### 1. Set up providers
14
12
 
15
13
  ```tsx
16
14
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
@@ -21,142 +19,108 @@ const queryClient = new QueryClient()
21
19
  function App() {
22
20
  return (
23
21
  <QueryClientProvider client={queryClient}>
24
- <ArbiProvider url="https://arbi.mycompany.com">
25
- <MyApp />
22
+ <ArbiProvider url="https://www.arbidocs.com">
23
+ <Chat />
26
24
  </ArbiProvider>
27
25
  </QueryClientProvider>
28
26
  )
29
27
  }
30
28
  ```
31
29
 
32
- Then use the hooks in any component:
30
+ ### 2. Build a streaming chat
33
31
 
34
32
  ```tsx
35
- import { useArbi, useWorkspaces, useDocuments } from '@arbidocs/react'
33
+ import { useState, useRef } from 'react'
34
+ import { useArbi, useDocuments, useAssistantQuery } from '@arbidocs/react'
36
35
 
37
- function WorkspaceView() {
36
+ function Chat() {
38
37
  const arbi = useArbi()
39
- const { data: workspaces, isLoading } = useWorkspaces()
38
+ const [workspaceId, setWorkspaceId] = useState<string>()
39
+
40
+ if (!workspaceId) {
41
+ return (
42
+ <button onClick={async () => {
43
+ await arbi.login('user@example.com', 'password')
44
+ const ws = await arbi.workspaces.list()
45
+ await arbi.selectWorkspace(ws[0].external_id)
46
+ setWorkspaceId(ws[0].external_id)
47
+ }}>
48
+ Connect
49
+ </button>
50
+ )
51
+ }
52
+
53
+ return <ChatWindow workspaceId={workspaceId} />
54
+ }
40
55
 
41
- if (isLoading) return <div>Loading...</div>
56
+ function ChatWindow({ workspaceId }: { workspaceId: string }) {
57
+ const { data: docs } = useDocuments(workspaceId)
58
+ const mutation = useAssistantQuery()
59
+ const [input, setInput] = useState('')
60
+ const [response, setResponse] = useState('')
61
+ const lastId = useRef<string | null>(null)
42
62
 
43
63
  return (
44
- <ul>
45
- {workspaces?.map((ws) => (
46
- <li key={ws.external_id}>{ws.name}</li>
47
- ))}
48
- </ul>
64
+ <div>
65
+ <div>{response}</div>
66
+ <form onSubmit={(e) => {
67
+ e.preventDefault()
68
+ setResponse('')
69
+ mutation.mutate({
70
+ question: input,
71
+ docIds: docs?.map((d) => d.external_id) ?? [],
72
+ previousResponseId: lastId.current,
73
+ onToken: (t) => setResponse((r) => r + t),
74
+ onStreamStart: ({ assistant_message_ext_id }) => {
75
+ lastId.current = assistant_message_ext_id
76
+ },
77
+ })
78
+ setInput('')
79
+ }}>
80
+ <input value={input} onChange={(e) => setInput(e.target.value)} />
81
+ <button type="submit" disabled={mutation.isPending}>Send</button>
82
+ </form>
83
+ </div>
49
84
  )
50
85
  }
51
86
  ```
52
87
 
53
- ## Hooks
54
-
55
- ### `useArbi()`
56
-
57
- Returns the `Arbi` instance from context. Use this for imperative operations like login, workspace selection, and direct API calls.
58
-
59
- ```tsx
60
- const arbi = useArbi()
61
-
62
- await arbi.login('user@example.com', 'password')
63
- await arbi.selectWorkspace('wrk-123')
64
- ```
65
-
66
- ### `useWorkspaces(options?)`
67
-
68
- Fetches the user's workspaces. Automatically enabled when logged in.
69
-
70
- ```tsx
71
- const { data, isLoading, error } = useWorkspaces()
72
- const { data } = useWorkspaces({ enabled: false }) // manual control
73
- ```
74
-
75
- ### `useDocuments(workspaceId, options?)`
76
-
77
- Fetches documents for a workspace. Automatically disabled when `workspaceId` is undefined.
78
-
79
- ```tsx
80
- const { data: docs } = useDocuments('wrk-123')
81
- const { data: docs } = useDocuments(undefined) // won't fetch
82
- ```
83
-
84
- ### `useConversations(workspaceId, options?)`
85
-
86
- Fetches conversations for a workspace.
87
-
88
- ```tsx
89
- const { data: conversations } = useConversations('wrk-123')
90
- ```
91
-
92
- ### `useTags(workspaceId, options?)`
93
-
94
- Fetches tags for a workspace.
88
+ That's it — three hooks and you have a streaming RAG chat.
95
89
 
96
- ```tsx
97
- const { data: tags } = useTags('wrk-123')
98
- ```
90
+ ## Hooks
99
91
 
100
- ### `useHealth(options?)`
92
+ | Hook | Returns | Auto-enabled when |
93
+ |------|---------|-------------------|
94
+ | `useArbi()` | `Arbi` instance | Always |
95
+ | `useWorkspaces()` | User's workspaces | Logged in |
96
+ | `useDocuments(workspaceId)` | Workspace documents | Workspace selected |
97
+ | `useConversations(workspaceId)` | Workspace conversations | Workspace selected |
98
+ | `useTags(workspaceId)` | Workspace tags | Workspace selected |
99
+ | `useAssistantQuery()` | Streaming mutation | Call `.mutate()` |
100
+ | `useHealth()` | Backend status | Pass `{ enabled: true }` |
101
101
 
102
- Checks backend health.
102
+ ## Streaming callbacks
103
103
 
104
- ```tsx
105
- const { data } = useHealth({ enabled: true })
106
- // { status: 'ok' }
107
- ```
104
+ Pass these to `mutation.mutate()` alongside `question` and `docIds`:
108
105
 
109
- ### `useAssistantQuery()`
106
+ | Callback | Description |
107
+ |----------|-------------|
108
+ | `onToken(token)` | Each text chunk as it streams |
109
+ | `onStreamStart({ assistant_message_ext_id })` | Stream started — save the ID for follow-up queries |
110
+ | `onAgentStep(step)` | Agent tool usage (searching, reading, etc.) |
111
+ | `onError(message)` | Error during streaming |
112
+ | `onComplete()` | Stream finished |
110
113
 
111
- Returns a React Query mutation for streaming AI queries.
112
-
113
- ```tsx
114
- const mutation = useAssistantQuery()
115
-
116
- const handleAsk = () => {
117
- mutation.mutate({
118
- question: 'What does section 3 say?',
119
- docIds: ['doc-123'],
120
- onToken: (token) => setResponse((prev) => prev + token),
121
- onComplete: () => console.log('Done'),
122
- })
123
- }
124
- ```
125
-
126
- ## Query Keys
127
-
128
- All hooks use the `arbiQueryKeys` factory for cache management:
114
+ ## Cache invalidation
129
115
 
130
116
  ```tsx
131
117
  import { arbiQueryKeys } from '@arbidocs/react'
132
118
  import { useQueryClient } from '@tanstack/react-query'
133
119
 
134
120
  const queryClient = useQueryClient()
135
-
136
- // Invalidate all documents
137
- queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents('wrk-123') })
138
-
139
- // Available keys:
140
- arbiQueryKeys.workspaces() // ['arbi', 'workspaces']
141
- arbiQueryKeys.documents(workspaceId) // ['arbi', 'documents', workspaceId]
142
- arbiQueryKeys.conversations(workspaceId)
143
- arbiQueryKeys.tags(workspaceId)
144
- arbiQueryKeys.health()
121
+ queryClient.invalidateQueries({ queryKey: arbiQueryKeys.documents(workspaceId) })
145
122
  ```
146
123
 
147
- ## Re-exports
148
-
149
- The package re-exports key types from `@arbidocs/sdk/browser` for convenience:
150
-
151
- ```tsx
152
- import { Arbi, ArbiError } from '@arbidocs/react'
153
- import type { ArbiOptions, QueryOptions, SSEStreamResult, SSEStreamCallbacks } from '@arbidocs/react'
154
- ```
155
-
156
- ## Examples
157
-
158
- See the **[React Chat App](../../examples/react-chat/)** for a complete working example with login, workspace selection, document picker, and streaming chat.
159
-
160
- ## Peer Dependencies
124
+ ## Peer dependencies
161
125
 
162
126
  - `react` >= 18