Skip to content

Commit 2d1f912

Browse files
support Smart lifecycle aliases and schema unions
1 parent 0003910 commit 2d1f912

4 files changed

Lines changed: 28 additions & 9 deletions

File tree

integrations/prime_agent/src/engraphis_prime_agent/agent.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,10 @@ async def _dispatch_session_lifecycle(
378378
the server's session state.
379379
"""
380380
action = args.get("action", "start")
381+
action = {
382+
"start_session": "start",
383+
"end_session": "end",
384+
}.get(action, action)
381385
if action not in {"start", "end"}:
382386
raise EngraphisMcpToolError(
383387
"engraphis_session action must be 'start' or 'end'."

integrations/prime_agent/src/engraphis_prime_agent/tools.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -357,15 +357,15 @@ def _coerce_type(value: Any, declared: Any) -> bool:
357357
declared = [declared]
358358
# bool is a subclass of int in Python; reject it where the schema
359359
# says "integer" / "number" so a stray `True` is not silently accepted.
360-
for t in declared:
361-
py = _TYPE_RANK.get(t)
362-
if py is None:
363-
continue
364-
if t in ("integer", "number") and isinstance(value, bool):
365-
return False
366-
if not isinstance(value, py):
367-
return False
368-
return True
360+
for t in declared:
361+
py = _TYPE_RANK.get(t)
362+
if py is None:
363+
continue
364+
if t in ("integer", "number") and isinstance(value, bool):
365+
continue
366+
if isinstance(value, py):
367+
return True
368+
return False
369369

370370

371371
def _validate_schema(schema: dict[str, Any], value: Any, path: str = "") -> list[str]:

integrations/prime_agent/tests/test_fleet.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,15 @@ async def test_lifecycle_rejects_unknown_action(fleet) -> None:
227227
await fleet["researcher"].call("engraphis_session", {"action": "resume"})
228228

229229

230+
@pytest.mark.asyncio
231+
async def test_lifecycle_accepts_compatibility_action_aliases(fleet) -> None:
232+
agent = fleet["researcher"]
233+
await agent.call("engraphis_session", {"action": "start_session"})
234+
assert agent.session_id is not None
235+
await agent.call("engraphis_session", {"action": "end_session"})
236+
assert agent.session_id is None
237+
238+
230239
@pytest.mark.asyncio
231240
async def test_lifecycle_rejects_non_boolean_force_new(fleet) -> None:
232241
with pytest.raises(EngraphisMcpToolError, match="force_new must be a boolean"):

integrations/prime_agent/tests/test_tools.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
all_tools,
1111
apply_scope_defaults,
1212
build_tool,
13+
validate_args,
1314
)
1415

1516

@@ -57,6 +58,11 @@ def test_session_agent_is_optional_for_registered_lifecycle_calls() -> None:
5758
assert "agent" not in schema["required"]
5859

5960

61+
def test_nullable_schema_types_accept_each_union_member() -> None:
62+
assert validate_args("engraphis_session", {"repo": "api"})["repo"] == "api"
63+
assert validate_args("engraphis_session", {"repo": None})["repo"] is None
64+
65+
6066
def test_build_tool_unknown_name_raises() -> None:
6167
config = EngraphisRuntimeConfig(command="x")
6268
client = EngraphisMcpClient(config)

0 commit comments

Comments
 (0)