@wrenai/genbi 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +141 -0
- package/bin/genbi.mjs +31 -0
- package/dist/assets/echarts-LTFC-ysd.js +40 -0
- package/dist/assets/index-Bo--QMUN.js +441 -0
- package/dist/assets/index-Xs4q7pNo.css +1 -0
- package/dist/index.html +14 -0
- package/dist/wrenai_logo.png +0 -0
- package/dist/wrenai_logo_white.png +0 -0
- package/dist-server/harness/auth/detect.d.ts +18 -0
- package/dist-server/harness/auth/detect.js +37 -0
- package/dist-server/harness/auth/index.d.ts +4 -0
- package/dist-server/harness/auth/index.js +2 -0
- package/dist-server/harness/auth/probe.d.ts +18 -0
- package/dist-server/harness/auth/probe.js +52 -0
- package/dist-server/harness/auth/types.d.ts +42 -0
- package/dist-server/harness/auth/types.js +9 -0
- package/dist-server/harness/bundle/loader.d.ts +32 -0
- package/dist-server/harness/bundle/loader.js +43 -0
- package/dist-server/harness/bundle/schema.d.ts +199 -0
- package/dist-server/harness/bundle/schema.js +127 -0
- package/dist-server/harness/bundle/version.d.ts +10 -0
- package/dist-server/harness/bundle/version.js +43 -0
- package/dist-server/harness/capability/gate.d.ts +6 -0
- package/dist-server/harness/capability/gate.js +29 -0
- package/dist-server/harness/capability/registry.d.ts +6 -0
- package/dist-server/harness/capability/registry.js +17 -0
- package/dist-server/harness/cli-args.d.ts +123 -0
- package/dist-server/harness/cli-args.js +247 -0
- package/dist-server/harness/cli.d.ts +2 -0
- package/dist-server/harness/cli.js +151 -0
- package/dist-server/harness/compile/cache.d.ts +23 -0
- package/dist-server/harness/compile/cache.js +109 -0
- package/dist-server/harness/compile/compose-profile.d.ts +34 -0
- package/dist-server/harness/compile/compose-profile.js +95 -0
- package/dist-server/harness/compile/errors.d.ts +22 -0
- package/dist-server/harness/compile/errors.js +41 -0
- package/dist-server/harness/compile/fingerprint.d.ts +22 -0
- package/dist-server/harness/compile/fingerprint.js +84 -0
- package/dist-server/harness/compile/index.d.ts +8 -0
- package/dist-server/harness/compile/index.js +7 -0
- package/dist-server/harness/compile/pipeline.d.ts +66 -0
- package/dist-server/harness/compile/pipeline.js +176 -0
- package/dist-server/harness/compile/resolve-binary.d.ts +55 -0
- package/dist-server/harness/compile/resolve-binary.js +133 -0
- package/dist-server/harness/compile/types.d.ts +107 -0
- package/dist-server/harness/compile/types.js +1 -0
- package/dist-server/harness/compile/warble-identity.d.ts +12 -0
- package/dist-server/harness/compile/warble-identity.js +33 -0
- package/dist-server/harness/compliance/gate.d.ts +35 -0
- package/dist-server/harness/compliance/gate.js +48 -0
- package/dist-server/harness/compliance/index.d.ts +2 -0
- package/dist-server/harness/compliance/index.js +1 -0
- package/dist-server/harness/compliance/types.d.ts +16 -0
- package/dist-server/harness/compliance/types.js +1 -0
- package/dist-server/harness/events/emitter.d.ts +34 -0
- package/dist-server/harness/events/emitter.js +25 -0
- package/dist-server/harness/events/index.d.ts +4 -0
- package/dist-server/harness/events/index.js +2 -0
- package/dist-server/harness/events/sse.d.ts +20 -0
- package/dist-server/harness/events/sse.js +48 -0
- package/dist-server/harness/events/types.d.ts +131 -0
- package/dist-server/harness/events/types.js +1 -0
- package/dist-server/harness/exec/errors.d.ts +16 -0
- package/dist-server/harness/exec/errors.js +29 -0
- package/dist-server/harness/exec/index.d.ts +5 -0
- package/dist-server/harness/exec/index.js +2 -0
- package/dist-server/harness/exec/local.d.ts +32 -0
- package/dist-server/harness/exec/local.js +134 -0
- package/dist-server/harness/exec/policy.d.ts +12 -0
- package/dist-server/harness/exec/policy.js +1 -0
- package/dist-server/harness/exec/types.d.ts +63 -0
- package/dist-server/harness/exec/types.js +1 -0
- package/dist-server/harness/guardrails/index.d.ts +2 -0
- package/dist-server/harness/guardrails/index.js +1 -0
- package/dist-server/harness/guardrails/policy.d.ts +45 -0
- package/dist-server/harness/guardrails/policy.js +57 -0
- package/dist-server/harness/index.d.ts +37 -0
- package/dist-server/harness/index.js +19 -0
- package/dist-server/harness/loop/errors.d.ts +53 -0
- package/dist-server/harness/loop/errors.js +72 -0
- package/dist-server/harness/loop/executor.d.ts +123 -0
- package/dist-server/harness/loop/executor.js +380 -0
- package/dist-server/harness/loop/guard.d.ts +16 -0
- package/dist-server/harness/loop/guard.js +1 -0
- package/dist-server/harness/loop/index.d.ts +5 -0
- package/dist-server/harness/loop/index.js +3 -0
- package/dist-server/harness/native-producer/index.d.ts +109 -0
- package/dist-server/harness/native-producer/index.js +302 -0
- package/dist-server/harness/npm-package-resolve.d.ts +28 -0
- package/dist-server/harness/npm-package-resolve.js +47 -0
- package/dist-server/harness/providers/adapters/anthropic.d.ts +7 -0
- package/dist-server/harness/providers/adapters/anthropic.js +6 -0
- package/dist-server/harness/providers/adapters/mock.d.ts +4 -0
- package/dist-server/harness/providers/adapters/mock.js +5 -0
- package/dist-server/harness/providers/adapters/openai-compatible.d.ts +10 -0
- package/dist-server/harness/providers/adapters/openai-compatible.js +10 -0
- package/dist-server/harness/providers/binding.d.ts +23 -0
- package/dist-server/harness/providers/binding.js +13 -0
- package/dist-server/harness/providers/errors.d.ts +6 -0
- package/dist-server/harness/providers/errors.js +12 -0
- package/dist-server/harness/providers/index.d.ts +18 -0
- package/dist-server/harness/providers/index.js +22 -0
- package/dist-server/harness/providers/registry.d.ts +16 -0
- package/dist-server/harness/providers/registry.js +24 -0
- package/dist-server/harness/render/envelope.d.ts +145 -0
- package/dist-server/harness/render/envelope.js +428 -0
- package/dist-server/harness/render/errors.d.ts +33 -0
- package/dist-server/harness/render/errors.js +46 -0
- package/dist-server/harness/render/index.d.ts +5 -0
- package/dist-server/harness/render/index.js +3 -0
- package/dist-server/harness/render/validate.d.ts +13 -0
- package/dist-server/harness/render/validate.js +88 -0
- package/dist-server/harness/route/adapter-spec.d.ts +40 -0
- package/dist-server/harness/route/adapter-spec.js +61 -0
- package/dist-server/harness/route/agent-sdk-cli.d.ts +30 -0
- package/dist-server/harness/route/agent-sdk-cli.js +86 -0
- package/dist-server/harness/route/agent-sdk-manifest.d.ts +31 -0
- package/dist-server/harness/route/agent-sdk-manifest.js +56 -0
- package/dist-server/harness/route/artifact-content.d.ts +53 -0
- package/dist-server/harness/route/artifact-content.js +83 -0
- package/dist-server/harness/route/chat-event-mapper.d.ts +95 -0
- package/dist-server/harness/route/chat-event-mapper.js +164 -0
- package/dist-server/harness/route/codex-ask-events.d.ts +25 -0
- package/dist-server/harness/route/codex-ask-events.js +395 -0
- package/dist-server/harness/route/codex-ask.d.ts +15 -0
- package/dist-server/harness/route/codex-ask.js +242 -0
- package/dist-server/harness/route/codex-local-cli.d.ts +20 -0
- package/dist-server/harness/route/codex-local-cli.js +78 -0
- package/dist-server/harness/route/codex-local-manifest.d.ts +22 -0
- package/dist-server/harness/route/codex-local-manifest.js +180 -0
- package/dist-server/harness/route/describe.d.ts +54 -0
- package/dist-server/harness/route/describe.js +84 -0
- package/dist-server/harness/route/dispatched.d.ts +138 -0
- package/dist-server/harness/route/dispatched.js +339 -0
- package/dist-server/harness/route/in-process.d.ts +43 -0
- package/dist-server/harness/route/in-process.js +106 -0
- package/dist-server/harness/route/index.d.ts +19 -0
- package/dist-server/harness/route/index.js +12 -0
- package/dist-server/harness/route/profile-source.d.ts +37 -0
- package/dist-server/harness/route/profile-source.js +76 -0
- package/dist-server/harness/route/route.d.ts +33 -0
- package/dist-server/harness/route/route.js +114 -0
- package/dist-server/harness/route/tier-binding.d.ts +36 -0
- package/dist-server/harness/route/tier-binding.js +63 -0
- package/dist-server/harness/route/types.d.ts +286 -0
- package/dist-server/harness/route/types.js +1 -0
- package/dist-server/harness/session/errors.d.ts +4 -0
- package/dist-server/harness/session/errors.js +7 -0
- package/dist-server/harness/session/gate.d.ts +11 -0
- package/dist-server/harness/session/gate.js +13 -0
- package/dist-server/harness/session/index.d.ts +5 -0
- package/dist-server/harness/session/index.js +3 -0
- package/dist-server/harness/session/run.d.ts +60 -0
- package/dist-server/harness/session/run.js +333 -0
- package/dist-server/harness/session/types.d.ts +29 -0
- package/dist-server/harness/session/types.js +1 -0
- package/dist-server/harness/setup/codex-events.d.ts +12 -0
- package/dist-server/harness/setup/codex-events.js +108 -0
- package/dist-server/harness/setup/runner.d.ts +497 -0
- package/dist-server/harness/setup/runner.js +1314 -0
- package/dist-server/harness/tools/errors.d.ts +107 -0
- package/dist-server/harness/tools/errors.js +141 -0
- package/dist-server/harness/tools/index.d.ts +13 -0
- package/dist-server/harness/tools/index.js +8 -0
- package/dist-server/harness/tools/mcp.d.ts +26 -0
- package/dist-server/harness/tools/mcp.js +15 -0
- package/dist-server/harness/tools/native.d.ts +179 -0
- package/dist-server/harness/tools/native.js +322 -0
- package/dist-server/harness/tools/parse.d.ts +14 -0
- package/dist-server/harness/tools/parse.js +18 -0
- package/dist-server/harness/tools/resolve-wren-binary.d.ts +12 -0
- package/dist-server/harness/tools/resolve-wren-binary.js +21 -0
- package/dist-server/harness/tools/resolve.d.ts +51 -0
- package/dist-server/harness/tools/resolve.js +79 -0
- package/dist-server/harness/tools/setup-native.d.ts +84 -0
- package/dist-server/harness/tools/setup-native.js +353 -0
- package/dist-server/harness/tools/wiring.d.ts +10 -0
- package/dist-server/harness/tools/wiring.js +16 -0
- package/dist-server/providers/setup.provider.yaml +31 -0
- package/dist-server/providers/wren.provider.yaml +33 -0
- package/dist-server/server/adopt.d.ts +87 -0
- package/dist-server/server/adopt.js +263 -0
- package/dist-server/server/app.d.ts +6 -0
- package/dist-server/server/app.js +2521 -0
- package/dist-server/server/auth-choice.d.ts +16 -0
- package/dist-server/server/auth-choice.js +36 -0
- package/dist-server/server/bin.d.ts +2 -0
- package/dist-server/server/bin.js +601 -0
- package/dist-server/server/bootstrap-project-binding.d.ts +31 -0
- package/dist-server/server/bootstrap-project-binding.js +71 -0
- package/dist-server/server/clarify.d.ts +10 -0
- package/dist-server/server/clarify.js +17 -0
- package/dist-server/server/codex-setup-mcp.d.ts +2 -0
- package/dist-server/server/codex-setup-mcp.js +147 -0
- package/dist-server/server/compose.d.ts +89 -0
- package/dist-server/server/compose.js +271 -0
- package/dist-server/server/conn-config.d.ts +30 -0
- package/dist-server/server/conn-config.js +253 -0
- package/dist-server/server/context-files.d.ts +12 -0
- package/dist-server/server/context-files.js +117 -0
- package/dist-server/server/context-map.d.ts +30 -0
- package/dist-server/server/context-map.js +95 -0
- package/dist-server/server/context-source.d.ts +68 -0
- package/dist-server/server/context-source.js +85 -0
- package/dist-server/server/db.d.ts +862 -0
- package/dist-server/server/db.js +1839 -0
- package/dist-server/server/enrichment-runner.d.ts +184 -0
- package/dist-server/server/enrichment-runner.js +213 -0
- package/dist-server/server/enrichment-verify.d.ts +73 -0
- package/dist-server/server/enrichment-verify.js +290 -0
- package/dist-server/server/enrichment.d.ts +232 -0
- package/dist-server/server/enrichment.js +199 -0
- package/dist-server/server/env-detect.d.ts +8 -0
- package/dist-server/server/env-detect.js +17 -0
- package/dist-server/server/env-field-hints.d.ts +46 -0
- package/dist-server/server/env-field-hints.js +48 -0
- package/dist-server/server/fold.d.ts +133 -0
- package/dist-server/server/fold.js +407 -0
- package/dist-server/server/harness-profile-sources.d.ts +3 -0
- package/dist-server/server/harness-profile-sources.js +24 -0
- package/dist-server/server/harness.d.ts +19 -0
- package/dist-server/server/harness.js +439 -0
- package/dist-server/server/impact.d.ts +18 -0
- package/dist-server/server/impact.js +85 -0
- package/dist-server/server/interactive-terminal.d.ts +175 -0
- package/dist-server/server/interactive-terminal.js +336 -0
- package/dist-server/server/native-artifacts.d.ts +1004 -0
- package/dist-server/server/native-artifacts.js +564 -0
- package/dist-server/server/native-dispatch-registry.d.ts +42 -0
- package/dist-server/server/native-dispatch-registry.js +45 -0
- package/dist-server/server/native-producer-fence.d.ts +14 -0
- package/dist-server/server/native-producer-fence.js +48 -0
- package/dist-server/server/native-session-resume.d.ts +6 -0
- package/dist-server/server/native-session-resume.js +103 -0
- package/dist-server/server/native-session-workspace.d.ts +40 -0
- package/dist-server/server/native-session-workspace.js +175 -0
- package/dist-server/server/native-sessions.d.ts +374 -0
- package/dist-server/server/native-sessions.js +1517 -0
- package/dist-server/server/native-wren-runtime.d.ts +20 -0
- package/dist-server/server/native-wren-runtime.js +259 -0
- package/dist-server/server/node-pty-host.d.ts +31 -0
- package/dist-server/server/node-pty-host.js +100 -0
- package/dist-server/server/route-intent.d.ts +40 -0
- package/dist-server/server/route-intent.js +23 -0
- package/dist-server/server/runtime-binding.d.ts +52 -0
- package/dist-server/server/runtime-binding.js +258 -0
- package/dist-server/server/source-catalog.d.ts +84 -0
- package/dist-server/server/source-catalog.js +221 -0
- package/dist-server/server/source-driver.d.ts +35 -0
- package/dist-server/server/source-driver.js +124 -0
- package/dist-server/server/spa.d.ts +2 -0
- package/dist-server/server/spa.js +51 -0
- package/dist-server/server/subscription-model-catalog.d.ts +27 -0
- package/dist-server/server/subscription-model-catalog.js +203 -0
- package/dist-server/server/turn.d.ts +249 -0
- package/dist-server/server/turn.js +1074 -0
- package/dist-server/server/wire-types.d.ts +799 -0
- package/dist-server/server/wire-types.js +1 -0
- package/dist-server/server/wren-home.d.ts +19 -0
- package/dist-server/server/wren-home.js +33 -0
- package/dist-server/server/wren-profiles.d.ts +43 -0
- package/dist-server/server/wren-profiles.js +123 -0
- package/package.json +93 -0
- package/profiles/genbi-default/context/binding.yml +9 -0
- package/profiles/genbi-default/ir.golden.json +506 -0
- package/profiles/genbi-default/profile.yml +16 -0
- package/profiles/genbi-enrich-context/components/apply_enrichment/component.yml +42 -0
- package/profiles/genbi-enrich-context/components/draft_enrichment/component.yml +30 -0
- package/profiles/genbi-enrich-context/components/draft_enrichment/steps/draft.md +34 -0
- package/profiles/genbi-enrich-context/components/inspect_context/component.yml +32 -0
- package/profiles/genbi-enrich-context/components/inspect_context/steps/inspect.md +13 -0
- package/profiles/genbi-enrich-context/context/binding.yml +4 -0
- package/profiles/genbi-enrich-context/ir.golden.json +302 -0
- package/profiles/genbi-enrich-context/profile.yml +15 -0
- package/profiles/genbi-monitor/context/binding.yml +7 -0
- package/profiles/genbi-monitor/ir.golden.json +188 -0
- package/profiles/genbi-monitor/profile.yml +27 -0
- package/profiles/genbi-setup/components/build_context/component.yml +44 -0
- package/profiles/genbi-setup/components/build_context/steps/build.md +14 -0
- package/profiles/genbi-setup/components/connect_source/component.yml +51 -0
- package/profiles/genbi-setup/components/connect_source/steps/connect.md +23 -0
- package/profiles/genbi-setup/context/binding.yml +8 -0
- package/profiles/genbi-setup/ir.golden.json +140 -0
- package/profiles/genbi-setup/profile.yml +18 -0
- package/profiles/genbi-setup/raw/schema.json +5 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": [
|
|
3
|
+
{
|
|
4
|
+
"borrowed_actions": [
|
|
5
|
+
"introspect"
|
|
6
|
+
],
|
|
7
|
+
"context_binding": {
|
|
8
|
+
"binding_mode": "runtime_selected",
|
|
9
|
+
"project": "../../../../examples/v5-jaffle"
|
|
10
|
+
},
|
|
11
|
+
"context_precondition": [
|
|
12
|
+
{
|
|
13
|
+
"predicate": "mdl_parseable"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"context_requirements": [
|
|
17
|
+
"a wren project (semantic layer) to introspect"
|
|
18
|
+
],
|
|
19
|
+
"description": "Survey the bound semantic model and report what can be asked of it — its models, metrics, dimensions and grain — without querying any rows. Use it to orient before analysis, or when someone asks what data is available; it answers questions *about* the model, not questions *from* the data.",
|
|
20
|
+
"effect": {
|
|
21
|
+
"outcome": {
|
|
22
|
+
"kind": "none"
|
|
23
|
+
},
|
|
24
|
+
"render_blocks": []
|
|
25
|
+
},
|
|
26
|
+
"eval": {
|
|
27
|
+
"metrics": [
|
|
28
|
+
"coverage"
|
|
29
|
+
],
|
|
30
|
+
"template_ref": "eval/"
|
|
31
|
+
},
|
|
32
|
+
"eval_ref": "explore_model.eval",
|
|
33
|
+
"examples": [
|
|
34
|
+
"What's in this dataset?",
|
|
35
|
+
"Which metrics and dimensions are available?",
|
|
36
|
+
"Can I break revenue down by region?"
|
|
37
|
+
],
|
|
38
|
+
"guardrails": [
|
|
39
|
+
{
|
|
40
|
+
"locked": true,
|
|
41
|
+
"name": "read_only_execution"
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
"id": "explore_model",
|
|
45
|
+
"llm_calls": [
|
|
46
|
+
{
|
|
47
|
+
"conditional": false,
|
|
48
|
+
"consumes": [],
|
|
49
|
+
"name": "summarize_semantics",
|
|
50
|
+
"produces": "semantic_summary",
|
|
51
|
+
"prompt": "You introspect the `v5-jaffle` wren project (a semantic layer at `../../../../examples/v5-jaffle`) and return a\nstructured summary of what it contains — the map the other GenBI components build on.\n\n- Introspect the semantic layer with the `wren` CLI: run `wren context show` (and, if available,\n `wren cube list`) to read the models, columns, relationships, and metrics/cubes. This is the\n `raw_introspect_result` you consume — read it, do not assume the schema.\n- Cover the FULL set: every model, its key columns and their roles (dimension vs measure vs\n time), the relationships between models, and any defined metrics/cubes. Do not drop entries to\n keep the summary short — coverage is the point.\n- Produce `semantic_summary`: a compact structured listing of every model and metric found. Your\n FINAL message must be a single JSON object of the form\n `{\"columns\": [\"model\"], \"rows\": [[\"<model_name>\"], ...]}` listing every model in the layer\n (one row per model), so coverage can be checked deterministically. You may add a short prose\n summary after the JSON.",
|
|
52
|
+
"tier": "cheap",
|
|
53
|
+
"when": null
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"params": [],
|
|
57
|
+
"precondition_result": {
|
|
58
|
+
"checks": [
|
|
59
|
+
{
|
|
60
|
+
"outcome": "pass",
|
|
61
|
+
"predicate": "mdl_parseable"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"status": "pass"
|
|
65
|
+
},
|
|
66
|
+
"prompt_fragment": "## summarize_semantics\n\nYou introspect the `v5-jaffle` wren project (a semantic layer at `../../../../examples/v5-jaffle`) and return a\nstructured summary of what it contains — the map the other GenBI components build on.\n\n- Introspect the semantic layer with the `wren` CLI: run `wren context show` (and, if available,\n `wren cube list`) to read the models, columns, relationships, and metrics/cubes. This is the\n `raw_introspect_result` you consume — read it, do not assume the schema.\n- Cover the FULL set: every model, its key columns and their roles (dimension vs measure vs\n time), the relationships between models, and any defined metrics/cubes. Do not drop entries to\n keep the summary short — coverage is the point.\n- Produce `semantic_summary`: a compact structured listing of every model and metric found. Your\n FINAL message must be a single JSON object of the form\n `{\"columns\": [\"model\"], \"rows\": [[\"<model_name>\"], ...]}` listing every model in the layer\n (one row per model), so coverage can be checked deterministically. You may add a short prose\n summary after the JSON.",
|
|
67
|
+
"realization_kind": "skill",
|
|
68
|
+
"required_capabilities": [
|
|
69
|
+
"semantic_introspection",
|
|
70
|
+
"llm:cheap"
|
|
71
|
+
],
|
|
72
|
+
"trigger": {
|
|
73
|
+
"kind": "one_shot"
|
|
74
|
+
},
|
|
75
|
+
"type": "analytical",
|
|
76
|
+
"verb": "explore_model"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"borrowed_actions": [],
|
|
80
|
+
"context_binding": {
|
|
81
|
+
"binding_mode": "runtime_selected",
|
|
82
|
+
"project": "../../../../examples/v5-jaffle"
|
|
83
|
+
},
|
|
84
|
+
"context_precondition": [
|
|
85
|
+
{
|
|
86
|
+
"predicate": "mdl_parseable"
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
"context_requirements": [
|
|
90
|
+
"a wren project (semantic layer) to query"
|
|
91
|
+
],
|
|
92
|
+
"description": "Answer one natural-language question about the bound semantic model: resolve the intent, generate SQL against the semantic layer, run it read-only, and repair the query if it fails. Returns a result table with the definitions it relied on. Use it for a single question with a single answer, not for a multi-panel overview.",
|
|
93
|
+
"effect": {
|
|
94
|
+
"outcome": {
|
|
95
|
+
"kind": "none"
|
|
96
|
+
},
|
|
97
|
+
"render_blocks": [
|
|
98
|
+
{
|
|
99
|
+
"fields": {
|
|
100
|
+
"columns": "string[]",
|
|
101
|
+
"rows": "row[]"
|
|
102
|
+
},
|
|
103
|
+
"type": "table"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"fields": {
|
|
107
|
+
"filters": "string[]",
|
|
108
|
+
"source_tables": "string[]",
|
|
109
|
+
"sql": "string"
|
|
110
|
+
},
|
|
111
|
+
"type": "definition"
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
"eval": {
|
|
116
|
+
"metrics": [
|
|
117
|
+
"execution_accuracy",
|
|
118
|
+
"tier_cost_pareto"
|
|
119
|
+
],
|
|
120
|
+
"template_ref": "eval/"
|
|
121
|
+
},
|
|
122
|
+
"eval_ref": "answer_query.eval",
|
|
123
|
+
"examples": [
|
|
124
|
+
"What were last quarter's top 10 customers by revenue?",
|
|
125
|
+
"How many orders shipped late in March?",
|
|
126
|
+
"Compare average order value between new and returning customers."
|
|
127
|
+
],
|
|
128
|
+
"guardrails": [
|
|
129
|
+
{
|
|
130
|
+
"locked": true,
|
|
131
|
+
"name": "read_only_execution"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"locked": false,
|
|
135
|
+
"name": "row_limit",
|
|
136
|
+
"threshold": 1000
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"locked": false,
|
|
140
|
+
"name": "statement_timeout",
|
|
141
|
+
"threshold": 30
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"locked": true,
|
|
145
|
+
"name": "deterministic_gate"
|
|
146
|
+
}
|
|
147
|
+
],
|
|
148
|
+
"id": "answer_query",
|
|
149
|
+
"llm_calls": [
|
|
150
|
+
{
|
|
151
|
+
"conditional": false,
|
|
152
|
+
"consumes": [],
|
|
153
|
+
"name": "resolve_intent",
|
|
154
|
+
"produces": "query_intent",
|
|
155
|
+
"prompt": "You answer a single data question over the `v5-jaffle` wren project (a semantic layer at\n`../../../../examples/v5-jaffle`). This first step resolves the user's question into a concrete query intent.\n\n- If unsure of the schema, introspect first: `wren context show`.\n- Identify which model(s), metric(s), dimension(s), filters, grouping, and ordering the question\n implies. Resolve ambiguous business terms to concrete columns/metrics in the semantic layer.\n- Produce `query_intent`: a short, explicit statement of exactly what to compute (measures,\n grouping, filters, ordering, row limit) — enough for the next step to write SQL without\n re-reading the question.",
|
|
156
|
+
"tier": "cheap",
|
|
157
|
+
"when": null
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"conditional": false,
|
|
161
|
+
"consumes": [
|
|
162
|
+
"query_intent"
|
|
163
|
+
],
|
|
164
|
+
"name": "generate_sql",
|
|
165
|
+
"produces": "query_result",
|
|
166
|
+
"prompt": "Given the resolved `query_intent`, write and execute the query through the semantic layer.\n\n- Query ONLY through the wren CLI, which returns JSON: `wren -q -o json -s '<SQL>'`. Never\n hand-write SQL against raw tables outside the model — always go through the semantic layer.\n- Respect the guardrails: read-only only, keep within the row limit, and prefer a deterministic\n ordering when the question implies a ranking or a top-N.\n- **Verify the result set (deterministic gate — required before answering).** After the query runs,\n check it is legitimate: it actually executed (no error), it is non-empty where a value is expected,\n the types/units are sane, and the grain matches the question. Record whether it passed.\n- On success, produce `query_result` as exactly one object with this shape and no extra keys:\n ```\n {\"columns\": [\"col1\", ...], \"rows\": [[v1, ...], ...],\n \"summary\": \"<a concise prose answer grounded only in the returned rows>\",\n \"verified\": true,\n \"definition\": {\"sql\": \"<the exact SQL you ran>\", \"source_tables\": [\"...\"], \"filters\": [\"...\"]}}\n ```\n Object rows from `wren` are also valid; preserve their values exactly. Emit numbers as numbers.\n Set `verified: true` only after both execution and the deterministic result-set validation pass.\n The summary must state the useful conclusion, not merely describe the columns or claim that the\n query succeeded. `definition` is run-level provenance only; do not invent formal lineage.\n- On failure, keep the attempted SQL, execution/validation evidence, and stable non-secret error in\n `query_result` so the declared repair step can diagnose it. Never mark a failed result verified.",
|
|
167
|
+
"tier": "strong",
|
|
168
|
+
"when": null
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"conditional": true,
|
|
172
|
+
"consumes": [
|
|
173
|
+
"query_result"
|
|
174
|
+
],
|
|
175
|
+
"name": "repair_sql",
|
|
176
|
+
"produces": "repaired_result",
|
|
177
|
+
"prompt": "Repair step — runs ONLY when `query_result` came back with an execution error or an empty/obviously\nwrong result. If the previous step succeeded with a sensible result, do nothing and pass it through.\n\n- Diagnose the failure from the error text (unknown column, bad join, type mismatch, wrong grain),\n fix the SQL, and re-run it through `wren -q -o json -s '<SQL>'`. Bound your attempts — a few\n retries at most; do not loop indefinitely (retry depth is this step's concern, not the profile's).\n- **If the result still cannot be validated, REFUSE.** Do not fabricate a number. Emit\n `{\"verified\": false, \"refused\": true, \"reason\": \"<why it could not be verified>\"}` and stop.\n- Produce `repaired_result`. On success return exactly the same canonical rich result shape as\n `generate_sql`, with no extra keys:\n ```\n {\"columns\": [\"col1\", ...], \"rows\": [[v1, ...], ...],\n \"summary\": \"<a concise prose answer grounded only in the returned rows>\",\n \"verified\": true,\n \"definition\": {\"sql\": \"<the exact SQL you ran>\", \"source_tables\": [\"...\"], \"filters\": [\"...\"]}}\n ```\n Object rows from `wren` are also valid; preserve their values exactly and emit numbers as numbers.\n Set `verified: true` only when the repaired query ran and its result set passed validation. The\n summary must state the useful conclusion grounded only in those rows. The `definition` is\n run-level provenance only (the query behind this answer) — do not invent unit/owner/formal-metric\n lineage (out of scope for this run-level card).",
|
|
178
|
+
"tier": "strong",
|
|
179
|
+
"when": {
|
|
180
|
+
"guard": "on_failure",
|
|
181
|
+
"target": "generate_sql"
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
],
|
|
185
|
+
"params": [],
|
|
186
|
+
"precondition_result": {
|
|
187
|
+
"checks": [
|
|
188
|
+
{
|
|
189
|
+
"outcome": "pass",
|
|
190
|
+
"predicate": "mdl_parseable"
|
|
191
|
+
}
|
|
192
|
+
],
|
|
193
|
+
"status": "pass"
|
|
194
|
+
},
|
|
195
|
+
"prompt_fragment": "## resolve_intent\n\nYou answer a single data question over the `v5-jaffle` wren project (a semantic layer at\n`../../../../examples/v5-jaffle`). This first step resolves the user's question into a concrete query intent.\n\n- If unsure of the schema, introspect first: `wren context show`.\n- Identify which model(s), metric(s), dimension(s), filters, grouping, and ordering the question\n implies. Resolve ambiguous business terms to concrete columns/metrics in the semantic layer.\n- Produce `query_intent`: a short, explicit statement of exactly what to compute (measures,\n grouping, filters, ordering, row limit) — enough for the next step to write SQL without\n re-reading the question.\n\n## generate_sql\n\nGiven the resolved `query_intent`, write and execute the query through the semantic layer.\n\n- Query ONLY through the wren CLI, which returns JSON: `wren -q -o json -s '<SQL>'`. Never\n hand-write SQL against raw tables outside the model — always go through the semantic layer.\n- Respect the guardrails: read-only only, keep within the row limit, and prefer a deterministic\n ordering when the question implies a ranking or a top-N.\n- **Verify the result set (deterministic gate — required before answering).** After the query runs,\n check it is legitimate: it actually executed (no error), it is non-empty where a value is expected,\n the types/units are sane, and the grain matches the question. Record whether it passed.\n- On success, produce `query_result` as exactly one object with this shape and no extra keys:\n ```\n {\"columns\": [\"col1\", ...], \"rows\": [[v1, ...], ...],\n \"summary\": \"<a concise prose answer grounded only in the returned rows>\",\n \"verified\": true,\n \"definition\": {\"sql\": \"<the exact SQL you ran>\", \"source_tables\": [\"...\"], \"filters\": [\"...\"]}}\n ```\n Object rows from `wren` are also valid; preserve their values exactly. Emit numbers as numbers.\n Set `verified: true` only after both execution and the deterministic result-set validation pass.\n The summary must state the useful conclusion, not merely describe the columns or claim that the\n query succeeded. `definition` is run-level provenance only; do not invent formal lineage.\n- On failure, keep the attempted SQL, execution/validation evidence, and stable non-secret error in\n `query_result` so the declared repair step can diagnose it. Never mark a failed result verified.\n\n## repair_sql\n\nRepair step — runs ONLY when `query_result` came back with an execution error or an empty/obviously\nwrong result. If the previous step succeeded with a sensible result, do nothing and pass it through.\n\n- Diagnose the failure from the error text (unknown column, bad join, type mismatch, wrong grain),\n fix the SQL, and re-run it through `wren -q -o json -s '<SQL>'`. Bound your attempts — a few\n retries at most; do not loop indefinitely (retry depth is this step's concern, not the profile's).\n- **If the result still cannot be validated, REFUSE.** Do not fabricate a number. Emit\n `{\"verified\": false, \"refused\": true, \"reason\": \"<why it could not be verified>\"}` and stop.\n- Produce `repaired_result`. On success return exactly the same canonical rich result shape as\n `generate_sql`, with no extra keys:\n ```\n {\"columns\": [\"col1\", ...], \"rows\": [[v1, ...], ...],\n \"summary\": \"<a concise prose answer grounded only in the returned rows>\",\n \"verified\": true,\n \"definition\": {\"sql\": \"<the exact SQL you ran>\", \"source_tables\": [\"...\"], \"filters\": [\"...\"]}}\n ```\n Object rows from `wren` are also valid; preserve their values exactly and emit numbers as numbers.\n Set `verified: true` only when the repaired query ran and its result set passed validation. The\n summary must state the useful conclusion grounded only in those rows. The `definition` is\n run-level provenance only (the query behind this answer) — do not invent unit/owner/formal-metric\n lineage (out of scope for this run-level card).",
|
|
196
|
+
"realization_kind": "skill",
|
|
197
|
+
"required_capabilities": [
|
|
198
|
+
"sql_execution:read_only",
|
|
199
|
+
"llm:per_step_tier",
|
|
200
|
+
"llm:strong",
|
|
201
|
+
"llm:cheap"
|
|
202
|
+
],
|
|
203
|
+
"trigger": {
|
|
204
|
+
"kind": "one_shot"
|
|
205
|
+
},
|
|
206
|
+
"type": "analytical",
|
|
207
|
+
"verb": "answer_query"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"binds": {
|
|
211
|
+
"topic_default": "overview"
|
|
212
|
+
},
|
|
213
|
+
"borrowed_actions": [],
|
|
214
|
+
"context_binding": {
|
|
215
|
+
"binding_mode": "runtime_selected",
|
|
216
|
+
"project": "../../../../examples/v5-jaffle"
|
|
217
|
+
},
|
|
218
|
+
"context_precondition": [],
|
|
219
|
+
"context_requirements": [
|
|
220
|
+
"a wren project (semantic layer) to build dashboards over"
|
|
221
|
+
],
|
|
222
|
+
"description": "Build a multi-panel dashboard on a topic: plan which panels answer it, run each panel's query read-only, and compose them into one laid-out result of KPI cards, tables and charts. Use it when someone wants an overview of a subject from several angles rather than one specific answer.",
|
|
223
|
+
"effect": {
|
|
224
|
+
"outcome": {
|
|
225
|
+
"kind": "none"
|
|
226
|
+
},
|
|
227
|
+
"render_blocks": [
|
|
228
|
+
{
|
|
229
|
+
"fields": {
|
|
230
|
+
"delta": "number?",
|
|
231
|
+
"label": "string",
|
|
232
|
+
"unit": "string?",
|
|
233
|
+
"value": "number|string"
|
|
234
|
+
},
|
|
235
|
+
"type": "kpi_card"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"fields": {
|
|
239
|
+
"columns": "string[]",
|
|
240
|
+
"rows": "row[]"
|
|
241
|
+
},
|
|
242
|
+
"type": "table"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"fields": {
|
|
246
|
+
"chart_type": "bar|line|pie|area|scatter",
|
|
247
|
+
"rows": "row[]",
|
|
248
|
+
"series": "string[]",
|
|
249
|
+
"x": "string"
|
|
250
|
+
},
|
|
251
|
+
"type": "chart"
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"fields": {
|
|
255
|
+
"filters": "string[]",
|
|
256
|
+
"source_tables": "string[]",
|
|
257
|
+
"sql": "string"
|
|
258
|
+
},
|
|
259
|
+
"type": "definition"
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
},
|
|
263
|
+
"eval": {
|
|
264
|
+
"metrics": [
|
|
265
|
+
"panel_validity",
|
|
266
|
+
"relevance"
|
|
267
|
+
],
|
|
268
|
+
"template_ref": "eval/"
|
|
269
|
+
},
|
|
270
|
+
"eval_ref": "generate_dashboard.eval",
|
|
271
|
+
"examples": [
|
|
272
|
+
"Give me a sales overview for this quarter.",
|
|
273
|
+
"Build a dashboard for customer retention.",
|
|
274
|
+
"Show me how the marketing funnel is doing."
|
|
275
|
+
],
|
|
276
|
+
"guardrails": [
|
|
277
|
+
{
|
|
278
|
+
"locked": true,
|
|
279
|
+
"name": "read_only_execution"
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"locked": true,
|
|
283
|
+
"name": "artifact_write",
|
|
284
|
+
"scope": "."
|
|
285
|
+
}
|
|
286
|
+
],
|
|
287
|
+
"id": "generate_dashboard",
|
|
288
|
+
"llm_calls": [
|
|
289
|
+
{
|
|
290
|
+
"conditional": false,
|
|
291
|
+
"consumes": [],
|
|
292
|
+
"name": "plan_dashboard",
|
|
293
|
+
"produces": "dashboard_plan",
|
|
294
|
+
"prompt": "You build data dashboards over the `v5-jaffle` wren project (a semantic layer at\n`../../../../examples/v5-jaffle`).\n\nGiven the user's topic, plan the dashboard:\n\n- If the request doesn't name a fresh topic of its own — it refers back to a dashboard already in\n play (\"the dashboard,\" \"it,\" \"that dashboard\"), or is a bare \"create an artifact for it\" /\n \"build it\" follow-up — do NOT stop here to ask what dashboard or what topic. Take the topic from\n the conversation so far (whatever dashboard/topic was most recently discussed); if there is\n truly none, fall back to an overview of the project's key metrics. Either way, keep planning:\n this step always ends with a `dashboard_plan`, never a clarifying question.\n- Discover available models, columns, and cubes **at query time** using the `wren` CLI\n (`wren context show`, `wren cube list`, `wren cube describe <cube>`). Do not assume the schema —\n introspect it.\n- Decide which metrics and dimensions answer the topic, and what panels are needed\n (KPI cards for headline numbers, a chart for trends/breakdowns, a table for detail).\n- Produce `dashboard_plan`: for each panel, the panel type (kpi_card | table | chart) and the exact\n query (through the semantic layer) that populates it. Every query goes through `wren`; never\n hand-write SQL against raw tables outside the model.",
|
|
295
|
+
"tier": "strong",
|
|
296
|
+
"when": null
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"conditional": false,
|
|
300
|
+
"consumes": [
|
|
301
|
+
"dashboard_plan"
|
|
302
|
+
],
|
|
303
|
+
"name": "compose_layout",
|
|
304
|
+
"produces": "dashboard",
|
|
305
|
+
"prompt": "Given the `dashboard_plan`, run each panel's query and compose the dashboard.\n\n- Run each planned panel query with the `wren` CLI (`wren -q -o json -s '<SQL>'`) and collect the\n results — these are the `panel_results` you consume. (This inlines the query behavior; it does not\n call a separate query component.)\n- Assemble each panel into a typed render block conforming to the render contract:\n `kpi_card` for headline numbers, `chart` for trends/breakdowns, `table` for detail.\n- Produce `dashboard`: follow the \"Render output\" instructions the dispatcher appends below for the\n active render flavor — emit the `{ blocks, summary }` envelope (programmatic) or write the HTML\n (prompt). The blocks must carry real values from `panel_results`, not placeholders.\n- The rendered dashboard IS the artifact. Never ask the user what kind of artifact they want, and\n never offer alternatives — saving the plan/JSON to a file, exporting to CSV, \"something else?\",\n etc. Whatever the user called it (\"an artifact,\" \"a report,\" \"the dashboard\"), this step's only\n job is to compose it and produce `dashboard` per the render flavor above; don't stop to\n clarify format, and don't do anything else instead (no writing files outside what \"Render\n output\" already directs).",
|
|
306
|
+
"tier": "cheap",
|
|
307
|
+
"when": null
|
|
308
|
+
}
|
|
309
|
+
],
|
|
310
|
+
"params": [
|
|
311
|
+
{
|
|
312
|
+
"bind": "optional",
|
|
313
|
+
"default": "overview",
|
|
314
|
+
"name": "topic_default"
|
|
315
|
+
}
|
|
316
|
+
],
|
|
317
|
+
"precondition_result": {
|
|
318
|
+
"checks": [],
|
|
319
|
+
"status": "pass"
|
|
320
|
+
},
|
|
321
|
+
"prompt_fragment": "## plan_dashboard\n\nYou build data dashboards over the `v5-jaffle` wren project (a semantic layer at\n`../../../../examples/v5-jaffle`).\n\nGiven the user's topic, plan the dashboard:\n\n- If the request doesn't name a fresh topic of its own — it refers back to a dashboard already in\n play (\"the dashboard,\" \"it,\" \"that dashboard\"), or is a bare \"create an artifact for it\" /\n \"build it\" follow-up — do NOT stop here to ask what dashboard or what topic. Take the topic from\n the conversation so far (whatever dashboard/topic was most recently discussed); if there is\n truly none, fall back to an overview of the project's key metrics. Either way, keep planning:\n this step always ends with a `dashboard_plan`, never a clarifying question.\n- Discover available models, columns, and cubes **at query time** using the `wren` CLI\n (`wren context show`, `wren cube list`, `wren cube describe <cube>`). Do not assume the schema —\n introspect it.\n- Decide which metrics and dimensions answer the topic, and what panels are needed\n (KPI cards for headline numbers, a chart for trends/breakdowns, a table for detail).\n- Produce `dashboard_plan`: for each panel, the panel type (kpi_card | table | chart) and the exact\n query (through the semantic layer) that populates it. Every query goes through `wren`; never\n hand-write SQL against raw tables outside the model.\n\n## compose_layout\n\nGiven the `dashboard_plan`, run each panel's query and compose the dashboard.\n\n- Run each planned panel query with the `wren` CLI (`wren -q -o json -s '<SQL>'`) and collect the\n results — these are the `panel_results` you consume. (This inlines the query behavior; it does not\n call a separate query component.)\n- Assemble each panel into a typed render block conforming to the render contract:\n `kpi_card` for headline numbers, `chart` for trends/breakdowns, `table` for detail.\n- Produce `dashboard`: follow the \"Render output\" instructions the dispatcher appends below for the\n active render flavor — emit the `{ blocks, summary }` envelope (programmatic) or write the HTML\n (prompt). The blocks must carry real values from `panel_results`, not placeholders.\n- The rendered dashboard IS the artifact. Never ask the user what kind of artifact they want, and\n never offer alternatives — saving the plan/JSON to a file, exporting to CSV, \"something else?\",\n etc. Whatever the user called it (\"an artifact,\" \"a report,\" \"the dashboard\"), this step's only\n job is to compose it and produce `dashboard` per the render flavor above; don't stop to\n clarify format, and don't do anything else instead (no writing files outside what \"Render\n output\" already directs).",
|
|
322
|
+
"realization_kind": "skill",
|
|
323
|
+
"required_capabilities": [
|
|
324
|
+
"sql_execution:read_only",
|
|
325
|
+
"genbi_build",
|
|
326
|
+
"render_contract",
|
|
327
|
+
"artifact_write",
|
|
328
|
+
"llm:per_step_tier",
|
|
329
|
+
"llm:strong",
|
|
330
|
+
"llm:cheap"
|
|
331
|
+
],
|
|
332
|
+
"trigger": {
|
|
333
|
+
"kind": "one_shot"
|
|
334
|
+
},
|
|
335
|
+
"type": "analytical",
|
|
336
|
+
"verb": "generate_dashboard"
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"borrowed_actions": [],
|
|
340
|
+
"context_binding": {
|
|
341
|
+
"binding_mode": "runtime_selected",
|
|
342
|
+
"project": "../../../../examples/v5-jaffle"
|
|
343
|
+
},
|
|
344
|
+
"context_precondition": [],
|
|
345
|
+
"context_requirements": [
|
|
346
|
+
"a wren project with an additive metric plus a time dimension and a groupable dimension"
|
|
347
|
+
],
|
|
348
|
+
"description": "Explain why a metric moved: decompose the change across time and the dimensions that drive it, then report the contributing drivers as a narrative. Needs an additive metric with a time dimension; the specific metric's additivity is checked at run time. Use it for causal \"why did this move\" questions, not for retrieving the number itself.",
|
|
349
|
+
"effect": {
|
|
350
|
+
"outcome": {
|
|
351
|
+
"kind": "none"
|
|
352
|
+
},
|
|
353
|
+
"render_blocks": [
|
|
354
|
+
{
|
|
355
|
+
"fields": {
|
|
356
|
+
"text": "string",
|
|
357
|
+
"title": "string?"
|
|
358
|
+
},
|
|
359
|
+
"type": "narrative"
|
|
360
|
+
}
|
|
361
|
+
]
|
|
362
|
+
},
|
|
363
|
+
"eval": {
|
|
364
|
+
"metrics": [
|
|
365
|
+
"driver_correctness",
|
|
366
|
+
"additivity_guard"
|
|
367
|
+
],
|
|
368
|
+
"template_ref": "eval/"
|
|
369
|
+
},
|
|
370
|
+
"eval_ref": "explain_change.eval",
|
|
371
|
+
"examples": [
|
|
372
|
+
"Why did revenue drop last month?",
|
|
373
|
+
"What's driving the increase in churn this quarter?",
|
|
374
|
+
"Which regions explain the spike in refunds?"
|
|
375
|
+
],
|
|
376
|
+
"guardrails": [
|
|
377
|
+
{
|
|
378
|
+
"locked": true,
|
|
379
|
+
"name": "read_only_execution"
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
"locked": false,
|
|
383
|
+
"name": "drill_depth_limit",
|
|
384
|
+
"threshold": 3
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"locked": true,
|
|
388
|
+
"name": "additivity_guard"
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
"locked": true,
|
|
392
|
+
"name": "artifact_write",
|
|
393
|
+
"scope": "."
|
|
394
|
+
}
|
|
395
|
+
],
|
|
396
|
+
"id": "explain_change",
|
|
397
|
+
"llm_calls": [
|
|
398
|
+
{
|
|
399
|
+
"conditional": false,
|
|
400
|
+
"consumes": [],
|
|
401
|
+
"name": "plan_decomposition",
|
|
402
|
+
"produces": "decomposition_plan",
|
|
403
|
+
"prompt": "You explain why a metric changed over the `v5-jaffle` wren project (a semantic layer at\n`../../../../examples/v5-jaffle`), by planning how to decompose the change.\n\n- Introspect the layer as needed (`wren context show`) to find the metric, its time dimension, and\n the dimensions you can break the change down by.\n- Confirm the metric is **additive** across the dimensions you intend to decompose along (a sum of\n parts equals the whole). Nothing upstream guarantees this — you must check that the **specific**\n metric you decompose is additive. If it is a ratio/average/distinct-count or otherwise\n non-additive, note that: decomposing it can mislead.\n- Produce `decomposition_plan`: the metric, the two periods being compared, and the ordered list of\n dimensions to decompose the delta along (bounded by the drill-depth limit).",
|
|
404
|
+
"tier": "strong",
|
|
405
|
+
"when": null
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
"conditional": false,
|
|
409
|
+
"consumes": [
|
|
410
|
+
"decomposition_plan"
|
|
411
|
+
],
|
|
412
|
+
"name": "synthesize_drivers",
|
|
413
|
+
"produces": "driver_explanation",
|
|
414
|
+
"prompt": "Given the `decomposition_plan`, quantify the change and synthesize the drivers into an explanation.\n\n- Run the decomposition queries through the `wren` CLI (`wren -q -o json -s '<SQL>'`): compute the\n metric for each period and the per-dimension contribution to the delta. Rank contributors by the\n size of their contribution.\n- Produce `driver_explanation` as a `narrative` render block: a short, ordered account of what drove\n the change (largest contributors first), with the actual numbers. Follow the \"Render output\"\n instructions the dispatcher appends below.\n- **Additivity caveat (required):** if the metric is not strictly additive across the decomposition\n dimensions, state plainly in the narrative that the attribution is approximate and additivity was\n not enforced. Never present a decomposition of a non-additive metric as exact — the hero output\n must not claim to run on verified reasoning it did not.",
|
|
415
|
+
"tier": "strong",
|
|
416
|
+
"when": null
|
|
417
|
+
}
|
|
418
|
+
],
|
|
419
|
+
"params": [],
|
|
420
|
+
"precondition_result": {
|
|
421
|
+
"checks": [],
|
|
422
|
+
"status": "pass"
|
|
423
|
+
},
|
|
424
|
+
"prompt_fragment": "## plan_decomposition\n\nYou explain why a metric changed over the `v5-jaffle` wren project (a semantic layer at\n`../../../../examples/v5-jaffle`), by planning how to decompose the change.\n\n- Introspect the layer as needed (`wren context show`) to find the metric, its time dimension, and\n the dimensions you can break the change down by.\n- Confirm the metric is **additive** across the dimensions you intend to decompose along (a sum of\n parts equals the whole). Nothing upstream guarantees this — you must check that the **specific**\n metric you decompose is additive. If it is a ratio/average/distinct-count or otherwise\n non-additive, note that: decomposing it can mislead.\n- Produce `decomposition_plan`: the metric, the two periods being compared, and the ordered list of\n dimensions to decompose the delta along (bounded by the drill-depth limit).\n\n## synthesize_drivers\n\nGiven the `decomposition_plan`, quantify the change and synthesize the drivers into an explanation.\n\n- Run the decomposition queries through the `wren` CLI (`wren -q -o json -s '<SQL>'`): compute the\n metric for each period and the per-dimension contribution to the delta. Rank contributors by the\n size of their contribution.\n- Produce `driver_explanation` as a `narrative` render block: a short, ordered account of what drove\n the change (largest contributors first), with the actual numbers. Follow the \"Render output\"\n instructions the dispatcher appends below.\n- **Additivity caveat (required):** if the metric is not strictly additive across the decomposition\n dimensions, state plainly in the narrative that the attribution is approximate and additivity was\n not enforced. Never present a decomposition of a non-additive metric as exact — the hero output\n must not claim to run on verified reasoning it did not.",
|
|
425
|
+
"realization_kind": "skill",
|
|
426
|
+
"required_capabilities": [
|
|
427
|
+
"sql_execution:read_only",
|
|
428
|
+
"render_contract",
|
|
429
|
+
"artifact_write",
|
|
430
|
+
"llm:strong"
|
|
431
|
+
],
|
|
432
|
+
"trigger": {
|
|
433
|
+
"kind": "one_shot"
|
|
434
|
+
},
|
|
435
|
+
"type": "analytical",
|
|
436
|
+
"verb": "explain_change"
|
|
437
|
+
}
|
|
438
|
+
],
|
|
439
|
+
"config": {},
|
|
440
|
+
"context_binding": {
|
|
441
|
+
"binding_mode": "runtime_selected",
|
|
442
|
+
"project": "../../../../examples/v5-jaffle",
|
|
443
|
+
"resolved": {
|
|
444
|
+
"dimensions": [
|
|
445
|
+
{
|
|
446
|
+
"name": "customer_id",
|
|
447
|
+
"temporal": false
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
"name": "name",
|
|
451
|
+
"temporal": false
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
"name": "order_date",
|
|
455
|
+
"temporal": true
|
|
456
|
+
}
|
|
457
|
+
],
|
|
458
|
+
"lineage": {
|
|
459
|
+
"consumers": {
|
|
460
|
+
"dashboards": 0,
|
|
461
|
+
"queries": 1
|
|
462
|
+
},
|
|
463
|
+
"edges": 7,
|
|
464
|
+
"nodes": 8,
|
|
465
|
+
"resolvable": true
|
|
466
|
+
},
|
|
467
|
+
"metrics": [
|
|
468
|
+
{
|
|
469
|
+
"additivity": "additive",
|
|
470
|
+
"declared": true,
|
|
471
|
+
"name": "total_revenue"
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
"additivity": "additive",
|
|
475
|
+
"declared": true,
|
|
476
|
+
"name": "order_count"
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
"declared": false,
|
|
480
|
+
"name": "id"
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"declared": false,
|
|
484
|
+
"name": "id"
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
"declared": false,
|
|
488
|
+
"name": "customer_id"
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
"declared": false,
|
|
492
|
+
"name": "amount"
|
|
493
|
+
}
|
|
494
|
+
],
|
|
495
|
+
"models": [
|
|
496
|
+
"customers",
|
|
497
|
+
"orders"
|
|
498
|
+
],
|
|
499
|
+
"time_dimensions": [
|
|
500
|
+
"order_date"
|
|
501
|
+
]
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
"profile": "genbi-default",
|
|
505
|
+
"warble_ir_version": "0.6"
|
|
506
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# genbi-default — the flagship GenBI profile.
|
|
2
|
+
#
|
|
3
|
+
# Mounts the four consuming GenBI components as a single git-authoritative behavior surface, bound to
|
|
4
|
+
# one semantic context. The components themselves live in Warble's shared Hub component library; this
|
|
5
|
+
# profile mounts them by id and does not own its own component library.
|
|
6
|
+
|
|
7
|
+
profile: genbi-default
|
|
8
|
+
|
|
9
|
+
context:
|
|
10
|
+
project: ./context/binding.yml
|
|
11
|
+
|
|
12
|
+
components:
|
|
13
|
+
- use: explore_model
|
|
14
|
+
- use: answer_query
|
|
15
|
+
- use: generate_dashboard
|
|
16
|
+
- use: explain_change
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# apply_enrichment — deterministic, sink-scoped post-approval lifecycle. This component has no
|
|
2
|
+
# llm_steps: the host validates the typed proposal, enforces stale/replay checks, applies one
|
|
3
|
+
# operation at a time, validates each MDL operation (reverting that operation on failure), then
|
|
4
|
+
# builds once at session end. It is intentionally a gated-tool so targets without an approval
|
|
5
|
+
# channel wall-hit instead of weakening the high-impact approval requirement.
|
|
6
|
+
id: apply_enrichment
|
|
7
|
+
verb: apply_enrichment
|
|
8
|
+
type: constitutive
|
|
9
|
+
realization_kind: gated-tool
|
|
10
|
+
|
|
11
|
+
binding_mode: pinned
|
|
12
|
+
context_requirements:
|
|
13
|
+
- "an existing pinned Wren project whose semantic layer parses and has a successful build proof"
|
|
14
|
+
context_precondition:
|
|
15
|
+
- { predicate: wren_project_exists }
|
|
16
|
+
|
|
17
|
+
params: []
|
|
18
|
+
llm_steps: []
|
|
19
|
+
trigger: { kind: one_shot }
|
|
20
|
+
guardrails:
|
|
21
|
+
- { name: must_dry_run, locked: true }
|
|
22
|
+
- { name: human_approval, locked: true }
|
|
23
|
+
- { name: no_silent_overwrite, locked: true }
|
|
24
|
+
- { name: context_write_authz, locked: true, scope: "enrichment-sinks" }
|
|
25
|
+
- { name: rollback_available, locked: true }
|
|
26
|
+
required_capabilities:
|
|
27
|
+
- context_write_authz
|
|
28
|
+
- context_validate
|
|
29
|
+
- context_build
|
|
30
|
+
- version_control
|
|
31
|
+
- human_approval
|
|
32
|
+
- enrichment_apply:deterministic
|
|
33
|
+
borrowed_actions: []
|
|
34
|
+
effect:
|
|
35
|
+
render_blocks: [diff, status]
|
|
36
|
+
outcome:
|
|
37
|
+
kind: mutation
|
|
38
|
+
target: context
|
|
39
|
+
change_type: context_enrichment
|
|
40
|
+
eval:
|
|
41
|
+
template_ref: eval/
|
|
42
|
+
metrics: [enrichment_apply_safety, compliance]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# draft_enrichment — strong-model proposal drafting over the read-only inspection result.
|
|
2
|
+
# The concrete payload stays executor-side; the host-facing proposal contains content digests,
|
|
3
|
+
# evidence ids, confidence, and sink-scoped operation identities only.
|
|
4
|
+
id: draft_enrichment
|
|
5
|
+
verb: draft_enrichment
|
|
6
|
+
type: analytical
|
|
7
|
+
realization_kind: skill
|
|
8
|
+
|
|
9
|
+
binding_mode: pinned
|
|
10
|
+
context_requirements:
|
|
11
|
+
- "an existing pinned Wren project whose semantic layer parses and has a successful build proof"
|
|
12
|
+
context_precondition:
|
|
13
|
+
- { predicate: wren_project_exists }
|
|
14
|
+
|
|
15
|
+
params: []
|
|
16
|
+
llm_steps:
|
|
17
|
+
- { name: draft, tier: strong, prompt_ref: steps/draft.md, produces: enrichment_proposal }
|
|
18
|
+
trigger: { kind: one_shot }
|
|
19
|
+
guardrails:
|
|
20
|
+
- { name: read_only_execution, locked: true }
|
|
21
|
+
required_capabilities:
|
|
22
|
+
- semantic_introspection
|
|
23
|
+
- llm:strong
|
|
24
|
+
borrowed_actions: []
|
|
25
|
+
effect:
|
|
26
|
+
render_blocks: [diff]
|
|
27
|
+
outcome: { kind: none }
|
|
28
|
+
eval:
|
|
29
|
+
template_ref: eval/
|
|
30
|
+
metrics: [enrichment_proposal_soundness, enrichment_sink_routing]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Turn the read-only gap inventory into concrete, minimal, append-only proposals. Do not apply them.
|
|
2
|
+
|
|
3
|
+
- Treat the pinned project revision as input, not something to infer. Return canonicalizable draft
|
|
4
|
+
material and evidence locators, but do not invent or claim authoritative proposal hashes or content
|
|
5
|
+
digests. The host validates the sink and revision, canonicalizes the payload, and computes both.
|
|
6
|
+
- Each proposed operation has exactly one allowed relative sink. Existing text, MDL fields, cubes,
|
|
7
|
+
and relationships are never overwritten.
|
|
8
|
+
- A cube proposal must target `cubes/<name>/metadata.yml` and use Wren's cube schema: `name`,
|
|
9
|
+
`base_object`, `measures`, optional `dimensions` / `time_dimensions`, and `properties`. Measures and
|
|
10
|
+
dimensions may reference only columns that actually exist on the chosen base object. Never invent
|
|
11
|
+
columns, use model-MDL keys such as `columns` / `metrics` / `relationships`, or hide a required join
|
|
12
|
+
inside a cube expression. If one append-only operation cannot implement the gap, emit a paused
|
|
13
|
+
decision explaining the missing prerequisite instead of fabricating a payload.
|
|
14
|
+
- For a cube, put the file body in `recommended_yaml` and follow this exact field grammar:
|
|
15
|
+
`measures: [{name, expression, type}]`, `dimensions: [{name, expression, type}]`, and
|
|
16
|
+
`time_dimensions: [{name, expression, type}]`. Use SQL aggregate expressions such as
|
|
17
|
+
`SUM(units_on_hand)` and Wren scalar types such as `BIGINT`, `INTEGER`, and `DATE`. Do not emit
|
|
18
|
+
`sql`, `model`, `columns`, `metrics`, or aggregation names such as `type: sum`.
|
|
19
|
+
- Grill mode emits one decision request at a time with a concrete recommended draft and accepts only
|
|
20
|
+
accept, edit, or skip for that operation. Skip is final for this run.
|
|
21
|
+
- Autopilot may mark only append-only low-risk model/column descriptions, knowledge rules, and
|
|
22
|
+
NL-to-SQL pairs as eligible to apply. It must pause for raw-vs-current conflicts, ambiguous sink
|
|
23
|
+
selection, and every new cube, view, relationship, MDL metric, or calculated column.
|
|
24
|
+
- Mark all inference and partial-raw evidence with confidence. Do not include raw text, credentials,
|
|
25
|
+
local paths, provider-session ids, or SDK internals in the host-facing proposal.
|
|
26
|
+
- A new cube is high impact, always requires approval, and is never autopilot-eligible.
|
|
27
|
+
|
|
28
|
+
Produce `enrichment_proposal`; approval, canonical hashes/digests, and application are deterministic
|
|
29
|
+
host responsibilities. Your FINAL message must be one JSON object only. Do not include prose or
|
|
30
|
+
Markdown fences. The top level is `{ "enrichment_proposal": { ... } }`; for Grill it contains the
|
|
31
|
+
supplied `project_revision`, exactly one operation with `relative_sink` and `recommended_yaml`,
|
|
32
|
+
confidence/evidence locators, `impact: "high"`, `requires_approval: true`,
|
|
33
|
+
`autopilot_eligible: false`, and one decision whose allowed responses are exactly
|
|
34
|
+
`["accept", "edit", "skip"]`.
|