@fungi.computer/bird-dog

中文文档
0.3.6发布于 2026/11/08MITTypeScriptES Module近 30 天下载 1.1万

Durable addressed agent mail over generic Watchdog work

原始使用文档
文档目录7 节
  1. Install or set up
  2. Quick start
  3. Core concepts
  4. API reference
  5. Examples and checks
  6. Limits and errors
  7. Contribute and license

BirdDog (@fungi.computer/bird-dog)

BirdDog translates addressed Agent work into Watchdog jobs and builds replies when that work settles. It owns envelope grammar, reply keys and settlement content. The host stages each reply batch through its existing Carrier Post owner; Watchdog owns delivery attempts and wakes.

Every sender and recipient is an ordinary Agent Session. Parent and child relationships remain in the host's domain records.

Install or set up

npm install @fungi.computer/bird-dog

BirdDog is ESM-only. It depends on @fungi.computer/watchdog and effect, which npm installs for you. It does no I/O of its own, so it runs in Node, Cloudflare Workers or any runtime that can stage a batch of mail in its existing delivery owner.

Entrypoints:

  • @fungi.computer/bird-dog: the Promise API on BirdDog and its types.
  • @fungi.computer/bird-dog/effect: the Effect-native mail room (make), settlementReplies, the Effect Schema parsers and BirdDogError. settlementReplies builds the same reply envelopes for a host-owned Post transport.

Quick start

This constructs a reply batch. The example prints it; a durable host stages the batch in its existing Carrier Post transaction.

import { BirdDog, type BirdDogMail } from "@fungi.computer/bird-dog";

const parent = {
  kind: "agent",
  agentId: "parent",
  sessionId: "parent-session",
} as const;
const child = {
  kind: "agent",
  agentId: "child",
  sessionId: "child-session",
} as const;

const room = await BirdDog.make({
  stage: async (mail: readonly BirdDogMail[]) => {
    for (const reply of mail) console.log(reply.content);
  },
  now: () => Date.now(),
});

// 1. Turn accepted work into a Watchdog job. Hand this to Watchdog's ingest.
const job = BirdDog.agentJob({
  delivery: "followUp",
  work: {
    jobId: "job-1",
    sessionId: child.sessionId,
    commandFactId: "command-1",
  },
  mail: {
    key: "delegation-1",
    to: child,
    from: parent,
    replyTo: [parent],
    content: "Find out why the build is red",
    createdAt: Date.now(),
  },
});

// 2. Your Watchdog executor decodes the payload and runs the child's work.
const payload = BirdDog.decodeAgentJob(job);
console.log(payload.work.commandFactId); // "command-1"

// 3. When Watchdog settles the job, stage the replies.
await room.fanOut({
  job: { ...job, state: "settled", outcome: "completed" },
  content: "A test fixture was missing. Fixed it.",
});

In a real host, the settled job comes from Watchdog and stage commits the whole batch before the settlement cursor advances. Replaying a stable reply key retains the first staged letter, including its original timestamp.

Core concepts

Addresses. An agent address is { kind: "agent", agentId, sessionId }. IDs are 1 to 256 characters. There is no special kind for subagents.

Mail. A BirdDogMail has a stable key, a to and from address, a replyTo list, string content and a createdAt time in milliseconds. The key must identify the request across retries. BirdDog derives every reply key from it.

Agent jobs. BirdDog.agentJob({ work, delivery, mail? }) validates the input and returns a queued Watchdog job. The job's queue is the target sessionId, its lane is default, its priority is 0, and its payload carries the sessionId, the commandFactId and the optional mail. work.recovery passes straight through to Watchdog's recovery policy. Because it is synchronous, you can call it inside an owner transaction and pass the result to Watchdog's transactional.enqueueAcceptedJob. BirdDog.decodeAgentJob(job) parses the payload back on the executor side. Watchdog never reads it.

Fan-out. fanOut({ job, content, diagnostic? }) takes a settled job, the content owed to correspondents and the Session's terminal diagnostic. It passes one reply per replyTo address to stage, keyed <mail key>:reply:<index>. Each reply's from is the mail's recipient, its content is your content verbatim (or, when it is empty, The delegated work ended <outcome> without reply text., so a reply is always admissible text), and its typed reply field carries the settlement facts:

{
  commandId: "command-1", // the settled work's commandFactId
  outcome: "failed", // the exact Watchdog outcome
  diagnostic: "provider_error: 401 Authorization: Bearer [redacted]",
}

outcome is exactly the job's: completed, failed, interrupted, cancelled or outcome_unknown. Only failed, interrupted and outcome_unknown replies carry a diagnostic. boundedDiagnostic makes it one line, masks credential-shaped values (authorization-scheme credentials, named keys, tokens, secrets and passwords, and long letter-and-digit runs), then cuts it to BIRD_DOG_DIAGNOSTIC_MAX_LENGTH (200) characters. A cancelled job delivers the supplied cancellation result as its content. A settlement's meta is for your own fan-out wrapper, such as naming who cancelled; replies never carry it. A job without mail sends nothing.

The recipient's host owns authentication and presentation. It trusts the reply facts only after checking the reply against the mail it sent, then decides who authors the line and how its model sees it.

Host ports. BirdDog.make takes stage(mail) and now(). Staging is one batch operation so the host can commit all replies atomically. The host retains stable keys, prepared delivery facts and receipts through Carrier Post. Watchdog reserves attempts, resumes retries after reopen and reports the next wake.

API reference

The generated reference is in docs/api.

  • @fungi.computer/bird-dog: BirdDog with agentJob, decodeAgentJob and make, plus the BirdDogMail, BirdDogAgentReference, BirdDogAgentWork, BirdDogAgentJobPayload, BirdDogReply, BirdDogOptions, BirdDogSettlement and BirdDogRuntime types.
  • @fungi.computer/bird-dog/effect: make, agentJobFromInput, decodeAgentJob, settlementReplies, boundedDiagnostic, BIRD_DOG_DIAGNOSTIC_MAX_LENGTH, BirdDogError, EffectBirdDogOptions, BirdDogEffect and the schemas BirdDogAgentReferenceSchema, BirdDogReplySchema, BirdDogMailSchema, BirdDogAgentWorkSchema, BirdDogAgentJobPayloadSchema and BirdDogAgentJobInputSchema.

Examples and checks

The Effect entrypoint takes the same ports as Effect values. Using job from the quick start, this prints the settlement reply batch:

import * as Effect from "effect/Effect";
import { make } from "@fungi.computer/bird-dog/effect";

const room = await Effect.runPromise(
  make({
    stage: (mail) =>
      Effect.sync(() => {
        for (const reply of mail) console.log(reply.content);
      }),
    now: () => Date.now(),
  }),
);
await Effect.runPromise(
  room.fanOut({
    job: { ...job, state: "settled", outcome: "completed" },
    content: "A test fixture was missing. Fixed it.",
  }),
);

Use the schemas to parse mail that arrives from outside your process:

import * as Schema from "effect/Schema";
import { BirdDogMailSchema } from "@fungi.computer/bird-dog/effect";

const mail = Schema.decodeUnknownSync(BirdDogMailSchema)(JSON.parse(body));

The package tests cover job translation, typed settlement replies, bounded and redacted diagnostics, and batch staging failures. Carrier and Local consumer tests cover durable retries, receipt loss and physical reopen.

pnpm test

Limits and errors

agentJob and decodeAgentJob reject invalid input using the maintained schema. A failing Promise staging port becomes BirdDogError("mail staging failed") with the original error as its cause. The caller must retain the settlement cursor until staging succeeds. Delivery remains at least once: receivers must admit a repeated mail key idempotently.

Contribute and license

BirdDog is MIT licensed. See LICENSE.

版本与发布记录

@fungi.computer/bird-dog 共发布 12 个版本,首次发布于 2026/10/15;过去 12 个月发布了 12 个版本。

版本发布日期距今
0.3.6latest2026/11/087 天前
0.3.52026/11/087 天前
0.3.42026/11/088 天前
0.3.32026/11/079 天前
0.3.22026/11/0412 天前
0.3.12026/10/3016 天前

关于 @fungi.computer/bird-dog 的常见问题

@fungi.computer/bird-dog 是什么?

Durable addressed agent mail over generic Watchdog work

如何安装 @fungi.computer/bird-dog?

在项目目录运行 npm install @fungi.computer/bird-dog,或使用 pnpm add / yarn add / bun add。

@fungi.computer/bird-dog 支持 TypeScript 吗?

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

@fungi.computer/bird-dog 支持 ESM 还是 CommonJS?

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

@fungi.computer/bird-dog 可以商用吗?

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

@fungi.computer/bird-dog 的下载量有多少?

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

@fungi.computer/bird-dog 还在维护吗?

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