feat(palace): add ActivityEvent sink on PalaceBuilder (jcode shape) (mp-migration 5/8)#23
Merged
Merged
Conversation
jcode's `MemoryEventSink = Arc<dyn Fn(ServerEvent) + Send + Sync>`
is the per-call activity stream that drives the TUI info widget's
`MemoryActivity` snapshot. The snapshot has 4 pipeline states
(search → verify → inject → maintain) and 24 event kinds; jcode
publishes transitions at every meaningful point.
mempalace has no equivalent on the public API today. The closest
is the internal `background.rs` `tracing::info!()` calls, which
aren't visible to library consumers and don't carry a typed
shape.
Add:
- `pub struct ActivityEvent { state, detail, timestamp }`
- `pub enum ActivityState { Idle, Embedding, SidecarChecking,
FoundRelevant, Extracting,
Maintaining, ToolAction { action } }`
- `PalaceBuilder::activity_sink(sink)` builder method
- `Palace::activity_sink` pub field
- `Palace::emit_activity(state, detail)` private helper that
no-ops when no sink is set
This PR is the **API shape** for activity streaming; it does NOT
yet wire the emit calls into the `impl MemoryProvider for Palace`
methods (that's a follow-up that touches `add_drawer`,
`forget`, `search`, `extract_from_transcript`, and the
`background.rs` consolidation/lesson-decay loops).
The jcode adapter can already use the API as-is to bridge its
`MemoryEventSink` — it will receive no events until the
follow-up lands, but the type and registration path are stable.
This is PR 5/8 in the jcode → mempalace Mode C library migration
series (the runtime-wiring half; PRs 1+2+3+4+6+7+8 are the trait-
method/field/type half).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add the API shape for activity streaming — the type, the builder method, and the storage slot. The jcode adapter can already register a sink; emit-calls from the runtime are scoped to a follow-up.
Motivation
Required for the jcode → mempalace Mode C library migration (mp-migration 5/8). jcode's
MemoryEventSink = Arc<dyn Fn(ServerEvent) + Send + Sync>drives the TUI info widget'sMemoryActivitysnapshot, which has 4 pipeline states (search → verify → inject → maintain) and 24 event kinds. jcode publishes transitions at every meaningful point and the TUI reads them to render the "memory is searching…" / "found 3 relevant" / "extracting from session…" indicators.mempalace has the same internal concept (in
background.rsviatracing::info!) but it's:This PR ships the type and the registration path. The emit-calls from the
impl MemoryProvider for Palacemethods (add_drawer,forget,search,extract_from_transcript, and thebackground.rsconsolidation/lesson-decay loops) are scoped to a follow-up because they touch more lines.This is PR 5/8 in the migration series. Independent of the trait-method PRs (1/2/4) — type and builder only.
Change
crates/core/src/palace.rs:pub struct ActivityEvent+pub enum ActivityState(~50 lines, includes the 6 state variants)Palace::activity_sink: Option<Arc<dyn Fn(ActivityEvent) + Send + Sync>>fieldPalace::emit_activity(state, detail)private helper that no-ops when no sink is setcrates/core/src/palace/builder.rs:PalaceBuilder::activity_sink: Option<Arc<dyn Fn(super::ActivityEvent) + Send + Sync>>fieldPalaceBuilder::activity_sink(sink)builder method (~15 lines)Palaceatopen()timeTotal: 93 lines added across 2 files.
Out of scope (deliberate follow-ups)
Palace::emit_activity(Embedding, …)at the start ofsearchandsearch_with_embedding.Palace::emit_activity(FoundRelevant { count }, …)after a non-empty result.Palace::emit_activity(ToolAction { action }, …)from the trait mutation methods (PR Fix real-run CLI flows and formatting issues #1 + fix: bug fixes to Rust core #2) where applicable.Palace::emit_activity(Extracting, …)fromextract_from_transcript.Palace::emit_activity(Maintaining, …)frombackground.rs::run_consolidationandrun_lesson_decay.These are individual
self.emit_activity(...)calls at the right pipeline points; each is a 1-3 line change. Tracking them as separate PRs keeps this one focused on the API surface.Test plan
cargo test -p mempalace-core --lib→ 1127 passed, 0 failed (228s)cargo check -p mempalace-corecleancargo fmt --check -p mempalace-corecleanSeries status
🤖 Generated with Claude Code