Skip to content

Commit 58ccb81

Browse files
ethan6188jacoblee93vtrivedy
authored andcommitted
fix(acp): support agent-client-protocol v0.9.0 schema changes (langchain-ai#2700)
Fixes langchain-ai#2678 `agent-client-protocol` v0.9.0 upgraded the ACP schema from v0.10.8 to v0.11.2 ([agentclientprotocol/python-sdk#80](agentclientprotocol/python-sdk#80)), which removed the `SessionConfigOption` wrapper type. Config options are now bare `SessionConfigOptionSelect` / `SessionConfigOptionBoolean` instances. Since `deepagents-acp` pins `agent-client-protocol>=0.8.0` with no upper bound, new installs resolve to v0.9.0 and hit `ImportError: cannot import name 'SessionConfigOption' from 'acp.schema'` at startup. Uses a conditional import to support both v0.8.x (with `SessionConfigOption` wrapper) and v0.9.0+ (without wrapper). When the wrapper is available, config options are constructed as `SessionConfigOption(root=SessionConfigOptionSelect(...))`; when absent, they are bare `SessionConfigOptionSelect(...)` instances. All 76 existing ACP tests pass. ``` $ pytest tests/ -v ======================== 76 passed, 1 warning in 3.31s ========================= ``` > This contribution was developed with AI assistance (Cursor). --------- Co-authored-by: shengyi <shengyi.tang@shopee.com> Co-authored-by: Jacob Lee <jacoblee93@gmail.com> Co-authored-by: Vivek Trivedy <vivek.trivedy@langchain.dev>
1 parent 4888e78 commit 58ccb81

1 file changed

Lines changed: 34 additions & 25 deletions

File tree

libs/acp/deepagents_acp/server.py

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
PlanEntry,
4040
PromptCapabilities,
4141
ResourceContentBlock,
42-
SessionConfigOption,
4342
SessionConfigOptionSelect,
4443
SessionConfigSelectOption,
4544
SessionModeState,
@@ -49,6 +48,13 @@
4948
ToolCallUpdate,
5049
ToolKind,
5150
)
51+
52+
try:
53+
from acp.schema import SessionConfigOption
54+
except ImportError:
55+
# agent-client-protocol >=0.9.0 removed the SessionConfigOption wrapper;
56+
# config options are now bare SessionConfigOptionSelect instances.
57+
SessionConfigOption = None # type: ignore[assignment,misc]
5258
from deepagents import create_deep_agent
5359
from deepagents.backends import CompositeBackend, FilesystemBackend, StateBackend
5460
from langgraph.checkpoint.memory import MemorySaver
@@ -136,14 +142,17 @@ def on_connect(self, conn: Client) -> None:
136142
"""Store the client connection for sending session updates."""
137143
self._conn = conn
138144

139-
def _build_config_options(self, session_id: str) -> list[SessionConfigOption]:
145+
def _build_config_options(
146+
self,
147+
session_id: str,
148+
) -> list[SessionConfigOptionSelect]:
140149
"""Build the list of session configuration options.
141150
142151
Returns a list combining mode and model selectors if available.
143152
Modes are mapped to config options with category='mode'.
144153
Models are exposed as config options with category='model'.
145154
"""
146-
config_options: list[SessionConfigOption] = []
155+
config_options: list[SessionConfigOptionSelect] = []
147156

148157
# Add mode selector if modes are configured
149158
if self._modes is not None:
@@ -157,18 +166,18 @@ def _build_config_options(self, session_id: str) -> list[SessionConfigOption]:
157166
for mode in self._modes.available_modes
158167
]
159168

160-
mode_config = SessionConfigOption(
161-
root=SessionConfigOptionSelect(
162-
id="mode",
163-
name="Session Mode",
164-
description="Controls how the agent requests permission",
165-
category="mode",
166-
type="select",
167-
current_value=current_mode,
168-
options=mode_options,
169-
)
169+
mode_select = SessionConfigOptionSelect(
170+
id="mode",
171+
name="Session Mode",
172+
description="Controls how the agent requests permission",
173+
category="mode",
174+
type="select",
175+
current_value=current_mode,
176+
options=mode_options,
177+
)
178+
config_options.append(
179+
SessionConfigOption(root=mode_select) if SessionConfigOption else mode_select,
170180
)
171-
config_options.append(mode_config)
172181

173182
# Add model selector if models are configured
174183
if self._models is not None and len(self._models) > 0:
@@ -182,18 +191,18 @@ def _build_config_options(self, session_id: str) -> list[SessionConfigOption]:
182191
for model in self._models
183192
]
184193

185-
model_config = SessionConfigOption(
186-
root=SessionConfigOptionSelect(
187-
id="model",
188-
name="Model",
189-
description="The LLM model to use for this session",
190-
category="model",
191-
type="select",
192-
current_value=current_model,
193-
options=model_options,
194-
)
194+
model_select = SessionConfigOptionSelect(
195+
id="model",
196+
name="Model",
197+
description="The LLM model to use for this session",
198+
category="model",
199+
type="select",
200+
current_value=current_model,
201+
options=model_options,
202+
)
203+
config_options.append(
204+
SessionConfigOption(root=model_select) if SessionConfigOption else model_select,
195205
)
196-
config_options.append(model_config)
197206

198207
return config_options
199208

0 commit comments

Comments
 (0)