diff --git a/public/kai/kai-action-approval.png b/public/kai/kai-action-approval.png new file mode 100644 index 000000000..3a145e2e7 Binary files /dev/null and b/public/kai/kai-action-approval.png differ diff --git a/public/kai/kai-clarifying-question.png b/public/kai/kai-clarifying-question.png new file mode 100644 index 000000000..5571b6a2e Binary files /dev/null and b/public/kai/kai-clarifying-question.png differ diff --git a/public/kai/kai-close-chat.png b/public/kai/kai-close-chat.png new file mode 100644 index 000000000..831402d87 Binary files /dev/null and b/public/kai/kai-close-chat.png differ diff --git a/public/kai/kai-expand-chat.png b/public/kai/kai-expand-chat.png new file mode 100644 index 000000000..205fb9572 Binary files /dev/null and b/public/kai/kai-expand-chat.png differ diff --git a/public/kai/kai-follow-mode.png b/public/kai/kai-follow-mode.png new file mode 100644 index 000000000..f1b16820b Binary files /dev/null and b/public/kai/kai-follow-mode.png differ diff --git a/public/kai/kai-new-chat.png b/public/kai/kai-new-chat.png new file mode 100644 index 000000000..ef72e9d78 Binary files /dev/null and b/public/kai/kai-new-chat.png differ diff --git a/public/kai/kai-open.png b/public/kai/kai-open.png new file mode 100644 index 000000000..68d7f45cd Binary files /dev/null and b/public/kai/kai-open.png differ diff --git a/public/kai/kai-plan-mode.png b/public/kai/kai-plan-mode.png new file mode 100644 index 000000000..35390281a Binary files /dev/null and b/public/kai/kai-plan-mode.png differ diff --git a/public/kai/kai-report-bug.png b/public/kai/kai-report-bug.png new file mode 100644 index 000000000..8f77ab099 Binary files /dev/null and b/public/kai/kai-report-bug.png differ diff --git a/public/kai/kai-settings-gear.png b/public/kai/kai-settings-gear.png new file mode 100644 index 000000000..fd0891c98 Binary files /dev/null and b/public/kai/kai-settings-gear.png differ diff --git a/public/kai/kai-upload-file.png b/public/kai/kai-upload-file.png new file mode 100644 index 000000000..1ece54652 Binary files /dev/null and b/public/kai/kai-upload-file.png differ diff --git a/public/kai/kai-welcome.png b/public/kai/kai-welcome.png deleted file mode 100644 index 6370932dd..000000000 Binary files a/public/kai/kai-welcome.png and /dev/null differ diff --git a/src/content/docs/kai/best-practices.md b/src/content/docs/kai/best-practices.md index 0885f1ab7..06adcaaf9 100644 --- a/src/content/docs/kai/best-practices.md +++ b/src/content/docs/kai/best-practices.md @@ -51,6 +51,12 @@ Test changes safely by creating a development branch in the Keboola UI, then wor - **One topic per chat** — don't mix unrelated tasks - **Reset when stuck** — if Kai gets confused after 2-3 tries, start fresh with clearer context - **Let Kai read logs** — instead of pasting, use `"Read the latest job log for ex-google-analytics"` +- **Attach what Kai cannot reach** — for security reasons Kai cannot open links, so upload + a file rather than pasting a URL +- **Compact rather than lose your place** — in a long session that is still on topic, run + [`/compact`](/kai/getting-started/#compacting-a-long-conversation) and name what has to survive + the summary. It keeps the thread going where a new chat would drop everything. If the topic has + actually changed, start a new chat instead — compacting carries context you no longer want ## Security @@ -71,6 +77,9 @@ Test changes safely by creating a development branch in the Keboola UI, then wor - **Don't argue with a confused Kai** — reset the conversation instead - **Don't skip verification** — always review business logic, data quality rules, and production deployments - **Don't expect cross-project knowledge** — Kai only sees your current project +- **Don't paste a link and expect Kai to read it** — for security reasons Kai cannot open + links. Attach the document to your message, or add it as a + [context file](/kai/settings/#context-files) if you need it in every conversation ## Team Tips diff --git a/src/content/docs/kai/getting-started.md b/src/content/docs/kai/getting-started.md index 65e7914f9..0a598c43a 100644 --- a/src/content/docs/kai/getting-started.md +++ b/src/content/docs/kai/getting-started.md @@ -13,9 +13,9 @@ Kai is now in **Public Beta** and available to all users in supported stacks. Every user can see the Kai button in their project (on supported stacks). To enable Kai: -- **Organization Admins** — Can enable the feature directly from the chat screen when first clicking the Kai button -- **Other users** — Need to ask their Organization Admin to enable the feature, or [contact Keboola Support](mailto:support@keboola.com) for assistance -- **Settings** — Kai can also be enabled via **Settings → Features** in your project +- **Organization Admins** can enable the feature directly from the chat screen when first clicking the Kai button. +- **Other users** need to ask their Organization Admin to enable the feature, or [contact Keboola Support](mailto:support@keboola.com) for assistance. +- Kai can also be enabled via **Settings → Features** in your project. ## Opening Kai @@ -24,55 +24,205 @@ Click the **Kai Agent** button in your project's top bar, or use keyboard shortc | Shortcut | Action | |----------|--------| | **A** | Open the chat window (shows recent conversation) | -| **Ctrl + Shift + A** | Open a new chat | +| **Shift + A** | Open a new chat | -![Kai Chat Panel](/kai/kai-welcome.png) +![Kai open in a project](/kai/kai-open.png) ## Example Prompts -**Explore your project:** -- "What tables do we have in this project?" -- "Show me the latest job runs and their status" -- "What extractors are configured?" +**Get oriented in an unfamiliar project:** +- "What is the purpose of this project? Summarize what it does end to end." +- "What data is being ingested, from which sources, and how often?" +- "What output tables does this project produce, and what feeds each one?" +- "Trace the lineage from the raw source tables to the final output tables." + +**Understand a specific part of it:** +- "Explain what this transformation does and why the joins are shaped this way." +- "Which configurations write to the `orders` table, and which read from it?" +- "Is anything here unused? Tables nothing reads, configurations nothing runs." + +**Debug a failure:** +- "Analyze the latest failed job and tell me what went wrong." +- "This flow started failing last week. What changed in its configuration?" +- "Why did this job take 40 minutes when it usually takes 5?" + +**Maintain and improve:** +- "Help me optimize the core pipeline to reduce costs." +- "Which jobs in this project run longest, and what would you change first?" +- "This transformation full-loads every run. Can it be incremental?" + +**Build something new:** +- "Set up a Google Sheets extractor for this spreadsheet and load it into a new bucket." +- "Create a SQL transformation that calculates monthly revenue per customer from `orders`." +- "Build an integration with the Acme API that pulls orders. Its API documentation is + attached. Handle authentication and pagination." + +Building an integration for an API that has no ready-made connector is one of the stronger +things to hand Kai. For security reasons Kai cannot open links, so give it the API +documentation as a file: +attach it with [Upload files](#below-the-message-box), or add it as a +[context file](/kai/settings/#context-files) if you will be working with that API +repeatedly. A URL on its own is not enough unless the API is well known. + +For prompts that get better answers, see +[Effective Prompting](/kai/best-practices/#effective-prompting) in Best Practices. -**Analyze data:** -- "Show me the schema for the orders table" -- "How many rows are in the customers table?" +## Action Approval -**Debug issues:** -- "Analyze the latest failed job and tell me what went wrong" +Before Kai changes anything, it requests your approval: creating a configuration, +modifying a transformation, or running a job. Read-only operations do not require +approval. -**Build things:** -- "Help me create a Google Sheets extractor" -- "Create a SQL transformation that calculates monthly totals from my sales data" +Each request shows the exact parameters Kai will use. -## Action Approval +![Kai asking for approval before running a job](/kai/kai-action-approval.png) -When Kai wants to modify your project, you'll see a tool approval prompt. Review what Kai wants to do before approving. All actions are logged in your project's audit trail. +You have three options: -You can also click **Always allow** directly in the approval dialog to skip future confirmations for that specific tool. +- **Approve** — run this action once. +- **Decline** — do not run it. +- **Always allow** — run it, and stop asking for that tool in future. -For more granular control, see [Tool Permissions](/kai/settings/#tool-permissions) in Kai Settings. +All actions are logged in your project's audit trail. -## Contextual Awareness & Follow Mode +For more granular control, see [Tool Permissions](/kai/settings/#tool-permissions) in +Kai Settings. -Kai is aware of what you're currently viewing in the Keboola UI. Every message you send includes your current page location, so Kai understands your context without needing explicit references. +## Plan Mode -### How Context Works +For anything bigger than a single change — setting up a pipeline, restructuring a set of +transformations — start in plan mode. Kai explores your project read-only, then shows you what it +intends to do and waits. Nothing changes until you approve. -- **Automatic context capture** — When you send a message, Kai receives your current URL path (e.g., which configuration, job, or table you're viewing) -- **Context-aware responses** — Kai uses this information to provide relevant suggestions and can reference "this configuration" or "the current job" naturally -- **Dynamic updates** — Kai checks for the latest context during conversations, so you can navigate to different pages and Kai will adapt +Turn it on with the **Plan mode** button below the message box, or type `/plan` in your message. +They do the same thing; the button just inserts the command for you. `/plan` works anywhere in a +sentence, so "help me /plan a revenue model" is a valid plan-mode prompt. + +When Kai finishes exploring, it presents the plan as a card with three choices: + +- **Approve** — Kai leaves plan mode and starts working. Shortcut: **Cmd/Ctrl + Enter**. +- **Request changes** — say what is wrong and Kai revises the plan, staying in plan mode. +- **Dismiss** — close the plan and do nothing. + +Prefer **Request changes** over dismissing. Kai keeps everything it learned while exploring, so +revising a plan costs far less than starting over. + +The message box is hidden while a plan card is waiting, so resolve the card before you carry on +chatting. Resolving it also switches plan mode back off for you, unless you requested changes — in +that case it stays on, because Kai is still planning. + +## When Kai Asks You a Question + +When Kai needs a decision from you — which tables to model, which of two approaches to take — it +asks with clickable options instead of a paragraph of prose. Pick one and Kai carries on. + +![Kai asking which of three approaches to take](/kai/kai-clarifying-question.png) + +- Some questions take **more than one answer**; select as many as apply. +- Every question has a free-text **Other** field, so you are never limited to the options offered. +- Questions can arrive as a short series, one step at a time. The counter in the corner shows how + far through you are, and you can step back to change an earlier answer. +- **Skip** a question and Kai decides for you. + +## Chat Controls + +The chat panel has controls in two places: along the top of the panel, and below the +message box. + +### Panel header + +| Button | Control | What it does | +|--------|---------|--------------| +| ![New chat](/kai/kai-new-chat.png) | **New chat** | Start a fresh conversation. Kai keeps no context from the previous one. | +| ![Report a bug](/kai/kai-report-bug.png) | **Report a bug** | **Send support ticket** opens the support form with the details Keboola support needs — conversation ID, trace link, project, stack — pre-filled in its description. You still write the summary, pick a severity, and send it. **Copy debug info** puts the same details on your clipboard instead. On stacks without support tickets, **Report a bug** only copies. | +| ![Settings](/kai/kai-settings-gear.png) | **Settings** | Open your [Tool Permissions and System Instructions](/kai/settings/). These are personal to you and apply to this project only. Project-wide settings live in **Settings → Kai Agent**. | +| ![Expand](/kai/kai-expand-chat.png) | **Expand** | Widen the panel. The expanded view also lists your chat history, so you can reopen a previous conversation. Useful when Kai returns a long table or diagram. | +| ![Close](/kai/kai-close-chat.png) | **Close** | Close the panel. Your conversation is kept. | + +### Below the message box + +| Button | Control | What it does | +|--------|---------|--------------| +| ![Upload file](/kai/kai-upload-file.png) | **Upload files** | Attach a file or image to your message — a screenshot of an error, a sample CSV, a spec, or documentation Kai has no other way to read. See [Attaching files](#attaching-files). | +| ![Plan mode](/kai/kai-plan-mode.png) | **Plan mode** | Kai explores your project read-only, drafts a plan, and waits for your approval before changing anything. See [Plan Mode](#plan-mode). | +| ![Follow mode](/kai/kai-follow-mode.png) | **Follow mode** | Your browser navigates along as Kai works, so you can watch what it reads and modifies. Toggle it on or off at any time. | + +### Attaching files -### Follow Mode +Use **Upload files**, or drag and drop or paste straight into the chat. You can attach several +files at once. What happens next depends on the file type. -Follow mode lets you watch Kai work in real-time: +**CSV, TSV, and `.gz` files become Storage tables.** Kai opens the table-creation dialog and loads +the file into the `in.c-uploads-from-Kai` bucket, creating that bucket the first time. Kai then +works with the table, so the data is queryable like anything else in your project and outlives the +conversation. -- **Automatic navigation** — When Kai accesses a configuration, table, or other resource, your browser navigates to that page automatically -- **Visual feedback** — See exactly what Kai is reading or modifying as it happens -- **Toggle control** — Enable or disable follow mode from the chat interface based on your preference +**Every other file is attached to the conversation.** It is uploaded to your project's +[File Storage](/storage/files/) and restored each time you return to that chat, so you can refer +back to something you attached much earlier in the same conversation. Images and PDFs are read +directly by Kai, so a screenshot of a failing job or a PDF spec works as well as plain text. + +Since Kai cannot open links, a file is how you hand it anything that lives on the web. + +Two limits are worth knowing: + +- **10 MB per file.** Anything larger is skipped. +- Attachments are stored as non-permanent files, so they are **deleted after 15 days**, like any + other non-permanent file in Storage. Reopen an older chat and Kai no longer has them. + +:::tip[Do you want the file in every conversation?] +An attachment belongs to one chat and is gone after 15 days. To give Kai a document it should read +every time, such as an API reference or your naming conventions, add it as a +[context file](/kai/settings/#context-files) instead. Context files are stored permanently and Kai +reads them at the start of every conversation, until you remove them. +::: + +## Slash Commands + +Type `/` in the message box to open a searchable menu. It lists the three built-in commands below +plus any [skill files](/kai/settings/#skill-files) uploaded to your project, each with a +description, so you can find what is available without memorizing names. + +| Command | What it does | +|---------|--------------| +| `/plan` | Turn on [plan mode](#plan-mode) for this message. The same as the Plan mode button. | +| `/compact` | Summarize the conversation so far and continue from that summary. See below. | +| `/feedback` | Report a bug or send feedback. Kai copies the debug details to your clipboard by default. Ask it to "open a ticket" and it opens the same support form as [Report a bug](#panel-header), pre-filled the same way. | + +### Compacting a long conversation + +Kai works from a limited amount of conversation at a time. When a chat gets long, `/compact` +replaces the earlier turns with a summary so there is room to keep going. Kai also compacts on its +own when a conversation grows too long, without you asking. + +**Your messages stay on screen, and that is intended.** Compaction adds a *Conversation compacted.* +line and removes nothing above it, so you keep the full transcript. + +What changes is what Kai reads. Everything above that line now reaches Kai as a summary, not as the +original messages. So you can scroll up and read a detail that Kai no longer has. + +Anything you type after the command steers the summary, which is worth doing when you know what +matters: + +``` +/compact keep the column mapping we worked out for the orders table +``` + +Compaction cannot be undone, so name what you need before you run it. For when to compact rather +than start a new chat, see [Manage Context](/kai/best-practices/#manage-context) in Best Practices. + +## Contextual Awareness + +Kai is aware of what you're currently viewing in the Keboola UI. Every message you send +includes your current page location, so Kai understands your context without needing +explicit references. + +- **Automatic context capture** — When you send a message, Kai receives your current URL path (e.g., which configuration, job, or table you're viewing) +- **Context-aware responses** — Kai uses this information to provide relevant suggestions and can reference "this configuration" or "the current job" naturally -This makes interactions more natural—you can say "analyze this job" while viewing a job, and Kai knows exactly which job you mean. When Kai investigates an issue across multiple configurations, you can follow along as it moves through your project. +This means you can say "analyze this job" while viewing a job, and Kai knows exactly +which job you mean. Turn on [Follow mode](#below-the-message-box) to watch it move through your project as +it works. ## Tips for New Users diff --git a/src/content/docs/kai/settings.md b/src/content/docs/kai/settings.md index 24cfee97c..b5a71c88f 100644 --- a/src/content/docs/kai/settings.md +++ b/src/content/docs/kai/settings.md @@ -98,7 +98,7 @@ This means user-level instructions can refine or add to the project-level instru ## Context Files -Context files (also called knowledge files) are Markdown documents that Kai reads automatically at the start of every conversation. Use them to give Kai project knowledge that is too long for system instructions: data standards, naming conventions, business glossaries, or documentation of your data model. +Context files (also called knowledge files) are Markdown documents that Kai reads automatically at the start of every conversation. Use them to give Kai project knowledge that is too long for system instructions: data standards, naming conventions, business glossaries, or documentation of your data model. For security reasons Kai cannot open links, so anything it needs to read has to arrive as a file — context files are the place for documentation it should have in every conversation, such as the API reference for a system you integrate with repeatedly. To manage them, go to **Settings → Kai Agent** in the main Keboola navigation and use the **Context files** card: diff --git a/src/integrations/beacon-transforms.mjs b/src/integrations/beacon-transforms.mjs index 557259a50..1f4dabc06 100644 --- a/src/integrations/beacon-transforms.mjs +++ b/src/integrations/beacon-transforms.mjs @@ -557,6 +557,14 @@ function transformGlossaryList(tree) { if (!para?.children?.length) continue; const [term, ...rest] = para.children; if (!rest.length) continue; + // The em dash is only the delimiter that identifies this shape in Markdown. + // Once the list is a 2-col grid, the columns do the separating, so strip it — + // otherwise every definition renders as "— definition". + if (rest[0].type === 'text') { + rest[0].value = rest[0].value.replace(/^\s*(—|–|--|-)\s+/, ''); + if (!rest[0].value) rest.shift(); + } + if (!rest.length) continue; para.children = [ term, {