NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Go modules · #633 by repository stars
Last release today
01 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
923 releases · first in 2025
One column per month.
Perf(executions): skip payload columns in all list and aggregate queries
All execution list, stats, and aggregate endpoints were fetching input_payload and result_payload for every row. With ~1.1 MB average payload size in pr-af, common endpoints were transferring hundreds of MB per request:
Detail endpoints (GetExecutionDetailsGlobalHandler, GetExecutionDetailsHandler) are intentionally unchanged — they legitimately need the full payload for the IO viewer tab.
Co-authored-by: Claude Sonnet 4.6 noreply@anthropic.com (b523755)
Feat(sdk-go): add harness package for CLI-based coding agent dispatch
Implements the Go equivalent of the Python SDK's harness subsystem, enabling structured output extraction from external coding agents (opencode, claude-code) via subprocess execution.
New harness/ package:
Agent integration:
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Provider fixes validated through end-to-end testing:
Add examples/go_harness_demo with structured output extraction test for both providers.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 (1M context) noreply@anthropic.com Co-authored-by: Santosh santosh@agentfield.ai (eaaed38)
Nothing published for this version
Perf(dashboard): skip fetching input/result payloads in dashboard queries
Dashboard API endpoints (summary and enhanced) call QueryExecutionRecords with limits up to 50,000 rows but never use the input_payload or result_payload columns in any of their processing functions. In deployments with large execution payloads (e.g. ~1.1 MB average per row), this caused dashboard API responses of 9-11 seconds due to fetching ~1 GB of TOAST data per request.
Add ExcludePayloads bool to ExecutionFilter. When set, the query substitutes NULL AS input_payload, NULL AS result_payload so the column count stays identical and scanExecution requires no changes. Set ExcludePayloads: true on all six dashboard QueryExecutionRecords call sites.
Co-authored-by: Claude Sonnet 4.6 noreply@anthropic.com (5558f40)
Nothing published for this version
Fix(storage): apply default idle connections when MaxIdleConns is unconfigured
The guard maxIdle < 0 never triggers for the zero-value of int (0),
so SetMaxIdleConns(0) is called — telling database/sql to keep no
idle connections. Every query opens and closes a fresh TCP connection
to Postgres, adding ~30-150 ms of overhead per request and causing
connection churn (~5 new backend PIDs/sec).
Changing to <= 0 ensures the default of 5 idle connections is applied
when the setting is omitted, matching the existing maxOpen <= 0 guard
on the line above.
Co-authored-by: Claude Opus 4.6 (1M context) noreply@anthropic.com (5b3e08c)
Revert "feat(harness): parse real cost from opencode JSON output (#269)"
This reverts commit b1a023dded6f03ea76487fa416aa077f17889429. (7377a72)
Feat(harness): parse real cost from opencode JSON output
The ClaudeCodeProvider was not passing a stderr callback to ClaudeAgentOptions, so when the claude CLI exited with code 1, the actual error message was lost. Logs only showed "Command failed with exit code 1" with no actionable details.
Now passes a stderr callback that collects output and includes it in both the error log and the RawResult.error_message field.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Avoids test assertion failures caused by unexpected 'stderr' key in the agent_options dictionary.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Use -f json flag when invoking opencode CLI and parse cost, prompt_tokens, and completion_tokens from the response. Falls back to estimate_cli_cost() for older opencode versions that don't include metrics in their JSON output.
Depends on: opencode-ai/opencode#TBD
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 (1M context) noreply@anthropic.com (b1a023d)
Fix: capture stderr from Claude Code CLI for error diagnosis
The ClaudeCodeProvider was not passing a stderr callback to ClaudeAgentOptions, so when the claude CLI exited with code 1, the actual error message was lost. Logs only showed "Command failed with exit code 1" with no actionable details.
Now passes a stderr callback that collects output and includes it in both the error log and the RawResult.error_message field.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Avoids test assertion failures caused by unexpected 'stderr' key in the agent_options dictionary.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 (1M context) noreply@anthropic.com (afcbeee)
Nothing published for this version
Fix: prevent async executions from getting stuck in running state
Two issues caused async executions to remain in "running" state forever when the reasoner failed:
SDK: asyncio.create_task() return values were not stored, making fire-and-forget tasks eligible for GC before the status callback could be delivered. Now stored in a set with auto-cleanup via done_callback. Also increased callback timeout from 10s to 30s since the shared httpx client's default is too aggressive for concurrent status updates over internal networking.
CP: stale execution reaper ran every 1h with a 30m timeout (worst case ~90min to clean up). Reduced to 5m interval with 10m timeout so stuck executions are marked as timed-out within 15 minutes.
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (950b01c)
Nothing published for this version
Fix(sdk): tune rate limiter defaults for fail-fast behavior
Reduce exponential backoff aggressiveness to prevent 2+ hour workflow runtimes when using rate-limited providers like OpenRouter. The previous defaults (20 retries, 300s max delay, 300s circuit breaker) caused cascading backoff that compounded across parallel agents.
New defaults: 5 retries, 0.5s base delay, 30s max delay, circuit breaker threshold 5 with 30s timeout. Max theoretical wait per call drops from ~100 minutes to ~2.5 minutes.
Changes:
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (486ff3d)
Nothing published for this version
Feat(sdk): surface cost_usd and usage from .ai() responses
MultimodalResponse now exposes cost_usd (estimated via litellm) and usage (token counts) extracted from litellm response objects. This enables downstream consumers like pr-af to track .ai() call costs instead of hardcoding them to zero.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (3944cb6)
Replace direct GitHub links for SWE-AF, Deep Research, MongoDB, and sec-af with tracked redirects through agentfield.ai/github/* routes to measure README-driven traffic via Umami analytics. (96cbb77)
Fix: reap stale workflow executions and use updated_at for staleness
The existing MarkStaleExecutions only covered the executions table and used started_at to detect staleness, which missed orphaned workflow executions entirely and could incorrectly timeout legitimately long-running executions. This change:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Tests run against a real database (no mocks) covering:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com Co-authored-by: Santosh santosh@agentfield.ai (56410a6)
Nothing published for this version
Fix: update estimate_cli_cost for litellm v1.80+ API
litellm removed prompt_tokens/completion_tokens kwargs from completion_cost() in v1.80. Switch to prompt/completion string params which litellm tokenizes internally.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The test was asserting token_counter calls and prompt_tokens/completion_tokens kwargs which were removed in the implementation fix. Update to match the new prompt/completion string params API.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (4583e3c)
Nothing published for this version
Feat: add token-based cost estimation for CLI harness providers
OpenCode, Gemini, and Codex providers now estimate LLM cost using litellm's pricing database, so HarnessResult.cost_usd is no longer always None for subprocess-based providers. This enables budget enforcement and cost reporting in downstream consumers like pr-af.
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (8b94345)
Fix: use status snapshot for node status endpoints to prevent flickering
GetNodeStatusHandler and BulkNodeStatusHandler were performing live HTTP health checks on every call (1s cache for active agents). With the UI polling every 3s, a single transient network failure in Railway would immediately return "offline", causing agent status to flicker. Now uses GetAgentStatusSnapshot which returns the stored status managed by the background HealthMonitor (which has proper 3-consecutive-failure debouncing and heartbeat gating). The explicit POST .../status/refresh endpoint remains available for on-demand live checks.
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (584b995)
Nothing published for this version
Fix: wire ApplyEnvOverrides into server startup
The applyEnvOverrides function (handling short env var names like AGENTFIELD_CONNECTOR_ENABLED) was never called from the actual server startup path. main.go uses Viper for config loading, but Viper's AutomaticEnv only matches keys it already knows about from config files. On Railway (no config file), ALL connector env vars were silently ignored, causing connector routes to never be registered.
Export ApplyEnvOverrides and call it after Viper unmarshal so env vars like AGENTFIELD_CONNECTOR_ENABLED, AGENTFIELD_CONNECTOR_TOKEN, and capability flags (AGENTFIELD_CONNECTOR_CAP_*) work on file-less deploys.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The connector's status handler was calling /api/v1/nodes (a regular API endpoint requiring API key auth) instead of connector-scoped routes. Added /api/v1/connector/nodes and /api/v1/connector/nodes/:id/status routes gated by status_read capability, matching the pattern used by other connector domains.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (c731519)
Fix: add config_management to connector capability env var map
The connectorCapEnvMap was missing the config_management capability, so AGENTFIELD_CONNECTOR_CAP_CONFIG_MANAGEMENT env var was silently ignored. This caused connector config routes to not be accessible when configured via environment variables (e.g. Railway deployments).
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (ff098c1)
Nothing published for this version
Fix: skip global API key check for connector routes
Connector routes have their own dedicated ConnectorTokenAuth middleware that enforces X-Connector-Token with constant-time comparison. The global APIKeyAuth middleware was incorrectly requiring the API key on these routes too, forcing connectors to know and send the CP's global API key — a credential they should never need.
This adds a prefix skip for /api/v1/connector/ in APIKeyAuth, matching the existing pattern for /health, /ui, and /api/v1/did/ routes.
Also adds comprehensive functional tests for the full connector auth chain:
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (6d969a1)
Feat: database-backed configuration storage
Add ability to store and manage configuration files in the database instead of (or in addition to) YAML files on disk. This enables remote config management via the connector/SaaS flow.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Adds POST /configs/reload endpoint that re-applies database config to the running control plane without requiring a process restart. Only active when AGENTFIELD_CONFIG_SOURCE=db is set.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The ExecutionCleanup struct was being replaced wholesale when only RetentionPeriod was set, zeroing out CleanupInterval and causing a panic (non-positive interval for NewTicker). Now merges each field individually. Also excludes connector config from DB merge since token and capabilities are security-sensitive.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com Co-authored-by: Santosh santosh@agentfield.ai (7ac9c87)
Fix(install): BSD sed compatibility and env var pipe scoping in install.sh
Replace GNU-only \s with POSIX [[:space:]]* in get_latest_prerelease_version() sed regex — \s is not recognized by macOS BSD sed, causing the version string to contain raw JSON instead of just the tag name.
Fix documented VERSION/STAGING env var patterns: VAR=val cmd1 | cmd2 scopes VAR to cmd1 only (POSIX shell behavior), so bash never sees it. Corrected to: curl ... | VERSION=X bash
Fixes #250 (96c3ae9)
Fix: allow state transitions from stopping to active/starting
When a node restarts while the control plane still considers it "stopping", heartbeats get rejected causing the node to be stuck offline. Allow stopping → active/starting transitions so nodes can recover from this state.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com (d328e60)
Nothing published for this version
Fix(sdk): catch Pydantic ValidationError in structured output parsing
Pydantic v2 ValidationError does not inherit from ValueError, so schema validation failures (e.g. missing required fields) were not caught by the retry logic. This caused LLM responses with incomplete JSON to crash the execution instead of retrying.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com (e2330d9)
Fix squished authorization table layout
Widen the grid template columns for Status, Registered, and Actions so they don't overlap. Use flexible sizing for Registered and Actions columns to accommodate varying content widths.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The fr-based columns were consuming nearly all space, squeezing Status/Registered/Actions into a tiny area. Use fixed px widths for the right 3 columns (matching the pattern used by other tables) so they get space allocated first before fr columns divide the rest.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
All three flexible columns now use 1fr instead of 2fr/1.5fr, giving equal weight and leaving more room for Status, Registered, and Actions.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (4d534b9)
Feat: External Cancel/Pause/Resume Execution (Epic #238)
Part of epic #238 — External Cancel/Pause Execution
The 'waiting' status (used by HITL approval flow) was a valid canonical status in Go code but was missing from database CHECK constraints. This would cause INSERT/UPDATE failures when executions transition to 'waiting' state.
Fixes both SQLite (local.go) and PostgreSQL (migration 027) constraints.
WorkflowNode, HoverDetailPanel, StatusSection, EnhancedWorkflowIdentity, and ExecutionHistoryList all had Record<CanonicalStatus, ...> maps missing the 'paused' entry, causing TypeScript build failures.
Match existing toolbar convention (ghost variant, h-8 w-8, title tooltips). Remove text labels and destructive variant to reduce visual weight. Add separator between execution controls and view controls. Keeps AlertDialog confirmation for cancel safety.
Restructure both detail page headers from single-row into a semantically-organized 2-row layout with proper information hierarchy, responsive behavior, and mobile support.
Row 1: status cluster + identity cluster + lifecycle controls Row 2: section navigation tabs (absorbed from separate components) + summary metrics
Use thread-safe syncBuffer for concurrent log writes from cleanup goroutine and Stop() goroutine. The bytes.Buffer is not safe for concurrent writes, causing race detector failures on CI.
feat(ui): redesign workflow DAG graph toolbar (#248)
feat(ui): redesign workflow DAG toolbar with unified GraphToolbar component
Replace scattered graph controls (layout buttons, search, center, fit view, view mode toggle, focus mode) with a single compact icon-based toolbar.
The cancel/pause/resume handlers previously checked execution state before the atomic update callback, allowing concurrent requests to slip through. Now the state check happens inside the callback where it reads the locked current value, and state-conflict errors are properly mapped to 409 Conflict instead of 500.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Abir Abbas abirabbas1998@gmail.com Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (56f7f5c)
Fix(ui): center sidebar nav icons when collapsed
Remove redundant px-2 from SidebarContent that stacked with SidebarGroup's built-in p-2, causing 32px of horizontal padding inside the 48px collapsed rail. The 32px icon buttons overflowed right, appearing right-justified instead of centered. (6c1eebb)
Nothing published for this version
Fix: include API key in note() request headers
The note() method was sending execution context headers but not the X-API-Key, causing 401 when the control plane has API key auth enabled (production). Works locally because local dev typically has no API key configured.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The test_note_sends_async_request test was failing because the agent stub's client (SimpleNamespace) lacked the _get_auth_headers method added in the note auth fix. The _send_note coroutine calls self.client._get_auth_headers(), which raised AttributeError and silently prevented the HTTP post from executing.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (087c2c6)
Revert "fix: include API key in note() request headers"
This reverts commit 94725ff34008e2fad19d778ec12470c213753168. (8091824)
Feat: add sec-af autonomous security audit to Built With examples
Adds the AI Security Auditor (sec-af) showcase to the README examples table with a custom editorial image and link to github.com/Agent-Field/sec-af.
The note() method was sending execution context headers but not the X-API-Key, causing 401 when the control plane has API key auth enabled (production). Works locally because local dev typically has no API key configured.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com (94725ff)
Nothing published for this version
Docs: add AI tool calling documentation to READMEs
Document the new native LLM tool-calling feature (PR #228) in the main README and all three SDK READMEs with examples showing auto-discovery, filtered discovery, lazy hydration, guardrails, and observability.
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (56bf930)
Nothing published for this version
Feat: native LLM tool-calling support via discover → ai → call pipeline
Add tools= parameter to app.ai() that enables automatic tool-call loops: discover available capabilities, convert to LLM tool schemas, dispatch calls via app.call(), and feed results back until the LLM produces a final response.
Python SDK:
Go SDK:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Refs: #225, #229
fix(test): update harness schema test to match #230 prompt wording change
feat: add TS SDK tool-calling parity, lazy hydration, examples, and E2E-tested fixes
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
SkillHandler receives a single SkillContext arg — input lives on ctx.input, not as a second parameter. Also fix app.run() → app.serve() to match the TS SDK's actual API. Found during E2E manual testing.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com Co-authored-by: Santosh santosh@agentfield.ai (40638d0)
Fix(harness): add concurrency limiter, stdout fallback, and stronger prompts
Root cause: unbounded concurrent opencode subprocess calls (20+) overwhelm the LLM API, causing transient failures where output files are never created.
Changes:
Validated: full SEC-AF pipeline (11 hunt strategies, 30 verified findings) completes end-to-end with 0 enricher failures, vs repeated failures before. (2947d5b)
Nothing published for this version
Fix(did): add did:web resolution to document endpoint
The GetDIDDocument handler only resolved did:key identities via the in-memory registry. did:web lookups returned "DID not found" even when the agent had a valid did:web document stored in the database.
Add did:web resolution (via didWebService) before falling back to did:key, matching the pattern already used by the ResolveDID handler and the server's serveDIDDocument method.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Gin URL-decodes path parameters, turning did:web:localhost%3A8080:agents:foo into did:web:localhost:8080:agents:foo. The database stores the canonical form with %3A, so lookups failed with "DID not found".
Add normalizeDIDWeb() helper that detects decoded port separators and re-encodes them. Applied to both ResolveDID and GetDIDDocument handlers.
Manually verified against running control plane:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (cdf4e8b)
Feat(ui): display both did:key and did:web identities
The UI previously only showed did:key identifiers, making did:web identities invisible to users who need them for JWT and external integrations.
Backend: Wire DIDWebService into UI DIDHandler and return did_web in the node DID API response.
Frontend: Show both identity types as clearly separated sections with descriptive labels — "Cryptographic Identity" (did:key) for signing/auth, and "Web Identity" (did:web) for JWT/external use. Each has its own copy button and View Document action.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Wire DIDWebService into IdentityHandlers so the DID Explorer page returns did_web alongside did:key. Remove unused Analytics import that was breaking CI builds.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (8ffdc28)
Feat(ui): improve duration display in workflow and execution tables
Closes #222
Feat(ai): retry LLM calls on malformed structured output JSON
When using schema-based structured output, LLMs occasionally return malformed JSON that fails parsing. This adds automatic retry (up to 2 retries) specifically for parse failures, avoiding unnecessary retries for network or API errors.
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (a462b3a)
Feat(harness): OpenCode support with schema retry, error preservation, and project_dir routing
Add diagnose_output_failure() that classifies validation failures into specific categories: file missing, empty, invalid JSON, or schema mismatch with field-level diff. Enhance build_followup_prompt() to include schema file references and explicit rewrite instructions for the retry loop.
Replace single-shot _handle_schema_output() with _handle_schema_with_retry() that retries up to schema_max_retries times (default 2) when JSON validation fails. Each retry:
This activates the previously dead-code build_followup_prompt() from _schema.py and adds resume_session_id support to the Claude Code provider.
Standalone script exercising the harness with 5 escalating schema levels:
Tests now pass server_url to skip auto-serve lifecycle in CI where opencode binary is not installed. Asserts updated to match --attach command structure.
opencode run --attach loses auto-approve because the serve process treats attached sessions as interactive, causing permission prompts to hang forever when the model tries to write files.
fix(harness): align opencode tests with direct run (no --attach)
fix(harness): crash-safe retry with FailureType classification
opencode run and never
called any of itCo-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Abir Abbas abirabbas1998@gmail.com Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (909038b)
Add 3-column visual 'Built With AgentField' section with premium editorial images for Autonomous Engineering Team, Deep Research Engine, and Reactive MongoDB Intelligence. Moved higher in README (after 'What is AgentField?') for better visibility. Removed old text-only Production Examples table. (b9add36)
GitHub already renders ## headings with visual separation. The 11 --- rules created double-spacing that made the README choppy. (48baf65)
Nothing published for this version
Feat(webhook): support all HITL template response formats
The webhook approval handler previously only extracted the "decision" field from template responses, causing templates that use "action" (confirm-action, rich-text-editor) or have no explicit decision field (signature-capture) to fail silently.
Changes:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The previous commit cleared ApprovalRequestID on both "approved" and "request_changes" decisions. This broke:
Fix:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (aa15d64)
Feat(harness): add .harness() method for external coding agent dispatch
Design document for .harness() feature — first-class coding agent integration. Covers architecture, provider matrix, universal file-write schema handling with 4-layer recovery, config types, and implementation phases.
Ref: #208
Closes #199
Closes #200
Closes #201
Tested: Codex 4/4 ✅, Claude Code 4/4 ✅, cross-provider ✅ OpenCode: upstream 'Session not found' bug (not our code)
Pydantic evaluates annotations at runtime via eval(), so list[str] (PEP 585) fails on Python 3.8 even with 'from future import annotations'. Use typing.List[str] instead.
Users can now install the Claude Code SDK dependency declaratively: pip install agentfield[harness] # all harness provider deps pip install agentfield[harness-claude] # just Claude Code SDK
Codex, Gemini, and OpenCode are CLI binaries — no pip packages needed.
Co-authored-by: Abir Abbas abirabbas1998@gmail.com Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (ef1fac5)
Fix: allow empty input for parameterless skills/reasoners
Remove binding:"required" constraint on Input field in ExecuteRequest and ExecuteReasonerRequest structs. Gin interprets required on maps as "must be present AND non-empty", which rejects the valid {"input":{}} payload that SDKs send for parameterless calls.
Also remove the explicit len(req.Input)==0 check in prepareExecution and add nil-input guards in the reasoner and skill handlers to match the existing pattern in execute.go.
Closes #196
test: strengthen empty-input handler coverage
fix: update empty_input_test.go for ExecuteHandler signature change
Main added an internalToken parameter to ExecuteHandler in PR #197. Update the two test call sites to pass empty string for the new param.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Abir Abbas abirabbas1998@gmail.com Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (cbdc23a)
Nothing published for this version
Docs: add human-in-the-loop approval docs to SDK READMEs
Add approval workflow documentation with code examples to all three SDK READMEs (Python, TypeScript, Go), covering the waiting state feature for pausing agent execution pending human review.
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (88f24cf)
Test(control-plane): add execution cleanup service coverage
Feat: waiting state with approval workflows, VC-based authorization, and multi-version reasoners
This commit introduces the foundation for the new VC-based authorization system that replaces API key distribution with admin-approved permissions.
Key components added:
The system enables:
Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com
Co-Authored-By: Claude noreply@anthropic.com
TestGetNodeDetailsHandler_Structure expected HTTP 400 for missing route param but Gin returns 404. TestGetNodeStatusHandler_Structure was missing a mock expectation for GetAgentStatus causing a panic.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The CI workflow change from go test ./... to go test -tags sqlite_fts5 ./...
caused previously-skipped tests to execute, revealing 15 pre-existing bugs:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Multiple SSE tests called req.Context().Done() expecting it to cancel the context, but Done() only returns a channel — it doesn't cancel anything. This caused SSE handler goroutines to block forever, leaking and eventually causing a 10-minute test timeout in CI.
Fixed all affected tests to use context.WithCancel + explicit cancel() call, matching the pattern already used by the working SSE tests.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
ts sdk and bug fix on did web
feat(examples): add permission test agents and enable VC authorization config
Add two example agents for manually testing the VC authorization system end-to-end: permission-agent-a (caller) and permission-agent-b (protected target). Enable authorization in the default config with seeded protection rules.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Fixes
fix(sdk-python): update test fakes for DID credential wiring in _register_agent_with_did
The previous commit added identity_package access and client credential wiring to _register_agent_with_did but didn't update the test fakes. _FakeDIDManager now provides a realistic identity_package and _FakeAgentFieldClient supports set_did_credentials, so the full registration path is exercised in tests.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
more improvements
6th iteration of fixes
end to end tested
feat(sdk): add Go & TS permission test agents, fix DID auth signing
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The execute() method now passes a JSON string instead of an object to axios for DID auth signing consistency. Update test assertion to match.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
manual testing updates
fix(vc-auth): fix re-approval deadlock, empty caller_agent_id, and error propagation
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
fix go missing func
address dx changes
temp
more fixes
finalized
better error prop
fix: update TS DID auth tests to match nonce-based signing format
Tests expected the old 3-header format ({timestamp}:{bodyHash}) but the implementation correctly uses 4 headers with nonce ({timestamp}:{nonce}:{bodyHash}), matching Go and Python SDKs.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Addresses code scanning alert about missing rate limiting on the authorization route handler. Adds a sliding-window rate limiter (30 requests per IP per 60s) to the local verification middleware.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Replace custom Map-based rate limiter with express-rate-limit package, which CodeQL recognizes as a proper rate limiting implementation.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
UI cleanup
pydantic formatting fix
connector changes
implemented multi agents with versioning
feat(ui): polished authorization page with unified tabs and visual standardization
Replace separate TagApprovalPage and AccessPoliciesPage with a single tabbed AuthorizationPage. Add polished authorization components:
Backend additions:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
multi versioning connector setup
add agent to agent direct checks
bugfixes on connector
QA fixes
package lock
bug fixes on permissions & versioning flow
fix: add missing DeleteAgentVersion stub and guard postgres migration for fresh DBs
Two CI failures:
linux-tests: stubStorage in server_routes_test.go was missing the DeleteAgentVersion method added to the StorageProvider interface by the multi-version work. Add the stub.
Functional Tests (postgres): migrateAgentNodesCompositePKPostgres tried to ALTER TABLE agent_nodes before GORM created it on fresh databases. The information_schema.columns query returns count=0 (not an error) when the table doesn't exist, so the function proceeded to run ALTER statements against a nonexistent table. Add an explicit table existence check matching the pattern already used by the SQLite migration path.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
add postgres testing to dev
wait flow
improvements
bugfix on reasoner path
reasoner name mismatch fix
fix skill name mismatch bug
fix: update test to include approval_expires_at column
The merge brought in a test from main that expected 42 columns in the workflow execution insert query, but the feature branch added approval_expires_at as the 43rd column. Update the test's column list and expected placeholder count to match.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Ruff lint flagged the unused import (F401). The tests use httpx_mock fixture from pytest-httpx, not httpx directly.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Python SDK:
TypeScript SDK:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
After the reasoner name fix, @agent.reasoner(name="reports_generate") registers at /reasoners/reports_generate (the explicit name), not /reasoners/generate_report (the function name).
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
add examples for waiting state
fix: resolve Gin route parameter conflict between waiting-state and tag-vc endpoints
The waiting-state feature added routes under /api/v1/agents/:node_id/... which conflicted with the existing tag-vc endpoint using :agentId as the parameter name. Gin requires consistent wildcard names for the same path segment, causing a panic on server startup.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
fix tests
fix: correct async endpoint URLs and assertion in waiting state functional tests
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.5 noreply@anthropic.com Co-authored-by: Santosh santosh@agentfield.ai (414f91c)
Nothing published for this version
Feat: VC-based authorization, sidecar management APIs, and multi-version reasoners
This commit introduces the foundation for the new VC-based authorization system that replaces API key distribution with admin-approved permissions.
Key components added:
The system enables:
Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com
Co-Authored-By: Claude noreply@anthropic.com
TestGetNodeDetailsHandler_Structure expected HTTP 400 for missing route param but Gin returns 404. TestGetNodeStatusHandler_Structure was missing a mock expectation for GetAgentStatus causing a panic.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The CI workflow change from go test ./... to go test -tags sqlite_fts5 ./...
caused previously-skipped tests to execute, revealing 15 pre-existing bugs:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Multiple SSE tests called req.Context().Done() expecting it to cancel the context, but Done() only returns a channel — it doesn't cancel anything. This caused SSE handler goroutines to block forever, leaking and eventually causing a 10-minute test timeout in CI.
Fixed all affected tests to use context.WithCancel + explicit cancel() call, matching the pattern already used by the working SSE tests.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
ts sdk and bug fix on did web
feat(examples): add permission test agents and enable VC authorization config
Add two example agents for manually testing the VC authorization system end-to-end: permission-agent-a (caller) and permission-agent-b (protected target). Enable authorization in the default config with seeded protection rules.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Fixes
fix(sdk-python): update test fakes for DID credential wiring in _register_agent_with_did
The previous commit added identity_package access and client credential wiring to _register_agent_with_did but didn't update the test fakes. _FakeDIDManager now provides a realistic identity_package and _FakeAgentFieldClient supports set_did_credentials, so the full registration path is exercised in tests.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
more improvements
6th iteration of fixes
end to end tested
feat(sdk): add Go & TS permission test agents, fix DID auth signing
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
The execute() method now passes a JSON string instead of an object to axios for DID auth signing consistency. Update test assertion to match.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
manual testing updates
fix(vc-auth): fix re-approval deadlock, empty caller_agent_id, and error propagation
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
fix go missing func
address dx changes
temp
more fixes
finalized
better error prop
fix: update TS DID auth tests to match nonce-based signing format
Tests expected the old 3-header format ({timestamp}:{bodyHash}) but the implementation correctly uses 4 headers with nonce ({timestamp}:{nonce}:{bodyHash}), matching Go and Python SDKs.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Addresses code scanning alert about missing rate limiting on the authorization route handler. Adds a sliding-window rate limiter (30 requests per IP per 60s) to the local verification middleware.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Replace custom Map-based rate limiter with express-rate-limit package, which CodeQL recognizes as a proper rate limiting implementation.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
UI cleanup
pydantic formatting fix
connector changes
implemented multi agents with versioning
feat(ui): polished authorization page with unified tabs and visual standardization
Replace separate TagApprovalPage and AccessPoliciesPage with a single tabbed AuthorizationPage. Add polished authorization components:
Backend additions:
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
multi versioning connector setup
add agent to agent direct checks
bugfixes on connector
QA fixes
package lock
bug fixes on permissions & versioning flow
fix: add missing DeleteAgentVersion stub and guard postgres migration for fresh DBs
Two CI failures:
linux-tests: stubStorage in server_routes_test.go was missing the DeleteAgentVersion method added to the StorageProvider interface by the multi-version work. Add the stub.
Functional Tests (postgres): migrateAgentNodesCompositePKPostgres tried to ALTER TABLE agent_nodes before GORM created it on fresh databases. The information_schema.columns query returns count=0 (not an error) when the table doesn't exist, so the function proceeded to run ALTER statements against a nonexistent table. Add an explicit table existence check matching the pattern already used by the SQLite migration path.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
add postgres testing to dev
docs: add changelog and env vars for connector, versioning, and authorization
Document the feat/connector release including multi-versioning, VC-based authorization, and connector subsystem in CHANGELOG.md. Add authorization and connector environment variable sections to ENVIRONMENT_VARIABLES.md.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
Co-authored-by: Claude Opus 4.5 noreply@anthropic.com Co-authored-by: Santosh santosh@agentfield.ai (917b49b)
Fix(release): add [skip ci] to version bump commit to prevent infinite loop
The release workflow pushes a version bump commit to main, which triggers another release workflow run, creating an infinite loop. Adding [skip ci] to the commit message prevents the pushed commit from triggering any workflows.
Co-authored-by: Claude Opus 4.6 noreply@anthropic.com (ff0a88f)
Your coding agent can read these notes before it upgrades. Set up the MCP server →