Skip to content

Addressing PR comments#7

Merged
raux merged 3 commits into
mainfrom
copilot/add-url-connection-test-button
Feb 23, 2026
Merged

Addressing PR comments#7
raux merged 3 commits into
mainfrom
copilot/add-url-connection-test-button

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 23, 2026


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: raux <5723643+raux@users.noreply.github.com>
@raux
Copy link
Copy Markdown
Owner

raux commented Feb 23, 2026

@codex[agent]

…lity

Co-authored-by: raux <5723643+raux@users.noreply.github.com>
Copilot AI changed the title [WIP] Add button to test LM Studio URL connection and model response Add Test Connection button for LM Studio URL verification Feb 23, 2026
Copilot AI requested a review from raux February 23, 2026 04:17
@Codex Codex AI changed the title Add Test Connection button for LM Studio URL verification Addressing PR comments Feb 23, 2026
@raux raux marked this pull request as ready for review February 23, 2026 04:24
Copilot AI review requested due to automatic review settings February 23, 2026 04:24
@raux raux merged commit 3c35713 into main Feb 23, 2026
1 check passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a "Test Connection" feature to the BonsAIDE application, allowing users to verify connectivity to their LM Studio server before performing operations. The feature is implemented for both the VSCode extension and standalone web server modes.

Changes:

  • Adds test connection button and status display to the UI (webview and client interfaces)
  • Implements backend logic to validate URL format and send a minimal test request to LM Studio
  • Provides visual feedback (success/error/testing states) via color-coded status messages

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/server.ts Adds testConnection command handler for standalone server mode with URL validation and LLM test request
src/extension.ts Adds testConnection command handler for VSCode extension mode with URL validation and LLM test request
media/webview.html Adds test connection button, status span, and styling for the VSCode extension webview UI
client/index.html Adds test connection button and status span for the standalone web client UI
client/js/app.js Implements click handler for test connection button and result message handling
client/css/styles.css Adds CSS styling for connection test status states (testing, success, error)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread media/webview.html
<div style="margin:6px 0; display:flex; flex-wrap:wrap; gap:8px;">
<div style="margin:6px 0; display:flex; flex-wrap:wrap; gap:8px; align-items:center;">
<label>LM_Studio URL:
<input id="baseUrlInput" type="text" size="40" placeholder="http://localhost:1234/v1" />
Copy link

Copilot AI Feb 23, 2026

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.

Suggested change
<input id="baseUrlInput" type="text" size="40" placeholder="http://localhost:1234/v1" />
<input id="baseUrlInput" type="text" size="40" placeholder="localhost:1234/v1" />

Copilot uses AI. Check for mistakes.
Comment thread src/extension.ts
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`, {
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL validation regex rejects URLs that contain the protocol prefix. However, looking at extension.ts line 899, there's code that uses a default URL with the "http://" protocol prefix ("http://10.184.201.141:1234/v1"). The regex should either be updated to optionally accept the protocol prefix, or all code should be consistent about expecting URLs without the protocol. Consider updating the regex to: /^(https?://)?[\w.-]+(:\d+)?(/[\w./]*)?$/ and strip the protocol before prepending "http://" in the fetch call.

Suggested change
// 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 uses AI. Check for mistakes.
Comment thread src/server.ts
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`, {
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL validation regex rejects URLs that contain the protocol prefix. However, the media/webview.html placeholder shows "http://localhost:1234/v1" (with protocol). The regex should either be updated to optionally accept the protocol prefix, or all code should be consistent about expecting URLs without the protocol. Consider updating the regex to: /^(https?://)?[\w.-]+(:\d+)?(/[\w./]*)?$/ and strip the protocol before prepending "http://" in the fetch call.

Suggested change
// 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 uses AI. Check for mistakes.
Comment thread src/extension.ts
Comment on lines +567 to +581
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,
}),
});

Copy link

Copilot AI Feb 23, 2026

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.

Suggested change
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 uses AI. Check for mistakes.
Comment thread src/server.ts
Comment on lines +505 to +518
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,
}),
});
Copy link

Copilot AI Feb 23, 2026

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.

Copilot uses AI. Check for mistakes.
Comment thread src/extension.ts
Comment on lines +555 to +596
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`, {
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,
}),
});

if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(`HTTP ${res.status} ${res.statusText}${text ? ` - ${text}` : ''}`);
}

const json: any = await res.json();
const output = json?.choices?.[0]?.message?.content?.trim?.() ?? '';
bonsaiLog('Connection test successful. Response:', output);
panel.webview.postMessage({ command: 'connectionTestResult', success: true, message: `✓ Connected! Model responded: "${output}"` });
} catch (err: any) {
bonsaiLog('Connection test failed:', err?.message || err);
panel.webview.postMessage({ command: 'connectionTestResult', success: false, message: `✗ Connection failed: ${err?.message || err}` });
}
return;
}
Copy link

Copilot AI Feb 23, 2026

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.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants