mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-08 07:17:39 +00:00
feat: add Grok Build support (#1030)
* test: define Grok Build integration behavior * feat: add Grok Build agent integration * test: cover Grok permissions and resume paths * docs: add Grok Build setup guide * fix: scope Grok ACP discovery to session cwd * fix: align Grok permission UI semantics * docs: clarify Grok runner setup * test: require Grok create model and effort options * feat: add Grok create model and effort pickers * test: define Grok runtime parity behavior * feat: add Grok runtime ACP controls and discovery * fix: tighten Grok runtime controls * fix: suppress nonfatal Grok title quota errors * feat: support Grok Auto permission mode * feat: forward ACP native session titles for Grok * fix: guard Grok Windows shell arguments
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import type { AgentFlavor } from '@hapi/protocol'
|
||||
import type { AgentFlavor, PermissionMode } from '@hapi/protocol'
|
||||
import type { ApiClient } from '@/api/client'
|
||||
import type { SpawnResponse } from '@/types/api'
|
||||
import { queryKeys } from '@/lib/query-keys'
|
||||
@@ -12,6 +12,7 @@ type SpawnInput = {
|
||||
effort?: string
|
||||
modelReasoningEffort?: string
|
||||
yolo?: boolean
|
||||
permissionMode?: PermissionMode
|
||||
sessionType?: 'simple' | 'worktree'
|
||||
worktreeName?: string
|
||||
}
|
||||
@@ -37,7 +38,8 @@ export function useSpawnSession(api: ApiClient | null): {
|
||||
input.yolo,
|
||||
input.sessionType,
|
||||
input.worktreeName,
|
||||
input.effort
|
||||
input.effort,
|
||||
input.permissionMode
|
||||
)
|
||||
},
|
||||
onSuccess: () => {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import type { ApiClient } from '@/api/client'
|
||||
import type { GrokModelSummary } from '@/types/api'
|
||||
import { queryKeys } from '@/lib/query-keys'
|
||||
|
||||
export function useGrokModels(args: {
|
||||
api: ApiClient | null
|
||||
sessionId?: string | null
|
||||
enabled?: boolean
|
||||
}): {
|
||||
availableModels: GrokModelSummary[]
|
||||
currentModelId: string | null
|
||||
isLoading: boolean
|
||||
error: string | null
|
||||
} {
|
||||
const enabled = Boolean(args.enabled && args.api && args.sessionId)
|
||||
const query = useQuery({
|
||||
queryKey: args.sessionId
|
||||
? queryKeys.sessionGrokModels(args.sessionId)
|
||||
: ['session-grok-models', 'unknown'] as const,
|
||||
queryFn: async () => {
|
||||
if (!args.api || !args.sessionId) throw new Error('Grok session unavailable')
|
||||
return await args.api.getSessionGrokModels(args.sessionId)
|
||||
},
|
||||
enabled,
|
||||
staleTime: 30_000,
|
||||
retry: false,
|
||||
})
|
||||
|
||||
return {
|
||||
availableModels: query.data?.availableModels ?? [],
|
||||
currentModelId: query.data?.currentModelId ?? null,
|
||||
isLoading: query.isLoading,
|
||||
error: query.data?.success === false
|
||||
? (query.data.error ?? 'Failed to load Grok models')
|
||||
: query.error instanceof Error ? query.error.message : null,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import type { ApiClient } from '@/api/client'
|
||||
import type { GrokModelSummary } from '@/types/api'
|
||||
import { queryKeys } from '@/lib/query-keys'
|
||||
|
||||
export function useGrokModelsForCwd(args: {
|
||||
api: ApiClient | null
|
||||
machineId?: string | null
|
||||
cwd?: string | null
|
||||
enabled?: boolean
|
||||
}): {
|
||||
availableModels: GrokModelSummary[]
|
||||
currentModelId: string | null
|
||||
autoPermissionModeSupported: boolean | null
|
||||
isLoading: boolean
|
||||
error: string | null
|
||||
} {
|
||||
const { api, machineId, cwd } = args
|
||||
const trimmedCwd = typeof cwd === 'string' ? cwd.trim() : ''
|
||||
const enabled = Boolean(args.enabled && api && machineId && trimmedCwd)
|
||||
|
||||
const query = useQuery({
|
||||
queryKey: machineId && trimmedCwd
|
||||
? queryKeys.machineGrokModelsForCwd(machineId, trimmedCwd)
|
||||
: ['machine-grok-models', 'unknown', 'unknown'] as const,
|
||||
queryFn: async () => {
|
||||
if (!api || !machineId || !trimmedCwd) {
|
||||
throw new Error('Grok models target unavailable')
|
||||
}
|
||||
return await api.getMachineGrokModelsForCwd(machineId, trimmedCwd)
|
||||
},
|
||||
enabled,
|
||||
staleTime: 60_000,
|
||||
retry: false,
|
||||
})
|
||||
|
||||
return {
|
||||
availableModels: query.data?.availableModels ?? [],
|
||||
currentModelId: query.data?.currentModelId ?? null,
|
||||
autoPermissionModeSupported: query.data?.autoPermissionModeSupported ?? null,
|
||||
isLoading: query.isLoading,
|
||||
error: query.data?.success === false
|
||||
? (query.data.error ?? 'Failed to load Grok models')
|
||||
: query.error instanceof Error
|
||||
? query.error.message
|
||||
: query.error
|
||||
? 'Failed to load Grok models'
|
||||
: null,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import type { ApiClient } from '@/api/client'
|
||||
import type { GrokReasoningEffortOption } from '@/types/api'
|
||||
import { queryKeys } from '@/lib/query-keys'
|
||||
|
||||
export function useGrokReasoningEffortOptions(args: {
|
||||
api: ApiClient | null
|
||||
sessionId?: string | null
|
||||
enabled?: boolean
|
||||
}): {
|
||||
options: GrokReasoningEffortOption[]
|
||||
currentValue: string | null
|
||||
isLoading: boolean
|
||||
error: string | null
|
||||
} {
|
||||
const enabled = Boolean(args.enabled && args.api && args.sessionId)
|
||||
const query = useQuery({
|
||||
queryKey: args.sessionId
|
||||
? queryKeys.sessionGrokReasoningEffortOptions(args.sessionId)
|
||||
: ['session-grok-reasoning-effort-options', 'unknown'] as const,
|
||||
queryFn: async () => {
|
||||
if (!args.api || !args.sessionId) throw new Error('Grok session unavailable')
|
||||
return await args.api.getSessionGrokReasoningEffortOptions(args.sessionId)
|
||||
},
|
||||
enabled,
|
||||
staleTime: 30_000,
|
||||
retry: false,
|
||||
})
|
||||
|
||||
return {
|
||||
options: query.data?.options ?? [],
|
||||
currentValue: query.data?.currentValue ?? null,
|
||||
isLoading: query.isLoading,
|
||||
error: query.data?.success === false
|
||||
? (query.data.error ?? 'Failed to load Grok effort options')
|
||||
: query.error instanceof Error ? query.error.message : null,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user