Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions agentrun/server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
>>> from agentrun.server import AgentEvent, EventType
>>>
>>> async def invoke_agent(request: AgentRequest):
... # 发送自定义事件(如步骤开始)
... # 发送步骤开始事件
... yield AgentEvent(
... event=EventType.CUSTOM,
... data={"name": "step_started", "value": {"step": "processing"}}
... event=EventType.STEP_STARTED,
... data={"stepName": "processing"}
... )
...
... # 流式输出内容
Expand All @@ -35,8 +35,8 @@
...
... # 发送步骤结束事件
... yield AgentEvent(
... event=EventType.CUSTOM,
... data={"name": "step_finished", "value": {"step": "processing"}}
... event=EventType.STEP_FINISHED,
... data={"stepName": "processing"}
... )

Example (工具调用事件):
Expand Down
35 changes: 35 additions & 0 deletions agentrun/server/agui_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from dataclasses import dataclass, field
import json
import logging
from typing import (
Any,
AsyncIterator,
Expand All @@ -20,6 +21,8 @@
)
import uuid

logger = logging.getLogger(__name__)

if TYPE_CHECKING:
from ag_ui.core import (
Message as AguiMessage,
Expand Down Expand Up @@ -456,6 +459,8 @@ def _process_event_with_boundaries(
RunErrorEvent,
StateDeltaEvent,
StateSnapshotEvent,
StepFinishedEvent,
StepStartedEvent,
TextMessageContentEvent,
ToolCallArgsEvent,
ToolCallEndEvent,
Expand Down Expand Up @@ -767,6 +772,36 @@ def _process_event_with_boundaries(
)
return

# STEP_STARTED 事件
if event.event == EventType.STEP_STARTED:
step_name = event.data.get("stepName") or event.data.get("step_name")
if step_name:
yield self._encoder.encode(StepStartedEvent(step_name=step_name))
else:
logger.warning(
"STEP_STARTED event missing 'stepName' field, falling back to CustomEvent. "
"Provide data={'stepName': '...'} for standard AG-UI Step lifecycle events."
)
Comment on lines +781 to +784
yield self._encoder.encode(
AguiCustomEvent(name="step_started", value=event.data)
)
return

# STEP_FINISHED 事件
if event.event == EventType.STEP_FINISHED:
step_name = event.data.get("stepName") or event.data.get("step_name")
if step_name:
yield self._encoder.encode(StepFinishedEvent(step_name=step_name))
else:
logger.warning(
"STEP_FINISHED event missing 'stepName' field, falling back to CustomEvent. "
"Provide data={'stepName': '...'} for standard AG-UI Step lifecycle events."
)
Comment on lines +796 to +799
yield self._encoder.encode(
AguiCustomEvent(name="step_finished", value=event.data)
)
return

# CUSTOM 事件
if event.event == EventType.CUSTOM:
yield self._encoder.encode(
Expand Down
36 changes: 31 additions & 5 deletions agentrun/server/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ class EventType(str, Enum):
# =========================================================================
HITL = "HITL" # Human-in-the-Loop,请求人类介入

# =========================================================================
# 步骤生命周期事件
# =========================================================================
STEP_STARTED = "STEP_STARTED" # 标记命名步骤开始(如 "reasoning", "final_answer")
STEP_FINISHED = "STEP_FINISHED" # 标记命名步骤结束

# =========================================================================
# 扩展事件
# =========================================================================
Expand Down Expand Up @@ -262,10 +268,30 @@ class AgentEvent(BaseModel):
... )
>>> # 用户响应将通过下一轮对话的 messages 中的 tool message 传回

Example (步骤生命周期事件):
>>> yield AgentEvent(
... event=EventType.STEP_STARTED,
... data={"stepName": "reasoning"}
... )
>>> yield "thinking content..."
>>> yield AgentEvent(
... event=EventType.STEP_FINISHED,
... data={"stepName": "reasoning"}
... )
>>> yield AgentEvent(
... event=EventType.STEP_STARTED,
... data={"stepName": "final_answer"}
... )
>>> yield "final answer content..."
>>> yield AgentEvent(
... event=EventType.STEP_FINISHED,
... data={"stepName": "final_answer"}
... )

Example (自定义事件):
>>> yield AgentEvent(
... event=EventType.CUSTOM,
... data={"name": "step_started", "value": {"step": "thinking"}}
... data={"name": "custom_event", "value": {"key": "value"}}
... )

Example (原始协议数据):
Expand Down Expand Up @@ -315,13 +341,13 @@ class AgentRequest(BaseModel):
Example (使用事件):
>>> async def invoke_agent(request: AgentRequest):
... yield AgentEvent(
... event=EventType.CUSTOM,
... data={"name": "step_started", "value": {"step": "thinking"}}
... event=EventType.STEP_STARTED,
... data={"stepName": "thinking"}
... )
... yield "I'm thinking..."
... yield AgentEvent(
... event=EventType.CUSTOM,
... data={"name": "step_finished", "value": {"step": "thinking"}}
... event=EventType.STEP_FINISHED,
... data={"stepName": "thinking"}
... )

Example (工具调用):
Expand Down
4 changes: 4 additions & 0 deletions agentrun/server/openai_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,10 @@ async def _format_stream(
if event.event == EventType.HITL:
continue

# STEP 事件:AG-UI 特有,OpenAI 协议不支持
if event.event in (EventType.STEP_STARTED, EventType.STEP_FINISHED):
continue

# 其他事件忽略
# (ERROR, STATE, CUSTOM 等不直接映射到 OpenAI 格式)

Expand Down
10 changes: 5 additions & 5 deletions agentrun/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ class AgentRunServer:
>>> server.start(port=8000)

Example (使用事件):
>>> from agentrun.server import AgentResult, EventType
>>> from agentrun.server import AgentEvent, EventType
>>>
>>> async def invoke_agent(request: AgentRequest):
... yield AgentResult(
... yield AgentEvent(
... event=EventType.STEP_STARTED,
... data={"step_name": "thinking"}
... data={"stepName": "thinking"}
... )
... yield "I'm thinking..."
... yield AgentResult(
... yield AgentEvent(
... event=EventType.STEP_FINISHED,
... data={"step_name": "thinking"}
... data={"stepName": "thinking"}
... )
>>>
>>> server = AgentRunServer(invoke_agent=invoke_agent)
Expand Down
Loading
Loading