Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 26 additions & 17 deletions apps/ask-gateway/app/chat_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import asyncio
import json
import logging
import re
import uuid
from typing import Any, AsyncIterator, Callable

logger = logging.getLogger("ask-gateway.chat")

from .config import Settings
from .llm_client import LlmClientError, OpenAiLlmClient
from .mcp_client import McpClientError, McpHttpClient
Expand Down Expand Up @@ -229,6 +232,23 @@ async def _stream_agentic(
"sessionId": session_id,
},
)
# Append assistant message with tool_calls FIRST (before tool results)
messages.append(
{
"role": "assistant",
"content": collected_content or None,
"tool_calls": [
{
"id": tc["id"],
"type": "function",
"function": tc["function"],
}
for tc in collected_tool_calls
],
}
)

# Execute tools and append results
for tc in collected_tool_calls:
tool_name = tc["function"]["name"]
try:
Expand All @@ -242,6 +262,7 @@ async def _stream_agentic(
{
"name": tool_name,
"arguments": tool_args,
"call_id": tc["id"],
"requestId": request_id,
"sessionId": session_id,
},
Expand All @@ -254,6 +275,7 @@ async def _stream_agentic(
"tool_result",
{
"name": tool_name,
"call_id": tc["id"],
"ok": True,
"result": result,
"requestId": request_id,
Expand All @@ -268,21 +290,6 @@ async def _stream_agentic(
}
)

messages.append(
{
"role": "assistant",
"content": collected_content or None,
"tool_calls": [
{
"id": tc["id"],
"type": "function",
"function": tc["function"],
}
for tc in collected_tool_calls
],
}
)

yield sse_event(
"error",
{
Expand Down Expand Up @@ -318,16 +325,18 @@ async def _stream_agentic(
"requestId": request_id,
},
)
except LlmClientError:
except LlmClientError as exc:
logger.exception("LLM client error for request %s: %s", request_id, exc)
yield sse_event(
"error",
{
"code": "upstream_error",
"message": "The language model dependency failed.",
"message": f"LLM error: {exc}",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep upstream LLM details out of client-visible errors

Returning f"LLM error: {exc}" to the SSE client leaks raw provider error text; LlmClientError is raised with full OpenRouter HTTP bodies in OpenAiLlmClient (including whatever the upstream sends back), so end users can now receive internal dependency details that were previously hidden behind a generic message. This is a regression in error-surface safety and should be limited to logs while keeping the public error.message generic.

Useful? React with 👍 / 👎.

"requestId": request_id,
},
)
except Exception as exc: # pragma: no cover - defensive fallback
logger.exception("Unexpected error for request %s: %s", request_id, exc)
yield sse_event(
"error",
{"code": "unknown_error", "message": str(exc), "requestId": request_id},
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/lib/components/general/AppHeader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ dark:border-zinc-700 border-zinc-200"
{/if}
</button>

<button class="btn-circ" onclick={() => goto("/ask-ai")}>
<!-- Ask AI button disabled until feature is ready -->
<!-- <button class="btn-circ" onclick={() => goto("/ask-ai")}>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
Expand All @@ -137,7 +138,7 @@ dark:border-zinc-700 border-zinc-200"
{#if !$isMobile}
Ask AI
{/if}
</button>
</button> -->

<button class="btn-circ" onclick={handleLogout}>
<svg
Expand Down
Loading