mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-29 18:46:59 +00:00
fmt(js): npm run fix on merge (#73770)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
f088fa5070
commit
ada389004f
11 changed files with 43 additions and 21 deletions
|
|
@ -133,10 +133,7 @@ export function useComposerMicroActionProviders(): ComposerMicroActionProvider[]
|
|||
const contributions = useContributions(COMPOSER_AREAS.microActions)
|
||||
|
||||
return useMemo(
|
||||
() =>
|
||||
contributions
|
||||
.map(c => c.data as ComposerMicroActionProvider)
|
||||
.filter(p => typeof p?.resolve === 'function'),
|
||||
() => contributions.map(c => c.data as ComposerMicroActionProvider).filter(p => typeof p?.resolve === 'function'),
|
||||
[contributions]
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,18 @@ import { Codicon } from '@/components/ui/codicon'
|
|||
import { Tip, TipKeybindLabel } from '@/components/ui/tooltip'
|
||||
import { useI18n } from '@/i18n'
|
||||
import { triggerHaptic } from '@/lib/haptics'
|
||||
import { AudioLines, Ear, EarOff, iconSize, Layers3, Loader2, Square, SteeringWheel, Volume2, VolumeX } from '@/lib/icons'
|
||||
import {
|
||||
AudioLines,
|
||||
Ear,
|
||||
EarOff,
|
||||
iconSize,
|
||||
Layers3,
|
||||
Loader2,
|
||||
Square,
|
||||
SteeringWheel,
|
||||
Volume2,
|
||||
VolumeX
|
||||
} from '@/lib/icons'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { $wakeWord, toggleWakeWord } from '@/store/wake-word'
|
||||
|
||||
|
|
@ -316,11 +327,13 @@ function WakeWordButton({ disabled, pausedForVoice = false }: { disabled: boolea
|
|||
const wake = useStore($wakeWord)
|
||||
|
||||
const phrase = wake.phrase || 'hey hermes'
|
||||
|
||||
const label = pausedForVoice
|
||||
? c.wakeWordPausedVoice(phrase)
|
||||
: wake.listening
|
||||
? c.wakeWordListening(phrase)
|
||||
: c.wakeWordOff(phrase)
|
||||
|
||||
const tooltip = !pausedForVoice && wake.notice ? `${label} — ${wake.notice}` : label
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ export function useComposerVoice({
|
|||
// it guards resumeWakeIfPaused from resuming a detector another surface owns.
|
||||
const pauseWakeForVoice = useCallback(() => {
|
||||
wakePausedRef.current = true
|
||||
|
||||
const barrier = (async () => {
|
||||
try {
|
||||
await $gateway.get()?.request('wake.pause', {})
|
||||
|
|
@ -193,6 +194,7 @@ export function useComposerVoice({
|
|||
// No wake listener / older backend — nothing held the mic.
|
||||
}
|
||||
})()
|
||||
|
||||
wakePauseBarrierRef.current = barrier
|
||||
|
||||
return barrier
|
||||
|
|
|
|||
|
|
@ -35,7 +35,15 @@ import { requestVoiceConversationStart } from '@/store/composer'
|
|||
import { setCronFocusJobId } from '@/store/cron'
|
||||
import { $pinnedSessionIds, pinSession, restoreWorktree, unpinSession } from '@/store/layout'
|
||||
import { $previewTarget } from '@/store/preview'
|
||||
import { $activeGatewayProfile, $freshSessionRequest, $profileScope, ensureGatewayProfile, newSessionInProfile, normalizeProfileKey, refreshActiveProfile } from '@/store/profile'
|
||||
import {
|
||||
$activeGatewayProfile,
|
||||
$freshSessionRequest,
|
||||
$profileScope,
|
||||
ensureGatewayProfile,
|
||||
newSessionInProfile,
|
||||
normalizeProfileKey,
|
||||
refreshActiveProfile
|
||||
} from '@/store/profile'
|
||||
import { $startWorkSessionRequest, followActiveSessionCwd } from '@/store/projects'
|
||||
import {
|
||||
$activeSessionId,
|
||||
|
|
@ -667,9 +675,7 @@ export function ContribWiring({ children }: { children: ReactNode }) {
|
|||
emitGatewayEvent(event)
|
||||
|
||||
if (event.type === 'wake.detected') {
|
||||
const payload = event.payload as
|
||||
| { profile?: null | string; start_new_session?: boolean }
|
||||
| undefined
|
||||
const payload = event.payload as { profile?: null | string; start_new_session?: boolean } | undefined
|
||||
|
||||
// Audible confirmation that the wake registered, before voice capture
|
||||
// starts. Gated by the shared sound-mute toggle.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ describe('terminalClipboardIntent', () => {
|
|||
})
|
||||
|
||||
it('claims paste regardless of selection, since paste has nothing to do with one', () => {
|
||||
expect(terminalClipboardIntent(key({ key: 'v', metaKey: true }), { hasSelection: false, isMac: true })).toBe('paste')
|
||||
expect(terminalClipboardIntent(key({ key: 'v', metaKey: true }), { hasSelection: false, isMac: true })).toBe(
|
||||
'paste'
|
||||
)
|
||||
expect(
|
||||
terminalClipboardIntent(key({ ctrlKey: true, key: 'v', shiftKey: true }), { hasSelection: false, isMac: false })
|
||||
).toBe('paste')
|
||||
|
|
|
|||
|
|
@ -832,7 +832,6 @@ export function useTerminalSession({
|
|||
|
||||
return false
|
||||
}
|
||||
|
||||
void (async () => {
|
||||
const text = (await window.hermesDesktop?.readClipboard?.()) ?? ''
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,6 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import {
|
||||
isMessagingSource,
|
||||
MESSAGING_SESSION_SOURCE_IDS,
|
||||
sessionSourceSearchTerms
|
||||
} from './session-source'
|
||||
import { isMessagingSource, MESSAGING_SESSION_SOURCE_IDS, sessionSourceSearchTerms } from './session-source'
|
||||
|
||||
// Regression guard for #46761 / PR #47395: Photon (iMessage) must keep its own
|
||||
// sidebar section. refreshMessagingSessions() filters rows through
|
||||
|
|
|
|||
|
|
@ -273,6 +273,7 @@ function openSpeechStream(wsUrl: string, options: VoicePlaybackOptions): SpeechS
|
|||
if (frame.type === 'start') {
|
||||
streamRate = frame.sample_rate || 24_000
|
||||
context = new AudioContext()
|
||||
|
||||
// Autoplay policy can hand back a suspended context when playback wasn't
|
||||
// started by a user gesture (e.g. a wake-word-started voice turn). Resume
|
||||
// it so the first reply is audible instead of silently buffering. Electron
|
||||
|
|
@ -281,6 +282,7 @@ function openSpeechStream(wsUrl: string, options: VoicePlaybackOptions): SpeechS
|
|||
if (context.state === 'suspended') {
|
||||
void context.resume().catch(() => undefined)
|
||||
}
|
||||
|
||||
nextStartAt = 0
|
||||
} else if (frame.type === 'end') {
|
||||
finishWhenDrained()
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ describe('playWakeSound', () => {
|
|||
expect(oscillators).toHaveLength(2)
|
||||
expect(oscillators[0].frequency.setValueAtTime).toHaveBeenCalledWith(783.99, expect.any(Number))
|
||||
expect(oscillators[1].frequency.setValueAtTime).toHaveBeenCalledWith(1046.5, expect.any(Number))
|
||||
|
||||
for (const osc of oscillators) {
|
||||
expect(osc.start).toHaveBeenCalled()
|
||||
expect(osc.stop).toHaveBeenCalled()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ import {
|
|||
} from './wake-word'
|
||||
|
||||
const requester = (impl: (method: string, params?: Record<string, unknown>) => unknown) =>
|
||||
vi.fn(async (method: string, params: Record<string, unknown> = {}) => impl(method, params)) as unknown as WakeRequester
|
||||
vi.fn(async (method: string, params: Record<string, unknown> = {}) =>
|
||||
impl(method, params)
|
||||
) as unknown as WakeRequester
|
||||
|
||||
beforeEach(() => {
|
||||
resetWakeWordState()
|
||||
|
|
@ -108,9 +110,7 @@ describe('toggleWakeWord', () => {
|
|||
it('marks the feature unavailable when start refuses with reason unavailable', async () => {
|
||||
applyWakeStatus({ available: true, listening: false, phrase: 'hey hermes' })
|
||||
|
||||
await toggleWakeWord(
|
||||
requester(() => ({ hint: 'Set PORCUPINE_ACCESS_KEY', reason: 'unavailable', started: false }))
|
||||
)
|
||||
await toggleWakeWord(requester(() => ({ hint: 'Set PORCUPINE_ACCESS_KEY', reason: 'unavailable', started: false })))
|
||||
|
||||
const state = $wakeWord.get()
|
||||
expect(state.available).toBe(false)
|
||||
|
|
|
|||
|
|
@ -621,7 +621,11 @@ export type GatewayEvent =
|
|||
}
|
||||
| { payload?: { state?: 'idle' | 'listening' | 'transcribing' }; session_id?: string; type: 'voice.status' }
|
||||
| { payload?: { no_speech_limit?: boolean; text?: string }; session_id?: string; type: 'voice.transcript' }
|
||||
| { payload?: { phrase?: string; profile?: null | string; start_new_session?: boolean }; session_id?: string; type: 'wake.detected' }
|
||||
| {
|
||||
payload?: { phrase?: string; profile?: null | string; start_new_session?: boolean }
|
||||
session_id?: string
|
||||
type: 'wake.detected'
|
||||
}
|
||||
| { payload?: { reason?: string }; session_id?: string; type: 'dashboard.new_session_requested' }
|
||||
| { payload: { line: string }; session_id?: string; type: 'gateway.stderr' }
|
||||
| {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue