feat(vscode): codex 命令统一组装,模型/思考级别可在设置面板配置

新增 cc/codexCommand.ts 作为 codex 调用的唯一出口(buildCodexArgs /
buildCodexCommandString),把 exec-review / resume / interactive 三种形态
的 flag 拼装收敛到一处;模型与思考级别作为自由文本项写入全局设置并贯穿
webview 消息通道,空值则不传 -c,沿用 codex config.toml 默认。
This commit is contained in:
2026-07-13 06:43:58 +08:00
parent aff99c57f3
commit 5188c23765
11 changed files with 225 additions and 12 deletions
+81
View File
@@ -0,0 +1,81 @@
/**
* Single source of truth for assembling `codex` invocations.
*
* The review flow shells codex three different ways — headless
* `codex exec review` (spawned as an arg array), `codex resume <id>` and the
* interactive `codex '<prompt>'` TUI (both sent to a terminal). Building the
* flags in one place keeps `--dangerously-bypass-approvals-and-sandbox` and the
* optional model / reasoning-effort `-c` overrides from drifting apart.
*
* Model and reasoning effort are free-form: an empty value omits the override
* so codex falls back to its own `config.toml` default.
*/
export interface CodexCommandOpts {
/** 'exec-review' = `codex exec review ...`'resume' = `codex resume <id>`'interactive' = `codex '<prompt>'` */
mode: 'exec-review' | 'resume' | 'interactive'
/** resume 模式必填:codex thread id */
sessionId?: string
/** interactive / exec-review 模式的 promptpositional)。调用方保证 interactive 模式下不含单引号。 */
prompt?: string
/** 空 = 不传 `-c model=`,用 codex 默认 */
model?: string
/** 空 = 不传 `-c model_reasoning_effort=`,用 codex 默认。合法值 minimal/low/medium/high/xhigh */
reasoningEffort?: string
/** exec-review 模式:追加 --json */
json?: boolean
}
const BYPASS_FLAG = '--dangerously-bypass-approvals-and-sandbox'
/**
* `-c key=value` overrides for model / reasoning effort. Blank values are
* dropped so codex keeps its config.toml default.
*/
function configOverrides(opts: CodexCommandOpts): string[] {
const parts: string[] = []
const model = opts.model?.trim()
if (model)
parts.push('-c', `model=${model}`)
const effort = opts.reasoningEffort?.trim()
if (effort)
parts.push('-c', `model_reasoning_effort=${effort}`)
return parts
}
/**
* Shared assembly for both output shapes. `quotePrompt` wraps the positional
* prompt in single quotes for the shell-string form; the spawn-array form
* passes it raw (no shell, so no quoting).
*/
function buildParts(opts: CodexCommandOpts, quotePrompt: boolean): string[] {
const overrides = configOverrides(opts)
const prompt = opts.prompt
? (quotePrompt ? `'${opts.prompt}'` : opts.prompt)
: undefined
switch (opts.mode) {
case 'exec-review':
return [
'exec',
'review',
...overrides,
BYPASS_FLAG,
...(opts.json ? ['--json'] : []),
...(prompt !== undefined ? [prompt] : []),
]
case 'resume':
return ['resume', ...overrides, BYPASS_FLAG, ...(opts.sessionId ? [opts.sessionId] : [])]
case 'interactive':
return [...overrides, BYPASS_FLAG, ...(prompt !== undefined ? [prompt] : [])]
}
}
/** Argument array (without the leading `codex`) for `spawn('codex', args)`. */
export function buildCodexArgs(opts: CodexCommandOpts): string[] {
return buildParts(opts, false)
}
/** Full shell command string (with `codex` prefix) for `terminal.sendText`. */
export function buildCodexCommandString(opts: CodexCommandOpts): string {
return ['codex', ...buildParts(opts, true)].join(' ')
}
+12 -9
View File
@@ -11,11 +11,16 @@
import { spawn } from 'node:child_process' import { spawn } from 'node:child_process'
import { logger } from '../logging/logger' import { logger } from '../logging/logger'
import { buildCodexArgs } from './codexCommand'
export interface RunReviewOpts { export interface RunReviewOpts {
workspaceRoot: string workspaceRoot: string
/** Already-substituted prompt — placeholders must be resolved by the caller. */ /** Already-substituted prompt — placeholders must be resolved by the caller. */
prompt: string prompt: string
/** 空 = 不传 `-c model=`,用 codex config.toml 默认。 */
model?: string
/** 空 = 不传 `-c model_reasoning_effort=`,用 codex 默认。 */
reasoningEffort?: string
/** Spawn timeout in milliseconds. Defaults to 5 minutes. */ /** Spawn timeout in milliseconds. Defaults to 5 minutes. */
timeoutMs?: number timeoutMs?: number
/** /**
@@ -34,15 +39,13 @@ const DEFAULT_TIMEOUT_MS = 300_000
*/ */
export async function runReview(opts: RunReviewOpts): Promise<void> { export async function runReview(opts: RunReviewOpts): Promise<void> {
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS
const args: string[] = [ const args = buildCodexArgs({
'exec', mode: 'exec-review',
'-c', prompt: opts.prompt,
'model_reasoning_effort=xhigh', model: opts.model,
'review', reasoningEffort: opts.reasoningEffort,
'--dangerously-bypass-approvals-and-sandbox', json: true,
'--json', })
opts.prompt,
]
await new Promise<void>((resolve) => { await new Promise<void>((resolve) => {
let child: ReturnType<typeof spawn> let child: ReturnType<typeof spawn>
+4
View File
@@ -855,6 +855,8 @@ export class KanbanWebviewPanel {
implTabPreCreateScript: s.implTabPreCreateScript, implTabPreCreateScript: s.implTabPreCreateScript,
implTabPostCloseScript: s.implTabPostCloseScript, implTabPostCloseScript: s.implTabPostCloseScript,
conflictResolutionProfilePath: s.conflictResolutionProfilePath, conflictResolutionProfilePath: s.conflictResolutionProfilePath,
codexModel: s.codexModel,
codexReasoningEffort: s.codexReasoningEffort,
}) })
return return
} }
@@ -918,6 +920,8 @@ export class KanbanWebviewPanel {
implTabPreCreateScript: s.implTabPreCreateScript, implTabPreCreateScript: s.implTabPreCreateScript,
implTabPostCloseScript: s.implTabPostCloseScript, implTabPostCloseScript: s.implTabPostCloseScript,
conflictResolutionProfilePath: s.conflictResolutionProfilePath, conflictResolutionProfilePath: s.conflictResolutionProfilePath,
codexModel: s.codexModel,
codexReasoningEffort: s.codexReasoningEffort,
}) })
return return
} }
+22 -3
View File
@@ -9,6 +9,7 @@ import * as path from 'node:path'
import { window, workspace } from 'vscode' import { window, workspace } from 'vscode'
import { getToken } from '../../auth/secrets' import { getToken } from '../../auth/secrets'
import { buildCcCommand } from '../../cc/ccCommand' import { buildCcCommand } from '../../cc/ccCommand'
import { buildCodexCommandString } from '../../cc/codexCommand'
import { watchForNewCodexSession } from '../../cc/codexSessionWatcher' import { watchForNewCodexSession } from '../../cc/codexSessionWatcher'
import { getBrainstormContinuePrompt, getImplementPlanPrompt } from '../../cc/prompts' import { getBrainstormContinuePrompt, getImplementPlanPrompt } from '../../cc/prompts'
import { projectsDirFor, watchForNewSession } from '../../cc/sessionWatcher' import { projectsDirFor, watchForNewSession } from '../../cc/sessionWatcher'
@@ -287,7 +288,13 @@ export async function handleResumeReviewSession(panel: KanbanWebviewPanel, sessi
panel.reviewTerminals.set(sessionId, terminal) panel.reviewTerminals.set(sessionId, terminal)
panel.trackSessionTerminal(terminal, issueNumber, 'review') panel.trackSessionTerminal(terminal, issueNumber, 'review')
terminal.show(false) terminal.show(false)
terminal.sendText(`codex resume -c model_reasoning_effort=xhigh --dangerously-bypass-approvals-and-sandbox ${sessionId}`) const settings = getSettings(panel.context)
terminal.sendText(buildCodexCommandString({
mode: 'resume',
sessionId,
model: settings.codexModel,
reasoningEffort: settings.codexReasoningEffort,
}))
logger.add({ logger.add({
level: 'info', level: 'info',
source: 'terminal', source: 'terminal',
@@ -418,7 +425,13 @@ export async function triggerAutoReviewTab(panel: KanbanWebviewPanel, opts: {
panel.reviewTerminals.set(existingSessionId, terminal) panel.reviewTerminals.set(existingSessionId, terminal)
panel.trackSessionTerminal(terminal, opts.issueNumber, 'review') panel.trackSessionTerminal(terminal, opts.issueNumber, 'review')
terminal.show(false) terminal.show(false)
terminal.sendText(`codex resume -c model_reasoning_effort=xhigh --dangerously-bypass-approvals-and-sandbox ${existingSessionId}`) const settings = getSettings(panel.context)
terminal.sendText(buildCodexCommandString({
mode: 'resume',
sessionId: existingSessionId,
model: settings.codexModel,
reasoningEffort: settings.codexReasoningEffort,
}))
// codex resume rebuilds the conversation from the jsonl rollout // codex resume rebuilds the conversation from the jsonl rollout
// before the TUI accepts input — empirically much slower than the // before the TUI accepts input — empirically much slower than the
// 250ms gap the reuse path uses. 8s is a conservative guess that // 250ms gap the reuse path uses. 8s is a conservative guess that
@@ -494,7 +507,13 @@ export async function triggerAutoReviewTab(panel: KanbanWebviewPanel, opts: {
// the terminal alive after the run so users can follow up with codex, // the terminal alive after the run so users can follow up with codex,
// mirroring how claude implementation/brainstorm sessions stay open. // mirroring how claude implementation/brainstorm sessions stay open.
// 提示词模板自带 /review 前缀,不在这里再拼。 // 提示词模板自带 /review 前缀,不在这里再拼。
const cmd = `codex -c model_reasoning_effort=xhigh --dangerously-bypass-approvals-and-sandbox '${opts.prompt}'` const settings = getSettings(panel.context)
const cmd = buildCodexCommandString({
mode: 'interactive',
prompt: opts.prompt,
model: settings.codexModel,
reasoningEffort: settings.codexReasoningEffort,
})
terminal.sendText(cmd) terminal.sendText(cmd)
logger.add({ logger.add({
level: 'info', level: 'info',
+11
View File
@@ -33,6 +33,8 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
implTabPreCreateScript: string implTabPreCreateScript: string
implTabPostCloseScript: string implTabPostCloseScript: string
conflictResolutionProfilePath: string conflictResolutionProfilePath: string
codexModel: string
codexReasoningEffort: string
youtrackBaseUrl: string youtrackBaseUrl: string
youtrackProjectShortName: string youtrackProjectShortName: string
youtrackCloseCommand: string youtrackCloseCommand: string
@@ -61,6 +63,9 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
const trimmedImplPost = payload.implTabPostCloseScript.trim() const trimmedImplPost = payload.implTabPostCloseScript.trim()
// conflict-resolution profile: '' is meaningful (= DEFAULT_PROFILE_PATH). // conflict-resolution profile: '' is meaningful (= DEFAULT_PROFILE_PATH).
const trimmedConflictProfile = payload.conflictResolutionProfilePath.trim() const trimmedConflictProfile = payload.conflictResolutionProfilePath.trim()
// codex 模型 / 思考级别:空串有意义(= 用 codex 默认),只 trim。
const trimmedCodexModel = payload.codexModel.trim()
const trimmedCodexReasoningEffort = payload.codexReasoningEffort.trim()
const prev = getSettings(panel.context) const prev = getSettings(panel.context)
// Capture the previous token *for this host* before overwriting it, so // Capture the previous token *for this host* before overwriting it, so
// we can decide below whether the kanban needs a re-fetch. (Only host // we can decide below whether the kanban needs a re-fetch. (Only host
@@ -91,6 +96,8 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
implTabPreCreateScript: trimmedImplPre, implTabPreCreateScript: trimmedImplPre,
implTabPostCloseScript: trimmedImplPost, implTabPostCloseScript: trimmedImplPost,
conflictResolutionProfilePath: trimmedConflictProfile, conflictResolutionProfilePath: trimmedConflictProfile,
codexModel: trimmedCodexModel,
codexReasoningEffort: trimmedCodexReasoningEffort,
}) })
return return
} }
@@ -113,6 +120,8 @@ export async function handleSettingsSave(panel: KanbanWebviewPanel, payload: {
implTabPreCreateScript: trimmedImplPre, implTabPreCreateScript: trimmedImplPre,
implTabPostCloseScript: trimmedImplPost, implTabPostCloseScript: trimmedImplPost,
conflictResolutionProfilePath: trimmedConflictProfile, conflictResolutionProfilePath: trimmedConflictProfile,
codexModel: trimmedCodexModel,
codexReasoningEffort: trimmedCodexReasoningEffort,
youtrackBaseUrl: trimmedYtBase, youtrackBaseUrl: trimmedYtBase,
youtrackProjectShortName: trimmedYtProject, youtrackProjectShortName: trimmedYtProject,
youtrackCloseCommand: trimmedYtClose, youtrackCloseCommand: trimmedYtClose,
@@ -196,6 +205,8 @@ export async function handleEditSettingsRequest(panel: KanbanWebviewPanel): Prom
implTabPreCreateScript: s.implTabPreCreateScript, implTabPreCreateScript: s.implTabPreCreateScript,
implTabPostCloseScript: s.implTabPostCloseScript, implTabPostCloseScript: s.implTabPostCloseScript,
conflictResolutionProfilePath: s.conflictResolutionProfilePath, conflictResolutionProfilePath: s.conflictResolutionProfilePath,
codexModel: s.codexModel,
codexReasoningEffort: s.codexReasoningEffort,
youtrackBaseUrl: s.youtrackBaseUrl, youtrackBaseUrl: s.youtrackBaseUrl,
youtrackProjectShortName: s.youtrackProjectShortName, youtrackProjectShortName: s.youtrackProjectShortName,
youtrackCloseCommand: s.youtrackCloseCommand, youtrackCloseCommand: s.youtrackCloseCommand,
+4
View File
@@ -67,6 +67,8 @@ export type ExtensionToWebview
implTabPreCreateScript: string implTabPreCreateScript: string
implTabPostCloseScript: string implTabPostCloseScript: string
conflictResolutionProfilePath: string conflictResolutionProfilePath: string
codexModel: string
codexReasoningEffort: string
youtrackBaseUrl?: string youtrackBaseUrl?: string
youtrackProjectShortName?: string youtrackProjectShortName?: string
youtrackCloseCommand?: string youtrackCloseCommand?: string
@@ -129,6 +131,8 @@ export type WebviewToExtension
implTabPreCreateScript: string implTabPreCreateScript: string
implTabPostCloseScript: string implTabPostCloseScript: string
conflictResolutionProfilePath: string conflictResolutionProfilePath: string
codexModel: string
codexReasoningEffort: string
youtrackBaseUrl: string youtrackBaseUrl: string
youtrackProjectShortName: string youtrackProjectShortName: string
youtrackCloseCommand: string youtrackCloseCommand: string
+21
View File
@@ -169,6 +169,16 @@ export interface Settings {
* (drag to 完成 when PR merge conflicts). Empty = DEFAULT_PROFILE_PATH. * (drag to 完成 when PR merge conflicts). Empty = DEFAULT_PROFILE_PATH.
*/ */
conflictResolutionProfilePath: string conflictResolutionProfilePath: string
/**
* codex 审查会话使用的模型(`-c model=`)。空串 = 不传,用 codex
* `config.toml` 默认。
*/
codexModel: string
/**
* codex 审查会话的思考级别(`-c model_reasoning_effort=`)。空串 = 不传,
* 用 codex 默认。合法值 minimal/low/medium/high/xhigh。
*/
codexReasoningEffort: string
} }
export const SETTINGS_KEY = 'superpowers.settings' export const SETTINGS_KEY = 'superpowers.settings'
@@ -194,6 +204,8 @@ function defaults(ctx: ExtensionContext): Settings {
youtrackProjectShortName: '', youtrackProjectShortName: '',
youtrackCloseCommand: '', youtrackCloseCommand: '',
conflictResolutionProfilePath: '', conflictResolutionProfilePath: '',
codexModel: '',
codexReasoningEffort: '',
} }
} }
@@ -278,6 +290,13 @@ export function getSettings(ctx: ExtensionContext): Settings {
const conflictResolutionProfilePath = typeof stored.conflictResolutionProfilePath === 'string' const conflictResolutionProfilePath = typeof stored.conflictResolutionProfilePath === 'string'
? stored.conflictResolutionProfilePath ? stored.conflictResolutionProfilePath
: base.conflictResolutionProfilePath : base.conflictResolutionProfilePath
// codex 模型 / 思考级别:'' 有意义(= 用 codex 默认),不强制回退。
const codexModel = typeof stored.codexModel === 'string'
? stored.codexModel
: base.codexModel
const codexReasoningEffort = typeof stored.codexReasoningEffort === 'string'
? stored.codexReasoningEffort
: base.codexReasoningEffort
return { return {
webhookPort, webhookPort,
@@ -299,6 +318,8 @@ export function getSettings(ctx: ExtensionContext): Settings {
youtrackProjectShortName, youtrackProjectShortName,
youtrackCloseCommand, youtrackCloseCommand,
conflictResolutionProfilePath, conflictResolutionProfilePath,
codexModel,
codexReasoningEffort,
} }
} }
+2
View File
@@ -453,6 +453,8 @@ export function App() {
initialImplTabPreCreateScript={settings?.implTabPreCreateScript ?? ''} initialImplTabPreCreateScript={settings?.implTabPreCreateScript ?? ''}
initialImplTabPostCloseScript={settings?.implTabPostCloseScript ?? ''} initialImplTabPostCloseScript={settings?.implTabPostCloseScript ?? ''}
initialConflictResolutionProfilePath={settings?.conflictResolutionProfilePath ?? ''} initialConflictResolutionProfilePath={settings?.conflictResolutionProfilePath ?? ''}
initialCodexModel={settings?.codexModel ?? ''}
initialCodexReasoningEffort={settings?.codexReasoningEffort ?? ''}
initialYoutrackBaseUrl={settings?.youtrackBaseUrl ?? ''} initialYoutrackBaseUrl={settings?.youtrackBaseUrl ?? ''}
initialYoutrackProjectShortName={settings?.youtrackProjectShortName ?? ''} initialYoutrackProjectShortName={settings?.youtrackProjectShortName ?? ''}
initialYoutrackCloseCommand={settings?.youtrackCloseCommand ?? ''} initialYoutrackCloseCommand={settings?.youtrackCloseCommand ?? ''}
@@ -32,6 +32,8 @@ interface SubmitValues {
implTabPreCreateScript: string implTabPreCreateScript: string
implTabPostCloseScript: string implTabPostCloseScript: string
conflictResolutionProfilePath: string conflictResolutionProfilePath: string
codexModel: string
codexReasoningEffort: string
youtrackBaseUrl: string youtrackBaseUrl: string
youtrackProjectShortName: string youtrackProjectShortName: string
youtrackCloseCommand: string youtrackCloseCommand: string
@@ -72,6 +74,8 @@ export interface SettingsModalProps {
initialImplTabPreCreateScript: string initialImplTabPreCreateScript: string
initialImplTabPostCloseScript: string initialImplTabPostCloseScript: string
initialConflictResolutionProfilePath: string initialConflictResolutionProfilePath: string
initialCodexModel: string
initialCodexReasoningEffort: string
initialYoutrackBaseUrl: string initialYoutrackBaseUrl: string
initialYoutrackProjectShortName: string initialYoutrackProjectShortName: string
initialYoutrackCloseCommand: string initialYoutrackCloseCommand: string
@@ -146,6 +150,8 @@ export function SettingsModal({
initialImplTabPreCreateScript, initialImplTabPreCreateScript,
initialImplTabPostCloseScript, initialImplTabPostCloseScript,
initialConflictResolutionProfilePath, initialConflictResolutionProfilePath,
initialCodexModel,
initialCodexReasoningEffort,
initialYoutrackBaseUrl, initialYoutrackBaseUrl,
initialYoutrackProjectShortName, initialYoutrackProjectShortName,
initialYoutrackCloseCommand, initialYoutrackCloseCommand,
@@ -174,6 +180,8 @@ export function SettingsModal({
const [implTabPreCreateScript, setImplTabPreCreateScript] = useState(initialImplTabPreCreateScript) const [implTabPreCreateScript, setImplTabPreCreateScript] = useState(initialImplTabPreCreateScript)
const [implTabPostCloseScript, setImplTabPostCloseScript] = useState(initialImplTabPostCloseScript) const [implTabPostCloseScript, setImplTabPostCloseScript] = useState(initialImplTabPostCloseScript)
const [conflictResolutionProfilePath, setConflictResolutionProfilePath] = useState(initialConflictResolutionProfilePath) const [conflictResolutionProfilePath, setConflictResolutionProfilePath] = useState(initialConflictResolutionProfilePath)
const [codexModel, setCodexModel] = useState(initialCodexModel)
const [codexReasoningEffort, setCodexReasoningEffort] = useState(initialCodexReasoningEffort)
const [youtrackBaseUrl, setYoutrackBaseUrl] = useState(initialYoutrackBaseUrl) const [youtrackBaseUrl, setYoutrackBaseUrl] = useState(initialYoutrackBaseUrl)
const [youtrackProjectShortName, setYoutrackProjectShortName] = useState(initialYoutrackProjectShortName) const [youtrackProjectShortName, setYoutrackProjectShortName] = useState(initialYoutrackProjectShortName)
const [youtrackCloseCommand, setYoutrackCloseCommand] = useState(initialYoutrackCloseCommand) const [youtrackCloseCommand, setYoutrackCloseCommand] = useState(initialYoutrackCloseCommand)
@@ -204,6 +212,8 @@ export function SettingsModal({
setImplTabPreCreateScript(initialImplTabPreCreateScript) setImplTabPreCreateScript(initialImplTabPreCreateScript)
setImplTabPostCloseScript(initialImplTabPostCloseScript) setImplTabPostCloseScript(initialImplTabPostCloseScript)
setConflictResolutionProfilePath(initialConflictResolutionProfilePath) setConflictResolutionProfilePath(initialConflictResolutionProfilePath)
setCodexModel(initialCodexModel)
setCodexReasoningEffort(initialCodexReasoningEffort)
setYoutrackBaseUrl(initialYoutrackBaseUrl) setYoutrackBaseUrl(initialYoutrackBaseUrl)
setYoutrackProjectShortName(initialYoutrackProjectShortName) setYoutrackProjectShortName(initialYoutrackProjectShortName)
setYoutrackCloseCommand(initialYoutrackCloseCommand) setYoutrackCloseCommand(initialYoutrackCloseCommand)
@@ -287,6 +297,9 @@ export function SettingsModal({
implTabPostCloseScript: implTabPostCloseScript.trim(), implTabPostCloseScript: implTabPostCloseScript.trim(),
// 冲突解决 profile:空串 = 用 DEFAULT_PROFILE_PATH // 冲突解决 profile:空串 = 用 DEFAULT_PROFILE_PATH
conflictResolutionProfilePath: conflictResolutionProfilePath.trim(), conflictResolutionProfilePath: conflictResolutionProfilePath.trim(),
// codex 模型 / 思考级别:trim 后留空 = 用 codex config.toml 默认
codexModel: codexModel.trim(),
codexReasoningEffort: codexReasoningEffort.trim(),
youtrackBaseUrl: youtrackBaseUrl.trim(), youtrackBaseUrl: youtrackBaseUrl.trim(),
youtrackProjectShortName: youtrackProjectShortName.trim(), youtrackProjectShortName: youtrackProjectShortName.trim(),
youtrackCloseCommand: youtrackCloseCommand.trim(), youtrackCloseCommand: youtrackCloseCommand.trim(),
@@ -463,6 +476,49 @@ export function SettingsModal({
)} )}
</select> </select>
</Field> </Field>
<Field
label="codex 模型"
hint={(
<>
使 codex
<code>-c model=</code>
codex
{' '}
<code>config.toml</code>
{' '}
</>
)}
>
<input
type="text"
value={codexModel}
onChange={e => setCodexModel(e.target.value)}
placeholder="留空用 codex 默认(如 gpt-5.6-sol"
className={inputClass}
/>
</Field>
<Field
label="codex 思考级别"
hint={(
<>
{' '}
<code>model_reasoning_effort</code>
codex
</>
)}
>
<input
type="text"
value={codexReasoningEffort}
onChange={e => setCodexReasoningEffort(e.target.value)}
placeholder="留空用 codex 默认(minimal/low/medium/high/xhigh"
className={inputClass}
/>
</Field>
</> </>
)} )}
+8
View File
@@ -41,6 +41,8 @@ export interface SettingsValues {
implTabPreCreateScript: string implTabPreCreateScript: string
implTabPostCloseScript: string implTabPostCloseScript: string
conflictResolutionProfilePath: string conflictResolutionProfilePath: string
codexModel: string
codexReasoningEffort: string
youtrackBaseUrl: string youtrackBaseUrl: string
youtrackProjectShortName: string youtrackProjectShortName: string
youtrackCloseCommand: string youtrackCloseCommand: string
@@ -67,6 +69,8 @@ export interface SettingsOverlayState {
implTabPreCreateScript: string implTabPreCreateScript: string
implTabPostCloseScript: string implTabPostCloseScript: string
conflictResolutionProfilePath: string conflictResolutionProfilePath: string
codexModel: string
codexReasoningEffort: string
youtrackBaseUrl: string youtrackBaseUrl: string
youtrackProjectShortName: string youtrackProjectShortName: string
youtrackCloseCommand: string youtrackCloseCommand: string
@@ -281,6 +285,8 @@ export function useIssues(): UseIssuesResult {
implTabPreCreateScript: values.implTabPreCreateScript, implTabPreCreateScript: values.implTabPreCreateScript,
implTabPostCloseScript: values.implTabPostCloseScript, implTabPostCloseScript: values.implTabPostCloseScript,
conflictResolutionProfilePath: values.conflictResolutionProfilePath, conflictResolutionProfilePath: values.conflictResolutionProfilePath,
codexModel: values.codexModel,
codexReasoningEffort: values.codexReasoningEffort,
youtrackBaseUrl: values.youtrackBaseUrl, youtrackBaseUrl: values.youtrackBaseUrl,
youtrackProjectShortName: values.youtrackProjectShortName, youtrackProjectShortName: values.youtrackProjectShortName,
youtrackCloseCommand: values.youtrackCloseCommand, youtrackCloseCommand: values.youtrackCloseCommand,
@@ -610,6 +616,8 @@ export function useIssues(): UseIssuesResult {
implTabPreCreateScript: msg.implTabPreCreateScript, implTabPreCreateScript: msg.implTabPreCreateScript,
implTabPostCloseScript: msg.implTabPostCloseScript, implTabPostCloseScript: msg.implTabPostCloseScript,
conflictResolutionProfilePath: msg.conflictResolutionProfilePath, conflictResolutionProfilePath: msg.conflictResolutionProfilePath,
codexModel: msg.codexModel,
codexReasoningEffort: msg.codexReasoningEffort,
youtrackBaseUrl: msg.youtrackBaseUrl ?? '', youtrackBaseUrl: msg.youtrackBaseUrl ?? '',
youtrackProjectShortName: msg.youtrackProjectShortName ?? '', youtrackProjectShortName: msg.youtrackProjectShortName ?? '',
youtrackCloseCommand: msg.youtrackCloseCommand ?? '', youtrackCloseCommand: msg.youtrackCloseCommand ?? '',
+4
View File
@@ -82,6 +82,8 @@ export type ExtensionToWebview
implTabPreCreateScript: string implTabPreCreateScript: string
implTabPostCloseScript: string implTabPostCloseScript: string
conflictResolutionProfilePath: string conflictResolutionProfilePath: string
codexModel: string
codexReasoningEffort: string
youtrackBaseUrl?: string youtrackBaseUrl?: string
youtrackProjectShortName?: string youtrackProjectShortName?: string
youtrackCloseCommand?: string youtrackCloseCommand?: string
@@ -144,6 +146,8 @@ export type WebviewToExtension
implTabPreCreateScript: string implTabPreCreateScript: string
implTabPostCloseScript: string implTabPostCloseScript: string
conflictResolutionProfilePath: string conflictResolutionProfilePath: string
codexModel: string
codexReasoningEffort: string
youtrackBaseUrl: string youtrackBaseUrl: string
youtrackProjectShortName: string youtrackProjectShortName: string
youtrackCloseCommand: string youtrackCloseCommand: string