@yeaft/webchat-agent 1.0.555 → 1.0.557
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/local-runtime/server/handlers/agent-output.js +28 -8
- package/local-runtime/server/yeaft-asset-store.js +41 -2
- package/local-runtime/version.json +1 -1
- package/local-runtime/web/app.bundle.js +138 -141
- package/local-runtime/web/app.bundle.js.gz +0 -0
- package/local-runtime/web/index.html +2 -2
- package/local-runtime/web/style.bundle.css +1 -1
- package/local-runtime/web/style.bundle.css.gz +0 -0
- package/package.json +1 -1
- package/yeaft/web-bridge.js +3 -1
- package/yeaft/work-center/projection.js +30 -0
|
@@ -170,19 +170,33 @@ function hydrateInlinePreviewData(data) {
|
|
|
170
170
|
return message === data.message ? data : { ...data, message };
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
function projectConfirmedAssetImages(messages, { ownerId, agentId, sessionId }) {
|
|
174
|
-
const turnIds = messages
|
|
175
|
-
.filter(message => message?.role === 'assistant'
|
|
173
|
+
export function projectConfirmedAssetImages(messages, { ownerId, agentId, sessionId }, assetStore = yeaftAssetStore) {
|
|
174
|
+
const turnIds = [...new Set(messages
|
|
175
|
+
.filter(message => message?.role === 'assistant')
|
|
176
176
|
.map(message => message.turnId || message.threadId || null)
|
|
177
|
-
.filter(Boolean);
|
|
178
|
-
const imagesByTurn =
|
|
177
|
+
.filter(Boolean))];
|
|
178
|
+
const imagesByTurn = assetStore.describeTurns({ ownerId, agentId, sessionId, turnIds });
|
|
179
179
|
return messages.map((message) => {
|
|
180
180
|
if (!message || message.role !== 'assistant') return message;
|
|
181
181
|
const { images: _pendingImages, ...rest } = message;
|
|
182
|
-
if (message.imageAssetAnchor !== true) return rest;
|
|
183
182
|
const turnId = message.turnId || message.threadId || null;
|
|
184
183
|
const images = turnId ? imagesByTurn.get(turnId) || [] : [];
|
|
185
|
-
|
|
184
|
+
const toolCallIds = new Set((Array.isArray(message.toolCalls) ? message.toolCalls : [])
|
|
185
|
+
.map(toolCall => toolCall?.id)
|
|
186
|
+
.filter(Boolean));
|
|
187
|
+
const vpId = message.speakerVpId || message.vpId || null;
|
|
188
|
+
const projectedImages = images.filter(image => {
|
|
189
|
+
if (image.vpId && image.vpId !== vpId) return false;
|
|
190
|
+
return image.sourceToolCallId
|
|
191
|
+
? toolCallIds.has(image.sourceToolCallId)
|
|
192
|
+
: message.imageAssetAnchor === true;
|
|
193
|
+
});
|
|
194
|
+
const toolOrder = [...toolCallIds];
|
|
195
|
+
projectedImages.sort((a, b) => (
|
|
196
|
+
toolOrder.indexOf(a.sourceToolCallId) - toolOrder.indexOf(b.sourceToolCallId)
|
|
197
|
+
|| (a.sourceImageIndex ?? 0) - (b.sourceImageIndex ?? 0)
|
|
198
|
+
));
|
|
199
|
+
return projectedImages.length > 0 ? { ...rest, images: projectedImages } : rest;
|
|
186
200
|
});
|
|
187
201
|
}
|
|
188
202
|
|
|
@@ -550,6 +564,8 @@ export async function handleAgentOutput(agentId, agent, msg) {
|
|
|
550
564
|
width: msg.metadata?.width ?? msg.image.width,
|
|
551
565
|
height: msg.metadata?.height ?? msg.image.height,
|
|
552
566
|
turnId: msg.turnId || null,
|
|
567
|
+
sourceToolCallId: msg.sourceToolCallId || null,
|
|
568
|
+
sourceImageIndex: msg.sourceImageIndex,
|
|
553
569
|
vpId: msg.vpId || null,
|
|
554
570
|
threadId: msg.threadId || null,
|
|
555
571
|
});
|
|
@@ -560,7 +576,11 @@ export async function handleAgentOutput(agentId, agent, msg) {
|
|
|
560
576
|
...(msg.vpId ? { vpId: msg.vpId } : {}),
|
|
561
577
|
...(msg.turnId ? { turnId: msg.turnId } : {}),
|
|
562
578
|
...(msg.threadId ? { threadId: msg.threadId } : {}),
|
|
563
|
-
image
|
|
579
|
+
image: msg.sourceToolCallId
|
|
580
|
+
? { ...image, sourceToolCallId: msg.sourceToolCallId,
|
|
581
|
+
...(Number.isInteger(msg.sourceImageIndex) && msg.sourceImageIndex >= 0 ? { sourceImageIndex: msg.sourceImageIndex } : {}) }
|
|
582
|
+
: image,
|
|
583
|
+
_requestUserId: agent.ownerId,
|
|
564
584
|
});
|
|
565
585
|
ok = true;
|
|
566
586
|
} catch (err) {
|
|
@@ -196,7 +196,7 @@ export function createYeaftAssetStore({
|
|
|
196
196
|
collectGarbage();
|
|
197
197
|
|
|
198
198
|
return {
|
|
199
|
-
put({ ownerId, agentId, sessionId, assetId, data, mimeType, filename, width = null, height = null, turnId = null, vpId = null, threadId = null }) {
|
|
199
|
+
put({ ownerId, agentId, sessionId, assetId, data, mimeType, filename, width = null, height = null, turnId = null, vpId = null, threadId = null, sourceToolCallId = null, sourceImageIndex = null }) {
|
|
200
200
|
if (!ownerId || !agentId || !sessionId) throw new Error('Asset owner, agent, and Session are required');
|
|
201
201
|
const buffer = Buffer.isBuffer(data) ? data : Buffer.from(String(data || ''), 'base64');
|
|
202
202
|
if (!buffer.length || buffer.length > MAX_ASSET_BYTES) throw new Error(`Image asset must be between 1 byte and ${MAX_ASSET_BYTES} bytes`);
|
|
@@ -222,6 +222,25 @@ export function createYeaftAssetStore({
|
|
|
222
222
|
if (duplicate) {
|
|
223
223
|
try { existing = JSON.parse(readFileSync(paths.meta, 'utf8')); } catch { /* rewrite below */ }
|
|
224
224
|
}
|
|
225
|
+
// An asset is content-addressed, but each use owns its own turn/tool/VP
|
|
226
|
+
// anchor. Preserve old unanchored uses when the same pixels are uploaded again.
|
|
227
|
+
const turnAssociations = Array.isArray(existing?.turnAssociations)
|
|
228
|
+
? existing.turnAssociations.filter(association => association
|
|
229
|
+
&& typeof association.turnId === 'string' && association.turnId)
|
|
230
|
+
: [...new Set([existing?.turnId, ...(existing?.turnIds || [])].filter(Boolean))]
|
|
231
|
+
.map(legacyTurnId => ({ turnId: legacyTurnId }));
|
|
232
|
+
if (turnId) {
|
|
233
|
+
const association = {
|
|
234
|
+
turnId,
|
|
235
|
+
...(typeof sourceToolCallId === 'string' && sourceToolCallId ? { sourceToolCallId } : {}),
|
|
236
|
+
...(Number.isInteger(sourceImageIndex) && sourceImageIndex >= 0 ? { sourceImageIndex } : {}),
|
|
237
|
+
...(vpId ? { vpId } : {}),
|
|
238
|
+
};
|
|
239
|
+
if (!turnAssociations.some(item => item.turnId === association.turnId
|
|
240
|
+
&& item.sourceToolCallId === association.sourceToolCallId
|
|
241
|
+
&& item.sourceImageIndex === association.sourceImageIndex
|
|
242
|
+
&& item.vpId === association.vpId)) turnAssociations.push(association);
|
|
243
|
+
}
|
|
225
244
|
const metadata = {
|
|
226
245
|
assetId: computedAssetId,
|
|
227
246
|
scopeId,
|
|
@@ -238,6 +257,7 @@ export function createYeaftAssetStore({
|
|
|
238
257
|
...(existing?.turnId ? [existing.turnId] : []),
|
|
239
258
|
...(turnId ? [turnId] : []),
|
|
240
259
|
])],
|
|
260
|
+
turnAssociations,
|
|
241
261
|
vpId: vpId || existing?.vpId || null,
|
|
242
262
|
threadId: threadId || existing?.threadId || null,
|
|
243
263
|
createdAt: Number(existing?.createdAt) || now(),
|
|
@@ -305,12 +325,31 @@ export function createYeaftAssetStore({
|
|
|
305
325
|
const associatedTurns = new Set([
|
|
306
326
|
...(row.metadata.turnId ? [row.metadata.turnId] : []),
|
|
307
327
|
...(Array.isArray(row.metadata.turnIds) ? row.metadata.turnIds : []),
|
|
328
|
+
...(Array.isArray(row.metadata.turnAssociations)
|
|
329
|
+
? row.metadata.turnAssociations.map(association => association?.turnId)
|
|
330
|
+
: []),
|
|
308
331
|
]);
|
|
309
332
|
const matches = Array.from(associatedTurns).filter(turnId => requested.has(turnId));
|
|
310
333
|
if (matches.length === 0) continue;
|
|
311
334
|
const image = this.describe({ ownerId, agentId, sessionId, assetId: row.metadata.assetId });
|
|
312
335
|
if (!image) continue;
|
|
313
|
-
for (const turnId of matches)
|
|
336
|
+
for (const turnId of matches) {
|
|
337
|
+
const associations = Array.isArray(row.metadata.turnAssociations)
|
|
338
|
+
? row.metadata.turnAssociations.filter(association => association?.turnId === turnId)
|
|
339
|
+
: [];
|
|
340
|
+
if (associations.length > 0) {
|
|
341
|
+
for (const association of associations) {
|
|
342
|
+
result.get(turnId).push({
|
|
343
|
+
...image,
|
|
344
|
+
...(association.sourceToolCallId ? { sourceToolCallId: association.sourceToolCallId } : {}),
|
|
345
|
+
...(Number.isInteger(association.sourceImageIndex) ? { sourceImageIndex: association.sourceImageIndex } : {}),
|
|
346
|
+
...(association.vpId ? { vpId: association.vpId } : {}),
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
result.get(turnId).push(image);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
314
353
|
}
|
|
315
354
|
return result;
|
|
316
355
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.0.
|
|
1
|
+
{"version":"1.0.557"}
|