feat: Enhance Kol Generation Service with web search and knowledge group support

- Added `EnableWebSearch` and `KnowledgeGroupIDs` fields to `KolGenerationSubmitRequest`.
- Updated `Submit` method in `KolGenerationService` to handle new request fields.
- Integrated web search and knowledge group validation based on card configuration.
- Introduced caching mechanisms in `KolPackageService`, `KolPromptService`, and `KolSubscriptionAdminService` to improve performance.
- Implemented knowledge context resolution in `KolGenerationWorker` to enrich prompts with relevant knowledge snippets.
- Added utility functions for handling card configuration in both backend and frontend.
- Created tests for knowledge extraction and rendering to ensure accuracy and reliability.
This commit is contained in:
2026-04-18 13:47:32 +08:00
parent 3ef0807456
commit b2605abd6a
27 changed files with 2051 additions and 171 deletions
+76 -3
View File
@@ -7,6 +7,8 @@ import { message } from "ant-design-vue";
import { ArrowLeftOutlined, ThunderboltOutlined } from "@ant-design/icons-vue";
import { kolGenerateApi } from "@/lib/api";
import KolDynamicForm from "@/components/kol/KolDynamicForm.vue";
import KnowledgeGroupSelect from "@/components/KnowledgeGroupSelect.vue";
import { parseKolCardConfig } from "@/lib/kol-card-config";
const route = useRoute();
const router = useRouter();
@@ -21,6 +23,13 @@ const schemaQuery = useQuery({
});
const values = ref<Record<string, any>>({});
const enableWebSearch = ref(false);
const selectedKnowledgeGroupIds = ref<number[]>([]);
const schema = computed(() => schemaQuery.data.value);
const cardConfig = computed(() => parseKolCardConfig(schema.value?.card_config_json));
const allowWebSearch = computed(() => cardConfig.value.allow_web_search);
const allowUserKnowledge = computed(() => cardConfig.value.allow_user_knowledge);
function fieldKey(key?: string | null, id?: string): string {
return key?.trim() || id || "";
@@ -36,6 +45,8 @@ watch(
newValues[fieldKey(v.key, v.id)] = v.type === "checkbox" ? [] : undefined;
});
values.value = newValues;
enableWebSearch.value = false;
selectedKnowledgeGroupIds.value = [];
}
},
{ immediate: true }
@@ -43,7 +54,11 @@ watch(
const generateMutation = useMutation({
mutationFn: (variables: Record<string, any>) =>
kolGenerateApi.submit(subscriptionPromptId.value, { variables }),
kolGenerateApi.submit(subscriptionPromptId.value, {
variables,
enable_web_search: allowWebSearch.value ? enableWebSearch.value : undefined,
knowledge_group_ids: allowUserKnowledge.value ? selectedKnowledgeGroupIds.value : undefined,
}),
onSuccess: (data) => {
message.success(t("common.copySuccess")); // Or a generic success message
void router.push({ name: "article-editor", params: { id: String(data.article_id) } });
@@ -75,8 +90,6 @@ function handleSubmit() {
generateMutation.mutate(values.value);
}
const schema = computed(() => schemaQuery.data.value);
</script>
<template>
@@ -112,6 +125,29 @@ const schema = computed(() => schemaQuery.data.value);
{{ t("kol.generate.fillVariables") }}
</div>
<div v-if="allowWebSearch || allowUserKnowledge" class="capability-card">
<div v-if="allowWebSearch" class="capability-row">
<div class="capability-copy">
<div class="capability-label">联网搜索</div>
<div class="capability-hint">按需启用生成时可参考实时网页信息</div>
</div>
<a-switch
v-model:checked="enableWebSearch"
:disabled="generateMutation.isPending.value"
/>
</div>
<div v-if="allowUserKnowledge" class="capability-knowledge">
<label class="capability-label">知识库引用</label>
<KnowledgeGroupSelect
v-model="selectedKnowledgeGroupIds"
:disabled="generateMutation.isPending.value"
placeholder="可选,选择你自己的知识库分组辅助生成"
/>
<div class="capability-hint">只会使用你当前租户下可访问的知识库分组</div>
</div>
</div>
<KolDynamicForm
v-model="values"
:variables="schema.schema_json.variables"
@@ -207,6 +243,43 @@ const schema = computed(() => schemaQuery.data.value);
margin-bottom: 24px;
}
.capability-card {
margin-bottom: 24px;
padding: 16px;
border: 1px solid #e6edf5;
border-radius: 12px;
background: #fafcff;
}
.capability-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.capability-knowledge {
margin-top: 16px;
}
.capability-copy {
min-width: 0;
}
.capability-label {
display: block;
margin-bottom: 8px;
color: #111827;
font-size: 14px;
font-weight: 600;
}
.capability-hint {
color: #667085;
font-size: 13px;
line-height: 1.5;
}
.form-actions {
margin-top: 32px;
}