Rebyte TypeScript SDK
The Rebyte TypeScript SDK is split into three layers so an integration can use the Agent runtime without adopting a particular frontend:
| Package | Responsibility |
|---|---|
@rebyte/agent-sdk | Framework-free Responses client, durable Conversations, SSE parsing, and response accumulation |
@rebyte/agent-react | Headless React chat state plus browser/server transports |
@rebyte/agent-ui | Optional App Kit-style chat UI and execution inspector |
The source is available in
ReByteAI/rebyte-agent-sdk.
The packages are not yet published to the npm registry. Until the first
registry release, consume them from that repository as a workspace or file
dependency. The package boundaries and public names above are stable; npm
installation commands will be added when the release is available.
Core SDK
Organization API keys belong only in trusted server runtimes. The Core SDK refuses browser construction by default.
import { Rebyte } from "@rebyte/agent-sdk";
const client = new Rebyte({
apiKey: process.env.REBYTE_API_KEY,
baseURL: "https://api.rebyte.ai/v1",
});
Stream one Response
const stream = await client.responses.create({
model: process.env.REBYTE_AGENT_ID,
input: "Inspect this repository and summarize it.",
stream: true,
});
for await (const event of stream) {
if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
}
}
const response = await stream.finalResponse();
console.log(response.conversation.id);
The event stream keeps standard Responses events and Rebyte's additive
response.rebyte_tool_call.* events in arrival order.
Keep one durable Conversation
Use the Conversation helper when your application wants a stateful object:
const conversation = client.conversation({
model: process.env.REBYTE_AGENT_ID,
});
await conversation.send("Remember that the deployment color is blue.");
await conversation.send("What is the deployment color?");
console.log(conversation.id); // one stable conv_... ID
The helper sends no continuity field on the first turn. It binds the returned
conversation.id immediately and sends that ID on every later turn. It does
not maintain a client-side previous_response_id chain or Conversation
snapshot.
To attach to an existing Conversation:
const conversation = client.conversation({
model: process.env.REBYTE_AGENT_ID,
id: "conv_...",
});
Manage Conversations
The Conversation resource wraps Rebyte's durable Session lifecycle:
const created = await client.conversations.create({
model: process.env.REBYTE_AGENT_ID,
title: "Competitive research",
});
const current = await client.conversations.retrieve(created.id);
const page = await client.conversations.list({ model: current.model });
await client.conversations.interrupt(current.id);
await client.conversations.delete(current.id);
interrupt stops the active turn without deleting the Conversation. Deletion
removes the Session runtime.
Headless React
@rebyte/agent-react owns state and transport, not markup. In a browser, point
it at endpoints in your application so the organization key remains on your
server:
import { useMemo } from "react";
import {
createFetchTransport,
useRebyteChat,
} from "@rebyte/agent-react";
export function Chat() {
const transport = useMemo(
() => createFetchTransport({
url: "/api/responses",
interruptUrl: "/api/conversations/interrupt",
}),
[],
);
const chat = useRebyteChat({ transport });
return (
<form onSubmit={(event) => {
event.preventDefault();
void chat.send("Hello");
}}>
{chat.messages.map((message) => (
<p key={message.id}>{message.content}</p>
))}
<button disabled={chat.status === "streaming"}>Send</button>
{chat.status === "streaming" && (
<button type="button" onClick={() => void chat.stop()}>
Stop
</button>
)}
</form>
);
}
useRebyteChat exposes conversationId, streamed messages, status, errors,
send, stop, and reset. stop calls the server-side Conversation
interrupt before aborting the browser stream.
Optional UI
@rebyte/agent-ui provides one UI implementation on top of the headless hook:
import { createFetchTransport } from "@rebyte/agent-react";
import { AgentChat } from "@rebyte/agent-ui";
import "@rebyte/agent-ui/styles.css";
const transport = createFetchTransport({
url: "/api/responses",
interruptUrl: "/api/conversations/interrupt",
});
export function App() {
return (
<AgentChat
transport={transport}
agentName="Research Agent"
inspector
/>
);
}
The UI package is optional. A product can use the Core SDK alone, combine Core with the React hook, or replace every visual component while keeping the same Conversation transport.
Server proxy contract
The browser-facing Responses endpoint accepts text and an optional stable Conversation ID:
{
"input": "Compare it with the previous company.",
"conversation": "conv_..."
}
Your server adds the Rebyte Agent ID and organization API key, calls
client.responses.create({ stream: true }), and forwards the upstream SSE body
without buffering it. The interrupt endpoint accepts the Conversation ID and
calls client.conversations.interrupt(conversation).
Never put REBYTE_API_KEY in browser code, client bundles, local storage, or a
public environment variable.
Current protocol boundary
The initial SDK intentionally exposes the Responses subset Rebyte executes today:
- text input and user text-message arrays;
- synchronous Responses and live SSE;
- stable
conversationcontinuity; - durable Response retrieval;
- standard text and MCP call events;
- additive Rebyte tool-progress events;
- Conversation create, retrieve, list, interrupt, and delete.
The raw Responses resource still accepts previous_response_id for wire
compatibility, but Rebyte's Conversation helper, React bindings, and UI do not
use it as state. Request-level OpenAI tools, file/image inputs, structured
output, background mode, and Responses-native HITL continuation are not part
of this release.