diff --git a/auto-claude-ui/src/main/insights-service.ts b/auto-claude-ui/src/main/insights-service.ts
index 3a76d00d..59fe3cb2 100644
--- a/auto-claude-ui/src/main/insights-service.ts
+++ b/auto-claude-ui/src/main/insights-service.ts
@@ -2,7 +2,8 @@ import { EventEmitter } from 'events';
import type {
InsightsSession,
InsightsSessionSummary,
- InsightsChatMessage
+ InsightsChatMessage,
+ InsightsModelConfig
} from '../shared/types';
import { InsightsConfig } from './insights/config';
import { InsightsPaths } from './insights/paths';
@@ -111,7 +112,12 @@ export class InsightsService extends EventEmitter {
/**
* Send a message and get AI response
*/
- async sendMessage(projectId: string, projectPath: string, message: string): Promise {
+ async sendMessage(
+ projectId: string,
+ projectPath: string,
+ message: string,
+ modelConfig?: InsightsModelConfig
+ ): Promise {
// Cancel any existing session
this.executor.cancelSession(projectId);
@@ -150,13 +156,17 @@ export class InsightsService extends EventEmitter {
content: m.content
}));
+ // Use provided modelConfig or fall back to session's config
+ const configToUse = modelConfig || session.modelConfig;
+
try {
// Execute insights query
const result = await this.executor.execute(
projectId,
projectPath,
message,
- conversationHistory
+ conversationHistory,
+ configToUse
);
// Add assistant message to session
@@ -177,6 +187,13 @@ export class InsightsService extends EventEmitter {
console.error('[InsightsService] Error executing insights:', error);
}
}
+
+ /**
+ * Update model configuration for a session
+ */
+ updateSessionModelConfig(projectPath: string, sessionId: string, modelConfig: InsightsModelConfig): boolean {
+ return this.sessionManager.updateSessionModelConfig(projectPath, sessionId, modelConfig);
+ }
}
// Singleton instance
diff --git a/auto-claude-ui/src/main/insights/insights-executor.ts b/auto-claude-ui/src/main/insights/insights-executor.ts
index cf45fa90..ec0c01bf 100644
--- a/auto-claude-ui/src/main/insights/insights-executor.ts
+++ b/auto-claude-ui/src/main/insights/insights-executor.ts
@@ -6,8 +6,10 @@ import type {
InsightsChatMessage,
InsightsChatStatus,
InsightsStreamChunk,
- InsightsToolUsage
+ InsightsToolUsage,
+ InsightsModelConfig
} from '../../shared/types';
+import { MODEL_ID_MAP } from '../../shared/constants';
import { InsightsConfig } from './config';
import { detectRateLimit, createSDKRateLimitInfo } from '../rate-limit-detector';
@@ -59,7 +61,8 @@ export class InsightsExecutor extends EventEmitter {
projectId: string,
projectPath: string,
message: string,
- conversationHistory: Array<{ role: string; content: string }>
+ conversationHistory: Array<{ role: string; content: string }>,
+ modelConfig?: InsightsModelConfig
): Promise {
// Cancel any existing session
this.cancelSession(projectId);
@@ -69,7 +72,7 @@ export class InsightsExecutor extends EventEmitter {
throw new Error('Auto Claude source not found');
}
- const runnerPath = path.join(autoBuildSource, 'insights_runner.py');
+ const runnerPath = path.join(autoBuildSource, 'runners', 'insights_runner.py');
if (!existsSync(runnerPath)) {
throw new Error('insights_runner.py not found in auto-claude directory');
}
@@ -83,13 +86,23 @@ export class InsightsExecutor extends EventEmitter {
// Get process environment
const processEnv = this.config.getProcessEnv();
- // Spawn Python process
- const proc = spawn(this.config.getPythonPath(), [
+ // Build command arguments
+ const args = [
runnerPath,
'--project-dir', projectPath,
'--message', message,
'--history', JSON.stringify(conversationHistory)
- ], {
+ ];
+
+ // Add model config if provided
+ if (modelConfig) {
+ const modelId = MODEL_ID_MAP[modelConfig.model] || MODEL_ID_MAP['sonnet'];
+ args.push('--model', modelId);
+ args.push('--thinking-level', modelConfig.thinkingLevel);
+ }
+
+ // Spawn Python process
+ const proc = spawn(this.config.getPythonPath(), args, {
cwd: autoBuildSource,
env: processEnv
});
diff --git a/auto-claude-ui/src/main/insights/session-manager.ts b/auto-claude-ui/src/main/insights/session-manager.ts
index 7be98682..7293d527 100644
--- a/auto-claude-ui/src/main/insights/session-manager.ts
+++ b/auto-claude-ui/src/main/insights/session-manager.ts
@@ -1,4 +1,4 @@
-import type { InsightsSession, InsightsSessionSummary } from '../../shared/types';
+import type { InsightsSession, InsightsSessionSummary, InsightsModelConfig } from '../../shared/types';
import { SessionStorage } from './session-storage';
import { InsightsPaths } from './paths';
@@ -119,6 +119,30 @@ export class SessionManager {
return true;
}
+ /**
+ * Update model configuration for a session
+ */
+ updateSessionModelConfig(projectPath: string, sessionId: string, modelConfig: InsightsModelConfig): boolean {
+ const session = this.storage.loadSessionById(projectPath, sessionId);
+ if (!session) return false;
+
+ session.modelConfig = modelConfig;
+ session.updatedAt = new Date();
+ this.storage.saveSession(projectPath, session);
+
+ // Update cache if this session is cached
+ for (const [projectId, cachedSession] of this.sessions) {
+ if (cachedSession.id === sessionId) {
+ cachedSession.modelConfig = modelConfig;
+ cachedSession.updatedAt = new Date();
+ this.sessions.set(projectId, cachedSession);
+ break;
+ }
+ }
+
+ return true;
+ }
+
/**
* Save session to disk and update cache
*/
diff --git a/auto-claude-ui/src/main/ipc-handlers/insights-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/insights-handlers.ts
index 8db91bc3..cef96a6d 100644
--- a/auto-claude-ui/src/main/ipc-handlers/insights-handlers.ts
+++ b/auto-claude-ui/src/main/ipc-handlers/insights-handlers.ts
@@ -3,7 +3,7 @@ import type { BrowserWindow } from 'electron';
import path from 'path';
import { existsSync, readdirSync, mkdirSync, writeFileSync } from 'fs';
import { IPC_CHANNELS, getSpecsDir, AUTO_BUILD_PATHS } from '../../shared/constants';
-import type { IPCResult, InsightsSession, InsightsSessionSummary, Task, TaskMetadata } from '../../shared/types';
+import type { IPCResult, InsightsSession, InsightsSessionSummary, InsightsModelConfig, Task, TaskMetadata } from '../../shared/types';
import { projectStore } from '../project-store';
import { insightsService } from '../insights-service';
@@ -32,7 +32,7 @@ export function registerInsightsHandlers(
ipcMain.on(
IPC_CHANNELS.INSIGHTS_SEND_MESSAGE,
- async (_, projectId: string, message: string) => {
+ async (_, projectId: string, message: string, modelConfig?: InsightsModelConfig) => {
const project = projectStore.getProject(projectId);
if (!project) {
const mainWindow = getMainWindow();
@@ -44,7 +44,7 @@ export function registerInsightsHandlers(
// Note: Python environment initialization should be handled by insightsService
// or added here with proper dependency injection if needed
- insightsService.sendMessage(projectId, project.path, message);
+ insightsService.sendMessage(projectId, project.path, message, modelConfig);
}
);
@@ -241,4 +241,57 @@ export function registerInsightsHandlers(
}
);
+ // Update model configuration for a session
+ ipcMain.handle(
+ IPC_CHANNELS.INSIGHTS_UPDATE_MODEL_CONFIG,
+ async (_, projectId: string, sessionId: string, modelConfig: InsightsModelConfig): Promise => {
+ const project = projectStore.getProject(projectId);
+ if (!project) {
+ return { success: false, error: 'Project not found' };
+ }
+
+ const success = insightsService.updateSessionModelConfig(project.path, sessionId, modelConfig);
+ if (success) {
+ return { success: true };
+ }
+ return { success: false, error: 'Failed to update model configuration' };
+ }
+ );
+
+ // ============================================
+ // Insights Event Forwarding (Service -> Renderer)
+ // ============================================
+
+ // Forward streaming chunks to renderer
+ insightsService.on('stream-chunk', (projectId: string, chunk: unknown) => {
+ const mainWindow = getMainWindow();
+ if (mainWindow) {
+ mainWindow.webContents.send(IPC_CHANNELS.INSIGHTS_STREAM_CHUNK, projectId, chunk);
+ }
+ });
+
+ // Forward status updates to renderer
+ insightsService.on('status', (projectId: string, status: unknown) => {
+ const mainWindow = getMainWindow();
+ if (mainWindow) {
+ mainWindow.webContents.send(IPC_CHANNELS.INSIGHTS_STATUS, projectId, status);
+ }
+ });
+
+ // Forward errors to renderer
+ insightsService.on('error', (projectId: string, error: string) => {
+ const mainWindow = getMainWindow();
+ if (mainWindow) {
+ mainWindow.webContents.send(IPC_CHANNELS.INSIGHTS_ERROR, projectId, error);
+ }
+ });
+
+ // Forward SDK rate limit events to renderer
+ insightsService.on('sdk-rate-limit', (rateLimitInfo: unknown) => {
+ const mainWindow = getMainWindow();
+ if (mainWindow) {
+ mainWindow.webContents.send(IPC_CHANNELS.CLAUDE_SDK_RATE_LIMIT, rateLimitInfo);
+ }
+ });
+
}
diff --git a/auto-claude-ui/src/preload/api/modules/insights-api.ts b/auto-claude-ui/src/preload/api/modules/insights-api.ts
index a058b4c6..0dc258f8 100644
--- a/auto-claude-ui/src/preload/api/modules/insights-api.ts
+++ b/auto-claude-ui/src/preload/api/modules/insights-api.ts
@@ -4,6 +4,7 @@ import type {
InsightsSessionSummary,
InsightsChatStatus,
InsightsStreamChunk,
+ InsightsModelConfig,
Task,
TaskMetadata,
IPCResult
@@ -16,7 +17,7 @@ import { createIpcListener, invokeIpc, sendIpc, IpcListenerCleanup } from './ipc
export interface InsightsAPI {
// Operations
getInsightsSession: (projectId: string) => Promise>;
- sendInsightsMessage: (projectId: string, message: string) => void;
+ sendInsightsMessage: (projectId: string, message: string, modelConfig?: InsightsModelConfig) => void;
clearInsightsSession: (projectId: string) => Promise;
createTaskFromInsights: (
projectId: string,
@@ -29,6 +30,7 @@ export interface InsightsAPI {
switchInsightsSession: (projectId: string, sessionId: string) => Promise>;
deleteInsightsSession: (projectId: string, sessionId: string) => Promise;
renameInsightsSession: (projectId: string, sessionId: string, newTitle: string) => Promise;
+ updateInsightsModelConfig: (projectId: string, sessionId: string, modelConfig: InsightsModelConfig) => Promise;
// Event Listeners
onInsightsStreamChunk: (
@@ -50,8 +52,8 @@ export const createInsightsAPI = (): InsightsAPI => ({
getInsightsSession: (projectId: string): Promise> =>
invokeIpc(IPC_CHANNELS.INSIGHTS_GET_SESSION, projectId),
- sendInsightsMessage: (projectId: string, message: string): void =>
- sendIpc(IPC_CHANNELS.INSIGHTS_SEND_MESSAGE, projectId, message),
+ sendInsightsMessage: (projectId: string, message: string, modelConfig?: InsightsModelConfig): void =>
+ sendIpc(IPC_CHANNELS.INSIGHTS_SEND_MESSAGE, projectId, message, modelConfig),
clearInsightsSession: (projectId: string): Promise =>
invokeIpc(IPC_CHANNELS.INSIGHTS_CLEAR_SESSION, projectId),
@@ -79,6 +81,9 @@ export const createInsightsAPI = (): InsightsAPI => ({
renameInsightsSession: (projectId: string, sessionId: string, newTitle: string): Promise =>
invokeIpc(IPC_CHANNELS.INSIGHTS_RENAME_SESSION, projectId, sessionId, newTitle),
+ updateInsightsModelConfig: (projectId: string, sessionId: string, modelConfig: InsightsModelConfig): Promise =>
+ invokeIpc(IPC_CHANNELS.INSIGHTS_UPDATE_MODEL_CONFIG, projectId, sessionId, modelConfig),
+
// Event Listeners
onInsightsStreamChunk: (
callback: (projectId: string, chunk: InsightsStreamChunk) => void
diff --git a/auto-claude-ui/src/renderer/components/CustomModelModal.tsx b/auto-claude-ui/src/renderer/components/CustomModelModal.tsx
new file mode 100644
index 00000000..8e6d0072
--- /dev/null
+++ b/auto-claude-ui/src/renderer/components/CustomModelModal.tsx
@@ -0,0 +1,105 @@
+import { useState } from 'react';
+import {
+ Dialog,
+ DialogContent,
+ DialogHeader,
+ DialogTitle,
+ DialogFooter,
+ DialogDescription
+} from './ui/dialog';
+import { Button } from './ui/button';
+import { Label } from './ui/label';
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue
+} from './ui/select';
+import { AVAILABLE_MODELS, THINKING_LEVELS } from '../../shared/constants';
+import type { InsightsModelConfig } from '../../shared/types';
+import type { ModelType, ThinkingLevel } from '../../shared/types';
+
+interface CustomModelModalProps {
+ currentConfig?: InsightsModelConfig;
+ onSave: (config: InsightsModelConfig) => void;
+ onClose: () => void;
+}
+
+export function CustomModelModal({ currentConfig, onSave, onClose }: CustomModelModalProps) {
+ const [model, setModel] = useState(
+ currentConfig?.model || 'sonnet'
+ );
+ const [thinkingLevel, setThinkingLevel] = useState(
+ currentConfig?.thinkingLevel || 'medium'
+ );
+
+ const handleSave = () => {
+ onSave({
+ profileId: 'custom',
+ model,
+ thinkingLevel
+ });
+ };
+
+ return (
+
+ );
+}
diff --git a/auto-claude-ui/src/renderer/components/Insights.tsx b/auto-claude-ui/src/renderer/components/Insights.tsx
index d410812b..9ed75b31 100644
--- a/auto-claude-ui/src/renderer/components/Insights.tsx
+++ b/auto-claude-ui/src/renderer/components/Insights.tsx
@@ -29,12 +29,14 @@ import {
switchSession,
deleteSession,
renameSession,
+ updateModelConfig,
createTaskFromSuggestion,
setupInsightsListeners
} from '../stores/insights-store';
import { loadTasks } from '../stores/task-store';
import { ChatHistorySidebar } from './ChatHistorySidebar';
-import type { InsightsChatMessage } from '../../shared/types';
+import { InsightsModelSelector } from './InsightsModelSelector';
+import type { InsightsChatMessage, InsightsModelConfig } from '../../shared/types';
import {
TASK_CATEGORY_LABELS,
TASK_CATEGORY_COLORS,
@@ -141,6 +143,13 @@ export function Insights({ projectId }: InsightsProps) {
}
};
+ const handleModelConfigChange = async (config: InsightsModelConfig) => {
+ // If we have a session, persist the config
+ if (session?.id) {
+ await updateModelConfig(projectId, session.id, config);
+ }
+ };
+
const isLoading = status.phase === 'thinking' || status.phase === 'streaming';
const messages = session?.messages || [];
@@ -187,14 +196,21 @@ export function Insights({ projectId }: InsightsProps) {
-
+
{/* Messages */}
diff --git a/auto-claude-ui/src/renderer/components/InsightsModelSelector.tsx b/auto-claude-ui/src/renderer/components/InsightsModelSelector.tsx
new file mode 100644
index 00000000..12bcf76a
--- /dev/null
+++ b/auto-claude-ui/src/renderer/components/InsightsModelSelector.tsx
@@ -0,0 +1,144 @@
+import { useState } from 'react';
+import { Brain, Scale, Zap, Sliders, Check } from 'lucide-react';
+import { Button } from './ui/button';
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+ DropdownMenuLabel
+} from './ui/dropdown-menu';
+import { DEFAULT_AGENT_PROFILES, AVAILABLE_MODELS } from '../../shared/constants';
+import type { InsightsModelConfig } from '../../shared/types';
+import { CustomModelModal } from './CustomModelModal';
+
+interface InsightsModelSelectorProps {
+ currentConfig?: InsightsModelConfig;
+ onConfigChange: (config: InsightsModelConfig) => void;
+ disabled?: boolean;
+}
+
+const iconMap: Record = {
+ Brain,
+ Scale,
+ Zap
+};
+
+export function InsightsModelSelector({
+ currentConfig,
+ onConfigChange,
+ disabled
+}: InsightsModelSelectorProps) {
+ const [showCustomModal, setShowCustomModal] = useState(false);
+
+ // Default to 'balanced' if no config
+ const selectedProfileId = currentConfig?.profileId || 'balanced';
+ const profile = DEFAULT_AGENT_PROFILES.find(p => p.id === selectedProfileId);
+
+ // Get the appropriate icon
+ const Icon = selectedProfileId === 'custom'
+ ? Sliders
+ : (profile?.icon ? iconMap[profile.icon] : Scale);
+
+ const handleSelectProfile = (profileId: string) => {
+ if (profileId === 'custom') {
+ setShowCustomModal(true);
+ return;
+ }
+
+ const selected = DEFAULT_AGENT_PROFILES.find(p => p.id === profileId);
+ if (selected) {
+ onConfigChange({
+ profileId: selected.id,
+ model: selected.model,
+ thinkingLevel: selected.thinkingLevel
+ });
+ }
+ };
+
+ const handleCustomSave = (config: InsightsModelConfig) => {
+ onConfigChange(config);
+ setShowCustomModal(false);
+ };
+
+ // Build display text for current selection
+ const getDisplayText = () => {
+ if (selectedProfileId === 'custom' && currentConfig) {
+ const modelLabel = AVAILABLE_MODELS.find(m => m.value === currentConfig.model)?.label || currentConfig.model;
+ return `${modelLabel} + ${currentConfig.thinkingLevel}`;
+ }
+ return profile?.name || 'Balanced';
+ };
+
+ return (
+ <>
+
+
+
+
+
+ Agent Profile
+ {DEFAULT_AGENT_PROFILES.map((p) => {
+ const ProfileIcon = iconMap[p.icon || 'Brain'];
+ const isSelected = selectedProfileId === p.id;
+ const modelLabel = AVAILABLE_MODELS.find(m => m.value === p.model)?.label;
+ return (
+ handleSelectProfile(p.id)}
+ className="flex cursor-pointer items-center gap-2"
+ >
+
+
+
{p.name}
+
+ {modelLabel} + {p.thinkingLevel}
+
+
+ {isSelected && (
+
+ )}
+
+ );
+ })}
+
+ handleSelectProfile('custom')}
+ className="flex cursor-pointer items-center gap-2"
+ >
+
+
+
Custom...
+
+ Choose model & thinking level
+
+
+ {selectedProfileId === 'custom' && (
+
+ )}
+
+
+
+
+ {showCustomModal && (
+ setShowCustomModal(false)}
+ />
+ )}
+ >
+ );
+}
diff --git a/auto-claude-ui/src/renderer/stores/insights-store.ts b/auto-claude-ui/src/renderer/stores/insights-store.ts
index b2f875a9..09ee971c 100644
--- a/auto-claude-ui/src/renderer/stores/insights-store.ts
+++ b/auto-claude-ui/src/renderer/stores/insights-store.ts
@@ -6,6 +6,7 @@ import type {
InsightsChatStatus,
InsightsStreamChunk,
InsightsToolUsage,
+ InsightsModelConfig,
TaskMetadata,
Task
} from '../../shared/types';
@@ -221,8 +222,9 @@ export async function loadInsightsSession(projectId: string): Promise {
await loadInsightsSessions(projectId);
}
-export function sendMessage(projectId: string, message: string): void {
+export function sendMessage(projectId: string, message: string, modelConfig?: InsightsModelConfig): void {
const store = useInsightsStore.getState();
+ const session = store.session;
// Add user message to session
const userMessage: InsightsChatMessage = {
@@ -242,8 +244,11 @@ export function sendMessage(projectId: string, message: string): void {
message: 'Processing your message...'
});
+ // Use provided modelConfig, or fall back to session's config
+ const configToUse = modelConfig || session?.modelConfig;
+
// Send to main process
- window.electronAPI.sendInsightsMessage(projectId, message);
+ window.electronAPI.sendInsightsMessage(projectId, message, configToUse);
}
export async function clearSession(projectId: string): Promise {
@@ -296,6 +301,25 @@ export async function renameSession(projectId: string, sessionId: string, newTit
return false;
}
+export async function updateModelConfig(projectId: string, sessionId: string, modelConfig: InsightsModelConfig): Promise {
+ const result = await window.electronAPI.updateInsightsModelConfig(projectId, sessionId, modelConfig);
+ if (result.success) {
+ // Update local session state
+ const store = useInsightsStore.getState();
+ if (store.session?.id === sessionId) {
+ store.setSession({
+ ...store.session,
+ modelConfig,
+ updatedAt: new Date()
+ });
+ }
+ // Reload sessions list to reflect the change
+ await loadInsightsSessions(projectId);
+ return true;
+ }
+ return false;
+}
+
export async function createTaskFromSuggestion(
projectId: string,
title: string,
diff --git a/auto-claude-ui/src/shared/constants/ipc.ts b/auto-claude-ui/src/shared/constants/ipc.ts
index f5ec0ab0..dfb3ebda 100644
--- a/auto-claude-ui/src/shared/constants/ipc.ts
+++ b/auto-claude-ui/src/shared/constants/ipc.ts
@@ -248,6 +248,7 @@ export const IPC_CHANNELS = {
INSIGHTS_SWITCH_SESSION: 'insights:switchSession',
INSIGHTS_DELETE_SESSION: 'insights:deleteSession',
INSIGHTS_RENAME_SESSION: 'insights:renameSession',
+ INSIGHTS_UPDATE_MODEL_CONFIG: 'insights:updateModelConfig',
// Insights events (main -> renderer)
INSIGHTS_STREAM_CHUNK: 'insights:streamChunk',
diff --git a/auto-claude-ui/src/shared/constants/models.ts b/auto-claude-ui/src/shared/constants/models.ts
index 3f987f2d..ce832c2c 100644
--- a/auto-claude-ui/src/shared/constants/models.ts
+++ b/auto-claude-ui/src/shared/constants/models.ts
@@ -15,6 +15,22 @@ export const AVAILABLE_MODELS = [
{ value: 'haiku', label: 'Claude Haiku 4.5' }
] as const;
+// Maps model shorthand to actual Claude model IDs
+export const MODEL_ID_MAP: Record = {
+ opus: 'claude-opus-4-5-20251101',
+ sonnet: 'claude-sonnet-4-5-20250929',
+ haiku: 'claude-haiku-4-5-20250929'
+} as const;
+
+// Maps thinking levels to budget tokens (null = no extended thinking)
+export const THINKING_BUDGET_MAP: Record = {
+ none: null,
+ low: 1024,
+ medium: 4096,
+ high: 16384,
+ ultrathink: 65536
+} as const;
+
// ============================================
// Thinking Levels
// ============================================
diff --git a/auto-claude-ui/src/shared/types/insights.ts b/auto-claude-ui/src/shared/types/insights.ts
index c76892fc..ea8903f8 100644
--- a/auto-claude-ui/src/shared/types/insights.ts
+++ b/auto-claude-ui/src/shared/types/insights.ts
@@ -154,6 +154,16 @@ export interface IdeationSummary {
// Insights Chat Types
// ============================================
+import type { ThinkingLevel } from './settings';
+import type { ModelType } from './task';
+
+// Model configuration for insights sessions
+export interface InsightsModelConfig {
+ profileId: string; // 'complex' | 'balanced' | 'quick' | 'custom'
+ model: ModelType; // 'haiku' | 'sonnet' | 'opus'
+ thinkingLevel: ThinkingLevel;
+}
+
export type InsightsChatRole = 'user' | 'assistant';
// Tool usage record for showing what tools the AI used
@@ -183,6 +193,7 @@ export interface InsightsSession {
projectId: string;
title?: string; // Auto-generated from first message or user-set
messages: InsightsChatMessage[];
+ modelConfig?: InsightsModelConfig; // Per-session model configuration
createdAt: Date;
updatedAt: Date;
}
@@ -193,6 +204,7 @@ export interface InsightsSessionSummary {
projectId: string;
title: string;
messageCount: number;
+ modelConfig?: InsightsModelConfig; // For displaying model indicator in sidebar
createdAt: Date;
updatedAt: Date;
}
diff --git a/auto-claude/runners/insights_runner.py b/auto-claude/runners/insights_runner.py
index 55762f2f..81217061 100644
--- a/auto-claude/runners/insights_runner.py
+++ b/auto-claude/runners/insights_runner.py
@@ -128,7 +128,13 @@ Be conversational and helpful. Focus on providing actionable insights and clear
Keep responses concise but informative."""
-async def run_with_sdk(project_dir: str, message: str, history: list) -> None:
+async def run_with_sdk(
+ project_dir: str,
+ message: str,
+ history: list,
+ model: str = "claude-sonnet-4-5-20250929",
+ thinking_level: str = "medium"
+) -> None:
"""Run the chat using Claude SDK with streaming."""
if not SDK_AVAILABLE:
print("Claude SDK not available, falling back to simple mode", file=sys.stderr)
@@ -163,11 +169,18 @@ async def run_with_sdk(project_dir: str, message: str, history: list) -> None:
Current question: {message}"""
+ debug(
+ "insights_runner",
+ "Using model configuration",
+ model=model,
+ thinking_level=thinking_level,
+ )
+
try:
# Create Claude SDK client with appropriate settings for insights
client = ClaudeSDKClient(
options=ClaudeAgentOptions(
- model="claude-opus-4-5-20251101", # Opus 4.5 for quality analysis
+ model=model, # Use configured model
system_prompt=system_prompt,
allowed_tools=[
"Read",
@@ -318,18 +331,33 @@ def main():
parser.add_argument("--project-dir", required=True, help="Project directory path")
parser.add_argument("--message", required=True, help="User message")
parser.add_argument("--history", default="[]", help="JSON conversation history")
+ parser.add_argument(
+ "--model",
+ default="claude-sonnet-4-5-20250929",
+ help="Claude model ID (default: claude-sonnet-4-5-20250929)"
+ )
+ parser.add_argument(
+ "--thinking-level",
+ default="medium",
+ choices=["none", "low", "medium", "high", "ultrathink"],
+ help="Thinking level for extended reasoning (default: medium)"
+ )
args = parser.parse_args()
debug_section("insights_runner", "Starting Insights Chat")
project_dir = args.project_dir
user_message = args.message
+ model = args.model
+ thinking_level = args.thinking_level
debug(
"insights_runner",
"Arguments",
project_dir=project_dir,
message_length=len(user_message),
+ model=model,
+ thinking_level=thinking_level,
)
try:
@@ -341,7 +369,7 @@ def main():
# Run the async SDK function
debug("insights_runner", "Running SDK query")
- asyncio.run(run_with_sdk(project_dir, user_message, history))
+ asyncio.run(run_with_sdk(project_dir, user_message, history, model, thinking_level))
debug_success("insights_runner", "Query completed")