{
  "id": "near-provider-entry",
  "name": "Taifoon × NEAR AI Cloud — the provider entry (one external provider, in NEAR's admin shape)",
  "nodes": [
    {
      "parameters": {},
      "id": "start",
      "name": "Start",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        300
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "name",
              "name": "name",
              "value": "taifoon",
              "type": "string"
            },
            {
              "id": "backend",
              "name": "backend",
              "value": "openai_compatible",
              "type": "string"
            },
            {
              "id": "base_url",
              "name": "base_url",
              "value": "https://coord.taifoon.dev/v1",
              "type": "string"
            },
            {
              "id": "credential_env",
              "name": "credential_env",
              "value": "TAIFOON_API_KEY",
              "type": "string"
            },
            {
              "id": "models_path",
              "name": "models_path",
              "value": "models",
              "type": "string"
            },
            {
              "id": "execution_security",
              "name": "execution_security",
              "value": "non_tee",
              "type": "string"
            },
            {
              "id": "default_tee_requirement",
              "name": "default_tee_requirement",
              "value": "any",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "entry",
      "name": "Provider entry",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        300
      ],
      "notes": "The whole entry. cloud-api registry (PR #1275): POST /v1/admin/providers {name, config:{backend, base_url}, credential_env, models_path}. The key behind TAIFOON_API_KEY is minted by NEAR at POST https://coord.taifoon.dev/v1/register and funded by a USDC top-up on Base (GET /v1/access/quote); its value is never in this workflow.",
      "notesInFlow": true
    },
    {
      "parameters": {
        "options": {},
        "method": "GET",
        "url": "https://coord.taifoon.dev/v1/models"
      },
      "id": "models",
      "name": "Read the Taifoon catalogue",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        440,
        300
      ],
      "notes": "Discovery, exactly what the registry reads at {base_url}/{models_path}: OpenAI-shaped data[], each model with its exact price per 1M tokens in and out (the one format of the catalogue: price {unit usd_per_mtok, in, out}).",
      "notesInFlow": true
    },
    {
      "parameters": {
        "jsCode": "// One row per model, in the shape cloud-api's PATCH /v1/admin/models takes (crates/api/tests/e2e_all/external_providers.rs) and the\n// registry's approved pair + cost profile (PR #1275). Prices: Taifoon lists USD per 1M tokens (in, out); NEAR stores {amount, scale: 9}\n// per token (1.1 USD per 1M = {amount: 1100, scale: 9}) and the registry's cost profile in micro-USD per million tokens.\nconst e = $('Provider entry').first().json;\nconst list = ($('Read the Taifoon catalogue').first().json.data ?? []);\nconst price = (m) => { const p = m.pricing ?? m.price ?? {}; const i = Number(p.input ?? p.in ?? p.prompt), o = Number(p.output ?? p.out ?? p.completion); return Number.isFinite(i) && Number.isFinite(o) ? { in: i, out: o } : null; };\nconst perToken = (usdPerMtok) => ({ amount: Math.round(usdPerMtok * 1000), scale: 9, currency: 'USD' });\nconst models = [], skipped = [];\nfor (const m of list) {\n  const p = price(m); if (!p) { skipped.push(m.id); continue; }\n  models.push({\n    modelName: m.id, modelDisplayName: m.name ?? m.id, providerType: 'external', providerConfig: { backend: e.backend, base_url: e.base_url },\n    attestationSupported: false, verifiable: false, isActive: true, is_listed: true, allow_free: false,\n    inputCostPerToken: perToken(p.in), outputCostPerToken: perToken(p.out),\n    contextLength: m.context_length ?? m.context ?? null, maxOutputLength: m.max_output_length ?? null, quantization: m.quantization ?? null, hugging_face_id: m.hugging_face_id ?? (/^[^/]+\\/[^/]+$/.test(m.id) ? m.id : null),\n    inputModalities: ['text'], outputModalities: ['text'], supported_features: ['chat', 'streaming'], datacenters: ['DE'],\n    registry: { provider: e.name, pair: { upstream_model: m.id, model_name: m.id }, cost_profile: { billing_unit: 'million_tokens', input_microunits: Math.round(p.in * 1e6), output_microunits: Math.round(p.out * 1e6) }, routing: { default_tee_requirement: e.default_tee_requirement } },\n  });\n}\nreturn [{ json: { provider: { name: e.name, config: { backend: e.backend, base_url: e.base_url }, credential_env: e.credential_env, models_path: e.models_path, execution_security: e.execution_security }, models, count: models.length, skipped } }];"
      },
      "id": "shape",
      "name": "Shape the admin batch",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        660,
        300
      ],
      "notes": "Pure. Every price comes from the catalogue read one node earlier; nothing is typed by hand.",
      "notesInFlow": true
    },
    {
      "parameters": {
        "options": {},
        "method": "PATCH",
        "url": "https://cloud-api.near.ai/v1/admin/models",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ models: $json.models }) }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "id": "patch",
      "name": "PATCH /v1/admin/models — NEAR runs this",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        880,
        300
      ],
      "notes": "Disabled on purpose: this call is NEAR's (admin only). Enable it on NEAR's own n8n with NEAR's admin credential; the body is the batch from the node before.",
      "notesInFlow": true,
      "disabled": true
    },
    {
      "parameters": {
        "jsCode": "const b = $('Shape the admin batch').first().json;\nreturn [{ json: { provider_entry: b.provider, models_offered: b.count, first_three: b.models.slice(0, 3).map((m) => ({ model: m.modelName, in_usd_per_mtok: m.inputCostPerToken.amount / 1000, out_usd_per_mtok: m.outputCostPerToken.amount / 1000 })), skipped_unpriced: b.skipped,\n  then: ['approve the {upstream_model, model_name} pairs you want (PUT /v1/admin/providers/{id}/models)', 'route them tee: any', 'settle each attempt against the invoice reference Taifoon returns (sale id)'], docs: 'https://www.taifoon.io/docs/provider-entry' } }];"
      },
      "id": "summary",
      "name": "What NEAR gets",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1100,
        300
      ],
      "notes": "The summary a reviewer reads.",
      "notesInFlow": true
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Provider entry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Provider entry": {
      "main": [
        [
          {
            "node": "Read the Taifoon catalogue",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read the Taifoon catalogue": {
      "main": [
        [
          {
            "node": "Shape the admin batch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Shape the admin batch": {
      "main": [
        [
          {
            "node": "PATCH /v1/admin/models — NEAR runs this",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PATCH /v1/admin/models — NEAR runs this": {
      "main": [
        [
          {
            "node": "What NEAR gets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveDataSuccessExecution": "all",
    "saveManualExecutions": true
  },
  "meta": {
    "templateCredsSetupCompleted": false,
    "instanceId": "taifoon-coordination"
  }
}
