Skip to content

Feat/rfc 0027 acp subagent zed - #45

Closed
Leoyzen wants to merge 10 commits into
feat/session-pool-architecturefrom
feat/rfc-0027-acp-subagent-zed
Closed

Feat/rfc 0027 acp subagent zed#45
Leoyzen wants to merge 10 commits into
feat/session-pool-architecturefrom
feat/rfc-0027-acp-subagent-zed

Conversation

@Leoyzen

@Leoyzen Leoyzen commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

Leoyzen added 10 commits June 1, 2026 11:04
- SpawnSessionStart in zed mode now generates a NEW tool_call_id
  instead of reusing the PydanticAI-native tool_call_id
- This creates a distinct tool call bearing _meta.subagent_session_info
- Zed can recognize this as a subagent and load the child session
- Original PydanticAI tool call remains untouched

Related Zed-side change: dynamic subagent loading via EntryUpdated
…e providers

- Reverted accidental deletion of get_skills() from ResourceProvider base class
  which broke 18 callers across agent_routes, command_registry, aggregating, etc.
- Restored missing return skill in LocalResourceProvider.get_skill()

Fixes: serve-acp config loading error "Failed to import class"
…fications)

Reverted 50 files that contained:
- ruff auto-fix (import sorting, line length, TYPE_CHECKING moves)
- Exception type changes in tools/base.py (ValueError -> TypeError)
- Import removals in provider_router.py
- Various formatting and style changes

Kept only RFC-0027 core files:
- acp_server/ event_converter, session, session_manager, server, acp_agent
- pool_server config, serve_acp CLI
- Tests and snapshots
- resource_providers base.py and local.py (get_skills fix)
- Fix local.py task_ref garbage collection with _background_tasks set
- Fix zed_provider.py database connection leaks with finally blocks
- Fix event_converter.py child_session_id mismatch using returned ID
- Fix event_converter.py exception handling to catch Exception broadly
- Fix event_converter.py cleanup _subagent_message_counts and _subagent_tool_map on completion
- Fix session.py and event_converter.py _display_mode propagation
- Move RFC-0027 to implemented status
- fix(session_manager): add session.close() on initialization failure to prevent resource leaks
- feat(session_manager): allow passing explicit child_session_id to create_child_session for ID consistency
- fix(event_converter): clean up subagent state on StreamCompleteEvent fallback path to prevent memory accumulation
- fix(sessions/manager): accept optional child_session_id in create_child_session

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request implements RFC-0027 to introduce an experimental 'zed' subagent display mode, enabling compatibility with the Zed editor by tracking subagent session boundaries, message indices, and routing child subsessions. Feedback on the changes highlights a bug in the test fixtures where a missing child_session_id parameter causes snapshot tests to fall back to legacy mode, an indentation violation of PEP 8 in session.py, and an unidiomatic use of locals() for variable binding checks in session_manager.py.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +91 to +103
def _get_subagent_event(
source_name: str,
inner_event: Any,
source_type: str = "agent",
depth: int = 1,
) -> SubAgentEvent:
"""Wrap an event in a SubAgentEvent."""
return SubAgentEvent(
source_name=source_name,
source_type=source_type, # type: ignore[arg-type]
event=inner_event,
depth=depth,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The _get_subagent_event helper does not accept or forward a child_session_id parameter. Consequently, all SubAgentEvents generated by the Zed test fixtures have child_session_id set to None.

In event_converter.py, the "zed" mode match arm requires child_session_id to be truthy:

match self._display_mode:
    case "zed" if child_session_id:

Because child_session_id is missing/falsy in these test events, the converter falls back to legacy mode (_convert_subagent_legacy) for all SubAgentEvents in the snapshot tests. This means the snapshot tests are not actually testing the "zed" mode routing or parent-only fallback behavior for subagent progress/completion events, but are instead snapshotting the legacy fallback behavior.

To fix this, _get_subagent_event should accept and default child_session_id (e.g., to "child_sess_001" to match the spawn event), and pass it to SubAgentEvent.

Suggested change
def _get_subagent_event(
source_name: str,
inner_event: Any,
source_type: str = "agent",
depth: int = 1,
) -> SubAgentEvent:
"""Wrap an event in a SubAgentEvent."""
return SubAgentEvent(
source_name=source_name,
source_type=source_type, # type: ignore[arg-type]
event=inner_event,
depth=depth,
)
def _get_subagent_event(
source_name: str,
inner_event: Any,
source_type: str = "agent",
depth: int = 1,
child_session_id: str = "child_sess_001",
) -> SubAgentEvent:
"""Wrap an event in a SubAgentEvent."""
return SubAgentEvent(
source_name=source_name,
source_type=source_type,
event=inner_event,
depth=depth,
child_session_id=child_session_id,
)
References
  1. Treat the use of '# type: ignore' in protocol implementation code as a 'code smell' that may indicate a semantic mismatch, such as an incorrect message direction or incompatible schema types.

Comment on lines +763 to +766
if isinstance(self.agent, Agent) and self.get_cwd_context in self.agent.sys_prompts.prompts:
self.agent.sys_prompts.prompts.remove(
self.get_cwd_context # pyright: ignore[reportArgumentType]
) # ty: ignore[invalid-argument-type]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The indentation of the body of this combined if statement is incorrect (8 spaces instead of 4 spaces), violating PEP 8 guidelines.

Suggested change
if isinstance(self.agent, Agent) and self.get_cwd_context in self.agent.sys_prompts.prompts:
self.agent.sys_prompts.prompts.remove(
self.get_cwd_context # pyright: ignore[reportArgumentType]
) # ty: ignore[invalid-argument-type]
if isinstance(self.agent, Agent) and self.get_cwd_context in self.agent.sys_prompts.prompts:
self.agent.sys_prompts.prompts.remove(
self.get_cwd_context
)
References
  1. PEP 8: Use 4 spaces per indentation level. (link)

Comment on lines +185 to +187
if "session" in locals() and session is not None:
with contextlib.suppress(Exception):
await session.close()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using "session" in locals() to check if a variable is bound is unidiomatic in Python and relies on dynamic namespace inspection. A cleaner and more robust approach is to initialize session = None before the try block (above line 164), and then simply check if session is not None: in the except block.

Suggested change
if "session" in locals() and session is not None:
with contextlib.suppress(Exception):
await session.close()
if session is not None:
with contextlib.suppress(Exception):
await session.close()

@Million-mo

Copy link
Copy Markdown
Collaborator

状态分析

此 PR 是 #42 的旧版重复(同一功能的不同分支版本),功能已全部在主分支上实现。

具体情况

详见 #42 的分析评论。

结论

功能已被主分支完全覆盖,关闭此 PR。

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