@diagrid/agent-core

中文文档
0.2.0发布于 2026/09/18BUSL-1.1TypeScriptESM + CJS构建来源已验证近 30 天下载 5626

Diagrid AI 代理框架适配器共享 Dapr 工作流程运行时间

中文使用文档
文档目录6 节
  1. 住在这里的东西
  2. 为什么代理循环是在这里而不是在适配器
  3. 写入适配器
  4. 遥测
  5. 身份
  6. 许可证

@ diagrid/ 代理核心

在Diagrid AI代理适配器后共享的 Dapr 工作流运行时间.

应用程序代码通常安装适配器(例如. @diagrid/agent-mastra)而不是这个包 直接说 即时直接安装 写入适配器 - 这是 软件包,您执行的两个基础类.

住在这里的东西

模块导出作用
agent/agentWorkflow, (中文(简体) ), invokeModelActivity,, , , , , , , , 耐用剂循环 ——管弦乐手,活动与活动再试,框架-不可知
agent/agentWorkflowInputSchema,, , , , , , , , 任何跨越工作流程界限的 Zod 计划
workflow/BaseWorkflowRunner运行时间生命周期、犬类工作流程命名、状态/终止/清洗、优雅关闭
workflow/buildWorkflowName, (中文(简体) ), sanitizeAgentName跨语言命名合同(dapr.<framework>.<AgentName>.workflow(中文(简体) )
mapping/BaseAgentMapper, (中文(简体) ), AgentMapper框架延长点 将本地代理映射到注册元数据
metadata/agentMetadataRecordSchema,, , , , , , , , 代理登记记录的Zod计划
state/DaprStateStoreJSON 串行化包装器, 覆盖一个 Dapr 状态仓库组件
state/DaprAgentCheckpointer对话-记忆检查站;与 python-ai,每个适配器前缀
pubsub/DaprPubSub代理生命周期事件出版商
telemetry/setupTelemetry, (中文(简体) ), getTracerOTLP/gRPC追踪——a 无 -op 除非 OTEL_EXPORTER_OTLP_ENDPOINT (或配置)已经设定
identity/oauthMiddleware, (中文(简体) ), oauthPlugin,, , , , , , , , 已核实的来电者 ——JWKS支持的JWT验证,快取和快取适配器
workflow/daprDapr 工作流程类型只有类型再导出,所以适配器从不依赖 @dapr/dapr 本身

为什么代理循环是在这里而不是在适配器

它开始于马斯特拉适配器,一次回顾使后果变得显而易见: 它提到一个框架。 一个消息,一个工具呼叫,一个模型转动,重试 政策和检查站密钥布局是相同的形状,以SDK生产为准 因此适配器 #2 会复制整个持久循环,包括 容易误入歧途的变体(管弦乐手必须是 async function*; 计程车必须坐 外部 复试区域 钟必须来自 getCurrentUtcDateTime()) (中文(简体) ). 两份漂流,和 流出无声.

真正的每个框架都很小:一步一步地推动SDK 工具执行停留在检查的活动内,并读取本地代理 其元数据的结构.

写入适配器

执行两件事:

import {
  BaseAgentMapper,
  BaseWorkflowRunner,
  SupportedFrameworks,
  type AgentMapper,
  type AgentMetadataRecord,
  type SupportedFramework,
  type WorkflowRuntime,
} from '@diagrid/agent-core';

class MyFrameworkMapper extends BaseAgentMapper {
  readonly framework: SupportedFramework = SupportedFrameworks.MY_FRAMEWORK;

  // Async by contract: frameworks commonly hide an agent's config behind async
  // accessors (Mastra's `Agent.listTools()` returns a Promise), and a sync
  // mapper would silently report empty tools for every real agent.
  async mapAgentMetadata(agent: unknown): Promise<AgentMetadataRecord> {
    // Read the framework-native agent, then hand the partial record to
    // `this.finalize(...)`, which fills defaults, derives the workflow name
    // and validates the result.
    return this.finalize({/* … */});
  }
}

class MyFrameworkRunner extends BaseWorkflowRunner {
  readonly #mapper = new MyFrameworkMapper();

  get mapper(): AgentMapper {
    return this.#mapper;
  }

  protected registerWorkflowComponents(runtime: WorkflowRuntime): void {
    runtime.registerWorkflowWithName(this.workflowName, myAgentWorkflow);
    runtime.registerActivityWithName('…', myActivity);
  }
}

CI警卫执行的两条规则:

  • 导入框架 SDK 作为对等方, 从不依赖 . 读取本地代理 结构上,框架不会出现在运行时间图中。 读取配置 通过框架 访问者 (单位:千美元)getInstructions(), (中文(简体) ), listTools()(没有) 它的平地属性——一个真正的实例通常使这些特性保持私人性质,而且 仅限属性的映射器通过每个基于固定的测试而无任何报告 对于真正的特工.
  • 从这里导入 Dapr 类型, 不从 @dapr/dapr。 。 。 . 一个包拥有 SDK 版本; 见 src/workflow/dapr.ts 为什么.

然后添加一个 ADAPTERS 输入 tests/guards/cross-framework-imports.test.ts - 它失败,直到你这样做.

遥测

setupTelemetry() 返回时 undefined 当没有配置 OTLP 端点时,以及 这是成功,而不是出错——这是正常的局部路径. getTracer() 总是可以安全拨打: 没有供应商注册 OTel API 手拿回 a 没有追踪器,所以仪器 从来不需要分辨是否在追踪.

最终点的解析优先性是明确的配置-然后 OTEL_EXPORTER_OTLP_ENDPOINT,与 enabled: false 电路短路. 信号路径后缀( S)/v1/traces由于GRPC出口商想要 一个赤 host:port。 。 。 .

身份

经核实的来电人和半个出门电话 diagrid.identity 在Python SDK(英语:Python SDK)中. 一行的应用程序代码可以买入 一半;外出的一半没有花费.

import express from 'express';
import { getVerifiedUser, oauthMiddleware } from '@diagrid/agent-core/express';

const app = express();
app.use(oauthMiddleware({ scopes: ['agent.invoke'] }));

app.post('/invoke', (req, res) => {
  res.json({ caller: getVerifiedUser(req)?.subject });
});

以相同的选项快捷:

import Fastify from 'fastify';
import { getVerifiedUser, oauthPlugin } from '@diagrid/agent-core/fastify';

const app = Fastify();
await app.register(oauthPlugin, { scopes: ['agent.invoke'] });

app.post('/invoke', (request) => ({
  caller: getVerifiedUser(request)?.subject,
}));

快取和快取是可选的对等点,每个适配器都是自己的 子路径入口 : @diagrid/agent-core/express 财务报告和审定财务报表 @diagrid/agent-core/fastify安装您所服务的任何一种; 安装两个都不行,而且包筒也解决不了问题 运行时间,而不是在类型检查时,再出口的枪管会在那里 手执 TS2307 输入到任何类型中 skipLibCheck。 。 。 . tests/guards/cross-framework-imports.test.ts 保持这条线.

经核实的呼叫器读取 getVerifiedUser(req) 而不是从 req.user。 。 。 . user 是应用程序的插槽——护照的,典型的——和a 库中声称将在运行时覆盖应用程序自己的用户 与 @types/passport'在编译时声明它. 活猫 SDK同样区分 request.state.diagrid_user。 。 。 .

出门的半个电话除了 fetch 你造过一次. createIdentityFetch() 手背一个普通的 fetch- 形状的功能,所以 app会发出一个普通的呼叫, 并且从不组装身份标题本身 :

import { createIdentityFetch } from '@diagrid/agent-core';

// Once, at module scope. The token is read per call, not captured here.
const identityFetch = createIdentityFetch();

export async function search(query: string): Promise<Response> {
  return identityFetch('https://mcp.example.com/tools/search', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query }),
  });
}

一个功能而不是客户类 因为这就是MCP SDK, 生成了 API 客户端, 大多数 HTTP 库接受: pass identityFetch 无论什么习俗 fetch 它的下方的电话载着 来电.

有三个属性是值得知道的, 因为它们是原因不 用手组装标题:

  • 信使在呼叫时宣读. 一个长寿,共享 identityFetch 实值 安全:每个同时提出的申请都携带自己的呼号。 标题 当函数构建时, 将会发送任何用户 电流.
  • 取出头前取出. 请求从不包含 特性当前上下文不存在,无论设置是什么。 户外a 经核实的请求——预定的、酒吧/分公司或克龙触发器——标题是 完全省略而不是发送为空,呼叫开始 而不是抛出.
  • 信物只写在您给的来源上. 重定向到另一个 原产地放弃;没有此选项, a Location 被传唤者选择的 将呼叫器的代号交给任何主机 一个例外是 同宿主升级自 http 端口为 80 到 https 在港口443。 执行 意思是链子是走在这里而不是走在里面 fetch,所以随行 Response 报告 redirected === false。 。 。 .

自己传 fetch 作为 createIdentityFetch({ fetch }) {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}给你打包 已经存在——追踪,回想,测试双层——上面有分层的身份. 对于一个你完全无法替代的客户来说, attachIdentityHeaders(request) 这是 与单请求截取器相同的行为 原地警卫不能从那里掩护.

范围检查 hasScope(user, scope) - 自由活动兄弟会 has_scope 在 Python SDK 中和 HasScope 在爪哇语和.NET中。 这是一个 函数而不是方法,因为 VerifiedUser 是普通的形状,所以 继续研究从工作流程有效载荷、缓存或固定装置中恢复的一个:

import express from 'express';
import { hasScope } from '@diagrid/agent-core';
import { getVerifiedUser } from '@diagrid/agent-core/express';

const app = express();

app.post('/admin', (req, res) => {
  const user = getVerifiedUser(req);
  if (!user || !hasScope(user, 'agent.admin')) {
    res.status(403).json({ error: 'oauth.missing_scope' });
    return;
  }
  res.json({ ok: true });
});

发现核查坐标,以便: issuer + 键 jwksUri - 本地侧车 /v1.0/metadata (单位:千美元)DAPR_HTTP_PORT- 遥控器 侧车 /v1.0/metadata (单位:千美元)DAPR_HTTP_ENDPOINT,这就是如何 diagrid dev run 到达催化装置的侧车,无任何回路) • DIAGRID_DP_SENTRY_ISSUER。本地到远程之前,所以部署在集群中 应用程序继续从回回回调中响应. 单一的清晰字段缩小 不管是哪一个源答案,而不是替换它,所以只给一个 audience 仍然让我们找到发行商 issuer 由于JWKS URI 本身就足够了 issuer + 键 /jwks.jsonA级 jwks_uri 侧车广告被采用 以获得 价值,但只有当发行人 广告是 发行人实际上 解决了:绝不能用外国发行人的钥匙来核实被钉住的发行人 设置。 何时 DAPR_API_TOKEN 设置为 遥控探测器载着它 dapr-api-token过一个非..https 终点是 仍然派遣,并警告说,它行走在晴朗的地方.

整个过程中没有关闭——401个是来电者的坏消息或丢失的信号,403个是 缺少范围, 当关键材料或配置是服务器的问题时为 503 . 每个拒绝都回答 {"error":"<code>"} 下级 Cache-Control: no-store, (中文(简体) ), 和Diagrid SDK的代码完全一样 他们的十人,在 顺序 OAuthErrorCodes 声明:

状态代码何时
401 (中文(简体) )oauth.missing_token没有 X-Diagrid-User-Token 请求必须满足.
第503条oauth.not_configured无法建立校验器:没有提供源代码,或者JWKS URI无法使用.
第503条oauth.verifier_unavailable无法获取密钥集, 或没有匹配符号的密钥 .
401 (中文(简体) )oauth.expiredexp 已经过去,超过120年代的时钟.
401 (中文(简体) )oauth.invalid_issueriss 不匹配已解决的发行者.
401 (中文(简体) )oauth.invalid_audienceaud 不匹配决心的受众.
401 (中文(简体) )oauth.invalid_signature签名不对照 JWKS 密钥进行校验 .
401 (中文(简体) )oauth.decode_error代号完全不是很好的JWS.
401 (中文(简体) )oauth.invalid_token任何其他索赔或算法失败——缺失 exp编号 :iss编号 :sub,一个 alg 在许可名单之外.
403 (韩语)oauth.missing_scope证物已经核实,但并非每个范围 scopes 问取来.

VerifiedUser.scopes 已按正常排序,没有重复,以 联 合 国 scp 编号 : scope 编号 : scopes 使用的指使牌及其排列顺序 他们。 范围是一组:一个符号碰巧列出它们的顺序不是 和每个Diagrid SDK报告相同同义词的顺序 因为回声 user.scopes 进入JSON的身体是最常见的事情 一个处理者会处理他们.

requireAuth 处理无案,别的事 默认时左转 联 合 国 true,请求没有 X-Diagrid-User-Token 被拒绝 401 oauth.missing_token; 设置为 false,该请求通过时没有 已核实的呼叫器附后。 一个标志 实值 总是被验证 总是被拒之门外.

但是,JWKS URI已经解决了,它必须是 https。拒绝使用 第503条 oauth.not_configured,因为密钥集是整个信任根:a 重写路径攻击者 http 反应取代了自己的键并 之后的每次签名检查都证实了他的签名. 循环主机是 免责——这是本地侧车发布其密钥的地方,主机是 解析而非图案匹配,所以DNS名称类似 127.evil.example 实值 没有. allowInsecureJwks: true 选择离开任何地方, 它放松平坦 http 仅限: 选入纯文本对读取签名密钥没有任何影响 从一个文件系统,所以 file:// URI在国旗设定时拒绝。 一个JWKS 无法解析的URI被同样拒绝 在建设时间 而不是在每一个请求中,这是一个配置错误,而不是降级.

许可证

业务来源许可证1.1 2026年 — Present Diagrid Inc.

版本与发布记录

@diagrid/agent-core 共发布 3 个版本,首次发布于 2026/08/23;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.2.0latest2026/09/181 个月前
0.1.12026/09/181 个月前
0.1.02026/08/232 个月前

关于 @diagrid/agent-core 的常见问题

@diagrid/agent-core 是什么?

Diagrid AI 代理框架适配器共享 Dapr 工作流程运行时间

如何安装 @diagrid/agent-core?

在项目目录运行 npm install @diagrid/agent-core,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:zod(^4.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@diagrid/agent-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@diagrid/agent-core 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@diagrid/agent-core 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.13.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@diagrid/agent-core 可以商用吗?

@diagrid/agent-core 使用 BUSL-1.1 许可。声明的许可为 BUSL-1.1,请阅读许可原文确认使用条件。以上为概括,不构成法律意见,请以许可原文为准。

@diagrid/agent-core 的下载量有多少?

根据 npm 官方下载统计,@diagrid/agent-core 在 2026/10/12 – 2026/11/10 这 30 天内被下载 5,626 次,日均约 188 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@diagrid/agent-core 还在维护吗?

最新版本 0.2.0 发布于 2026/09/18(1 个月前);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/08/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。