-
Notifications
You must be signed in to change notification settings - Fork 0
Addressing PR comments #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -552,6 +552,49 @@ export function activate(context: vscode.ExtensionContext) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (message.command === 'testConnection') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const testUrl = message.baseUrl || baseUrl; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const testModel = message.model || LLMmodel; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bonsaiLog('Testing connection to:', testUrl, 'with model:', testModel); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| panel.webview.postMessage({ command: 'loading', text: 'Testing connection...' }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Validate URL format (should be host:port/path pattern) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!/^[\w.-]+(:\d+)?(\/[\w./]*)?$/.test(testUrl)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw new Error('Invalid URL format. Expected format: host:port/path (e.g., localhost:1234/v1)'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const res = await fetch(`http://${testUrl}/chat/completions`, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+562
to
+567
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Validate URL format (should be host:port/path pattern) | |
| if (!/^[\w.-]+(:\d+)?(\/[\w./]*)?$/.test(testUrl)) { | |
| throw new Error('Invalid URL format. Expected format: host:port/path (e.g., localhost:1234/v1)'); | |
| } | |
| const res = await fetch(`http://${testUrl}/chat/completions`, { | |
| // Validate URL format (allows optional http/https protocol and host:port/path pattern) | |
| if (!/^(https?:\/\/)?[\w.-]+(:\d+)?(\/[\w./]*)?$/.test(testUrl)) { | |
| throw new Error('Invalid URL format. Expected format: host:port/path (e.g., localhost:1234/v1) or with protocol (e.g., http://localhost:1234/v1)'); | |
| } | |
| const normalizedUrl = testUrl.replace(/^https?:\/\//, ''); | |
| const res = await fetch(`http://${normalizedUrl}/chat/completions`, { |
Copilot
AI
Feb 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The connection test fetch request has no timeout configured. If the LM Studio server is unreachable or not responding, the user may have to wait for the default fetch timeout (which can be very long). Consider adding an AbortController with a reasonable timeout (e.g., 10 seconds) to provide better user experience.
| const res = await fetch(`http://${testUrl}/chat/completions`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': 'Bearer lm-studio', | |
| }, | |
| body: JSON.stringify({ | |
| model: testModel, | |
| messages: [{ role: 'user', content: 'Say "connected" in one word.' }], | |
| temperature: 0, | |
| max_tokens: 10, | |
| stream: false, | |
| }), | |
| }); | |
| const controller = new AbortController(); | |
| const timeoutMs = 10_000; | |
| const timeoutId = setTimeout(() => controller.abort(), timeoutMs); | |
| const res = await (async () => { | |
| try { | |
| return await fetch(`http://${testUrl}/chat/completions`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': 'Bearer lm-studio', | |
| }, | |
| body: JSON.stringify({ | |
| model: testModel, | |
| messages: [{ role: 'user', content: 'Say "connected" in one word.' }], | |
| temperature: 0, | |
| max_tokens: 10, | |
| stream: false, | |
| }), | |
| signal: controller.signal, | |
| }); | |
| } finally { | |
| clearTimeout(timeoutId); | |
| } | |
| })(); |
Copilot
AI
Feb 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The testConnection handler code in extension.ts (lines 555-596) is nearly identical to the code in server.ts (lines 493-534). This duplication makes maintenance harder and increases the risk of bugs when changes are made to one but not the other. Consider extracting this logic into a shared utility function that both files can use, or at minimum document this duplication so future maintainers are aware they need to update both places.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -489,6 +489,49 @@ async function handleMessage(message: any): Promise<void> { | |||||||||||||||||||||||||||
| bonsaiLog('Config updated – baseUrl:', baseUrl, 'model:', LLMmodel); | ||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if (message.command === 'testConnection') { | ||||||||||||||||||||||||||||
| const testUrl = message.baseUrl || baseUrl; | ||||||||||||||||||||||||||||
| const testModel = message.model || LLMmodel; | ||||||||||||||||||||||||||||
| bonsaiLog('Testing connection to:', testUrl, 'with model:', testModel); | ||||||||||||||||||||||||||||
| broadcast({ command: 'loading', text: 'Testing connection...' }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||
| // Validate URL format (should be host:port/path pattern) | ||||||||||||||||||||||||||||
| if (!/^[\w.-]+(:\d+)?(\/[\w./]*)?$/.test(testUrl)) { | ||||||||||||||||||||||||||||
| throw new Error('Invalid URL format. Expected format: host:port/path (e.g., localhost:1234/v1)'); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const res = await fetch(`http://${testUrl}/chat/completions`, { | ||||||||||||||||||||||||||||
|
Comment on lines
+500
to
+505
|
||||||||||||||||||||||||||||
| // Validate URL format (should be host:port/path pattern) | |
| if (!/^[\w.-]+(:\d+)?(\/[\w./]*)?$/.test(testUrl)) { | |
| throw new Error('Invalid URL format. Expected format: host:port/path (e.g., localhost:1234/v1)'); | |
| } | |
| const res = await fetch(`http://${testUrl}/chat/completions`, { | |
| // Normalize and validate URL format (accept optional protocol, ensure host:port/path pattern) | |
| const normalizedTestUrl = testUrl.replace(/^https?:\/\//, ''); | |
| if (!/^(https?:\/\/)?[\w.-]+(:\d+)?(\/[\w./]*)?$/.test(testUrl)) { | |
| throw new Error('Invalid URL format. Expected format similar to: localhost:1234/v1 or http://localhost:1234/v1'); | |
| } | |
| const res = await fetch(`http://${normalizedTestUrl}/chat/completions`, { |
Copilot
AI
Feb 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The connection test fetch request has no timeout configured. If the LM Studio server is unreachable or not responding, the user may have to wait for the default fetch timeout (which can be very long). Consider adding an AbortController with a reasonable timeout (e.g., 10 seconds) to provide better user experience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The placeholder value includes the protocol prefix "http://localhost:1234/v1", but the URL validation regex at line 563 in extension.ts expects URLs without the protocol (host:port/path pattern). This will cause the validation to fail if a user copies the placeholder value. The placeholder should be changed to "localhost:1234/v1" to match the expected format.