Skip to content

Commit a7688e5

Browse files
committed
feat: enable durable memory extraction lifecycle
1 parent 429a128 commit a7688e5

34 files changed

Lines changed: 3607 additions & 213 deletions

CHANGELOG.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,45 @@ 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+
## [Unreleased]
9+
10+
## [4.3.0] - 2026-07-04
11+
12+
### Added
13+
14+
- Sessions now resolve a default memory store even when callers do not pass one,
15+
preferring an explicit store, then a file memory directory, then configured
16+
`memory_dir`, then `<workspace>/.a3s/memory`, with an in-memory fallback and
17+
init warning if the file store cannot be created.
18+
- LLM memory extraction is enabled by default and runs behind a completed-turn
19+
significance gate instead of mechanically extracting after every input or tool
20+
result. Extraction prompts include related existing memories, including
21+
existing `supersedes` / `conflicts_with` relation metadata when available, so
22+
the model can consolidate or preserve conflicts. Streaming runs schedule gated
23+
extraction in the background after the final response event so UI completion is
24+
not blocked by the maintenance LLM call; each memory instance now also runs at
25+
most one background extraction at a time to keep maintenance calls bounded.
26+
27+
### Changed
28+
29+
- Successful tool outputs are no longer mechanically written when LLM memory
30+
extraction is enabled; failures are still stored immediately.
31+
- Recalled memory context now carries memory metadata plus concise relation
32+
annotations for `supersedes` and `conflicts_with` when present.
33+
- Memory recall now preserves query-specific search ranking when injecting
34+
memories into prompt context, so precise matches are not drowned out by generic
35+
high-importance memories. The LLM extraction parser also keeps valid extracted
36+
memories when a sibling item is malformed.
37+
- Session memory now consumes the store's canonical returned item, so store-level
38+
duplicate consolidation keeps short-term memory and emitted memory ids aligned
39+
with the durable item that actually represents the fact.
40+
- LLM memory extraction now merges near-duplicate extracted memories into the
41+
existing canonical item instead of silently discarding the improved wording,
42+
tags, importance, or provenance metadata.
43+
- Default memory stores now also perform conservative near-duplicate
44+
consolidation and conflict-safe pruning, so manually written memories and LLM
45+
extracted memories share the same canonical-item lifecycle.
46+
847
## [4.2.1] - 2026-06-23
948

1049
### Fixed

Cargo.lock

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "a3s-code-core"
3-
version = "4.2.8"
3+
version = "4.3.0"
44
edition = "2021"
55
authors = ["A3S Lab Team"]
66
license = "MIT"
@@ -14,7 +14,7 @@ path = "src/lib.rs"
1414
[dependencies]
1515
# Internal crates
1616
a3s-common = { version = "0.1.1", path = "../../common" }
17-
a3s-memory = { version = "0.1.1", path = "../../memory" }
17+
a3s-memory = { version = "0.1.2", path = "../../memory" }
1818
a3s-lane = { version = "0.4", path = "../../lane" }
1919
a3s-search = { version = "1.2.3", path = "../../search", default-features = false, features = ["lightpanda"] }
2020

core/src/agent.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ mod hook_runtime;
3939
mod llm_turn;
4040
mod loop_builder;
4141
mod loop_runtime;
42+
mod memory_extraction_runtime;
4243
mod parallel_tool_runtime;
4344
mod plan_execution;
4445
mod planning_runtime;
@@ -106,9 +107,10 @@ pub(crate) struct AgentConfig {
106107
pub max_parse_retries: u32,
107108
/// Per-tool execution timeout in milliseconds (`None` = no timeout).
108109
///
109-
/// When set, each tool execution is wrapped in `tokio::time::timeout`.
110-
/// A timeout produces an error result sent back to the LLM rather than
111-
/// crashing the session.
110+
/// This applies only after permission/HITL approval has completed. HITL
111+
/// confirmation waiting is governed by `ConfirmationPolicy` and must not
112+
/// consume this tool execution budget. A timeout produces an error result
113+
/// sent back to the LLM rather than crashing the session.
112114
pub tool_timeout_ms: Option<u64>,
113115
/// Per-model API HTTP timeout in milliseconds (`None` = no timeout).
114116
///
@@ -143,7 +145,10 @@ pub(crate) struct AgentConfig {
143145
/// Maximum context window size in tokens (used for auto-compact calculation).
144146
/// Default: 200_000.
145147
pub max_context_tokens: usize,
146-
/// Optional agent memory for auto-remember after tool execution and recall before prompts.
148+
/// Agent memory for recall and completed-turn extraction.
149+
///
150+
/// Session construction resolves a default memory store; this remains
151+
/// optional for lower-level/manual `AgentLoop` construction.
147152
pub memory: Option<Arc<crate::memory::AgentMemory>>,
148153
/// Inject a continuation message when the LLM stops calling tools before the
149154
/// task is complete. Enabled by default. Set to `false` to disable.

core/src/agent/completion_runtime.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ impl AgentLoop {
5757
.await;
5858

5959
if let Some(sid) = session_id {
60+
self.schedule_turn_memory_extraction(
61+
state,
62+
effective_prompt,
63+
&final_text,
64+
sid,
65+
event_tx,
66+
)
67+
.await;
6068
self.notify_turn_complete(sid, effective_prompt, &final_text)
6169
.await;
6270
}

0 commit comments

Comments
 (0)