Skip to content

Commit 2e70aab

Browse files
committed
fix(chat): fix mcpcnf id & checking thread existence when working with subresources
1 parent 3bc8fec commit 2e70aab

File tree

12 files changed

+2261
-10
lines changed

12 files changed

+2261
-10
lines changed

src/askui/chat/api/mcp_configs/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class McpConfig(McpConfigBase, Resource):
4040
@classmethod
4141
def create(cls, params: McpConfigCreateParams) -> "McpConfig":
4242
return cls(
43-
id=generate_time_ordered_id("mcp_config"),
43+
id=generate_time_ordered_id("mcpcnf"),
4444
created_at=now(),
4545
**params.model_dump(),
4646
)

src/askui/chat/api/messages/router.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from askui.chat.api.messages.models import Message, MessageCreateParams
66
from askui.chat.api.messages.service import MessageService
77
from askui.chat.api.models import MessageId, ThreadId
8+
from askui.chat.api.threads.dependencies import ThreadFacadeDep
9+
from askui.chat.api.threads.facade import ThreadFacade
810
from askui.utils.api_utils import ListQuery, ListResponse
911

1012
router = APIRouter(prefix="/threads/{thread_id}/messages", tags=["messages"])
@@ -14,18 +16,18 @@
1416
def list_messages(
1517
thread_id: ThreadId,
1618
query: ListQuery = ListQueryDep,
17-
message_service: MessageService = MessageServiceDep,
19+
thread_facade: ThreadFacade = ThreadFacadeDep,
1820
) -> ListResponse[Message]:
19-
return message_service.list_(thread_id, query=query)
21+
return thread_facade.list_messages(thread_id, query=query)
2022

2123

2224
@router.post("", status_code=status.HTTP_201_CREATED)
2325
async def create_message(
2426
thread_id: ThreadId,
2527
params: MessageCreateParams,
26-
message_service: MessageService = MessageServiceDep,
28+
thread_facade: ThreadFacade = ThreadFacadeDep,
2729
) -> Message:
28-
return message_service.create(thread_id=thread_id, params=params)
30+
return thread_facade.create_message(thread_id=thread_id, params=params)
2931

3032

3133
@router.get("/{message_id}")

src/askui/chat/api/runs/router.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from askui.chat.api.dependencies import ListQueryDep
99
from askui.chat.api.models import RunId, ThreadId
1010
from askui.chat.api.runs.models import RunCreateParams
11+
from askui.chat.api.threads.dependencies import ThreadFacadeDep
12+
from askui.chat.api.threads.facade import ThreadFacade
1113
from askui.utils.api_utils import ListQuery, ListResponse
1214

1315
from .dependencies import RunServiceDep
@@ -22,10 +24,10 @@ async def create_run(
2224
thread_id: Annotated[ThreadId, Path(...)],
2325
params: RunCreateParams,
2426
background_tasks: BackgroundTasks,
25-
run_service: RunService = RunServiceDep,
27+
thread_facade: ThreadFacade = ThreadFacadeDep,
2628
) -> Response:
2729
stream = params.stream
28-
run, async_generator = await run_service.create(thread_id, params)
30+
run, async_generator = await thread_facade.create_run(thread_id, params)
2931
if stream:
3032

3133
async def sse_event_stream() -> AsyncGenerator[str, None]:
@@ -64,9 +66,9 @@ def retrieve_run(
6466
def list_runs(
6567
thread_id: Annotated[ThreadId, Path(...)],
6668
query: ListQuery = ListQueryDep,
67-
run_service: RunService = RunServiceDep,
69+
thread_facade: ThreadFacade = ThreadFacadeDep,
6870
) -> ListResponse[Run]:
69-
return run_service.list_(thread_id, query=query)
71+
return thread_facade.list_runs(thread_id, query=query)
7072

7173

7274
@router.post("/{run_id}/cancel")

src/askui/chat/api/threads/dependencies.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from askui.chat.api.messages.service import MessageService
88
from askui.chat.api.runs.dependencies import RunServiceDep
99
from askui.chat.api.runs.service import RunService
10+
from askui.chat.api.threads.facade import ThreadFacade
1011
from askui.chat.api.threads.service import ThreadService
1112

1213

@@ -24,3 +25,18 @@ def get_thread_service(
2425

2526

2627
ThreadServiceDep = Depends(get_thread_service)
28+
29+
30+
def get_thread_facade(
31+
thread_service: ThreadService = ThreadServiceDep,
32+
message_service: MessageService = MessageServiceDep,
33+
run_service: RunService = RunServiceDep,
34+
) -> ThreadFacade:
35+
return ThreadFacade(
36+
thread_service=thread_service,
37+
message_service=message_service,
38+
run_service=run_service,
39+
)
40+
41+
42+
ThreadFacadeDep = Depends(get_thread_facade)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from collections.abc import AsyncGenerator
2+
3+
from askui.chat.api.messages.models import Message, MessageCreateParams
4+
from askui.chat.api.messages.service import MessageService
5+
from askui.chat.api.models import ThreadId
6+
from askui.chat.api.runs.models import Run, RunCreateParams
7+
from askui.chat.api.runs.runner.events.events import Events
8+
from askui.chat.api.runs.service import RunService
9+
from askui.chat.api.threads.service import ThreadService
10+
from askui.utils.api_utils import ListQuery, ListResponse
11+
12+
13+
class ThreadFacade:
14+
"""
15+
Facade service that coordinates operations across threads, messages, and runs.
16+
"""
17+
18+
def __init__(
19+
self,
20+
thread_service: ThreadService,
21+
message_service: MessageService,
22+
run_service: RunService,
23+
) -> None:
24+
self._thread_service = thread_service
25+
self._message_service = message_service
26+
self._run_service = run_service
27+
28+
def _ensure_thread_exists(self, thread_id: ThreadId) -> None:
29+
"""Validate that a thread exists before allowing operations on it."""
30+
self._thread_service.retrieve(thread_id)
31+
32+
def create_message(
33+
self, thread_id: ThreadId, params: MessageCreateParams
34+
) -> Message:
35+
"""Create a message, ensuring the thread exists first."""
36+
self._ensure_thread_exists(thread_id)
37+
return self._message_service.create(thread_id, params)
38+
39+
async def create_run(
40+
self, thread_id: ThreadId, params: RunCreateParams
41+
) -> tuple[Run, AsyncGenerator[Events, None]]:
42+
"""Create a run, ensuring the thread exists first."""
43+
self._ensure_thread_exists(thread_id)
44+
return await self._run_service.create(thread_id, params)
45+
46+
def list_messages(
47+
self, thread_id: ThreadId, query: ListQuery
48+
) -> ListResponse[Message]:
49+
"""List messages, ensuring the thread exists first."""
50+
self._ensure_thread_exists(thread_id)
51+
return self._message_service.list_(thread_id, query)
52+
53+
def list_runs(self, thread_id: ThreadId, query: ListQuery) -> ListResponse[Run]:
54+
"""List runs, ensuring the thread exists first."""
55+
self._ensure_thread_exists(thread_id)
56+
return self._run_service.list_(thread_id, query)

0 commit comments

Comments
 (0)