@@ -361,6 +361,70 @@ describe("live model switch", () => {
|
361 | 361 | expect(state.piEmbeddedModuleImported).toBe(false); |
362 | 362 | }); |
363 | 363 | |
| 364 | +it("treats active openai-codex as an already-applied openai runtime promotion", async () => { |
| 365 | +const { hasDifferentLiveSessionModelSelection } = await loadModule(); |
| 366 | + |
| 367 | +expect( |
| 368 | +hasDifferentLiveSessionModelSelection( |
| 369 | +{ |
| 370 | +provider: "openai-codex", |
| 371 | +model: "gpt-5.5", |
| 372 | +}, |
| 373 | +{ |
| 374 | +provider: "openai", |
| 375 | +model: "gpt-5.5", |
| 376 | +}, |
| 377 | +), |
| 378 | +).toBe(false); |
| 379 | +}); |
| 380 | + |
| 381 | +it("does not suppress explicit runtime provider switches with the same model", async () => { |
| 382 | +const { hasDifferentLiveSessionModelSelection } = await loadModule(); |
| 383 | + |
| 384 | +expect( |
| 385 | +hasDifferentLiveSessionModelSelection( |
| 386 | +{ |
| 387 | +provider: "openai", |
| 388 | +model: "gpt-5.5", |
| 389 | +}, |
| 390 | +{ |
| 391 | +provider: "openai-codex", |
| 392 | +model: "gpt-5.5", |
| 393 | +}, |
| 394 | +), |
| 395 | +).toBe(true); |
| 396 | + |
| 397 | +expect( |
| 398 | +hasDifferentLiveSessionModelSelection( |
| 399 | +{ |
| 400 | +provider: "anthropic", |
| 401 | +model: "claude-sonnet-4-6", |
| 402 | +}, |
| 403 | +{ |
| 404 | +provider: "claude-cli", |
| 405 | +model: "claude-sonnet-4-6", |
| 406 | +}, |
| 407 | +), |
| 408 | +).toBe(true); |
| 409 | +}); |
| 410 | + |
| 411 | +it("does not suppress switch when model actually differs across runtime alias", async () => { |
| 412 | +const { hasDifferentLiveSessionModelSelection } = await loadModule(); |
| 413 | + |
| 414 | +expect( |
| 415 | +hasDifferentLiveSessionModelSelection( |
| 416 | +{ |
| 417 | +provider: "openai-codex", |
| 418 | +model: "gpt-5.5", |
| 419 | +}, |
| 420 | +{ |
| 421 | +provider: "openai", |
| 422 | +model: "gpt-5.4", |
| 423 | +}, |
| 424 | +), |
| 425 | +).toBe(true); |
| 426 | +}); |
| 427 | + |
364 | 428 | it("treats auth-profile-source changes as no-op when no auth profile is selected", async () => { |
365 | 429 | const { hasDifferentLiveSessionModelSelection } = await loadModule(); |
366 | 430 | |
@@ -485,6 +549,28 @@ describe("live model switch", () => {
|
485 | 549 | |
486 | 550 | expect(result).toBeUndefined(); |
487 | 551 | }); |
| 552 | + |
| 553 | +it("does not trigger switch when runtime promotes openai to openai-codex", async () => { |
| 554 | +const sessionEntry = { |
| 555 | +liveModelSwitchPending: true, |
| 556 | +providerOverride: "openai", |
| 557 | +modelOverride: "gpt-5.5", |
| 558 | +}; |
| 559 | +state.loadSessionStoreMock.mockReturnValue({ main: sessionEntry }); |
| 560 | + |
| 561 | +const { shouldSwitchToLiveModel } = await loadModule(); |
| 562 | + |
| 563 | +const result = shouldSwitchToLiveModel( |
| 564 | +makeShouldSwitchParams({ |
| 565 | +currentProvider: "openai-codex", |
| 566 | +currentModel: "gpt-5.5", |
| 567 | +defaultProvider: "openai", |
| 568 | +defaultModel: "gpt-5.5", |
| 569 | +}), |
| 570 | +); |
| 571 | + |
| 572 | +expect(result).toBeUndefined(); |
| 573 | +}); |
488 | 574 | }); |
489 | 575 | |
490 | 576 | describe("clearLiveModelSwitchPending", () => { |
|