{"_id":"@egova/egovis-sdk","_rev":"8-2508a6996c329a4fd08dca260dccfec2","name":"@egova/egovis-sdk","dist-tags":{"latest":"0.1.5"},"versions":{"0.1.1":{"name":"@egova/egovis-sdk","version":"0.1.1","_id":"@egova/egovis-sdk@0.1.1","maintainers":[{"name":"chendebao","email":"chendb1985@gmail.com"},{"name":"nirvana_x","email":"zane295384295@gmail.com"},{"name":"surelee","email":"565937915@qq.com"},{"name":"yuhaoz","email":"843453966@qq.com"},{"name":"xyr610911","email":"2414303902@qq.com"},{"name":"egova-liaojunjie1","email":"593230531@qq.com"},{"name":"peritot","email":"peritotchan@gmail.com"},{"name":"liujiaqian","email":"1448406404@qq.com"},{"name":"big_orange_233","email":"liujiaqian@egova.com.cn"},{"name":"xiaqingyun","email":"xiaqingyun@egova.com.cn"}],"dist":{"shasum":"a3d02037673c877f05ce5f312f42c1ada92d2090","tarball":"https://registry.npmjs.org/@egova/egovis-sdk/-/egovis-sdk-0.1.1.tgz","fileCount":10,"integrity":"sha512-HQMKsH6HVF7tkQW5qq17myMe+pv5tQSHvV7HTow/zxfHqn6LVONSbQZet79scogcQdA2vVcSw8gSY+UTdse2NA==","signatures":[{"sig":"MEQCIBwF4f8Awi2Sz2TOPBdW7E07x58P9XvcUyRRKu3O38yTAiB8sKn4QAerBgdniNwjGZnkAjgMdCK+fMkjPYZzYY3H8w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":255783},"main":"./dist/egovis-sdk.es.js","type":"module","_from":"file:egova-egovis-sdk-0.1.1.tgz","types":"./dist/types/index.d.ts","unpkg":"./dist/egovis-sdk.iife.js","module":"./dist/egovis-sdk.es.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/egovis-sdk.es.js"}},"scripts":{"test":"vitest run","build":"vite build && vite build --config vite.iife.config.ts && tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"peritot","email":"peritotchan@gmail.com"},"_resolved":"/private/var/folders/5p/whwbq5jx1lvd2hl0nfst4w880000gn/T/274e3c244a440170176ddcf4101401a3/egova-egovis-sdk-0.1.1.tgz","_integrity":"sha512-HQMKsH6HVF7tkQW5qq17myMe+pv5tQSHvV7HTow/zxfHqn6LVONSbQZet79scogcQdA2vVcSw8gSY+UTdse2NA==","_npmVersion":"10.8.2","description":"Egovis 嵌入式智能助手 SDK","directories":{},"_nodeVersion":"20.20.0","dependencies":{"zod":"^4.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","vitest":"^4.1.6","happy-dom":"^20.10.5","typescript":"~5.7.2","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/egovis-sdk_0.1.1_1785117107316_0.14054325491785713","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@egova/egovis-sdk","version":"0.1.2","_id":"@egova/egovis-sdk@0.1.2","maintainers":[{"name":"chendebao","email":"chendb1985@gmail.com"},{"name":"nirvana_x","email":"zane295384295@gmail.com"},{"name":"surelee","email":"565937915@qq.com"},{"name":"yuhaoz","email":"843453966@qq.com"},{"name":"xyr610911","email":"2414303902@qq.com"},{"name":"egova-liaojunjie1","email":"593230531@qq.com"},{"name":"peritot","email":"peritotchan@gmail.com"},{"name":"liujiaqian","email":"1448406404@qq.com"},{"name":"big_orange_233","email":"liujiaqian@egova.com.cn"},{"name":"xiaqingyun","email":"xiaqingyun@egova.com.cn"}],"dist":{"shasum":"81e68e72220e729c5fbaeb7238dd65b17846e93e","tarball":"https://registry.npmjs.org/@egova/egovis-sdk/-/egovis-sdk-0.1.2.tgz","fileCount":16,"integrity":"sha512-JvqDkKHUUqCdA8EFb3VOlBjCzBp3lMr7oajTqylehsIgIy06lRNIUob7Zrp5gxOpH4HAl9lCH8k2+VLJr3k4Ww==","signatures":[{"sig":"MEUCIQCSbMZ8NVF2qhf11aeXPb6r7Yox2IAwe4JJVxqSSMJ/kQIgZ/sGpJ55sgwMP5LpZq8qBvUpFXw/ZhDs2fLgTFAig3Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":360629},"main":"./dist/egovis-sdk.es.js","type":"module","_from":"file:egova-egovis-sdk-0.1.2.tgz","types":"./dist/types/index.d.ts","unpkg":"./dist/egovis-sdk.iife.js","module":"./dist/egovis-sdk.es.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/egovis-sdk.es.js"}},"scripts":{"test":"vitest run","build":"vite build && vite build --config vite.iife.config.ts && tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"peritot","email":"peritotchan@gmail.com"},"_resolved":"/private/var/folders/5p/whwbq5jx1lvd2hl0nfst4w880000gn/T/0e74f2005c5fa337eb0c92a108801480/egova-egovis-sdk-0.1.2.tgz","_integrity":"sha512-JvqDkKHUUqCdA8EFb3VOlBjCzBp3lMr7oajTqylehsIgIy06lRNIUob7Zrp5gxOpH4HAl9lCH8k2+VLJr3k4Ww==","_npmVersion":"10.8.2","description":"Egovis 嵌入式智能助手 SDK","directories":{},"_nodeVersion":"20.20.0","dependencies":{"zod":"^4.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","vitest":"^4.1.6","happy-dom":"^20.10.5","typescript":"~5.7.2","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/egovis-sdk_0.1.2_1786937763564_0.9542640165204808","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@egova/egovis-sdk","version":"0.1.3","_id":"@egova/egovis-sdk@0.1.3","maintainers":[{"name":"chendebao","email":"chendb1985@gmail.com"},{"name":"nirvana_x","email":"zane295384295@gmail.com"},{"name":"surelee","email":"565937915@qq.com"},{"name":"yuhaoz","email":"843453966@qq.com"},{"name":"xyr610911","email":"2414303902@qq.com"},{"name":"egova-liaojunjie1","email":"593230531@qq.com"},{"name":"peritot","email":"peritotchan@gmail.com"},{"name":"liujiaqian","email":"1448406404@qq.com"},{"name":"big_orange_233","email":"liujiaqian@egova.com.cn"},{"name":"xiaqingyun","email":"xiaqingyun@egova.com.cn"}],"dist":{"shasum":"6be3fcc3c161b2fc3cbeeda4c7486f2f9e492801","tarball":"https://registry.npmjs.org/@egova/egovis-sdk/-/egovis-sdk-0.1.3.tgz","fileCount":23,"integrity":"sha512-irry9FhOUu4xLyUUOnhI0JuLhVTAH0xHfOr3sAs5tuUamg3n2k2UojGG03nGU9dvAfxXXyfC7tYpLjdVJwnS/A==","signatures":[{"sig":"MEYCIQDwK24ExBjJ0anubGfqpKctjhvszctsBEDMiz3sS/2HKwIhAP/h4VOCuZSKRen4qa+aRHVHosCdvxJ6Vmzj7uKfrLZF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":431624},"main":"./dist/egovis-sdk.es.js","type":"module","_from":"file:egova-egovis-sdk-0.1.3.tgz","types":"./dist/types/index.d.ts","unpkg":"./dist/egovis-sdk.iife.js","module":"./dist/egovis-sdk.es.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/egovis-sdk.es.js"}},"scripts":{"test":"vitest run","build":"vite build && vite build --config vite.iife.config.ts && tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"peritot","email":"peritotchan@gmail.com"},"_resolved":"/private/var/folders/5p/whwbq5jx1lvd2hl0nfst4w880000gn/T/71a72adc1661729354dec6dc58288965/egova-egovis-sdk-0.1.3.tgz","_integrity":"sha512-irry9FhOUu4xLyUUOnhI0JuLhVTAH0xHfOr3sAs5tuUamg3n2k2UojGG03nGU9dvAfxXXyfC7tYpLjdVJwnS/A==","_npmVersion":"10.8.2","description":"Egovis 嵌入式智能助手 SDK","directories":{},"_nodeVersion":"20.20.0","dependencies":{"zod":"^4.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","vitest":"^4.1.6","happy-dom":"^20.10.5","typescript":"~5.7.2","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/egovis-sdk_0.1.3_1787042073844_0.5781451677487015","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@egova/egovis-sdk","version":"0.1.4","_id":"@egova/egovis-sdk@0.1.4","maintainers":[{"name":"chendebao","email":"chendb1985@gmail.com"},{"name":"nirvana_x","email":"zane295384295@gmail.com"},{"name":"surelee","email":"565937915@qq.com"},{"name":"yuhaoz","email":"843453966@qq.com"},{"name":"xyr610911","email":"2414303902@qq.com"},{"name":"egova-liaojunjie1","email":"593230531@qq.com"},{"name":"peritot","email":"peritotchan@gmail.com"},{"name":"liujiaqian","email":"1448406404@qq.com"},{"name":"big_orange_233","email":"liujiaqian@egova.com.cn"},{"name":"xiaqingyun","email":"xiaqingyun@egova.com.cn"}],"dist":{"shasum":"9d1ef59da3a690ceb1829d952cd95236bae4b5af","tarball":"https://registry.npmjs.org/@egova/egovis-sdk/-/egovis-sdk-0.1.4.tgz","fileCount":23,"integrity":"sha512-5aMMlhphhFIu9DgJLApr28f84xBR82CuLVARa7cuLLeC7x3IO0EYkBUVtRdVnkNincyb2mYsPvCR35a/KFnF+g==","signatures":[{"sig":"MEYCIQDFJ2qoc78RwAPSs0JC9cDTQLjb5F4RdqijqZH5lt//CAIhAIUeEfCM9KKZyuTpRyKHPecWDe0S0F0H3ZznqFI7PxPJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":438703},"main":"./dist/egovis-sdk.es.js","type":"module","_from":"file:egova-egovis-sdk-0.1.4.tgz","types":"./dist/types/index.d.ts","unpkg":"./dist/egovis-sdk.iife.js","module":"./dist/egovis-sdk.es.js","exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/egovis-sdk.es.js"}},"scripts":{"test":"vitest run","build":"vite build && vite build --config vite.iife.config.ts && tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"peritot","email":"peritotchan@gmail.com"},"_resolved":"/private/var/folders/5p/whwbq5jx1lvd2hl0nfst4w880000gn/T/86071d0505832eae4712665e684c6222/egova-egovis-sdk-0.1.4.tgz","_integrity":"sha512-5aMMlhphhFIu9DgJLApr28f84xBR82CuLVARa7cuLLeC7x3IO0EYkBUVtRdVnkNincyb2mYsPvCR35a/KFnF+g==","_npmVersion":"10.8.2","description":"Egovis 嵌入式智能助手 SDK","directories":{},"_nodeVersion":"20.20.0","dependencies":{"zod":"^4.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.3.1","vitest":"^4.1.6","happy-dom":"^20.10.5","typescript":"~5.7.2","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/egovis-sdk_0.1.4_1787313821998_0.19029963886518764","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@egova/egovis-sdk","version":"0.1.5","description":"Egovis 嵌入式智能助手 SDK","type":"module","main":"./dist/egovis-sdk.es.js","module":"./dist/egovis-sdk.es.js","types":"./dist/types/index.d.ts","unpkg":"./dist/egovis-sdk.iife.js","publishConfig":{"access":"public"},"exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/egovis-sdk.es.js"}},"dependencies":{"zod":"^4.4.3"},"devDependencies":{"@types/node":"^22.10.2","happy-dom":"^20.10.5","typescript":"~5.7.2","vite":"^7.3.1","vitest":"^4.1.6"},"scripts":{"test":"vitest run","typecheck":"tsc --noEmit","build":"vite build && vite build --config vite.iife.config.ts && tsc -p tsconfig.build.json"},"_id":"@egova/egovis-sdk@0.1.5","_integrity":"sha512-uht5HQSyGjlt3Z0u/GeLJhjuWuNXk2HJ3ijfxJ6HNxx+a6eVJJeKUe1uasNcYVo96a+LW+YD4hx4t/DaJpIJng==","_resolved":"/private/var/folders/5p/whwbq5jx1lvd2hl0nfst4w880000gn/T/67b969278edf675e21f968fa17bd42f8/egova-egovis-sdk-0.1.5.tgz","_from":"file:egova-egovis-sdk-0.1.5.tgz","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-uht5HQSyGjlt3Z0u/GeLJhjuWuNXk2HJ3ijfxJ6HNxx+a6eVJJeKUe1uasNcYVo96a+LW+YD4hx4t/DaJpIJng==","shasum":"a49d7816d39a070a0a6b2d103d29debbbd1ac8e2","tarball":"https://registry.npmjs.org/@egova/egovis-sdk/-/egovis-sdk-0.1.5.tgz","fileCount":23,"unpackedSize":453449,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDVk19jPvOITfSbd6Y0NfGAqSotEFmAMm5o2b8UvKzJ5QIhAIySnMMjUQ1yC4c8XEXZLo+SfLjB4+W4/KxrwgXPe54d"}]},"_npmUser":{"name":"peritot","email":"peritotchan@gmail.com"},"directories":{},"maintainers":[{"name":"chendebao","email":"chendb1985@gmail.com"},{"name":"nirvana_x","email":"zane295384295@gmail.com"},{"name":"surelee","email":"565937915@qq.com"},{"name":"yuhaoz","email":"843453966@qq.com"},{"name":"xyr610911","email":"2414303902@qq.com"},{"name":"egova-liaojunjie1","email":"593230531@qq.com"},{"name":"peritot","email":"peritotchan@gmail.com"},{"name":"liujiaqian","email":"1448406404@qq.com"},{"name":"big_orange_233","email":"liujiaqian@egova.com.cn"},{"name":"xiaqingyun","email":"xiaqingyun@egova.com.cn"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/egovis-sdk_0.1.5_1787749363272_0.23382472103397212"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-27T01:51:47.075Z","modified":"2026-08-26T13:02:43.628Z","0.1.0":"2026-07-25T17:50:01.853Z","0.1.1":"2026-07-27T01:51:47.462Z","0.1.2":"2026-08-17T03:36:03.713Z","0.1.3":"2026-08-18T08:34:34.049Z","0.1.4":"2026-08-21T12:03:42.131Z","0.1.5":"2026-08-26T13:02:43.421Z"},"description":"Egovis 嵌入式智能助手 SDK","maintainers":[{"name":"chendebao","email":"chendb1985@gmail.com"},{"name":"nirvana_x","email":"zane295384295@gmail.com"},{"name":"surelee","email":"565937915@qq.com"},{"name":"yuhaoz","email":"843453966@qq.com"},{"name":"xyr610911","email":"2414303902@qq.com"},{"name":"egova-liaojunjie1","email":"593230531@qq.com"},{"name":"peritot","email":"peritotchan@gmail.com"},{"name":"liujiaqian","email":"1448406404@qq.com"},{"name":"big_orange_233","email":"liujiaqian@egova.com.cn"},{"name":"xiaqingyun","email":"xiaqingyun@egova.com.cn"}],"readme":"# Egovis 智能助手 SDK\n\n`@egova/egovis-sdk` 用于在业务系统中接入 Egovis 智能助手，支持抽屉、页面内 Modal 和页面嵌入三种布局，并可向助手提供当前页面的业务上下文、快捷提问和宿主动作。\n\nSDK 仅在浏览器环境中运行。Nuxt、Next.js 等服务端渲染项目应在客户端生命周期内加载 SDK。\n\n## 安装\n\n```bash\npnpm add @egova/egovis-sdk\n```\n\n也可以使用 npm：\n\n```bash\nnpm install @egova/egovis-sdk\n```\n\n## 快速开始\n\n```ts\nimport { create, type BusinessPageContext } from '@egova/egovis-sdk'\n\nconst assistant = create({\n  assistantUrl: 'https://ai.example.com/assistant.html',\n  projectId: 'project-100',\n  display: {\n    theme: 'light',\n    starterTitle: '案件办理助手',\n    starterSubtitle: '分析当前案件并生成处置建议。',\n    conversationWidthPercent: 120,\n    themeToggleVisible: true,\n    fontSize: 100,\n  },\n  contextProvider: (): BusinessPageContext => ({\n    source: {\n      systemCode: 'case-center',\n      pageCode: 'case-list',\n    },\n    page: {\n      title: '案件统计',\n      path: location.pathname,\n    },\n    content: {\n      filters: { status: 'pending' },\n      selectedCaseIds: ['case-1'],\n    },\n    summary: [\n      { key: 'total', label: '案件数', value: '12' },\n    ],\n    questions: [\n      { title: '分析趋势', content: '分析当前案件变化趋势' },\n    ],\n  }),\n})\n\nassistant.on('error', error => console.error('智能助手异常', error))\n```\n\n默认使用 `drawer` 布局，并在页面右下角显示系统 AI 图标。首次点击图标时加载并打开智能助手。\n\nSDK 写入 iframe URL 的业务参数只有 `projectId`，其他配置通过 iframe 桥接发送。iframe 内独立完成登录；登录跳转不会销毁 SDK 创建的 iframe，登录成功后会继续完成桥接初始化。\n\n使用新增展示字段前应先部署支持对应 Bridge 字段的新版 `assistant.html`，再升级业务系统中的 SDK。新版助手仍兼容旧 SDK 未携带新增展示字段的初始化消息。\n\n## 初始化选项\n\n| 选项 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `assistantUrl` | `string` | - | 必填，助手 `assistant.html` 的绝对 HTTP(S) 地址。 |\n| `projectId` | `string` | - | 必填，当前 Egovis 项目 ID。 |\n| `mountTarget` | `string \\| HTMLElement` | `document.body` | SDK 挂载节点。 |\n| `layout` | `'drawer' \\| 'modal' \\| 'embedded'` | `'drawer'` | 助手布局方式。 |\n| `trigger.label` | `string` | - | AI 按钮文案；未配置时只显示系统 AI 图标。 |\n| `trigger.placement` | `'left' \\| 'right'` | `'right'` | AI 按钮位于页面左下角或右下角。 |\n| `trigger.hidden` | `boolean` | `false` | 是否隐藏 SDK 内置 AI 按钮。 |\n| `trigger.draggable` | `boolean` | `true` | 是否允许拖动 SDK 内置 AI 按钮。 |\n| `drawer.width` | `number \\| px \\| vw` | `480` | 抽屉宽度，最小 `360 px`，最大为当前视口宽度。 |\n| `drawer.placement` | `'left' \\| 'right'` | `'right'` | 抽屉打开方向。 |\n| `drawer.resizable` | `boolean` | `true` | 是否允许调整抽屉宽度。 |\n| `modal.width` | `number \\| px \\| vw` | `90vw` | Modal 默认宽度，数字按 px 处理。 |\n| `modal.height` | `number \\| px \\| vh` | `90vh` | Modal 默认高度，数字按 px 处理。 |\n| `modal.draggable` | `boolean` | `true` | 是否允许拖动 Modal。 |\n| `modal.resizable` | `boolean` | `true` | 是否允许调整 Modal 尺寸。 |\n| `modal.backdropVisible` | `boolean` | `true` | 是否显示半透明遮罩；隐藏后仍会阻断宿主交互。 |\n| `interaction.snap` | `boolean` | `true` | 是否为 Trigger、Drawer 和 Modal 启用吸附。 |\n| `interaction.showSnapIndicators` | `boolean` | `true` | 是否显示吸附视觉反馈；不影响实际吸附。 |\n| `persistenceScope` | `'origin' \\| 'project'` | `'origin'` | 交互位置和尺寸按当前 Origin 或项目持久化。 |\n| `display.contextVisible` | `boolean` | `true` | 是否在助手中显示页面数据卡片。 |\n| `display.starterTitle` | `string` | `把想法变成成果，用 AI 高效完成工作` | 助手新对话欢迎区标题，最长 256 个字符；空白值回退默认文案。 |\n| `display.starterSubtitle` | `string` | `您好，我是您的智能助手，可以帮您梳理思路、拆解任务、生成内容，让工作推进更简单。` | 助手新对话欢迎区副标题，最长 512 个字符；空白值回退默认文案。 |\n| `display.conversationWidthPercent` | `number` | `100` | 对话内容和输入框共享宽度百分比，范围 `80–140`，步长 `10`。 |\n| `display.theme` | `'light' \\| 'dark' \\| 'system'` | `'light'` | 助手初始主题；`system` 会在当前 iframe 会话内实时跟随操作系统主题变化。 |\n| `display.themeToggleVisible` | `boolean` | `true` | 是否显示 assistant 页面右上角的主题切换按钮，宽屏和紧凑布局同时生效。 |\n| `display.fontSize` | `number` | 跟随 iframe 宽度 | `assistant.html` 的 HTML 根字号，单位为 px，范围 `80–120`；显式配置固定覆盖，缺省时按 iframe width 自动计算。 |\n| `contextProvider` | `(scope: EgovisProjectScope) => BusinessPageContext \\| Promise<BusinessPageContext>` | - | 返回当前项目的最新业务上下文。 |\n| `actions` | `EgovisHostActionDefinition[]` | `[]` | 注册宿主动作，供助手生成固定动作卡片。 |\n| `timeouts.loadMs` | `number` | `10000` | iframe 文档首次加载超时时间，单位为 ms。 |\n| `timeouts.contextAckMs` | `number` | `10000` | 上下文同步确认超时时间，单位为 ms。 |\n| `timeouts.actionExecutionMs` | `number` | `10000` | 宿主动作 Handler 执行超时时间，单位为 ms。 |\n\n三项超时仅接受有限正数；无效值统一回退到 `10000 ms`。\n\n展示配置通过 Bridge 应用于当前 SDK iframe。宿主配置的对话宽度是每次加载的初始值；用户仍可在页面配置中临时调整当前会话宽度。`display.theme` 缺省为浅色主题，配置为 `system` 时会跟随操作系统主题实时变化；用户在助手内手动切换后仅影响当前 iframe 会话。`fontSize` 会直接写入 iframe 文档的 `document.documentElement.style.fontSize`，只影响 `assistant.html`，不会修改宿主页面字号。\n\n## 业务上下文\n\n### 字段说明\n\n| 字段 | 必填 | 说明 |\n| --- | --- | --- |\n| `source.systemCode` | 是 | 来源系统编码，最长 128 个字符。 |\n| `source.pageCode` | 是 | 来源页面编码，最长 128 个字符。 |\n| `page.title` | 是 | 页面标题，最长 256 个字符。 |\n| `page.path` | 否 | 以 `/` 开头且不包含 query 或 hash，最长 1024 个字符。 |\n| `subject` | 否 | 当前业务主体，包含 `type` 和 `title`。 |\n| `summary` | 否 | 页面摘要，最多 8 项，`key` 必须唯一。 |\n| `content` | 是 | 提供给助手的结构化页面数据，根节点必须是 JSON 对象。 |\n| `questions` | 否 | 快捷提问，最多 20 项，仅用于助手界面。 |\n\n单个上下文序列化后最多 `64 KB`，最大嵌套深度为 16 层。上下文只能包含标准 JSON 值，不支持循环引用、函数、`undefined`、日期对象、访问器属性或稀疏数组。\n\n对象键禁止包含 Token、Cookie、密码、密钥等敏感字段。业务系统应按白名单组装数据，并在传给 SDK 前完成脱敏。\n\n### 更新上下文\n\n页面路由、查询条件、表格数据或选中项发生变化后，重新获取当前页面数据：\n\n```ts\nasync function handleSearch() {\n  await loadTableData()\n  await assistant.refreshContext()\n}\n```\n\n`contextProvider` 接收 `{ projectId, signal }`。后续刷新、Provider 替换、项目切换或实例销毁会中止旧信号，并丢弃旧 Provider 的迟到结果。\n\n如果业务系统已经持有完整的新上下文，也可以直接更新：\n\n```ts\nassistant.setContext(nextContext)\n```\n\n每次更新都应提供完整上下文；`summary`、`content` 和 `questions` 会整体替换，不与上一次数据合并。用户发送消息时，助手会使用发送瞬间的上下文快照；`questions` 只用于快捷提问，不提交后端。\n\n`display.contextVisible: false` 只隐藏页面数据卡片，不会清除或停止同步上下文。需要停止携带上下文时，应调用 `clearContext()`。\n\n## 宿主动作\n\n宿主动作让对话能够触发业务系统中的固定操作：\n\n1. SDK 将已注册动作的名称、描述、参数 Schema 和默认参数提供给助手。\n2. 当用户对话符合某个业务操作场景时，助手生成固定动作卡片。\n3. 用户点击卡片后，iframe 向 SDK 发起动作请求，SDK 调用对应 Handler 并回传结果。\n\n助手不会获得 Handler 实现，也不会绕过用户点击直接执行宿主操作。\n\n### 动作字段\n\n| 字段 | 必填 | 说明 |\n| --- | --- | --- |\n| `call` | 是 | 动作唯一名称，必须符合 `EGOVIS_XXX_XXX` 格式。 |\n| `label` | 是 | 动作卡片按钮文案。 |\n| `description` | 是 | 描述适用场景，供助手选择动作。 |\n| `parameterSchema` | 否 | 约束助手生成的卡片参数；省略时表示无参数。 |\n| `defaultArgs` | 否 | 卡片默认参数；助手生成的同名参数会覆盖默认值。 |\n| `defaultButtonType` | 是 | 默认按钮类型。 |\n| `allowedButtonTypes` | 是 | 助手可选择的按钮类型范围。 |\n| `interaction` | 否 | 配置点击后的终态和结果消息策略；省略时使用默认行为。 |\n| `handler` | 是 | 用户点击卡片后执行的宿主函数。 |\n\n```ts\nimport { create, type EgovisHostActionDefinition } from '@egova/egovis-sdk'\n\nconst actions: EgovisHostActionDefinition[] = [\n  {\n    call: 'EGOVIS_OPEN_CASE_LEDGER',\n    label: '打开案件台账',\n    description: '打开当前区域的案件台账页。',\n    parameterSchema: {\n      type: 'object',\n      properties: {\n        regionId: { type: 'string' },\n      },\n      required: ['regionId'],\n      additionalProperties: false,\n    },\n    defaultArgs: {\n      regionId: 'all',\n    },\n    defaultButtonType: 'info',\n    allowedButtonTypes: ['primary', 'info'],\n    interaction: {\n      disableAfterSuccess: true,\n      resultMessage: {\n        success: true,\n        failure: '案件台账打开失败，请稍后重试。',\n      },\n    },\n    handler: async (args, { projectId, signal }) => {\n      const response = await fetch(\n        `/api/projects/${encodeURIComponent(projectId)}/case-ledger`,\n        { signal },\n      )\n      if (!response.ok) {\n        return {\n          status: 'failed',\n          errorCode: 'LOAD_CASE_LEDGER_FAILED',\n          message: '案件台账接口暂不可用。',\n        }\n      }\n      location.assign(`/case-ledger?regionId=${encodeURIComponent(String(args.regionId))}`)\n      return { status: 'success', message: '案件台账已打开。' }\n    },\n  },\n]\n\nconst assistant = create({\n  assistantUrl: 'https://ai.example.com/assistant.html',\n  projectId: 'project-100',\n  actions,\n})\n\nassistant.on('action-result', result => {\n  console.log('宿主动作执行结果', result)\n})\n\nassistant.on('action-execution', telemetry => {\n  console.log('宿主动作监控', telemetry)\n})\n```\n\n按钮类型支持 Element Plus 的 `default`、`primary`、`success`、`warning`、`danger` 和 `info`。\n\n`interaction.disableAfterSuccess` 控制动作成功后是否将当前卡片按钮置为“已完成”并禁用；默认 `false`。该状态只影响当前消息卡片中的当前动作，不会禁用同名动作的其他卡片或其他布局实例。\n\n`interaction.resultMessage.success` 和 `interaction.resultMessage.failure` 控制结果提示策略：`false` 表示不提示，`true` 表示使用 Handler 返回的 `message`，没有动态消息时回退为 SDK 默认文案，字符串表示固定覆盖文案。默认值为 `{ success: false, failure: true }`。`rejected`、`failed` 和 `timeout` 均使用 `failure` 策略，`unsupported` 不展示结果消息。\n\n`parameterSchema` 用于约束助手生成的动作卡片。SDK 执行时只校验参数是否为标准 JSON 对象且不超过 `16 KB`，Handler 必须自行校验最终参数、用户权限和当前项目状态。未知动作返回 `unsupported`，参数格式或大小不合法返回 `rejected`，Handler 抛错返回 `failed`，超过动作超时返回 `timeout`。\n\n每次 Handler 执行都会收到独立的 `{ projectId, signal }`。调用 `replaceActions()`、切换项目、执行超时或销毁实例会中止信号；`unregisterAction()` 和同名 Handler 替换不会取消已经开始的执行。\n\nHandler 返回的 `message` 只用于当前动作结果提示，最大 240 个字符；空白字符串、控制字符、HTML 标签和非字符串值会被忽略。`message` 不会进入动作注册描述、请求参数或 `action-execution` 监控事件。\n\n`action-execution` 事件只提供 `projectId`、`call`、`status` 和 `durationMs`，不包含参数、Handler 返回内容或异常对象。`action-result` 事件会携带基础结果字段；当 Handler 返回了有效动态消息时，事件载荷会额外包含 `message`。\n\n## 布局\n\n### 抽屉\n\n```ts\nconst assistant = create({\n  assistantUrl: 'https://ai.example.com/assistant.html',\n  projectId: 'project-100',\n  layout: 'drawer',\n  trigger: { label: 'AI 助手', placement: 'right' },\n  drawer: { width: 440, placement: 'right', resizable: true },\n  contextProvider: () => currentPageContext,\n})\n```\n\n抽屉首次打开时加载助手；关闭后保留对话状态，再次打开时重新获取页面上下文。Trigger 位置和抽屉宽度会根据 `persistenceScope` 持久化。\n\n隐藏 SDK 内置按钮后，可以使用业务系统自己的入口：\n\n```ts\nconst assistant = create({\n  assistantUrl: 'https://ai.example.com/assistant.html',\n  projectId: 'project-100',\n  trigger: { hidden: true },\n})\n\ndocument.querySelector('#ai-button')?.addEventListener('click', () => {\n  void assistant.toggle()\n})\n```\n\n### Modal\n\n```ts\nconst assistant = create({\n  assistantUrl: 'https://ai.example.com/assistant.html',\n  projectId: 'project-100',\n  layout: 'modal',\n  modal: {\n    width: '80vw',\n    height: '80vh',\n    draggable: true,\n    resizable: true,\n    backdropVisible: true,\n  },\n  interaction: {\n    snap: true,\n    showSnapIndicators: true,\n  },\n})\n```\n\nModal 支持拖动、八方向缩放、位置与尺寸持久化，并在窄屏下自动切换为近全屏模式。关闭按钮、遮罩点击和 `Escape` 均可关闭 Modal；打开期间会保持焦点循环并锁定页面滚动。\n\n`modal.backdropVisible: false` 只隐藏遮罩颜色，透明遮罩仍会阻断宿主页面交互。\n\n### 页面嵌入\n\n```html\n<div id=\"assistant-panel\"></div>\n```\n\n```css\n#assistant-panel {\n  width: 420px;\n  height: 100vh;\n}\n```\n\n```ts\nconst assistant = create({\n  assistantUrl: 'https://ai.example.com/assistant.html',\n  projectId: 'project-100',\n  mountTarget: '#assistant-panel',\n  layout: 'embedded',\n  contextProvider: () => currentPageContext,\n})\n```\n\n`embedded` 布局会填满挂载节点，因此挂载节点必须具有明确尺寸。该布局始终显示，`close()` 不会隐藏助手；嵌入区域尺寸由业务系统管理。\n\nDrawer 和 Modal 使用 `position: fixed`。自定义 `mountTarget` 的祖先不应通过 `transform`、`filter`、`perspective` 或 `contain` 建立 Fixed Positioning Containing Block。\n\n## 实例方法\n\n| 方法 | 说明 |\n| --- | --- |\n| `open()` | 打开 Drawer 或 Modal，并重新获取当前页面上下文。 |\n| `close()` | 关闭 Drawer 或 Modal；对 `embedded` 布局无效。 |\n| `toggle()` | 切换 Drawer 或 Modal 的打开状态。 |\n| `refreshContext()` | 重新执行 `contextProvider`。 |\n| `setContext(context)` | 使用完整快照更新业务上下文。 |\n| `clearContext()` | 清除当前业务上下文。 |\n| `setProjectId(projectId, options?)` | 原子更新项目、上下文来源和宿主动作。 |\n| `registerAction(action)` | 注册单个宿主动作。 |\n| `unregisterAction(call)` | 按动作名注销宿主动作。 |\n| `replaceActions(actions)` | 原子替换全部宿主动作。 |\n| `listActions()` | 返回当前可公开的动作描述列表。 |\n| `getState()` | 返回实例当前状态的只读快照。 |\n| `on(event, handler)` | 监听 SDK 事件，返回取消监听函数。 |\n| `destroy()` | 销毁 SDK 实例并移除页面元素。 |\n\n业务页面卸载或微前端应用销毁时，必须调用 `destroy()`。\n\n## 事件\n\n| 事件 | 载荷 |\n| --- | --- |\n| `open`、`close`、`ready` | `{ projectId }` |\n| `context-ack` | `ContextAckPayload` |\n| `context-rejected` | `ContextRejectedPayload` |\n| `action-ack`、`action-rejected` | `EgovisHostActionsAckPayload` |\n| `action-result` | `EgovisHostActionResultPayload & { message?: string }` |\n| `action-execution` | `{ projectId, call, status, durationMs }` |\n| `error` | `{ code, message, projectId }` |\n\n```ts\nconst offReady = assistant.on('ready', ({ projectId }) => {\n  console.info('智能助手已就绪', projectId)\n})\n\nconst offError = assistant.on('error', error => {\n  console.error('智能助手异常', error)\n})\n\n// 不再需要监听时取消订阅\noffReady()\noffError()\n```\n\niframe 首次触发 `load` 只表示文档已加载，不要求用户已经登录。`ready` 在助手登录并完成业务桥接后触发，表示助手业务已就绪。\n\n## 切换项目\n\n业务系统切换项目后，可以同时更新 SDK 的项目、上下文来源和动作：\n\n```ts\nawait assistant.setProjectId(nextProjectId, {\n  contextProvider: ({ projectId, signal }) => loadProjectContext(projectId, { signal }),\n  actions: buildProjectActions(nextProjectId),\n})\n```\n\n| 选项 | 行为 |\n| --- | --- |\n| 不传 `options` | 复用当前 Provider 和动作；项目变化时清除旧快照。 |\n| `contextProvider` | 替换 Provider；传 `null` 时移除 Provider 并清空上下文。 |\n| `context` | 切换为直接快照模式；传 `null` 时清空上下文。 |\n| `actions` | 原子替换动作；传 `[]` 时清空动作。 |\n\n`context` 与 `contextProvider` 不能同时传入。SDK 会先完整校验本次更新，校验失败时保持原状态。`setProjectId()` 的 Promise 不等待 iframe 登录或桥接 `ready`，应通过 `ready` 事件确认远端业务就绪。\n\n```ts\nconst state = assistant.getState()\n// { projectId, open, ready, contextMode, actionRevision, destroyed }\n```\n\n## 样式调整\n\n按钮位置、抽屉方向和尺寸优先通过初始化选项配置。字体、颜色和层级可以通过 CSS 变量覆盖：\n\n```css\negovis-ai-assistant {\n  --egovis-assistant-font-family: var(--eg-font-sans);\n  --egovis-assistant-trigger-bg: #1677ff;\n  --egovis-assistant-trigger-color: #ffffff;\n  --egovis-assistant-z-index: 2000;\n}\n```\n\n## IIFE/CDN 接入\n\n```html\n<script src=\"https://cdn.example.com/egovis-sdk.iife.js\"></script>\n<script>\n  const assistant = EgovisSDK.create({\n    assistantUrl: 'https://ai.example.com/assistant.html',\n    projectId: 'project-100',\n    contextProvider: () => ({\n      source: { systemCode: 'case-center', pageCode: 'case-detail' },\n      page: { title: '案件详情', path: location.pathname },\n      content: { caseId: 'case-1', status: 'pending' }\n    })\n  })\n</script>\n```\n\n## 数据安全与跨域\n\n- `contextProvider` 应按白名单组装数据，并在返回前完成脱敏。\n- 不要提供 Token、Cookie、密码、身份证明、完整手机号或其他认证凭证。\n- `assistantUrl` 不应携带 Token 或其他敏感信息。\n- 宿主动作的 `description`、`defaultArgs` 和 Handler 返回 `message` 均会进入助手 iframe，应避免包含敏感数据、内部错误堆栈或可用于越权操作的信息。\n- 动作 Handler 必须在宿主侧重新校验参数、当前用户权限和项目归属；助手生成的卡片参数不能视为可信输入。\n- 跨域部署时，助手服务端必须通过 CSP `frame-ancestors` 允许业务系统 Origin。\n- 智能助手前端必须配置允许接入的业务系统 Origin，例如 `VITE_ASSISTANT_HOST_ORIGINS=https://business.example.com`。\n- 生产环境使用 HTTPS，Origin 配置不得使用 `*`、路径、查询参数或片段。\n","readmeFilename":"README.md"}