package semantic import ( _ "embed" "encoding/json" "fmt" "sort" ) //go:embed corpus_v1.json var corpusV1JSON []byte // RouteExample — one labeled utterance in the coarse-route experiment corpus. // Every row carries provenance so no row can masquerade as independent when // related paraphrases exist. type RouteExample struct { Text string `json:"text"` Route SemanticRoute `json:"route"` Source string `json:"source"` // where this row came from SourceID string `json:"source_id"` // case ID in the source corpus SplitGroup string `json:"split_group"` // family/seed ID for split discipline Tags []string `json:"tags,omitempty"` // FastPathResolved is true when a stage-0 grammar already handles this // utterance. The learned router should not be measured on these unless // explicitly desired; they are tagged, not removed. FastPathResolved bool `json:"fast_path_resolved"` } // CorpusEnvelope — the versioned JSON envelope. type CorpusEnvelope struct { SchemaVersion int `json:"schema_version"` Name string `json:"name"` Notes []string `json:"notes"` Examples []RouteExample `json:"examples"` } // SchemaVersionV1 is the version this package understands. const SchemaVersionV1 = 1 // LoadCorpus returns the embedded corpus, rejecting unknown schema versions. func LoadCorpus() ([]RouteExample, error) { var env CorpusEnvelope if err := json.Unmarshal(corpusV1JSON, &env); err != nil { return nil, fmt.Errorf("semantic corpus: parse: %w", err) } if env.SchemaVersion != SchemaVersionV1 { return nil, fmt.Errorf("semantic corpus: schema_version %d, want %d", env.SchemaVersion, SchemaVersionV1) } return env.Examples, nil } // ByRoute groups examples by their semantic route, for per-route inspection. func ByRoute(exs []RouteExample) map[SemanticRoute][]RouteExample { m := make(map[SemanticRoute][]RouteExample) for _, e := range exs { m[e.Route] = append(m[e.Route], e) } for k := range m { sort.Slice(m[k], func(i, j int) bool { return m[k][i].Text < m[k][j].Text }) } return m } // SplitCounts returns the number of fast-path-resolved vs // general-route-required examples. func SplitCounts(exs []RouteExample) (fastPath, residual int) { for _, e := range exs { if e.FastPathResolved { fastPath++ } else { residual++ } } return }