12 KiB
@aoagents/ao-core
0.4.0
Minor Changes
-
faaddb1: Sessions whose PRs are detected as merged now auto-terminate (tmux kill + worktree remove + metadata archive) instead of lingering in the active
sessions/directory with amergedstatus.ao statusandao session lsstay clean without an external watchdog.Enabled by default. Guarded by an idleness check so in-flight agents are not killed mid-task; deferred cleanups retry on each lifecycle poll until the agent idles or a 5-minute grace window elapses.
Opt out or tune via the new top-level
lifecycleconfig inagent-orchestrator.yaml:lifecycle: autoCleanupOnMerge: false # preserve merged worktrees for inspection mergeCleanupIdleGraceMs: 300000 # grace window before forcing cleanupsessionManager.kill()now takes an optionalreason("manually_killed" | "pr_merged" | "auto_cleanup") and returnsKillResult({ cleaned, alreadyTerminated }) instead ofvoid. All existing call sites ignore the return value so this is backward-compatible in practice.Closes #1309. Part of #536.
-
331f1ce: Enrich lifecycle events with PR/issue context for webhook consumers. All events now carry
data.contextwithpr(url, title, number, branch),issueId,issueTitle,summary, andbranchwhen available, plusdata.schemaVersion: 2.Additional changes:
- Persist
issueTitlein session metadata during spawn so it survives across restarts and is available for event enrichment. - Refactor
executeReaction()to accept aSessionobject instead of separatesessionId/projectIdarguments. - Add
maybeDispatchCIFailureDetails()— when a session entersci_failed, the agent receives a follow-up message with the failed check names and URLs (deduped via fingerprint so subsequent polls don't re-send the same failure set). bugbot-commentsreaction dispatches an enriched message listing every automated comment inline, so the agent doesn't need to re-fetch viagh api.
- Persist
-
e7ad928: Allow workers to report non-terminal PR workflow events like
pr-created,draft-pr-created, andready-for-reviewwith optional PR URL/number metadata, while keeping merged and closed PR state SCM-owned.Migration:
Sessionnow carries canonical lifecycle truth insession.lifecycle
and explicit activity-evidence metadata insession.activitySignal. Third-party
callers that constructSessionobjects directly must populate those fields or
route through the core session helpers that synthesize them. -
7b82374: Add centralized lifecycle transitions and report watcher for agent monitoring.
- Lifecycle transitions (#137): Centralize all lifecycle state mutations through
applyLifecycleDecision()for consistent timestamp handling, atomic metadata persistence, and observability. - Detecting bounds (#138): Add time-based (5 min) and attempt-based (3 attempts) bounds to detecting state with evidence hashing to prevent counter reset on unchanged probe results.
- Report watcher (#140): Background trigger system that audits agent reports for anomalies (no_acknowledge, stale_report, agent_needs_input) and integrates with the reaction engine.
New exports:
applyLifecycleDecision,applyDecisionToLifecycle,buildTransitionMetadataPatch,createStateTransitionDecisionDETECTING_MAX_ATTEMPTS,DETECTING_MAX_DURATION_MS,hashEvidence,isDetectingTimedOutauditAgentReports,checkAcknowledgeTimeout,checkStaleReport,checkBlockedAgent,shouldAuditSession,getReactionKeyForTrigger,DEFAULT_REPORT_WATCHER_CONFIG,REPORT_WATCHER_METADATA_KEYS
- Lifecycle transitions (#137): Centralize all lifecycle state mutations through
-
c8af50f: Make
ProjectConfig.repooptional to support projects without a configured remote.Migration:
ProjectConfig.repois nowstring | undefinedinstead ofstring.
External plugins that accessproject.repodirectly (e.g.project.repo.split("/")) must
add a null check first. Use a guard likeif (!project.repo) return null;or a helper that
throws with a descriptive error. -
c447c7c: Improve lifecycle detection to use bounded
detectingretries when runtime, process, and activity evidence disagree, and make recovery validation escalate probe uncertainty for human review instead of treating it as cleanup-safe death.
Patch Changes
-
2306078: Add SQLite-backed activity event logging for session and lifecycle diagnostics, plus
ao eventscommands for listing, searching, and inspecting event log stats. -
f330a1e:
ao session lsandao statusnow hide terminated sessions (killed,terminated,done,merged,errored,cleanup) by default. A dim footer reports how many were hidden and how to surface them. Pass--include-terminatedto restore the previous unfiltered output.Core change:
parseCanonicalLifecycle()now preservespr.state="merged"when reconstructing legacy metadata withstatus=mergedbut nopr=URL (previously collapsed topr.state="none", which madeisTerminalSession()return false for those sessions). Also exportssessionFromMetadataso consumers can round-trip flat metadata through the canonical lifecycle.Breaking — JSON output shape:
ao session ls --jsonandao status --jsonnow emit{ data: [...], meta: { hiddenTerminatedCount: number } }instead of a bare array. Scripts consuming the JSON must read.datafor the session list.--include-terminatedrestores full data and reportshiddenTerminatedCount: 0.The existing
-a, --allflag still only governs orchestrator visibility onao session ls— it does not re-enable terminated sessions. Combine with--include-terminatedwhen you want both. -
a862327: Stop carrying forward
stuck/probe_failuresession truth when the runtime is still confirmed alive and activity is merely unavailable, and degrade that combination todetectinguntil stronger evidence arrives. -
703d584: fix(core): prevent double-billing reaction attempts on changes_requested transition
The enriched review dispatch in
maybeDispatchReviewBacklognow sends directly via
sessionManager.sendwhen the transition handler already calledexecuteReactionfor
the same reaction key. This prevents the attempt counter from incrementing twice in a
single poll cycle, which would cause premature escalation for projects withretries: 1.Also moves the review backlog throttle timestamp after the SCM fetch so a failed
getReviewThreadscall doesn't block retries for 2 minutes. -
f674422: Make project orchestrators deterministic and idempotent.
- ensure each project uses the canonical
{prefix}-orchestratorsession instead of creating numbered main orchestrators - make
ao start, the dashboard, and the orchestrator API reuse or restore the canonical session - keep legacy numbered orchestrators visible as stale sessions without treating them as the main orchestrator
- ensure each project uses the canonical
-
62353eb: Harden worker branch refresh during lifecycle polling by preserving branch metadata through transient detached Git states, skipping orchestrators and active open PRs, and preventing duplicate branch adoption within a single poll cycle.
-
bd36c7b: Keep lifecycle observability and batch diagnostic logs out of user-visible terminal stderr by routing them into AO's observability audit files instead, while preserving structured traces for debugging and regression coverage.
-
ca8c4cc: Model activity evidence explicitly across lifecycle inference and dashboard rendering so missing or failed probes cannot spuriously produce idle or stuck interpretations. This also stabilizes repeated polls by preserving stronger prior lifecycle states when the only new evidence is weak or unavailable.
-
4701122: opencode: bound /tmp blast radius and consolidate session-list cache
Addresses review feedback on PR #1478:
- TMPDIR isolation. Every
opencodechild we spawn now points at
~/.agent-orchestrator/.bun-tmp/viaTMPDIR/TMP/TEMP. Bun's
embedded shared-library extraction lands there instead of the system
/tmp, so the cli janitor only ever sweeps AO-owned files. Other
users' or other applications' Bun artifacts on a shared host can no
longer be touched by the regex. - Single shared session-list cache. Core and the agent-opencode
plugin previously kept independent caches; per poll cycle the system
spawned at least twoopencode session listprocesses instead of
one. Both consumers now use the shared cache exported from
@aoagents/ao-core(getCachedOpenCodeSessionList). - TTL no longer covers the send-confirmation loop. The cache TTL
dropped from 3s to 500ms so the
updatedAt > baselineUpdatedAtdelivery signal in
sendWithConfirmationactually fires. Concurrent callers still
share the in-flight promise. - Delete invalidates the cache.
deleteOpenCodeSessionnow calls
invalidateOpenCodeSessionListCache()on success so reuse, remap,
and restore code paths cannot observe a deleted session id within
the TTL window. - Janitor reliability.
sweepOncenow filters synchronously
before allocating per-file promises (matters on hosts with thousands
of/tmpentries), andstopBunTmpJanitor()is now async and awaits
any in-flight sweep so SIGTERM cannot exit whileunlinkis mid-flight. - Janitor observability. The sweep callback in
ao startnow logs
successful reclaims, not just errors, so operators can confirm the
janitor is doing useful work.
- TMPDIR isolation. Every
-
bcdda4b: Tighten the session lifecycle review follow-ups by debouncing report-watcher reactions, restoring the shared Geist/JetBrains font setup, wiring recovery validation to real agent activity probes, adding direct coverage for
ao report, activity-signal classification, and dashboard lifecycle audit panels, fixing the remaining lifecycle-state regressions around legacy merged-session rehydration and malformed canonical payload parsing, making agent-report metadata writes atomic, persisting canonical payloads for legacy sessions on read, stabilizing detecting evidence hashes, and removing the remaining inline-style cleanup debt from the session detail view. Follow-on fixes also split the Session Detail view into smaller components, harden PR URL parsing and wrapper capture for GitHub Enterprise and GitLab-style hosts, redact sensitive observability payload fields, bound on-disk audit logs, and align cleanup wording with the current merged-session lifecycle policy. -
1cbf657: Split orchestrator-only detail views from worker detail views, add an auditable history for
ao acknowledge/ao report, and preserve canonicalneeds_input/stucklifecycle states when polling only has weak or unchanged evidence. -
a45eb32: Decouple canonical session state from PR state so workers stay idle while waiting on reviews or merged/closed PR decisions, stop cleanup from auto-killing merged PR sessions, and make the dashboard/rendered labels follow canonical PR truth instead of inferring it from legacy lifecycle aliases.
-
7072143: Expose split session, PR, and runtime lifecycle truth in dashboard API payloads, render that truth directly in session cards and detail views, and extend lifecycle observability with structured transition evidence, reasons, and recovery context while preserving legacy metadata compatibility.
-
ed2dcea: Split worker session prompts into persistent system instructions and task-only input, materialize OpenCode worker/orchestrator instructions into session-scoped
AGENTS.md, and keep restore behavior aligned with the updated AO prompt markers.
0.2.0
Minor Changes
- 3a650b0: Zero-friction onboarding:
ao startauto-detects project, generates config, and launches dashboard — no prompts, no manual setup. Renamed npm package to@composio/ao. Made@composio/ao-webpublishable with production entry point. Cross-platform agent detection. Auto-port-finding. Permission auto-retry in shell scripts.