feat(nest): POST/GET nest messages, Jev-first tagging, event-driven crow response (#10)

This commit is contained in:
Smokey committed 2026-10-28 03:34:37 -06:00
1 parent ba5dbbc7ae
commit e4e4d12dea
5 files changed
+281 -1

No files matched your search

+62
View File
@@ -159,6 +159,68 @@ func (c JevCall) confident(threshold float64) bool {
return c.ModeConf >= threshold && c.TaskTypeConf >= threshold
}
// kindQuestions tags a nest message with its kind (A1: Jev first). The escape
// option "say" keeps Jev from forcing a wrong label: any message it isn't sure
// about falls back to the safest kind.
var kindQuestions = map[string]any{
"kind": map[string]any{
"type": "choice",
"instructions": "What kind of chatroom message is this?",
"criteria": map[string]string{
"request": "Asks a member or the room for work.",
"claim": "Takes ownership of a request.",
"deliver": "Posts the result of a request.",
"refer": "Points to a file or artifact instead of pasting it.",
"say": "Ordinary talk, or unclear.",
},
},
}
// ClassifyKind returns the kind when Jev is set and its choice sits at or
// above the confidence band, with the choice probabilities for the log. Not ok
// means the caller falls back to the poster's header (EVENTS.md tagging rule).
func (j *JevClient) ClassifyKind(ctx context.Context, text string) (string, map[string]float64, bool) {
if j == nil {
return "", nil, false
}
answers, _, _, err := j.SystemOne(ctx, text, kindQuestions)
if err != nil {
return "", nil, false
}
a := answers["kind"]
if a.Choice == "" || a.Confidence == nil || *a.Confidence < j.threshold {
return "", nil, false
}
return a.Choice, a.Probabilities, true
}
// ClassifyKind tags a nest message under the same guardrails as any call:
// flock cap, timeout and flight log, with the probabilities recorded.
func (f *Flock) ClassifyKind(ctx context.Context, text string, budgets ...*Budget) (string, map[string]float64, bool) {
if f.jev == nil {
return "", nil, false
}
for _, b := range budgets {
if err := b.Check(); err != nil {
return "", nil, false
}
}
f.sem <- struct{}{}
defer func() { <-f.sem }()
cctx, cancel := context.WithTimeout(ctx, f.g.CrowTimeout)
defer cancel()
start := time.Now()
kind, probs, ok := f.jev.ClassifyKind(cctx, text)
e := Event{Kind: "tag", Item: text, Crow: "Sentry", Model: f.jev.model, Ms: time.Since(start).Milliseconds(), Prob: probs, Note: kind}
if !ok {
e.Note = "" // unsure: the header decides
}
if f.log != nil {
f.log.Write(e)
}
return kind, probs, ok
}
func (c JevCall) summary() string {
return fmt.Sprintf("Jev: %s %.0f%%, %s %.0f%%", c.Mode, c.ModeConf*100, c.TaskType, c.TaskTypeConf*100)
}