import { EventSource } from "eventsource";
class RoutaClient {
constructor(private baseUrl: string) {}
async rpc(method: string, params: any): Promise<any> {
const response = await fetch(`${this.baseUrl}/api/a2a/rpc`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
method,
params,
id: Date.now(),
}),
});
const result = await response.json();
if (result.error) {
throw new Error(result.error.message);
}
return result.result;
}
streamSession(sessionId: string, onEvent: (event: any) => void) {
const url = `${this.baseUrl}/api/a2a/rpc?sessionId=${sessionId}`;
const es = new EventSource(url);
es.onmessage = (event) => {
onEvent({ type: event.type, data: JSON.parse(event.data) });
};
return es;
}
}
// Usage
const client = new RoutaClient("http://localhost:3000");
// 1. Initialize
await client.rpc("initialize", {
clientInfo: { name: "My AI", version: "1.0.0" },
});
// 2. Create session
const { sessionId } = await client.rpc("session/new", {
provider: "opencode",
workspaceId: "default",
message: "Implement user authentication",
});
console.log("Session:", sessionId);
// 3. Stream events
const stream = client.streamSession(sessionId, (event) => {
console.log(event.type, event.data);
});
// 4. Send follow-up message
setTimeout(async () => {
await client.rpc("session/prompt", {
sessionId,
message: "Add password reset functionality",
});
}, 5000);
// 5. Clean up
process.on("SIGINT", () => {
stream.close();
process.exit();
});