mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 20:00:47 +00:00
Feat : tts
This commit is contained in:
@@ -13,7 +13,9 @@ export default function CodexToolCard({ tool, isExpanded, onToggle, baseUrl, api
|
||||
const [showInstallGuide, setShowInstallGuide] = useState(false);
|
||||
const [selectedApiKey, setSelectedApiKey] = useState("");
|
||||
const [selectedModel, setSelectedModel] = useState("");
|
||||
const [subagentModel, setSubagentModel] = useState("");
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [subagentModalOpen, setSubagentModalOpen] = useState(false);
|
||||
const [modelAliases, setModelAliases] = useState({});
|
||||
const [showManualConfigModal, setShowManualConfigModal] = useState(false);
|
||||
const [customBaseUrl, setCustomBaseUrl] = useState("");
|
||||
@@ -46,11 +48,15 @@ export default function CodexToolCard({ tool, isExpanded, onToggle, baseUrl, api
|
||||
}
|
||||
};
|
||||
|
||||
// Parse model from config content (don't sync URL - always use baseUrl from props)
|
||||
// Parse model and subagent settings from config content
|
||||
useEffect(() => {
|
||||
if (codexStatus?.config) {
|
||||
const modelMatch = codexStatus.config.match(/^model\s*=\s*"([^"]+)"/m);
|
||||
if (modelMatch) setSelectedModel(modelMatch[1]);
|
||||
|
||||
// Parse subagent settings
|
||||
const subagentModelMatch = codexStatus.config.match(/\[agents\.subagent\]\s*\n\s*model\s*=\s*"([^"]+)"/m);
|
||||
if (subagentModelMatch) setSubagentModel(subagentModelMatch[1]);
|
||||
}
|
||||
}, [codexStatus]);
|
||||
|
||||
@@ -96,7 +102,12 @@ export default function CodexToolCard({ tool, isExpanded, onToggle, baseUrl, api
|
||||
const res = await fetch("/api/cli-tools/codex-settings", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ baseUrl: getEffectiveBaseUrl(), apiKey: keyToUse, model: selectedModel }),
|
||||
body: JSON.stringify({
|
||||
baseUrl: getEffectiveBaseUrl(),
|
||||
apiKey: keyToUse,
|
||||
model: selectedModel,
|
||||
subagentModel: subagentModel || selectedModel
|
||||
}),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (res.ok) {
|
||||
@@ -121,6 +132,7 @@ export default function CodexToolCard({ tool, isExpanded, onToggle, baseUrl, api
|
||||
if (res.ok) {
|
||||
setMessage({ type: "success", text: "Settings reset successfully!" });
|
||||
setSelectedModel("");
|
||||
setSubagentModel("");
|
||||
checkCodexStatus();
|
||||
} else {
|
||||
setMessage({ type: "error", text: data.error || "Failed to reset settings" });
|
||||
@@ -134,6 +146,10 @@ export default function CodexToolCard({ tool, isExpanded, onToggle, baseUrl, api
|
||||
|
||||
const handleModelSelect = (model) => {
|
||||
setSelectedModel(model.value);
|
||||
// Auto-set subagent model if not set
|
||||
if (!subagentModel) {
|
||||
setSubagentModel(model.value);
|
||||
}
|
||||
setModalOpen(false);
|
||||
};
|
||||
|
||||
@@ -142,6 +158,8 @@ export default function CodexToolCard({ tool, isExpanded, onToggle, baseUrl, api
|
||||
? selectedApiKey
|
||||
: (!cloudEnabled ? "sk_9router" : "<API_KEY_FROM_DASHBOARD>");
|
||||
|
||||
const effectiveSubagentModel = subagentModel || selectedModel;
|
||||
|
||||
const configContent = `# 9Router Configuration for Codex CLI
|
||||
model = "${selectedModel}"
|
||||
model_provider = "9router"
|
||||
@@ -150,6 +168,9 @@ model_provider = "9router"
|
||||
name = "9Router"
|
||||
base_url = "${getEffectiveBaseUrl()}"
|
||||
wire_api = "responses"
|
||||
|
||||
[agents.subagent]
|
||||
model = "${effectiveSubagentModel}"
|
||||
`;
|
||||
|
||||
const authContent = JSON.stringify({
|
||||
@@ -290,6 +311,35 @@ wire_api = "responses"
|
||||
<button onClick={() => setModalOpen(true)} disabled={!activeProviders?.length} className={`px-2 py-1.5 rounded border text-xs transition-colors shrink-0 whitespace-nowrap ${activeProviders?.length ? "bg-surface border-border text-text-main hover:border-primary cursor-pointer" : "opacity-50 cursor-not-allowed border-border"}`}>Select Model</button>
|
||||
{selectedModel && <button onClick={() => setSelectedModel("")} className="p-1 text-text-muted hover:text-red-500 rounded transition-colors" title="Clear"><span className="material-symbols-outlined text-[14px]">close</span></button>}
|
||||
</div>
|
||||
|
||||
{/* Subagent Model */}
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="w-32 shrink-0 text-sm font-semibold text-text-main text-right">Subagent Model</span>
|
||||
<span className="material-symbols-outlined text-text-muted text-[14px]">arrow_forward</span>
|
||||
<input
|
||||
type="text"
|
||||
value={subagentModel}
|
||||
onChange={(e) => setSubagentModel(e.target.value)}
|
||||
placeholder={selectedModel || "provider/model-id (defaults to main model)"}
|
||||
className="flex-1 px-2 py-1.5 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50"
|
||||
/>
|
||||
<button
|
||||
onClick={() => setSubagentModalOpen(true)}
|
||||
disabled={!activeProviders?.length}
|
||||
className={`px-2 py-1.5 rounded border text-xs transition-colors shrink-0 whitespace-nowrap ${activeProviders?.length ? "bg-surface border-border text-text-main hover:border-primary cursor-pointer" : "opacity-50 cursor-not-allowed border-border"}`}
|
||||
>
|
||||
Select Model
|
||||
</button>
|
||||
{subagentModel && (
|
||||
<button
|
||||
onClick={() => setSubagentModel("")}
|
||||
className="p-1 text-text-muted hover:text-red-500 rounded transition-colors"
|
||||
title="Clear (will use main model)"
|
||||
>
|
||||
<span className="material-symbols-outlined text-[14px]">close</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{message && (
|
||||
@@ -325,6 +375,16 @@ wire_api = "responses"
|
||||
title="Select Model for Codex"
|
||||
/>
|
||||
|
||||
<ModelSelectModal
|
||||
isOpen={subagentModalOpen}
|
||||
onClose={() => setSubagentModalOpen(false)}
|
||||
onSelect={(model) => { setSubagentModel(model.value); setSubagentModalOpen(false); }}
|
||||
selectedModel={subagentModel}
|
||||
activeProviders={activeProviders}
|
||||
modelAliases={modelAliases}
|
||||
title="Select Subagent Model for Codex"
|
||||
/>
|
||||
|
||||
<ManualConfigModal
|
||||
isOpen={showManualConfigModal}
|
||||
onClose={() => setShowManualConfigModal(false)}
|
||||
|
||||
Reference in New Issue
Block a user