@@ -26,19 +26,15 @@ import com.google.gson.JsonObject
2626
2727/* *
2828 * Main tool window content for PicoCode RAG Assistant
29- * Handles server lifecycle, API key management, and streaming responses
29+ * Communicates with PicoCode backend only (no direct OpenAI calls)
3030 */
3131class PicoCodeToolWindowContent (private val project : Project ) {
32- private val serverPort = 8000
33- private val serverHost = " localhost"
32+ // PicoCode server configuration
33+ private val serverHostField = JBTextField (" localhost" )
34+ private val serverPortField = JBTextField (" 8000" )
3435 private var serverProcess: Process ? = null
35- private var wsClient: WebSocketClient ? = null
3636
3737 // UI Components
38- private val apiKeyField = JPasswordField (20 )
39- private val apiBaseField = JBTextField (" https://api.openai.com/v1" )
40- private val embeddingModelField = JBTextField (" text-embedding-3-small" )
41- private val codingModelField = JBTextField (" gpt-4" )
4238 private val queryField = JBTextArea (3 , 40 )
4339 private val responseArea = JBTextArea (20 , 40 )
4440 private val statusLabel = JLabel (" Server: Not running" )
@@ -53,20 +49,18 @@ class PicoCodeToolWindowContent(private val project: Project) {
5349 retrievedFilesPanel.layout = BoxLayout (retrievedFilesPanel, BoxLayout .Y_AXIS )
5450 progressBar.isIndeterminate = false
5551 progressBar.isVisible = false
56-
57- // Load saved API key from IDE password safe
58- loadApiKey()
5952 }
6053
54+ private fun getServerHost (): String = serverHostField.text.trim()
55+ private fun getServerPort (): Int = serverPortField.text.trim().toIntOrNull() ? : 8000
56+
6157 fun getContent (): JComponent {
6258 val panel = JPanel (BorderLayout ())
6359
64- // Top panel with configuration
60+ // Top panel with PicoCode server configuration
6561 val configPanel = FormBuilder .createFormBuilder()
66- .addLabeledComponent(" API Base URL:" , apiBaseField)
67- .addLabeledComponent(" API Key:" , apiKeyField)
68- .addLabeledComponent(" Embedding Model:" , embeddingModelField)
69- .addLabeledComponent(" Coding Model:" , codingModelField)
62+ .addLabeledComponent(" PicoCode Host:" , serverHostField)
63+ .addLabeledComponent(" PicoCode Port:" , serverPortField)
7064 .panel
7165
7266 // Control buttons
@@ -75,7 +69,6 @@ class PicoCodeToolWindowContent(private val project: Project) {
7569 val stopServerBtn = JButton (" Stop Server" )
7670 val indexProjectBtn = JButton (" Index Project" )
7771 val queryBtn = JButton (" Query" )
78- val saveApiKeyBtn = JButton (" Save API Key" )
7972
8073 stopServerBtn.isEnabled = false
8174 indexProjectBtn.isEnabled = false
@@ -97,11 +90,6 @@ class PicoCodeToolWindowContent(private val project: Project) {
9790 queryBtn.isEnabled = false
9891 }
9992
100- saveApiKeyBtn.addActionListener {
101- saveApiKey()
102- JOptionPane .showMessageDialog(panel, " API Key saved securely" )
103- }
104-
10593 indexProjectBtn.addActionListener {
10694 indexProject()
10795 }
@@ -114,7 +102,6 @@ class PicoCodeToolWindowContent(private val project: Project) {
114102 buttonPanel.add(stopServerBtn)
115103 buttonPanel.add(indexProjectBtn)
116104 buttonPanel.add(queryBtn)
117- buttonPanel.add(saveApiKeyBtn)
118105
119106 // Query panel
120107 val queryPanel = JPanel (BorderLayout ())
@@ -158,6 +145,8 @@ class PicoCodeToolWindowContent(private val project: Project) {
158145 */
159146 private fun startServer () {
160147 val projectPath = project.basePath ? : return
148+ val host = getServerHost()
149+ val port = getServerPort()
161150
162151 statusLabel.text = " Server: Starting..."
163152
@@ -192,7 +181,7 @@ class PicoCodeToolWindowContent(private val project: Project) {
192181 Thread .sleep(3000 )
193182
194183 SwingUtilities .invokeLater {
195- statusLabel.text = " Server: Running on http://$serverHost : $serverPort "
184+ statusLabel.text = " Server: Running on http://$host : $port "
196185 }
197186 } catch (e: Exception ) {
198187 SwingUtilities .invokeLater {
@@ -209,25 +198,25 @@ class PicoCodeToolWindowContent(private val project: Project) {
209198 private fun stopServer () {
210199 serverProcess?.destroy()
211200 serverProcess = null
212- wsClient?.close()
213- wsClient = null
214201 statusLabel.text = " Server: Stopped"
215202 }
216203
217204 /* *
218- * Index the current project
205+ * Index the current project via PicoCode backend
219206 */
220207 private fun indexProject () {
221208 val projectPath = project.basePath ? : return
222- val storeDir = File (projectPath, " .local_rag" ).absolutePath
209+ val host = getServerHost()
210+ val port = getServerPort()
223211
224212 progressBar.isVisible = true
225213 progressBar.isIndeterminate = true
226214 statusLabel.text = " Indexing project..."
227215
228216 ApplicationManager .getApplication().executeOnPooledThread {
229217 try {
230- val url = URL (" http://$serverHost :$serverPort /api/projects" )
218+ // Create/get project
219+ val url = URL (" http://$host :$port /api/projects" )
231220 val connection = url.openConnection() as HttpURLConnection
232221 connection.requestMethod = " POST"
233222 connection.setRequestProperty(" Content-Type" , " application/json" )
@@ -248,7 +237,7 @@ class PicoCodeToolWindowContent(private val project: Project) {
248237 val projectId = jsonResponse.get(" id" ).asString
249238
250239 // Start indexing
251- val indexUrl = URL (" http://$serverHost : $serverPort /api/projects/index" )
240+ val indexUrl = URL (" http://$host : $port /api/projects/index" )
252241 val indexConnection = indexUrl.openConnection() as HttpURLConnection
253242 indexConnection.requestMethod = " POST"
254243 indexConnection.setRequestProperty(" Content-Type" , " application/json" )
@@ -262,7 +251,7 @@ class PicoCodeToolWindowContent(private val project: Project) {
262251 SwingUtilities .invokeLater {
263252 progressBar.isVisible = false
264253 statusLabel.text = " Project indexed successfully"
265- JOptionPane .showMessageDialog(null , " Project indexed. Store: $storeDir " )
254+ JOptionPane .showMessageDialog(null , " Project indexed successfully " )
266255 }
267256 } else {
268257 throw Exception (" Server returned error: $responseCode - $response " )
@@ -278,7 +267,7 @@ class PicoCodeToolWindowContent(private val project: Project) {
278267 }
279268
280269 /* *
281- * Execute a query with WebSocket streaming
270+ * Execute a query via PicoCode backend /code endpoint
282271 */
283272 private fun executeQuery () {
284273 val query = queryField.text.trim()
@@ -288,25 +277,27 @@ class PicoCodeToolWindowContent(private val project: Project) {
288277 }
289278
290279 val projectPath = project.basePath ? : return
280+ val host = getServerHost()
281+ val port = getServerPort()
291282
292283 responseArea.text = " "
293284 retrievedFilesPanel.removeAll()
294285 statusLabel.text = " Querying..."
295286
296- // Get project ID first
297287 ApplicationManager .getApplication().executeOnPooledThread {
298288 try {
299- // Get projects list to find our project
300- val projectsUrl = URL (" http://$serverHost : $serverPort /api/projects" )
289+ // Get project ID first
290+ val projectsUrl = URL (" http://$host : $port /api/projects" )
301291 val connection = projectsUrl.openConnection() as HttpURLConnection
302292 val projectsResponse = connection.inputStream.bufferedReader().readText()
303293 val projects = gson.fromJson(projectsResponse, Array <JsonObject >::class .java)
304294
305295 val currentProject = projects.find { it.get(" path" ).asString == projectPath }
306- val projectId = currentProject?.get(" id" )?.asString ? : throw Exception (" Project not found" )
296+ val projectId = currentProject?.get(" id" )?.asString
297+ ? : throw Exception (" Project not indexed. Please index first." )
307298
308- // Use synchronous query endpoint (WebSocket would require additional dependencies )
309- val queryUrl = URL (" http://$serverHost : $serverPort /api /code" )
299+ // Use /code endpoint with project_id (backend will handle finding the analysis )
300+ val queryUrl = URL (" http://$host : $port /code" )
310301 val queryConnection = queryUrl.openConnection() as HttpURLConnection
311302 queryConnection.requestMethod = " POST"
312303 queryConnection.setRequestProperty(" Content-Type" , " application/json" )
@@ -372,37 +363,4 @@ class PicoCodeToolWindowContent(private val project: Project) {
372363 }
373364 }
374365 }
375-
376- /* *
377- * Load API key from IDE password safe
378- */
379- private fun loadApiKey () {
380- try {
381- val credentials = PasswordSafe .instance.get(
382- com.intellij.credentialStore.CredentialAttributes (
383- " PicoCodeAPIKey" ,
384- " api_key"
385- )
386- )
387- credentials?.getPasswordAsString()?.let {
388- apiKeyField.text = it
389- }
390- } catch (e: Exception ) {
391- // API key not found or error, use empty
392- }
393- }
394-
395- /* *
396- * Save API key to IDE password safe
397- */
398- private fun saveApiKey () {
399- val apiKey = String (apiKeyField.password)
400- PasswordSafe .instance.setPassword(
401- com.intellij.credentialStore.CredentialAttributes (
402- " PicoCodeAPIKey" ,
403- " api_key"
404- ),
405- apiKey
406- )
407- }
408366}
0 commit comments