@malloy-publisher/server 0.9.1 → 0.9.3

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.
Files changed (36) hide show
  1. package/README.docker.md +14 -0
  2. package/dist/app/api-doc.yaml +414 -98
  3. package/dist/app/assets/EnvironmentPage-uo3igcP9.js +1 -0
  4. package/dist/app/assets/{HomePage-D3MvQaZn.js → HomePage-0OQVchl4.js} +1 -1
  5. package/dist/app/assets/MainPage-D4SOACdm.js +1 -0
  6. package/dist/app/assets/ModelPage-B5CpdEDl.js +2 -0
  7. package/dist/app/assets/PackagePage-BzUfTQKy.js +1 -0
  8. package/dist/app/assets/RenderedResult-DwB0-9Yx.es-1MzhmBXH.js +141 -0
  9. package/dist/app/assets/{RouteError-BQnzPJvb.js → RouteError-BXcrPjvD.js} +1 -1
  10. package/dist/app/assets/ThemeEditorPage-FpYg5NPt.js +1 -0
  11. package/dist/app/assets/{ToggleButtonGroup-CJT2JKTC.js → ToggleButtonGroup-Vkkjsbxx.js} +1 -1
  12. package/dist/app/assets/documentRoutes-BWHzvbNO.js +1 -0
  13. package/dist/app/assets/index-BZEvIUf-.js +484 -0
  14. package/dist/app/assets/index-CprgMbE_.js +1 -0
  15. package/dist/app/assets/{index-ufFZR_K-.js → index-DFvJYp4Q.js} +7 -7
  16. package/dist/app/assets/index-NVPzfbUZ.js +1317 -0
  17. package/dist/app/assets/{index-ireHUsv_.js → index-sKcoT1e_.js} +422 -427
  18. package/dist/app/assets/index.es-D2Ts8adM.js +195 -0
  19. package/dist/app/index.html +1 -1
  20. package/dist/package_load_worker.mjs +801 -80
  21. package/dist/server.mjs +21707 -17510
  22. package/package.json +15 -15
  23. package/dist/app/assets/EnvironmentPage-UMS7Py4Q.js +0 -1
  24. package/dist/app/assets/LightMode-e1lNBfpL.js +0 -1
  25. package/dist/app/assets/MainPage-B0ozqtQO.js +0 -2
  26. package/dist/app/assets/ModelPage-lQj4Axqu.js +0 -2
  27. package/dist/app/assets/PackagePage-BT0YKNKU.js +0 -1
  28. package/dist/app/assets/RenderedResult-BRgIgxWh.es-DiE7kPNX.js +0 -136
  29. package/dist/app/assets/ThemeEditorPage-D6t7w9Js.js +0 -1
  30. package/dist/app/assets/index-ByieDZlo.js +0 -23
  31. package/dist/app/assets/index-CCNqF0-G.js +0 -1
  32. package/dist/app/assets/index-CKmZ4HG7.js +0 -1322
  33. package/dist/app/assets/index-CdExa3Pk.js +0 -1
  34. package/dist/app/assets/index-TiWjmdoW.js +0 -450
  35. package/dist/app/assets/index.es-iUV0gCYk.js +0 -111
  36. package/dist/sshcrypto-cqb52edz.node +0 -0
@@ -7,7 +7,7 @@ info:
7
7
  description: |
8
8
  The Malloy Publisher - Semantic Model Serving API provides access to Malloy packages and everything they contain.
9
9
  A Malloy package is a directory with a `publisher.json` manifest at its root, holding Malloy models (`.malloy` files),
10
- notebooks (`.malloynb` files and `.malloy` files under `notebooks/`), embedded data (`.parquet`, `.csv`, and `.xlsx` files), and optionally an HTML data app
10
+ notebooks (`.malloynb` files and tagged `.malloy` files that are notebooks), embedded data (`.parquet`, `.csv`, and `.xlsx` files), and optionally an HTML data app
11
11
  under `public/`.
12
12
 
13
13
  ## Key Features
@@ -1574,8 +1574,9 @@ paths:
1574
1574
  On a package with a surface (a root `index.malloy`, or a legacy `explores`), only the
1575
1575
  files on that surface are listed, unless `includeHiddenFilesAndSources` is true. With it, every
1576
1576
  model file is listed, and `isHidden` marks the ones the package hides. Dashboard files
1577
- are listed by the dashboards route either way. Served notebooks (`.malloy` files under
1578
- `notebooks/` that carry an `## artifact` note) are not models here, with or without a
1577
+ are listed by the dashboards route either way. Served notebooks (a `.malloy` at the top of
1578
+ `notebooks/` or `dashboards/` whose model-level `## artifact` tag says `kind=notebook`, or
1579
+ names no `kind` and sits under `notebooks/`) are not models here, with or without a
1579
1580
  surface; they are listed by list-notebooks.
1580
1581
  parameters:
1581
1582
  - name: environmentName
@@ -1631,14 +1632,15 @@ paths:
1631
1632
  On a package with a surface (a root `index.malloy`, or a legacy `explores`), a file off
1632
1633
  that surface answers 404 with the same message a query to it gets, unless
1633
1634
  `includeHiddenFilesAndSources` is true. With it, the file is returned with its `sourceText`, whatever
1634
- sources the text names. Dashboard files and served notebooks (`notebooks/*.malloy` with
1635
- an `## artifact` note) are always returned. A package with no surface, or with
1635
+ sources the text names. Dashboard files and served notebooks (a `.malloy` at the top of
1636
+ `notebooks/` or `dashboards/` whose model-level `## artifact` tag says `kind=notebook`, or
1637
+ names no `kind` and sits under `notebooks/`) are always returned. A package with no surface, or with
1636
1638
  `queryableSources: "all"`, returns every file. For a file it returns, `modelDef.contents` and `modelDef.exports`,
1637
1639
  `modelInfo`, `sources` and `sourceInfos` are limited to the names the file publishes, so
1638
1640
  the surface file does not carry the hidden sources it imports. A join to a hidden source
1639
1641
  keeps only its name and the names and types of its fields. `sourceText` is left out
1640
- when the text names a source the file does not publish; the text of a dashboard is
1641
- always returned.
1642
+ when the text names a source the file does not publish, unless
1643
+ `includeHiddenFilesAndSources` is true; the text of a dashboard is always returned.
1642
1644
  parameters:
1643
1645
  - name: environmentName
1644
1646
  in: path
@@ -1686,12 +1688,15 @@ paths:
1686
1688
  tags:
1687
1689
  - models
1688
1690
  operationId: update-model-source
1689
- summary: Write a dashboard file into the package
1691
+ summary: Write a dashboard or notebook file into the package
1690
1692
  description: |
1691
- Writes the Malloy text of a dashboard file — `dashboards/<slug>.malloy`,
1692
- the only paths this endpoint accepts — into the package, and reloads the
1693
- package in place so the dashboard is served from the new text. This is
1694
- the dashboard builder's save.
1693
+ Writes the Malloy text of a dashboard file — `dashboards/<slug>.malloy` —
1694
+ or a notebook file — `notebooks/<slug>.malloy`, which must carry an
1695
+ `## artifact` tag (an untagged file there is a shared include and is
1696
+ refused with 400, and so is a write over an existing file that is
1697
+ not a notebook) — the only paths this endpoint accepts,
1698
+ into the package, and reloads the package in place so it is served from
1699
+ the new text. This is the dashboard and notebook builder's save.
1695
1700
 
1696
1701
  The text is compiled first, as the file, and refused with its problems
1697
1702
  when it does not compile; nothing is written. The write is atomic (a
@@ -1700,16 +1705,30 @@ paths:
1700
1705
  a new file removed) and the package reloaded again, so a save never
1701
1706
  leaves the package serving less than it did.
1702
1707
 
1703
- `expectedHash` is the SHA-256 (hex) of the text the caller opened, as
1704
- `GET …/models/{path}` returned it in `sourceText`. When the file on disk
1705
- no longer hashes to it, the write is refused with 409 and nothing is
1708
+ `expectedHash` is the SHA-256 (hex) of the file's text as the caller
1709
+ opened it, as `GET …/models/{path}` returned it in `sourceText`. On a
1710
+ package with a surface, that GET withholds `sourceText` only when the
1711
+ text names a source the file does not publish, and returns it anyway
1712
+ with `includeHiddenFilesAndSources=true`. When the file on disk no
1713
+ longer hashes to it, the write is refused with 409 and nothing is
1706
1714
  merged: the caller re-opens and reapplies its change. Omit it to CREATE
1707
- the file: a file that already exists is then refused with 409 too, so an
1708
- unconditional overwrite is not something a caller can ask for by leaving
1709
- a field out. The check, the write, the reload and the restore all happen
1710
- under one hold of the package lock, so two saves racing on one file
1711
- cannot both pass the check, and a rollback cannot revert the other
1712
- writer's text instead of its own.
1715
+ the file: a file that already exists is then refused with 409 too, so
1716
+ an unconditional overwrite is not something a caller can ask for by
1717
+ leaving a field out. A notebook path over an existing file the package
1718
+ does not serve as a notebook answers 400 instead, with or without a
1719
+ hash, because that check comes before the hash. The check, the write,
1720
+ the reload and the restore all happen under one hold of the package
1721
+ lock, so two saves racing on one file cannot both pass the check, and a
1722
+ rollback cannot revert the other writer's text instead of its own.
1723
+
1724
+ A dashboard whose name (the file's basename) another file already holds
1725
+ is refused with 409 before anything is written, since the name is its
1726
+ URL and its `# drill` target. A `dashboards/` file whose text has no
1727
+ `# artifact` or `## artifact` tag (an `artifact` property anywhere on a
1728
+ tag line, outside a string) is refused with 400 before anything is
1729
+ written; a tag only inside a block comment passes that check but the
1730
+ compiled model carries none, so it is rolled back and answers 500. A
1731
+ tagged dashboard with no tiles saves but is not served until it has one.
1713
1732
 
1714
1733
  A create answers 201 and an update 200; `created` in the body says the
1715
1734
  same thing.
@@ -1732,7 +1751,7 @@ paths:
1732
1751
  type: string
1733
1752
  - name: path
1734
1753
  in: path
1735
- description: The dashboard file, `dashboards/<slug>.malloy`
1754
+ description: The file, `dashboards/<slug>.malloy` or `notebooks/<slug>.malloy`
1736
1755
  required: true
1737
1756
  schema:
1738
1757
  $ref: "#/components/schemas/PathPattern"
@@ -1771,8 +1790,9 @@ paths:
1771
1790
  $ref: "#/components/responses/NotFound"
1772
1791
  "409":
1773
1792
  description:
1774
- The file changed since the caller opened it, or already exists and
1775
- no `expectedHash` was sent
1793
+ The file changed since the caller opened it, already exists and
1794
+ no `expectedHash` was sent, or is a dashboard whose name another
1795
+ file already holds
1776
1796
  content:
1777
1797
  application/json:
1778
1798
  schema:
@@ -1864,6 +1884,33 @@ paths:
1864
1884
  access to all sources, imports, and queries defined in the model.
1865
1885
  Relative imports resolve correctly against sibling model files.
1866
1886
  Returns compilation status and any problems (errors or warnings) found.
1887
+
1888
+ When the submitted source (scope `append`) carries a model-level
1889
+ `## artifact` tag, it is read as a document and the response gains a
1890
+ `document`: the cells and manifest the same text would serve once saved,
1891
+ read from the submitted text alone so the model's own `run:` statements
1892
+ and `##` notes never mix in. The compile runs nothing, including a
1893
+ control's `suggest` query. A cell or tile whose source the caller may
1894
+ not read is not compiled at all and comes back `restricted` with no
1895
+ diagnostic; the rest of the document compiles. A tile expression that
1896
+ uses a construct `append` refuses (a data root of its own, such as
1897
+ `duckdb.table(...)`) is refused with 400, and a tile that does not parse
1898
+ is reported as a `tile-does-not-compile` problem. Submitted text that is a document (it carries the tag, at scope `append`) and writes a render tag turning a value
1899
+ into a URL (`# image`, `# link`), or HTML in a `# label`, is refused with 400
1900
+ before anything compiles, for a field, view or query alike, because other
1901
+ viewers run it; plain `append` text without the tag, and a model file,
1902
+ keep the tags they define themselves. The same refusal covers an annotation that
1903
+ reads `@env.` (in a `##` note too), one the tag parser rejects or that exceeds 8,192 characters,
1904
+ text that frees a column (`except:`, `rename:`) and declares one of the same name
1905
+ in the same extend chain, and one with over 1,000 annotations or 64 KB of them.
1906
+ This removes the author-written paths only: the renderer's other
1907
+ value-to-HTML sinks are not covered by it. A cell that names a source
1908
+ that is both gated and hidden from the caller answers 404 for the whole
1909
+ request, as it does without a document. In a document, problem positions
1910
+ are lines of the submitted text, problems carry no `model` tag, and
1911
+ `includeSql` returns no `sql`. A tag that names no `kind` is a dashboard
1912
+ when it lists `tiles` or carries a `dashboard { … }` grid tag, and a
1913
+ notebook otherwise, since submitted text has no folder to take a kind from.
1867
1914
  parameters:
1868
1915
  - name: environmentName
1869
1916
  in: path
@@ -1918,10 +1965,12 @@ paths:
1918
1965
  operationId: list-dashboards
1919
1966
  summary: List package dashboards
1920
1967
  description: |
1921
- Lists the dashboards in the specified package — every `.malloy` file in
1922
- the package's `dashboards/` directory that carries an `# artifact` (or
1923
- model-level `## artifact`) annotation. A file in that directory with no
1924
- artifact tag is a shared include and is not listed, whether or not it
1968
+ Lists the dashboards in the specified package — every tagged `.malloy`
1969
+ file at the top of `dashboards/` or `notebooks/` carrying an
1970
+ `# artifact` (or model-level `## artifact`) annotation whose `kind` is
1971
+ `dashboard`, or names none under `dashboards/`. A `kind=notebook` file is
1972
+ listed as a notebook instead, whichever folder it sits in. A file with
1973
+ no artifact tag is a shared include and is not listed, whether or not it
1925
1974
  compiles.
1926
1975
 
1927
1976
  A tagged dashboard that failed to compile is listed carrying its
@@ -2055,8 +2104,9 @@ paths:
2055
2104
  summary: List package notebooks
2056
2105
  description: |
2057
2106
  Retrieves a list of all Malloy notebooks within the specified package: every
2058
- `.malloynb` file, and every `.malloy` file directly under `notebooks/` that has a
2059
- model-level `## artifact` note. Each notebook entry includes the relative path,
2107
+ `.malloynb` file, and every `.malloy` file at the top of `notebooks/` or `dashboards/`
2108
+ whose model-level `## artifact` tag says `kind=notebook` (or names no `kind` and sits
2109
+ under `notebooks/`). Each notebook entry includes the relative path,
2060
2110
  package name, title, description, and any compilation or reading error. This endpoint
2061
2111
  is useful for discovering available notebooks and checking their status.
2062
2112
  parameters:
@@ -2107,8 +2157,9 @@ paths:
2107
2157
  description: |
2108
2158
  Retrieves a Malloy notebook with its raw cell contents (markdown and code).
2109
2159
  Cell execution should be done separately via the execute-notebook-cell endpoint.
2110
- A served `notebooks/*.malloy` (one with an `## artifact` note) answers here as well as a
2111
- `.malloynb`.
2160
+ A served notebook (a `.malloy` at the top of `notebooks/` or `dashboards/` whose
2161
+ model-level `## artifact` tag says `kind=notebook`, or names no `kind` and sits under
2162
+ `notebooks/`) answers here as well as a `.malloynb`.
2112
2163
  On a package with a surface, the response shows only the sources the notebook may read.
2113
2164
  parameters:
2114
2165
  - name: environmentName
@@ -2160,8 +2211,9 @@ paths:
2160
2211
  description: |
2161
2212
  Executes a specific cell in a Malloy notebook by index. For code cells, this compiles
2162
2213
  and runs the Malloy code, returning query results and any new sources defined.
2163
- For markdown cells, this simply returns the cell content. A served `notebooks/*.malloy`
2164
- answers here as well as a `.malloynb`.
2214
+ For markdown cells, this simply returns the cell content. A served notebook
2215
+ (tagged `kind=notebook`, or untagged-kind under `notebooks/`) answers here as well as a
2216
+ `.malloynb`.
2165
2217
 
2166
2218
  On a package with a surface (a root `index.malloy`, or a legacy `explores`) with
2167
2219
  `queryableSources` left at `"declared"`, a code cell may read only sources the surface
@@ -3048,6 +3100,60 @@ components:
3048
3100
  type: string
3049
3101
  dark:
3050
3102
  type: string
3103
+ border:
3104
+ type: object
3105
+ description: Hairline color for table gridlines and row rules,
3106
+ per mode.
3107
+ properties:
3108
+ light:
3109
+ type: string
3110
+ dark:
3111
+ type: string
3112
+ cardBorder:
3113
+ type: object
3114
+ description: Edge color of a dashboard card and of a pinned table
3115
+ header row, per mode. A step stronger than `border`, so a
3116
+ card reads as a card on a page whose ground and tile share
3117
+ one colour.
3118
+ properties:
3119
+ light:
3120
+ type: string
3121
+ dark:
3122
+ type: string
3123
+ axis:
3124
+ type: object
3125
+ description: Color of chart axis domain and tick lines, per mode.
3126
+ properties:
3127
+ light:
3128
+ type: string
3129
+ dark:
3130
+ type: string
3131
+ gridline:
3132
+ type: object
3133
+ description: Color of chart gridlines, per mode.
3134
+ properties:
3135
+ light:
3136
+ type: string
3137
+ dark:
3138
+ type: string
3139
+ chartText:
3140
+ type: object
3141
+ description: Color of chart text (axis labels and titles, legend,
3142
+ chart and header titles), per mode.
3143
+ properties:
3144
+ light:
3145
+ type: string
3146
+ dark:
3147
+ type: string
3148
+ value:
3149
+ type: object
3150
+ description: Color of the big-value (KPI) number in a dashboard
3151
+ tile, per mode.
3152
+ properties:
3153
+ light:
3154
+ type: string
3155
+ dark:
3156
+ type: string
3051
3157
  font:
3052
3158
  type: object
3053
3159
  description:
@@ -3655,75 +3761,173 @@ components:
3655
3761
  description: >-
3656
3762
  Server-computed, read-only: the state of this package's semantic
3657
3763
  discovery index, which is what `get_context` ranks against
3658
- when an embedding provider is configured. Absent when the server
3659
- has no provider, because there is no index to describe.
3764
+ when an embedding provider is configured. `status: lexical` when
3765
+ the server has no provider, because there is no index to describe.
3660
3766
 
3661
3767
  PackageEmbeddingIndex:
3662
3768
  type: object
3663
3769
  readOnly: true
3664
3770
  description: >-
3665
- State of a package's semantic discovery index. Poll `status` until
3666
- `ready` to know retrieval is warm - before this, that state existed
3667
- only as a server log line, so anything waiting on a warm index had to
3668
- scrape logs. Send the package one `get_context` question first, then
3669
- poll: only a question starts the sync, and a restart forgets which
3670
- syncs completed, so after every restart each package reads `indexing`
3671
- until it is asked something. Polling before asking waits forever.
3771
+ State of a package's semantic discovery index. The server builds the
3772
+ index in the background when the package loads (and reloads), one
3773
+ package at a time across the whole server, saving each batch of vectors
3774
+ as it goes. Poll `status` until `ready` to know retrieval is warm.
3775
+ While `indexing`, `embeddedRows` rises toward `totalRows`. A restart
3776
+ starts every package's index again, but vectors already stored for
3777
+ unchanged content are reused, so a restart over an unchanged package
3778
+ embeds nothing new.
3672
3779
  Every count is scoped to the embedding model currently configured, so
3673
- rows left behind by an earlier model are never counted. Read `status` for readiness and the counts for
3674
- coverage: they answer different questions, and only `status` tracks
3675
- what the search path will do. The first read after a package loads or
3676
- reloads builds the package's entity index and its content
3677
- fingerprint, which is work a metadata read would not otherwise do.
3678
- After that a read is two row counts and never waits on a sync, so
3679
- polling is cheap.
3780
+ rows left behind by an earlier model are never counted. Read `status`
3781
+ for readiness and the counts for progress: they answer different
3782
+ questions, and only `status` tracks what the search path will do. The
3783
+ first read after a package loads builds the package's entity index and
3784
+ its content fingerprint, which is work a metadata read would not
3785
+ otherwise do. After that a read is two row counts and never waits on a
3786
+ sync, so polling is cheap.
3680
3787
  properties:
3681
3788
  status:
3682
3789
  type: string
3683
3790
  enum:
3791
+ - lexical
3684
3792
  - indexing
3685
3793
  - ready
3794
+ - error
3686
3795
  - cooldown
3687
3796
  - too-many-entities
3688
3797
  description: >-
3689
- `ready` = the index is warm, so the next `get_context` question
3690
- about this package is ranked semantically rather than lexically.
3691
- (It is a statement about the index, not a promise about the next
3692
- response: a question whose own query embedding fails still falls
3693
- back, reporting `retrieval_reason: provider-error`.) It is decided
3694
- by the same completed sync the search path gates on, not by
3695
- whether cached rows happen to cover the current entity names.
3696
- Those two differ exactly where it matters - the rows outlive a
3697
- restart and a reload, so a coverage test called an index warm
3698
- while the next question was still answered lexically.
3699
- `indexing` = no completed sync covers the package's current
3700
- content under the current model, so retrieval answers lexically
3701
- meanwhile. A reload whose files did not change stays `ready`,
3702
- because the vectors still describe that content. Four things move
3703
- a package to `indexing`: an edit, a new package, a changed
3704
- `EMBEDDING_MODEL`, and a server restart - the sync is recorded in
3705
- memory, so a restart reports `indexing` until the first question
3706
- re-establishes it, even though the vectors are still on disk. It
3707
- clears when a `get_context` question triggers a sync, which is
3708
- what builds the index; a package nothing has ever queried does not
3709
- warm on its own.
3710
- `cooldown` = the provider failed recently, so the semantic path is
3711
- short-circuited for a window. `too-many-entities` = the package has
3712
- more entities than the embedding cap, so it stays lexical
3713
- permanently rather than transiently. The same vocabulary as
3714
- `get_context`'s `retrieval_reason`, deliberately.
3798
+ `lexical` = no embedding provider is configured, so `get_context`
3799
+ ranks by words only. That is a mode of the server, not a failure.
3800
+ `indexing` = vectors for this package are being built or are
3801
+ queued behind another package's; while this lasts and a provider is
3802
+ configured, `get_context` answers a search with an "indexing"
3803
+ message and no results, not a lexical ranking. `ready` = the index
3804
+ is warm, so the next `get_context` question about this package is
3805
+ ranked semantically. (It is a statement about the index, not a
3806
+ promise about the next response: a question whose own query
3807
+ embedding fails returns an error naming the provider failure.) It
3808
+ is decided by the same completed sync the search path gates on, not
3809
+ by whether cached rows happen to cover the current entity names.
3810
+ `error` = the index cannot serve now; `reason` and `lastError`
3811
+ say why. A changed `EMBEDDING_MODEL` or a changed package moves a
3812
+ `ready` package back to `indexing`.
3813
+ `cooldown` and `too-many-entities` are deprecated. Earlier versions
3814
+ reported them as the `status` itself; they are now the `reason` of
3815
+ an `error`. They stay in this list so a client generated from an
3816
+ earlier spec still understands every value, and they are never sent.
3817
+ reason:
3818
+ type: string
3819
+ enum:
3820
+ - cooldown
3821
+ - too-many-entities
3822
+ description: >-
3823
+ Present when `status` is `error` for one of two reasons that earlier
3824
+ versions reported as the `status` itself. `cooldown` = the provider
3825
+ failed (after retries) and the package is waiting out a window
3826
+ before the next try; `lastError.retryAt` says when. `too-many-entities`
3827
+ = the package has more entities than the embedding cap, which no
3828
+ retry fixes. Absent for other errors, such as an invalid embedding
3829
+ configuration, which `lastError.message` describes.
3830
+ stage:
3831
+ type: string
3832
+ enum:
3833
+ - keyphrase
3834
+ - source_summary
3835
+ description: >-
3836
+ The sync stage that failed, when `status` is `error` because of one.
3837
+ `keyphrase` = the LLM could not write the package's keyphrases
3838
+ (after retries), so nothing was embedded; `source_summary` = the
3839
+ LLM could not write the package's source summaries (after retries),
3840
+ so nothing was embedded. `lastError.message` has the reason.
3841
+ Absent when the embedding call itself failed.
3842
+ keyphraseProgress:
3843
+ type: object
3844
+ description: >-
3845
+ Present only when keyphrases are on: the package asks for them
3846
+ (`retrieval.keyphrases` is `auto` or `always`, the default being
3847
+ `auto`) and `retrieval.llm` is configured. Counts the entities whose
3848
+ keyphrase comes from the LLM; an entity with a short description
3849
+ uses it as its keyphrase and is not counted.
3850
+ properties:
3851
+ done:
3852
+ type: integer
3853
+ description: Entities that need an LLM keyphrase and have one stored.
3854
+ total:
3855
+ type: integer
3856
+ description: Entities that need an LLM keyphrase.
3857
+ capped:
3858
+ type: boolean
3859
+ description: >-
3860
+ True when `retrieval.llm.maxCallsPerSync` stopped the step before
3861
+ every entity had one. The status can be `ready` with `done` below
3862
+ `total`; the next sync (a restart) continues from there.
3863
+ sourceSummaryProgress:
3864
+ type: object
3865
+ description: >-
3866
+ Present only when source summaries are on: the package does not turn
3867
+ them off (`retrieval.sourceSummary.enabled` is `auto` or `true`, the
3868
+ default being `auto`) and `retrieval.llm` is configured. Counts the
3869
+ sources that get an LLM-written summary. A source with no fields is
3870
+ not counted.
3871
+ properties:
3872
+ done:
3873
+ type: integer
3874
+ description: Sources that get a summary and have a current one stored.
3875
+ total:
3876
+ type: integer
3877
+ description: Sources that get a summary.
3878
+ capped:
3879
+ type: boolean
3880
+ description: >-
3881
+ True when `retrieval.llm.maxCallsPerSync` stopped the step before
3882
+ every source had one. The status can be `ready` with `done` below
3883
+ `total`; the next sync (a restart) continues from there.
3884
+ lastError:
3885
+ type: object
3886
+ description: Present when `status` is `error`.
3887
+ properties:
3888
+ message:
3889
+ type: string
3890
+ description: >-
3891
+ What went wrong, with the fix where there is one. Never
3892
+ contains the provider's URL or the API key; the full error
3893
+ is in the server log.
3894
+ retryAt:
3895
+ type: string
3896
+ format: date-time
3897
+ description: >-
3898
+ The earliest time a retry can start. Nothing retries on a
3899
+ timer: the first `get_context` question about this package
3900
+ after this time starts the retry, so a package nobody asks
3901
+ about stays in `error` and a status poll alone never sees it
3902
+ recover. Absent when no retry can start (for example
3903
+ `too-many-entities`).
3904
+ startedAt:
3905
+ type: string
3906
+ format: date-time
3907
+ description: >-
3908
+ When the sync now running began. Absent when none is running,
3909
+ including while this package waits its turn in the queue.
3715
3910
  embeddedRows:
3716
3911
  type: integer
3717
3912
  description: >-
3718
3913
  Cached vectors for this package under the current embedding model.
3719
- An entity contributes one row for its name plus one per chunk of
3720
- its documentation, so this exceeds `totalEntities` on a documented
3721
- model and is not a count of entities. Scoped by model only, not by
3914
+ With the default `retrieval.representation` of `single` an entity
3915
+ contributes one row, so this equals `totalEntities` once indexed.
3916
+ With `facets` an entity contributes one row for its name plus one
3917
+ per chunk of its documentation, so this exceeds `totalEntities` on
3918
+ a documented model and is not a count of entities. A keyphrase row
3919
+ is an extra on top of those and is not counted here or in
3920
+ `totalRows`. Scoped by model only, not by
3722
3921
  vector length, so it counts what is cached rather than what a
3723
3922
  search could read today: after a change to `EMBEDDING_DIMENSIONS`
3724
3923
  that no question has probed yet, rows of the old length are still
3725
3924
  counted here until the next search discards them. `status` is
3726
3925
  already `indexing` in that window.
3926
+ totalRows:
3927
+ type: integer
3928
+ description: >-
3929
+ Rows the package wants cached: the denominator for `embeddedRows`.
3930
+ `embeddedRows` of `totalRows` is the progress of a first index.
3727
3931
  totalEntities:
3728
3932
  type: integer
3729
3933
  description: Entities the package currently exposes to retrieval.
@@ -3881,8 +4085,8 @@ components:
3881
4085
  Dashboard:
3882
4086
  type: object
3883
4087
  description: |
3884
- A dashboard within a Malloy package: a self-contained `.malloy` file in
3885
- the package's `dashboards/` directory carrying an `# artifact` (or
4088
+ A dashboard within a Malloy package: a self-contained `.malloy` file at
4089
+ the top of the package's `dashboards/` or `notebooks/` directory carrying an `# artifact` (or
3886
4090
  model-level `## artifact`) annotation. The list entry; see
3887
4091
  DashboardManifest for the detail a viewer needs to render one.
3888
4092
  properties:
@@ -3960,6 +4164,16 @@ components:
3960
4164
  error:
3961
4165
  type: string
3962
4166
  description: Error message if the dashboard file failed to compile
4167
+ kind:
4168
+ type: string
4169
+ enum: [dashboard, notebook]
4170
+ description: >-
4171
+ What the document is, from the `kind` property of its artifact tag
4172
+ (the folder only decides the default when the tag says nothing). A
4173
+ `notebook` is laid out as one column: `dashboardColumns` is 1
4174
+ whatever the file says. Always `dashboard` on
4175
+ `GET …/dashboards/{dashboardName}`; a notebook's manifest is the
4176
+ `dashboard` field of `GET …/notebooks/{path}`.
3963
4177
  query:
3964
4178
  type: string
3965
4179
  description: >-
@@ -4001,7 +4215,8 @@ components:
4001
4215
  type: array
4002
4216
  description: |
4003
4217
  The control row. Normally one entry per given the dashboard runs
4004
- with: the union over `tiles`, or what `query` references when the tag
4218
+ with: the union over `tiles` (less a given only a source's gate
4219
+ reads, which a host injects rather than a viewer sets), or what `query` references when the tag
4005
4220
  sits on a query, and which the entry file
4006
4221
  can bind. The row widens to
4007
4222
  every given the entry file surfaces when any tile is one discovery
@@ -4031,28 +4246,58 @@ components:
4031
4246
 
4032
4247
  DashboardTile:
4033
4248
  type: object
4034
- description: One tile of a dashboard
4249
+ description: >-
4250
+ One tile of a dashboard. A `query` tile (the default) runs a query; a
4251
+ `text` tile shows markdown and runs nothing, so a caller that runs a
4252
+ dashboard's tiles skips the ones with `kind` `text`.
4035
4253
  properties:
4254
+ kind:
4255
+ type: string
4256
+ enum: [query, text]
4257
+ description: >-
4258
+ `query` runs `query` through the model query endpoint; `text` shows
4259
+ `markdown`. Absent means `query`.
4260
+ name:
4261
+ type: string
4262
+ description: >-
4263
+ A text tile's name: the bare word in `tiles=[…]` and on its
4264
+ `##|(markdown) name` block. Absent on a query tile.
4265
+ markdown:
4266
+ type: string
4267
+ description: >-
4268
+ A text tile's body, the text of its `##|(markdown) name` block
4269
+ without the opener. Empty when the file has no such block. Absent on
4270
+ a query tile.
4036
4271
  query:
4037
4272
  type: string
4038
4273
  description: >-
4039
- The run expression exactly as written in `tiles=[…]`, for example
4274
+ Absent on a text tile. The run expression exactly as written in `tiles=[…]`, for example
4040
4275
  "orders -> by_month". An EXPRESSION rather than a name, so it goes in
4041
4276
  the `query` field of a `POST …/models/{path}/query` body, prefixed
4042
4277
  with `run:`. Sending it in `queryName`, the field
4043
4278
  `DashboardManifest.query` takes, is rejected.
4279
+ restricted:
4280
+ type: boolean
4281
+ description: >-
4282
+ Set on a tile of a compiled document (`CompileResult.document`) whose
4283
+ source the caller may not read. The tile carries its `query` and
4284
+ nothing derived from the source: no `givenNames`, no layout tags.
4044
4285
  givenNames:
4045
4286
  type: array
4046
4287
  items:
4047
4288
  type: string
4048
4289
  description: |
4049
- Names of the givens this tile references. This is a scoping hint,
4050
- not a binding constraint: it tells a caller which tiles a changed
4051
- control actually needs to re-run. Running a tile with the
4052
- dashboard's whole control row also works, because an unreferenced
4053
- given is ignored. Absent when the tile expression is not one
4054
- discovery can resolve, a refinement or a multi-stage pipeline for
4055
- instance, in which case send the whole control row. One such tile
4290
+ Names of the givens this tile's compiled query reads: through its
4291
+ view, its source's `where:`, a joined source's `where:`, a
4292
+ dimension or measure it uses, and its source's `#(authorize)` and
4293
+ `#(access_filter)` gates. A control not listed does not change the
4294
+ tile, which is what a viewer's "Doesn't respond to" chip says. It
4295
+ also tells a caller which tiles a changed control needs to re-run;
4296
+ running a tile with the dashboard's whole control row also works,
4297
+ because an unreferenced given is ignored. Absent when discovery
4298
+ could not resolve the tile (its expression neither compiles nor is
4299
+ a plain `source -> view` or named query the static walk reads), in
4300
+ which case send the whole control row. One such tile
4056
4301
  widens `DashboardManifest.givens` to every given the entry file
4057
4302
  surfaces, rather than the union over the resolvable tiles, so that
4058
4303
  the row actually contains the givens that tile filters by.
@@ -4071,13 +4316,15 @@ components:
4071
4316
  type: integer
4072
4317
  description: >-
4073
4318
  Grid columns this tile spans, from a `# colspan=N` on the view or
4074
- query it names. Clamped to `dashboardColumns` at render time. Absent
4319
+ query it names, or from `colspan=N` on a text tile's entry in
4320
+ `tiles=[…]`. Clamped to `dashboardColumns` at render time. Absent
4075
4321
  means one column.
4076
4322
  break:
4077
4323
  type: boolean
4078
4324
  description: >-
4079
4325
  Start a new grid row at this tile, from a `# break` on the view or
4080
- query it names. Named for the tag, so every per-tile field on this
4326
+ query it names, or from `break` on a text tile's entry in
4327
+ `tiles=[…]`. Named for the tag, so every per-tile field on this
4081
4328
  schema is spelled the way an author writes it. A generated client
4082
4329
  escapes the attribute where the word is reserved (the Python client
4083
4330
  exposes `break_`) while the wire key stays `break`.
@@ -4143,8 +4390,9 @@ components:
4143
4390
  enum: ["malloynb", "malloy"]
4144
4391
  description:
4145
4392
  The file format the notebook is written in. `malloynb` is the
4146
- cell-separated format; `malloy` is a `.malloy` file under
4147
- `notebooks/` with a model-level `## artifact` note, whose cells are
4393
+ cell-separated format; `malloy` is a `.malloy` at the top of `notebooks/` or
4394
+ `dashboards/` whose model-level `## artifact` tag says `kind=notebook` (or names no
4395
+ `kind` and sits under `notebooks/`), whose cells are
4148
4396
  its statements and its floating `(markdown)` notes in file order.
4149
4397
  malloyVersion:
4150
4398
  type: string
@@ -4157,6 +4405,16 @@ components:
4157
4405
  description: Array of notebook cells containing raw markdown and code content
4158
4406
  items:
4159
4407
  $ref: "#/components/schemas/NotebookCell"
4408
+ dashboard:
4409
+ allOf:
4410
+ - $ref: "#/components/schemas/DashboardManifest"
4411
+ description: >-
4412
+ The tile layout of a notebook written as one (`## artifact {
4413
+ kind=notebook tiles=[…] }`), in the shape a dashboard has, with
4414
+ `kind` `notebook` and one column. Absent on a notebook written as
4415
+ cells. Its tiles run through the model query endpoint at
4416
+ `modelPath`; `notebookCells` carries the same content as cells for
4417
+ readers that do not draw a layout.
4160
4418
  annotations:
4161
4419
  type: array
4162
4420
  description:
@@ -4249,7 +4507,8 @@ components:
4249
4507
  server-side warning) when the file cannot be read, so a compiled
4250
4508
  model is never withheld for want of its text; and omitted when the
4251
4509
  file text names a source it does not publish, on a package with a
4252
- surface. A dashboard's text is always returned.
4510
+ surface, unless `includeHiddenFilesAndSources` is true. A
4511
+ dashboard's text is always returned.
4253
4512
 
4254
4513
  View:
4255
4514
  type: object
@@ -4351,6 +4610,13 @@ components:
4351
4610
  description: Annotations attached to the given declaration
4352
4611
  items:
4353
4612
  type: string
4613
+ secure:
4614
+ type: boolean
4615
+ description: >-
4616
+ True when the declaration carries `#(secure)`: its value is the
4617
+ host's to set. The builder withholds its control only when it edits
4618
+ a document held as text; a saved dashboard or notebook renders it
4619
+ as before. Absent otherwise.
4354
4620
  default:
4355
4621
  type: string
4356
4622
  description: The given's default value as a Malloy source literal
@@ -4690,6 +4956,12 @@ components:
4690
4956
  maxItems: 2
4691
4957
  items:
4692
4958
  type: integer
4959
+ restricted:
4960
+ type: boolean
4961
+ description: >-
4962
+ Set on a cell of a compiled document (`CompileResult.document`) whose
4963
+ source the caller may not read. It was not compiled, so nothing else
4964
+ is known about what it reads.
4693
4965
  codeLine:
4694
4966
  type: integer
4695
4967
  description:
@@ -5986,6 +6258,16 @@ components:
5986
6258
  and a model that does not exist is a 400 that deliberately says only
5987
6259
  that it could not be loaded. An invalid scope value is rejected with
5988
6260
  a 400 naming the valid set.
6261
+
6262
+ "append" text that carries a model-level `## artifact` tag is a
6263
+ document, which other viewers run, and is also refused with a 400
6264
+ for `# image`, `# link`, markup in a `# label`, `@env.` in an
6265
+ annotation, an annotation the tag parser rejects or that exceeds
6266
+ 8,192 characters, `except:` or `rename:` followed by a declaration
6267
+ of the same name in the same extend chain, and more than 1,000
6268
+ annotations or 64 KB of them. Plain "append" text without that tag
6269
+ keeps those tags; a model file defines them itself, and its edit is
6270
+ checked at "file".
5989
6271
  includeSql:
5990
6272
  type: boolean
5991
6273
  default: false
@@ -5998,7 +6280,7 @@ components:
5998
6280
 
5999
6281
  ModelSourceWriteRequest:
6000
6282
  type: object
6001
- description: The text to write into a dashboard file
6283
+ description: The text to write into a dashboard or notebook file
6002
6284
  required:
6003
6285
  - source
6004
6286
  properties:
@@ -6014,7 +6296,7 @@ components:
6014
6296
 
6015
6297
  ModelSourceWriteResult:
6016
6298
  type: object
6017
- description: What a dashboard write left in the package
6299
+ description: What a dashboard or notebook write left in the package
6018
6300
  required:
6019
6301
  - path
6020
6302
  - contentHash
@@ -6052,6 +6334,40 @@ components:
6052
6334
  description:
6053
6335
  Generated SQL for the compiled query. Only present when includeSql
6054
6336
  is true and compilation succeeds with a runnable query.
6337
+ document:
6338
+ $ref: "#/components/schemas/CompiledDocument"
6339
+
6340
+ CompiledDocument:
6341
+ type: object
6342
+ description: >-
6343
+ The document a compiled source describes, in the shape the same text
6344
+ serves once saved. Present only when the source carries a model-level
6345
+ `## artifact` tag and compiled far enough to read.
6346
+ properties:
6347
+ kind:
6348
+ type: string
6349
+ enum: [dashboard, notebook]
6350
+ description: >-
6351
+ From the tag's `kind`. When it names none, a document that lists
6352
+ `tiles` or carries a `dashboard { … }` grid tag is a dashboard and
6353
+ any other is a notebook: submitted text has no folder to decide.
6354
+ manifest:
6355
+ allOf:
6356
+ - $ref: "#/components/schemas/DashboardManifest"
6357
+ description: >-
6358
+ Shaped like a served dashboard's manifest, with two differences:
6359
+ `path` is absent (the text runs on the model it was compiled on top
6360
+ of, which is the model in the request URL) and `name` is that
6361
+ model's file slug rather than a document name, which the host owns;
6362
+ `title` is the heading.
6363
+ cells:
6364
+ type: array
6365
+ description: >-
6366
+ The file's own cells. A document laid out as tiles lists only its
6367
+ definition cells, as a saved one does; its prose and queries are
6368
+ `manifest.tiles`.
6369
+ items:
6370
+ $ref: "#/components/schemas/NotebookCell"
6055
6371
 
6056
6372
  CompileProblem:
6057
6373
  type: object