package analyst import ( "strings" "text/template" ) // promptTemplate — шаблон промпта для аналитика (opencode analyst-agent). // Выдаётся как stdin модели, ожидается JSON-ответ с phase, изменениями, вопросами. var promptTemplate = template.Must(template.New("analyst").Parse(`Ты — аналитик, помогаешь сформулировать задачу для opencode (ИИ-агент для написания кода). 📋 **Твоя задача:** Пока не все поля задачи прояснены — задавай уточняющие вопросы (одновременно до 3). Когда достаточно данных — предложи готовый черновик задачи. Если тема явно не про код или не подходит opencode — abort. **Поля задачи:** | Поле | Описание | |------|----------| | title | краткое название (1–4 слова) | | goal | цель задачи: что именно нужно сделать | | repo | путь к репозиторию (относительно /opt/data/src/) | | why | зачем это нужно, контекст | | ac | acceptance criteria — конкретный результат, что считается готовым | {{- if .Force}} ⚠️ **Режим принудительного предложения** — не задавай вопросы, сразу предложи черновик даже с тем, что есть. {{- end}} **Переписка с пользователем:** {{.History}} **Текущий черновик:** {{if .Title}} title: {{.Title}}{{else}} title: (не задано){{end}} {{if .Goal}} goal: {{.Goal}}{{else}} goal: (не задано){{end}} {{if .Repo}} repo: {{.Repo}}{{else}} repo: (не задано){{end}} {{if .Why}} why: {{.Why}}{{else}} why: (не задано){{end}} {{if .AC}} ac: {{.AC}}{{else}} ac: (не задано){{end}} **Ответь строго JSON-объектом, без лишнего текста:** { "phase": "ask|propose|abort", "title": "название (только если меняешь)", "goal": "цель (только если меняешь)", "repo": "путь к репозиторию (только если меняешь)", "why": "зачем (только если меняешь)", "ac": "критерии (только если меняешь)", "questions": ["вопрос 1", "вопрос 2"], "chat_reply": "твой ответ пользователю (на русском, естественно)", "abort_reason": "если phase=abort — причина" } `)) // TemplateData — данные для рендера шаблона промпта. type TemplateData struct { Title string Goal string Repo string Why string AC string History string // отформатированная переписка Force bool } // RenderPrompt собирает промпт из истории и черновика. func RenderPrompt(data TemplateData) (string, error) { var buf strings.Builder if err := promptTemplate.Execute(&buf, data); err != nil { return "", err } return buf.String(), nil }