npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

aily-lex

v1.0.6

Published

Headless AI Agent Runtime — multi-host, MCP-compatible

Downloads

107

Readme

aily-lex

Headless AI Agent Runtime — 无渲染、多宿主、MCP 兼容的 Agent 核心。

从 aily-blockly 的 aily-chat 模块解耦而来,作为独立的 Agent 运行时,服务于 blockly 图形化 → code 代码版 → simulator 仿真版 产品路线。

特性

  • AsyncGenerator 核心循环 — query() 驱动:调模型→收集工具调用→执行→追加结果→循环,每步 yield AgentEvent
  • 完全无状态 — 客户端持有全部对话历史,每次调用发送完整 messages 数组
  • 15 个内置工具 — 文件读写编辑、grep/glob 搜索、bash 执行、子 Agent、网络请求等
  • 工具 prompt.ts 模式 — 每个工具自包含 name + description + prompt (Claude Code 模式)
  • 读写并发分区 — readOnly 工具并发执行,write 工具顺序执行
  • 三级上下文压缩 — microcompact (截断长输出) → autocompact (摘要旧消息) → manual
  • AbortController 层级 — 会话→查询→工具,逐层取消
  • Skill 系统 — 声明式提示增强器,按优先级注入系统提示
  • 可插拔端点 — IEndpoint 接口适配 Anthropic/OpenAI/DeepSeek/aily-services 等
  • Node.js 直接执行 — 工具通过 fs/promises + child_process.spawn 直接操作,无 IPC 开销
  • worker_threads 隔离 — IDE 通过 WorkerThreadBridge 与 Agent 通信

快速开始

npm install
npm run build
npm test

使用

import { AilyLexAgent, getAllBaseTools } from 'aily-lex';
import type { IEndpoint } from 'aily-lex';

// 1. 实现 IEndpoint 对接你的 LLM
const endpoint: IEndpoint = { /* ... */ };

// 2. 创建 Agent
const agent = new AilyLexAgent({
  host: nodeHostAccess,         // NodeHostAccess 实例
  endpoint,
  model: { modelId: 'claude-sonnet-4-20250514' },
  systemPrompt: '你是一个编程助手。',
});

// 3. 注册工具
agent.registerTools(getAllBaseTools());

// 4. 对话
for await (const event of agent.chat('帮我读取 package.json')) {
  switch (event.type) {
    case 'text_delta':
      process.stdout.write(event.text);
      break;
    case 'tool_call_start':
      console.log(`\n[调用工具: ${event.toolName}]`);
      break;
  }
}

项目结构

src/
├── index.ts                      根 barrel export
├── base/common/                  零依赖基础设施
│   ├── lifecycle.ts              IDisposable, DisposableStore
│   ├── event.ts                  Event<T>, Emitter<T>
│   ├── observable.ts             observable<T>(), derived<T>()
│   ├── async.ts                  createLinkedAbortController, raceAbort
│   └── errors.ts                 AilyLexError 层级
├── types/                        集中类型定义
│   ├── events.ts                 AgentEvent 联合类型 (12 种)
│   ├── tool.ts                   IAilyTool, ToolAnnotations, ToolContext
│   ├── message.ts                APIMessage, Turn, SessionSnapshot
│   ├── skill.ts                  IAilySkill
│   ├── hooks.ts                  QueryHooks, HookDecision
│   └── host.ts                   IAilyHostAPI, HostCapabilities
├── platform/                     服务接口
│   ├── endpoint/                 IEndpoint, IEndpointService, ModelStreamChunk
│   ├── instantiation/            ServiceIdentifier, ServiceCollection (DI)
│   ├── configuration/            IConfigurationService
│   ├── log/                      ILogService, ConsoleLogService
│   ├── mcp/                      IMcpClientService
│   └── telemetry/                ITelemetryService
├── agent/common/                 核心 Agent 逻辑
│   ├── agent.ts                  AilyLexAgent 主编排器
│   ├── query.ts                  query() AsyncGenerator 核心循环
│   ├── deps.ts                   QueryDeps (可注入 I/O 依赖)
│   ├── config.ts                 QueryConfig
│   ├── turnManager.ts            TurnManager 会话管理
│   ├── contextManager.ts         ContextManager 三级压缩
│   ├── transitions.ts            工具执行读写分区
│   ├── stopHooks.ts              停止点钩子
│   └── tokenBudget.ts            Token 预算计算
├── tools/                        内置工具
│   ├── tools.ts                  getAllBaseTools() 中央注册
│   ├── common/                   ToolRegistry, toolUtils
│   ├── fileRead/                 读文件
│   ├── fileWrite/                写文件
│   ├── fileEdit/                 精确字符串替换
│   ├── fileMultiEdit/            批量替换
│   ├── fileDelete/               删除文件
│   ├── listDir/                  列目录
│   ├── createDirectory/          创建目录
│   ├── grep/                     文本搜索
│   ├── glob/                     文件名模式搜索
│   ├── bash/                     Shell 命令执行
│   ├── runSubagent/              子 Agent
│   ├── askUser/                  用户交互
│   ├── getErrors/                诊断错误
│   ├── getChangedFiles/          Git 变更文件
│   └── webFetch/                 网络请求
├── skills/common/                SkillRegistry
└── host/                         宿主层
    ├── common/protocol.ts        IPC 协议 (UIToAgentMessage / AgentToUIMessage)
    ├── worker/workerBridge.ts    WorkerThreadBridge (node:worker_threads)
    └── node/                     Node.js 直接执行
        ├── nodeFileSystem.ts     fs/promises 实现
        ├── nodeTerminal.ts       child_process.spawn 实现
        └── nodeHostAccess.ts     组合入口

系统提示构建

AilyLexAgent._buildSystemPrompt() 三阶段构建:

  1. systemPromptPrefix — 宿主传入的基础系统提示
  2. Skills — SkillRegistry.getAll() 按优先级排序,包裹在 <skill> 标签中
  3. Tool instructions — 每个工具的 prompt 字段,包裹在 <toolInstructions> 标签中

架构参考

融合了两大 Agent 代码库的模式:

| 模式 | 来源 | |----------------------|----------------| | AsyncGenerator 核心循环 | Claude Code | | 显式依赖注入 (QueryDeps) | Claude Code | | 工具自包含目录 + prompt.ts | Claude Code | | 读写并发分区 | Claude Code | | AbortController 树 | Claude Code | | 三层目录结构 | VS Code Copilot | | Observable 状态 | VS Code Copilot | | ToolAnnotations 分区 | VS Code Copilot | | ServiceIdentifier DI | VS Code Copilot | | 多模型端点抽象 | VS Code Copilot | | StopHook | VS Code Copilot |

宿主端集成(aily-blockly)

aily-blockly 通过本地路径引用 aily-lex(package.json 中配置为 "aily-lex": "file:../aily-lex")。

首次安装

# 1. 构建 aily-lex
cd aily-lex
npm run build

# 2. 在 aily-blockly 中安装
cd ../aily-blockly
npm install

更新(修改 aily-lex 代码后)

# 在 aily-lex 目录执行
npm run build

# 在 aily-blockly 目录重新安装(更新 node_modules/aily-lex 中的 dist)
npm install d:\codes\aily-lex   # Windows 绝对路径
# 或
npm install ../aily-lex          # 相对路径(在 aily-blockly 目录执行)

为什么要重新 npm install?
file: 协议依赖在首次安装时会复制文件到 node_modules,之后修改源码不会自动同步。
每次 npm run build 后需重新 npm install 才能让 aily-blockly 用到最新 dist/。

快速验证

# 确认 QueryHooks 等最新类型已同步到宿主
Select-String "askHandler" node_modules/aily-lex/dist/types/hooks.d.ts

开发

npm run build          # TypeScript 编译
npm run build:watch    # 监听模式
npm test               # vitest 运行测试
npm run test:watch     # 测试监听模式

License

MIT