Nodaro ドキュメント
ドキュメントノードリファレンスモデルAI エージェント(MCP)開発者向けセルフホスティングリサーチ

ピッカーカタログ

@nodaro/prompts を使って、Nodaro のピッカーを自分のアプリに実装します。選択をプロンプトの一節に変換し、ラベルを翻訳し、画像を表示します。API でカタログを読み取ることもできます。

ピッカーカタログは、ムード(Mood)、レンズ(Lens)、フレーミング(Framing)、人物(Person)といった、Nodaro のピッカー(クリエイティブコントロールのノード)の 1 つを支えるデータです。ピッカーの選択肢、各選択肢が追加するプロンプトのテキスト、そのカテゴリー、翻訳のキーを保持します。カタログは npm パッケージの中に単純なデータとして同梱されているため、自分のアプリに、自分のスタイルで同じピッカーを実装し、Nodaro が組み立てるのとまったく同じプロンプトを組み立てられます。

ピッカーがモデルを呼び出すことはありません。ピッカーは、自分がつながっている先のノードのプロンプトに、説明的な一節を追加するだけです。クリエイティブコントロールを参照してください。

パッケージをインポートするか、API を呼び出す

あなたのアプリ方法
npm パッケージを同梱できる@nodaro/prompts からカタログをインポートします。型が付いていて、オフラインで動作し、API 呼び出しは不要です。
パッケージを同梱できない(MCP 経由の AI エージェントなど)同じデータを、ディスカバリー用のインターフェースから読み取ります。REST エンドポイントの GET /v1/picker-catalogs、SDK の client.pickerCatalogs、CLI の nodaro pickers、または MCP ツールの get_picker_catalog です。

できる場合は、パッケージを優先してください。リリースのときにしか変わらないデータのために、往復通信を省けます。

npm install @nodaro/prompts @nodaro/shared @nodaro/sdk

@nodaro/prompts にはカタログとプロンプト用の関数が、@nodaro/shared には翻訳が入っており、@nodaro/sdk が生成を実行します。

レジストリ

import { PICKER_CATALOGS, getPickerCatalog, listPickerCatalogs } from "@nodaro/prompts"
エクスポート返す内容
PICKER_CATALOGSすべてのピッカーカタログです。単一次元のピッカーが 28 個、複数次元のピッカーが 11 個あります。
getPickerCatalog(nodeTypeOrCatalogId)ノードタイプ("mood" など)またはカタログ ID で指定する、1 つのカタログです。
listPickerCatalogs()そのすべてです。

カタログの型は、次のとおりです。

interface PickerOption {
  id: string
  label: string            // English display text; translate it with the catalogId (see below)
  description?: string
  category?: string        // group id, matching categoryOrder and categoryLabels
  promptHint: string       // the clause this option adds ("" for a no-op option such as "auto")
  term: string             // the short professional term Compact mode adds ("" for a no-op option)
  icon?: string            // reserved; pictures are served separately (see "Pictures")
}

interface PickerDimension {  // multi-dimension pickers, and the secondary fields of a single-dimension picker
  field: string              // for example "shotSize"
  label: string
  options: readonly PickerOption[]
}

interface PickerCatalog {
  nodeType: string           // "mood", "framing", ...
  label: string
  catalogId: string          // the key of the translations
  kind: "single" | "multi"
  valueField?: string        // single: the field a selection writes
  defaultValue?: string
  categoryOrder?: readonly string[]
  categoryLabels?: Readonly<Record<string, string>>
  options?: readonly PickerOption[]        // single-dimension pickers
  fields?: readonly string[]               // multi-dimension pickers: the dimension fields
  dimensions?: readonly PickerDimension[]  // multi-dimension pickers, and secondary fields
}

label は画面に表示し、term または promptHint はモデルに送ってください。一方からもう一方を導き出さないでください。

単一次元のピッカーを実装する

ムードのような単一次元のピッカーは、フラットなリストから 1 つを選ぶもので、グループ分けされることもあります。options には、グリッドを描画するために必要なものがすべて入っています。

import { getPickerCatalog, getParameterPromptHint } from "@nodaro/prompts"
import { createClient, StaticTokenAuth } from "@nodaro/sdk"

const client = createClient({
  baseUrl: "https://app.nodaro.ai",
  auth: new StaticTokenAuth(process.env.NODARO_ACCESS_TOKEN!),
})
const mood = getPickerCatalog("mood")! // { nodeType: "mood", valueField: "mood", options, categoryOrder, categoryLabels }

// 1. Render your own tile grid, grouped by category
function MoodPicker({ value, onChange }: { value?: string; onChange: (id: string) => void }) {
  return (mood.categoryOrder ?? [undefined]).map((cat) => (
    <section key={cat ?? "all"}>
      {cat && <h4>{mood.categoryLabels?.[cat]}</h4>}
      {mood.options!
        .filter((o) => !cat || o.category === cat)
        .map((o) => (
          <button key={o.id} aria-pressed={value === o.id} title={o.description} onClick={() => onChange(o.id)}>
            {o.label}
          </button>
        ))}
    </section>
  ))
}

// 2. Selection, then prompt clause, then generation
const selected = "serene"
const clause = getParameterPromptHint({ type: "mood", data: { mood: selected } })
// or: mood.options!.find((o) => o.id === selected)!.promptHint

const prompt = ["a portrait of a woman", clause].filter(Boolean).join(", ")
const result = await client.nodes.runAndWait("generate-image", { prompt })
console.log(result.imageUrl)

トランジション、キャラクター FX、キャラクターモーションの副次パラメーター

3 つの単一次元のピッカーには、主要な選択のほかに、追加のフィールドがあります。トランジション(Transition)とキャラクター FX(Character FX)には、それぞれ position、duration、intensity があります。キャラクターモーション(Character Motion)には position と pace があります。

これらのフィールドもカタログであり、ほかのすべての選択肢と同じ行の形を持ち、各リストの先頭には、何もしない auto があります。カタログはこれらを、options に加えて、dimensions として公開します。メインのピッカーは options から、ドロップダウンは dimensions から描画してください。ID だけを送るクライアントが、タイミングの一節を自分で書くことはありません。

const fx = getPickerCatalog("character-fx")!
fx.options     // the effects of the main picker
fx.dimensions  // [{ field: "position", ... }, { field: "duration", ... }, { field: "intensity", ... }]

// Each dimension's rows are also exported directly:
//   TRANSITION_POSITIONS / TRANSITION_DURATIONS / TRANSITION_INTENSITIES
//   CHARACTER_FX_POSITIONS / CHARACTER_FX_DURATIONS / CHARACTER_FX_INTENSITIES
//   CHARACTER_MOTION_POSITIONS / CHARACTER_MOTION_PACES

トランジションとキャラクター FX は、同じ ID を共有します。start、middle、end、full。instant、short、medium、long。subtle、natural、dynamic、crazy です。ただし、文言までは共有しません。トランジションの文言は「起こる」「クリップ全体にわたる」、エフェクトの文言は「現れる」「持続する」のように書かれています。行は必ず、そのノード自身のカタログから読み取ってください。キャラクターモーションは position の ID を共有し、それに加えて、独自の pace の ID(slow-motion、slow、natural、fast、explosive)を、独自の文言とともに持ちます。

複数次元のピッカーを実装する

複数次元のピッカーは、いくつかの独立したフィールドを同時に設定します。たとえばフレーミングは、ショットサイズ、アングル、カバレッジ、構図、撮影方向を設定します。そのカタログには、dimensions の中に、フィールドごとに 1 つの { field, label, options } エントリがあります。

import { getPickerCatalog, getParameterPromptHint } from "@nodaro/prompts"

const framing = getPickerCatalog("framing")!
// framing.dimensions = [
//   { field: "shotSize",    label: "Shot Size",   options: [{ id: "close-up", ... }, ...] },
//   { field: "angle",       label: "Angle",       options: [{ id: "low-angle", ... }, ...] },
//   { field: "coverage",    label: "Coverage",    options: [...] },
//   { field: "composition", label: "Composition", options: [...] },
//   { field: "vantage",     label: "Vantage",     options: [...] },
// ]

function FramingPicker({ value, onChange }: {
  value: Record<string, string>
  onChange: (v: Record<string, string>) => void
}) {
  return framing.dimensions!.map((dim) => (
    <section key={dim.field}>
      <h4>{dim.label}</h4>
      {dim.options.map((o) => (
        <button
          key={o.id}
          aria-pressed={value[dim.field] === o.id}
          title={o.description}
          onClick={() => onChange({ ...value, [dim.field]: o.id })}
        >
          {o.label}
        </button>
      ))}
    </section>
  ))
}

// Selection to clause: getParameterPromptHint composes every field that is set
const value = { shotSize: "close-up", angle: "low-angle", composition: "rule-of-thirds" }
const clause = getParameterPromptHint({ type: "framing", data: value })

選択をプロンプトに変換する

getParameterPromptHint({ type, data }) は、単一次元でも複数次元でも、どの選択もその一節に変換します。Nodaro がサーバー上で実行しているのと同じ関数なので、あなたのプロンプトはエディターのものと一致します。カタログごとのビルダーもあります。複数次元のピッカー向けの buildFramingHints(value) や、1 つの選択肢向けの getMoodPromptHint(id) などです。

// Several pickers, one prompt, one generation
const clauses = [
  getParameterPromptHint({ type: "mood",    data: { mood: "serene" } }),
  getParameterPromptHint({ type: "lens",    data: { lens: "portrait-85mm" } }),
  getParameterPromptHint({ type: "framing", data: { shotSize: "close-up", angle: "eye-level" } }),
]
const prompt = ["a portrait of a woman in a garden", ...clauses].filter(Boolean).join(", ")
const result = await client.nodes.runAndWait("generate-image", { prompt, provider: "nano-banana-2" })

ピッカーの data に hintMode: "compact" を追加すると、完全な一節の代わりに、短い term を取得できます。これは、エディターのプロンプトヒントトグルのコンパクトモードです。フルとコンパクトを参照してください。

関数内容
getParameterPromptHint({ type, data })どの選択も、組み立てられた一節に変換します。
build<Name>Hints(value)buildFramingHints など、1 つのカタログの一節を組み立てます。
get<Name>PromptHint(id)getMoodPromptHint など、1 つの選択肢の一節を返します。
PICKER_CATALOGS、getPickerCatalog、listPickerCatalogsレジストリです。

ラベルを翻訳する

カタログのラベルは英語です。12 ロケール(en、es、fr、de、pt-BR、ru、hi、ja、ko、zh-CN、he、ar)の翻訳が、各カタログの catalogId をキーとして @nodaro/shared に同梱されています。promptHint と term の値は、モデルが読み取るため、英語のままです。

英語にはセットアップが不要です。それ以外のロケールでは、起動時に一度だけ翻訳バンドルを登録し、そのあとは同期的にラベルを取得します。フォールバックは英語です。

import { registerSidecarLoaders, ensureLocaleCatalogLoaded, resolveLabel } from "@nodaro/shared"

// 1. Once at startup, in a Vite app: wire the lazily loaded locale bundles
registerSidecarLoaders(import.meta.glob("/node_modules/@nodaro/shared/src/i18n/*.*.ts"))

// 2. Before rendering a locale, load that catalog's bundle
await ensureLocaleCatalogLoaded(mood.catalogId, "fr")

// 3. Resolve a label, synchronously; English when a translation is missing or not loaded yet
const label = resolveLabel(mood.catalogId, option.id, option.label, "fr")

バンドルはオンデマンドで読み込まれるため、registerSidecarLoaders は、Vite の import.meta.glob が返すもののような、ローダーのマップを受け取ります。バックエンドとテストでは、翻訳を省略して、英語の label を使ってかまいません。

画像を表示する

自分のアプリでも、これらのピッカーについて、エディターと同じ画像を表示できます。

  • 写真。人物、スタイリング(Styling)、手に持つ小道具(Held Prop)、素材(Material)、動物(Animal)に表示されます。
  • アート。音楽と音声のピッカー、音楽ジャンル(Music Genre)、音楽のムード(Music Mood)、楽器編成(Instrumentation)、声の特徴(Voice Character)、話し方(Voice Delivery)に表示されます。
  • プレビュー静止画。見た目系のピッカーに表示されますが、Nodaro Cloud だけです。対象は、スタイル(Style)、カラー/ルック(Color / Look)、年代/時代(Era / Period)、レンズ、ムードです。ほかに、大気効果(Atmosphere)、構図エフェクト(Composition Effect)、カメラ/フィルム(Camera / Film)、フレーミング、ライティング(Lighting)、カメラモーション(Camera Motion)も含まれます。

API 経由の場合、画像がある選択肢には、問い合わせたインストール環境上の絶対 URL である imageUrl が付き、画像がない選択肢には何も付きません。人物とスタイリングは sections も返します。これは、各トピックを順番に並べたもので、それぞれに丸い画像が付きます。URL の規則は、後述の API でカタログを読み取るにあります。

ライブラリの場合、@nodaro/prompts が、同じデータから同じ URL を組み立てます。

  • 選択肢には pickerOptionImageUrl(catalog, field, id, { baseUrl })。
  • 人物やスタイリングのトピックには pickerSectionImageUrl(topicLabel, { baseUrl })。

baseUrl は、ファイルを配信する Nodaro のインストール環境です。画像は npm パッケージにではなく、インストール環境に属します。lookPreviews: true は、Nodaro Cloud に対してだけ渡してください。それ以外のピッカーについては、label、description、category から、自分で見た目を作成してください。

API でカタログを読み取る

どちらのエンドポイントも公開されていて、トークンは不要で、5 分間キャッシュされます。

メソッドパス返す内容
GET/v1/picker-catalogsすべてのピッカーの一覧です。nodeType、label、catalogId、kind、valueField または fields、optionCount、そして画像がある選択肢の数である imageCount が含まれます。
GET/v1/picker-catalogs/:nodeType1 つのピッカーのカタログです。不明なタイプには 404 not_found が返ります。

GET /v1/picker-catalogs/:nodeType は、3 つのクエリパラメーターを受け取ります。不正な値には 400 validation_error が返ります。

パラメーター値動作
detailcompact(デフォルト)または fullcompact は id、label、category、term、icon、imageUrl を返します。full は、各選択肢の description と promptHint を追加します。
categoryカテゴリー ID単一次元のピッカーを、1 つのカテゴリーに絞り込みます。
fieldフィールド名複数次元のピッカーの 1 つの次元、またはトランジション、キャラクター FX、キャラクターモーションの副次フィールドの 1 つを返します。
curl -s https://app.nodaro.ai/v1/picker-catalogs/mood | jq '.data.options[0]'
{ "id": "happy", "label": "Happy", "category": "positive", "term": "happy expression",
  "imageUrl": "https://cdn.nodaro.ai/cdn-cgi/image/width=480,format=auto,quality=80/images/710df65a-3c1e-485b-b8b7-29f7b3baf479.png" }

画像の URL

ピッカー画像
person、styling、held-prop、material、animal写真です。WebP、幅は最大 480 px です。
music-genre、music-mood、instrumentation、voice-character、voice-delivery3D の絵文字画像(WebP、128 px)または国旗の画像(WebP、幅 120 px)です。
style、color-look、lens、framing、lighting、mood、camera-format、camera-motion などの見た目系のピッカーNodaro Cloud では、Nodaro CDN から配信される、レンダリング済みプレビューの 480 px の静止画です。camera-motion の場合はクリップの 1 フレームです。セルフホスティング環境では、何も返りません。
  • ホスト。インストール環境は、自分の画像を /picker-art/ の下で配信するため、imageUrl はその公開アドレスを使います。Nodaro Cloud では https://app.nodaro.ai、セルフホスティング環境では PUBLIC_URL です。各 URL は、与えられたとおりに使ってください。選択肢の ID から自分で組み立てないでください。
  • キャッシュ。ファイル名にはコンテンツのハッシュが含まれるため、画像が変わると URL も変わります。ファイルは Cache-Control: public, max-age=31536000, immutable と Access-Control-Allow-Origin: * 付きで配信されるため、どのオリジンからでも、<img>、fetch、キャンバスで読み込めます。
  • トピック。person と styling は sections も返します。それぞれに label、まとめる fields、任意の丸い imageUrl が含まれます。
curl -s https://app.nodaro.ai/v1/picker-catalogs/person | jq '.data.sections[0], .data.dimensions[0].options[0]'
{ "label": "Identity", "fields": ["type", "age", "ethnicity", "regionalAesthetic"],
  "imageUrl": "https://app.nodaro.ai/picker-art/character/sections/identity.2d5ec1a4.webp" }
{ "id": "man", "label": "Man", "term": "man",
  "imageUrl": "https://app.nodaro.ai/picker-art/character/person/man.441363db.webp" }

デプロイメントのキュレーションされたカタログ

GET /v1/catalogs は、すべてのカタログを 1 回の呼び出しで、1 つのフラットな形として返します。デプロイメントは、選択肢を置き換え、追加、除外するベンダーパックを使って、自分のカタログをキュレーションでき、このエンドポイントはそのキュレーションを反映します。デプロイメントがパックを登録している場合、レスポンスには curated: true と、data にカタログが含まれます。登録していない場合は curated: false になり、同梱されているカタログは、ピッカーごとに /v1/picker-catalogs/:nodeType から読み取ります。SDK のメソッドは client.catalogs.list() です。

説明文からピッカーを埋める

POST /v1/text-to-picker は、シーンやショットの自由記述の説明文から、ピッカーの値を選びます。これは AI Fill 機能です。トークンが必要で、LLM の呼び出しとして課金されます。返されるのは、ピッカーのタイプ、次元、選ばれた ID の順にキーが付いた pickerJson と、どのカタログの選択肢にも当てはまらなかった説明内容である gaps です。SDK のメソッドは client.pickerCatalogs.analyzeText()、CLI のコマンドは nodaro pickers analyze です。

キャラクターモーションのメタデータ

キャラクターモーションのカタログの選択肢は、両方の詳細レベルで motion メタデータを持つことがあります。このメタデータは、動きを次のように説明します。

  • 必要条件、開始と終了のポーズ、そして動作後の可視性と手の状態です。
  • 手が空いている必要があるか、その種類、固定のペース、対になる動きです。
  • 検索用の別名、そして ID が廃止されているかどうかと、その代わりとなる ID です。

フィールドがない場合は、不明を意味します。

保存されたワークフローを読み込むときは、廃止された ID も動作するようにし、新しい選択肢には表示しないでください。この型は CharacterMotionMetadata で、@nodaro/prompts からエクスポートされています。

よくある質問

最終更新

目次