Skip to content

feat(setup): add session end lifecycle for OpenCode, Gemini, and Codex#527

Open
daniel-baf wants to merge 1 commit into
Gentleman-Programming:mainfrom
daniel-baf:feat/session-end-lifecycle
Open

feat(setup): add session end lifecycle for OpenCode, Gemini, and Codex#527
daniel-baf wants to merge 1 commit into
Gentleman-Programming:mainfrom
daniel-baf:feat/session-end-lifecycle

Conversation

@daniel-baf

@daniel-baf daniel-baf commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Closes #48

PR Type

  • type:bug — Bug fix
  • type:feature — New feature
  • type:docs — Documentation only
  • type:refactor — Code refactoring (no behavior change)
  • type:chore — Maintenance, dependencies, tooling
  • type:breaking-change — Breaking change

Summary

  • Adds session-ending lifecycle support for OpenCode, Gemini CLI, and Codex.
  • Standardizes ending the session (ended_at is set) by calling the POST /sessions/{id}/end API endpoint.
  • For OpenCode: Calls the end-session endpoint inside the session.deleted event handler.
  • For Gemini CLI (and other agents using the setup Markdown): Instructs them to call mem_session_end at the end of a session.
  • For Codex: Instructs it to call mem_session_end at the end of a session.

Changes

File Change
plugin/opencode/engram.ts Send POST /sessions/{id}/end on session.deleted
internal/setup/plugins/opencode/engram.ts Sync setup copy of OpenCode plugin
internal/setup/setup.go Update memoryProtocolMarkdown instructions with mem_session_end
plugin/codex/skills/memory/SKILL.md Update close protocol instruction with mem_session_end

Test Plan

  • Unit tests pass locally: go test ./...
  • E2E tests pass locally: go test -tags e2e ./internal/server/...
  • Manually tested the affected functionality (verified via unit/E2E tests)

Contributor Checklist

  • I linked an approved issue above (Closes #48)
  • I added exactly one type:* label to this PR
  • I ran unit tests locally
  • I ran e2e tests locally
  • Docs updated (instructions updated)
  • Commits follow conventional commits format
  • No Co-Authored-By trailers in commits

Summary by CodeRabbit

  • Bug Fixes

    • Sessions now send explicit end-of-session notifications to the backend upon deletion, ensuring proper cleanup and accurate session tracking.
  • Documentation

    • Updated session close protocol to document the new session-end notification step.

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

On session.deleted events, both copies of engram.ts now POST to /sessions/{sessionId}/end on the Engram server before clearing local tracking state. The session-close protocol instructions in setup.go and plugin/codex/skills/memory/SKILL.md are updated to require agents to call mem_session_end as an explicit step.

Changes

Session End Lifecycle

Layer / File(s) Summary
POST /sessions/{id}/end on session.deleted
internal/setup/plugins/opencode/engram.ts, plugin/opencode/engram.ts
Both copies of the engram plugin now call engramFetch to POST /sessions/{encodedSessionId}/end before removing the session from in-memory tracking maps (toolCounts, knownSessions, subAgentSessions, lastNudgeTime).
mem_session_end added to session-close protocol instructions
internal/setup/setup.go, plugin/codex/skills/memory/SKILL.md
The embedded memoryProtocolMarkdown in setup.go and the Codex SKILL.md both add an explicit step requiring agents to call mem_session_end following mem_session_summary in the SESSION CLOSE PROTOCOL.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • Gentleman-Programming/engram#514: Implements the same POST /sessions/{sessionId}/end pattern for Claude Code via a session-stop.sh hook, establishing the endpoint convention that this PR now applies to OpenCode and MCP agents.
  • Gentleman-Programming/engram#516: Modifies the same session.deleted handler in plugin/opencode/engram.ts, adding lastNudgeTime cleanup — directly adjacent to the state cleanup block this PR now precedes with the end-session call.

Suggested labels

type:feature

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding session end lifecycle support for three agents (OpenCode, Gemini, and Codex), which directly aligns with the PR objectives and linked issue #48.
Linked Issues check ✅ Passed The PR fully implements all objectives from issue #48: OpenCode adds POST /sessions/{id}/end on session deletion, Gemini CLI and Codex are instructed to call mem_session_end via system protocol, establishing consistent session lifecycle tracking across all three agents.
Out of Scope Changes check ✅ Passed All code changes directly address the session-end lifecycle objectives for OpenCode, Gemini, and Codex specified in issue #48; no unrelated or out-of-scope modifications are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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: 2

🤖 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 `@internal/setup/setup.go`:
- Line 200: The instruction at line 200 that reads "Call mem_session_end" is
incomplete and does not specify the required parameters. Update this instruction
to clarify that mem_session_end requires an explicit id parameter (the session
identifier to close) and optionally accepts a summary parameter describing the
work completed. The updated instruction should read "Call mem_session_end with
the active session id and an optional summary of work completed" to provide
clear guidance on the parameters needed.

In `@plugin/opencode/engram.ts`:
- Around line 319-321: The `engramFetch` call to POST
`/sessions/{sessionId}/end` is being made for all deleted sessions, including
sub-agent sessions that were never actually created since `ensureSession`
early-exits for those. Add a condition before the `engramFetch` call that skips
the POST request for sub-agent sessions or sessions that were never persisted,
checking whether the session is a sub-agent session type or verifying that the
session was actually persisted before attempting to call the end endpoint.
🪄 Autofix (Beta)

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: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0c98b8f8-f108-4b94-939c-4a304934ae99

📥 Commits

Reviewing files that changed from the base of the PR and between 44faeee and c745112.

📒 Files selected for processing (4)
  • internal/setup/plugins/opencode/engram.ts
  • internal/setup/setup.go
  • plugin/codex/skills/memory/SKILL.md
  • plugin/opencode/engram.ts

Comment thread internal/setup/setup.go
- path/to/file — [what it does or what changed]

This is NOT optional. If you skip this, the next session starts blind.
2. Call mem_session_end.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Inspect tool definitions/usage for mem_session_end parameter requirements
rg -n -C4 'mem_session_end' 

# 2) Check whether wrappers auto-inject session id before tool dispatch
rg -n -C5 'activeSessionId|sessionId|params.id|callMemoryTool|executeMemoryTool'

# 3) Locate server-side /sessions/{id}/end handler contract (body requirements, validation)
rg -n -C5 '/sessions/.*/end|session.*end' --type go --type ts

Repository: Gentleman-Programming/engram

Length of output: 50385


Clarify mem_session_end requires explicit session identifier and optional summary.

At line 200, "Call mem_session_end" is incomplete. The tool requires an explicit id parameter (the session identifier to close) and optionally accepts a summary describing what was accomplished. Update the instruction to read: "Call mem_session_end with the active session id and an optional summary of work completed."

🤖 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 `@internal/setup/setup.go` at line 200, The instruction at line 200 that reads
"Call mem_session_end" is incomplete and does not specify the required
parameters. Update this instruction to clarify that mem_session_end requires an
explicit id parameter (the session identifier to close) and optionally accepts a
summary parameter describing the work completed. The updated instruction should
read "Call mem_session_end with the active session id and an optional summary of
work completed" to provide clear guidance on the parameters needed.

Comment thread plugin/opencode/engram.ts
Comment on lines +319 to +321
await engramFetch(`/sessions/${encodeURIComponent(sessionId)}/end`, {
method: "POST",
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Skip /end for sub-agent sessions that were never persisted.

At Line 319, the handler posts /sessions/{id}/end for every deleted session, but sub-agent sessions are intentionally not created (ensureSession early-exits for subAgentSessions). This introduces avoidable network calls/noisy failures on Task-heavy runs.

Suggested patch
         const info = (event.properties as any)?.info
         const sessionId = info?.id
         if (sessionId) {
-          await engramFetch(`/sessions/${encodeURIComponent(sessionId)}/end`, {
-            method: "POST",
-          })
+          if (!subAgentSessions.has(sessionId)) {
+            await engramFetch(`/sessions/${encodeURIComponent(sessionId)}/end`, {
+              method: "POST",
+            })
+          }
           toolCounts.delete(sessionId)
           knownSessions.delete(sessionId)
           subAgentSessions.delete(sessionId)
           lastNudgeTime.delete(sessionId)
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await engramFetch(`/sessions/${encodeURIComponent(sessionId)}/end`, {
method: "POST",
})
if (!subAgentSessions.has(sessionId)) {
await engramFetch(`/sessions/${encodeURIComponent(sessionId)}/end`, {
method: "POST",
})
}
🤖 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 `@plugin/opencode/engram.ts` around lines 319 - 321, The `engramFetch` call to
POST `/sessions/{sessionId}/end` is being made for all deleted sessions,
including sub-agent sessions that were never actually created since
`ensureSession` early-exits for those. Add a condition before the `engramFetch`
call that skips the POST request for sub-agent sessions or sessions that were
never persisted, checking whether the session is a sub-agent session type or
verifying that the session was actually persisted before attempting to call the
end endpoint.

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.

Session end lifecycle missing for OpenCode, Gemini CLI, and Codex

1 participant