From ffa1c6cb856817ca9a93039a432a09aa78e41311 Mon Sep 17 00:00:00 2001 From: david <58231312+davseby@users.noreply.github.com> Date: Fri, 11 Sep 2026 19:33:19 +0300 Subject: [PATCH] add titled code block example for proper naming --- server/core/internal/assistant/prompt.go | 3 ++- server/core/internal/assistant/tools/schema.go | 2 +- .../core/internal/assistant/tools/testdata/tool_schemas.golden | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/core/internal/assistant/prompt.go b/server/core/internal/assistant/prompt.go index 1c82b825..88185abe 100644 --- a/server/core/internal/assistant/prompt.go +++ b/server/core/internal/assistant/prompt.go @@ -119,7 +119,7 @@ A split_doc_param_list captures a named, typed parameter table: request bodies, } ], "right": [ - {"type": "titled_code", "attrs": {"title": "Request"}, "text": "POST /api/auth/login\n{\n \"email\": \"...\",\n \"password\": \"...\"\n}"} + {"type": "titled_code", "attrs": {"title": "POST /api/auth/login"}, "text": "{\n \"email\": \"...\",\n \"password\": \"...\"\n}"} ] } @@ -147,6 +147,7 @@ Documents are for humans to read. Make them read well. - The document name is shown above the content, so open with the first real paragraph or section rather than a heading that repeats it. - split_doc draws its own dividers, so leave horizontal_rule out next to it. - For code and titled_code, write language-agnostic pseudo-code or a natural-language sketch unless the document names a stack, and leave language empty rather than guessing one. +- A titled_code title names what the code is. For a request or response that is the method and route, such as POST /v1/assets/{id}/due-date/preview, so the body itself does not repeat it. - Use callout for a constraint, warning or gotcha the reader must not miss; ordinary emphasis belongs in prose. - Keep the outline flat: most documents need two or three sections, and a heading earns its place only when the section under it runs longer than a paragraph or two. diff --git a/server/core/internal/assistant/tools/schema.go b/server/core/internal/assistant/tools/schema.go index b81a3e08..9411054e 100644 --- a/server/core/internal/assistant/tools/schema.go +++ b/server/core/internal/assistant/tools/schema.go @@ -132,7 +132,7 @@ func blockVariant(t block.Type) (map[string]any, bool) { "attrs": map[string]any{ "type": "object", "properties": map[string]any{ - document.AttrTitle: map[string]any{"type": "string", "description": "Plain-text title of the block."}, + document.AttrTitle: map[string]any{"type": "string", "description": "Plain-text label naming what the code is. For an endpoint, the method and route, such as POST /v1/assets/{id}/due-date/preview."}, document.AttrLanguage: map[string]any{"type": "string", "description": "Optional; leave empty rather than guess."}, }, "required": []string{document.AttrTitle}, diff --git a/server/core/internal/assistant/tools/testdata/tool_schemas.golden b/server/core/internal/assistant/tools/testdata/tool_schemas.golden index 4e7758af..600e982f 100644 --- a/server/core/internal/assistant/tools/testdata/tool_schemas.golden +++ b/server/core/internal/assistant/tools/testdata/tool_schemas.golden @@ -1 +1 @@ -{"assign_tag":{"desc":"Put a tag on one branch of a document, so the document is listed under the tag in the sidebar when the branch is its default one. document_id and branch_id name the branch the way the content tools do, and tag_id is the tag's id from list_tags. A tag the branch already carries is left as it is, and a hidden tag can still be assigned. Returns {document_id, branch_id, tag_id}.","has_params_one_of":true,"json_schema":{"properties":{"branch_id":{"description":"The id of the branch the tag goes on or comes off: a document's default_branch_id from list_documents or list_tags, or any id from the branches get_document lists.","type":"string"},"document_id":{"description":"The document id.","type":"string"},"tag_id":{"description":"The tag id, as list_tags or a document's tags report it.","type":"string"}},"required":["document_id","branch_id","tag_id"],"type":"object"},"name":"assign_tag"},"create_document":{"desc":"Create a new document and return {document_id, branch_id}, the branch_id being its default branch. The document starts with a single empty paragraph, so follow up with insert_block calls (position end, that branch_id) in the same turn to fill it. Omit parent_id to create it at the organisation root.","has_params_one_of":true,"json_schema":{"properties":{"icon":{"description":"Iconify identifier, as \"collection:name\". The product's own icons are MingCute fills (e.g. \"mingcute:file-code-fill\"); prefer one so the document matches the rest of the sidebar. Defaults to \"mingcute:document-2-fill\" when empty.","type":"string"},"name":{"description":"Display name for the new document.","type":"string"},"parent_id":{"description":"Optional parent document id. Omit to create at the org root.","type":"string"}},"required":["name"],"type":"object"},"name":"create_document"},"create_hook":{"desc":"Add a freshness hook to one branch of a document and return it as list_hooks would. settings.type is one of scheduled-reminder, github-tracking, url-watcher and container-image-watcher, and the rest of settings is that type's own fields. github-tracking and url-watcher depend on the deployment's GitHub App and changedetection.io integrations, and are refused where those are missing. block_uid anchors the hook to a block; a uid the branch does not hold is refused. A new hook starts at score 100.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"Optional. The uid of a block on the branch to anchor the hook to, from get_document; omit to put the hook on the document as a whole.","type":"string"},"branch_id":{"description":"The id of the branch the hook goes on: a document's default_branch_id from list_documents, or any id from the branches get_document lists.","type":"string"},"document_id":{"description":"The document id.","type":"string"},"settings":{"anyOf":[{"additionalProperties":false,"properties":{"schedule":{"description":"The RFC 3339 timestamp at which the reminder is due.","type":"string"},"type":{"const":"scheduled-reminder"}},"required":["type","schedule"],"title":"scheduled-reminder","type":"object"},{"additionalProperties":false,"properties":{"branch":{"description":"The repository branch to follow.","type":"string"},"paths":{"description":"The repository paths whose changes mark the document stale.","items":{"type":"string"},"minItems":1,"type":"array"},"repository":{"description":"The repository to follow, as owner/name.","type":"string"},"type":{"const":"github-tracking"}},"required":["type","repository","branch","paths"],"title":"github-tracking","type":"object"},{"additionalProperties":false,"properties":{"type":{"const":"url-watcher"},"url":{"description":"The web address to watch for changes.","type":"string"}},"required":["type","url"],"title":"url-watcher","type":"object"},{"additionalProperties":false,"properties":{"image":{"description":"The container image reference to watch for new digests.","type":"string"},"type":{"const":"container-image-watcher"}},"required":["type","image"],"title":"container-image-watcher","type":"object"}],"description":"The hook's type and its settings."}},"required":["document_id","branch_id","settings"],"type":"object"},"name":"create_hook"},"create_tag":{"desc":"Create a tag and return {tag_id}. name is the display name, which has to be unused in the organisation, and color a hex triplet with the leading hash; a malformed colour or a name already in use is refused. The new tag lands last in the sidebar order, so use move_tag to place it, and assign_tag to put it on a document branch.","has_params_one_of":true,"json_schema":{"properties":{"color":{"description":"The tag's colour as a hex triplet with the leading hash, such as \"#22c55e\".","type":"string"},"name":{"description":"Display name for the new tag; unique within the organisation.","type":"string"}},"required":["name","color"],"type":"object"},"name":"create_tag"},"delete_block":{"desc":"Delete one block by uid, including anything nested inside it. Its comments, hooks and files go with it and cannot be restored, so use move_block when the aim is to reorder and update_block_text when the aim is new wording. Returns {deleted: uid}.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"The uid of the block to delete.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"}},"required":["document_id","branch_id","block_uid"],"type":"object"},"name":"delete_block"},"delete_document":{"desc":"Delete a document and every document nested under it. The whole subtree goes and cannot be restored, so check the tree with list_documents first, and use update_document when the aim is to relocate rather than remove. Returns {document_id, deleted}.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id to delete.","type":"string"}},"required":["document_id"],"type":"object"},"name":"delete_document"},"delete_hook":{"desc":"Delete a hook, tearing down whatever it watches outside the document; it cannot be restored, so use reset_hook when the aim is to clear what it flagged rather than stop watching. Returns {hook_id, deleted}.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id.","type":"string"},"hook_id":{"description":"The hook id, as list_hooks reports it.","type":"string"}},"required":["document_id","hook_id"],"type":"object"},"name":"delete_hook"},"delete_tag":{"desc":"Delete a tag. Every document carrying it loses it, on every branch, and the tag cannot be restored; use unassign_tag when the aim is to take it off one document rather than remove it. Returns {tag_id, deleted}.","has_params_one_of":true,"json_schema":{"properties":{"tag_id":{"description":"The id of the tag to delete.","type":"string"}},"required":["tag_id"],"type":"object"},"name":"delete_tag"},"get_document":{"desc":"Read one document on one branch: its name, icon, parent_id, protected flag and updated_at, the branch read and every branch the document has (each with the id a branch_id argument takes), the tags the branch carries as [{id, tagName, color}], followed by one row per block with the block's uid, kind, flattened text, depth, parent_uid and the few attrs that matter for reading (heading level, callout icon, code language, task checked). Use it as the way to read a document before editing it; branch_id is the default_branch_id a listing or search hit carries, or any id from branches. A protected branch can be read but refuses every write, so pick an unprotected branch id from branches to write to. Rows marked has_children hold nested blocks the rows do not list, and read_block returns those when you need them.","has_params_one_of":true,"json_schema":{"properties":{"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The document id.","type":"string"}},"required":["document_id","branch_id"],"type":"object"},"name":"get_document"},"get_prometheus_metadata":{"desc":"List the metrics a Prometheus data source exposes, with each metric's type, help text and unit. Use it to find the metric names to write a PromQL query against instead of guessing them.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"}},"required":["data_source_id"],"type":"object"},"name":"get_prometheus_metadata"},"get_sql_metadata":{"desc":"List the tables and their columns in a PostgreSQL, MariaDB or MySQL data source, plus the default schema. Read it before writing a query so the table and column names are the real ones.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"}},"required":["data_source_id"],"type":"object"},"name":"get_sql_metadata"},"get_sql_query_labels":{"desc":"Run a SQL query limited to one row and return its string columns with an example value each, which are the columns a chart would treat as series labels. Use it to check what a query returns before charting it; it is cheaper than query_sql.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"query":{"description":"The SQL query to probe. $__ macros are expanded as they are for a metric block.","type":"string"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","query"],"type":"object"},"name":"get_sql_query_labels"},"insert_block":{"desc":"Insert one canonical block into a document. position start or end puts it at the document's start or end; before or after puts it beside the block reference_block_uid names, which stays in place. The block has to be legal where it lands: the document root takes every type except titled_code, metric and split_doc_param_list, and a reference inside a split_doc or metric_grid takes only what that container holds. Returns the summary rows of the new block and everything nested in it, uids included, with depth counted from the block itself.","has_params_one_of":true,"json_schema":{"properties":{"block":{"anyOf":[{"additionalProperties":false,"properties":{"children":{"description":"Only when the paragraph is a list or task-list entry: the blocks indented under it, each a paragraph, bullet_list, ordered_list or task_list.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one.","type":"string"},"type":{"const":"paragraph"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"paragraph","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"level":{"description":"The heading level.","enum":[1,2,3],"type":"integer"}},"required":["level"],"type":"object"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one.","type":"string"},"type":{"const":"heading"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"heading","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The blocks it quotes, of any type legal at the document root. Use text or items, not both.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one. Use text or items, not both.","type":"string"},"type":{"const":"blockquote"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"blockquote","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The entries, each a paragraph block. Blocks nested under an entry go in that paragraph's children.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"bullet_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"bullet_list","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The entries, each a paragraph block. Blocks nested under an entry go in that paragraph's children.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"ordered_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"ordered_list","type":"object"},{"additionalProperties":false,"properties":{"task_items":{"description":"The rows, each a checked flag and a paragraph block. Blocks nested under a row go in that paragraph's children.","items":{"properties":{"block":{"type":"object"},"checked":{"type":"boolean"}},"required":["block"],"type":"object"},"minItems":1,"type":"array"},"type":{"const":"task_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","task_items"],"title":"task_list","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"icon":{"description":"Iconify identifier; defaults to lucide:text.","type":"string"}},"type":"object"},"items":{"description":"The blocks it holds, each a paragraph, bullet_list, ordered_list or task_list. Use text or items, not both.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one. Use text or items, not both.","type":"string"},"type":{"const":"callout"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"callout","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"language":{"description":"Optional; leave empty rather than guess.","type":"string"}},"type":"object"},"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"code"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"code","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"language":{"description":"Optional; leave empty rather than guess.","type":"string"},"title":{"description":"Plain-text title of the block.","type":"string"}},"required":["title"],"type":"object"},"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"titled_code"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"titled_code","type":"object"},{"additionalProperties":false,"properties":{"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"mermaid"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"mermaid","type":"object"},{"additionalProperties":false,"properties":{"type":{"const":"horizontal_rule"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"horizontal_rule","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"alt":{"description":"Alternative text.","type":"string"},"src":{"description":"The image address.","type":"string"},"title":{"description":"Caption.","type":"string"},"width":{"description":"Display width in pixels.","type":"integer"}},"required":["src"],"type":"object"},"type":{"const":"image"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"image","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"height":{"description":"Display height in pixels.","type":"integer"},"src":{"description":"The Figma frame address.","type":"string"},"width":{"description":"Display width in pixels.","type":"integer"}},"required":["src"],"type":"object"},"type":{"const":"figma"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"figma","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"description":"The chart configuration: the data source, the queries, the window and the display settings, as the block model describes them. Legal only inside a metric_grid or on a split_doc right side.","properties":{"refreshInterval":{"description":"How often the chart re-queries.","enum":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"type":"string"},"simulationPreset":{"description":"Draws this generated series in place of the query's own result, for a block documenting a metric that has no real data yet. Omit it to chart the query.","enum":["cpu_usage","memory_usage","disk_usage","http_requests","http_latency","error_rate"],"type":"string"},"timeRange":{"description":"The window queried.","enum":["last_5_minutes","last_15_minutes","last_30_minutes","last_1_hour","last_3_hours","last_6_hours","last_12_hours","last_24_hours","last_2_days","last_7_days","last_30_days","last_90_days","last_6_months","last_1_year","last_2_years","last_5_years","today","yesterday","today_so_far","this_week","this_week_so_far","this_month","this_month_so_far","this_year","this_year_so_far","previous_week","previous_month","previous_year"],"type":"string"},"unitType":{"description":"The unit values are read in. With custom, put the label in unitCustom.","enum":["custom","nanoseconds","microseconds","milliseconds","seconds","minutes","hours","days","bytes","kilobytes","megabytes","gigabytes","terabytes","bits","kilobits","megabits","gigabits","terabits","percent0to100","percent0to1"],"type":"string"},"visualizationType":{"description":"The chart kind.","enum":["line_chart","bar_chart","gauge_chart"],"type":"string"},"width":{"description":"The chart's size.","enum":["compact","standard","wide"],"type":"string"}},"type":"object"},"type":{"const":"metric"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"metric","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The metric blocks it holds.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"metric_grid"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"metric_grid","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"inversed":{"description":"Flips the two sides.","type":"boolean"}},"type":"object"},"left":{"description":"The concept side. Must start with a level-1 heading; then paragraphs, lists and callouts; then any split_doc_param_list, which is legal only here.","items":{"type":"object"},"minItems":1,"type":"array"},"right":{"description":"The example side. Holds titled_code, metric or mermaid only, and is the one place titled_code is legal.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"split_doc"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","left","right"],"title":"split_doc","type":"object"},{"additionalProperties":false,"properties":{"header":{"description":"The section header, as plain text.","type":"string"},"params":{"description":"The rows.","items":{"properties":{"description":{"description":"The description, in minimal markdown.","type":"string"},"name":{"description":"The parameter name, as plain text.","type":"string"},"type":{"description":"The parameter type, as plain text.","type":"string"}},"required":["name"],"type":"object"},"minItems":1,"type":"array"},"type":{"const":"split_doc_param_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","header","params"],"title":"split_doc_param_list","type":"object"}],"description":"A canonical block. Its type decides which fields it takes."},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"},"position":{"description":"Where the block lands: before or after the reference block, or at the start or end of the document.","enum":["before","after","start","end"],"type":"string"},"reference_block_uid":{"description":"The uid of the block to insert beside. Required with before and after; leave it out with start and end.","type":"string"}},"required":["document_id","branch_id","position","block"],"type":"object"},"name":"insert_block"},"list_data_sources":{"desc":"List the organisation's data sources. Returns id, name, type (prometheus, postgresql, mariadb, mysql) and connection status. Start here: every other data-source tool takes an id from this list, and the type decides which of them serves it.","has_params_one_of":true,"json_schema":{"properties":{},"type":"object"},"name":"list_data_sources"},"list_documents":{"desc":"List the organisation's documents as a tree of {id, name, default_branch_id, children}; default_branch_id is what get_document and the block tools take as branch_id for the document's default branch. Use it to find a document by name or to see what sits under a parent; use search_documents when you are looking for content rather than a title. Pass parent_id to get only that document's direct children, or omit it for the whole organisation.","has_params_one_of":true,"json_schema":{"properties":{"parent_id":{"description":"Optional. Return only the direct children of this document. Omit for the full tree.","type":"string"}},"type":"object"},"name":"list_documents"},"list_hooks":{"desc":"List the freshness hooks on one branch of a document as [{id, type, block_uid, settings, score, state, created_at, updated_at}]. A hook watches something outside the document and lowers its score as that thing changes or a date approaches; block_uid names the block it is anchored to, or is null for a hook on the document as a whole. Use it to learn the id that update_hook, reset_hook and delete_hook take as hook_id. document_id and branch_id name the branch the way the content tools do.","has_params_one_of":true,"json_schema":{"properties":{"branch_id":{"description":"The id of the branch whose hooks to list: a document's default_branch_id from list_documents, or any id from the branches get_document lists.","type":"string"},"document_id":{"description":"The document id.","type":"string"}},"required":["document_id","branch_id"],"type":"object"},"name":"list_hooks"},"list_prometheus_label_names":{"desc":"List the label names present in a Prometheus data source, optionally only those on the series the matchers select. Pair it with list_prometheus_label_values to build a filtered PromQL query.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"matchers":{"description":"Optional. PromQL series selectors, e.g. [\"up\", \"{job=\\\"api\\\"}\"].","items":{"type":"string"},"type":"array"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id"],"type":"object"},"name":"list_prometheus_label_names"},"list_prometheus_label_values":{"desc":"List the values a label takes in a Prometheus data source, optionally only on the series the matchers select. Use it to discover the concrete label values a query should filter on.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"label":{"description":"The label whose values to list, e.g. \"job\".","type":"string"},"matchers":{"description":"Optional. PromQL series selectors, e.g. [\"up\", \"{job=\\\"api\\\"}\"].","items":{"type":"string"},"type":"array"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","label"],"type":"object"},"name":"list_prometheus_label_values"},"list_prometheus_series":{"desc":"List the series matching a set of selectors in a Prometheus data source, each as its full label set. Use it to see which label combinations a metric actually has before querying it.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"matchers":{"description":"PromQL series selectors, e.g. [\"up\", \"{job=\\\"api\\\"}\"].","items":{"type":"string"},"type":"array"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","matchers"],"type":"object"},"name":"list_prometheus_series"},"list_tags":{"desc":"List the organisation's tags in their sidebar order as [{id, name, color, hidden, documents}], where documents is [{id, name, default_branch_id}] for every document whose default branch carries the tag. Use it to find a tag by name before assigning it, and to learn the id that update_tag, delete_tag, move_tag, assign_tag and unassign_tag take as tag_id. A tag assigned to a non-default branch shows under tags on get_document for that branch but not here. hidden says whether the current user keeps the tag out of their own sidebar; it does not stop the tag being assigned.","has_params_one_of":true,"json_schema":{"properties":{},"type":"object"},"name":"list_tags"},"move_block":{"desc":"Move an existing block before or after another block in the same document. The block keeps its uid, attrs and nested content, so comments, hooks and files attached to it stay attached; deleting it and inserting a copy would lose them. The landing spot has to accept the block's type, by the same rule insert_block applies. Returns the summary rows of the moved block and everything nested in it.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"The uid of the block to move.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"},"position":{"description":"Landing side relative to the reference block.","enum":["before","after"],"type":"string"},"reference_block_uid":{"description":"The uid of the block to move relative to.","type":"string"}},"required":["document_id","branch_id","block_uid","position","reference_block_uid"],"type":"object"},"name":"move_block"},"move_tag":{"desc":"Move a tag to a position in the sidebar order, which is the order list_tags returns. sort_index is the 0-based position the tag should end up at, so 0 puts it first, and a position past the last tag is refused; the other tags keep their relative order. Returns {tag_id, sort_index}.","has_params_one_of":true,"json_schema":{"properties":{"sort_index":{"description":"The 0-based position the tag should end up at among the organisation's tags.","type":"integer"},"tag_id":{"description":"The tag id, as list_tags or a document's tags report it.","type":"string"}},"required":["tag_id","sort_index"],"type":"object"},"name":"move_tag"},"query_prometheus":{"desc":"Run a PromQL range query against a Prometheus data source over the given window. Returns the raw result by default; with chart_type set it instead describes what a metric block would render, which is how to check a query before writing it into a block.","has_params_one_of":true,"json_schema":{"properties":{"chart_type":{"description":"Optional. One of line_chart, bar_chart, gauge_chart. When set, the result describes what the metric block would draw (render status, series count, and each series' labels, point count and endpoints) instead of the raw data. Use it to check a query before putting it in a metric block; omit it when you need the values themselves.","type":"string"},"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"query":{"description":"The PromQL expression to run.","type":"string"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","query"],"type":"object"},"name":"query_prometheus"},"query_sql":{"desc":"Run a read-only query against a PostgreSQL, MariaDB or MySQL data source. Returns columns and rows by default; with chart_type set it instead describes what a metric block would render, which is how to check a query before writing it into a block. $__ macros ($__timeFilter, $__timeGroupAlias and the rest) are expanded against the window.","has_params_one_of":true,"json_schema":{"properties":{"chart_type":{"description":"Optional. One of line_chart, bar_chart, gauge_chart. When set, the result describes what the metric block would draw (render status, series count, and each series' labels, point count and endpoints) instead of the raw data. Use it to check a query before putting it in a metric block; omit it when you need the values themselves.","type":"string"},"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"query":{"description":"The SQL query to run. For a chart, select a time column aliased \"time\" plus one or more numeric columns.","type":"string"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","query"],"type":"object"},"name":"query_sql"},"read_block":{"desc":"Return the full canonical content of one block by uid, including any nested children. Use it only when get_document's rows are not enough: to edit a split_doc, a nested list or a split_doc_param_list, whose inner structure has to be written back in full. Fails when the uid is not in the document.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"The block uid to fetch.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The document id.","type":"string"}},"required":["document_id","branch_id","block_uid"],"type":"object"},"name":"read_block"},"read_tool_output":{"desc":"Retrieve the full output of an earlier tool call that was too large to keep in the conversation. Pass the path shown in the truncation notice.","has_params_one_of":true,"json_schema":{"properties":{"file_path":{"description":"The stored output path from the truncation notice.","type":"string"}},"required":["file_path"],"type":"object"},"name":"read_tool_output"},"replace_block":{"desc":"Replace a block by uid with a new block in the same position. The old block's uid, content and children are all gone unless the new block carries them, so use it to change a block's type or its whole structure. For a wording change use update_block_text, and for an attribute change update_block_attrs; both keep the uid, which comments, hooks and files hang off. Returns the summary rows of the new block and everything nested in it, uids included, with depth counted from the block itself.","has_params_one_of":true,"json_schema":{"properties":{"block":{"anyOf":[{"additionalProperties":false,"properties":{"children":{"description":"Only when the paragraph is a list or task-list entry: the blocks indented under it, each a paragraph, bullet_list, ordered_list or task_list.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one.","type":"string"},"type":{"const":"paragraph"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"paragraph","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"level":{"description":"The heading level.","enum":[1,2,3],"type":"integer"}},"required":["level"],"type":"object"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one.","type":"string"},"type":{"const":"heading"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"heading","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The blocks it quotes, of any type legal at the document root. Use text or items, not both.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one. Use text or items, not both.","type":"string"},"type":{"const":"blockquote"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"blockquote","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The entries, each a paragraph block. Blocks nested under an entry go in that paragraph's children.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"bullet_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"bullet_list","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The entries, each a paragraph block. Blocks nested under an entry go in that paragraph's children.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"ordered_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"ordered_list","type":"object"},{"additionalProperties":false,"properties":{"task_items":{"description":"The rows, each a checked flag and a paragraph block. Blocks nested under a row go in that paragraph's children.","items":{"properties":{"block":{"type":"object"},"checked":{"type":"boolean"}},"required":["block"],"type":"object"},"minItems":1,"type":"array"},"type":{"const":"task_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","task_items"],"title":"task_list","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"icon":{"description":"Iconify identifier; defaults to lucide:text.","type":"string"}},"type":"object"},"items":{"description":"The blocks it holds, each a paragraph, bullet_list, ordered_list or task_list. Use text or items, not both.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one. Use text or items, not both.","type":"string"},"type":{"const":"callout"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"callout","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"language":{"description":"Optional; leave empty rather than guess.","type":"string"}},"type":"object"},"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"code"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"code","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"language":{"description":"Optional; leave empty rather than guess.","type":"string"},"title":{"description":"Plain-text title of the block.","type":"string"}},"required":["title"],"type":"object"},"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"titled_code"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"titled_code","type":"object"},{"additionalProperties":false,"properties":{"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"mermaid"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"mermaid","type":"object"},{"additionalProperties":false,"properties":{"type":{"const":"horizontal_rule"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"horizontal_rule","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"alt":{"description":"Alternative text.","type":"string"},"src":{"description":"The image address.","type":"string"},"title":{"description":"Caption.","type":"string"},"width":{"description":"Display width in pixels.","type":"integer"}},"required":["src"],"type":"object"},"type":{"const":"image"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"image","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"height":{"description":"Display height in pixels.","type":"integer"},"src":{"description":"The Figma frame address.","type":"string"},"width":{"description":"Display width in pixels.","type":"integer"}},"required":["src"],"type":"object"},"type":{"const":"figma"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"figma","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"description":"The chart configuration: the data source, the queries, the window and the display settings, as the block model describes them. Legal only inside a metric_grid or on a split_doc right side.","properties":{"refreshInterval":{"description":"How often the chart re-queries.","enum":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"type":"string"},"simulationPreset":{"description":"Draws this generated series in place of the query's own result, for a block documenting a metric that has no real data yet. Omit it to chart the query.","enum":["cpu_usage","memory_usage","disk_usage","http_requests","http_latency","error_rate"],"type":"string"},"timeRange":{"description":"The window queried.","enum":["last_5_minutes","last_15_minutes","last_30_minutes","last_1_hour","last_3_hours","last_6_hours","last_12_hours","last_24_hours","last_2_days","last_7_days","last_30_days","last_90_days","last_6_months","last_1_year","last_2_years","last_5_years","today","yesterday","today_so_far","this_week","this_week_so_far","this_month","this_month_so_far","this_year","this_year_so_far","previous_week","previous_month","previous_year"],"type":"string"},"unitType":{"description":"The unit values are read in. With custom, put the label in unitCustom.","enum":["custom","nanoseconds","microseconds","milliseconds","seconds","minutes","hours","days","bytes","kilobytes","megabytes","gigabytes","terabytes","bits","kilobits","megabits","gigabits","terabits","percent0to100","percent0to1"],"type":"string"},"visualizationType":{"description":"The chart kind.","enum":["line_chart","bar_chart","gauge_chart"],"type":"string"},"width":{"description":"The chart's size.","enum":["compact","standard","wide"],"type":"string"}},"type":"object"},"type":{"const":"metric"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"metric","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The metric blocks it holds.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"metric_grid"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"metric_grid","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"inversed":{"description":"Flips the two sides.","type":"boolean"}},"type":"object"},"left":{"description":"The concept side. Must start with a level-1 heading; then paragraphs, lists and callouts; then any split_doc_param_list, which is legal only here.","items":{"type":"object"},"minItems":1,"type":"array"},"right":{"description":"The example side. Holds titled_code, metric or mermaid only, and is the one place titled_code is legal.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"split_doc"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","left","right"],"title":"split_doc","type":"object"},{"additionalProperties":false,"properties":{"header":{"description":"The section header, as plain text.","type":"string"},"params":{"description":"The rows.","items":{"properties":{"description":{"description":"The description, in minimal markdown.","type":"string"},"name":{"description":"The parameter name, as plain text.","type":"string"},"type":{"description":"The parameter type, as plain text.","type":"string"}},"required":["name"],"type":"object"},"minItems":1,"type":"array"},"type":{"const":"split_doc_param_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","header","params"],"title":"split_doc_param_list","type":"object"}],"description":"A canonical block. Its type decides which fields it takes."},"block_uid":{"description":"The uid of the block being replaced.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"}},"required":["document_id","branch_id","block_uid","block"],"type":"object"},"name":"replace_block"},"reset_hook":{"desc":"Reset a hook's score to 100 and its state to what a fresh hook has, keeping its settings, and return it as list_hooks would. Use it once the document has been brought up to date with whatever the hook flagged.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id.","type":"string"},"hook_id":{"description":"The hook id, as list_hooks reports it.","type":"string"}},"required":["document_id","hook_id"],"type":"object"},"name":"reset_hook"},"search_documents":{"desc":"Full-text search across every branch of every document in the organisation for blocks whose text matches the query. Returns hits with document_id, document_name, branch_id, branch_name, default (whether that branch is the document's default), block_uid and text; branch_id is what a follow-up get_document or read_block takes. A block a fork copied unchanged is found on every branch that holds it. Use it to find where a topic is discussed or which documents the user might mean; use list_documents when you know the title. A hit names the innermost block holding the text, which may sit below anything get_document lists; read_block resolves it.","has_params_one_of":true,"json_schema":{"properties":{"limit":{"description":"Maximum number of hits to return. Defaults to 20; cap is 50.","type":"integer"},"query":{"description":"The full-text search query (typo-tolerant, matches block text).","type":"string"}},"required":["query"],"type":"object"},"name":"search_documents"},"unassign_tag":{"desc":"Take a tag off one branch of a document; the tag itself stays for other documents, so use delete_tag to remove it everywhere. document_id and branch_id name the branch the way the content tools do, and tag_id is the tag's id from the document's tags on get_document or from list_tags. A tag the branch does not carry is nothing to do, and the call still succeeds. Returns {document_id, branch_id, tag_id}.","has_params_one_of":true,"json_schema":{"properties":{"branch_id":{"description":"The id of the branch the tag goes on or comes off: a document's default_branch_id from list_documents or list_tags, or any id from the branches get_document lists.","type":"string"},"document_id":{"description":"The document id.","type":"string"},"tag_id":{"description":"The tag id, as list_tags or a document's tags report it.","type":"string"}},"required":["document_id","branch_id","tag_id"],"type":"object"},"name":"unassign_tag"},"update_block_attrs":{"desc":"Set or override named attributes on an existing block, such as a heading's level or a callout's icon. Attributes not mentioned are kept and uid cannot change. Values are validated for the block's type, so a level outside 1 to 3 or a metric width other than compact, standard or wide is rejected. Use replace_block when the type itself has to change. Returns the summary rows of the block and everything nested in it, attrs as they now stand.","has_params_one_of":true,"json_schema":{"properties":{"attrs":{"description":"Attribute keys and values to set (e.g. {\"level\": 2}, {\"icon\": \"lucide:warning\"}).","type":"object"},"block_uid":{"description":"The uid of the block whose attrs should be updated.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"}},"required":["document_id","branch_id","block_uid","attrs"],"type":"object"},"name":"update_block_attrs"},"update_block_text":{"desc":"Replace the inline text of one text-bearing block: paragraph, heading, blockquote, code, titled_code, mermaid, or a callout written with text. Type, attrs and uid are kept, so this is the tool for wording changes. Text follows the canonical markdown subset (**bold**, *italic*, _underline_, ~~strike~~, backtick code, [label](url)), and is raw in code, titled_code and mermaid. One block is one paragraph; to add a paragraph, insert a block instead. Returns the block's summary row with the new text.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"The uid of the block whose text should be replaced.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"},"text":{"description":"New inline text in canonical markdown.","type":"string"}},"required":["document_id","branch_id","block_uid","text"],"type":"object"},"name":"update_block_text"},"update_document":{"desc":"Change a document's name, icon or place in the tree, any combination in one call; content is untouched. Give only the fields to change: name is the new display name, icon an Iconify identifier as \"collection:name\" (the product's own icons are MingCute fills, e.g. \"mingcute:rocket-fill\", so prefer one to match the sidebar), and parent_id the new parent, or an empty string for the organisation root. A call with none of the three is refused, and a parent that is the document itself or one of its descendants fails. Returns {document_id} with the fields that changed.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id.","type":"string"},"icon":{"description":"Optional. The new icon identifier; omit to keep the current one.","type":"string"},"name":{"description":"Optional. The new display name; omit to keep the current one.","type":"string"},"parent_id":{"description":"Optional. The new parent document id, or an empty string to move the document to the organisation root; omit to leave it where it is.","type":"string"}},"required":["document_id"],"type":"object"},"name":"update_document"},"update_hook":{"desc":"Replace the settings of a hook and reset its score and state, returning it as list_hooks would. settings.type is one of scheduled-reminder, github-tracking, url-watcher and container-image-watcher, and the rest of settings is that type's own fields. github-tracking and url-watcher depend on the deployment's GitHub App and changedetection.io integrations, and are refused where those are missing. The hook keeps its type, so settings.type is the type list_hooks reports for it; to change the type, delete the hook and create another.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id.","type":"string"},"hook_id":{"description":"The hook id, as list_hooks reports it.","type":"string"},"settings":{"anyOf":[{"additionalProperties":false,"properties":{"schedule":{"description":"The RFC 3339 timestamp at which the reminder is due.","type":"string"},"type":{"const":"scheduled-reminder"}},"required":["type","schedule"],"title":"scheduled-reminder","type":"object"},{"additionalProperties":false,"properties":{"branch":{"description":"The repository branch to follow.","type":"string"},"paths":{"description":"The repository paths whose changes mark the document stale.","items":{"type":"string"},"minItems":1,"type":"array"},"repository":{"description":"The repository to follow, as owner/name.","type":"string"},"type":{"const":"github-tracking"}},"required":["type","repository","branch","paths"],"title":"github-tracking","type":"object"},{"additionalProperties":false,"properties":{"type":{"const":"url-watcher"},"url":{"description":"The web address to watch for changes.","type":"string"}},"required":["type","url"],"title":"url-watcher","type":"object"},{"additionalProperties":false,"properties":{"image":{"description":"The container image reference to watch for new digests.","type":"string"},"type":{"const":"container-image-watcher"}},"required":["type","image"],"title":"container-image-watcher","type":"object"}],"description":"The hook's type and its settings."}},"required":["document_id","hook_id","settings"],"type":"object"},"name":"update_hook"},"update_tag":{"desc":"Rename and/or recolour a tag; give only the fields to change, and the other keeps its value. name is the new display name, which has to be unused in the organisation, and color a hex triplet with the leading hash; a call with neither is refused. Returns {tag_id} with the fields that changed. To change which documents carry the tag use assign_tag and unassign_tag instead.","has_params_one_of":true,"json_schema":{"properties":{"color":{"description":"Optional. The new colour as a hex triplet with the leading hash; omit to keep the current one.","type":"string"},"name":{"description":"Optional. The new display name; omit to keep the current one.","type":"string"},"tag_id":{"description":"The tag id, as list_tags or a document's tags report it.","type":"string"}},"required":["tag_id"],"type":"object"},"name":"update_tag"}} \ No newline at end of file +{"assign_tag":{"desc":"Put a tag on one branch of a document, so the document is listed under the tag in the sidebar when the branch is its default one. document_id and branch_id name the branch the way the content tools do, and tag_id is the tag's id from list_tags. A tag the branch already carries is left as it is, and a hidden tag can still be assigned. Returns {document_id, branch_id, tag_id}.","has_params_one_of":true,"json_schema":{"properties":{"branch_id":{"description":"The id of the branch the tag goes on or comes off: a document's default_branch_id from list_documents or list_tags, or any id from the branches get_document lists.","type":"string"},"document_id":{"description":"The document id.","type":"string"},"tag_id":{"description":"The tag id, as list_tags or a document's tags report it.","type":"string"}},"required":["document_id","branch_id","tag_id"],"type":"object"},"name":"assign_tag"},"create_document":{"desc":"Create a new document and return {document_id, branch_id}, the branch_id being its default branch. The document starts with a single empty paragraph, so follow up with insert_block calls (position end, that branch_id) in the same turn to fill it. Omit parent_id to create it at the organisation root.","has_params_one_of":true,"json_schema":{"properties":{"icon":{"description":"Iconify identifier, as \"collection:name\". The product's own icons are MingCute fills (e.g. \"mingcute:file-code-fill\"); prefer one so the document matches the rest of the sidebar. Defaults to \"mingcute:document-2-fill\" when empty.","type":"string"},"name":{"description":"Display name for the new document.","type":"string"},"parent_id":{"description":"Optional parent document id. Omit to create at the org root.","type":"string"}},"required":["name"],"type":"object"},"name":"create_document"},"create_hook":{"desc":"Add a freshness hook to one branch of a document and return it as list_hooks would. settings.type is one of scheduled-reminder, github-tracking, url-watcher and container-image-watcher, and the rest of settings is that type's own fields. github-tracking and url-watcher depend on the deployment's GitHub App and changedetection.io integrations, and are refused where those are missing. block_uid anchors the hook to a block; a uid the branch does not hold is refused. A new hook starts at score 100.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"Optional. The uid of a block on the branch to anchor the hook to, from get_document; omit to put the hook on the document as a whole.","type":"string"},"branch_id":{"description":"The id of the branch the hook goes on: a document's default_branch_id from list_documents, or any id from the branches get_document lists.","type":"string"},"document_id":{"description":"The document id.","type":"string"},"settings":{"anyOf":[{"additionalProperties":false,"properties":{"schedule":{"description":"The RFC 3339 timestamp at which the reminder is due.","type":"string"},"type":{"const":"scheduled-reminder"}},"required":["type","schedule"],"title":"scheduled-reminder","type":"object"},{"additionalProperties":false,"properties":{"branch":{"description":"The repository branch to follow.","type":"string"},"paths":{"description":"The repository paths whose changes mark the document stale.","items":{"type":"string"},"minItems":1,"type":"array"},"repository":{"description":"The repository to follow, as owner/name.","type":"string"},"type":{"const":"github-tracking"}},"required":["type","repository","branch","paths"],"title":"github-tracking","type":"object"},{"additionalProperties":false,"properties":{"type":{"const":"url-watcher"},"url":{"description":"The web address to watch for changes.","type":"string"}},"required":["type","url"],"title":"url-watcher","type":"object"},{"additionalProperties":false,"properties":{"image":{"description":"The container image reference to watch for new digests.","type":"string"},"type":{"const":"container-image-watcher"}},"required":["type","image"],"title":"container-image-watcher","type":"object"}],"description":"The hook's type and its settings."}},"required":["document_id","branch_id","settings"],"type":"object"},"name":"create_hook"},"create_tag":{"desc":"Create a tag and return {tag_id}. name is the display name, which has to be unused in the organisation, and color a hex triplet with the leading hash; a malformed colour or a name already in use is refused. The new tag lands last in the sidebar order, so use move_tag to place it, and assign_tag to put it on a document branch.","has_params_one_of":true,"json_schema":{"properties":{"color":{"description":"The tag's colour as a hex triplet with the leading hash, such as \"#22c55e\".","type":"string"},"name":{"description":"Display name for the new tag; unique within the organisation.","type":"string"}},"required":["name","color"],"type":"object"},"name":"create_tag"},"delete_block":{"desc":"Delete one block by uid, including anything nested inside it. Its comments, hooks and files go with it and cannot be restored, so use move_block when the aim is to reorder and update_block_text when the aim is new wording. Returns {deleted: uid}.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"The uid of the block to delete.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"}},"required":["document_id","branch_id","block_uid"],"type":"object"},"name":"delete_block"},"delete_document":{"desc":"Delete a document and every document nested under it. The whole subtree goes and cannot be restored, so check the tree with list_documents first, and use update_document when the aim is to relocate rather than remove. Returns {document_id, deleted}.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id to delete.","type":"string"}},"required":["document_id"],"type":"object"},"name":"delete_document"},"delete_hook":{"desc":"Delete a hook, tearing down whatever it watches outside the document; it cannot be restored, so use reset_hook when the aim is to clear what it flagged rather than stop watching. Returns {hook_id, deleted}.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id.","type":"string"},"hook_id":{"description":"The hook id, as list_hooks reports it.","type":"string"}},"required":["document_id","hook_id"],"type":"object"},"name":"delete_hook"},"delete_tag":{"desc":"Delete a tag. Every document carrying it loses it, on every branch, and the tag cannot be restored; use unassign_tag when the aim is to take it off one document rather than remove it. Returns {tag_id, deleted}.","has_params_one_of":true,"json_schema":{"properties":{"tag_id":{"description":"The id of the tag to delete.","type":"string"}},"required":["tag_id"],"type":"object"},"name":"delete_tag"},"get_document":{"desc":"Read one document on one branch: its name, icon, parent_id, protected flag and updated_at, the branch read and every branch the document has (each with the id a branch_id argument takes), the tags the branch carries as [{id, tagName, color}], followed by one row per block with the block's uid, kind, flattened text, depth, parent_uid and the few attrs that matter for reading (heading level, callout icon, code language, task checked). Use it as the way to read a document before editing it; branch_id is the default_branch_id a listing or search hit carries, or any id from branches. A protected branch can be read but refuses every write, so pick an unprotected branch id from branches to write to. Rows marked has_children hold nested blocks the rows do not list, and read_block returns those when you need them.","has_params_one_of":true,"json_schema":{"properties":{"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The document id.","type":"string"}},"required":["document_id","branch_id"],"type":"object"},"name":"get_document"},"get_prometheus_metadata":{"desc":"List the metrics a Prometheus data source exposes, with each metric's type, help text and unit. Use it to find the metric names to write a PromQL query against instead of guessing them.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"}},"required":["data_source_id"],"type":"object"},"name":"get_prometheus_metadata"},"get_sql_metadata":{"desc":"List the tables and their columns in a PostgreSQL, MariaDB or MySQL data source, plus the default schema. Read it before writing a query so the table and column names are the real ones.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"}},"required":["data_source_id"],"type":"object"},"name":"get_sql_metadata"},"get_sql_query_labels":{"desc":"Run a SQL query limited to one row and return its string columns with an example value each, which are the columns a chart would treat as series labels. Use it to check what a query returns before charting it; it is cheaper than query_sql.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"query":{"description":"The SQL query to probe. $__ macros are expanded as they are for a metric block.","type":"string"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","query"],"type":"object"},"name":"get_sql_query_labels"},"insert_block":{"desc":"Insert one canonical block into a document. position start or end puts it at the document's start or end; before or after puts it beside the block reference_block_uid names, which stays in place. The block has to be legal where it lands: the document root takes every type except titled_code, metric and split_doc_param_list, and a reference inside a split_doc or metric_grid takes only what that container holds. Returns the summary rows of the new block and everything nested in it, uids included, with depth counted from the block itself.","has_params_one_of":true,"json_schema":{"properties":{"block":{"anyOf":[{"additionalProperties":false,"properties":{"children":{"description":"Only when the paragraph is a list or task-list entry: the blocks indented under it, each a paragraph, bullet_list, ordered_list or task_list.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one.","type":"string"},"type":{"const":"paragraph"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"paragraph","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"level":{"description":"The heading level.","enum":[1,2,3],"type":"integer"}},"required":["level"],"type":"object"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one.","type":"string"},"type":{"const":"heading"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"heading","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The blocks it quotes, of any type legal at the document root. Use text or items, not both.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one. Use text or items, not both.","type":"string"},"type":{"const":"blockquote"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"blockquote","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The entries, each a paragraph block. Blocks nested under an entry go in that paragraph's children.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"bullet_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"bullet_list","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The entries, each a paragraph block. Blocks nested under an entry go in that paragraph's children.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"ordered_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"ordered_list","type":"object"},{"additionalProperties":false,"properties":{"task_items":{"description":"The rows, each a checked flag and a paragraph block. Blocks nested under a row go in that paragraph's children.","items":{"properties":{"block":{"type":"object"},"checked":{"type":"boolean"}},"required":["block"],"type":"object"},"minItems":1,"type":"array"},"type":{"const":"task_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","task_items"],"title":"task_list","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"icon":{"description":"Iconify identifier; defaults to lucide:text.","type":"string"}},"type":"object"},"items":{"description":"The blocks it holds, each a paragraph, bullet_list, ordered_list or task_list. Use text or items, not both.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one. Use text or items, not both.","type":"string"},"type":{"const":"callout"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"callout","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"language":{"description":"Optional; leave empty rather than guess.","type":"string"}},"type":"object"},"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"code"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"code","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"language":{"description":"Optional; leave empty rather than guess.","type":"string"},"title":{"description":"Plain-text label naming what the code is. For an endpoint, the method and route, such as POST /v1/assets/{id}/due-date/preview.","type":"string"}},"required":["title"],"type":"object"},"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"titled_code"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"titled_code","type":"object"},{"additionalProperties":false,"properties":{"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"mermaid"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"mermaid","type":"object"},{"additionalProperties":false,"properties":{"type":{"const":"horizontal_rule"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"horizontal_rule","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"alt":{"description":"Alternative text.","type":"string"},"src":{"description":"The image address.","type":"string"},"title":{"description":"Caption.","type":"string"},"width":{"description":"Display width in pixels.","type":"integer"}},"required":["src"],"type":"object"},"type":{"const":"image"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"image","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"height":{"description":"Display height in pixels.","type":"integer"},"src":{"description":"The Figma frame address.","type":"string"},"width":{"description":"Display width in pixels.","type":"integer"}},"required":["src"],"type":"object"},"type":{"const":"figma"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"figma","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"description":"The chart configuration: the data source, the queries, the window and the display settings, as the block model describes them. Legal only inside a metric_grid or on a split_doc right side.","properties":{"refreshInterval":{"description":"How often the chart re-queries.","enum":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"type":"string"},"simulationPreset":{"description":"Draws this generated series in place of the query's own result, for a block documenting a metric that has no real data yet. Omit it to chart the query.","enum":["cpu_usage","memory_usage","disk_usage","http_requests","http_latency","error_rate"],"type":"string"},"timeRange":{"description":"The window queried.","enum":["last_5_minutes","last_15_minutes","last_30_minutes","last_1_hour","last_3_hours","last_6_hours","last_12_hours","last_24_hours","last_2_days","last_7_days","last_30_days","last_90_days","last_6_months","last_1_year","last_2_years","last_5_years","today","yesterday","today_so_far","this_week","this_week_so_far","this_month","this_month_so_far","this_year","this_year_so_far","previous_week","previous_month","previous_year"],"type":"string"},"unitType":{"description":"The unit values are read in. With custom, put the label in unitCustom.","enum":["custom","nanoseconds","microseconds","milliseconds","seconds","minutes","hours","days","bytes","kilobytes","megabytes","gigabytes","terabytes","bits","kilobits","megabits","gigabits","terabits","percent0to100","percent0to1"],"type":"string"},"visualizationType":{"description":"The chart kind.","enum":["line_chart","bar_chart","gauge_chart"],"type":"string"},"width":{"description":"The chart's size.","enum":["compact","standard","wide"],"type":"string"}},"type":"object"},"type":{"const":"metric"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"metric","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The metric blocks it holds.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"metric_grid"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"metric_grid","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"inversed":{"description":"Flips the two sides.","type":"boolean"}},"type":"object"},"left":{"description":"The concept side. Must start with a level-1 heading; then paragraphs, lists and callouts; then any split_doc_param_list, which is legal only here.","items":{"type":"object"},"minItems":1,"type":"array"},"right":{"description":"The example side. Holds titled_code, metric or mermaid only, and is the one place titled_code is legal.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"split_doc"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","left","right"],"title":"split_doc","type":"object"},{"additionalProperties":false,"properties":{"header":{"description":"The section header, as plain text.","type":"string"},"params":{"description":"The rows.","items":{"properties":{"description":{"description":"The description, in minimal markdown.","type":"string"},"name":{"description":"The parameter name, as plain text.","type":"string"},"type":{"description":"The parameter type, as plain text.","type":"string"}},"required":["name"],"type":"object"},"minItems":1,"type":"array"},"type":{"const":"split_doc_param_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","header","params"],"title":"split_doc_param_list","type":"object"}],"description":"A canonical block. Its type decides which fields it takes."},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"},"position":{"description":"Where the block lands: before or after the reference block, or at the start or end of the document.","enum":["before","after","start","end"],"type":"string"},"reference_block_uid":{"description":"The uid of the block to insert beside. Required with before and after; leave it out with start and end.","type":"string"}},"required":["document_id","branch_id","position","block"],"type":"object"},"name":"insert_block"},"list_data_sources":{"desc":"List the organisation's data sources. Returns id, name, type (prometheus, postgresql, mariadb, mysql) and connection status. Start here: every other data-source tool takes an id from this list, and the type decides which of them serves it.","has_params_one_of":true,"json_schema":{"properties":{},"type":"object"},"name":"list_data_sources"},"list_documents":{"desc":"List the organisation's documents as a tree of {id, name, default_branch_id, children}; default_branch_id is what get_document and the block tools take as branch_id for the document's default branch. Use it to find a document by name or to see what sits under a parent; use search_documents when you are looking for content rather than a title. Pass parent_id to get only that document's direct children, or omit it for the whole organisation.","has_params_one_of":true,"json_schema":{"properties":{"parent_id":{"description":"Optional. Return only the direct children of this document. Omit for the full tree.","type":"string"}},"type":"object"},"name":"list_documents"},"list_hooks":{"desc":"List the freshness hooks on one branch of a document as [{id, type, block_uid, settings, score, state, created_at, updated_at}]. A hook watches something outside the document and lowers its score as that thing changes or a date approaches; block_uid names the block it is anchored to, or is null for a hook on the document as a whole. Use it to learn the id that update_hook, reset_hook and delete_hook take as hook_id. document_id and branch_id name the branch the way the content tools do.","has_params_one_of":true,"json_schema":{"properties":{"branch_id":{"description":"The id of the branch whose hooks to list: a document's default_branch_id from list_documents, or any id from the branches get_document lists.","type":"string"},"document_id":{"description":"The document id.","type":"string"}},"required":["document_id","branch_id"],"type":"object"},"name":"list_hooks"},"list_prometheus_label_names":{"desc":"List the label names present in a Prometheus data source, optionally only those on the series the matchers select. Pair it with list_prometheus_label_values to build a filtered PromQL query.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"matchers":{"description":"Optional. PromQL series selectors, e.g. [\"up\", \"{job=\\\"api\\\"}\"].","items":{"type":"string"},"type":"array"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id"],"type":"object"},"name":"list_prometheus_label_names"},"list_prometheus_label_values":{"desc":"List the values a label takes in a Prometheus data source, optionally only on the series the matchers select. Use it to discover the concrete label values a query should filter on.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"label":{"description":"The label whose values to list, e.g. \"job\".","type":"string"},"matchers":{"description":"Optional. PromQL series selectors, e.g. [\"up\", \"{job=\\\"api\\\"}\"].","items":{"type":"string"},"type":"array"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","label"],"type":"object"},"name":"list_prometheus_label_values"},"list_prometheus_series":{"desc":"List the series matching a set of selectors in a Prometheus data source, each as its full label set. Use it to see which label combinations a metric actually has before querying it.","has_params_one_of":true,"json_schema":{"properties":{"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"matchers":{"description":"PromQL series selectors, e.g. [\"up\", \"{job=\\\"api\\\"}\"].","items":{"type":"string"},"type":"array"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","matchers"],"type":"object"},"name":"list_prometheus_series"},"list_tags":{"desc":"List the organisation's tags in their sidebar order as [{id, name, color, hidden, documents}], where documents is [{id, name, default_branch_id}] for every document whose default branch carries the tag. Use it to find a tag by name before assigning it, and to learn the id that update_tag, delete_tag, move_tag, assign_tag and unassign_tag take as tag_id. A tag assigned to a non-default branch shows under tags on get_document for that branch but not here. hidden says whether the current user keeps the tag out of their own sidebar; it does not stop the tag being assigned.","has_params_one_of":true,"json_schema":{"properties":{},"type":"object"},"name":"list_tags"},"move_block":{"desc":"Move an existing block before or after another block in the same document. The block keeps its uid, attrs and nested content, so comments, hooks and files attached to it stay attached; deleting it and inserting a copy would lose them. The landing spot has to accept the block's type, by the same rule insert_block applies. Returns the summary rows of the moved block and everything nested in it.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"The uid of the block to move.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"},"position":{"description":"Landing side relative to the reference block.","enum":["before","after"],"type":"string"},"reference_block_uid":{"description":"The uid of the block to move relative to.","type":"string"}},"required":["document_id","branch_id","block_uid","position","reference_block_uid"],"type":"object"},"name":"move_block"},"move_tag":{"desc":"Move a tag to a position in the sidebar order, which is the order list_tags returns. sort_index is the 0-based position the tag should end up at, so 0 puts it first, and a position past the last tag is refused; the other tags keep their relative order. Returns {tag_id, sort_index}.","has_params_one_of":true,"json_schema":{"properties":{"sort_index":{"description":"The 0-based position the tag should end up at among the organisation's tags.","type":"integer"},"tag_id":{"description":"The tag id, as list_tags or a document's tags report it.","type":"string"}},"required":["tag_id","sort_index"],"type":"object"},"name":"move_tag"},"query_prometheus":{"desc":"Run a PromQL range query against a Prometheus data source over the given window. Returns the raw result by default; with chart_type set it instead describes what a metric block would render, which is how to check a query before writing it into a block.","has_params_one_of":true,"json_schema":{"properties":{"chart_type":{"description":"Optional. One of line_chart, bar_chart, gauge_chart. When set, the result describes what the metric block would draw (render status, series count, and each series' labels, point count and endpoints) instead of the raw data. Use it to check a query before putting it in a metric block; omit it when you need the values themselves.","type":"string"},"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"query":{"description":"The PromQL expression to run.","type":"string"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","query"],"type":"object"},"name":"query_prometheus"},"query_sql":{"desc":"Run a read-only query against a PostgreSQL, MariaDB or MySQL data source. Returns columns and rows by default; with chart_type set it instead describes what a metric block would render, which is how to check a query before writing it into a block. $__ macros ($__timeFilter, $__timeGroupAlias and the rest) are expanded against the window.","has_params_one_of":true,"json_schema":{"properties":{"chart_type":{"description":"Optional. One of line_chart, bar_chart, gauge_chart. When set, the result describes what the metric block would draw (render status, series count, and each series' labels, point count and endpoints) instead of the raw data. Use it to check a query before putting it in a metric block; omit it when you need the values themselves.","type":"string"},"data_source_id":{"description":"The data source id, from list_data_sources.","type":"string"},"from":{"description":"Optional. Range start as an RFC3339 timestamp. Defaults to an hour before 'to'.","type":"string"},"query":{"description":"The SQL query to run. For a chart, select a time column aliased \"time\" plus one or more numeric columns.","type":"string"},"to":{"description":"Optional. Range end as an RFC3339 timestamp. Defaults to now.","type":"string"}},"required":["data_source_id","query"],"type":"object"},"name":"query_sql"},"read_block":{"desc":"Return the full canonical content of one block by uid, including any nested children. Use it only when get_document's rows are not enough: to edit a split_doc, a nested list or a split_doc_param_list, whose inner structure has to be written back in full. Fails when the uid is not in the document.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"The block uid to fetch.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The document id.","type":"string"}},"required":["document_id","branch_id","block_uid"],"type":"object"},"name":"read_block"},"read_tool_output":{"desc":"Retrieve the full output of an earlier tool call that was too large to keep in the conversation. Pass the path shown in the truncation notice.","has_params_one_of":true,"json_schema":{"properties":{"file_path":{"description":"The stored output path from the truncation notice.","type":"string"}},"required":["file_path"],"type":"object"},"name":"read_tool_output"},"replace_block":{"desc":"Replace a block by uid with a new block in the same position. The old block's uid, content and children are all gone unless the new block carries them, so use it to change a block's type or its whole structure. For a wording change use update_block_text, and for an attribute change update_block_attrs; both keep the uid, which comments, hooks and files hang off. Returns the summary rows of the new block and everything nested in it, uids included, with depth counted from the block itself.","has_params_one_of":true,"json_schema":{"properties":{"block":{"anyOf":[{"additionalProperties":false,"properties":{"children":{"description":"Only when the paragraph is a list or task-list entry: the blocks indented under it, each a paragraph, bullet_list, ordered_list or task_list.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one.","type":"string"},"type":{"const":"paragraph"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"paragraph","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"level":{"description":"The heading level.","enum":[1,2,3],"type":"integer"}},"required":["level"],"type":"object"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one.","type":"string"},"type":{"const":"heading"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"heading","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The blocks it quotes, of any type legal at the document root. Use text or items, not both.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one. Use text or items, not both.","type":"string"},"type":{"const":"blockquote"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"blockquote","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The entries, each a paragraph block. Blocks nested under an entry go in that paragraph's children.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"bullet_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"bullet_list","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The entries, each a paragraph block. Blocks nested under an entry go in that paragraph's children.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"ordered_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"ordered_list","type":"object"},{"additionalProperties":false,"properties":{"task_items":{"description":"The rows, each a checked flag and a paragraph block. Blocks nested under a row go in that paragraph's children.","items":{"properties":{"block":{"type":"object"},"checked":{"type":"boolean"}},"required":["block"],"type":"object"},"minItems":1,"type":"array"},"type":{"const":"task_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","task_items"],"title":"task_list","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"icon":{"description":"Iconify identifier; defaults to lucide:text.","type":"string"}},"type":"object"},"items":{"description":"The blocks it holds, each a paragraph, bullet_list, ordered_list or task_list. Use text or items, not both.","items":{"type":"object"},"type":"array"},"text":{"description":"Inline text in minimal markdown. One block is one paragraph; a newline inside text does not start a new one. Use text or items, not both.","type":"string"},"type":{"const":"callout"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"callout","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"language":{"description":"Optional; leave empty rather than guess.","type":"string"}},"type":"object"},"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"code"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"code","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"language":{"description":"Optional; leave empty rather than guess.","type":"string"},"title":{"description":"Plain-text label naming what the code is. For an endpoint, the method and route, such as POST /v1/assets/{id}/due-date/preview.","type":"string"}},"required":["title"],"type":"object"},"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"titled_code"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"titled_code","type":"object"},{"additionalProperties":false,"properties":{"text":{"description":"Raw source; no markdown.","type":"string"},"type":{"const":"mermaid"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"mermaid","type":"object"},{"additionalProperties":false,"properties":{"type":{"const":"horizontal_rule"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"horizontal_rule","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"alt":{"description":"Alternative text.","type":"string"},"src":{"description":"The image address.","type":"string"},"title":{"description":"Caption.","type":"string"},"width":{"description":"Display width in pixels.","type":"integer"}},"required":["src"],"type":"object"},"type":{"const":"image"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"image","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"height":{"description":"Display height in pixels.","type":"integer"},"src":{"description":"The Figma frame address.","type":"string"},"width":{"description":"Display width in pixels.","type":"integer"}},"required":["src"],"type":"object"},"type":{"const":"figma"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","attrs"],"title":"figma","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"description":"The chart configuration: the data source, the queries, the window and the display settings, as the block model describes them. Legal only inside a metric_grid or on a split_doc right side.","properties":{"refreshInterval":{"description":"How often the chart re-queries.","enum":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"type":"string"},"simulationPreset":{"description":"Draws this generated series in place of the query's own result, for a block documenting a metric that has no real data yet. Omit it to chart the query.","enum":["cpu_usage","memory_usage","disk_usage","http_requests","http_latency","error_rate"],"type":"string"},"timeRange":{"description":"The window queried.","enum":["last_5_minutes","last_15_minutes","last_30_minutes","last_1_hour","last_3_hours","last_6_hours","last_12_hours","last_24_hours","last_2_days","last_7_days","last_30_days","last_90_days","last_6_months","last_1_year","last_2_years","last_5_years","today","yesterday","today_so_far","this_week","this_week_so_far","this_month","this_month_so_far","this_year","this_year_so_far","previous_week","previous_month","previous_year"],"type":"string"},"unitType":{"description":"The unit values are read in. With custom, put the label in unitCustom.","enum":["custom","nanoseconds","microseconds","milliseconds","seconds","minutes","hours","days","bytes","kilobytes","megabytes","gigabytes","terabytes","bits","kilobits","megabits","gigabits","terabits","percent0to100","percent0to1"],"type":"string"},"visualizationType":{"description":"The chart kind.","enum":["line_chart","bar_chart","gauge_chart"],"type":"string"},"width":{"description":"The chart's size.","enum":["compact","standard","wide"],"type":"string"}},"type":"object"},"type":{"const":"metric"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type"],"title":"metric","type":"object"},{"additionalProperties":false,"properties":{"items":{"description":"The metric blocks it holds.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"metric_grid"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","items"],"title":"metric_grid","type":"object"},{"additionalProperties":false,"properties":{"attrs":{"properties":{"inversed":{"description":"Flips the two sides.","type":"boolean"}},"type":"object"},"left":{"description":"The concept side. Must start with a level-1 heading; then paragraphs, lists and callouts; then any split_doc_param_list, which is legal only here.","items":{"type":"object"},"minItems":1,"type":"array"},"right":{"description":"The example side. Holds titled_code, metric or mermaid only, and is the one place titled_code is legal.","items":{"type":"object"},"minItems":1,"type":"array"},"type":{"const":"split_doc"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","left","right"],"title":"split_doc","type":"object"},{"additionalProperties":false,"properties":{"header":{"description":"The section header, as plain text.","type":"string"},"params":{"description":"The rows.","items":{"properties":{"description":{"description":"The description, in minimal markdown.","type":"string"},"name":{"description":"The parameter name, as plain text.","type":"string"},"type":{"description":"The parameter type, as plain text.","type":"string"}},"required":["name"],"type":"object"},"minItems":1,"type":"array"},"type":{"const":"split_doc_param_list"},"uid":{"description":"Leave unset; generated server-side.","type":"string"}},"required":["type","header","params"],"title":"split_doc_param_list","type":"object"}],"description":"A canonical block. Its type decides which fields it takes."},"block_uid":{"description":"The uid of the block being replaced.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"}},"required":["document_id","branch_id","block_uid","block"],"type":"object"},"name":"replace_block"},"reset_hook":{"desc":"Reset a hook's score to 100 and its state to what a fresh hook has, keeping its settings, and return it as list_hooks would. Use it once the document has been brought up to date with whatever the hook flagged.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id.","type":"string"},"hook_id":{"description":"The hook id, as list_hooks reports it.","type":"string"}},"required":["document_id","hook_id"],"type":"object"},"name":"reset_hook"},"search_documents":{"desc":"Full-text search across every branch of every document in the organisation for blocks whose text matches the query. Returns hits with document_id, document_name, branch_id, branch_name, default (whether that branch is the document's default), block_uid and text; branch_id is what a follow-up get_document or read_block takes. A block a fork copied unchanged is found on every branch that holds it. Use it to find where a topic is discussed or which documents the user might mean; use list_documents when you know the title. A hit names the innermost block holding the text, which may sit below anything get_document lists; read_block resolves it.","has_params_one_of":true,"json_schema":{"properties":{"limit":{"description":"Maximum number of hits to return. Defaults to 20; cap is 50.","type":"integer"},"query":{"description":"The full-text search query (typo-tolerant, matches block text).","type":"string"}},"required":["query"],"type":"object"},"name":"search_documents"},"unassign_tag":{"desc":"Take a tag off one branch of a document; the tag itself stays for other documents, so use delete_tag to remove it everywhere. document_id and branch_id name the branch the way the content tools do, and tag_id is the tag's id from the document's tags on get_document or from list_tags. A tag the branch does not carry is nothing to do, and the call still succeeds. Returns {document_id, branch_id, tag_id}.","has_params_one_of":true,"json_schema":{"properties":{"branch_id":{"description":"The id of the branch the tag goes on or comes off: a document's default_branch_id from list_documents or list_tags, or any id from the branches get_document lists.","type":"string"},"document_id":{"description":"The document id.","type":"string"},"tag_id":{"description":"The tag id, as list_tags or a document's tags report it.","type":"string"}},"required":["document_id","branch_id","tag_id"],"type":"object"},"name":"unassign_tag"},"update_block_attrs":{"desc":"Set or override named attributes on an existing block, such as a heading's level or a callout's icon. Attributes not mentioned are kept and uid cannot change. Values are validated for the block's type, so a level outside 1 to 3 or a metric width other than compact, standard or wide is rejected. Use replace_block when the type itself has to change. Returns the summary rows of the block and everything nested in it, attrs as they now stand.","has_params_one_of":true,"json_schema":{"properties":{"attrs":{"description":"Attribute keys and values to set (e.g. {\"level\": 2}, {\"icon\": \"lucide:warning\"}).","type":"object"},"block_uid":{"description":"The uid of the block whose attrs should be updated.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"}},"required":["document_id","branch_id","block_uid","attrs"],"type":"object"},"name":"update_block_attrs"},"update_block_text":{"desc":"Replace the inline text of one text-bearing block: paragraph, heading, blockquote, code, titled_code, mermaid, or a callout written with text. Type, attrs and uid are kept, so this is the tool for wording changes. Text follows the canonical markdown subset (**bold**, *italic*, _underline_, ~~strike~~, backtick code, [label](url)), and is raw in code, titled_code and mermaid. One block is one paragraph; to add a paragraph, insert a block instead. Returns the block's summary row with the new text.","has_params_one_of":true,"json_schema":{"properties":{"block_uid":{"description":"The uid of the block whose text should be replaced.","type":"string"},"branch_id":{"description":"The id of the branch to read or write: a document's default_branch_id from list_documents, a search hit's branch_id, or any id from the branches get_document lists. A protected branch can be read but refuses every write.","type":"string"},"document_id":{"description":"The target document id.","type":"string"},"text":{"description":"New inline text in canonical markdown.","type":"string"}},"required":["document_id","branch_id","block_uid","text"],"type":"object"},"name":"update_block_text"},"update_document":{"desc":"Change a document's name, icon or place in the tree, any combination in one call; content is untouched. Give only the fields to change: name is the new display name, icon an Iconify identifier as \"collection:name\" (the product's own icons are MingCute fills, e.g. \"mingcute:rocket-fill\", so prefer one to match the sidebar), and parent_id the new parent, or an empty string for the organisation root. A call with none of the three is refused, and a parent that is the document itself or one of its descendants fails. Returns {document_id} with the fields that changed.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id.","type":"string"},"icon":{"description":"Optional. The new icon identifier; omit to keep the current one.","type":"string"},"name":{"description":"Optional. The new display name; omit to keep the current one.","type":"string"},"parent_id":{"description":"Optional. The new parent document id, or an empty string to move the document to the organisation root; omit to leave it where it is.","type":"string"}},"required":["document_id"],"type":"object"},"name":"update_document"},"update_hook":{"desc":"Replace the settings of a hook and reset its score and state, returning it as list_hooks would. settings.type is one of scheduled-reminder, github-tracking, url-watcher and container-image-watcher, and the rest of settings is that type's own fields. github-tracking and url-watcher depend on the deployment's GitHub App and changedetection.io integrations, and are refused where those are missing. The hook keeps its type, so settings.type is the type list_hooks reports for it; to change the type, delete the hook and create another.","has_params_one_of":true,"json_schema":{"properties":{"document_id":{"description":"The document id.","type":"string"},"hook_id":{"description":"The hook id, as list_hooks reports it.","type":"string"},"settings":{"anyOf":[{"additionalProperties":false,"properties":{"schedule":{"description":"The RFC 3339 timestamp at which the reminder is due.","type":"string"},"type":{"const":"scheduled-reminder"}},"required":["type","schedule"],"title":"scheduled-reminder","type":"object"},{"additionalProperties":false,"properties":{"branch":{"description":"The repository branch to follow.","type":"string"},"paths":{"description":"The repository paths whose changes mark the document stale.","items":{"type":"string"},"minItems":1,"type":"array"},"repository":{"description":"The repository to follow, as owner/name.","type":"string"},"type":{"const":"github-tracking"}},"required":["type","repository","branch","paths"],"title":"github-tracking","type":"object"},{"additionalProperties":false,"properties":{"type":{"const":"url-watcher"},"url":{"description":"The web address to watch for changes.","type":"string"}},"required":["type","url"],"title":"url-watcher","type":"object"},{"additionalProperties":false,"properties":{"image":{"description":"The container image reference to watch for new digests.","type":"string"},"type":{"const":"container-image-watcher"}},"required":["type","image"],"title":"container-image-watcher","type":"object"}],"description":"The hook's type and its settings."}},"required":["document_id","hook_id","settings"],"type":"object"},"name":"update_hook"},"update_tag":{"desc":"Rename and/or recolour a tag; give only the fields to change, and the other keeps its value. name is the new display name, which has to be unused in the organisation, and color a hex triplet with the leading hash; a call with neither is refused. Returns {tag_id} with the fields that changed. To change which documents carry the tag use assign_tag and unassign_tag instead.","has_params_one_of":true,"json_schema":{"properties":{"color":{"description":"Optional. The new colour as a hex triplet with the leading hash; omit to keep the current one.","type":"string"},"name":{"description":"Optional. The new display name; omit to keep the current one.","type":"string"},"tag_id":{"description":"The tag id, as list_tags or a document's tags report it.","type":"string"}},"required":["tag_id"],"type":"object"},"name":"update_tag"}} \ No newline at end of file