feat(frontend): switch skill messaging to selectedSkills payload
This commit is contained in:
parent
a8cfe1c42e
commit
10cf4f0b00
|
|
@ -56,13 +56,17 @@ export function IframeTestPanel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSendSelectSkill() {
|
function handleSendSelectSkill() {
|
||||||
iframeSkill.sendSelectSkill(["skill_001"]);
|
iframeSkill.sendSelectSkill([{ id: "skill_001", name: "测试技能1" }]);
|
||||||
addLog("postMessage → selectSkill (skill_id=['skill_001'])");
|
addLog("postMessage → selectedSkills ([{id:'skill_001',name:'测试技能1'}])");
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSendSelectSkillArray() {
|
function handleSendSelectSkillArray() {
|
||||||
iframeSkill.sendSelectSkill(["1246", "1247", "1248"]);
|
iframeSkill.sendSelectSkill([
|
||||||
addLog("postMessage → selectSkill (skill_id=['1246','1247','1248'])");
|
{ id: "1246", name: "技能A" },
|
||||||
|
{ id: "1247", name: "技能B" },
|
||||||
|
{ id: "1248", name: "技能C" },
|
||||||
|
]);
|
||||||
|
addLog("postMessage → selectedSkills (3 skills)");
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleOpenSkillDialog() {
|
function handleOpenSkillDialog() {
|
||||||
|
|
@ -72,7 +76,7 @@ export function IframeTestPanel() {
|
||||||
|
|
||||||
function handleClearSkill() {
|
function handleClearSkill() {
|
||||||
iframeSkill.clearSkill();
|
iframeSkill.clearSkill();
|
||||||
addLog("clearSkill 已调用,postMessage → skill_id=[]");
|
addLog("clearSkill 已调用,postMessage → selectedSkills=[]");
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTestClipboardCopy() {
|
function handleTestClipboardCopy() {
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,10 @@ import {
|
||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/dropdown-menu";
|
||||||
import { useI18n } from "@/core/i18n/hooks";
|
import { useI18n } from "@/core/i18n/hooks";
|
||||||
|
import type {
|
||||||
|
SelectedSkillPayloadItem,
|
||||||
|
SuggestionSkillChildren,
|
||||||
|
} from "@/core/i18n/locales/types";
|
||||||
import { POST_MESSAGE_TYPES, sendToParent } from "@/core/iframe-messages";
|
import { POST_MESSAGE_TYPES, sendToParent } from "@/core/iframe-messages";
|
||||||
import { useModels } from "@/core/models/hooks";
|
import { useModels } from "@/core/models/hooks";
|
||||||
import type { AgentThreadContext } from "@/core/threads";
|
import type { AgentThreadContext } from "@/core/threads";
|
||||||
|
|
@ -491,7 +495,7 @@ export function InputBox({
|
||||||
function SuggestionListContainer({
|
function SuggestionListContainer({
|
||||||
sendSelectSkill,
|
sendSelectSkill,
|
||||||
}: {
|
}: {
|
||||||
sendSelectSkill: (skill_id: string[]) => void;
|
sendSelectSkill: (selectedSkills: SelectedSkillPayloadItem[]) => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="absolute right-0 bottom-0 left-0 z-0 flex translate-y-full items-center justify-center pt-4">
|
<div className="absolute right-0 bottom-0 left-0 z-0 flex translate-y-full items-center justify-center pt-4">
|
||||||
|
|
@ -504,7 +508,7 @@ function SuggestionListContainer({
|
||||||
function SuggestionList({
|
function SuggestionList({
|
||||||
sendSelectSkill,
|
sendSelectSkill,
|
||||||
}: {
|
}: {
|
||||||
sendSelectSkill: (skill_id: string[]) => void;
|
sendSelectSkill: (selectedSkills: SelectedSkillPayloadItem[]) => void;
|
||||||
}) {
|
}) {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { textInput } = usePromptInputController();
|
const { textInput } = usePromptInputController();
|
||||||
|
|
@ -521,20 +525,31 @@ function SuggestionList({
|
||||||
suggestion: {
|
suggestion: {
|
||||||
prompt: string;
|
prompt: string;
|
||||||
skill_id?: string[];
|
skill_id?: string[];
|
||||||
children?: { skill_id: string[] }[];
|
children?: SuggestionSkillChildren[];
|
||||||
|
suggestion: string;
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
// 优先从 children 中提取 skill_id 数组,发送给宿主页
|
// 优先从 children 中提取 skill_id 数组,转换为 selectedSkills 发送给宿主页
|
||||||
const childSkillIds = (suggestion.children ?? [])
|
const childSkillIds = (suggestion.children ?? [])
|
||||||
.flatMap((item) => item.skill_id)
|
.flatMap((item) => item.skill_id)
|
||||||
.map((item) => item.trim())
|
.map((item) => item.trim())
|
||||||
.filter((id): id is string => Boolean(id));
|
.filter((id): id is string => Boolean(id));
|
||||||
if (childSkillIds.length > 0) {
|
if (childSkillIds.length > 0) {
|
||||||
sendSelectSkill(childSkillIds);
|
sendSelectSkill(
|
||||||
|
childSkillIds.map((id) => ({
|
||||||
|
id,
|
||||||
|
name: suggestion.suggestion,
|
||||||
|
})),
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (suggestion.skill_id && suggestion.skill_id.length > 0) {
|
if (suggestion.skill_id && suggestion.skill_id.length > 0) {
|
||||||
sendSelectSkill(suggestion.skill_id);
|
sendSelectSkill(
|
||||||
|
suggestion.skill_id.map((id) => ({
|
||||||
|
id,
|
||||||
|
name: suggestion.suggestion,
|
||||||
|
})),
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 原有逻辑
|
// 原有逻辑
|
||||||
|
|
|
||||||
|
|
@ -120,34 +120,34 @@ export const enUS: Translations = {
|
||||||
prompt:
|
prompt:
|
||||||
"Write an academic paper about [topic], including abstract, introduction, body and references.",
|
"Write an academic paper about [topic], including abstract, introduction, body and references.",
|
||||||
icon: PenLineIcon,
|
icon: PenLineIcon,
|
||||||
skill_id: "1245",
|
children: [{ id: "1245", name: "Paper Writing" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
suggestion: "Report Generation",
|
suggestion: "Report Generation",
|
||||||
prompt:
|
prompt:
|
||||||
"Analyze [topic] in depth and generate a well-structured research report.",
|
"Analyze [topic] in depth and generate a well-structured research report.",
|
||||||
icon: MicroscopeIcon,
|
icon: MicroscopeIcon,
|
||||||
skill_id: "520",
|
children: [{ id: "520", name: "Report Generation" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
suggestion: "Copywriting",
|
suggestion: "Copywriting",
|
||||||
prompt:
|
prompt:
|
||||||
"Create a complete planning proposal and promotional copy for [project/event].",
|
"Create a complete planning proposal and promotional copy for [project/event].",
|
||||||
icon: ShapesIcon,
|
icon: ShapesIcon,
|
||||||
skill_id: "409",
|
children: [{ id: "409", name: "Copywriting" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
suggestion: "Document Processing",
|
suggestion: "Document Processing",
|
||||||
prompt:
|
prompt:
|
||||||
"Process [document] with reading, summarizing, translating or format conversion.",
|
"Process [document] with reading, summarizing, translating or format conversion.",
|
||||||
icon: CompassIcon,
|
icon: CompassIcon,
|
||||||
skill_id: "5",
|
children: [{ id: "5", name: "Document Processing" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
suggestion: "Market Research",
|
suggestion: "Market Research",
|
||||||
prompt: "TestingTestingTestingTestingTesting",
|
prompt: "TestingTestingTestingTestingTesting",
|
||||||
icon: ShapesIcon,
|
icon: ShapesIcon,
|
||||||
skill_id: "1216",
|
children: [{ id: "1216", name: "Market Research" }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
suggestionsCreate: [
|
suggestionsCreate: [
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
import type { LucideIcon } from "lucide-react";
|
import type { LucideIcon } from "lucide-react";
|
||||||
|
|
||||||
|
export interface SelectedSkillPayloadItem {
|
||||||
|
id: string | number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface Translations {
|
export interface Translations {
|
||||||
// Locale meta
|
// Locale meta
|
||||||
locale: {
|
locale: {
|
||||||
|
|
@ -97,7 +103,7 @@ export interface Translations {
|
||||||
suggestion: string;
|
suggestion: string;
|
||||||
prompt: string;
|
prompt: string;
|
||||||
icon: LucideIcon;
|
icon: LucideIcon;
|
||||||
skill_id?: string;
|
children: SelectedSkillPayloadItem[];
|
||||||
}[];
|
}[];
|
||||||
suggestionsCreate: (
|
suggestionsCreate: (
|
||||||
| {
|
| {
|
||||||
|
|
|
||||||
|
|
@ -117,31 +117,31 @@ export const zhCN: Translations = {
|
||||||
prompt:
|
prompt:
|
||||||
"为[主题/产品]撰写吸引人的自媒体文案,包括标题、正文和话题标签。",
|
"为[主题/产品]撰写吸引人的自媒体文案,包括标题、正文和话题标签。",
|
||||||
icon: PenLineIcon,
|
icon: PenLineIcon,
|
||||||
skill_id: "1245",
|
children: [{ id: "1245", name: "自媒体文案" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
suggestion: "需求文档",
|
suggestion: "需求文档",
|
||||||
prompt: "编写[项目/功能]的需求文档,包含功能描述、用户故事和验收标准。",
|
prompt: "编写[项目/功能]的需求文档,包含功能描述、用户故事和验收标准。",
|
||||||
icon: CompassIcon,
|
icon: CompassIcon,
|
||||||
skill_id: "520",
|
children: [{ id: "520", name: "需求文档" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
suggestion: "使用指南",
|
suggestion: "使用指南",
|
||||||
prompt: "编写[产品/功能]的使用指南,包含操作步骤、注意事项和常见问题。",
|
prompt: "编写[产品/功能]的使用指南,包含操作步骤、注意事项和常见问题。",
|
||||||
icon: GraduationCapIcon,
|
icon: GraduationCapIcon,
|
||||||
skill_id: "409",
|
children: [{ id: "409", name: "使用指南" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
suggestion: "Excel数据分析",
|
suggestion: "Excel数据分析",
|
||||||
prompt: "对[Excel文件/数据]进行分析,生成数据洞察和可视化建议。",
|
prompt: "对[Excel文件/数据]进行分析,生成数据洞察和可视化建议。",
|
||||||
icon: MicroscopeIcon,
|
icon: MicroscopeIcon,
|
||||||
skill_id: "5",
|
children: [{ id: "5", name: "Excel数据分析" }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
suggestion: "市场调研",
|
suggestion: "市场调研",
|
||||||
prompt: "针对[行业/产品]进行市场调研,分析市场规模、竞品和趋势。",
|
prompt: "针对[行业/产品]进行市场调研,分析市场规模、竞品和趋势。",
|
||||||
icon: ShapesIcon,
|
icon: ShapesIcon,
|
||||||
skill_id: "1216",
|
children: [{ id: "1216", name: "市场调研" }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
suggestionsCreate: [
|
suggestionsCreate: [
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export const POST_MESSAGE_TYPES = {
|
||||||
// 会话是否处于聊天态
|
// 会话是否处于聊天态
|
||||||
IS_CHATTING: "isChatting",
|
IS_CHATTING: "isChatting",
|
||||||
// 选择预定义 skill
|
// 选择预定义 skill
|
||||||
SELECT_SKILL: "selectSkill",
|
SELECT_SKILL: "selectedSkills",
|
||||||
// 打开 skill 选择对话框
|
// 打开 skill 选择对话框
|
||||||
OPEN_SKILL_DIALOG: "openSkillDialog",
|
OPEN_SKILL_DIALOG: "openSkillDialog",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
@ -42,7 +42,7 @@ export interface IsChattingMessage {
|
||||||
|
|
||||||
export interface SelectSkillMessage {
|
export interface SelectSkillMessage {
|
||||||
type: typeof POST_MESSAGE_TYPES.SELECT_SKILL;
|
type: typeof POST_MESSAGE_TYPES.SELECT_SKILL;
|
||||||
skill_id: string[];
|
selectedSkills: SelectedSkillPayloadItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OpenSkillDialogMessage {
|
export interface OpenSkillDialogMessage {
|
||||||
|
|
@ -56,6 +56,11 @@ export interface SelectedSkillMessage {
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SelectedSkillPayloadItem {
|
||||||
|
id: string | number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
type UnknownRecord = Record<string, unknown>;
|
type UnknownRecord = Record<string, unknown>;
|
||||||
|
|
||||||
function asRecord(value: unknown): UnknownRecord | null {
|
function asRecord(value: unknown): UnknownRecord | null {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import {
|
||||||
POST_MESSAGE_TYPES,
|
POST_MESSAGE_TYPES,
|
||||||
RECEIVE_MESSAGE_TYPES,
|
RECEIVE_MESSAGE_TYPES,
|
||||||
isSelectedSkillMessage,
|
isSelectedSkillMessage,
|
||||||
|
type SelectedSkillPayloadItem,
|
||||||
sendToParent,
|
sendToParent,
|
||||||
} from "@/core/iframe-messages";
|
} from "@/core/iframe-messages";
|
||||||
|
|
||||||
|
|
@ -17,7 +18,7 @@ interface SkillData {
|
||||||
// Hook 返回类型
|
// Hook 返回类型
|
||||||
interface UseIframeSkillReturn {
|
interface UseIframeSkillReturn {
|
||||||
selectedSkill: SkillData | null;
|
selectedSkill: SkillData | null;
|
||||||
sendSelectSkill: (skill_id: string[]) => void;
|
sendSelectSkill: (selectedSkills: SelectedSkillPayloadItem[]) => void;
|
||||||
openSkillDialog: () => void;
|
openSkillDialog: () => void;
|
||||||
clearSkill: () => void;
|
clearSkill: () => void;
|
||||||
}
|
}
|
||||||
|
|
@ -68,8 +69,8 @@ export function useIframeSkill(): UseIframeSkillReturn {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// 发送选择预定义 skill
|
// 发送选择预定义 skill
|
||||||
const sendSelectSkill = useCallback((skill_id: string[]) => {
|
const sendSelectSkill = useCallback((selectedSkills: SelectedSkillPayloadItem[]) => {
|
||||||
const message = { type: POST_MESSAGE_TYPES.SELECT_SKILL, skill_id };
|
const message = { type: POST_MESSAGE_TYPES.SELECT_SKILL, selectedSkills };
|
||||||
console.log("[useIframeSkill] sendSelectSkill:", message);
|
console.log("[useIframeSkill] sendSelectSkill:", message);
|
||||||
sendToParent(message);
|
sendToParent(message);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
@ -84,12 +85,12 @@ export function useIframeSkill(): UseIframeSkillReturn {
|
||||||
sendToParent(message);
|
sendToParent(message);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// 清除选中并发送空 skill_id 数组给主页
|
// 清除选中并发送空 selectedSkills 数组给主页
|
||||||
const clearSkill = useCallback(() => {
|
const clearSkill = useCallback(() => {
|
||||||
setSelectedSkill(null);
|
setSelectedSkill(null);
|
||||||
// 发送空数组给主页,通知取消选择
|
// 发送空数组给主页,通知取消选择
|
||||||
const message = { type: POST_MESSAGE_TYPES.SELECT_SKILL, skill_id: [] };
|
const message = { type: POST_MESSAGE_TYPES.SELECT_SKILL, selectedSkills: [] };
|
||||||
console.log("[useIframeSkill] clearSkill, sending skill_id=[]:", message);
|
console.log("[useIframeSkill] clearSkill, sending selectedSkills=[]:", message);
|
||||||
sendToParent(message);
|
sendToParent(message);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue