Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,11 @@ Workspace 清除策略通过 PUT `batch_clean_time` 提交当前智能体的单
知识库及目标文档选项通过当前范围 Knowledge/Document API 查询,文档使用 `getAllDocuments(knowledgeId)`。
聊天记录与标注接口保留在同一 API 文件;日志详情使用现有 `LogConversation`,其聊天记录查询仍使用 Workspace API。

简易智能体详情的 `model`、`stt_model`、`tts_model`、`long_term_model` 为模型 ID 响应别名,
`knowledge_list` 为已关联知识库快照;保存映射到对应的 `*_model_id` 字段(主模型为 `model_id`)。
语音及长期记忆模型的空 ID 使用 `null`,不提交空 UUID 字符串;简易设置不将详情的 `work_flow`
回传,避免触发工作流配置提取。

### 智能体发布渠道

`admin/workspace/application/access.ts` 和 `admin/system/resource-management/application/access.ts`
Expand Down
11 changes: 8 additions & 3 deletions ui/src/api/types/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { APPLICATION_ACCESS_PLATFORM, APPLICATION_TYPE } from '@/api/enums'
import type { DefaultModelSettingPayload } from './model'
import type { WorkflowStoreTemplate } from './workflow-template'
import type { Dict } from './common'
import type { KnowledgeItem } from './knowledge'

export type ApplicationType = (typeof APPLICATION_TYPE)[keyof typeof APPLICATION_TYPE]

Expand All @@ -26,6 +27,10 @@ export interface ApplicationAccessStatusPayload {
export interface ApplicationDetail extends Omit<ApplicationFormPayload, 'desc'> {
/** 详情接口返回的主模型 ID。 */
model?: string | null
stt_model?: string | null
tts_model?: string | null
long_term_model?: string | null
knowledge_list?: KnowledgeItem[]
default_model_setting?: DefaultModelSettingPayload
create_time?: string
desc?: string | null
Expand Down Expand Up @@ -67,8 +72,8 @@ export interface ApplicationFormPayload {
model_params_setting?: Record<string, unknown>
tts_model_params_setting?: Record<string, unknown>
stt_model_params_setting?: Record<string, unknown>
stt_model_id?: string
tts_model_id?: string
stt_model_id?: string | null
tts_model_id?: string | null
stt_model_enable?: boolean
tts_model_enable?: boolean
tts_type?: string
Expand All @@ -88,7 +93,7 @@ export interface ApplicationFormPayload {
mcp_output_enable?: boolean
work_flow_template?: Record<string, unknown>
long_term_enable?: boolean
long_term_model_id?: string
long_term_model_id?: string | null
long_term_model_params_setting?: Record<string, unknown>
long_term_trigger_setting?: Record<string, unknown>
long_term_trigger_type?: string
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/global/mk-list-item/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const hasActionDropdown = computed(() => hasRenderableSlotContent(slots['action-

<template>
<div
class="group flex-align-center cursor-pointer rounded-md px-2 py-[9px] hover:bg-N900/10"
class="group flex-align-center cursor-pointer rounded-md p-2 hover:bg-N900/10"
:class="{ 'bg-primary/10 font-medium text-primary hover:bg-primary/10': active }"
@click="emit('click')"
>
Expand Down
19 changes: 19 additions & 0 deletions ui/src/views/VIEW_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,25 @@
提交入口同时阻止共享写入。System 文档、标签与分段 API 已装配,具体服务能力仍需对应部署支持。
知识库全屏 WorkflowView 的加载、保存、模型查询仍直接使用 Workspace API,其他来源仅完成导航,不能视为范围接入完成。

### 简易智能体设置

`application-detail/setting/` 使用可折叠配置表单和调试预览占位双栏布局,仅模型设置和知识库
通过 `:expanded="true"` 默认展开,未绑定更新事件时由组件内部切换状态。通过详情上下文按
Workspace/System 资源管理范围保存、发布,发布前先保存当前配置;草稿独立深拷贝,保存失败
保留输入,保存成功后用返回详情回填。详情返回的模型别名统一回填,空语音模型 ID 提交
`null`,简易设置不提交详情中的画布或只读字段,保留范围外配置。

知识库、智能体、技能和工具复用公共资源选择弹窗,保留未能查询到的关联 ID;智能体排除自身。
技能区域复用 AI 对话节点的 `ResourceSetting`,统一选择、移除及 MCP 来源配置;资源 ID 与回显
快照回写页面草稿,保存时剔除回显快照。详情回填时,有关联智能体 ID 才查询智能体列表,
有工具、Skills 或 MCP ID 才查询工具列表,用于补全名称和图标。长期记忆使用功能本地 `ButtonLongTermSetting`,沿用工作流的轮次、周期和 Cron 交互,
直接选择模型与参数,不提供默认模型选项;打开时若未配置模型,选中首个可用模型,
选项异步返回后同样补选,已有选择不覆盖。简易接口提交具体模型 ID。语音输入直接选择模型,语音播放提供浏览器播放和自定义模型,
不提供默认语音模型选项;启用后显示自动发送/播放,关闭时清空对应模型,播放恢复浏览器方式。输出思考复用工作流的 `ThinkingSetting`,确认时合并思考字段并保留系统和用户提示词。
知识库检索、无引用处理和问题优化由功能本地 `ButtonKnowledgeSetting` 维护,按钮与弹窗封装在同一组件,
弹窗确认只更新页面草稿。模型使用当前范围的共享模型查询和参数接口。系统提示词生成复用
工作流的 `PromptGenerate`,由页面注入 `resourceScope`,使用当前模型与参数生成后回填草稿。

### 创建与设置

四类知识库创建入口集中在 `knowledge/create-knowledge/`:`BaseKnowledgeDialog`、
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<script setup lang="ts">
import { ref, useTemplateRef } from 'vue'
import { cloneDeep } from 'lodash'
import type { FormInstance } from 'element-plus'
import { KNOWLEDGE_SEARCH_MODE } from '@/api/enums'
import { KNOWLEDGE_SEARCH_MODE_OPTIONS } from '@/constants/knowledge'
import { createSettings, DEFAULT_DESIGNATED_ANSWER, DEFAULT_PROBLEM_OPTIMIZATION_PROMPT, type ApplicationSettings } from '../settings'

defineOptions({ name: 'ButtonKnowledgeSetting' })

const props = defineProps<{ setting: ApplicationSettings }>()
const emit = defineEmits<{ submit: [settings: Partial<ApplicationSettings>] }>()
const visible = ref(false)
const formData = ref(createSettings())
const noReferenceAnswers = ref<Record<string, string>>({ ai_questioning: '{question}', designated_answer: DEFAULT_DESIGNATED_ANSWER })
function changeNoReferenceStatus(status: string | number | boolean | undefined) {
formData.value.knowledge_setting.no_references_setting.value = noReferenceAnswers.value[String(status)] ?? '{question}'
}
const formRef = useTemplateRef<FormInstance>('formRef')
function open() {
formData.value = cloneDeep(props.setting)
const responseSetting = props.setting.knowledge_setting.no_references_setting
const answer = responseSetting.value || noReferenceAnswers.value[responseSetting.status] || '{question}'
noReferenceAnswers.value[responseSetting.status] = answer
formData.value.knowledge_setting.no_references_setting.value = answer
visible.value = true
}
// 全文检索切换为 0,其余模式恢复为 0.6,与工作流参数设置保持一致。
function changeSearchMode() {
formData.value.knowledge_setting.similarity = formData.value.knowledge_setting.search_mode === KNOWLEDGE_SEARCH_MODE.KEYWORDS ? 0 : 0.6
}
function submit() {
formRef.value?.validate((valid) => {
if (!valid) return
const settings = formData.value
emit(
'submit',
cloneDeep({
knowledge_setting: settings.knowledge_setting,
problem_optimization: settings.problem_optimization,
problem_optimization_prompt: settings.problem_optimization_prompt,
}),
)
visible.value = false
})
}
function resetData() {
formRef.value?.clearValidate()
formData.value = createSettings()
noReferenceAnswers.value = { ai_questioning: '{question}', designated_answer: DEFAULT_DESIGNATED_ANSWER }
}
</script>

<template>
<!-- 配置知识库检索参数 -->
<el-button text type="primary" @click.stop="open">
<MkIcon name="icon_setting" />
</el-button>
<MkDialog v-model="visible" title="参数设置" @closed="resetData" align-center>
<el-form ref="formRef" :model="formData" label-position="top" require-asterisk-position="right" @submit.prevent>
<el-form-item label="检索模式">
<!-- 选择检索模式 -->
<el-radio-group v-model="formData.knowledge_setting.search_mode" class="space-y-2" @change="changeSearchMode">
<template v-for="mode in KNOWLEDGE_SEARCH_MODE_OPTIONS" :key="mode.value">
<el-card shadow="hover" class="w-full" :class="{ 'border-primary!': formData.knowledge_setting.search_mode === mode.value }">
<el-radio :value="mode.value" class="mk-card-radio">
<h6>{{ mode.label }}</h6>
<span class="block text-sm text-N600">{{ mode.description }}</span>
</el-radio>
</el-card>
</template>
</el-radio-group>
</el-form-item>
<div class="grid grid-cols-2 gap-3">
<el-form-item>
<template #label>
<span class="flex-align-center gap-1">
相似度高于
<MkTooltip content="相似度越高相关性越强。" placement="right"><MkIcon name="icon_info_outlined" class="text-N600!" /></MkTooltip>
</span>
</template>
<el-input-number
v-model="formData.knowledge_setting.similarity"
:min="0"
:max="formData.knowledge_setting.search_mode === KNOWLEDGE_SEARCH_MODE.BLEND ? 2 : 1"
:step="0.1"
:precision="3"
:value-on-clear="0"
controls-position="right"
align="left"
/>
</el-form-item>
<el-form-item label="召回分段数 TOP">
<el-input-number
v-model="formData.knowledge_setting.top_n"
:min="1"
:max="10000"
:precision="0"
:value-on-clear="1"
controls-position="right"
align="left"
/>
</el-form-item>
</div>
<el-form-item label="最多引用字符数">
<MkSlider v-model="formData.knowledge_setting.max_paragraph_char_number" :min="500" :max="100000" />
</el-form-item>
<el-form-item label="无引用知识库分段时">
<el-radio-group
:model-value="formData.knowledge_setting.no_references_setting.status"
@change="changeNoReferenceStatus"
@update:model-value="formData.knowledge_setting.no_references_setting.status = String($event)"
>
<el-radio value="ai_questioning">继续向 AI 提问</el-radio>
<el-radio value="designated_answer">指定回答</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
class="-mt-2"
v-if="formData.knowledge_setting.no_references_setting.status === 'designated_answer'"
prop="knowledge_setting.no_references_setting.value"
:rules="{ required: true, whitespace: true, message: '请输入回答内容', trigger: 'blur' }"
>
<el-input
v-model="formData.knowledge_setting.no_references_setting.value"
@input="noReferenceAnswers[formData.knowledge_setting.no_references_setting.status] = $event"
type="textarea"
:rows="3"
maxlength="2048"
:placeholder="DEFAULT_DESIGNATED_ANSWER"
/>
</el-form-item>
<el-form-item label="问题优化"><el-switch v-model="formData.problem_optimization" size="small" /></el-form-item>
<el-form-item v-if="formData.problem_optimization" label="提示词">
<el-input
v-model="formData.problem_optimization_prompt"
type="textarea"
maxlength="2048"
:rows="5"
:placeholder="DEFAULT_PROBLEM_OPTIMIZATION_PROMPT"
/>
</el-form-item>
</el-form>
<template #footer>
<!-- 取消配置 -->
<el-button plain @click="visible = false">取消</el-button>
<!-- 确认配置,暂存到页面草稿 -->
<el-button type="primary" @click="submit">保存</el-button>
</template>
</MkDialog>
</template>
Loading
Loading