Skip to content

Commit d2ed389

Browse files
authored
Merge pull request #47 from AI45Lab/release/v3.3.0
Release v3.3.0 — cluster-grade runtime + review hardening
2 parents 6499123 + cd991a5 commit d2ed389

56 files changed

Lines changed: 6720 additions & 425 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,96 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [3.3.0] - 2026-05-29
9+
10+
Cluster-grade runtime: everything needed for a host platform (e.g. 书安OS)
11+
to run long-lived agent sessions across many nodes — graceful shutdown,
12+
multi-tenant identity, cost governance, deterministic replay, crash-tolerant
13+
runs, and bounded in-memory state — plus an adversarial-review hardening
14+
pass. All additions are backward compatible (new methods, new optional
15+
fields, new `SessionStore` trait methods with default no-op impls).
16+
17+
### Added
18+
19+
- **Session / Agent lifecycle control.**
20+
- `AgentSession::close()` is now a full graceful stop: flips `is_closed`
21+
(further `send`/`stream` fast-fail with `CodeError::SessionClosed`),
22+
cancels the active run, all in-flight delegated subagent tasks, and
23+
pending HITL confirmations. `AgentSession::is_closed()` accessor.
24+
- Agent-side session registry: `Agent::list_sessions()`,
25+
`close_session(id)`, `close()` (also disconnects global MCP), and
26+
`is_closed()`. Sessions are tracked by `Weak` ref and pruned lazily.
27+
- Session-level `CancellationToken` parent: every run derives its token
28+
via `child_token()`, so `close()` cascades to all in-flight work.
29+
`AgentSession::session_cancel_token()` exposes it for embedders.
30+
- **Host-provided identity labels**`tenant_id`, `principal`,
31+
`agent_template_id`, `correlation_id` on `SessionOptions` (builder
32+
methods + accessors), persisted in `SessionData`, restored on resume.
33+
Framework treats them as opaque; the host drives multi-tenant
34+
aggregation / billing / tracing. Exposed on both SDKs.
35+
- **`BudgetGuard` cost/quota contract** (`budget` module) — host-supplied
36+
`check_before_llm` / `record_after_llm` / `check_before_tool`, consulted
37+
at the LLM call site. `Deny` aborts with `CodeError::BudgetExhausted`;
38+
`SoftLimit` emits an event and proceeds. SDK bridges: a Python class
39+
(`opts.budget_guard`) and Node `session.setBudgetGuard({...})`. The Node
40+
bridge fails **closed** (timeout / unreadable return → deny).
41+
- **`HostEnv` (IdGenerator + Clock) injection** (`host_env` module) —
42+
replace the default UUID + wall-clock pair for deterministic replay of a
43+
run on another node. `SequentialIdGenerator` / `FixedClock` helpers.
44+
- **Loop checkpoints + run resumption** (`loop_checkpoint` module) — the
45+
agent loop persists a `LoopCheckpoint` after each completed tool round
46+
(when a `SessionStore` is configured); `AgentSession::resume_run(run_id)`
47+
replays from the last boundary on any node sharing the store, continuing
48+
cumulative token/tool-call accounting. `SessionStore` gains
49+
`save/load/delete_loop_checkpoint`; file writes are crash-atomic.
50+
- **`SessionRetentionLimits`** (`retention` module) — optional FIFO caps on
51+
the in-memory run store (runs + per-run events), trace sink, and terminal
52+
subagent task snapshots, so long-running sessions don't grow unbounded.
53+
Exposed on both SDKs. Default is unbounded (no behavior change).
54+
- **MCP idle disconnect**`McpManager::disconnect_idle(threshold_ms)` and
55+
`Agent::disconnect_idle_mcp(...)` (both SDKs) reap quiet MCP servers
56+
(releasing FDs / background workers) while keeping their config for
57+
on-demand reconnect.
58+
- **Cluster `AgentEvent` variants**`BudgetThresholdHit`,
59+
`PassivationRequested`, `PeerInvocation`: platform-level events a host
60+
emits via `HookExecutor` so in-session code can react uniformly.
61+
- `SessionStore` now persists the subagent task tracker across
62+
save/resume (`save/load_subagent_tasks`), so a migrated session keeps a
63+
queryable history of its delegated child runs.
64+
- New errors: `CodeError::SessionClosed`, `CodeError::BudgetExhausted`.
65+
66+
### Changed
67+
68+
- `resume_run` continues cumulative metrics (`total_usage`,
69+
`tool_calls_count`) from the checkpoint instead of restarting at zero.
70+
- Run-store and subagent-tracker FIFO eviction now hold their parallel
71+
maps under a single canonical lock order, so eviction is atomic with
72+
respect to concurrent record/cancel (no transient map inconsistency).
73+
74+
### Fixed
75+
76+
- **Loop checkpoint leak**: checkpoints were written after every tool round
77+
but never deleted — unbounded disk/memory growth on every completed run.
78+
They are now removed when a run reaches a terminal state in-process; only
79+
a true crash leaves one for resume.
80+
- **`event_count` corruption**: restoring a session whose per-run event
81+
buffer had been trimmed reset the cumulative `event_count` to the trimmed
82+
length. The persisted cumulative count is now preserved.
83+
- **Node `BudgetGuard` fail-open**: a hung or slow guard silently *allowed*
84+
the LLM call (disabling enforcement). It now fails **closed** (deny) on
85+
timeout and on an unreadable return.
86+
- **MCP timestamp leak**: `touch()`-without-connect orphan timestamps are
87+
now purged by `disconnect_idle`.
88+
- Session registry dangling `Weak` entries are pruned on `Agent::close()`.
89+
90+
### Known limitations
91+
92+
- Node `BudgetGuard` callbacks **must not throw** — due to a napi-rs
93+
constraint a thrown exception aborts the host process at return-value
94+
conversion. Wrap guard logic in try/catch and return a decision. Hangs
95+
are handled safely (fail-closed timeout). The Python `BudgetGuard`
96+
catches exceptions and is unaffected.
97+
898
## [3.2.1] - 2026-05-24
999

10100
### Added

0 commit comments

Comments
 (0)