mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-28 22:20:35 +00:00
docs: list the summarize event tag and scope the extension example's claims (#6582)
* docs: list the summarize event tag and scope the extension example's claims RUN_EVENT_STREAM.md listed seven middleware tags, but the catalog and the run event stream contract carry eight; `summarize` is emitted by SummarizationMiddleware for every successful summary result. Add the tag, describe the event, and pin the documented list to MIDDLEWARE_EVENT_TAGS so the next tag cannot drift silently. summarization.md now lists all eight `changes` fields of that event. The extension example said it showed all five (README, pyproject, module docstrings, test name) or every contribution kind, while ExtensionRegistry has eight. Say it demonstrates five, name the three it does not, point to the observers guide and the bookmarks plugin, and assert in the example's test that the two observer kinds stay unregistered. * docs(changelog): reference #6582 * docs: clarify extension example package layout scope --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
parent
be44c36b2b
commit
d3887531e9
10
CHANGELOG.md
10
CHANGELOG.md
@ -4423,6 +4423,15 @@ This release closes that milestone with **439 merged pull requests**.
|
||||
changes, and a generic `extension-api` hook plus an extension when existing
|
||||
contribution points cannot express the feature. ([#6178])
|
||||
|
||||
- **docs:** Bring the run-event and extension-example docs back in line with
|
||||
the code. `backend/docs/RUN_EVENT_STREAM.md` now lists the `summarize`
|
||||
middleware tag that the catalog and contract already carried, describes the
|
||||
`middleware:summarize` event, and a test pins the documented tag list to
|
||||
`MIDDLEWARE_EVENT_TAGS`; `backend/docs/summarization.md` lists the event's
|
||||
three missing `changes` fields. The extension example no longer claims to
|
||||
cover every contribution kind: it shows five of the eight, and its README
|
||||
points to the observers guide and the bookmarks plugin for the rest. ([#6582])
|
||||
|
||||
### Internal
|
||||
|
||||
- **persistence:** Add historical regression coverage for the run-change clock repair
|
||||
@ -9407,3 +9416,4 @@ with **180 merged pull requests** since the first 2.0 milestone tag.
|
||||
[#6537]: https://github.com/bytedance/deer-flow/pull/6537
|
||||
[#6543]: https://github.com/bytedance/deer-flow/pull/6543
|
||||
[#6556]: https://github.com/bytedance/deer-flow/pull/6556
|
||||
[#6582]: https://github.com/bytedance/deer-flow/pull/6582
|
||||
|
||||
@ -3453,6 +3453,13 @@
|
||||
时,为 `extension-api` 增加通用钩子并以扩展实现,而不是把业务逻辑硬编码
|
||||
进核心。([#6178])
|
||||
|
||||
- **文档:** 让运行事件与扩展示例文档重新与代码一致。
|
||||
`backend/docs/RUN_EVENT_STREAM.md` 现在列出目录与契约中早已存在的
|
||||
`summarize` 中间件标签并说明 `middleware:summarize` 事件,并新增测试将文档中
|
||||
的标签列表固定为 `MIDDLEWARE_EVENT_TAGS`;`backend/docs/summarization.md`
|
||||
补充该事件缺失的三个 `changes` 字段。扩展示例不再声称覆盖全部贡献类型:
|
||||
它演示八种中的五种,README 为其余类型指向观察者指南和 bookmarks 插件示例。([#6582])
|
||||
|
||||
### 内部改进
|
||||
|
||||
- **测试:** 为 run-change 时钟修复及其回滚补充历史回归覆盖。从已
|
||||
@ -7596,3 +7603,4 @@ DeerFlow 2.0 是围绕"超级智能体"框架的彻底重写,核心包含子
|
||||
[#6520]: https://github.com/bytedance/deer-flow/pull/6520
|
||||
[#6537]: https://github.com/bytedance/deer-flow/pull/6537
|
||||
[#6556]: https://github.com/bytedance/deer-flow/pull/6556
|
||||
[#6582]: https://github.com/bytedance/deer-flow/pull/6582
|
||||
|
||||
@ -86,7 +86,7 @@ through run-event or specialized APIs:
|
||||
|
||||
Current middleware tags are `guardrail`, `loop_detection`,
|
||||
`safety_termination`, `skill_activation`, `skill_secrets`, `tool_promotion`,
|
||||
and `tool_progress`. The pattern is intentionally open so new middleware tags
|
||||
`tool_progress`, and `summarize`. The pattern is intentionally open so new middleware tags
|
||||
are additive. Because the full event type is limited to 32 characters and
|
||||
`middleware:` uses 11, a tag must contain 1-21 characters.
|
||||
|
||||
@ -134,6 +134,14 @@ no names emit no event. Queries, routing keywords, catalog hashes, tool schemas
|
||||
and descriptions, arguments, and results are not copied into this middleware
|
||||
event. Other event types retain their existing payload contracts.
|
||||
|
||||
`middleware:summarize` records each successful summary result from
|
||||
`SummarizationMiddleware` with `action` `summary_result`, including results
|
||||
reused from the no-op cache. The `changes` object carries the no-op and
|
||||
cache-skip flags, summary and previous-summary lengths, the number of
|
||||
summarized messages, and the middleware's cumulative counters; see
|
||||
[summarization.md](summarization.md). Summary text and message content are
|
||||
never copied into this event.
|
||||
|
||||
Ordinary task-tool subagents forward loop-detection, tool-promotion, and
|
||||
tool-progress appends to the parent run loop through dedicated recorder context
|
||||
keys. The loop-bound `RunJournal` itself never enters the isolated subagent
|
||||
|
||||
@ -30,6 +30,9 @@ Each successful summary result emits a `middleware:summarize` journal event with
|
||||
|
||||
- `noop`: the result is byte-identical to the previous summary.
|
||||
- `llm_call_skipped`: this result came from the no-op cache.
|
||||
- `summary_chars`: length of the new summary.
|
||||
- `previous_summary_chars`: length of the previous summary, or `null` when there was none.
|
||||
- `summarized_message_count`: messages folded into this summary.
|
||||
- `call_count`: completed summary results, including cache reuse and canned results.
|
||||
- `noop_count`: completed results identical to the previous summary.
|
||||
- `skip_count`: completed results reused from the no-op cache.
|
||||
|
||||
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import ast
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from uuid import uuid4
|
||||
|
||||
@ -33,6 +34,7 @@ from deerflow.subagents.step_events import SUBAGENT_STEP_MAX_CHARS, capture_step
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
CONTRACT_PATH = REPO_ROOT / "contracts" / "run_event_stream_contract.json"
|
||||
DOC_PATH = REPO_ROOT / "backend" / "docs" / "RUN_EVENT_STREAM.md"
|
||||
|
||||
|
||||
def _load_contract() -> dict:
|
||||
@ -369,6 +371,14 @@ def test_dynamic_middleware_event_rejects_tags_that_do_not_fit_persistence(tag):
|
||||
)
|
||||
|
||||
|
||||
def test_documented_middleware_tags_match_the_catalog():
|
||||
doc = DOC_PATH.read_text(encoding="utf-8")
|
||||
sentence = re.search(r"Current middleware tags are (.+?)\.", doc, re.DOTALL)
|
||||
|
||||
assert sentence is not None
|
||||
assert set(re.findall(r"`([^`]+)`", sentence.group(1))) == set(MIDDLEWARE_EVENT_TAGS)
|
||||
|
||||
|
||||
def test_tool_promotion_tag_is_declared_and_fits_the_persisted_event_type():
|
||||
pattern = _load_contract()["dynamic_event_patterns"][0]
|
||||
|
||||
|
||||
@ -1,9 +1,16 @@
|
||||
# DeerFlow extension example
|
||||
|
||||
This directory is a compact, standalone Python package showing all five DeerFlow
|
||||
extension contribution kinds. It depends on the public
|
||||
This directory is a compact, standalone Python package showing five of the
|
||||
eight DeerFlow extension contribution kinds: middleware, task lifecycle,
|
||||
system-model observer, service, and router. It depends on the public
|
||||
`deerflow-extension-api` contract and never imports `deerflow.*` or `app.*`.
|
||||
|
||||
It does not register an agent-assembly observer, a context-compaction observer,
|
||||
or a full-stack plugin. The observers are covered in the
|
||||
[Lifecycle and Observers](../../frontend/src/content/en/harness/extensions/observers.mdx)
|
||||
guide, and [`deerflow-extension-bookmarks`](../deerflow-extension-bookmarks/)
|
||||
shows a plugin.
|
||||
|
||||
The contract package intentionally has no framework dependencies. An extension
|
||||
must therefore declare every framework it imports itself; this example explicitly
|
||||
depends on FastAPI, LangChain, and LangGraph in `pyproject.toml`.
|
||||
@ -184,7 +191,7 @@ name or the `module:install` value.
|
||||
```text
|
||||
deerflow_extension_example/
|
||||
├── __init__.py # version-stamped install() entry point
|
||||
└── plugin.py # state plus all five small contribution implementations
|
||||
└── plugin.py # state plus the five demonstrated contribution implementations
|
||||
tests/
|
||||
├── test_entry_point.py
|
||||
├── test_plugin.py
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
"""A compact, standalone DeerFlow extension exercising every contribution kind."""
|
||||
"""A compact, standalone DeerFlow extension exercising five contribution kinds."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@ -20,7 +20,7 @@ __all__ = ["install"]
|
||||
|
||||
@extension(api="0.2.0", name="example")
|
||||
def install(registry: ExtensionRegistry, config: Mapping[str, Any]) -> None:
|
||||
"""Register one example of each supported contribution kind."""
|
||||
"""Register one middleware, task lifecycle, system-model observer, service, and router."""
|
||||
if config.get("enabled", True) is False:
|
||||
return
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "deerflow-extension-example"
|
||||
version = "0.1.0"
|
||||
description = "A compact standalone example covering every DeerFlow extension contribution kind"
|
||||
description = "A compact standalone example covering five DeerFlow extension contribution kinds"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
|
||||
@ -70,7 +70,7 @@ class FakeToolRequest:
|
||||
runtime: FakeRuntime
|
||||
|
||||
|
||||
def test_install_registers_all_five_contribution_kinds() -> None:
|
||||
def test_install_registers_the_five_demonstrated_contribution_kinds() -> None:
|
||||
registry = FakeRegistry()
|
||||
|
||||
install(registry, {})
|
||||
@ -81,6 +81,9 @@ def test_install_registers_all_five_contribution_kinds() -> None:
|
||||
assert len(registry.system_model_observers) == 1
|
||||
assert len(registry.services) == 1
|
||||
assert len(registry.contributed_routers) == 1
|
||||
# The README names these as not demonstrated here.
|
||||
assert registry.agent_assembly_observers == []
|
||||
assert registry.context_compaction_observers == []
|
||||
assert [route.path for route in registry.contributed_routers[0].routes] == ["/api/extension-example/stats"]
|
||||
assert install.__deerflow_api__ == "0.2.0"
|
||||
assert install.__deerflow_name__ == "example"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user