fix(cli): hint tokenized schema path failures at the path-form boundary

- the unknown runtime schema path error now states that canonical paths
  contain dots and must be a single argument while space-separated tokens
  resolve as a CLI path; help text and docs only reach agents that consult
  them, the error is the one surface guaranteed to be seen at failure time
- the app trust diagnostic comment is shortened to the durable constraint
  (do not pin absolute Catalog-size counts) instead of narrating the change
- NewDeliveryToolSearchEngine's doc comment notes the memo serves long-lived
  hosts; the shipped schema search command rebuilds per invocation through
  NewDeliveryToolSearchEngineWithConfig
This commit is contained in:
玉澜
2026-08-17 19:10:18 +08:00
parent b8c9ff2619
commit f2a3dd2344
3 changed files with 13 additions and 11 deletions
+4 -7
View File
@@ -73,13 +73,10 @@ func TestToolSearchDeliveryDiagnosticTrustAndChineseSlices(t *testing.T) {
if err != nil {
t.Fatalf("BuildDeliveryToolSearchDiagnosticComparison() error = %v", err)
}
// Absolute population/hit counts (1123 intent cases, 990/1123 Recall@5, 1098
// tools, 402 chinese_only, 721 mixed_chinese_ascii) were removed: they were
// pinned to one Catalog generation and went stale as soon as main added
// tools, which turned a real trust gate into a size-drift failure. The
// observed values are logged for CI forensics and the headline numbers stay
// in the generated comparison JSON (make generate-tool-search-comparison);
// what this test enforces is the size-independent trust contract below.
// Do not pin absolute Catalog-size counts here: they go stale when main
// adds tools. Enforce the size-independent trust contract below; observed
// counts are logged for CI forensics and live in the generated comparison
// JSON (make generate-tool-search-comparison).
t.Logf("intent proxy = %+v excluded_over_budget=%d", report.IntentProxy, report.IntentExcludedOverBudget)
t.Logf("language slices = %+v", report.IntentLanguageSlices)
t.Logf("context comparison = %+v", report.Context)
+4 -1
View File
@@ -325,7 +325,10 @@ func schemaPayloadFromLoadedCatalog(loaded loadedSchemaCatalog, args []string) (
}
}
}
return nil, apperrors.NewValidation("unknown runtime schema path " + strconvQuote(raw))
// The message carries the path-form boundary because it is the one surface
// an Agent is guaranteed to see at failure time.
return nil, apperrors.NewValidation("unknown runtime schema path " + strconvQuote(raw) +
": canonical paths contain dots and must be a single argument (e.g. dws schema chat.query_msg_read_status), while space-separated tokens resolve as a CLI path")
}
func schemaCatalogSnapshotHash(snapshot SchemaCatalogSnapshot) string {
+5 -3
View File
@@ -268,9 +268,11 @@ func resetDeliveryToolSearchEngineState() {
// The default engine is memoized per Catalog generation: the delivery Catalog
// is frozen and DWS_TOOL_SEARCH_* overrides are read once, so the engine is
// built once per process (a CLI invocation constructs it exactly once either
// way; long-lived hosts such as a daemon or MCP server reuse it).
// Re-registering the source root resets Catalog delivery, which invalidates
// this memo so the engine can never serve a stale Catalog or stale hashes.
// way; long-lived hosts such as a daemon or MCP server reuse it). The memo
// serves long-lived hosts: the shipped schema search command rebuilds per
// invocation through NewDeliveryToolSearchEngineWithConfig. Re-registering
// the source root resets Catalog delivery, which invalidates this memo so
// the engine can never serve a stale Catalog or stale hashes.
func NewDeliveryToolSearchEngine() (*ToolSearchEngine, error) {
deliveryToolSearchEngineOnce.Do(func() {
deliveryToolSearchEngine, deliveryToolSearchEngineErr =