@armoriq/sdk-dev

中文文档
0.8.23发布于 2026/10/21MITTypeScriptCommonJS近 30 天下载 3253

ArmorIQ SDK - Build secure AI agents with cryptographic intent verification.

原始使用文档
文档目录27 节
  1. Why ArmorIQ?
  2. Installation
  3. Quick Start
  4. 1. Get Your API Key
  5. 2. Initialize the Client
  6. 3. Capture Your Plan
  7. 4. Get Intent Token
  8. 5. Invoke Actions
  9. Environment Variables
  10. Native OpenTelemetry observability
  11. 1. ArmorIQ OTLP
  12. 2. Generic external OTLP endpoint
  13. 3. Caller-owned tracer provider
  14. Langfuse example
  15. What is exported externally
  16. Capture modes and per-session opt-out
  17. Transcript token usage
  18. 0.7.0 breaking changes
  19. Advanced Usage
  20. Delegation
  21. Custom Proxy Endpoints
  22. Error Handling
  23. API Reference
  24. ArmorIQClient
  25. Documentation
  26. Links
  27. License

ArmorIQ SDK (TypeScript)

Build secure AI agents with cryptographic intent verification.

The ArmorIQ SDK enables developers to build AI agents with built-in security and auditability. Just one API key - no cloud complexity.


Why ArmorIQ?

  • Simple - Just one API key, no cloud credentials
  • Secure - Cryptographic verification for every action
  • Auditable - Complete execution trail
  • Fast - Get started in 5 minutes

Installation

npm install @armoriq/sdk
# or
yarn add @armoriq/sdk

Quick Start

1. Get Your API Key

Visit platform.armoriq.ai to generate your API key.

2. Initialize the Client

import { ArmorIQClient } from '@armoriq/sdk';

const client = new ArmorIQClient({
  apiKey: 'ak_your_key_here',
  userId: 'your-user-id',
  agentId: 'your-agent-id',
});

3. Capture Your Plan

const plan = {
  goal: 'Get weather forecast',
  steps: [
    {
      action: 'get_weather',
      tool: 'weather_api',
      mcp: 'weather-mcp',
      inputs: { city: 'Boston' },
    },
  ],
};

const planCapture = client.capturePlan('gpt-4', "What's the weather in Boston?", plan);

4. Get Intent Token

const token = await client.getIntentToken(planCapture);

5. Invoke Actions

const result = await client.invoke('weather-mcp', 'get_weather', token, {
  city: 'Boston',
});

console.log(result);

Environment Variables

# Required
ARMORIQ_API_KEY=ak_your_key_here
USER_ID=your-user-id
AGENT_ID=your-agent-id

# Optional
ARMORIQ_ENV=production  # or 'local' for local development
CONTEXT_ID=default
ARMORIQ_BACKEND_URL=https://api.armoriq.ai  # read before BACKEND_ENDPOINT, by the CLI and the client
PROXY_ENDPOINT=https://proxy.armoriq.ai
IAP_ENDPOINT=https://iap.armoriq.ai

Unset, PROXY_ENDPOINT and IAP_ENDPOINT follow the backend: a production, staging or local backend gets that environment's proxy and IAP. Any other backend needs both set, or the first call that uses one fails naming the missing variable.


Native OpenTelemetry observability

Version 0.7.0 has one native OpenTelemetry span tree per session. It supports exactly three exporter choices. Organization policy still governs every choice; when observability is off or policy authority is unavailable, the SDK does not export telemetry and agent execution continues.

1. ArmorIQ OTLP

ArmorIQ OTLP is the default. No endpoint configuration is needed.

const session = client.startSession({ mode: 'sdk' });

2. Generic external OTLP endpoint

Use a standards-compatible HTTP/protobuf endpoint through options or standard OpenTelemetry environment variables.

const client = new ArmorIQClient({
  apiKey: 'ak_your_key_here',
  observability: {
    exporter: 'external',
    endpoint: 'https://collector.example.com/v1/traces',
    headers: { Authorization: 'Bearer token' },
  },
});
OTEL_SERVICE_NAME=my-agent
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://observability.example.com/v1/traces
OTEL_EXPORTER_OTLP_TRACES_HEADERS=Authorization=Bearer%20token,x-tenant-id=my-tenant

You can instead supply a base endpoint. The SDK appends /v1/traces only for this base form:

OTEL_EXPORTER_OTLP_ENDPOINT=https://collector.example.com
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer%20token

Trace-specific settings take precedence over general settings:

OTEL_EXPORTER_OTLP_TRACES_ENDPOINT > OTEL_EXPORTER_OTLP_ENDPOINT
OTEL_EXPORTER_OTLP_TRACES_HEADERS  > OTEL_EXPORTER_OTLP_HEADERS
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL > OTEL_EXPORTER_OTLP_PROTOCOL
OTEL_EXPORTER_OTLP_TRACES_TIMEOUT  > OTEL_EXPORTER_OTLP_TIMEOUT

3. Caller-owned tracer provider

Pass your own OpenTelemetry tracer provider when your application owns provider lifecycle and exporter setup.

import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';

const provider = new NodeTracerProvider();
const session = client.startSession({
  observability: { exporter: 'provider', tracerProvider: provider },
});

Only http/protobuf is supported for the SDK-managed external exporter. gRPC, OTLP/JSON, compression, HTTP proxy configuration, and mTLS configuration are not supported by that exporter. Set those features on an OpenTelemetry Collector when they are required. The exporter is fail-open: a remote outage, bad response, or timeout never changes the result of an agent request. content-type headers are ignored because the SDK always sends application/x-protobuf.

Before the first external trace, the SDK waits up to 1.4 seconds for the organization policy authority. This one-time bound prevents unauthorized data from reaching a third party. If authority is not available within the bound, external telemetry stays disabled for that session and the agent continues.

One SDK runtime has one exporter choice. For fan-out to ArmorIQ and external tools, use an OpenTelemetry Collector to route permitted traces.

Langfuse example

Langfuse is one OTLP-compatible destination. Configure its OTLP endpoint and standard headers in the environment; do not add Langfuse-specific runtime code to your agent:

OTEL_SERVICE_NAME=my-agent
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://cloud.langfuse.com/api/public/otel/v1/traces
OTEL_EXPORTER_OTLP_TRACES_HEADERS=Authorization=Basic%20BASE64_PUBLIC_KEY_COLON_SECRET_KEY,x-langfuse-ingestion-version=4

For another vendor, use that vendor's documented OTLP trace endpoint and headers. The SDK does not infer vendor URLs, credentials, or private fields.

What is exported externally

External OTLP export always includes the trace hierarchy, stable span names, service identity, supported GenAI model and token-use attributes, and safe resource attributes. API keys, policy payloads, private ArmorIQ IDs, and arbitrary user metadata are never exported to an external destination.

Prompt content, outputs, and tool arguments/results are withheld by default. They are exported to an external destination only when the organization's policy lease grants both content capture and external content capture, and the effective capture mode is enhanced or debug — every other combination (including a policy fetch that is not currently authoritative) withholds them. Do not rely on external export being content-free by default if your organization runs with those grants and capture modes enabled; check your organization's observability policy if that guarantee matters to you.

Supported safe resource attributes are:

OTEL_SERVICE_NAME=my-agent
OTEL_RESOURCE_ATTRIBUTES=service.namespace=education,deployment.environment.name=staging

Do not put secrets or user content in resource attributes. Unsupported resource attributes, malformed attributes, and values that look like a phone number, SSN, or payment-card number are ignored before export.

Capture modes and per-session opt-out

The capture modes are exactly off, metadata, enhanced, and debug. Select an upper bound with ARMORIQ_OTEL_CAPTURE_MODE or observability.captureMode; the organization policy can only narrow it.

Streamed chat requests include stream_options: { include_usage: true } by default (otel.streamUsage, ARMORIQ_OTEL_STREAM_USAGE, default on) so token usage arrives on a usage-only chunk that is hidden from the caller. Set ARMORIQ_OTEL_STREAM_USAGE=0 (or observability.streamUsage: false) when a gateway rejects stream_options or the raw stream must stay untouched. An explicit stream_options on the request is never changed.

const noTelemetrySession = client.startSession({
  observability: { enabled: false },
});

Transcript token usage

Token usage is stored per session, model, UTC date and UTC hour. Each message counts in the hour of its own timestamp. Pass the session's native OTel bridge when you record transcript usage so model tokens become gen_ai.chat spans on the same trace.

await client.captureTranscriptTokens({
  transcriptPath: '/tmp/transcript.jsonl',
  product: 'armorclaude',
  sessionId: session.sessionId,
  otel: session.otelSession,
});

To post a Claude Code session yourself, including its subagent transcripts, summarize it by hour and send one recordTokenUsage call per hour. usageDate (YYYY-MM-DD) and usageHour (0-23) are required; a call without a valid pair returns { ok: false, reason } and posts nothing.

import { summarizeSessionUsageByHour } from '@armoriq/sdk';

const seen = new Set<string>();
const { hours, repo } = summarizeSessionUsageByHour(mainTranscriptPath, { seen });
for (const { usageDate, usageHour, entries } of hours) {
  await client.recordTokenUsage({
    product: 'armorclaude',
    sessionId,
    usageDate,
    usageHour,
    entries,
    repo,
  });
}

Each post replaces the row for that session, model, date, hour and device. Share one seen set across sessions so history copied into a forked session counts once.

0.7.0 breaking changes

The prior pipeline selector, JSON recorder and shipper APIs, recorder handles, schema and trace-summary exports, and defaultObservabilityConfig are removed. Use session.otelSession for native spans. See the 0.7.0 breaking-change notes in CHANGELOG.md for the complete removed public surface.


Advanced Usage

Delegation

import * as crypto from 'crypto';

// Generate delegate keypair
const { publicKey, privateKey } = crypto.generateKeyPairSync('ed25519');
const pubKeyHex = publicKey.export({ type: 'spki', format: 'der' }).toString('hex');

const delegation = await client.delegate(token, pubKeyHex, 1800);
console.log(`Delegated token: ${delegation.delegatedToken.tokenId}`);

Custom Proxy Endpoints

const client = new ArmorIQClient({
  apiKey: 'ak_your_key_here',
  userId: 'user-123',
  agentId: 'agent-456',
  proxyEndpoints: {
    'weather-mcp': 'https://weather-proxy.example.com',
    'finance-mcp': 'https://finance-proxy.example.com',
  },
});

Error Handling

import {
  InvalidTokenException,
  MCPInvocationException,
  PolicyBlockedException,
  TokenExpiredException,
} from '@armoriq/sdk';

try {
  const result = await client.invoke('weather-mcp', 'get_weather', token, { city: 'Boston' });
} catch (error) {
  if (error instanceof TokenExpiredException) {
    console.error('Token expired, please get a new one');
  } else if (error instanceof PolicyBlockedException) {
    // The backend refuses a step outside the anchored plan, or one a policy blocks.
    console.error('Blocked:', error.reason);
  } else if (error instanceof MCPInvocationException) {
    console.error('MCP invocation failed:', error.message);
  }
}

API Reference

ArmorIQClient

Constructor Options

interface SDKConfig {
  apiKey: string; // Required: Your API key
  userId: string; // Required: User identifier
  agentId: string; // Required: Agent identifier
  contextId?: string; // Optional: Context identifier (default: 'default')
  useProduction?: boolean; // Optional: Use production endpoints (default: true)
  iapEndpoint?: string; // Optional: Override IAP endpoint
  proxyEndpoint?: string; // Optional: Override proxy endpoint
  backendEndpoint?: string; // Optional: Override backend endpoint
  proxyEndpoints?: Record<string, string>; // Optional: MCP-specific proxies
  timeout?: number; // Optional: Request timeout in ms (default: 30000)
  maxRetries?: number; // Optional: Max retry attempts (default: 3)
  verifySsl?: boolean; // Optional: Verify SSL (default: true)
}

Methods

  • capturePlan(llm, prompt, plan, metadata?) - Capture an execution plan
  • getIntentToken(planCapture, policy?, validitySeconds?) - Get a signed intent token
  • invoke(mcp, action, intentToken, params?, userEmail?) - Invoke an MCP action
  • delegate(intentToken, delegatePublicKey, validitySeconds?, allowedActions?, targetAgent?, subtask?) - Delegate to another agent
  • verifyToken(intentToken) - Verify a token locally
  • close() - Cleanup resources

Documentation

For complete documentation, visit docs.armoriq.ai

For native framework adapter versions, lifecycle hooks, callback chaining, and known limits, see the framework compatibility matrix.

For the OTLP-only 0.7.0 release sequence, see the release runbook.



License

MIT License - see LICENSE file for details.

版本与发布记录

@armoriq/sdk-dev 共发布 53 个版本,首次发布于 2026/04/14;过去 12 个月发布了 53 个版本。

版本发布日期距今
0.8.23latest2026/10/2117 天前
0.8.222026/10/2117 天前
0.8.212026/10/2018 天前
0.8.202026/10/1919 天前
0.8.192026/10/1920 天前
0.8.182026/10/1820 天前

关于 @armoriq/sdk-dev 的常见问题

@armoriq/sdk-dev 是什么?

ArmorIQ SDK - Build secure AI agents with cryptographic intent verification.

如何安装 @armoriq/sdk-dev?

在项目目录运行 npm install @armoriq/sdk-dev,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 armoriq-dev,可以用 npx armoriq-dev 直接运行。

@armoriq/sdk-dev 支持 TypeScript 吗?

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

@armoriq/sdk-dev 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@armoriq/sdk-dev 需要什么版本的 Node.js?

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

@armoriq/sdk-dev 可以商用吗?

@armoriq/sdk-dev 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@armoriq/sdk-dev 的下载量有多少?

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

@armoriq/sdk-dev 还在维护吗?

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