Skip to content

fix(amp): capture agent-end messages incrementally - #497

Merged
wey-gu merged 1 commit into
nowledge-co:mainfrom
IceCodeNew:fix/amp-incremental-session-capture
Aug 12, 2026
Merged

fix(amp): capture agent-end messages incrementally#497
wey-gu merged 1 commit into
nowledge-co:mainfrom
IceCodeNew:fix/amp-incremental-session-capture

Conversation

@IceCodeNew

@IceCodeNew IceCodeNew commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Capture automatic Amp session updates from the agent.end payload instead of querying the thread transcript.
  • Keep explicit manual saves as full-history captures.
  • Preserve the latest agent.end payload when another capture is already in flight.

This removes the expensive Plugin RPC read from the automatic agent.end path, which can stall long Amp sessions. Manual save retains its full-history contract.

Summary by CodeRabbit

  • Performance Improvements

    • Improved automatic synchronization by using messages already available from completed agent events.
    • Prevented unnecessary transcript reads during incremental message capture.
  • Bug Fixes

    • Manual saves now read the complete conversation transcript.
    • Preserved the latest message batch when synchronization is delayed or rescheduled.
    • Ensured incremental messages are saved even when synchronization is already in progress.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b2a015d4-537c-4b23-bd40-4fb2156e1dc1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The Amp plugin now passes agent.end messages into synchronization. Manual saves still read the full transcript. Automatic captures reuse supplied messages during coalescing and fall back to transcript reads when needed. Tests cover both paths.

Changes

Message-aware synchronization

Layer / File(s) Summary
Message sources and event integration
nowledge-mem-amp-plugin/src/index.ts, nowledge-mem-amp-plugin/tests/index.test.ts
Manual saves request the full transcript. agent.end passes converted event messages into synchronization. Tests record query options and include event messages.
Coalesced capture scheduling
nowledge-mem-amp-plugin/src/sync.ts, nowledge-mem-amp-plugin/tests/sync.test.ts
SessionSyncManager retains supplied message batches across pending and in-flight captures. captureThread uses supplied messages before falling back to transcript reads. Tests verify that supplied messages bypass readThreadMessages.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AgentEnd as agent.end event
  participant Sync as SessionSyncManager
  participant Capture as captureThread
  participant Threads as /threads

  AgentEnd->>Sync: scheduleSync(threadId, messages)
  Sync->>Capture: captureThread(threadId, messages)
  Capture->>Threads: write supplied messages
  Sync->>Sync: retain pending messages during coalescing
  Sync->>Capture: reschedule with pending messages
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: capturing agent.end messages incrementally.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@IceCodeNew
IceCodeNew force-pushed the fix/amp-incremental-session-capture branch from 67e50f3 to b601261 Compare August 12, 2026 06:47

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
nowledge-mem-amp-plugin/tests/sync.test.ts (1)

303-315: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Test multiple supplied batches.

This test covers one batch and verifies that the transcript reader is bypassed. It does not detect loss of an earlier agent.end batch during debounce or an in-flight capture.

Schedule two distinct batches before the next capture completes. Assert that both batches reach the persistence request in order, and that readThreadMessages is not called.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nowledge-mem-amp-plugin/tests/sync.test.ts` around lines 303 - 315, Update
the test around SessionSyncManager.scheduleSync to submit two distinct agent.end
batches before the next capture completes, then allow the capture to finish and
assert the persistence request contains both batches in order. Retain the
assertion that readThreadMessages is not called, and ensure the scenario covers
batches queued during debounce or an in-flight capture.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@nowledge-mem-amp-plugin/src/sync.ts`:
- Around line 63-64: Replace the single latest-batch pendingMessages slot and
associated debounce rescheduling in the sync flow with a FIFO queue that retains
every agent.end.messages batch, including batches received while a capture is in
flight. Drain the queue in order without allowing completion of an older capture
to cancel a newer scheduled batch, and add a regression test covering two
distinct event batches to verify neither is lost.

---

Nitpick comments:
In `@nowledge-mem-amp-plugin/tests/sync.test.ts`:
- Around line 303-315: Update the test around SessionSyncManager.scheduleSync to
submit two distinct agent.end batches before the next capture completes, then
allow the capture to finish and assert the persistence request contains both
batches in order. Retain the assertion that readThreadMessages is not called,
and ensure the scenario covers batches queued during debounce or an in-flight
capture.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b906410-9bc4-4cd0-ad2a-4478a97ae1ed

📥 Commits

Reviewing files that changed from the base of the PR and between c3ef77d and 67e50f3.

📒 Files selected for processing (4)
  • nowledge-mem-amp-plugin/src/index.ts
  • nowledge-mem-amp-plugin/src/sync.ts
  • nowledge-mem-amp-plugin/tests/index.test.ts
  • nowledge-mem-amp-plugin/tests/sync.test.ts

Comment thread nowledge-mem-amp-plugin/src/sync.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@nowledge-mem-amp-plugin/src/index.ts`:
- Around line 86-91: Update both manual save paths that invoke
SessionSyncManager.syncNow to limit the transcript to the latest 20
non-compacted messages before synchronization. Ensure the bounded, filtered
message collection is passed to syncNow while leaving automatic agent.end
capture unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b894a098-6fb5-4075-bb93-d08da0a81273

📥 Commits

Reviewing files that changed from the base of the PR and between 67e50f3 and b601261.

📒 Files selected for processing (3)
  • nowledge-mem-amp-plugin/src/index.ts
  • nowledge-mem-amp-plugin/src/sync.ts
  • nowledge-mem-amp-plugin/tests/index.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • nowledge-mem-amp-plugin/src/sync.ts
  • nowledge-mem-amp-plugin/tests/index.test.ts

Comment on lines +86 to +91
* Reads the full message transcript for an explicit manual save through the
* Amp SDK.
*
* Automatic capture uses the messages already included in the `agent.end`
* event, avoiding a Plugin RPC entirely. Manual saves retain their full-history
* contract even though that explicit operation may require a large RPC read.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

sed -n '1,230p' nowledge-mem-amp-plugin/src/index.ts
printf '\n--- related symbols ---\n'
rg -n "SessionSyncManager|thread\.messages|full: true|agent\.end|manual|save" nowledge-mem-amp-plugin -g '*.{ts,tsx,js}'

Repository: nowledge-co/community

Length of output: 33178


🏁 Script executed:

# Trace the manual-save and automatic-capture call paths without executing repository code.
rg -n -C 8 "SessionSyncManager|thread\.messages|full: true|agent\.end|manual|save" nowledge-mem-amp-plugin
printf '\n--- candidate files ---\n'
git ls-files | rg 'SessionSyncManager|amp-plugin|sync'

Repository: nowledge-co/community

Length of output: 50378


🏁 Script executed:

printf '%s\n' '--- sync capture path ---'
sed -n '123,350p' nowledge-mem-amp-plugin/src/sync.ts
printf '%s\n' '--- index integration tests ---'
sed -n '1,180p' nowledge-mem-amp-plugin/tests/index.test.ts
printf '%s\n' '--- bounded/non-compacted references ---'
rg -n -i -C 3 "20|compact|non.?comp|latest|full history|full-history" nowledge-mem-amp-plugin/src nowledge-mem-amp-plugin/tests nowledge-mem-amp-plugin/README.md nowledge-mem-amp-plugin/CHANGELOG.md

Repository: nowledge-co/community

Length of output: 46028


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path

index = Path("nowledge-mem-amp-plugin/src/index.ts").read_text()
sync = Path("nowledge-mem-amp-plugin/src/sync.ts").read_text()
tools = Path("nowledge-mem-amp-plugin/src/tools.ts").read_text()
commands = Path("nowledge-mem-amp-plugin/src/commands.ts").read_text()

checks = {
    "manual SDK read is full": 'thread.messages({ full: true })' in index,
    "manual sync reads injected transcript when no batch is supplied":
        'const rawMessages = options.messages ?? await this.ports.readThreadMessages(threadId)' in sync,
    "manual sync calls captureThread without a message batch":
        'return this.captureThread(threadId, { force: true })' in sync,
    "save-thread tool calls syncNow":
        'const result = await deps.syncManager.syncNow(threadId)' in tools,
    "save-thread command calls syncNow":
        'syncManager.syncNow(threadId)' in commands,
    "manual path applies a 20-message limit":
        '.slice(-20)' in index or '.slice(-20)' in sync or '.slice(-20)' in tools or '.slice(-20)' in commands,
    "manual path filters compacted messages":
        'compacted' in index.lower() or 'compacted' in sync.lower() or
        'compacted' in tools.lower() or 'compacted' in commands.lower(),
}
for name, value in checks.items():
    print(f"{name}: {value}")
PY

Repository: nowledge-co/community

Length of output: 490


Bound manual saves to the latest 20 non-compacted messages.

Both manual save paths call SessionSyncManager.syncNow, which reads thread.messages({ full: true }) without a message limit or compacted-message filter. Bound the transcript before synchronization to avoid unbounded Plugin RPC reads.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nowledge-mem-amp-plugin/src/index.ts` around lines 86 - 91, Update both
manual save paths that invoke SessionSyncManager.syncNow to limit the transcript
to the latest 20 non-compacted messages before synchronization. Ensure the
bounded, filtered message collection is passed to syncNow while leaving
automatic agent.end capture unchanged.

@IceCodeNew
IceCodeNew marked this pull request as draft August 12, 2026 07:02
@wey-gu
wey-gu force-pushed the fix/amp-incremental-session-capture branch from c7ffe5e to 157d753 Compare August 12, 2026 07:02
@wey-gu
wey-gu marked this pull request as ready for review August 12, 2026 07:03
@wey-gu
wey-gu merged commit 55fa2fe into nowledge-co:main Aug 12, 2026
5 checks passed
@IceCodeNew
IceCodeNew deleted the fix/amp-incremental-session-capture branch August 12, 2026 07:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants