mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-08 12:00:36 +00:00
* fix(todos): keep an unusable stored todo list from failing every model call
`todos` is a reducer channel that `POST /threads/{id}/state` and run input can
Overwrite directly, but neither boundary validated its shape. The todo
middleware rendered it with `entry.get(...)` in both `before_model` and
`after_model`, so a non-object entry — or a value that is not a list — raised
AttributeError on every model call, permanently for that thread.
Validate caller-written todos beside `goal` in `_normalize_external_todos`: a
list of objects with string content and a known status, or HTTP 400. The
middleware now reads the channel through `_usable_todos` and ignores entries of
any other stored shape, so checkpoints and direct integrations written before
this boundary still run.
* fix(todos): normalize stored todos in token-usage attribution
TokenUsageMiddleware reads the same stored `todos` channel through
`_build_attribution` whenever the last AIMessage calls write_todos, and
`token_usage.enabled` defaults on, so a value the todo middleware now tolerates
still aborted the step here. Route the stored list through `_normalize_todos`
before reading entries.
Document that a caller-written todo without a status is accepted as pending and
cover that shape at both external boundaries.
* docs: keep backend agent guidance within size budgets
* fix(todos): keep the channel metadata strip on caller-written todos
The dedicated todos branch in strip_server_owned_state_metadata replaced the
generic list branch, which stripped server-owned metadata from every entry. A
caller could therefore persist additional_kwargs.original_user_content,
untrusted_input, or artifact.knowledge_sources on a todo entry. Re-apply the
per-entry strip after normalization, keeping None and empty lists untouched.
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>