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

@_daniel_jiang/host-sdk

v1.1.3

Published

Agent 平台宿主嵌入 SDK(iframe Hub/Widget,框架无关)

Readme

@_daniel_jiang/host-sdk

Agent 平台宿主嵌入 SDK(iframe 模式)。UI 由 Agent /host/hub、/host/widget 渲染;宿主只需 init + registerPage。

表单提交与附件上传均在 Agent Widget iframe 内完成:用户点「开始」后,Widget 以 multipart 一次调用 POST /api/v1/host/scenarios/{workflow}/run(表单 JSON 字段 + 可选 attachment_files)。不再使用独立的 POST /sessions/{id}/files。

本文档随 npm 包发布,面向接入方(安装与用法)。本仓库维护者改 SDK / 发版说明见仓库根目录 README.md §4。

安装

npm install @_daniel_jiang/host-sdk
# 或 yarn add @_daniel_jiang/host-sdk
{
  "dependencies": {
    "@_daniel_jiang/host-sdk": "^1.1.3"
  }
}

官方源:https://www.npmjs.com/package/@_daniel_jiang/host-sdk
国内阿里云等私库一般可代理拉取。

用法

import { AgentHost } from '@_daniel_jiang/host-sdk'

await AgentHost.init({
  host: 'edc',
  // 推荐:BFF bootstrap 返回 agent_token + agent_web_origin,无需前端环境变量
  bootstrap: () => fetch('/boot-admin/agent/bootstrap?hosts=edc', { credentials: 'include' }).then((r) => r.json()),
  // 可选:打开需 establish 的 Widget 前强制刷新会话
  // prepareOpenWidget: () => bootstrapAgentSession(true),
  // 按需:Hub 场景弹窗打开时现取系统 / 名称 / 描述 / 菜单(不必全局 watch 路由)
  // getHostContext: () => ({ system: '我的项目', name: projectName, description, menu }),
})

AgentHost.registerPage(
  'edc_patient_list',
  [{
    id: 'form_fill',
    workflow: 'edc_form_fill',
    label: 'AI 填表',
    host: 'edc',
    prefilled: () => ({
      sub_project_id: currentSubProjectId,
      project_id: currentProjectId,
      target: buildTargetFromEdcSelection(selectedForm),
    }),
    enabled: () => Boolean(currentSubProjectId && selectedForm),
    hostContext: { refresh: 'patient_list' },
  }],
  {
    // 任务 success 且 hostContext.refresh 匹配时调用;unregisterPage 后自动失效
    refreshKey: 'patient_list',
    onRefresh: () => refreshPatientList(),
  },
)

// 表单列表页:AI 设计 CRF(上传 Word/PDF)
AgentHost.registerPage(
  'edc_form_list',
  [{
    id: 'crf_design',
    workflow: 'edc_crf_design',
    label: 'AI 设计 CRF',
    host: 'edc',
    prefilled: () => ({
      sub_project_id: currentSubProjectId,
      sort_start: nextFormSort,
    }),
    enabled: () => Boolean(currentSubProjectId),
    hostContext: { refresh: 'form_list' },
  }],
  { refreshKey: 'form_list', onRefresh: () => refreshFormList() },
)

AgentHost.openAction('edc_patient_list', 'form_fill')

// 离开页时务必 unregister(keep-alive 切走 / destroy),避免后台误刷
AgentHost.unregisterPage('edc_patient_list')

EDC / 专病库可用 createAgentPageMixin 自动处理进出页 register/unregister。

宿主上下文在 init({ getHostContext }) 提供:Hub 场景弹窗打开时 request-host-context 现取系统 / 名称 / 描述 / 菜单,不必对路由或专病做全局 watch。system 建议用:专病数据库系统 / 我的项目 / 数据探索(后两者为科研平台子系统)。手册 / 建设探讨是 Hub 全局场景,业务页只需 registerPage 本页 AI 能力。

无弹窗直跑(kind: 'direct')

缺省仍打开 Widget。kind: 'direct' 时点「立即开始」不弹 Widget:

  • 有 skill:Hub 创建会话并发送 Chat 消息(selected_skill_slugs),不走 POST /host/scenarios
  • 仅有 workflow:Hub 创建会话后静默 POST /host/scenarios(物化/推沙盒),仍不弹 Widget
  • 执行策略(no_tools / skip_post_summary)写在 Agent host_ui_registry,不写 Skill、也不由宿主 action 定死。Hub 直跑 skill 时拉 GET /host/workflows/{name}/ui;Chat @ 同一技能不读 host_ui,仍是完整 Agent。
  • 可选 noTools: true:仅作覆盖(旧宿主);新场景请只在 host_ui 声明 no_tools。 直跑不必填 workflow(纯 skill)或不必填 skill(纯 workflow)。hintPlacement: 'anchor' + anchor 把横幅贴到控件旁,仅当该控件聚焦时显示;不设则仍贴在右下角 FAB 上方。完成时 onRefresh 可收到 apply(如 { remark } 或 { form_values })。旧宿主不升级、不传这些字段,行为与 1.0 相同。

能否启动由宿主自己的 enabled() 决定,SDK 不按场景 slug 拦截。canOpen() 仅兼容旧调用,恒为 true。

Widget 内提交流程(iframe,宿主无需处理文件)

  1. SDK 打开 /host/widget?workflow=... iframe
  2. Widget 拉取 GET /host/workflows/{name}/ui 渲染表单(勾选填表场景 Widget 仅上传文书/文本)
  3. Widget 创建会话 POST /sessions
  4. 用户提交 → POST /host/scenarios/{name}/run(multipart,一次完成)
  5. Hub iframe 展示任务进度;成功 / 失败 / 取消完成后 SDK 对仍注册页触发 onRefresh(失败时通常无 apply,宿主可据此关 loading)

complete / success 来自 Agent 任务协议(Hub/Widget postMessage),与宿主业务 API 返回结构无关。

带附件的工作流(如 Excel 批量填表)无需宿主先上传文件;附件在 Widget 内选好后随 scenario run 一并提交。

Bootstrap 契约(宿主 BFF)

GET /agent/bootstrap?hosts=edc 建议返回:

{
  "agent_token": "...",
  "refresh_token": "...",
  "agent_web_origin": "https://agent.example.com"
}
  • agent_web_origin:Agent 前端地址(iframe、Hub)
  • Token 换取走 boot-admin → Agent API(agent-host-api-base-url),与 agent_web_origin 分离

可选:init({ agentOrigin: '...' }) 显式覆盖 BFF 下发的地址。

Scenario API(Headless / 自绘表单时)

iframe SDK 一般不需要宿主直调;若宿主自画表单、绕过 Widget,可按下列契约提交:

POST /api/v1/host/scenarios/{workflow_name}/run
Authorization: Bearer <token>
Content-Type: multipart/form-data

| 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | session_id | string | 是 | 已创建的 Agent 会话 UUID | | host | string | 否 | 宿主标识,默认 research_portal | | host_context | string (JSON) | 否 | 页面上下文、刷新回调等 | | prefilled | string (JSON) | 否 | 宿主勾选带入的只读参数 | | form_values | string (JSON) | 否 | 用户在表单中的选择 | | prompt_extra | string | 否 | 附加 prompt | | attachment_files | file[] | 否 | 附件,可多文件 |

响应示例:

{
  "success": true,
  "data": {
    "task_id": "uuid",
    "session_id": "uuid",
    "status": "queued",
    "stream_url": "/api/v1/tasks/{task_id}/stream"
  }
}

与 Chat 对比:

| 场景 | 接口 | |------|------| | Chat 发消息 + 附件 | POST /sessions/{id}/messages-with-files | | Host Widget / Scenario | POST /host/scenarios/{name}/run(multipart) |

完整契约见仓库 PRD/11_host_widget_integration.md §6。