Version, authenticate and fully trace ecosystem calls #84

Merged
claude merged 135 commits from overnight/eco-versioned-traces into master 2026-08-01 14:50:26 +02:00
2 changed files with 64 additions and 4 deletions
Showing only changes of commit bddf52d1ee - Show all commits
+29 -4
View File
@@ -29,13 +29,26 @@ var dayPlanWords = []string{
"plan", "plans", "schedule", "agenda",
}
// otherDayWords — a day that is not today. The plan is built for the clock's
// own day only, so an utterance naming another one belongs to the calendar
// listing instead. Claiming it here would answer the wrong day, which is worse
// than answering more tersely.
// otherDayWords — a span that is not the clock's own day. The plan can only be
// built for today, so an utterance naming another day, a weekday, a week or a
// weekend belongs to the calendar listing instead. Claiming it here would
// answer today and stamp it with today's date, which is a wrong answer where
// falling through is only a terse one.
//
// The weekday names are here as a refusal, not as a feature. "какие планы на
// понедельник?" carries no other-day token in the сегодня family and does carry
// "планы", so the plan used to claim it and recite today.
var otherDayWords = []string{
"завтра", "послезавтра", "вчера", "позавчера",
"tomorrow", "yesterday",
"понедельник", "вторник", "среду", "среда", "четверг", "пятницу", "пятница",
"субботу", "суббота", "воскресенье",
"понедельника", "вторника", "четверга", "пятницы", "субботы", "воскресенья",
"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday",
"неделю", "неделя", "недели", "неделе",
"выходные", "выходных", "выходным",
"месяц", "месяца", "месяце",
"week", "weekend", "month",
}
// IsDayPlanQuery reports whether an utterance asks for today's plan (Vikunja
@@ -67,6 +80,18 @@ func IsDayPlanQuery(text string) bool {
(hasTok(toks, "what") && hasTok(toks, "next"))
}
// IsRestOfDayQuery reports whether the utterance asks for what is left of the
// day rather than for the whole of it — "что дальше?" and its English form.
//
// Tokenized for the same reason IsDayPlanQuery is: the substring form matched
// "дальше" inside longer words and "next" inside "nextcloud", and the two
// predicates deciding the same utterance differently is worse than either
// being wrong on its own.
func IsRestOfDayQuery(text string) bool {
toks := planTokens(text)
return hasTok(toks, "дальше") || hasTok(toks, "next")
}
func hasTok(toks []string, w string) bool {
for _, t := range toks {
if t == w {
+35
View File
@@ -81,3 +81,38 @@ func TestIsDayPlanQuery(t *testing.T) {
}
}
}
// The plan is built for the clock's own day. A weekday, a week or a weekend
// carries no сегодня-family token, so the plan used to claim the utterance and
// recite today under today's date. Refusing is the right answer until the plan
// can build a day that is not the clock's own.
func TestIsDayPlanQueryRefusesOtherSpans(t *testing.T) {
for _, s := range []string{
"какие планы на понедельник?",
"планы на пятницу",
"какие планы на неделю?",
"планы на выходные",
"какие планы на месяц?",
"what are my plans for friday?",
"my plan for the week",
} {
if IsDayPlanQuery(s) {
t.Errorf("IsDayPlanQuery(%q) = true, want false", s)
}
}
}
// The rest-of-day test tokenizes like IsDayPlanQuery does. The substring form
// it replaced fired on any word containing "next" or "дальше".
func TestIsRestOfDayQuery(t *testing.T) {
for _, s := range []string{"что дальше?", "и что потом, дальше?", "what's next", "NEXT"} {
if !IsRestOfDayQuery(s) {
t.Errorf("IsRestOfDayQuery(%q) = false, want true", s)
}
}
for _, s := range []string{"какие планы на сегодня?", "проверь nextcloud", "дальшесъезд", ""} {
if IsRestOfDayQuery(s) {
t.Errorf("IsRestOfDayQuery(%q) = true, want false", s)
}
}
}