mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(hub,web): query Codex models via machine RPC instead of session cwd (#1186)
SessionChat fetched Codex models through the session-scoped endpoint, so the CLI listed models in the session process cwd, where a missing directory or project-level Codex config could skew or break the result. Use the machine-scoped endpoint (already used by NewSession) and drop the now-unused session route and RPC plumbing. Fixes #1072
This commit is contained in:
@@ -294,10 +294,6 @@ export class RpcGateway {
|
||||
}
|
||||
}
|
||||
|
||||
async listCodexModelsForSession(sessionId: string): Promise<RpcListCodexModelsResponse> {
|
||||
return await this.sessionRpc(sessionId, RPC_METHODS.ListCodexModels, {}, MODEL_LIST_RPC_TIMEOUT_MS) as RpcListCodexModelsResponse
|
||||
}
|
||||
|
||||
async listCodexModelsForMachine(machineId: string): Promise<RpcListCodexModelsResponse> {
|
||||
return await this.machineRpc(machineId, RPC_METHODS.ListCodexModels, {}, MODEL_LIST_RPC_TIMEOUT_MS) as RpcListCodexModelsResponse
|
||||
}
|
||||
|
||||
@@ -1696,10 +1696,6 @@ export class SyncEngine {
|
||||
return await this.rpcGateway.listSkills(sessionId, flavor)
|
||||
}
|
||||
|
||||
async listCodexModelsForSession(sessionId: string): Promise<RpcListCodexModelsResponse> {
|
||||
return await this.rpcGateway.listCodexModelsForSession(sessionId)
|
||||
}
|
||||
|
||||
async listCodexModelsForMachine(machineId: string): Promise<RpcListCodexModelsResponse> {
|
||||
return await this.rpcGateway.listCodexModelsForMachine(machineId)
|
||||
}
|
||||
|
||||
@@ -69,12 +69,6 @@ function createApp(session: Session, opts?: {
|
||||
const applySessionConfig = async (sessionId: string, config: Record<string, unknown>) => {
|
||||
applySessionConfigCalls.push([sessionId, config])
|
||||
}
|
||||
const listCodexModelsForSession = async () => ({
|
||||
success: true,
|
||||
models: [
|
||||
{ id: 'gpt-5.5', displayName: 'GPT-5.5', isDefault: true }
|
||||
]
|
||||
})
|
||||
const listOpencodeModelsForSession = async () => ({
|
||||
success: true,
|
||||
availableModels: [
|
||||
@@ -128,7 +122,6 @@ function createApp(session: Session, opts?: {
|
||||
? { ok: true, sessionId: session.id, session }
|
||||
: { ok: false, reason: 'not-found' },
|
||||
applySessionConfig,
|
||||
listCodexModelsForSession,
|
||||
listCursorModelsForSession,
|
||||
listOpencodeModelsForSession,
|
||||
listOpencodeReasoningEffortOptionsForSession,
|
||||
@@ -717,20 +710,6 @@ describe('sessions routes', () => {
|
||||
expect(localApp.applySessionConfigCalls).toEqual([])
|
||||
})
|
||||
|
||||
it('returns Codex models for active Codex sessions', async () => {
|
||||
const { app } = createApp(createSession())
|
||||
|
||||
const response = await app.request('/api/sessions/session-1/codex-models')
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
expect(await response.json()).toEqual({
|
||||
success: true,
|
||||
models: [
|
||||
{ id: 'gpt-5.5', displayName: 'GPT-5.5', isDefault: true }
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
it('returns OpenCode reasoning effort options for active OpenCode sessions', async () => {
|
||||
const session = createSession({
|
||||
metadata: { path: '/tmp/project', host: 'localhost', flavor: 'opencode' }
|
||||
|
||||
@@ -766,36 +766,6 @@ export function createSessionsRoutes(getSyncEngine: () => SyncEngine | null): Ho
|
||||
}
|
||||
})
|
||||
|
||||
app.get('/sessions/:id/codex-models', async (c) => {
|
||||
const engine = requireSyncEngine(c, getSyncEngine)
|
||||
if (engine instanceof Response) {
|
||||
return engine
|
||||
}
|
||||
|
||||
const sessionResult = requireSessionFromParam(c, engine, { requireActive: true })
|
||||
if (sessionResult instanceof Response) {
|
||||
return sessionResult
|
||||
}
|
||||
|
||||
const flavor = sessionResult.session.metadata?.flavor ?? 'claude'
|
||||
if (flavor !== 'codex') {
|
||||
return c.json({
|
||||
success: false,
|
||||
error: 'Codex models are only available for Codex sessions'
|
||||
}, 400)
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await engine.listCodexModelsForSession(sessionResult.sessionId)
|
||||
return c.json(result)
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Failed to list Codex models'
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
|
||||
app.get('/sessions/:id/opencode-models', async (c) => {
|
||||
const engine = requireSyncEngine(c, getSyncEngine)
|
||||
if (engine instanceof Response) {
|
||||
|
||||
@@ -653,12 +653,6 @@ export class ApiClient {
|
||||
)
|
||||
}
|
||||
|
||||
async getSessionCodexModels(sessionId: string): Promise<CodexModelsResponse> {
|
||||
return await this.request<CodexModelsResponse>(
|
||||
`/api/sessions/${encodeURIComponent(sessionId)}/codex-models`
|
||||
)
|
||||
}
|
||||
|
||||
async getSessionOpencodeModels(sessionId: string): Promise<OpencodeModelsResponse> {
|
||||
return await this.request<OpencodeModelsResponse>(
|
||||
`/api/sessions/${encodeURIComponent(sessionId)}/opencode-models`
|
||||
|
||||
@@ -544,7 +544,7 @@ function SessionChatInner(props: SessionChatProps) {
|
||||
const codexCollaborationModeSupported = agentFlavor === 'codex' && !controlledByUser
|
||||
const codexModelsState = useCodexModels({
|
||||
api: props.api,
|
||||
sessionId: props.session.id,
|
||||
machineId: props.session.metadata?.machineId ?? null,
|
||||
enabled: agentFlavor === 'codex' && props.session.active && !controlledByUser
|
||||
})
|
||||
const effectiveCodexServiceTier = agentFlavor === 'codex'
|
||||
|
||||
@@ -5,7 +5,6 @@ import { queryKeys } from '@/lib/query-keys'
|
||||
|
||||
export function useCodexModels(args: {
|
||||
api: ApiClient | null
|
||||
sessionId?: string | null
|
||||
machineId?: string | null
|
||||
enabled?: boolean
|
||||
}): {
|
||||
@@ -13,11 +12,9 @@ export function useCodexModels(args: {
|
||||
isLoading: boolean
|
||||
error: string | null
|
||||
} {
|
||||
const { api, sessionId, machineId } = args
|
||||
const enabled = Boolean(args.enabled && api && (sessionId || machineId))
|
||||
const queryKey = sessionId
|
||||
? queryKeys.sessionCodexModels(sessionId)
|
||||
: queryKeys.machineCodexModels(machineId ?? 'unknown')
|
||||
const { api, machineId } = args
|
||||
const enabled = Boolean(args.enabled && api && machineId)
|
||||
const queryKey = queryKeys.machineCodexModels(machineId ?? 'unknown')
|
||||
|
||||
const query = useQuery({
|
||||
queryKey,
|
||||
@@ -25,9 +22,6 @@ export function useCodexModels(args: {
|
||||
if (!api) {
|
||||
throw new Error('API unavailable')
|
||||
}
|
||||
if (sessionId) {
|
||||
return await api.getSessionCodexModels(sessionId)
|
||||
}
|
||||
if (machineId) {
|
||||
return await api.getMachineCodexModels(machineId)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ export const queryKeys = {
|
||||
staged ? 'staged' : 'unstaged'
|
||||
] as const,
|
||||
slashCommands: (sessionId: string) => ['slash-commands', sessionId] as const,
|
||||
sessionCodexModels: (sessionId: string) => ['session-codex-models', 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,
|
||||
|
||||
Reference in New Issue
Block a user