@corti/embedded-web 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +273 -0
- package/dist/CortiEmbedded.d.ts +102 -0
- package/dist/CortiEmbedded.js +452 -0
- package/dist/CortiEmbedded.js.map +1 -0
- package/dist/bundle.js +96 -0
- package/dist/corti-embedded.d.ts +1 -0
- package/dist/corti-embedded.js +5 -0
- package/dist/corti-embedded.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/internal-types.d.ts +231 -0
- package/dist/internal-types.js +2 -0
- package/dist/internal-types.js.map +1 -0
- package/dist/public-types.d.ts +238 -0
- package/dist/public-types.js +2 -0
- package/dist/public-types.js.map +1 -0
- package/dist/react/CortiEmbeddedReact.d.ts +25 -0
- package/dist/react/CortiEmbeddedReact.js +28 -0
- package/dist/react/CortiEmbeddedReact.js.map +1 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +2 -0
- package/dist/react/index.js.map +1 -0
- package/dist/styles/base.d.ts +4 -0
- package/dist/styles/base.js +10 -0
- package/dist/styles/base.js.map +1 -0
- package/dist/styles/container-styles.d.ts +1 -0
- package/dist/styles/container-styles.js +35 -0
- package/dist/styles/container-styles.js.map +1 -0
- package/dist/styles/theme.d.ts +2 -0
- package/dist/styles/theme.js +101 -0
- package/dist/styles/theme.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils/PostMessageHandler.d.ts +119 -0
- package/dist/utils/PostMessageHandler.js +353 -0
- package/dist/utils/PostMessageHandler.js.map +1 -0
- package/dist/utils/baseUrl.d.ts +1 -0
- package/dist/utils/baseUrl.js +25 -0
- package/dist/utils/baseUrl.js.map +1 -0
- package/dist/utils/embedUrl.d.ts +2 -0
- package/dist/utils/embedUrl.js +23 -0
- package/dist/utils/embedUrl.js.map +1 -0
- package/dist/utils/errorFormatter.d.ts +10 -0
- package/dist/utils/errorFormatter.js +163 -0
- package/dist/utils/errorFormatter.js.map +1 -0
- package/dist/web-bundle.js +89 -0
- package/dist/web-index.d.ts +3 -0
- package/dist/web-index.js +3 -0
- package/dist/web-index.js.map +1 -0
- package/package.json +129 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Henrik Cullen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Corti Embedded Web Component
|
|
2
|
+
|
|
3
|
+
A web component and React component library that provides an embedded interface for Corti AI assistant.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Web Component & React**: Available as both a native web component and React component
|
|
8
|
+
- **Show/Hide**: Control the visibility of the chat interface
|
|
9
|
+
- **Authentication Support**: Built-in authentication message handling
|
|
10
|
+
- **TypeScript Support**: Full TypeScript definitions included
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @corti/embedded-web
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The package provides a web component by default. For React usage, also install React as a peer dependency:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install react @types/react
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Web Component
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<corti-embedded
|
|
30
|
+
id="corti-component"
|
|
31
|
+
base-url="https://assistant.eu.corti.app" <!-- REQUIRED -->
|
|
32
|
+
></corti-embedded>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
const myComponent = document.getElementById('corti-component');
|
|
37
|
+
|
|
38
|
+
const userResponse = await myComponent.auth({...});
|
|
39
|
+
|
|
40
|
+
const interaction = await myComponent.createInteraction({
|
|
41
|
+
"assignedUserId": null,
|
|
42
|
+
"encounter": {
|
|
43
|
+
"identifier": `encounter-${Date.now()}`,
|
|
44
|
+
"status": "planned",
|
|
45
|
+
"type": "first_consultation",
|
|
46
|
+
"period": {
|
|
47
|
+
"startedAt": "2025-11-11T16:14:59.923Z"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
await myComponent.configureSession({"defaultTemplateKey": "soap_note"});
|
|
53
|
+
await myComponent.addFacts([{"text": "Chest pain", "group": "other"}]);
|
|
54
|
+
await myComponent.navigate('/interactions/123');
|
|
55
|
+
await myComponent.show()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### React Component
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import React, { useRef } from 'react';
|
|
62
|
+
import {
|
|
63
|
+
CortiEmbeddedReact,
|
|
64
|
+
type CortiEmbeddedReactRef,
|
|
65
|
+
type EmbeddedEventData,
|
|
66
|
+
} from '@corti/embedded-web/react';
|
|
67
|
+
|
|
68
|
+
function App() {
|
|
69
|
+
const cortiRef = useRef<CortiEmbeddedReactRef>(null);
|
|
70
|
+
|
|
71
|
+
const handleReady = () => {
|
|
72
|
+
console.log('Corti component is ready!');
|
|
73
|
+
cortiRef.current?.show();
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const handleAuthChanged = (
|
|
77
|
+
event: CustomEvent<EmbeddedEventData['auth-changed']>,
|
|
78
|
+
) => {
|
|
79
|
+
console.log('User authenticated:', event.detail.user);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const handleAuth = async () => {
|
|
83
|
+
if (!cortiRef.current) return;
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
const user = await cortiRef.current.auth({
|
|
87
|
+
access_token: 'your-token',
|
|
88
|
+
token_type: 'Bearer',
|
|
89
|
+
// ... rest of the token response
|
|
90
|
+
});
|
|
91
|
+
console.log('Authenticated:', user);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error('Auth failed:', error);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<div style={{ height: '100vh' }}>
|
|
99
|
+
<button onClick={handleAuth}>Authenticate</button>
|
|
100
|
+
|
|
101
|
+
<CortiEmbeddedReact
|
|
102
|
+
ref={cortiRef}
|
|
103
|
+
baseURL="https://assistant.eu.corti.app" // REQUIRED
|
|
104
|
+
visibility="visible"
|
|
105
|
+
onReady={handleReady}
|
|
106
|
+
style={{ width: '100%', height: '500px' }}
|
|
107
|
+
// or use className
|
|
108
|
+
className="w-full h-full"
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Show/Hide the Component
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
const component = document.getElementById('corti-component');
|
|
119
|
+
|
|
120
|
+
// Show the chat interface
|
|
121
|
+
component.show();
|
|
122
|
+
|
|
123
|
+
// Hide the chat interface
|
|
124
|
+
component.hide();
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### API methods (recommended)
|
|
128
|
+
|
|
129
|
+
- Use these named helpers for common tasks. They provide clearer intent and sensible defaults.
|
|
130
|
+
|
|
131
|
+
#### auth
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
const authResponse = await component.auth({
|
|
135
|
+
// Example: Keycloak-style token + mode
|
|
136
|
+
access_token: 'YOUR_JWT',
|
|
137
|
+
token_type: 'Bearer',
|
|
138
|
+
mode: 'stateful',
|
|
139
|
+
...
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### configureSession
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
await component.configureSession({
|
|
147
|
+
defaultLanguage: 'en',
|
|
148
|
+
defaultOutputLanguage: 'en',
|
|
149
|
+
defaultTemplateKey: 'discharge-summary',
|
|
150
|
+
defaultMode: 'virtual',
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### addFacts
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
await component.addFacts([
|
|
158
|
+
{ text: 'Patient reports chest pain', group: 'subjective' },
|
|
159
|
+
{ text: 'BP 120/80', group: 'vitals' },
|
|
160
|
+
],
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### navigate
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
await component.navigate('/interactions/123');
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### createInteraction
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
const created = await component.createInteraction({
|
|
173
|
+
assignedUserId: null,
|
|
174
|
+
encounter: {
|
|
175
|
+
identifier: 'enc-123',
|
|
176
|
+
status: 'in-progress',
|
|
177
|
+
type: 'consult',
|
|
178
|
+
period: { startedAt: new Date().toISOString() },
|
|
179
|
+
title: 'Visit for cough',
|
|
180
|
+
},
|
|
181
|
+
patient: {
|
|
182
|
+
identifier: 'pat-456',
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
#### startRecording / stopRecording
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
await component.startRecording();
|
|
191
|
+
// ... later
|
|
192
|
+
await component.stopRecording();
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### getStatus (debugging)
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
console.log(component.getStatus());
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Architecture
|
|
202
|
+
|
|
203
|
+
The component uses a `PostMessageHandler` utility class that:
|
|
204
|
+
|
|
205
|
+
- Manages message listeners and cleanup
|
|
206
|
+
- Tracks pending requests with unique IDs
|
|
207
|
+
- Handles response correlation
|
|
208
|
+
- Ensures proper cleanup on component destruction
|
|
209
|
+
|
|
210
|
+
## React Component Features
|
|
211
|
+
|
|
212
|
+
The React component (`CortiEmbeddedReact`) is available as an additional export and provides:
|
|
213
|
+
|
|
214
|
+
- **All Web Component APIs**: Full access to all methods via ref
|
|
215
|
+
- **React Event Handlers**: Native React event handling with proper typing
|
|
216
|
+
- **TypeScript Support**: Complete type definitions
|
|
217
|
+
- **Forward Ref**: Access to the underlying component instance
|
|
218
|
+
- **React Props**: Standard React props like `className`, `style`, etc.
|
|
219
|
+
|
|
220
|
+
### React Component Import
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import {
|
|
224
|
+
CortiEmbeddedReact,
|
|
225
|
+
CortiEmbedded, // Web component also available
|
|
226
|
+
type CortiEmbeddedReactProps,
|
|
227
|
+
type CortiEmbeddedReactRef,
|
|
228
|
+
} from '@corti/embedded-web/react';
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Available Events (React)
|
|
232
|
+
|
|
233
|
+
- `onReady`: Component is ready to receive API calls
|
|
234
|
+
- `onAuthChanged`: User authentication status changed
|
|
235
|
+
- `onInteractionCreated`: New interaction was created
|
|
236
|
+
- `onRecordingStarted` / `onRecordingStopped`: Recording status changes
|
|
237
|
+
- `onDocumentGenerated` / `onDocumentUpdated`: Document events
|
|
238
|
+
- `onNavigationChanged`: Navigation within the embedded UI changed
|
|
239
|
+
- `onUsage`: Usage data (credits used)
|
|
240
|
+
- `onError`: An error occurred
|
|
241
|
+
|
|
242
|
+
### Event Data Access
|
|
243
|
+
|
|
244
|
+
Events in React carry data in the `detail` property:
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
import type {
|
|
248
|
+
EmbeddedEventData,
|
|
249
|
+
CortiEmbeddedReactProps,
|
|
250
|
+
} from '@corti/embedded-web/react';
|
|
251
|
+
|
|
252
|
+
// Method 1: Use typed event handler interface
|
|
253
|
+
const handleAuthChanged: CortiEmbeddedReactProps['onAuthChanged'] = event => {
|
|
254
|
+
console.log('User:', event.detail.user);
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
// Method 2: Cast events manually
|
|
258
|
+
const handleDocumentGenerated = (event: Event) => {
|
|
259
|
+
const customEvent = event as CustomEvent<
|
|
260
|
+
EmbeddedEventData['document-generated']
|
|
261
|
+
>;
|
|
262
|
+
console.log('Document:', customEvent.detail.document);
|
|
263
|
+
};
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
For detailed React usage examples, see [docs/react-usage.md](./docs/react-usage.md).
|
|
267
|
+
|
|
268
|
+
## Package Structure
|
|
269
|
+
|
|
270
|
+
- **Default export**: Web component only (`dist/web-bundle.js`)
|
|
271
|
+
- **React export**: Web component + React component (`@corti/embedded-web/react`)
|
|
272
|
+
- **No dependencies**: Web component bundle has zero external dependencies
|
|
273
|
+
- **Peer dependencies**: React components require React as peer dependency only
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { Corti } from '@corti/sdk';
|
|
2
|
+
import { LitElement, type PropertyValues } from 'lit';
|
|
3
|
+
import type { ConfigureAppPayload, SetCredentialsPayload } from './internal-types.js';
|
|
4
|
+
import type { AuthCredentials, ComponentStatus, ConfigureAppResponsePayload, CortiEmbeddedAPI, InteractionDetails, InteractionPayload, SessionConfig, User } from './public-types.js';
|
|
5
|
+
export declare class CortiEmbedded extends LitElement implements CortiEmbeddedAPI {
|
|
6
|
+
static styles: import("lit").CSSResult[];
|
|
7
|
+
visibility: string;
|
|
8
|
+
baseURL: string;
|
|
9
|
+
private postMessageHandler;
|
|
10
|
+
private normalizedBaseURL;
|
|
11
|
+
connectedCallback(): void;
|
|
12
|
+
disconnectedCallback(): void;
|
|
13
|
+
private setupPostMessageHandler;
|
|
14
|
+
private dispatchPublicEvent;
|
|
15
|
+
private dispatchErrorEvent;
|
|
16
|
+
private isRealIframeLoad;
|
|
17
|
+
private handleIframeLoad;
|
|
18
|
+
private getIframe;
|
|
19
|
+
protected updated(changedProps: PropertyValues): void;
|
|
20
|
+
/**
|
|
21
|
+
* Authenticate with the Corti system
|
|
22
|
+
* @param credentials Authentication credentials
|
|
23
|
+
* @returns Promise resolving to user information
|
|
24
|
+
*/
|
|
25
|
+
auth(credentials: AuthCredentials): Promise<User>;
|
|
26
|
+
/**
|
|
27
|
+
* Create a new interaction
|
|
28
|
+
* @param encounter Encounter request data
|
|
29
|
+
* @returns Promise resolving to interaction details
|
|
30
|
+
*/
|
|
31
|
+
createInteraction(encounter: InteractionPayload): Promise<InteractionDetails>;
|
|
32
|
+
/**
|
|
33
|
+
* Configure the current session
|
|
34
|
+
* @param config Session configuration
|
|
35
|
+
* @returns Promise that resolves when configuration is complete
|
|
36
|
+
*/
|
|
37
|
+
configureSession(config: SessionConfig): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Add facts to the current session
|
|
40
|
+
* @param facts Array of facts to add
|
|
41
|
+
* @returns Promise that resolves when facts are added
|
|
42
|
+
*/
|
|
43
|
+
addFacts(facts: Corti.FactsCreateInput[]): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Navigate to a specific path within the embedded UI
|
|
46
|
+
* @param path Path to navigate to
|
|
47
|
+
* @returns Promise that resolves when navigation is complete
|
|
48
|
+
*/
|
|
49
|
+
navigate(path: string): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Start recording
|
|
52
|
+
* @returns Promise that resolves when recording starts
|
|
53
|
+
*/
|
|
54
|
+
startRecording(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Stop recording
|
|
57
|
+
* @returns Promise that resolves when recording stops
|
|
58
|
+
*/
|
|
59
|
+
stopRecording(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Get current component status
|
|
62
|
+
* @returns Promise resolving to current status
|
|
63
|
+
*/
|
|
64
|
+
getStatus(): Promise<ComponentStatus>;
|
|
65
|
+
/**
|
|
66
|
+
* Configure the component
|
|
67
|
+
* @param config Component configuration
|
|
68
|
+
* @returns Promise that resolves when configuration is applied
|
|
69
|
+
*/
|
|
70
|
+
configure(config: ConfigureAppPayload): Promise<ConfigureAppResponsePayload>;
|
|
71
|
+
/**
|
|
72
|
+
* Set authentication credentials without triggering auth flow
|
|
73
|
+
* @param credentials Authentication credentials to store
|
|
74
|
+
* @returns Promise that resolves when credentials are set
|
|
75
|
+
*/
|
|
76
|
+
setCredentials(credentials: SetCredentialsPayload): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Show the embedded UI
|
|
79
|
+
*/
|
|
80
|
+
show(): void;
|
|
81
|
+
/**
|
|
82
|
+
* Hide the embedded UI
|
|
83
|
+
*/
|
|
84
|
+
hide(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Check the current status of the iframe and PostMessageHandler
|
|
87
|
+
* Useful for debugging
|
|
88
|
+
* @deprecated Use getStatus() instead
|
|
89
|
+
*/
|
|
90
|
+
getDebugStatus(): {
|
|
91
|
+
ready: boolean;
|
|
92
|
+
iframeExists: boolean;
|
|
93
|
+
iframeSrc: string | undefined;
|
|
94
|
+
iframeContentWindow: boolean;
|
|
95
|
+
iframeContentDocument: boolean;
|
|
96
|
+
iframeReadyState: DocumentReadyState | undefined;
|
|
97
|
+
postMessageHandlerExists: boolean;
|
|
98
|
+
postMessageHandlerReady: boolean;
|
|
99
|
+
baseURL: string;
|
|
100
|
+
};
|
|
101
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
102
|
+
}
|