Skip to content

Core API

Full API reference for @store-ai/core.

createAIStore(options?)

Creates a new AI store instance.

typescript
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.

typescript
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.

typescript
// 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.

typescript
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

typescript
// With a provider adapter (parses SSE)
store.submit({ message: 'Hello', stream: response.body });

// Direct events (skip parsing)
store.submit({ events: myAsyncGenerator() });

Non-streaming

typescript
// 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.

typescript
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.

Released under the MIT License.