Skip to content
AI

AI

Chat, answers and natural-language actions with any model. The AI can run your app's commands as tools.

Add one option and your command bar becomes an assistant that can act on the user’s behalf:

import { createQikbar, proxy } from '@qikbar/qikbar'

createQikbar({
  routes,
  commands,
  sources,
  ai: proxy('/api/qikbar'), // or anthropic(), openai(), gemini(), byok()…
})

What users get

  • Ask AI from anywhere. Type a question and press Tab, or pick the Ask AI fallback at the bottom of the results.
  • Natural-language actions. “Take me to billing”, “open the Apollo project”, “invite sam@acme.co as an admin”. The model calls your commands and sources as tools.
  • Page awareness. “Summarize this page” or “what does this error mean?” The model can read the current page if you allow it.
  • Follow-ups. The chat keeps context. Esc stops a response, and pressing it again goes back.

How it works

When a chat starts, Qikbar builds a system prompt with the page title, the current path, and a compact list of your commands (id, title, section). It also gives the model these tools:

Tool What it does
search Searches commands, routes and every source, and returns items with ids
run Runs an item’s primary action by id: navigates, runs code, or opens a view
read_page Returns the visible text of the current page (turn off with pageContext: false)
Your tools Anything in tools or in an extension’s tools

The model runs in a loop. It streams text, calls tools, reads the results and continues, for up to maxSteps steps. Each tool call shows up as a small chip in the chat (“Opening Billing”, “Searching ‘acme’”). Destructive actions and tools marked confirm ask the user before running.

Options

createQikbar({
  ai: {
    provider: anthropic({ apiKey }),   // required
    name: 'Acme AI',                   // label in the UI, default "AI"
    system: 'Our product is called Acme. Be friendly.', // added to the system prompt
    fallback: true,                    // show "Ask AI" in results, default true
    tools: true,                       // let the model run commands, default true
    pageContext: true,                 // allow read_page, default true
    maxSteps: 6,                       // tool-calling steps per message
    suggestions: ['What can I do here?', 'Open my latest invoice'],
  },
})

Passing a provider directly (ai: anthropic()) uses the defaults.

Choosing where the key lives

Setup Use when Key exposure
proxy() + createHandler Production apps paying for AI Server only ✅
byok() Users bring their own key Each user’s own browser
anthropic({ apiKey }) in the browser Prototypes, internal tools, local dev Visible to anyone who opens devtools ⚠️
browserAI() Free, private, on-device None

An API key in browser code is public. Anyone can copy it from devtools. Use a server proxy for anything real.

Using AI in your own commands

ctx.ai is available everywhere:

{
  title: 'Write release notes',
  icon: 'wand',
  run: (ctx) => detail({
    title: 'Release notes',
    markdown: ctx.ai!.stream(`Write release notes for these commits:\n${commits}`),
  }),
}

ctx.ai.ask(prompt) returns the whole answer as a promise. ctx.ai.stream(prompt) returns an async iterable you can pass straight to a detail view.

The aiActions() extension adds Summarize This Page, Explain Selected Text and Translate.

Opening a chat from code

bar.ask('How do I invite my team?')                     // opens and sends
bar.open({ view: chat({ system: 'You are a SQL expert.' }) }) // empty chat with a custom prompt

Privacy

Qikbar sends nothing anywhere unless you configure a provider. When a chat runs, the provider receives the conversation, the page title and path, and your command titles. It receives page text only if the model calls read_page, and search results only if it calls search. Turn tools off with tools: false for a plain chat.

Edit this page on GitHub