{"_id":"@_daniel_jiang/host-sdk","name":"@_daniel_jiang/host-sdk","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@_daniel_jiang/host-sdk","version":"1.0.0","description":"Agent 平台宿主嵌入 SDK（iframe Hub/Widget，框架无关）","type":"module","main":"./dist/agent-host.js","module":"./dist/agent-host.mjs","types":"./index.d.ts","exports":{".":{"import":"./dist/agent-host.mjs","require":"./dist/agent-host.js","default":"./dist/agent-host.mjs"}},"scripts":{"build":"vite build"},"sideEffects":false,"license":"MIT","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_id":"@_daniel_jiang/host-sdk@1.0.0","gitHead":"a613b9ca16d87f67c726c9c1945dc69ec3407a38","_nodeVersion":"22.15.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-ssXh0De2MvuMWVKokyzvtLgcMYHvU4GPaymXJU2ZOcP4OTnbTw6ZgYZeYQlsbfUYZsK2SYOMA9VcQaeUfWVGHw==","shasum":"866fb882e3abf90423dc8b791d32b155cfb60e26","tarball":"https://registry.npmjs.org/@_daniel_jiang/host-sdk/-/host-sdk-1.0.0.tgz","fileCount":5,"unpackedSize":53380,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHa/TuipEfrp+JafeZAiOU2FC9I2dCFQjjIfyFBU8PcCAiB0W697akRFCgONipK34BT4L/4NobxgJ7MJFhfhDTCvsw=="}]},"_npmUser":{"name":"_daniel_jiang","email":"867226280@qq.com"},"directories":{},"maintainers":[{"name":"_daniel_jiang","email":"867226280@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/host-sdk_1.0.0_1785141095124_0.7077185445173271"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-27T08:31:34.876Z","1.0.0":"2026-07-27T08:31:35.281Z","modified":"2026-07-27T08:31:35.523Z"},"maintainers":[{"name":"_daniel_jiang","email":"867226280@qq.com"}],"description":"Agent 平台宿主嵌入 SDK（iframe Hub/Widget，框架无关）","license":"MIT","readme":"# @agent-platform/host-sdk\n\nAgent 平台宿主嵌入 SDK（iframe 模式）。UI 由 Agent `/host/hub`、`/host/widget` 渲染；宿主只需 `init` + `registerPage`。\n\n表单提交与附件上传均在 **Agent Widget iframe 内**完成：用户点「开始」后，Widget 以 **multipart** 一次调用 `POST /api/v1/host/scenarios/{workflow}/run`（表单 JSON 字段 + 可选 `attachment_files`）。**不再**使用独立的 `POST /sessions/{id}/files`。\n\n## 安装\n\n宿主工程（EDC `boot-ui` / 专病库 `imedway-rdr-web`）使用**已拷贝到本仓的 vendor 包**，不依赖 agent-platform 源码树：\n\n```bash\n# 依赖已指向本地副本，例如：\n# \"@agent-platform/host-sdk\": \"file:./vendor/agent-platform-host-sdk\"\nnpm install\n```\n\n在 **agent-platform** 更新 SDK 后，于本目录执行同步（会先 `pnpm run build:sdk`）：\n\n```bash\nbash web/packages/host-sdk/sync-to-hosts.sh\n# 然后在对应宿主工程重新 npm install\n```\n\nmonorepo 内临时联调仍可指向源包：\n\n```bash\nnpm install file:../../../web/packages/host-sdk\n```\n\n安装前需已生成 `dist/`（`web/` 下执行 `pnpm run build:sdk`）。\n\n## 用法\n\n```javascript\nimport { AgentHost } from '@agent-platform/host-sdk'\n\nawait AgentHost.init({\n  host: 'edc',\n  // 推荐：BFF bootstrap 返回 agent_token + agent_web_origin，无需前端环境变量\n  bootstrap: () => fetch('/boot-admin/agent/bootstrap?hosts=edc', { credentials: 'include' }).then((r) => r.json()),\n  // 可选：打开需 establish 的 Widget 前强制刷新会话\n  // prepareOpenWidget: () => bootstrapAgentSession(true),\n})\n\nAgentHost.registerPage(\n  'edc_patient_list',\n  [{\n    id: 'form_fill',\n    workflow: 'edc_form_fill',\n    label: 'AI 填表',\n    host: 'edc',\n    prefilled: () => ({\n      sub_project_id: currentSubProjectId,\n      project_id: currentProjectId,\n      target: buildTargetFromEdcSelection(selectedForm),\n    }),\n    enabled: () => AgentHost.canOpen('edc_form_fill', { prefilled: { ... } }),\n    hostContext: { refresh: 'patient_list' },\n  }],\n  {\n    // 任务 success 且 hostContext.refresh 匹配时调用；unregisterPage 后自动失效\n    refreshKey: 'patient_list',\n    onRefresh: () => refreshPatientList(),\n  },\n)\n\n// 表单列表页：AI 设计 CRF（上传 Word/PDF）\nAgentHost.registerPage(\n  'edc_form_list',\n  [{\n    id: 'crf_design',\n    workflow: 'edc_crf_design',\n    label: 'AI 设计 CRF',\n    host: 'edc',\n    prefilled: () => ({\n      sub_project_id: currentSubProjectId,\n      sort_start: nextFormSort,\n    }),\n    enabled: () => AgentHost.canOpen('edc_crf_design', { prefilled: { sub_project_id: currentSubProjectId } }),\n    hostContext: { refresh: 'form_list' },\n  }],\n  { refreshKey: 'form_list', onRefresh: () => refreshFormList() },\n)\n\nAgentHost.openAction('edc_patient_list', 'form_fill')\n\n// 离开页时务必 unregister（keep-alive 切走 / destroy），避免后台误刷\nAgentHost.unregisterPage('edc_patient_list')\n```\n\nEDC / 专病库可用 `createAgentPageMixin` 自动处理进出页 register/unregister。\n\n### Widget 内提交流程（iframe，宿主无需处理文件）\n\n1. SDK 打开 `/host/widget?workflow=...` iframe  \n2. Widget 拉取 `GET /host/workflows/{name}/ui` 渲染表单（勾选填表场景 Widget **仅**上传文书/文本）  \n3. Widget 创建会话 `POST /sessions`  \n4. 用户提交 → **`POST /host/scenarios/{name}/run`（multipart，一次完成）**  \n5. Hub iframe 展示任务进度；成功完成后 SDK 对仍注册页触发 `onRefresh`  \n\n`complete` / `success` 来自 Agent 任务协议（Hub/Widget `postMessage`），与宿主业务 API 返回结构无关。\n\n带附件的工作流（如 Excel 批量填表）无需宿主先上传文件；附件在 Widget 内选好后随 scenario run 一并提交。\n\n## Bootstrap 契约（宿主 BFF）\n\n`GET /agent/bootstrap?hosts=edc` 建议返回：\n\n```json\n{\n  \"agent_token\": \"...\",\n  \"refresh_token\": \"...\",\n  \"agent_web_origin\": \"https://agent.example.com\"\n}\n```\n\n- `agent_web_origin`：Agent **前端**地址（iframe、Hub）\n- Token 换取走 boot-admin → Agent API（`agent-host-api-base-url`），与 `agent_web_origin` 分离\n\n可选：`init({ agentOrigin: '...' })` 显式覆盖 BFF 下发的地址。\n\n## Scenario API（Headless / 自绘表单时）\n\niframe SDK 一般不需要宿主直调；若宿主自画表单、绕过 Widget，可按下列契约提交：\n\n```http\nPOST /api/v1/host/scenarios/{workflow_name}/run\nAuthorization: Bearer <token>\nContent-Type: multipart/form-data\n```\n\n| 字段 | 类型 | 必填 | 说明 |\n|------|------|------|------|\n| `session_id` | string | 是 | 已创建的 Agent 会话 UUID |\n| `host` | string | 否 | 宿主标识，默认 `research_portal` |\n| `host_context` | string (JSON) | 否 | 页面上下文、刷新回调等 |\n| `prefilled` | string (JSON) | 否 | 宿主勾选带入的只读参数 |\n| `form_values` | string (JSON) | 否 | 用户在表单中的选择 |\n| `prompt_extra` | string | 否 | 附加 prompt |\n| `attachment_files` | file[] | 否 | 附件，可多文件 |\n\n响应示例：\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"task_id\": \"uuid\",\n    \"session_id\": \"uuid\",\n    \"status\": \"queued\",\n    \"stream_url\": \"/api/v1/tasks/{task_id}/stream\"\n  }\n}\n```\n\n与 Chat 对比：\n\n| 场景 | 接口 |\n|------|------|\n| Chat 发消息 + 附件 | `POST /sessions/{id}/messages-with-files` |\n| Host Widget / Scenario | `POST /host/scenarios/{name}/run`（multipart） |\n\n完整契约见仓库 `PRD/11_host_widget_integration.md` §6。\n","readmeFilename":"README.md","_rev":"1-ba2ac28551531d83a18203dbb7ca7e89"}