amendsSelf-host

Packages

The parts amends runs agents with

Run any agent in any sandbox from your own Effect program. Contracts say what every implementation agrees on, and each adapter implements one over one system.

bun add @amends-dev/harness @amends-dev/sandbox
Your Effect program
  • @amends-dev/harness
    • harness-amends
    • harness-claude
    • harness-codex
    • harness-opencode
  • @amends-dev/sandbox
    • sandbox-daytona
    • sandbox-e2b
    • sandbox-local
    • sandbox-vercel

Contracts

What every implementation agrees on. Depend on a contract, and choose the adapter behind it when the program runs.

  • @amends-dev/harness

    Contract0.2.0

    Runs an agent, such as opencode or one in your own process over an Effect AI language model, and streams every agent's turns in one format.

  • @amends-dev/sandbox

    Contract0.2.1

    Sandboxes that agents work in: the contract every sandbox provider implements, with Effect's own file system and processes inside, and the conformance suites each provider runs.

  • @amends-dev/channel

    Contract0.2.0

    Channels that bring external conversations in: the contract every channel transport implements, receiving what a system sends and replying in its conversations.

  • @amends-dev/log

    Contract0.2.0

    Typed append-only logs over host storage: positions, commits that span logs, idempotent appends, paged reads, and live tails, with a memory implementation and the suites every adapter runs.

  • @amends-dev/toolkit

    Contract0.2.1

    Tools from MCP servers and HTTP APIs in one shape, assembled into the toolkit an agent calls, with search and code mode to present many tools as few, and the conformance suites each source runs.

Adapters

Each implements one contract over one system, with only that system's dependencies.

  • @amends-dev/codemode-opencode

    Implements codemode0.2.0

    opencode's code mode as the runtime of @amends-dev/toolkit's code mode: the code a model writes runs on an interpreter that reaches nothing but the tools it is given.

  • @amends-dev/harness-amends

    Implements harness0.2.0

    An agent in your own process for the @amends-dev/harness contract: a loop over an Effect AI language model, with tools for the files and the shell of a sandbox.

  • @amends-dev/harness-claude

    Implements harness0.2.0

    Claude Agent SDK behind the amends sandbox bridge.

  • @amends-dev/harness-codex

    Implements harness0.2.0

    Codex app-server as an agent for the amends harness contract

  • @amends-dev/harness-opencode

    Implements harness0.2.0

    opencode as an agent for the @amends-dev/harness contract: opencode works in a sandbox behind its bridge, which the agent's template installs there.

  • @amends-dev/sandbox-daytona

    Implements sandbox0.2.0

    Sandboxes on Daytona for the @amends-dev/sandbox contract: a Linux machine of its own for each sandbox, made from a snapshot of its template's version.

  • @amends-dev/sandbox-e2b

    Implements sandbox0.2.0

    Sandboxes on E2B for the @amends-dev/sandbox contract.

  • @amends-dev/sandbox-local

    Implements sandbox0.2.0

    Sandboxes as directories on this machine, for the @amends-dev/sandbox contract: for development, tests, and agents you would trust on this machine anyway.

  • @amends-dev/sandbox-vercel

    Implements sandbox0.2.0

    Sandboxes on Vercel for the @amends-dev/sandbox contract.

Quick start

An agent in a few lines

  1. Make an agent

    From an adapter: amends's own agent over an Effect AI model, or opencode in a sandbox.

  2. Run it with a harness

    Every agent gets the same sessions and turns, streamed in one format.

  3. Keep the session

    Release a session as JSON and resume it later, on any host and on any agent.

hello.ts
import { AmendsAgent, Models } from "@amends-dev/harness-amends"
import { Agent, Harness } from "@amends-dev/harness"
import { Config, Effect, Layer } from "effect"
import { FetchHttpClient } from "effect/http"

const program = Effect.gen(function* () {
  const agent = yield* AmendsAgent.make({
    model: {
      provider: "anthropic",
      model: "claude-sonnet-5-5",
      protocol: "anthropic-messages",
      url: "https://api.anthropic.com/v1",
      apiKey: yield* Config.Redacted("ANTHROPIC_API_KEY"),
      contextWindow: 200_000
    }
  })
  const harness = Harness.make(agent)
  const session = yield* harness.createSession({ id: Agent.SessionId.make("hello") })
  const answer = yield* session.generate({ prompt: "Say hello in one word." })
  return answer.text
}).pipe(Effect.provide(Models.layer.pipe(Layer.provide(FetchHttpClient.layer))))

Write your own

An integration connects amends to another system. Each kind has a contract, and each implementation is a package of its own.

  • An agent

    Implement the harness contract, and every host runs your agent's turns in the same stream.

    Writing an adapter →
  • A sandbox provider

    Implement the sandbox contract, then run its conformance suites against your provider.

    Writing a provider →