Toggle navigation
Toggle navigation
This project
Loading...
Sign in
万朱浩
/
Venue-Ops
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
马一丁
2025-11-15 02:54:29 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
5e1fbc97cccb004271b7d8fc6cd49e29d4ef88c8
5e1fbc97
1 parent
5ef63ece
Add Comments
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
35 additions
and
0 deletions
ReportEngine/agent.py
ReportEngine/flask_interface.py
ReportEngine/nodes/chapter_generation_node.py
ReportEngine/renderers/html_renderer.py
ReportEngine/agent.py
View file @
5e1fbc9
...
...
@@ -433,6 +433,14 @@ class ReportAgent:
})
# 章节流式回调:把LLM返回的delta透传给SSE,便于前端实时渲染
def
chunk_callback
(
delta
:
str
,
meta
:
Dict
[
str
,
Any
],
section_ref
:
TemplateSection
=
section
):
"""
章节内容流式回调。
Args:
delta: LLM最新输出的增量文本。
meta: 节点回传的章节元数据,兜底时使用。
section_ref: 默认指向当前章节,保证在缺失元信息时也能定位。
"""
emit
(
'chapter_chunk'
,
{
'chapterId'
:
meta
.
get
(
'chapterId'
)
or
section_ref
.
chapter_id
,
'title'
:
meta
.
get
(
'title'
)
or
section_ref
.
title
,
...
...
ReportEngine/flask_interface.py
View file @
5e1fbc9
...
...
@@ -634,6 +634,13 @@ def stream_task(task_id: str):
last_event_id
=
None
def
event_generator
():
"""
SSE事件生成器。
- 负责注册并消费对应任务的事件队列;
- 先回放历史事件再持续监听实时事件;
- 周期性发送心跳并在任务结束后自动注销监听。
"""
queue
=
_register_stream
(
task_id
)
try
:
# 断线重连场景下,先补发历史事件,保证界面状态一致
...
...
ReportEngine/nodes/chapter_generation_node.py
View file @
5e1fbc9
...
...
@@ -34,6 +34,13 @@ class ChapterJsonParseError(ValueError):
"""章节LLM输出无法解析为合法JSON时抛出的异常,附带原始文本方便排查。"""
def
__init__
(
self
,
message
:
str
,
raw_text
:
Optional
[
str
]
=
None
):
"""
构造异常并附加原始输出,便于日志中定位。
Args:
message: 人类可读的错误描述。
raw_text: 触发异常的完整LLM输出。
"""
super
()
.
__init__
(
message
)
self
.
raw_text
=
raw_text
...
...
@@ -674,6 +681,7 @@ class ChapterGenerationNode(BaseNode):
"""
def
walk
(
node
:
Any
)
->
int
:
"""递归下钻
block
树并返回字符估算,跳过非正文类型"""
if
node
is
None
:
return
0
if
isinstance
(
node
,
list
):
...
...
@@ -891,6 +899,7 @@ class ChapterGenerationNode(BaseNode):
fragment_buffer
:
List
[
Dict
[
str
,
Any
]]
=
[]
def
flush_buffer
():
"""将当前片段缓冲写入
merged
列表,必要时合并为单段
paragraph
"""
nonlocal
fragment_buffer
if
not
fragment_buffer
:
return
...
...
ReportEngine/renderers/html_renderer.py
View file @
5e1fbc9
...
...
@@ -427,6 +427,7 @@ class HTMLRenderer:
extracted
:
List
[
Dict
[
str
,
Any
]]
=
[]
def
traverse
(
node
:
Any
)
->
None
:
"""递归遍历block树,识别text字段内潜在的嵌套block JSON"""
if
isinstance
(
node
,
dict
):
for
key
,
value
in
list
(
node
.
items
()):
if
key
==
"text"
and
isinstance
(
value
,
str
):
...
...
@@ -1087,10 +1088,20 @@ class HTMLRenderer:
return
tuple
(
normalized
)
if
normalized
else
None
def
_normalize_kpi_item
(
self
,
item
:
Any
)
->
tuple
[
str
,
str
,
str
,
str
,
str
]
|
None
:
"""
将单条KPI记录规整为可对比的签名。
参数:
item: KPI数组中的原始字典,可能缺失字段或类型混杂。
返回:
tuple | None: (label, value, unit, delta, tone) 的五元组;若输入非法则为None。
"""
if
not
isinstance
(
item
,
dict
):
return
None
def
normalize
(
value
:
Any
)
->
str
:
"""统一各类值的表现形式,便于生成稳定签名"""
if
value
is
None
:
return
""
if
isinstance
(
value
,
(
int
,
float
)):
...
...
Please
register
or
login
to post a comment