From 54d11b643f20b9bff125d861bb199b6e1897fac7 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Sat, 16 May 2026 02:14:41 +0200 Subject: [PATCH] docs: update analytics skill for memory ingest --- .../content/docs/integrations/agent-clients.mdx | 2 +- packages/cli/src/setup-agents.test.ts | 3 +++ packages/cli/src/skills/analytics/SKILL.md | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs-site/content/docs/integrations/agent-clients.mdx b/docs-site/content/docs/integrations/agent-clients.mdx index 883e6ea5..1934c978 100644 --- a/docs-site/content/docs/integrations/agent-clients.mdx +++ b/docs-site/content/docs/integrations/agent-clients.mdx @@ -87,7 +87,7 @@ skill**. | Universal `.agents` | Printed MCP endpoint, `.agents/skills/ktx-analytics/SKILL.md` | `.agents/skills/ktx/SKILL.md` | MCP config gives agents access to KTX context tools such as discovery, -semantic-layer queries, wiki search, SQL execution, and memory capture. The +semantic-layer queries, wiki search, SQL execution, and memory ingest. The analytics skill explains how to use those tools for semantic-layer-first analysis. Optional admin skill and rule files list pinned CLI commands for developer or operator agents. diff --git a/packages/cli/src/setup-agents.test.ts b/packages/cli/src/setup-agents.test.ts index 67ac9433..61d0682b 100644 --- a/packages/cli/src/setup-agents.test.ts +++ b/packages/cli/src/setup-agents.test.ts @@ -193,6 +193,9 @@ describe('setup agents', () => { expect(analyticsSkill).toContain('name: ktx-analytics'); expect(analyticsSkill).toContain('Always run `discover_data` before writing SQL.'); expect(analyticsSkill).toContain('Treat a `dictionary_search` miss as non-authoritative.'); + expect(analyticsSkill).toContain('memory_ingest'); + expect(analyticsSkill).toContain('ARR is reported in cents'); + expect(analyticsSkill).not.toContain('memory_capture'); }); it('writes PATH-independent launcher commands for skills', async () => { diff --git a/packages/cli/src/skills/analytics/SKILL.md b/packages/cli/src/skills/analytics/SKILL.md index ae358e4b..e4aa86d2 100644 --- a/packages/cli/src/skills/analytics/SKILL.md +++ b/packages/cli/src/skills/analytics/SKILL.md @@ -5,7 +5,7 @@ description: Use when answering a question that needs data from a KTX-connected # KTX Analytics Workflow -You have access to KTX MCP tools for data discovery, semantic-layer analysis, raw read-only SQL, wiki context, and memory capture. Follow this workflow. +You have access to KTX MCP tools for data discovery, semantic-layer analysis, raw read-only SQL, wiki context, and memory ingest. Follow this workflow. 1. **Discover** - call `discover_data` first to see what exists across wiki pages, semantic-layer sources, metrics, dimensions, raw tables, and columns. Returns refs only. @@ -19,7 +19,7 @@ You have access to KTX MCP tools for data discovery, semantic-layer analysis, ra - Prefer `sl_query` when the semantic layer covers the question. - Use `sql_execution` only for questions the semantic layer does not cover. 6. **Validate and explain** - sanity-check totals, filters, null handling, and time zones. State the source tables or semantic-layer objects used. -7. **Capture durable learnings** - at the end of the turn, call `memory_capture` when the investigation produced reusable business context, metric definitions, or schema knowledge. +7. **Capture durable learnings** - call `memory_ingest` whenever a turn produces something worth remembering (business rules, metric definitions, schema gotchas, recurring findings) **or** whenever the user asks you to remember something. Pass markdown in `content` including any source context the memory agent should weigh. Each call is a feedback loop; better notes today mean smarter `discover_data` and `wiki_search` results tomorrow. @@ -28,6 +28,7 @@ You have access to KTX MCP tools for data discovery, semantic-layer analysis, ra - Read entity details before writing SQL against an unfamiliar table. Do not assume column names. - Treat `sql_execution` as read-only. Writes are rejected by the server. - Validate value mentions with `dictionary_search` instead of guessing case or spelling. Treat a `dictionary_search` miss as non-authoritative. The index is built from profile-sampled values, so a missing value may simply have been outside the sample. Follow up with `sql_execution` against the most plausible columns before concluding the value is absent. +- When `connection_list` shows multiple connections, pass an explicit `connectionId` to every tool that takes one and where user intent pins a specific warehouse. Required: `entity_details`, `sl_read_source`, and `sql_execution`. Required when user intent is warehouse-specific, including wording like "in our warehouse" or "this warehouse": `memory_ingest`; without `connectionId`, the memory agent cannot update the semantic layer and the knowledge lands as wiki-only. Pass `connectionId` when intent pins a warehouse, otherwise omit for unscoped discovery: `sl_query`, `discover_data`, and `dictionary_search`. Never pass `connectionId` to `connection_list`, `wiki_search`, `wiki_read`, or `memory_ingest_status`. If intent is ambiguous for a required-or-scoped tool, ask the user which warehouse before calling. - Show compact result tables for small outputs. For broad results, summarize the top findings and mention the applied limit. - Ask a concise clarification only when the metric, date range, entity, or grain is genuinely ambiguous and cannot be inferred from context. @@ -40,7 +41,7 @@ You have access to KTX MCP tools for data discovery, semantic-layer analysis, ra 2. `discover_data({ query: "orders customer monthly" })` finds an orders semantic-layer source. 3. `sl_read_source({ connectionId: "warehouse", sourceName: "orders_facts" })` confirms the source grain, measures, and dimensions. 4. `sl_query({ connectionId: "warehouse", measures: ["order_count"], filters: ["customer_name = 'Acme Corp'"] })` answers through the semantic layer. -5. `memory_capture({ userMessage, assistantMessage })` captures the durable finding. +5. `memory_ingest({ connectionId: "warehouse", content: "Acme Corp order analysis used orders_facts.order_count filtered by customers.name = 'Acme Corp'. Source: current analysis turn." })` captures the durable finding. --- @@ -50,4 +51,12 @@ You have access to KTX MCP tools for data discovery, semantic-layer analysis, ra 1. `discover_data({ query: "events table" })` returns a `table` ref. 2. `entity_details({ connectionId: "warehouse", entities: [{ table: "analytics.events" }] })` returns columns, types, and foreign keys. 3. Answer directly. No query is needed. + +--- + +**Input:** "Heads up: ARR is always reported in cents in our warehouse." + +**Workflow:** +1. If multiple connections exist, call `connection_list` and identify the warehouse the user means. Ask if ambiguous. +2. `memory_ingest({ connectionId: "warehouse", content: "ARR is reported in cents (not dollars) in this warehouse. Multiply by 0.01 for dollar amounts. Source: user clarification." })` remembers the warehouse-specific rule without running an analysis turn.