@standardagents/vue 0.1.0-dev.ffffff
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.txt +48 -0
- package/README.md +379 -0
- package/dist/index.cjs +356 -0
- package/dist/index.d.cts +293 -0
- package/dist/index.d.ts +293 -0
- package/dist/index.js +314 -0
- package/package.json +55 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
PROPRIETARY SOFTWARE LICENSE
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2025 FormKit Inc. All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
UNLICENSED - DO NOT USE
|
|
6
|
+
|
|
7
|
+
This software and associated documentation files (the "Software") are the sole
|
|
8
|
+
and exclusive property of FormKit Inc. ("FormKit").
|
|
9
|
+
|
|
10
|
+
USE RESTRICTIONS
|
|
11
|
+
|
|
12
|
+
The Software is UNLICENSED and proprietary. NO PERMISSION is granted to use,
|
|
13
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
14
|
+
the Software, or to permit persons to whom the Software is furnished to do so,
|
|
15
|
+
under any circumstances, without prior written authorization from FormKit Inc.
|
|
16
|
+
|
|
17
|
+
UNAUTHORIZED USE PROHIBITED
|
|
18
|
+
|
|
19
|
+
Any use of this Software without a valid, written license agreement signed by
|
|
20
|
+
authorized officers of FormKit Inc. is strictly prohibited and constitutes
|
|
21
|
+
unauthorized use and infringement of FormKit's intellectual property rights.
|
|
22
|
+
|
|
23
|
+
LICENSING INQUIRIES
|
|
24
|
+
|
|
25
|
+
Organizations interested in licensing this Software should contact:
|
|
26
|
+
enterprise@formkit.com
|
|
27
|
+
|
|
28
|
+
A written license agreement must be executed before any use of this Software
|
|
29
|
+
is authorized.
|
|
30
|
+
|
|
31
|
+
NO WARRANTY
|
|
32
|
+
|
|
33
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
34
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
35
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
36
|
+
FORMKIT INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
37
|
+
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
38
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
39
|
+
|
|
40
|
+
GOVERNING LAW
|
|
41
|
+
|
|
42
|
+
This license shall be governed by and construed in accordance with the laws
|
|
43
|
+
of the jurisdiction in which FormKit Inc. is incorporated, without regard to
|
|
44
|
+
its conflict of law provisions.
|
|
45
|
+
|
|
46
|
+
FormKit Inc.
|
|
47
|
+
https://formkit.com
|
|
48
|
+
enterprise@formkit.com
|
package/README.md
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
# @standardagents/vue
|
|
2
|
+
|
|
3
|
+
Vue 3 composables and components for Standard Agents - connect to AI agent threads with real-time updates, send messages, manage files, and listen for custom events.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @standardagents/vue
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @standardagents/vue
|
|
11
|
+
# or
|
|
12
|
+
yarn add @standardagents/vue
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Requirements:** Vue 3.3+
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// main.ts
|
|
21
|
+
import { createApp } from 'vue'
|
|
22
|
+
import { StandardAgentsPlugin } from '@standardagents/vue'
|
|
23
|
+
import App from './App.vue'
|
|
24
|
+
|
|
25
|
+
const app = createApp(App)
|
|
26
|
+
app.use(StandardAgentsPlugin, { endpoint: 'https://api.example.com' })
|
|
27
|
+
app.mount('#app')
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```vue
|
|
31
|
+
<!-- App.vue -->
|
|
32
|
+
<script setup lang="ts">
|
|
33
|
+
import { ThreadProvider, useThread } from '@standardagents/vue'
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<template>
|
|
37
|
+
<ThreadProvider threadId="thread-123">
|
|
38
|
+
<ChatInterface />
|
|
39
|
+
</ThreadProvider>
|
|
40
|
+
</template>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```vue
|
|
44
|
+
<!-- ChatInterface.vue -->
|
|
45
|
+
<script setup lang="ts">
|
|
46
|
+
import { ref } from 'vue'
|
|
47
|
+
import { useThread } from '@standardagents/vue'
|
|
48
|
+
|
|
49
|
+
const { messages, sendMessage, status } = useThread()
|
|
50
|
+
const input = ref('')
|
|
51
|
+
|
|
52
|
+
const handleSend = async () => {
|
|
53
|
+
await sendMessage({ role: 'user', content: input.value })
|
|
54
|
+
input.value = ''
|
|
55
|
+
}
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<template>
|
|
59
|
+
<div>
|
|
60
|
+
<p>Status: {{ status }}</p>
|
|
61
|
+
<div v-for="msg in messages" :key="msg.id">
|
|
62
|
+
<strong>{{ msg.role }}:</strong> {{ msg.content }}
|
|
63
|
+
</div>
|
|
64
|
+
<input v-model="input" @keyup.enter="handleSend" />
|
|
65
|
+
<button @click="handleSend">Send</button>
|
|
66
|
+
</div>
|
|
67
|
+
</template>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Authentication
|
|
71
|
+
|
|
72
|
+
The package reads the authentication token from `localStorage` using the key `agentbuilder_auth_token`:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// Set the token before using the composables
|
|
76
|
+
localStorage.setItem('agentbuilder_auth_token', 'your-token-here')
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
All API requests and WebSocket connections will automatically include this token.
|
|
80
|
+
|
|
81
|
+
## API Reference
|
|
82
|
+
|
|
83
|
+
### `StandardAgentsPlugin`
|
|
84
|
+
|
|
85
|
+
Vue plugin that configures the Standard Agents client for all components.
|
|
86
|
+
|
|
87
|
+
**Options:**
|
|
88
|
+
|
|
89
|
+
- `endpoint: string` - The API endpoint URL (required)
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { createApp } from 'vue'
|
|
93
|
+
import { StandardAgentsPlugin } from '@standardagents/vue'
|
|
94
|
+
|
|
95
|
+
const app = createApp(App)
|
|
96
|
+
app.use(StandardAgentsPlugin, { endpoint: 'https://api.example.com' })
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
### `ThreadProvider`
|
|
102
|
+
|
|
103
|
+
Component that establishes a WebSocket connection to a specific thread and provides context to child components.
|
|
104
|
+
|
|
105
|
+
**Props:**
|
|
106
|
+
|
|
107
|
+
- `threadId: string` - The thread ID to connect to
|
|
108
|
+
- `preload?: boolean` - Fetch existing messages on mount (default: `true`)
|
|
109
|
+
- `live?: boolean` - Enable WebSocket for real-time updates (default: `true`)
|
|
110
|
+
- `useWorkblocks?: boolean` - Group tool calls into workblocks (default: `false`)
|
|
111
|
+
- `depth?: number` - Message depth level (default: `0`)
|
|
112
|
+
- `includeSilent?: boolean` - Include silent messages (default: `false`)
|
|
113
|
+
- `endpoint?: string` - Override the endpoint from plugin config
|
|
114
|
+
|
|
115
|
+
```vue
|
|
116
|
+
<template>
|
|
117
|
+
<ThreadProvider threadId="thread-123" :live="true">
|
|
118
|
+
<YourComponents />
|
|
119
|
+
</ThreadProvider>
|
|
120
|
+
</template>
|
|
121
|
+
|
|
122
|
+
<script setup lang="ts">
|
|
123
|
+
import { ThreadProvider } from '@standardagents/vue'
|
|
124
|
+
</script>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### `useThread()`
|
|
130
|
+
|
|
131
|
+
Composable to access the full thread context. Must be used within a `ThreadProvider`.
|
|
132
|
+
|
|
133
|
+
**Returns:**
|
|
134
|
+
|
|
135
|
+
- `threadId: string` - The thread ID
|
|
136
|
+
- `messages: Ref<Message[]>` - Reactive array of messages
|
|
137
|
+
- `workblocks: ComputedRef<ThreadMessage[]>` - Messages transformed to workblocks (if `useWorkblocks` is true)
|
|
138
|
+
- `status: Ref<ConnectionStatus>` - Connection status (`"connecting"` | `"connected"` | `"disconnected"` | `"reconnecting"`)
|
|
139
|
+
- `loading: Ref<boolean>` - Loading state (alias: `isLoading`)
|
|
140
|
+
- `error: Ref<Error | null>` - Error state
|
|
141
|
+
- `options: ThreadProviderOptions` - Options passed to the provider
|
|
142
|
+
- `sendMessage: (payload: SendMessagePayload) => Promise<Message>` - Send a message
|
|
143
|
+
- `stopExecution: () => Promise<void>` - Stop current execution
|
|
144
|
+
- `onEvent: <T>(eventType, callback) => () => void` - Subscribe to custom events (alias: `subscribeToEvent`)
|
|
145
|
+
- `files: ComputedRef<ThreadFile[]>` - All files (pending + committed)
|
|
146
|
+
- `addFiles: (files: File[] | FileList) => void` - Upload files
|
|
147
|
+
- `removeFile: (id: string) => void` - Remove a pending file
|
|
148
|
+
- `getFileUrl: (file: ThreadFile) => string` - Get file URL
|
|
149
|
+
- `getThumbnailUrl: (file: ThreadFile) => string` - Get thumbnail URL
|
|
150
|
+
- `getPreviewUrl: (file: ThreadFile) => string | null` - Get preview URL
|
|
151
|
+
|
|
152
|
+
**Example:**
|
|
153
|
+
|
|
154
|
+
```vue
|
|
155
|
+
<script setup lang="ts">
|
|
156
|
+
import { useThread } from '@standardagents/vue'
|
|
157
|
+
|
|
158
|
+
const {
|
|
159
|
+
messages,
|
|
160
|
+
sendMessage,
|
|
161
|
+
stopExecution,
|
|
162
|
+
status,
|
|
163
|
+
isLoading,
|
|
164
|
+
files,
|
|
165
|
+
addFiles,
|
|
166
|
+
onEvent,
|
|
167
|
+
} = useThread()
|
|
168
|
+
|
|
169
|
+
// Subscribe to custom events
|
|
170
|
+
onEvent<{ todos: string[] }>('todo-updated', (data) => {
|
|
171
|
+
console.log('Todos:', data.todos)
|
|
172
|
+
})
|
|
173
|
+
</script>
|
|
174
|
+
|
|
175
|
+
<template>
|
|
176
|
+
<div>
|
|
177
|
+
<p v-if="isLoading">Loading...</p>
|
|
178
|
+
<p>Status: {{ status }}</p>
|
|
179
|
+
|
|
180
|
+
<div v-for="msg in messages" :key="msg.id">
|
|
181
|
+
<strong>{{ msg.role }}:</strong> {{ msg.content }}
|
|
182
|
+
</div>
|
|
183
|
+
|
|
184
|
+
<input type="file" multiple @change="(e) => addFiles(e.target.files)" />
|
|
185
|
+
|
|
186
|
+
<div v-for="file in files" :key="file.id">
|
|
187
|
+
{{ file.name }} ({{ file.status }})
|
|
188
|
+
</div>
|
|
189
|
+
|
|
190
|
+
<button @click="sendMessage({ role: 'user', content: 'Hello!' })">Send</button>
|
|
191
|
+
<button @click="stopExecution">Stop</button>
|
|
192
|
+
</div>
|
|
193
|
+
</template>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## File Management
|
|
199
|
+
|
|
200
|
+
The `useThread()` composable provides file management capabilities:
|
|
201
|
+
|
|
202
|
+
```vue
|
|
203
|
+
<script setup lang="ts">
|
|
204
|
+
import { useThread } from '@standardagents/vue'
|
|
205
|
+
|
|
206
|
+
const { files, addFiles, removeFile, getPreviewUrl } = useThread()
|
|
207
|
+
|
|
208
|
+
const handleFileChange = (event: Event) => {
|
|
209
|
+
const input = event.target as HTMLInputElement
|
|
210
|
+
if (input.files) {
|
|
211
|
+
addFiles(input.files)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
</script>
|
|
215
|
+
|
|
216
|
+
<template>
|
|
217
|
+
<div>
|
|
218
|
+
<input type="file" multiple accept="image/*,.pdf,.txt" @change="handleFileChange" />
|
|
219
|
+
|
|
220
|
+
<div v-for="file in files" :key="file.id">
|
|
221
|
+
<img
|
|
222
|
+
v-if="file.isImage && file.status !== 'uploading'"
|
|
223
|
+
:src="getPreviewUrl(file) || ''"
|
|
224
|
+
:alt="file.name"
|
|
225
|
+
width="50"
|
|
226
|
+
/>
|
|
227
|
+
<span>{{ file.name }}</span>
|
|
228
|
+
<span>{{ file.status }}</span>
|
|
229
|
+
<span v-if="file.status === 'uploading'">Uploading...</span>
|
|
230
|
+
<span v-if="file.status === 'error'">Error: {{ file.error }}</span>
|
|
231
|
+
<button v-if="file.status !== 'committed'" @click="removeFile(file.id)">
|
|
232
|
+
Remove
|
|
233
|
+
</button>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
</template>
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### File States
|
|
240
|
+
|
|
241
|
+
- `uploading` - File is being uploaded
|
|
242
|
+
- `ready` - Upload complete, file ready to attach to message
|
|
243
|
+
- `committed` - File is attached to a sent message
|
|
244
|
+
- `error` - Upload failed
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Types
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
interface Message {
|
|
252
|
+
id: string
|
|
253
|
+
role: 'user' | 'assistant' | 'system' | 'tool'
|
|
254
|
+
content: string | null
|
|
255
|
+
created_at: number
|
|
256
|
+
attachments?: string // JSON array of AttachmentRef
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
interface SendMessagePayload {
|
|
260
|
+
role: 'user' | 'assistant' | 'system'
|
|
261
|
+
content: string
|
|
262
|
+
silent?: boolean
|
|
263
|
+
attachments?: string[] // Paths of files to attach
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
interface ThreadFile {
|
|
267
|
+
id: string
|
|
268
|
+
name: string
|
|
269
|
+
mimeType: string
|
|
270
|
+
size: number
|
|
271
|
+
isImage: boolean
|
|
272
|
+
status: 'uploading' | 'ready' | 'committed' | 'error'
|
|
273
|
+
error?: string
|
|
274
|
+
path?: string
|
|
275
|
+
localPreviewUrl: string | null
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'reconnecting'
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Complete Example
|
|
284
|
+
|
|
285
|
+
```vue
|
|
286
|
+
<script setup lang="ts">
|
|
287
|
+
import { onMounted } from 'vue'
|
|
288
|
+
import { ThreadProvider } from '@standardagents/vue'
|
|
289
|
+
|
|
290
|
+
onMounted(() => {
|
|
291
|
+
localStorage.setItem('agentbuilder_auth_token', 'your-token')
|
|
292
|
+
})
|
|
293
|
+
</script>
|
|
294
|
+
|
|
295
|
+
<template>
|
|
296
|
+
<ThreadProvider threadId="thread-123">
|
|
297
|
+
<AgentChat />
|
|
298
|
+
</ThreadProvider>
|
|
299
|
+
</template>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
```vue
|
|
303
|
+
<!-- AgentChat.vue -->
|
|
304
|
+
<script setup lang="ts">
|
|
305
|
+
import { ref } from 'vue'
|
|
306
|
+
import { useThread } from '@standardagents/vue'
|
|
307
|
+
|
|
308
|
+
const input = ref('')
|
|
309
|
+
|
|
310
|
+
const {
|
|
311
|
+
messages,
|
|
312
|
+
sendMessage,
|
|
313
|
+
stopExecution,
|
|
314
|
+
status,
|
|
315
|
+
isLoading,
|
|
316
|
+
files,
|
|
317
|
+
addFiles,
|
|
318
|
+
removeFile,
|
|
319
|
+
getPreviewUrl,
|
|
320
|
+
} = useThread()
|
|
321
|
+
|
|
322
|
+
const handleSend = async () => {
|
|
323
|
+
if (!input.value.trim()) return
|
|
324
|
+
await sendMessage({ role: 'user', content: input.value })
|
|
325
|
+
input.value = ''
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const handleFileChange = (event: Event) => {
|
|
329
|
+
const target = event.target as HTMLInputElement
|
|
330
|
+
if (target.files) addFiles(target.files)
|
|
331
|
+
}
|
|
332
|
+
</script>
|
|
333
|
+
|
|
334
|
+
<template>
|
|
335
|
+
<div>
|
|
336
|
+
<p v-if="isLoading">Loading messages...</p>
|
|
337
|
+
|
|
338
|
+
<div v-for="msg in messages" :key="msg.id">
|
|
339
|
+
<strong>{{ msg.role }}:</strong> {{ msg.content }}
|
|
340
|
+
</div>
|
|
341
|
+
|
|
342
|
+
<input type="file" multiple @change="handleFileChange" />
|
|
343
|
+
|
|
344
|
+
<div v-for="file in files.filter(f => f.status !== 'committed')" :key="file.id">
|
|
345
|
+
<img
|
|
346
|
+
v-if="file.isImage && getPreviewUrl(file)"
|
|
347
|
+
:src="getPreviewUrl(file)!"
|
|
348
|
+
:alt="file.name"
|
|
349
|
+
width="50"
|
|
350
|
+
/>
|
|
351
|
+
<span>{{ file.name }} ({{ file.status }})</span>
|
|
352
|
+
<button @click="removeFile(file.id)">x</button>
|
|
353
|
+
</div>
|
|
354
|
+
|
|
355
|
+
<div>
|
|
356
|
+
<input v-model="input" @keyup.enter="handleSend" />
|
|
357
|
+
<button @click="handleSend">Send</button>
|
|
358
|
+
<button @click="stopExecution">Stop</button>
|
|
359
|
+
<span>Status: {{ status }}</span>
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
</template>
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## TypeScript Support
|
|
368
|
+
|
|
369
|
+
The package includes full TypeScript definitions:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
import type {
|
|
373
|
+
Message,
|
|
374
|
+
SendMessagePayload,
|
|
375
|
+
ThreadFile,
|
|
376
|
+
ConnectionStatus,
|
|
377
|
+
ThreadContext,
|
|
378
|
+
} from '@standardagents/vue'
|
|
379
|
+
```
|