Аналитик теперь может вернуть phase=ready, когда черновик уже полный и менять нечего. Раньше модель не могла это выразить и возвращала пустой propose, который валидатор резал A3 (нет изменённых полей). - analyst: case ready в validateResponse (без требований к полям) - core: propose и ready обрабатываются одинаково (applyDraft + E1 + ready) - prompt/analyst.md: контракт фаз обновлён (ask|propose|ready|abort) - тест TestDecideReady + README: раздел фаз аналитика
49 lines
1.4 KiB
Go
49 lines
1.4 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
"github.com/kamelion/ratatoskr-go/internal/storage"
|
|
)
|
|
|
|
// Message — запись диалога.
|
|
type Message struct {
|
|
Role string // "user" | "assistant"
|
|
Content string
|
|
}
|
|
|
|
// Decision — вердикт аналитика.
|
|
type Decision struct {
|
|
Phase string // "ask" | "propose" | "ready" | "abort"
|
|
Draft storage.Task // обновлённые поля черновика
|
|
Questions []string // вопросы для phase=ask
|
|
ChatReply string // ответ пользователю
|
|
}
|
|
|
|
// Decider — интерфейс для вызова аналитика (opencode).
|
|
type Decider interface {
|
|
Decide(ctx context.Context, history []Message, draft storage.Task, force bool) (Decision, error)
|
|
}
|
|
|
|
// Result — результат одного хода.
|
|
type Result struct {
|
|
Reply string
|
|
Action string // send | summary | created:N | abort | drop | greeting
|
|
TaskID int64
|
|
Status storage.Status
|
|
}
|
|
|
|
// consentPhrases — слова и фразы согласия.
|
|
var consentPhrases = []string{"создавай", "подтверждаю", "создать", "ок", "давай", "go"}
|
|
|
|
// isConsent проверяет, является ли текст согласием на создание.
|
|
func isConsent(text string) bool {
|
|
t := strings.ToLower(strings.TrimSpace(text))
|
|
for _, p := range consentPhrases {
|
|
if t == p {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
} |