JavaScript SDK
@vedika-io/agent-sdk-js is the typed JavaScript / TypeScript
client for the Vedika agent harness. Streams turns over the UI Message
Stream v1 wire, resumes with Last-Event-ID, and surfaces typed
errors.
Install
npm install @vedika-io/agent-sdk-js
In a TypeScript project, also install @types/node
(npm install -D @types/node) so the quickstart's
process.env type-checks.
Quickstart
import { createVedikaAgent } from "@vedika-io/agent-sdk-js";
const agent = createVedikaAgent({
baseUrl: "https://harness.example.com",
apiKey: process.env.VEDIKA_AGENT_KEY!,
});
const thread = await agent.threads.create();
const turn = await agent.threads.sendTurn(thread.id, {
kind: "text",
text: "Show my kundli.",
// A kundli or report turn needs to know whose chart it is.
birth: { name: "Asha", dateOfBirth: "1990-06-15", timeOfBirth: "10:30", latitude: 28.6139, longitude: 77.209, timezone: "Asia/Kolkata" },
});
for await (const chunk of turn) {
if (chunk.type === "text-delta") process.stdout.write(chunk.delta);
}
await turn.done();
API
createVedikaAgent(config)
Returns a client with a threads namespace.
| Field | Type | Description |
|---|---|---|
baseUrl | string | Harness base URL. Required. |
apiKey | string | API key for the harness-server. Sent as Authorization: Bearer. |
fetch | typeof fetch | Custom fetch implementation. Defaults to the global fetch. |
defaultHeaders | Record<string,string> | Default headers added to every request (after auth and idempotency). |
agent.threads.create(opts?)
POST /api/v1/agent/threads. Returns a Thread.
| Field | Type | Description |
|---|---|---|
idempotencyKey | string | Optional. Default UUID v4. |
metadata | Record<string,string> | Optional. Stored on the thread. |
signal | AbortSignal | Optional. |
headers | Record<string,string> | Optional extra headers. |
agent.threads.sendTurn(threadId, input, opts?)
POST /threads/{id}/turns with
Accept: text/event-stream. Returns a Turn you can
iterate.
const turn = await agent.threads.sendTurn(
thread.id,
{ kind: "text", text: "What does my chart say about career in 2026?" },
{ model: "vedika-swift", memory: { oldMemory: true } },
);
for await (const chunk of turn) {
if (chunk.type === "text-delta") process.stdout.write(chunk.delta);
}
await turn.done();
agent.threads.resumeTurn(turnId, opts)
GET /turns/{id}/events with Last-Event-ID.
Resume a turn after a stream drop.
const lastEventId = await saveCursor(); // e.g. "12.3"
const turn = await agent.threads.resumeTurn(turnId, { lastEventId });
agent.threads.cancelTurn(turnId, opts?)
POST /turns/{id}/cancel. Idempotent. 404 and 410 are treated as success (the turn already finished).
The Turn object
| Member | Description |
|---|---|
turnId | The server-assigned turn id. |
threadId | The thread the turn belongs to. |
messageId | A promise resolving to the start.messageId when seen. |
for await (chunk of turn) | Async iterator over every chunk. |
turn.done() | Resolves on finish / abort, rejects on error. |
turn.cancel() | Calls the cancel endpoint. |
Memory toggles
Pass memory: { oldMemory, sensitiveInfo } on
sendTurn. They are sent as x-vedika-memory-old and
x-vedika-memory-sensitive. Both default to false.
Errors
See Errors for the full list. The SDK exposes:
VedikaAgentError— base class.AuthenticationError— 401 / 403.NotFoundError— 404 / 410.RateLimitError— 429, withretryAfterSeconds.InvalidRequestError— 4xx, with preservedcode.ServerError— 5xx, withretryable.TurnCancelledError,StreamError,ProtocolError.NetworkError— no response at all (DNS failure, refused or reset connection);causeholds the original error.
Whose chart
A turn that generates a kundli or a report ("Show my kundli") needs a
subject. Send birth on the turn, as in the quickstart.
Without it, and without a profile bound to the thread, the harness
answers 409 SUBJECT_UNRESOLVED, surfaced as
InvalidRequestError with code: "SUBJECT_UNRESOLVED".
A plain astrology question needs no birth.
Idempotency
Every create and sendTurn carries an
Idempotency-Key header. A fresh UUID v4 is generated when you
do not pass one; pass your own to retry safely across processes.
Reserved headers
The SDK refuses to override authorization,
accept, content-type,
idempotency-key, last-event-id, and
x-vercel-ai-ui-message-stream.