router: extract stage-0 grammars into TryFastPath (slice 10)
This commit is contained in:
@@ -72,48 +72,14 @@ func New(cfg Config) *Router {
|
|||||||
// since(key)==null → don't fire: a misrouted fact is a confident wrong write,
|
// since(key)==null → don't fire: a misrouted fact is a confident wrong write,
|
||||||
// worse than a gap).
|
// worse than a gap).
|
||||||
func (r *Router) Route(ctx context.Context, utterance string, now time.Time) (Decision, error) {
|
func (r *Router) Route(ctx context.Context, utterance string, now time.Time) (Decision, error) {
|
||||||
// stage 0 — exact match / grammar. First match wins; grammars are ordered.
|
// stage 0 — deterministic fast path. First match wins; grammars are ordered.
|
||||||
// Grammars like time/date/reminder don't expect a wake-word prefix, but
|
fast, err := r.TryFastPath(ctx, NormalizedInput{Text: utterance}, now)
|
||||||
// the STT often includes one (transcribed phonetically, any script) — try
|
if err != nil {
|
||||||
// the wake-stripped utterance too so those grammars still fire.
|
return Decision{}, err
|
||||||
stripped, hadWake := StripWakeToken(utterance)
|
}
|
||||||
// declinedBuild — the grammars that matched the shape and refused the
|
if fast.Matched {
|
||||||
// content, kept for the decision record (V-564) so a reader can tell that
|
return fast.Decision, nil
|
||||||
// rule from one whose pattern never fired.
|
|
||||||
var declinedBuild map[int]bool
|
|
||||||
for i, g := range r.grammars {
|
|
||||||
d, matched, ok := g.Evaluate(utterance)
|
|
||||||
if !matched && hadWake {
|
|
||||||
d, matched, ok = g.Evaluate(stripped)
|
|
||||||
}
|
|
||||||
if !matched {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !ok {
|
|
||||||
if declinedBuild == nil {
|
|
||||||
declinedBuild = map[int]bool{}
|
|
||||||
}
|
|
||||||
declinedBuild[i] = true
|
|
||||||
continue // grammar matched shape but not content → fall through
|
|
||||||
}
|
|
||||||
d.Utterance = utterance
|
|
||||||
d.Producer = RouteProducerGrammar
|
|
||||||
// A literal pattern named that destination, which is the one provenance
|
|
||||||
// allowed to take the personal boundary off a turn (V-666). Set here and
|
|
||||||
// nowhere else, so no other arm of the cascade can claim it.
|
|
||||||
d.SourceAnchored = d.Source != SourceUnknown
|
|
||||||
// The grammar decided the intent; the extractor fills the slots it did
|
|
||||||
// not match (V-572). See fillMatchedSlots for why every grammar gets it.
|
|
||||||
r.fillMatchedSlots(ctx, &d, now)
|
|
||||||
// Capability selection: deterministic grammars that already resolved Fn
|
|
||||||
// (wakeword-act, praxis, task-status) bypass the general selector.
|
|
||||||
// SelectCapability records the existing result with
|
|
||||||
// InputKind=SelectionDeterministic.
|
|
||||||
applyCapabilityToSlots(&d, SelectCapability(d, r.extractor.Acts))
|
|
||||||
r.noteGrammarOutcomes(ctx, i+1, declinedBuild, g.Name, d.Intent)
|
|
||||||
return d, nil
|
|
||||||
}
|
}
|
||||||
r.noteGrammarOutcomes(ctx, len(r.grammars), declinedBuild, "", "")
|
|
||||||
|
|
||||||
// stage 0b — routing heads (when wired). A softmax over the label set, so
|
// stage 0b — routing heads (when wired). A softmax over the label set, so
|
||||||
// it cannot name an intent or a destination that does not exist, and its
|
// it cannot name an intent or a destination that does not exist, and its
|
||||||
|
|||||||
Reference in New Issue
Block a user