Skip to content

Commit 7b90c82

Browse files
committed
refactor: extract model config info logic to service layer and improve type exports
Move getModelConfigsInfo implementation from SimpleCodeGeneratorAgent to ModelConfigService for better separation of concerns. Export ModelConfigsInfoMessage, AgentDisplayConfig, and ModelConfigsInfo types from websocketTypes for frontend consumption. Remove duplicate AgentDisplayConfig interface from model-config-tabs.tsx. Add blueprint_chunk WebSocket message type. Remove 'advanced' workflow tab and update agent
1 parent 38b0e8a commit 7b90c82

File tree

8 files changed

+82
-106
lines changed

8 files changed

+82
-106
lines changed

src/api-types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,10 @@ export type {
115115
export type {
116116
WebSocketMessage,
117117
WebSocketMessageData,
118-
CodeFixEdits
118+
CodeFixEdits,
119+
ModelConfigsInfoMessage,
120+
AgentDisplayConfig,
121+
ModelConfigsInfo
119122
} from 'worker/api/websocketTypes';
120123

121124
// Database/Schema Types commonly used in frontend

src/components/config-card.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import { Button } from '@/components/ui/button';
33
import { Badge } from '@/components/ui/badge';
44
import { Card, CardContent, CardHeader } from '@/components/ui/card';
55
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
6-
import type { ModelConfig, UserModelConfigWithMetadata } from '@/api-types';
7-
import type { AgentDisplayConfig } from './model-config-tabs';
6+
import type { AgentDisplayConfig, ModelConfig, UserModelConfigWithMetadata } from '@/api-types';
87

98
interface ConfigCardProps {
109
agent: AgentDisplayConfig;

src/components/config-modal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ import type {
2929
UserModelConfigWithMetadata,
3030
ModelConfigUpdate,
3131
AIModels,
32-
ByokProvidersData
32+
ByokProvidersData,
33+
AgentDisplayConfig
3334
} from '@/api-types';
34-
import type { AgentDisplayConfig } from './model-config-tabs';
3535

3636
interface ConfigModalProps {
3737
isOpen: boolean;

src/components/model-config-tabs.tsx

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { useState, useCallback } from 'react';
22
import {
33
Settings,
44
Rocket,
5-
Wrench,
65
Code,
76
Bug,
87
Brain,
@@ -17,7 +16,7 @@ import { Badge } from '@/components/ui/badge';
1716
import { toast } from 'sonner';
1817
import { ConfigCard } from './config-card';
1918
import { ConfigModal } from './config-modal';
20-
import type { ModelConfig, UserModelConfigWithMetadata, ModelConfigUpdate } from '@/api-types';
19+
import type { ModelConfig, UserModelConfigWithMetadata, ModelConfigUpdate, AgentDisplayConfig } from '@/api-types';
2120

2221
// Define workflow-based tab structure with dynamic agent categorization
2322
export const WORKFLOW_TABS = {
@@ -49,13 +48,6 @@ export const WORKFLOW_TABS = {
4948
description: 'Code fixing and review',
5049
patterns: ['fixer', 'fix', 'review', 'debug']
5150
},
52-
advanced: {
53-
id: 'advanced',
54-
label: 'Advanced',
55-
icon: Wrench,
56-
description: 'Specialized operations',
57-
patterns: ['screenshot', 'analysis', 'image', 'vision']
58-
}
5951
} as const;
6052

6153
// Helper function to categorize agents dynamically with specific mappings
@@ -64,11 +56,11 @@ const categorizeAgent = (agentKey: string): string => {
6456
const specificMappings: Record<string, string> = {
6557
// Quick Start - Most commonly used
6658
'templateSelection': 'quickstart',
67-
'blueprint': 'quickstart',
6859
'conversationalResponse': 'quickstart',
6960

7061
// Planning - Project planning and setup
7162
'phaseGeneration': 'planning',
63+
'blueprint': 'quickstart',
7264
'projectSetup': 'planning',
7365

7466
// Coding - Development and implementation
@@ -77,12 +69,7 @@ const categorizeAgent = (agentKey: string): string => {
7769
'fileRegeneration': 'coding', // Fix: was going to planning due to "generation"
7870

7971
// Debugging - Code fixing and review
80-
'realtimeCodeFixer': 'debugging',
81-
'fastCodeFixer': 'debugging',
82-
'codeReview': 'debugging',
83-
84-
// Advanced - Specialized operations
85-
'screenshotAnalysis': 'advanced'
72+
'deepDebugger': 'debugging',
8673
};
8774

8875
// Check specific mappings first
@@ -117,17 +104,6 @@ const categorizeAgent = (agentKey: string): string => {
117104
return 'advanced';
118105
};
119106

120-
// Frontend-specific agent display interface
121-
export interface AgentDisplayConfig {
122-
key: string;
123-
name: string;
124-
description: string;
125-
constraint?: {
126-
enabled: boolean;
127-
allowedModels: string[];
128-
};
129-
}
130-
131107
interface ModelConfigTabsProps {
132108
agentConfigs: AgentDisplayConfig[];
133109
modelConfigs: Record<string, UserModelConfigWithMetadata>;

src/routes/chat/components/model-config-info.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ import {
1010
DialogHeader,
1111
DialogTitle,
1212
} from '@/components/ui/dialog';
13-
import type { ModelConfig, UserModelConfigWithMetadata } from '@/api-types';
14-
import type { AgentDisplayConfig } from '@/components/model-config-tabs';
13+
import type { AgentDisplayConfig, ModelConfig, UserModelConfigWithMetadata } from '@/api-types';
1514

1615
// Reuse workflow tabs from settings (DRY principle)
1716
const WORKFLOW_TABS = {

worker/agents/core/simpleGeneratorAgent.ts

Lines changed: 4 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ import { ScreenshotAnalysisOperation } from '../operations/ScreenshotAnalysis';
3030
// Database schema imports removed - using zero-storage OAuth flow
3131
import { BaseSandboxService } from '../../services/sandbox/BaseSandboxService';
3232
import { WebSocketMessageData, WebSocketMessageType } from '../../api/websocketTypes';
33-
import { InferenceContext, AgentActionKey, ModelConfig } from '../inferutils/config.types';
34-
import { AGENT_CONFIG, AGENT_CONSTRAINTS } from '../inferutils/config';
33+
import { InferenceContext, ModelConfig } from '../inferutils/config.types';
3534
import { ModelConfigService } from '../../database/services/ModelConfigService';
3635
import { fixProjectIssues } from '../../services/code-fixer';
3736
import { GitVersionControl } from '../git';
@@ -1344,73 +1343,9 @@ export class SimpleCodeGeneratorAgent extends Agent<Env, CodeGenState> {
13441343
};
13451344
}
13461345

1347-
/**
1348-
* Get current model configurations (defaults + user overrides)
1349-
* Used by WebSocket to provide configuration info to frontend
1350-
*/
1351-
async getModelConfigsInfo() {
1352-
const userId = this.state.inferenceContext.userId;
1353-
if (!userId) {
1354-
throw new Error('No user session available for model configurations');
1355-
}
1356-
1357-
try {
1358-
const modelConfigService = new ModelConfigService(this.env);
1359-
1360-
// Get all user configs
1361-
const userConfigsRecord = await modelConfigService.getUserModelConfigs(userId);
1362-
1363-
// Transform to match frontend interface with constraint info
1364-
const agents = Object.entries(AGENT_CONFIG).map(([key, config]) => {
1365-
const constraint = AGENT_CONSTRAINTS.get(key as AgentActionKey);
1366-
return {
1367-
key,
1368-
name: config.name,
1369-
description: config.description,
1370-
constraint: constraint ? {
1371-
enabled: constraint.enabled,
1372-
allowedModels: Array.from(constraint.allowedModels)
1373-
} : undefined
1374-
};
1375-
});
1376-
1377-
const userConfigs: Record<string, any> = {};
1378-
const defaultConfigs: Record<string, any> = {};
1379-
1380-
for (const [actionKey, mergedConfig] of Object.entries(userConfigsRecord)) {
1381-
if (mergedConfig.isUserOverride) {
1382-
userConfigs[actionKey] = {
1383-
name: mergedConfig.name,
1384-
max_tokens: mergedConfig.max_tokens,
1385-
temperature: mergedConfig.temperature,
1386-
reasoning_effort: mergedConfig.reasoning_effort,
1387-
fallbackModel: mergedConfig.fallbackModel,
1388-
isUserOverride: true
1389-
};
1390-
}
1391-
1392-
// Always include default config
1393-
const defaultConfig = AGENT_CONFIG[actionKey as AgentActionKey];
1394-
if (defaultConfig) {
1395-
defaultConfigs[actionKey] = {
1396-
name: defaultConfig.name,
1397-
max_tokens: defaultConfig.max_tokens,
1398-
temperature: defaultConfig.temperature,
1399-
reasoning_effort: defaultConfig.reasoning_effort,
1400-
fallbackModel: defaultConfig.fallbackModel
1401-
};
1402-
}
1403-
}
1404-
1405-
return {
1406-
agents,
1407-
userConfigs,
1408-
defaultConfigs
1409-
};
1410-
} catch (error) {
1411-
this.logger().error('Error fetching model configs info:', error);
1412-
throw error;
1413-
}
1346+
getModelConfigsInfo() {
1347+
const modelService = new ModelConfigService(this.env);
1348+
return modelService.getModelConfigsInfo(this.state.inferenceContext.userId);
14141349
}
14151350

14161351
getTotalFiles(): number {

worker/api/websocketTypes.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,11 @@ type BlueprintUpdatedMessage = {
352352
updatedKeys: string[];
353353
};
354354

355+
type BlueprintChunkMessage = {
356+
type: 'blueprint_chunk';
357+
chunk: string;
358+
};
359+
355360
type DeterministicCodeFixStartedMessage = {
356361
type: 'deterministic_code_fix_started';
357362
message: string;
@@ -365,14 +370,18 @@ type DeterministicCodeFixCompletedMessage = {
365370
issues: CodeIssue[];
366371
};
367372

368-
type ModelConfigsInfoMessage = {
373+
export type ModelConfigsInfoMessage = {
369374
type: 'model_configs_info';
370375
message: string;
371376
configs: {
372377
agents: Array<{
373378
key: string;
374379
name: string;
375380
description: string;
381+
constraint?: {
382+
enabled: boolean;
383+
allowedModels: string[];
384+
};
376385
}>;
377386
userConfigs: Record<string, {
378387
name?: string;
@@ -392,6 +401,9 @@ type ModelConfigsInfoMessage = {
392401
};
393402
};
394403

404+
export type AgentDisplayConfig = ModelConfigsInfoMessage['configs']['agents'][number];
405+
export type ModelConfigsInfo = ModelConfigsInfoMessage['configs'];
406+
395407
type TerminalCommandMessage = {
396408
type: 'terminal_command';
397409
command: string;
@@ -462,6 +474,7 @@ export type WebSocketMessage =
462474
| ConversationClearedMessage
463475
| ProjectNameUpdatedMessage
464476
| BlueprintUpdatedMessage
477+
| BlueprintChunkMessage
465478
| DeterministicCodeFixStartedMessage
466479
| DeterministicCodeFixCompletedMessage
467480
| ModelConfigsInfoMessage
@@ -478,4 +491,4 @@ type WebSocketMessagePayload<T extends WebSocketMessageType> = Extract<WebSocket
478491

479492
// A utility type to get only the data part of the payload, excluding the 'type' property.
480493
// This is what your 'data' parameter will be.
481-
export type WebSocketMessageData<T extends WebSocketMessageType> = Omit<WebSocketMessagePayload<T>, 'type'>;
494+
export type WebSocketMessageData<T extends WebSocketMessageType> = Omit<WebSocketMessagePayload<T>, 'type'>;

worker/database/services/ModelConfigService.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { BaseService } from './BaseService';
77
import { UserModelConfig, NewUserModelConfig, userModelConfigs } from '../schema';
88
import { eq, and } from 'drizzle-orm';
99
import { AgentActionKey, ModelConfig } from '../../agents/inferutils/config.types';
10-
import { AGENT_CONFIG } from '../../agents/inferutils/config';
10+
import { AGENT_CONFIG, AGENT_CONSTRAINTS } from '../../agents/inferutils/config';
1111
import type { ReasoningEffort } from 'openai/resources.mjs';
1212
import { generateId } from '../../utils/idGenerator';
1313
import type { UserModelConfigWithMetadata } from '../types';
@@ -206,6 +206,57 @@ export class ModelConfigService extends BaseService {
206206
};
207207
}
208208

209+
/**
210+
* Get current model configurations (defaults + user overrides)
211+
* Used by WebSocket to provide configuration info to frontend
212+
*/
213+
async getModelConfigsInfo(userId: string) {
214+
if (!userId) {
215+
throw new Error('No user session available for model configurations');
216+
}
217+
218+
try {
219+
// Get all user configs
220+
const userConfigsRecord = await this.getUserModelConfigs(userId);
221+
222+
// Transform to match frontend interface with constraint info
223+
const agents = Object.entries(AGENT_CONFIG).map(([key, config]) => {
224+
const constraint = AGENT_CONSTRAINTS.get(key as AgentActionKey);
225+
return {
226+
key,
227+
name: config.name,
228+
description: config.description,
229+
constraint: constraint ? {
230+
enabled: constraint.enabled,
231+
allowedModels: Array.from(constraint.allowedModels)
232+
} : undefined
233+
};
234+
});
235+
236+
const userModelConfigs: Record<string, ModelConfig> = {}
237+
const defaultConfigs: Record<string, ModelConfig> = {};
238+
for (const [actionKey, mergedConfig] of Object.entries(userConfigsRecord)) {
239+
if (mergedConfig.isUserOverride) {
240+
const { isUserOverride, userConfigId, ...modelConfig } = mergedConfig;
241+
userModelConfigs[actionKey] = modelConfig;
242+
}
243+
const defaultConfig = AGENT_CONFIG[actionKey as AgentActionKey];
244+
if (defaultConfig) {
245+
defaultConfigs[actionKey] = defaultConfig;
246+
}
247+
}
248+
249+
return {
250+
agents,
251+
userConfigs: userModelConfigs,
252+
defaultConfigs
253+
};
254+
} catch (error) {
255+
console.error('Error fetching model configs info:', error);
256+
throw error;
257+
}
258+
}
259+
209260
/**
210261
* Update or create a user model configuration.
211262
* Validates constraints - throws on violation.

0 commit comments

Comments
 (0)