@corti/embedded-web

中文文档
2.1.0发布于 2026/10/29MITTypeScriptES Module构建来源已验证近 30 天下载 4876

Corti 嵌入的 Web 组件

中文使用文档
文档目录14 节
  1. 特征
  2. 安装
  3. 测试
  4. 使用量
  5. 网络组件
  6. 反应组件
  7. 显示/隐藏组件
  8. API 方法(建议)
  9. 建筑
  10. 反应组件特性
  11. 反应组件导入
  12. 事件收听器设置
  13. API 方法( 反应)
  14. 软件包结构

Corti 嵌入式网络组件

一个网络组件和React组件库,为Corti AI助手提供嵌入式接口.

特征

  • Web 组件和反应: 既可作为本地网络组件,也可以作为反应组件
  • 显示/ 隐藏: 控制聊天界面的能见度
  • 认证支持: 内置认证信件处理
  • 类型脚本支持: 包含全部类型脚本定义

安装

npm install @corti/embedded-web

测试

运行测试前安装依赖性 :

npm install

运行完整的测试套件 :

npm test

开发时以监视模式运行测试 :

npm run test:watch

只运行嵌入式组件通信集成测试 :

npx tsc -p tsconfig.test.json && npx wtr .tmp/test-dist/test/corti-embedded.integration.test.js

在Chrimium、Firefox和WebKit进行整合测试:

npx tsc -p tsconfig.test.json && EMBEDDED_WEB_TEST_BROWSERS=chromium,firefox,webkit npx wtr .tmp/test-dist/test/corti-embedded.integration.test.js

对已安装的微软边缘频道进行集成测试 :

npx tsc -p tsconfig.test.json && EMBEDDED_WEB_TEST_BROWSERS=chromium EMBEDDED_WEB_CHROMIUM_CHANNEL=msedge npx wtr .tmp/test-dist/test/corti-embedded.integration.test.js

集成测试默认在Playwright Chromium中运行,可被扩展为Firefox,WebKit,或已安装的Edge通道. 它根据真实的iframe验证了公共网络组件 API postMessage 边界并使用本地测试跑道设置,因此不需要访问活式嵌入式助理服务.

Pull requests也在Windows GitHub Actions transfer上运行了针对Microsoft Edge的集成测试.

使用量

网络组件

<corti-embedded
  id="corti-component"
  baseurl="https://assistant.eu.corti.app" <!-- REQUIRED -->
></corti-embedded>
const myComponent = document.getElementById('corti-component');

const userResponse = await myComponent.auth({...});

const interaction = await myComponent.createInteraction({
  "assignedUserId": null,
  "encounter": {
    "identifier": `encounter-${Date.now()}`,
    "status": "planned",
    "type": "first_consultation",
    "period": {
      "startedAt": "2025-11-11T16:14:59.923Z"
    }
  }
});

await myComponent.setInteractionOptions({
  templates: {
    defaultTemplate: {
      behaviour: "fallback",
      template: { source: "standard", id: "soap_note" },
    },
  },
});
await myComponent.addFacts([{"text": "Chest pain", "group": "other"}]);
await myComponent.navigate({ path: "/interactions/123" });
await myComponent.show()

一般活动收听器(网络组件)

使用 event 作为网络组件集成的犬科事件流。 遗产 embedded-event 流已删除.

myComponent.addEventListener("event", event => {
  const { detail } = event;
  console.log(detail.name, detail.payload);
});

反应组件

import React, { useRef } from "react";
import {
  CortiEmbeddedReact,
  type CortiEmbeddedReactRef,
  type CortiEmbeddedEvent,
  type CortiEmbeddedReadyEvent,
  useCortiEmbeddedApi,
  useCortiEmbeddedStatus,
} from "@corti/embedded-web/react";

function App() {
  const cortiRef = useRef<CortiEmbeddedReactRef>(null);
  const api = useCortiEmbeddedApi(cortiRef);
  const { status } = useCortiEmbeddedStatus(cortiRef);

  const handleReady = (event: CortiEmbeddedReadyEvent) => {
    console.log("Corti component is ready!", event.detail);
  };

  const handleEvent = (event: CortiEmbeddedEvent) => {
    console.log("Event name:", event.detail.name);
    console.log("Event payload:", event.detail.payload);
  };

  const handleAuth = async () => {
    try {
      const user = await api.auth({
        access_token: "your-token",
        token_type: "Bearer",
        // ... rest of the token response
      });
      console.log("Authenticated:", user);

      await api.setInteractionOptions({
        templates: {
          defaultTemplate: {
            behaviour: "fallback",
            template: { source: "standard", id: "soap_note" },
          },
        },
      });
      await api.createInteraction({
        encounter: {
          identifier: `encounter-${Date.now()}`,
          status: "planned",
          type: "first_consultation",
          period: { startedAt: new Date().toISOString() },
        },
      });
    } catch (error) {
      console.error("Auth failed:", error);
    }
  };

  return (
    <div style={{ height: "100vh" }}>
      <button onClick={handleAuth}>Authenticate</button>

      <CortiEmbeddedReact
        ref={cortiRef}
        baseURL="https://assistant.eu.corti.app" // REQUIRED
        visibility="visible"
        onReady={handleReady}
        onEvent={handleEvent}
        onError={event => console.error("Embedded error:", event.detail)}
        style={{ width: "100%", height: "500px" }}
      />

      <pre>{JSON.stringify(status, null, 2)}</pre>
    </div>
  );
}

显示/隐藏组件

const component = document.getElementById("corti-component");

// Show the chat interface
component.show();

// Hide the chat interface
component.hide();
  • 使用这些命名的助手执行共同的任务 。 它们提供了更明确的意图和合理的默认.

认证

在使用嵌入式应用程序之前需要认证 。 载荷传到 component.auth(...) 应直接取自您的身份代号 响应(例如,Keycloak/OIDC符号端点响应).

使用基于用户的认证(OAuth2/OIDC). 仅限客户端的流量 不支持嵌入式应用程序 .

const authResponse = await component.auth({
  // Use the full token response from your IdP
  access_token: 'YOUR_JWT',
  token_type: 'Bearer',
  // include other token fields from your provider response (expires_in, refresh_token, etc.)
  ...
});

配置辅助

await component.configureApp({
  ui: {
    aiChat: true,
    navigation: false,
  },
  appearance: {
    primaryColor: "#000000",
  },
});

设置交互选项

await component.setInteractionOptions({
  mode: {
    fallback: "virtual",
    options: ["in-person", "virtual"],
  },
  spokenLanguage: {
    fallback: "en",
  },
  templates: {
    defaultTemplate: {
      behaviour: "fallback",
      template: { source: "standard", id: "discharge-summary" },
    },
  },
});

添加事实

await component.addFacts([
    { text: 'Patient reports chest pain', group: 'subjective' },
    { text: 'BP 120/80', group: 'vitals' },
  ],

导航

await component.navigate({ path: "/interactions/123" });

创建交互

const created = await component.createInteraction({
  assignedUserId: null,
  encounter: {
    identifier: "enc-123",
    status: "in-progress",
    type: "consult",
    period: { startedAt: new Date().toISOString() },
    title: "Visit for cough",
  },
  patient: {
    identifier: "pat-456",
  },
});

开始记录/ 停止记录

await component.startRecording();
// ... later
await component.stopRecording();

获取状态

const status = await component.getStatus();

回返情况:

  • auth数字 : { isAuthenticated, user? }
  • applicationVersion: 嵌入式 Corti 助手的版本
  • currentUrl: iframe 内的当前 URL
  • interaction: 开放式互动的细节,或 null
  • isMedicalDevice:运行的建筑是否为医疗器械. 何时 true, (中文(简体) ), medicalDevice 包含 buildDate, (中文(简体) ), deviceIdentifier,以及 udi。 。 。 .

获得模板

const { templates } = await component.getTemplates();

每个模板都有 id, (中文(简体) ), name, (中文(简体) ), language,以及 isCustom附加可选 description, (中文(简体) ), templateType, (中文(简体) ), outputLanguages,以及 sections。 。 。 .

建筑

本构成部分使用a PostMessageHandler 工具类:

  • 管理信件收听器并清理
  • 使用独有的ID跟踪待决请求
  • 处理响应关联
  • 确保适当清理销毁部件

反应组件特性

反应组件( R)CortiEmbeddedReact)作为额外出口,提供:

  • 基于 Hook 的 API 访问数字 : useCortiEmbeddedApi(ref) 暴露有实例限制的方法(auth, (中文(简体) ), navigate, (中文(简体) ), createInteraction, (中文(简体) ), showDeviceLinkQR页:1
  • 一般事件流数字 : onEvent 收到包装 event CustomEvent,与 event.detail 形状为 { name, payload }
  • 状态钩数字 : useCortiEmbeddedStatus(ref) 保持最新状态/反应状态
  • 多机构安全: API 方法被设定为您通过
  • 反应道具: 标准反应道具如 className, (中文(简体) ), style等 (中文(简体) ).

反应组件导入

import {
  CortiEmbeddedReact,
  CortiEmbedded, // Web component also available
  type CortiEmbeddedReactRef,
  useCortiEmbeddedApi,
  useCortiEmbeddedStatus,
} from "@corti/embedded-web/react";

事件收听器设置

  • 使用 onEvent 作为包装的全副听者 event 流线.
  • onEvent 接收原始数据 event CustomEvent,以及 event.detail 形状如下: { name: string; payload: unknown }。 。 。 .
  • 通用流包括: embedded.ready 以及我们文件中列出的其他已转发的嵌入事件.
  • onReady 是原始事物的方便倾听者 embedded.ready CustomEvent。 。 。 .
  • error.triggered 未通过 onEvent它会去 onError 换句话说.
  • 完整活动目录和有效载荷细节记录在:
  • onEvent, (中文(简体) ), onReady,以及 onError 穿过生地 CustomEvent。 。 。 .
<CortiEmbeddedReact
  baseURL="https://assistant.eu.corti.app"
  onEvent={event => {
    console.log(event.detail.name, event.detail.payload);
  }}
  onReady={event => console.log("Ready", event.detail)}
  onError={event => console.error(event.detail)}
/>

API 方法( 反应)

使用具有相同组件的 API 钩:

import React, { useRef } from 'react';
import {
  CortiEmbeddedReact,
  type CortiEmbeddedReactRef,
  useCortiEmbeddedApi,
} from '@corti/embedded-web/react';

function Example() {
  const ref = useRef<CortiEmbeddedReactRef>(null);
  const api = useCortiEmbeddedApi(ref);

  const run = async () => {
    await api.auth({ access_token: '...', token_type: 'Bearer' });
    const created = await api.createInteraction({ encounter: { ... } });
    await api.navigate({ path: `/session/${created.id}` });
  };

  return (
    <>
      <button onClick={() => void run()}>Run</button>
      <CortiEmbeddedReact ref={ref} baseURL="https://assistant.eu.corti.app" />
    </>
  );
}

详细反应用法示例见 文件/反应-使用.md。 。 。 .

关于配置迁移细节,见 文件/移民指南.md 财务报告和审定财务报表 文件/折旧时间线.md。 。 。 .

软件包结构

  • 默认导出仅限网页部分(dist/web-bundle.js,可读非最小捆绑)
  • 反应导出:网络组件+反应组件(@corti/embedded-web/react(中文(简体) )
  • 无依赖关系: Web 组件捆绑没有外部依赖性
  • 同伴依赖关系: React 组件仅要求作为对等依赖的 React

版本与发布记录

@corti/embedded-web 共发布 13 个版本,首次发布于 2026/01/12;过去 12 个月发布了 13 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.1.0latest2026/10/2912 天前
2.0.12026/10/1625 天前
2.0.02026/10/1526 天前
1.1.02026/09/111 个月前
1.0.22026/09/032 个月前
1.0.12026/07/243 个月前

其他发布通道:alpha → 0.1.0-alpha.3。

关于 @corti/embedded-web 的常见问题

@corti/embedded-web 是什么?

Corti 嵌入的 Web 组件

如何安装 @corti/embedded-web?

在项目目录运行 npm install @corti/embedded-web,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^18.0.0 || ^19.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@corti/embedded-web 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@corti/embedded-web 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@corti/embedded-web 可以商用吗?

@corti/embedded-web 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@corti/embedded-web 的下载量有多少?

根据 npm 官方下载统计,@corti/embedded-web 在 2026/10/11 – 2026/11/09 这 30 天内被下载 4,876 次,日均约 163 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@corti/embedded-web 还在维护吗?

最新版本 2.1.0 发布于 2026/10/29(12 天前);至今共发布 13 个版本,其中过去 12 个月发布了 13 个;首次发布于 2026/01/12。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。