feat: 新增技能编排引擎和工作流构建器组件
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
refactor: 统一Hands系统常量到单个源文件 refactor: 更新Hands中文名称和描述 fix: 修复技能市场在连接状态变化时重新加载 fix: 修复身份变更提案的错误处理逻辑 docs: 更新多个功能文档的验证状态和实现位置 docs: 更新Hands系统文档 test: 添加测试文件验证工作区路径
This commit is contained in:
81
desktop/src/constants/api-urls.ts
Normal file
81
desktop/src/constants/api-urls.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* API URL Constants - Single Source of Truth
|
||||
*
|
||||
* All API URLs should reference this file.
|
||||
* Backend (Rust) should use the same values in config.rs
|
||||
*/
|
||||
|
||||
// === LLM Provider URLs ===
|
||||
|
||||
/**
|
||||
* LLM Provider API URLs
|
||||
*/
|
||||
export const LLM_PROVIDER_URLS = {
|
||||
// OpenAI
|
||||
OPENAI: 'https://api.openai.com/v1',
|
||||
|
||||
// Anthropic
|
||||
ANTHROPIC: 'https://api.anthropic.com',
|
||||
|
||||
// Gemini
|
||||
GEMINI: 'https://generativelanguage.googleapis.com/v1beta',
|
||||
|
||||
// DeepSeek
|
||||
DEEPSEEK: 'https://api.deepseek.com/v1',
|
||||
|
||||
// 智谱 (Zhipu)
|
||||
ZHIPU: 'https://open.bigmodel.cn/api/paas/v4',
|
||||
ZHIPU_CODING: 'https://open.bigmodel.cn/api/coding/paas/v4',
|
||||
|
||||
// Kimi (Moonshot)
|
||||
KIMI: 'https://api.moonshot.cn/v1',
|
||||
KIMI_CODING: 'https://api.kimi.com/coding/v1',
|
||||
|
||||
// 百炼 (Qwen/Bailian)
|
||||
QWEN: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
||||
QWEN_CODING: 'https://coding.dashscope.aliyuncs.com/v1',
|
||||
|
||||
// 火山引擎 (Volcengine/Doubao)
|
||||
VOLCENGINE: 'https://ark.cn-beijing.volces.com/api/v3',
|
||||
|
||||
// Local/OLLama
|
||||
OLLAMA: 'http://localhost:11434/v1',
|
||||
LM_STUDIO: 'http://localhost:1234/v1',
|
||||
VLLM: 'http://localhost:8000/v1',
|
||||
} as const;
|
||||
|
||||
// === ZCLAW Gateway URLs ===
|
||||
|
||||
/**
|
||||
* ZCLAW Gateway default URLs
|
||||
*/
|
||||
export const GATEWAY_URLS = {
|
||||
DEFAULT_HTTP: 'http://127.0.0.1:50051',
|
||||
DEFAULT_WS: 'ws://127.0.0.1:50051/ws',
|
||||
FALLBACK_HTTP: 'http://127.0.0.1:4200',
|
||||
FALLBACK_WS: 'ws://127.0.0.1:4200/ws',
|
||||
} as const;
|
||||
|
||||
// === Helper Functions ===
|
||||
|
||||
/**
|
||||
* Get provider URL by name
|
||||
*/
|
||||
export function getProviderUrl(provider: string): string {
|
||||
const key = provider.toUpperCase().replace(/-/g, '_') as keyof typeof LLM_PROVIDER_URLS;
|
||||
return LLM_PROVIDER_URLS[key] || LLM_PROVIDER_URLS.OPENAI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if URL is a coding plan endpoint
|
||||
*/
|
||||
export function isCodingUrl(url: string): boolean {
|
||||
return url.includes('/coding/') || url.includes('-coding');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if URL is a local endpoint
|
||||
*/
|
||||
export function isLocalUrl(url: string): boolean {
|
||||
return url.includes('localhost') || url.includes('127.0.0.1') || url.includes('[::1]');
|
||||
}
|
||||
79
desktop/src/constants/hands.ts
Normal file
79
desktop/src/constants/hands.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Hand ID Constants - Single Source of Truth
|
||||
*
|
||||
* All Hand-related constants should reference this file.
|
||||
* Do NOT hardcode Hand IDs elsewhere.
|
||||
*/
|
||||
|
||||
// === Hand IDs (must match backend zclaw-hands) ===
|
||||
|
||||
export const HAND_IDS = {
|
||||
BROWSER: 'browser',
|
||||
RESEARCHER: 'researcher',
|
||||
COLLECTOR: 'collector',
|
||||
PREDICTOR: 'predictor',
|
||||
LEAD: 'lead',
|
||||
TRADER: 'trader',
|
||||
CLIP: 'clip',
|
||||
TWITTER: 'twitter',
|
||||
// Additional hands from backend
|
||||
SLIDESHOW: 'slideshow',
|
||||
SPEECH: 'speech',
|
||||
QUIZ: 'quiz',
|
||||
WHITEBOARD: 'whiteboard',
|
||||
} as const;
|
||||
|
||||
export type HandIdType = typeof HAND_IDS[keyof typeof HAND_IDS];
|
||||
|
||||
// === Hand Categories ===
|
||||
|
||||
export const HAND_CATEGORIES = {
|
||||
RESEARCH: 'research',
|
||||
DATA: 'data',
|
||||
AUTOMATION: 'automation',
|
||||
COMMUNICATION: 'communication',
|
||||
CONTENT: 'content',
|
||||
PRODUCTIVITY: 'productivity',
|
||||
} as const;
|
||||
|
||||
export type HandCategoryType = typeof HAND_CATEGORIES[keyof typeof HAND_CATEGORIES];
|
||||
|
||||
// === Hand ID to Category Mapping ===
|
||||
|
||||
export const HAND_CATEGORY_MAP: Record<string, HandCategoryType> = {
|
||||
[HAND_IDS.BROWSER]: HAND_CATEGORIES.RESEARCH,
|
||||
[HAND_IDS.RESEARCHER]: HAND_CATEGORIES.RESEARCH,
|
||||
[HAND_IDS.COLLECTOR]: HAND_CATEGORIES.DATA,
|
||||
[HAND_IDS.PREDICTOR]: HAND_CATEGORIES.DATA,
|
||||
[HAND_IDS.TRADER]: HAND_CATEGORIES.DATA,
|
||||
[HAND_IDS.LEAD]: HAND_CATEGORIES.COMMUNICATION,
|
||||
[HAND_IDS.TWITTER]: HAND_CATEGORIES.COMMUNICATION,
|
||||
[HAND_IDS.CLIP]: HAND_CATEGORIES.CONTENT,
|
||||
[HAND_IDS.SLIDESHOW]: HAND_CATEGORIES.CONTENT,
|
||||
[HAND_IDS.SPEECH]: HAND_CATEGORIES.CONTENT,
|
||||
[HAND_IDS.QUIZ]: HAND_CATEGORIES.PRODUCTIVITY,
|
||||
[HAND_IDS.WHITEBOARD]: HAND_CATEGORIES.PRODUCTIVITY,
|
||||
};
|
||||
|
||||
// === Helper Functions ===
|
||||
|
||||
/**
|
||||
* Get the category for a Hand ID
|
||||
*/
|
||||
export function getHandCategory(handId: string): HandCategoryType {
|
||||
return HAND_CATEGORY_MAP[handId] || HAND_CATEGORIES.PRODUCTIVITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Hand ID is valid
|
||||
*/
|
||||
export function isValidHandId(id: string): id is HandIdType {
|
||||
return Object.values(HAND_IDS).includes(id as HandIdType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Hand IDs as an array
|
||||
*/
|
||||
export function getAllHandIds(): string[] {
|
||||
return Object.values(HAND_IDS);
|
||||
}
|
||||
9
desktop/src/constants/index.ts
Normal file
9
desktop/src/constants/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Constants Index - Single Source of Truth
|
||||
*
|
||||
* Re-export all constants from a single entry point.
|
||||
*/
|
||||
|
||||
export * from './hands';
|
||||
export * from './models';
|
||||
export * from './api-urls';
|
||||
112
desktop/src/constants/models.ts
Normal file
112
desktop/src/constants/models.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Model Default Constants - Single Source of Truth
|
||||
*
|
||||
* All model-related defaults should reference this file.
|
||||
* Backend (Rust) should use the same values in kernel_commands.rs
|
||||
*/
|
||||
|
||||
// === Default Model Configuration ===
|
||||
|
||||
/**
|
||||
* Default model ID when user hasn't configured one
|
||||
* Using gpt-4o-mini as it's cost-effective and capable
|
||||
*/
|
||||
export const DEFAULT_MODEL_ID = 'gpt-4o-mini' as const;
|
||||
|
||||
/**
|
||||
* Default provider when user hasn't configured one
|
||||
*/
|
||||
export const DEFAULT_PROVIDER = 'openai' as const;
|
||||
|
||||
/**
|
||||
* Default max tokens for responses
|
||||
*/
|
||||
export const DEFAULT_MAX_TOKENS = 4096 as const;
|
||||
|
||||
/**
|
||||
* Default temperature for responses
|
||||
*/
|
||||
export const DEFAULT_TEMPERATURE = 0.7 as const;
|
||||
|
||||
/**
|
||||
* Default base URL for OpenAI API
|
||||
*/
|
||||
export const DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1' as const;
|
||||
|
||||
/**
|
||||
* Default base URL for Anthropic API
|
||||
*/
|
||||
export const DEFAULT_ANTHROPIC_BASE_URL = 'https://api.anthropic.com' as const;
|
||||
|
||||
// === Provider-Specific Defaults ===
|
||||
|
||||
export const PROVIDER_DEFAULTS = {
|
||||
openai: {
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
defaultModel: 'gpt-4o-mini',
|
||||
},
|
||||
anthropic: {
|
||||
baseUrl: 'https://api.anthropic.com',
|
||||
defaultModel: 'claude-sonnet-4-20250514',
|
||||
},
|
||||
zhipu: {
|
||||
baseUrl: 'https://open.bigmodel.cn/api/paas/v4',
|
||||
defaultModel: 'glm-4-flash',
|
||||
},
|
||||
zhipu_coding: {
|
||||
baseUrl: 'https://open.bigmodel.cn/api/coding/paas/v4',
|
||||
defaultModel: 'glm-4-flash',
|
||||
},
|
||||
kimi: {
|
||||
baseUrl: 'https://api.moonshot.cn/v1',
|
||||
defaultModel: 'moonshot-v1-8k',
|
||||
},
|
||||
kimi_coding: {
|
||||
baseUrl: 'https://api.kimi.com/coding/v1',
|
||||
defaultModel: 'kimi-for-coding',
|
||||
},
|
||||
qwen: {
|
||||
baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
|
||||
defaultModel: 'qwen-turbo',
|
||||
},
|
||||
qwen_coding: {
|
||||
baseUrl: 'https://coding.dashscope.aliyuncs.com/v1',
|
||||
defaultModel: 'qwen3-coder-next',
|
||||
},
|
||||
deepseek: {
|
||||
baseUrl: 'https://api.deepseek.com/v1',
|
||||
defaultModel: 'deepseek-chat',
|
||||
},
|
||||
gemini: {
|
||||
baseUrl: 'https://generativelanguage.googleapis.com/v1beta',
|
||||
defaultModel: 'gemini-2.0-flash',
|
||||
},
|
||||
local: {
|
||||
baseUrl: 'http://localhost:11434/v1',
|
||||
defaultModel: 'llama3',
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type ProviderType = keyof typeof PROVIDER_DEFAULTS;
|
||||
|
||||
// === Helper Functions ===
|
||||
|
||||
/**
|
||||
* Get provider default configuration
|
||||
*/
|
||||
export function getProviderDefaults(provider: string): {
|
||||
baseUrl: string;
|
||||
defaultModel: string;
|
||||
} {
|
||||
return PROVIDER_DEFAULTS[provider as ProviderType] || {
|
||||
baseUrl: DEFAULT_OPENAI_BASE_URL,
|
||||
defaultModel: DEFAULT_MODEL_ID,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a provider is a coding plan provider
|
||||
*/
|
||||
export function isCodingProvider(provider: string): boolean {
|
||||
return provider.endsWith('-coding') || provider === 'zhipu-coding';
|
||||
}
|
||||
Reference in New Issue
Block a user