AgentSkillsCN

incognito-mode-patterns

为短暂对话提供隐身模式,支持空白画布选项。控制工具访问权限(始终禁用写入工具,可配置读取工具)、自定义指令应用,以及非活动状态下的自动清理功能。此工具会在“incognito”、“ephemeral”、“blank slate”、“private mode”、“no memory”、“read tools”、“write tools”、“custom instructions”、“incognito settings”、“inactivity timeout”等事件触发时自动运行。

SKILL.md
--- frontmatter
name: incognito-mode-patterns
description: Incognito mode patterns for ephemeral conversations with blank slate option. Controls tool access (write tools always disabled, read tools configurable), custom instruction application, and inactivity auto-cleanup. Triggers on "incognito", "ephemeral", "blank slate", "private mode", "no memory", "read tools", "write tools", "custom instructions", "incognito settings", "inactivity timeout".

Incognito Mode Patterns

Incognito conversations provide ephemeral, privacy-focused chat sessions with configurable tool access and optional blank slate mode (skips memories and custom instructions).

Core Behavior

Always disabled in incognito:

  • Write tools: saveMemory, deleteMemory, manageTasks
  • Canvas/Document mode tools

Configurable in incognito:

  • Read tools: search (files, notes, tasks, history, memories, knowledge bank)
  • Custom instructions application
  • Memory injection

Schema Structure

Conversation Table Fields

typescript
// From conversations.ts:30-36
isIncognito: v.optional(v.boolean()),
incognitoSettings: v.optional(
  v.object({
    enableReadTools: v.optional(v.boolean()),
    applyCustomInstructions: v.optional(v.boolean()),
    inactivityTimeoutMinutes: v.optional(v.number()),
  }),
),

Creation Pattern

typescript
// From conversations.ts:57-67
...(args.isIncognito && {
  isIncognito: true,
  incognitoSettings: {
    enableReadTools: args.incognitoSettings?.enableReadTools ?? true,
    applyCustomInstructions:
      args.incognitoSettings?.applyCustomInstructions ?? true,
    inactivityTimeoutMinutes:
      args.incognitoSettings?.inactivityTimeoutMinutes,
    lastActivityAt: now,
  },
}),

Default behavior: Read tools enabled, custom instructions applied unless explicitly disabled.

Tool Filtering Logic

Write Tools: Always Disabled

typescript
// From tools.ts:167-210
// Write tools: DISABLED for incognito
if (!isIncognito) {
  // Memory write tools
  if (enableMemoryWriteTools) {
    tools.saveMemory = createMemorySaveTool(ctx, userId);
    if (memoryExtractionLevel !== "passive") {
      tools.deleteMemory = createMemoryDeleteTool(ctx, userId);
    }
  }

  // Task manager
  tools.manageTasks = createTaskManagerTool(ctx, userId, conversation?.projectId);

  // Document mode tools
  tools.enterDocumentMode = createEnterDocumentModeTool(ctx, conversationId);
  if (isDocumentMode) {
    tools.exitDocumentMode = createExitDocumentModeTool(ctx, conversationId);
    tools.createDocument = createDocumentTool(ctx, userId, conversationId);
    tools.updateDocument = createUpdateDocumentTool(ctx, userId, conversationId);
    tools.readDocument = createReadDocumentTool(ctx, userId, conversationId);
    tools.resolveConflict = createResolveConflictTool(ctx, userId, conversationId);
  }
}

Read Tools: Configurable

typescript
// From tools.ts:86-97
const isIncognito = conversation?.isIncognito ?? false;
const incognitoSettings = conversation?.incognitoSettings;
const enableReadTools = !isIncognito || incognitoSettings?.enableReadTools !== false;

// Memory tool settings based on extraction level
const enableMemoryWriteTools = !isIncognito && memoryExtractionLevel !== "none";
const enableMemoryReadTools = enableReadTools && memoryExtractionLevel !== "none";
typescript
// From tools.ts:212-238
// Read tools: Configurable for incognito (search user data)
if (enableReadTools) {
  // Memory search: respects extraction level
  if (enableMemoryReadTools) {
    tools.searchMemories = createMemorySearchTool(ctx, userId);
  }

  // Other search tools
  tools.searchFiles = createSearchFilesTool(ctx, userId);
  tools.searchNotes = createSearchNotesTool(ctx, userId);
  tools.searchTasks = createSearchTasksTool(ctx, userId);
  tools.queryHistory = createQueryHistoryTool(ctx, userId, conversationId);
  tools.searchAll = createSearchAllTool(ctx, userId, conversationId, searchCache, budgetState);
  tools.searchKnowledgeBank = createSearchKnowledgeBankTool(ctx, userId, conversation?.projectId);
}

Logic: enableReadTools defaults to true unless explicitly set to false via incognitoSettings.enableReadTools.

Capability Tools: Always Available

Stateless tools (calculator, datetime, web search, URL reader, code execution, weather, YouTube, file docs) are always enabled regardless of incognito mode.

Blank Slate Mode

Skip memories and custom instructions when applyCustomInstructions: false.

typescript
// From systemBuilder.ts:59-62
const isBlankSlate =
  conversation?.isIncognito &&
  conversation?.incognitoSettings?.applyCustomInstructions === false;

Skipped Sections

typescript
// From systemBuilder.ts:95-133
// === 2. IDENTITY MEMORIES ===
// Skip for incognito blank slate mode
if (!isBlankSlate) {
  const identityMemories = await ctx.runQuery(
    internal.memories.search.getIdentityMemories,
    { userId: args.userId, limit: 20 }
  );
  // ... format and inject
}
typescript
// From systemBuilder.ts:135-142
// === 3. CONTEXTUAL MEMORIES ===
// Skip for incognito blank slate mode
if (args.prefetchedMemories && !isBlankSlate) {
  systemMessages.push({
    role: "system",
    content: `## Contextual Memories\n\n${args.prefetchedMemories}`,
  });
}
typescript
// From systemBuilder.ts:160-186
// === 4.25. KNOWLEDGE BANK ===
// Skip for incognito blank slate mode
if (!isBlankSlate && args.hasFunctionCalling) {
  const hasKnowledge = await ctx.runQuery(
    internal.knowledgeBank.index.hasKnowledge,
    { userId: args.userId }
  );
  const kbPrompt = getKnowledgeBankSystemPrompt(hasKnowledge);
  if (kbPrompt) {
    systemMessages.push({ role: "system", content: kbPrompt });
  }
}
typescript
// From systemBuilder.ts:227-304
// === 6. USER CUSTOM INSTRUCTIONS ===
// Skip for incognito blank slate mode
if (customInstructions?.enabled && !isBlankSlate) {
  // ... build and inject user preferences
}

Effect: Blank slate mode provides completely fresh AI behavior without personalization or history context.

Inactivity Timeout

Optional auto-cleanup for incognito conversations.

Field Structure

typescript
incognitoSettings: {
  inactivityTimeoutMinutes?: number;  // Optional timeout in minutes
  lastActivityAt: number;             // Timestamp of last activity
}

Implementation: Set during creation, updated on message activity. Cleanup logic runs via scheduled job (not shown in provided files but referenced in schema).

Usage Patterns

Standard Incognito (Read Tools Enabled)

typescript
await ctx.runMutation(api.conversations.create, {
  model: "openai:gpt-5-mini",
  isIncognito: true,
  incognitoSettings: {
    enableReadTools: true,          // Can search files/notes/tasks
    applyCustomInstructions: true,  // Apply user preferences
  },
});

Tools: Web search, URL reader, code execution + file/note/task/history search. No writes.

Strict Incognito (Read Tools Disabled)

typescript
await ctx.runMutation(api.conversations.create, {
  model: "openai:gpt-5-mini",
  isIncognito: true,
  incognitoSettings: {
    enableReadTools: false,         // No data access
    applyCustomInstructions: true,  // Still apply preferences
  },
});

Tools: Only capability tools (web search, calculator, datetime, URL reader, code execution). No data access.

Blank Slate Mode

typescript
await ctx.runMutation(api.conversations.create, {
  model: "openai:gpt-5-mini",
  isIncognito: true,
  incognitoSettings: {
    enableReadTools: false,              // No data access
    applyCustomInstructions: false,      // Skip memories + custom instructions
    inactivityTimeoutMinutes: 60,        // Auto-delete after 1 hour of inactivity
  },
});

Tools: Only capability tools. System prompt: Skips identity memories, contextual memories, knowledge bank, and custom instructions. Fully anonymous.

Key Files

  • packages/backend/convex/conversations.ts - Schema + creation mutation (lines 30-112)
  • packages/backend/convex/generation/tools.ts - Tool filtering logic (lines 42-241)
  • packages/backend/convex/lib/prompts/systemBuilder.ts - Blank slate prompt filtering (lines 59-304)

Anti-Patterns

Don't assume incognito = no read tools. Default is enableReadTools: true. Must explicitly set to false for strict privacy.

Don't confuse blank slate with incognito. Incognito only controls tool access. Blank slate (applyCustomInstructions: false) controls system prompt personalization.

Don't use incognito for temporary chats. Use inactivityTimeoutMinutes for auto-cleanup. Otherwise incognito conversations persist like normal ones.

Don't expose write tools in incognito UI. Backend enforces this but frontend must not offer task creation, memory saving, or canvas tools when isIncognito: true.