Skip to content

AmendsAgent

The agent amends: a loop over an Effect AI LanguageModel that runs in the host’s process. Each step streams the model’s response to the conversation so far while Effect AI runs the tools the model calls, and a turn takes steps until the model answers without calling a tool. With a sandbox the agent works with the tools in Tools; without one, it answers from its model alone, calling only the host’s tools.

It keeps nothing of its own between turns: a session it resumes goes on from the conversation the session recorded, tool calls and results included. A turn does not outlive the process running it: continueTurn goes on from the steps of a turn suspendTurn cut short that the session has, and runs the step in flight again.

Before each step, once the conversation fills most of the model’s context window, the agent compacts it: the model summarizes all but the latest messages, which the conversation keeps as they were. compact summarizes all of it, between turns. A model whose endpoint does not know its context window is compacted only on request.

Since v0.1.0

The agent, which makes the language model of each of its endpoints with Models.LanguageModels, as Models.layer provides it over the HttpClient the requests go out through.

Example (A turn on Anthropic’s API, in the host’s process)

import { Agent, Harness } from "@amends-dev/harness"
import { AmendsAgent, Models } from "@amends-dev/harness-amends"
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))))

Signature

declare const make: (options: Options) => Effect.Effect<Agent.Agent, never, Models.LanguageModels>

Source

Since v0.1.0

What the agent is made with: the endpoints its turns run on, as Agent.Options give them, and what only this agent takes.

Signature

export interface Options extends Agent.Options {
/** The most steps a turn takes, ending it even while the model calls tools. Unlimited by default. */
readonly maxSteps?: number
/** How long a `bash` command runs before the agent kills it, 2 minutes by default. */
readonly commandTimeout?: Duration.Duration
}

Source

Since v0.1.0