refactor(types): comprehensive TypeScript type system improvements
Major type system refactoring and error fixes across the codebase: **Type System Improvements:** - Extended OpenFangStreamEvent with 'connected' and 'agents_updated' event types - Added GatewayPong interface for WebSocket pong responses - Added index signature to MemorySearchOptions for Record compatibility - Fixed RawApproval interface with hand_name, run_id properties **Gateway & Protocol Fixes:** - Fixed performHandshake nonce handling in gateway-client.ts - Fixed onAgentStream callback type definitions - Fixed HandRun runId mapping to handle undefined values - Fixed Approval mapping with proper default values **Memory System Fixes:** - Fixed MemoryEntry creation with required properties (lastAccessedAt, accessCount) - Replaced getByAgent with getAll method in vector-memory.ts - Fixed MemorySearchOptions type compatibility **Component Fixes:** - Fixed ReflectionLog property names (filePath→file, proposedContent→suggestedContent) - Fixed SkillMarket suggestSkills async call arguments - Fixed message-virtualization useRef generic type - Fixed session-persistence messageCount type conversion **Code Cleanup:** - Removed unused imports and variables across multiple files - Consolidated StoredError interface (removed duplicate) - Deleted obsolete test files (feedbackStore.test.ts, memory-index.test.ts) **New Features:** - Added browser automation module (Tauri backend) - Added Active Learning Panel component - Added Agent Onboarding Wizard - Added Memory Graph visualization - Added Personality Selector - Added Skill Market store and components Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
361
desktop/src/lib/personality-presets.ts
Normal file
361
desktop/src/lib/personality-presets.ts
Normal file
@@ -0,0 +1,361 @@
|
||||
/**
|
||||
* Personality Presets Configuration
|
||||
*
|
||||
* Defines personality styles, scenario tags, and emoji presets for Agent onboarding.
|
||||
* Used by AgentOnboardingWizard to provide guided personality setup.
|
||||
*/
|
||||
|
||||
// === Personality Options ===
|
||||
|
||||
export interface PersonalityOption {
|
||||
id: string;
|
||||
label: string;
|
||||
description: string;
|
||||
icon: string; // Icon name for Lucide
|
||||
traits: string[];
|
||||
communicationStyle: string;
|
||||
}
|
||||
|
||||
export const PERSONALITY_OPTIONS: PersonalityOption[] = [
|
||||
{
|
||||
id: 'professional',
|
||||
label: '专业严谨',
|
||||
description: '精确、可靠、技术导向',
|
||||
icon: 'Briefcase',
|
||||
traits: ['精确', '可靠', '技术导向', '系统化'],
|
||||
communicationStyle: '专业、准确、注重细节,提供技术深度和可操作的建议',
|
||||
},
|
||||
{
|
||||
id: 'friendly',
|
||||
label: '友好亲切',
|
||||
description: '温暖、耐心、易于沟通',
|
||||
icon: 'Heart',
|
||||
traits: ['温暖', '耐心', '易于沟通', '善解人意'],
|
||||
communicationStyle: '亲切、耐心、善解人意,用易懂的语言解释复杂概念',
|
||||
},
|
||||
{
|
||||
id: 'creative',
|
||||
label: '创意灵活',
|
||||
description: '想象力丰富、善于探索',
|
||||
icon: 'Sparkles',
|
||||
traits: ['想象力丰富', '善于探索', '思维开放', '创新'],
|
||||
communicationStyle: '富有创意、思维开放,鼓励探索新想法和解决方案',
|
||||
},
|
||||
{
|
||||
id: 'concise',
|
||||
label: '简洁高效',
|
||||
description: '快速、直接、结果导向',
|
||||
icon: 'Zap',
|
||||
traits: ['快速', '直接', '结果导向', '高效'],
|
||||
communicationStyle: '简洁明了、直奔主题,专注于快速解决问题',
|
||||
},
|
||||
];
|
||||
|
||||
// === Scenario Tags ===
|
||||
|
||||
export interface ScenarioTag {
|
||||
id: string;
|
||||
label: string;
|
||||
description: string;
|
||||
icon: string; // Icon name for Lucide
|
||||
keywords: string[];
|
||||
}
|
||||
|
||||
export const SCENARIO_TAGS: ScenarioTag[] = [
|
||||
{
|
||||
id: 'coding',
|
||||
label: '编程开发',
|
||||
description: '代码编写、调试、代码审查',
|
||||
icon: 'Code',
|
||||
keywords: ['编程', '代码', '开发', '调试', 'Bug', '重构'],
|
||||
},
|
||||
{
|
||||
id: 'writing',
|
||||
label: '内容写作',
|
||||
description: '文章撰写、文案创作、编辑润色',
|
||||
icon: 'PenLine',
|
||||
keywords: ['写作', '文案', '文章', '内容', '编辑', '润色'],
|
||||
},
|
||||
{
|
||||
id: 'product',
|
||||
label: '产品策划',
|
||||
description: '产品规划、需求分析、用户研究',
|
||||
icon: 'Package',
|
||||
keywords: ['产品', '需求', '用户', '规划', '功能', 'PRD'],
|
||||
},
|
||||
{
|
||||
id: 'data',
|
||||
label: '数据分析',
|
||||
description: '数据处理、统计分析、可视化',
|
||||
icon: 'BarChart',
|
||||
keywords: ['数据', '分析', '统计', '图表', '可视化', '报表'],
|
||||
},
|
||||
{
|
||||
id: 'design',
|
||||
label: '设计创意',
|
||||
description: 'UI/UX设计、视觉设计、原型制作',
|
||||
icon: 'Palette',
|
||||
keywords: ['设计', 'UI', 'UX', '视觉', '原型', '界面'],
|
||||
},
|
||||
{
|
||||
id: 'devops',
|
||||
label: '运维部署',
|
||||
description: '系统运维、CI/CD、容器化部署',
|
||||
icon: 'Server',
|
||||
keywords: ['运维', '部署', 'CI/CD', 'Docker', 'K8s', '服务器'],
|
||||
},
|
||||
{
|
||||
id: 'research',
|
||||
label: '研究调研',
|
||||
description: '技术调研、文献研究、竞品分析',
|
||||
icon: 'Search',
|
||||
keywords: ['研究', '调研', '分析', '文献', '竞品', '技术'],
|
||||
},
|
||||
{
|
||||
id: 'marketing',
|
||||
label: '营销推广',
|
||||
description: '营销策略、内容营销、社媒运营',
|
||||
icon: 'Megaphone',
|
||||
keywords: ['营销', '推广', '运营', '社媒', '增长', '转化'],
|
||||
},
|
||||
{
|
||||
id: 'other',
|
||||
label: '其他',
|
||||
description: '其他用途或综合场景',
|
||||
icon: 'MoreHorizontal',
|
||||
keywords: [],
|
||||
},
|
||||
];
|
||||
|
||||
// === Emoji Presets ===
|
||||
|
||||
export const EMOJI_PRESETS = {
|
||||
animals: ['🦞', '🐱', '🐶', '🦊', '🐼', '🦁', '🐬', '🦄'],
|
||||
objects: ['💻', '🚀', '⚡', '🔧', '📚', '🎨', '⭐', '💎'],
|
||||
expressions: ['😊', '🤓', '😎', '🤖'],
|
||||
};
|
||||
|
||||
export const ALL_EMOJIS = [
|
||||
...EMOJI_PRESETS.animals,
|
||||
...EMOJI_PRESETS.objects,
|
||||
...EMOJI_PRESETS.expressions,
|
||||
];
|
||||
|
||||
// === Quick Start Suggestions ===
|
||||
|
||||
export interface QuickStartSuggestion {
|
||||
icon: string;
|
||||
text: string;
|
||||
scenarios: string[]; // Which scenarios this suggestion applies to
|
||||
}
|
||||
|
||||
export const QUICK_START_SUGGESTIONS: QuickStartSuggestion[] = [
|
||||
{
|
||||
icon: '💡',
|
||||
text: '帮我写一个 Python 脚本处理 Excel 文件',
|
||||
scenarios: ['coding', 'data'],
|
||||
},
|
||||
{
|
||||
icon: '📊',
|
||||
text: '分析这个数据集的趋势和关键指标',
|
||||
scenarios: ['data', 'research'],
|
||||
},
|
||||
{
|
||||
icon: '✍️',
|
||||
text: '帮我起草一份产品需求文档',
|
||||
scenarios: ['product', 'writing'],
|
||||
},
|
||||
{
|
||||
icon: '🔍',
|
||||
text: '帮我研究一下这个技术方案的可行性',
|
||||
scenarios: ['research', 'coding'],
|
||||
},
|
||||
{
|
||||
icon: '🎨',
|
||||
text: '给我一些 UI 设计的创意建议',
|
||||
scenarios: ['design'],
|
||||
},
|
||||
{
|
||||
icon: '📝',
|
||||
text: '帮我写一篇技术博客文章',
|
||||
scenarios: ['writing'],
|
||||
},
|
||||
{
|
||||
icon: '🚀',
|
||||
text: '帮我规划一个完整的营销方案',
|
||||
scenarios: ['marketing', 'product'],
|
||||
},
|
||||
{
|
||||
icon: '⚙️',
|
||||
text: '帮我配置一个自动化部署流程',
|
||||
scenarios: ['devops', 'coding'],
|
||||
},
|
||||
];
|
||||
|
||||
// === Helper Functions ===
|
||||
|
||||
/**
|
||||
* Get personality option by ID
|
||||
*/
|
||||
export function getPersonalityById(id: string): PersonalityOption | undefined {
|
||||
return PERSONALITY_OPTIONS.find((p) => p.id === id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scenario tag by ID
|
||||
*/
|
||||
export function getScenarioById(id: string): ScenarioTag | undefined {
|
||||
return SCENARIO_TAGS.find((s) => s.id === id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get quick start suggestions for given scenarios
|
||||
*/
|
||||
export function getQuickStartSuggestions(scenarios: string[]): QuickStartSuggestion[] {
|
||||
if (!scenarios || scenarios.length === 0) {
|
||||
// Return first 3 general suggestions if no scenarios selected
|
||||
return QUICK_START_SUGGESTIONS.slice(0, 3);
|
||||
}
|
||||
|
||||
// Filter suggestions that match any of the selected scenarios
|
||||
const matching = QUICK_START_SUGGESTIONS.filter((s) =>
|
||||
s.scenarios.some((scenario) => scenarios.includes(scenario))
|
||||
);
|
||||
|
||||
// Return up to 3 matching suggestions, fallback to first 3 if none match
|
||||
return matching.length > 0 ? matching.slice(0, 3) : QUICK_START_SUGGESTIONS.slice(0, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate welcome message based on personality and scenarios
|
||||
*/
|
||||
export function generateWelcomeMessage(config: {
|
||||
userName?: string;
|
||||
agentName: string;
|
||||
emoji?: string;
|
||||
personality?: string;
|
||||
scenarios?: string[];
|
||||
}): string {
|
||||
const { userName, agentName, emoji, personality, scenarios } = config;
|
||||
|
||||
// Build greeting
|
||||
let greeting = '';
|
||||
if (userName) {
|
||||
greeting = `你好,${userName}!`;
|
||||
} else {
|
||||
greeting = '你好!';
|
||||
}
|
||||
|
||||
// Build introduction
|
||||
let intro = `我是${emoji ? ' ' + emoji : ''} ${agentName}`;
|
||||
|
||||
// Add scenario context
|
||||
if (scenarios && scenarios.length > 0) {
|
||||
const scenarioLabels = scenarios
|
||||
.map((id) => getScenarioById(id)?.label)
|
||||
.filter(Boolean)
|
||||
.slice(0, 3);
|
||||
if (scenarioLabels.length > 0) {
|
||||
intro += `,你的${scenarioLabels.join('、')}助手`;
|
||||
}
|
||||
}
|
||||
|
||||
// Add personality touch
|
||||
if (personality) {
|
||||
const personalityOption = getPersonalityById(personality);
|
||||
if (personalityOption) {
|
||||
intro += `。我会以${personalityOption.traits[0]}的方式为你提供帮助`;
|
||||
}
|
||||
}
|
||||
|
||||
// Add closing
|
||||
intro += '。有什么我可以帮你的吗?';
|
||||
|
||||
return `${greeting}\n\n${intro}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate SOUL.md content based on personality config
|
||||
*/
|
||||
export function generateSoulContent(config: {
|
||||
agentName: string;
|
||||
emoji?: string;
|
||||
personality?: string;
|
||||
scenarios?: string[];
|
||||
communicationStyle?: string;
|
||||
}): string {
|
||||
const { agentName, emoji, personality, scenarios, communicationStyle } = config;
|
||||
|
||||
const personalityOption = personality ? getPersonalityById(personality) : undefined;
|
||||
const scenarioLabels =
|
||||
scenarios
|
||||
?.map((id) => getScenarioById(id)?.label)
|
||||
.filter(Boolean)
|
||||
.join('、') || '通用';
|
||||
|
||||
return `# ${agentName} 人格
|
||||
|
||||
> ${emoji || '🤖'} ${agentName} - ${scenarioLabels}助手
|
||||
|
||||
## 核心特质
|
||||
|
||||
${
|
||||
personalityOption
|
||||
? personalityOption.traits.map((t) => `- ${t}`).join('\n')
|
||||
: '- 高效执行\n- 专业可靠\n- 主动服务'
|
||||
}
|
||||
|
||||
## 沟通风格
|
||||
|
||||
${communicationStyle || personalityOption?.communicationStyle || '简洁、专业、友好'}
|
||||
|
||||
## 专业领域
|
||||
|
||||
${scenarioLabels}
|
||||
|
||||
## 边界
|
||||
|
||||
- 安全约束:不执行可能损害用户或系统的操作
|
||||
- 隐私保护:不主动收集或分享敏感信息
|
||||
- 能力边界:超出能力范围时坦诚告知
|
||||
|
||||
## 语气
|
||||
|
||||
- 使用中文进行交流
|
||||
- 保持专业但友好的态度
|
||||
- 适时提供额外上下文和建议
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate USER.md content based on user profile
|
||||
*/
|
||||
export function generateUserContent(config: {
|
||||
userName?: string;
|
||||
userRole?: string;
|
||||
scenarios?: string[];
|
||||
}): string {
|
||||
const { userName, userRole, scenarios } = config;
|
||||
|
||||
const scenarioLabels =
|
||||
scenarios
|
||||
?.map((id) => getScenarioById(id)?.label)
|
||||
.filter(Boolean)
|
||||
.join('、') || '通用';
|
||||
|
||||
const sections: string[] = ['# 用户档案\n'];
|
||||
|
||||
if (userName) {
|
||||
sections.push(`## 基本信息\n\n- 姓名:${userName}`);
|
||||
if (userRole) {
|
||||
sections.push(`- 角色:${userRole}`);
|
||||
}
|
||||
sections.push('');
|
||||
}
|
||||
|
||||
sections.push(`## 关注领域\n\n${scenarioLabels}\n`);
|
||||
|
||||
sections.push(`## 偏好设置\n\n- 语言:中文\n- 沟通风格:直接、高效\n`);
|
||||
|
||||
return sections.join('\n');
|
||||
}
|
||||
Reference in New Issue
Block a user