npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@egova/egovis-sdk

v0.1.1

Published

Egovis 嵌入式智能助手 SDK

Downloads

0

Readme

Egovis 智能助手 SDK

@egova/egovis-sdk 用于在业务系统中接入 Egovis 智能助手,支持抽屉和页面嵌入两种布局,并可向助手提供当前页面的业务数据和快捷提问。

SDK 仅在浏览器环境中运行。Nuxt、Next.js 等服务端渲染项目应在客户端生命周期内加载 SDK。

安装

pnpm add @egova/egovis-sdk

也可以使用 npm:

npm install @egova/egovis-sdk

快速开始

import { create, type BusinessPageContext } from '@egova/egovis-sdk'

const assistant = create({
  assistantUrl: 'https://ai.example.com/assistant.html',
  projectId: 'project-100',
  contextProvider: (): BusinessPageContext => ({
    source: {
      systemCode: 'case-center',
      pageCode: 'case-list',
    },
    page: {
      title: '案件统计',
      path: location.pathname,
    },
    content: {
      filters: { status: 'pending' },
      selectedCaseIds: ['case-1'],
    },
    summary: [
      { key: 'total', label: '案件数', value: '12' },
    ],
    questions: [
      { title: '分析趋势', content: '分析当前案件变化趋势' },
    ],
  }),
})

assistant.on('error', error => console.error('智能助手异常', error))

默认使用 drawer 布局,并在页面右下角显示系统 AI 图标。首次点击图标时打开智能助手。

初始化选项

| 选项 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | assistantUrl | string | - | 必填,助手 assistant.html 的绝对 HTTP(S) 地址。 | | projectId | string | - | 必填,当前 Egovis 项目 ID。 | | mountTarget | string \| HTMLElement | document.body | SDK 挂载节点。 | | layout | 'drawer' \| 'embedded' | 'drawer' | 助手布局方式。 | | trigger.label | string | - | AI 按钮文案;未配置时只显示系统 AI 图标。 | | trigger.placement | 'left' \| 'right' | 'right' | AI 按钮位于页面左下角或右下角。 | | trigger.hidden | boolean | false | 是否隐藏 SDK 内置 AI 按钮。 | | drawer.width | number | 480 | 抽屉宽度,取值限制为 360~960 px。 | | drawer.placement | 'left' \| 'right' | 'right' | 抽屉从页面左侧或右侧打开。 | | contextProvider | () => BusinessPageContext \| Promise<BusinessPageContext> | - | 返回当前页面最新业务上下文。 | | handshakeTimeoutMs | number | 5000 | 助手加载就绪超时时间,单位为 ms。 | | ackTimeoutMs | number | 3000 | 上下文同步超时时间,单位为 ms。 |

业务上下文

字段说明

| 字段 | 必填 | 限制 | | --- | --- | --- | | source.systemCode | 是 | 非空字符串,最长 128 个字符。 | | source.pageCode | 是 | 非空字符串,最长 128 个字符。 | | page.title | 是 | 非空字符串,最长 256 个字符。 | | page.path | 否 | 最长 1024 个字符,必须以 / 开头,不能包含 query(?)或 hash(#)。 | | subject.type | 否 | 非空字符串,最长 128 个字符。 | | subject.title | 否 | 最长 256 个字符。 | | summary | 否 | 最多 8 项,各项 key 必须唯一。 | | summary[].key | 是 | 非空字符串,最长 128 个字符。 | | summary[].label | 是 | 非空字符串,最长 256 个字符。 | | summary[].value | 是 | 最长 2048 个字符。 | | content | 是 | 根必须是普通 JSON 对象(允许 null 原型),属性值只能包含标准 JSON 值,最大嵌套深度为 16 层。 | | questions | 否 | 最多 20 项,仅用于 iframe 快捷提问,不提交后端。 | | questions[].title | 是 | 非空字符串,最长 256 个字符。 | | questions[].content | 是 | 非空字符串,单个字符串最长 16 KB。 |

summary 中每一项包含 keylabelvaluequestions 中每一项包含 titlecontent

单个上下文序列化后最多 64 KB,questions 也参与该 iframe 协议大小校验。所有对象键最长 128 个字符,所有未设置更小字段上限的单个字符串最长 16 KB。content 从根容器开始计数,数组和对象容器最大嵌套深度为 16 层,基础值不增加深度。上下文使用严格字段校验,数组必须是无空洞的密集数组;不支持循环引用、访问器属性、数组额外自有属性、函数、undefined、日期对象和其他非 JSON 值。

对象键按大小写不敏感方式检查,禁止使用 tokenaccessTokenrefreshTokenidTokenauthorizationcookiesetCookiepasswordsecretclientSecretprivateKey 等敏感键。业务系统仍应按白名单组装数据并主动脱敏。

上下文 Hash

上下文 Hash 只包含 sourcepagesubjectsummarycontentquestions 排除在 Hash 输入之外,也不会提交后端,只通过 iframe 协议提供快捷提问。SDK 先递归排序对象键并生成稳定 JSON,再按 UTF-8 字节执行 FNV-1a 32 位计算,输出 8 位小写十六进制字符串。

以下固定向量用于跨语言实现校验:

{"content":{"area":"东城区","icon":"🚀"},"page":{"path":"/statistics/cases","title":"案件统计"},"source":{"pageCode":"case-overview","systemCode":"statistics"},"summary":[{"key":"total","label":"案件数","value":"12"}]}

对应 Hash 为 4c456b2a

更新上下文

页面路由、查询条件、表格数据或选中项发生变化后,调用 refreshContext() 重新获取当前页面数据:

async function handleSearch() {
  await loadTableData()
  await assistant.refreshContext()
}

refreshContext() 会重新执行初始化时传入的 contextProvider。建议先完成业务页面的数据更新,再调用该方法。

如果业务系统已经持有完整的新上下文,也可以直接更新:

assistant.setContext(nextContext)

每次更新都应提供完整上下文。summarycontentquestions 会整体替换,不会与上一次数据合并。

发送与后端流转

  • 用户每次发送消息时,iframe 会冻结发送瞬间的完整业务上下文快照,并随 /api/v1/conversation-orchestrator/stream 请求提交。
  • contextHash 相同也不会省略快照;后端仍会为当前 user 行保存完整业务上下文,保证后续 Agent 每轮都能从持久化消息恢复。
  • questions 只用于前端快捷提问,不进入请求、数据库或模型输入。
  • 用户点击“移除页面数据”后,下一轮请求不携带业务上下文;后端不会从历史轮次恢复旧快照。
  • 确认续接、同轮重试和 SSE 重连必须复用首次持久化的快照;重连请求不允许携带新的 businessContext
  • 当前只支持主助手和 Builder ReAct 子 Agent 使用业务上下文;工作流、专家团和 Plan-Execute 默认不接收完整业务上下文。
  • 后端会再次校验 Schema、64 KB 大小、Hash、项目归属和内部 Part 伪造,业务系统不能绕过 SDK 直接写入内部消息结构;tokenaccessTokenrefreshTokenidTokenauthorizationcookiesetCookiepasswordsecretclientSecretprivateKey 等敏感字段会被拒绝。
  • 业务上下文保存于 mate_message.content_parts 的两个内部 Part:结构化 egovis_business_context_v1 与回放 egovis_part_v2,不写入 task、conversation 或 message 普通文本字段。

抽屉布局

const assistant = create({
  assistantUrl: 'https://ai.example.com/assistant.html',
  projectId: 'project-100',
  layout: 'drawer',
  trigger: {
    label: 'AI 助手',
    placement: 'right',
  },
  drawer: {
    width: 440,
    placement: 'right',
  },
  contextProvider: () => currentPageContext,
})

抽屉首次打开时加载助手;关闭后保留当前助手页面和对话状态,再次打开时会重新获取当前页面上下文。

使用业务系统自己的按钮

隐藏 SDK 内置按钮,由业务系统调用实例方法打开或关闭助手:

const assistant = create({
  assistantUrl: 'https://ai.example.com/assistant.html',
  projectId: 'project-100',
  trigger: { hidden: true },
  contextProvider: () => currentPageContext,
})

document.querySelector('#ai-button')?.addEventListener('click', () => {
  void assistant.toggle()
})

页面嵌入布局

<div id="assistant-panel"></div>
#assistant-panel {
  width: 420px;
  height: 100vh;
}
const assistant = create({
  assistantUrl: 'https://ai.example.com/assistant.html',
  projectId: 'project-100',
  mountTarget: '#assistant-panel',
  layout: 'embedded',
  contextProvider: () => currentPageContext,
})

embedded 布局会填满挂载节点,因此挂载节点必须具有明确的宽度和高度。该布局始终显示,调用 close() 不会隐藏助手。

实例方法

| 方法 | 说明 | | --- | --- | | open() | 打开抽屉并重新获取当前页面上下文。 | | close() | 关闭抽屉;对 embedded 布局无效。 | | toggle() | 切换抽屉的打开状态。 | | refreshContext() | 重新执行 contextProvider。 | | setContext(context) | 使用完整快照更新业务上下文。 | | clearContext() | 清除当前业务上下文。 | | setProjectId(projectId) | 切换 Egovis 项目。 | | on(event, handler) | 监听 SDK 事件,返回取消监听函数。 | | destroy() | 销毁 SDK 实例并移除页面元素。 |

业务页面卸载或微前端应用销毁时,必须销毁 SDK 实例:

assistant.destroy()

事件

const offReady = assistant.on('ready', () => {
  console.info('智能助手已就绪')
})

const offError = assistant.on('error', error => {
  console.error('智能助手异常', error)
})

// 不再需要监听时取消订阅
offReady()
offError()

支持的事件包括 openclosereadycontext-ackcontext-rejectederror

切换项目

业务系统切换项目后,应同步更新 SDK 的 projectId

await assistant.setProjectId(nextProjectId)

调用前应先完成业务系统自身的项目状态切换,确保 contextProvider 能返回新项目的数据。

样式调整

按钮位置、抽屉方向和宽度优先通过初始化选项配置。颜色和层级可以通过 CSS 变量覆盖:

egovis-ai-assistant {
  --egovis-assistant-trigger-bg: #1677ff;
  --egovis-assistant-trigger-color: #ffffff;
  --egovis-assistant-z-index: 2000;
}

IIFE/CDN 接入

<script src="https://cdn.example.com/egovis-sdk.iife.js"></script>
<script>
  const assistant = EgovisSDK.create({
    assistantUrl: 'https://ai.example.com/assistant.html',
    projectId: 'project-100',
    contextProvider: () => ({
      source: { systemCode: 'case-center', pageCode: 'case-detail' },
      page: { title: '案件详情', path: location.pathname },
      content: { caseId: 'case-1', status: 'pending' }
    })
  })
</script>

数据安全

contextProvider 应按白名单组装数据,并在返回前完成脱敏:

contextProvider: () => ({
  source: { systemCode: 'case-center', pageCode: 'case-detail' },
  page: { title: '案件详情', path: location.pathname },
  content: {
    caseId: currentCase.id,
    category: currentCase.category,
    reporterPhone: maskPhone(currentCase.reporterPhone),
  },
})

不要提供 Token、Cookie、密码、身份证明、完整手机号或其他认证凭证。assistantUrl 也不应携带 Token 或其他敏感信息。

跨域配置

业务系统与智能助手跨域部署时,需要完成以下配置:

  1. 在实际托管 assistant.html 的服务端响应中配置 CSP frame-ancestors,允许业务系统 Origin。
  2. 为智能助手前端配置允许接入的业务系统 Origin,例如 VITE_ASSISTANT_HOST_ORIGINS=https://business.example.com

只填写规范的 HTTP(S) Origin,不要使用 *、路径、查询参数或片段。生产环境应使用 HTTPS。