@aid-framework/ir

中文文档
0.1.98发布于 2026/11/03Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 1.2万

The AID Framework intermediate representation: IR v0.1 shapes, the spec-to-IR builder, six build-time gates, the PolicyExpr parser, and canonical JSON serialization.

原始使用文档
文档目录11 节
  1. Install
  2. Quick start
  3. The IR
  4. An empty collection is a contract
  5. The build-time gates
  6. PolicyExpr
  7. Canonical serialization
  8. Model catalog
  9. Capabilities
  10. API
  11. License

@aid-framework/ir

The intermediate representation of AID Framework: the one normalized, stack-independent, versioned form of an application that every code generator consumes.

Generators never read a spec. This package resolves the spec once into an IR, so a Python target and a TypeScript target are looking at the same program — the same names, the same defaults, the same resolved references.

spec.yaml ──buildIR──▶ IR ──runGates──▶ buildable ──▶ generator plan ──▶ code

Install

npm install @aid-framework/ir

Requires Node.js 24 or newer. Depends only on @aid-framework/spec.

Quick start

import { checkSpecText, formatDiagnostics } from '@aid-framework/spec';
import { buildIR, runGates, serializeIR } from '@aid-framework/ir';

const checked = checkSpecText(source, { file: 'app/app.spec.yaml' });
if (!checked.ok) throw new Error(formatDiagnostics(checked.diagnostics));

const built = buildIR(checked.value, { file: 'app/app.spec.yaml' });
if (built.diagnostics.some((d) => d.severity === 'error')) {
  throw new Error(formatDiagnostics(built.diagnostics));
}

const gates = runGates(built.ir, { file: 'app/app.spec.yaml' });
if (!gates.ok) throw new Error(formatDiagnostics(gates.diagnostics));

const canonical = serializeIR(built.ir);

buildIR resolves every type, model, prompt and tool reference eagerly, materializes every default, and derives each stable identity from identity rather than from content — so editing one prompt does not renumber an unrelated pipeline.

The IR

IR_VERSION is "0.1.0". specVersion is carried through from the spec, so a consumer can always tell which spec revision produced an IR. The two are independent: neither implies the other.

An IR always carries all twenty top-level keys, even when a collection is empty:

irVersion, specVersion, project, types, models, prompts, tools, retrievers, embeddings,
stores, memory, agents, pipelines, evals, guardrails, decisions, deployments,
observability, runtime, requiredCapabilities

An empty collection is a contract

An empty array here is not "missing" — it is a statement. The collections are present and required by the schema even when empty, so a later version can fill one in without touching a single consumer:

  • agents, guardrails, memory, deployments, decisions — declared by the spec language but unused by this document.
  • embeddings — not a spec section at all. A spec declares embedding capacity by giving a model the embeddings capability and pointing a retriever at it, so this collection is derived from that content. Empty means the app embeds nothing.

observability and runtime are objects with defaults rather than arrays: tracing on, and a runtime descriptor naming plain-async control flow.

The build-time gates

Gates decide whether an IR is buildable, before a single byte of code is emitted. There are sixteen, run as one report by runGates. All of them emit diagnostics rather than throwing, in the same compiler-style shape as @aid-framework/spec, so a user gets one report whatever layer rejected the input.

GateRejects
referentialAn unresolvable type or reference, a reference of the wrong kind, prompt variables that do not match the template, an undefined or duplicated step binding, a malformed eval target, a fallback cycle
normalizeA value left implicit for the generator to invent, a provider this build does not serve, params above a model's limits
capabilityA target declaring no capabilities, an unknown target, a capability outside the vocabulary, a required capability the target does not declare
costA budget declared against an unpriced model. Warns for an estimate above a budget, and for an unpriced, unbudgeted model
securityA write or destructive tool with no auth policy, a destructive tool without confirmation, an under-redacting trace config, an HTTP path reaching a write with no auth
eval-coverageNothing — warns when an HTTP-served pipeline has no CI-gating eval
agents/refs-resolveAn agent naming a tool, prompt or model that does not exist
agents/handoff-cyclesTransfer or delegation graphs that can re-enter an agent
agents/budgetsAn agent budget that cannot be honoured
agents/budget-degradeonBudgetExhausted: degrade with no strictly cheaper alias to step down to
guardrails/coverageA guardrail not attached to an input or output it can act on
guardrails/policiesA guardrail policy that does not parse, or names an unknown builtin
hitl/side-effectsA human-in-the-loop pause guarding a side effect it cannot actually hold
memory/refsA memory reference that does not resolve to a declared scope
deploy/streamingA deployment declaring streaming the target cannot emit
orchestration/deepagentsAn agent engine declaration the runtime cannot honour

Suppression is explicit. A check this build genuinely cannot enforce appears in suppressed with a stated reason rather than being skipped silently — because a skipped check and a passing check look identical from the outside.

The capability set the gates check is derived from the IR's own content and written back onto requiredCapabilities, so the value a generator reads is the value that was actually checked:

const result = runGates(ir, {
  targetCapabilities: {
    'py-fastapi': ['http-trigger', 'json-schema', 'otel'],
  },
});

result.ok;         // false when any gate emitted an error
result.byGate;     // per-gate diagnostics
result.suppressed; // what was not enforced, and why

PolicyExpr

Tool auth policies are written in a small expression language. This package parses them into a plain-JSON AST, so the AST can live in the IR, serialize canonically, and be evaluated by any target in any language.

or         := and ('or' and)*
and        := comparison ('and' comparison)*
comparison := unary (('==' | '!=' | '<' | '<=' | '>' | '>=') unary)?
unary      := 'not' unary | primary
primary    := 'true' | 'false' | builtin '(' args ')' | '(' or ')'
builtin    := hasRole | hasScope | isAuthenticated
import { parsePolicyExpr, formatPolicyExpr } from '@aid-framework/ir';

const parsed = parsePolicyExpr("hasRole('admin') or hasScope('tickets:write')");
if (parsed.ok) console.log(formatPolicyExpr(parsed.value));

Parsing is a total function: it returns either an AST or positioned diagnostics, never a thrown exception. Anything outside this grammar is a validation error, including an unknown builtin. That is the fail-closed rule — a policy the runtime cannot evaluate must never be treated as true.

Eval predicates use a companion grammar with the same properties (parsePredicateExpr, PREDICATE_BUILTINS), so a gate condition is as strict as an auth policy.

Canonical serialization

serializeIR is deterministic, so regeneration is byte-reproducible and golden files are stable:

  • object keys sorted, LF endings, two-space indent, exactly one trailing newline;
  • no NaN, Infinity or undefined; an absent field is omitted rather than written as null;
  • array order preserved, because an array's order is meaningful and an object's is not.

Two documents that differ only in key order or whitespace therefore produce byte-identical IR.

Model catalog

The catalog is the build-time source of truth for model pricing and limits, used by the cost and normalize gates.

import {
  CATALOG_VERSION, catalogCostProfile, catalogCostProfiles, catalogModel,
} from '@aid-framework/ir';

The catalog JSON is also exported as @aid-framework/ir/catalog/models.json, and the IR schema as @aid-framework/ir/ir.schema.json.

Capabilities

import {
  DEFERRED_CAPABILITIES, MODEL_CAPABILITIES, REQUIRED_CAPABILITIES,
  deriveRequiredCapabilities, isRequiredCapability,
} from '@aid-framework/ir';

deriveRequiredCapabilities(ir) returns the capabilities the IR's own content requires, in vocabulary order. runGates calls it before gating, so the gates and the generator never disagree about what is required.

API

ExportPurpose
buildIR(value, options?)Spec value → { ir, diagnostics }
runGates(ir, options?)Run all gates; returns { ok, diagnostics, suppressed, byGate }
GATESThe gate registry, in execution order
serializeIR(ir), canonicalJson(value)Canonical JSON rendering
IR_VERSIONThe IR shape version (0.1.0)
IR_COLLECTIONS, IR_ONLY_COLLECTIONSThe collection vocabulary
deriveRequiredCapabilities(ir)The capabilities the content requires
REQUIRED_CAPABILITIES, MODEL_CAPABILITIES, DEFERRED_CAPABILITIESThe capability vocabularies
parsePolicyExpr, formatPolicyExpr, POLICY_BUILTINSThe tool-auth policy language
parsePredicateExpr, formatPredicateExpr, PREDICATE_BUILTINSThe eval predicate language
catalogModel, catalogCostProfile, catalogCostProfiles, CATALOG_VERSIONModel pricing and limits

License

Apache-2.0. Code generated by AID Framework is not subject to this license.

版本与发布记录

@aid-framework/ir 共发布 52 个版本,首次发布于 2026/10/31;过去 12 个月发布了 52 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.98latest2026/11/032 天前
0.1.972026/11/032 天前
0.1.962026/11/033 天前
0.1.952026/11/033 天前
0.1.942026/11/033 天前
0.1.932026/11/033 天前

关于 @aid-framework/ir 的常见问题

@aid-framework/ir 是什么?

The AID Framework intermediate representation: IR v0.1 shapes, the spec-to-IR builder, six build-time gates, the PolicyExpr parser, and canonical JSON serialization.

如何安装 @aid-framework/ir?

在项目目录运行 npm install @aid-framework/ir,或使用 pnpm add / yarn add / bun add。

@aid-framework/ir 支持 TypeScript 吗?

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

@aid-framework/ir 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@aid-framework/ir 需要什么版本的 Node.js?

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

@aid-framework/ir 可以商用吗?

@aid-framework/ir 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@aid-framework/ir 的下载量有多少?

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

@aid-framework/ir 还在维护吗?

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