From f89fbb76ebc79da89635efd7bbce34176ce76ee2 Mon Sep 17 00:00:00 2001 From: linshen <32978552+linshenkx@users.noreply.github.com> Date: Sun, 8 Jun 2025 21:58:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(template):=20=E5=A2=9E=E5=BC=BA=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E7=AE=A1=E7=90=86=E5=99=A8=E4=BB=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=86=85=E7=BD=AE=E6=A8=A1=E6=9D=BF=E8=AF=AD=E8=A8=80=E5=88=87?= =?UTF-8?q?=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增内置模板语言服务,支持中英文切换 - 更新模板管理器以根据当前语言加载相应的内置模板 - 实现语言切换功能,允许用户动态更改模板语言 - 增强错误处理,确保在语言切换和模板加载过程中稳定性 - 更新相关测试用例以验证新功能的正确性 --- packages/core/src/index.ts | 2 + packages/core/src/services/data/manager.ts | 3 +- .../core/src/services/template/defaults_en.ts | 474 ++++++++++++++++++ .../src/services/template/languageService.ts | 118 +++++ .../core/src/services/template/manager.ts | 228 ++++++++- .../core/tests/unit/prompt/service.test.ts | 5 +- .../unit/template/languageService.test.ts | 158 ++++++ .../core/tests/unit/template/manager.test.ts | 120 ++++- .../BuiltinTemplateLanguageSwitch.vue | 218 ++++++++ .../ui/src/components/TemplateManager.vue | 68 ++- packages/ui/src/components/TemplateSelect.vue | 12 +- packages/ui/src/composables/useModals.ts | 2 +- .../ui/src/composables/usePromptOptimizer.ts | 13 +- .../src/composables/useServiceInitializer.ts | 11 +- .../ui/src/composables/useTemplateManager.ts | 13 +- packages/ui/src/i18n/locales/en-US.ts | 6 + packages/ui/src/i18n/locales/zh-CN.ts | 6 + packages/ui/src/index.ts | 3 +- 18 files changed, 1401 insertions(+), 59 deletions(-) create mode 100644 packages/core/src/services/template/defaults_en.ts create mode 100644 packages/core/src/services/template/languageService.ts create mode 100644 packages/core/tests/unit/template/languageService.test.ts create mode 100644 packages/ui/src/components/BuiltinTemplateLanguageSwitch.vue diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index c0627c0b..6c082139 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -3,6 +3,8 @@ // 导出模板相关 export { TemplateManager, templateManager } from './services/template/manager' export { TemplateProcessor } from './services/template/processor' +export { TemplateLanguageService, templateLanguageService } from './services/template/languageService' +export type { BuiltinTemplateLanguage } from './services/template/languageService' export * from './services/template/types' export * from './services/template/defaults' export * from './services/template/errors' diff --git a/packages/core/src/services/data/manager.ts b/packages/core/src/services/data/manager.ts index c58011b3..f0a8d608 100644 --- a/packages/core/src/services/data/manager.ts +++ b/packages/core/src/services/data/manager.ts @@ -17,7 +17,8 @@ interface AllData { // 需要导出的UI配置键 const UI_SETTINGS_KEYS = [ 'theme-id', - 'preferred-language', + 'preferred-language', + 'builtin-template-language', 'app:selected-optimize-model', 'app:selected-test-model', 'app:selected-optimize-template', diff --git a/packages/core/src/services/template/defaults_en.ts b/packages/core/src/services/template/defaults_en.ts new file mode 100644 index 00000000..6e51c839 --- /dev/null +++ b/packages/core/src/services/template/defaults_en.ts @@ -0,0 +1,474 @@ +import { Template, MessageTemplate } from './types'; + +/** + * English built-in prompt templates + */ +export const DEFAULT_TEMPLATES_EN: Record = { + 'general-optimize': { + id: 'general-optimize', + name: 'General Optimization', + content: `You are a professional AI prompt optimization expert. Please help me optimize the following prompt and return it in the following format: + +# Role: [Role Name] + +## Profile +- language: [Language] +- description: [Detailed role description] +- background: [Role background] +- personality: [Personality traits] +- expertise: [Professional domain] +- target_audience: [Target user group] + +## Skills + +1. [Core skill category] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + +2. [Supporting skill category] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + +## Rules + +1. [Basic principles]: + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + +2. [Behavioral guidelines]: + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + +3. [Constraints]: + - [Specific constraint]: [Detailed description] + - [Specific constraint]: [Detailed description] + - [Specific constraint]: [Detailed description] + - [Specific constraint]: [Detailed description] + +## Workflows + +- Goal: [Clear objective] +- Step 1: [Detailed description] +- Step 2: [Detailed description] +- Step 3: [Detailed description] +- Expected result: [Description] + + +## Initialization +As [Role Name], you must follow the above Rules and execute tasks according to Workflows. + + +Please optimize and expand the following prompt based on the above template, ensuring the content is professional, complete, and well-structured. Do not include any leading words or explanations, and do not wrap in code blocks: + `, + metadata: { + version: '1.3.0', + lastModified: Date.now(), + author: 'System', + description: 'General optimization prompt suitable for most scenarios', + templateType: 'optimize' + }, + isBuiltin: true + }, + 'output-format-optimize': { + id: 'output-format-optimize', + name: 'General Optimization with Output Format', + content: `You are a professional AI prompt optimization expert. Please help me optimize the following prompt and return it in the following format: + +# Role: [Role Name] + +## Profile +- language: [Language] +- description: [Detailed role description] +- background: [Role background] +- personality: [Personality traits] +- expertise: [Professional domain] +- target_audience: [Target user group] + +## Skills + +1. [Core skill category] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + +2. [Supporting skill category] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + - [Specific skill]: [Brief description] + +## Rules + +1. [Basic principles]: + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + +2. [Behavioral guidelines]: + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + - [Specific rule]: [Detailed description] + +3. [Constraints]: + - [Specific constraint]: [Detailed description] + - [Specific constraint]: [Detailed description] + - [Specific constraint]: [Detailed description] + - [Specific constraint]: [Detailed description] + +## Workflows + +- Goal: [Clear objective] +- Step 1: [Detailed description] +- Step 2: [Detailed description] +- Step 3: [Detailed description] +- Expected result: [Description] + +## OutputFormat + +1. [Output format type]: + - format: [Format type, such as text/markdown/json etc.] + - structure: [Output structure description] + - style: [Style requirements] + - special_requirements: [Special requirements] + +2. [Format specifications]: + - indentation: [Indentation requirements] + - sections: [Section requirements] + - highlighting: [Emphasis methods] + +3. [Validation rules]: + - validation: [Format validation rules] + - constraints: [Format constraint conditions] + - error_handling: [Error handling methods] + +4. [Example descriptions]: + 1. Example 1: + - Title: [Example name] + - Format type: [Corresponding format type] + - Description: [Special description of the example] + - Example content: | + [Specific example content] + + 2. Example 2: + - Title: [Example name] + - Format type: [Corresponding format type] + - Description: [Special description of the example] + - Example content: | + [Specific example content] + +## Initialization +As [Role Name], you must follow the above Rules, execute tasks according to Workflows, and output according to [Output Format]. + + +Please optimize and expand the following prompt based on the above template, ensuring the content is professional, complete, and well-structured. Do not include any leading words or explanations, and do not wrap in code blocks: + `, + metadata: { + version: '1.3.0', + lastModified: Date.now(), + author: 'System', + description: 'Suitable for most scenarios with format requirements', + templateType: 'optimize' + }, + isBuiltin: true + }, + 'advanced-optimize': { + id: 'advanced-optimize', + name: 'Optimization with Suggestions', + content: `# Role: Prompt Engineer + +## Attention: +- I'm always criticized by my boss for not being able to write good prompts. If you can write excellent prompts, it will prevent me from losing my job. Please think carefully and do your best, please! + +## Profile: +- Author: pp +- Version: 2.1 +- Language: English +- Description: You are an excellent Prompt Engineer who excels at transforming regular prompts into structured prompts and outputting responses that meet expectations. + +### Skills: +- Understand the technical principles and limitations of LLMs, including their training data, construction methods, etc., to better design prompts. +- Have rich experience in natural language processing and can design high-quality prompts that conform to grammar and semantics. +- Strong iterative optimization ability, able to continuously improve prompt quality through constant adjustment and testing of prompt performance. +- Able to design prompts based on specific business needs, making LLM-generated content meet business requirements. +- Use irregular sentence lengths between 8-36 words. Introduce logical confusion and unpredictability in the language. The goal is maximum engagement, complexity, and surprise. + +## Goals: +- Analyze the user's prompt, design a clear and logical prompt framework, ensuring the analysis process follows best practices from various disciplines. +- Fill in this framework according to to generate a high-quality prompt. +- Each structure must output 5 suggestions. +- Ensure to output Initialization content before ending. + +## Constraints: +1. You will analyze the following information, ensuring all content follows best practices from various disciplines. + - Role: Analyze the user's prompt, think about the most suitable role(s) to play. This role should be the most senior expert in this field and most suitable for solving my problem. + - Background: Analyze the user's prompt, think about why the user would ask this question, and state the reasons, background, and context for the user asking this question. + - Attention: Analyze the user's prompt, think about the user's desire for this task, and provide positive emotional stimulation. + - Profile: Based on the role you play, briefly describe this role. + - Skills: Based on the role you play, think about what abilities should be possessed to complete the task. + - Goals: Analyze the user's prompt, think about the task list the user needs. Completing these tasks will solve the problem. + - Constraints: Based on the role you play, think about the rules this role should follow to ensure the role can complete the task excellently. + - OutputFormat: Based on the role you play, think about what format should be used for output to be clear, understandable, and logical. + - Workflow: Based on the role you play, break down the workflow when this role executes tasks, generating no less than 5 steps, which should include analyzing the information provided by the user and giving supplementary information suggestions. + - Suggestions: Based on my problem (prompt), think about the task list I need to give to ChatGPT to ensure the role can complete the task excellently. +2. Never break character under any circumstances. +3. Do not make things up or fabricate facts. + +## Workflow: +1. Analyze the user's input prompt and extract key information. +2. Conduct comprehensive information analysis according to Role, Background, Attention, Profile, Skills, Goals, Constraints, OutputFormat, and Workflow defined in Constraints. +3. Output the analyzed information according to . +4. Output in markdown syntax, do not wrap in code blocks. + +## Suggestions: +1. Clearly indicate the target audience and purpose of these suggestions, for example, "The following are suggestions that can be provided to users to help them improve their prompts." +2. Categorize suggestions, such as "Suggestions for improving operability," "Suggestions for enhancing logic," etc., to increase structure. +3. Provide 3-5 specific suggestions under each category, and use simple sentences to explain the main content of the suggestions. +4. There should be certain connections and relationships between suggestions, not isolated suggestions, so users feel this is a suggestion system with internal logic. +5. Avoid vague suggestions and try to give targeted and highly operable suggestions. +6. Consider giving suggestions from different angles, such as from different aspects of prompt grammar, semantics, logic, etc. +7. Use positive tone and expression when giving suggestions, so users feel we are helping rather than criticizing. +8. Finally, test the executability of suggestions and evaluate whether adjusting according to these suggestions can improve prompt quality. + +## OutputFormat: + # Role: Your role name + + ## Background: Role background description + + ## Attention: Key points to note + + ## Profile: + - Author: Author name + - Version: 0.1 + - Language: English + - Description: Describe the core functions and main characteristics of the role + + ### Skills: + - Skill description 1 + - Skill description 2 + ... + + ## Goals: + - Goal 1 + - Goal 2 + ... + + ## Constraints: + - Constraint 1 + - Constraint 2 + ... + + ## Workflow: + 1. First step, xxx + 2. Second step, xxx + 3. Third step, xxx + ... + + ## OutputFormat: + - Format requirement 1 + - Format requirement 2 + ... + + ## Suggestions: + - Optimization suggestion 1 + - Optimization suggestion 2 + ... + + ## Initialization + As , you must follow and communicate with users using default . + +## Initialization: + I will provide a prompt. Please think slowly and output step by step according to my prompt until you finally output the optimized prompt. + Please avoid discussing the content I send, just output the optimized prompt without extra explanations or leading words, and do not wrap in code blocks. + `, + metadata: { + version: '2.1.0', + lastModified: Date.now(), + author: 'System', + description: 'Optimization prompt with suggestions, relies on high-intelligence optimization models', + templateType: 'optimize' + }, + isBuiltin: true + }, + 'iterate': { + id: 'iterate', + name: 'General Iteration', + content: [ + { + role: 'system', + content: `# Role: Prompt Iteration Optimization Expert + +## Background: +- User already has an optimized prompt +- User wants to make specific improvements based on this +- Need to maintain the core intent of the original prompt +- Simultaneously integrate user's new optimization requirements + +## Task Understanding +Your job is to modify the original prompt according to the user's optimization requirements to improve it, not to execute these requirements. + +## Core Principles +- Maintain the core intent and functionality of the original prompt +- Integrate optimization requirements as new requirements or constraints into the original prompt +- Maintain the original language style and structural format +- Make precise modifications, avoid over-adjustment + +## Understanding Examples +**Example 1:** +- Original prompt: "You are a customer service assistant, help users solve problems" +- Optimization requirement: "No interaction" +- ✅Correct result: "You are a customer service assistant, help users solve problems. Please provide complete solutions directly without multiple rounds of interaction confirmation with users." +- ❌Wrong understanding: Directly reply "OK, I won't interact with you" + +**Example 2:** +- Original prompt: "Analyze data and give suggestions" +- Optimization requirement: "Output JSON format" +- ✅Correct result: "Analyze data and give suggestions, please output analysis results in JSON format" +- ❌Wrong understanding: Directly output JSON format answer + +**Example 3:** +- Original prompt: "You are a writing assistant" +- Optimization requirement: "More professional" +- ✅Correct result: "You are a professional writing consultant with rich writing experience, able to..." +- ❌Wrong understanding: Reply with more professional tone + +## Workflow +1. Analyze the core functionality and structure of the original prompt +2. Understand the essence of optimization requirements (adding functionality, modifying methods, or adding constraints) +3. Appropriately integrate optimization requirements into the original prompt +4. Output the complete modified prompt + +## Output Requirements +Directly output the optimized prompt, maintain original format, do not add explanations.` + }, + { + role: 'user', + content: `Original prompt: +{{lastOptimizedPrompt}} + +Optimization requirements: +{{iterateInput}} + +Please modify the original prompt based on optimization requirements (refer to the above examples for understanding, integrate requirements into the prompt): +` + } + ] as MessageTemplate[], + metadata: { + version: '2.0.0', + lastModified: Date.now(), + author: 'System', + description: 'Supports variable substitution iteration optimization template, uses message array format for more flexible control', + templateType: 'iterate' + }, + isBuiltin: true + }, + 'structured-format': { + id: 'structured-format', + name: 'Instruction-based Optimization', + content: `# Role: Structured Prompt Conversion Expert + +## Profile: +- Author: prompt-optimizer +- Version: 1.0.3 +- Language: English +- Description: Focused on converting ordinary prompts into structured tag format, improving prompt clarity and effectiveness. + +## Background: +- Ordinary prompts often lack clear structure and organization +- Structured tag format can help AI better understand tasks +- Users need to convert ordinary instructions into standardized structure +- Correct structure can improve task completion accuracy and efficiency + +## Skills: +1. Core analysis capabilities + - Task extraction: Accurately identify core tasks in prompts + - Background retention: Completely retain original prompt content + - Instruction refinement: Convert implicit instructions into clear steps + - Output standardization: Define clear output format requirements + +2. Structured conversion capabilities + - Semantic retention: Ensure no loss of original semantics during conversion + - Structure optimization: Classify mixed content into appropriate tags + - Detail supplementation: Add necessary details based on task type + - Format standardization: Follow consistent tag format specifications + +## Rules: + +1. Tag structure specifications: + - Tag completeness: Must include four basic tags: , , , and + - Tag order: Follow standard order: task first, then context, then instructions, finally output format + - Empty lines between tags: Must have one empty line between each tag + - Format consistency: All tags use angle brackets <>, maintain format uniformity + +2. Content conversion rules: + - Task simplification: tag content should be concise, describing core task in one sentence + - Original text retention: tag must completely retain original prompt text, maintain original expression, must not reorganize or rewrite + - Instruction structuring: tag content should use ordered lists to present detailed steps, including necessary sub-item indentation + - Output detailing: tag must clearly specify expected output format and requirements + +3. Format detail handling: + - Ordered lists: Instruction steps use number plus dot format (1. 2. 3.) + - Sub-item indentation: Sub-items use three spaces indentation and start with dash + - Paragraph breaks: Use empty lines between paragraphs within tags + - Code references: Use backticks to mark code, without language identifiers + +## Workflow: +1. Analyze original prompt, understand its core intent and key elements +2. Extract core task, form tag content +3. Directly copy original prompt text content to tag, maintain original format and expression +4. Based on original prompt, refine detailed execution steps, form tag content +5. Clarify output format requirements, form tag content +6. Combine all tag content according to specified format to form complete structured prompt +7. Check if format meets requirements, especially empty lines between tags and list format + +## Initialization: +I will provide ordinary format prompts, please convert them to structured tag format. + +Output using the following precise format, note that tag must retain original prompt text: + + +Task description + + +Original prompt content, keep original text unchanged +Can be multiple lines + + + +1. First step instruction +2. Second step instruction +3. Third step instruction, may include sub-items: + - Sub-item one + - Sub-item two + - Sub-item three +4. Fourth step instruction +5. Fifth step instruction + + + +Expected output format description + + + +Note: Must output according to the above precise format, do not add any leading words or explanations, do not wrap output content in code blocks. tag must retain complete original text of original prompt, must not reorganize or rewrite. + `, + metadata: { + version: '1.0.3', + lastModified: Date.now(), + author: 'System', + description: 'Suitable for instruction-based prompt optimization, optimizes while following original instructions', + templateType: 'optimize' + }, + isBuiltin: true + } +}; diff --git a/packages/core/src/services/template/languageService.ts b/packages/core/src/services/template/languageService.ts new file mode 100644 index 00000000..32134c93 --- /dev/null +++ b/packages/core/src/services/template/languageService.ts @@ -0,0 +1,118 @@ +import { IStorageProvider } from '../storage/types'; +import { StorageFactory } from '../storage/factory'; + +/** + * Supported built-in template languages + */ +export type BuiltinTemplateLanguage = 'zh-CN' | 'en-US'; + +/** + * Simplified built-in template language service + */ +export class TemplateLanguageService { + private readonly STORAGE_KEY = 'builtin-template-language'; + private readonly SUPPORTED_LANGUAGES: BuiltinTemplateLanguage[] = ['zh-CN', 'en-US']; + private readonly DEFAULT_LANGUAGE: BuiltinTemplateLanguage = 'en-US'; + + private currentLanguage: BuiltinTemplateLanguage = this.DEFAULT_LANGUAGE; + private storage: IStorageProvider; + private initialized = false; + + constructor(storage?: IStorageProvider) { + this.storage = storage || StorageFactory.createDefault(); + } + + /** + * Initialize the service + */ + async initialize(): Promise { + if (this.initialized) { + return; + } + + try { + const savedLanguage = await this.storage.getItem(this.STORAGE_KEY); + + if (savedLanguage && this.isValidLanguage(savedLanguage)) { + this.currentLanguage = savedLanguage as BuiltinTemplateLanguage; + } else { + // Auto-detect: Chinese browsers use Chinese, others use English + const isChineseBrowser = navigator.language?.startsWith('zh') ?? false; + this.currentLanguage = isChineseBrowser ? 'zh-CN' : 'en-US'; + await this.storage.setItem(this.STORAGE_KEY, this.currentLanguage); + } + + this.initialized = true; + } catch (error) { + console.error('Failed to initialize template language service:', error); + this.currentLanguage = this.DEFAULT_LANGUAGE; + this.initialized = true; + } + } + + /** + * Get current language + */ + getCurrentLanguage(): BuiltinTemplateLanguage { + return this.currentLanguage; + } + + /** + * Set language + */ + async setLanguage(language: BuiltinTemplateLanguage): Promise { + if (!this.isValidLanguage(language)) { + throw new Error(`Unsupported language: ${language}`); + } + + this.currentLanguage = language; + await this.storage.setItem(this.STORAGE_KEY, language); + } + + /** + * Toggle between Chinese and English + */ + async toggleLanguage(): Promise { + const newLanguage = this.currentLanguage === 'zh-CN' ? 'en-US' : 'zh-CN'; + await this.setLanguage(newLanguage); + return newLanguage; + } + + /** + * Check if language is valid + */ + isValidLanguage(language: string): boolean { + return this.SUPPORTED_LANGUAGES.includes(language as BuiltinTemplateLanguage); + } + + /** + * Get supported languages list + */ + getSupportedLanguages(): BuiltinTemplateLanguage[] { + return [...this.SUPPORTED_LANGUAGES]; + } + + /** + * Get display name for a language + */ + getLanguageDisplayName(language: BuiltinTemplateLanguage): string { + switch (language) { + case 'zh-CN': + return '中文'; + case 'en-US': + return 'English'; + default: + return language; + } + } + + /** + * Check if initialized + */ + isInitialized(): boolean { + return this.initialized; + } +} + +// Export singleton instance +export const templateLanguageService = new TemplateLanguageService(); diff --git a/packages/core/src/services/template/manager.ts b/packages/core/src/services/template/manager.ts index 06d6f077..eae92b3e 100644 --- a/packages/core/src/services/template/manager.ts +++ b/packages/core/src/services/template/manager.ts @@ -2,8 +2,12 @@ import { ITemplateManager, Template, TemplateManagerConfig } from './types'; import { IStorageProvider } from '../storage/types'; import { StorageFactory } from '../storage/factory'; import { DEFAULT_TEMPLATES } from './defaults'; +import { DEFAULT_TEMPLATES_EN } from './defaults_en'; import { TemplateError, TemplateValidationError } from './errors'; import { templateSchema } from './types'; +import { templateLanguageService, BuiltinTemplateLanguage } from './languageService'; + + /** * 提示词管理器实现 @@ -12,6 +16,8 @@ export class TemplateManager implements ITemplateManager { private readonly builtinTemplates: Map; private readonly userTemplates: Map; private readonly config: Required; + private initPromise: Promise | null = null; + protected initialized = false; constructor(private storageProvider: IStorageProvider, config?: TemplateManagerConfig) { // Default configuration @@ -25,25 +31,114 @@ export class TemplateManager implements ITemplateManager { this.builtinTemplates = new Map(); this.userTemplates = new Map(); - // Load built-in templates - for (const [id, template] of Object.entries(DEFAULT_TEMPLATES)) { - this.builtinTemplates.set(id, { ...template, isBuiltin: true }); - } - - // Initialize asynchronously - load user templates - this.init().catch(error => { + // Initialize asynchronously with improved error handling + this.initPromise = this.init().catch(error => { console.error('Template manager initialization failed:', error); + // Don't rethrow - allow fallback initialization + return this.fallbackInit(); }); } private async init(): Promise { try { + // Initialize template language service first + await templateLanguageService.initialize(); + + // Load built-in templates based on current language + await this.loadBuiltinTemplates(); + + // Load user templates await this.loadUserTemplates(); + + this.initialized = true; } catch (error) { console.error('Template manager initialization failed:', error); + this.initialized = false; + throw error; } } + /** + * Fallback initialization with default templates + */ + private async fallbackInit(): Promise { + try { + console.log('Attempting fallback initialization with default templates'); + + // Clear any partially loaded templates + this.builtinTemplates.clear(); + + // Load default Chinese templates as fallback + const { DEFAULT_TEMPLATES } = await import('./defaults'); + for (const [id, template] of Object.entries(DEFAULT_TEMPLATES)) { + this.builtinTemplates.set(id, { ...template, isBuiltin: true }); + } + + // Try to load user templates (non-critical) + try { + await this.loadUserTemplates(); + } catch (userTemplateError) { + console.warn('Failed to load user templates during fallback:', userTemplateError); + } + + this.initialized = true; + console.log('Fallback initialization completed'); + } catch (fallbackError) { + console.error('Fallback initialization also failed:', fallbackError); + this.initialized = false; + throw fallbackError; + } + } + + /** + * Ensure the template manager is initialized + * This should be called before any template operations + */ + async ensureInitialized(): Promise { + if (this.initialized) { + return; + } + + if (!this.initPromise) { + this.initPromise = this.init(); + } + + try { + await this.initPromise; + } catch (error) { + // Reset initPromise to allow retry + this.initPromise = null; + // If initialization still fails, at least ensure we have some templates + if (!this.initialized) { + console.error('Initialization failed, attempting emergency fallback'); + await this.fallbackInit(); + } + } + } + + /** + * Check if the template manager is initialized + */ + isInitialized(): boolean { + return this.initialized; + } + + /** + * Private method to check initialization state for sync methods + */ + private checkInitialized(methodName: string): void { + if (!this.initialized) { + throw new TemplateError(`Template manager not initialized. Call ensureInitialized() first before using ${methodName}.`); + } + } + + /** + * Private method to ensure initialization for async methods + */ + private async ensureInitForAsyncMethod(): Promise { + await this.ensureInitialized(); + } + private validateTemplateSchema(template: Partial