@aseity/lyra

中文文档
0.23.0发布于 2026/11/05MITTypeScriptESM + CJS近 30 天下载 1849

Lyra agent library

原始使用文档
文档目录17 节
  1. Changelog
  2. Install
  3. Quick start
  4. Xiaomi MiMo
  5. Command Code
  6. DeepSeek Search API
  7. DeepSeek hosted web search
  8. DeepSeek Responses JSON output
  9. OpenRouter
  10. License
  11. Model parameter compatibility
  12. MCP
  13. Image validation
  14. Optional view_image compression
  15. Docker lifecycle
  16. Application operation tracing
  17. Product thinking effort

@aseity/lyra

Lyra is a TypeScript library for running tool-using agents across OpenAI, Anthropic, and compatible model providers. It includes streaming, sessions, handoffs, structured outputs, tracing, MCP clients, and sandbox capabilities.

Changelog

See the release history for changes in each version. CHANGELOG.md is also included in the npm package.

Install

pnpm add @aseity/lyra zod

Quick start

import { Agent, OpenAIProvider, run } from '@aseity/lyra';

const provider = new OpenAIProvider({
  apiKey: process.env.OPENAI_API_KEY,
});
const model = await provider.getModel('gpt-5.4-mini');

const agent = new Agent({
  name: 'Assistant',
  instructions: 'Answer clearly and concisely.',
  model,
});

const result = await run(agent, 'Hello!');
console.log(result.finalOutput);

Pass concrete Model instances when model selection is owned by your application. Use Runner when you need reusable workflow, tracing, or session configuration.

See tool input schemas and question approval for strict optional parameters, filesystem defaults, and restoring user answers.

Xiaomi MiMo

import { MiMoProvider, MIMO_MODEL_NAMES } from '@aseity/lyra';

const provider = new MiMoProvider(); // reads MIMO_API_KEY
const pro = await provider.getModel(); // mimo-v2.6-pro
const flash = await provider.getModel('mimo-v2.6-flash');
// MIMO_MODEL_NAMES contains the two built-in model names.

MiMo uses the Anthropic Messages API at https://api.xiaomimimo.com/anthropic. Pass apiKey, baseURL, or defaultModel to override the defaults; MIMO_DEFAULT_MODEL also sets the default model. Token Plan users can supply their plan's Anthropic base URL and key. Both built-in models have a 1M-token context window and a 131,072-token output limit, with image input, streaming, tool calls, and thinking replay.

Thinking follows the service default. Use modelSettings.reasoning.effort: 'none' to disable it, or modelSettings.providerData.thinking: { type: 'enabled' } to enable it explicitly. MiMo has no reasoning effort levels. In thinking mode, the service fixes temperature and top-p to its own defaults. See the model list and thinking guide.

Command Code

import { CommandCodeProvider } from '@aseity/lyra';

const provider = new CommandCodeProvider(); // COMMAND_CODE_API_KEY
const model = await provider.getModel(); // gpt-6-luna

Claude uses Messages; GPT and google/gemini-3.8-flash use Responses. Other Claude/GPT IDs can pass through without inheriting verified capabilities. Other Gemini models are rejected. See configuration, parameter limits and live acceptance, including Gemini's numeric enum Schema limit.

DeepSeek Search API

Use DeepSeekSearchClient to call the standalone Search API from a local function tool. It works independently of the Agent's model provider. The application owns credentials, shared rate limiting, retries, and cancellation deadlines. See the client contract.

Add webSearch() from @aseity/lyra to an agent's tools when using DeepSeekProvider. The model decides whether to search; no parameters or local executor are needed. Only DeepSeek Messages supports this declaration. See hosted web search for normalized search records, citations, streaming events, and persistent Session replay.

DeepSeek Responses JSON output

DeepSeekProvider continues to use Anthropic Messages. For JSON Schema output, pass the separately exported DeepSeekResponsesModel directly to an agent:

import { Agent, DeepSeekResponsesModel, run } from '@aseity/lyra';
import { z } from 'zod';

const agent = new Agent({
  name: 'Extractor',
  model: new DeepSeekResponsesModel({
    model: 'deepseek-v4-pro',
    apiKey: process.env.DEEPSEEK_API_KEY,
  }),
  instructions: 'Extract the name and age from the input.',
  outputType: z.object({ name: z.string(), age: z.number() }),
});

const result = await run(agent, 'Alice is 30 years old.');
console.log(result.finalOutput);

The model sends outputType as text.format.type: 'json_schema'. It defaults to https://api.deepseek.com and uses the configured DeepSeek key when apiKey is omitted. Its baseURL is independent of DEEPSEEK_BASE_URL, which belongs to the Anthropic provider. You can supply fetch, maxRetries, and metadata, or inject an openAIClient instead of client configuration.

Streaming is supported. modelSettings.maxTokens overrides the default 32,768 output tokens; reasoning effort supports low, high, max, and none/null to disable thinking. Omission preserves the server's thinking default. Responses are stateless: send full history, not conversation or previous-response IDs. See the DeepSeek Responses reference.

To run the non-streaming and streaming live checks with DEEPSEEK_API_KEY set: bun packages/lyra/test/manual/deepseek-responses.ts (makes two paid API calls).

OpenRouter

OpenRouterProvider uses OpenRouter's Chat Completions endpoint while preserving OpenRouter routing metadata, cost data, structured reasoning, and in-band stream errors:

import { OpenRouterProvider } from '@aseity/lyra';

const provider = new OpenRouterProvider({
  apiKey: process.env.OPENROUTER_API_KEY,
  httpReferer: 'https://example.com',
  appTitle: 'Example Agent',
  defaultRequest: {
    provider: { require_parameters: true },
  },
});

const model = await provider.getModel('anthropic/claude-sonnet-4.6');

Per-request OpenRouter extensions such as provider, models, plugins, reasoning, and session_id can also be passed through modelSettings.providerData.

License

MIT

Model parameter compatibility

See model parameter transport for modern effort support, legacy thinking budgets, explicit output validation, and migration from aliased effort values. Provider/model support is distinct from transport support.

MCP

Connect stdio, Streamable HTTP or SSE MCP servers and expose their tools to any Lyra tool-capable model provider. See MCP clients for connection management, authentication, filtering, resources and upstream compatibility.

Image validation

view_image validates inline PNG/JPEG/WebP/GIF bytes before native image results or vision fallback requests, even when compression is disabled. It performs a strict Sharp decode, including all animation frames; GIF block boundaries are also checked because the decoder tolerates some truncated GIFs. Invalid images return toolError text without image content, so the model can regenerate the file and retry within the same turn. Source files are never repaired or rewritten. A provider's later HTTP 400 still ends the turn; local validation does not guarantee provider acceptance and does not add model retries. Remote image references from custom sandboxes cannot be locally validated and return a tool error.

Byte and dimension limits are checked before full decoding. Host ceilings are 32 MiB per input, 8000 pixels per side and 64 million pixels summed across all frames; stricter model limits also apply. At most two decodes run concurrently per process. Validation uses streaming pixel statistics instead of returning a full raw pixel buffer. Queued calls retain their bounded input bytes, so callers must still bound tool-call concurrency. Sharp loads lazily on the first image. Static compression doubles as validation instead of decoding the image twice.

Offline regression: pnpm --filter @aseity/lyra exec vitest run test/view-image-validation.test.ts. Set LYRA_TEST_DOCKER_IMAGE to an existing image with bash to include real Docker Runner recovery. bun packages/lyra/test/manual/image-validation.ts measures four concurrent calls at roughly 1, 16 and 64 million pixels; optional file arguments replay local failures without contacting a model. Local 64-million-pixel runs took 6.8 seconds for four calls with sampled process RSS peaking near 232 MiB; these measurements depend on codecs, pixels, runtime, and machine, and are not a memory guarantee.

Optional view_image compression

view_image preserves original image bytes by default. To reduce inline image payloads:

filesystem({ viewImageCompression: true })

This applies to both native vision and viewImageCaptioner requests. Static inline images are encoded as JPEG at quality 90 with 4:4:4 chroma, without downscaling; EXIF orientation is applied and transparent backgrounds become white. If encoding would increase the payload, the original is retained. Animated images retain their original bytes after validation. Source files are never overwritten; returned MIME type, byte size and dimensions describe the actual transmitted image.

Validation and compression share the installed sharp dependency. Existing input and model image limits still apply. This reduces individual image payloads but does not limit accumulated conversation size or guarantee avoidance of HTTP 413 responses. Lossy compression can affect fine text; retain original files for detailed crops and verification.

Docker lifecycle

Docker startup failures are cleaned up before the error returns. If cleanup also fails, catch DockerSandboxStartupError, retain the execution-resource reservation, and retry error.cleanup() after Docker recovers. See Docker startup and cleanup for the error contract, cancellation, and shutdown behavior.

See explicit skill input for manual selection, discovery flags, original message display and frozen model history.

Inline file references preserve their position in the user's message:

await runner.run(agent, [{
  type: 'message',
  role: 'user',
  content: [
    { type: 'input_text', text: 'Read ' },
    { type: 'input_file_ref', name: 'notes.md', path: '/workspace/notes.md' },
    { type: 'input_text', text: ' and summarize it.' },
  ],
}]);

The host must make the file available at path before running the agent. Lyra projects the reference to @notes.md and appends a reminder with its workspace path and reading guidance in model and compaction inputs. Ambiguous same-name references keep their paths inline instead, without repeating them at the end. Session items retain the original parts. See file references. userMessageText displays @notes.md; the exported InputFileRef schema contains only type, name, and path, without a host-specific library ID.

See workspace file edits for structured input_file_edits notifications, optional diffs, and model projection with original history preserved.

See per-run ephemeral context for frozen context snapshots that appear in model requests without entering history or compaction.

See background incremental summaries for frozen request inputs, configurable summary templates, and caller-scheduled memory updates that preserve the model prefix without blocking subsequent turns.

See model input reminders for the public wrapping and escaping API, host ownership, and migration, and uploads for reference-only file and image projection.

Application operation tracing

Import withTrace and withCustomSpan from @aseity/lyra to trace application work around model calls. They share the processors configured by setTraceProcessors and respect setTracingDisabled. withTrace(name, work, { groupId, metadata }) starts a separate trace. Within its callback, withCustomSpan(work, { data: { name, data } }) adds a timed child span, and model calls with tracing: true or tracing: 'enabled_without_data' join that trace. ModelTracing is also exported as a type.

Custom span data is exported as supplied. The application must omit private payloads when its sensitive-data setting is off. A custom span records errors thrown by its callback; catch inside the callback and set a redacted span error when the original exception contains private data.

Non-streaming generation errors and Runner Agent errors retain the exception name when sensitive-data tracing is disabled. The original exception still reaches the caller.

Anthropic and Anthropic-compatible streaming generation spans record the assembled model output at response_done, including text, reasoning and tool calls. They record the model and final usage even when payload capture is off. The output uses Lyra's normalized model items, with private replay metadata removed, rather than the empty initial message_start payload.

Product thinking effort

Set modelSettings: { thinkingEffort: 'low' } to opt into Lyra's four-level none | low | high | max intent. Verified direct providers map it before requests; unknown channels attempt standard protocol fields. Native reasoning.effort remains available separately. Catch ThinkingEffortUnsupportedError (code THINKING_EFFORT_UNSUPPORTED) for explicit thinking-parameter rejection. See the contract, provider mappings and examples.

版本与发布记录

@aseity/lyra 共发布 48 个版本,首次发布于 2026/06/24;过去 12 个月发布了 48 个版本。

版本发布日期距今
0.23.0latest2026/11/053 天前
0.22.02026/10/2810 天前
0.21.32026/10/2316 天前
0.21.22026/10/2316 天前
0.21.12026/10/1425 天前
0.21.02026/10/1425 天前

关于 @aseity/lyra 的常见问题

@aseity/lyra 是什么?

Lyra agent library

如何安装 @aseity/lyra?

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

@aseity/lyra 支持 TypeScript 吗?

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

@aseity/lyra 支持 ESM 还是 CommonJS?

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

@aseity/lyra 可以商用吗?

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

@aseity/lyra 的下载量有多少?

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

@aseity/lyra 还在维护吗?

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