diff --git a/app/gateway-status.tsx b/app/gateway-status.tsx index dd8f1e1..01a4bc3 100644 --- a/app/gateway-status.tsx +++ b/app/gateway-status.tsx @@ -3,6 +3,15 @@ import { useEffect, useState, useCallback } from "react"; import { useI18n } from "@/lib/i18n"; +function resolveGatewayUrl(url?: string): string | undefined { + if (!url || typeof window === "undefined") return url; + try { + const parsed = new URL(url); + if (parsed.hostname === "localhost") parsed.hostname = window.location.hostname; + return parsed.toString(); + } catch { return url; } +} + interface HealthResult { ok: boolean; error?: string; @@ -31,7 +40,7 @@ export function GatewayStatus() { return (
; sessionTestResult?: { ok: boolean; reply?: string; error?: string; elapsed: number } | null; agentState?: string; dmSessionResults?: Record; providerAccessModeMap?: Record }) { const sessionKey = `agent:${agent.id}:main`; - let sessionUrl = `http://localhost:${gatewayPort}/chat?session=${encodeURIComponent(sessionKey)}`; - if (gatewayToken) sessionUrl += `&token=${encodeURIComponent(gatewayToken)}`; + let sessionUrl = buildGatewayUrl(gatewayPort, "/chat", { session: sessionKey }); + if (gatewayToken) sessionUrl = buildGatewayUrl(gatewayPort, "/chat", { session: sessionKey, token: gatewayToken }); const modelProvider = agent.model.includes("/") ? agent.model.split("/", 1)[0] : "default"; const modelAccessMode = providerAccessModeMap?.[modelProvider]; diff --git a/app/pixel-office/page.tsx b/app/pixel-office/page.tsx index 62e438c..ef002ff 100644 --- a/app/pixel-office/page.tsx +++ b/app/pixel-office/page.tsx @@ -3,6 +3,7 @@ import { useEffect, useRef, useState, useCallback } from 'react' import { OfficeState } from '@/lib/pixel-office/engine/officeState' import { renderFrame } from '@/lib/pixel-office/engine/renderer' +import { buildGatewayUrl } from "@/lib/gateway-url" import type { EditorRenderState } from '@/lib/pixel-office/engine/renderer' import type { ContributionData } from '@/lib/pixel-office/engine/renderer' import { syncAgentsToOffice, AgentActivity } from '@/lib/pixel-office/agentBridge' @@ -647,8 +648,8 @@ export default function PixelOfficePage() { // Click on PC — open gateway chat for main agent const gw = gatewayRef.current const sessionKey = 'agent:main:main' - let chatUrl = `http://localhost:${gw.port}/chat?session=${encodeURIComponent(sessionKey)}` - if (gw.token) chatUrl += `&token=${encodeURIComponent(gw.token)}` + let chatUrl = buildGatewayUrl(gw.port, '/chat', { session: sessionKey }) + if (gw.token) chatUrl = buildGatewayUrl(gw.port, '/chat', { session: sessionKey, token: gw.token }) window.open(chatUrl, '_blank') } else if (office.layout.furniture.some(f => { if (f.uid !== 'library-r') return false diff --git a/app/sessions/page.tsx b/app/sessions/page.tsx index cc459e7..fd900a6 100644 --- a/app/sessions/page.tsx +++ b/app/sessions/page.tsx @@ -3,6 +3,7 @@ import { useEffect, useState, Suspense } from "react"; import { useSearchParams } from "next/navigation"; import Link from "next/link"; +import { buildGatewayUrl } from "@/lib/gateway-url"; import { useI18n } from "@/lib/i18n"; interface AgentInfo { @@ -288,8 +289,8 @@ function SessionList({ agentId }: { agentId: string }) {
{sessions.map((s) => { const typeInfo = getTypeLabel(s.type); - let chatUrl = `http://localhost:${gateway.port}/chat?session=${encodeURIComponent(s.key)}`; - if (gateway.token) chatUrl += `&token=${encodeURIComponent(gateway.token)}`; + let chatUrl = buildGatewayUrl(gateway.port, "/chat", { session: s.key }); + if (gateway.token) chatUrl = buildGatewayUrl(gateway.port, "/chat", { session: s.key, token: gateway.token }); return (
): string { + const host = typeof window !== "undefined" ? window.location.hostname : "localhost"; + const url = new URL(`http://${host}:${port}${path}`); + if (params) { + for (const [k, v] of Object.entries(params)) { + if (v) url.searchParams.set(k, v); + } + } + return url.toString(); +}