test(mcp): build immutable lifecycle updates and replica results

This commit is contained in:
Yuneng Jiang 2026-09-08 14:22:33 -07:00
parent 1625f8e7f5
commit 42385177a3
No known key found for this signature in database
3 changed files with 22 additions and 14 deletions

View file

@ -136,14 +136,14 @@ async def update_mcp_toolset(
tool list, so a null ``toolset_name`` or ``tools`` is a no-op rather than a clear;
emptying the tool selection is an explicit ``[]``, which cannot be mistaken for a
caller that left the field out."""
data_dict: Final = data.model_dump(exclude_unset=True, exclude={"toolset_id"})
if data_dict.get("toolset_name", "") is None:
_ = data_dict.pop("toolset_name")
if data_dict.get("tools", "") is None:
_ = data_dict.pop("tools")
if "tools" in data_dict:
data_dict["tools"] = json.dumps(data_dict["tools"])
data_dict["updated_by"] = touched_by
data_dict: Final = dict( # mutable-ok: Prisma requires a plain dict for JSON query serialization
(
(field, json.dumps(value) if field == "tools" else value)
for field, value in data.model_dump(exclude_unset=True).items()
if field != "toolset_id" and (field not in ("toolset_name", "tools") or value is not None)
),
updated_by=touched_by,
)
try:
row: Final = await _toolset_table(prisma_client).update(
where={"toolset_id": data.toolset_id},

View file

@ -607,7 +607,7 @@ class ToolsetRow(BaseModel):
toolset_id: str
toolset_name: str
description: str | None = None
tools: list[ToolsetTool] = []
tools: list[ToolsetTool] = Field(default_factory=list)
class ToolsetListResponse(RootModel[list[ToolsetRow]]):

View file

@ -12,6 +12,7 @@ import time
import warnings
from collections.abc import Callable, Mapping
from dataclasses import dataclass
from functools import reduce
from datetime import datetime
from types import MappingProxyType
from typing import Final
@ -296,9 +297,14 @@ def await_everywhere[T](
"""`_last_answer` against every replica in turn, each with the full budget, so a
write counts as visible only once the last replica reflects it, and stop at the
first replica that never converges. Clock and sleep are injected."""
answers: dict[str, T] = {}
for replica, read in reads.items():
answer = _last_answer(
def read_replica(
outcome: EverywhereConverged[T] | NeverConvergedOn[T],
item: tuple[str, ReplicaRead[T]],
) -> EverywhereConverged[T] | NeverConvergedOn[T]:
if isinstance(outcome, NeverConvergedOn):
return outcome
replica, read = item
answer: Final = _last_answer(
read,
settled=settled,
timeout=timeout,
@ -309,8 +315,10 @@ def await_everywhere[T](
)
if not settled(answer):
return NeverConvergedOn(replica=replica, last=answer)
answers[replica] = answer
return EverywhereConverged(answers=MappingProxyType(answers))
return EverywhereConverged(answers=MappingProxyType({**outcome.answers, replica: answer}))
initial: Final[EverywhereConverged[T] | NeverConvergedOn[T]] = EverywhereConverged(answers=MappingProxyType({}))
return reduce(read_replica, reads.items(), initial)
def _is_not_found[R: BaseModel](result: Result[R]) -> bool: