11/**
22 * Chat View Provider - Webview for chat interface
33 *
4- * Uses mpp-core's CodingAgent for agent-based interactions
5- * Mirrors mpp-ui's AgentChatInterface and IdeaAgentViewModel architecture
6- *
4+ * Uses mpp-core's JsCodingAgent for agent-based interactions
75 * Configuration is loaded from ~/.autodev/config.yaml (same as CLI and Desktop)
6+ *
7+ * Architecture mirrors:
8+ * - mpp-ui/src/jsMain/typescript/modes/AgentMode.ts
9+ * - mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentViewModel.kt
810 */
911
1012import * as vscode from 'vscode' ;
1113import { ConfigManager , AutoDevConfigWrapper , LLMConfig } from '../services/config-manager' ;
1214
13- // Import mpp-core bridge
1415// @ts -ignore - Kotlin/JS generated module
1516import MppCore from '@autodev/mpp-core' ;
1617
17- const { JsKoogLLMService , JsModelConfig } = MppCore . cc . unitmesh . llm ;
18- const { JsCodingAgent , JsAgentTask } = MppCore . cc . unitmesh . agent ;
18+ // Access Kotlin/JS exports - same pattern as AgentMode.ts
19+ const KotlinCC = MppCore . cc . unitmesh ;
1920
2021/**
2122 * Chat View Provider for the sidebar webview
@@ -64,13 +65,56 @@ export class ChatViewProvider implements vscode.WebviewViewProvider {
6465 case 'openConfig' :
6566 await this . openConfigFile ( ) ;
6667 break ;
68+ case 'stopExecution' :
69+ this . stopExecution ( ) ;
70+ break ;
71+ case 'selectConfig' :
72+ await this . selectConfig ( message . data ?. configName as string ) ;
73+ break ;
6774 }
6875 } ) ;
6976
7077 // Initialize agent from config file
7178 this . initializeFromConfig ( ) ;
7279 }
7380
81+ /**
82+ * Stop current execution
83+ */
84+ private stopExecution ( ) : void {
85+ if ( this . isExecuting ) {
86+ this . isExecuting = false ;
87+ this . postMessage ( { type : 'taskComplete' , data : { success : false , message : 'Stopped by user' } } ) ;
88+ this . log ( 'Execution stopped by user' ) ;
89+ }
90+ }
91+
92+ /**
93+ * Select a different config
94+ */
95+ private async selectConfig ( configName : string ) : Promise < void > {
96+ if ( ! this . configWrapper || ! configName ) return ;
97+
98+ const configs = this . configWrapper . getAllConfigs ( ) ;
99+ const selectedConfig = configs . find ( c => c . name === configName ) ;
100+
101+ if ( selectedConfig ) {
102+ // Recreate LLM service with new config
103+ this . llmService = this . createLLMService ( selectedConfig ) ;
104+ this . codingAgent = null ; // Reset agent to use new LLM service
105+
106+ this . log ( `Switched to config: ${ configName } ` ) ;
107+
108+ // Send updated config state to webview
109+ this . sendConfigUpdate ( configName ) ;
110+
111+ this . postMessage ( {
112+ type : 'responseChunk' ,
113+ content : `✨ Switched to: \`${ selectedConfig . name } \` (${ selectedConfig . provider } /${ selectedConfig . model } )`
114+ } ) ;
115+ }
116+ }
117+
74118 /**
75119 * Send a message programmatically
76120 */
@@ -88,6 +132,28 @@ export class ChatViewProvider implements vscode.WebviewViewProvider {
88132 this . webviewView ?. webview . postMessage ( message ) ;
89133 }
90134
135+ /**
136+ * Send config update to webview
137+ */
138+ private sendConfigUpdate ( currentConfigName ?: string ) : void {
139+ if ( ! this . configWrapper ) return ;
140+
141+ const configs = this . configWrapper . getAllConfigs ( ) ;
142+ const availableConfigs = configs . map ( c => ( {
143+ name : c . name ,
144+ provider : c . provider ,
145+ model : c . model
146+ } ) ) ;
147+
148+ this . postMessage ( {
149+ type : 'configUpdate' ,
150+ data : {
151+ availableConfigs,
152+ currentConfigName : currentConfigName || this . configWrapper . getActiveConfig ( ) ?. name || null
153+ }
154+ } ) ;
155+ }
156+
91157 /**
92158 * Initialize from ~/.autodev/config.yaml
93159 * Mirrors IdeaAgentViewModel.loadConfiguration()
@@ -97,6 +163,9 @@ export class ChatViewProvider implements vscode.WebviewViewProvider {
97163 this . configWrapper = await ConfigManager . load ( ) ;
98164 const activeConfig = this . configWrapper . getActiveConfig ( ) ;
99165
166+ // Send config state to webview
167+ this . sendConfigUpdate ( ) ;
168+
100169 if ( ! activeConfig || ! this . configWrapper . isValid ( ) ) {
101170 this . log ( 'No valid configuration found in ~/.autodev/config.yaml' ) ;
102171 // Show welcome message with config instructions
@@ -125,23 +194,25 @@ export class ChatViewProvider implements vscode.WebviewViewProvider {
125194
126195 /**
127196 * Create LLM service from config
197+ * Same pattern as AgentMode.ts
128198 */
129199 private createLLMService ( config : LLMConfig ) : any {
130- const modelConfig = new JsModelConfig (
131- config . provider . toUpperCase ( ) ,
200+ const modelConfig = new KotlinCC . llm . JsModelConfig (
201+ config . provider , // Use lowercase provider name like AgentMode.ts
132202 config . model ,
133203 config . apiKey || '' ,
134204 config . temperature ?? 0.7 ,
135205 config . maxTokens ?? 8192 ,
136206 config . baseUrl || ''
137207 ) ;
138- return new JsKoogLLMService ( modelConfig ) ;
208+ return new KotlinCC . llm . JsKoogLLMService ( modelConfig ) ;
139209 }
140210
141211 /**
142212 * Initialize CodingAgent (lazy initialization)
213+ * Same pattern as AgentMode.ts
143214 */
144- private async initializeCodingAgent ( ) : Promise < any > {
215+ private initializeCodingAgent ( ) : any {
145216 if ( this . codingAgent ) {
146217 return this . codingAgent ;
147218 }
@@ -150,13 +221,14 @@ export class ChatViewProvider implements vscode.WebviewViewProvider {
150221 throw new Error ( 'LLM service not configured. Please configure ~/.autodev/config.yaml' ) ;
151222 }
152223
153- const workspacePath = vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri . fsPath || '' ;
224+ const workspacePath = vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri . fsPath || process . cwd ( ) ;
154225 const mcpServers = this . configWrapper ?. getEnabledMcpServers ( ) || { } ;
155226
156227 // Create renderer that forwards events to webview
157228 const renderer = this . createRenderer ( ) ;
158229
159- this . codingAgent = new JsCodingAgent (
230+ // Create CodingAgent - same constructor as AgentMode.ts
231+ this . codingAgent = new KotlinCC . agent . JsCodingAgent (
160232 workspacePath ,
161233 this . llmService ,
162234 10 , // maxIterations
@@ -258,15 +330,15 @@ export class ChatViewProvider implements vscode.WebviewViewProvider {
258330
259331 try {
260332 // Initialize agent if needed
261- const agent = await this . initializeCodingAgent ( ) ;
262- const workspacePath = vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri . fsPath || '' ;
333+ const agent = this . initializeCodingAgent ( ) ;
334+ const workspacePath = vscode . workspace . workspaceFolders ?. [ 0 ] ?. uri . fsPath || process . cwd ( ) ;
263335
264- // Create task and execute
265- const task = new JsAgentTask ( trimmedContent , workspacePath ) ;
336+ // Create task and execute - same pattern as AgentMode.ts
337+ const task = new KotlinCC . agent . JsAgentTask ( trimmedContent , workspacePath ) ;
266338 const result = await agent . executeTask ( task ) ;
267339
268340 // Add completion message
269- if ( result . message ) {
341+ if ( result && result . message ) {
270342 this . messages . push ( { role : 'assistant' , content : result . message } ) ;
271343 }
272344
0 commit comments