You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
25 KiB
310 lines
25 KiB
import { defineComponent, ref, reactive, computed, useSSRContext } from 'vue';
|
|
import { ssrRenderAttrs, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderList, ssrRenderAttr, ssrInterpolate, ssrRenderStyle, ssrRenderClass, ssrRenderComponent } from 'vue/server-renderer';
|
|
import { u as useApi } from './useApi-BNSkSrat.mjs';
|
|
import { u as useToast } from './useToast-MBvLaNjH.mjs';
|
|
import { L as LANG_OPTIONS } from './useLangOptions-CXXbv5NM.mjs';
|
|
import { _ as __nuxt_component_0 } from './LangSelect-Bvw-e1Cn.mjs';
|
|
import { _ as _export_sfc } from './server.mjs';
|
|
import '../nitro/nitro.mjs';
|
|
import 'node:http';
|
|
import 'node:https';
|
|
import 'node:events';
|
|
import 'node:buffer';
|
|
import 'node:fs';
|
|
import 'node:path';
|
|
import 'node:crypto';
|
|
import 'node:url';
|
|
import '../routes/renderer.mjs';
|
|
import 'vue-bundle-renderer/runtime';
|
|
import 'unhead/server';
|
|
import 'devalue';
|
|
import 'unhead/utils';
|
|
import 'pinia';
|
|
import 'perfect-debounce';
|
|
|
|
const CAT_STT = 1;
|
|
const CAT_TTS = 2;
|
|
const CAT_MT = 3;
|
|
const CAT_AST = 4;
|
|
const CAT_LLM = 5;
|
|
const CAT_STS = 7;
|
|
const CAT_LLM_VISION = 9;
|
|
const CAT_MCP = 10;
|
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
__name: "agents",
|
|
__ssrInlineRender: true,
|
|
setup(__props) {
|
|
const AGENT_TYPES = [
|
|
{ value: "chat", label: "chat-agent 对话", icon: "💬", hint: "STT → LLM → TTS 三段拼接", color: "#b45309", bg: "#fef9c3" },
|
|
{ value: "sts-chat", label: "sts-chat-agent 端到端对话", icon: "⚡", hint: "单个 STS 服务直接完成语音对话", color: "#be185d", bg: "#fce7f3" }
|
|
];
|
|
const LEGACY_TYPES = {
|
|
translate: { label: "翻译(已下线)", icon: "🧩", color: "#64748b", bg: "#f1f5f9" },
|
|
"ast-translate": { label: "端到端翻译(已下线)", icon: "🚀", color: "#64748b", bg: "#f1f5f9" }
|
|
};
|
|
const SLOTS = {
|
|
chat: [
|
|
{ key: "stt_svc_id", slot: "STT", label: "语音识别", cats: [CAT_STT], color: "#1664ff" },
|
|
{ key: "llm_svc_id", slot: "LLM", label: "大语言模型", cats: [CAT_LLM, CAT_LLM_VISION], color: "#b45309" },
|
|
{ key: "tts_svc_id", slot: "TTS", label: "语音合成", cats: [CAT_TTS], color: "#7c3aed" }
|
|
],
|
|
translate: [
|
|
{ key: "stt_svc_id", slot: "STT", label: "语音识别", cats: [CAT_STT], color: "#1664ff" },
|
|
{ key: "mt_svc_id", slot: "MT", label: "机器翻译", cats: [CAT_MT], color: "#059669" },
|
|
{ key: "tts_svc_id", slot: "TTS", label: "语音合成", cats: [CAT_TTS], color: "#7c3aed" }
|
|
],
|
|
"sts-chat": [{ key: "sts_svc_id", slot: "STS", label: "端到端语音对话", cats: [CAT_STS], color: "#be185d" }],
|
|
"ast-translate": [{ key: "ast_svc_id", slot: "AST", label: "端到端语音翻译", cats: [CAT_AST], color: "#f97316" }]
|
|
};
|
|
function slotsOfType(t) {
|
|
return SLOTS[t] ?? [];
|
|
}
|
|
useApi();
|
|
useToast();
|
|
const scopeApp = ref("");
|
|
const scopeApps = ref([]);
|
|
const agents2 = ref([]);
|
|
const allSvcs = ref([]);
|
|
const ttsVoices = ref([]);
|
|
const modalOpen = ref(false);
|
|
const isEditing = ref(false);
|
|
const submitting = ref(false);
|
|
function emptyForm() {
|
|
return {
|
|
app_name: "",
|
|
id: "",
|
|
name: "",
|
|
type: "chat",
|
|
description: "",
|
|
avatar_url: "",
|
|
enable: true,
|
|
stt_svc_id: "",
|
|
llm_svc_id: "",
|
|
tts_svc_id: "",
|
|
mt_svc_id: "",
|
|
sts_svc_id: "",
|
|
ast_svc_id: "",
|
|
system_prompt: "",
|
|
gender: 0,
|
|
greeting_enabled: false,
|
|
greeting_text: "",
|
|
support_langs: "",
|
|
default_lang: "",
|
|
voice_map: [],
|
|
mcp_svc_ids: [],
|
|
variables: [],
|
|
sort: 0
|
|
};
|
|
}
|
|
const form = reactive(emptyForm());
|
|
const isChatType = computed(() => form.type === "chat" || form.type === "sts-chat");
|
|
const supportedLangOptions = computed(() => {
|
|
const codes = (form.support_langs || "").split(",").map((x) => x.trim()).filter(Boolean);
|
|
if (!codes.length) return LANG_OPTIONS;
|
|
return LANG_OPTIONS.filter((o) => codes.includes(o.code));
|
|
});
|
|
const bySort = (a, b) => (b.sort || 0) - (a.sort || 0) || (a.name || "").localeCompare(b.name || "");
|
|
const grouped = computed(() => {
|
|
const groups = AGENT_TYPES.map((t) => ({
|
|
...t,
|
|
type: t.value,
|
|
items: agents2.value.filter((a) => a.type === t.value).sort(bySort)
|
|
})).filter((g) => g.items.length);
|
|
for (const [type, meta] of Object.entries(LEGACY_TYPES)) {
|
|
const items = agents2.value.filter((a) => a.type === type).sort(bySort);
|
|
if (items.length) groups.push({ value: type, type, hint: "已下线的类型,仅供查看与清理", ...meta, items });
|
|
}
|
|
return groups;
|
|
});
|
|
const voiceSvcId = computed(() => form.type === "sts-chat" ? form.sts_svc_id : form.tts_svc_id);
|
|
const voiceProvider = computed(() => allSvcs.value.find((s) => s.id === voiceSvcId.value)?.provider ?? "");
|
|
const voiceTableSupported = computed(() => !!voiceProvider.value && ttsVoices.value.some((v) => v.provider === voiceProvider.value));
|
|
function voiceOptions(language, gender) {
|
|
const provider = voiceProvider.value;
|
|
if (!provider || !language) return [];
|
|
const base = (language.split("-")[0] || "").toLowerCase();
|
|
const hit = ttsVoices.value.filter((v) => {
|
|
if (v.provider !== provider) return false;
|
|
if (gender && v.gender !== gender) return false;
|
|
return v.language.toLowerCase() === language.toLowerCase();
|
|
});
|
|
if (hit.length) return hit;
|
|
return ttsVoices.value.filter((v) => {
|
|
if (v.provider !== provider) return false;
|
|
if (gender && v.gender !== gender) return false;
|
|
return (v.language.split("-")[0] || "").toLowerCase() === base;
|
|
});
|
|
}
|
|
const mcpSvcs = computed(() => svcsByCats([CAT_MCP]));
|
|
function svcCats(s) {
|
|
return (s.categories || "").split(",").map(Number);
|
|
}
|
|
function svcsByCats(cats) {
|
|
return allSvcs.value.filter((s) => s.enable && svcCats(s).some((c) => cats.includes(c)));
|
|
}
|
|
function isVisionSvc(s) {
|
|
return svcCats(s).includes(CAT_LLM_VISION);
|
|
}
|
|
function svcName(id) {
|
|
if (!id) return "未配置";
|
|
const s = allSvcs.value.find((x) => x.id === id);
|
|
return s ? s.name : id;
|
|
}
|
|
function pipelineOf(a) {
|
|
return slotsOfType(a.type).map((s) => ({ slot: s.slot, color: s.color, id: a[s.key] }));
|
|
}
|
|
return (_ctx, _push, _parent, _attrs) => {
|
|
_push(`<div${ssrRenderAttrs(_attrs)} data-v-dcf87e76><div class="flex items-center justify-between mb-5 flex-wrap gap-3" data-v-dcf87e76><div data-v-dcf87e76><h2 class="text-lg font-semibold text-slate-800" data-v-dcf87e76>Agent 配置</h2><p class="text-xs text-slate-400 mt-1" data-v-dcf87e76> 把已配置的第三方服务编排成可下发客户端的智能体。四种类型按需引用不同服务;通话翻译规则只能引用「翻译」与「端到端翻译」两类。 </p></div><div class="flex items-center gap-3" data-v-dcf87e76><span class="text-sm text-slate-500" data-v-dcf87e76>作用域</span><select class="select select-bordered select-sm" data-v-dcf87e76><option value="" data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(scopeApp.value) ? ssrLooseContain(scopeApp.value, "") : ssrLooseEqual(scopeApp.value, "")) ? " selected" : ""}>全局默认</option><!--[-->`);
|
|
ssrRenderList(scopeApps.value, (a) => {
|
|
_push(`<option${ssrRenderAttr("value", a)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(scopeApp.value) ? ssrLooseContain(scopeApp.value, a) : ssrLooseEqual(scopeApp.value, a)) ? " selected" : ""}>${ssrInterpolate(a)}</option>`);
|
|
});
|
|
_push(`<!--]--></select><button class="btn btn-primary btn-sm text-white" data-v-dcf87e76>+ 新建 Agent</button></div></div>`);
|
|
if (!agents2.value.length) {
|
|
_push(`<div class="text-center py-20 text-slate-300" data-v-dcf87e76><div class="text-5xl mb-3" data-v-dcf87e76>🤖</div><p class="text-sm" data-v-dcf87e76>当前作用域下还没有 Agent</p><p class="text-xs mt-1" data-v-dcf87e76>先在「第三方服务配置」里配好服务,再来把它们组装成 Agent</p></div>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<!--[-->`);
|
|
ssrRenderList(grouped.value, (g) => {
|
|
_push(`<div class="mb-6" data-v-dcf87e76><div class="flex items-center gap-2 mb-3" data-v-dcf87e76><span class="type-tag" style="${ssrRenderStyle({ background: g.bg, color: g.color })}" data-v-dcf87e76>${ssrInterpolate(g.icon)} ${ssrInterpolate(g.label)}</span><span class="text-xs text-slate-400" data-v-dcf87e76>${ssrInterpolate(g.hint)}</span><span class="text-xs text-slate-300" data-v-dcf87e76>·</span><span class="text-xs text-slate-400" data-v-dcf87e76>${ssrInterpolate(g.items.length)} 个</span></div><div class="agent-grid" data-v-dcf87e76><!--[-->`);
|
|
ssrRenderList(g.items, (a) => {
|
|
_push(`<div class="agent-card" data-v-dcf87e76><div class="flex items-start justify-between gap-2" data-v-dcf87e76><div class="min-w-0" data-v-dcf87e76><div class="font-semibold text-sm text-slate-800 truncate" data-v-dcf87e76>${ssrInterpolate(a.name || a.id)}</div><div class="text-[11px] text-slate-400 mt-0.5 truncate" data-v-dcf87e76>${ssrInterpolate(a.id)}</div></div><div class="flex items-center gap-1 flex-shrink-0" data-v-dcf87e76>`);
|
|
if (a.enable) {
|
|
_push(`<span class="badge badge-success badge-xs" data-v-dcf87e76>启用</span>`);
|
|
} else {
|
|
_push(`<span class="badge badge-ghost badge-xs" data-v-dcf87e76>停用</span>`);
|
|
}
|
|
_push(`<button class="btn btn-ghost btn-xs text-error" data-v-dcf87e76>删除</button></div></div>`);
|
|
if (a.description) {
|
|
_push(`<p class="text-xs text-slate-500 mt-2 line-clamp-2" data-v-dcf87e76>${ssrInterpolate(a.description)}</p>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<div class="flex flex-wrap items-center gap-1.5 mt-3" data-v-dcf87e76><!--[-->`);
|
|
ssrRenderList(pipelineOf(a), (s) => {
|
|
_push(`<span class="svc-pill" style="${ssrRenderStyle({ background: s.color })}" data-v-dcf87e76>${ssrInterpolate(s.slot)}: ${ssrInterpolate(svcName(s.id))}</span>`);
|
|
});
|
|
_push(`<!--]--></div>`);
|
|
if (a.support_langs) {
|
|
_push(`<div class="text-[11px] text-slate-400 mt-2 truncate" data-v-dcf87e76> 支持语言:${ssrInterpolate(a.support_langs)}</div>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</div>`);
|
|
});
|
|
_push(`<!--]--></div></div>`);
|
|
});
|
|
_push(`<!--]--><div class="ag-overlay" style="${ssrRenderStyle(modalOpen.value ? null : { display: "none" })}" data-v-dcf87e76><div class="ag-box" data-v-dcf87e76><div class="flex items-center justify-between mb-4" data-v-dcf87e76><div class="flex items-center gap-3" data-v-dcf87e76><h3 class="text-base font-semibold text-slate-800" data-v-dcf87e76>${ssrInterpolate(isEditing.value ? "编辑 Agent" : "新建 Agent")}</h3><span class="scope-chip" data-v-dcf87e76>${ssrInterpolate(scopeApp.value || "全局默认")}</span></div><button class="btn btn-ghost btn-xs" data-v-dcf87e76>✕ 关闭</button></div><section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>类型</div><div class="type-row" data-v-dcf87e76><!--[-->`);
|
|
ssrRenderList(AGENT_TYPES, (t) => {
|
|
_push(`<button type="button" class="${ssrRenderClass([{ on: form.type === t.value, locked: isEditing.value && form.type !== t.value }, "ttab"])}"${ssrIncludeBooleanAttr(isEditing.value) ? " disabled" : ""} data-v-dcf87e76><span class="ttab-title" data-v-dcf87e76>${ssrInterpolate(t.icon)} ${ssrInterpolate(t.label)}</span><span class="ttab-desc" data-v-dcf87e76>${ssrInterpolate(t.hint)}</span></button>`);
|
|
});
|
|
_push(`<!--]--></div>`);
|
|
if (isEditing.value) {
|
|
_push(`<p class="ed-tip" data-v-dcf87e76>类型创建后不可更改;需要换类型请新建一个 Agent。</p>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</section><section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>基本信息</div><div class="grid grid-cols-2 gap-3" data-v-dcf87e76><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>Agent ID <i class="req" data-v-dcf87e76>*</i></span><input${ssrRenderAttr("value", form.id)}${ssrIncludeBooleanAttr(isEditing.value) ? " disabled" : ""} class="input input-bordered input-sm w-full" placeholder="如 trans-cn-en(作用域内唯一,创建后不可改)" data-v-dcf87e76></div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>名称 <i class="req" data-v-dcf87e76>*</i></span><input${ssrRenderAttr("value", form.name)} class="input input-bordered input-sm w-full" placeholder="展示名,如 中英实时翻译" data-v-dcf87e76></div></div><div class="mt-3" data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>描述</span><input${ssrRenderAttr("value", form.description)} class="input input-bordered input-sm w-full" placeholder="这个 Agent 用在什么场景" data-v-dcf87e76></div><div class="grid grid-cols-3 gap-3 mt-3" data-v-dcf87e76><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>头像 URL</span><input${ssrRenderAttr("value", form.avatar_url)} class="input input-bordered input-sm w-full" placeholder="可留空" data-v-dcf87e76></div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>排序(越大越靠前)</span><input${ssrRenderAttr("value", form.sort)} type="number" class="input input-bordered input-sm w-full" data-v-dcf87e76></div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>音色性别偏好</span><select class="select select-bordered select-sm w-full" data-v-dcf87e76><option${ssrRenderAttr("value", 0)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form.gender) ? ssrLooseContain(form.gender, 0) : ssrLooseEqual(form.gender, 0)) ? " selected" : ""}>不限</option><option${ssrRenderAttr("value", 1)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form.gender) ? ssrLooseContain(form.gender, 1) : ssrLooseEqual(form.gender, 1)) ? " selected" : ""}>男</option><option${ssrRenderAttr("value", 2)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form.gender) ? ssrLooseContain(form.gender, 2) : ssrLooseEqual(form.gender, 2)) ? " selected" : ""}>女</option></select></div></div></section><section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>服务编排</div><div class="slot-row" data-v-dcf87e76><!--[-->`);
|
|
ssrRenderList(slotsOfType(form.type), (s, i) => {
|
|
_push(`<!--[--><div class="slot-item" data-v-dcf87e76><span class="stage-tag" style="${ssrRenderStyle({ background: s.color })}" data-v-dcf87e76>${ssrInterpolate(s.slot)}</span><span class="ed-label inline" data-v-dcf87e76>${ssrInterpolate(s.label)}</span><select class="select select-bordered select-sm w-full" data-v-dcf87e76><option value="" disabled data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form[s.key]) ? ssrLooseContain(form[s.key], "") : ssrLooseEqual(form[s.key], "")) ? " selected" : ""}>${ssrInterpolate(svcsByCats(s.cats).length ? "请选择服务" : "(无可用服务,请先去第三方服务配置里添加)")}</option><!--[-->`);
|
|
ssrRenderList(svcsByCats(s.cats), (v) => {
|
|
_push(`<option${ssrRenderAttr("value", v.id)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(form[s.key]) ? ssrLooseContain(form[s.key], v.id) : ssrLooseEqual(form[s.key], v.id)) ? " selected" : ""}>${ssrInterpolate(v.name)}${ssrInterpolate(isVisionSvc(v) ? " 🖼" : "")}</option>`);
|
|
});
|
|
_push(`<!--]--></select></div>`);
|
|
if (i < slotsOfType(form.type).length - 1) {
|
|
_push(`<span class="slot-arrow" data-v-dcf87e76>→</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<!--]-->`);
|
|
});
|
|
_push(`<!--]--></div></section><section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>语言与音色</div><div class="grid grid-cols-2 gap-3" data-v-dcf87e76><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>支持语言(多选)</span>`);
|
|
_push(ssrRenderComponent(__nuxt_component_0, {
|
|
modelValue: form.support_langs,
|
|
"onUpdate:modelValue": ($event) => form.support_langs = $event,
|
|
multiple: ""
|
|
}, null, _parent));
|
|
_push(`</div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>默认语言</span>`);
|
|
_push(ssrRenderComponent(__nuxt_component_0, {
|
|
modelValue: form.default_lang,
|
|
"onUpdate:modelValue": ($event) => form.default_lang = $event,
|
|
options: supportedLangOptions.value
|
|
}, null, _parent));
|
|
_push(`</div></div><div class="mt-3" data-v-dcf87e76><div class="flex items-center justify-between mb-1" data-v-dcf87e76><span class="ed-label mb-0" data-v-dcf87e76>音色(按语言+性别配,Agent 切语言时自动换音色)</span><div class="flex gap-1" data-v-dcf87e76><button class="btn btn-ghost btn-xs"${ssrIncludeBooleanAttr(!voiceTableSupported.value) ? " disabled" : ""} data-v-dcf87e76>按支持语言补全</button><button class="btn btn-ghost btn-xs" data-v-dcf87e76>+ 添加一行</button></div></div><p class="ed-tip mb-1" data-v-dcf87e76>`);
|
|
if (!voiceSvcId.value) {
|
|
_push(`<!--[-->先在上方选好语音服务,这里才能列出可用音色。<!--]-->`);
|
|
} else if (voiceTableSupported.value) {
|
|
_push(`<!--[--> 候选来自内置音色表(${ssrInterpolate(voiceProvider.value)});同一语言+性别有多个时默认第一个,可在下拉里换。没配到的语言走服务商默认音色。 <!--]-->`);
|
|
} else {
|
|
_push(`<!--[-->「${ssrInterpolate(voiceProvider.value || "该服务商")}」不在内置音色表里,请手填服务商的音色 id。<!--]-->`);
|
|
}
|
|
_push(`</p>`);
|
|
if (!form.voice_map.length) {
|
|
_push(`<div class="text-xs text-slate-300 py-2" data-v-dcf87e76>未设置,全部走服务商默认音色</div>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<!--[-->`);
|
|
ssrRenderList(form.voice_map, (v, i) => {
|
|
_push(`<div class="voice-row" data-v-dcf87e76><select class="select select-bordered select-xs" data-v-dcf87e76><option value="" data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.language) ? ssrLooseContain(v.language, "") : ssrLooseEqual(v.language, "")) ? " selected" : ""}>(语言)</option><!--[-->`);
|
|
ssrRenderList(supportedLangOptions.value, (o) => {
|
|
_push(`<option${ssrRenderAttr("value", o.code)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.language) ? ssrLooseContain(v.language, o.code) : ssrLooseEqual(v.language, o.code)) ? " selected" : ""}>${ssrInterpolate(o.code)} · ${ssrInterpolate(o.name)}</option>`);
|
|
});
|
|
_push(`<!--]--></select><select class="select select-bordered select-xs" data-v-dcf87e76><option${ssrRenderAttr("value", 0)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.gender) ? ssrLooseContain(v.gender, 0) : ssrLooseEqual(v.gender, 0)) ? " selected" : ""}>不限</option><option${ssrRenderAttr("value", 1)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.gender) ? ssrLooseContain(v.gender, 1) : ssrLooseEqual(v.gender, 1)) ? " selected" : ""}>男</option><option${ssrRenderAttr("value", 2)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.gender) ? ssrLooseContain(v.gender, 2) : ssrLooseEqual(v.gender, 2)) ? " selected" : ""}>女</option></select>`);
|
|
if (voiceTableSupported.value && voiceOptions(v.language, v.gender).length) {
|
|
_push(`<select class="select select-bordered select-xs flex-1" data-v-dcf87e76><!--[-->`);
|
|
ssrRenderList(voiceOptions(v.language, v.gender), (o, oi) => {
|
|
_push(`<option${ssrRenderAttr("value", o.voice_id)} data-v-dcf87e76${ssrIncludeBooleanAttr(Array.isArray(v.voice) ? ssrLooseContain(v.voice, o.voice_id) : ssrLooseEqual(v.voice, o.voice_id)) ? " selected" : ""}>${ssrInterpolate(o.name)} · ${ssrInterpolate(o.voice_id)}${ssrInterpolate(oi === 0 ? "(默认)" : "")}</option>`);
|
|
});
|
|
_push(`<!--]--></select>`);
|
|
} else {
|
|
_push(`<input${ssrRenderAttr("value", v.voice)} class="input input-bordered input-xs flex-1" placeholder="音色 id,如 zh-CN-XiaoxiaoNeural" data-v-dcf87e76>`);
|
|
}
|
|
_push(`<button class="btn btn-ghost btn-xs text-error" data-v-dcf87e76>删除</button></div>`);
|
|
});
|
|
_push(`<!--]--></div></section>`);
|
|
if (isChatType.value) {
|
|
_push(`<section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>对话设定</div><div data-v-dcf87e76><span class="ed-label" data-v-dcf87e76>系统提示词</span><textarea class="textarea textarea-bordered w-full text-xs" rows="3" placeholder="定义这个智能体的人设与行为" data-v-dcf87e76>${ssrInterpolate(form.system_prompt)}</textarea></div><div class="mt-3" data-v-dcf87e76><label class="flex items-center gap-2 text-sm cursor-pointer" data-v-dcf87e76><input${ssrIncludeBooleanAttr(Array.isArray(form.greeting_enabled) ? ssrLooseContain(form.greeting_enabled, null) : form.greeting_enabled) ? " checked" : ""} type="checkbox" class="checkbox checkbox-sm checkbox-primary" data-v-dcf87e76><span data-v-dcf87e76>开场白</span></label>`);
|
|
if (form.greeting_enabled) {
|
|
_push(`<input${ssrRenderAttr("value", form.greeting_text)} class="input input-bordered input-sm w-full mt-2" placeholder="接通后先说的一句话" data-v-dcf87e76>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</div></section>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<section class="ed-section" data-v-dcf87e76><div class="ed-section-title" data-v-dcf87e76>MCP 服务(可选,给 Agent 挂工具)</div>`);
|
|
if (!mcpSvcs.value.length) {
|
|
_push(`<p class="ed-tip" data-v-dcf87e76>还没有启用的 MCP 服务,先去「第三方服务配置 → MCP 服务」添加。</p>`);
|
|
} else {
|
|
_push(`<div class="mcp-grid" data-v-dcf87e76><!--[-->`);
|
|
ssrRenderList(mcpSvcs.value, (m) => {
|
|
_push(`<label class="${ssrRenderClass([{ on: form.mcp_svc_ids.includes(m.id) }, "mcp-item"])}" data-v-dcf87e76><input type="checkbox" class="checkbox checkbox-xs checkbox-primary"${ssrIncludeBooleanAttr(form.mcp_svc_ids.includes(m.id)) ? " checked" : ""} data-v-dcf87e76><span class="min-w-0" data-v-dcf87e76><span class="block truncate" data-v-dcf87e76>${ssrInterpolate(m.name)}</span><span class="block truncate text-[10px] text-slate-400 font-mono" data-v-dcf87e76>${ssrInterpolate(m.id)}</span></span></label>`);
|
|
});
|
|
_push(`<!--]--></div>`);
|
|
}
|
|
_push(`</section><section class="ed-section" data-v-dcf87e76><div class="flex items-center justify-between mb-1" data-v-dcf87e76><div class="ed-section-title mb-0" data-v-dcf87e76>变量(提示词/开场白里用 {{key}} 占位)</div><button class="btn btn-ghost btn-xs" data-v-dcf87e76>+ 添加变量</button></div>`);
|
|
if (!form.variables.length) {
|
|
_push(`<div class="text-xs text-slate-300 py-2" data-v-dcf87e76>未定义变量</div>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<!--[-->`);
|
|
ssrRenderList(form.variables, (v, i) => {
|
|
_push(`<div class="var-row" data-v-dcf87e76><input${ssrRenderAttr("value", v.key)} class="input input-bordered input-xs" placeholder="key" data-v-dcf87e76><input${ssrRenderAttr("value", v.label)} class="input input-bordered input-xs" placeholder="展示名" data-v-dcf87e76><input${ssrRenderAttr("value", v.def_value)} class="input input-bordered input-xs flex-1" placeholder="默认值(客户端没传时用它)" data-v-dcf87e76><button class="btn btn-ghost btn-xs text-error" data-v-dcf87e76>删除</button></div>`);
|
|
});
|
|
_push(`<!--]--></section><div class="ed-footer" data-v-dcf87e76><label class="flex items-center gap-2 text-sm cursor-pointer" data-v-dcf87e76><input${ssrIncludeBooleanAttr(Array.isArray(form.enable) ? ssrLooseContain(form.enable, null) : form.enable) ? " checked" : ""} type="checkbox" class="checkbox checkbox-sm checkbox-primary" data-v-dcf87e76><span data-v-dcf87e76>启用</span></label><div class="flex gap-2" data-v-dcf87e76><button class="btn btn-ghost btn-sm" data-v-dcf87e76>取消</button><button class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(submitting.value) ? " disabled" : ""} data-v-dcf87e76>保存</button></div></div></div></div></div>`);
|
|
};
|
|
}
|
|
});
|
|
const _sfc_setup = _sfc_main.setup;
|
|
_sfc_main.setup = (props, ctx) => {
|
|
const ssrContext = useSSRContext();
|
|
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/agents.vue");
|
|
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
|
|
};
|
|
const agents = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-dcf87e76"]]);
|
|
|
|
export { agents as default };
|
|
//# sourceMappingURL=agents-Bh_gLb1p.mjs.map
|
|
|