mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
feat: add codex reasoning effort option (#297)
This commit is contained in:
@@ -381,13 +381,14 @@ export class ApiClient {
|
||||
directory: string,
|
||||
agent?: 'claude' | 'codex' | 'cursor' | 'gemini' | 'opencode',
|
||||
model?: string,
|
||||
modelReasoningEffort?: string,
|
||||
yolo?: boolean,
|
||||
sessionType?: 'simple' | 'worktree',
|
||||
worktreeName?: string
|
||||
): Promise<SpawnResponse> {
|
||||
return await this.request<SpawnResponse>(`/api/machines/${encodeURIComponent(machineId)}/spawn`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ directory, agent, model, yolo, sessionType, worktreeName })
|
||||
body: JSON.stringify({ directory, agent, model, modelReasoningEffort, yolo, sessionType, worktreeName })
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { AgentType, CodexReasoningEffort } from './types'
|
||||
import { CODEX_REASONING_EFFORT_OPTIONS } from './types'
|
||||
import { useTranslation } from '@/lib/use-translation'
|
||||
|
||||
export function ReasoningEffortSelector(props: {
|
||||
agent: AgentType
|
||||
value: CodexReasoningEffort
|
||||
isDisabled: boolean
|
||||
onChange: (value: CodexReasoningEffort) => void
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
if (props.agent !== 'codex') {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-1.5 px-3 py-3">
|
||||
<label className="text-xs font-medium text-[var(--app-hint)]">
|
||||
{t('newSession.reasoningEffort')}{' '}
|
||||
<span className="font-normal">({t('newSession.model.optional')})</span>
|
||||
</label>
|
||||
<select
|
||||
value={props.value}
|
||||
onChange={(e) => props.onChange(e.target.value as CodexReasoningEffort)}
|
||||
disabled={props.isDisabled}
|
||||
className="w-full px-3 py-2 text-sm rounded-lg border border-[var(--app-divider)] bg-[var(--app-bg)] text-[var(--app-text)] focus:outline-none focus:ring-2 focus:ring-[var(--app-link)] disabled:opacity-50"
|
||||
>
|
||||
{CODEX_REASONING_EFFORT_OPTIONS.map((option) => (
|
||||
<option key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -7,12 +7,13 @@ import { useSessions } from '@/hooks/queries/useSessions'
|
||||
import { useActiveSuggestions, type Suggestion } from '@/hooks/useActiveSuggestions'
|
||||
import { useDirectorySuggestions } from '@/hooks/useDirectorySuggestions'
|
||||
import { useRecentPaths } from '@/hooks/useRecentPaths'
|
||||
import type { AgentType, SessionType } from './types'
|
||||
import type { AgentType, CodexReasoningEffort, SessionType } from './types'
|
||||
import { ActionButtons } from './ActionButtons'
|
||||
import { AgentSelector } from './AgentSelector'
|
||||
import { DirectorySection } from './DirectorySection'
|
||||
import { MachineSelector } from './MachineSelector'
|
||||
import { ModelSelector } from './ModelSelector'
|
||||
import { ReasoningEffortSelector } from './ReasoningEffortSelector'
|
||||
import {
|
||||
loadPreferredAgent,
|
||||
loadPreferredYoloMode,
|
||||
@@ -43,6 +44,7 @@ export function NewSession(props: {
|
||||
const [pathExistence, setPathExistence] = useState<Record<string, boolean>>({})
|
||||
const [agent, setAgent] = useState<AgentType>(loadPreferredAgent)
|
||||
const [model, setModel] = useState('auto')
|
||||
const [modelReasoningEffort, setModelReasoningEffort] = useState<CodexReasoningEffort>('default')
|
||||
const [yoloMode, setYoloMode] = useState(loadPreferredYoloMode)
|
||||
const [sessionType, setSessionType] = useState<SessionType>('simple')
|
||||
const [worktreeName, setWorktreeName] = useState('')
|
||||
@@ -220,11 +222,15 @@ export function NewSession(props: {
|
||||
setError(null)
|
||||
try {
|
||||
const resolvedModel = model !== 'auto' && agent !== 'opencode' ? model : undefined
|
||||
const resolvedModelReasoningEffort = agent === 'codex' && modelReasoningEffort !== 'default'
|
||||
? modelReasoningEffort
|
||||
: undefined
|
||||
const result = await spawnSession({
|
||||
machineId,
|
||||
directory: directory.trim(),
|
||||
agent,
|
||||
model: resolvedModel,
|
||||
modelReasoningEffort: resolvedModelReasoningEffort,
|
||||
yolo: yoloMode,
|
||||
sessionType,
|
||||
worktreeName: sessionType === 'worktree' ? (worktreeName.trim() || undefined) : undefined
|
||||
@@ -294,6 +300,12 @@ export function NewSession(props: {
|
||||
isDisabled={isFormDisabled}
|
||||
onModelChange={setModel}
|
||||
/>
|
||||
<ReasoningEffortSelector
|
||||
agent={agent}
|
||||
value={modelReasoningEffort}
|
||||
isDisabled={isFormDisabled}
|
||||
onChange={setModelReasoningEffort}
|
||||
/>
|
||||
<YoloToggle
|
||||
yoloMode={yoloMode}
|
||||
isDisabled={isFormDisabled}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export type AgentType = 'claude' | 'codex' | 'cursor' | 'gemini' | 'opencode'
|
||||
export type SessionType = 'simple' | 'worktree'
|
||||
export type CodexReasoningEffort = 'default' | 'low' | 'medium' | 'high' | 'xhigh'
|
||||
|
||||
export const MODEL_OPTIONS: Record<AgentType, { value: string; label: string }[]> = {
|
||||
claude: [
|
||||
@@ -27,3 +28,11 @@ export const MODEL_OPTIONS: Record<AgentType, { value: string; label: string }[]
|
||||
],
|
||||
opencode: [],
|
||||
}
|
||||
|
||||
export const CODEX_REASONING_EFFORT_OPTIONS: { value: CodexReasoningEffort; label: string }[] = [
|
||||
{ value: 'default', label: 'Default' },
|
||||
{ value: 'low', label: 'Low' },
|
||||
{ value: 'medium', label: 'Medium' },
|
||||
{ value: 'high', label: 'High' },
|
||||
{ value: 'xhigh', label: 'XHigh' },
|
||||
]
|
||||
|
||||
@@ -8,6 +8,7 @@ type SpawnInput = {
|
||||
directory: string
|
||||
agent?: 'claude' | 'codex' | 'cursor' | 'gemini' | 'opencode'
|
||||
model?: string
|
||||
modelReasoningEffort?: string
|
||||
yolo?: boolean
|
||||
sessionType?: 'simple' | 'worktree'
|
||||
worktreeName?: string
|
||||
@@ -30,6 +31,7 @@ export function useSpawnSession(api: ApiClient | null): {
|
||||
input.directory,
|
||||
input.agent,
|
||||
input.model,
|
||||
input.modelReasoningEffort,
|
||||
input.yolo,
|
||||
input.sessionType,
|
||||
input.worktreeName
|
||||
|
||||
@@ -104,6 +104,7 @@ export default {
|
||||
'newSession.agent': 'Agent',
|
||||
'newSession.model': 'Model',
|
||||
'newSession.model.optional': 'optional',
|
||||
'newSession.reasoningEffort': 'Reasoning effort',
|
||||
'newSession.yolo': 'YOLO mode',
|
||||
'newSession.yolo.title': 'Bypass approvals and sandbox',
|
||||
'newSession.yolo.desc': 'Uses dangerous agent flags when spawning.',
|
||||
|
||||
@@ -106,6 +106,7 @@ export default {
|
||||
'newSession.agent': '代理',
|
||||
'newSession.model': '模型',
|
||||
'newSession.model.optional': '可选',
|
||||
'newSession.reasoningEffort': '推理强度',
|
||||
'newSession.yolo': 'YOLO 模式',
|
||||
'newSession.yolo.title': '跳过审批和沙箱',
|
||||
'newSession.yolo.desc': '启动时使用危险的代理标志。',
|
||||
|
||||
Reference in New Issue
Block a user