tardigrade README

The project's README from github.com/clavia-labs/tardigrade. As one markdown file: README.md.


Tardigrade

npm version Join Discord

Tardigrade

Tardigrade is a typescript framework for building modular agents around an immutable event log. It is built on Effect TS and is inspired by React's declarative approach to building user interfaces.

Agents that can self-improve

As models get increasingly smart, they will be capable of writing their own harnesses to improve themselves (Meta-Harness). A harness that is too rigid and complex is a bottleneck to this. We need something more composable, and easy to author.

We took inspiration from React. React derives its component tree and declared effects from state. Tardigrade applies the same idea to agent harnesses. Each component derives a view and enabled transitions from an event log.

{ view, transitions } = f(event log)

Why Tardigrade

Quickstart

Install Tardigrade and initialize an editable template actor. Use Bun 1.4 or later. If you are using a coding agent, the Tardigrade skill can help.

If you have an existing agent application, follow the migration guide to move its harness, history, API, client, and deployment configuration.

bun add -g tardie@latest
tdg init tardie-agent --template quickstart
cd tardie-agent
bun run dev

tdg init configures the first provider and model. Edit actor.ts to describe the agent. The CLI guide covers non-interactive setup, more providers, and deployment.

From another shell, discover the actor's methods, allocate a root thread, and send it a message:

tdg methods
tdg thread create --name quickstart
tdg call message '{"text":"What is the weather in Singapore?"}' --thread quickstart

The API listens at localhost:4242 by default.

An actor serving API requests from its generated Bun development server

Examples

Deploy

Deploy the generated Worker with either platform CLI:

Cloudflare:

bunx wrangler deploy

Celld:

celld deploy --config celld.jsonc

See the Cloudflare and Celld guides for platform configuration and secrets.

Build your own harness

bun add tardie

You can use npm install tardie instead. Install tardie@next to test a release candidate.

Create a component

An agent is made of components. Each component owns a machine with initial, step, and output. Its state retains the information from prior events that can affect its future output. An agent view includes system fragments, tool bindings, and context policy. This component gives the model one tool and owes no autonomous work:

import { component } from "tardie/core"
import { type AgentComponent, type AgentView } from "tardie/agent"

const deploys: AgentComponent = component<undefined, AgentView>({
  name: "deploys",
  initial: () => undefined,
  step: (state, _event) => state,
  output: () => ({
    view: {
      system: ["Inspect recent deployments when a release may explain an incident."],
      tools: [{
        spec: {
          name: "recent_deploys",
          description: "List recent production deploys",
          inputSchema: { type: "object", properties: {}, additionalProperties: false }
        },
        serve: (_call, _log, answer) => [
          answer([{ service: "api", revision: "a17c", summary: "Add rate limiting" }])
        ]
      }],
      context: [],
      output: []
    },
    transitions: []
  })
})

initial creates private state. step updates it for each event. This component ignores events and preserves its state. output derives its view and enabled transitions. Each tool keeps its specification and handler together. answer records the result. Replace the sample result with your deployment API.

An offered tool follows this lifecycle:

  1. The component adds recent_deploys to the agent's composed view.
  2. infer includes its specification in the model request.
  3. The model calls it. Tardigrade records ToolCalled.
  4. Tardigrade runs the attached handler and records ToolReturned.
  5. infer includes the result in the next model request.

Compose an agent

Mount the component beside the built-in parts that this task needs:

import { actor } from "tardie/core"
import { agentMethods, agentsPackage, budget, budgetAuthority, caller, codeMode, compaction, infer, outputValidateOnce, system } from "tardie/agent"
import { fetchPackage, filesPackage, workspacePackage } from "tardie/code"

const instructions = system(
  "You are a release analyst. Identify risky changes and recommend the safest next action."
)

const releaseAnalyst = actor({
  // name supplies the actor's stable identity.
  name: "release-analyst",
  // methods declare how the world can communicate with this actor.
  methods: agentMethods,
  // components implement those methods and derive transitions from the actor's private log.
  components: [
    // infer handles messages as model loops composed by children.
    infer([
      instructions, // system prompt
      deploys,      // provides recent_deploys tool and paired handler
      // budget scopes the tool-call limit to the codeMode subtree
      budget([
        codeMode([  // sandboxed code execution
          filesPackage(),
          fetchPackage(),
          agentsPackage(),
          workspacePackage()
        ])
      ], { authority: caller() }),
      compaction(), // bounded model context
      outputValidateOnce // validates structured result once without correction
    ]),
    budgetAuthority() // budgetAuthority handles requestBudget for this actor.
  ]
})

This agent can inspect deployments and files, fetch sources, delegate research, and analyze results with JavaScript. Change the package list to create another harness.

A run can follow this path:

MessageReceived -> recent_deploys -> execute -> TurnCompleted

Each action and result becomes an event that every component can interpret.

Run the composition

Bind a model and durable SQLite host

The three code blocks form one program. Run it in a project configured by tdg init or tdg setup, with the provider credentials available in the environment. This example registers the adapter for OpenAI Responses and compatible chat completions; use the adapter for your configured protocol.

import { createBunHost } from "tardie/bun"
import { modelAdapters } from "tardie/model/adapter"
import { openAICompatibleAdapter } from "tardie/model/openai"
import { bunModelServices } from "tardie/server/model-services"

const { layers } = await bunModelServices({
  env: process.env,
  adapters: modelAdapters(openAICompatibleAdapter)
})

const host = await createBunHost({
  actor: releaseAnalyst,
  storage: ".tardigrade",
  layersFor: () => layers
})

try {
  const thread = await host.allocateRootThread({ instance: "analyst", name: "main" })
  const result = await thread.methods.message(
    { text: "What changed in the deploy?" },
    { key: "deploy-review" }
  )
  console.log(result)
} finally {
  await host.close()
}

bunModelServices reads the model policy from wrangler.jsonc and binds inference and platform services. createBunHost stores actor instances under storage. The method call returns the completed result; retries with the same key return the same invocation. Use a new key for each new request.

How durability works

Every message, model action, tool result, and checkpoint lands in the log. Component machines consume those events and derive keyed transitions from their current state.

Sₙ₊₁ = step(Sₙ, eₙ₊₁)

The host runs transitions with unrecorded keys. It appends their events and repeats until the agent rests.

If the process stops during recent_deploys, the log still contains its unanswered ToolCalled. host.recover() replays the log through the component machines, derives the same key and input, then runs the handler again. Live execution only steps the machines with newly appended events.

External effects have at-least-once execution. Each keyed result is recorded once. Providers can use the transition key as an idempotency key.

Learn more

Contributing

Read CONTRIBUTING.md and run bun run gate before finishing a change.

tardigrade (clavia-labs/tardigrade)

Searching Database…

这是什么?Tardigrade 是一个 TypeScript 框架,用于围绕不可变事件日志构建模块化 agent。它构建在 Effect TS 之上,借鉴了 React 的声明式组件模型,从日志而非可变状态推导 agent 的视图和可用转换。
这是供我在其上构建的框架,还是现成的 agent 应用?它是一个用于编写 agent harness 的框架,不是开箱即用的 agent。你需要把独立的组件(工具、预算、压缩、代码执行)组合成一个 “actor”,然后自行运行这个组合。
怎么让它跑起来?安装 Tardigrade 并运行 `tdg init` 生成可编辑的 actor 模板,编辑 actor.ts 来描述 agent,然后在另一个 shell 里调用它的方法。本地 API 默认监听 4242 端口。
试用之前需要装好什么?运行 CLI 和框架需要 Bun 1.4 或更高版本,还需要你选定模型提供商(如 OpenAI)的凭据,以及一个持久化存储:本地可用 SQLite,若部署到相应平台则用 Cloudflare/Celld。
如果我的进程在运行途中崩溃会怎样?不会丢失任何东西:每个操作都先落入事件日志,`host.recover()` 会通过各组件的状态机重放日志,重新推导并重新执行所有未完成的转换,包括未得到响应的工具调用。
为什么基于不可变事件日志构建,而不是用普通状态?以日志为状态的设计让运行具备抗崩溃、无服务器(不需要任何进程一直存活)和完全可检查的特点——你可以从某次运行历史中的任意检查点重放或分叉实验。
提到过的面向编程 agent 的 Tardigrade skill 是什么?它是给编程 agent 用的辅助 skill(快速上手部分有提到),当由编程 agent 而非人来完成安装搭建时,它可以协助搭建脚手架并在 Tardigrade 项目内开展工作。
我可以用 npm 代替 Bun 的工具链吗?框架本身以 `tardie` npm 包的形式发布,可以用 `npm install tardie`(发布候选版用 `tardie@next`)安装,不过 CLI 和项目工具链是围绕 Bun 构建的。
Tardigrade agent 可以部署到哪里?生成的 agent 可用各平台自己的 CLI 以 Workers 形式部署到 Cloudflare 或 Celld;两者都有专门的部署指南,涵盖配置和密钥。
What are similar projects?flue, cayu, ruflo, go-micro, open-multi-agent, hive, MiMo-Code, computer
Size
14 MB
Stars
425
Age
2mo
Commits · 90 Days