diff --git a/packages/app/src/components/toast-host.tsx b/packages/app/src/components/toast-host.tsx
index 082a03787..e275f0bb0 100644
--- a/packages/app/src/components/toast-host.tsx
+++ b/packages/app/src/components/toast-host.tsx
@@ -6,7 +6,7 @@ import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { useTranslation } from "react-i18next";
import { useIsCompactFormFactor } from "@/constants/layout";
import { isWeb } from "@/constants/platform";
-import { AlertTriangle, CheckCircle2 } from "lucide-react-native";
+import { AlertTriangle, CheckCircle2, Info } from "lucide-react-native";
import { getOverlayRoot, OVERLAY_Z } from "@/lib/overlay-root";
import {
HEADER_INNER_HEIGHT,
@@ -14,7 +14,7 @@ import {
HEADER_TOP_PADDING_MOBILE,
} from "@/constants/layout";
-export type ToastVariant = "default" | "success" | "error";
+export type ToastVariant = "default" | "info" | "success" | "warning" | "error";
export interface ToastShowOptions {
icon?: ReactNode;
@@ -230,7 +230,9 @@ export function ToastViewport({
const toastAnimatedStyle = useMemo(
() => [
styles.toast,
+ toastVariant === "info" ? styles.toastInfo : null,
toastVariant === "success" ? styles.toastSuccess : null,
+ toastVariant === "warning" ? styles.toastWarning : null,
toastVariant === "error" ? styles.toastError : null,
{
marginTop: topOffset,
@@ -250,8 +252,12 @@ export function ToastViewport({
}
let defaultIcon: ReactNode = null;
- if (toast.variant === "success") {
+ if (toast.variant === "info") {
+ defaultIcon = ;
+ } else if (toast.variant === "success") {
defaultIcon = ;
+ } else if (toast.variant === "warning") {
+ defaultIcon = ;
} else if (toast.variant === "error") {
defaultIcon = ;
}
@@ -313,6 +319,12 @@ const styles = StyleSheet.create((theme) => ({
toastSuccess: {
borderColor: theme.colors.border,
},
+ toastInfo: {
+ borderColor: theme.colors.palette.blue[300],
+ },
+ toastWarning: {
+ borderColor: theme.colors.palette.amber[500],
+ },
toastError: {
borderColor: theme.colors.destructive,
},
diff --git a/packages/app/src/utils/provider-notice-toast.ts b/packages/app/src/utils/provider-notice-toast.ts
index 478f929f8..7c3ace8b5 100644
--- a/packages/app/src/utils/provider-notice-toast.ts
+++ b/packages/app/src/utils/provider-notice-toast.ts
@@ -13,7 +13,7 @@ export function showProviderNoticeToast(
return;
}
toast.show(notice.message, {
- variant: "default",
- durationMs: notice.type === "warning" ? 3200 : undefined,
+ variant: notice.type,
+ durationMs: notice.type === "warning" ? 5000 : undefined,
});
}
diff --git a/packages/server/src/server/agent/provider-notices.ts b/packages/server/src/server/agent/provider-notices.ts
index 921f70a50..d2a9c3af5 100644
--- a/packages/server/src/server/agent/provider-notices.ts
+++ b/packages/server/src/server/agent/provider-notices.ts
@@ -1,6 +1,11 @@
import type { AgentProviderNotice } from "./agent-sdk-types.js";
-export const SETTING_APPLIES_NEXT_TURN_NOTICE: AgentProviderNotice = {
- type: "info",
- message: "This change applies next turn.",
+export const MODE_APPLIES_NEXT_TURN_NOTICE: AgentProviderNotice = {
+ type: "warning",
+ message: "Permission mode applies next turn",
+};
+
+export const THINKING_APPLIES_NEXT_TURN_NOTICE: AgentProviderNotice = {
+ type: "warning",
+ message: "Thinking level applies next turn",
};
diff --git a/packages/server/src/server/agent/providers/claude/agent.test.ts b/packages/server/src/server/agent/providers/claude/agent.test.ts
index 20f8f5235..bd535ac13 100644
--- a/packages/server/src/server/agent/providers/claude/agent.test.ts
+++ b/packages/server/src/server/agent/providers/claude/agent.test.ts
@@ -704,8 +704,8 @@ describe("ClaudeAgentSession features", () => {
});
await expect(session.setThinkingOption?.("ultracode")).resolves.toEqual({
- type: "info",
- message: "This change applies next turn.",
+ type: "warning",
+ message: "Thinking level applies next turn",
});
await session.close();
diff --git a/packages/server/src/server/agent/providers/claude/agent.ts b/packages/server/src/server/agent/providers/claude/agent.ts
index 99a6acfe2..a0403f2e6 100644
--- a/packages/server/src/server/agent/providers/claude/agent.ts
+++ b/packages/server/src/server/agent/providers/claude/agent.ts
@@ -50,7 +50,7 @@ import { claudeQuery, type ClaudeOptions, type ClaudeQueryFactory } from "./quer
import { realClaudeRewindSdk, revertClaudeConversation, revertClaudeFiles } from "./rewind.js";
import { normalizeProviderReplayTimestamp } from "../../provider-history-timestamps.js";
import { claudeProjectDirSync } from "./project-dir.js";
-import { SETTING_APPLIES_NEXT_TURN_NOTICE } from "../../provider-notices.js";
+import { THINKING_APPLIES_NEXT_TURN_NOTICE } from "../../provider-notices.js";
import {
isProviderImageMarkdown,
materializeProviderImage,
@@ -2209,7 +2209,7 @@ class ClaudeAgentSession implements AgentSession {
}
this.queryRestartNeeded = true;
if (this.activeForegroundTurnId || this.autonomousTurn) {
- return SETTING_APPLIES_NEXT_TURN_NOTICE;
+ return THINKING_APPLIES_NEXT_TURN_NOTICE;
}
}
diff --git a/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts b/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts
index 569370cae..7a585f0ce 100644
--- a/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts
+++ b/packages/server/src/server/agent/providers/codex-app-server-agent.test.ts
@@ -347,12 +347,12 @@ describe("Codex app-server provider", () => {
const session = createSession({ modeId: "auto", thinkingOptionId: "medium" });
await expect(session.setMode("full-access")).resolves.toEqual({
- type: "info",
- message: "This change applies next turn.",
+ type: "warning",
+ message: "Permission mode applies next turn",
});
await expect(session.setThinkingOption?.("high")).resolves.toEqual({
- type: "info",
- message: "This change applies next turn.",
+ type: "warning",
+ message: "Thinking level applies next turn",
});
session.activeForegroundTurnId = null;
diff --git a/packages/server/src/server/agent/providers/codex-app-server-agent.ts b/packages/server/src/server/agent/providers/codex-app-server-agent.ts
index fd6b7b68e..f816e33b0 100644
--- a/packages/server/src/server/agent/providers/codex-app-server-agent.ts
+++ b/packages/server/src/server/agent/providers/codex-app-server-agent.ts
@@ -92,7 +92,10 @@ import {
resolveBinaryVersion,
} from "./diagnostic-utils.js";
import { appendOrReplaceGrowingAssistantMessage, runProviderTurn } from "./provider-runner.js";
-import { SETTING_APPLIES_NEXT_TURN_NOTICE } from "../provider-notices.js";
+import {
+ MODE_APPLIES_NEXT_TURN_NOTICE,
+ THINKING_APPLIES_NEXT_TURN_NOTICE,
+} from "../provider-notices.js";
import type { WorkspaceGitService } from "../../workspace-git-service.js";
function assertChildWithPipes(
@@ -3943,7 +3946,7 @@ export class CodexAppServerAgentSession implements AgentSession {
this.currentMode = modeId;
this.cachedRuntimeInfo = null;
if (this.activeForegroundTurnId) {
- return SETTING_APPLIES_NEXT_TURN_NOTICE;
+ return MODE_APPLIES_NEXT_TURN_NOTICE;
}
}
@@ -3961,7 +3964,7 @@ export class CodexAppServerAgentSession implements AgentSession {
this.refreshResolvedCollaborationMode();
this.cachedRuntimeInfo = null;
if (this.activeForegroundTurnId) {
- return SETTING_APPLIES_NEXT_TURN_NOTICE;
+ return THINKING_APPLIES_NEXT_TURN_NOTICE;
}
}
diff --git a/packages/server/src/server/agent/providers/omp/agent.test.ts b/packages/server/src/server/agent/providers/omp/agent.test.ts
index be6666248..032315696 100644
--- a/packages/server/src/server/agent/providers/omp/agent.test.ts
+++ b/packages/server/src/server/agent/providers/omp/agent.test.ts
@@ -232,7 +232,10 @@ describe("OMP agent client and session", () => {
expect.objectContaining({ name: "review", kind: "skill" }),
]),
);
- await expect(omp.setMode("ask")).resolves.toEqual(expect.objectContaining({ type: "info" }));
+ await expect(omp.setMode("ask")).resolves.toEqual({
+ type: "warning",
+ message: "Start a new OMP session to change approval mode",
+ });
});
test("rewinds natively, interrupts, and shuts down", async () => {
diff --git a/packages/server/src/server/agent/providers/omp/agent.ts b/packages/server/src/server/agent/providers/omp/agent.ts
index a16187096..1e002c9f4 100644
--- a/packages/server/src/server/agent/providers/omp/agent.ts
+++ b/packages/server/src/server/agent/providers/omp/agent.ts
@@ -1084,9 +1084,8 @@ export class OmpAgentSession implements AgentSession {
throw new Error(`Invalid OMP mode '${modeId}'`);
}
return {
- type: "info",
- message:
- "OMP approval mode is set when the agent launches. Start a new OMP session to use a different mode.",
+ type: "warning",
+ message: "Start a new OMP session to change approval mode",
};
}