One attribute, full context
Add data-askable to any element. The library tracks focus, click, and hover interactions and serializes exactly what the user is looking at into a string your LLM can act on.
Annotate any DOM element with data-askable and instantly turn what the user is looking at into structured, prompt-ready context.
Current npm release: v0.12.0.
Need a breaking-release upgrade path? See Migration Guides. Versioned docs are available at
/docs/<version>/.
shape: 'lasso' for freehand-selected page regionsregisterSource() resolvers plus source helper factories for app-owned contexttoPromptContextAsync(), toContextAsync(), and toContextPacketAsync()toAgentRequest()subscribeAsync()^0.12.0Askable can capture context at different levels of user intent:
| Pattern | Use it when | API |
|---|---|---|
| Element focus | The user clicks, hovers, or tabs into annotated UI | data-askable, ctx.observe() |
| Ask AI button | A known widget should be selected before opening chat | ctx.select(element) |
| App event | Your code already knows the semantic object | ctx.push(meta, text) |
| Region | The user wants to mark a rectangular area | createAskableRegionCapture() |
| Circle | The user wants to point at an anomaly or object | shape: 'circle' |
| Lasso | The user wants to freehand-select an irregular area | shape: 'lasso' |
| Highlighted text | The user wants to send selected copy | createAskableTextSelectionCapture() |
Every pattern can produce a prompt string with toPromptContext() or a structured Context packet with toContextPacket().
Start here:
import { createAskableContext } from '@askable-ui/core';
const ctx = createAskableContext();
ctx.observe(document);
// Anywhere in your AI handler:
ctx.toPromptContext();
// → "User is focused on: metric: revenue, delta: -12%, period: Q3"import { useAskable, Askable } from '@askable-ui/react';
function Dashboard({ data }) {
const { promptContext } = useAskable();
return (
<Askable meta={{ metric: 'revenue', delta: data.delta }}>
<RevenueChart data={data} />
</Askable>
);
}import { Pressable, Text } from 'react-native';
import { useAskable, Askable } from '@askable-ui/react-native';
function RevenueCard() {
const { ctx, promptContext } = useAskable();
return (
<Askable ctx={ctx} meta={{ metric: 'revenue' }} text="Revenue card">
<Pressable>
<Text>Revenue</Text>
</Pressable>
</Askable>
);
}<script setup>
import { useAskable, Askable } from '@askable-ui/vue';
const { promptContext } = useAskable();
</script>
<template>
<Askable :meta="{ metric: 'revenue', delta: data.delta }">
<RevenueChart :data="data" />
</Askable>
</template><script>
import { createAskableStore, Askable } from '@askable-ui/svelte';
const { promptContext } = createAskableStore();
</script>
<Askable meta={{ metric: 'revenue', delta: data.delta }}>
<RevenueChart {data} />
</Askable>