@ cloudgrid-io/ 运行时间
CloudGrid的运行时间 SDK. 从网格上的任何实体内部零配置访问平台服务——在您代码中没有API密钥. 今天有两个能力: runtime.ai.* 用于平台AI,以及 runtime.call 给应用电话.
此软件包取代 @cloudgrid-io/ai. 大赦国际现在生活在 runtime.ai。旧的软件包名称仍然有效(它再导出这个名称),所以现有的实体继续运行,没有更改代码.
安装
npm install @cloudgrid-io/runtime
先决条件
添加 ai 页:1 requires: 块 cloudgrid.yaml数字 :
name: my-app
services:
api:
type: node
path: /
requires:
- ai
该平台注入 RUNTIME_GATEWAY_URL 在运行时间——SDK唯一的网关env var. SDK在内部解决身份问题——你的代码看不到一个符号,从不看到或处理提供者的密钥.
使用
import { runtime } from '@cloudgrid-io/runtime';
// Chat
const { text } = await runtime.ai.chat({
prompt: 'Summarize this report: ...',
model: 'claude-haiku',
});
// Generate (single prompt)
const out = await runtime.ai.generate({ prompt: 'Write a haiku' });
// Vision
const image = await readFile('./screenshot.png');
const desc = await runtime.ai.vision({ image, prompt: 'What is in this image?' });
// Embeddings — for search and RAG
const vec = await runtime.ai.embeddings({ text: 'hello world' });
// vec.values : number[] (1536 for the default model)
// vec.model, vec.dim, vec.tokens
// Batch embeddings — preserves input order
const vecs = await runtime.ai.embeddings({ text: ['a', 'b', 'c'] });
// Streaming chat
for await (const chunk of runtime.ai.chat({ prompt, stream: true })) {
if (chunk.type === 'text') process.stdout.write(chunk.text);
}
SDK没有身份争议 它从两个地方中的一个读取身份:
- 在 CloudGrid 舱内,平台挂载的身份文件
/var/run/cloudgrid/identity/token - 在开发者机器上,
~/.cloudgrid/credentials加号<cwd>/.cloudgrid/link.json
在两个外头,第一个呼叫投出 IdentityNotFoundError。 。 。 .
平台对你的拥有
每个人工智能服务chat, (中文(简体) ), image, (中文(简体) ), embeddings) 包含每个Grid提供商的决定,由Console的Grid 管理员设定,下方为: 网格设置 – 服务数字 :
- 平台 (默认)——呼叫运行在平台的密钥上;使用被干扰到网格.
- 带上你自己的 ——呼叫运行在Grid自己的密钥上(存储在Grid Vault中被加密);平台仪表的使用,但不为此计费.
你的代码没有改变。 同一行运行于站台代号上或Grid的密钥上,取决于Grid设置中的一个开关. 密钥永远不会离开服务器 .
管理下基底——不要拿私人钥匙
需要嵌入时,请使用 runtime.ai.embeddings. 不安装个人 OpenAI 键或第三方向量服务——平台提供模型并(当Grid选择输入)计费. 默认嵌入模型为1536维,与平台管理的pgvector相匹配.
方法
runtime.ai.chat(req): Promise<AIResponse>
runtime.ai.chat({ ...req, stream: true }): AsyncGenerator<StreamChunk>
runtime.ai.generate(req): Promise<AIResponse>
runtime.ai.vision(req): Promise<AIResponse>
runtime.ai.embeddings({ text: string }): Promise<EmbeddingVector>
runtime.ai.embeddings({ text: string[] }): Promise<EmbeddingVector[]>
runtime.ai.image(req): Promise<ImageResponse>
runtime.call(address, path?, init?): Promise<Response>
interface AIResponse {
text: string;
model: string;
usage: { input_tokens: number; output_tokens: number };
}
interface EmbeddingVector {
values: number[];
model: string;
dim: number;
tokens: number;
}
模型
过 model: 作为门户之一的别名—— claude-haiku (快速), claude-sonnet (违约), claude-opus (最高能力)——并网关解决了服务器侧. 嵌入默认值 text-embedding-3-small。网关执行服务器侧模式白名单.
App-to-app电话
runtime.call 到达网络上的另一个应用程序。 该型号(第051号决定):只有在被调用人已经准许调用人的情况下,一个应用才能被另一个应用调用. 赠款由被呼叫者的网络政策执行,所以没有符号可以携带,也没有注入到您环境中的任何东西——地址在呼叫时解决,请求是平庸的 fetch。 。 。 . RUNTIME_GATEWAY_URL 是唯一使用它的地方,平台将它注入每一个服务; runtime.call 需要没有 requires:编号 :needs: 输入.
宣布关系
来电者列出其称谓;来电者列出谁可以称呼.
# caller's cloudgrid.yaml
calls:
- todo-api # an app in this grid (the common case)
- qa-todo/todo-api # <grid-slug>/<app-slug> (same-grid only in this release)
- 42f6e1c3-... # or the entity id, stable across renames
# callee's cloudgrid.yaml
callers:
scope: explicit
allowed_apps:
- todo-viewer # named callers are granted at the caller's plug
# policy: auto # or: grant every same-grid caller (a deliberate opt-in)
# policy: manual # or: every grant waits for admin approval in Console
默认为否认. 未命名于 allowed_apps (但不包括在 policy: auto)是诞生的 requested 并等待被调用者管理员在Console的批准. 批准或撤销生效——呼叫者不重新插出。 加入一个网格并不自取其利;只有明确的赠款才是如此.
打个电话
import { runtime } from '@cloudgrid-io/runtime';
const res = await runtime.call('todo-api', '/todos');
if (res.ok) {
const todos = await res.json();
}
runtime.call(address, path?, init?) 返回标准 Response数字 :
address- 同样的三种形式calls:接受( app swit,<grid-slug>/<app-slug>,或实体编号).path——附在被调用人内部URL上;省略后打出根.init- 一个标准RequestInit,转至fetch无所未有. SDK没有自己的头,所以Authorization保持免费的应用自己的协议.
这个 Response 返回为- is: HTTP 错误状态是被调用者的答案,而不是 SDK 失败 . runtime.call 仅当无法调用时才丢出 — 参见下面的错误 。 它在部署的应用程序内工作;在开发者机器上工作 GridError CALLER_NOT_CONFIGURED,将应用程序插入 grid plug 并呼叫其他应用程序从那里.
从非 JS 运行时间调用
runtime.call 是一个细的包裹 在一个平台请求外加一个平坦的获取。 Python 或 Go app 直接执行相同的两个步骤.
-
解决地址。 该平台注入
RUNTIME_GATEWAY_URL输入每个服务,并挂载显示符/var/run/cloudgrid/identity/token。 。 。 .GET ${RUNTIME_GATEWAY_URL}/app-connection/resolve?address=todo-api Authorization: Bearer <contents of /var/run/cloudgrid/identity/token>成功与否
200与{ "url": "http://<svc>-app.<namespace>.svc.cluster.local", "entity_id": "<uuid>" }缓存url——SDK再用约5分钟,集群内名分稳定跨再插. 端点需要签名的 pock 符; 遗留X-CloudGrid-*身份头被拒绝。 失败状态 :状态 代码 含义 401 (中文(简体) ) MISSING_IDENTITY编号 :IDENTITY_TOKEN_REQUIRED没有无记名符号,也没有使用遗留头路径. 401 (中文(简体) ) IDENTITY_EXPIRED鼠标旋转; 等待 ( Retry-After: 60)并重试.403 (韩语) CALL_NOT_GRANTED这个应用没有被批准,或者还有待批准. fix命名下一步.404 (韩语) CALLER_TARGET_NOT_FOUND编号 :CALLEE_NOT_ROUTABLE目标在此网格中不存在,或者没有可调用的服务. 400个 CALLER_INVALID_ADDRESS编号 :CROSS_GRID_NOT_SUPPORTED地址不正确,或交叉网格目标(不支持此发布). -
使用纯请求调用已解决的 URL — 没有来自平台的认证头 。 被调用者的网络政策已经决定您可以连接 .
GET <url>/todos
错误
import {
GridError,
GridAIError,
IdentityNotFoundError,
MalformedIdentityError,
} from '@cloudgrid-io/runtime';
GridError 是运行时表面的基础网格错误;它携带 code (弦声), status (HTTP 状态),以及可选 fix (下一步可采取行动). GridAIError 被丢弃的子类 runtime.ai.* 打电话. CloudGridAIError 仍作为已贬值的别名导出 GridAIError,因此已经存在 instanceof CloudGridAIError 渔获继续工作. IdentityNotFoundError 既无网状又无网状身份时被扔出; MalformedIdentityError 当身份文件或 link.json 已存在但无法解析.
runtime.call 掷出 GridError 在无法拨打时使用两个代码中的一个: CALLER_NOT_CONFIGURED 当地址无法解决时(该应用程序没有被授予,目标不存在,或地址不正确),以及 CALLEE_UNREACHABLE 当地址解决了但连接失败时(被调用者已下架,或者其管理员从调用者中移除了此应用程序). 非-2xx HTTP 状态不是一个错误 – 它在 Response。 。 。 .
兼容性
@cloudgrid-io/[email protected] 将AI SDK重回原地 runtime.ai。顶级 createClient()遗产 ai 单子,和 createLegacyClient() 仍然导出用于反相匹配。 堕落者 @cloudgrid-io/ai 包再出口这里的所有东西,所以现有的进口继续工作.
再来
- AI 网关文件 ——网关合同:模式,预算,模式别名.
- App 连接合同 - 满分
runtime.call参考:模型,解析端点,出错代码. - 第014号决定——运行时SDK身份模型 ——为什么身份被平台解析,而不是呼叫者提供.
- 第051号决定——应用连接 ——申报来电,网络强制.
- 国 际 —— 说
@cloudgrid-io/cli。 。 。 .