DEV Community

Jia
Jia

Posted on

Warm a Vector Engine Model Catalog in Node.js Before Dify and Cursor Deployments

Many model_not_found incidents start with a small assumption: the model name that worked in a local Node.js test will also be accepted by Dify, Cursor, and every background worker after a deployment.

That assumption is fragile. When a team uses Vector Engine as an OpenAI-compatible API gateway, the model catalog becomes a contract. A deployment should confirm that the configured model names still exist before users reach the broken path.

This tutorial builds a Node.js model catalog warmer. It calls the Vector Engine Base URL, reads the model list, compares it with the model names expected by Dify, Cursor, and the service, then fails early with a useful message if a route is missing.

Registration URL: https://api.vectorengine.cn/register?aff=Igym

Configuration to keep in one file

Create vector-engine-models.json:

{
  "provider": "Vector Engine",
  "baseUrl": "https://api.vectorengine.cn/v1",
  "tools": {
    "dify": ["gpt-4o-mini"],
    "cursor": ["gpt-4o-mini"],
    "nodejs": ["gpt-4o-mini"]
  }
}
Enter fullscreen mode Exit fullscreen mode

The important part is not the sample model. The important part is that Dify, Cursor, and Node.js declare the model name they expect from the same LLM API provider layer.

Keep the API Key outside this file:

export VECTOR_ENGINE_API_KEY="replace-with-your-key"
Enter fullscreen mode Exit fullscreen mode

Build the warmer

Create warm-vector-engine-catalog.mjs:

import fs from "node:fs/promises";

const config = JSON.parse(
  await fs.readFile(new URL("./vector-engine-models.json", import.meta.url), "utf8")
);

const apiKey = process.env.VECTOR_ENGINE_API_KEY;

if (!apiKey) {
  throw new Error("Missing VECTOR_ENGINE_API_KEY");
}

async function fetchModels() {
  const response = await fetch(`${config.baseUrl}/models`, {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
  });

  if (!response.ok) {
    throw new Error(`Model catalog request failed: ${response.status} ${response.statusText}`);
  }

  const payload = await response.json();
  return new Set((payload.data || []).map((model) => model.id));
}

function expectedModelsByTool() {
  return Object.entries(config.tools).flatMap(([tool, models]) =>
    models.map((model) => ({ tool, model }))
  );
}

const available = await fetchModels();
const missing = expectedModelsByTool().filter(({ model }) => !available.has(model));

if (missing.length > 0) {
  console.error("Vector Engine model catalog check failed.");
  for (const item of missing) {
    console.error(`- ${item.tool}: ${item.model} -> model_not_found risk`);
  }
  process.exit(1);
}

console.log("Vector Engine model catalog check passed.");
console.log(`Base URL: ${config.baseUrl}`);
console.log(`Checked tools: ${Object.keys(config.tools).join(", ")}`);
Enter fullscreen mode Exit fullscreen mode

Run it during deployment:

node warm-vector-engine-catalog.mjs
Enter fullscreen mode Exit fullscreen mode

If the model exists, the script exits cleanly. If it does not, the deployment can stop before Dify, Cursor, or a Node.js service starts returning model_not_found to users.

Add it to a CI job

Here is a minimal CI-style command:

VECTOR_ENGINE_API_KEY="$VECTOR_ENGINE_API_KEY" \
node warm-vector-engine-catalog.mjs
Enter fullscreen mode Exit fullscreen mode

Store the API Key in the CI secret manager. Do not commit it, and do not paste it into a ticket. The script only needs runtime access to verify the provider contract.

Troubleshooting guide

Failure Meaning Fix
Missing VECTOR_ENGINE_API_KEY The job cannot authenticate Add the secret to the runtime environment
Catalog request returns 401 The API Key is wrong or out of scope Check key ownership in Vector Engine
Missing model for Dify Dify expects a route that is not available Update the model name or route mapping
Missing model for Cursor Cursor config drifted from the shared file Align Cursor with the shared model list
Missing model for Node.js Service config references an old model Update the service environment variable

The goal is simple: move model validation from user traffic to deployment time. Vector Engine can still act as the OpenAI-compatible API gateway, but each tool gets a clearer contract before it sends traffic.


在 Dify 和 Cursor 部署前用 Node.js 预热向量引擎模型目录

很多 model_not_found 事故都来自一个很小的假设:本地 Node.js 测试里可用的 model name,在部署后也一定会被 Dify、Cursor 和所有后台任务接受。

这个假设并不稳。团队把向量引擎作为 OpenAI-compatible API gateway 使用时,模型目录就变成了一份契约。部署流程应该在用户进入故障路径之前,确认配置里的模型名仍然存在。

这篇教程会构建一个 Node.js 模型目录预热脚本。它会调用向量引擎的 Base URL,读取模型列表,把结果和 Dify、Cursor、服务端期望的 model name 做比较。如果某条路由缺失,就提前失败并给出清楚信息。这里的向量引擎也可以理解为向量引擎API中转站。

把配置收敛到一个文件

创建 vector-engine-models.json

{
  "provider": "Vector Engine",
  "baseUrl": "https://api.vectorengine.cn/v1",
  "tools": {
    "dify": ["gpt-4o-mini"],
    "cursor": ["gpt-4o-mini"],
    "nodejs": ["gpt-4o-mini"]
  }
}
Enter fullscreen mode Exit fullscreen mode

重点不是示例模型名本身,而是 Dify、Cursor 和 Node.js 都声明自己期望从同一个 LLM API provider layer 获得哪个模型。

API Key 要放在文件外:

export VECTOR_ENGINE_API_KEY="replace-with-your-key"
Enter fullscreen mode Exit fullscreen mode

编写预热脚本

创建 warm-vector-engine-catalog.mjs

import fs from "node:fs/promises";

const config = JSON.parse(
  await fs.readFile(new URL("./vector-engine-models.json", import.meta.url), "utf8")
);

const apiKey = process.env.VECTOR_ENGINE_API_KEY;

if (!apiKey) {
  throw new Error("Missing VECTOR_ENGINE_API_KEY");
}

async function fetchModels() {
  const response = await fetch(`${config.baseUrl}/models`, {
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
  });

  if (!response.ok) {
    throw new Error(`Model catalog request failed: ${response.status} ${response.statusText}`);
  }

  const payload = await response.json();
  return new Set((payload.data || []).map((model) => model.id));
}

function expectedModelsByTool() {
  return Object.entries(config.tools).flatMap(([tool, models]) =>
    models.map((model) => ({ tool, model }))
  );
}

const available = await fetchModels();
const missing = expectedModelsByTool().filter(({ model }) => !available.has(model));

if (missing.length > 0) {
  console.error("Vector Engine model catalog check failed.");
  for (const item of missing) {
    console.error(`- ${item.tool}: ${item.model} -> model_not_found risk`);
  }
  process.exit(1);
}

console.log("Vector Engine model catalog check passed.");
console.log(`Base URL: ${config.baseUrl}`);
console.log(`Checked tools: ${Object.keys(config.tools).join(", ")}`);
Enter fullscreen mode Exit fullscreen mode

在部署期间运行:

node warm-vector-engine-catalog.mjs
Enter fullscreen mode Exit fullscreen mode

如果模型存在,脚本正常退出。如果模型不存在,部署可以在 Dify、Cursor 或 Node.js 服务向用户返回 model_not_found 之前停止。

加入 CI 任务

一个简化的 CI 命令可以这样写:

VECTOR_ENGINE_API_KEY="$VECTOR_ENGINE_API_KEY" \
node warm-vector-engine-catalog.mjs
Enter fullscreen mode Exit fullscreen mode

API Key 应该保存在 CI 的 secret manager 中,不要提交到仓库,也不要粘贴进工单。脚本只需要在运行时访问它,用来验证 provider contract。

排查指南

失败信息 含义 修复方式
Missing VECTOR_ENGINE_API_KEY 任务无法鉴权 把 secret 加到运行环境
Catalog request returns 401 API Key 错误或权限范围不匹配 在向量引擎控制台检查 key ownership
Dify 缺模型 Dify 期望的路由不可用 更新模型名或路由映射
Cursor 缺模型 Cursor 配置和共享文件发生漂移 让 Cursor 对齐共享模型列表
Node.js 缺模型 服务配置引用了旧模型 更新服务环境变量

目标很直接:把模型校验从用户流量阶段前移到部署阶段。向量引擎中转站仍然可以作为 OpenAI-compatible API gateway 工作,但每个工具在发送真实流量之前都有更清楚的契约。这也是让 API中转站 更容易被工程团队治理的一种方式。

注册地址:https://api.vectorengine.cn/register?aff=Igym

Top comments (0)