Core API
Full API reference for @store-ai/core.
createAIStore(options?)
Creates a new AI store instance.
interface AIStoreOptions<T = unknown> {
provider?: ProviderAdapter;
middleware?: Middleware[];
schema?: ZodType<T>;
initialMessages?: Message[];
batchStrategy?: 'microtask' | 'raf' | 'sync' | ((notify: () => void) => void);
}
function createAIStore<T = unknown>(options?: AIStoreOptions<T>): AIStore<T>;store.get(key?)
Read current state or a specific key.
store.get(); // full AIState
store.get('text'); // string
store.get('status'); // "idle" | "streaming" | ...
store.get('messages'); // Message[]store.subscribe(listener) / store.subscribe(key, listener)
Subscribe to state changes. Returns an unsubscribe function.
// Full state
const unsub = store.subscribe((state, prev) => { ... });
// Specific key (only fires when that key changes)
const unsub = store.subscribe('text', (text, prevText) => { ... });store.submit(input)
Start a new stream or process a complete response. Returns a StreamHandle with abort() and signal.
interface SubmitInput {
messages?: Message[];
message?: string;
response?: CompleteResponse;
stream?: ReadableStream;
events?: ReadableStream<StreamEvent> | AsyncIterable<StreamEvent>;
body?: Record<string, unknown>;
signal?: AbortSignal;
headers?: Record<string, string>;
}
interface CompleteResponse {
text?: string;
thinking?: string;
toolCalls?: { id: string; name: string; input: unknown }[];
object?: DeepPartial<unknown> | null;
usage?: Partial<TokenUsage>;
finishReason?: FinishReason;
}Streaming
// With a provider adapter (parses SSE)
store.submit({ message: 'Hello', stream: response.body });
// Direct events (skip parsing)
store.submit({ events: myAsyncGenerator() });Non-streaming
// Complete response — no streaming needed
store.submit({
message: 'Hello',
response: {
text: 'Hi there!',
toolCalls: [{ id: 'tc-1', name: 'search', input: { q: 'cats' } }],
object: { items: [{ name: 'cat' }] },
usage: { inputTokens: 100, outputTokens: 50 },
},
});The response is internally converted to stream events, so all middleware (persistence, logging, cost tracking) works identically.
store.abort()
Abort the active stream. Status transitions to "aborted". Accumulated text and messages are preserved.
store.reset()
Reset state to initial values. Aborts any active stream.
store.retry()
Re-submit the last request. Returns a new StreamHandle.
store.setMessages(messages)
Replace the message history.
store.addToolResult(toolCallId, result)
Provide a result for a pending tool call.
store.use(middleware)
Add middleware at runtime. Returns an unsubscribe function.
store.destroy()
Clean up all subscriptions, abort active streams, release resources.
createChatManager(defaults?)
Create a multi-chat coordinator. See the Multi-Chat guide.
restoreChat(storage, chatId)
Restore a previously persisted conversation. Returns SerializedChat | null.
listChats(storage)
List all persisted chat IDs from a storage adapter.
deleteChat(storage, chatId)
Delete a persisted conversation.
createPartialJSONParser<T>()
Create an incremental JSON parser for streaming structured output.
const parser = createPartialJSONParser<MyType>();
parser.push('{"name": "Jo'); // { name: "Jo" }
parser.push('hn"}'); // { name: "John" }
parser.getFinal(); // { name: "John" }
parser.reset();State Types
See the Core Concepts guide for full type definitions of AIState, Message, MessageContent, ToolCallState, TokenUsage, and LatencyInfo.