Skip to content

Conversation

@integrate-your-mind
Copy link
Owner

@integrate-your-mind integrate-your-mind commented Feb 3, 2026

Summary

  • reduce snapshot delta comparisons by caching serialized agents and meta
  • avoid snapshot JSON serialization when all clients use JSON protocol
  • centralize OpenCode inflight idle window logic
  • simplify agent identity formatting on client

Performance impact

  • Snapshot delta comparison now serializes each agent once per tick instead of per comparison.
  • Snapshot broadcast avoids JSON serialization unless a legacy client is connected.
  • OpenCode inflight window calculation is centralized to avoid repeated parsing.

Tradeoffs

  • Delta building now stores per-agent JSON strings in a Map for the tick, which increases transient memory but reduces repeated serialization cost.
  • Meta comparison still uses JSON stringify when references differ; retains correctness over deep equality.
  • No behavior changes in OpenCode activity detection; only refactoring and reused logic.

Testing

  • npm run build

Open with Devin

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ffb533fa0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +361 to +368
const groupKey = state.agentGroupKey.get(id);
if (groupKey && coord) {
const group = state.groups.get(groupKey);
if (group) {
group.freeStack.push(gridKeyFromWorld(coord));
}
}
state.agentGroupKey.delete(id);

Choose a reason for hiding this comment

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

P2 Badge Prune group/seen entries when agents are removed

removeAgent only drops the layout entry and agentGroupKey but never clears seenGen or groups/groupAnchors for identities that disappear. In a long‑running server with many short‑lived sessions or changing group keys, these maps will grow without bound, increasing memory use and slowing layout maintenance. Consider deleting the removed id from seenGen and removing group state/anchors when a group has no remaining agents (the previous implementation pruned inactive group anchors each tick).

Useful? React with 👍 / 👎.

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View issue and 7 additional flags in Devin Review.

Open in Devin Review

Comment on lines +354 to +369
function removeAgent(state: LayoutState, id: string): void {
const coord = state.layout.get(id);
if (coord) {
unindexAgent(id, state.spatial);
}
state.layout.delete(id);

const groupKey = state.agentGroupKey.get(id);
if (groupKey && coord) {
const group = state.groups.get(groupKey);
if (group) {
group.freeStack.push(gridKeyFromWorld(coord));
}
}
state.agentGroupKey.delete(id);
}

Choose a reason for hiding this comment

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

🟡 Memory leak: seenGen map entries not cleaned up when agents are removed

The removeAgent function in layout.ts doesn't delete the agent's entry from the seenGen map, causing unbounded memory growth over time.

Click to expand

Issue

When an agent is removed via removeAgent() at line 354-368, the function cleans up layout, spatial, and agentGroupKey, but never removes the agent's entry from seenGen.

Code flow

  1. updateLayout() adds agents to seenGen at line 404: state.seenGen.set(id, gen);
  2. When agents disappear, removeAgent() is called at line 417
  3. removeAgent() cleans up other maps but not seenGen
  4. seenGen is only cleared when agents.length === 0 (line 393) or setLayoutPositions (line 457)

Impact

Over time, as agents come and go, seenGen accumulates stale entries. In long-running sessions with many agent churn, this causes unbounded memory growth.

Expected behavior

removeAgent() should include state.seenGen.delete(id);

Recommendation: Add state.seenGen.delete(id); to the removeAgent function after line 368.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@integrate-your-mind
Copy link
Owner Author

Superseded by cherry-picked Codex tail fixes in fix/activity-state.

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.

1 participant