@opengeni/react 0.44.5 → 0.46.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/README.md +3 -0
- package/dist/{chunk-L3EWO3UK.js → chunk-3PB7MIT6.js} +243 -22
- package/dist/chunk-3PB7MIT6.js.map +1 -0
- package/dist/{chunk-EHSYZ4KP.js → chunk-FGZUCXZF.js} +2 -2
- package/dist/{chunk-EHSYZ4KP.js.map → chunk-FGZUCXZF.js.map} +1 -1
- package/dist/{chunk-LYRJUU5V.js → chunk-LGVMUIRV.js} +543 -200
- package/dist/chunk-LGVMUIRV.js.map +1 -0
- package/dist/components/user-message-body.d.ts +36 -0
- package/dist/composer.js +2 -2
- package/dist/hooks/use-voice-input.d.ts +8 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/dist/realtime.js +4 -4
- package/dist/realtime.js.map +1 -1
- package/dist/session-ui.d.ts +2 -0
- package/dist/session-ui.js +7 -3
- package/package.json +2 -2
- package/src/components/composer.tsx +4 -4
- package/src/components/copy-button.tsx +1 -1
- package/src/components/markdown.tsx +1 -1
- package/src/components/message-timeline.tsx +134 -25
- package/src/components/model-picker.tsx +1 -1
- package/src/components/model-policy-picker.tsx +1 -1
- package/src/components/user-message-body.tsx +341 -0
- package/src/hooks/use-codex-accounts.ts +1 -1
- package/src/hooks/use-voice-input.ts +320 -19
- package/src/index.ts +2 -0
- package/src/realtime/realtime-control.tsx +3 -3
- package/src/session-ui.ts +2 -0
- package/src/timeline/activity-rail.tsx +1 -1
- package/src/timeline/shared.tsx +3 -3
- package/src/timeline/turn-summary.tsx +4 -4
- package/dist/chunk-L3EWO3UK.js.map +0 -1
- package/dist/chunk-LYRJUU5V.js.map +0 -1
package/README.md
CHANGED
|
@@ -412,6 +412,9 @@ intentional changes should regenerate those snapshots and review the diff.
|
|
|
412
412
|
"jump to latest" affordance, streaming caret, collapsible activity clusters,
|
|
413
413
|
and worker cards (wire `onOpenSession` to drill into a worker). Pass
|
|
414
414
|
`renderMessageText` to plug a markdown renderer.
|
|
415
|
+
- `UserMessageBody` — the shared lossless rendered-height disclosure for
|
|
416
|
+
already-sent user text. Use it inside a custom `renderMessageText` user branch
|
|
417
|
+
so attachments and voice identity remain outside the clipped Markdown region.
|
|
415
418
|
- `SessionStatus` / `StatusDot` — status badges; live states breathe.
|
|
416
419
|
- `FleetTile` — one session in a fleet grid: title, status, model, recency.
|
|
417
420
|
- `ModelPicker` — a compact model dropdown for a composer slot, grouping the
|
|
@@ -1113,9 +1113,31 @@ var VOICE_RECORDING_TIMESLICE_MILLISECONDS = 5e3;
|
|
|
1113
1113
|
var VOICE_RECORDING_OWNER_HEARTBEAT_MILLISECONDS = 5e3;
|
|
1114
1114
|
var VOICE_RECORDING_OWNER_STALE_MILLISECONDS = 3e4;
|
|
1115
1115
|
var VOICE_RECORDING_CLIENT_MAX_DURATION_SECONDS = 600;
|
|
1116
|
+
var VOICE_RECORDING_RESUMABLE_CLIENT_MAX_DURATION_SECONDS = 8 * 60 * 60;
|
|
1117
|
+
var VOICE_RECORDING_RECOVERY_STATUS_POLL_MILLISECONDS = 2e3;
|
|
1118
|
+
var VOICE_RECORDING_RECOVERY_MAX_MUTATION_DELAY_MILLISECONDS = 3e4;
|
|
1119
|
+
var TRANSCRIPTION_RECORDING_RECOVERY_RETRY_AFTER_MILLISECONDS = 5e3;
|
|
1116
1120
|
var MIME_PREFERENCES = ["audio/webm;codecs=opus", "audio/mp4", "audio/ogg;codecs=opus"];
|
|
1117
1121
|
var createDefaultVoiceRecordingId = () => crypto.randomUUID();
|
|
1118
1122
|
var currentDate = () => /* @__PURE__ */ new Date();
|
|
1123
|
+
function transcriptionRecoveryMutationDelayMilliseconds(retryAfterMilliseconds, attempt, random = Math.random) {
|
|
1124
|
+
const hint = typeof retryAfterMilliseconds === "number" && Number.isInteger(retryAfterMilliseconds) && retryAfterMilliseconds > 0 ? retryAfterMilliseconds : TRANSCRIPTION_RECORDING_RECOVERY_RETRY_AFTER_MILLISECONDS;
|
|
1125
|
+
const boundedHint = Math.max(
|
|
1126
|
+
500,
|
|
1127
|
+
Math.min(hint, VOICE_RECORDING_RECOVERY_MAX_MUTATION_DELAY_MILLISECONDS)
|
|
1128
|
+
);
|
|
1129
|
+
const exponent = Math.max(0, Math.min(Math.floor(attempt), 6));
|
|
1130
|
+
const exponential = Math.min(
|
|
1131
|
+
VOICE_RECORDING_RECOVERY_MAX_MUTATION_DELAY_MILLISECONDS,
|
|
1132
|
+
boundedHint * 2 ** exponent
|
|
1133
|
+
);
|
|
1134
|
+
const sampledJitter = random();
|
|
1135
|
+
const jitterRatio = Number.isFinite(sampledJitter) ? Math.max(0, Math.min(1, sampledJitter)) : 0;
|
|
1136
|
+
return Math.min(
|
|
1137
|
+
VOICE_RECORDING_RECOVERY_MAX_MUTATION_DELAY_MILLISECONDS,
|
|
1138
|
+
Math.ceil(exponential * (1 + jitterRatio * 0.2))
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1119
1141
|
function useVoiceInput({
|
|
1120
1142
|
client,
|
|
1121
1143
|
workspaceId,
|
|
@@ -1337,8 +1359,10 @@ function useVoiceInput({
|
|
|
1337
1359
|
const finalizePersistedRecording = useCallback2(
|
|
1338
1360
|
async (generation) => {
|
|
1339
1361
|
const manifest = manifestRef.current;
|
|
1340
|
-
const
|
|
1341
|
-
|
|
1362
|
+
const resumable = capability?.resumable && isResumableVoiceInputClient(client) ? capability.resumable : null;
|
|
1363
|
+
const maxSizeBytes = resumable?.maxSizeBytes ?? capability?.maxSizeBytes;
|
|
1364
|
+
if (!manifest || !client || !capability || !maxSizeBytes || manifest.workspaceId !== workspaceId)
|
|
1365
|
+
return;
|
|
1342
1366
|
const controller = new AbortController();
|
|
1343
1367
|
controllerRef.current?.abort();
|
|
1344
1368
|
controllerRef.current = controller;
|
|
@@ -1378,16 +1402,12 @@ function useVoiceInput({
|
|
|
1378
1402
|
await preserveForRetry(retained, "invalid_audio", generation);
|
|
1379
1403
|
return;
|
|
1380
1404
|
}
|
|
1381
|
-
const
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
const response = await client.transcribeAudio(workspaceId, {
|
|
1388
|
-
audio,
|
|
1389
|
-
mimeType: audio.type,
|
|
1390
|
-
durationSeconds: transcribing.totalDurationMilliseconds / 1e3,
|
|
1405
|
+
const response = await transcribePersistedRecording({
|
|
1406
|
+
client,
|
|
1407
|
+
workspaceId,
|
|
1408
|
+
capability,
|
|
1409
|
+
manifest: transcribing,
|
|
1410
|
+
chunks,
|
|
1391
1411
|
signal: controller.signal
|
|
1392
1412
|
});
|
|
1393
1413
|
if (!active()) return;
|
|
@@ -1428,6 +1448,12 @@ function useVoiceInput({
|
|
|
1428
1448
|
}
|
|
1429
1449
|
if (!active()) return;
|
|
1430
1450
|
rememberManifest(handedOff);
|
|
1451
|
+
if (resumable && isResumableVoiceInputClient(client)) {
|
|
1452
|
+
await client.discardTranscriptionRecording(workspaceId, handedOff.recordingId, {
|
|
1453
|
+
signal: controller.signal
|
|
1454
|
+
}).catch(() => void 0);
|
|
1455
|
+
}
|
|
1456
|
+
if (!active()) return;
|
|
1431
1457
|
await store.discard(handedOff.recordingId, ownerIdRef.current ?? void 0).catch(() => void 0);
|
|
1432
1458
|
if (!active()) return;
|
|
1433
1459
|
clearVisibleRecording();
|
|
@@ -1452,7 +1478,7 @@ function useVoiceInput({
|
|
|
1452
1478
|
}
|
|
1453
1479
|
},
|
|
1454
1480
|
[
|
|
1455
|
-
capability
|
|
1481
|
+
capability,
|
|
1456
1482
|
clearVisibleRecording,
|
|
1457
1483
|
client,
|
|
1458
1484
|
ensureStore,
|
|
@@ -1568,7 +1594,8 @@ function useVoiceInput({
|
|
|
1568
1594
|
});
|
|
1569
1595
|
if (!startAttemptIsCurrent()) return;
|
|
1570
1596
|
rememberManifest(result.manifest);
|
|
1571
|
-
|
|
1597
|
+
const maxSizeBytes = capability.resumable && isResumableVoiceInputClient(client) ? capability.resumable.maxSizeBytes : capability.maxSizeBytes;
|
|
1598
|
+
if (result.manifest.totalBytes > maxSizeBytes) {
|
|
1572
1599
|
attemptCaptureLimitError = "too_large";
|
|
1573
1600
|
if (attemptOwnsSharedCapture()) captureLimitErrorRef.current = "too_large";
|
|
1574
1601
|
if (recorder.state !== "inactive") recorder.stop();
|
|
@@ -1627,7 +1654,10 @@ function useVoiceInput({
|
|
|
1627
1654
|
setStatus("recording");
|
|
1628
1655
|
timerRef.current = setTimeout(
|
|
1629
1656
|
stop,
|
|
1630
|
-
Math.min(
|
|
1657
|
+
Math.min(
|
|
1658
|
+
capability.resumable && isResumableVoiceInputClient(client) ? capability.resumable.maxDurationSeconds : capability.maxDurationSeconds,
|
|
1659
|
+
capability.resumable && isResumableVoiceInputClient(client) ? VOICE_RECORDING_RESUMABLE_CLIENT_MAX_DURATION_SECONDS : VOICE_RECORDING_CLIENT_MAX_DURATION_SECONDS
|
|
1660
|
+
) * 1e3
|
|
1631
1661
|
);
|
|
1632
1662
|
return true;
|
|
1633
1663
|
} catch (reason) {
|
|
@@ -1728,6 +1758,10 @@ function useVoiceInput({
|
|
|
1728
1758
|
return;
|
|
1729
1759
|
}
|
|
1730
1760
|
if (generation !== generationRef.current) return;
|
|
1761
|
+
if (capability?.resumable && isResumableVoiceInputClient(client)) {
|
|
1762
|
+
await client.discardTranscriptionRecording(workspaceId, handedOff.recordingId).catch(() => void 0);
|
|
1763
|
+
}
|
|
1764
|
+
if (generation !== generationRef.current) return;
|
|
1731
1765
|
await store.discard(handedOff.recordingId, ownerIdRef.current ?? void 0).catch(() => void 0);
|
|
1732
1766
|
if (generation !== generationRef.current) return;
|
|
1733
1767
|
clearVisibleRecording();
|
|
@@ -1737,6 +1771,8 @@ function useVoiceInput({
|
|
|
1737
1771
|
await loadNextRecoverable(generation);
|
|
1738
1772
|
}, [
|
|
1739
1773
|
clearVisibleRecording,
|
|
1774
|
+
capability?.resumable,
|
|
1775
|
+
client,
|
|
1740
1776
|
ensureStore,
|
|
1741
1777
|
focusInput,
|
|
1742
1778
|
loadNextRecoverable,
|
|
@@ -1760,6 +1796,10 @@ function useVoiceInput({
|
|
|
1760
1796
|
await captureSettled.catch(() => void 0);
|
|
1761
1797
|
if (generation !== generationRef.current) return;
|
|
1762
1798
|
if (manifest) {
|
|
1799
|
+
if (capability?.resumable && isResumableVoiceInputClient(client)) {
|
|
1800
|
+
await client.discardTranscriptionRecording(workspaceId, manifest.recordingId).catch(() => void 0);
|
|
1801
|
+
}
|
|
1802
|
+
if (generation !== generationRef.current) return;
|
|
1763
1803
|
try {
|
|
1764
1804
|
await (await ensureStore()).discard(manifest.recordingId, ownerIdRef.current ?? void 0);
|
|
1765
1805
|
} catch {
|
|
@@ -1781,10 +1821,13 @@ function useVoiceInput({
|
|
|
1781
1821
|
}, [
|
|
1782
1822
|
clearCaptureRuntime,
|
|
1783
1823
|
clearVisibleRecording,
|
|
1824
|
+
capability?.resumable,
|
|
1825
|
+
client,
|
|
1784
1826
|
ensureStore,
|
|
1785
1827
|
focusInput,
|
|
1786
1828
|
loadNextRecoverable,
|
|
1787
|
-
rememberManifest
|
|
1829
|
+
rememberManifest,
|
|
1830
|
+
workspaceId
|
|
1788
1831
|
]);
|
|
1789
1832
|
const cancel = useCallback2(() => {
|
|
1790
1833
|
if (status === "recording" || status === "requesting-permission") {
|
|
@@ -1924,6 +1967,184 @@ function useVoiceInput({
|
|
|
1924
1967
|
discard
|
|
1925
1968
|
};
|
|
1926
1969
|
}
|
|
1970
|
+
async function transcribePersistedRecording(input) {
|
|
1971
|
+
const client = input.client;
|
|
1972
|
+
const resumable = input.capability.resumable;
|
|
1973
|
+
const ordered = [...input.chunks].sort((left, right) => left.chunkNumber - right.chunkNumber);
|
|
1974
|
+
if (!resumable || !isResumableVoiceInputClient(client)) {
|
|
1975
|
+
const audio = new Blob(
|
|
1976
|
+
ordered.map((chunk) => chunk.audio),
|
|
1977
|
+
{ type: input.manifest.mimeType }
|
|
1978
|
+
);
|
|
1979
|
+
if (audio.size > input.capability.maxSizeBytes) throw { code: "too_large" };
|
|
1980
|
+
return await client.transcribeAudio(input.workspaceId, {
|
|
1981
|
+
audio,
|
|
1982
|
+
mimeType: audio.type,
|
|
1983
|
+
durationSeconds: input.manifest.totalDurationMilliseconds / 1e3,
|
|
1984
|
+
signal: input.signal
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
if (input.manifest.totalBytes > resumable.maxSizeBytes || input.manifest.totalDurationMilliseconds > resumable.maxDurationSeconds * 1e3) {
|
|
1988
|
+
throw { code: "too_large" };
|
|
1989
|
+
}
|
|
1990
|
+
if (ordered.some((chunk, index) => chunk.chunkNumber !== index) || ordered.length !== input.manifest.chunkCount) {
|
|
1991
|
+
throw { code: "invalid_audio" };
|
|
1992
|
+
}
|
|
1993
|
+
const finalizeInput = {
|
|
1994
|
+
chunkCount: input.manifest.chunkCount,
|
|
1995
|
+
totalBytes: input.manifest.totalBytes,
|
|
1996
|
+
totalDurationMilliseconds: input.manifest.totalDurationMilliseconds,
|
|
1997
|
+
signal: input.signal
|
|
1998
|
+
};
|
|
1999
|
+
let remote = await client.createTranscriptionRecording(input.workspaceId, {
|
|
2000
|
+
recordingId: input.manifest.recordingId,
|
|
2001
|
+
mimeType: input.manifest.mimeType,
|
|
2002
|
+
signal: input.signal
|
|
2003
|
+
});
|
|
2004
|
+
for (const chunk of ordered) {
|
|
2005
|
+
if (chunk.chunkNumber < remote.recording.nextChunkNumber) continue;
|
|
2006
|
+
if (chunk.chunkNumber !== remote.recording.nextChunkNumber) {
|
|
2007
|
+
throw { code: "invalid_audio" };
|
|
2008
|
+
}
|
|
2009
|
+
if (chunk.byteLength > resumable.maxChunkSizeBytes) throw { code: "too_large" };
|
|
2010
|
+
const uploaded = await client.uploadTranscriptionRecordingChunk(
|
|
2011
|
+
input.workspaceId,
|
|
2012
|
+
input.manifest.recordingId,
|
|
2013
|
+
chunk.chunkNumber,
|
|
2014
|
+
{
|
|
2015
|
+
audio: chunk.audio,
|
|
2016
|
+
mimeType: input.manifest.mimeType,
|
|
2017
|
+
sha256: chunk.sha256,
|
|
2018
|
+
startMilliseconds: chunk.startMilliseconds,
|
|
2019
|
+
durationMilliseconds: chunk.durationMilliseconds,
|
|
2020
|
+
signal: input.signal
|
|
2021
|
+
}
|
|
2022
|
+
);
|
|
2023
|
+
remote = { recording: uploaded.recording, segments: remote.segments };
|
|
2024
|
+
}
|
|
2025
|
+
if (remote.recording.nextChunkNumber !== ordered.length) {
|
|
2026
|
+
throw { code: "invalid_audio" };
|
|
2027
|
+
}
|
|
2028
|
+
remote = await client.finalizeTranscriptionRecording(
|
|
2029
|
+
input.workspaceId,
|
|
2030
|
+
input.manifest.recordingId,
|
|
2031
|
+
finalizeInput
|
|
2032
|
+
);
|
|
2033
|
+
let recoveryMutationAttempt = 0;
|
|
2034
|
+
let recoveryMutationDueAt = 0;
|
|
2035
|
+
const scheduleRecoveryMutation = (response) => {
|
|
2036
|
+
if (response.recording.state !== "segmenting" && response.recording.state !== "transcribing") {
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
recoveryMutationDueAt = Date.now() + transcriptionRecoveryMutationDelayMilliseconds(
|
|
2040
|
+
response.retryAfterMilliseconds,
|
|
2041
|
+
recoveryMutationAttempt
|
|
2042
|
+
);
|
|
2043
|
+
recoveryMutationAttempt += 1;
|
|
2044
|
+
};
|
|
2045
|
+
scheduleRecoveryMutation(remote);
|
|
2046
|
+
for (; ; ) {
|
|
2047
|
+
if (input.signal.aborted) throw new DOMException("Aborted", "AbortError");
|
|
2048
|
+
switch (remote.recording.state) {
|
|
2049
|
+
case "complete":
|
|
2050
|
+
if (remote.recording.transcriptText === null) throw { code: "invalid_audio" };
|
|
2051
|
+
return {
|
|
2052
|
+
text: remote.recording.transcriptText,
|
|
2053
|
+
languages: remote.recording.languages
|
|
2054
|
+
};
|
|
2055
|
+
case "ready":
|
|
2056
|
+
remote = await client.processNextTranscriptionRecordingSegment(
|
|
2057
|
+
input.workspaceId,
|
|
2058
|
+
input.manifest.recordingId,
|
|
2059
|
+
{ signal: input.signal }
|
|
2060
|
+
);
|
|
2061
|
+
scheduleRecoveryMutation(remote);
|
|
2062
|
+
break;
|
|
2063
|
+
case "failed": {
|
|
2064
|
+
if (!remote.recording.retryable) {
|
|
2065
|
+
throw { code: remote.recording.errorCode ?? "unknown" };
|
|
2066
|
+
}
|
|
2067
|
+
const retried = remote.recording.segmentCount === 0 ? await client.finalizeTranscriptionRecording(
|
|
2068
|
+
input.workspaceId,
|
|
2069
|
+
input.manifest.recordingId,
|
|
2070
|
+
finalizeInput
|
|
2071
|
+
) : await client.processNextTranscriptionRecordingSegment(
|
|
2072
|
+
input.workspaceId,
|
|
2073
|
+
input.manifest.recordingId,
|
|
2074
|
+
{ signal: input.signal }
|
|
2075
|
+
);
|
|
2076
|
+
if (retried.recording.state === "failed") {
|
|
2077
|
+
throw { code: retried.recording.errorCode ?? "unknown" };
|
|
2078
|
+
}
|
|
2079
|
+
remote = retried;
|
|
2080
|
+
scheduleRecoveryMutation(remote);
|
|
2081
|
+
break;
|
|
2082
|
+
}
|
|
2083
|
+
case "discarded":
|
|
2084
|
+
throw { code: "invalid_audio" };
|
|
2085
|
+
case "uploading":
|
|
2086
|
+
remote = await client.finalizeTranscriptionRecording(
|
|
2087
|
+
input.workspaceId,
|
|
2088
|
+
input.manifest.recordingId,
|
|
2089
|
+
finalizeInput
|
|
2090
|
+
);
|
|
2091
|
+
scheduleRecoveryMutation(remote);
|
|
2092
|
+
break;
|
|
2093
|
+
case "segmenting":
|
|
2094
|
+
case "transcribing":
|
|
2095
|
+
if (Date.now() < recoveryMutationDueAt) {
|
|
2096
|
+
await abortableDelay(
|
|
2097
|
+
Math.min(
|
|
2098
|
+
recoveryMutationDueAt - Date.now(),
|
|
2099
|
+
VOICE_RECORDING_RECOVERY_STATUS_POLL_MILLISECONDS
|
|
2100
|
+
),
|
|
2101
|
+
input.signal
|
|
2102
|
+
);
|
|
2103
|
+
remote = await client.getTranscriptionRecording(
|
|
2104
|
+
input.workspaceId,
|
|
2105
|
+
input.manifest.recordingId,
|
|
2106
|
+
{ signal: input.signal }
|
|
2107
|
+
);
|
|
2108
|
+
break;
|
|
2109
|
+
}
|
|
2110
|
+
if (remote.recording.state === "segmenting") {
|
|
2111
|
+
remote = await client.finalizeTranscriptionRecording(
|
|
2112
|
+
input.workspaceId,
|
|
2113
|
+
input.manifest.recordingId,
|
|
2114
|
+
finalizeInput
|
|
2115
|
+
);
|
|
2116
|
+
} else {
|
|
2117
|
+
remote = await client.processNextTranscriptionRecordingSegment(
|
|
2118
|
+
input.workspaceId,
|
|
2119
|
+
input.manifest.recordingId,
|
|
2120
|
+
{ signal: input.signal }
|
|
2121
|
+
);
|
|
2122
|
+
}
|
|
2123
|
+
scheduleRecoveryMutation(remote);
|
|
2124
|
+
break;
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
function isResumableVoiceInputClient(client) {
|
|
2129
|
+
return Boolean(
|
|
2130
|
+
client && client.createTranscriptionRecording && client.getTranscriptionRecording && client.uploadTranscriptionRecordingChunk && client.finalizeTranscriptionRecording && client.processNextTranscriptionRecordingSegment && client.discardTranscriptionRecording
|
|
2131
|
+
);
|
|
2132
|
+
}
|
|
2133
|
+
async function abortableDelay(milliseconds, signal) {
|
|
2134
|
+
if (signal.aborted) throw new DOMException("Aborted", "AbortError");
|
|
2135
|
+
await new Promise((resolve, reject) => {
|
|
2136
|
+
const timer = setTimeout(() => {
|
|
2137
|
+
signal.removeEventListener("abort", onAbort);
|
|
2138
|
+
resolve();
|
|
2139
|
+
}, milliseconds);
|
|
2140
|
+
const onAbort = () => {
|
|
2141
|
+
clearTimeout(timer);
|
|
2142
|
+
signal.removeEventListener("abort", onAbort);
|
|
2143
|
+
reject(new DOMException("Aborted", "AbortError"));
|
|
2144
|
+
};
|
|
2145
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
2146
|
+
});
|
|
2147
|
+
}
|
|
1927
2148
|
function chooseMimeType(accepted) {
|
|
1928
2149
|
const normalized = accepted.map((value) => value.trim().toLowerCase());
|
|
1929
2150
|
return MIME_PREFERENCES.find((mimeType) => {
|
|
@@ -2499,7 +2720,7 @@ function ModelPicker({
|
|
|
2499
2720
|
disabled: disabled === true,
|
|
2500
2721
|
"aria-label": label,
|
|
2501
2722
|
className: cn(
|
|
2502
|
-
"h-8 max-w-[180px] cursor-pointer appearance-none truncate rounded-og-md bg-transparent",
|
|
2723
|
+
"h-8 max-w-[180px] cursor-pointer appearance-none truncate rounded-og-md bg-transparent pointer-coarse:h-11",
|
|
2503
2724
|
"py-0 pl-2 pr-6 text-[13px] text-og-fg-muted",
|
|
2504
2725
|
"transition-colors duration-150 hover:bg-og-surface-2 hover:text-og-fg",
|
|
2505
2726
|
"focus:outline-none focus-visible:outline-none",
|
|
@@ -3163,7 +3384,7 @@ var Input = forwardRef(function ComposerInput({ rows = 1, placeholder, className
|
|
|
3163
3384
|
"aria-controls": paletteOpen ? controller.listboxId : void 0,
|
|
3164
3385
|
"aria-activedescendant": paletteOpen ? `${controller.listboxId}-option-${controller.palette.highlight}` : void 0,
|
|
3165
3386
|
className: cn(
|
|
3166
|
-
"block w-full resize-none bg-transparent px-3.5 pt-3 pb-1 text-og-composer md:px-4 md:text-og-composer-wide",
|
|
3387
|
+
"block w-full resize-none bg-transparent px-3.5 pt-3 pb-1 text-og-composer md:px-4 md:text-og-composer-wide pointer-coarse:min-h-11",
|
|
3167
3388
|
"text-og-fg placeholder:text-og-fg-subtle focus:outline-none focus-visible:outline-none",
|
|
3168
3389
|
"disabled:cursor-not-allowed disabled:opacity-60",
|
|
3169
3390
|
className
|
|
@@ -3273,7 +3494,7 @@ var AttachButton = forwardRef(
|
|
|
3273
3494
|
className: cn(
|
|
3274
3495
|
"inline-flex size-8 items-center justify-center rounded-og-md",
|
|
3275
3496
|
"text-og-fg-muted transition-colors duration-150 hover:bg-og-surface-2 hover:text-og-fg",
|
|
3276
|
-
"disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-
|
|
3497
|
+
"disabled:cursor-not-allowed disabled:opacity-50 pointer-coarse:size-11",
|
|
3277
3498
|
className
|
|
3278
3499
|
),
|
|
3279
3500
|
children: children ?? /* @__PURE__ */ jsx3(PaperclipIcon, { className: "size-4" })
|
|
@@ -3322,7 +3543,7 @@ var PauseButton = forwardRef(
|
|
|
3322
3543
|
disabled: busy,
|
|
3323
3544
|
"aria-label": ariaLabel ?? controller.messages.pauseAriaLabel,
|
|
3324
3545
|
className: cn(
|
|
3325
|
-
"inline-flex size-8 items-center justify-center rounded-og-md border border-og-border pointer-coarse:size-
|
|
3546
|
+
"inline-flex size-8 items-center justify-center rounded-og-md border border-og-border pointer-coarse:size-11",
|
|
3326
3547
|
"bg-og-surface-2 text-og-fg-muted transition-colors duration-150",
|
|
3327
3548
|
"hover:border-og-status-waiting/50 hover:text-og-status-waiting",
|
|
3328
3549
|
"disabled:opacity-50",
|
|
@@ -3348,7 +3569,7 @@ var SendButton = forwardRef(
|
|
|
3348
3569
|
"data-og-tip": tip,
|
|
3349
3570
|
"aria-label": ariaLabel ?? (controller.paused ? controller.messages.sendAndResumeAriaLabel : controller.messages.sendMessageAriaLabel),
|
|
3350
3571
|
className: cn(
|
|
3351
|
-
"inline-flex size-8 items-center justify-center rounded-og-md pointer-coarse:size-
|
|
3572
|
+
"inline-flex size-8 items-center justify-center rounded-og-md pointer-coarse:size-11",
|
|
3352
3573
|
"bg-og-accent text-og-accent-fg shadow-og-sm",
|
|
3353
3574
|
"transition-[background-color,transform,opacity] duration-150 ease-og-spring",
|
|
3354
3575
|
"hover:bg-og-accent-strong active:scale-95",
|
|
@@ -4162,4 +4383,4 @@ export {
|
|
|
4162
4383
|
Status,
|
|
4163
4384
|
ComposerTranscriptionControl
|
|
4164
4385
|
};
|
|
4165
|
-
//# sourceMappingURL=chunk-
|
|
4386
|
+
//# sourceMappingURL=chunk-3PB7MIT6.js.map
|