feat(speech): add prompt voice input (#249)

## Summary
- add server-backed speech capabilities and transcription endpoints plus
UI settings for speech configuration
- add push-to-talk prompt voice input with microphone controls,
transcription insertion, and browser capability gating
- keep prompt controls aligned by restoring right-side nav placement and
moving the mic beside the expand control
This commit is contained in:
Shantur Rathore
2026-03-25 14:08:11 +00:00
committed by GitHub
parent a950d47df0
commit 1233121a13
40 changed files with 1545 additions and 27 deletions

View File

@@ -36,8 +36,8 @@
.prompt-input {
@apply w-full pt-2.5 border text-sm resize-none outline-none transition-colors;
padding-inline-start: 2.5rem;
padding-inline-end: 0.75rem;
padding-inline-start: 0.75rem;
padding-inline-end: 5.5rem;
font-family: inherit;
background-color: var(--surface-base);
color: var(--text-primary);
@@ -83,21 +83,27 @@
color: var(--text-primary);
}
/* Navigation buttons container (expand, prev, next).
Intentionally at inline-start (left in LTR, right in RTL) so buttons never overlap
the scrollbar, which browsers always place at inline-end. */
/* Navigation buttons container (expand, prev, next). */
.prompt-nav-buttons {
position: absolute;
top: 0.25rem;
inset-inline-start: 0.25rem;
inset-inline-end: 0.25rem;
bottom: 0.25rem;
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: flex-start;
gap: 0.125rem;
z-index: 2;
}
.prompt-nav-top-row {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 0.125rem;
}
.prompt-expand-button,
.prompt-history-button {
@apply w-7 h-7 flex items-center justify-center rounded-md;
@@ -179,6 +185,53 @@
color: var(--button-danger-text, var(--text-inverted, #ffffff));
}
.prompt-voice-button {
@apply h-10 rounded-md border-none cursor-pointer flex items-center justify-center transition-all flex-shrink-0;
min-width: 2.5rem;
background-color: color-mix(in oklab, var(--surface-secondary) 82%, var(--surface-base));
color: var(--text-secondary);
}
.prompt-voice-button:hover:not(:disabled) {
color: var(--text-primary);
background-color: color-mix(in oklab, var(--accent-primary) 12%, var(--surface-secondary));
@apply scale-105;
}
.prompt-voice-button:active:not(:disabled) {
@apply scale-95;
}
.prompt-voice-button.is-recording {
min-width: 3.5rem;
background-color: color-mix(in oklab, var(--button-danger-bg, rgba(239, 68, 68, 0.85)) 88%, white 12%);
color: var(--button-danger-text, var(--text-inverted, #ffffff));
}
.prompt-nav-voice-button {
min-width: 1.75rem;
width: 1.75rem;
height: 1.75rem;
border-radius: 0.375rem;
}
.prompt-nav-voice-button.is-recording {
min-width: 3.5rem;
width: auto;
}
.prompt-voice-button:disabled {
@apply opacity-50 cursor-not-allowed;
}
.prompt-voice-timer {
font-size: 0.68rem;
font-variant-numeric: tabular-nums;
font-weight: 600;
line-height: 1;
color: currentColor;
}
.stop-button:hover:not(:disabled) {
background-color: var(--button-danger-hover-bg, rgba(239, 68, 68, 0.9));
@apply opacity-95 scale-105;
@@ -344,7 +397,7 @@
.prompt-input {
min-height: 0;
padding: 0.5rem 0.75rem;
padding-inline-start: 2.5rem; /* preserve space for nav buttons */
padding-inline-end: 5.5rem;
padding-bottom: 0.75rem;
}