Unified Agent + reusable Go agent core.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Refactor: Move MAEP feedback prompt rendering to templates

Lyric 80b7b328 0866ebd7

+121 -14
+4 -13
cmd/mistermorph/telegramcmd/command.go
··· 3215 3215 if len(recent) > 8 { 3216 3216 recent = recent[len(recent)-8:] 3217 3217 } 3218 - payload := map[string]any{ 3219 - "recent_turns": recent, 3220 - "inbound_text": inboundText, 3221 - "allowed_next": []string{"continue", "wrap_up", "switch_topic"}, 3222 - "signal_bounds": "[0,1]", 3218 + systemPrompt, userPrompt, err := renderMAEPFeedbackPrompts(recent, inboundText) 3219 + if err != nil { 3220 + return feedback, fmt.Errorf("render maep feedback prompts: %w", err) 3223 3221 } 3224 - rawPayload, _ := json.Marshal(payload) 3225 - systemPrompt := strings.Join([]string{ 3226 - "Classify conversational feedback into numeric signals.", 3227 - "Return JSON only with schema:", 3228 - "{\"signal_positive\":0..1,\"signal_negative\":0..1,\"signal_bored\":0..1,\"next_action\":\"continue|wrap_up|switch_topic\",\"confidence\":0..1}.", 3229 - "Use wrap_up only when the user shows clear stop/low-interest intent.", 3230 - }, " ") 3231 3222 res, err := client.Chat(ctx, llm.Request{ 3232 3223 Model: model, 3233 3224 ForceJSON: true, 3234 3225 Messages: []llm.Message{ 3235 3226 {Role: "system", Content: systemPrompt}, 3236 - {Role: "user", Content: string(rawPayload)}, 3227 + {Role: "user", Content: userPrompt}, 3237 3228 }, 3238 3229 Parameters: map[string]any{ 3239 3230 "temperature": 0,
+53
cmd/mistermorph/telegramcmd/maep_prompts.go
··· 1 + package telegramcmd 2 + 3 + import ( 4 + _ "embed" 5 + "encoding/json" 6 + "text/template" 7 + 8 + "github.com/quailyquaily/mistermorph/internal/prompttmpl" 9 + "github.com/quailyquaily/mistermorph/llm" 10 + ) 11 + 12 + //go:embed prompts/maep_feedback_system.tmpl 13 + var maepFeedbackSystemPromptTemplateSource string 14 + 15 + //go:embed prompts/maep_feedback_user.tmpl 16 + var maepFeedbackUserPromptTemplateSource string 17 + 18 + var maepPromptTemplateFuncs = template.FuncMap{ 19 + "toJSON": func(v any) (string, error) { 20 + b, err := json.Marshal(v) 21 + if err != nil { 22 + return "", err 23 + } 24 + return string(b), nil 25 + }, 26 + } 27 + 28 + var maepFeedbackSystemPromptTemplate = prompttmpl.MustParse("telegram_maep_feedback_system", maepFeedbackSystemPromptTemplateSource, nil) 29 + var maepFeedbackUserPromptTemplate = prompttmpl.MustParse("telegram_maep_feedback_user", maepFeedbackUserPromptTemplateSource, maepPromptTemplateFuncs) 30 + 31 + type maepFeedbackUserPromptData struct { 32 + RecentTurns []llm.Message 33 + InboundText string 34 + AllowedNext []string 35 + SignalBounds string 36 + } 37 + 38 + func renderMAEPFeedbackPrompts(recentTurns []llm.Message, inboundText string) (string, string, error) { 39 + systemPrompt, err := prompttmpl.Render(maepFeedbackSystemPromptTemplate, struct{}{}) 40 + if err != nil { 41 + return "", "", err 42 + } 43 + userPrompt, err := prompttmpl.Render(maepFeedbackUserPromptTemplate, maepFeedbackUserPromptData{ 44 + RecentTurns: recentTurns, 45 + InboundText: inboundText, 46 + AllowedNext: []string{"continue", "wrap_up", "switch_topic"}, 47 + SignalBounds: "[0,1]", 48 + }) 49 + if err != nil { 50 + return "", "", err 51 + } 52 + return systemPrompt, userPrompt, nil 53 + }
+47
cmd/mistermorph/telegramcmd/maep_prompts_test.go
··· 1 + package telegramcmd 2 + 3 + import ( 4 + "encoding/json" 5 + "strings" 6 + "testing" 7 + 8 + "github.com/quailyquaily/mistermorph/llm" 9 + ) 10 + 11 + func TestRenderMAEPFeedbackPrompts(t *testing.T) { 12 + recent := []llm.Message{ 13 + {Role: "user", Content: "hello"}, 14 + {Role: "assistant", Content: "hi"}, 15 + } 16 + inbound := "sounds good" 17 + 18 + sys, user, err := renderMAEPFeedbackPrompts(recent, inbound) 19 + if err != nil { 20 + t.Fatalf("renderMAEPFeedbackPrompts() error = %v", err) 21 + } 22 + if !strings.Contains(sys, "Classify conversational feedback") { 23 + t.Fatalf("unexpected system prompt: %q", sys) 24 + } 25 + 26 + var payload struct { 27 + RecentTurns []llm.Message `json:"recent_turns"` 28 + InboundText string `json:"inbound_text"` 29 + AllowedNext []string `json:"allowed_next"` 30 + SignalBounds string `json:"signal_bounds"` 31 + } 32 + if err := json.Unmarshal([]byte(user), &payload); err != nil { 33 + t.Fatalf("user prompt is not valid json: %v", err) 34 + } 35 + if payload.InboundText != inbound { 36 + t.Fatalf("inbound_text = %q, want %q", payload.InboundText, inbound) 37 + } 38 + if len(payload.RecentTurns) != len(recent) { 39 + t.Fatalf("recent_turns len = %d, want %d", len(payload.RecentTurns), len(recent)) 40 + } 41 + if len(payload.AllowedNext) == 0 { 42 + t.Fatalf("allowed_next is empty") 43 + } 44 + if payload.SignalBounds != "[0,1]" { 45 + t.Fatalf("signal_bounds = %q, want %q", payload.SignalBounds, "[0,1]") 46 + } 47 + }
+4
cmd/mistermorph/telegramcmd/prompts/maep_feedback_system.tmpl
··· 1 + Classify conversational feedback into numeric signals. 2 + Return JSON only with schema: 3 + {"signal_positive":0..1,"signal_negative":0..1,"signal_bored":0..1,"next_action":"continue|wrap_up|switch_topic","confidence":0..1}. 4 + Use wrap_up only when the user shows clear stop/low-interest intent.
+6
cmd/mistermorph/telegramcmd/prompts/maep_feedback_user.tmpl
··· 1 + { 2 + "recent_turns": {{toJSON .RecentTurns}}, 3 + "inbound_text": {{toJSON .InboundText}}, 4 + "allowed_next": {{toJSON .AllowedNext}}, 5 + "signal_bounds": {{toJSON .SignalBounds}} 6 + }
+7 -1
docs/prompt.md
··· 102 102 | `telegramcmd/prompts/memory_task_match_user.tmpl` | user | Carries existing tasks, updates, and matching rules. | 103 103 | `telegramcmd/prompts/memory_task_dedup_system.tmpl` | system | Defines the output contract for semantic task deduplication. | 104 104 | `telegramcmd/prompts/memory_task_dedup_user.tmpl` | user | Carries tasks and deduplication rules. | 105 + | `telegramcmd/prompts/maep_feedback_system.tmpl` | system | Defines the output contract for MAEP feedback classification. | 106 + | `telegramcmd/prompts/maep_feedback_user.tmpl` | user | Carries recent turns, inbound text, allowed actions, and signal bounds for MAEP feedback classification. | 105 107 106 108 ### 1) Intent inference 107 109 ··· 254 256 ### 17) MAEP feedback classifier 255 257 256 258 - File/Function: `cmd/mistermorph/telegramcmd/command.go` / `classifyMAEPFeedback(...)` 259 + - Templates: 260 + - `cmd/mistermorph/telegramcmd/prompts/maep_feedback_system.tmpl` 261 + - `cmd/mistermorph/telegramcmd/prompts/maep_feedback_user.tmpl` 262 + - Renderer: `cmd/mistermorph/telegramcmd/maep_prompts.go` 257 263 - Purpose: classify inbound feedback signals and next conversational action 258 - - Primary input: recent turns + inbound text + allowed next actions 264 + - Primary input: recent turns + inbound text 259 265 - Output: `maepFeedbackClassification{signal_positive, signal_negative, signal_bored, next_action, confidence}` 260 266 - JSON required: **Yes** (`ForceJSON=true`) 261 267