mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-07 19:20:34 +00:00
fix(runs): trim event_types filter entries before querying (#7758)
* fix(runs): trim event_types filter entries before querying * style(runs): compute the trimmed event type once per entry Addresses the review nit on #7758: use the walrus pattern already present in this file (lines 657 and 1658) instead of stripping each entry twice. No behavior change. --------- Co-authored-by: gouyu-hou <gouyu-hou@users.noreply.github.com> Co-authored-by: gouyu-hou <213296172+gouyu-hou@users.noreply.github.com>
This commit is contained in:
parent
51f732304a
commit
830c8ff6f1
@ -1920,12 +1920,18 @@ async def list_run_events(
|
||||
user_id = await _run_scope_user_id(request, thread_id)
|
||||
event_store = get_run_event_store(request)
|
||||
if event_types:
|
||||
types = event_types.split(",")
|
||||
# Split on commas and normalise each entry: the value goes straight into
|
||||
# a SQL ``IN``, so a padded entry ("message, tool") would silently match
|
||||
# nothing and return a 200 with a truncated audit trail. Blank entries
|
||||
# carry no intent and are dropped; a filter that reduces to nothing is
|
||||
# the same as no filter, matching the empty-string case above.
|
||||
types = [name for entry in event_types.split(",") if (name := entry.strip())]
|
||||
if len(types) > MAX_EVENT_TYPE_FILTERS:
|
||||
raise HTTPException(
|
||||
status_code=422,
|
||||
detail=f"event_types accepts at most {MAX_EVENT_TYPE_FILTERS} values",
|
||||
)
|
||||
types = types or None
|
||||
else:
|
||||
types = None
|
||||
events = await event_store.list_events(
|
||||
|
||||
@ -253,3 +253,56 @@ async def test_list_run_events_bounds_event_type_filter_cardinality(count: int)
|
||||
else:
|
||||
assert await list_run_events(**kwargs) == []
|
||||
assert len(calls["event_types"]) == MAX_EVENT_TYPE_FILTERS
|
||||
|
||||
|
||||
async def _event_type_filter_reaches_store(event_types: str | None) -> object:
|
||||
"""Call the route with *event_types* and return what the store received."""
|
||||
|
||||
from app.gateway.routers.thread_runs import list_run_events
|
||||
|
||||
calls: dict = {}
|
||||
|
||||
class FakeStore:
|
||||
async def list_events(self, thread_id, run_id, *, event_types=None, task_id=None, limit=500, after_seq=None, user_id=None):
|
||||
calls["event_types"] = event_types
|
||||
return []
|
||||
|
||||
class FakeState:
|
||||
run_event_store = FakeStore()
|
||||
|
||||
class FakeApp:
|
||||
state = FakeState()
|
||||
|
||||
class FakeRequest:
|
||||
app = FakeApp()
|
||||
_deerflow_test_bypass_auth = True
|
||||
cookies: dict = {}
|
||||
|
||||
await list_run_events(
|
||||
thread_id="t1",
|
||||
run_id="r1",
|
||||
request=FakeRequest(),
|
||||
event_types=event_types,
|
||||
task_id=None,
|
||||
limit=500,
|
||||
after_seq=None,
|
||||
)
|
||||
return calls["event_types"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("raw", ["message, tool", " message ,tool ", "message,\ttool\n"])
|
||||
@pytest.mark.anyio
|
||||
async def test_event_type_filter_entries_are_trimmed_before_reaching_the_store(raw: str) -> None:
|
||||
"""A padded filter must not silently match nothing.
|
||||
|
||||
The entries are handed to a SQL ``IN``, so ``" tool"`` (leading space, the
|
||||
natural result of ``?event_types=message, tool``) matched no row and the
|
||||
endpoint returned 200 with a truncated audit trail.
|
||||
"""
|
||||
assert await _event_type_filter_reaches_store(raw) == ["message", "tool"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("raw, expected", [("message,,tool", ["message", "tool"]), (" , ", None), (",", None), ("", None)])
|
||||
@pytest.mark.anyio
|
||||
async def test_event_type_filter_drops_blank_entries(raw: str, expected) -> None:
|
||||
assert await _event_type_filter_reaches_store(raw) == expected
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user