@corti/embedded-web

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

Web component for Corti Embedded

原始使用文档
文档目录14 节
  1. Features
  2. Installation
  3. Testing
  4. Usage
  5. Web Component
  6. React Component
  7. Show/Hide the Component
  8. API methods (recommended)
  9. Architecture
  10. React Component Features
  11. React Component Import
  12. Event Listener Setup
  13. API Methods (React)
  14. Package Structure

Corti Embedded Web Component

A web component and React component library that provides an embedded interface for Corti AI assistant.

Features

  • Web Component & React: Available as both a native web component and React component
  • Show/Hide: Control the visibility of the chat interface
  • Authentication Support: Built-in authentication message handling
  • TypeScript Support: Full TypeScript definitions included

Installation

npm install @corti/embedded-web

Testing

Install dependencies before running tests:

npm install

Run the full test suite:

npm test

Run tests in watch mode while developing:

npm run test:watch

Run only the embedded component communication integration test:

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

Run the integration test across Chromium, Firefox, and 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

Run the integration test against an installed Microsoft Edge channel:

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

The integration test runs in Playwright Chromium by default and can be expanded to Firefox, WebKit, or an installed Edge channel. It validates the public web component API against a real iframe postMessage boundary and uses the local test runner setup, so it does not require access to the live embedded Assistant service.

Pull requests also run the integration test against Microsoft Edge on a Windows GitHub Actions runner.

Usage

Web Component

<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()

Generic Event Listener (Web Component)

Use event as the canonical event stream for web component integrations. The legacy embedded-event stream has been removed.

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

React Component

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>
  );
}

Show/Hide the Component

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

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

// Hide the chat interface
component.hide();
  • Use these named helpers for common tasks. They provide clearer intent and sensible defaults.

auth

Authentication is required before using the embedded app. The payload passed to component.auth(...) should come directly from your identity provider token response (for example, Keycloak/OIDC token endpoint response).

Use user-based authentication (OAuth2/OIDC). Client-credentials-only flows are not supported for the embedded app.

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.)
  ...
});

configureApp

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

setInteractionOptions

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

addFacts

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

navigate

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

createInteraction

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",
  },
});

startRecording / stopRecording

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

getStatus

const status = await component.getStatus();

Returns:

  • auth: { isAuthenticated, user? }
  • applicationVersion: version of the embedded Corti Assistant
  • currentUrl: current URL inside the iframe
  • interaction: details of the open interaction, or null
  • isMedicalDevice: whether the running build is a medical device. When true, medicalDevice contains buildDate, deviceIdentifier, and udi.

getTemplates

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

Each template has id, name, language, and isCustom, plus optional description, templateType, outputLanguages, and sections.

Architecture

The component uses a PostMessageHandler utility class that:

  • Manages message listeners and cleanup
  • Tracks pending requests with unique IDs
  • Handles response correlation
  • Ensures proper cleanup on component destruction

React Component Features

The React component (CortiEmbeddedReact) is available as an additional export and provides:

  • Hook-based API access: useCortiEmbeddedApi(ref) exposes instance-bound methods (auth, navigate, createInteraction, showDeviceLinkQR, etc.)
  • Generic event stream: onEvent receives the wrapper's event CustomEvent, with event.detail shaped as { name, payload }
  • Status hook: useCortiEmbeddedStatus(ref) keeps latest status/reactive state
  • Multi-instance safety: API methods are scoped to the ref you pass
  • React Props: Standard React props like className, style, etc.

React Component Import

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

Event Listener Setup

  • Use onEvent as the catch-all listener for the wrapper's generic event stream.
  • onEvent receives the raw event CustomEvent, and event.detail has the following shape: { name: string; payload: unknown }.
  • That generic stream includes embedded.ready and other forwarded embedded events listed in our documentation.
  • onReady is a convenience listener for the raw embedded.ready CustomEvent.
  • error.triggered is not forwarded through onEvent. It goes to onError instead.
  • Full event catalog and payload details are documented at:
  • onEvent, onReady, and onError pass through the raw 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 Methods (React)

Use the API hook with the same component ref:

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" />
    </>
  );
}

For detailed React usage examples, see docs/react-usage.md.

For configuration migration details, see docs/migration-guide.md and docs/deprecation-timeline.md.

Package Structure

  • Default export: Web component only (dist/web-bundle.js, readable non-minified bundle)
  • React export: Web component + React component (@corti/embedded-web/react)
  • No dependencies: Web component bundle has zero external dependencies
  • Peer dependencies: React components require React as peer dependency only

版本与发布记录

@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 是什么?

Web component for Corti Embedded

如何安装 @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 和提交记录判断。