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
+61
View File
@@ -100,6 +100,35 @@ function createAdminLayoutPool(adminRow) {
};
}
function createRoleSkillSeedPool(adminRow, { existingRoleSkills = {} } = {}) {
const roleSkills = { ...existingRoleSkills };
const roleSkillSeedSql = [];
const basePool = createAdminLayoutPool(adminRow);
return {
roleSkills,
roleSkillSeedSql,
async query(sql, params = []) {
if (
sql.includes('INSERT INTO h5_user_skill_grants') &&
sql.includes("VALUES ('role', 'user'")
) {
roleSkillSeedSql.push(sql);
const [skillName, enabled] = params;
if (skillName in roleSkills) {
if (!sql.includes('ON DUPLICATE KEY UPDATE skill_name = skill_name')) {
roleSkills[skillName] = enabled;
}
} else {
roleSkills[skillName] = enabled;
}
return [[]];
}
return basePool.query(sql, params);
},
};
}
function createAgentPolicyPool(userRow) {
return {
async query(sql, params = []) {
@@ -290,6 +319,38 @@ test('ensureAdminUser repairs existing admin workspace without password env', as
assert.equal(adminRow.workspace_root, path.join(root, 'MindSpace', adminRow.id));
});
test('ensureAdminUser seedRoleSkillDefaults preserves admin-configured role skill grants', async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'memind-role-skill-seed-'));
const adminRow = {
id: 'admin-3',
username: 'admin',
slug: 'admin',
email: 'admin@example.com',
display_name: '管理员',
role: 'admin',
status: 'active',
plan_type: 'free',
workspace_root: path.join(root, 'MindSpace', 'admin-3'),
balance_cents: 0,
tokens_used: 0,
};
const pool = createRoleSkillSeedPool(adminRow, {
existingRoleSkills: { 'static-page-publish': 1 },
});
const auth = createUserAuth(pool, {
h5Root: root,
env: { H5_PUBLIC_BASE_URL: 'https://example.com' },
persistSessions: false,
});
await auth.ensureAdminUser();
assert.equal(pool.roleSkills['static-page-publish'], 1);
assert.ok(pool.roleSkillSeedSql.length > 0);
assert.match(pool.roleSkillSeedSql[0], /ON DUPLICATE KEY UPDATE skill_name = skill_name/);
assert.doesNotMatch(pool.roleSkillSeedSql.join('\n'), /ON DUPLICATE KEY UPDATE enabled = VALUES\(enabled\)/);
});
test('agent session policy preserves sandbox root and exposes workspace ref metadata', async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'memind-agent-policy-'));
const userRow = {