@opengeni/react 0.36.0 → 0.37.0
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/README.md +4 -0
- package/dist/{chunk-J2RVJ6JX.js → chunk-4IJCL7YO.js} +13 -2
- package/dist/chunk-4IJCL7YO.js.map +1 -0
- package/dist/{chunk-OKKMZDQF.js → chunk-FSPDND3P.js} +2 -2
- package/dist/{chunk-FT2TXNGZ.js → chunk-HJ4OQVGW.js} +174 -14
- package/dist/chunk-HJ4OQVGW.js.map +1 -0
- package/dist/{chunk-PVW56EVR.js → chunk-IP22SLO6.js} +447 -13
- package/dist/chunk-IP22SLO6.js.map +1 -0
- package/dist/{chunk-U255M5EZ.js → chunk-SJKT4TKW.js} +39 -6
- package/dist/chunk-SJKT4TKW.js.map +1 -0
- package/dist/{chunk-XT7JF2EH.js → chunk-UCZPNXV3.js} +96 -17
- package/dist/chunk-UCZPNXV3.js.map +1 -0
- package/dist/components/chat-composer.d.ts +3 -1
- package/dist/components/model-policy-picker.d.ts +78 -0
- package/dist/components/session-chrome.d.ts +1 -1
- package/dist/composer.d.ts +2 -0
- package/dist/composer.js +17 -3
- package/dist/hooks/use-composer.d.ts +9 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +30 -9
- package/dist/index.js.map +1 -1
- package/dist/model-policy.d.ts +12 -4
- package/dist/model-policy.js +5 -1
- package/dist/session-ui.js +2 -2
- package/dist/session.js +3 -3
- package/dist/timeline/types.d.ts +5 -0
- package/package.json +2 -2
- package/src/components/chat-composer.tsx +8 -3
- package/src/components/composer.tsx +17 -1
- package/src/components/copy-button.tsx +13 -6
- package/src/components/model-picker.tsx +2 -2
- package/src/components/model-policy-picker.tsx +582 -0
- package/src/components/session-chrome.tsx +138 -14
- package/src/composer.ts +13 -0
- package/src/hooks/use-composer.ts +213 -16
- package/src/index.ts +15 -0
- package/src/model-policy.ts +69 -14
- package/src/timeline/projection.ts +21 -1
- package/src/timeline/types.ts +5 -0
- package/dist/chunk-FT2TXNGZ.js.map +0 -1
- package/dist/chunk-J2RVJ6JX.js.map +0 -1
- package/dist/chunk-PVW56EVR.js.map +0 -1
- package/dist/chunk-U255M5EZ.js.map +0 -1
- package/dist/chunk-XT7JF2EH.js.map +0 -1
- /package/dist/{chunk-OKKMZDQF.js.map → chunk-FSPDND3P.js.map} +0 -0
package/dist/model-policy.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ClientModel, ReasoningEffort, WorkspaceModelCatalogModel } from "@opengeni/sdk";
|
|
2
2
|
export type PickerBillingClass = "opengeni_credits" | "codex_subscription" | "byok";
|
|
3
|
-
export type PickerModelRow = {
|
|
3
|
+
export type PickerModelRow<TCatalog extends ClientModel = WorkspaceModelCatalogModel> = {
|
|
4
4
|
id: string;
|
|
5
5
|
label: string;
|
|
6
6
|
billingClass: PickerBillingClass;
|
|
@@ -9,7 +9,7 @@ export type PickerModelRow = {
|
|
|
9
9
|
unavailableReason: string | null;
|
|
10
10
|
provider: string;
|
|
11
11
|
providerLabel: string;
|
|
12
|
-
catalog:
|
|
12
|
+
catalog: TCatalog;
|
|
13
13
|
};
|
|
14
14
|
export type LatencyModeId = "standard" | "priority" | "fast";
|
|
15
15
|
export declare function billingClassForModel(model: ClientModel): PickerBillingClass;
|
|
@@ -20,13 +20,21 @@ export declare function defaultEffortForModel(model: ClientModel): ReasoningEffo
|
|
|
20
20
|
export declare function coerceReasoningEffortForModel(model: ClientModel, effort: ReasoningEffort): ReasoningEffort;
|
|
21
21
|
export declare function runnableLatencyModesForModel(model: ClientModel): LatencyModeId[];
|
|
22
22
|
export declare function labelLatencyMode(mode: LatencyModeId): string;
|
|
23
|
+
export declare function labelReasoningEffort(effort: ReasoningEffort): string;
|
|
23
24
|
export declare function payerSummaryForModel(model: ClientModel): string;
|
|
24
25
|
export declare function advancedSourceSummary(model: ClientModel): string | null;
|
|
25
26
|
export declare function projectPickerRows(models: WorkspaceModelCatalogModel[]): PickerModelRow[];
|
|
26
|
-
|
|
27
|
-
export declare function
|
|
27
|
+
/** Project the lightweight client-config model list into the same picker contract. */
|
|
28
|
+
export declare function projectClientModelRows(models: ClientModel[]): PickerModelRow<ClientModel>[];
|
|
29
|
+
export declare function sortPickerRows<TCatalog extends ClientModel>(rows: PickerModelRow<TCatalog>[]): PickerModelRow<TCatalog>[];
|
|
30
|
+
export declare function findPickerRow<TCatalog extends ClientModel>(rows: PickerModelRow<TCatalog>[], modelId: string): PickerModelRow<TCatalog> | null;
|
|
28
31
|
export declare function groupPickerRowsByBillingClass(rows: PickerModelRow[]): Array<{
|
|
29
32
|
billingClass: PickerBillingClass;
|
|
30
33
|
label: string;
|
|
31
34
|
rows: PickerModelRow[];
|
|
32
35
|
}>;
|
|
36
|
+
export declare function groupPickerRowsByBillingClass<TCatalog extends ClientModel>(rows: PickerModelRow<TCatalog>[]): Array<{
|
|
37
|
+
billingClass: PickerBillingClass;
|
|
38
|
+
label: string;
|
|
39
|
+
rows: PickerModelRow<TCatalog>[];
|
|
40
|
+
}>;
|
package/dist/model-policy.js
CHANGED
|
@@ -9,11 +9,13 @@ import {
|
|
|
9
9
|
findPickerRow,
|
|
10
10
|
groupPickerRowsByBillingClass,
|
|
11
11
|
labelLatencyMode,
|
|
12
|
+
labelReasoningEffort,
|
|
12
13
|
payerSummaryForModel,
|
|
14
|
+
projectClientModelRows,
|
|
13
15
|
projectPickerRows,
|
|
14
16
|
runnableLatencyModesForModel,
|
|
15
17
|
sortPickerRows
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-SJKT4TKW.js";
|
|
17
19
|
export {
|
|
18
20
|
advancedSourceSummary,
|
|
19
21
|
availabilityReasonLabel,
|
|
@@ -25,7 +27,9 @@ export {
|
|
|
25
27
|
findPickerRow,
|
|
26
28
|
groupPickerRowsByBillingClass,
|
|
27
29
|
labelLatencyMode,
|
|
30
|
+
labelReasoningEffort,
|
|
28
31
|
payerSummaryForModel,
|
|
32
|
+
projectClientModelRows,
|
|
29
33
|
projectPickerRows,
|
|
30
34
|
runnableLatencyModesForModel,
|
|
31
35
|
sortPickerRows
|
package/dist/session-ui.js
CHANGED
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
SessionChrome,
|
|
7
7
|
TimelineRow,
|
|
8
8
|
sessionChromeGoalPillState
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-UCZPNXV3.js";
|
|
10
|
+
import "./chunk-4IJCL7YO.js";
|
|
11
11
|
import "./chunk-ATSTR5P3.js";
|
|
12
12
|
import "./chunk-TK7G6XLT.js";
|
|
13
13
|
import "./chunk-LAKLF4PA.js";
|
package/dist/session.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
useSessionLineage,
|
|
19
19
|
useSessionMcpApprovalPolicy,
|
|
20
20
|
useTurnQueue
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-FSPDND3P.js";
|
|
22
22
|
import {
|
|
23
23
|
buildTimeline,
|
|
24
24
|
creditExhaustedFromEvents,
|
|
@@ -26,14 +26,14 @@ import {
|
|
|
26
26
|
groupTimeline,
|
|
27
27
|
sessionStatusFromEvents,
|
|
28
28
|
toolDisplayName
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-4IJCL7YO.js";
|
|
30
30
|
import {
|
|
31
31
|
FILE_ONLY_MESSAGE_TEXT,
|
|
32
32
|
composeSendInput,
|
|
33
33
|
shouldSteerOnKey,
|
|
34
34
|
shouldSubmitOnKey,
|
|
35
35
|
useComposer
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-HJ4OQVGW.js";
|
|
37
37
|
import "./chunk-7CJOAW3V.js";
|
|
38
38
|
import "./chunk-LAKLF4PA.js";
|
|
39
39
|
export {
|
package/dist/timeline/types.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ export type UserMessageItem = {
|
|
|
3
3
|
kind: "user-message";
|
|
4
4
|
id: string;
|
|
5
5
|
text: string;
|
|
6
|
+
presentation?: {
|
|
7
|
+
kind: "realtime_voice" | "realtime_voice_handoff";
|
|
8
|
+
/** Full bounded execution context sent with this visible voice request. */
|
|
9
|
+
context: string;
|
|
10
|
+
};
|
|
6
11
|
/** Resources attached to this message (file uploads, repositories). */
|
|
7
12
|
resources: ResourceRef[];
|
|
8
13
|
/** Tools requested for the turn this message starts. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.0",
|
|
4
4
|
"description": "React hooks and styled components for OpenGeni: live session streaming, chat composer, message timeline, session status, and fleet views — token-themed (CSS variables), dark-first, built on Tailwind v4 + Radix + Motion.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"@dnd-kit/utilities": "3.2.2",
|
|
71
71
|
"@fontsource-variable/noto-sans-arabic": "5.2.10",
|
|
72
72
|
"@fontsource-variable/noto-sans-jp": "5.2.10",
|
|
73
|
-
"@opengeni/sdk": "^0.
|
|
73
|
+
"@opengeni/sdk": "^0.37.0",
|
|
74
74
|
"clsx": "^2.1.1",
|
|
75
75
|
"lucide-react": "^1.8.0",
|
|
76
76
|
"motion": "^12.0.0",
|
|
@@ -53,6 +53,8 @@ export type ChatComposerProps = {
|
|
|
53
53
|
hint?: string | undefined;
|
|
54
54
|
/** App controls in the footer row, replacing the hint. */
|
|
55
55
|
controlsStart?: ReactNode | undefined;
|
|
56
|
+
/** App actions beside Pause/Send, ordered before the built-in actions. */
|
|
57
|
+
actionsStart?: ReactNode | undefined;
|
|
56
58
|
/** Provider-neutral speech capability. Provider configuration stays in workspace settings. */
|
|
57
59
|
transcription?: ComposerTranscriptionControlProps | undefined;
|
|
58
60
|
/** Content rendered above the textarea, inside the field chrome. */
|
|
@@ -89,6 +91,7 @@ export function ChatComposer({
|
|
|
89
91
|
autoFocus,
|
|
90
92
|
hint,
|
|
91
93
|
controlsStart,
|
|
94
|
+
actionsStart,
|
|
92
95
|
transcription,
|
|
93
96
|
header,
|
|
94
97
|
onPaste,
|
|
@@ -119,6 +122,7 @@ export function ChatComposer({
|
|
|
119
122
|
messages,
|
|
120
123
|
});
|
|
121
124
|
const hasControls = Boolean(attachments || models || controlsStart || transcription);
|
|
125
|
+
const stackActions = hasControls && Boolean(actionsStart);
|
|
122
126
|
|
|
123
127
|
return (
|
|
124
128
|
<Root controller={controller} className={className}>
|
|
@@ -133,9 +137,9 @@ export function ChatComposer({
|
|
|
133
137
|
{controller.confirmState ? (
|
|
134
138
|
<Confirmation />
|
|
135
139
|
) : (
|
|
136
|
-
<Footer>
|
|
140
|
+
<Footer className={stackActions ? "flex-wrap" : undefined}>
|
|
137
141
|
{hasControls ? (
|
|
138
|
-
<Controls>
|
|
142
|
+
<Controls className={stackActions ? "w-full sm:w-auto" : undefined}>
|
|
139
143
|
<AttachButton />
|
|
140
144
|
{transcription ? <ComposerTranscriptionControl {...transcription} /> : null}
|
|
141
145
|
{models ? (
|
|
@@ -146,7 +150,8 @@ export function ChatComposer({
|
|
|
146
150
|
) : (
|
|
147
151
|
<Hint>{hint}</Hint>
|
|
148
152
|
)}
|
|
149
|
-
<Actions>
|
|
153
|
+
<Actions className={stackActions ? "w-full justify-end sm:w-auto" : undefined}>
|
|
154
|
+
{actionsStart}
|
|
150
155
|
<PauseButton />
|
|
151
156
|
<SendButton />
|
|
152
157
|
</Actions>
|
|
@@ -851,12 +851,27 @@ type OwnedInputProps =
|
|
|
851
851
|
export type ComposerInputProps = Omit<ComponentPropsWithoutRef<"textarea">, OwnedInputProps>;
|
|
852
852
|
|
|
853
853
|
export const Input = forwardRef<HTMLTextAreaElement, ComposerInputProps>(function ComposerInput(
|
|
854
|
-
{ rows = 1, placeholder, className, "aria-label": ariaLabel, ...props },
|
|
854
|
+
{ rows = 1, placeholder, className, "aria-label": ariaLabel, autoFocus = false, ...props },
|
|
855
855
|
forwardedRef,
|
|
856
856
|
) {
|
|
857
857
|
const controller = useComposerController();
|
|
858
|
+
const autoFocusedRef = useRef(false);
|
|
858
859
|
const paletteOpen =
|
|
859
860
|
controller.paletteEnabled && controller.paletteMounted && controller.palette.open;
|
|
861
|
+
|
|
862
|
+
// Native autoFocus loses when the textarea mounts disabled (create-session draft
|
|
863
|
+
// hydrate). Retry once the controller becomes interactive.
|
|
864
|
+
useEffect(() => {
|
|
865
|
+
if (!autoFocus || controller.disabled || autoFocusedRef.current) return;
|
|
866
|
+
const frame = window.requestAnimationFrame(() => {
|
|
867
|
+
const textarea = controller.textareaRef.current;
|
|
868
|
+
if (!textarea || textarea.disabled) return;
|
|
869
|
+
autoFocusedRef.current = true;
|
|
870
|
+
textarea.focus();
|
|
871
|
+
});
|
|
872
|
+
return () => window.cancelAnimationFrame(frame);
|
|
873
|
+
}, [autoFocus, controller.disabled, controller.textareaRef]);
|
|
874
|
+
|
|
860
875
|
return (
|
|
861
876
|
<textarea
|
|
862
877
|
{...props}
|
|
@@ -872,6 +887,7 @@ export const Input = forwardRef<HTMLTextAreaElement, ComposerInputProps>(functio
|
|
|
872
887
|
: (placeholder ?? controller.messages.messagePlaceholder)
|
|
873
888
|
}
|
|
874
889
|
disabled={controller.disabled}
|
|
890
|
+
autoFocus={autoFocus && !controller.disabled}
|
|
875
891
|
aria-label={ariaLabel ?? controller.messages.inputLabel}
|
|
876
892
|
aria-keyshortcuts="Enter Meta+Enter Control+Enter Shift+Enter"
|
|
877
893
|
aria-autocomplete={
|
|
@@ -44,6 +44,11 @@ export function CopyButton({
|
|
|
44
44
|
const onClick = async (event: MouseEvent<HTMLButtonElement>) => {
|
|
45
45
|
event.preventDefault();
|
|
46
46
|
event.stopPropagation();
|
|
47
|
+
// Capture before any await: React nulls `currentTarget` after the
|
|
48
|
+
// synchronous handler turn. Blurring via the stale target throws and used
|
|
49
|
+
// to skip the copied-reset timer, leaving the tip stuck on "Copied".
|
|
50
|
+
const button = event.currentTarget;
|
|
51
|
+
const pointerActivated = event.detail > 0;
|
|
47
52
|
const value = typeof text === "function" ? text() : text;
|
|
48
53
|
const ok = await copyTextToClipboard(value);
|
|
49
54
|
if (!ok) {
|
|
@@ -51,20 +56,22 @@ export function CopyButton({
|
|
|
51
56
|
}
|
|
52
57
|
setCopied(true);
|
|
53
58
|
setTipOpen(true);
|
|
54
|
-
// Pointer activation focuses the button and leaves `group-focus-within`
|
|
55
|
-
// stuck after the cursor leaves — chrome never "unhovers". Keyboard
|
|
56
|
-
// activation (`detail === 0`) keeps focus for a11y.
|
|
57
|
-
if (event.detail > 0) {
|
|
58
|
-
event.currentTarget.blur();
|
|
59
|
-
}
|
|
60
59
|
if (timerRef.current !== null) {
|
|
61
60
|
clearTimeout(timerRef.current);
|
|
62
61
|
}
|
|
62
|
+
// Always arm the reset before blur — a throw here must not leave the
|
|
63
|
+
// forced "Copied" tip open forever.
|
|
63
64
|
timerRef.current = setTimeout(() => {
|
|
64
65
|
timerRef.current = null;
|
|
65
66
|
setCopied(false);
|
|
66
67
|
setTipOpen(false);
|
|
67
68
|
}, COPIED_MS);
|
|
69
|
+
// Pointer activation focuses the button and leaves `group-focus-within`
|
|
70
|
+
// stuck after the cursor leaves — chrome never "unhovers". Keyboard
|
|
71
|
+
// activation (`detail === 0`) keeps focus for a11y.
|
|
72
|
+
if (pointerActivated) {
|
|
73
|
+
button.blur();
|
|
74
|
+
}
|
|
68
75
|
};
|
|
69
76
|
|
|
70
77
|
const tip = copied ? "Copied" : label;
|
|
@@ -24,11 +24,11 @@ export type ModelPickerProps = {
|
|
|
24
24
|
const EMPTY_CLIENT_MODELS: ClientModel[] = [];
|
|
25
25
|
|
|
26
26
|
function isCodexClientModel(model: ClientModel): boolean {
|
|
27
|
-
return model.id.startsWith("codex/") || model.
|
|
27
|
+
return model.id.startsWith("codex/") || model.source === "codex";
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function isCodexPickerRow(row: PickerModelRow): boolean {
|
|
31
|
-
return row.id.startsWith("codex/") || row.
|
|
31
|
+
return row.id.startsWith("codex/") || row.catalog.source === "codex";
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
function applyCodexOnlyRows(rows: PickerModelRow[], codexOnly: boolean): PickerModelRow[] {
|