Skip to content

Latest commit

 

History

History
285 lines (208 loc) · 9.07 KB

File metadata and controls

285 lines (208 loc) · 9.07 KB

askable-ui

askable-ui

Two lines of code to give your LLM eyes.
One attribute. Zero prompt engineering. It knows exactly what the user sees.

npm version npm downloads MIT license CI PRs welcome

askable-promo.mp4

Quick Start  ·  Why  ·  How it works  ·  Works with  ·  Features  ·  Packages  ·  Docs  ·  Agent Templates  ·  Live Demo


Quick start

npm install @askable-ui/react

Want a runnable Askable + CopilotKit starter app instead?

npx create-askable-app my-app
cd my-app
npm install
npm run dev
import { Askable, useAskable } from '@askable-ui/react';

function Dashboard({ kpi }) {
  const { promptContext } = useAskable();
  // promptContext: "User is focused on: metric=revenue, value=$2.3M, delta=+12%"

  return (
    <Askable meta={{ metric: kpi.name, value: kpi.value, delta: kpi.delta }}>
      <KPICard data={kpi} />
    </Askable>
  );
}

That's it. promptContext updates automatically as the user interacts. Pass it to any LLM.


Why

AI copilots ask users to describe what they're looking at. That's friction — and it's imprecise.

askable-ui solves this with one HTML attribute. Mark any element with data-askable, and the library tracks user focus and serializes it into a prompt-ready string. The model gets the user's exact visual context — not a guess, the real thing.

No page scraping. No DOM serialization. No prompt bloat. Lightweight and zero-dependency.


How it works

1. Annotate — same data that renders your chart feeds the AI

<Askable meta={{ metric: 'revenue', value: '$2.3M', delta: '+12%', period: 'Q3' }}>
  <RevenueChart data={data} />
</Askable>

2. Observe — automatic, zero config

const { ctx, promptContext } = useAskable();
// promptContext updates whenever the user clicks, hovers, or focuses

const { ctx: tableCtx } = useAskable({ name: 'table' });
const { ctx: chartCtx } = useAskable({ name: 'chart' });
// named contexts stay isolated for multi-region pages

const { ctx: screenCtx } = useAskable({ viewport: true });
// screenCtx.toViewportContext() serializes currently visible annotated elements

3. Inject — at the AI boundary, one line

const result = await streamText({
  model: openai('gpt-4o'),
  system: `You are a helpful analytics assistant.\n\n${promptContext}`,
  messages,
});

Works with

LLM SDKs — OpenAI · Anthropic · Vercel AI SDK · CopilotKit · LangChain · any SDK

Frameworks — React · Vue 3 · Svelte · Vanilla JS · Next.js · Nuxt · SvelteKit

askable-ui is the context layer. It doesn't replace your LLM SDK — it gives it eyes.


Features

  • Zero config — one attribute, works with any DOM structure, styling system, or component library
  • React, Vue, Svelte — idiomatic hooks and components; core is framework-agnostic
  • SSR safe — defers to client lifecycle, no window is not defined
  • "Ask AI" buttonctx.select(element) pins focus to any element programmatically
  • Conversation historyctx.toHistoryContext(n) for multi-turn context
  • Viewport awarenessctx.getVisibleElements() / ctx.toViewportContext() for on-screen context
  • Redaction hooks — strip sensitive fields before data reaches serialization
  • Inspector panel<AskableInspector /> or useAskable({ inspector: true }) for a live dev overlay
  • Agent templates — reusable AGENTS.md guidance and copy-paste prompts for coding-agent-driven adoption
  • Lightweight core — zero runtime dependencies

Packages

Package Version Use when
@askable-ui/core npm Vanilla JS, custom framework, or as a peer dep
@askable-ui/react npm React 18+
@askable-ui/react-native npm React Native (initial press-driven adapter)
@askable-ui/vue npm Vue 3
@askable-ui/svelte npm Svelte 4 & 5
create-askable-app npm package React + Vite + CopilotKit starter scaffold
Framework quick starts

React Native

npm install @askable-ui/react-native
import { Pressable, Text } from 'react-native';
import { Askable, useAskable } from '@askable-ui/react-native';

function RevenueCard() {
  const { ctx, promptContext } = useAskable();

  return (
    <Askable ctx={ctx} meta={{ widget: 'revenue' }} text="Revenue card">
      <Pressable>
        <Text>Revenue</Text>
      </Pressable>
    </Askable>
  );
}

For a runnable mobile demo, see examples/react-native-expo.

Vue 3

npm install @askable-ui/vue
<script setup>
import { Askable, useAskable } from '@askable-ui/vue';
const { promptContext } = useAskable();
const props = defineProps(['kpi']);
</script>

<template>
  <Askable :meta="{ metric: kpi.name, value: kpi.value }">
    <KPICard :data="kpi" />
  </Askable>
</template>

Svelte

npm install @askable-ui/svelte
<script>
  import { Askable, useAskable } from '@askable-ui/svelte';
  const { promptContext } = useAskable();
  export let kpi;
</script>

<Askable meta={{ metric: kpi.name, value: kpi.value }}>
  <KPICard data={kpi} />
</Askable>

Vanilla JS

npm install @askable-ui/core
import { createAskableContext } from '@askable-ui/core';

const ctx = createAskableContext();
ctx.observe(document.body);

ctx.on('focus', () => {
  console.log(ctx.toPromptContext());
  // "User is focused on: — metric: revenue, value: $2.3M"
});

Live links


Documentation

askable-ui.com/docs

Guide
Getting started Install, observe, inject
Annotating elements data-askable, nesting, priority
React · Vue · Svelte Framework guides
CopilotKit integration Context-in-input pattern
API reference Full type docs

Using with coding agents

AGENTS.md contains copy-pasteable instructions for Claude, Cursor, Codex, and similar tools. Drop it into your project root and your coding agent will know how to integrate askable-ui correctly — annotation patterns, passive vs explicit flows, sanitization, and common mistakes.


Contributing

PRs welcome! See CONTRIBUTING.md for setup instructions.

License

MIT — see LICENSE