@axonity-ai/mcp 0.15.0 → 0.17.0

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.
@@ -1,20 +1,28 @@
1
1
  /**
2
- * Warehouses, the syncs that copy from them, and the numbers read off the
3
- * tables they fill (axonity-mcp#78, the connector half of axonity-flow#1849).
2
+ * Warehouses, and the numbers read off the tables they fill (axonity-mcp#78,
3
+ * the connector half of axonity-flow#1849; reshaped by the semantic model,
4
+ * axonity-mcp#81 / axonity-flow#1881).
4
5
  *
5
6
  * The plain entity verbs — list/read/create/update/delete/restore for a data
6
7
  * source, a table relationship and a dashboard — come from `registerEntityTools`
7
8
  * (see `ENTITIES` in index.ts). What is here is everything that does not fit
8
- * that shape: asking a warehouse something, the syncs that belong to ONE source,
9
- * the measures a dashboard reads, and duplicating a dashboard.
9
+ * that shape: asking a warehouse something, reading the numbers a dashboard
10
+ * shows, and duplicating a dashboard.
10
11
  *
11
- * **Most writes here are administrator-only on the backend**, and a service
12
- * token always resolves as a member. So against today's platform those calls
13
- * answer 403, and `ForbiddenError` says why in words rather than as a generic
14
- * "not allowed" — the tool descriptions say it up front as well, so an agent
15
- * does not spend three calls discovering it. Whether that is the right line is
16
- * the platform's decision, not this connector's: the tools exist so that the
17
- * moment the backend lets a token through, they work.
12
+ * **There are no sync tools any more.** A sync was a separate object beside
13
+ * the table it filled; the semantic model made it the table's own
14
+ * `provenance` (source, query, grain, key, mode, schedule), so a changed query
15
+ * goes through the same approval as a changed column. Filling a table is now
16
+ * `create_data_table` / `update_data_table` with `provenance`, and running it
17
+ * early is `refresh_data_table` (tools/dataTables.ts). A measure is no longer
18
+ * a field on a table either: it is its own versioned entity (`create_measure`
19
+ * and the rest of the generic family).
20
+ *
21
+ * **Who may write.** These routes were administrator-only when they arrived,
22
+ * and a service token always resolves as a member, so every write answered
23
+ * 403. The platform lifted that (axonity-flow#1855): a data source is created
24
+ * like any other object now. `ForbiddenError` still says "administrator only"
25
+ * in words when some other route answers that way.
18
26
  *
19
27
  * **Nothing here holds a credential.** A data source points at a secret by
20
28
  * `secretId`; the key itself is put in the vault by a human (secret writes are
@@ -24,14 +32,7 @@ import { z } from "zod";
24
32
  import { guard, jsonResult } from "./result.js";
25
33
  const SOURCES = "/api/v1/data-sources";
26
34
  const MEASURES = "/api/v1/measures";
27
- /** The sentence every admin-only tool here carries, so it is said once. */
28
- export const ADMIN_ONLY = "\n\nADMINISTRATOR ONLY. The backend lets only a workspace administrator do " +
29
- "this, and a service token always counts as a member — so a 403 \"Only " +
30
- "administrators can perform this action\" means exactly that, not a broken " +
31
- "call and not a missing scope. Do not retry: tell your human, who can do it " +
32
- "in Axonity.";
33
35
  const SOURCE_ID = z.string().describe("The data source's id.");
34
- const SYNC_ID = z.string().describe("The sync's id (from list_data_source_syncs).");
35
36
  export function registerDataSourceTools(server, client) {
36
37
  server.tool("list_data_source_drivers", "Which warehouses can be connected, and what each one needs. Read-only. " +
37
38
  "\n\nREAD THIS BEFORE create_data_source. Each driver lists its " +
@@ -44,23 +45,26 @@ export function registerDataSourceTools(server, client) {
44
45
  "where it is false, use `policy.maxSeconds` instead. `credentialKinds` " +
45
46
  "says which kind of secret the source's `secretId` must point at.", {}, async () => guard(async () => jsonResult(await client.get(`${SOURCES}/drivers`))));
46
47
  server.tool("test_data_source", "Ask the warehouse the cheapest question there is, and report what it " +
47
- "said. Use it right after create_data_source, and whenever a sync or " +
48
- "query fails for a reason that sounds like the connection. " +
48
+ "said. Use it right after create_data_source, and whenever a table's " +
49
+ "fill or a query fails for a reason that sounds like the connection. " +
49
50
  "\n\nA FAILURE IS AN ANSWER, NOT AN ERROR: the response is " +
50
51
  "`{ ok, message, checkedAt }`, and `ok: false` with a message is the " +
51
52
  "warehouse telling you what is wrong (missing credential, wrong project, " +
52
- "no access). Read `message` — the call itself succeeded." +
53
- ADMIN_ONLY, { id: SOURCE_ID }, async ({ id }) => guard(async () => jsonResult(await client.post(`${SOURCES}/${id}/test`))));
53
+ "no access). Read `message` — the call itself succeeded.", { id: SOURCE_ID }, async ({ id }) => guard(async () => jsonResult(await client.post(`${SOURCES}/${id}/test`))));
54
54
  server.tool("read_data_source_schema", "Which tables and columns the warehouse holds. Read-only, and free: it " +
55
55
  "reads the warehouse's own catalogue, not the data. " +
56
56
  "\n\nEach table's `name` is `container.table` — what you write in a " +
57
57
  "query. `containerWord` is what this warehouse calls the container " +
58
58
  "(\"dataset\" on BigQuery, \"schema\" on PostgreSQL). Column types are " +
59
59
  "the warehouse's own names, passed through. Read this before writing a " +
60
- "query or a sync, rather than guessing table names.", { id: SOURCE_ID }, async ({ id }) => guard(async () => jsonResult(await client.get(`${SOURCES}/${id}/schema`))));
60
+ "query or a table's provenance, rather than guessing table names. " +
61
+ "On a source restricted to `policy.allowedDatasets` it reads those " +
62
+ "datasets one by one, so it answers even when the key may not list " +
63
+ "the whole project.", { id: SOURCE_ID }, async ({ id }) => guard(async () => jsonResult(await client.get(`${SOURCES}/${id}/schema`))));
61
64
  server.tool("query_data_source", "Run a READ-ONLY SQL query against the warehouse and get the rows back. " +
62
- "For looking — checking what a table holds, trying the query a sync " +
63
- "will run. To fill a table regularly, use create_data_source_sync. " +
65
+ "For looking — checking what a warehouse table holds, trying the " +
66
+ "query a table's provenance will run. To fill a table regularly, give " +
67
+ "it a `provenance` (create_data_table / update_data_table). " +
64
68
  "\n\nTHE ROWS ARE CAPPED. `truncated: true` means rows were left out: " +
65
69
  "`rowCount` is what came back, `totalRows` is what matched. Never report " +
66
70
  "a count or a total off a truncated answer — aggregate in the SQL " +
@@ -70,8 +74,7 @@ export function registerDataSourceTools(server, client) {
70
74
  "uses `*` where personal columns are configured, would scan more than " +
71
75
  "the source allows) — the reason says what to change. A 502 is the " +
72
76
  "WAREHOUSE refusing or not answering — the query may be fine; do not " +
73
- "rewrite it, check test_data_source." +
74
- ADMIN_ONLY, {
77
+ "rewrite it, check test_data_source.", {
75
78
  id: SOURCE_ID,
76
79
  sql: z
77
80
  .string()
@@ -83,118 +86,67 @@ export function registerDataSourceTools(server, client) {
83
86
  .int()
84
87
  .optional()
85
88
  .describe("How many rows you want back. Clamped by the platform — a bigger " +
86
- "answer belongs in a sync, not in a response."),
89
+ "answer belongs in a table with provenance, not in a response."),
87
90
  }, async ({ id, sql, maxRows }) => guard(async () => jsonResult(await client.post(`${SOURCES}/${id}/query`, {
88
91
  sql,
89
92
  ...(maxRows !== undefined ? { maxRows } : {}),
90
93
  }))));
91
- server.tool("list_data_source_syncs", "The syncs of ONE data source: the queries that keep tables filled from " +
92
- "that warehouse, on a schedule. Read-only. " +
93
- "\n\nEach sync says when it runs next (`nextFireAt`), when it last ran " +
94
- "(`lastRunAt`), how many rows the table held afterwards " +
95
- "(`lastRowCount`), and — when the last attempt wrote nothing — why " +
96
- "(`lastError`). A `lastError` here is the first thing to read when a " +
97
- "dashboard number looks stale.", { id: SOURCE_ID }, async ({ id }) => guard(async () => jsonResult(await client.get(`${SOURCES}/${id}/syncs`))));
98
- server.tool("create_data_source_sync", "Set up a query that fills a table from this warehouse on a schedule. " +
99
- "\n\nThe table must be a DYNAMIC table (create_data_table with " +
100
- "`isDynamic: true`). Its rows then come from here, not from authoring. " +
101
- "Try the SQL with query_data_source first: what one row of its result " +
102
- "means decides what the table can be asked afterwards. " +
103
- "\n\nThe response says when it will first run (`nextFireAt`). To run " +
104
- "it now, follow with run_data_source_sync." +
105
- ADMIN_ONLY, {
106
- id: SOURCE_ID,
107
- name: z.string().describe("What the sync is called."),
108
- description: z.string().optional().describe("What it fills, and why."),
109
- tableId: z
110
- .string()
111
- .describe("The dynamic table the result lands in (a data_table id)."),
112
- sql: z
113
- .string()
114
- .describe("The query whose RESULT is copied into the table. Read-only, in the " +
115
- "warehouse's own dialect."),
116
- mode: z
117
- .enum(["append", "upsert"])
118
- .optional()
119
- .describe("`upsert` (default) replaces rows whose key columns match and adds " +
120
- "the rest. `append` adds everything that came back, every run — " +
121
- "only right when each run returns NEW rows."),
122
- keyColumns: z
123
- .array(z.string())
124
- .optional()
125
- .describe("Which columns identify a row, for `upsert`. Without them an upsert " +
126
- "has nothing to match on."),
127
- cronExpr: z
128
- .string()
129
- .describe('When it runs, as a five-field cron expression, e.g. "0 6 * * *".'),
130
- timezone: z
131
- .string()
132
- .optional()
133
- .describe('The time zone the cron expression is read in. Defaults to "UTC".'),
134
- enabled: z
135
- .boolean()
136
- .optional()
137
- .describe("Whether it runs on its schedule. Defaults to true."),
138
- }, async ({ id, ...fields }) => guard(async () => jsonResult(await client.post(`${SOURCES}/${id}/syncs`, fields))));
139
- server.tool("run_data_source_sync", "Bring a sync's next run forward to now. " +
140
- "\n\nTHIS DOES NOT WAIT FOR THE RESULT. The query can take tens of " +
141
- "seconds, so the platform accepts the request and its scheduler runs " +
142
- "it. The response is the sync with its new `nextFireAt`. To see how it " +
143
- "went, read list_data_source_syncs again after a moment: `lastRunAt`, " +
144
- "`lastRowCount` and `lastError` describe the run." +
145
- ADMIN_ONLY, { id: SOURCE_ID, syncId: SYNC_ID }, async ({ id, syncId }) => guard(async () => jsonResult(await client.post(`${SOURCES}/${id}/syncs/${syncId}/run`))));
146
- server.tool("delete_data_source_sync", "Stop a sync. The rows it already wrote STAY in the table; it simply " +
147
- "stops refreshing them. Recoverable with restore_data_source_sync." +
148
- ADMIN_ONLY, {
149
- id: SOURCE_ID,
150
- syncId: SYNC_ID,
151
- confirm: z
152
- .literal(true)
153
- .describe("Must be true. Acknowledges the table stops being refreshed."),
154
- }, async ({ id, syncId }) => guard(async () => jsonResult(await client.del(`${SOURCES}/${id}/syncs/${syncId}`))));
155
- server.tool("restore_data_source_sync", "Bring a stopped sync back. It comes back SWITCHED OFF on purpose — a " +
156
- "sync is usually stopped because it did the wrong thing — so switching " +
157
- "it on again is a separate, deliberate step in Axonity." +
158
- ADMIN_ONLY, { id: SOURCE_ID, syncId: SYNC_ID }, async ({ id, syncId }) => guard(async () => jsonResult(await client.post(`${SOURCES}/${id}/syncs/${syncId}/restore`))));
159
94
  }
160
95
  /** The period names a measure question accepts. Mirrors `PeriodPreset`. */
161
96
  const PERIODS = "today, this_week, last_week, this_month, last_month, this_quarter, " +
162
97
  "year_to_date, last_30_days, last_12_months, all_time";
163
98
  export function registerMeasureTools(server, client) {
164
- server.tool("read_measure_design", "What can be asked of one dynamic table: its published measures, its " +
165
- "columns and its time axis. Read-only. " +
166
- "\n\nRead this before query_measures or before putting a tile on a " +
167
- "dashboard — a tile names a measure by the id or name this returns. " +
168
- "Measures themselves are DEFINED on the table (update_data_table) and " +
169
- "go live when the table is published; this only reads them.", {
99
+ server.tool("read_measure_design", "What a number over one dynamic table may ask for: its columns and its " +
100
+ "time axis. Read-only. " +
101
+ "\n\nTHE MEASURES ARE NOT HERE. A measure belongs to the model, not " +
102
+ "to one table: list_measures({ tableId }) answers which measures read " +
103
+ "this table, and create_measure defines one. Read this for the column " +
104
+ "names a measure's formula, `splitBy` or `filters` may use — or " +
105
+ "get_measure_formula_spec({ includeWorkspace: true }) for every " +
106
+ "table's columns at once.", {
170
107
  tableId: z.string().describe("The dynamic table's id."),
171
108
  useDraft: z
172
109
  .boolean()
173
110
  .optional()
174
111
  .describe("Read the table's working design instead of its published one — to " +
175
- "preview a measure before publishing. Defaults to false."),
112
+ "preview a change before it is published. Defaults to false."),
176
113
  }, async ({ tableId, useDraft }) => guard(async () => jsonResult(await client.get(`${MEASURES}/tables/${tableId}`, { useDraft }))));
177
114
  server.tool("query_measures", "Compute measures: up to 40 questions in one call, each answered on its " +
178
115
  "own. Read-only. This is where a dashboard's numbers come from. " +
179
116
  "\n\nEach question is " +
180
- "`{ key, tableId, measure, period?, start?, end?, compare?, grain?, " +
117
+ "`{ key, measure, tableId?, period?, start?, end?, compare?, grain?, " +
181
118
  "splitBy?, filters?, limit?, useDraft? }`. `key` is your own label and " +
182
- "comes back on the answer. `period` is one of: " +
119
+ "comes back on the answer. `measure` is the measure's NAME — its " +
120
+ "handle, unique in the workspace (list_measures); `tableId` is " +
121
+ "optional and no longer what finds it. `period` is one of: " +
183
122
  PERIODS +
184
123
  " (default this_month) — or set it to null and send `start`/`end` " +
185
124
  "(YYYY-MM-DD) for a custom range. `compare` is none, previous_period or " +
186
125
  "previous_year. `grain` (none, auto, day, week, month, quarter, year) " +
187
126
  "draws a series. `splitBy` names a column to group by; `limit` (1-50) " +
188
127
  "keeps the largest groups. " +
128
+ "\n\nA MEASURE OVER OTHER MEASURES is computed per group: each of " +
129
+ "its parts is aggregated on its own table, and the formula is applied " +
130
+ "to the results. Its TOTAL is computed again over the whole period, " +
131
+ "never added up from the groups — the total of a margin % is total " +
132
+ "margin over total revenue, not the average of the monthly " +
133
+ "percentages. Report the total you are given; do not sum the series. " +
134
+ "read_measure shows which parts a number is made of. " +
189
135
  "\n\nONE BAD QUESTION DOES NOT FAIL THE CALL: every answer carries " +
190
136
  "`ok`, and `ok: false` comes with an `error` of its own. Check each one. " +
191
137
  "\n\n`freshAsOf` says how old the newest row behind the number is; " +
192
- "`certified: false` means it was computed from a draft. Say so when you " +
138
+ "`certified: false` means it was computed from a draft; `tables` names " +
139
+ "every table the number came from. Say so when you " +
193
140
  "report a number that is either stale or uncertified.", {
194
141
  queries: z
195
142
  .array(z.record(z.unknown()))
196
143
  .describe("The questions, 1 to 40, in the shape described above."),
197
144
  }, async ({ queries }) => guard(async () => jsonResult(await client.post(`${MEASURES}/query`, { queries }))));
145
+ server.tool("list_measure_live_versions", "Which major versions of one measure are PUBLISHED right now, as a list " +
146
+ "of numbers. Read-only. An empty list means it has never been " +
147
+ "published, so every number it gives is a draft preview " +
148
+ "(`certified: false` on query_measures) — request_publish_measure is " +
149
+ "what changes that.", { id: z.string().describe("The measure's id.") }, async ({ id }) => guard(async () => jsonResult(await client.get(`${MEASURES}/${id}/live-versions`))));
198
150
  server.tool("list_measure_rows", "The first rows of a published dynamic table in an order — what a list " +
199
151
  "tile shows (\"the ten biggest orders this month\"). Read-only. " +
200
152
  "\n\n`matched` in the answer is how many rows matched before the limit, " +
@@ -1 +1 @@
1
- {"version":3,"file":"dataSources.js","sourceRoot":"","sources":["../../src/tools/dataSources.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dataSources.js","sourceRoot":"","sources":["../../src/tools/dataSources.ts"],"names":[],"mappings":"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"}
@@ -159,6 +159,17 @@ export function registerDataTableTools(server, client) {
159
159
  // The page envelope is forwarded WHOLE — unwrapping to `items` would
160
160
  // rebuild the silent truncation this tool exists to avoid.
161
161
  jsonResult(await client.get(`${BASE}/${tableId}/rows`, { q, limit, cursor }))));
162
+ server.tool("refresh_data_table", "Fill a table from its source NOW instead of at its next scheduled time. " +
163
+ "Replaces run_data_source_sync: a table's fill is its own `provenance` " +
164
+ "now, not a separate sync. " +
165
+ "\n\nTHIS DOES NOT WAIT FOR THE RESULT. The query can take tens of " +
166
+ "seconds, so the platform brings the table's next fill forward and its " +
167
+ "scheduler runs it. The response is the table, with `fill.nextAt` set " +
168
+ "to now. To see how it went, read_data_table again after a moment: " +
169
+ "`fill.lastAt`, `fill.lastRowCount` and `fill.lastError` describe the " +
170
+ "run. " +
171
+ "\n\nRefused with a 422 when the table has no `provenance` — its rows " +
172
+ "come from a workflow or an author, and there is nothing to run.", { id: z.string().describe("The table's id.") }, async ({ id }) => guard(async () => jsonResult(await client.post(`${BASE}/${id}/refresh`))));
162
173
  server.tool("list_data_table_tools", "Which tools this table yields, and which of them a RUN can actually " +
163
174
  "reach. Read-only. " +
164
175
  "\n\nA published table mints its own CRUD tools, so giving an agent " +
@@ -1 +1 @@
1
- {"version":3,"file":"dataTables.js","sourceRoot":"","sources":["../../src/tools/dataTables.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dataTables.js","sourceRoot":"","sources":["../../src/tools/dataTables.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * A measure is one formula (axonity-mcp#83, the connector half of phase 1 of
3
+ * axonity-flow#1908).
4
+ *
5
+ * A measure used to be one aggregation over one table, or a division of two
6
+ * parts. It is now ONE expression over the model — `[net_revenue] -
7
+ * [variable_costs]`, `divide([cm1], [net_revenue])` — stored as a tree of ids
8
+ * and shown as text of names, the two one-to-one.
9
+ *
10
+ * **The words of the formula are not here.** They come from
11
+ * `GET /measures/formula-spec`, which the platform generates from the module
12
+ * that also parses — the same list its editor shows. A copy in this connector
13
+ * would be a second list, and two lists drift: the reason
14
+ * `get_workflow_authoring_spec` exists. `get_measure_formula_spec` forwards it
15
+ * untouched.
16
+ *
17
+ * **Checking is the platform's too.** `validate_measure` forwards to
18
+ * `POST /measures/validate`, the route the editor calls while somebody types,
19
+ * so an agent and a person can never disagree about whether a formula is
20
+ * acceptable. `read_measure` asks that same route to write the stored tree back
21
+ * as text, rather than this connector unparsing it.
22
+ *
23
+ * The one rule held HERE is the shape of a write: a measure is written as
24
+ * `definition.expression`, and the fields from before the formula are refused
25
+ * with `legacy_field`. The platform still accepts them while its own form is
26
+ * replaced; an agent has no such form to keep working, and a measure written
27
+ * the old way today is one that has to be migrated again.
28
+ */
29
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
30
+ import type { AxonityClient } from "../client.js";
31
+ /** The language: every word, operator, grain, limit, code and recipe. */
32
+ export declare const FORMULA_SPEC_ROUTE = "/api/v1/measures/formula-spec";
33
+ /** The vocabulary of THIS workspace: its measures, tables, columns, calendars. */
34
+ export declare const FORMULA_SYMBOLS_ROUTE = "/api/v1/measures/formula-symbols";
35
+ /** Check a formula without saving it. */
36
+ export declare const VALIDATE_ROUTE = "/api/v1/measures/validate";
37
+ /**
38
+ * Refuse a measure write in the shape from before the formula.
39
+ *
40
+ * Throws with `legacy_field` — the platform's own code for it, so an agent
41
+ * that repairs on codes reads the same word from either side. A `definition`
42
+ * without `expression` is refused too: the platform would quietly store it as
43
+ * a `sum`, which is a definition nobody wrote.
44
+ */
45
+ export declare function assertFormulaShape(fields: Record<string, unknown>): void;
46
+ export declare function registerMeasureFormulaTools(server: McpServer, client: AxonityClient): void;
@@ -0,0 +1,239 @@
1
+ /**
2
+ * A measure is one formula (axonity-mcp#83, the connector half of phase 1 of
3
+ * axonity-flow#1908).
4
+ *
5
+ * A measure used to be one aggregation over one table, or a division of two
6
+ * parts. It is now ONE expression over the model — `[net_revenue] -
7
+ * [variable_costs]`, `divide([cm1], [net_revenue])` — stored as a tree of ids
8
+ * and shown as text of names, the two one-to-one.
9
+ *
10
+ * **The words of the formula are not here.** They come from
11
+ * `GET /measures/formula-spec`, which the platform generates from the module
12
+ * that also parses — the same list its editor shows. A copy in this connector
13
+ * would be a second list, and two lists drift: the reason
14
+ * `get_workflow_authoring_spec` exists. `get_measure_formula_spec` forwards it
15
+ * untouched.
16
+ *
17
+ * **Checking is the platform's too.** `validate_measure` forwards to
18
+ * `POST /measures/validate`, the route the editor calls while somebody types,
19
+ * so an agent and a person can never disagree about whether a formula is
20
+ * acceptable. `read_measure` asks that same route to write the stored tree back
21
+ * as text, rather than this connector unparsing it.
22
+ *
23
+ * The one rule held HERE is the shape of a write: a measure is written as
24
+ * `definition.expression`, and the fields from before the formula are refused
25
+ * with `legacy_field`. The platform still accepts them while its own form is
26
+ * replaced; an agent has no such form to keep working, and a measure written
27
+ * the old way today is one that has to be migrated again.
28
+ */
29
+ import { z } from "zod";
30
+ import { guard, jsonResult } from "./result.js";
31
+ const MEASURES = "/api/v1/measures";
32
+ /** The language: every word, operator, grain, limit, code and recipe. */
33
+ export const FORMULA_SPEC_ROUTE = `${MEASURES}/formula-spec`;
34
+ /** The vocabulary of THIS workspace: its measures, tables, columns, calendars. */
35
+ export const FORMULA_SYMBOLS_ROUTE = `${MEASURES}/formula-symbols`;
36
+ /** Check a formula without saving it. */
37
+ export const VALIDATE_ROUTE = `${MEASURES}/validate`;
38
+ /** Top-level fields from before the formula: the measure's "home table". */
39
+ const LEGACY_TOP = ["tableId", "clearTable"];
40
+ /** Fields inside `definition` that the formula replaces. */
41
+ const LEGACY_DEFINITION = ["aggregation", "column", "numerator", "denominator"];
42
+ /** Present in the sense that matters: sent, and not a null that clears nothing. */
43
+ function isSent(value) {
44
+ return value !== undefined && value !== null && value !== false;
45
+ }
46
+ /**
47
+ * Refuse a measure write in the shape from before the formula.
48
+ *
49
+ * Throws with `legacy_field` — the platform's own code for it, so an agent
50
+ * that repairs on codes reads the same word from either side. A `definition`
51
+ * without `expression` is refused too: the platform would quietly store it as
52
+ * a `sum`, which is a definition nobody wrote.
53
+ */
54
+ export function assertFormulaShape(fields) {
55
+ const found = LEGACY_TOP.filter((key) => isSent(fields[key]));
56
+ const definition = fields.definition;
57
+ if (definition !== undefined && definition !== null) {
58
+ if (typeof definition !== "object" || Array.isArray(definition)) {
59
+ throw new Error("`definition` must be an object with an `expression`.");
60
+ }
61
+ const def = definition;
62
+ found.push(...LEGACY_DEFINITION.filter((key) => isSent(def[key])).map((key) => `definition.${key}`));
63
+ if (found.length === 0 && !isSent(def.expression)) {
64
+ throw new Error("legacy_field: `definition` has no `expression`. A measure is one " +
65
+ "formula — send it as `definition.expression`, e.g. " +
66
+ '"sum(orders.amount)" or "[net_revenue] - [variable_costs]". ' +
67
+ "Read get_measure_formula_spec for the words, and check it with " +
68
+ "validate_measure first.");
69
+ }
70
+ }
71
+ if (found.length === 0)
72
+ return;
73
+ throw new Error(`legacy_field: ${found.map((f) => `\`${f}\``).join(", ")} ` +
74
+ `${found.length === 1 ? "is" : "are"} the shape from before the formula. ` +
75
+ "A measure is one `definition.expression` now, and the tables it reads " +
76
+ "follow from it: `sum(orders.amount)` instead of `tableId` + " +
77
+ "`aggregation` + `column`, `divide(sum(a.x), sum(b.y))` instead of a " +
78
+ "`numerator` and a `denominator`, `… where table.column = 'value'` " +
79
+ "for a condition on one part. Remove these fields and write the " +
80
+ "formula — validate_measure checks it before you save.");
81
+ }
82
+ /**
83
+ * The stored tree, written back as text with its leaves, by the platform.
84
+ *
85
+ * Best effort, and said so: a read must not fail because the explanation
86
+ * could not be produced. When it cannot, the measure comes back as stored with
87
+ * a sentence saying why its formula text is missing.
88
+ */
89
+ async function explainFormula(client, measure, useDraftChain) {
90
+ const expression = measure.definition?.expression;
91
+ if (expression === undefined || expression === null) {
92
+ return {
93
+ formula: null,
94
+ formulaNote: "This measure has no formula yet — it is still in the shape from " +
95
+ "before the formula. Write one with update_measure " +
96
+ "(`definition.expression`).",
97
+ };
98
+ }
99
+ try {
100
+ const checked = (await client.post(VALIDATE_ROUTE, {
101
+ expression,
102
+ measureId: typeof measure.id === "string" ? measure.id : undefined,
103
+ quantity: measure.definition?.quantity ?? undefined,
104
+ format: measure.definition?.format ?? undefined,
105
+ useDraftChain,
106
+ }));
107
+ return {
108
+ formula: {
109
+ text: checked.formula,
110
+ tree: expression,
111
+ leaves: checked.leaves ?? [],
112
+ quantity: checked.quantity ?? null,
113
+ problems: checked.problems ?? [],
114
+ chain: useDraftChain ? "drafts" : "published",
115
+ },
116
+ };
117
+ }
118
+ catch (err) {
119
+ return {
120
+ formula: { text: null, tree: expression },
121
+ formulaNote: "The formula text and its leaves could not be read from this deploy " +
122
+ `(\`POST ${VALIDATE_ROUTE}\`: ${err instanceof Error ? err.message : String(err)}). ` +
123
+ "The stored tree is above.",
124
+ };
125
+ }
126
+ }
127
+ export function registerMeasureFormulaTools(server, client) {
128
+ server.tool("get_measure_formula_spec", "The ONLY valid list of words for a measure's formula — read it BEFORE " +
129
+ "create_measure or update_measure, and never write a function, " +
130
+ "operator or grain from memory. Read-only. " +
131
+ "\n\nServed by the platform from the code that parses a formula, so it " +
132
+ "is the same list its formula editor shows: per word its signature, " +
133
+ "what it returns, its quantity rule and an example; the operators, " +
134
+ "grains and limits; every refusal `code` with `when` and `fix`; " +
135
+ "`recipes` for the numbers a management team asks for (a sum over two " +
136
+ "facts, a margin %, a share of the total); and `buildOrder`. A word " +
137
+ "with `available: false` is coming and is refused by name " +
138
+ "(`not_yet_supported`) — do not use it. " +
139
+ "\n\n`includeWorkspace: true` adds THIS workspace's vocabulary as " +
140
+ "`workspace`: its measures (name, label, quantity, status), its tables " +
141
+ "and columns, and which dimensions each table reaches — the names a " +
142
+ "formula may use. The answer is then `{ spec, workspace }`; without " +
143
+ "it, the spec itself.", {
144
+ includeWorkspace: z
145
+ .boolean()
146
+ .optional()
147
+ .describe("Also return this workspace's measures, tables, columns and " +
148
+ "reachable dimensions. Defaults to false."),
149
+ useDraftChain: z
150
+ .boolean()
151
+ .optional()
152
+ .describe("With includeWorkspace: include tables and measures that were never " +
153
+ "published. Defaults to false — a published number reads " +
154
+ "published definitions."),
155
+ }, async ({ includeWorkspace, useDraftChain }) => guard(async () => {
156
+ const spec = await client.get(FORMULA_SPEC_ROUTE);
157
+ if (!includeWorkspace)
158
+ return jsonResult(spec);
159
+ const workspace = await client.get(FORMULA_SYMBOLS_ROUTE, {
160
+ useDraftChain: useDraftChain ?? false,
161
+ });
162
+ return jsonResult({ spec, workspace });
163
+ }));
164
+ server.tool("validate_measure", "Check a measure's formula WITHOUT saving it — call it before every " +
165
+ "create_measure and update_measure. Read-only. The same check the " +
166
+ "platform's editor runs while somebody types. " +
167
+ "\n\nAnswers `{ ok, formula, expression, quantity, leaves, problems }`: " +
168
+ "`formula` is the one spelling of it (names resolved, the brackets " +
169
+ "that apply shown); `expression` the tree that would be stored; " +
170
+ "`quantity` what the number counts, derived; `leaves` every " +
171
+ "aggregation it folds down to — table, aggregation, column, the " +
172
+ "conditions and ignored dimensions on that part, and the measures " +
173
+ "walked to reach it. " +
174
+ "\n\nEach problem has a `code`, a `message` and `where` (an `offset` " +
175
+ "in the text, or a `path` in the tree). `severity: error` blocks " +
176
+ "saving; a warning does not. Repair on the code — " +
177
+ "get_measure_formula_spec lists every one with its `fix` — before you " +
178
+ "ask a person: `parse_error` (the message says what was expected " +
179
+ "where), `unknown_measure` / `unknown_table` / `unknown_column` " +
180
+ "(similar names are suggested), `ambiguous_column` (write " +
181
+ "table.column), `column_kind`, `arity`, `cycle` (the chain is in the " +
182
+ "message), `too_complex` (give a part its own name), " +
183
+ "`quantity_mismatch` (adding euros to dogs, or a format that does not " +
184
+ "fit), `unreachable_dimension` (declare the relationship, or write " +
185
+ "`ignore` to mean the total on purpose), `not_yet_supported`. " +
186
+ "`quantity_generic` is a warning: the migration left the placeholder " +
187
+ "quantity — say what the number counts.", {
188
+ expression: z
189
+ .union([z.string(), z.record(z.unknown())])
190
+ .describe("The formula, as text (`divide([cm1], [net_revenue])`) or as the " +
191
+ "stored tree."),
192
+ measureId: z
193
+ .string()
194
+ .optional()
195
+ .describe("The measure being edited, when there is one — it is what makes a " +
196
+ "reference back to itself a `cycle`."),
197
+ quantity: z
198
+ .string()
199
+ .optional()
200
+ .describe("What the number counts, when you have said (EUR, customers, " +
201
+ "orders). Required on save for a single aggregation."),
202
+ format: z
203
+ .record(z.unknown())
204
+ .optional()
205
+ .describe("How it will be shown, as on the measure's `definition.format` — " +
206
+ "checked against what the number counts."),
207
+ useDraftChain: z
208
+ .boolean()
209
+ .optional()
210
+ .describe("Read the DRAFTS of the measures underneath instead of their " +
211
+ "published versions. Defaults to false, because a published " +
212
+ "number reads published definitions."),
213
+ }, async (body) => guard(async () => jsonResult(await client.post(VALIDATE_ROUTE, body))));
214
+ server.tool("read_measure", "Read one measure by id, including its current draft and version. Read " +
215
+ "before you update — you need the current version. " +
216
+ "\n\nIts formula comes back twice, from the platform: `formula.text` " +
217
+ "with names, as you would write it, and `formula.tree`, the stored " +
218
+ "form with ids. Beside them `formula.leaves` — the aggregations it " +
219
+ "folds down to, each on its own table — `formula.quantity`, and " +
220
+ "`formula.problems`: a measure that rests on a column or measure that " +
221
+ "has since gone says so here. `readsTables` follows from the leaves; " +
222
+ "there is no home table.", {
223
+ id: z.string().describe("The measure's id."),
224
+ useDraftChain: z
225
+ .boolean()
226
+ .optional()
227
+ .describe("Resolve the measures it rests on from their drafts instead of " +
228
+ "their published versions. Defaults to false; set it for a " +
229
+ "measure whose parts were never published, or their names " +
230
+ "cannot be shown."),
231
+ }, async ({ id, useDraftChain }) => guard(async () => {
232
+ const measure = (await client.get(`${MEASURES}/${id}`));
233
+ return jsonResult({
234
+ ...measure,
235
+ ...(await explainFormula(client, measure, useDraftChain ?? false)),
236
+ });
237
+ }));
238
+ }
239
+ //# sourceMappingURL=measureFormula.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measureFormula.js","sourceRoot":"","sources":["../../src/tools/measureFormula.ts"],"names":[],"mappings":"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"}