mirror of
https://github.com/wu736139669/hapi.git
synced 2026-11-11 02:11:37 +00:00
* feat(config): add agent config descriptor protocol and advertise via runner capability Introduce shared agent configuration descriptors covering model, effort, permission, and secondary settings per agent flavor, plus the canonical HAPI YOLO -> native permission mode mapping. Runners advertise the builtin descriptors through the runner-state capability so hubs and web can render configuration without hardcoded flavor branches. Migrate the OpenCode create-session model picker from a bespoke radio list to the shared SelectControl combobox. * feat(web): render create-session permission from agent config descriptor Replace the flavor-branched Grok/Codex-family/YOLO permission block with a descriptor-driven PermissionField. Pi now reports permission as managed instead of silently ignoring the YOLO toggle, and YOLO-only flavors show the native permission mode the preference maps to. Removes the superseded GrokPermissionModeSelector and CodexFamilyPermissionModeSelector components. * ci: retry flaky claudeRemote 5s-timeout failure * fix(web): persist explicit OpenCode Default selection instead of restoring a concrete model The parent initialization effect treated every null selected model as 'uninitialized' and auto-picked a concrete advertised model, clobbering the user's explicit Default choice (and a restored Default preference). null now means explicit Default and is preserved; only undefined (no choice made yet) triggers probe-based initialization. Add parent-level regression tests for Default persistence and remembered-model restore. * fix(web): accept undefined selected model in OpencodeModelSelector props * feat(web+cli+hub): unify create-session model/effort fields and add Pi model/effort support Pi's agent config descriptor now advertises model (machine) and effort (static thinking levels) for create AND session availability: - cli: ListPiModelsForMachine RPC runs 'pi --list-models' (cached, inflight deduped) and parses the provider/model table; startup model match accepts provider-qualified ids - hub: GET /api/machines/:id/pi-models route + rpcGateway/syncEngine passthrough - web: NewSession renders Pi models grouped by provider through the generic ModelSelector and a new descriptor-driven EffortField (replaces the per-flavor LaunchEffortSelector/ReasoningEffortSelector pair); launch payload forwards Pi model + thinking-level effort (runner already supported --model/ --effort for pi) * fix(web): render Pi provider groups in ModelSelector and scope Grok availability warning - ModelSelector now renders grouped options as <optgroup> (Pi models are provider-grouped; identical modelIds from different providers stay distinct) - PermissionField only receives autoPermissionModeSupported for Grok — a cached Grok probe result no longer leaks the Grok warning onto other agents Addresses HAPI Bot Minor findings on #1469. * fix(web): drop Object.groupBy from ModelSelector; revalidate restored Pi models against the catalog - ModelSelector buckets options with a reduce instead of Object.groupBy (Safari < 17.4 has no polyfill — New Session would throw on those clients) - Pi restored model/effort are cleared when the value is absent from the live machine catalog, and Create waits for the catalog while a non-default Pi choice is being validated (mirrors Codex/Grok/Copilot handling) Addresses HAPI Bot findings on #1469. * fix(pi+web): serialize startup model before thinking level; hide Pi launch controls during history import - PiSession gains startupModelSettled; the startup set_thinking_level waits for the requested model's set_model attempt to settle first, so a level the default model rejects is not lost before the requested model is confirmed (set_model and set_thinking_level were already serialized by the runtime mutation lock; this pins the model-first ordering) - Create Session hides Pi model/effort controls while a Pi history import is selected — the import reopens the native session as-is and would silently ignore launch-only model/effort values Addresses HAPI Bot findings on #1469. * fix(pi): settle startup-model gate when model discovery fails or returns no models A failed or empty get_available_models response would leave the startupModelSettled gate unresolved, stranding a requested startup effort indefinitely. Resolve the gate on the error path and the empty-models path; adds regression tests for both.
39 lines
2.8 KiB
TypeScript
39 lines
2.8 KiB
TypeScript
export const queryKeys = {
|
|
sessions: ['sessions'] as const,
|
|
session: (sessionId: string) => ['session', sessionId] as const,
|
|
messages: (sessionId: string) => ['messages', sessionId] as const,
|
|
machines: ['machines'] as const,
|
|
sqliteStorage: ['sqlite-storage'] as const,
|
|
hubSettings: ['hub-settings'] as const,
|
|
usageSummary: (range: string, timeZone: string) => ['usage-summary', range, timeZone] as const,
|
|
machineCodexModels: (machineId: string) => ['machine-codex-models', machineId] as const,
|
|
sessionCodexModels: (sessionId: string) => ['session-codex-models', sessionId] as const,
|
|
gitStatus: (sessionId: string) => ['git-status', sessionId] as const,
|
|
sessionFiles: (sessionId: string, query: string) => ['session-files', sessionId, query] as const,
|
|
sessionDirectory: (sessionId: string, path: string) => ['session-directory', sessionId, path] as const,
|
|
sessionFile: (sessionId: string, path: string) => ['session-file', sessionId, path] as const,
|
|
gitFileDiff: (sessionId: string, path: string, staged?: boolean) => [
|
|
'git-file-diff',
|
|
sessionId,
|
|
path,
|
|
staged ? 'staged' : 'unstaged'
|
|
] as const,
|
|
slashCommands: (sessionId: string) => ['slash-commands', sessionId] as const,
|
|
sessionCursorModels: (sessionId: string) => ['session-cursor-models', sessionId] as const,
|
|
sessionCursorChatStore: (sessionId: string) => ['session-cursor-chat-store', sessionId] as const,
|
|
sessionPiModels: (sessionId: string) => ['session-pi-models', sessionId] as const,
|
|
machineCursorModels: (machineId: string) => ['machine-cursor-models', machineId] as const,
|
|
sessionOpencodeModels: (sessionId: string) => ['session-opencode-models', sessionId] as const,
|
|
sessionOpencodeReasoningEffortOptions: (sessionId: string) => ['session-opencode-reasoning-effort-options', sessionId] as const,
|
|
machineOpencodeModelsForCwd: (machineId: string, cwd: string) => ['machine-opencode-models', machineId, cwd] as const,
|
|
machineGrokModelsForCwd: (machineId: string, cwd: string) => ['machine-grok-models', machineId, cwd] as const,
|
|
sessionGrokModels: (sessionId: string) => ['session-grok-models', sessionId] as const,
|
|
sessionCopilotModels: (sessionId: string) => ['session-copilot-models', sessionId] as const,
|
|
machineCopilotModelsForCwd: (machineId: string, cwd: string) => ['machine-copilot-models', machineId, cwd] as const,
|
|
sessionGrokReasoningEffortOptions: (sessionId: string) => ['session-grok-reasoning-effort-options', sessionId] as const,
|
|
machineAgyModels: (machineId: string) => ['machine-agy-models', machineId] as const,
|
|
machinePiModels: (machineId: string) => ['machine-pi-models', machineId] as const,
|
|
skills: (sessionId: string) => ['skills', sessionId] as const,
|
|
scratchlist: (sessionId: string) => ['scratchlist', sessionId] as const,
|
|
}
|