Skip to content

feat(acp): implement session/fork (unstable)#1104

Open
YoungY620 wants to merge 4 commits intoacp-upgradefrom
acp-fork
Open

feat(acp): implement session/fork (unstable)#1104
YoungY620 wants to merge 4 commits intoacp-upgradefrom
acp-fork

Conversation

@YoungY620
Copy link
Collaborator

@YoungY620 YoungY620 commented Feb 11, 2026

Related Issue

N/A (internal ACP feature)

Description

Implement session/fork for the ACP unstable protocol:

  • Extract _init_session helper from new_session/_setup_session to deduplicate session initialization logic (KimiCLI creation, ACPSession registration, tool replacement)
  • Implement fork_session: finds source session, creates a new session, copies context.jsonl/wire.jsonl via shutil.copy2, then initializes via _init_session
  • Advertise fork in session_capabilities during initialize
  • Add 3 tests: fork response shape, fork-not-found error, prompt on forked session

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked the related issue, if any.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have run make gen-changelog to update the changelog.
  • I have run make gen-docs to update the user documentation.

Open with Devin

RealKai42 and others added 4 commits February 11, 2026 15:37
Extract _init_session from new_session/_setup_session to share session
initialization logic, then implement fork_session by copying source
session's context.jsonl/wire.jsonl into a new session directory.
Advertise fork capability in initialize response.
Copy link
Contributor

@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 6 additional findings in Devin Review.

Open in Devin Review

Comment on lines +268 to +285

return acp.schema.ForkSessionResponse(
session_id=new_session.id,
modes=acp.schema.SessionModeState(
available_modes=[
acp.schema.SessionMode(
id="default",
name="Default",
description="The default mode.",
),
],
current_mode_id="default",
),
models=acp.schema.SessionModelState(
available_models=_expand_llm_models(config.models),
current_model_id=model_id_conv.to_acp_model_id(),
),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 Forked session missing AvailableCommandsUpdate notification to ACP client

The fork_session method creates a new session (with a new session_id) but does not send the AvailableCommandsUpdate session update to the ACP client. In contrast, new_session at src/kimi_cli/acp/server.py:154-167 sends this update immediately after session creation so the client knows which slash commands are available.

Root Cause

When new_session creates a session, it builds the available commands list and fires an AvailableCommandsUpdate notification:

available_commands = [
    acp.schema.AvailableCommand(name=cmd.name, description=cmd.description)
    for cmd in soul_slash_registry.list_commands()
]
asyncio.create_task(
    self.conn.session_update(
        session_id=session.id,
        update=acp.schema.AvailableCommandsUpdate(
            session_update="available_commands_update",
            available_commands=available_commands,
        ),
    )
)

The fork_session method at lines 242-285 creates a brand new session with a different session_id but omits this notification entirely. The ACP client (e.g., an IDE integration) will not receive the list of available slash commands for the forked session, so features like command autocomplete won't work.

The project's own src/kimi_cli/acp/AGENTS.md states: "Both send AvailableCommandsUpdate for slash commands on session creation."

Impact: Slash command discovery/autocomplete will be missing in the forked session's client UI.

Suggested change
return acp.schema.ForkSessionResponse(
session_id=new_session.id,
modes=acp.schema.SessionModeState(
available_modes=[
acp.schema.SessionMode(
id="default",
name="Default",
description="The default mode.",
),
],
current_mode_id="default",
),
models=acp.schema.SessionModelState(
available_models=_expand_llm_models(config.models),
current_model_id=model_id_conv.to_acp_model_id(),
),
)
available_commands = [
acp.schema.AvailableCommand(name=cmd.name, description=cmd.description)
for cmd in soul_slash_registry.list_commands()
]
asyncio.create_task(
self.conn.session_update(
session_id=new_session.id,
update=acp.schema.AvailableCommandsUpdate(
session_update="available_commands_update",
available_commands=available_commands,
),
)
)
return acp.schema.ForkSessionResponse(
session_id=new_session.id,
modes=acp.schema.SessionModeState(
available_modes=[
acp.schema.SessionMode(
id="default",
name="Default",
description="The default mode.",
),
],
current_mode_id="default",
),
models=acp.schema.SessionModelState(
available_models=_expand_llm_models(config.models),
current_model_id=model_id_conv.to_acp_model_id(),
),
)
Open in Devin Review

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

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