@omniloy/sofia-sdk 1.0.4 → 1.0.6
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/dist/legacy/webcomponents.d.ts +14 -2
- package/dist/legacy/webcomponents.es.js +12407 -9491
- package/dist/legacy/webcomponents.umd.js +12404 -9488
- package/dist/react/index.css +326 -0
- package/dist/react/index.d.ts +33 -6
- package/dist/react/index.es.js +17954 -14461
- package/dist/webcomponents.d.ts +14 -2
- package/dist/webcomponents.es.js +21564 -18546
- package/dist/webcomponents.umd.js +21564 -18546
- package/package.json +1 -1
package/dist/react/index.css
CHANGED
|
@@ -646,6 +646,74 @@
|
|
|
646
646
|
color: var(--color-gray-600, #4b5563);
|
|
647
647
|
}
|
|
648
648
|
|
|
649
|
+
/* Connection status pill - inline banner replacing toasts.
|
|
650
|
+
Three states: reconnecting (neutral), disconnected (red), restored (dark). */
|
|
651
|
+
.omniscribe_connection-pill {
|
|
652
|
+
display: inline-flex;
|
|
653
|
+
align-items: center;
|
|
654
|
+
gap: 6px;
|
|
655
|
+
padding: 4px 10px;
|
|
656
|
+
border-radius: 9999px;
|
|
657
|
+
white-space: nowrap;
|
|
658
|
+
flex-shrink: 0;
|
|
659
|
+
font-weight: 500;
|
|
660
|
+
margin-inline: 8px;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
.omniscribe_connection-pill-icon {
|
|
664
|
+
display: inline-flex;
|
|
665
|
+
align-items: center;
|
|
666
|
+
justify-content: center;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
.omniscribe_connection-pill-icon--spin {
|
|
670
|
+
animation: omniscribe-connection-spin 1s linear infinite;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
@keyframes omniscribe-connection-spin {
|
|
674
|
+
from {
|
|
675
|
+
transform: rotate(0deg);
|
|
676
|
+
}
|
|
677
|
+
to {
|
|
678
|
+
transform: rotate(360deg);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
.omniscribe_connection-pill--reconnecting {
|
|
683
|
+
background-color: var(--color-gray-50, #f9fafb);
|
|
684
|
+
border: 1px solid var(--color-gray-200, #e5e7eb);
|
|
685
|
+
color: var(--color-gray-700, #374151);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
.omniscribe_connection-pill--disconnected {
|
|
689
|
+
background-color: #fdecec;
|
|
690
|
+
border: 1px solid #f8c7c7;
|
|
691
|
+
color: #b42318;
|
|
692
|
+
padding-right: 4px;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
.omniscribe_connection-pill--restored {
|
|
696
|
+
background-color: #1f2937;
|
|
697
|
+
border: 1px solid #1f2937;
|
|
698
|
+
color: #ffffff;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
.omniscribe_connection-pill-retry {
|
|
702
|
+
border-radius: 9999px !important;
|
|
703
|
+
gap: 4px;
|
|
704
|
+
padding-block: 3px !important;
|
|
705
|
+
padding-inline: 8px !important;
|
|
706
|
+
height: auto !important;
|
|
707
|
+
background-color: #d92d20 !important;
|
|
708
|
+
color: #ffffff !important;
|
|
709
|
+
border: none !important;
|
|
710
|
+
margin-left: 2px;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.omniscribe_connection-pill-retry:hover:not(:disabled) {
|
|
714
|
+
background-color: #b42318 !important;
|
|
715
|
+
}
|
|
716
|
+
|
|
649
717
|
/* Generate Report Button - Figma style */
|
|
650
718
|
.omniscribe_transcribe-generate-btn {
|
|
651
719
|
border-radius: 12px !important;
|
|
@@ -900,6 +968,236 @@
|
|
|
900
968
|
background-color: color-mix(in oklab, var(--report) 60%, transparent);
|
|
901
969
|
}
|
|
902
970
|
}
|
|
971
|
+
.omniscribe_modal-overlay {
|
|
972
|
+
position: absolute;
|
|
973
|
+
background-color: color-mix(in oklab, var(--black) 50%, transparent);
|
|
974
|
+
display: flex;
|
|
975
|
+
justify-content: center;
|
|
976
|
+
align-items: center;
|
|
977
|
+
z-index: 50;
|
|
978
|
+
height: 100vh;
|
|
979
|
+
width: 100vw;
|
|
980
|
+
right: 0;
|
|
981
|
+
bottom: calc(var(--spacing) * -5.2);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
.omniscribe_modal-container {
|
|
985
|
+
position: relative;
|
|
986
|
+
background-color: var(--white);
|
|
987
|
+
z-index: 100;
|
|
988
|
+
border-radius: 12px;
|
|
989
|
+
border: solid 1px var(--light-border);
|
|
990
|
+
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
|
991
|
+
padding: calc(var(--spacing) * 5);
|
|
992
|
+
transition-duration: 300ms;
|
|
993
|
+
transition-property: opacity;
|
|
994
|
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
995
|
+
max-width: 90vw;
|
|
996
|
+
max-height: 90vh;
|
|
997
|
+
}
|
|
998
|
+
.omniscribe_modal-container-scroll {
|
|
999
|
+
overflow: auto;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
.omniscribe_modal-container-show {
|
|
1003
|
+
opacity: 100%;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
.omniscribe_modal-container-hide {
|
|
1007
|
+
opacity: 0%;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
.omniscribe_modal-subcontainer {
|
|
1011
|
+
display: flex;
|
|
1012
|
+
flex-direction: column;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
.omniscribe_modal-title-container {
|
|
1016
|
+
display: flex;
|
|
1017
|
+
flex-direction: row;
|
|
1018
|
+
align-items: center;
|
|
1019
|
+
justify-content: space-between;
|
|
1020
|
+
margin-bottom: calc(var(--spacing) * 2);
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
.omniscribe_modal-title {
|
|
1024
|
+
font-size: var(--text-3xl); /* 1.875rem = 30px */
|
|
1025
|
+
line-height: var(--text-xl--line-height);
|
|
1026
|
+
font-weight: var(--font-weight-bold);
|
|
1027
|
+
margin: 0;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
.omniscribe_modal-button {
|
|
1031
|
+
border: none;
|
|
1032
|
+
background: transparent;
|
|
1033
|
+
line-height: var(--text-2xl--line-height);
|
|
1034
|
+
cursor: pointer;
|
|
1035
|
+
color: var(--black);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
@media (min-width: 768px) {
|
|
1039
|
+
.omniscribe_modal-container {
|
|
1040
|
+
max-width: 60vw;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/* Large screens: desktop */
|
|
1045
|
+
@media (min-width: 1024px) {
|
|
1046
|
+
.omniscribe_modal-container {
|
|
1047
|
+
max-width: 50vw;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
/* Very large screens: large desktop and ultra-wide */
|
|
1052
|
+
@media (min-width: 1440px) {
|
|
1053
|
+
.omniscribe_modal-container {
|
|
1054
|
+
max-width: 40vw;
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
/* Intermediate breakpoint: large tablets */
|
|
1059
|
+
@media (min-width: 640px) and (max-width: 767px) {
|
|
1060
|
+
.omniscribe_modal-container {
|
|
1061
|
+
max-width: 70vw;
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
/* The shared Modal overlay uses position: absolute anchored to its
|
|
1065
|
+
nearest positioned ancestor — which in our case is the chat footer,
|
|
1066
|
+
not the widget root. That puts the modal at the bottom of the widget.
|
|
1067
|
+
Override to position: fixed so the overlay covers the full viewport
|
|
1068
|
+
and the modal truly centers regardless of where in the React tree it
|
|
1069
|
+
was rendered. */
|
|
1070
|
+
.omniscribe_modal-overlay:has(.omniscribe_audio-cuts-modal) {
|
|
1071
|
+
position: fixed;
|
|
1072
|
+
inset: 0;
|
|
1073
|
+
width: 100%;
|
|
1074
|
+
height: 100%;
|
|
1075
|
+
top: 0;
|
|
1076
|
+
left: 0;
|
|
1077
|
+
bottom: 0;
|
|
1078
|
+
right: 0;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
.omniscribe_audio-cuts-modal {
|
|
1082
|
+
width: 480px;
|
|
1083
|
+
max-width: 90vw;
|
|
1084
|
+
padding: 24px !important;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
/* Override Modal's giant default h2 size for this dialog. */
|
|
1088
|
+
.omniscribe_audio-cuts-modal .omniscribe_modal-title-container {
|
|
1089
|
+
margin-bottom: 16px;
|
|
1090
|
+
align-items: flex-start;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
.omniscribe_audio-cuts-modal .omniscribe_modal-title {
|
|
1094
|
+
font-size: 18px;
|
|
1095
|
+
line-height: 1.3;
|
|
1096
|
+
font-weight: 700;
|
|
1097
|
+
letter-spacing: -0.01em;
|
|
1098
|
+
color: var(--color-gray-900, #0f172a);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
.omniscribe_audio-cuts-body {
|
|
1102
|
+
display: flex;
|
|
1103
|
+
flex-direction: column;
|
|
1104
|
+
gap: 16px;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/* Summary card: warning icon + paragraph in a soft container. */
|
|
1108
|
+
.omniscribe_audio-cuts-summary {
|
|
1109
|
+
display: flex;
|
|
1110
|
+
align-items: flex-start;
|
|
1111
|
+
gap: 12px;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
.omniscribe_audio-cuts-summary-icon {
|
|
1115
|
+
display: inline-flex;
|
|
1116
|
+
align-items: center;
|
|
1117
|
+
justify-content: center;
|
|
1118
|
+
flex-shrink: 0;
|
|
1119
|
+
width: 32px;
|
|
1120
|
+
height: 32px;
|
|
1121
|
+
border-radius: 9999px;
|
|
1122
|
+
background-color: #fef3c7;
|
|
1123
|
+
color: #b45309;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
.omniscribe_audio-cuts-summary-text {
|
|
1127
|
+
margin: 0;
|
|
1128
|
+
font-size: 14px;
|
|
1129
|
+
line-height: 1.5;
|
|
1130
|
+
color: var(--color-gray-800, #1f2937);
|
|
1131
|
+
flex: 1;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
/* Cut list: rounded gray container, clock icon per row, no bullets. */
|
|
1135
|
+
.omniscribe_audio-cuts-list {
|
|
1136
|
+
margin: 0;
|
|
1137
|
+
padding: 12px 14px;
|
|
1138
|
+
border-radius: 12px;
|
|
1139
|
+
background-color: var(--color-gray-50, #f9fafb);
|
|
1140
|
+
border: 1px solid var(--color-gray-200, #e5e7eb);
|
|
1141
|
+
list-style: none;
|
|
1142
|
+
max-height: 240px;
|
|
1143
|
+
overflow-y: auto;
|
|
1144
|
+
display: flex;
|
|
1145
|
+
flex-direction: column;
|
|
1146
|
+
gap: 8px;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
.omniscribe_audio-cuts-item {
|
|
1150
|
+
display: flex;
|
|
1151
|
+
align-items: center;
|
|
1152
|
+
gap: 8px;
|
|
1153
|
+
color: var(--color-gray-700, #374151);
|
|
1154
|
+
font-variant-numeric: tabular-nums;
|
|
1155
|
+
font-size: 13px;
|
|
1156
|
+
line-height: 1.4;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
.omniscribe_audio-cuts-item-icon {
|
|
1160
|
+
display: inline-flex;
|
|
1161
|
+
align-items: center;
|
|
1162
|
+
justify-content: center;
|
|
1163
|
+
flex-shrink: 0;
|
|
1164
|
+
color: var(--color-gray-500, #6b7280);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/* Action row: right-aligned, secondary as text-link, primary as blue pill. */
|
|
1168
|
+
.omniscribe_audio-cuts-actions {
|
|
1169
|
+
display: flex;
|
|
1170
|
+
justify-content: flex-end;
|
|
1171
|
+
align-items: center;
|
|
1172
|
+
gap: 16px;
|
|
1173
|
+
margin-top: 4px;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
.omniscribe_audio-cuts-secondary {
|
|
1177
|
+
background: transparent;
|
|
1178
|
+
border: none;
|
|
1179
|
+
cursor: pointer;
|
|
1180
|
+
padding: 8px 12px;
|
|
1181
|
+
font-size: 14px;
|
|
1182
|
+
font-weight: 500;
|
|
1183
|
+
color: var(--color-gray-700, #374151);
|
|
1184
|
+
border-radius: 9999px;
|
|
1185
|
+
transition: background-color 0.15s ease;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
.omniscribe_audio-cuts-secondary:hover {
|
|
1189
|
+
background-color: var(--color-gray-100, #f3f4f6);
|
|
1190
|
+
color: var(--color-gray-900, #0f172a);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
.omniscribe_audio-cuts-primary {
|
|
1194
|
+
border-radius: 9999px !important;
|
|
1195
|
+
gap: 8px;
|
|
1196
|
+
padding-block: 10px !important;
|
|
1197
|
+
padding-inline: 18px !important;
|
|
1198
|
+
height: auto !important;
|
|
1199
|
+
font-weight: 600;
|
|
1200
|
+
}
|
|
903
1201
|
/* Draggable Collapsed Container */
|
|
904
1202
|
.omniscribe_draggable-collapsed {
|
|
905
1203
|
position: fixed;
|
|
@@ -3755,6 +4053,34 @@
|
|
|
3755
4053
|
line-height: 1.7 !important;
|
|
3756
4054
|
}
|
|
3757
4055
|
|
|
4056
|
+
/* Audio-loss divider rendered between segments where a recording cut
|
|
4057
|
+
occurred. Visually separates captured speech from the gap so the doctor
|
|
4058
|
+
can spot lost portions while reviewing the transcription. */
|
|
4059
|
+
.omniscribe_transcription-panel-cut {
|
|
4060
|
+
display: flex;
|
|
4061
|
+
align-items: center;
|
|
4062
|
+
gap: 8px;
|
|
4063
|
+
margin-block: 10px;
|
|
4064
|
+
padding-inline: 4px;
|
|
4065
|
+
}
|
|
4066
|
+
|
|
4067
|
+
.omniscribe_transcription-panel-cut-line {
|
|
4068
|
+
flex: 1;
|
|
4069
|
+
height: 1px;
|
|
4070
|
+
background-color: #fed7aa;
|
|
4071
|
+
}
|
|
4072
|
+
|
|
4073
|
+
.omniscribe_transcription-panel-cut-label {
|
|
4074
|
+
flex-shrink: 0;
|
|
4075
|
+
padding: 2px 10px;
|
|
4076
|
+
border-radius: 9999px;
|
|
4077
|
+
background-color: #fff7ed;
|
|
4078
|
+
border: 1px solid #fed7aa;
|
|
4079
|
+
color: #c2410c;
|
|
4080
|
+
font-weight: 600;
|
|
4081
|
+
font-variant-numeric: tabular-nums;
|
|
4082
|
+
}
|
|
4083
|
+
|
|
3758
4084
|
/* Scrollbar styles */
|
|
3759
4085
|
.omniscribe_transcription-panel-content::-webkit-scrollbar {
|
|
3760
4086
|
width: 6px;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { JSX } from 'react/jsx-runtime';
|
|
|
3
3
|
import * as React_2 from 'react';
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
6
|
-
export declare function Button({ className, variant, size, asChild, isDisabled, isLoading, text, whitespace, rounded, ...props }: ButtonProps): JSX.Element;
|
|
6
|
+
export declare function Button({ className, variant, size, asChild, isDisabled, isLoading, text, whitespace, rounded, type, ...props }: ButtonProps): JSX.Element;
|
|
7
7
|
|
|
8
8
|
declare type ButtonProps = React_2.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
|
|
9
9
|
asChild?: boolean;
|
|
@@ -57,9 +57,19 @@ export declare interface OmniscribeProps {
|
|
|
57
57
|
wssurl: string;
|
|
58
58
|
/** API key for authentication */
|
|
59
59
|
apikey: string;
|
|
60
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* Unique identifier of the healthcare professional.
|
|
62
|
+
* SECURITY: Must be an INTERNAL system / surrogate id, never an MRN,
|
|
63
|
+
* national id, or other directly-identifying value. It is sent to the
|
|
64
|
+
* backend (and used as LLM context) without anonymization.
|
|
65
|
+
*/
|
|
61
66
|
userid: string;
|
|
62
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Unique identifier of the patient.
|
|
69
|
+
* SECURITY: Must be an INTERNAL system / surrogate id, never an MRN,
|
|
70
|
+
* national id, or other directly-identifying value. It is sent to the
|
|
71
|
+
* backend (and used as LLM context) without anonymization.
|
|
72
|
+
*/
|
|
63
73
|
patientid: string;
|
|
64
74
|
/** Template ID - enables report generation when provided with template */
|
|
65
75
|
templateid?: string;
|
|
@@ -124,6 +134,8 @@ export declare interface OmniscribeProps {
|
|
|
124
134
|
disablegenerate?: boolean;
|
|
125
135
|
/** Enable debug logging */
|
|
126
136
|
debug?: boolean;
|
|
137
|
+
/** Doctor's medical specialty at the time of the event. Optional. When provided, it is attached to every tracked event for analytics segmentation. */
|
|
138
|
+
userMedicalSpecialty?: string;
|
|
127
139
|
/** Expose function to get last generated report */
|
|
128
140
|
setGetLastReport?: (fn: () => Promise<object | undefined>) => void;
|
|
129
141
|
}
|
|
@@ -143,7 +155,23 @@ declare type TDayData = {
|
|
|
143
155
|
patientId: string;
|
|
144
156
|
doctorId: string;
|
|
145
157
|
date: string;
|
|
146
|
-
report: object;
|
|
158
|
+
report: object | undefined;
|
|
159
|
+
/** Last incremental extraction result (not the final report).
|
|
160
|
+
* Used as previous_extraction context when Generate fallback is triggered. */
|
|
161
|
+
lastExtraction?: object;
|
|
162
|
+
/** Auto-generated report sitting in storage waiting for the user to
|
|
163
|
+
* click Generate. Cleared (set to undefined) once the user consumes it
|
|
164
|
+
* via deliverReport, at which point the same payload is promoted to
|
|
165
|
+
* the `report` field. Stored separately so a reload doesn't make the
|
|
166
|
+
* UI think the user has already consumed it (which would switch the
|
|
167
|
+
* button to Regenerate). */
|
|
168
|
+
autoPendingReport?: object;
|
|
169
|
+
/** ISO timestamp set when the user clicks Generate. Cleared once the
|
|
170
|
+
* report is delivered. Persisted so a page reload mid-generation can
|
|
171
|
+
* restore the loading-state UI ("Generating..." while waiting for
|
|
172
|
+
* pendingReport / storage / API to resolve) without the user needing
|
|
173
|
+
* to click again. */
|
|
174
|
+
pendingClickAt?: string;
|
|
147
175
|
transcript: TProcessedSegment[];
|
|
148
176
|
transcriptionId?: string;
|
|
149
177
|
clinicalNoteId?: string;
|
|
@@ -170,9 +198,8 @@ declare type TProcessedSegment = {
|
|
|
170
198
|
declare type TRenderReport = (report: object, selected: string) => React_2.JSX.Element[] | React_2.JSX.Element;
|
|
171
199
|
|
|
172
200
|
declare type TSegmentText = {
|
|
173
|
-
speaker
|
|
201
|
+
speaker?: string;
|
|
174
202
|
text: string;
|
|
175
|
-
speaker_id: string;
|
|
176
203
|
}[];
|
|
177
204
|
|
|
178
205
|
export declare type TToastState = {
|