דילוג לתוכן
תיעוד Nodaro
תיעודמדריך הרכיביםמודליםתבניותסוכני AI (MCP)מפתחיםאירוח עצמימחקרהשוואות
SDK ל-TypeScript

הרצת רכיבים

הרצת כל רכיב של Nodaro מ-TypeScript בלי תהליך: גילוי סוגי רכיבים, התחלת הרצות, המתנה לתוצאות ושליחה של ייחוסים ושל הכוונת מצלמה.

client.nodes מחזיר את רשימת סוגי הרכיבים ששרת Nodaro תומך בהם, ומריץ כל אחד מהם ישירות, בלי לבנות תהליך. הרצה שולחת את הפרמטרים שלכם לנתיב של הרכיב עצמו, POST /v1/<type> ברוב סוגי הרכיבים, ומחזירה משימה שאפשר להמתין לה. זה אותו נתיב שה-CLI משתמש בו ב-nodaro nodes run ושכלי ה-MCP של Nodaro משתמשים בו. לגרסת ה-REST, ראו את דף ה-API הרצת רכיב יחיד.

מתודות

מתודהמה היא עושה
nodes.list()רשימת כל סוגי הרכיבים, עם המודלים והמחיר בקרדיטים של כל אחד
nodes.get(type)קריאת סוג רכיב אחד
nodes.run(type, params?, options?)התחלת רכיב והחזרה מיידית של מזהה המשימה שלו
nodes.quote(type, params?)אומדן מחיר להרצה לפני שמתחילים אותה
nodes.runAndWait(type, params?, opts?)התחלת רכיב, בדיקת הסטטוס של המשימה שלו והחזרת הפלט
nodes.runMany(type, paramsList, opts?)התחלה של כמה הרצות של רכיב אחד בבת אחת, והמתנה לכולן
nodes.runBatchAndWait(type, params, opts?)יצירת כמה תמונות בקריאה אחת לרכיב יצירת תמונה, והמתנה לכל אחת מהן

client.nodes

list()‎

מחזירה את כל סוגי הרכיבים שהשרת תומך בהם. השרת עשוי לשמור את התשובה במטמון למשך 5 דקות. הקריאה לא עולה כלום ולא דורשת הרשאות.

list(): Promise<{ data: NodeDescriptor[] }>
const { data: nodes } = await client.nodes.list()

const imageGenerators = nodes.filter((n) => n.category === "ai-image")
const takesReferences = nodes.filter((n) => n.capabilities?.includes("supports-reference-image"))

לכל NodeDescriptor יש השדות האלה:

שדהסוגתיאור
typestringהסוג ב-API, למשל generate-image. העבירו אותו ל-run().
labelstringהשם של הרכיב בעורך.
categorystringהקטגוריה, למשל ai-image, ai-video, ai-audio, ai-text, processing או parameter.
descriptionstringתיאור בשורה אחת.
outputTypestringtext, image, video, audio, data או none.
creditCostnumber | stringהמחיר בקרדיטים שנגבה על הרצה, אותו מספר שמופיע בכפתור הרצה של הרכיב: מספר כשהמחיר קבוע, או טווח כגון "3-682" כשהמחיר נקבע לפי המודל. ברכיבים קיצוץ וידאו, לולאת וידאו ושילוב סרטונים, הערך הוא במקום זאת המחיר של מדרגה אחת של 5 שניות, והרצה עולה כמה מדרגות כאלה. ב-Nodaro Cloud בלבד.
estimatebooleanהערך הוא true כשהשדה creditCost הוא אומדן: הקריאה הטיפוסית של רכיב LLM עם חיוב לפי השימוש, במודל ברירת המחדל שלו. הציגו אותו כ-≈N. רכיב LLM עם חיוב לפי השימוש, שלמודל ברירת המחדל שלו עדיין אין מחיר, מופיע ברשימה עם creditCost: "unpriced".
creditRateNodeCreditRateלרכיב שהמחיר שלו נקבע לפי יחידה של מדד משלו, כגון רכיב מסגרות דוברים (עם creditCost שערכו "per-1000-frames"): { identifier, unit, creditsPerUnit, minUnits, rounding, note }. הרצה של N יחידות עולה Math.ceil(Math.max(minUnits, N) * creditsPerUnit), ומעגלים פעם אחת בלבד.
providersstring[]מזהי המודלים שהרכיב יכול להריץ, בשביל הפרמטר provider.
capabilitiesstring[]דגלים, כגון supports-reference-image או supports-end-frame.
inputSchema{ fields }שדות הקלט שאפשר לקבוע, כל אחד עם key, type, required ו-options.
maxDurationSecnumberמשך הזמן הארוך ביותר שהרכיב מקבל, ברכיבים שיש להם מגבלה כזו.
providerResolutionsRecord<string, string[]>הרזולוציות שכל מודל מקבל, כשהן שונות בין המודלים.

בהתקנות של מהדורת Community ומהדורת Business באירוח עצמי אין מערכת קרדיטים, ולכן המתארים שלהן לא כוללים את creditCost.

get(type)‎

מחזירה את המתאר של סוג רכיב אחד.

get(type: string): Promise<{ data: NodeDescriptor }>

מאפיין

סוג

const { data: node } = await client.nodes.get("generate-video")
console.log(node.providers)  // every video model id
console.log(node.creditCost) // Nodaro Cloud only

כדי להציג מחירים ליד המודלים, העבירו את node.providers ל-client.credits.modelCosts().

run(type, params?, options?)‎

מתחילה רכיב אחד ומחזירה תשובה מיד. גוף הבקשה נשלח לנתיב של הרכיב, POST /v1/<type> ברוב סוגי הרכיבים. שמות השדות זהים לשדות הקלט של הרכיב.

run(type: string, params?: Record<string, unknown>, options?: { idempotencyKey?: string }): Promise<RunNodeResult>

מאפיין

סוג

const result = await client.nodes.run("generate-image", {
  prompt: "A snow leopard in the mountains",
  provider: "nano-banana-2",
})

if ("jobId" in result) {
  const { data: job } = await client.jobs.getStatus(result.jobId)
  console.log(job.status)
}

סוגי רכיבים עם נתיב משלהם. כמה סוגי רכיבים רצים בנתיב אחר, והמתודה run() שולחת אליו בשבילכם:

סוגי רכיביםנתיב
generate-3d-scene, edit-3d-scene/v1/3d-scene/generate, /v1/3d-scene/edit
llm-chat, after-effects, motion-graphics, lottie-overlay, 3d-title/v1/<type>/generate
image-to-text/v1/image-to-text/describe
video-composer/v1/scene-graph/generate
telegram-channel-feed/v1/telegram-channel/fetch
כל רכיב suno-*, כגון suno-generate ו-suno-cover/v1/suno/<name>. הרכיב suno-voice משתמש ב-/v1/suno/voice/generate.
instagram-post, tiktok-post, youtube-upload, linkedin-post, x-post, facebook-post, telegram-post, publish-social/v1/social/publish
ugc-creator, ugc-script, ugc-clips, ugc-clip, ugc-cards/v1/ugc/creator, /v1/ugc/script וכן הלאה. ב-Nodaro Cloud בלבד.
render-video עם planType/v1/render-video/plan

נתיב הפרסום דורש platform. רכיב פרסום של רשת אחת, כגון x-post, ממלא אותו לפי הסוג שלו כשלא שולחים אותו. הרכיב publish-social מקבל את ה-platform ששולחים.

סוגי רכיבים שלא רצים לבד. קריאה לסוג רכיב בלי נתיב משלו נכשלת עם NodaroError שה-code שלו הוא node_not_runnable, בלי שום פנייה ל-API. ההודעה מציינת מה להריץ במקומו:

  • הרכיב modify-image רץ דרך image-to-image, או דרך edit-image במודל nano-banana-edit.
  • הרכיבים upscale-image ו-remove-background רצים דרך edit-image.
  • הרכיב image-to-video רץ דרך generate-video.
  • הרכיבים composite, manual-edit ו-paint-mask רצים רק בתוך תהליך. הרכיבים scene ו-generative-pipeline רצים רק בתוך פייפליין.

קריאה לסוגי רכיבים שרצים רק בתוך תהליך, כגון קלטים, טריגרים, כלי עזר ובוררים (upload-image, combine-text), נכשלת באותו אופן ברגע שה-API עונה שאין לו נתיב בשבילם. שגיאת 404 על משאב חסר, כגון מזהה דמות שלא קיים, נשארת NotFoundError.

בקשה עם מודל שהפריסה הזו לא מציעה, או עם מודל שמנהל כיבה, נדחית לפני שמשוריינים קרדיטים. הקריאה נכשלת עם ModelUnavailableError, וה-code הוא model_not_available או model_disabled. בחרו מודל אחר: ניסיון חוזר לא ישנה כלום.

מה חוזר. רוב סוגי הרכיבים הם אסינכרוניים: התוצאה כוללת jobId, ו-worker מבצע את היצירה. בדקו את הסטטוס עם client.jobs.getStatus(jobId) מדי כמה שניות עד שהמשימה מסתיימת, או השתמשו ב-runAndWait(). כמה סוגי רכיבים סינכרוניים, כגון meta-ads-scrape, מחזירים את התוצאה המלאה שלהם מיד, בלי jobId. בדקו אם יש jobId, ופעלו לפי זה.

תיקוני פרמטרים. בסוגי רכיבי התמונה (generate-image, image-to-image ו-edit-image), השרת עשוי לתקן ערך שהמודל שנבחר לא מקבל. ההרצה ממשיכה עם הערך המתוקן, והקרדיטים שמשוריינים תואמים אותו. התוצאה כוללת אז את adjustments, פריט אחד לכל שדה שתוקן:

const result = await client.nodes.run("generate-image", {
  prompt: "A snow leopard",
  provider: "gpt-image-2",
  aspectRatio: "3:2",
})
if ("adjustments" in result && result.adjustments?.length) {
  for (const a of result.adjustments) {
    console.warn(`${a.field}: ${a.from} -> ${a.to ?? "(dropped)"} (${a.reason})`)
  }
}

בכל תיקון יש field (aspectRatio, resolution, quality או duration), from, to ו-reason. כששום דבר לא השתנה, השדה adjustments לא מופיע.

המתודה זורקת InsufficientCreditsError כשאין בחשבון מספיק קרדיטים, StorageExceededError כשהאחסון מלא ו-JobBlockedError כשמדיניות תוכן של הפריסה דוחה את הבקשה. ראו את הדף שגיאות.

quote(type, params?)‎

נותנת אומדן מחיר להרצה לפני שמתחילים אותה, עם POST /v1/quote. העבירו בדיוק את גוף הבקשה שהייתם מעבירים למתודה run. הפלטפורמה מתמחרת אותו עם הקוד של נתיב ההרצה עצמו: אותה בדיקת תקינות, אותה מדידה של קליפי ייחוס, אותו מזהה קרדיטים ואותו סכום. שום דבר לא מתחיל, ולא נגבים קרדיטים. ב-Nodaro Cloud בלבד.

quote(type: string, params?: Record<string, unknown>): Promise<NodeQuote>

למתודה יש טיפוסים ל-text-to-video, ל-generate-video, ל-video-to-video ול-video-upscale (ההשלמה ב-1080p של טיוטה ב-Seedance 2.5 מתומחרת לפי הטיוטה): הסוגים שהפלטפורמה יכולה לתת להם אומדן מחיר כרגע. קריאה עם כל סוג אחר נדחית עם 400 quote_unsupported.

const q = await client.nodes.quote("video-to-video", {
  videoUrl, prompt: "make it black and white", provider: "seedance-2-5", resolution: "480p",
})
q.reserve   // credits held when the run starts
q.expected  // what the run should actually cost, when known

הטיפוס NodeQuote הוא { identifier, reserve, expected?, adjustments, warnings }. ראו בדף ה-API אומדני מחיר להרצה לכל השדות והקודים.

runAndWait(type, params?, opts?)‎

מריצה רכיב אסינכרוני אחד עד הסוף. המתודה קוראת ל-run(), לוקחת את ה-jobId ובודקת את הסטטוס עם client.jobs.getStatus() מדי כמה שניות, עד שהמשימה מסתיימת. כשהסטטוס הוא completed, היא מחזירה את הפלט של המשימה.

runAndWait(type: string, params?: Record<string, unknown>, opts?: RunAndWaitOptions): Promise<NodeJobOutput>

מאפיין

סוג

const output = await client.nodes.runAndWait(
  "generate-video",
  { prompt: "Rain falls on a neon street at night", provider: "seedance-2-fast", duration: 4 },
  { onProgress: (s) => console.log(`${s.progress ?? 0}%`) },
)
console.log(output.videoUrl, output.thumbnailUrl)

במשימת תמונה, הטיפוס NodeJobOutput כולל גם את גודל התמונה בפיקסלים, כך שלקוח יכול לסדר רשת לפני שהתמונות נטענות:

שדהסוגתיאור
imageUrlstringהתמונה, או הראשונה מביניהן כשהמשימה יצרה כמה תמונות.
imageUrlsreadonly string[]כל התמונות, כשהמשימה יצרה יותר מתמונה אחת.
width, heightnumberהגודל של imageUrl בפיקסלים, כפי שהקובץ שמור, אחרי שהכיוון לפי EXIF הוחל. סימן המים של המסלול החינמי כלול.
imagesreadonly JobOutputImage[]אובייקט { url, width?, height? } אחד לכל פריט ב-imageUrls, באותו סדר. בפריט בלי גודל, אי אפשר היה למדוד את התמונה.

ארבעת שדות הגודל הם אופציונליים. במשימות ישנות יותר הם חסרים, והשרת אף פעם לא מנחש גודל שהוא לא הצליח לקרוא.

const output = await client.nodes.runAndWait("generate-image", { prompt: "a snow leopard in the mountains" })
console.log(output.imageUrl, output.width, output.height)
for (const image of output.images ?? []) console.log(image.url, image.width ?? "?", image.height ?? "?")

הפלט הוא NodeJobOutput: השדה imageUrl ברכיבי תמונה, videoUrl ו-thumbnailUrl ברכיבי וידאו, audioUrl ברכיבי אודיו ועוד כל שדה אחר שהרכיב כותב. רכיב הפרדת אודיו, למשל, מוסיף כתובת לכל סטם, כגון vocalUrl ו-instrumentalUrl.

אלה השגיאות עם טיפוסים שהמתודה זורקת:

שגיאהמתי
NodaroError עם הקוד batch_requires_run_batch_and_waitבקשת generate-image עם count גדול מ-1 או עם models יוצרת כמה משימות. המתודה runAndWait() דוחה אותה לפני שנשלח משהו. השתמשו ב-runBatchAndWait().
InsufficientCreditsError, StorageExceededError, JobBlockedErrorבקשת ההרצה נדחתה, לפני כל בדיקת סטטוס.
ModelUnavailableErrorהפריסה הזו לא מציעה את המודל, או שמנהל כיבה אותו. ההרצה נדחית לפני שמשוריינים קרדיטים. בחרו מודל אחר.
JobFailedErrorהמשימה הסתיימה בסטטוס failed או cancelled. השגיאה כוללת את jobId ואת הודעת השגיאה של המשימה.
JobTimeoutErrorהזמן שב-maxMs עבר. המשימה לא מבוטלת.
JobAbortedErrorה-signal שלכם ביטל את ההמתנה. המשימה לא מבוטלת.
JobHeldErrorהמשימה ממתינה לבדיקה של אדם, בפריסות שיש להן מדיניות תוכן.

התאוששות איטית. לפעמים מודל מוסר את התוצאה שלו אחרי שה-worker כבר ויתר עליה. המשימה נשארת אז בסטטוס processing עם recovering: true בזמן שהפלטפורמה מתקנת אותה, ובמודלים איטיים זה יכול לקחת עשרות דקות. אם השגיאה JobTimeoutError מסיימת את ההמתנה שלכם, שלפו את המשימה מאוחר יותר עם client.jobs.get(jobId), או הגדילו את maxMs.

runMany(type, paramsList, opts?)‎

מתחילה כמה הרצות של סוג רכיב אחד באותו זמן וממתינה לכולן, למשל כדי ליצור רשת של מועמדים. כל פריט רץ דרך runAndWait().

runMany(type: string, paramsList: Record<string, unknown>[], opts?: RunAndWaitOptions): Promise<RunManyResult[]>

מאפיין

סוג

const results = await client.nodes.runMany("generate-image", [
  { prompt: "A snow leopard at sunrise" },
  { prompt: "A snow leopard at golden hour" },
  { prompt: "A snow leopard at blue hour" },
])
for (const { jobId, output } of results) console.log(jobId, output.imageUrl)

המתודה מחזירה תשובה כשכל ההרצות הסתיימו: אובייקט { jobId, output } אחד לכל פריט, בסדר של הקלט. היא נכשלת ברגע שהרצה כלשהי נכשלת, עם אותן שגיאות כמו runAndWait(). פריט שהוא בעצמו אצווה, עם count גדול מ-1 או עם models, נדחה לפני שנשלח משהו. כדי לבחור אחר כך את התוצאה הטובה ביותר, העבירו את הכתובות ל-client.reduce.run().

runBatchAndWait(type, params, opts?)‎

יוצרת כמה תמונות בקריאה אחת לרכיב יצירת תמונה, וממתינה לכל אחת מהן. השתמשו ב-count כדי לקבל מ-1 עד 4 תמונות, כל אחת במשימה משלה. השתמשו ב-models כדי לשלוח את אותה בקשה אל 2–4 מודלי תמונה, במקום provider אחד. כשמשתמשים בשניהם, הפרמטר count חל על כל מודל, עד 8 תמונות בסך הכול.

runBatchAndWait(
  type: "generate-image",
  params: GenerateImageParams,
  opts?: RunAndWaitOptions,
): Promise<GenerateImageBatchOutput>

המתודה שולחת את האצווה פעם אחת, ואז ממתינה לכל משימה כמו ש-runAndWait() ממתינה. האצווה נבדקת מול היתרה שלכם, והיא מחויבת כולה או לא מחויבת בכלל. עם opts.idempotencyKey, המפתח של תמונה מספר i הוא <key>:<i>, ולכן ניסיון חוזר מחזיר את אותן משימות ולא נגבים קרדיטים פעם נוספת. הפרמטר presetId משתלב עם שתי האפשרויות: מספר תמונות לפי count מהבקשה של הערכה, או הערכה שמוחלת פעם אחת לכל מודל.

const { batch, results } = await client.nodes.runBatchAndWait(
  "generate-image",
  { prompt: "a lighthouse at dusk", models: ["gpt-image-2", "flux-2-max"], count: 2, seed: 41 },
  { idempotencyKey: crypto.randomUUID() },
)
console.log(batch.batchId, batch.totalCredits)
for (const r of results) {
  if (r.status === "completed") console.log(r.model, r.output.imageUrl)
  else console.warn(r.model, r.jobId, r.error.message)
}

המתודה מחזירה { batch, results }:

  • batch הוא התשובה לשליחה, מסוג GenerateImageBatchResult. יש בו jobId (המשימה הראשונה), jobIds (מודל אחר מודל, ובתוך כל מודל תמונה אחר תמונה), batchId, groups ({ model, jobIds, credits?, adjustments? } לכל מודל) ו-totalCredits. גם המתודה nodes.run("generate-image", …) מחזירה את אותו אובייקט כשהפרמטרים קובעים count גדול מ-1 או models.
  • results כולל BatchJobOutcome אחד לכל משימה, בסדר של batch.jobIds. כל אחד מהם הוא { jobId, model, status: "completed", output } או { jobId, model, status: "error", error }. השדה error הוא השגיאה JobFailedError, JobHeldError או JobTimeoutError שסיימה את ההמתנה. תמונה אחת שנכשלה אף פעם לא מבטלת את התמונות האחרות.

המתודה נכשלת רק לפני שקיימת משימה כלשהי, עם השגיאות של השליחה עצמה, כגון InsufficientCreditsError עם הסכום הכולל של האצווה ב-required. היא נכשלת גם עם JobAbortedError כשה-signal שלכם מבטל את ההמתנה. בקשה לתמונה אחת נדחית לפני שנשלח משהו, עם הקוד not_a_batch: המתינו לה עם runAndWait(). עם seed, תמונה i מקבלת seed + i. כדי למצוא מאוחר יותר את המשימות של אצווה, השתמשו ב-client.jobs.list({ batchId }).

פרמטרים עם טיפוסים

לסוגי הרכיבים האלה יש פרמטרים עם טיפוסים, ולכן עורך הקוד שלכם משלים את השדות שלהם ובודק אותם. כל סוג רכיב אחר מקבל אובייקט רגיל, והשדות שלו הם שדות הקלט של הרכיב, שמפורטים ב-inputSchema ובדף שלו במדריך הרכיבים. גם לרכיבי סצנות התלת־ממד יש פרמטרים עם טיפוסים: ראו את הדף סצנות תלת־ממד.

סוג הרכיבטיפוס הפרמטריםדף הרכיב
generate-imageGenerateImageParamsיצירת תמונה
image-to-imageImageToImageParamsעריכת תמונה
edit-imageEditImageParamsהגדלת תמונה
split-imageSplitImageParams
generate-maskGenerateMaskParamsיצירת מסכה
generate-videoGenerateVideoParamsיצירת וידאו
text-to-videoTextToVideoParamsיצירת וידאו
video-to-videoVideoToVideoParamsוידאו לווידאו
assemble-narrated-videoAssembleNarratedVideoParamsהרכבת וידאו עם קריינות
video-depthVideoDepthParamsעומק וידאו
video-upscaleVideoUpscaleParamsהגדלת וידאו

כל אובייקט פרמטרים עם טיפוסים מקבל גם שדות אחרים של הנתיב. השרת בודק את התקינות של גוף הבקשה כולו.

GenerateImageParams

מאפיין

סוג

גם השדות strength ו-guidanceScale מוגדרים בטיפוס GenerateImageParams.

ערכות ברכיב יצירת תמונה

הפרמטר presetId מחיל ערכה בדיוק כמו שהעורך מחיל אותה: הפרומפט, הטקסט לפני ואחרי, ערכי ברירת המחדל של המשתנים, הסגנון, הפרומפט השלילי וההגדרות. כך המשימה זהה לזו שהכפתור הרצה בעורך היה יוצר. השתמשו במזהה מובנה מ-presets.listFactory("generate-image"), או באחת הערכות שלכם. שדות שאתם מעבירים גוברים על הערכה.

משתנה בלי ברירת מחדל צריך ערך ב-presetVariables. בלי ערך, הקריאה נדחית עם 400 preset_variables_required, והשגיאה מציינת את המשתנה.

await client.nodes.runAndWait("generate-image", {
  presetId: "generate-image/logo-wordmark",
  presetVariables: { BRAND: "Acme" },
})

GenerateVideoParams

הנתיב מתמונה לווידאו: פריים פתיחה, פריים סיום אופציונלי וייחוסים.

מאפיין

סוג

TextToVideoParams

הנתיב לווידאו מפרומפט בלבד, POST /v1/text-to-video. הפרומפט נדרש, ופריימי פתיחה וסיום שייכים ל-generate-video. בקשה למודל בלי מצב של טקסט לווידאו נדחית עם 400 image_required.

מאפיין

סוג

הטיפוס TextToVideoParams מקבל contentPolicyRewrite?: boolean. כשהשדה חסר או true, אחרי דחייה בגלל זכויות יוצרים יש ניסיון חוזר אחד עם פרומפט בניסוח אחר. עם false, דחייה בגלל זכויות יוצרים מכשילה את המשימה.

טיוטות ב-Seedance 2.5

הטיפוסים GenerateVideoParams ו-TextToVideoParams מקבלים draft: true. ב-seedance-2-5, ההרצה היא טיוטה ב-480p במחיר של הרצה ב-480p. השלימו את הטייק שאהבתם עם run("video-upscale", { provider: "seedance-2-5-hd", sourceJobId }): אותו טייק, מרונדר מחדש ב-1080p, במחיר שנקבע לפי האורך של הטיוטה. מקור שהוא לא טיוטה שלכם שהסתיימה נדחה עם קוד 4xx לפני שנגבים קרדיטים. ראו את הסעיף מצב טיוטה ב-Seedance 2.5 בדף יצירת וידאו.

const draft = await client.nodes.run("generate-video", { prompt, provider: "seedance-2-5", draft: true, duration: 8 })
// Wait for the draft and review it. When you like the take, finalize it at 1080p.
if ("jobId" in draft) {
  const final = await client.nodes.runAndWait("video-upscale", { provider: "seedance-2-5-hd", sourceJobId: draft.jobId })
  console.log(final.videoUrl)
}

הגדלת וידאו עם Topaz. הטיפוס VideoUpscaleParams מקבל targetResolution ("720p", "1080p" או "4k", לפי הצלע הקצרה של הפריים; ברירת המחדל היא 1080p) ו-targetFps (מ-15 עד 60; ברירת המחדל היא הקצב של המקור עצמו): run("video-upscale", { videoUrl, targetResolution: "4k", targetFps: 60 }). ב-Topaz החיוב הוא לפי שימוש. ראו את הסעיף קרדיטים בדף הגדלת וידאו. הפרמטר upscaleFactor מיושן. השרת עדיין מקבל אותו ומחיל אותו על הצלע הקצרה של המקור.

VideoToVideoParams

נתיב עריכת הווידאו, POST /v1/video-to-video. עריכה ב-seedance-2-5 נבנית בשרת, ולכן שולחים את אותו גוף בקשה כמו לכל מודל עריכה אחר. ראו את הדף וידאו לווידאו.

מאפיין

סוג

הטיפוס כולל גם את audio, multiShots, videoEditDuration, audioSetting ו-promptExtend למודלים שמקבלים אותם, ובנוסף את sessionId ו-origin. כל מודל אחר דוחה את שלוש רשימות הייחוסים. המספור של הייחוסים והמגבלות מופיעים בדף וידאו לווידאו.

נתיבי תמונה עם טיפוסים

ל-image-to-image, ל-edit-image, ל-split-image ול-generate-mask יש ב-run overloads עם טיפוסים. לשלושת הסוגים שמתחילים משימה יש אותם גם ב-runAndWait. כל טיפוס פרמטרים מבוסס על רשימות הערכים של הפלטפורמה עצמה, כגון ModifyImageProvider, ImageEditProvider, ImageAspectRatio ו-ImageResolution, שה-SDK מייצא מחדש. כל שדה אחר של הנתיב עדיין עובר.

הבדיקה בזמן ההידור חלה כשגוף הבקשה מוגדר מטיפוס הפרמטרים: const params: EditImageParams = …, או { … } satisfies EditImageParams בתוך הקריאה. גוף בקשה שנכתב ישירות בתוך הקריאה, וה-overload עם הטיפוסים דוחה אותו, עדיין עובר הידור. הוא נופל ל-overload הכללי run(type: string, …), שאין לו טיפוסים, והנתיב מחזיר 400. השתמשו ב-satisfies כדי לקבל את הבדיקה.

  • image-to-image, edit-image ו-generate-mask. המתודה run מחזירה ImageJobStarted, כלומר { jobId: string; adjustments? }, ולכן השדה result.jobId לא צריך המרת טיפוס.
  • ImageToImageParams דורש imageUrl ו-prompt. השדה maskUrl שלו (הלבן הוא האזור לשינוי) נשלח למודל כמסכה בפני עצמה, ולכן רק המודלים ideogram-edit ו-flux-fill משתמשים בו.
  • EditImageParams הוא אחת משתי צורות. הוא מקבל imageUrl בכל מודל, חוץ מפעולות ה-task של Grok. בהן הוא מקבל taskId עם provider: "grok-2-edit" | "grok-2-segment": מזהה ה-task של יצירה קודמת ב-Grok Imagine 2, ששמור בנתוני הפלט של המשימה ההיא. גוף בקשה עם טיפוסים ששולח את שניהם, או taskId עם מודל אחר, לא עובר הידור. מודל ברירת המחדל הוא recraft-upscale. השדה prompt נדרש ב-nano-banana-edit וב-grok-2-edit. השדה maskIndexes מיועד ל-grok-2-edit בלבד.
  • split-image לא עולה כלום ומחזיר תשובה מיד. הוא לא יוצר משימה, ולכן המתודה runAndWait לא רלוונטית לו. המתודה run מחזירה SplitImageResult, כלומר { images: { name, url }[] }: קובץ PNG אחד לכל אריח, בסדר של names. ב-names חייבים להיות בדיוק gridCols × gridRows פריטים, וכל אחד מ-gridCols ו-gridRows הוא בין 1 ל-6.
  • generate-mask הוא הדרך של ה-SDK להתחיל משימה של רכיב יצירת מסכה. הקריאה runAndWait("generate-mask", …) מחזירה GenerateMaskJobOutput: השדה maskUrl, קובץ ה-PNG של המסכה, שבו הלבן הוא הנושא, והשדה imageUrl, תמונת המקור, שמועברת בלי שינוי.
import type { EditImageParams, GenerateImageParams, GenerateMaskParams } from "@nodaro/sdk"

const { maskUrl } = await client.nodes.runAndWait("generate-mask", { imageUrl, prompt: "the red car" } satisfies GenerateMaskParams)
await client.nodes.runAndWait("generate-image", { prompt: "a blue car", baseImageUrl: imageUrl, maskUrl } satisfies GenerateImageParams)
const { jobId } = await client.nodes.run("edit-image", { imageUrl, provider: "topaz-image-upscale", upscaleFactor: "4" } satisfies EditImageParams)

VideoDepthParams

הרכיב הופך קליפ לסרטון עומק, שבו מה שקרוב בהיר ומה שרחוק כהה (POST /v1/video-depth). במשימה שהסתיימה יש videoUrl ו-thumbnailUrl. המחירים ומגבלות האורך מופיעים בדף עומק וידאו.

מאפיין

סוג

השרת מתעלם מהגדרה שהספק שנבחר לא מקבל, ולכן החלפת ספק אף פעם לא מכשילה בקשה. ערך מחוץ לרשימות שלמעלה נדחה עם 400 validation_error. הקליפ נמדד לפני שמשוריינים קרדיטים. קליפ ארוך מדי נדחה עם 400 video_too_long: יותר מ-2,400 פריימים או מ-300 שניות ב-video-depth-anything ויותר מ-80 שניות ב-depth-anything-frames. קליפ שאי אפשר לקרוא נדחה עם 400 video_unreadable.

const { videoUrl } = await client.nodes.runAndWait("video-depth", {
  videoUrl: "https://cdn.example.com/clip.mp4",
  colormap: "turbo",
  resolution: "720p",
})

AssembleNarratedVideoParams

הרכיב מאחד מקטעי וידאו עם קריינות לסרטון אחד. המחיר של ההרצה נקבע לפי מספר המקטעים, והיא עולה 44–143 קרדיטים: 3 יחידות ועוד יחידה אחת לכל 6 מקטעים, או חלק מהם. איך כל מקטע מותאם לקריינות שלו מוסבר בדף הרכבת וידאו עם קריינות.

מאפיין

סוג

ייחוסים

הרכיבים generate-image, generate-video ו-text-to-video מקבלים ייחוסים כמו שהעורך מחבר אותם. השרת הופך אותם בפרומפט להוראות ממוספרות, כגון @image_1, כך שלא צריך לכתוב בעצמכם "Image 1 is..." (תמונה 1 היא…).

  • connectedReferences הוא רשימה של רשומות ConnectedReference, המבנה של ייחוס מחובר בעורך, שה-SDK מייצא. השרת מסיר כפילויות ומשאיר רק את מספר הייחוסים שהמודל מקבל. השדה referenceOrder קובע את הסדר שלהם לפי מזהה.
  • נעילת זהות. רשומה יכולה לכלול identityLock: { enabled: true, text? }. השרת מוסיף אז שורה קצרה שמבקשת מהמודל לשמור על הזהות של הייחוס הזה. השדה text מחליף את הניסוח המובנה, והמשתנה {ref} בתוכו מייצג את השם של הייחוס. נעילת הזהות כבויה כברירת מחדל.
  • describedReferences מקבל עד 10 רשומות { name, description } לנושאים שאפשר לתת להם שם אבל אין לכם תמונה שלהם, כגון תפקיד בתסריט. כל רשומה הופכת בפרומפט לשורה Name — description.. השאירו את השם בטקסט של הפרומפט, כדי שהמודל יידע מי זה.
  • descriptionOverride ברשומת ייחוס מחליף את התיאור השמור שלה, בהרצה הזו בלבד.
  • כיתובים לייחוסי וידאו ואודיו. השדות referenceVideoCaptions ו-referenceAudioCaptions תואמים לסדר של referenceVideoUrls ו-referenceAudioUrls. כל כיתוב מופיע בפרומפט כ-@video_1: caption. או כ-@audio_1: caption..
  • אזכור של תמונת ייחוס בפרומפט. ב-generate-image, תנו שם לייחוס והזכירו אותו כ-@<name>:<index> או כ-@<name>:<index>:<role>, למשל @town:1:background. האזכור מציב את הייחוס הזה, או את התפקיד שלו, בנקודה הזו של הפרומפט. הסימונים ~lock ו-~nolock עובדים כמו באזכורים של דמויות.

ראו את המדריך תפקידי ייחוס לתפקידים שאפשר להשתמש בהם ואת המדריך דמויות עקביות לשמירה על זהות.

הכוונה קולנועית

הרכיבים generate-image, generate-video ו-text-to-video מקבלים אובייקט direction של מזהי בוררים במקום מילים. Nodaro כותב לפרומפט ניסוח בדוק לכל מזהה, כך שהקוד שלכם שולח מזהים, והניסוח נשאר מעודכן.

await client.nodes.runAndWait("generate-image", {
  prompt: "A detective waits under a street lamp",
  direction: { shotSize: "wide-shot", timeOfDay: "golden-hour", mood: "suspicious" },
})
  • המפתחות הם ממדים של בוררים, כגון shotSize, lightingStyle, style, mood, photographer או era. נתיבי הווידאו מוסיפים מפתחות תנועה, כגון cameraMotion, actionFx, transition, loopSubject ומפתחות ה-temporal.
  • הערכים הם מזהה אחד או מערך של מזהים. ממד שמקבל כמה ערכים שומר לכל היותר את מספר הערכים שהמגבלה שלו מאפשרת ומשמיט את השאר. הבקשה נדחית רק מעל 8 ערכים למפתח או 100 תווים למזהה.
  • מפתחות ומזהים לא מוכרים מדולגים, ולא נדחים. אובייקט direction ריק לא משנה את הפרומפט שלכם.
  • מפה אחת משרתת גם תמונות וגם וידאו. מפתח שמיועד רק לתמונות ונשלח להרצת וידאו מתקבל ולא מוסיף כלום.
  • הרכיב extend-video לא מקבל direction, כי הפרומפט שלו ממשיך קליפ קיים.
  • הפלטות והמודבורדים שלכם עובדים ב-generate-image. קבעו את colorLook ל-paletteDirectionId(id), או את style ל-moodboardDirectionId(id). ראו את הסעיף פלטות ומודבורדים בדף בוררים, ערכות ופרומפטים.

את המזהים התקפים אפשר לקבל מ-client.pickerCatalogs. כל הממדים מפורטים בדף קטלוגי הבוררים.

הנושא

ב-GenerateImageParams וב-TextToVideoParams יש שדה אופציונלי subject, עם הטיפוס המיוצא Subject. השדה מתאר מי מופיע בשוט: האדם, הסטיילינג שלו והאביזרים בפריים, כמפה שטוחה משדה של בורר למזהה בקטלוג. אף פעם לא כותבים בשבילו טקסט של פרומפט. Nodaro כותב את הניסוח ומציב אותו מיד אחרי ה-prompt שלכם, לפני כל direction.

import type { Subject } from "@nodaro/sdk"

const subject: Subject = { type: "woman", age: "age-30s", hairBase: "base-short-straight", heldProp: "smartphone" }
await client.nodes.run("generate-image", { prompt: "on the seawall at dusk", subject })
  • שמות השדות והמזהים מגיעים מקטלוגי הבוררים. הקריאות client.pickerCatalogs.get("person") ו-get("styling") מחזירות את ה-field של כל ממד, עם ה-options[].id שלו. הקריאות get("held-prop"), get("material") ו-get("animal") כותבות את המזהים שלהן ל-valueField של הקטלוג: heldProp, material ו-animal.
  • הערכים הם מזהה אחד או רשימה של מזהים. מזהים מעבר למגבלה של הממד נשמטים, ולא נדחים. השדה customAge הוא המספר היחיד, בשנים, והשרת משתמש בו רק עם age: "age-custom".
  • מגבלות. בלי ערכה, הנתיב בודק את המפה. בקשה עם יותר מ-128 מפתחות, עם מפתח ארוך מ-64 תווים, עם יותר מ-8 מזהים במפתח אחד או עם מזהה ארוך מ-100 תווים נדחית עם 400 validation_error. מפתחות ומזהים לא מוכרים בתוך המגבלות האלה מדולגים, והשדה input_data.subject של המשימה שומר בדיוק את המזהים שהיו בשימוש.
  • עם presetId, השדה subject שלכם מחליף את זה של הערכה ומתווסף לפרומפט של הערכה, כמו direction. ערכים ארוכים מדי נשמטים במקום להידחות, והשדה input_data לא מתעד את הנושא.

כל המפתחות, והסדר שבו הניסוח מתווסף, מפורטים בדף ה-API רכיבים.

רכיבי מודל שפה

המתודה run(type, params) שולחת כל סוג של רכיב מודל שפה לנתיב שלו: הנתיב /v1/<type> ל-generate-script, ל-image-critic, ל-qa-check ול-describe-to-picker, ונתיב ארוך יותר לאחרים. לא צריך בשבילם את client.request():

סוג הרכיבנקודת קצה
llm-chat/v1/llm-chat/generate
after-effects/v1/after-effects/generate
motion-graphics/v1/motion-graphics/generate
lottie-overlay/v1/lottie-overlay/generate
3d-title/v1/3d-title/generate
image-to-text/v1/image-to-text/describe
video-composer/v1/scene-graph/generate
await client.nodes.run("generate-script", {
  prompt: "A 3-scene product launch script for a smart water bottle",
  reasoningEffort: "high",
})
  • reasoningEffort הוא "none", "low", "medium", "high", "xhigh" או "max", לפי המודל. השמיטו אותו, או שלחו רמה שהמודל לא תומך בה, כדי לקבל את ברירת המחדל של המודל. לרמת המאמץ אין מחיר משלה. כל קריאת LLM מחויבת לפי הטוקנים שהיא השתמשה בהם, בתעריף של המודל בשירות שהריץ אותה, ולכן רמה גבוהה יותר עולה יותר רק בגלל הטוקנים שהמודל כותב. במודל Claude, כל רמת מאמץ מריצה את הקריאה ב-API של היצרן עצמו, בתעריף של אותו שירות. המודלים מפורטים בדף יצירת טקסט - כל LLM, והחיוב מוסבר בסעיף איך מחויבות קריאות LLM בדף קרדיטים. חריג אחד: הרכיב describe-to-picker וגרסת הטקסט שלו, text-to-picker, רצים ברמה "high" כשמשמיטים את השדה והמודל ב-llmModel הוא claude-opus-5.5. ההרצה הזו עוברת דרך ה-API של Anthropic עצמה, בתעריף של אותו שירות. שלחו רמה אחרת כדי לשנות אותה. כל מודל אחר שומר על ברירת המחדל שלו, כולל מודל ברירת המחדל של שני הסוגים האלה, Gemini 3.8 Flash.
  • advancedMode: true מריץ מודל Gemini או Claude ישירות ב-API של היצרן שלו. רק שם temperature, maxTokens וכל טווח רמות המאמץ נכנסים לתוקף במלואם. הקריאה מחויבת בתעריף לטוקן של אותו שירות. בקשה עם מודל בלי האפשרות הזו נדחית עם 400 advanced_mode_unsupported. כל עוד הספק של המודל עצמו לא יכול לקבל בקשות, הקריאה נכשלת עם advanced_mode_unavailable במקום לרוץ בשירות ברירת המחדל: עם הקוד 400 מראש, או 502 באמצע הקריאה, והקרדיטים מוחזרים אלא אם הספק חייב על הניסיון. כבו את המצב המתקדם כדי להריץ את המודל. רכיב תיאור לבורר הוא החריג: שם, הרצה של Claude שהספק דוחה עוברת ל-Gemini 3.8 Flash, כמו שקורה כשהמצב המתקדם כבוי.
  • אומדן מחיר לקריאה. הקריאה client.credits.modelCosts([llmPriceKey(feature, model)]) מחזירה אומדן של קריאה טיפוסית, שמופיע ב-estimates. הציגו אותו כ-≈N. הפונקציה llmPriceKey מגיעה מ-@nodaro/shared/llm-models. ראו את הדף מודלים וקרדיטים.
  • אין מעטפת להזרמה. ה-SDK לא קורא את התשובה בהזרמה של רכיב יצירת טקסט - כל LLM. בשבילה, השתמשו ב-fetch עם זרם קריא.

כללים לפי מודל

כמה מודלי וידאו מקבלים ערכים שמודלים אחרים לא מקבלים. בדף של כל מודל מופיעים כל האפשרויות והמחירים.

  • Seedance 2 מקבל resolution: "4k" ו-aspectRatio: "adaptive" או "21:9". Seedance 2 Fast ו-Seedance 2 Mini מרנדרים ב-480p או ב-720p בלבד.
  • Seedance 2.5 מרנדר ב-480p, ב-720p או ב-1080p, יוצר עד 30 שניות בקריאה אחת ומקבל 30 תמונות ייחוס, 10 סרטוני ייחוס ו-10 קטעי אודיו ייחוס. עם פריים פתיחה, הוא משתמש ביחס של הפריים הזה ודוחה aspectRatio מפורש.
  • MiniMax H3 (minimax-h3) מקבל 9 תמונות ייחוס, 3 סרטוני ייחוס ו-3 קטעי אודיו ייחוס, ב-resolution: "2K" (ברירת המחדל) או "768P". כל ערך אחר מרונדר ומתומחר כמו 2K.
  • Wan 3.0 (wan-3 ו-wan-3-prime המהיר יותר) מקבל 10 תמונות ייחוס, 5 סרטוני ייחוס ו-5 קטעי אודיו ייחוס. אי אפשר לשלב את רשימות הייחוסים עם imageUrl או עם endFrameUrl. הערך של duration הוא מספר שלם מ-2 עד 30, והערך של resolution הוא 480p, 720p או 1080p.
  • Gemini Omni Flash מקבל אותה בקשה כמו Gemini Omni: אורכים של 4, 6, 8 או 10 שניות, מ-720p עד 4K ורק 16:9 או 9:16.
  • Kling 4.0 (kling-4) רץ מטקסט בלבד, או מחומרי ייחוס. הוא מקבל referenceImageUrls (עד 10), referenceVideoUrls (עד 5, כל אחד באורך של 2–30 שניות), characterReferences (עד 7, כנושאים עם שם) ו-referenceAudioUrls (עד 3). בקשה עם יותר מ-15 חומרים בסך הכול נדחית עם 400 לפני שמשוריינים קרדיטים. השדות imageUrl ו-endFrameUrl, כשהם נשלחים, מצטרפים לתמונות הייחוס. ב-kling-4, כל ייחוס דמות נבנה מ-imageUrl, מ-bodyImageUrl ומ-extraImageUrls (עד 3), מותר לשלוח פריים פתיחה, ואילו השדה voice נדחה. הערך keepOriginalSound: true שומר על הסאונד המקורי של סרטון ייחוס. קטע האודיו הראשון מתנגן כברירת מחדל כפסקול. הוא נשלח כעוד סרטון ייחוס, ולכן ההרצה מתומחרת כמו הרצה עם סרטון ייחוס, ושאר הקטעים נשארים קולות עם שם. הערך audioSoundtrack: false משאיר כל קטע כדגימת קול. בהרצה עם סרטון ייחוס משלמים על הפלט ועוד על הארוך מבין הפלט והקליפים, בתעריף הייחוס. Kling 4.0 Keyframes (kling-4-keyframes) מקבל imageUrl, עד 8 פריימי ביניים ב-referenceImageUrls, לפי הסדר, ו-endFrameUrl. המספר הכולל של הפריימים מוגבל לפי duration: מ-4 ב-3 שניות ועד 10 מ-9 שניות ומעלה, ובקשה עם יותר פריימים נדחית עם 400. שני המודלים מקבלים duration מ-3 עד 30 (ברירת המחדל היא 5) ו-resolution של 720p או 1080p; כל ערך אחר מרונדר ב-720p. הערך של aspectRatio הוא auto, 16:9, 9:16, 1:1 או 21:9. האודיו תמיד מופעל, ואין זרע.
  • Gemini Omni ו-Gemini Omni Flash (gemini-omni-video ו-gemini-omni-flash) שומרים על הפנים של אדם אמיתי עם characterReferences. העבירו עד 3 רשומות בצורה { imageUrl, description, bodyImageUrl?, name?, voice? }. השדה voice הוא { preset, description?, exampleLine? }, והשדה preset הוא אחד המזהים של GEMINI_OMNI_VOICE_PRESETS מ-@nodaro/shared. השדה הזה שומר על קול אחד לדמות בכל הקליפים. בכל מודל אחר הבקשה נדחית עם 400, ואי אפשר לשלב את characterReferences עם פריים פתיחה (imageUrl). כל דמות תופסת יחידה אחת מתוך 7 יחידות הקלט של המודל, או 2 עם bodyImageUrl, ותמונות ייחוס וסרטון מקור חולקים את אותן יחידות. ייחוסי דמויות לא מוסיפים קרדיטים. השתמשו בהם במקום ב-referenceImageUrls כשהפנים חייבות להישאר זהות.

טקסט לדיבור. כשמשמיטים את provider, רכיב טקסט לדיבור משתמש ב-ElevenLabs v4 לטקסט של עד 10,000 תווים. טקסט ארוך יותר עובר ל-ElevenLabs Turbo v2.5, שהמגבלה שלו היא 40,000 תווים, כך שהוא לא נחתך. כשאתם מציינים provider, הרכיב תמיד משתמש בו. שלחו provider: "elevenlabs-v3" כדי להישאר עם ElevenLabs v3, שהמגבלה שלו היא 5,000 תווים.

רציפות בין קליפים. רכיב טקסט לדיבור מקבל גם previousText ו-nextText: השורות שנאמרות ממש לפני הקליפ ואחריו, עד 1,000 תווים כל אחת. הן לא מוקראות. ElevenLabs v4, v4 Turbo, Turbo v2.5 ו-Multilingual v2 משתמשים בהן כדי לשמור על אינטונציה אחת בקליפים שנוצרו בנפרד. ElevenLabs v3 מתעלם מהן.

רכיבי גריפה ורכיבי קלט אחרים

רכיבי קלט רצים באותו אופן. רכיב גריפה, כגון גריפת אתר, עונה מיד: התוצאה כוללת jobId בשביל ההיסטוריה שלכם וגם את הנתונים עצמם, כך שאפשר להשתמש בהם בלי לבדוק את הסטטוס מדי כמה שניות. שדות הבקשה הם שדות הקלט של הרכיב, שמפורטים ב-inputSchema.

שאלות נפוצות

איך יוצרים תמונה עם ה-SDK של Nodaro?

קראו למתודה client.nodes.runAndWait עם סוג הרכיב generate-image ועם פרומפט. המתודה runAndWait מחזירה את הפלט של המשימה, וה-imageUrl שבפלט הוא התמונה שנוצרה.

מה ההבדל בין המתודה run למתודה runAndWait?

המתודה run מתחילה את הרכיב ומחזירה jobId מיד. המתודה runAndWait מתחילה אותו, בודקת את הסטטוס של המשימה כל 2 שניות ומחזירה את הפלט כשהמשימה מסתיימת.

כמה זמן המתודה runAndWait ממתינה?

המתודה runAndWait ממתינה עד 15 דקות כברירת מחדל. אפשר לשנות את הזמן עם האפשרות maxMs. פסק זמן לא מבטל את המשימה, ובדרך כלל היא עדיין מסתיימת בשרת.

אילו סוגי רכיבים אפשר להריץ?

קראו למתודה client.nodes.list()‎ כדי לקבל כל סוג שהשרת תומך בו, עם הקטגוריה, סוג הפלט, המודלים והמחיר בקרדיטים שלו. לכל רכיב במדריך הרכיבים יש סוג ב-API.

איך יוצרים כמה תמונות בקריאה אחת?

קראו למתודה client.nodes.runBatchAndWait עם generate-image ועם count (מ-1 עד 4 תמונות) או models (בין 2 ל-4 מודלי תמונה). האצווה מחויבת כולה או לא מחויבת בכלל, ותמונה אחת שנכשלה אף פעם לא מבטלת את התמונות האחרות.

איך נמנעים מתשלום כפול כשמנסים שוב בקשה?

העבירו idempotencyKey באפשרויות של המתודה run או של המתודה runAndWait, והשתמשו באותו מפתח כשאתם מנסים שוב. הפלטפורמה מחזירה את ההרצה הראשונה במקום להתחיל הרצה שנייה.

עודכן לאחרונה

בדף הזה