@rytora.ai/api-client
v0.1.3
Published
Typed TypeScript client for Rytora BuildLabs API — auth, projects, chat, agent, credits, plans
Maintainers
Readme
@rytora.ai/api-client
Typed TypeScript client for the Rytora BuildLabs API. Used by Rytora Code (desktop IDE) and the BuildLabs web platform.
Install
npm install @rytora.ai/api-client
# or
pnpm add @rytora.ai/api-clientQuick start
import { RytoraClient } from '@rytora.ai/api-client';
const client = new RytoraClient({
environment: 'production', // or 'staging' | 'local'
token: 'jwt-from-keychain',
onTokenExpired: async () => {
// refresh token via your keychain
return myKeychain.refreshToken();
},
source: 'rytora-code', // or 'buildlabs-web'
});
// Get current user
const me = await client.auth.getCurrentUser();
console.log(me.plan, me.credits);
// Stream a chat completion
for await (const ev of client.chat.stream({
messages: [{ role: 'user', content: 'Refactor this function' }],
model: 'auto',
})) {
if (ev.type === 'text_delta') process.stdout.write(ev.delta!);
if (ev.type === 'usage') console.log(`Used ${ev.usage!.creditsUsed} credits`);
}Clients
| Client | Purpose |
|--------|---------|
| client.auth | Sign in/out, refresh token, validate, build sign-in URL |
| client.projects | List/get/create projects, read files, pull/push cloud archive |
| client.chat | Streaming + non-streaming chat, Tab completion, Cmd+K helpers |
| client.agent | Multi-iteration tool_use loop with local tool execution |
| client.credits | Balance, transactions, cost estimates |
| client.plans | Plan info, upgrade URL, feature gating helpers |
Error handling
import {
BuildLabsError,
AuthError,
PlanGatedError,
InsufficientCreditsError,
RateLimitError,
} from '@rytora.ai/api-client';
try {
await client.chat.complete({ messages: [...] });
} catch (err) {
if (err instanceof PlanGatedError) {
showUpgradePrompt(err.requiredPlan);
} else if (err instanceof InsufficientCreditsError) {
showCreditsLow(err.required, err.available);
} else if (err instanceof RateLimitError) {
showRateLimit(err.retryAfterSeconds);
} else if (err instanceof BuildLabsError) {
showError(err.code, err.message);
} else {
throw err;
}
}Auth flow (Rytora Code desktop)
// 1. Generate CSRF state
const state = crypto.randomUUID();
await keychain.set('auth-state', state);
// 2. Open browser to sign-in URL
const url = client.auth.buildSignInUrl({ state });
shell.openExternal(url);
// 3. App receives deep link rytora-code://auth/callback?token=...&state=...
// 4. Validate state matches, persist token to keychain
await keychain.set('access-token', token);
// 5. Use client
const session = new RytoraClient({ token });Agent tool_use loop
import { RytoraClient, type AgentToolUse, type AgentToolResult } from '@rytora.ai/api-client';
const client = new RytoraClient({ token });
async function executeToolLocally(use: AgentToolUse): Promise<AgentToolResult> {
switch (use.name) {
case 'read_file':
const content = await fs.readFile(use.input.path as string, 'utf8');
return { toolUseId: use.toolUseId, output: content };
case 'edit_file':
// apply edit, return success
...
default:
return { toolUseId: use.toolUseId, output: 'Tool not supported', isError: true };
}
}
for await (const ev of client.agent.run({ prompt: 'Refactor src/api.ts' }, executeToolLocally)) {
switch (ev.type) {
case 'text_delta': process.stdout.write(ev.delta!); break;
case 'tool_use': console.log(`Using tool: ${ev.toolUse!.name}`); break;
case 'agent_complete': console.log('Done'); break;
}
}License
MIT — © 2026 Rytora AI Technology & Solutions
