Skip to main content
OpenHarness integrates with AI SDK 5’s data stream protocol, so you can stream agent sessions directly to useChat-based React and Vue UIs.

toResponse()

Both Session and Conversation provide two methods for streaming to the client:
  • toUIMessageStream(input) — returns a ReadableStream<UIMessageChunk> that maps session events to AI SDK 5 typed chunks
  • toResponse(input, options) — wraps the stream in an HTTP Response with SSE headers, ready to return from any route handler

Next.js Example

app/api/chat/route.ts
import {
  Agent, Conversation, toRunner, apply,
  withTurnTracking, withCompaction, withRetry, withPersistence,
  extractUserInput, type SessionStore,
} from "@openharness/core";

const store: SessionStore = {
  async load(id) { return db.get(id); },
  async save(id, messages) { await db.set(id, messages); },
};

const conversations = new Map<string, Conversation>();

function getOrCreateConversation(id?: string): Conversation {
  const convId = id ?? crypto.randomUUID();
  let conv = conversations.get(convId);
  if (!conv) {
    const runner = apply(
      toRunner(agent),
      withTurnTracking(),
      withCompaction({ contextWindow: 128_000, model: agent.model }),
      withRetry(),
      withPersistence({ store, sessionId: convId }),
    );
    conv = new Conversation({ runner, sessionId: convId, store });
    conversations.set(convId, conv);
  }
  return conv;
}

export async function POST(req: Request) {
  const { id, messages } = await req.json();
  const conv = getOrCreateConversation(id);
  const input = await extractUserInput(messages);
  return conv.toResponse(input, { signal: req.signal });
}

Custom Data Parts

The stream emits all standard AI SDK 5 chunk types (text-delta, reasoning-delta, tool-input-available, tool-output-available, start, finish, etc.) plus custom OpenHarness data parts for subagent activity, compaction, retry, and turn lifecycle:
Data partDescription
data-oh:subagent.startA subagent task was spawned
data-oh:subagent.doneA subagent task completed
data-oh:subagent.errorA subagent task failed
data-oh:compaction.startCompaction started
data-oh:compaction.doneCompaction finished
data-oh:retryRetrying after transient error
data-oh:turn.startTurn started
data-oh:turn.doneTurn finished
data-oh:session.compactingSession is compacting

Using Data Part Types

If you’re building custom UI components that consume the stream directly, the core package exports typed data part types and guards:
import {
  type OHDataPart,
  isSubagentEvent,
  isCompactionEvent,
} from "@openharness/core";