From 159e816f36c20a42ab10d17cf6f22a9b8d3ded6f Mon Sep 17 00:00:00 2001 From: Kaiohz Date: Mon, 6 Apr 2026 07:36:46 +0200 Subject: [PATCH 1/4] feat: add CORS middleware for composable-ui frontend Allow cross-origin requests from http://localhost:8030 to enable the composable-ui frontend to interact with the API. --- src/main.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main.py b/src/main.py index 90c9c32..a6fea2e 100644 --- a/src/main.py +++ b/src/main.py @@ -4,6 +4,7 @@ from pathlib import Path from fastapi import FastAPI, Request +from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from src.application.routes.agents import router as agents_router @@ -95,6 +96,14 @@ async def lifespan(_app: FastAPI): lifespan=lifespan, ) +app.add_middleware( + CORSMiddleware, + allow_origins=["http://localhost:8030"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + app.include_router(health_router) app.include_router(threads_router) app.include_router(chat_router) From 34143930c08d58d3c1333df3c428ad4027ca48f8 Mon Sep 17 00:00:00 2001 From: Kaiohz Date: Mon, 6 Apr 2026 08:26:49 +0200 Subject: [PATCH 2/4] fix: streaming response empty due to wrong tuple unpacking stream_mode="messages-tuple" yields (chunk, metadata), not (type_str, msg). The filter msg_type == "ai" never matched because msg_type was an AIMessageChunk object. Switch to stream_mode="messages" and check chunk.type == "AIMessageChunk" instead. --- src/infrastructure/deepagent/adapter.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/infrastructure/deepagent/adapter.py b/src/infrastructure/deepagent/adapter.py index 2152f22..4155a36 100644 --- a/src/infrastructure/deepagent/adapter.py +++ b/src/infrastructure/deepagent/adapter.py @@ -110,14 +110,13 @@ async def stream(self, thread_id: str, message: str) -> AsyncIterator[str]: config = self._build_config(thread_id) logger.info("[thread=%s] Streaming agent response", thread_id) try: - async for event in self._graph.astream( + async for chunk, _metadata in self._graph.astream( {"messages": [{"role": "human", "content": message}]}, config=config, - stream_mode="messages-tuple", + stream_mode="messages", ): - msg_type, msg = event - if msg_type == "ai" and hasattr(msg, "content") and msg.content: - yield msg.content + if hasattr(chunk, "content") and chunk.content and chunk.type == "AIMessageChunk": + yield chunk.content except Exception as e: logger.exception("[thread=%s] Streaming error", thread_id) raise AgentError(f"Streaming error: {e}") from e From 46eecaf7ca55e2ccd2b9b70555a803d78efdbbec Mon Sep 17 00:00:00 2001 From: Kaiohz Date: Mon, 6 Apr 2026 09:50:31 +0200 Subject: [PATCH 3/4] chore: add .DS_Store file to repository --- .DS_Store | Bin 0 -> 8196 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..81fc130e821bfd275c599acf1c1a8397daecea33 GIT binary patch literal 8196 zcmeHM%}OId5U$qQkR=En1x4lw#NZ2zGTDQm2tI(CsL6scS$__D8`uX>5HIRsVMW*{ z*hdfrPa=5n?m^g#53pZ#H%Yb0L{H1gR)y|w(p5F}%{QHNdO}2IZhyT@G)6>4G{(^q zx<1B!Zap^SM<##<`LtCpFV|Ylc2A@Zr~;~hDxeCe0;<5jq5#%xwqnk@@4VWp0;<4& zsQ`aJ#Au9($IPMq>Og0=0Kf>t)^I$^2f)~4;xTgw56rk!pi4D=i(yKn*uO`WRQj5&G_7v6su(N& z9G}1c^6PRo^sf)}w;STwKq*5il~A`yU#X3@LN!`LYtV*d5iPcV=SNCT-+mk|RL?A@ zobxtYU52kmOTN+VH1iz+U*@_;8?=i)hcnTq$-&W*_wmW>`R%FYJ>dM3``a=kf1*R? z&${f;K5gQa%iZu@&xw@0Z_W;;gx-D5D>=U&9rCq$7ce90(0UtM@5)(0RN#QXFS%Vm z96r|ETzC=FodJ0bUqtCPwLR?4eAxXbG;9p85Ul3 z;ezLt@XET?nX5bhnG7PjSKL1$sQ;16cZ`?X7>zOUm^tJj9@q7sg-}xk-k}1+j`JAr z|10^=|KH)2DP>ha6?m%xCQ6snIYir4y-yae@-f;f8XL!D4s8m$;D-R-cm6QMag0#T VNjzo_F#^*E0aga>RDr*$z#lcA0)hYl literal 0 HcmV?d00001 From 479a0f87dd2a90f31c025014af3c25b73f0a2ae1 Mon Sep 17 00:00:00 2001 From: Kaiohz Date: Mon, 6 Apr 2026 09:53:39 +0200 Subject: [PATCH 4/4] fix: update stream tracing test for new stream_mode=messages format Mock now yields (chunk_with_type, metadata) instead of (type_str, msg) to match the stream_mode="messages" format used in the adapter. --- tests/unit/test_runner_tracing.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_runner_tracing.py b/tests/unit/test_runner_tracing.py index 8c6dd28..54b43d4 100644 --- a/tests/unit/test_runner_tracing.py +++ b/tests/unit/test_runner_tracing.py @@ -73,7 +73,8 @@ async def test_stream_with_tracing_injects_callbacks(self, mock_tracing_provider async def mock_astream(*_args, **_kwargs): mock_msg = MagicMock() mock_msg.content = "chunk" - yield ("ai", mock_msg) + mock_msg.type = "AIMessageChunk" + yield (mock_msg, {"langgraph_node": "agent"}) mock_graph.astream = mock_astream