Skip to content

Agent store

import { Aside } from ‘@astrojs/starlight/components’;

Add a Claude-powered chat assistant to any artifact. Access via sdk.agent.

At publish time, add an agent block to the publish payload:

{
"name": "My Dashboard",
"files": [...],
"agent": {
"enabled": true,
"systemPrompt": "You are a data analyst. Answer only from the data provided.",
"model": "claude-sonnet-4-20250514",
"contextJson": true,
"contextTables": ["sales"]
}
}

Or after publish via API (owner token):

PUT /v1/data/{artifactId}/agent/config
Content-Type: application/json
{
"visitor_enabled": true,
"visitor_system_prompt": "You are a helpful assistant.",
"visitor_model": "claude-sonnet-4-20250514",
"visitor_context_tables": ["sales"]
}

Partial PUT bodies are safe — omitted fields keep their existing values, so you can toggle one setting without resending the full config.

configure(config: AgentConfig): void
chat(options: ChatMessage): AsyncGenerator<ChatChunk>
// Conversation management
conversations.list(options?: { limit?: number; offset?: number }):
Promise<{ conversations: Conversation[]; total: number }>
conversations.get(id: string):
Promise<{ conversation: Conversation; messages: unknown[] }>
conversations.delete(id: string): Promise<{ deleted: boolean }>
// Pre-built widget
widget.mount(selector: string, options?: WidgetOptions): void
widget.unmount(): void
widget.toggle(): void
widget.setTheme(theme: 'light' | 'dark' | 'auto'): void
interface AgentConfig {
systemPrompt?: string;
model?: 'claude-sonnet-4-20250514' | 'claude-3-5-haiku-20241022';
maxTokens?: number;
temperature?: number;
context?: { json?: boolean; tables?: string[]; blobs?: boolean };
}
interface ChatMessage {
message: string;
conversationId?: string;
context?: Record<string, unknown>; // Live page data for this turn (~200 KB cap)
}
interface ChatChunk {
type: 'content' | 'done' | 'error';
content?: string;
conversationId?: string;
usage?: { input_tokens: number; output_tokens: number };
error?: string;
}
interface WidgetOptions {
position?: 'bottom-right' | 'bottom-left' | 'inline';
theme?: 'light' | 'dark' | 'auto';
placeholder?: string;
welcomeMessage?: string;
minimized?: boolean;
}
const sdk = await ShareOut.create();
sdk.agent.widget.mount('#chat', {
position: 'bottom-right',
theme: 'auto',
welcomeMessage: 'Hi! How can I help?',
});
const sdk = await ShareOut.create();
let conversationId = null;
async function send(text) {
let reply = '';
for await (const chunk of sdk.agent.chat({
message: text,
conversationId,
})) {
if (chunk.type === 'content') {
reply += chunk.content;
output.textContent = reply;
} else if (chunk.type === 'done') {
conversationId = chunk.conversationId;
}
}
}

Pass a snapshot of on-screen state each turn so the agent answers from current data, not just stored tables:

function snapshot() {
return { filters: activeFilters, kpis: computedKpis, series: chartRows };
}
for await (const chunk of sdk.agent.chat({
message: userText,
context: snapshot(),
})) {
if (chunk.type === 'content') append(chunk.content);
}
LimitDefault
Requests/min10 per artifact
Tokens/day100,000 per artifact

Exceeded returns HTTP 429 with Retry-After header and error code RATE_LIMIT_EXCEEDED.