mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-07 02:51:50 +00:00
refactor(tui): store-driven turn state + slash registry + module split
Hoist turn state from a 286-line hook into $turnState atom + turnController
singleton. createGatewayEventHandler becomes a typed dispatch over the
controller; its ctx shrinks from 30 fields to 5. Event-handler refs and 16
threaded actions are gone.
Fold three createSlash*Handler factories into a data-driven SlashCommand[]
registry under slash/commands/{core,session,ops}.ts. Aliases are data;
findSlashCommand does name+alias lookup. Shared guarded/guardedErr combinator
in slash/guarded.ts.
Split constants.ts + app/helpers.ts into config/ (timing/limits/env),
content/ (faces/placeholders/hotkeys/verbs/charms/fortunes), domain/ (roles/
details/messages/paths/slash/viewport/usage), protocol/ (interpolation/paste).
Type every RPC response in gatewayTypes.ts (26 new interfaces); drop all
`(r: any)` across slash + main app.
Shrink useMainApp from 1216 -> 646 lines by extracting useSessionLifecycle,
useSubmission, useConfigSync. Add <Fg> themed primitive and strip ~50
`as any` color casts.
Tests: 50 passing. Build + type-check clean.
This commit is contained in:
parent
9c71f3a6ea
commit
68ecdb6e26
56 changed files with 3666 additions and 4117 deletions
|
|
@ -1,23 +1,26 @@
|
|||
import { useEffect, useRef } from 'react'
|
||||
|
||||
import { toolTrailLabel } from '../lib/text.js'
|
||||
import type { ActiveTool, ActivityItem } from '../types.js'
|
||||
import { LONG_RUN_CHARMS } from '../content/charms.js'
|
||||
import { pick, toolTrailLabel } from '../lib/text.js'
|
||||
import type { ActiveTool } from '../types.js'
|
||||
|
||||
import { turnController } from './turnController.js'
|
||||
|
||||
const DELAY_MS = 8_000
|
||||
const INTERVAL_MS = 10_000
|
||||
const MAX = 2
|
||||
const CHARMS = ['still cooking…', 'polishing edges…', 'asking the void nicely…']
|
||||
const MAX_CHARMS_PER_TOOL = 2
|
||||
|
||||
export function useLongRunToolCharms(
|
||||
busy: boolean,
|
||||
tools: ActiveTool[],
|
||||
pushActivity: (text: string, tone?: ActivityItem['tone'], replaceLabel?: string) => void
|
||||
) {
|
||||
const slotRef = useRef(new Map<string, { count: number; lastAt: number }>())
|
||||
interface Slot {
|
||||
count: number
|
||||
lastAt: number
|
||||
}
|
||||
|
||||
export function useLongRunToolCharms(busy: boolean, tools: ActiveTool[]) {
|
||||
const slots = useRef(new Map<string, Slot>())
|
||||
|
||||
useEffect(() => {
|
||||
if (!busy || !tools.length) {
|
||||
slotRef.current.clear()
|
||||
slots.current.clear()
|
||||
|
||||
return
|
||||
}
|
||||
|
|
@ -26,9 +29,9 @@ export function useLongRunToolCharms(
|
|||
const now = Date.now()
|
||||
const liveIds = new Set(tools.map(t => t.id))
|
||||
|
||||
for (const key of [...slotRef.current.keys()]) {
|
||||
for (const key of [...slots.current.keys()]) {
|
||||
if (!liveIds.has(key)) {
|
||||
slotRef.current.delete(key)
|
||||
slots.current.delete(key)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -37,20 +40,17 @@ export function useLongRunToolCharms(
|
|||
continue
|
||||
}
|
||||
|
||||
const slot = slotRef.current.get(tool.id) ?? { count: 0, lastAt: 0 }
|
||||
const slot = slots.current.get(tool.id) ?? { count: 0, lastAt: 0 }
|
||||
|
||||
if (slot.count >= MAX || now - slot.lastAt < INTERVAL_MS) {
|
||||
if (slot.count >= MAX_CHARMS_PER_TOOL || now - slot.lastAt < INTERVAL_MS) {
|
||||
continue
|
||||
}
|
||||
|
||||
slot.count += 1
|
||||
slot.lastAt = now
|
||||
slotRef.current.set(tool.id, slot)
|
||||
slots.current.set(tool.id, { count: slot.count + 1, lastAt: now })
|
||||
|
||||
const charm = CHARMS[Math.floor(Math.random() * CHARMS.length)]!
|
||||
const sec = Math.round((now - tool.startedAt) / 1000)
|
||||
|
||||
pushActivity(`${charm} (${toolTrailLabel(tool.name)} · ${sec}s)`)
|
||||
turnController.pushActivity(`${pick(LONG_RUN_CHARMS)} (${toolTrailLabel(tool.name)} · ${sec}s)`)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,5 +58,5 @@ export function useLongRunToolCharms(
|
|||
const id = setInterval(tick, 1000)
|
||||
|
||||
return () => clearInterval(id)
|
||||
}, [busy, pushActivity, tools])
|
||||
}, [busy, tools])
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue