package types import ( "strings" "time" ) // PromptPlaceholder represents a placeholder that can be used in prompt templates type PromptPlaceholder struct { // Name is the placeholder name (without braces), e.g., "query" Name string `json:"name"` // Label is a short label for the placeholder Label string `json:"label"` // Description explains what this placeholder represents Description string `json:"description"` } // PromptFieldType represents the type of prompt field type PromptFieldType string const ( // PromptFieldSystemPrompt is for system prompts (normal mode) PromptFieldSystemPrompt PromptFieldType = "system_prompt" // PromptFieldAgentSystemPrompt is for agent mode system prompts PromptFieldAgentSystemPrompt PromptFieldType = "agent_system_prompt" // PromptFieldContextTemplate is for context templates PromptFieldContextTemplate PromptFieldType = "context_template" // PromptFieldRewriteSystemPrompt is for rewrite system prompts PromptFieldRewriteSystemPrompt PromptFieldType = "rewrite_system_prompt" // PromptFieldRewritePrompt is for rewrite user prompts PromptFieldRewritePrompt PromptFieldType = "rewrite_prompt" // PromptFieldFallbackPrompt is for fallback prompts PromptFieldFallbackPrompt PromptFieldType = "fallback_prompt" ) // All available placeholders in the system var ( // Common placeholders PlaceholderQuery = PromptPlaceholder{ Name: "query", Label: "用户问题", Description: "用户当前的问题或查询内容", } PlaceholderContexts = PromptPlaceholder{ Name: "contexts", Label: "检索内容", Description: "从知识库检索到的相关内容列表", } PlaceholderCurrentTime = PromptPlaceholder{ Name: "current_time", Label: "当前时间", Description: "当前日期(ISO 格式:2006-01-02)。只用日期、不用时钟,避免秒级变化打断 provider 前缀缓存。", } PlaceholderCurrentWeek = PromptPlaceholder{ Name: "current_week", Label: "当前星期", Description: "当前星期几(如:星期一、Monday)", } // Rewrite prompt placeholders PlaceholderConversation = PromptPlaceholder{ Name: "conversation", Label: "历史对话", Description: "格式化的历史对话内容,用于多轮对话改写", } PlaceholderYesterday = PromptPlaceholder{ Name: "yesterday", Label: "昨天日期", Description: "昨天的日期(格式:2006-01-02)", } PlaceholderAnswer = PromptPlaceholder{ Name: "answer", Label: "助手回答", Description: "助手的回答内容(用于对话历史格式化)", } // Agent mode specific placeholders PlaceholderKnowledgeBases = PromptPlaceholder{ Name: "knowledge_bases", Label: "知识库列表", Description: "自动格式化的知识库列表,包含名称、描述、文档数量等信息", } PlaceholderWebSearchStatus = PromptPlaceholder{ Name: "web_search_status", Label: "网络搜索状态", Description: "网络搜索工具是否启用的状态(Enabled 或 Disabled)", } PlaceholderLanguage = PromptPlaceholder{ Name: "language", Label: "用户语言", Description: "用户界面的语言偏好,如 Chinese (Simplified)、English、Korean 等,用于控制 LLM 回答语言", } ) // PlaceholdersByField returns the available placeholders for a specific prompt field type func PlaceholdersByField(fieldType PromptFieldType) []PromptPlaceholder { switch fieldType { case PromptFieldSystemPrompt: // Normal mode system prompt return []PromptPlaceholder{ PlaceholderQuery, PlaceholderContexts, PlaceholderCurrentTime, PlaceholderCurrentWeek, PlaceholderLanguage, } case PromptFieldAgentSystemPrompt: // Agent mode system prompt return []PromptPlaceholder{ PlaceholderKnowledgeBases, PlaceholderWebSearchStatus, PlaceholderCurrentTime, PlaceholderLanguage, } case PromptFieldContextTemplate: return []PromptPlaceholder{ PlaceholderQuery, PlaceholderContexts, PlaceholderCurrentTime, PlaceholderCurrentWeek, PlaceholderLanguage, } case PromptFieldRewriteSystemPrompt: // Rewrite system prompt supports same placeholders as rewrite user prompt return []PromptPlaceholder{ PlaceholderQuery, PlaceholderConversation, PlaceholderCurrentTime, PlaceholderYesterday, PlaceholderLanguage, } case PromptFieldRewritePrompt: return []PromptPlaceholder{ PlaceholderQuery, PlaceholderConversation, PlaceholderCurrentTime, PlaceholderYesterday, PlaceholderLanguage, } case PromptFieldFallbackPrompt: return []PromptPlaceholder{ PlaceholderQuery, PlaceholderLanguage, } default: return []PromptPlaceholder{} } } // AllPlaceholders returns all available placeholders in the system func AllPlaceholders() []PromptPlaceholder { return []PromptPlaceholder{ PlaceholderQuery, PlaceholderContexts, PlaceholderCurrentTime, PlaceholderCurrentWeek, PlaceholderConversation, PlaceholderYesterday, PlaceholderAnswer, PlaceholderKnowledgeBases, PlaceholderWebSearchStatus, PlaceholderLanguage, } } // PlaceholderMap returns a map of field types to their available placeholders func PlaceholderMap() map[PromptFieldType][]PromptPlaceholder { return map[PromptFieldType][]PromptPlaceholder{ PromptFieldSystemPrompt: PlaceholdersByField(PromptFieldSystemPrompt), PromptFieldAgentSystemPrompt: PlaceholdersByField(PromptFieldAgentSystemPrompt), PromptFieldContextTemplate: PlaceholdersByField(PromptFieldContextTemplate), PromptFieldRewriteSystemPrompt: PlaceholdersByField(PromptFieldRewriteSystemPrompt), PromptFieldRewritePrompt: PlaceholdersByField(PromptFieldRewritePrompt), PromptFieldFallbackPrompt: PlaceholdersByField(PromptFieldFallbackPrompt), } } // --------------------------------------------------------------------------- // Unified prompt placeholder rendering // --------------------------------------------------------------------------- // PlaceholderValues is a map of placeholder names (without braces) to their // replacement values. Example: {"query": "How to use?", "language": "English"} type PlaceholderValues map[string]string // RenderPromptPlaceholders replaces all {{key}} occurrences in template with // the corresponding values from vals. Unknown placeholders are left untouched. // // Built-in auto-values (filled when not supplied explicitly): // - {{current_time}} -> time.Now().Format("2006-01-02") (date only; clock // precision would bust provider prefix caches on every request) // - {{current_week}} -> current weekday name // - {{yesterday}} -> yesterday's date (2006-01-02) func RenderPromptPlaceholders(template string, vals PlaceholderValues) string { if template == "" { return "" } // Populate auto-generated values when callers don't supply them. autoFill := func(key, value string) { if _, exists := vals[key]; !exists { if strings.Contains(template, "{{"+key+"}}") { vals[key] = value } } } now := time.Now() autoFill("current_time", now.Format("2006-01-02")) autoFill("current_week", now.Weekday().String()) autoFill("yesterday", now.AddDate(0, 0, -1).Format("2006-01-02")) result := template for key, value := range vals { placeholder := "{{" + key + "}}" if strings.Contains(result, placeholder) { result = strings.ReplaceAll(result, placeholder, value) } } return result }