@standardagents/vue 0.10.1-dev.cea2b66 → 0.10.1-dev.d2d335e
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.cjs +84 -25
- package/dist/index.d.cts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +84 -25
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,18 @@ function useStandardAgents() {
|
|
|
35
35
|
|
|
36
36
|
// src/composables/useThreadSetup.ts
|
|
37
37
|
var uploadManager = new client.FileUploadManager();
|
|
38
|
+
function fileToBase64(file) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const reader = new FileReader();
|
|
41
|
+
reader.onload = () => {
|
|
42
|
+
const result = reader.result;
|
|
43
|
+
const base64 = result.split(",")[1];
|
|
44
|
+
resolve(base64);
|
|
45
|
+
};
|
|
46
|
+
reader.onerror = () => reject(new Error("Failed to read file"));
|
|
47
|
+
reader.readAsDataURL(file);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
38
50
|
function useThreadSetup(threadId, options = {}) {
|
|
39
51
|
const {
|
|
40
52
|
preload = true,
|
|
@@ -58,6 +70,7 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
58
70
|
const isLoading = vue.ref(preload);
|
|
59
71
|
const error = vue.ref(null);
|
|
60
72
|
const pendingFiles = vue.ref([]);
|
|
73
|
+
const attachments = vue.ref([]);
|
|
61
74
|
const committedFiles = vue.computed(() => {
|
|
62
75
|
return client.messagesToFiles(messages.value);
|
|
63
76
|
});
|
|
@@ -128,44 +141,53 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
128
141
|
}, { depth, includeSilent });
|
|
129
142
|
connectionManager.connect();
|
|
130
143
|
}
|
|
131
|
-
function buildOptimisticAttachments(attachmentPaths) {
|
|
132
|
-
if (!attachmentPaths || attachmentPaths.length === 0) return null;
|
|
133
|
-
const refs = attachmentPaths.map((path) => {
|
|
134
|
-
const file = pendingFiles.value.find((f) => f.path === path);
|
|
135
|
-
const ref2 = {
|
|
136
|
-
id: path,
|
|
137
|
-
type: "file",
|
|
138
|
-
path,
|
|
139
|
-
name: file?.name || path.split("/").pop() || "file",
|
|
140
|
-
mimeType: file?.mimeType || "application/octet-stream",
|
|
141
|
-
size: file?.size || 0
|
|
142
|
-
};
|
|
143
|
-
if (file?.isImage) {
|
|
144
|
-
if (file.width) ref2.width = file.width;
|
|
145
|
-
if (file.height) ref2.height = file.height;
|
|
146
|
-
if (file.localPreviewUrl) ref2.localPreviewUrl = file.localPreviewUrl;
|
|
147
|
-
}
|
|
148
|
-
return ref2;
|
|
149
|
-
});
|
|
150
|
-
return JSON.stringify(refs);
|
|
151
|
-
}
|
|
152
144
|
async function sendMessage(payload) {
|
|
153
145
|
const optimisticId = `optimistic-${crypto.randomUUID()}`;
|
|
146
|
+
const optimisticAttachments = attachments.value.map((a) => ({
|
|
147
|
+
id: a.id,
|
|
148
|
+
type: "file",
|
|
149
|
+
path: "",
|
|
150
|
+
// No path yet - will be assigned by server
|
|
151
|
+
name: a.name,
|
|
152
|
+
mimeType: a.mimeType,
|
|
153
|
+
size: a.size,
|
|
154
|
+
width: a.width,
|
|
155
|
+
height: a.height,
|
|
156
|
+
localPreviewUrl: a.previewUrl || void 0
|
|
157
|
+
}));
|
|
154
158
|
const optimisticMessage = {
|
|
155
159
|
id: optimisticId,
|
|
156
160
|
role: payload.role,
|
|
157
161
|
content: payload.content,
|
|
158
|
-
attachments:
|
|
162
|
+
attachments: optimisticAttachments.length > 0 ? JSON.stringify(optimisticAttachments) : null,
|
|
159
163
|
created_at: Date.now() * 1e3,
|
|
160
164
|
// microseconds
|
|
161
165
|
status: "pending"
|
|
162
166
|
};
|
|
163
167
|
messages.value = [...messages.value, optimisticMessage];
|
|
168
|
+
const currentAttachments = [...attachments.value];
|
|
169
|
+
attachments.value = [];
|
|
164
170
|
try {
|
|
165
|
-
const
|
|
171
|
+
const attachmentPayloads = await Promise.all(
|
|
172
|
+
currentAttachments.map(async (a) => ({
|
|
173
|
+
name: a.name,
|
|
174
|
+
mimeType: a.mimeType,
|
|
175
|
+
data: await fileToBase64(a.file),
|
|
176
|
+
width: a.width,
|
|
177
|
+
height: a.height
|
|
178
|
+
}))
|
|
179
|
+
);
|
|
180
|
+
const result = await client$1.sendMessage(threadId, {
|
|
181
|
+
...payload,
|
|
182
|
+
attachments: attachmentPayloads.length > 0 ? attachmentPayloads : void 0
|
|
183
|
+
});
|
|
166
184
|
messages.value = messages.value.filter((m) => m.id !== optimisticId);
|
|
185
|
+
currentAttachments.forEach((a) => {
|
|
186
|
+
if (a.previewUrl) URL.revokeObjectURL(a.previewUrl);
|
|
187
|
+
});
|
|
167
188
|
return result;
|
|
168
189
|
} catch (err) {
|
|
190
|
+
attachments.value = currentAttachments;
|
|
169
191
|
messages.value = messages.value.filter((m) => m.id !== optimisticId);
|
|
170
192
|
error.value = err instanceof Error ? err : new Error(String(err));
|
|
171
193
|
throw err;
|
|
@@ -218,6 +240,35 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
218
240
|
}
|
|
219
241
|
return null;
|
|
220
242
|
}
|
|
243
|
+
function addAttachment(input) {
|
|
244
|
+
const filesToAdd = input instanceof FileList ? Array.from(input) : Array.isArray(input) ? input : [input];
|
|
245
|
+
const newAttachments = filesToAdd.map((file) => {
|
|
246
|
+
const isImage = file.type.startsWith("image/");
|
|
247
|
+
return {
|
|
248
|
+
id: crypto.randomUUID(),
|
|
249
|
+
file,
|
|
250
|
+
name: file.name,
|
|
251
|
+
mimeType: file.type,
|
|
252
|
+
size: file.size,
|
|
253
|
+
isImage,
|
|
254
|
+
previewUrl: isImage ? URL.createObjectURL(file) : null
|
|
255
|
+
};
|
|
256
|
+
});
|
|
257
|
+
attachments.value = [...attachments.value, ...newAttachments];
|
|
258
|
+
}
|
|
259
|
+
function removeAttachment(id) {
|
|
260
|
+
const attachment = attachments.value.find((a) => a.id === id);
|
|
261
|
+
if (attachment?.previewUrl) {
|
|
262
|
+
URL.revokeObjectURL(attachment.previewUrl);
|
|
263
|
+
}
|
|
264
|
+
attachments.value = attachments.value.filter((a) => a.id !== id);
|
|
265
|
+
}
|
|
266
|
+
function clearAttachments() {
|
|
267
|
+
attachments.value.forEach((a) => {
|
|
268
|
+
if (a.previewUrl) URL.revokeObjectURL(a.previewUrl);
|
|
269
|
+
});
|
|
270
|
+
attachments.value = [];
|
|
271
|
+
}
|
|
221
272
|
function onEvent(eventType, callback) {
|
|
222
273
|
if (!eventHandlers.has(eventType)) {
|
|
223
274
|
eventHandlers.set(eventType, /* @__PURE__ */ new Set());
|
|
@@ -242,6 +293,9 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
242
293
|
vue.onUnmounted(() => {
|
|
243
294
|
connectionManager?.disconnect();
|
|
244
295
|
eventHandlers.clear();
|
|
296
|
+
attachments.value.forEach((a) => {
|
|
297
|
+
if (a.previewUrl) URL.revokeObjectURL(a.previewUrl);
|
|
298
|
+
});
|
|
245
299
|
});
|
|
246
300
|
return {
|
|
247
301
|
threadId,
|
|
@@ -260,13 +314,18 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
260
314
|
onEvent,
|
|
261
315
|
subscribeToEvent: onEvent,
|
|
262
316
|
// alias
|
|
263
|
-
// File management
|
|
317
|
+
// File management (uploads to filesystem)
|
|
264
318
|
files,
|
|
265
319
|
addFiles,
|
|
266
320
|
removeFile,
|
|
267
321
|
getFileUrl,
|
|
268
322
|
getThumbnailUrl,
|
|
269
|
-
getPreviewUrl
|
|
323
|
+
getPreviewUrl,
|
|
324
|
+
// Attachment management (sent inline with messages)
|
|
325
|
+
attachments,
|
|
326
|
+
addAttachment,
|
|
327
|
+
removeAttachment,
|
|
328
|
+
clearAttachments
|
|
270
329
|
};
|
|
271
330
|
}
|
|
272
331
|
|
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as vue from 'vue';
|
|
2
2
|
import { Ref, ComputedRef, InjectionKey, Plugin, PropType } from 'vue';
|
|
3
3
|
import * as _standardagents_client from '@standardagents/client';
|
|
4
|
-
import { AgentBuilderClient, SendMessagePayload, Message, ThreadFile } from '@standardagents/client';
|
|
5
|
-
export { AgentBuilderClient, AttachmentRef, ConnectionStatus, FileUploadManager, GetMessagesOptions, Message, SendMessagePayload, Thread, ThreadConnectionCallbacks, ThreadConnectionManager, ThreadConnectionOptions, ThreadFile, ThreadMessage, WorkItem, WorkMessage, generatePendingFileId, isImageMimeType, messagesToFiles, parseAttachments, readFileAsDataUrl, transformToWorkblocks } from '@standardagents/client';
|
|
4
|
+
import { AgentBuilderClient, SendMessagePayload, Message, ThreadFile, PendingAttachment } from '@standardagents/client';
|
|
5
|
+
export { AgentBuilderClient, AttachmentPayload, AttachmentRef, ConnectionStatus, FileUploadManager, GetMessagesOptions, Message, PendingAttachment, SendMessagePayload, Thread, ThreadConnectionCallbacks, ThreadConnectionManager, ThreadConnectionOptions, ThreadFile, ThreadMessage, WorkItem, WorkMessage, generatePendingFileId, isImageMimeType, messagesToFiles, parseAttachments, readFileAsDataUrl, transformToWorkblocks } from '@standardagents/client';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Configuration for the StandardAgents plugin
|
|
@@ -57,8 +57,8 @@ interface ThreadContext {
|
|
|
57
57
|
loading: Ref<boolean>;
|
|
58
58
|
/** Any error that occurred */
|
|
59
59
|
error: Ref<Error | null>;
|
|
60
|
-
/** Send a message to the thread */
|
|
61
|
-
sendMessage: (payload: SendMessagePayload) => Promise<Message>;
|
|
60
|
+
/** Send a message to the thread (auto-includes pending attachments) */
|
|
61
|
+
sendMessage: (payload: Omit<SendMessagePayload, 'attachments'>) => Promise<Message>;
|
|
62
62
|
/** Stop the current execution */
|
|
63
63
|
stopExecution: () => Promise<void>;
|
|
64
64
|
/** Subscribe to custom events */
|
|
@@ -67,7 +67,7 @@ interface ThreadContext {
|
|
|
67
67
|
subscribeToEvent: <T = unknown>(eventType: string, callback: (data: T) => void) => () => void;
|
|
68
68
|
/** All files in the thread (pending uploads + committed from messages) */
|
|
69
69
|
files: ComputedRef<ThreadFile[]>;
|
|
70
|
-
/** Add files and start uploading immediately */
|
|
70
|
+
/** Add files and start uploading immediately to filesystem */
|
|
71
71
|
addFiles: (files: File[] | FileList) => void;
|
|
72
72
|
/** Remove a pending file (cannot remove committed files) */
|
|
73
73
|
removeFile: (id: string) => void;
|
|
@@ -77,6 +77,14 @@ interface ThreadContext {
|
|
|
77
77
|
getThumbnailUrl: (file: ThreadFile) => string;
|
|
78
78
|
/** Get preview URL - localPreviewUrl for pending images, thumbnail for committed */
|
|
79
79
|
getPreviewUrl: (file: ThreadFile) => string | null;
|
|
80
|
+
/** Pending attachments to be sent with next message */
|
|
81
|
+
attachments: Ref<PendingAttachment[]>;
|
|
82
|
+
/** Add attachment(s) to be sent with next message (no upload, stored locally) */
|
|
83
|
+
addAttachment: (files: File | File[] | FileList) => void;
|
|
84
|
+
/** Remove a pending attachment */
|
|
85
|
+
removeAttachment: (id: string) => void;
|
|
86
|
+
/** Clear all pending attachments */
|
|
87
|
+
clearAttachments: () => void;
|
|
80
88
|
}
|
|
81
89
|
/**
|
|
82
90
|
* Options for useThread composable
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as vue from 'vue';
|
|
2
2
|
import { Ref, ComputedRef, InjectionKey, Plugin, PropType } from 'vue';
|
|
3
3
|
import * as _standardagents_client from '@standardagents/client';
|
|
4
|
-
import { AgentBuilderClient, SendMessagePayload, Message, ThreadFile } from '@standardagents/client';
|
|
5
|
-
export { AgentBuilderClient, AttachmentRef, ConnectionStatus, FileUploadManager, GetMessagesOptions, Message, SendMessagePayload, Thread, ThreadConnectionCallbacks, ThreadConnectionManager, ThreadConnectionOptions, ThreadFile, ThreadMessage, WorkItem, WorkMessage, generatePendingFileId, isImageMimeType, messagesToFiles, parseAttachments, readFileAsDataUrl, transformToWorkblocks } from '@standardagents/client';
|
|
4
|
+
import { AgentBuilderClient, SendMessagePayload, Message, ThreadFile, PendingAttachment } from '@standardagents/client';
|
|
5
|
+
export { AgentBuilderClient, AttachmentPayload, AttachmentRef, ConnectionStatus, FileUploadManager, GetMessagesOptions, Message, PendingAttachment, SendMessagePayload, Thread, ThreadConnectionCallbacks, ThreadConnectionManager, ThreadConnectionOptions, ThreadFile, ThreadMessage, WorkItem, WorkMessage, generatePendingFileId, isImageMimeType, messagesToFiles, parseAttachments, readFileAsDataUrl, transformToWorkblocks } from '@standardagents/client';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Configuration for the StandardAgents plugin
|
|
@@ -57,8 +57,8 @@ interface ThreadContext {
|
|
|
57
57
|
loading: Ref<boolean>;
|
|
58
58
|
/** Any error that occurred */
|
|
59
59
|
error: Ref<Error | null>;
|
|
60
|
-
/** Send a message to the thread */
|
|
61
|
-
sendMessage: (payload: SendMessagePayload) => Promise<Message>;
|
|
60
|
+
/** Send a message to the thread (auto-includes pending attachments) */
|
|
61
|
+
sendMessage: (payload: Omit<SendMessagePayload, 'attachments'>) => Promise<Message>;
|
|
62
62
|
/** Stop the current execution */
|
|
63
63
|
stopExecution: () => Promise<void>;
|
|
64
64
|
/** Subscribe to custom events */
|
|
@@ -67,7 +67,7 @@ interface ThreadContext {
|
|
|
67
67
|
subscribeToEvent: <T = unknown>(eventType: string, callback: (data: T) => void) => () => void;
|
|
68
68
|
/** All files in the thread (pending uploads + committed from messages) */
|
|
69
69
|
files: ComputedRef<ThreadFile[]>;
|
|
70
|
-
/** Add files and start uploading immediately */
|
|
70
|
+
/** Add files and start uploading immediately to filesystem */
|
|
71
71
|
addFiles: (files: File[] | FileList) => void;
|
|
72
72
|
/** Remove a pending file (cannot remove committed files) */
|
|
73
73
|
removeFile: (id: string) => void;
|
|
@@ -77,6 +77,14 @@ interface ThreadContext {
|
|
|
77
77
|
getThumbnailUrl: (file: ThreadFile) => string;
|
|
78
78
|
/** Get preview URL - localPreviewUrl for pending images, thumbnail for committed */
|
|
79
79
|
getPreviewUrl: (file: ThreadFile) => string | null;
|
|
80
|
+
/** Pending attachments to be sent with next message */
|
|
81
|
+
attachments: Ref<PendingAttachment[]>;
|
|
82
|
+
/** Add attachment(s) to be sent with next message (no upload, stored locally) */
|
|
83
|
+
addAttachment: (files: File | File[] | FileList) => void;
|
|
84
|
+
/** Remove a pending attachment */
|
|
85
|
+
removeAttachment: (id: string) => void;
|
|
86
|
+
/** Clear all pending attachments */
|
|
87
|
+
clearAttachments: () => void;
|
|
80
88
|
}
|
|
81
89
|
/**
|
|
82
90
|
* Options for useThread composable
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,18 @@ function useStandardAgents() {
|
|
|
34
34
|
|
|
35
35
|
// src/composables/useThreadSetup.ts
|
|
36
36
|
var uploadManager = new FileUploadManager();
|
|
37
|
+
function fileToBase64(file) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
const reader = new FileReader();
|
|
40
|
+
reader.onload = () => {
|
|
41
|
+
const result = reader.result;
|
|
42
|
+
const base64 = result.split(",")[1];
|
|
43
|
+
resolve(base64);
|
|
44
|
+
};
|
|
45
|
+
reader.onerror = () => reject(new Error("Failed to read file"));
|
|
46
|
+
reader.readAsDataURL(file);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
37
49
|
function useThreadSetup(threadId, options = {}) {
|
|
38
50
|
const {
|
|
39
51
|
preload = true,
|
|
@@ -57,6 +69,7 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
57
69
|
const isLoading = ref(preload);
|
|
58
70
|
const error = ref(null);
|
|
59
71
|
const pendingFiles = ref([]);
|
|
72
|
+
const attachments = ref([]);
|
|
60
73
|
const committedFiles = computed(() => {
|
|
61
74
|
return messagesToFiles(messages.value);
|
|
62
75
|
});
|
|
@@ -127,44 +140,53 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
127
140
|
}, { depth, includeSilent });
|
|
128
141
|
connectionManager.connect();
|
|
129
142
|
}
|
|
130
|
-
function buildOptimisticAttachments(attachmentPaths) {
|
|
131
|
-
if (!attachmentPaths || attachmentPaths.length === 0) return null;
|
|
132
|
-
const refs = attachmentPaths.map((path) => {
|
|
133
|
-
const file = pendingFiles.value.find((f) => f.path === path);
|
|
134
|
-
const ref2 = {
|
|
135
|
-
id: path,
|
|
136
|
-
type: "file",
|
|
137
|
-
path,
|
|
138
|
-
name: file?.name || path.split("/").pop() || "file",
|
|
139
|
-
mimeType: file?.mimeType || "application/octet-stream",
|
|
140
|
-
size: file?.size || 0
|
|
141
|
-
};
|
|
142
|
-
if (file?.isImage) {
|
|
143
|
-
if (file.width) ref2.width = file.width;
|
|
144
|
-
if (file.height) ref2.height = file.height;
|
|
145
|
-
if (file.localPreviewUrl) ref2.localPreviewUrl = file.localPreviewUrl;
|
|
146
|
-
}
|
|
147
|
-
return ref2;
|
|
148
|
-
});
|
|
149
|
-
return JSON.stringify(refs);
|
|
150
|
-
}
|
|
151
143
|
async function sendMessage(payload) {
|
|
152
144
|
const optimisticId = `optimistic-${crypto.randomUUID()}`;
|
|
145
|
+
const optimisticAttachments = attachments.value.map((a) => ({
|
|
146
|
+
id: a.id,
|
|
147
|
+
type: "file",
|
|
148
|
+
path: "",
|
|
149
|
+
// No path yet - will be assigned by server
|
|
150
|
+
name: a.name,
|
|
151
|
+
mimeType: a.mimeType,
|
|
152
|
+
size: a.size,
|
|
153
|
+
width: a.width,
|
|
154
|
+
height: a.height,
|
|
155
|
+
localPreviewUrl: a.previewUrl || void 0
|
|
156
|
+
}));
|
|
153
157
|
const optimisticMessage = {
|
|
154
158
|
id: optimisticId,
|
|
155
159
|
role: payload.role,
|
|
156
160
|
content: payload.content,
|
|
157
|
-
attachments:
|
|
161
|
+
attachments: optimisticAttachments.length > 0 ? JSON.stringify(optimisticAttachments) : null,
|
|
158
162
|
created_at: Date.now() * 1e3,
|
|
159
163
|
// microseconds
|
|
160
164
|
status: "pending"
|
|
161
165
|
};
|
|
162
166
|
messages.value = [...messages.value, optimisticMessage];
|
|
167
|
+
const currentAttachments = [...attachments.value];
|
|
168
|
+
attachments.value = [];
|
|
163
169
|
try {
|
|
164
|
-
const
|
|
170
|
+
const attachmentPayloads = await Promise.all(
|
|
171
|
+
currentAttachments.map(async (a) => ({
|
|
172
|
+
name: a.name,
|
|
173
|
+
mimeType: a.mimeType,
|
|
174
|
+
data: await fileToBase64(a.file),
|
|
175
|
+
width: a.width,
|
|
176
|
+
height: a.height
|
|
177
|
+
}))
|
|
178
|
+
);
|
|
179
|
+
const result = await client.sendMessage(threadId, {
|
|
180
|
+
...payload,
|
|
181
|
+
attachments: attachmentPayloads.length > 0 ? attachmentPayloads : void 0
|
|
182
|
+
});
|
|
165
183
|
messages.value = messages.value.filter((m) => m.id !== optimisticId);
|
|
184
|
+
currentAttachments.forEach((a) => {
|
|
185
|
+
if (a.previewUrl) URL.revokeObjectURL(a.previewUrl);
|
|
186
|
+
});
|
|
166
187
|
return result;
|
|
167
188
|
} catch (err) {
|
|
189
|
+
attachments.value = currentAttachments;
|
|
168
190
|
messages.value = messages.value.filter((m) => m.id !== optimisticId);
|
|
169
191
|
error.value = err instanceof Error ? err : new Error(String(err));
|
|
170
192
|
throw err;
|
|
@@ -217,6 +239,35 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
217
239
|
}
|
|
218
240
|
return null;
|
|
219
241
|
}
|
|
242
|
+
function addAttachment(input) {
|
|
243
|
+
const filesToAdd = input instanceof FileList ? Array.from(input) : Array.isArray(input) ? input : [input];
|
|
244
|
+
const newAttachments = filesToAdd.map((file) => {
|
|
245
|
+
const isImage = file.type.startsWith("image/");
|
|
246
|
+
return {
|
|
247
|
+
id: crypto.randomUUID(),
|
|
248
|
+
file,
|
|
249
|
+
name: file.name,
|
|
250
|
+
mimeType: file.type,
|
|
251
|
+
size: file.size,
|
|
252
|
+
isImage,
|
|
253
|
+
previewUrl: isImage ? URL.createObjectURL(file) : null
|
|
254
|
+
};
|
|
255
|
+
});
|
|
256
|
+
attachments.value = [...attachments.value, ...newAttachments];
|
|
257
|
+
}
|
|
258
|
+
function removeAttachment(id) {
|
|
259
|
+
const attachment = attachments.value.find((a) => a.id === id);
|
|
260
|
+
if (attachment?.previewUrl) {
|
|
261
|
+
URL.revokeObjectURL(attachment.previewUrl);
|
|
262
|
+
}
|
|
263
|
+
attachments.value = attachments.value.filter((a) => a.id !== id);
|
|
264
|
+
}
|
|
265
|
+
function clearAttachments() {
|
|
266
|
+
attachments.value.forEach((a) => {
|
|
267
|
+
if (a.previewUrl) URL.revokeObjectURL(a.previewUrl);
|
|
268
|
+
});
|
|
269
|
+
attachments.value = [];
|
|
270
|
+
}
|
|
220
271
|
function onEvent(eventType, callback) {
|
|
221
272
|
if (!eventHandlers.has(eventType)) {
|
|
222
273
|
eventHandlers.set(eventType, /* @__PURE__ */ new Set());
|
|
@@ -241,6 +292,9 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
241
292
|
onUnmounted(() => {
|
|
242
293
|
connectionManager?.disconnect();
|
|
243
294
|
eventHandlers.clear();
|
|
295
|
+
attachments.value.forEach((a) => {
|
|
296
|
+
if (a.previewUrl) URL.revokeObjectURL(a.previewUrl);
|
|
297
|
+
});
|
|
244
298
|
});
|
|
245
299
|
return {
|
|
246
300
|
threadId,
|
|
@@ -259,13 +313,18 @@ function useThreadSetup(threadId, options = {}) {
|
|
|
259
313
|
onEvent,
|
|
260
314
|
subscribeToEvent: onEvent,
|
|
261
315
|
// alias
|
|
262
|
-
// File management
|
|
316
|
+
// File management (uploads to filesystem)
|
|
263
317
|
files,
|
|
264
318
|
addFiles,
|
|
265
319
|
removeFile,
|
|
266
320
|
getFileUrl,
|
|
267
321
|
getThumbnailUrl,
|
|
268
|
-
getPreviewUrl
|
|
322
|
+
getPreviewUrl,
|
|
323
|
+
// Attachment management (sent inline with messages)
|
|
324
|
+
attachments,
|
|
325
|
+
addAttachment,
|
|
326
|
+
removeAttachment,
|
|
327
|
+
clearAttachments
|
|
269
328
|
};
|
|
270
329
|
}
|
|
271
330
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standardagents/vue",
|
|
3
|
-
"version": "0.10.1-dev.
|
|
3
|
+
"version": "0.10.1-dev.d2d335e",
|
|
4
4
|
"description": "Vue SDK for Standard Agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@standardagents/client": "0.10.1-dev.
|
|
25
|
+
"@standardagents/client": "0.10.1-dev.d2d335e"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"vue": "^3.3.0"
|