Skip to content

@helix-agents/ai-sdk

Vercel AI SDK UI binding layer for Helix Agents. Transforms Helix internal streaming protocol to AI SDK UI Data Stream protocol for use with useChat and other AI SDK React hooks.

Installation

bash
npm install @helix-agents/ai-sdk

v7 surface map

ExportModulePurpose
handleChatStream@helix-agents/ai-sdkServer-side seven-path orchestrator. Canonical v7 chat entry point.
extractResumeIntent@helix-agents/ai-sdkParse resume signals from incoming AI SDK v6 messages
findExpiredPending@helix-agents/ai-sdkSurface client-tool calls past their deadline
prepareHelixChatRequest@helix-agents/ai-sdk/clientPrepareSendMessagesRequest for DefaultChatTransport
prepareHelixReconnectRequest@helix-agents/ai-sdk/clientPrepareReconnectToStreamRequest for DefaultChatTransport
useResumeClientTools@helix-agents/ai-sdk/reactReact hook auto-dispatching client-executed tool calls
createHelixChatTransport@helix-agents/ai-sdkChatTransport that talks directly to @helix-agents/agent-server
buildSnapshot@helix-agents/ai-sdkStandalone SSR snapshot helper (replaces FrontendHandler.getSnapshot)
getUIMessages@helix-agents/ai-sdkStandalone message-history loader (replaces FrontendHandler.getMessages)
createCloudflareChatHandler@helix-agents/ai-sdk/cloudflareFactory wiring handleChatStream to a Cloudflare Durable Object backend
pipeWebResponseToExpress@helix-agents/ai-sdkPipe a web Response (from handleChatStream) into an Express response
createWebResponseExpressMiddleware@helix-agents/ai-sdkExpress middleware adapter for handleChatStream-style handlers
StreamTransformer@helix-agents/ai-sdkHelix chunk → AI SDK Data Stream event converter
convertToAISDKMessages@helix-agents/ai-sdkHelix Message[] → AI SDK v6 UIMessage[] converter
loadUIMessages / loadAllUIMessages@helix-agents/ai-sdkDirect loaders from a SessionStateStore
Recovery hooks (useResumableChat, useAutoResync, ...)@helix-agents/ai-sdk/reactSnapshot loading + resync handling

handleChatStream

The canonical v7 entry point. Takes the parsed { sessionId, messages } body (plus the incoming Request) and dispatches to one of seven paths, returning a web Response with an SSE body.

Signature

typescript
function handleChatStream(
  deps: HandleChatStreamDeps,
  params: HandleChatStreamParams
): Promise<Response>;

HandleChatStreamDeps

typescript
interface HandleChatStreamDeps {
  executor: MinimalExecutor;
  stateStore: MinimalStateStore;
  streamManager: MinimalStreamManager;
  /**
   * `AnyAgentConfig` for in-process integrations; pass a
   * `MinimalAgentConfig` (`{ name, type }`) when the agent runs in a
   * remote runtime and only routing info is available.
   */
  agent: AnyAgentConfig | MinimalAgentConfig;
  /** Optional structured logger. Defaults to noop. */
  logger?: Logger;
  /** Forwarded to the StreamTransformer when streaming back to the client. */
  transformerOptions?: StreamTransformerOptions;
  /** Max accepted request body size (default 10 MB). Checked against Content-Length. */
  maxRequestBytes?: number;
}

HandleChatStreamParams

typescript
interface HandleChatStreamParams {
  sessionId: string;
  /** Incoming AI SDK v6 messages. Only the tail is inspected. */
  messages: readonly UIMessage[];
  /** Forwarded to executor.execute as `userId`. */
  userId?: string;
  /** Forwarded to executor.execute / resume as metadata. */
  metadata?: Record<string, string>;
  /**
   * Optional incoming Request. When provided, the orchestrator extracts
   * `X-Resume-From-Sequence` / `Last-Event-ID` / `X-Existing-Message-Id`
   * from its headers — required for path 5 (active-stream attach) and
   * path 6 (already-completed retry).
   */
  request?: Request;
  /** Explicit override for `X-Resume-From-Sequence`. */
  resumeFromSequence?: number;
  /** Explicit override for `X-Existing-Message-Id`. */
  existingMessageId?: string;
}

The seven dispatch paths

  1. Fresh new sessionexecutor.execute()
  2. Continuing session, new user messageexecutor.execute() with sessionId
  3. Resume after tool / approval submitsubmitToolResult × N, then executor.resume()
  4. Abandonment recovery → fail every pending tool, then path 2
  5. Active-stream attach → passive subscriber on a running run
  6. Already-completed retry → terminal stream replay
  7. Stale runId rejection → SSE response with data-resume-rejected

Example

typescript
import { handleChatStream } from '@helix-agents/ai-sdk';

export async function POST(req: Request, { params }: { params: { sessionId: string } }) {
  const body = await req.json();
  return handleChatStream(
    { executor, stateStore, streamManager, agent: MyAgent },
    {
      sessionId: params.sessionId,
      messages: body.messages ?? [],
      request: req,
    }
  );
}

prepareHelixChatRequest

A PrepareSendMessagesRequest factory for use with the AI SDK v6 DefaultChatTransport. Forwards AI SDK fields (id, messages, trigger, messageId) onto the request body and stamps X-Resume-From-Sequence / X-Existing-Message-Id headers the chat orchestrator uses to dispatch.

Signature

typescript
function prepareHelixChatRequest<UI_MESSAGE extends UIMessage = UIMessage>(
  opts: PrepareHelixChatRequestOptions
): PrepareSendMessagesRequest<UI_MESSAGE>;

PrepareHelixChatRequestOptions

typescript
interface PrepareHelixChatRequestOptions {
  /** API endpoint path. Mirrors DefaultChatTransport's `api` field. */
  api: string;
  /** Sequence to resume from (X-Resume-From-Sequence). */
  resumeFromSequence?: number;
  /** Assistant message id to continue (X-Existing-Message-Id). */
  existingMessageId?: string;
  /** Static body fields merged underneath the AI SDK fields. */
  body?: Record<string, unknown>;
}

Example

typescript
import { DefaultChatTransport } from 'ai';
import { prepareHelixChatRequest } from '@helix-agents/ai-sdk/client';

const transport = new DefaultChatTransport({
  api: '/api/chat/abc',
  prepareSendMessagesRequest: prepareHelixChatRequest({
    api: '/api/chat/abc',
    resumeFromSequence: snapshot.streamSequence,
    existingMessageId: lastAssistantId,
  }),
});

prepareHelixReconnectRequest

A PrepareReconnectToStreamRequest factory. The Helix chat handler reuses ONE path for both POST (new messages) and GET (stream resume), so the AI SDK's default reconnect URL — ${api}/${chatId}/stream — does not match the route. Without overriding the reconnect, page-refresh-during-stream silently 404s and any tool that hadn't completed stays pending in the UI forever.

Signature

typescript
function prepareHelixReconnectRequest(
  opts: PrepareHelixChatRequestOptions
): PrepareReconnectToStreamRequest;

Same options shape as prepareHelixChatRequest.

Example

typescript
import { DefaultChatTransport } from 'ai';
import { prepareHelixChatRequest, prepareHelixReconnectRequest } from '@helix-agents/ai-sdk/client';

const helixOptions = {
  api: '/api/chat/abc',
  resumeFromSequence: snapshot.streamSequence,
  existingMessageId: lastAssistantId,
};

const transport = new DefaultChatTransport({
  api: '/api/chat/abc',
  prepareSendMessagesRequest: prepareHelixChatRequest(helixOptions),
  prepareReconnectToStreamRequest: prepareHelixReconnectRequest(helixOptions),
});

useResumeClientTools

React hook that auto-dispatches client-executed tool calls surfaced by AI SDK v6 useChat and reports the results back to the chat. Replaces ~280 LOC of consumer dispatcher boilerplate.

Signature

typescript
function useResumeClientTools(options: UseResumeClientToolsOptions): void;

UseResumeClientToolsOptions

typescript
interface UseResumeClientToolsOptions {
  chat: ResumeClientToolsChat; // Returned by useChat()
  toolHandlers: Record<string, ResumeClientToolHandler>;
  onError?: (err: unknown, ctx: { toolName: string; toolCallId: string }) => void;
}

type ResumeClientToolHandler = (
  input: unknown,
  ctx: { toolCallId: string; abortSignal: AbortSignal }
) => Promise<unknown>;

Behavior

  • Watches chat.messages for tool parts in state: 'input-available' on the LAST assistant message.
  • Dispatches handlers in parallel; each call dispatches at most once per Chat instance.
  • On Chat-instance identity change (e.g. session switch), in-flight handlers are aborted and dispatch state is cleared.
  • Skips approval-requested parts (those route through chat.addToolApprovalResponse) and parts whose tool name has no registered handler.
  • On success: chat.addToolOutput({ state: 'output-available', tool, toolCallId, output }).
  • On failure: chat.addToolOutput({ state: 'output-error', tool, toolCallId, errorText }) plus onError callback if provided.

Example

tsx
import { useChat } from '@ai-sdk/react';
import { useResumeClientTools } from '@helix-agents/ai-sdk/react';

const chat = useChat({ id: sessionId, transport });

useResumeClientTools({
  chat,
  toolHandlers: {
    editContent: async (input, { toolCallId, abortSignal }) => {
      const result = await runOnClient(input, abortSignal);
      return result;
    },
  },
  onError: (err, ctx) => console.error(`tool ${ctx.toolName} failed`, err),
});

extractResumeIntent

Parse incoming AI SDK v6 messages to determine which (if any) are resume signals — client-tool results or approval responses — for currently-pending tool calls.

Signature

typescript
function extractResumeIntent(
  messages: readonly UIMessage[],
  sessionState: SessionState | null,
  currentRunId: string | undefined
): ExtractResumeIntentResult;

Result types

typescript
interface ExtractResumeIntentResult {
  intents: ResumeIntent[];
  rejected: ResumeIntentRejection[];
  hasTrailingUserMessage: boolean;
}

type ResumeIntent =
  | {
      kind: 'client-tool-result';
      runId: string;
      toolCallId: string;
      output?: unknown;
      errorText?: string;
    }
  | {
      kind: 'approval-response';
      runId: string;
      toolCallId: string;
      approvalId: string;
      approved: boolean;
      reason?: string;
    };

type ResumeIntentRejection =
  | { reason: 'stale-run'; runId: string; toolCallId: string; currentRunId: string }
  | { reason: 'unknown-tool-call'; toolCallId: string }
  | { reason: 'malformed-approval-id'; approvalId: string };

Behavior notes

  • Only the LAST assistant message is inspected (Mastra invariant — stale resumes from earlier turns are ignored).
  • Only output-available, output-error, and approval-responded part states qualify as resume signals. Other states are skipped silently.
  • runId priority: parsed from ${runId}::${toolCallId} for approvals, then callProviderMetadata.helix.runId for client-tool results, then currentRunId. Mismatches surface as 'stale-run' rejections.

handleChatStream calls this internally; consumers calling it directly are wiring their own custom server.

findExpiredPending

Sweep a pendingClientToolCalls map for entries past their deadline.

Signature

typescript
function findExpiredPending(
  pendingClientToolCalls: Record<string, PendingClientToolCall>
): string[];

Returns an array of toolCallIds whose deadlineAt has elapsed. Defensive against malformed entries: non-finite deadlineAt values are not treated as expired.

Example

typescript
import { findExpiredPending } from '@helix-agents/ai-sdk';

const expired = findExpiredPending(sessionState.pendingClientToolCalls);
for (const toolCallId of expired) {
  await executor.submitToolResult({
    sessionId,
    toolCallId,
    error: 'client_tool_deadline_exceeded',
  });
}

handleChatStream calls this internally before resume detection (deadline-sweep step).

createHelixChatTransport

A Vercel AI SDK v6 ChatTransport that talks directly to the HTTP endpoints exposed by @helix-agents/agent-server (/start, /resume, /submit-tool-result, /status, /sse). Use this when you don't want to implement a single chat route on top of handleChatStream.

Signature

typescript
function createHelixChatTransport(opts: HelixChatTransportOptions): HelixChatTransport;

HelixChatTransportOptions

typescript
interface HelixChatTransportOptions {
  /** Base URL for the agent-server, e.g. '/api/agent'. */
  endpoint: string;
  /** Session identifier. Stable across the chat lifetime. */
  sessionId: string;
  /** Agent type (required on first /start; ignored on /resume). */
  agentType?: string;
  /** Per-request auth headers. */
  getAuthHeaders?: () => Record<string, string>;
  /** Override fetch (for tests). */
  fetch?: typeof globalThis.fetch;
}

Returned HelixChatTransport

typescript
interface HelixChatTransport {
  sendMessages(options: {
    messages: UIMessage[];
    trigger: 'submit-message' | 'regenerate-message';
    chatId: string;
    messageId: string | undefined;
    abortSignal: AbortSignal | undefined;
  }): Promise<ReadableStream<UIMessageChunk>>;
  reconnectToStream(options: {
    chatId: string;
    abortSignal?: AbortSignal;
  }): Promise<ReadableStream<UIMessageChunk> | null>;
  /**
   * Bypass AI SDK's `addToolOutput` auto-fire timing constraints to
   * submit a client-tool result while the SSE stream is still active.
   */
  submitToolResult(
    params: { sessionId?: string; toolCallId: string; result?: unknown; error?: string },
    abortSignal?: AbortSignal
  ): Promise<SubmitToolResultResponse>;
}

Example

tsx
import { useChat } from '@ai-sdk/react';
import { lastAssistantMessageIsCompleteWithToolCalls } from 'ai';
import { createHelixChatTransport } from '@helix-agents/ai-sdk';

const transport = createHelixChatTransport({
  endpoint: '/api/agent',
  sessionId: 'my-session',
  agentType: 'my-agent',
});

const { messages, addToolOutput } = useChat({
  transport,
  sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
  async onToolCall({ toolCall }) {
    if (toolCall.toolName === 'editContent') {
      const result = await runOnClient(toolCall.input);
      addToolOutput({
        tool: 'editContent',
        toolCallId: toolCall.toolCallId,
        output: result,
      });
    }
  },
});

This transport is separate from the prepareHelixChatRequest / prepareHelixReconnectRequest helpers, which are for DefaultChatTransport against the in-framework chat handler endpoints (those handlers already serve UIMessageChunks directly).

buildSnapshot

Standalone SSR-hydration snapshot helper. Replaces the v7 FrontendHandler.getSnapshot method. Implements the "sequence last" pattern, content replay (so partial mid-stream content isn't double-rendered), and stream-status detection.

Signature

typescript
function buildSnapshot<TState>(
  deps: BuildSnapshotDeps,
  params: { sessionId: string; includeThinking?: boolean } & Partial<SnapshotOptions>
): Promise<FrontendSnapshot<TState> | null>;

Returns null when the session doesn't exist.

BuildSnapshotDeps

typescript
interface BuildSnapshotDeps {
  stateStore: MinimalStateStore;
  streamManager: MinimalStreamManager;
  logger?: Logger;
  /**
   * When true, follow-up turns (currentRun.startSequence > 0) skip
   * including partial content in the snapshot (the live stream provides
   * it). First turns always include partial content.
   */
  contentReplayEnabled?: boolean;
  transformerOptions?: StreamTransformerOptions;
}

BuildSnapshotDeps omits executor and agent (this is a read-only helper that never invokes the executor or routes by agent config). A caller sharing a single deps object with handleChatStream can still pass the larger object — structural typing tolerates excess properties.

FrontendSnapshot

typescript
interface FrontendSnapshot<TState = unknown> {
  sessionId: string;
  state: TState | null;
  messages: UIMessage[];
  streamSequence: number;
  timestamp: number;
  status: 'active' | 'paused' | 'ended' | 'failed';
  checkpointId: string | null;
  stepCount: number;
  startSequence?: number;
  startMessageCount?: number;
}

Example

typescript
import { buildSnapshot } from '@helix-agents/ai-sdk';

const deps = { executor, stateStore, streamManager, agent: MyAgent, contentReplayEnabled: true };

const snapshot = await buildSnapshot<MyState>(deps, { sessionId });
if (!snapshot) {
  // session does not exist
}

getUIMessages

Standalone paginated message-history loader. Replaces the v7 FrontendHandler.getMessages method.

Signature

typescript
function getUIMessages(
  deps: GetUIMessagesDeps,
  params: GetUIMessagesParams
): Promise<GetUIMessagesResult>;

interface GetUIMessagesDeps {
  stateStore: MinimalStateStore;
  logger?: Logger;
}

interface GetUIMessagesParams {
  sessionId: string;
  offset?: number;
  limit?: number;
  includeThinking?: boolean;
  generateId?: (index: number, message: Message) => string;
}

Example

typescript
import { getUIMessages } from '@helix-agents/ai-sdk';

const { messages, hasMore } = await getUIMessages(
  { stateStore },
  { sessionId, offset: 0, limit: 50, includeThinking: true }
);

createCloudflareChatHandler

Factory wrapping handleChatStream / buildSnapshot / getUIMessages with Cloudflare Durable Object adapter clients. Imported from the @helix-agents/ai-sdk/cloudflare subpath.

typescript
import { createCloudflareChatHandler } from '@helix-agents/ai-sdk/cloudflare';

const chat = createCloudflareChatHandler({
  namespace: env.AGENTS,
  agentName: 'chat-agent',
});

// POST /chat
const response = await chat.handleChat({
  sessionId,
  messages,
  request,
});

// GET /snapshot
const snapshot = await chat.getSnapshot({ sessionId });

// GET /messages
const { messages, hasMore } = await chat.getMessages({ sessionId, offset: 0, limit: 50 });

See CloudflareChatHandlerOptions / CloudflareChatHandler in @helix-agents/ai-sdk/cloudflare for the full type surface.

StreamTransformer

Transforms Helix stream chunks to AI SDK UI events.

typescript
import { StreamTransformer } from '@helix-agents/ai-sdk';

const transformer = new StreamTransformer({
  generateMessageId: (agentId) => `msg-${agentId}`,
  includeStepEvents: false,
  chunkFilter: (chunk) => chunk.type !== 'state_patch',
  logger: console,
  startMetadata: { requestId: 'req-123', source: 'web-ui' },
  finishMetadata: { model: 'claude-3', totalTokens: 150 },
});

for await (const chunk of helixStream) {
  const { events, sequence } = transformer.transform(chunk);
  for (const event of events) yield { event, sequence };
}

// Always finalize.
const { events } = transformer.finalize();

StreamTransformerOptions

OptionTypeDescription
generateMessageId(agentId: string) => stringGenerate unique message IDs
includeStepEventsbooleanInclude step-start/finish events (default: false)
chunkFilter(chunk: StreamChunk) => booleanFilter chunks before transformation
startMetadataRecord<string, unknown> | (agentId: string) => Record<string, unknown>Metadata for start event
finishMetadataRecord<string, unknown> | (agentId: string) => Record<string, unknown>Metadata for finish event
loggerLoggerOptional logger instance

Event Mapping

See Frontend AI SDK guide for the full mapping table.

Message Converter

Convert Helix messages to AI SDK v6 UIMessage format.

typescript
import { convertToAISDKMessages } from '@helix-agents/ai-sdk';

const uiMessages = convertToAISDKMessages(helixMessages, {
  generateId: (index, msg) => `msg-${index}`,
  includeReasoning: true,
  mergeToolResults: true,
});

UIMessage shape (AI SDK v6)

typescript
interface UIMessage {
  id: string;
  role: 'user' | 'assistant' | 'system';
  parts: UIMessagePart[];
  metadata?: Record<string, unknown>;
}

type UIMessagePart = UIMessageTextPart | UIMessageReasoningPart | UIMessageToolInvocationPart;

interface UIMessageToolInvocationPart {
  type: `tool-${string}` | 'dynamic-tool';
  toolCallId: string;
  input: Record<string, unknown>;
  state: ToolInvocationState;
  output?: unknown;
  errorText?: string;
}

type ToolInvocationState =
  | 'input-streaming'
  | 'input-available'
  | 'output-available'
  | 'output-error'
  | 'approval-pending'
  | 'approval-resolved';

Store Utilities

loadUIMessages

Paginated loading.

typescript
import { loadUIMessages } from '@helix-agents/ai-sdk';

const { messages, hasMore } = await loadUIMessages(stateStore, sessionId, {
  offset: 0,
  limit: 50,
  includeReasoning: true,
  includeToolResults: true,
  generateId: (index, msg) => `msg-${index}`,
});

Note: Paginated loading may not correctly merge tool results when a tool call and its result span different pages. Use loadAllUIMessages for guaranteed merging.

loadAllUIMessages

Load all messages (auto-paginates).

typescript
import { loadAllUIMessages } from '@helix-agents/ai-sdk';

const allMessages = await loadAllUIMessages(stateStore, sessionId, {
  includeReasoning: true,
  includeToolResults: true,
});

LoadUIMessagesOptions

typescript
interface LoadUIMessagesOptions {
  offset?: number;
  limit?: number;
  includeReasoning?: boolean;
  includeToolResults?: boolean;
  generateId?: (index: number, message: Message) => string;
}

createUIMessageStore

Wrapper for repeated access.

typescript
import { createUIMessageStore } from '@helix-agents/ai-sdk';

const uiStore = createUIMessageStore(stateStore);
const { messages, hasMore } = await uiStore.getUIMessages(sessionId);
const all = await uiStore.getAllUIMessages(sessionId);

State Mapping

typescript
import { mapToolStateToAISDK } from '@helix-agents/ai-sdk';

mapToolStateToAISDK('pending'); // 'input-available'
mapToolStateToAISDK('executing'); // 'input-available'
mapToolStateToAISDK('completed'); // 'output-available'
mapToolStateToAISDK('error'); // 'output-error'

React Hooks Reference

Import from @helix-agents/ai-sdk/react:

HookSignaturePurpose
useResumeClientTools(options: UseResumeClientToolsOptions) => voidAuto-dispatch client-executed tools
useStreamResync(data, options: UseStreamResyncOptions) => voidManual resync handling via callback
useAutoResync(data, options: UseAutoResyncOptions) => voidAuto-handle resyncs from snapshot URL
useCheckpointSnapshot(options) => UseCheckpointSnapshotResult<TState>Load a specific checkpoint snapshot
useResyncState(data) => UseResyncStateResultTrack resync count without auto-handling
useResumableChat(data, options) => UseResumableChatResult<TState>Turnkey snapshot + resync solution

See Recovery hooks for usage examples.

SSE Response Builder

typescript
import { createSSEStream, createSSEHeaders, buildSSEResponse } from '@helix-agents/ai-sdk';

const response = buildSSEResponse(eventsGenerator, {
  headers: { 'X-Custom': 'value' },
});

SSE Format

id: 1
data: {"type":"text-delta","id":"block-1","delta":"Hello"}

id: 2
data: {"type":"text-delta","id":"block-1","delta":" world"}

data: {"type":"finish"}

Header Utilities

typescript
import {
  AI_SDK_UI_HEADER, // 'X-AI-SDK-UI'
  AI_SDK_UI_HEADER_VALUE, // 'vercel-ai-sdk-ui'
  extractResumePosition,
} from '@helix-agents/ai-sdk';

// Extract resume position from request headers
const headers = Object.fromEntries(request.headers.entries());
const resumeAt = extractResumePosition(headers);
// Reads (in priority order):
//   X-Resume-From-Sequence
//   Last-Event-ID
//   X-Resume-At

Errors

typescript
import {
  FrontendHandlerError,
  ValidationError, // 400
  StreamNotFoundError, // 404
  StreamReaderError, // 500
  StreamFailedError, // 410
  ConfigurationError, // 501
  ExecutionError, // 500
  StreamCreationError, // 500
  HelixStreamError,
} from '@helix-agents/ai-sdk';

FrontendHandlerError

typescript
interface FrontendHandlerError extends Error {
  code: string; // e.g., 'VALIDATION_ERROR'
  statusCode: number; // HTTP status
}

HelixStreamError

Typed error class for reconstructing stream errors on the client. Provides code and retryable for programmatic error handling.

typescript
const error = HelixStreamError.fromEvent({
  errorText: 'Provider overloaded',
  code: 'provider_overloaded',
  recoverable: true,
});

error.retryable; // true (maps from 'recoverable' on the wire)
PropertyTypeDescription
messagestringError description
codestring | undefinedError code from backend ErrorCode taxonomy
retryablebooleanWhether the operation can be safely retried

Types

Configuration Types

typescript
import type {
  HandleChatStreamDeps,
  HandleChatStreamParams,
  ExtractResumeIntentResult,
  ResumeIntent,
  ResumeIntentRejection,
  PrepareHelixChatRequestOptions,
  StreamTransformerOptions,
  BuildSnapshotDeps,
  GetUIMessagesDeps,
  GetUIMessagesParams,
  GetUIMessagesResult,
  FrontendResponse,
  FrontendSnapshot,
  ResumableStreamStatus,
  TransformResult,
  SequencedEvent,
  MessageConvertOptions,
  // Replay types (for stream resumption)
  ReplayContent,
  ReplayToolCall,
  ReplayToolState,
  ContentReplayOptions,
  // Minimal interfaces (adapter implementations)
  MinimalExecutor,
  MinimalExecutionHandle,
  MinimalStreamManager,
  MinimalStateStore,
} from '@helix-agents/ai-sdk';

Event Types

typescript
import type {
  AISDKUIEvent,
  AISDKStartEvent,
  AISDKFinishEvent,
  AISDKMessageMetadataEvent,
  AISDKTextStartEvent,
  AISDKTextDeltaEvent,
  AISDKTextEndEvent,
  AISDKReasoningStartEvent,
  AISDKReasoningDeltaEvent,
  AISDKReasoningEndEvent,
  AISDKToolInputAvailableEvent,
  AISDKToolOutputAvailableEvent,
  AISDKStartStepEvent,
  AISDKFinishStepEvent,
  AISDKDataEvent,
  AISDKErrorEvent,
  AISDKStreamResyncEvent,
} from '@helix-agents/ai-sdk';

See Also

Released under the MIT License.