NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Go modules · #688 by repository stars
Last release 3 days ago
05 Oct 2026
Ships on a steady schedule
a new release about every 9 days
Nearly every release is documented
notes for 57 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
11 months old
927 releases · first in 2025
One column per month.
security(deps): bump pytest to >=9.0.3 (CVE-2025-71176) by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/488
⚠️ This is a staging/pre-release version for testing. Not recommended for production use.
# Staging binary (use --staging flag)
curl -fsSL https://agentfield.ai/install.sh | bash -s -- --staging
# Python SDK (prerelease - requires --pre flag)
pip install --pre agentfield
# TypeScript SDK
npm install @agentfield/sdk@next
VERSION=v0.1.138-rc.11 curl -fsSL https://agentfield.ai/install.sh | bash
Download the binary for your platform below, make it executable, and move it to your PATH.
agentfield-darwin-amd64agentfield-darwin-arm64agentfield-linux-amd64agentfield-linux-arm64af call rejecting valid input for optional reasoner params by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/610_current_status issue where status stuck on `S… by @DebanKsahu in https://github.com/Agent-Field/agentfield/pull/673af install by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/738Note truncated.
On a non-UTC host using local SQLite storage, the stale-execution reaper could mark a fresh, active execution as timed out within seconds of starting. Later successful status callbacks were then rejected with HTTP 409 because the row had already become terminal.
Root cause: SQLite compares timestamp columns as text. Write paths persisted timestamps with time.Now(), so on a non-UTC host they carried a local zone offset (e.g. "...-05:00"). A fresh local value sorts lexically before a UTC cutoff even though its instant is newer, so the reaper's COALESCE(updated_at, created_at, started_at) <= cutoff test matched rows that were not actually stale.
Fix has two layers:
Read path: wrap the timestamp comparison and ORDER BY in julianday() for SQLite so the comparison is instant-aware and offset-correct. Postgres uses timestamptz (already instant-aware) and has no julianday(), so the Postgres query path is left unchanged via a dialect-aware helper. This covers rows already persisted with an offset.
Write path: normalize execution and workflow created_at/updated_at to time.Now().UTC() so newly stored rows never carry a local offset. This is the durable fix.
Applies to MarkStaleExecutions, MarkStaleWorkflowExecutions, and RetryStaleWorkflowExecutions.
Adds regression tests covering fresh and genuinely stale rows stored with a non-UTC offset, for both the mark-stale and retry-selection paths. (1ae0e5a)
security(deps): bump pytest to >=9.0.3 (CVE-2025-71176) by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/488
⚠️ This is a staging/pre-release version for testing. Not recommended for production use.
# Staging binary (use --staging flag)
curl -fsSL https://agentfield.ai/install.sh | bash -s -- --staging
# Python SDK (prerelease - requires --pre flag)
pip install --pre agentfield
# TypeScript SDK
npm install @agentfield/sdk@next
VERSION=v0.1.138-rc.10 curl -fsSL https://agentfield.ai/install.sh | bash
Download the binary for your platform below, make it executable, and move it to your PATH.
agentfield-darwin-amd64agentfield-darwin-arm64agentfield-linux-amd64agentfield-linux-arm64af call rejecting valid input for optional reasoner params by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/610_current_status issue where status stuck on `S… by @DebanKsahu in https://github.com/Agent-Field/agentfield/pull/673af install by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/738Note truncated.
Bumps the npm_and_yarn group with 1 update in the /control-plane/web/client directory: @humanfs/node. Bumps the npm_and_yarn group with 1 update in the /desktop directory: @xmldom/xmldom. Bumps the npm_and_yarn group with 1 update in the /examples/benchmarks/100k-scale/mastra-bench directory: qs.
Updates @humanfs/node from 0.16.6 to 0.16.7
Updates @xmldom/xmldom from 0.8.13 to 0.8.15
Updates qs from 6.15.2 to 6.16.0
updated-dependencies:
Signed-off-by: dependabot[bot] support@github.com Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (c9e3bcb)
Bumps the npm_and_yarn group with 2 updates in the /examples/python_agent_nodes/rag_evaluation/ui directory: browserslist and postcss-selector-parser.
Updates browserslist from 4.28.2 to 4.28.8
Updates postcss-selector-parser from 6.1.2 to 6.1.4
updated-dependencies:
Signed-off-by: dependabot[bot] support@github.com Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (1a50760)
Nothing published for this version
security(deps): bump pytest to >=9.0.3 (CVE-2025-71176) by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/488
⚠️ This is a staging/pre-release version for testing. Not recommended for production use.
# Staging binary (use --staging flag)
curl -fsSL https://agentfield.ai/install.sh | bash -s -- --staging
# Python SDK (prerelease - requires --pre flag)
pip install --pre agentfield
# TypeScript SDK
npm install @agentfield/sdk@next
VERSION=v0.1.138-rc.9 curl -fsSL https://agentfield.ai/install.sh | bash
Download the binary for your platform below, make it executable, and move it to your PATH.
agentfield-darwin-amd64agentfield-darwin-arm64agentfield-linux-amd64agentfield-linux-arm64af call rejecting valid input for optional reasoner params by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/610_current_status issue where status stuck on `S… by @DebanKsahu in https://github.com/Agent-Field/agentfield/pull/673af install by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/738Note truncated.
Bumps the npm_and_yarn group with 2 updates in the /control-plane/web/client directory: browserslist and postcss-selector-parser. Bumps the npm_and_yarn group with 1 update in the /desktop directory: browserslist.
Updates browserslist from 4.28.0 to 4.28.8
Updates postcss-selector-parser from 6.1.2 to 6.1.4
Updates browserslist from 4.28.5 to 4.28.8
updated-dependencies:
Signed-off-by: dependabot[bot] support@github.com Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (5210726)
Bumps the go_modules group with 1 update in the /control-plane directory: google.golang.org/grpc.
Updates google.golang.org/grpc from 1.82.1 to 1.83.1
updated-dependencies:
Signed-off-by: dependabot[bot] support@github.com Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (c831d89)
security(deps): bump pytest to >=9.0.3 (CVE-2025-71176) by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/488
⚠️ This is a staging/pre-release version for testing. Not recommended for production use.
# Staging binary (use --staging flag)
curl -fsSL https://agentfield.ai/install.sh | bash -s -- --staging
# Python SDK (prerelease - requires --pre flag)
pip install --pre agentfield
# TypeScript SDK
npm install @agentfield/sdk@next
VERSION=v0.1.138-rc.8 curl -fsSL https://agentfield.ai/install.sh | bash
Download the binary for your platform below, make it executable, and move it to your PATH.
agentfield-darwin-amd64agentfield-darwin-arm64agentfield-linux-amd64agentfield-linux-arm64af call rejecting valid input for optional reasoner params by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/610_current_status issue where status stuck on `S… by @DebanKsahu in https://github.com/Agent-Field/agentfield/pull/673af install by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/738Note truncated.
security(deps): bump pytest to >=9.0.3 (CVE-2025-71176) by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/488
⚠️ This is a staging/pre-release version for testing. Not recommended for production use.
# Staging binary (use --staging flag)
curl -fsSL https://agentfield.ai/install.sh | bash -s -- --staging
# Python SDK (prerelease - requires --pre flag)
pip install --pre agentfield
# TypeScript SDK
npm install @agentfield/sdk@next
VERSION=v0.1.138-rc.7 curl -fsSL https://agentfield.ai/install.sh | bash
Download the binary for your platform below, make it executable, and move it to your PATH.
agentfield-darwin-amd64agentfield-darwin-arm64agentfield-linux-amd64agentfield-linux-arm64af call rejecting valid input for optional reasoner params by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/610_current_status issue where status stuck on `S… by @DebanKsahu in https://github.com/Agent-Field/agentfield/pull/673af install by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/738Note truncated.
security(deps): bump pytest to >=9.0.3 (CVE-2025-71176) by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/488
⚠️ This is a staging/pre-release version for testing. Not recommended for production use.
# Staging binary (use --staging flag)
curl -fsSL https://agentfield.ai/install.sh | bash -s -- --staging
# Python SDK (prerelease - requires --pre flag)
pip install --pre agentfield
# TypeScript SDK
npm install @agentfield/sdk@next
VERSION=v0.1.138-rc.6 curl -fsSL https://agentfield.ai/install.sh | bash
Download the binary for your platform below, make it executable, and move it to your PATH.
agentfield-darwin-amd64agentfield-darwin-arm64agentfield-linux-amd64agentfield-linux-arm64af call rejecting valid input for optional reasoner params by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/610_current_status issue where status stuck on `S… by @DebanKsahu in https://github.com/Agent-Field/agentfield/pull/673af install by @AbirAbbas in https://github.com/Agent-Field/agentfield/pull/738Note truncated.
When the re-registration reap fails an in-flight execution, the row's status_reason names the departing instance but nothing in any read API exposed which instance the execution was actually created against. An operator had no way to tell a genuinely orphaned execution from a legacy row that the reap swept because its instance_id was empty.
Add agent_node_id and instance_id to ExecutionStatusResponse, populated in renderStatus -- the single builder GET /executions/:id, batch-status and the status callback all funnel through. Both are omitempty: instance_id vanishes for nodes that never report one (only the Python SDK does today), and agent_node_id stays absent on the synthetic not_found/error entries that handleBatchStatus builds inline, so those keep their current shape.
The UI details DTO gains instance_id alongside the agent_node_id it already carried, so the DAG step drawer can surface it.
No storage or schema change: migrations 033/035 added the columns and every execution SELECT already reads COALESCE(instance_id, '').
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
The deferred reap assumes a re-registration with a new instance_id means the previous OS process is gone. With replicas > 1 behind one node id that assumption is wrong: a sibling replica registering is indistinguishable from a replacement, so the reap fails the still-alive sibling's in-flight executions once the drain grace elapses (#987).
Add AGENTFIELD_AGENT_ORPHAN_REAP_ENABLED (default true = today's behaviour). When false, the new conjunct on shouldReapOrphans means the deferred goroutine is never armed at all, and the stale-execution sweep stays as the backstop. Startup logs one greppable warning when disabled.
Defaulting a bool to true needs presence tracking, since a zero value and
an explicit false are otherwise identical. This follows the existing
ExecutionCleanup.Enabled precedent and covers both loaders: yaml.v3 via an
UnmarshalYAML hook on NodeHealthConfig, and viper -- which decodes through
mapstructure and never calls that hook -- via IsSet in
MarkExecutionCleanupEnabledIfSet. ApplyDefaults runs before
ApplyEnvOverrides in all three load paths, so applyBoolEnv gets the last
word and its existing warn-and-keep behaviour makes a garbage value fall
back to true for free.
The grace wiring moves into configureAgentRestartSettings so the startup behaviour is testable without booting a server.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
EXECUTE.md enumerated the polling response's exact field list, so it went stale the moment the two new fields landed. Extend it, and state the semantics that are easy to get wrong: instance_id names the instance the execution was created against and is not re-stamped when a dispatch is replayed across an agent restart, so a restart-absorbed execution names the departed process even though the replacement ran the work. Re-stamping stays out of scope because that column is the reap scope key.
EXECUTION_RESTART.md notes that the reap also sweeps rows whose instance_id is empty, which is exactly why the new explicit field is what lets an operator tell that legacy case apart from a real orphan.
The k8s guide gains the replicas > 1 rationale for the new env var, and a warning not to treat instance_id as guaranteed pod attribution: only the Python SDK reports one, it is a bare uuid4().hex the SDK never logs, and the sole path from that value to a pod is the control plane's own re-registration reap log (old_instance_id / new_instance_id).
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Co-authored-by: Claude Fable 5 noreply@anthropic.com (2d7fc72)
Refs #651 (v1: offline-only; the registered/online mode stays open).
AgentMesh([a, b]) mounts every member on one FastAPI app (/{node_id})
so a single uvicorn serves them all, and resolves app.call() between
members in-process instead of round-tripping through the control plane.
Dispatch goes through the target Agent's own ASGI app — Agent already
subclasses FastAPI — so validation, the per-execution CostTracker,
workflow events, DID and trigger unwrapping all run exactly as they do
for an HTTP-routed execution. The ASGI scope/receive/send are built by
hand rather than through httpx.ASGITransport, because httpx is not a
declared runtime dependency of the SDK; the mesh adds no new dependency.
Three hazards the implementation is built around:
to_headers() emits X-Execution-ID, and the reasoner endpoint turns
that header plus a non-empty agentfield_server into a fire-and-forget
202. agentfield_server defaults to http://localhost:8080 even with
AGENTFIELD_SERVER unset, so the header is popped unconditionally —
otherwise every mesh call would return {"status": "processing"}._execute_reasoner_endpoint ends in _clear_current().
The dispatch therefore runs in a child context (asyncio.create_task),
which keeps the caller's agent/execution contextvars intact, and
snapshots/restores the Agent._current_agent CLASS attribute that a
child context cannot protect.Agent.call mapping
ladder (extracted verbatim into _map_call_args), so mesh and
control-plane paths bind identically — including the arg_0 degradation
for a cross-node positional call. A mesh-only improvement here would be
a dev/prod trap.Agent.call_local() ships the same in-process dispatch as an explicit
opt-in for a bare agent (Go SDK CallLocal parity); the intentionally
DISABLED same-agent short-circuit in call() is untouched, so implicit
short-circuiting still only happens inside a mesh.
v1 is offline-only: members get auto_register=False and
AgentMesh(register=True) raises NotImplementedError rather than
registering members at a mounted path the control plane cannot route back
to. An unknown node or member raises the new MeshTargetNotFound instead
of the misleading "server unavailable" error, with no control-plane
fallthrough. With no AgentMesh constructed, call() is unchanged.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Behaviour-level tests for every item of the AgentMesh contract, written
against the public surface (app.call, call_local, AgentMesh, the
mounted app over TestClient) rather than mesh internals.
The regression guards worth calling out:
test_mesh_does_not_forward_execution_id_header pins the 202
fire-and-forget trap: it captures the headers actually handed to the
ASGI app and asserts x-execution-id is gone while x-run-id and
x-parent-execution-id survive.test_mesh_nested_a_b_a_current_agent_at_each_hop walks a->b->a and
asserts both the contextvar and Agent.get_current() report the right
agent at every hop and after the outermost call returns.test_mesh_positional_binding_matches_control_plane asserts the mesh
and control-plane paths bind the same call identically, so a mesh-only
binding improvement cannot silently reintroduce the dev/prod trap.test_call_semantics_unchanged_without_mesh pins the exact existing
offline AgentFieldClientError text for an agent with no mesh.agentfield.mesh is added to the pytest --cov list because
scripts/coverage-surface.sh runs pytest with only those targets, so a new
module absent from the list produces no coverage rows and the required
patch-coverage gate cannot see it.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Adds docs/agent-mesh.md and a short README section pointing at it.
Every limitation listed is one verified against the code rather than
assumed: mesh calls carry no DID signature (so a member with
local_verification=True would 401 its own traffic), the connection
manager and memory-event client never connect because the mesh does not
run AgentServer.serve()'s resilient startup lifecycle, child executions
land at depth 0 because to_headers() never emits depth and from_request()
never reads it, and both Agent.get_current() and the set_current_agent
contextvar are last-writer-wins with several agents in one process —
which is why the mesh resolves targets from its own registry and never
from the ambient one.
The error-mapping table is part of the contract: unknown node or member raises MeshTargetNotFound, a validation failure raises ExecuteError(status_code=422) exactly as the control-plane path does, and a reasoner exception becomes ExecutionFailedError with the original exception as cause.
No new environment variable is introduced, so docs/ENVIRONMENT_VARIABLES.md is untouched.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Co-authored-by: Claude Fable 5 noreply@anthropic.com (164fb7a)
The per-agent concurrency limit and the LLM circuit breaker were checked before persistence only on the async lane. On the sync, restart and MCP lanes the check ran after prepare had already written an executions row, a workflow_executions row and an input payload blob, so a gate-rejected request was charged a failed execution for work that was never attempted.
There is now a single admission point, ahead of persistence, on all four lanes: prepareExecutionForTargetWithAdmission takes acquireSlot=true from the sync handler, the restart handler and the MCP start_run path, and the duplicate post-prepare gate blocks are gone. findReplayHit moves ahead of the gate so a replay hit — which never dials the agent — is never rejected by it and consumes no slot; the async lane no longer acquires and releases a slot for one. preparedExecution.slotHeld records whether a plan actually owns a slot, so every release site releases exactly what it took.
Two other holes in the rejection contract close with it:
Retry-After is completed at the same time: writeExecutionError takes the value stamped on the error, else a per-category default, so llm_unavailable advertises the circuit breaker's remaining recovery window (default 30s, floor 1s) via the new LLMHealthMonitor.RetryAfterSeconds — circuitOpenedAt is unexported, so the window has to be computed inside services — while concurrency_limit and node_unavailable stay at 1 and non-retryable rejections (413, agent_pending_approval) still carry nothing.
The stale reservation comment above pool.reserve() is corrected: the worker releases the reservation when its job returns, not on dequeue, so a reservation covers preparation, queue wait and the whole dispatch.
Both gate halves are opt-in and off by default (AGENTFIELD_MAX_CONCURRENT_PER_AGENT=0, llm_health.enabled=false), so a stock deployment sees no behaviour change.
Refs #986
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
One test per observable behaviour of the new admission point, written from the caller's side (HTTP status, headers, body, and what the store holds afterwards) rather than from the implementation:
Two existing fixtures build a preparedExecution by hand after acquiring a slot themselves; they now set slotHeld so the job still releases what they took. TestPrepareExecution_AdditionalCoverage pins the process-global limiter to nil, because prepareExecution now acquires a slot and its four direct calls would otherwise leak counts into unrelated tests.
Refs #986
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
README advertised "a durable PostgreSQL queue with lease-based processing, so a crash or a restart resumes where it left off". No such thing exists: the lease columns in migrations 011 and 013 are inert plumbing, and there is no acquisition, renewal or expiry-reclaim code anywhere in the tree. What the control plane actually does is admit work into a bounded in-process queue with backpressure (429/503 plus Retry-After) and, on graceful shutdown, terminate in-flight executions with status_reason control_plane_shutdown instead of silently dropping them. Both README claims now say that.
Alongside it:
Refs #986
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
The restart handler can still lose the race between reserve() and submitReserved when the pool stops in between. That branch is the one that used to answer concurrency_limit while writing status_reason internal_error, because the queue error was an untyped errors.New. Drive it through the same CreateExecutionRecord seam the async pool-stopped test uses and assert the persisted status_reason equals the error_category in the body, that Retry-After and retry_after are both present, and that the per-agent slot is released.
Refs #986
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
The restart and MCP submit-failure paths persisted the terminal state with the request context — during shutdown that context is likely already cancelled, stranding the freshly created rows in running (the same bug class #1001 fixed on the async lane). MCP also discarded the persistence error entirely. All three lanes now share one helper: detached bounded persistence context, failed/control_plane_shutdown on both tables, and a warn log carrying node_id and execution_id when persistence itself fails.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
fix(control-plane): balance admission ownership through shutdown
fix(control-plane): preserve replay input envelopes
Co-authored-by: Claude Fable 5 noreply@anthropic.com (2638b9e)
Your coding agent can read these notes before it upgrades. Set up the MCP server →