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:
john
2026-07-11 00:23:01 +08:00
parent e3063ea806
commit 32fb2cdeaf
51 changed files with 4588 additions and 186 deletions
+37
View File
@@ -2,6 +2,7 @@ import path from 'node:path';
import { DEFAULT_MAX_FILE_BYTES } from './mindspace.mjs';
import { createMindSpaceServiceFacade } from './mindspace-service.mjs';
import { createLocalMindSpaceStorageAdapter } from './mindspace-storage-adapter.mjs';
import { normalizeWorkspaceRelativePath } from './mindspace-workspace-relative-path.mjs';
import {
buildPublicUrl,
PUBLISH_ROOT_DIR,
@@ -10,6 +11,42 @@ import {
resolvePublishDir,
} from './user-publish.mjs';
export function resolvePageWorkspaceRelativePath(row) {
const fromColumn = normalizeWorkspaceRelativePath(row?.workspace_relative_path);
if (fromColumn) return fromColumn;
let snapshot = row?.source_snapshot_json;
if (typeof snapshot === 'string') {
try {
snapshot = JSON.parse(snapshot);
} catch {
snapshot = null;
}
}
return normalizeWorkspaceRelativePath(snapshot?.relative_path);
}
export function isPublicWorkspaceHtmlRelativePath(relativePath) {
const normalized = normalizeWorkspaceRelativePath(relativePath);
return Boolean(normalized?.startsWith('public/') && normalized.toLowerCase().endsWith('.html'));
}
/** MindSpace 工作区静态页 canonical 公网 URL/MindSpace/<用户ID>/public/... */
export function resolveWorkspaceMindSpacePublicUrl({
h5Root,
env = process.env,
userId,
relativePath,
} = {}) {
const normalized = normalizeWorkspaceRelativePath(relativePath);
if (!userId || !normalized || !isPublicWorkspaceHtmlRelativePath(normalized)) return null;
return buildMindSpacePublicUrlForUser({
h5Root: h5Root ?? process.cwd(),
env,
user: userId,
relativePath: normalized,
});
}
export function resolveMindSpaceStorageRoot(h5Root, env = process.env) {
return path.resolve(env.MINDSPACE_STORAGE_ROOT ?? path.join(h5Root, 'data', 'mindspace'));
}