@talk2view/sdk 0.1.0
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/LICENSE +7 -0
- package/README.md +594 -0
- package/dist/auth.d.ts +39 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +102 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +27 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +195 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +21 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +38 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +115 -0
- package/dist/index.js.map +1 -0
- package/dist/react/ChatInput.d.ts +13 -0
- package/dist/react/ChatInput.d.ts.map +1 -0
- package/dist/react/ChatInput.js +163 -0
- package/dist/react/ChatInput.js.map +1 -0
- package/dist/react/ChatMessage.d.ts +10 -0
- package/dist/react/ChatMessage.d.ts.map +1 -0
- package/dist/react/ChatMessage.js +53 -0
- package/dist/react/ChatMessage.js.map +1 -0
- package/dist/react/ChatPanel.d.ts +17 -0
- package/dist/react/ChatPanel.d.ts.map +1 -0
- package/dist/react/ChatPanel.js +385 -0
- package/dist/react/ChatPanel.js.map +1 -0
- package/dist/react/LoginModal.d.ts +10 -0
- package/dist/react/LoginModal.d.ts.map +1 -0
- package/dist/react/LoginModal.js +135 -0
- package/dist/react/LoginModal.js.map +1 -0
- package/dist/react/SettingsView.d.ts +9 -0
- package/dist/react/SettingsView.d.ts.map +1 -0
- package/dist/react/SettingsView.js +190 -0
- package/dist/react/SettingsView.js.map +1 -0
- package/dist/react/T2VProvider.d.ts +25 -0
- package/dist/react/T2VProvider.d.ts.map +1 -0
- package/dist/react/T2VProvider.js +38 -0
- package/dist/react/T2VProvider.js.map +1 -0
- package/dist/react/index.d.ts +38 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +28 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/theme.d.ts +32 -0
- package/dist/react/theme.d.ts.map +1 -0
- package/dist/react/theme.js +131 -0
- package/dist/react/theme.js.map +1 -0
- package/dist/react/useT2VAuth.d.ts +16 -0
- package/dist/react/useT2VAuth.d.ts.map +1 -0
- package/dist/react/useT2VAuth.js +52 -0
- package/dist/react/useT2VAuth.js.map +1 -0
- package/dist/react/useT2VChat.d.ts +28 -0
- package/dist/react/useT2VChat.d.ts.map +1 -0
- package/dist/react/useT2VChat.js +103 -0
- package/dist/react/useT2VChat.js.map +1 -0
- package/dist/react/useT2VTools.d.ts +11 -0
- package/dist/react/useT2VTools.d.ts.map +1 -0
- package/dist/react/useT2VTools.js +29 -0
- package/dist/react/useT2VTools.js.map +1 -0
- package/dist/react/useUserPreferences.d.ts +13 -0
- package/dist/react/useUserPreferences.d.ts.map +1 -0
- package/dist/react/useUserPreferences.js +40 -0
- package/dist/react/useUserPreferences.js.map +1 -0
- package/dist/sessions.d.ts +34 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +95 -0
- package/dist/sessions.js.map +1 -0
- package/dist/storage.d.ts +16 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +84 -0
- package/dist/storage.js.map +1 -0
- package/dist/streaming.d.ts +9 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +45 -0
- package/dist/streaming.js.map +1 -0
- package/dist/tools.d.ts +40 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +83 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +153 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2025 A2B Technology Corporation Pty Ltd.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
# @talk2view/sdk
|
|
2
|
+
|
|
3
|
+
Add AI-powered natural language control to any application. Talk2View's SDK handles authentication, tool registration, streaming chat, and the interrupt/resume cycle for client-side tool execution.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @talk2view/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### React (recommended)
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { T2VProvider, ChatPanel } from '@talk2view/sdk/react';
|
|
17
|
+
import type { ClientTool } from '@talk2view/sdk';
|
|
18
|
+
|
|
19
|
+
const tools: ClientTool[] = [
|
|
20
|
+
{
|
|
21
|
+
name: 'set_color',
|
|
22
|
+
description: 'Set the background color of the canvas',
|
|
23
|
+
parameters: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
color: { type: 'string', description: 'CSS color value' },
|
|
27
|
+
},
|
|
28
|
+
required: ['color'],
|
|
29
|
+
},
|
|
30
|
+
execute: async (args) => {
|
|
31
|
+
document.body.style.backgroundColor = args.color as string;
|
|
32
|
+
return JSON.stringify({ success: true, color: args.color });
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
function App() {
|
|
38
|
+
return (
|
|
39
|
+
<T2VProvider partnerKey="pk_live_..." baseUrl="https://api.talk2view.com">
|
|
40
|
+
<ChatPanel tools={tools} systemPrompt="You control a canvas." />
|
|
41
|
+
</T2VProvider>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
That's it. The `ChatPanel` handles login, tool registration, streaming chat, and tool execution automatically.
|
|
47
|
+
|
|
48
|
+
### Vanilla JavaScript
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { Talk2View } from '@talk2view/sdk';
|
|
52
|
+
|
|
53
|
+
const t2v = new Talk2View({ partnerKey: 'pk_live_...' });
|
|
54
|
+
|
|
55
|
+
// 1. Authenticate
|
|
56
|
+
await t2v.auth.login('user@example.com', 'password');
|
|
57
|
+
|
|
58
|
+
// 2. Register tools with handlers
|
|
59
|
+
t2v.tools.handle('get_time', async () => {
|
|
60
|
+
return new Date().toISOString();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
await t2v.tools.register([
|
|
64
|
+
{
|
|
65
|
+
name: 'get_time',
|
|
66
|
+
description: 'Get the current time',
|
|
67
|
+
parameters: { type: 'object', properties: {} },
|
|
68
|
+
},
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
// 3. Chat — tool calls are handled automatically
|
|
72
|
+
for await (const event of t2v.chat('What time is it?')) {
|
|
73
|
+
if (event.type === 'text') process.stdout.write(event.content);
|
|
74
|
+
if (event.type === 'done') console.log('\n');
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Concepts
|
|
81
|
+
|
|
82
|
+
### Partner Keys
|
|
83
|
+
|
|
84
|
+
Every request requires a partner API key (`X-T2V-Partner-Key` header). Keys are scoped to your application:
|
|
85
|
+
|
|
86
|
+
- `pk_test_...` — test keys for development
|
|
87
|
+
- `pk_live_...` — production keys
|
|
88
|
+
|
|
89
|
+
The SDK attaches this header automatically.
|
|
90
|
+
|
|
91
|
+
### Two-Tier Authentication
|
|
92
|
+
|
|
93
|
+
Talk2View uses two layers of auth on every request:
|
|
94
|
+
|
|
95
|
+
1. **Partner key** — identifies your application
|
|
96
|
+
2. **User JWT** — identifies the end-user (obtained via `auth.login()`)
|
|
97
|
+
|
|
98
|
+
The SDK manages token storage, refresh, and retry automatically.
|
|
99
|
+
|
|
100
|
+
### Client Tools
|
|
101
|
+
|
|
102
|
+
Tools are functions that run **in your application**, not on the server. When the AI decides to call a tool:
|
|
103
|
+
|
|
104
|
+
1. The server pauses the AI agent
|
|
105
|
+
2. The server sends a `tool_call` event to your app via SSE
|
|
106
|
+
3. Your app executes the tool locally using the registered handler
|
|
107
|
+
4. Your app sends the result back to the server (via `/resume`)
|
|
108
|
+
5. The server resumes the AI agent with the result
|
|
109
|
+
|
|
110
|
+
The SDK handles steps 2-5 automatically when you provide an `execute` function on your tools.
|
|
111
|
+
|
|
112
|
+
### `return_direct`
|
|
113
|
+
|
|
114
|
+
Tools with `return_direct: true` skip the AI's post-processing step. The tool result is returned directly to the user without the AI rephrasing it. Use this for tools that return UI updates or structured data that doesn't need summarization.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## React API
|
|
119
|
+
|
|
120
|
+
### `<T2VProvider>`
|
|
121
|
+
|
|
122
|
+
Context provider that initializes the Talk2View client. Wrap your app (or the section that uses Talk2View) with this.
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
<T2VProvider
|
|
126
|
+
partnerKey="pk_live_..." // Required
|
|
127
|
+
baseUrl="https://api.talk2view.com" // Optional, defaults to localhost:8100
|
|
128
|
+
model="gpt-4.1-mini" // Optional, uses server default
|
|
129
|
+
>
|
|
130
|
+
{children}
|
|
131
|
+
</T2VProvider>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### `<ChatPanel>`
|
|
135
|
+
|
|
136
|
+
Self-contained chat UI with built-in login, tool registration, message list, and input. Drop this in and it works.
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
<ChatPanel
|
|
140
|
+
tools={myTools} // ClientTool[] — tools with execute handlers
|
|
141
|
+
systemPrompt="You are..." // Optional system prompt
|
|
142
|
+
signupUrl="https://..." // Optional, link shown on login form
|
|
143
|
+
className="my-chat" // Optional CSS class
|
|
144
|
+
style={{ height: '100%' }} // Optional inline styles
|
|
145
|
+
/>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
If the user isn't logged in, `ChatPanel` shows a login form automatically. After login, it registers the provided tools and enables the chat input.
|
|
149
|
+
|
|
150
|
+
### `<LoginModal>`
|
|
151
|
+
|
|
152
|
+
Standalone login form. Use this if you want to control placement separately from the chat UI.
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
<LoginModal
|
|
156
|
+
signupUrl="https://talk2view.com/auth?signup" // Optional
|
|
157
|
+
onSuccess={() => console.log('Logged in!')} // Optional callback
|
|
158
|
+
className="my-login" // Optional CSS class
|
|
159
|
+
/>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Returns `null` if the user is already authenticated.
|
|
163
|
+
|
|
164
|
+
### `useT2V()`
|
|
165
|
+
|
|
166
|
+
Access the Talk2View client instance and auth state.
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
const { t2v, user, isAuthenticated } = useT2V();
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### `useT2VAuth()`
|
|
173
|
+
|
|
174
|
+
Authentication state and actions.
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
const {
|
|
178
|
+
user, // User | null
|
|
179
|
+
isAuthenticated, // boolean
|
|
180
|
+
isLoading, // boolean
|
|
181
|
+
error, // string | null
|
|
182
|
+
login, // (email: string, password: string) => Promise<void>
|
|
183
|
+
signup, // (email: string, password: string) => Promise<void>
|
|
184
|
+
logout, // () => Promise<void>
|
|
185
|
+
clearError, // () => void
|
|
186
|
+
} = useT2VAuth();
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### `useT2VChat()`
|
|
190
|
+
|
|
191
|
+
Chat state and message sending.
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
const {
|
|
195
|
+
messages, // DisplayMessage[]
|
|
196
|
+
isLoading, // boolean — true while streaming
|
|
197
|
+
error, // string | null
|
|
198
|
+
threadId, // string | null
|
|
199
|
+
sendMessage, // (content: string) => Promise<void>
|
|
200
|
+
clearMessages, // () => void
|
|
201
|
+
clearError, // () => void
|
|
202
|
+
} = useT2VChat({ systemPrompt: 'You are a helpful assistant.' });
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
`DisplayMessage` shape:
|
|
206
|
+
```typescript
|
|
207
|
+
{
|
|
208
|
+
id: string
|
|
209
|
+
role: 'user' | 'assistant'
|
|
210
|
+
content: string
|
|
211
|
+
timestamp: Date
|
|
212
|
+
isStreaming?: boolean // true while the assistant is still generating
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### `useT2VTools()`
|
|
217
|
+
|
|
218
|
+
Tool registration.
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
const {
|
|
222
|
+
registerTools, // (tools: ClientTool[]) => Promise<RegisterToolsResponse>
|
|
223
|
+
registeredTools, // string[] — names of registered tools
|
|
224
|
+
isRegistered, // boolean
|
|
225
|
+
} = useT2VTools();
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Core API (framework-agnostic)
|
|
231
|
+
|
|
232
|
+
### `Talk2View`
|
|
233
|
+
|
|
234
|
+
Main entry point. Use this directly for vanilla JS or non-React frameworks.
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
const t2v = new Talk2View({
|
|
238
|
+
partnerKey: 'pk_live_...', // Required
|
|
239
|
+
baseUrl: 'https://api.talk2view.com', // Optional
|
|
240
|
+
model: 'gpt-4.1-mini', // Optional
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
#### `t2v.auth`
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
await t2v.auth.login(email, password) // Returns User
|
|
248
|
+
await t2v.auth.signup(email, password) // Returns User
|
|
249
|
+
await t2v.auth.logout()
|
|
250
|
+
t2v.auth.getUser() // Returns User | null
|
|
251
|
+
t2v.auth.isAuthenticated() // Returns boolean
|
|
252
|
+
|
|
253
|
+
// Subscribe to auth state changes
|
|
254
|
+
const unsubscribe = t2v.auth.onAuthStateChange((user) => {
|
|
255
|
+
console.log(user ? 'Logged in' : 'Logged out');
|
|
256
|
+
});
|
|
257
|
+
unsubscribe(); // stop listening
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### `t2v.tools`
|
|
261
|
+
|
|
262
|
+
Register tool schemas with the server and provide local execution handlers.
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// Option A: inline execute function
|
|
266
|
+
await t2v.tools.register([
|
|
267
|
+
{
|
|
268
|
+
name: 'zoom_in',
|
|
269
|
+
description: 'Zoom the viewport in',
|
|
270
|
+
parameters: { type: 'object', properties: {} },
|
|
271
|
+
execute: async () => {
|
|
272
|
+
myApp.zoomIn();
|
|
273
|
+
return JSON.stringify({ success: true });
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
]);
|
|
277
|
+
|
|
278
|
+
// Option B: separate handler registration
|
|
279
|
+
t2v.tools.handle('zoom_in', async () => {
|
|
280
|
+
myApp.zoomIn();
|
|
281
|
+
return JSON.stringify({ success: true });
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
await t2v.tools.register([
|
|
285
|
+
{
|
|
286
|
+
name: 'zoom_in',
|
|
287
|
+
description: 'Zoom the viewport in',
|
|
288
|
+
parameters: { type: 'object', properties: {} },
|
|
289
|
+
},
|
|
290
|
+
]);
|
|
291
|
+
|
|
292
|
+
// Check state
|
|
293
|
+
t2v.tools.getRegistered() // ClientToolSchema[]
|
|
294
|
+
t2v.tools.hasHandler('zoom_in') // boolean
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### `t2v.chat()`
|
|
298
|
+
|
|
299
|
+
Send a message and stream the response. Tool calls are executed automatically if handlers are registered.
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
for await (const event of t2v.chat('Zoom in please')) {
|
|
303
|
+
switch (event.type) {
|
|
304
|
+
case 'text':
|
|
305
|
+
// Incremental text chunk from the AI
|
|
306
|
+
console.log(event.content);
|
|
307
|
+
break;
|
|
308
|
+
case 'tool_call':
|
|
309
|
+
// A tool was called (already executed automatically)
|
|
310
|
+
console.log(`Called ${event.toolName} with`, event.arguments);
|
|
311
|
+
break;
|
|
312
|
+
case 'done':
|
|
313
|
+
// Stream complete
|
|
314
|
+
console.log('Thread:', event.threadId);
|
|
315
|
+
break;
|
|
316
|
+
case 'error':
|
|
317
|
+
console.error(event.message);
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### `t2v.createSession()` / `t2v.getSession()`
|
|
324
|
+
|
|
325
|
+
For advanced use cases where you need direct session control:
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
const session = await t2v.createSession();
|
|
329
|
+
|
|
330
|
+
// Send message and handle events manually
|
|
331
|
+
for await (const event of session.sendMessage('Hello')) {
|
|
332
|
+
// ...
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Manual tool result submission
|
|
336
|
+
for await (const event of session.resumeToolCall(toolCallId, result)) {
|
|
337
|
+
// ...
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## Defining Tools
|
|
344
|
+
|
|
345
|
+
A tool needs a **schema** (so the AI knows when and how to call it) and an **execute function** (so your app can run it locally).
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
import type { ClientTool } from '@talk2view/sdk';
|
|
349
|
+
|
|
350
|
+
const myTool: ClientTool = {
|
|
351
|
+
name: 'set_window_level',
|
|
352
|
+
description: 'Set the brightness and contrast of the medical image viewer',
|
|
353
|
+
parameters: {
|
|
354
|
+
type: 'object',
|
|
355
|
+
properties: {
|
|
356
|
+
windowWidth: {
|
|
357
|
+
type: 'number',
|
|
358
|
+
description: 'Contrast range (window width)',
|
|
359
|
+
},
|
|
360
|
+
windowCenter: {
|
|
361
|
+
type: 'number',
|
|
362
|
+
description: 'Brightness level (window center)',
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
required: ['windowWidth', 'windowCenter'],
|
|
366
|
+
},
|
|
367
|
+
return_direct: false, // Let the AI summarize the result (default)
|
|
368
|
+
execute: async (args) => {
|
|
369
|
+
viewer.setWindowLevel(args.windowWidth as number, args.windowCenter as number);
|
|
370
|
+
return JSON.stringify({
|
|
371
|
+
success: true,
|
|
372
|
+
windowWidth: args.windowWidth,
|
|
373
|
+
windowCenter: args.windowCenter,
|
|
374
|
+
});
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Tool Schema Reference
|
|
380
|
+
|
|
381
|
+
| Field | Type | Required | Description |
|
|
382
|
+
|-------|------|----------|-------------|
|
|
383
|
+
| `name` | `string` | Yes | Unique tool identifier |
|
|
384
|
+
| `description` | `string` | Yes | What the tool does (the AI reads this) |
|
|
385
|
+
| `parameters` | `object` | Yes | JSON Schema for the tool's arguments |
|
|
386
|
+
| `parameters.properties` | `Record<string, { type, description }>` | Yes | Argument definitions |
|
|
387
|
+
| `parameters.required` | `string[]` | No | Required argument names |
|
|
388
|
+
| `return_direct` | `boolean` | No | Skip AI post-processing (default: `false`) |
|
|
389
|
+
| `execute` | `(args) => Promise<string>` | Yes* | Local execution handler |
|
|
390
|
+
|
|
391
|
+
*`execute` is required on `ClientTool`. If using `ClientToolSchema` with `t2v.tools.handle()`, provide the handler separately.
|
|
392
|
+
|
|
393
|
+
### Parameter Types
|
|
394
|
+
|
|
395
|
+
Supported `type` values in `parameters.properties`:
|
|
396
|
+
|
|
397
|
+
| Type | Maps to |
|
|
398
|
+
|------|---------|
|
|
399
|
+
| `'string'` | `string` |
|
|
400
|
+
| `'number'` | `number` |
|
|
401
|
+
| `'integer'` | `number` |
|
|
402
|
+
| `'boolean'` | `boolean` |
|
|
403
|
+
| `'array'` | `unknown[]` |
|
|
404
|
+
| `'object'` | `Record<string, unknown>` |
|
|
405
|
+
|
|
406
|
+
Use `enum` to restrict string values:
|
|
407
|
+
```typescript
|
|
408
|
+
{
|
|
409
|
+
type: 'string',
|
|
410
|
+
description: 'Image orientation',
|
|
411
|
+
enum: ['axial', 'sagittal', 'coronal'],
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Execute Function
|
|
416
|
+
|
|
417
|
+
The `execute` function receives the AI's arguments as a `Record<string, unknown>` and must return a `Promise<string>`. The returned string is sent back to the AI as the tool's result.
|
|
418
|
+
|
|
419
|
+
- Return `JSON.stringify(...)` for structured results
|
|
420
|
+
- Throw an error or return an error string if the tool fails — the SDK catches errors and sends them back to the AI as `{ result: "Error: ...", is_error: true }`
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## Token Storage
|
|
425
|
+
|
|
426
|
+
The SDK stores auth tokens in `localStorage` (keys prefixed with `talk2view_`). In private browsing or environments without `localStorage`, it falls back to in-memory storage automatically.
|
|
427
|
+
|
|
428
|
+
Stored keys:
|
|
429
|
+
- `talk2view_access_token`
|
|
430
|
+
- `talk2view_refresh_token`
|
|
431
|
+
- `talk2view_user`
|
|
432
|
+
- `talk2view_user_api_key`
|
|
433
|
+
|
|
434
|
+
On logout, all keys are cleared and a `talk2view_auth_cleared` event is dispatched on `window` for cross-component synchronization.
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## Error Handling
|
|
439
|
+
|
|
440
|
+
The SDK throws typed errors:
|
|
441
|
+
|
|
442
|
+
| Error Class | When |
|
|
443
|
+
|-------------|------|
|
|
444
|
+
| `AuthenticationError` | Invalid credentials, expired token |
|
|
445
|
+
| `PartnerKeyError` | Invalid or inactive partner API key |
|
|
446
|
+
| `SessionError` | Session not found or creation failed |
|
|
447
|
+
| `NetworkError` | Network failure, server unreachable |
|
|
448
|
+
| `T2VError` | Base class for all SDK errors |
|
|
449
|
+
|
|
450
|
+
```typescript
|
|
451
|
+
import { AuthenticationError, NetworkError } from '@talk2view/sdk';
|
|
452
|
+
|
|
453
|
+
try {
|
|
454
|
+
await t2v.auth.login(email, password);
|
|
455
|
+
} catch (err) {
|
|
456
|
+
if (err instanceof AuthenticationError) {
|
|
457
|
+
console.log('Bad credentials');
|
|
458
|
+
} else if (err instanceof NetworkError) {
|
|
459
|
+
console.log('Server unreachable');
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
In React, the hooks catch errors internally and expose them via the `error` state:
|
|
465
|
+
|
|
466
|
+
```tsx
|
|
467
|
+
const { error, clearError } = useT2VAuth();
|
|
468
|
+
// error is a string message, not a thrown exception
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
## Configuration
|
|
474
|
+
|
|
475
|
+
### `T2VConfig`
|
|
476
|
+
|
|
477
|
+
| Property | Type | Required | Default | Description |
|
|
478
|
+
|----------|------|----------|---------|-------------|
|
|
479
|
+
| `partnerKey` | `string` | Yes | — | Your partner API key |
|
|
480
|
+
| `baseUrl` | `string` | No | `'http://localhost:8100'` | Talk2View API server URL |
|
|
481
|
+
| `model` | `string` | No | Server default | LLM model to use |
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
## Full Integration Example
|
|
486
|
+
|
|
487
|
+
Here's a complete example integrating Talk2View into a hypothetical drawing app:
|
|
488
|
+
|
|
489
|
+
```tsx
|
|
490
|
+
import React, { useRef, useMemo } from 'react';
|
|
491
|
+
import { T2VProvider, ChatPanel } from '@talk2view/sdk/react';
|
|
492
|
+
import type { ClientTool } from '@talk2view/sdk';
|
|
493
|
+
import { Canvas } from './Canvas';
|
|
494
|
+
|
|
495
|
+
function App() {
|
|
496
|
+
const canvasRef = useRef<CanvasAPI>(null);
|
|
497
|
+
|
|
498
|
+
const tools: ClientTool[] = useMemo(() => [
|
|
499
|
+
{
|
|
500
|
+
name: 'draw_circle',
|
|
501
|
+
description: 'Draw a circle on the canvas',
|
|
502
|
+
parameters: {
|
|
503
|
+
type: 'object',
|
|
504
|
+
properties: {
|
|
505
|
+
x: { type: 'number', description: 'X coordinate' },
|
|
506
|
+
y: { type: 'number', description: 'Y coordinate' },
|
|
507
|
+
radius: { type: 'number', description: 'Radius in pixels' },
|
|
508
|
+
color: { type: 'string', description: 'Fill color' },
|
|
509
|
+
},
|
|
510
|
+
required: ['x', 'y', 'radius', 'color'],
|
|
511
|
+
},
|
|
512
|
+
execute: async (args) => {
|
|
513
|
+
canvasRef.current!.drawCircle(
|
|
514
|
+
args.x as number,
|
|
515
|
+
args.y as number,
|
|
516
|
+
args.radius as number,
|
|
517
|
+
args.color as string,
|
|
518
|
+
);
|
|
519
|
+
return JSON.stringify({ success: true });
|
|
520
|
+
},
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
name: 'clear_canvas',
|
|
524
|
+
description: 'Clear all drawings from the canvas',
|
|
525
|
+
parameters: { type: 'object', properties: {} },
|
|
526
|
+
execute: async () => {
|
|
527
|
+
canvasRef.current!.clear();
|
|
528
|
+
return JSON.stringify({ success: true });
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
name: 'get_canvas_info',
|
|
533
|
+
description: 'Get the current canvas dimensions and number of shapes',
|
|
534
|
+
parameters: { type: 'object', properties: {} },
|
|
535
|
+
return_direct: true,
|
|
536
|
+
execute: async () => {
|
|
537
|
+
const info = canvasRef.current!.getInfo();
|
|
538
|
+
return JSON.stringify(info);
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
], []);
|
|
542
|
+
|
|
543
|
+
return (
|
|
544
|
+
<T2VProvider partnerKey="pk_live_..." baseUrl="https://api.talk2view.com">
|
|
545
|
+
<div style={{ display: 'flex', height: '100vh' }}>
|
|
546
|
+
<Canvas ref={canvasRef} style={{ flex: 1 }} />
|
|
547
|
+
<ChatPanel
|
|
548
|
+
tools={tools}
|
|
549
|
+
systemPrompt="You control a drawing canvas. Use the tools to draw shapes and manage the canvas."
|
|
550
|
+
style={{ width: 360 }}
|
|
551
|
+
/>
|
|
552
|
+
</div>
|
|
553
|
+
</T2VProvider>
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
## TypeScript
|
|
561
|
+
|
|
562
|
+
The SDK is written in TypeScript with strict mode. All types are exported:
|
|
563
|
+
|
|
564
|
+
```typescript
|
|
565
|
+
// Core types
|
|
566
|
+
import type {
|
|
567
|
+
T2VConfig,
|
|
568
|
+
User,
|
|
569
|
+
ChatEvent,
|
|
570
|
+
ChatMessage,
|
|
571
|
+
ClientTool,
|
|
572
|
+
ClientToolSchema,
|
|
573
|
+
ToolHandler,
|
|
574
|
+
TokenResponse,
|
|
575
|
+
ToolCallInterrupt,
|
|
576
|
+
ChatCompletionChunk,
|
|
577
|
+
RegisterToolsResponse,
|
|
578
|
+
} from '@talk2view/sdk';
|
|
579
|
+
|
|
580
|
+
// React types
|
|
581
|
+
import type {
|
|
582
|
+
T2VProviderProps,
|
|
583
|
+
UseT2VAuthResult,
|
|
584
|
+
UseT2VChatResult,
|
|
585
|
+
UseT2VToolsResult,
|
|
586
|
+
DisplayMessage,
|
|
587
|
+
ChatPanelProps,
|
|
588
|
+
LoginModalProps,
|
|
589
|
+
} from '@talk2view/sdk/react';
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## License
|
|
593
|
+
|
|
594
|
+
MIT License. See [LICENSE](./LICENSE) for details.
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth module — login, signup, refresh, logout, auth state management.
|
|
3
|
+
*/
|
|
4
|
+
import type { T2VClient } from './client';
|
|
5
|
+
import type { User } from './types';
|
|
6
|
+
type AuthStateCallback = (user: User | null) => void;
|
|
7
|
+
export declare class T2VAuth {
|
|
8
|
+
private readonly client;
|
|
9
|
+
private listeners;
|
|
10
|
+
constructor(client: T2VClient);
|
|
11
|
+
/**
|
|
12
|
+
* Create a new Talk2View account.
|
|
13
|
+
*/
|
|
14
|
+
signup(email: string, password: string): Promise<User>;
|
|
15
|
+
/**
|
|
16
|
+
* Authenticate with email and password.
|
|
17
|
+
*/
|
|
18
|
+
login(email: string, password: string): Promise<User>;
|
|
19
|
+
/**
|
|
20
|
+
* Sign out the current user.
|
|
21
|
+
*/
|
|
22
|
+
logout(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Get the current user (from storage).
|
|
25
|
+
*/
|
|
26
|
+
getUser(): User | null;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a user is currently authenticated.
|
|
29
|
+
*/
|
|
30
|
+
isAuthenticated(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Subscribe to auth state changes.
|
|
33
|
+
*/
|
|
34
|
+
onAuthStateChange(callback: AuthStateCallback): () => void;
|
|
35
|
+
private storeTokens;
|
|
36
|
+
private notifyListeners;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAY1C,OAAO,KAAK,EAA8C,IAAI,EAAE,MAAM,SAAS,CAAC;AAEhF,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;AAErD,qBAAa,OAAO;IAGN,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,SAAS,CAAqC;gBAEzB,MAAM,EAAE,SAAS;IAS9C;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB5D;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3D;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAU7B;;OAEG;IACH,OAAO,IAAI,IAAI,GAAG,IAAI;IAUtB;;OAEG;IACH,eAAe,IAAI,OAAO;IAI1B;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAO1D,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,eAAe;CAKxB"}
|