Files
memind/mindspace-asset-agent-instructions.mjs
john 32fb2cdeaf 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>
2026-07-11 00:23:01 +08:00

112 lines
4.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
function resolveWorkspaceRelativePath(asset) {
const raw = asset?.workspaceRelativePath ?? asset?.workspace_relative_path ?? '';
const trimmed = String(raw).trim().replace(/^\.?\//, '');
if (!trimmed || trimmed.includes('..')) return null;
return trimmed;
}
function isSpreadsheetAsset(asset) {
const mime = String(asset?.mimeType ?? '').toLowerCase();
const name = String(asset?.displayName ?? asset?.filename ?? '').toLowerCase();
return (
mime.includes('spreadsheet')
|| mime.includes('csv')
|| name.endsWith('.xlsx')
|| name.endsWith('.xls')
|| name.endsWith('.csv')
);
}
function buildSpreadsheetAnalysisInstructions() {
return [
'【数据表汇总校验(硬性)】',
'- 分析数值汇总时,**必须**用 Python/pandas 等对源表列做 SUM,禁止手算或估算。',
'- 写入聊天回复或 HTML 报告前,自检:各分组明细之和必须与总计一致;不一致则重新计算后再输出。',
'',
];
}
export function buildSelectedAssetReadInstructions(context) {
const selected = context.selectedAssets ?? [];
if (selected.length !== 1) return [];
const asset = selected[0];
const h5ApiBase = String(context.h5ApiBase ?? '').replace(/\/$/, '');
const sessionId = String(context.agentSessionId ?? '').trim();
if (!h5ApiBase) return [];
const sessionToken = sessionId || '<CURRENT_AGENT_SESSION>';
const sessionHint = sessionId
? ''
: '- session_id 未写入上下文时,使用当前 Agent 会话 ID 替换 `<CURRENT_AGENT_SESSION>`。\n';
const workspacePath = resolveWorkspaceRelativePath(asset);
const lines = [
'【勾选资料读取(硬性)】',
`- 用户已勾选「${asset.displayName}」(id: ${asset.id}`,
'- **禁止** curl / fetch 浏览器登录接口 `GET /api/mindspace/v1/assets/:id/download`goosed 无 cookie,会 401',
];
if (workspacePath) {
lines.push(
`- **已落盘路径(硬性)**\`${workspacePath}\` — 直接 \`read_file ${workspacePath}\` 或脚本读取该路径`,
'- **禁止** list_dir / 工作目录探测 / 重复调用 mindspace_asset_download(文件已在工作区)',
'- 仅当读取该路径失败时,才允许调用下方 Agent 代理下载',
);
} else {
lines.push(
'- **优先**用 `list_dir oa` / `read_file` / `cat oa/文件名` 读取工作区已落盘副本',
);
}
lines.push(
sessionHint,
'- 若工作区尚无该文件,**必须**用 shell 调用 Agent 代理下载并落盘到 `oa/`',
'```bash',
`curl -sS -X POST '${h5ApiBase}/api/agent/mindspace_asset_download' \\`,
" -H 'Content-Type: application/json' \\",
` -d '{"session_id":"${sessionToken}","asset_id":"${asset.id}"}'`,
'```',
'- 成功后响应 JSON 含 `relativePath`(如 `oa/report.xlsx`),后续分析/引用只用该相对路径',
'- **禁止**访问其它用户目录、MindSpace 根目录或 `./MindSpace/<username>/` 等猜测路径',
'',
);
if (isSpreadsheetAsset(asset)) {
lines.push(...buildSpreadsheetAnalysisInstructions());
}
return lines.filter(Boolean);
}
export function buildSelectedAssetDeleteInstructions(context) {
const selected = context.selectedAssets ?? [];
if (selected.length !== 1) return [];
const asset = selected[0];
const h5ApiBase = String(context.h5ApiBase ?? '').replace(/\/$/, '');
const sessionId = String(context.agentSessionId ?? '').trim();
if (!h5ApiBase) return [];
const sessionToken = sessionId || '<CURRENT_AGENT_SESSION>';
const sessionHint = sessionId
? ''
: '- session_id 未写入上下文时,使用当前 Agent 会话 ID 替换 `<CURRENT_AGENT_SESSION>`。\n';
return [
'【勾选资料删除(硬性)】',
`- 你对用户 MindSpace 拥有完整读写删改权限;用户已勾选「${asset.displayName}」(id: ${asset.id})。`,
'- 用户要求删除这份资料时:先说明将删除哪一份并等待用户明确确认(如「确定」「删吧」「确认删除」);**禁止**未确认就删。',
sessionHint,
'- 用户确认后,**必须立即**用 shell 执行(不要只口头说已删,也不要让用户自己去界面点删除):',
'```bash',
`curl -sS -X POST '${h5ApiBase}/api/agent/mindspace_asset_delete' \\`,
" -H 'Content-Type: application/json' \\",
` -d '{"session_id":"${sessionToken}","asset_id":"${asset.id}","confirmed":true}'`,
'```',
'- curl 成功后再回复「已删除」;若返回 asset_in_use,说明被页面引用,告知用户先删关联页面。',
'- 禁止删除未勾选的其它文件。',
'',
].filter(Boolean);
}