Rivya TypeScript SDK
استخدم الإصدار التجريبي من Rivya TypeScript SDK لاستدعاء Public API v1 للنماذج، والتوليد، والملفات، والرصيد، والويبهوكات، وChat بما في ذلك بث SSE.
آخر مراجعة في 2026/08/29
توفر Rivya إصدارا تجريبيا من حزمة TypeScript SDK لتكاملات API العامة من جهة الخادم.
حزمة SDK عميل خفيف مبني فوق Rivya API العام بالإصدار v1. ويظل OpenAPI وعقد المخطط هو العقد الأساسي، كما يجب أن تبقى أساليب SDK متوافقة مع هذا المخطط.
توثق حزمة SDK سلوك العميل المنفذ. وما زالت الطلبات تتطلب تفعيل API العام للنشر، ومفتاح حساب صالحا، ونموذجا تسمح حالة API الحالية له بالعملية المطلوبة.
الحالة
تتم صيانة الحزمة حاليا داخل هذا المستودع كإصدار تجريبي خاص. ولن تنشر إلى npm حتى تتم الموافقة صراحة على اسم الحزمة، والبيانات الوصفية، وسجل التغييرات، وعملية الإصدار.
يدعم SDK:
سرد النماذج
إنشاء التوليدات غير المتزامنة واسترجاعها
رفع الملفات واسترجاعها عبر واجهة API للملفات
استرجاع رصيد الائتمان
إدارة نقاط الويبهوك، وتسليمات الاختبار، وقوائم الأحداث، وقوائم التسليم، وتدوير السر
التحقق من توقيع الويبهوك
استجابات محادثة عادية ومتدفقة، إضافة إلى الجلسات التي تنشئها API
يتوفر بث المحادثة في هذا الإصدار التجريبي الخاص عبر تحليل SSE من جهة الخادم. أبق مفاتيح API السرية على خادمك.
التثبيت في هذا المستودع
استخدم مصدر الحزمة المحلي ما دام SDK في المرحلة التجريبية:
pnpm --dir packages/rivya-sdk typecheckيجب أن يحتفظ كود التطبيق بمفتاح API السري على الخادم:
import { RivyaClient } from "@rivya/sdk";
const rivya = new RivyaClient({
apiKey: process.env.RIVYA_API_KEY
});لا تضع مفاتيح API السرية في حزم المتصفح، أو localStorage، أو أحداث التحليلات، أو لقطات الشاشة، أو التذاكر المشتركة.
سرد النماذج
models.list عام ولا يتطلب مفتاح API:
const models = await rivya.models.list();
for (const model of models.data) {
console.log(model.id, model.api_status, model.supported_api_inputs);
}إنشاء توليد
استخدم generations.create لإنشاء توليد غير متزامن لصورة أو فيديو أو صوت:
const generation = await rivya.generations.create(
{
model: "z-image",
prompt: "A clean editorial product image on a soft studio background",
client_request_id: "order-123-preview"
},
{
idempotencyKey: "order-123-preview"
}
);
console.log(generation.id, generation.status);ثم استطلع باستخدام generations.retrieve:
const current = await rivya.generations.retrieve(generation.id);
console.log(current.status, current.result?.primary_url);استخدم Idempotency-Key لطلبات الكتابة في الإنتاج. يعرض SDK هذا الحقل باسم idempotencyKey.
رفع الملفات
استخدم files.upload للصور أو الفيديوهات أو الصوتيات المرجعية:
import { readFile } from "node:fs/promises";
const file = new Blob([await readFile("./reference.png")], {
type: "image/png"
});
const uploaded = await rivya.files.upload({
file,
filename: "reference.png",
kind: "image",
model: "nano-banana-2-lite",
client_request_id: "asset-123"
});
console.log(uploaded.id, uploaded.url);استخدم files.retrieve لقراءة بيانات الملف المرفوع مرة أخرى:
const sameFile = await rivya.files.retrieve(uploaded.id);
console.log(sameFile.mime_type, sameFile.duration_token);عند استخدام ملف في توليد، مرر الحقول العامة العائدة عبر params.referenceMediaItems:
await rivya.generations.create({
model: "nano-banana-2-lite",
prompt: "Restyle this product photo for a clean editorial catalog page",
params: {
referenceMediaItems: [
{
url: uploaded.url,
kind: uploaded.kind,
name: uploaded.file_name,
mimeType: uploaded.mime_type,
durationSeconds: uploaded.duration_seconds ?? undefined,
durationToken: uploaded.duration_token ?? undefined,
width: uploaded.video_width ?? uploaded.width ?? undefined,
height: uploaded.video_height ?? uploaded.height ?? undefined,
sizeBytes: uploaded.video_file_size_bytes ?? uploaded.size_bytes,
imageDimensionsToken: uploaded.image_dimensions_token ?? undefined,
framesPerSecond: uploaded.frames_per_second ?? undefined,
videoBitrateMbps: uploaded.video_bitrate_mbps ?? undefined,
videoMetadataToken: uploaded.video_metadata_token ?? undefined
}
]
}
});تتطلب كل صورة مرجعية لنماذج Image5 أو لنموذج Grok Imagine Image 2.0 قيم width وheight وsize_bytes وimage_dimensions_token من استجابة الرفع الأصلية المرتبطة بالنموذج. قد يعيد استدعاء لاحق لـ files.retrieve الرمز بقيمة null؛ أعد رفع الصورة المصدر بدلا من تخمين نوع MIME أو الأبعاد أو حجم البايتات. ويفرض Layer Decomposition أيضا حدوده الهندسية لصورة واحدة؛ ويقبل Grok Image 2 من 1 إلى 5 مراجع JPEG أو PNG أو WebP موقعة لتحرير الصور القياسي.
بالنسبة إلى فيديو مرجعي لنماذج Video8، استخدم video_width وvideo_height وframes_per_second وvideo_bitrate_mbps وvideo_file_size_bytes وvideo_metadata_token من استجابة الرفع الأصلية المرتبطة بالنموذج بأسماء width وheight وframesPerSecond وvideoBitrateMbps وsizeBytes وvideoMetadataToken. احتفظ بـ durationSeconds وdurationToken كإثبات موقع مستقل للمدة. إذا كان أي من الرمزين غائبا في استدعاء لاحق لـ files.retrieve، فأعد رفع الفيديو المصدر.
يستخدم Wan 3.0 تعيين حقول SDK نفسه عبر مشاهد text وframes وreference المتبادلة الاستبعاد. ارفع كل مرجع باستخدام model: "wan-3-0-video"؛ تتطلب الصور حقول الصور الموقعة، وتتطلب الفيديوهات كلا من المدة الموقعة والبيانات الوصفية الموقعة للفيديو، ويتطلب الصوت القيم الأصلية mime_type وsize_bytes وduration_seconds وduration_token. اضبط داخل params الحقول seedance_scene وvariant وresolution وaspect_ratio وduration وaudio وseed الاختياري. قيمة المدة الذكية هي -1، وتحجز 30 ثانية، ولا يمكن دمجها مع فيديو مرجعي؛ وتظل اختصارات تحويل الملف إلى فيديو وتحويل الرابط إلى فيديو غير متاحة.
التحقق من الرصيد
const credits = await rivya.credits.retrieve();
console.log(credits.current_credits);إدارة إشعارات Webhook
عندما تكون إتاحة Webhook مفعلة للنشر والحساب، أنشئ نقطة نهاية لاستقبال الإشعارات:
const endpoint = await rivya.webhooks.create({
name: "Production webhook",
url: "https://example.com/rivya/webhook",
event_types: ["generation.succeeded", "generation.failed"]
});
console.log(endpoint.id, endpoint.signing_secret);لا يعاد signing_secret إلا بعد استدعاءات الإنشاء أو التدوير. خزنه على خادمك.
أدوات Webhook المساعدة الأخرى:
await rivya.webhooks.list();
await rivya.webhooks.retrieve(endpoint.id);
await rivya.webhooks.update(endpoint.id, { status: "disabled" });
await rivya.webhooks.test(endpoint.id);
await rivya.webhooks.rotateSecret(endpoint.id);
await rivya.webhooks.deliveries.list(endpoint.id, { limit: 20 });
await rivya.webhookEvents.list({ limit: 20 });تحقق من توقيعات التسليم قبل الوثوق بحمولات Webhook:
import { verifyRivyaWebhookSignature } from "@rivya/sdk";
const ok = await verifyRivyaWebhookSignature({
rawBody,
timestamp: request.headers.get("rivya-webhook-timestamp") || "",
signatureHeader: request.headers.get("rivya-webhook-signature") || "",
signingSecret: process.env.RIVYA_WEBHOOK_SIGNING_SECRET || ""
});
if (!ok) {
throw new Error("Invalid Rivya webhook signature");
}تستخدم أداة SDK المساعدة عقد HMAC-SHA256 نفسه الموثق في إشعارات Webhook عبر API.
المحادثة
استخدم chat.completions.create لإرسال دورة محادثة واحدة غير متدفقة عبر API:
const completion = await rivya.chat.completions.create(
{
model: "claude-sonnet-5-chat",
message: "Write a concise launch plan for a new product image campaign",
client_request_id: "chat-001"
},
{
idempotencyKey: "chat-001"
}
);
console.log(completion.session_id, completion.message.content);تابع باستخدام session_id العائد:
await rivya.chat.completions.create({
model: "claude-sonnet-5-chat",
session_id: completion.session_id,
message: "Now turn that into a 5-step execution checklist."
});اقرأ الجلسات التي أنشأتها API:
await rivya.chat.sessions.list({ limit: 20 });
await rivya.chat.sessions.retrieve(completion.session_id);استخدم chat.completions.stream لاستهلاك أحداث SSE عبر مكرر غير متزامن:
const stream = await rivya.chat.completions.stream(
{
model: "claude-sonnet-5-chat",
message: "Write a concise launch plan for a new product image campaign",
client_request_id: "chat-stream-001"
},
{
idempotencyKey: "chat-stream-001"
}
);
for await (const event of stream) {
if (event.event === "message.delta") {
process.stdout.write(event.data.delta);
}
if (event.event === "message.completed") {
console.log(event.data.message.id);
}
}message.delta مخصص للعرض فقط. النتيجة المعتمدة تكون متاحة بعد message.completed، ويمكن قراءتها لاحقا باستخدام chat.sessions.retrieve.
الأخطاء
تعيد حزمة SDK الخطأ RivyaAPIError لاستجابات API العامة التي لا تحمل رمزا من فئة 2xx:
import { RivyaAPIError } from "@rivya/sdk";
try {
await rivya.generations.retrieve("task_missing");
} catch (error) {
if (error instanceof RivyaAPIError) {
console.log(error.status, error.code, error.requestId);
}
}يتضمن RivyaAPIError حالة HTTP، وكود الخطأ العام، والرسالة، ومعرف الطلب عند توفره، ومجموعة فرعية آمنة من رؤوس الاستجابة.
التحقق
شغل فحوص SDK قبل اعتبار أي تغيير مكتملا:
pnpm sdk:check
pnpm --dir packages/rivya-sdk typecheck
pnpm content:api-docsيتضمن pnpm sdk:check فحصا ثابتا للعقد وفحصا وقت التشغيل من دون شبكة، ويغطي تحليل الأخطاء، ورؤوس الأخطاء الآمنة، ورؤوس منع التكرار، ومصادقة Bearer، وسرد النماذج العام، وتحليل بث المحادثة عبر SSE، وأحداث أخطاء البث، والتحقق من توقيع Webhook.
