Skip to content

[codex] Fix chat framework safety and preset switching - #3

Merged
mc3545dada merged 3 commits into
mainfrom
codex/fix-chat-framework-issues
May 6, 2026
Merged

mc3545dada merged 3 commits into
mainfrom
codex/fix-chat-framework-issues

Conversation

@mc3545dada

Copy link
Copy Markdown
Owner

What changed

  • Bind the local server to 127.0.0.1 by default and restrict CORS to local origins plus optional ALLOWED_ORIGINS.
  • Normalize OpenAI-compatible API URLs and fetch models from /v1/models first.
  • Add chat fallback retries for providers that reject image parts or thinking/reasoning parameters.
  • Align upload UI with the file types the app can actually parse/send.
  • Fix regenerate so it does not duplicate the previous user message.
  • Restore API preset switching with API keys, and prevent loading presets that no longer contain a key.

Why

The app had a few rough edges that could cause local API key exposure, model-list failures, bad provider compatibility, unsupported uploads, duplicated history entries, and 401s when presets were missing their own API key.

Validation

  • node --check frontend/js/app.js
  • npm.cmd run check
  • git diff --check
  • Local smoke test: GET http://127.0.0.1:3001/api/settings returned 200.

Copilot AI review requested due to automatic review settings May 6, 2026 09:19

Copy link
Copy Markdown
Owner Author

Review summary:

  • Checked the backend API URL normalization, CORS/local binding, upload validation, chat fallback retry flow, and preset-key handling changes.
  • No blocking issues found in the diff.
  • Validation passed: node --check frontend/js/app.js, npm.cmd run check, git diff --check, CI success, and local /api/settings smoke test returned 200.

Note: GitHub does not allow approving your own PR, so this is recorded as a review summary comment instead.

@mc3545dada
mc3545dada merged commit 6b09cc0 into main May 6, 2026
3 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the local chat app by defaulting the backend to loopback-only access with restricted CORS, improves OpenAI-compatible API URL/model discovery behavior, and increases provider compatibility via automatic request fallbacks.

Changes:

  • Bind server to 127.0.0.1 by default, add an allowlist-based CORS policy (with optional ALLOWED_ORIGINS).
  • Normalize API base URLs, fetch models from /v1/models first, and add retry fallbacks for multimodal/thinking parameter incompatibilities.
  • Align upload UI with parseable file types, fix regenerate to avoid duplicating the last user message, and improve API preset switching/key handling.

Reviewed changes

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

Show a summary per file
File Description
start.bat Opens the app at 127.0.0.1 instead of localhost.
README.md Updates Quick Start URL to 127.0.0.1.
frontend/js/app.js File-type gating + accept sync, refactored API message building, regenerate fix, preset switching/key handling.
frontend/index.html Narrows <input type="file"> accept list to match supported types.
backend/server.js Loopback host binding, CORS allowlist, API URL normalization, /v1/models discovery with fallback, chat retry fallbacks, upload-type enforcement.

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

Comment thread frontend/js/app.js
if (f.type === 'image' && f.dataUrl) parts.push({ type: 'image_url', image_url: { url: f.dataUrl } });
else if (f.text) parts.push({ type: 'text', text: '[文件内容: ' + f.name + ']\n' + f.text });
}
return { role: msg.role, content: parts.length > 1 ? parts : (parts[0]?.text || textContent) };
Comment thread frontend/js/app.js
Comment on lines 480 to +484
if (p.apiBaseUrl) settingUrl.value = p.apiBaseUrl;
if (p.model) settingModel.value = p.model;
settingKey.value = (p.apiKey && p.apiKey !== 'undefined') ? p.apiKey : '';
if (p.name) presetName.value = p.name;
if (!settingKey.value.trim()) {
Comment thread backend/server.js
Comment on lines +168 to +170
return callback(new Error('Not allowed by CORS'));
},
}));
Comment thread backend/server.js
return callback(new Error('Not allowed by CORS'));
},
}));
app.use(express.json({ limit: '2mb' }));
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.

2 participants