mirror of
https://github.com/xmanrui/OpenClaw-bot-review.git
synced 2026-07-27 22:25:52 +00:00
Merge pull request #3 from xmanrui/pr-3
This commit is contained in:
+10
-1
@@ -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 (
|
||||
<div className="relative inline-flex items-center gap-2">
|
||||
<a
|
||||
href={health?.ok && health.webUrl ? health.webUrl : undefined}
|
||||
href={health?.ok && health.webUrl ? resolveGatewayUrl(health.webUrl) : undefined}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium border bg-cyan-500/20 text-cyan-300 border-cyan-500/30 hover:bg-cyan-500/30 transition-colors cursor-pointer"
|
||||
|
||||
+5
-4
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useEffect, useState, useCallback, useRef } from "react";
|
||||
import { useI18n } from "@/lib/i18n";
|
||||
import { buildGatewayUrl } from "@/lib/gateway-url";
|
||||
import { GatewayStatus } from "./gateway-status";
|
||||
|
||||
interface Platform {
|
||||
@@ -186,8 +187,8 @@ function PlatformBadge({ platform, agentId, gatewayPort, gatewayToken, t, testRe
|
||||
} else {
|
||||
sessionKey = `agent:${agentId}: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 badgeStyle = pName === "feishu"
|
||||
? "bg-blue-500/20 text-blue-300 border border-blue-500/30 hover:bg-blue-500/40 hover:border-blue-400"
|
||||
@@ -321,8 +322,8 @@ function AgentStatusBadge({ state, t }: { state?: string; t: TFunc }) {
|
||||
// Agent 卡片
|
||||
function AgentCard({ agent, gatewayPort, gatewayToken, t, testResult, platformTestResults, sessionTestResult, agentState, dmSessionResults, providerAccessModeMap }: { agent: Agent; gatewayPort: number; gatewayToken?: string; t: TFunc; testResult?: { ok: boolean; text?: string; error?: string; elapsed: number } | null; platformTestResults?: Record<string, PlatformTestResult | null>; sessionTestResult?: { ok: boolean; reply?: string; error?: string; elapsed: number } | null; agentState?: string; dmSessionResults?: Record<string, PlatformTestResult | null>; providerAccessModeMap?: Record<string, "auth" | "api_key"> }) {
|
||||
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];
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }) {
|
||||
<div className="space-y-3">
|
||||
{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 (
|
||||
<div
|
||||
key={s.key}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Build a gateway URL using the current browser hostname instead of
|
||||
* hard-coded "localhost", so the dashboard works over LAN.
|
||||
* Falls back to "localhost" during SSR.
|
||||
*/
|
||||
export function buildGatewayUrl(port: number, path: string, params?: Record<string, string>): 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();
|
||||
}
|
||||
Reference in New Issue
Block a user