fix: resolve 6 issues (#32 #31 #25 #33 #29 #23)

- #32: parseCookies decodeURIComponent crash with malformed cookies (Authelia)
- #31: Gateway restart no longer overwrites user CORS allowedOrigins (merge instead)
- #25: Windows terminal flashing - add CREATE_NO_WINDOW to skills.rs + assistant.rs
- #33: Model test tolerates non-auth HTTP errors (Ali Coding Plan compatibility)
- #29: Auto-detect ws/wss protocol for reverse proxy + protocol-aware Docker URLs
- #23: Chat session sidebar stays open when switching sessions
This commit is contained in:
晴天
2026-03-10 22:51:15 +08:00
parent 044d866b57
commit 91f96ac96b
9 changed files with 112 additions and 60 deletions

View File

@@ -66,11 +66,13 @@ export class WsClient {
return () => { this._readyCallbacks = this._readyCallbacks.filter(cb => cb !== fn) }
}
connect(host, token) {
connect(host, token, opts = {}) {
this._intentionalClose = false
this._autoPairAttempts = 0
this._token = token || ''
this._url = `ws://${host}/ws?token=${encodeURIComponent(this._token)}`
// 自动检测协议:如果页面通过 HTTPS 加载(反代场景),使用 wss://
const proto = opts.secure ?? (typeof location !== 'undefined' && location.protocol === 'https:') ? 'wss' : 'ws'
this._url = `${proto}://${host}/ws?token=${encodeURIComponent(this._token)}`
this._doConnect()
}

View File

@@ -484,7 +484,6 @@ function switchSession(newKey) {
clearMessages()
loadHistory()
refreshSessionList()
_page?.querySelector('#chat-sidebar')?.classList.remove('open')
}
async function showNewSessionDialog() {

View File

@@ -332,7 +332,7 @@ function _renderUnitCard(c, showAdopt) {
</div>
${isRunning && (ports.panel || ports.gateway) ? `
<div class="unit-links">
${ports.panel ? `<a href="http://${host}:${ports.panel}" target="_blank" rel="noopener" class="unit-link panel">${icon('monitor', 12)} 面板 :${ports.panel}</a>` : ''}
${ports.panel ? `<a href="${location.protocol}//${host}:${ports.panel}" target="_blank" rel="noopener" class="unit-link panel">${icon('monitor', 12)} 面板 :${ports.panel}</a>` : ''}
${ports.gateway ? `<span class="unit-link gateway" data-action="quick-chat" data-container-id="${esc(c.id)}" data-node-id="${esc(c.nodeId || '')}" data-name="${esc(c.name)}" title="发送测试消息">${icon('zap', 12)} 通讯 :${ports.gateway}</span>` : ''}
</div>
` : ''}
@@ -1474,7 +1474,7 @@ async function showDeployDialog(page, nodeId) {
// 成功页面
const host = location.hostname || 'localhost'
const panelUrl = `http://${host}:${panelPort}`
const panelUrl = `${location.protocol}//${host}:${panelPort}`
const selectedRole = overlay.querySelector('#dd-role')?.value || 'general'
const roleInfo = MILITARY.roles[selectedRole] || MILITARY.roles.general
@@ -1488,7 +1488,7 @@ async function showDeployDialog(page, nodeId) {
<button class="btn" data-dismiss>关闭</button>
</div>
<div style="margin-top:16px;font-size:11px;color:var(--text-tertiary);font-family:var(--font-mono)">
Panel: ${panelUrl} · Gateway: ws://${host}:${gatewayPort}
Panel: ${panelUrl} · Gateway: ${location.protocol === 'https:' ? 'wss' : 'ws'}://${host}:${gatewayPort}
</div>
</div>
`
@@ -1543,18 +1543,18 @@ async function showInspectDialog(page, nodeId, containerId) {
<div class="inspect-section">
<div class="inspect-section-title">指挥通道</div>
<div class="inspect-links">
${ports.panel ? `<a href="http://${host}:${ports.panel}" target="_blank" rel="noopener" class="inspect-link-card">
${ports.panel ? `<a href="${location.protocol}//${host}:${ports.panel}" target="_blank" rel="noopener" class="inspect-link-card">
<span class="inspect-link-icon">${icon('monitor', 20)}</span>
<span class="inspect-link-text">
<strong>指挥台</strong>
<span>http://${host}:${ports.panel}</span>
<span>${location.protocol}//${host}:${ports.panel}</span>
</span>
</a>` : ''}
${ports.gateway ? `<div class="inspect-link-card" style="cursor:default;opacity:0.85">
<span class="inspect-link-icon">${icon('zap', 20)}</span>
<span class="inspect-link-text">
<strong>通讯链路 (WebSocket)</strong>
<span>ws://${host}:${ports.gateway}/ws</span>
<span>${location.protocol === 'https:' ? 'wss' : 'ws'}://${host}:${ports.gateway}/ws</span>
</span>
</div>` : ''}
</div>