mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
fix(codex): disable plugins in short-lived probes (#21617)
This commit is contained in:
@@ -1,10 +1,19 @@
|
||||
// The config override replaces legacy values before Codex validates config.toml.
|
||||
export const CODEX_DISABLE_PLUGINS_ARGS = ['-c', 'features.plugins=false'] as const
|
||||
const CODEX_READ_ONLY_APP_SERVER_TAIL = ['-s', 'read-only', '-a', 'never', 'app-server'] as const
|
||||
|
||||
export const CODEX_READ_ONLY_APP_SERVER_ARGS = [
|
||||
'-c',
|
||||
'approval_policy=never',
|
||||
'-s',
|
||||
'read-only',
|
||||
'-a',
|
||||
'never',
|
||||
'app-server'
|
||||
...CODEX_READ_ONLY_APP_SERVER_TAIL
|
||||
] as const
|
||||
|
||||
// Rate-limit probes are short-lived; plugin startup can launch marketplace
|
||||
// clones that outlive the probe teardown. Other read-only app-servers retain
|
||||
// normal plugin behavior.
|
||||
export const CODEX_RATE_LIMIT_APP_SERVER_ARGS = [
|
||||
'-c',
|
||||
'approval_policy=never',
|
||||
...CODEX_DISABLE_PLUGINS_ARGS,
|
||||
...CODEX_READ_ONLY_APP_SERVER_TAIL
|
||||
] as const
|
||||
|
||||
@@ -41,6 +41,8 @@ const STUB_CODEX_SOURCE = `
|
||||
const expectedArgs = [
|
||||
'-c',
|
||||
'approval_policy=never',
|
||||
'-c',
|
||||
'features.plugins=false',
|
||||
'-s',
|
||||
'read-only',
|
||||
'-a',
|
||||
|
||||
@@ -52,7 +52,7 @@ import { fetchCodexRateLimits } from './codex-fetcher'
|
||||
import { probeCodexAuthPresence } from './codex-auth-presence'
|
||||
import { getActiveHiddenRateLimitPtyCount } from './hidden-pty-cleanup'
|
||||
import { getCmdExePath } from '../win32-utils'
|
||||
import { CODEX_READ_ONLY_APP_SERVER_ARGS } from '../codex-cli/codex-read-only-app-server-args'
|
||||
import { CODEX_RATE_LIMIT_APP_SERVER_ARGS } from '../codex-cli/codex-read-only-app-server-args'
|
||||
|
||||
function makeDisposable() {
|
||||
return { dispose: vi.fn() }
|
||||
@@ -724,7 +724,7 @@ describe('fetchCodexRateLimits', () => {
|
||||
"export CODEX_HOME='\\''/home/alice/.local/share/orca/account/home'\\''"
|
||||
)
|
||||
expect(shellCommand).toContain(
|
||||
"exec codex '\\''-c'\\'' '\\''approval_policy=never'\\'' '\\''-s'\\'' '\\''read-only'\\'' '\\''-a'\\'' '\\''never'\\'' '\\''app-server'\\'' <&3 >&4 3<&- 4>&-"
|
||||
"exec codex '\\''-c'\\'' '\\''approval_policy=never'\\'' '\\''-c'\\'' '\\''features.plugins=false'\\'' '\\''-s'\\'' '\\''read-only'\\'' '\\''-a'\\'' '\\''never'\\'' '\\''app-server'\\'' <&3 >&4 3<&- 4>&-"
|
||||
)
|
||||
expect(shellCommand.match(/<&3 >&4 3<&- 4>&-/g)).toHaveLength(3)
|
||||
expect(shellCommand.match(/exec codex [^\n]+<&3 >&4 3<&- 4>&-/g)).toHaveLength(3)
|
||||
@@ -788,7 +788,7 @@ describe('fetchCodexRateLimits', () => {
|
||||
|
||||
const [spawnFile, spawnArgs, spawnOptions] = childSpawnMock.mock.calls[0]
|
||||
expect(spawnFile).toBe(getCmdExePath())
|
||||
expect(spawnArgs).toEqual(['/d', '/c', codexCommand, ...CODEX_READ_ONLY_APP_SERVER_ARGS])
|
||||
expect(spawnArgs).toEqual(['/d', '/c', codexCommand, ...CODEX_RATE_LIMIT_APP_SERVER_ARGS])
|
||||
expect(spawnOptions).toEqual(
|
||||
expect.objectContaining({
|
||||
env: expect.objectContaining({ CODEX_HOME: 'C:\\Users\\alice\\.codex' })
|
||||
@@ -848,6 +848,7 @@ describe('fetchCodexRateLimits', () => {
|
||||
"export CODEX_HOME='\\''/home/alice/.local/share/orca/account/home'\\''"
|
||||
)
|
||||
expect(shellCommand).toContain('exec codex ')
|
||||
expect(shellCommand).toContain('features.plugins=false')
|
||||
expect(shellCommand).not.toContain('_orca_codex')
|
||||
expect(shellCommand).not.toContain('wsl-codex-path')
|
||||
expect(spawnOptions).toEqual(
|
||||
|
||||
@@ -3,7 +3,10 @@ import { spawn } from 'node:child_process'
|
||||
import { isCodexAuthError } from '../../shared/codex-auth-errors'
|
||||
import { buildWslExecArgs, buildWslLoginShellCommand } from '../../shared/wsl-login-shell-command'
|
||||
import { parseWslUncPath } from '../../shared/wsl-paths'
|
||||
import { CODEX_READ_ONLY_APP_SERVER_ARGS } from '../codex-cli/codex-read-only-app-server-args'
|
||||
import {
|
||||
CODEX_DISABLE_PLUGINS_ARGS,
|
||||
CODEX_RATE_LIMIT_APP_SERVER_ARGS
|
||||
} from '../codex-cli/codex-read-only-app-server-args'
|
||||
import { resolveCodexCommand } from '../codex-cli/command'
|
||||
// Why: import from the shared module, not the codex-cli re-export, so a test that
|
||||
// mocks '../codex-cli/command' does not have to restate this pure helper.
|
||||
@@ -44,6 +47,11 @@ const WSL_RPC_TIMEOUT_MS = 25_000
|
||||
const RPC_INIT_TIMEOUT_MS = 30_000
|
||||
const WSL_RPC_INIT_TIMEOUT_MS = 40_000
|
||||
|
||||
// Keep the PTY fallback aligned with the RPC probe: rate-limit collection does
|
||||
// not need marketplace/plugin startup, and those background clones can outlive
|
||||
// the short-lived probe process.
|
||||
const CODEX_RATE_LIMIT_PLUGIN_ARGS = CODEX_DISABLE_PLUGINS_ARGS
|
||||
|
||||
export type FetchCodexRateLimitsOptions = CodexRateLimitFetchOptions
|
||||
|
||||
function buildWslCodexCommand(
|
||||
@@ -96,7 +104,7 @@ async function fetchViaRpc(options?: CodexRateLimitFetchOptions): Promise<Provid
|
||||
if (options?.signal?.aborted) {
|
||||
return abortedCodexRateLimitResult()
|
||||
}
|
||||
const codexArgs = [...CODEX_READ_ONLY_APP_SERVER_ARGS]
|
||||
const codexArgs = [...CODEX_RATE_LIMIT_APP_SERVER_ARGS]
|
||||
const wslCodex = options?.codexHomePath
|
||||
? buildWslCodexCommand(options.codexHomePath, codexArgs, true)
|
||||
: null
|
||||
@@ -126,13 +134,17 @@ async function fetchViaRpc(options?: CodexRateLimitFetchOptions): Promise<Provid
|
||||
|
||||
function resolvePtyCommand(options?: CodexRateLimitFetchOptions) {
|
||||
const wslCodex = options?.codexHomePath
|
||||
? buildWslCodexCommand(options.codexHomePath, [], false)
|
||||
? buildWslCodexCommand(options.codexHomePath, [...CODEX_RATE_LIMIT_PLUGIN_ARGS], false)
|
||||
: null
|
||||
const codexCommand = wslCodex ? 'codex' : resolveCodexCommand()
|
||||
const isWin32 = process.platform === 'win32'
|
||||
return {
|
||||
command: wslCodex ? wslCodex.command : isWin32 ? getCmdExePath() : codexCommand,
|
||||
args: wslCodex ? wslCodex.args : isWin32 ? ['/d', '/c', codexCommand] : [],
|
||||
args: wslCodex
|
||||
? wslCodex.args
|
||||
: isWin32
|
||||
? ['/d', '/c', codexCommand, ...CODEX_RATE_LIMIT_PLUGIN_ARGS]
|
||||
: [...CODEX_RATE_LIMIT_PLUGIN_ARGS],
|
||||
cwd: resolveHiddenRateLimitPtyCwd(),
|
||||
env: withCliRuntimeOnPath(codexCommand, {
|
||||
...(wslCodex ? processEnvWithoutCodexHome() : process.env),
|
||||
|
||||
Reference in New Issue
Block a user