fix(apiServer): use 127.0.0.1 instead of localhost for better compatibility (#11673)

* fix(apiServer): use 127.0.0.1 instead of localhost for better compatibility

- Change default host from localhost to 127.0.0.1 in config and settings
- Add buildApiServerUrl helper to properly construct API server URLs
- Update OpenAPI documentation server URL
- Update test files to use 127.0.0.1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(migration): migrate existing localhost config to 127.0.0.1

- Add migration 180 to automatically update localhost to 127.0.0.1
- Handle both plain host and hosts with http/https protocol
- Increment store version to 180

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(apiServer): simplify buildApiServerUrl implementation

- Remove complex URL parsing and protocol handling
- Use simple string concatenation for URL building
- Assume http protocol since API server is local

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: remove buildApiServerUrl helper and simplify migration

- Remove buildApiServerUrl helper function
- Use 127.0.0.1 directly in URL construction
- Simplify migration 180 to unconditionally set host to 127.0.0.1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(apiServer): fix critical bugs and improve code structure

🔴 Critical Fixes:
- Fix config.ts to use stored host value instead of ignoring it
- Fix hardcoded 127.0.0.1 URLs to use apiServerConfig.host

🟡 Improvements:
- Extract API_SERVER_DEFAULTS to shared constants in packages/shared/config/constant.ts
- Apply consistent fallback pattern using API_SERVER_DEFAULTS.HOST and API_SERVER_DEFAULTS.PORT
- Update all imports to use shared constants across main and renderer processes

Files changed:
- packages/shared/config/constant.ts: Add API_SERVER_DEFAULTS constants
- src/main/apiServer/config.ts: Use stored host with fallback
- src/main/apiServer/middleware/openapi.ts: Use constants
- src/renderer/src/pages/settings/ToolSettings/ApiServerSettings/ApiServerSettings.tsx: Use config host and constants
- src/renderer/src/store/settings.ts: Use constants in initial state
- src/renderer/src/store/migrate.ts: Use constants in migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* update

* fix(apiServer): use relative URL in OpenAPI spec for better compatibility

- Change server URL from hardcoded defaults to relative path '/'
- This ensures Swagger UI "Try it out" works correctly regardless of configured host/port
- Remove unused API_SERVER_DEFAULTS import

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
beyondkmp 2025-12-04 10:57:42 +08:00 committed by GitHub
parent aeabc28451
commit 4f701d3e45
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 34 additions and 23 deletions

View File

@ -7,6 +7,11 @@ export const documentExts = ['.pdf', '.doc', '.docx', '.pptx', '.xlsx', '.odt',
export const thirdPartyApplicationExts = ['.draftsExport']
export const bookExts = ['.epub']
export const API_SERVER_DEFAULTS = {
HOST: '127.0.0.1',
PORT: 23333
}
/**
* A flat array of all file extensions known by the linguist database.
* This is the primary source for identifying code files.

View File

@ -1,3 +1,4 @@
import { API_SERVER_DEFAULTS } from '@shared/config/constant'
import type { ApiServerConfig } from '@types'
import { v4 as uuidv4 } from 'uuid'
@ -6,9 +7,6 @@ import { reduxService } from '../services/ReduxService'
const logger = loggerService.withContext('ApiServerConfig')
const defaultHost = 'localhost'
const defaultPort = 23333
class ConfigManager {
private _config: ApiServerConfig | null = null
@ -30,8 +28,8 @@ class ConfigManager {
}
this._config = {
enabled: serverSettings?.enabled ?? false,
port: serverSettings?.port ?? defaultPort,
host: defaultHost,
port: serverSettings?.port ?? API_SERVER_DEFAULTS.PORT,
host: serverSettings?.host ?? API_SERVER_DEFAULTS.HOST,
apiKey: apiKey
}
return this._config
@ -39,8 +37,8 @@ class ConfigManager {
logger.warn('Failed to load config from Redux, using defaults', { error })
this._config = {
enabled: false,
port: defaultPort,
host: defaultHost,
port: API_SERVER_DEFAULTS.PORT,
host: API_SERVER_DEFAULTS.HOST,
apiKey: this.generateApiKey()
}
return this._config

View File

@ -20,8 +20,8 @@ const swaggerOptions: swaggerJSDoc.Options = {
},
servers: [
{
url: 'http://localhost:23333',
description: 'Local development server'
url: '/',
description: 'Current server'
}
],
components: {

View File

@ -4,6 +4,7 @@ import type { RootState } from '@renderer/store'
import { useAppDispatch } from '@renderer/store'
import { setApiServerApiKey, setApiServerPort } from '@renderer/store/settings'
import { formatErrorMessage } from '@renderer/utils/error'
import { API_SERVER_DEFAULTS } from '@shared/config/constant'
import { Alert, Button, Input, InputNumber, Tooltip, Typography } from 'antd'
import { Copy, ExternalLink, Play, RotateCcw, Square } from 'lucide-react'
import type { FC } from 'react'
@ -56,7 +57,7 @@ const ApiServerSettings: FC = () => {
}
const handlePortChange = (value: string) => {
const port = parseInt(value) || 23333
const port = parseInt(value) || API_SERVER_DEFAULTS.PORT
if (port >= 1000 && port <= 65535) {
dispatch(setApiServerPort(port))
}
@ -64,7 +65,9 @@ const ApiServerSettings: FC = () => {
const openApiDocs = () => {
if (apiServerRunning) {
window.open(`http://localhost:${apiServerConfig.port}/api-docs`, '_blank')
const host = apiServerConfig.host || API_SERVER_DEFAULTS.HOST
const port = apiServerConfig.port || API_SERVER_DEFAULTS.PORT
window.open(`http://${host}:${port}/api-docs`, '_blank')
}
}
@ -98,7 +101,9 @@ const ApiServerSettings: FC = () => {
{apiServerRunning ? t('apiServer.status.running') : t('apiServer.status.stopped')}
</StatusText>
<StatusSubtext>
{apiServerRunning ? `http://localhost:${apiServerConfig.port}` : t('apiServer.fields.port.description')}
{apiServerRunning
? `http://${apiServerConfig.host || API_SERVER_DEFAULTS.HOST}:${apiServerConfig.port || API_SERVER_DEFAULTS.PORT}`
: t('apiServer.fields.port.description')}
</StatusSubtext>
</StatusContent>
</StatusSection>
@ -119,11 +124,11 @@ const ApiServerSettings: FC = () => {
{!apiServerRunning && (
<StyledInputNumber
value={apiServerConfig.port}
onChange={(value) => handlePortChange(String(value || 23333))}
onChange={(value) => handlePortChange(String(value || API_SERVER_DEFAULTS.PORT))}
min={1000}
max={65535}
disabled={apiServerRunning}
placeholder="23333"
placeholder={String(API_SERVER_DEFAULTS.PORT)}
size="middle"
/>
)}

View File

@ -32,6 +32,7 @@ import {
isSupportDeveloperRoleProvider,
isSupportStreamOptionsProvider
} from '@renderer/utils/provider'
import { API_SERVER_DEFAULTS } from '@shared/config/constant'
import { defaultByPassRules, UpgradeChannel } from '@shared/config/constant'
import { isEmpty } from 'lodash'
import { createMigrate } from 'redux-persist'
@ -2032,8 +2033,8 @@ const migrateConfig = {
if (!state.settings.apiServer) {
state.settings.apiServer = {
enabled: false,
host: 'localhost',
port: 23333,
host: API_SERVER_DEFAULTS.HOST,
port: API_SERVER_DEFAULTS.PORT,
apiKey: `cs-sk-${uuid()}`
}
}
@ -2909,6 +2910,9 @@ const migrateConfig = {
},
'180': (state: RootState) => {
try {
if (state.settings.apiServer) {
state.settings.apiServer.host = API_SERVER_DEFAULTS.HOST
}
// @ts-expect-error
if (state.settings.openAI.summaryText === 'undefined') {
state.settings.openAI.summaryText = undefined

View File

@ -18,7 +18,7 @@ import type {
import { ThemeMode } from '@renderer/types'
import type { OpenAISummaryText, OpenAIVerbosity } from '@renderer/types/aiCoreTypes'
import { uuid } from '@renderer/utils'
import { UpgradeChannel } from '@shared/config/constant'
import { API_SERVER_DEFAULTS, UpgradeChannel } from '@shared/config/constant'
import type { RemoteSyncState } from './backup'
@ -410,8 +410,8 @@ export const initialState: SettingsState = {
// API Server
apiServer: {
enabled: false,
host: 'localhost',
port: 23333,
host: API_SERVER_DEFAULTS.HOST,
port: API_SERVER_DEFAULTS.PORT,
apiKey: `cs-sk-${uuid()}`
},
showMessageOutline: false

View File

@ -1,4 +1,4 @@
@host=http://localhost:23333
@host=http://127.0.0.1:23333
@token=cs-sk-af798ed4-7cf5-4fd7-ae4b-df203b164194
@agent_id=agent_1758092281575_tn9dxio9k
@ -56,4 +56,3 @@ Content-Type: application/json
"max_turns": 5
}
}

View File

@ -1,5 +1,5 @@
@host=http://localhost:23333
@host=http://127.0.0.1:23333
@token=cs-sk-af798ed4-7cf5-4fd7-ae4b-df203b164194
@agent_id=agent_1758092281575_tn9dxio9k
@session_id=session_1758278828236_mqj91e7c0

View File

@ -1,4 +1,4 @@
@host=http://localhost:23333
@host=http://127.0.0.1:23333
@token=cs-sk-af798ed4-7cf5-4fd7-ae4b-df203b164194
@agent_id=agent_1758092281575_tn9dxio9k