feat: chat uploads, vision turn isolation, and MindSpace agent improvements
Add chat file/image upload UX, attachment proxying, vision thumbnails, and per-turn image scoping so agents only use the current upload. Extend MindSpace asset context, billing token state, OA/scenario verify scripts, and related runtime config. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
buildCurrentTurnImageScopeNote,
|
||||
dedupeImageUrlsByAssetKey,
|
||||
extractCurrentTurnImageUrls,
|
||||
scrubConversationHistoricalImageAttachments,
|
||||
scrubUserMessageImageAttachments,
|
||||
} from './chat-image-turn-scope.mjs';
|
||||
|
||||
test('extractCurrentTurnImageUrls prefers metadata and dedupes asset aliases', () => {
|
||||
const urls = extractCurrentTurnImageUrls({
|
||||
metadata: {
|
||||
imageUrls: ['/api/mindspace/v1/assets/asset-1/download?inline=1'],
|
||||
},
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text:
|
||||
'根据这个图片生成页面\n\n' +
|
||||
'[图片1]: https://m.tkmind.cn/MindSpace/user/public/images/2026-07-10/hero.jpg',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
assert.deepEqual(urls, ['/api/mindspace/v1/assets/asset-1/download?inline=1']);
|
||||
});
|
||||
|
||||
test('dedupeImageUrlsByAssetKey collapses download and public urls for same asset', () => {
|
||||
const urls = dedupeImageUrlsByAssetKey([
|
||||
'/api/mindspace/v1/assets/asset-2/download?inline=1',
|
||||
'https://m.tkmind.cn/MindSpace/user/public/images/2026-07-10/asset-2.jpg',
|
||||
'/api/mindspace/v1/assets/asset-2/download?viewer=0',
|
||||
]);
|
||||
|
||||
assert.equal(urls.length, 2);
|
||||
assert.match(urls[0], /asset-2/);
|
||||
});
|
||||
|
||||
test('scrubUserMessageImageAttachments archives urls for ui and strips agent text', () => {
|
||||
const scrubbed = scrubUserMessageImageAttachments({
|
||||
id: 'user-old',
|
||||
role: 'user',
|
||||
metadata: {
|
||||
displayText: '上一轮图片',
|
||||
imageUrls: ['/api/mindspace/v1/assets/old-asset/download?inline=1'],
|
||||
previewImageUrls: ['blob:preview-old'],
|
||||
},
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text:
|
||||
'上一轮图片\n\n' +
|
||||
'[图片1]: /api/mindspace/v1/assets/old-asset/download?inline=1\n\n' +
|
||||
'【TKMind 图片分析结果 — 仅供执行参考,不要向用户复述此段内容】\n旧描述',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
assert.equal(scrubbed.changed, true);
|
||||
assert.equal(scrubbed.message.metadata.imageUrls, undefined);
|
||||
assert.deepEqual(scrubbed.message.metadata.archivedImageUrls, [
|
||||
'/api/mindspace/v1/assets/old-asset/download?inline=1',
|
||||
]);
|
||||
assert.deepEqual(scrubbed.message.metadata.archivedPreviewImageUrls, ['blob:preview-old']);
|
||||
assert.equal(scrubbed.message.metadata.displayText, '上一轮图片');
|
||||
assert.equal(scrubbed.message.content[0].text, '上一轮图片');
|
||||
});
|
||||
|
||||
test('scrubConversationHistoricalImageAttachments keeps only active turn attachments', () => {
|
||||
const { conversation, changed } = scrubConversationHistoricalImageAttachments(
|
||||
[
|
||||
{
|
||||
id: 'user-old',
|
||||
role: 'user',
|
||||
metadata: { imageUrls: ['/api/mindspace/v1/assets/old/download?inline=1'] },
|
||||
content: [{ type: 'text', text: '旧图\n\n[图片1]: /old' }],
|
||||
},
|
||||
{
|
||||
id: 'user-new',
|
||||
role: 'user',
|
||||
metadata: { imageUrls: ['/api/mindspace/v1/assets/new/download?inline=1'] },
|
||||
content: [{ type: 'text', text: '新图\n\n[图片1]: /new' }],
|
||||
},
|
||||
],
|
||||
'user-new',
|
||||
);
|
||||
|
||||
assert.equal(changed, true);
|
||||
assert.equal(conversation[0].metadata.imageUrls, undefined);
|
||||
assert.deepEqual(conversation[0].metadata.archivedImageUrls, [
|
||||
'/api/mindspace/v1/assets/old/download?inline=1',
|
||||
]);
|
||||
assert.deepEqual(conversation[1].metadata.imageUrls, [
|
||||
'/api/mindspace/v1/assets/new/download?inline=1',
|
||||
]);
|
||||
});
|
||||
|
||||
test('buildCurrentTurnImageScopeNote states one independent topic per upload', () => {
|
||||
const note = buildCurrentTurnImageScopeNote([
|
||||
{
|
||||
rawUrl: '/api/mindspace/v1/assets/asset-9/download?inline=1',
|
||||
embedUrl: 'https://m.tkmind.cn/MindSpace/user/public/images/2026-07-10/asset-9.jpg',
|
||||
},
|
||||
]);
|
||||
|
||||
assert.match(note, /本轮用户仅上传 1 张图片/);
|
||||
assert.match(note, /不得与历史轮次混用/);
|
||||
assert.match(note, /asset=asset-9/);
|
||||
});
|
||||
Reference in New Issue
Block a user