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 || ''; const sessionHint = sessionId ? '' : '- session_id 未写入上下文时,使用当前 Agent 会话 ID 替换 ``。\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//` 等猜测路径', '', ); 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 || ''; const sessionHint = sessionId ? '' : '- session_id 未写入上下文时,使用当前 Agent 会话 ID 替换 ``。\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); }