From c3738cf1c3ed125a90bd59416e21356b014f782a Mon Sep 17 00:00:00 2001 From: ekko <152005280+EKKOLearnAI@users.noreply.github.com> Date: Sat, 9 May 2026 11:37:26 +0800 Subject: [PATCH] fix(docker): resolve container networking and DB compatibility issues (#560) - Auto-detect Docker container environment and use service name 'hermes-agent' as default host instead of 127.0.0.1 - Replace hardcoded column names with SELECT * in session DB queries to compat with older Hermes agent state.db schemas - Remove unused UPSTREAM env var from docker-compose.yml - Include err.message in syncFromHermes failure logs - Add group chat rule to prevent self-mentioning Co-authored-by: Claude Opus 4.7 --- docker-compose.yml | 1 - packages/server/src/db/hermes/sessions-db.ts | 57 ++----------------- .../src/services/hermes/chat-run-socket.ts | 2 +- .../services/hermes/context-engine/prompt.ts | 1 + .../src/services/hermes/gateway-manager.ts | 8 ++- 5 files changed, 11 insertions(+), 58 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 182c54e..9f923e3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,7 +32,6 @@ services: - hermes-agent-src:/opt/hermes environment: - PORT=${PORT:-6060} - - UPSTREAM=${UPSTREAM:-http://hermes-agent:8642} - HERMES_HOME=/home/agent/.hermes - HERMES_BIN=${HERMES_BIN:-/opt/hermes/.venv/bin/hermes} - AUTH_DISABLED=${AUTH_DISABLED:-false} diff --git a/packages/server/src/db/hermes/sessions-db.ts b/packages/server/src/db/hermes/sessions-db.ts index 671c35d..f9929b7 100644 --- a/packages/server/src/db/hermes/sessions-db.ts +++ b/packages/server/src/db/hermes/sessions-db.ts @@ -598,11 +598,7 @@ export async function getSessionMessagesFromDb(sessionId: string): Promise<{ `).get(sessionId) as Record | undefined const messageRows = db.prepare(` - SELECT - id, session_id, role, content, tool_call_id, tool_calls, tool_name, - timestamp, token_count, finish_reason, reasoning, reasoning_details, - codex_reasoning_items, reasoning_content - FROM messages + SELECT * FROM messages WHERE session_id = ? ORDER BY timestamp, id `).all(sessionId) as Record[] @@ -629,22 +625,7 @@ export async function getSessionDetailFromDb(sessionId: string): Promise session.id) const placeholders = ids.map(() => '?').join(', ') const messageRows = db.prepare(` - SELECT - id, - session_id, - role, - content, - tool_call_id, - tool_calls, - tool_name, - timestamp, - token_count, - finish_reason, - reasoning, - reasoning_details, - codex_reasoning_items, - reasoning_content - FROM messages + SELECT * FROM messages WHERE session_id IN (${placeholders}) ORDER BY timestamp, id `).all(...ids) as Record[] @@ -670,22 +651,7 @@ export async function getSessionDetailFromDbWithProfile(sessionId: string, profi const ids = chain.map(session => session.id) const placeholders = ids.map(() => '?').join(', ') const messageRows = db.prepare(` - SELECT - id, - session_id, - role, - content, - tool_call_id, - tool_calls, - tool_name, - timestamp, - token_count, - finish_reason, - reasoning, - reasoning_details, - codex_reasoning_items, - reasoning_content - FROM messages + SELECT * FROM messages WHERE session_id IN (${placeholders}) ORDER BY timestamp, id `).all(...ids) as Record[] @@ -706,22 +672,7 @@ export async function getExactSessionDetailFromDbWithProfile(sessionId: string, if (!requested) return null const messageRows = db.prepare(` - SELECT - id, - session_id, - role, - content, - tool_call_id, - tool_calls, - tool_name, - timestamp, - token_count, - finish_reason, - reasoning, - reasoning_details, - codex_reasoning_items, - reasoning_content - FROM messages + SELECT * FROM messages WHERE session_id = ? ORDER BY timestamp, id `).all(sessionId) as Record[] diff --git a/packages/server/src/services/hermes/chat-run-socket.ts b/packages/server/src/services/hermes/chat-run-socket.ts index 505598e..f0fc2aa 100644 --- a/packages/server/src/services/hermes/chat-run-socket.ts +++ b/packages/server/src/services/hermes/chat-run-socket.ts @@ -1594,7 +1594,7 @@ export class ChatRunSocket { this.enqueueEphemeralDelete(hermesSessionId, profile) return true } catch (err: any) { - logger.warn(err, '[chat-run-socket] syncFromHermes failed for session %s (hermesId: %s, profile: %s)', localSessionId, hermesSessionId, profile || 'default') + logger.warn(err, '[chat-run-socket] syncFromHermes failed for session %s (hermesId: %s, profile: %s): %s', localSessionId, hermesSessionId, profile || 'default', err?.message) return false } } diff --git a/packages/server/src/services/hermes/context-engine/prompt.ts b/packages/server/src/services/hermes/context-engine/prompt.ts index 5c07ae5..fc8533d 100644 --- a/packages/server/src/services/hermes/context-engine/prompt.ts +++ b/packages/server/src/services/hermes/context-engine/prompt.ts @@ -53,6 +53,7 @@ ${memberSection} 规则: - 有人用 @${params.agentName} 提及你时才需要回复,重点回应提及你的人。 +- 禁止@自己。 - 回答简洁、对群聊有帮助。 - 不要假装是人类,需要时明确表明自己是 AI。 - 对话历史中包含多个人的消息,每条消息前标有发送者名字。 diff --git a/packages/server/src/services/hermes/gateway-manager.ts b/packages/server/src/services/hermes/gateway-manager.ts index 0f22dbb..023656d 100644 --- a/packages/server/src/services/hermes/gateway-manager.ts +++ b/packages/server/src/services/hermes/gateway-manager.ts @@ -163,7 +163,9 @@ export class GatewayManager { */ private readProfilePort(name: string): { port: number; host: string } { const configPath = join(this.profileDir(name), 'config.yaml') - if (!existsSync(configPath)) return { port: 8642, host: '127.0.0.1' } + const defaultHost = initSystem === 'container' ? 'hermes-agent' : '127.0.0.1' + + if (!existsSync(configPath)) return { port: 8642, host: defaultHost } try { const content = readFileSync(configPath, 'utf-8') @@ -172,11 +174,11 @@ export class GatewayManager { const extra = cfg?.platforms?.api_server?.extra const rawPort = extra?.port || 8642 const port = typeof rawPort === 'number' ? rawPort : parseInt(rawPort, 10) || 8642 - const host = extra?.host || '127.0.0.1' + const host = extra?.host || defaultHost // 端口超出合法范围时回退到默认值 return { port: port > 0 && port <= 65535 ? port : 8642, host } } catch { - return { port: 8642, host: '127.0.0.1' } + return { port: 8642, host: defaultHost } } }