Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/pr-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ jobs:

- name: Build frontend
working-directory: apps/codex-plus-manager
run: npm run vite:build
shell: bash
run: |
./node_modules/.bin/vite build
test -d dist

- name: Rust tests
run: cargo test --workspace
Expand Down Expand Up @@ -116,7 +119,10 @@ jobs:

- name: Build frontend
working-directory: apps/codex-plus-manager
run: npm run vite:build
shell: bash
run: |
./node_modules/.bin/vite build
test -d dist

- name: Build release binaries
run: cargo build --release --target ${{ matrix.target }}
Expand Down
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ members = [
]

[workspace.package]
version = "1.2.21"
version = "1.2.23"
edition = "2024"
license = "MIT"
repository = "https://github.com/BigPizzaV3/CodexPlusPlus"
repository = "https://github.com/yinsang0910-star/CodexPlusPlus"

[workspace.dependencies]
aes-gcm = "0.10"
Expand Down
3 changes: 3 additions & 0 deletions apps/codex-plus-launcher/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ async fn activate_existing_codex_app(options: &LaunchOptions) -> anyhow::Result<
hooks.start_helper(options.helper_port).await?;
}
let process_ids = codex_plus_core::watcher::find_codex_processes();
#[cfg(not(windows))]
let activated = false;
#[cfg(windows)]
let mut activated = false;
#[cfg(windows)]
{
Expand Down
54 changes: 40 additions & 14 deletions apps/codex-plus-manager/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ const defaultSettings: BackendSettings = {
codexAppUpstreamWorktreeCreate: true,
codexAppNativeMenuPlacement: true,
codexAppNativeMenuLocalization: true,
codexAppServiceTierControls: false,
codexAppServiceTierControls: true,
codexAppImageOverlayEnabled: false,
codexAppImageOverlayPath: "",
codexAppImageOverlayOpacity: 35,
Expand Down Expand Up @@ -1544,6 +1544,16 @@ export function App() {
targetRelayName: targetBeforeSnapshot.name,
targetRelayMode: targetBeforeSnapshot.relayMode,
});
const switchSettingsWithSnapshot = await snapshotActiveRelayFilesBeforeSwitch(switchSettings, previousActiveRelayId);
if (!switchSettingsWithSnapshot) {
logDiagnostic("switchRelayProfile.snapshot_failed", {
currentRelayId: previousActiveRelayId,
targetRelayId: switchSettings.activeRelayId,
});
return;
}
switchSettings = switchSettingsWithSnapshot;

const selectedBeforeSave = activeRelayProfile(switchSettings);
const validationError = relayProfileSwitchValidation(selectedBeforeSave);
if (validationError) {
Expand All @@ -1555,8 +1565,7 @@ export function App() {
showNotice("供应商配置可能不正确", validationError, "failed");
return;
}
switchSettings = await snapshotActiveRelayFilesBeforeSwitch(switchSettings, previousActiveRelayId);
const selectedAfterSave = activeRelayProfile(switchSettings);
const selectedAfterSave = selectedBeforeSave;
const command = relayProfileSwitchCommand(selectedAfterSave);

logDiagnostic("switchRelayProfile.apply_start", {
Expand Down Expand Up @@ -1618,21 +1627,38 @@ export function App() {
const snapshotActiveRelayFilesBeforeSwitch = async (
next: BackendSettings,
previousActiveRelayId: string,
): Promise<BackendSettings> => {
const profileId = previousActiveRelayId.trim();
if (!profileId) return next;
): Promise<BackendSettings | null> => {
const current = activeRelayProfile({ ...settingsForm, activeRelayId: previousActiveRelayId });
const selected = activeRelayProfile(next);
if (current.id === selected.id) return next;

logDiagnostic("snapshotActiveRelayFilesBeforeSwitch.start", {
currentRelayId: current.id,
currentRelayName: current.name,
selectedRelayId: selected.id,
selectedRelayName: selected.name,
});
const result = await run(() =>
call<SettingsBackfillResult>("backfill_relay_profile_from_live", {
request: { settings: next, profileId },
request: { settings: next, profileId: current.id },
}),
);
if (!result) return next;
const normalized = normalizeSettings(result.settings);
if (!isSuccessStatus(result.status)) {
showNotice("供应商切换", result.message, result.status);
return next;
if (!result || !isSuccessStatus(result.status)) {
logDiagnostic("snapshotActiveRelayFilesBeforeSwitch.failed", {
currentRelayId: current.id,
selectedRelayId: selected.id,
status: result?.status,
message: result?.message,
});
showNotice("供应商切换", result?.message ?? "读取当前配置文件失败,已停止切换以避免覆盖用户改动。", result?.status ?? "failed");
return null;
}
return normalized;

logDiagnostic("snapshotActiveRelayFilesBeforeSwitch.ok", {
currentRelayId: current.id,
selectedRelayId: selected.id,
});
return syncLegacyRelayFields(normalizeSettings(result.settings));
};

const copyText = async (text: string, message: string) => {
Expand Down Expand Up @@ -2733,7 +2759,7 @@ function EnhanceScreen({
<FeatureToggle title="特殊插件强制安装" detail="解除 App unavailable / 应用不可用导致的前端安装禁用。" checked={form.codexAppForcePluginInstall} disabled={!masterEnabled || !patchMode} onChange={(value) => setEnhanceFlag("codexAppForcePluginInstall", value)} />
<FeatureToggle title="插件列表全量展示" detail="进入插件页后自动连续展开“更多”,尽量一次显示完整插件列表。" checked={form.codexAppPluginAutoExpand} disabled={!masterEnabled} onChange={(value) => setEnhanceFlag("codexAppPluginAutoExpand", value)} />
<FeatureToggle title="模型白名单解锁" detail="从环境变量和 config.toml 的 /v1/models 拉取模型并补进模型列表。" checked={form.codexAppModelWhitelistUnlock} disabled={!masterEnabled} onChange={(value) => setEnhanceFlag("codexAppModelWhitelistUnlock", value)} />
<FeatureToggle title="Fast 按钮" detail="显示服务模式切换按钮;Fast 仅支持 gpt-5.4 / gpt-5.5,其他模型按 Standard 发送。" checked={form.codexAppServiceTierControls} disabled={!masterEnabled} onChange={(value) => setEnhanceFlag("codexAppServiceTierControls", value)} />
<FeatureToggle title="系统 Fast 开关" detail="是否开启系统 Fast 开关:已默认开启,API Key 登录复用 Codex 原生速度选项与标识;具体 Fast / Standard 在 Codex 界面选择。" checked={true} disabled onChange={() => {}} />
<FeatureToggle title="会话删除" detail="在会话列表悬停显示删除按钮,并支持撤销。" checked={form.codexAppSessionDelete} disabled={!masterEnabled} onChange={(value) => setEnhanceFlag("codexAppSessionDelete", value)} />
<FeatureToggle title="Markdown 导出" detail="在会话列表显示导出按钮,导出带时间戳的 Markdown。" checked={form.codexAppMarkdownExport} disabled={!masterEnabled} onChange={(value) => setEnhanceFlag("codexAppMarkdownExport", value)} />
<FeatureToggle title="粘贴修复" detail="从 Word 等富文本粘贴到 Codex composer 时只保留纯文本,避免被识别为图片/文件附件。需重启 Codex 才生效。" checked={form.codexAppPasteFix} disabled={!masterEnabled} onChange={(value) => setEnhanceFlag("codexAppPasteFix", value)} />
Expand Down
13 changes: 6 additions & 7 deletions assets/inject/renderer-inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@
}

function defaultCodexPlusSettings() {
return { pluginMarketplaceUnlock: true, forcePluginInstall: true, pluginAutoExpand: true, modelWhitelistUnlock: true, sessionDelete: true, markdownExport: true, pasteFix: false, projectMove: true, threadIdBadge: false, conversationView: false, conversationViewMaxWidth: conversationViewDefaultWidth, threadScrollRestore: true, zedRemoteOpen: true, upstreamWorktreeCreate: true, nativeMenuPlacement: true, serviceTierControls: false };
return { pluginMarketplaceUnlock: true, forcePluginInstall: true, pluginAutoExpand: true, modelWhitelistUnlock: true, sessionDelete: true, markdownExport: true, pasteFix: false, projectMove: true, threadIdBadge: false, conversationView: false, conversationViewMaxWidth: conversationViewDefaultWidth, threadScrollRestore: true, zedRemoteOpen: true, upstreamWorktreeCreate: true, nativeMenuPlacement: true, serviceTierControls: true };
}

const codexPlusBackendSettingMap = {
Expand Down Expand Up @@ -974,13 +974,15 @@
settings.pluginMarketplaceUnlock = false;
settings.forcePluginInstall = false;
}
settings.serviceTierControls = true;
return settings;
} catch {
const settings = { ...defaultCodexPlusSettings(), ...backendCodexPlusSettings() };
if (relayPatchDisabled) {
settings.pluginMarketplaceUnlock = false;
settings.forcePluginInstall = false;
}
settings.serviceTierControls = true;
return settings;
}
}
Expand Down Expand Up @@ -1736,10 +1738,7 @@
function applyCodexServiceTierRequestOverride(method, params, threadIdHint = "") {
const override = codexServiceTierOverrideForRequest(method, params, threadIdHint);
if (!override) return params;
const nextParams = { ...(params || {}), serviceTier: override.serviceTier };
if (Object.prototype.hasOwnProperty.call(nextParams, "service_tier") || override.fastBlocked) {
nextParams.service_tier = override.serviceTier;
}
const nextParams = { ...(params || {}), serviceTier: override.serviceTier, service_tier: override.serviceTier };
sendCodexPlusDiagnostic("service_tier_request_override_applied", {
method,
threadId: override.threadId || "",
Expand Down Expand Up @@ -2163,8 +2162,8 @@
<button type="button" class="codex-plus-toggle" data-codex-plus-setting="modelWhitelistUnlock"><span></span></button>
</div>
<div class="codex-plus-row">
<div><div class="codex-plus-row-title">Fast 按钮</div><div class="codex-plus-row-description">显示服务模式切换按钮;Fast 仅支持 ${codexServiceTierFastModelListLabel()},其他模型按 Standard 发送。</div></div>
<button type="button" class="codex-plus-toggle" data-codex-plus-setting="serviceTierControls"><span></span></button>
<div><div class="codex-plus-row-title">系统 Fast 开关</div><div class="codex-plus-row-description">是否开启系统 Fast 开关:已默认开启,API Key 登录复用 Codex 原生速度选项与标识;具体 Fast / Standard 在 Codex 界面选择,Fast 仅支持 ${codexServiceTierFastModelListLabel()}。</div></div>
<button type="button" class="codex-plus-toggle" data-codex-plus-setting="serviceTierControls" disabled><span></span></button>
</div>
<div class="codex-plus-row" data-codex-service-tier-controls="true">
<div><div class="codex-plus-row-title">服务模式</div><div class="codex-plus-row-description">继承使用 config.toml 的 service tier;全局模式覆盖全部 thread;自定义允许按 thread 覆盖。</div></div>
Expand Down
Loading