mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-12 09:12:40 +02:00
refactor(chat): stream agent events via stream_output and remove parity v2 flag
This commit is contained in:
parent
7e07092f67
commit
78f4747382
17 changed files with 76 additions and 1676 deletions
|
|
@ -85,8 +85,8 @@ class AssistantContentBuilder:
|
|||
self._current_text_idx: int = -1
|
||||
self._current_reasoning_idx: int = -1
|
||||
# ``ui_id``-keyed indexes for tool-call parts. ``ui_id`` is the
|
||||
# synthetic ``call_<run_id>`` (legacy) or the LangChain
|
||||
# ``tool_call.id`` (parity_v2) — same key the streaming layer
|
||||
# synthetic ``call_<run_id>`` (chunk fallback) or the LangChain
|
||||
# ``tool_call.id`` (indexed chunk path) — same key the streaming layer
|
||||
# threads through every ``tool-input-*`` / ``tool-output-*`` event.
|
||||
self._tool_call_idx_by_ui_id: dict[str, int] = {}
|
||||
# Live argsText accumulator (concatenated ``tool-input-delta`` chunks)
|
||||
|
|
@ -181,7 +181,7 @@ class AssistantContentBuilder:
|
|||
"""Register a tool-call card. Args are filled in by later events."""
|
||||
if not ui_id:
|
||||
return
|
||||
# Skip duplicate registration: parity_v2 may emit
|
||||
# Skip duplicate registration: the stream may emit
|
||||
# ``tool-input-start`` from both ``on_chat_model_stream``
|
||||
# (when tool_call_chunks register a name) and ``on_tool_start``
|
||||
# (the canonical path). The FE de-dupes via ``toolCallIndices``;
|
||||
|
|
@ -243,7 +243,7 @@ class AssistantContentBuilder:
|
|||
pretty-printed JSON, sets the full ``args`` dict, and backfills
|
||||
``langchainToolCallId`` if it wasn't known at ``tool-input-start`` time.
|
||||
Also creates the card if no prior ``tool-input-start`` registered it
|
||||
(legacy parity_v2-OFF / late-registration paths).
|
||||
(late-registration when no prior ``tool-input-start``).
|
||||
"""
|
||||
if not ui_id:
|
||||
return
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -5,7 +5,6 @@ from __future__ import annotations
|
|||
from collections.abc import AsyncIterator
|
||||
from typing import Any
|
||||
|
||||
from app.agents.new_chat.feature_flags import get_flags
|
||||
from app.tasks.chat.streaming.graph_stream.result import StreamingResult
|
||||
from app.tasks.chat.streaming.relay.event_relay import EventRelay
|
||||
from app.tasks.chat.streaming.relay.state import AgentEventRelayState
|
||||
|
|
@ -30,7 +29,6 @@ async def stream_output(
|
|||
initial_step_id=initial_step_id,
|
||||
initial_step_title=initial_step_title,
|
||||
initial_step_items=initial_step_items,
|
||||
parity_v2=bool(get_flags().enable_stream_parity_v2),
|
||||
)
|
||||
|
||||
astream_kwargs: dict[str, Any] = {"config": config, "version": "v2"}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ def iter_chat_model_stream_frames(
|
|||
reasoning_delta = parts["reasoning"]
|
||||
text_delta = parts["text"]
|
||||
|
||||
if state.parity_v2 and reasoning_delta:
|
||||
if reasoning_delta:
|
||||
if state.current_text_id is not None:
|
||||
yield streaming_service.format_text_end(state.current_text_id)
|
||||
if content_builder is not None:
|
||||
|
|
@ -100,7 +100,7 @@ def iter_chat_model_stream_frames(
|
|||
if content_builder is not None:
|
||||
content_builder.on_text_delta(state.current_text_id, text_delta)
|
||||
|
||||
if state.parity_v2 and parts["tool_call_chunks"]:
|
||||
if parts["tool_call_chunks"]:
|
||||
for tcc in parts["tool_call_chunks"]:
|
||||
idx = tcc.get("index")
|
||||
|
||||
|
|
|
|||
|
|
@ -77,12 +77,11 @@ def iter_tool_start_frames(
|
|||
yield emit_thinking_step_frame(**frame_kw)
|
||||
|
||||
matched_meta: dict[str, str] | None = None
|
||||
if state.parity_v2:
|
||||
taken_ui_ids = set(state.ui_tool_call_id_by_run.values())
|
||||
for meta in state.index_to_meta.values():
|
||||
if meta["name"] == tool_name and meta["ui_id"] not in taken_ui_ids:
|
||||
matched_meta = meta
|
||||
break
|
||||
taken_ui_ids = set(state.ui_tool_call_id_by_run.values())
|
||||
for meta in state.index_to_meta.values():
|
||||
if meta["name"] == tool_name and meta["ui_id"] not in taken_ui_ids:
|
||||
matched_meta = meta
|
||||
break
|
||||
|
||||
tool_call_id: str
|
||||
langchain_tool_call_id: str | None = None
|
||||
|
|
@ -97,13 +96,12 @@ def iter_tool_start_frames(
|
|||
if run_id
|
||||
else streaming_service.generate_tool_call_id()
|
||||
)
|
||||
if state.parity_v2:
|
||||
langchain_tool_call_id = match_buffered_langchain_tool_call_id(
|
||||
state.pending_tool_call_chunks,
|
||||
tool_name,
|
||||
run_id,
|
||||
state.lc_tool_call_id_by_run,
|
||||
)
|
||||
langchain_tool_call_id = match_buffered_langchain_tool_call_id(
|
||||
state.pending_tool_call_chunks,
|
||||
tool_name,
|
||||
run_id,
|
||||
state.lc_tool_call_id_by_run,
|
||||
)
|
||||
yield streaming_service.format_tool_input_start(
|
||||
tool_call_id,
|
||||
tool_name,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ class AgentEventRelayState:
|
|||
active_tool_depth: int = 0
|
||||
called_update_memory: bool = False
|
||||
current_reasoning_id: str | None = None
|
||||
parity_v2: bool = False
|
||||
pending_tool_call_chunks: list[dict[str, Any]] = field(default_factory=list)
|
||||
lc_tool_call_id_by_run: dict[str, str] = field(default_factory=dict)
|
||||
file_path_by_run: dict[str, str] = field(default_factory=dict)
|
||||
|
|
@ -39,7 +38,6 @@ class AgentEventRelayState:
|
|||
initial_step_id: str | None = None,
|
||||
initial_step_title: str = "",
|
||||
initial_step_items: list[str] | None = None,
|
||||
parity_v2: bool,
|
||||
) -> AgentEventRelayState:
|
||||
counter = 1 if initial_step_id else 0
|
||||
return cls(
|
||||
|
|
@ -47,7 +45,6 @@ class AgentEventRelayState:
|
|||
last_active_step_id=initial_step_id,
|
||||
last_active_step_title=initial_step_title,
|
||||
last_active_step_items=list(initial_step_items or []),
|
||||
parity_v2=parity_v2,
|
||||
)
|
||||
|
||||
def next_thinking_step_id(self, step_prefix: str) -> str:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue