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
4 changes: 4 additions & 0 deletions packages/coding-agent/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@

### Added

- `/fallback restore` returns the current session to the model and thinking level active before retry fallback, without changing global model defaults.

### Fixed

- An explicitly requested `/compact` now overrides Claude SDK OAuth's automatic-compaction delegation, providing a manual escape hatch when SDK-native compaction does not fire.

### New Features

### Breaking Changes
Expand Down
13 changes: 12 additions & 1 deletion packages/coding-agent/src/core/agent-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ import { expandPromptTemplateWithMetadata, type PromptTemplate } from "./prompt-
import { createProviderTimeoutRetryPlan, runBoundedRetryContinuation } from "./provider-timeout-retry.ts";
import type { ResourceExtensionPaths, ResourceLoader } from "./resource-loader.ts";
import { isBillingErrorMessage } from "./retry-fallback/billing.ts";
import { formatSelector } from "./retry-fallback/chains.ts";
import { formatSelector, parseFallbackSelector } from "./retry-fallback/chains.ts";
import { RetryFallbackController } from "./retry-fallback/controller.ts";
import { SelectorCooldowns } from "./retry-fallback/cooldown.ts";
import {
Expand Down Expand Up @@ -6880,6 +6880,17 @@ export class AgentSession {
pinned: active.pinned,
};
},
restoreFallbackPrimary: async () => {
const active = this._retryFallback.activeState;
if (!active) return false;
const selector = parseFallbackSelector(active.originalSelector, this._modelRegistry);
const model = selector ? this._modelRegistry.find(selector.provider, selector.id) : undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When the original model disappears from the registry, /fallback restore reports that no fallback is active while leaving the fallback state active. Return a distinct unavailable result or surface the unresolved original model instead of mapping this case to inactive.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/coding-agent/src/core/agent-session.ts, line 6887:

<comment>When the original model disappears from the registry, `/fallback restore` reports that no fallback is active while leaving the fallback state active. Return a distinct unavailable result or surface the unresolved original model instead of mapping this case to inactive.</comment>

<file context>
@@ -6880,6 +6880,17 @@ export class AgentSession {
+						const active = this._retryFallback.activeState;
+						if (!active) return false;
+						const selector = parseFallbackSelector(active.originalSelector, this._modelRegistry);
+						const model = selector ? this._modelRegistry.find(selector.provider, selector.id) : undefined;
+						if (!model) return false;
+						const originalThinkingLevel = active.originalThinkingLevel;
</file context>

if (!model) return false;
const originalThinkingLevel = active.originalThinkingLevel;
await this.setSessionModel(model);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When the model-select step fails, setSessionModel has already cleared _retryFallback; the runtime rolls back to the fallback model, but /fallback restore can no longer retry it. Use the fallback-revert switch path and clear the controller only after the switch succeeds.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/coding-agent/src/core/agent-session.ts, line 6890:

<comment>When the model-select step fails, `setSessionModel` has already cleared `_retryFallback`; the runtime rolls back to the fallback model, but `/fallback restore` can no longer retry it. Use the fallback-revert switch path and clear the controller only after the switch succeeds.</comment>

<file context>
@@ -6880,6 +6880,17 @@ export class AgentSession {
+						const model = selector ? this._modelRegistry.find(selector.provider, selector.id) : undefined;
+						if (!model) return false;
+						const originalThinkingLevel = active.originalThinkingLevel;
+						await this.setSessionModel(model);
+						if (originalThinkingLevel !== undefined) this.setSessionThinkingLevel(originalThinkingLevel);
+						return true;
</file context>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: restoreFallbackPrimary delegates to setSessionModel, which throws (auth missing via checkAuth, model unusable via assertModelUsable, or emitModelSelect failure) instead of returning false. The /fallback restore handler awaits it without try/catch, so such a failure surfaces as an uncaught command error rather than the graceful boolean/warning path, and on the auth-failure path the fallback state is left uncleared. Catch errors here and return false so the command reports "could not restore" instead of throwing.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/coding-agent/src/core/agent-session.ts, line 6890:

<comment>`restoreFallbackPrimary` delegates to `setSessionModel`, which throws (auth missing via `checkAuth`, model unusable via `assertModelUsable`, or `emitModelSelect` failure) instead of returning false. The `/fallback restore` handler awaits it without try/catch, so such a failure surfaces as an uncaught command error rather than the graceful boolean/warning path, and on the auth-failure path the fallback state is left uncleared. Catch errors here and return false so the command reports "could not restore" instead of throwing.</comment>

<file context>
@@ -6880,6 +6880,17 @@ export class AgentSession {
+						const model = selector ? this._modelRegistry.find(selector.provider, selector.id) : undefined;
+						if (!model) return false;
+						const originalThinkingLevel = active.originalThinkingLevel;
+						await this.setSessionModel(model);
+						if (originalThinkingLevel !== undefined) this.setSessionThinkingLevel(originalThinkingLevel);
+						return true;
</file context>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Restore bypasses the retry controller's revert semantics. It clears state only via the side effect of setSessionModel -> clearForManualModelChange (which does not emit), so no retry_fallback_reverted event fires and the switch is recorded as an ordinary manual model change rather than a fallback revert. Consider restoring through a controller-level revert/switchModel(...,"fallback-revert") so history and the retry_fallback_reverted event stay consistent.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/coding-agent/src/core/agent-session.ts, line 6890:

<comment>Restore bypasses the retry controller's revert semantics. It clears state only via the side effect of `setSessionModel` -> `clearForManualModelChange` (which does not emit), so no `retry_fallback_reverted` event fires and the switch is recorded as an ordinary manual model change rather than a fallback revert. Consider restoring through a controller-level revert/`switchModel(...,"fallback-revert")` so history and the `retry_fallback_reverted` event stay consistent.</comment>

<file context>
@@ -6880,6 +6880,17 @@ export class AgentSession {
+						const model = selector ? this._modelRegistry.find(selector.provider, selector.id) : undefined;
+						if (!model) return false;
+						const originalThinkingLevel = active.originalThinkingLevel;
+						await this.setSessionModel(model);
+						if (originalThinkingLevel !== undefined) this.setSessionThinkingLevel(originalThinkingLevel);
+						return true;
</file context>

if (originalThinkingLevel !== undefined) this.setSessionThinkingLevel(originalThinkingLevel);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: A restore interrupted after setSessionModel persists its model entry but before the next line persists the original thinking level reloads with the wrong thinking level. Apply the original level through the existing fallback-revert transition so model and thinking restoration are one persisted operation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/coding-agent/src/core/agent-session.ts, line 6891:

<comment>A restore interrupted after `setSessionModel` persists its model entry but before the next line persists the original thinking level reloads with the wrong thinking level. Apply the original level through the existing `fallback-revert` transition so model and thinking restoration are one persisted operation.</comment>

<file context>
@@ -6880,6 +6880,17 @@ export class AgentSession {
+						if (!model) return false;
+						const originalThinkingLevel = active.originalThinkingLevel;
+						await this.setSessionModel(model);
+						if (originalThinkingLevel !== undefined) this.setSessionThinkingLevel(originalThinkingLevel);
+						return true;
+					},
</file context>

return true;
},
},
compact: (options) => {
const admission = this._claimPendingCompactionAdmission();
Expand Down
18 changes: 18 additions & 0 deletions packages/coding-agent/src/core/changes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# changes

## 2026-09-02 - Restore the pre-fallback session model on request

### What changed

- `packages/coding-agent/src/core/agent-session.ts` binds a session-only `restoreFallbackPrimary` operation that resolves the retry controller's original selector, restores that model and its original thinking level, and clears active fallback state without changing global defaults.

### Why

- A successful fallback intentionally leaves the session on the fallback model. Users need an explicit, bounded way to return to the pre-fallback model after the incident clears without rewriting their configured defaults.

### Why an extension could not handle it

- The retry controller's original selector and thinking level are private session state. The builtin command can request restoration only through a host-bound session-settings operation.

### Expected merge conflict zones

- LOW: `packages/coding-agent/src/core/agent-session.ts` in the extension session-settings binding.

## 2026-08-31 - Session activity contract for host occupancy decisions

### What changed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,49 @@
# changes.md — builtin compaction policy

## An explicitly requested compaction overrides the SDK-native lane opt-out (2026-09-02)

### What changed

- `lane-policy.ts` gained `isLaneOverrideReason(reason)`, naming the `CompactionReason` values the
`claude-sdk-oauth` delegation does NOT cover. Today that is `manual` alone.
- The `session_before_compact` guard in `index.ts` now reads
`if (!isLaneOverrideReason(event.reason) && lanePolicy.disablesSenpiCompaction(ctx))`. Every automatic reason
(`threshold`, `overflow`, `pre_prompt`, `branch`, `extension`) is still cancelled with
`rejectionCause: "external-owner"` exactly as before; only an explicitly requested `/compact` proceeds.
- No other lane call site changed: the `before_agent_start`, `agent_end`, `turn_end`, `model_select`, `context`
and `message_end` guards still stand down unconditionally, because none of them carries a user request.

### Why

The opt-out added on 2026-08-01 rests on one premise: the Claude Agent SDK runs its own native auto-compaction over the
session it owns, so senpi compacting on top would rewrite a history senpi no longer owns. That premise is about
AUTOMATIC compaction, and senpi cannot observe that the SDK's compaction did not happen. Because the guard ignored
`event.reason`, an explicit `/compact` was cancelled with the same delegation message — and `interactive-mode.ts`
renders a manual rejection as a red error rather than the muted delegation notice. A session whose SDK-side compaction
never fired therefore had no way back under the limit: no automatic path, and no manual one either.

`manual` is the escape hatch for exactly that blind spot. The lane keeps full ownership in the steady state; the user
keeps a way out when the delegated owner does not deliver.

### Post-compaction continuity

A senpi-side compaction taints the SDK binding, so `session-continuity.ts` resolves the next turn to a fork at the last
assistant boundary instead of a delta. That path already existed (`PENDING_FORK_REASONS.compaction`); this change only
makes it reachable from `/compact`. Measured on the lane with `claude-haiku-4-5`: compacted from 64,779 tokens to 368,
and the following turn re-established the lane with 3.4KB re-sent at a 95.4% cache hit.

### Scope

- Senpi compaction remains fully active for every non-`claude-sdk-oauth` provider, and every automatic reason on the
lane is still delegated; both stay pinned in `test/claude-sdk-oauth-compaction-alignment.test.ts`.
- Coverage: `test/claude-sdk-oauth-compaction-alignment.test.ts` — "never delegates an explicitly requested manual
compaction to the SDK", beside the existing "cancels a requested senpi compaction with the lane reason".

### Expected merge conflict zones

- LOW: `lane-policy.ts` around the new `isLaneOverrideReason` export and its `CompactionReason` type import.
- LOW: `index.ts` at the single `session_before_compact` lane guard.

## Emergency-prune counter emitted at its one true site (2026-09-01)

### What changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
CLAUDE_SDK_OAUTH_COMPACT_ENTRY_TYPE,
collectCompactBoundaryEntries,
createCompactionLanePolicy,
isLaneOverrideReason,
SDK_NATIVE_LANE_REJECTION_REASON,
} from "./lane-policy.ts";
import { type CompactionLogger, createCompactionLogger } from "./log.ts";
Expand Down Expand Up @@ -556,7 +557,11 @@ export default function compactionExtension(
let warmJobConsumed = false;
invalidateSpeculativeCompaction(ctx);
try {
if (lanePolicy.disablesSenpiCompaction(ctx)) {
// The lane owns senpi's AUTOMATIC compaction only. An explicitly requested
// compaction overrides the delegation: senpi cannot observe that the SDK
// failed to compact, so `/compact` is the only way back under the limit
// once the delegated owner has not delivered.
if (!isLaneOverrideReason(event.reason) && lanePolicy.disablesSenpiCompaction(ctx)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When /compact fails on the Claude SDK lane, the session-compaction failure handler still treats the lane as externally owned and does not debit the circuit breaker. Count failures for the newly senpi-owned manual route as well, so repeated failures remain protected after switching to a senpi-owned provider.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/coding-agent/src/core/extensions/builtin/compaction/index.ts, line 564:

<comment>When `/compact` fails on the Claude SDK lane, the session-compaction failure handler still treats the lane as externally owned and does not debit the circuit breaker. Count failures for the newly senpi-owned `manual` route as well, so repeated failures remain protected after switching to a senpi-owned provider.</comment>

<file context>
@@ -556,7 +557,11 @@ export default function compactionExtension(
+			// compaction overrides the delegation: senpi cannot observe that the SDK
+			// failed to compact, so `/compact` is the only way back under the limit
+			// once the delegated owner has not delivered.
+			if (!isLaneOverrideReason(event.reason) && lanePolicy.disablesSenpiCompaction(ctx)) {
 				return {
 					cancel: true,
</file context>

return {
cancel: true,
rejectionCause: "external-owner",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
import type { AgentMessage } from "@earendil-works/pi-agent-core";
import type { AssistantMessageDiagnostic } from "@earendil-works/pi-ai";
import type { CompactionReason } from "../../types.ts";
import { CLAUDE_SDK_OAUTH_PROVIDER_ID } from "../claude-sdk-oauth/account-management.ts";
import type { ClaudeSdkOauthProviderSettings } from "../claude-sdk-oauth/settings.ts";
import { loadClaudeSdkOauthProviderSettingsFromDisk } from "../claude-sdk-oauth/settings.ts";
Expand All @@ -32,6 +33,24 @@ export const CLAUDE_SDK_OAUTH_COMPACT_BOUNDARY_DIAGNOSTIC = "claude_sdk_oauth_co
export const SDK_NATIVE_LANE_REJECTION_REASON = "the Claude Agent SDK owns compaction for this session";
const COMPACT_BOUNDARY_SCHEMA = "senpi.claude-sdk-oauth.compact-boundary.v1";

/**
* Compaction reasons the SDK-native delegation does NOT cover.
*
* The stand-down exists because the SDK owns the transcript and runs its own
* native auto-compaction over it, so senpi's AUTOMATIC compaction would rewrite
* a history senpi no longer owns. That argument only holds while the SDK's
* compaction actually happens; senpi cannot observe that it did not. `manual` is
* the escape hatch for exactly that blind spot: an explicitly requested
* `/compact` is the user stating the delegated owner did not deliver, and
* delegating it away leaves the session with no way back under the limit.
*
* Every automatic reason stays delegated, so the lane keeps its ownership in
* the steady state.
*/
export function isLaneOverrideReason(reason: CompactionReason): boolean {
return reason === "manual";
}

export interface LaneModel {
provider?: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function modelFallbackExtension(pi: ExtensionAPI): void {
});
pi.registerCommand("fallback", {
description: "View and manage retry model fallback chains.",
argumentHint: "[target [fallback1 fallback2 ...]]",
argumentHint: "[restore | target fallback1 [fallback2 ...]]",
handler: async (rawArgs, ctx) => handleFallbackCommand(rawArgs, ctx),
});
}
Expand Down Expand Up @@ -45,8 +45,16 @@ async function handleFallbackCommand(rawArgs: string, ctx: ExtensionCommandConte
});
return;
}
if (args.length === 1 && args[0] === "restore") {
const restored = await ctx.sessionSettings.restoreFallbackPrimary();
ctx.ui.notify(
restored ? "Restored the pre-fallback model for this session." : "This session has no active fallback model.",
restored ? "info" : "warning",
);
return;
}
if (args.length < 2) {
ctx.ui.notify("Usage: /fallback <target> <fallback1> [fallback2 ...]", "error");
ctx.ui.notify("Usage: /fallback restore | /fallback <target> <fallback1> [fallback2 ...]", "error");
return;
}
await saveChain(ctx, args[0], args.slice(1));
Expand Down
20 changes: 20 additions & 0 deletions packages/coding-agent/src/core/extensions/changes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Core Extensions Changes

## Session-only fallback restoration seam (2026-09-02)

### What changed

- `packages/coding-agent/src/core/extensions/types.ts` adds `restoreFallbackPrimary(): Promise<boolean>` to the session-settings command surface.
- `packages/coding-agent/src/core/extensions/runner.ts` supplies the inert default until the host binds the real operation.

### Why

- The builtin `/fallback restore` command must ask the owning session to restore its private retry state without reaching into `AgentSession` or changing persisted defaults.

### Why an extension could not handle it

- The command is an extension, but the original selector, thinking level, and active retry state are host-owned. A narrow bound operation is the extension-safe seam.

### Expected merge conflict zones

- LOW: `packages/coding-agent/src/core/extensions/types.ts` on `ExtensionSessionSettings`.
- LOW: `packages/coding-agent/src/core/extensions/runner.ts` in the default session-settings object.


## Expose the extension event bus for session activity signals (2026-08-31)

Expand Down
1 change: 1 addition & 0 deletions packages/coding-agent/src/core/extensions/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ function createNoOpSessionSettings(): ExtensionContextActions["sessionSettings"]
},
reload: () => settings.reload(),
getFallbackStatus: () => undefined,
restoreFallbackPrimary: async () => false,
};
}

Expand Down
2 changes: 2 additions & 0 deletions packages/coding-agent/src/core/extensions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ export interface ExtensionSessionSettings {
setFallbackRevertPolicy(policy: "cooldown-expiry" | "never"): Promise<void>;
reload(): Promise<void>;
getFallbackStatus(): RetryFallbackStatus | undefined;
/** Restore this session to the model and thinking level active before fallback. */
restoreFallbackPrimary(): Promise<boolean>;
}

export interface ContextUsage {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,10 @@ function beforeAgentStartEvent(): BeforeAgentStartEvent {
} as BeforeAgentStartEvent;
}

function beforeCompactEvent(): SessionBeforeCompactEvent {
function beforeCompactEvent(reason: SessionBeforeCompactEvent["reason"] = "threshold"): SessionBeforeCompactEvent {
return {
type: "session_before_compact",
reason: "threshold",
reason,
willRetry: false,
requestId: "request-1",
preparation: {
Expand Down Expand Up @@ -227,6 +227,17 @@ describe("claude-sdk-oauth lane: senpi compaction stands down", () => {
});
});

it("never delegates an explicitly requested manual compaction to the SDK", async () => {
const harness = createHarness({ provider: "claude-sdk-oauth" });

const result = await harness.sessionBeforeCompact(beforeCompactEvent("manual"), harness.ctx);

// The delegation covers senpi's AUTOMATIC compaction only. `/compact` is the
// user's escape hatch for the case the lane cannot detect: the SDK did not
// compact and the session has no other way back under the limit.
expect(result?.rejectionCause).not.toBe("external-owner");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The manual-compaction test only asserts that the result is not rejected as external-owner, so it also passes when the handler returns undefined and no compaction actually ran. Since this test is the failing-first proof for the /compact override, assert the positive outcome (e.g. result?.rejectionCause is undefined / the handler returns a compaction or ran applyCompaction) instead of only the absence of the lane rejection.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/coding-agent/test/claude-sdk-oauth-compaction-alignment.test.ts, line 238:

<comment>The manual-compaction test only asserts that the result is not rejected as `external-owner`, so it also passes when the handler returns `undefined` and no compaction actually ran. Since this test is the failing-first proof for the `/compact` override, assert the positive outcome (e.g. `result?.rejectionCause` is undefined / the handler returns a compaction or ran `applyCompaction`) instead of only the absence of the lane rejection.</comment>

<file context>
@@ -227,6 +227,17 @@ describe("claude-sdk-oauth lane: senpi compaction stands down", () => {
+		// The delegation covers senpi's AUTOMATIC compaction only. `/compact` is the
+		// user's escape hatch for the case the lane cannot detect: the SDK did not
+		// compact and the session has no other way back under the limit.
+		expect(result?.rejectionCause).not.toBe("external-owner");
+	});
+
</file context>
Suggested change
expect(result?.rejectionCause).not.toBe("external-owner");
expect(result?.rejectionCause).toBeUndefined();
expect(harness.applyCompaction).toHaveBeenCalled();

});

it("leaves context messages untouched while the same load reduces them for other providers", () => {
const reductionMessages = () => [
{ role: "user" as const, content: [{ type: "text" as const, text: "u1" }], timestamp: 1 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ export function createInMemoryExtensionSessionSettings(): ExtensionSessionSettin
},
reload: () => settings.reload(),
getFallbackStatus: () => undefined,
restoreFallbackPrimary: async () => false,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ async function context(
},
reload: () => settings.reload(),
getFallbackStatus: () => undefined,
restoreFallbackPrimary: async () => false,
},
compact: () => {},
getMessageRevision: () => 0,
Expand Down Expand Up @@ -185,7 +186,7 @@ describe("model fallback builtin command", () => {

it("registers /fallback with its quick-set hint", async () => {
const command = (await harness()).get("fallback");
expect(command?.argumentHint).toBe("[target [fallback1 fallback2 ...]]");
expect(command?.argumentHint).toBe("[restore | target fallback1 [fallback2 ...]]");
expect(command?.description).toContain("fallback");
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,27 @@ describe("model fallback host wiring", () => {
pinned: false,
});
});

it("restores the pre-fallback model for the current session on command", async () => {
const harness = await createHarness({
models: [{ id: "faux-1" }, { id: "faux-2" }],
settings: {
retry: { enabled: true, baseDelayMs: 1, maxRetries: 0, fallbackChains: { [primary]: [fallback] } },
},
extensionFactories: [{ factory: modelFallbackExtension }],
});
harnesses.push(harness);
harness.setResponses([
fauxAssistantMessage("", { stopReason: "error", errorMessage: "overloaded_error" }),
fauxAssistantMessage("fallback response"),
]);
await harness.session.prompt("enter fallback");
expect(harness.session.model?.id).toBe("faux-2");

const context = harness.getExtensionRunner().createCommandContext();
await getFallbackCommand(harness).handler("restore", context);

expect(harness.session.model?.id).toBe("faux-1");
expect(context.sessionSettings.getFallbackStatus()).toBeUndefined();
});
});