@malloy-publisher/skills 0.1.13 → 0.1.16
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/README.md +3 -3
- package/package.json +1 -1
- package/skills/eval-answer/SKILL.md +1 -1
- package/skills/eval-answer/scripts/check_contamination.py +2 -2
- package/skills/eval-answer/scripts/mcp_payload.py +1 -1
- package/skills/eval-answer/scripts/mcp_payload_test.py +1 -1
- package/skills/eval-diagnose/SKILL.md +1 -1
- package/skills/eval-diagnose/scripts/diagnose.py +3 -3
- package/skills/eval-improve/SKILL.md +1 -1
- package/skills/eval-improve/scripts/improve.py +5 -5
- package/skills/eval-judge/SKILL.md +1 -1
- package/skills/eval-loop/SKILL.md +2 -2
- package/skills/eval-loop/reference/running-a-run.md +1 -1
- package/skills/eval-loop/scripts/run_baseline.py +23 -18
- package/skills/eval-loop/templates/eval-run-package/README.md +3 -3
- package/skills/malloy/SKILL.md +2 -2
- package/skills/malloy-analysis/SKILL.md +3 -4
- package/skills/malloy-analysis-pitfalls/SKILL.md +1 -1
- package/skills/malloy-analysis-report/SKILL.md +1 -1
- package/skills/malloy-analyze/SKILL.md +1 -1
- package/skills/malloy-charts/SKILL.md +1 -1
- package/skills/malloy-dashboards/SKILL.md +4 -4
- package/skills/malloy-debug/SKILL.md +1 -1
- package/skills/malloy-define/SKILL.md +1 -1
- package/skills/malloy-discover/SKILL.md +1 -1
- package/skills/malloy-document/SKILL.md +2 -2
- package/skills/malloy-getting-started/SKILL.md +34 -18
- package/skills/malloy-gotchas-modeling/SKILL.md +1 -1
- package/skills/malloy-gotchas-queries/SKILL.md +1 -1
- package/skills/malloy-gotchas-rendering/SKILL.md +1 -1
- package/skills/malloy-html-data-app-embedding/SKILL.md +1 -1
- package/skills/malloy-html-data-app-runtime/SKILL.md +1 -1
- package/skills/malloy-html-data-apps/SKILL.md +1 -1
- package/skills/malloy-lookml-review/SKILL.md +1 -1
- package/skills/malloy-materialization/SKILL.md +1 -1
- package/skills/malloy-materialization-tuning/SKILL.md +2 -2
- package/skills/malloy-model/SKILL.md +1 -1
- package/skills/malloy-model-as-you-go/SKILL.md +1 -1
- package/skills/malloy-modeling/SKILL.md +16 -16
- package/skills/malloy-notebook-chat/SKILL.md +1 -1
- package/skills/malloy-notebooks/SKILL.md +1 -1
- package/skills/malloy-patterns/SKILL.md +1 -1
- package/skills/malloy-phrase-detection/SKILL.md +26 -24
- package/skills/malloy-publish/SKILL.md +2 -2
- package/skills/malloy-queries/SKILL.md +1 -1
- package/skills/malloy-review/SKILL.md +1 -1
- package/skills/malloy-scope/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -53,11 +53,11 @@ skill points to for detail it does not inline. Start with `malloy-getting-starte
|
|
|
53
53
|
`malloy-review` to check Malloy for correctness.
|
|
54
54
|
|
|
55
55
|
A few skills (`malloy-modeling`, `malloy-publish`, `malloy-document`, `malloy-getting-started`, and
|
|
56
|
-
the `malloy` index) are written for a Publisher host and name Publisher's
|
|
56
|
+
the `malloy` index) are written for a Publisher host and name Publisher's MCP tools
|
|
57
57
|
directly. The rest describe Malloy itself and refer to tools by bare name (`get_context`,
|
|
58
58
|
`execute_query`, `search_malloy_docs`), because the prefix depends on the
|
|
59
|
-
host. `search_database_schema` maps the same way if a shared skill starts using it. On Publisher those are `
|
|
60
|
-
`
|
|
59
|
+
host. `search_database_schema` maps the same way if a shared skill starts using it. On Publisher those are `get_context`, `execute_query`, `search_malloy_docs`, and
|
|
60
|
+
`search_database_schema`.
|
|
61
61
|
|
|
62
62
|
## Versioning
|
|
63
63
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: eval-answer
|
|
3
3
|
description: 'Score one analytical answer against a verified golden, and score which of the entities the golden depends on retrieval delivered to the answerer. Run the contamination checklist, re-execute the submitted query yourself, then spawn a judge subagent per skill:eval-judge. Append attempt, tool_call, score, and retrieval_score events to the file ledger (reference/ledger-schema.md). Never explain the failure (eval-diagnose) or edit the model (eval-improve). Use when asked whether an answer was correct, to score a run, or to baseline a model.'
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Evaluate One Answer
|
|
@@ -21,7 +21,7 @@ The log is a JSON object:
|
|
|
21
21
|
"toolUses": [
|
|
22
22
|
{"name": "Read", "input": {"path": "..."}},
|
|
23
23
|
{"name": "Shell", "input": {"command": "..."}},
|
|
24
|
-
{"name": "
|
|
24
|
+
{"name": "get_context", "input": {}}
|
|
25
25
|
],
|
|
26
26
|
"reportedCalls": 4
|
|
27
27
|
}
|
|
@@ -148,7 +148,7 @@ def check(
|
|
|
148
148
|
name = _tool_name(entry) or f"use[{i}]"
|
|
149
149
|
hay = _haystack(entry)
|
|
150
150
|
hits = _matches(hay, needles)
|
|
151
|
-
# modelPath on
|
|
151
|
+
# modelPath on execute_query is required, not a file read --
|
|
152
152
|
# including when the MCP call rides over Shell as a curl JSON-RPC.
|
|
153
153
|
if model_needles and _is_host_file_tool(name) and not _is_mcp_transport(hay):
|
|
154
154
|
hits.extend(_matches(hay, model_needles))
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Pull search terms and entity ids out of a get_context exchange. Stdlib only.
|
|
3
3
|
|
|
4
|
-
`
|
|
4
|
+
`get_context` has more than one request shape and more than one response
|
|
5
5
|
shape, and an extractor written against the one you happen to see first will
|
|
6
6
|
silently return nothing for the others -- scoring every attempt at zero recall
|
|
7
7
|
while the agent was in fact handed exactly what it needed.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""python mcp_payload_test.py
|
|
3
3
|
|
|
4
|
-
The fixtures are trimmed copies of real `
|
|
4
|
+
The fixtures are trimmed copies of real `get_context` exchanges. The
|
|
5
5
|
regression they exist for: an extractor written against the flat `results`
|
|
6
6
|
shape returned [] for the nested one, which scored attempts that had received
|
|
7
7
|
everything at 0% recall and moved three baseline failures off "query
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: eval-diagnose
|
|
3
3
|
description: 'Diagnose why a scored answer failed and who owns the fix, then cluster the failures by shared root cause. Walk dataset, agent-call, get_context/model, get_context/retrieval, construction, then model-definition. Append issue events to the file ledger, linked by traceId, one per cluster. Use after eval-answer, when triaging a run, or before changing a model. Does not edit the model (eval-improve).'
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Diagnose One Answer
|
|
@@ -61,9 +61,9 @@ import ledger # noqa: E402
|
|
|
61
61
|
from ledger import read_jsonl # noqa: E402
|
|
62
62
|
|
|
63
63
|
SKILLS_ROOT = pathlib.Path(__file__).resolve().parent.parent.parent
|
|
64
|
-
DIAGNOSE_TOOLS = ("
|
|
65
|
-
"
|
|
66
|
-
"
|
|
64
|
+
DIAGNOSE_TOOLS = ("mcp__publisher__get_context",
|
|
65
|
+
"mcp__publisher__execute_query",
|
|
66
|
+
"mcp__publisher__compile_model",
|
|
67
67
|
"Read", "Grep", "Glob")
|
|
68
68
|
# The platform target: a hosted MCP server. Its NAME has to match the one
|
|
69
69
|
# run_baseline.py's answerer used, because that name is the OAuth cache key --
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: eval-improve
|
|
3
3
|
description: 'Make the smallest safe Malloy model edit that closes a diagnosed model-owned gap, with a probe receipt for every factual claim. Use after eval-diagnose, or when asked to fix a model so an agent can discover the right answer. Never accepts its own edit; the acceptance check belongs to eval-loop. Does not decide whether an answer was wrong (eval-answer) or why (eval-diagnose).'
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Improve the Model
|
|
@@ -65,17 +65,17 @@ import ledger # noqa: E402
|
|
|
65
65
|
from ledger import read_jsonl # noqa: E402
|
|
66
66
|
|
|
67
67
|
SKILLS_ROOT = pathlib.Path(__file__).resolve().parent.parent.parent
|
|
68
|
-
IMPROVE_TOOLS = ("
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
68
|
+
IMPROVE_TOOLS = ("mcp__publisher__get_context",
|
|
69
|
+
"mcp__publisher__execute_query",
|
|
70
|
+
"mcp__publisher__compile_model",
|
|
71
|
+
"mcp__publisher__reload_package",
|
|
72
72
|
"Read", "Edit", "Write", "Grep", "Glob",
|
|
73
73
|
"Bash(bash ./sync_and_reload.sh)")
|
|
74
74
|
|
|
75
75
|
RELOAD = """curl -s -m 60 -X POST "{mcp_url}" \\
|
|
76
76
|
-H "Content-Type: application/json" \\
|
|
77
77
|
-H "Accept: application/json, text/event-stream" \\
|
|
78
|
-
-d '{{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{{"name":"
|
|
78
|
+
-d '{{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{{"name":"reload_package","arguments":{{"environmentName":"{environment}","packageName":"{package}"}}}}}}' \\
|
|
79
79
|
| grep -o '"sourceContentSha":"[^"]*"' | head -1"""
|
|
80
80
|
|
|
81
81
|
SYNC_SCRIPT = """#!/bin/bash
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: eval-judge
|
|
3
3
|
description: 'Decide whether ONE answer matches its golden, and say whether you believe the golden. Read this before emitting any verdict. Covers containment, column pairing, near_match, refusals, and the gold_status judgement. Use when scoring an attempt in an evaluation run; never to conduct a run (eval-loop), diagnose a failure (eval-diagnose) or edit a model (eval-improve).'
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# The judge
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: eval-loop
|
|
3
3
|
description: 'Conduct a local Publisher evaluation loop in five steps: scrape/run, eval, diagnose, improve, checkpoint. You are the conductor: import cases into the file ledger, spawn a blind answerer, then run eval-answer, eval-diagnose, and eval-improve. Persistence is plain files under the model package''s evals/ directory; checkpoints are git commits of the model repo. Use to score a model, diagnose failures, improve behind an acceptance check, or roll back a bad direction.'
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# The Evaluation Loop
|
|
@@ -202,7 +202,7 @@ the run measure something other than what it names:
|
|
|
202
202
|
default. Where that exists, point `--mcp-url` at the proxy on localhost
|
|
203
203
|
and no OAuth step is needed, because the extension holds it. Check what
|
|
204
204
|
the proxy actually exposes before relying on it: the same proxy may serve
|
|
205
|
-
a local Publisher's
|
|
205
|
+
a local Publisher's tools instead, and then `--hosted-tools` is
|
|
206
206
|
naming tools that are not there. This route is not available to someone
|
|
207
207
|
running the CLI alone.
|
|
208
208
|
|
|
@@ -76,7 +76,7 @@ chases `ModuleNotFoundError` three times.
|
|
|
76
76
|
Two failure modes worth pre-empting, because both produce a clean-looking run:
|
|
77
77
|
|
|
78
78
|
- **Pre-approve the tools.** A headless answerer that has to ask permission for
|
|
79
|
-
`
|
|
79
|
+
`get_context` stalls until the timeout and lands as a harness error.
|
|
80
80
|
- **Check the served revision is the one you edited.** Publisher serves a
|
|
81
81
|
snapshot copy, so a model fix can be absent from the run that is supposed to
|
|
82
82
|
measure it. Query the changed measure once before spending an arm on it.
|
|
@@ -74,9 +74,9 @@ import urllib.parse
|
|
|
74
74
|
import urllib.request
|
|
75
75
|
from typing import Any
|
|
76
76
|
|
|
77
|
-
ANSWER_TOOLS = ("
|
|
78
|
-
"
|
|
79
|
-
"
|
|
77
|
+
ANSWER_TOOLS = ("mcp__publisher__get_context",
|
|
78
|
+
"mcp__publisher__execute_query",
|
|
79
|
+
"mcp__publisher__compile_model")
|
|
80
80
|
# The platform target: a hosted MCP server exposing the same two operations
|
|
81
81
|
# under its own names. The CLI addresses a tool as `mcp__<server>__<tool>`, so
|
|
82
82
|
# both halves are configuration -- `--hosted-mcp-server` names the server (which
|
|
@@ -210,15 +210,20 @@ def next_run_label(out: pathlib.Path, set_name: str, phase: str) -> str:
|
|
|
210
210
|
return f"{stem}-{n:02d}"
|
|
211
211
|
|
|
212
212
|
|
|
213
|
-
# Tools only the open-source Publisher exposes. A
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
#
|
|
218
|
-
#
|
|
219
|
-
# a
|
|
220
|
-
|
|
221
|
-
|
|
213
|
+
# Tools only the open-source Publisher exposes. A skill naming these is a
|
|
214
|
+
# host/router skill written for Publisher, and on a hosted target it teaches the
|
|
215
|
+
# answerer tools it does not have. That does not error -- the answerer simply
|
|
216
|
+
# reads instructions for a different surface -- so it has to be said out loud or
|
|
217
|
+
# the run quietly measures a different system than the one it names.
|
|
218
|
+
#
|
|
219
|
+
# Keyed on tools Publisher HAS and a hosted target does not. It used to be keyed
|
|
220
|
+
# on the `malloy_` prefix, on the reasoning that a bare name was the portable
|
|
221
|
+
# spelling and a prefixed one meant Publisher. That distinction is gone:
|
|
222
|
+
# Publisher's tools are bare names now, so `get_context` and `execute_query` are
|
|
223
|
+
# what BOTH surfaces call them and neither can mark a skill as Publisher-only.
|
|
224
|
+
# Authoring, catalog and health have no hosted counterpart, so they still can.
|
|
225
|
+
PUBLISHER_ONLY_TOOLS = ("compile_model", "reload_package",
|
|
226
|
+
"list_packages", "get_status")
|
|
222
227
|
|
|
223
228
|
|
|
224
229
|
def publisher_only_skills(names: list[str],
|
|
@@ -411,8 +416,8 @@ Package: {package}
|
|
|
411
416
|
|
|
412
417
|
Question: {question}
|
|
413
418
|
|
|
414
|
-
Use
|
|
415
|
-
|
|
419
|
+
Use get_context to find the entities you need, then execute_query to run a
|
|
420
|
+
Malloy query against the model. Base the answer only on what the model
|
|
416
421
|
returns. If the model genuinely cannot answer the question, say so plainly and
|
|
417
422
|
name the specific data that is missing rather than substituting a proxy.
|
|
418
423
|
|
|
@@ -601,9 +606,9 @@ def run_answerer(case: dict[str, Any], a: argparse.Namespace,
|
|
|
601
606
|
answer.append(c["text"])
|
|
602
607
|
elif c.get("type") == "tool_use":
|
|
603
608
|
name = c["name"]
|
|
604
|
-
# Both surfaces
|
|
605
|
-
#
|
|
606
|
-
#
|
|
609
|
+
# Both surfaces answer to the bare names now. The old
|
|
610
|
+
# malloy_-prefixed names stay matched so a run recorded
|
|
611
|
+
# against an older Publisher still parses.
|
|
607
612
|
if (name.endswith("malloy_getContext")
|
|
608
613
|
or name.endswith("__get_context")):
|
|
609
614
|
n_get += 1
|
|
@@ -1124,7 +1129,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1124
1129
|
print(f" ! {len(mismatched)} answerer skill(s) name Publisher-only "
|
|
1125
1130
|
f"tools on a PLATFORM run: {', '.join(mismatched)}")
|
|
1126
1131
|
print(f" The answerer holds mcp__{a.hosted_mcp_server}__* tools "
|
|
1127
|
-
f"and will be told to call
|
|
1132
|
+
f"and will be told to call Publisher-only ones. Point "
|
|
1128
1133
|
f"--answerer-manifest at a manifest written for this host, or "
|
|
1129
1134
|
f"--skills-root at the checkout that ships it.")
|
|
1130
1135
|
print(f"answerer skills: "
|
|
@@ -128,7 +128,7 @@ which is the fastest way to see a compile failure. Notebooks are listed by
|
|
|
128
128
|
`404 "<file> is a notebook"`. A notebook fetched from `notebooks/<file>` reports
|
|
129
129
|
its cells' compiled schemas under `modelInfo`, but only the cells it treats as
|
|
130
130
|
anonymous queries -- do not read a low count there as cells failing to compile. To
|
|
131
|
-
verify every cell, run each named query through `
|
|
131
|
+
verify every cell, run each named query through `execute_query`.
|
|
132
132
|
|
|
133
133
|
Pass `--mcp_port` explicitly. It defaults to 4040 and any other local Publisher
|
|
134
134
|
already holds it; the server logs `Port 4040 in use` and carries on without an MCP
|
|
@@ -141,13 +141,13 @@ nothing.
|
|
|
141
141
|
|
|
142
142
|
It serves a **snapshot copy** under `publisher_data/<env>/<pkg>/`. The `location`
|
|
143
143
|
in `publisher.config.json` is a one-time import source, not a live mount, and
|
|
144
|
-
`
|
|
144
|
+
`reload_package` does **not** re-fetch from it -- it answers
|
|
145
145
|
`mode: in-place`, re-reading the snapshot. So the working recipe is sync then
|
|
146
146
|
reload:
|
|
147
147
|
|
|
148
148
|
```bash
|
|
149
149
|
rsync -a --delete <location>/ "$SERVER_ROOT/publisher_data/<env>/<pkg>/"
|
|
150
|
-
# then
|
|
150
|
+
# then reload_package {environmentName, packageName}
|
|
151
151
|
```
|
|
152
152
|
|
|
153
153
|
Sync the whole package. A new model over stale CSVs fails with a column-not-found
|
package/skills/malloy/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy
|
|
3
3
|
description: Index of all Malloy skills. Use when user asks "malloy help", "what malloy skills are available", "how do I use malloy", or needs guidance on which Malloy skill to use.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -99,4 +99,4 @@ Publishing is out of scope for open-source Publisher v1. Self-hosters move a fin
|
|
|
99
99
|
|
|
100
100
|
## Syntax Help
|
|
101
101
|
|
|
102
|
-
Call `
|
|
102
|
+
Call `search_malloy_docs` with your question. Use `skill:malloy-patterns` to discover available topics.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-analysis
|
|
3
3
|
description: Workflow for answering data questions against Malloy semantic models over MCP - structured discovery with get_context, query construction with execute_query, verification, and answer delivery. Use whenever the user asks a data question, wants a metric, a breakdown, a trend, or a chart over a model.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -23,8 +23,7 @@ Restate what is being asked: which metric, which breakdown (group-by), which fil
|
|
|
23
23
|
Find the right entities before writing any query.
|
|
24
24
|
|
|
25
25
|
- If you do not already know which package to work in, confirm the environment and package with the user before continuing.
|
|
26
|
-
- Call `get_context` with
|
|
27
|
-
- Drill down: call `get_context` again scoped to a single source to focus on the fields and views within it. Even when you know an entity's name, use a descriptive search rather than just echoing the name.
|
|
26
|
+
- Call `get_context` with entity targets that describe the fields the question needs: a `measure` for the metric, a `dimension` for each breakdown or filter, and a `view` if the question sounds like a canned report. `skill:malloy-phrase-detection` covers how to phrase them; the tool description covers what comes back and how to narrow or browse.
|
|
28
27
|
- Read the `#(doc)` on each returned entity: it is where grain, units, null handling, and any source-level filters are described. Confirm the exact field names against the results before using them.
|
|
29
28
|
- **Read the source's own docstring too, not just each field's.** The source-level `#(doc)` often defines the grain, the universe of rows it represents, how joins behave, and source-level filters or assumptions that apply to every query rooted on it. Factor both the source and the field docstrings into how you build and later verify the query.
|
|
30
29
|
- When unsure of Malloy syntax, call `search_malloy_docs` (for example "window functions", "histograms") rather than guessing. For decomposing a multi-part question into retrieval targets, load `skill:malloy-phrase-detection`.
|
|
@@ -84,4 +83,4 @@ Never re-run the exact same query expecting a different result: a given query al
|
|
|
84
83
|
|
|
85
84
|
Answer in plain language, lead with the number that was asked for, and show the supporting rows. State the assumptions you made (filter values, date ranges, any ad-hoc field). Acknowledge caveats the verification step surfaced, and say so if you could not fully verify something. When the result lends itself to a chart, say which Malloy render tag fits and why (load `skill:malloy-charts`), for example `# bar_chart` for a category breakdown or `# line_chart` for a trend over time.
|
|
86
85
|
|
|
87
|
-
End with a short **Next steps**: one or two specific deeper analyses the data could support (a finer breakdown, a comparison, a different angle), concrete to what you just found.
|
|
86
|
+
End with a short **Next steps**: one or two specific deeper analyses the data could support (a finer breakdown, a comparison, a different angle), concrete to what you just found. If a notebook-authoring skill is available to you, you can also offer to capture the analysis as a Malloy notebook so it can be re-run and shared.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-analysis-pitfalls
|
|
3
3
|
description: Common data analysis pitfalls to watch for during query construction and result interpretation. Reference this checklist when verifying queries and results to catch errors before presenting an answer.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-analysis-report
|
|
3
3
|
description: Combine validated Malloy queries into a notebook report or dashboard. Use when the user asks to "create a report", "build a dashboard", "combine these into a report", or wants a persistent multi-query artifact.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-analyze
|
|
3
3
|
description: Open-ended exploration with no specific question to answer, and building views/dashboards/notebooks on an existing model. Use when the user asks "what's interesting?", "explore this data", "find insights", "look for patterns", "build a dashboard", or "create views". Not for a specific data question - answering one is `malloy-analysis`, and writing down what the answer assumed is `malloy-model-as-you-go`. For exploration start at Step 1; for views on an existing model jump to View Patterns.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-charts
|
|
3
3
|
description: Chart selection guidance and renderer reference for Malloy views. Use when choosing visualization types, adding chart annotations, user asks "what chart should I use", "how should I visualize this", or when deciding between bar_chart, line_chart, scatter_chart, etc.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-dashboards
|
|
3
3
|
description: "Build or modify a Malloy Publisher dashboard, a tagged .malloy file in a package's dashboards/ directory, with auto-rendered filter controls, a grid layout, and # drill click-through. Use when the user asks for a dashboard, a filterable operational view, or drill-through between views, and no code is wanted."
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -28,7 +28,7 @@ Scanned at a glance is a dashboard; read top to bottom is a notebook.
|
|
|
28
28
|
## Build sequence
|
|
29
29
|
|
|
30
30
|
1. **READ THE MODEL FIRST.** Get the real source, view, dimension, and given names from the package:
|
|
31
|
-
`
|
|
31
|
+
`get_context` if you have it, otherwise the REST model endpoint or the `.malloy` files.
|
|
32
32
|
Never guess a name. A guessed field in a query fails the whole package load, not just that one
|
|
33
33
|
dashboard; a guessed tile or suggest source is quieter, and only shows up in the package warnings.
|
|
34
34
|
2. **PICK THE VIEWS TO SHOW.** A dashboard is `## artifact { tiles=[…] }` naming existing views, so
|
|
@@ -46,7 +46,7 @@ Scanned at a glance is a dashboard; read top to bottom is a notebook.
|
|
|
46
46
|
name, so the file compiles and the package loads, but running the picker fails with
|
|
47
47
|
`Undefined source '<name>'`. The package warnings name this one too, saying which source to
|
|
48
48
|
import. Import the source that suggest query reads, not just the query.
|
|
49
|
-
5. **COMPILE IT** with `
|
|
49
|
+
5. **COMPILE IT** with `compile_model` (or `POST …/models/<path>/compile`), against the source text,
|
|
50
50
|
before you save, at the path the file will have. **Editing one that already exists needs
|
|
51
51
|
`"scope": "file"`**, which compiles your source AS that file; the default appends it instead, so
|
|
52
52
|
every imported name and the query name collide with the saved copy and you get a wall of
|
|
@@ -56,7 +56,7 @@ Scanned at a glance is a dashboard; read top to bottom is a notebook.
|
|
|
56
56
|
dashboard that imports it. A clean compile is not a working dashboard: some tag mistakes surface
|
|
57
57
|
at step 6, and some only when you look at the page in step 7. (The third scope, `append`, is the
|
|
58
58
|
default and is what a not-yet-saved file gets.)
|
|
59
|
-
6. **SAVE IT, RELOAD, AND READ THE MANIFEST AND THE WARNINGS.** `
|
|
59
|
+
6. **SAVE IT, RELOAD, AND READ THE MANIFEST AND THE WARNINGS.** `reload_package`, or
|
|
60
60
|
`GET …/packages/<pkg>?reload=true`. Check the status the reload returns as well as the warnings:
|
|
61
61
|
a 424 means the package did not load and your edit is not live. **The `warnings` key is absent
|
|
62
62
|
when there are none**, so an empty response is the pass, not a sign you are reading the wrong
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-debug
|
|
3
3
|
description: Fix Malloy compile errors and understand error messages. Use when encountering errors in .malloy files, user says "fix this error", "malloy error", "compile error", "syntax error", or sees 20+ cascading errors.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-define
|
|
3
3
|
description: Propose a source plan and field definitions for a Malloy semantic model. Covers picking which sources to model and at what grain, then proposing the specific renames, dimensions, and measures per source, every proposal backed by querying the data.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-discover
|
|
3
3
|
description: Silent data discovery for Malloy modeling. Used at Step 1 of the modeling workflow. Scans tables, columns, distributions, and relationships without user interaction. The agent builds an internal picture before presenting anything.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-document
|
|
3
3
|
description: 'Add documentation with #(doc) tags to Malloy models so fields and sources are described in plain language. Use when user asks to "add documentation", "add doc tags", "document the model", or wants fields and sources described for natural-language search and discovery. For declaring parameterizable filters with #(filter), see the malloy-model skill. Filters are a runtime/modeling construct (governance, latency, correctness), not a documentation tag.'
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -184,7 +184,7 @@ After writing `#(doc)` tags, present any that required judgment to the user for
|
|
|
184
184
|
| `total` | "Total order amount in USD" | Medium | Could be gross or net, verified with sample query |
|
|
185
185
|
| `status` | "Order status: pending, shipped, delivered" | High | Values confirmed via a query of distinct values |
|
|
186
186
|
|
|
187
|
-
Only flag fields where the description required assumptions about business meaning, units, or valid values. When in doubt about valid values, run a quick query against the data to confirm them before writing the description. Use `
|
|
187
|
+
Only flag fields where the description required assumptions about business meaning, units, or valid values. When in doubt about valid values, run a quick query against the data to confirm them before writing the description. Use `get_context` to ground yourself in the package's sources and fields and `execute_query` to check distinct values, for example `run: source -> { group_by: status }`.
|
|
188
188
|
|
|
189
189
|
## Done
|
|
190
190
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-getting-started
|
|
3
|
-
description: First steps for using a Malloy Publisher deployment through its MCP tools. Use when connecting to Publisher for the first time, when you do not yet know the available environments, packages, or models, or when a user asks what data they can explore. Covers verifying the server, discovering data with
|
|
4
|
-
version: 0.1.
|
|
3
|
+
description: First steps for using a Malloy Publisher deployment through its MCP tools. Use when connecting to Publisher for the first time, when you do not yet know the available environments, packages, or models, or when a user asks what data they can explore. Covers verifying the server, discovering data with get_context, and running a first grounded query.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -14,7 +14,7 @@ Goal: go from "connected" to a correct, grounded answer without guessing any nam
|
|
|
14
14
|
|
|
15
15
|
## 0. Confirm the tools are reachable
|
|
16
16
|
|
|
17
|
-
At minimum you need `
|
|
17
|
+
At minimum you need `get_context`, `list_packages`, `execute_query`, and `search_malloy_docs`. Authoring a model also needs `compile_model` and `reload_package` (see section 4); an older Publisher may not serve those two.
|
|
18
18
|
|
|
19
19
|
If none of the tools are there, either the server is not running or your client connected before it was. Start the server (`npx @malloy-publisher/server --port 4000`, or `bun run build && bun run start` from a clone) and wait until `curl -s http://localhost:4000/api/v0/status` reports `operationalState: serving`. If the point is to author models against a local package, add `--watch-env <env>`: without it Publisher copies local packages at boot and serves the copies, so saved edits are never read.
|
|
20
20
|
|
|
@@ -25,9 +25,9 @@ If you started the server yourself in this session, the tools still will not app
|
|
|
25
25
|
Two escape hatches worth knowing:
|
|
26
26
|
|
|
27
27
|
- **When the session cannot be relaunched from the workspace directory** (a project `.mcp.json` is only discovered by sessions that *start* in its directory), register the server at user scope so the directory stops mattering: `claude mcp add --transport http malloy http://localhost:4040/mcp -s user` (use the MCP port the server actually bound; its startup log prints it). Caveat: for sessions that do start in the workspace, the project `.mcp.json` shadows the user-scoped entry, so prefer the project file when it is discoverable.
|
|
28
|
-
- **Do not trust an existing `.mcp.json`'s URL blindly.** The file outlives the server that wrote it, and a boot that failed partway (for example, the REST port was taken) can leave it pointing at a dead port while a live server sits on another. If connecting fails or answers look wrong, confirm identity with `
|
|
28
|
+
- **Do not trust an existing `.mcp.json`'s URL blindly.** The file outlives the server that wrote it, and a boot that failed partway (for example, the REST port was taken) can leave it pointing at a dead port while a live server sits on another. If connecting fails or answers look wrong, confirm identity with `list_packages`, which names the environment and packages you are really talking to; that check works on every platform, which the port check does not (`lsof -iTCP:4040 -sTCP:LISTEN` on macOS and Linux, `netstat -ano | findstr :4040` on Windows).
|
|
29
29
|
|
|
30
|
-
When a user is present, do not route around it by calling the REST API with curl. It appears to work, so the user never learns their session is missing the tools, and you lose what they are for: grounded discovery instead of guessed names, `
|
|
30
|
+
When a user is present, do not route around it by calling the REST API with curl. It appears to work, so the user never learns their session is missing the tools, and you lose what they are for: grounded discovery instead of guessed names, `compile_model` instead of throwaway queries, and `reload_package` instead of a restart. Say the tools are missing and let the user fix it in five seconds. Running unattended, with nobody who can reconnect you, is different: there the REST API is the supported interface, not a workaround. Discovery, query, compile, and reload all have REST equivalents (`search_malloy_docs` and `get_context`'s plain-English ranking do not; read the bundled skills for syntax and ground from model metadata instead); the running server serves the full spec at `http://localhost:4000/api-doc.yaml`, and AGENTS.md carries the endpoint map.
|
|
31
31
|
|
|
32
32
|
## 0.5 Ask whether they also use the CLI or the VS Code extension
|
|
33
33
|
|
|
@@ -81,41 +81,57 @@ that start failing auth after a long session mean the token expired, not that th
|
|
|
81
81
|
|
|
82
82
|
## 1. Discover what exists (never guess names)
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
Two tools, in this order.
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
- `environmentName` only: the packages in that environment.
|
|
88
|
-
- `environmentName` + `packageName`: that package's sources.
|
|
89
|
-
- `environmentName` + `packageName` + `query` (plain English): the sources, views, named queries, and dimension/measure fields most relevant to the question.
|
|
86
|
+
`list_packages` takes no arguments and returns every environment with its packages. That is where the environment and package names come from. It is also the only place a package that failed to load shows up, with the reason; a package missing from a plain listing looks like one that does not exist.
|
|
90
87
|
|
|
91
|
-
|
|
88
|
+
`get_context` retrieves against one package. Give it a `search_targets` entry per concept the question needs, and a `scopes` entry naming the environment and package:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"search_targets": [
|
|
93
|
+
{"target_type": "measure", "search_text": "total revenue"},
|
|
94
|
+
{"target_type": "dimension", "search_text": "the product category"}
|
|
95
|
+
],
|
|
96
|
+
"scopes": [{"environment": "examples", "package": "storefront"}]
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**One call answers.** The response groups the fields that matched under the sources holding them, so describing the fields is the whole search: there is no second call to drill into a source. Two variations are worth knowing:
|
|
101
|
+
|
|
102
|
+
- Omit a target's `search_text` to enumerate that type instead of ranking it. A lone `{"target_type": "source"}` is the catalog browse, which returns a thin card per source (a one-line summary rather than the full doc) and pages with `offset` and `next_offset`.
|
|
103
|
+
- Add `source` to the scope to narrow to one source, which is also how to read that source's full doc after a browse.
|
|
104
|
+
|
|
105
|
+
`scopes` is required and takes exactly one entry, because retrieval is indexed per package.
|
|
106
|
+
|
|
107
|
+
Use the names it returns exactly. Do not invent environments, packages, sources, or fields. A field reached through a join is named by its full dotted path; pass it verbatim rather than rebuilding it.
|
|
92
108
|
|
|
93
109
|
## 2. Run the query
|
|
94
110
|
|
|
95
|
-
|
|
111
|
+
A retrieval response is a `sources` array. Each entry's `source_info.resource_id` carries `environment`, `package`, and `model_path`; pass them to `execute_query` as `environmentName`, `packageName`, and `modelPath`, plus either:
|
|
96
112
|
|
|
97
|
-
- a named view or query: pass its `name` as `queryName` (with `sourceName` for a view), or
|
|
113
|
+
- a named view or query: pass its `name` as `queryName` (with the card's `resource_id.source` as `sourceName` for a view), or
|
|
98
114
|
- an ad-hoc query: pass Malloy code as `query`.
|
|
99
115
|
|
|
100
116
|
The result is JSON. Charts and dashboards defined in the model render in the Publisher UI at http://localhost:4000.
|
|
101
117
|
|
|
102
118
|
## 3. When you need Malloy syntax
|
|
103
119
|
|
|
104
|
-
Use `
|
|
120
|
+
Use `search_malloy_docs` for language questions (filters, aggregates, joins, nesting, renderers).
|
|
105
121
|
|
|
106
|
-
If the data you want is in a connected database but not yet in any package, use `
|
|
122
|
+
If the data you want is in a connected database but not yet in any package, use `search_database_schema` instead of `get_context`: it walks a connection's schemas and tables and ranks them against a plain-English description, and hands back the `source:` line to start a model from. It returns names and types only, so to see what a column actually contains run `execute_query` against a model in a package that uses the same connection, with an ad-hoc query like `run: my_conn.table('sales.orders') -> { group_by: order_status }`. That tool needs an existing model to run against, so a table you have not modelled yet has none of its own.
|
|
107
123
|
|
|
108
124
|
## 4. What else you can do here
|
|
109
125
|
|
|
110
126
|
Answering questions is the start, not the whole surface. When the user asks what is possible, say so rather than offering queries alone. Switch skills for the deeper work:
|
|
111
127
|
|
|
112
|
-
- `malloy-modeling`: build or change a model. Validate the edit with `
|
|
128
|
+
- `malloy-modeling`: build or change a model. Validate the edit with `compile_model`, save it, then `reload_package` so the new sources and views run by name without restarting the server.
|
|
113
129
|
- `malloy-analysis`: explore a package and answer data questions.
|
|
114
130
|
- `malloy-html-data-apps`: build a data app, a hand-authored HTML page in the package's `public/` directory that Publisher serves, backed by the package's models and needing no build step.
|
|
115
131
|
- `malloy-review`: check Malloy for correctness.
|
|
116
132
|
|
|
117
133
|
## Contract
|
|
118
134
|
|
|
119
|
-
- Ground every query in `
|
|
120
|
-
-
|
|
135
|
+
- Ground every query in `get_context` results. If a name is not in the results, do not use it.
|
|
136
|
+
- With an environment and package in hand, ask the question in one call: the matching sources come back with their fields nested. `list_packages` and the catalog browse are for finding a name you are missing, not steps to walk first.
|
|
121
137
|
- Confirm the environment and package before running a query.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-gotchas-modeling
|
|
3
3
|
description: Common Malloy modeling mistakes and how to avoid them. Read BEFORE writing source definitions, dimensions, measures, or joins. Covers reserved words, NULL checks, date functions, type casts, field management (extend except/accept/rename vs include public/internal/private), and query-based source gotchas.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-gotchas-queries
|
|
3
3
|
description: Common Malloy query and view mistakes. Read BEFORE writing views, queries, or notebooks. Covers chart constraints, aggregate filters, joined field aliasing, method syntax, and time truncation vs extraction.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-gotchas-rendering
|
|
3
3
|
description: Common Malloy renderer annotation mistakes. Read BEFORE adding chart annotations, formatting tags, or building dashboards. Covers tag syntax, scale rules, sparkline setup, and big_value patterns.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-html-data-app-embedding
|
|
3
3
|
description: Embed an in-package HTML data app into a host page or another application, including auto-sizing and auth. Read when embedding a Publisher page via Publisher.embed.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-html-data-app-runtime
|
|
3
3
|
description: Write the JavaScript that drives an in-package HTML data app, calling Publisher.query, building queries from filter state, and handling results and errors. Read before writing the page's data code.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-html-data-apps
|
|
3
3
|
description: Build or modify an in-package HTML data app for a Malloy Publisher package (a public/ directory the package serves). Use when the user wants a hand-authored HTML dashboard or web page backed by a package's Malloy models, with no build step.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-lookml-review
|
|
3
3
|
description: Analyze LookML files as prior art for Malloy modeling. Used during Step 1 (DISCOVER) when .lkml files are present. Coordinates reference files that extract business logic, relationships, and curation decisions. Works with or without a database connection.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-materialization
|
|
3
3
|
description: Add and debug Malloy Persistence materializations in a package - persist an expensive source so queries read a pre-built table. Read this whenever the user wants to materialize a source, add a persist annotation, speed up a slow source, or asks why a persist source isn't building.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-materialization-tuning
|
|
3
3
|
description: Optimize a package's Malloy Persistence materializations for cost and performance using the malloy-pub CLI and the materialization history. Recommend what to persist, what to stop persisting, and how to schedule/scope it. Use when the user asks to make a package cheaper or faster, tune persistence, decide what to materialize, or review persist/schedule choices.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -20,7 +20,7 @@ Assumes the `malloy-pub` CLI is on PATH and points at the server (`--url` or `MA
|
|
|
20
20
|
|
|
21
21
|
Establish what the package persists today and how it is governed.
|
|
22
22
|
|
|
23
|
-
- **Persist sources:** the sources annotated `#@ persist name="…"` in the package's `.malloy` files. Read the models (or `
|
|
23
|
+
- **Persist sources:** the sources annotated `#@ persist name="…"` in the package's `.malloy` files. Read the models (or `get_context` the package) to list them.
|
|
24
24
|
- **Schedule + scope:**
|
|
25
25
|
|
|
26
26
|
```bash
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-model
|
|
3
3
|
description: Build Malloy semantic models with base source and joined source files. Use when creating or modifying .malloy files, user asks to "create a malloy model", "add dimensions", "add measures", "create a source", or any Malloy model authoring task.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-model-as-you-go
|
|
3
3
|
description: After answering a data question, write down what the answer assumed so the next reader can trust the number. A field with a #(doc) in the model when you can edit it, an extend in the notebook when you can only author reports, or a stated assumption plus a Malloy snippet when you can only chat. Use after every answered question that rested on a judgment call, and whenever a question is asked against tables that have no model yet.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<!--
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-modeling
|
|
3
3
|
description: Build semantic models with Malloy for the Malloy Publisher. Read this skill whenever the user asks about modeling data or specifically mentions Malloy.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -15,10 +15,10 @@ SPDX-License-Identifier: MIT
|
|
|
15
15
|
## Pre-Flight Checklist
|
|
16
16
|
|
|
17
17
|
1. **Discover first**: ground yourself before writing ANY code, with the tool that matches what you are modelling.
|
|
18
|
-
- Modelling data **already in a package**: `
|
|
19
|
-
- Modelling **a database with no package yet**: `
|
|
18
|
+
- Modelling data **already in a package**: `get_context` returns that package's sources, views, and fields (with their docs).
|
|
19
|
+
- Modelling **a database with no package yet**: `get_context` has nothing to return, so use `search_database_schema` instead. It walks the connection's schemas and tables, ranks them against a plain-English description, and gives you each table's columns plus the `source:` line to start from. Take those names verbatim into step 5.
|
|
20
20
|
Never guess field names either way.
|
|
21
|
-
2. **Search docs proactively**: call `
|
|
21
|
+
2. **Search docs proactively**: call `search_malloy_docs` BEFORE writing unfamiliar patterns (window functions, query-based sources, pipelines). Don't guess. Malloy syntax is specific and SQL intuition is often wrong.
|
|
22
22
|
3. **Use `skill:malloy-patterns`** to discover available doc topics (YoY, cohorts, rendering, window functions).
|
|
23
23
|
4. **Check diagnostics** after writing: fix the FIRST error first, errors cascade.
|
|
24
24
|
5. **Read the gotcha skills**: `skill:malloy-gotchas-modeling`, `skill:malloy-gotchas-queries`, and `skill:malloy-gotchas-rendering` prevent the most common mistakes.
|
|
@@ -66,7 +66,7 @@ DISCOVER → SCOPE → SOURCES → DEFINITIONS → BUILD BASE → BUILD JOINED
|
|
|
66
66
|
|
|
67
67
|
| Step | Skill | What Happens |
|
|
68
68
|
|------|-------|-------------|
|
|
69
|
-
| 1. Discover | `skill:malloy-discover` | Read the model and data; scan sources, fields, distributions; detect prior art. With no package yet, start from `
|
|
69
|
+
| 1. Discover | `skill:malloy-discover` | Read the model and data; scan sources, fields, distributions; detect prior art. With no package yet, start from `search_database_schema` to find the tables in the connection |
|
|
70
70
|
| 2. Propose Scope | `skill:malloy-scope` | Present findings, user selects focus |
|
|
71
71
|
| 3. Propose Sources | `skill:malloy-define` | Propose source plan, user confirms architecture |
|
|
72
72
|
| 4. Propose Definitions | `skill:malloy-define` | Propose fields per base source, user confirms logic |
|
|
@@ -136,28 +136,28 @@ Ensure the Publisher MCP tools are configured before modeling. No server yet? `s
|
|
|
136
136
|
|
|
137
137
|
| Tool | Purpose |
|
|
138
138
|
|------|---------|
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
139
|
+
| `get_context` | Ground yourself in a package: its sources, views, and fields |
|
|
140
|
+
| `execute_query` | Run ad-hoc queries for validation |
|
|
141
|
+
| `compile_model` | Compile-check a change and get diagnostics back without running a query |
|
|
142
|
+
| `reload_package` | Recompile a package from disk so a saved edit becomes queryable by name |
|
|
143
|
+
| `search_malloy_docs` | Search Malloy docs (call BEFORE unfamiliar patterns) |
|
|
144
|
+
| `search_database_schema` | Find the tables in a database connection by plain-English description, when modelling data that is not in a package yet. Returns each table's columns and the `source:` line to start from. Names and types only: no row value is returned |
|
|
145
145
|
|
|
146
|
-
Never guess field names. Ground yourself with `
|
|
146
|
+
Never guess field names. Ground yourself with `get_context` to see the sources and fields a package defines.
|
|
147
147
|
|
|
148
148
|
### The edit-and-run loop
|
|
149
149
|
|
|
150
150
|
Publisher compiles each configured package at boot and serves that cached model, so a source or view you add afterwards is not queryable by name until you reload the package. The loop is:
|
|
151
151
|
|
|
152
|
-
1. **Validate** the change with `
|
|
152
|
+
1. **Validate** the change with `compile_model`, picking the scope that matches what you are doing:
|
|
153
153
|
- Adding a new definition or query: the default (`scope: "append"`) compiles your text in the model's namespace. Note its diagnostic positions land in the model-plus-your-text concatenation.
|
|
154
154
|
- **Editing an existing definition: `scope: "file"`**, with the whole edited file as `source`. It compiles your text AS the file (append would collide with "Cannot redefine"), and diagnostics land at the true line numbers of your text.
|
|
155
155
|
- Before saving a change other files import: `scope: "package"` with the edited file as `source` runs reload's worker compiler over every `.malloy` and `.malloynb` file against your edit, so a rename that breaks an importer surfaces now instead of at reload. Each diagnostic carries `model`, the file it points at; files hidden from discovery can appear. If `modelPath` does not exactly match an existing file, a warning says the source was treated as new.
|
|
156
156
|
2. **Save** it to the package's model file.
|
|
157
|
-
3. **Reload** with `
|
|
158
|
-
4. **Run** the new view with `
|
|
157
|
+
3. **Reload** with `reload_package`.
|
|
158
|
+
4. **Run** the new view with `execute_query`.
|
|
159
159
|
|
|
160
|
-
A reload that fails to compile is safe: your files are left alone and the previously compiled model keeps serving, with the compile errors returned to you. Compile first anyway for faster feedback, and a `scope: "package"` dry-run with no `source` uses reload's compiler and file selection (imports across files, every `.malloy` and `.malloynb` file as saved) without touching the served model. Keep the source of truth outside `publisher_data/`, which is not version-controlled and is wiped by a `--init` restart. If these tools are missing, the Publisher you are connected to predates them; fall back to validating with a throwaway `
|
|
160
|
+
A reload that fails to compile is safe: your files are left alone and the previously compiled model keeps serving, with the compile errors returned to you. Compile first anyway for faster feedback, and a `scope: "package"` dry-run with no `source` uses reload's compiler and file selection (imports across files, every `.malloy` and `.malloynb` file as saved) without touching the served model. Keep the source of truth outside `publisher_data/`, which is not version-controlled and is wiped by a `--init` restart. If these tools are missing, the Publisher you are connected to predates them; fall back to validating with a throwaway `execute_query`. An older Publisher that has `compile_model` but rejects `scope` supports only the append behavior.
|
|
161
161
|
|
|
162
162
|
## SQL-to-Malloy Quick Reference
|
|
163
163
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-notebook-chat
|
|
3
3
|
description: Steps to follow when the chat is bound to a notebook or saved report. The notebook's cells are the agent's primary context, answer from it, run its queries, and only reach for get_context when the user asks about something outside it.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-notebooks
|
|
3
3
|
description: Create Malloy notebooks (.malloynb) for interactive dashboards and data stories. Use when user asks to "create a notebook", "make a dashboard notebook", "write a malloynb", "data story", or needs to build reports/visualizations.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-patterns
|
|
3
3
|
description: Index of Malloy documentation topics. Use to discover what's available in search_malloy_docs. Covers language reference (sources, queries, views, fields, aggregates, joins, filters, expressions, functions), common patterns (YoY, cohorts, percent of total), rendering, and experimental features.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-phrase-detection
|
|
3
3
|
description: How to construct search targets for the get_context tool. Covers target-type classification and non-obvious decomposition patterns. Read the tool description for field definitions and the end-to-end workflow.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -10,31 +10,15 @@ SPDX-License-Identifier: MIT
|
|
|
10
10
|
|
|
11
11
|
# Search Target Construction for `get_context`
|
|
12
12
|
|
|
13
|
-
The `get_context` tool description defines each field and
|
|
13
|
+
The `get_context` tool description defines each field and what a call returns. This skill focuses on the parts you won't get right by default: classifying concepts into target types and splitting ambiguous phrases.
|
|
14
14
|
|
|
15
15
|
> **Tool names** are written bare here - `get_context`, `execute_query`, `search_malloy_docs`. The exact prefixed name depends on the host surface; match each against the tools you actually have.
|
|
16
16
|
|
|
17
|
-
**Scope of this skill:** the patterns below
|
|
17
|
+
**Scope of this skill:** the patterns below build `dimension` / `measure` / `view` targets. Phrasing for `source` targets is covered at the end.
|
|
18
18
|
|
|
19
19
|
**A note on matching:** `get_context` searches over the model (sources, fields, views, and their descriptions), not the distinct categorical *values* stored in the data. To find which literal values a categorical dimension holds, target the dimension, then query its distinct values with `execute_query` (see the patterns below).
|
|
20
20
|
|
|
21
|
-
## Authoring `search_text` for
|
|
22
|
-
|
|
23
|
-
Aim for **3-8 words that name the entity and its business process**. Don't include filter values, time ranges, or aggregations: those belong in phase-2 targets.
|
|
24
|
-
|
|
25
|
-
| Too vague | Over-specific (phase-2-ish) | Good |
|
|
26
|
-
|---|---|---|
|
|
27
|
-
| `"orders"` | `"total order revenue by customer last year"` | `"customer order history and line items"` |
|
|
28
|
-
| `"customer data"` | `"premium subscribers who churned in NYC"` | `"subscriber accounts and churn"` |
|
|
29
|
-
| `"metrics"` | `"monthly revenue variance by account"` | `"sales pipeline and revenue forecasts"` |
|
|
30
|
-
|
|
31
|
-
Heuristics:
|
|
32
|
-
|
|
33
|
-
1. **Translate, don't echo.** "How did sales go last month?" becomes `"sales order revenue"`, not `"sales last month"`.
|
|
34
|
-
2. **Differentiate by data shape or business process, not by the user's industry, brand, or product category.** Prefer `"order fulfillment and shipping"` over `"ecommerce data"` when multiple commerce-ish packages exist. Do NOT add words like `"eyewear"`, `"subscription box"`, `"Acme Corp"`, or the user's specific vertical/brand. Source summaries describe data structure, not the customer's vertical, so those words add noise and can hurt matching.
|
|
35
|
-
3. **Retry with alternative phrasings** if the right source isn't in the results before concluding it's missing.
|
|
36
|
-
|
|
37
|
-
## Authoring `search_text` for entity targets (phase 2)
|
|
21
|
+
## Authoring `search_text` for entity targets
|
|
38
22
|
|
|
39
23
|
Write `search_text` as a brief semantic **description** of what you're looking for, not an echo of the user's word. This applies even when you already know the entity name from a prior result: still describe it, don't just repeat the name.
|
|
40
24
|
|
|
@@ -48,7 +32,7 @@ One target per concept is enough: the tool handles phrasing variants internally.
|
|
|
48
32
|
- "total revenue" becomes `"the total revenue or sales amount"`
|
|
49
33
|
- **`view`**: pre-built analysis. Include one whenever the question sounds like a canned report (summary, breakdown, top-N, trend).
|
|
50
34
|
- "sales summary" becomes `"a summary of sales metrics"`
|
|
51
|
-
- **`source`**: data domain
|
|
35
|
+
- **`source`**: data domain, for a question that names a subject area rather than fields (phrasing below).
|
|
52
36
|
|
|
53
37
|
**Resolving categorical values (no value-search target in v1).** When the user names a literal value like "premium" or "New York City", target the *dimension* it lives on (`"the subscription tier"`, `"the city where the subscriber lives"`). Then confirm the exact stored string by querying that dimension's distinct values with `execute_query` before you filter on it. The data may store `"Premium"`, `"PREMIUM"`, `"NYC"`, or `"New York"`, and only the data tells you which.
|
|
54
38
|
|
|
@@ -64,11 +48,11 @@ These are the rules you won't apply correctly by default:
|
|
|
64
48
|
6. **"Top N" without a named measure, add a ranking measure.** "top 6 products" becomes a measure for the ranking concept (`"the performance metric for a product"`) plus a dimension for the entity. If the measure is explicit ("top products by total sales"), use it directly and skip the generic ranking measure.
|
|
65
49
|
7. **Multiple values for one concept, one dimension target.** Several values ("premium and basic") still map to a single dimension target for the parent field; enumerate the exact stored values with `execute_query`.
|
|
66
50
|
|
|
67
|
-
## Worked example
|
|
51
|
+
## Worked example
|
|
68
52
|
|
|
69
53
|
**User:** "Customer churn in NYC over the last year for premium and basic subscribers"
|
|
70
54
|
|
|
71
|
-
|
|
55
|
+
The targets for this question:
|
|
72
56
|
|
|
73
57
|
| target_type | search_text |
|
|
74
58
|
|---|---|
|
|
@@ -78,4 +62,22 @@ After source discovery surfaces a `subscriptions` source, the drill-down targets
|
|
|
78
62
|
| `dimension` | `"the tier of the subscription"` |
|
|
79
63
|
| `view` | `"subscriber churn or retention analysis"` |
|
|
80
64
|
|
|
81
|
-
Key moves: time ("last year") becomes a dimension on the cancellation date; "NYC" and "premium/basic subscribers" do not get their own value targets, they resolve to the city and tier dimensions.
|
|
65
|
+
Key moves: time ("last year") becomes a dimension on the cancellation date; "NYC" and "premium/basic subscribers" do not get their own value targets, they resolve to the city and tier dimensions. One `view` target is included to surface any canned churn analysis.
|
|
66
|
+
|
|
67
|
+
The response returns the source these fields live on (here `subscriptions`) with the matched fields on its card. Then run `execute_query` to read the city and tier dimensions' distinct values and confirm the exact strings to filter on ("New York City" vs "NYC", "premium" vs "Premium").
|
|
68
|
+
|
|
69
|
+
## Authoring `search_text` for `source` targets
|
|
70
|
+
|
|
71
|
+
Aim for **3-8 words that name the entity and its business process**. Don't include filter values, time ranges, or aggregations: those belong in entity targets.
|
|
72
|
+
|
|
73
|
+
| Too vague | Over-specific (entity-shaped) | Good |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `"orders"` | `"total order revenue by customer last year"` | `"customer order history and line items"` |
|
|
76
|
+
| `"customer data"` | `"premium subscribers who churned in NYC"` | `"subscriber accounts and churn"` |
|
|
77
|
+
| `"metrics"` | `"monthly revenue variance by account"` | `"sales pipeline and revenue forecasts"` |
|
|
78
|
+
|
|
79
|
+
Heuristics:
|
|
80
|
+
|
|
81
|
+
1. **Translate, don't echo.** "How did sales go last month?" becomes `"sales order revenue"`, not `"sales last month"`.
|
|
82
|
+
2. **Differentiate by data shape or business process, not by the user's industry, brand, or product category.** Prefer `"order fulfillment and shipping"` over `"ecommerce data"` when multiple commerce-ish packages exist. Do NOT add words like `"eyewear"`, `"subscription box"`, `"Acme Corp"`, or the user's specific vertical/brand. Source summaries describe data structure, not the customer's vertical, so those words add noise and can hurt matching.
|
|
83
|
+
3. **Retry with alternative phrasings** if the right source isn't in the results before concluding it's missing.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-publish
|
|
3
3
|
description: Package Malloy models for serving by Malloy Publisher. Use when user asks to "publish", "package", "deploy", or wants to share models with others.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -77,7 +77,7 @@ Two optional fields opt the package into curation:
|
|
|
77
77
|
|
|
78
78
|
**Why curate here:** declaring `explores` routes agents to the well-documented curated sources instead of raw tables, and `queryableSources: "declared"` keeps them from reaching the hidden sources by name. The two axes compose: list a file in `explores` for its models to be discoverable, and `export` a source within that file for it to be a landing point.
|
|
79
79
|
|
|
80
|
-
> **Not access control.** `queryableSources` gates the query surface (the query endpoints, REST and MCP alike), not compile and not raw file retrieval by exact path: `/compile` and `
|
|
80
|
+
> **Not access control.** `queryableSources` gates the query surface (the query endpoints, REST and MCP alike), not compile and not raw file retrieval by exact path: `/compile` and `compile_model` are deliberately exempt, because compile is the authoring loop and the boundary is discovery curation. It doesn't restrict *who* may query, only *what* is queryable by name. Queryable sources are the union of every `explores`-listed file's `export {}` closure, whichever listed model path a query addresses them through. To gate access by caller-supplied identity/role, use `#(authorize)` on the source, see `skill:malloy-model` § Access Control and `docs/authorize.md`. Discovery curation and `#(authorize)` are independent layers.
|
|
81
81
|
|
|
82
82
|
The manifest also carries a `scope` field (`"package"` | `"version"`, default `"package"`) controlling whether persisted/materialized artifacts are shared across published versions or owned by a single version, and a `materialization` field configuring that persistence policy (a cron `schedule` or a `freshness` window). Both are unrelated to discovery curation; there is no per-source `sharing` or `schedule` field, that was retired in favor of the single package-level `scope` and `materialization`.
|
|
83
83
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-queries
|
|
3
3
|
description: Malloy query patterns, syntax rules, and chart annotation reference. Consult before writing or debugging any query. Covers dates, aggregates vs dimensions, join paths, filters, string matching, and common error patterns.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-review
|
|
3
3
|
description: Malloy semantic-model code review. Invoke when the user asks to review, audit, or critique a `.malloy` file, a folder of Malloy models, or a GitHub PR that touches Malloy. Enforces project modeling standards and emits a navigable review file.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: malloy-scope
|
|
3
3
|
description: Present discovery findings and propose an analytical scope before modeling. Use after inspecting a package's model and data, to classify tables and recommend an analytical focus the user can pick from.
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.16
|
|
5
5
|
---
|
|
6
6
|
<!--
|
|
7
7
|
Copyright (c) Credible Data Inc.
|