package workflows import ( "encoding/json" "fmt" ) func gradeAnswerSystemPrompt() string { return fmt.Sprintf(`You are an expert technical interviewer grading a candidate's answer. Output valid JSON matching this schema: { "user_id": "string", "answer_id": "string", "question_id": "string", "concepts": [{"id": "string", "label": "string", "track": "string"}], "scores": { "correctness": 0, "depth": 0, "communication": 0, "production_judgment": 0 }, "overall": "miss|partial|solid|strong", "strengths": ["string"], "gaps": ["string"], "evidence": [{"kind": "answer|grading|source|session|asset", "id": "string", "quote": "string", "confidence": 0.0}], "misconception_candidates": [{"label": "string", "description": "string", "evidence": [], "confidence": 0.0}], "follow_up": {"needed": true, "question": "string", "purpose": "clarify|repair|stretch|pressure_test"} } Scoring rules: - scores: 1-4 integer scale (1=inadequate, 2=surface, 3=solid, 4=strong). - correctness: factual accuracy - depth: covers tradeoffs, edge cases, production context - communication: clarity, structure, conciseness - production_judgment: practical experience signals in the answer - overall: "miss" if mostly wrong, "partial" if some correct parts, "solid" if mostly correct with depth, "strong" if comprehensive and production-ready. - evidence: always include at least one EvidenceRef with kind "grading", quote from the answer, and confidence 0.5-1.0. - follow_up.needed: true unless the answer is "strong" and complete. Set purpose to "clarify" for unclear answers, "repair" for misconceptions, "stretch" to test depth, "pressure_test" for strong answers. - misconception_candidates: list any detected wrong mental models. Respond with ONLY the JSON object, no markdown fences.`) } func gradeAnswerUserPrompt(input GradeAnswerInput) string { payload, _ := json.Marshal(input) return fmt.Sprintf("Grade this interview answer: %s", string(payload)) } func extractMemorySystemPrompt() string { return fmt.Sprintf(`You are a learner memory extraction agent. From a graded interview answer, produce memory updates. Output valid JSON matching this schema: { "updates": [ { "kind": "concept_mastery|misconception|intervention|review_schedule", "concept": {"id": "string", "label": "string", "track": "string"}, "proposed_state": "unknown|fragile|improving|interview_ready|strong_signal", "summary": "string", "evidence": [{"kind": "grading", "id": "string", "quote": "string", "confidence": 0.0}], "confidence": 0.0, "durability": "tentative|confirmed" } ] } Rules: - For every concept in the grading, create a concept_mastery update with proposed_state derived from overall grade: "miss"→fragile, "partial"→improving, "solid"→interview_ready, "strong"→strong_signal. - If follow_up.needed is true and overall is "miss" or "partial", add a misconception update (kind="misconception") for each concept with proposed_state "fragile". - If follow_up.needed is true, add an intervention update (kind="intervention") for each concept with the follow_up question as summary. - If the answer shows gaps, add a review_schedule update (kind="review_schedule") for each concept with a review reason. - Confidence: 0.5-0.7 for tentative, 0.8-1.0 for confirmed. Durability: "confirmed" only for "strong" overall. Respond with ONLY the JSON object, no markdown fences.`) } func extractMemoryUserPrompt(grade GradedAnswer) string { payload, _ := json.Marshal(grade) return fmt.Sprintf("Extract memory updates from this graded answer: %s", string(payload)) } func nextChallengeSystemPrompt() string { return fmt.Sprintf(`You are a challenge selection agent. Given learner memory state, select the next challenge. Output valid JSON matching this schema: { "concept": {"id": "string", "label": "string", "track": "string"}, "ladder_level": "define|tradeoffs|debug|design_constraints|interview_pressure", "question": "string", "rationale": "string", "difficulty_action": "lower|hold|raise|recover", "evidence": [{"kind": "grading", "id": "string", "quote": "string", "confidence": 0.0}] } Rules: - Pick the concept with the weakest readiness state. - ladder_level: fragile→define, improving→tradeoffs, interview_ready→design_constraints, strong_signal→interview_pressure. - difficulty_action: fragile→recover, improving→hold, interview_ready+→raise. - Generate one concrete interview question for the selected concept at the appropriate ladder level. - rationale: explain why this concept and level was chosen. - evidence: reference the concept's existing evidence. Respond with ONLY the JSON object, no markdown fences.`) } func nextChallengeUserPrompt(masteryJSON, profileJSON string) string { return fmt.Sprintf(`Learner mastery: %s Learner profile: %s Select the next challenge for this learner.`, masteryJSON, profileJSON) } func diagnoseSystemPrompt() string { return fmt.Sprintf(`You are a diagnostic interview agent. Given a job seeker's profile, produce an initial readiness assessment. Output valid JSON matching this schema: { "user_id": "string", "track": "string", "target_role": "string", "stack": ["string"], "initial_readiness": "unknown|fragile|improving|interview_ready|strong_signal", "concept_findings": [ { "concept": {"id": "string", "label": "string", "track": "string"}, "readiness": "unknown|fragile|improving|interview_ready|strong_signal", "reason": "string", "evidence": [] } ], "recommended_next_concepts": [{"id": "string", "label": "string", "track": "string"}] } Rules: - initial_readiness: default to "unknown" unless you have strong signals from the profile. - For each concept, estimate readiness based on the stack and target role. Default to "unknown" if no strong signal. - recommended_next_concepts: pick up to 3 concepts to start with. - evidence: always empty for initial diagnostic (no answers yet). Respond with ONLY the JSON object, no markdown fences.`) } func diagnoseUserPrompt(input DiagnosticInput) string { payload, _ := json.Marshal(input) return fmt.Sprintf("Assess initial readiness for this job seeker: %s", string(payload)) } func readinessUpdateSystemPrompt() string { return fmt.Sprintf(`You are a readiness update agent. Given learner memory state, produce readiness deltas and unlocks. Output valid JSON matching this schema: { "concept_updates": [ { "concept": {"id": "string", "label": "string", "track": "string"}, "previous": "unknown|fragile|improving|interview_ready|strong_signal", "next": "unknown|fragile|improving|interview_ready|strong_signal", "reason": "string", "evidence": [{"kind": "grading", "id": "string", "quote": "string", "confidence": 0.0}] } ], "unlocks": [ { "kind": "boss_question|review_card|portfolio_entry", "label": "string", "reason": "string" } ] } Rules: - For each concept, determine if the readiness state should change based on evidence quality and quantity. - Unlock boss_question when 3+ concepts are at interview_ready or strong_signal. - Unlock review_card when concepts have misconceptions that need revisiting. - Unlock portfolio_entry when a concept reaches strong_signal. Respond with ONLY the JSON object, no markdown fences.`) } func readinessUpdateUserPrompt(input ReadinessUpdateInput) string { payload, _ := json.Marshal(input) return fmt.Sprintf("Analyze readiness updates for: %s", string(payload)) }