- Cowork: ComboFormModal

- BaseUrlSelect: add cloud endpoint option, custom URL local state, always
  default to first option; new cliEndpointMatch helper; CLI tool cards refactor
- API: new /v1/audio/voices and /v1/models/info; /v1/models filters disabled
  models, drop unused timestamp
- initializeApp: guard tunnel/tailscale auto-resume to once-per-process
- geminiHelper: ensureObjectType for schemas with properties but no type
- skills: minor SKILL.md tweaks (chat/embeddings/image/stt/tts/web-*)
This commit is contained in:
decolua committed 2026-05-07 15:45:09 +07:00
1 parent 6344abcf8d
commit 5c62e73cc6
28 files changed
+1897 -320

No files matched your search

@@ -4,6 +4,7 @@ import { useState, useEffect, useRef } from "react";
import { Card, Button, ModelSelectModal, ManualConfigModal } from "@/shared/components";
import Image from "next/image";
import BaseUrlSelect from "./BaseUrlSelect";
import { matchKnownEndpoint } from "./cliEndpointMatch";
export default function OpenClawToolCard({
tool,
@@ -39,10 +40,7 @@ export default function OpenClawToolCard({
if (!openclawStatus?.installed) return null;
const currentProvider = openclawStatus.settings?.models?.providers?.["9router"];
if (!currentProvider) return "not_configured";
const localMatch = currentProvider.baseUrl?.includes("localhost") || currentProvider.baseUrl?.includes("127.0.0.1") || currentProvider.baseUrl?.includes("0.0.0.0");
const tunnelMatch = baseUrl && currentProvider.baseUrl?.startsWith(baseUrl);
if (localMatch || tunnelMatch) return "configured";
return "other";
return matchKnownEndpoint(currentProvider.baseUrl, { tunnelPublicUrl, tailscaleUrl }) ? "configured" : "other";
};
const configStatus = getConfigStatus();
@@ -282,20 +280,9 @@ export default function OpenClawToolCard({
{!checkingOpenclaw && openclawStatus?.installed && (
<>
<div className="flex flex-col gap-2">
{/* Current Base URL */}
{openclawStatus?.settings?.models?.providers?.["9router"]?.baseUrl && (
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-[8rem_auto_1fr_auto] sm:items-center sm:gap-2">
<span className="text-xs font-semibold text-text-main sm:text-right sm:text-sm">Current</span>
<span className="material-symbols-outlined hidden text-text-muted text-[14px] sm:inline">arrow_forward</span>
<span className="min-w-0 truncate rounded bg-surface/40 px-2 py-2 text-xs text-text-muted sm:py-1.5">
{openclawStatus.settings.models.providers["9router"].baseUrl}
</span>
</div>
)}
{/* Base URL */}
{/* Endpoint (selector) */}
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-[8rem_auto_1fr] sm:items-center sm:gap-2">
<span className="text-xs font-semibold text-text-main sm:text-right sm:text-sm">Base URL</span>
<span className="text-xs font-semibold text-text-main sm:text-right sm:text-sm">Select Endpoint</span>
<span className="material-symbols-outlined hidden text-text-muted text-[14px] sm:inline">arrow_forward</span>
<BaseUrlSelect
value={customBaseUrl || getDisplayUrl()}
@@ -308,6 +295,17 @@ export default function OpenClawToolCard({
/>
</div>
{/* Current configured */}
{openclawStatus?.settings?.models?.providers?.["9router"]?.baseUrl && (
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-[8rem_auto_1fr_auto] sm:items-center sm:gap-2">
<span className="text-xs font-semibold text-text-main sm:text-right sm:text-sm">Current</span>
<span className="material-symbols-outlined hidden text-text-muted text-[14px] sm:inline">arrow_forward</span>
<span className="min-w-0 truncate rounded bg-surface/40 px-2 py-2 text-xs text-text-muted sm:py-1.5">
{openclawStatus.settings.models.providers["9router"].baseUrl}
</span>
</div>
)}
{/* API Key */}
<div className="grid grid-cols-1 gap-1.5 sm:grid-cols-[8rem_auto_1fr_auto] sm:items-center sm:gap-2">
<span className="text-xs font-semibold text-text-main sm:text-right sm:text-sm">API Key</span>