feat: 实现 AgentScope ReAct Runner 两阶段执行并重构事件处理
This commit is contained in:
@@ -14,7 +14,9 @@ from schemas.agent.runtime_models import (
|
||||
from schemas.agent.system_agent import AgentType, SystemAgentLLMConfig
|
||||
from schemas.agent.ui_hints import (
|
||||
UiHintAction,
|
||||
UiHintBlock,
|
||||
UiHintIntent,
|
||||
UiHintSection,
|
||||
UiHintStatus,
|
||||
UiHintsPayload,
|
||||
)
|
||||
|
||||
@@ -29,7 +31,9 @@ __all__ = [
|
||||
"ToolStatus",
|
||||
"UiMode",
|
||||
"UiHintAction",
|
||||
"UiHintBlock",
|
||||
"UiHintIntent",
|
||||
"UiHintSection",
|
||||
"UiHintStatus",
|
||||
"UiHintsPayload",
|
||||
"WorkerAgentOutputLite",
|
||||
"WorkerAgentOutputRich",
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
"""
|
||||
UiHints - 描述性 UI 提示
|
||||
|
||||
设计原则:
|
||||
- 描述性而非渲染性: 告诉编译器“要展示什么”,而不是“如何渲染”
|
||||
- 最小化 token: 保持字段简洁
|
||||
- 可编译: 可机械转换为 UiSchemaRenderer
|
||||
- 尽量无损: hints 中的主要内容字段应尽量被保留到 renderer 中
|
||||
|
||||
Version: 2.1
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
from typing import Annotated, Any, Literal
|
||||
from typing import Any, Literal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
# ============================================================
|
||||
# Enums
|
||||
# ============================================================
|
||||
|
||||
|
||||
class UiHintStatus(str, Enum):
|
||||
INFO = "info"
|
||||
@@ -14,6 +30,17 @@ class UiHintStatus(str, Enum):
|
||||
PENDING = "pending"
|
||||
|
||||
|
||||
class UiHintIntent(str, Enum):
|
||||
"""主要展示意图(弱提示,不应决定字段生死)"""
|
||||
|
||||
MESSAGE = "message" # 普通消息/说明
|
||||
DATA = "data" # 数据/结果摘要
|
||||
LIST = "list" # 列表为主
|
||||
STATUS = "status" # 状态结果为主
|
||||
FORM = "form" # 结构化内容(当前不表示真实输入表单)
|
||||
MIXED = "mixed" # 混合内容
|
||||
|
||||
|
||||
class UiHintActionStyle(str, Enum):
|
||||
PRIMARY = "primary"
|
||||
SECONDARY = "secondary"
|
||||
@@ -26,520 +53,238 @@ class UiHintTextFormat(str, Enum):
|
||||
MARKDOWN = "markdown"
|
||||
|
||||
|
||||
class UiHintContainerDirection(str, Enum):
|
||||
VERTICAL = "vertical"
|
||||
HORIZONTAL = "horizontal"
|
||||
class UiHintActionType(str, Enum):
|
||||
NAVIGATION = "navigation"
|
||||
URL = "url"
|
||||
EVENT = "event"
|
||||
TOOL = "tool"
|
||||
COPY = "copy"
|
||||
PAYLOAD = "payload"
|
||||
|
||||
|
||||
class UiHintKvLayout(str, Enum):
|
||||
VERTICAL = "vertical"
|
||||
HORIZONTAL = "horizontal"
|
||||
GRID = "grid"
|
||||
class UiHintIconSource(str, Enum):
|
||||
ICON = "icon"
|
||||
EMOJI = "emoji"
|
||||
URL = "url"
|
||||
|
||||
|
||||
class UiHintOperationType(str, Enum):
|
||||
CREATE = "create"
|
||||
UPDATE = "update"
|
||||
DELETE = "delete"
|
||||
EXECUTE = "execute"
|
||||
# ============================================================
|
||||
# Base Config
|
||||
# ============================================================
|
||||
|
||||
|
||||
class UiHintOperationResult(str, Enum):
|
||||
SUCCESS = "success"
|
||||
FAILURE = "failure"
|
||||
PARTIAL = "partial"
|
||||
|
||||
|
||||
class UiHintConfirm(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
title: str | None = Field(
|
||||
default=None,
|
||||
description="Optional confirmation dialog title.",
|
||||
)
|
||||
message: str | None = Field(
|
||||
default=None,
|
||||
description="Optional confirmation message shown before action execution.",
|
||||
)
|
||||
confirm_label: str | None = Field(
|
||||
default=None,
|
||||
alias="confirmLabel",
|
||||
description="Optional confirm button label, e.g. 'Delete'.",
|
||||
)
|
||||
cancel_label: str | None = Field(
|
||||
default=None,
|
||||
alias="cancelLabel",
|
||||
description="Optional cancel button label, e.g. 'Cancel'.",
|
||||
class UiHintBaseModel(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
extra="forbid",
|
||||
populate_by_name=True,
|
||||
)
|
||||
|
||||
|
||||
class UiHintActionNavigation(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
# ============================================================
|
||||
# Action Targets
|
||||
# ============================================================
|
||||
|
||||
|
||||
class UiHintActionNavigation(UiHintBaseModel):
|
||||
type: Literal["navigation"]
|
||||
path: str = Field(
|
||||
...,
|
||||
description="Internal route path to navigate to.",
|
||||
)
|
||||
params: dict[str, Any] | None = Field(
|
||||
default=None,
|
||||
description="Optional route params for internal navigation.",
|
||||
)
|
||||
path: str = Field(..., description="Internal route path.")
|
||||
params: dict[str, Any] | None = Field(default=None, description="Route params.")
|
||||
|
||||
|
||||
class UiHintActionUrl(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
class UiHintActionUrl(UiHintBaseModel):
|
||||
type: Literal["url"]
|
||||
url: str = Field(..., description="External URL to open.")
|
||||
target: Literal["_self", "_blank"] | None = Field(
|
||||
default=None,
|
||||
description="Optional browser target for URL action.",
|
||||
)
|
||||
url: str = Field(..., description="External URL.")
|
||||
target: Literal["_self", "_blank"] | None = Field(default=None)
|
||||
|
||||
|
||||
class UiHintActionEvent(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
class UiHintActionEvent(UiHintBaseModel):
|
||||
type: Literal["event"]
|
||||
event: str = Field(
|
||||
...,
|
||||
description="Frontend domain event name, e.g. 'chat.retry'.",
|
||||
)
|
||||
payload: dict[str, Any] | None = Field(
|
||||
default=None,
|
||||
description="Optional event payload for frontend event handling.",
|
||||
)
|
||||
event: str = Field(..., description="Frontend event name.")
|
||||
payload: dict[str, Any] | None = Field(default=None)
|
||||
|
||||
|
||||
class UiHintActionTool(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
class UiHintActionTool(UiHintBaseModel):
|
||||
type: Literal["tool"]
|
||||
tool_id: str = Field(
|
||||
alias="toolId",
|
||||
description="Tool identifier used to trigger another tool execution.",
|
||||
)
|
||||
params: dict[str, Any] | None = Field(
|
||||
default=None,
|
||||
description="Optional parameters for tool re-execution.",
|
||||
)
|
||||
tool_id: str = Field(alias="toolId", description="Tool identifier.")
|
||||
params: dict[str, Any] | None = Field(default=None)
|
||||
|
||||
|
||||
class UiHintActionCopy(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
class UiHintActionCopy(UiHintBaseModel):
|
||||
type: Literal["copy"]
|
||||
content: str = Field(..., description="Text content to copy to clipboard.")
|
||||
success_message: str | None = Field(
|
||||
default=None,
|
||||
alias="successMessage",
|
||||
description="Optional user-facing success message after copy.",
|
||||
)
|
||||
content: str = Field(..., description="Content to copy.")
|
||||
success_message: str | None = Field(alias="successMessage", default=None)
|
||||
|
||||
|
||||
class UiHintActionPayload(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
class UiHintActionPayload(UiHintBaseModel):
|
||||
type: Literal["payload"]
|
||||
payload: dict[str, Any] = Field(
|
||||
...,
|
||||
description="Structured payload to submit to frontend or gateway.",
|
||||
)
|
||||
submit_to: str | None = Field(
|
||||
default=None,
|
||||
alias="submitTo",
|
||||
description="Optional submit target path or endpoint key.",
|
||||
)
|
||||
payload: dict[str, Any] = Field(..., description="Structured payload.")
|
||||
submit_to: str | None = Field(alias="submitTo", default=None)
|
||||
|
||||
|
||||
UiHintActionTarget = Annotated[
|
||||
(
|
||||
UiHintActionNavigation
|
||||
| UiHintActionUrl
|
||||
| UiHintActionEvent
|
||||
| UiHintActionTool
|
||||
| UiHintActionCopy
|
||||
| UiHintActionPayload
|
||||
),
|
||||
Field(discriminator="type"),
|
||||
]
|
||||
UiHintActionTarget = (
|
||||
UiHintActionNavigation
|
||||
| UiHintActionUrl
|
||||
| UiHintActionEvent
|
||||
| UiHintActionTool
|
||||
| UiHintActionCopy
|
||||
| UiHintActionPayload
|
||||
)
|
||||
|
||||
|
||||
class UiHintAction(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
extra="forbid",
|
||||
json_schema_extra={
|
||||
"examples": [
|
||||
{
|
||||
"id": "action-open-calendar",
|
||||
"label": "Open calendar",
|
||||
"style": "primary",
|
||||
"action": {"type": "navigation", "path": "/calendar"},
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
id: str | None = Field(
|
||||
default=None,
|
||||
description="Optional stable action id for tracking and targeting.",
|
||||
)
|
||||
label: str = Field(
|
||||
...,
|
||||
description="User-facing action label shown on button/link.",
|
||||
)
|
||||
style: UiHintActionStyle | None = Field(
|
||||
default=None,
|
||||
description="Optional semantic button style.",
|
||||
)
|
||||
disabled: bool = Field(
|
||||
default=False,
|
||||
description="Whether this action should be rendered as disabled.",
|
||||
)
|
||||
action: UiHintActionTarget = Field(
|
||||
...,
|
||||
description="Executable action target definition.",
|
||||
)
|
||||
confirm: UiHintConfirm | None = Field(
|
||||
default=None,
|
||||
description="Optional confirmation requirement before execution.",
|
||||
)
|
||||
class UiHintAction(UiHintBaseModel):
|
||||
label: str = Field(..., description="Button label.")
|
||||
style: UiHintActionStyle | None = Field(default=None, description="Button style.")
|
||||
disabled: bool = Field(default=False, description="Disabled state.")
|
||||
action: UiHintActionTarget = Field(..., description="Action to execute.")
|
||||
|
||||
|
||||
class UiHintIcon(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
source: Literal["icon", "emoji", "url"] = Field(
|
||||
...,
|
||||
description="Icon source type.",
|
||||
)
|
||||
value: str = Field(
|
||||
...,
|
||||
description="Icon identifier, emoji text, or image URL based on source.",
|
||||
)
|
||||
color: str | None = Field(
|
||||
default=None,
|
||||
description="Optional semantic color hint. Do not encode pixel-level style rules.",
|
||||
)
|
||||
size: int | None = Field(
|
||||
default=None,
|
||||
description="Optional icon size hint in abstract UI units.",
|
||||
)
|
||||
# ============================================================
|
||||
# Small Descriptive Models
|
||||
# ============================================================
|
||||
|
||||
|
||||
class UiHintBadge(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
label: str = Field(..., description="Badge text label.")
|
||||
variant: Literal["default", "success", "warning", "error", "info"] = Field(
|
||||
default="default",
|
||||
description="Semantic badge variant.",
|
||||
)
|
||||
class UiHintIcon(UiHintBaseModel):
|
||||
source: UiHintIconSource = Field(default=UiHintIconSource.ICON)
|
||||
value: str = Field(..., description="Icon identifier / emoji / url.")
|
||||
color: str | None = Field(default=None)
|
||||
size: int | None = Field(default=None)
|
||||
|
||||
|
||||
class UiHintKeyValuePair(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
key: str = Field(..., description="Stable key identifier for this pair.")
|
||||
label: str | None = Field(
|
||||
default=None,
|
||||
description="Optional user-facing label. Fallback to key when missing.",
|
||||
)
|
||||
value: str | int | bool | None = Field(
|
||||
default=None,
|
||||
description="Scalar value for this key-value pair.",
|
||||
)
|
||||
copyable: bool = Field(
|
||||
default=False,
|
||||
description="Whether frontend may offer copy interaction for this value.",
|
||||
)
|
||||
class UiHintKvItem(UiHintBaseModel):
|
||||
key: str = Field(..., description="Key identifier.")
|
||||
label: str | None = Field(default=None, description="Display label.")
|
||||
value: Any = Field(default=None, description="Value.")
|
||||
copyable: bool = Field(default=False, description="Allow copy.")
|
||||
|
||||
|
||||
class UiHintListItem(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
id: str | None = Field(
|
||||
default=None,
|
||||
description="Optional stable list item id.",
|
||||
)
|
||||
title: str = Field(..., description="Primary list item title.")
|
||||
subtitle: str | None = Field(
|
||||
default=None,
|
||||
description="Optional short secondary text.",
|
||||
)
|
||||
description: str | None = Field(
|
||||
default=None,
|
||||
description="Optional detailed description for this item.",
|
||||
)
|
||||
icon: UiHintIcon | None = Field(
|
||||
default=None,
|
||||
description="Optional semantic icon metadata.",
|
||||
)
|
||||
badge: UiHintBadge | None = Field(
|
||||
default=None,
|
||||
description="Optional semantic badge metadata.",
|
||||
)
|
||||
metadata: dict[str, Any] = Field(
|
||||
default_factory=dict,
|
||||
description="Optional non-visual metadata for analytics or interactions.",
|
||||
)
|
||||
actions: list[UiHintAction] = Field(
|
||||
default_factory=list,
|
||||
description="Optional per-item actions, recommended up to 3.",
|
||||
)
|
||||
class UiHintListItem(UiHintBaseModel):
|
||||
id: str | None = Field(default=None)
|
||||
title: str = Field(..., description="Item title.")
|
||||
subtitle: str | None = Field(default=None)
|
||||
description: str | None = Field(default=None)
|
||||
icon: UiHintIcon | None = Field(default=None)
|
||||
status: UiHintStatus | None = Field(default=None)
|
||||
actions: list[UiHintAction] = Field(default_factory=list)
|
||||
|
||||
|
||||
class UiHintPagination(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
class UiHintSection(UiHintBaseModel):
|
||||
title: str | None = Field(default=None, description="Section title.")
|
||||
description: str | None = Field(default=None, description="Section description.")
|
||||
icon: UiHintIcon | None = Field(default=None, description="Section icon.")
|
||||
|
||||
page: int = Field(..., description="Current page number starting from 1.")
|
||||
page_size: int = Field(
|
||||
alias="pageSize",
|
||||
description="Page size used for this list page.",
|
||||
)
|
||||
total: int = Field(..., description="Total number of records.")
|
||||
has_more: bool = Field(
|
||||
alias="hasMore",
|
||||
description="Whether there are more pages after current page.",
|
||||
)
|
||||
|
||||
|
||||
class UiHintBaseBlock(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
id: str | None = Field(
|
||||
default=None,
|
||||
description="Optional stable block id.",
|
||||
)
|
||||
title: str | None = Field(
|
||||
default=None,
|
||||
description="Optional block title.",
|
||||
)
|
||||
description: str | None = Field(
|
||||
default=None,
|
||||
description="Optional block description.",
|
||||
)
|
||||
status: UiHintStatus | None = Field(
|
||||
default=None,
|
||||
description="Optional semantic status for this block.",
|
||||
)
|
||||
actions: list[UiHintAction] = Field(
|
||||
default_factory=list,
|
||||
description="Optional block-level actions, recommended up to 3.",
|
||||
)
|
||||
|
||||
|
||||
class UiHintTextBlock(UiHintBaseBlock):
|
||||
kind: Literal["text"]
|
||||
content: str = Field(
|
||||
...,
|
||||
description="Main text content to present.",
|
||||
)
|
||||
format: UiHintTextFormat = Field(
|
||||
content: str | None = Field(default=None, description="Main text content.")
|
||||
content_format: UiHintTextFormat = Field(
|
||||
default=UiHintTextFormat.PLAIN,
|
||||
description="Text format: plain or markdown.",
|
||||
alias="contentFormat",
|
||||
description="Section content text format.",
|
||||
)
|
||||
|
||||
|
||||
class UiHintCardBlock(UiHintBaseBlock):
|
||||
kind: Literal["card"]
|
||||
children: list["UiHintBlock"] = Field(
|
||||
items: list[UiHintKvItem] = Field(default_factory=list, description="KV items.")
|
||||
list_items: list[UiHintListItem] = Field(
|
||||
default_factory=list,
|
||||
description="Nested child blocks grouped under this card.",
|
||||
alias="listItems",
|
||||
description="List items.",
|
||||
)
|
||||
actions: list[UiHintAction] = Field(default_factory=list, description="Actions.")
|
||||
|
||||
|
||||
class UiHintKvBlock(UiHintBaseBlock):
|
||||
kind: Literal["kv"]
|
||||
pairs: list[UiHintKeyValuePair] = Field(
|
||||
default_factory=list,
|
||||
description="Key-value pairs to display.",
|
||||
)
|
||||
layout: UiHintKvLayout = Field(
|
||||
default=UiHintKvLayout.VERTICAL,
|
||||
description="Preferred semantic layout for key-value content.",
|
||||
)
|
||||
# ============================================================
|
||||
# Root Payload
|
||||
# ============================================================
|
||||
|
||||
|
||||
class UiHintListBlock(UiHintBaseBlock):
|
||||
kind: Literal["list"]
|
||||
items: list[UiHintListItem] = Field(
|
||||
default_factory=list,
|
||||
description="List items to present.",
|
||||
)
|
||||
pagination: UiHintPagination | None = Field(
|
||||
default=None,
|
||||
description="Optional pagination metadata.",
|
||||
)
|
||||
empty_text: str | None = Field(
|
||||
default=None,
|
||||
alias="emptyText",
|
||||
description="Optional message shown when list items are empty.",
|
||||
)
|
||||
class UiHintsPayload(UiHintBaseModel):
|
||||
"""
|
||||
描述性 UI 提示
|
||||
|
||||
设计目标:
|
||||
- agent 输出尽可能短
|
||||
- 不表达布局细节
|
||||
- 编译器负责转换为完整 UiSchemaRenderer
|
||||
"""
|
||||
|
||||
class UiHintOperationBlock(UiHintBaseBlock):
|
||||
kind: Literal["operation"]
|
||||
operation: UiHintOperationType = Field(
|
||||
...,
|
||||
description="Operation category: create/update/delete/execute.",
|
||||
)
|
||||
result: UiHintOperationResult = Field(
|
||||
...,
|
||||
description="Operation result: success/failure/partial.",
|
||||
)
|
||||
message: str | None = Field(
|
||||
default=None,
|
||||
description="Optional operation summary message.",
|
||||
)
|
||||
affected_count: int | None = Field(
|
||||
default=None,
|
||||
alias="affectedCount",
|
||||
description="Optional affected record count.",
|
||||
)
|
||||
details: dict[str, Any] | None = Field(
|
||||
default=None,
|
||||
description="Optional machine-readable operation details.",
|
||||
)
|
||||
|
||||
|
||||
class UiHintErrorBlock(UiHintBaseBlock):
|
||||
kind: Literal["error"]
|
||||
error_code: str = Field(
|
||||
alias="errorCode",
|
||||
description="Stable error code for categorization.",
|
||||
)
|
||||
message: str = Field(
|
||||
...,
|
||||
description="Human-readable error message.",
|
||||
)
|
||||
retryable: bool = Field(
|
||||
default=False,
|
||||
description="Whether retry is likely to succeed.",
|
||||
)
|
||||
details: str | None = Field(
|
||||
default=None,
|
||||
description="Optional plain-text diagnostic details.",
|
||||
)
|
||||
suggestions: list[str] = Field(
|
||||
default_factory=list,
|
||||
description="Optional actionable suggestions, recommended up to 3.",
|
||||
)
|
||||
|
||||
|
||||
class UiHintContainerBlock(UiHintBaseBlock):
|
||||
kind: Literal["container"]
|
||||
direction: UiHintContainerDirection = Field(
|
||||
default=UiHintContainerDirection.VERTICAL,
|
||||
description="Child block layout direction.",
|
||||
)
|
||||
gap: int | None = Field(
|
||||
default=None,
|
||||
description="Optional semantic spacing hint between children.",
|
||||
)
|
||||
children: list["UiHintBlock"] = Field(
|
||||
default_factory=list,
|
||||
description="Nested child blocks in this container.",
|
||||
)
|
||||
|
||||
|
||||
class UiHintCustomBlock(UiHintBaseBlock):
|
||||
kind: Literal["custom"]
|
||||
renderer_key: str = Field(
|
||||
alias="rendererKey",
|
||||
description=(
|
||||
"Custom semantic renderer key. Use only when standard block kinds "
|
||||
"cannot represent the intent."
|
||||
),
|
||||
)
|
||||
payload: dict[str, Any] = Field(
|
||||
default_factory=dict,
|
||||
description="Structured custom payload consumed by the renderer.",
|
||||
)
|
||||
|
||||
|
||||
UiHintBlock = Annotated[
|
||||
(
|
||||
UiHintTextBlock
|
||||
| UiHintCardBlock
|
||||
| UiHintKvBlock
|
||||
| UiHintListBlock
|
||||
| UiHintOperationBlock
|
||||
| UiHintErrorBlock
|
||||
| UiHintContainerBlock
|
||||
| UiHintCustomBlock
|
||||
),
|
||||
Field(discriminator="kind"),
|
||||
]
|
||||
|
||||
|
||||
class UiHintsPayload(BaseModel):
|
||||
model_config = ConfigDict(
|
||||
extra="forbid",
|
||||
populate_by_name=True,
|
||||
json_schema_extra={
|
||||
"examples": [
|
||||
{
|
||||
"version": "1.0",
|
||||
"status": "info",
|
||||
"title": "Schedule update",
|
||||
"blocks": [
|
||||
{
|
||||
"kind": "text",
|
||||
"content": "Your meeting is moved to 3:00 PM.",
|
||||
"format": "plain",
|
||||
},
|
||||
{
|
||||
"kind": "list",
|
||||
"title": "Next steps",
|
||||
"items": [
|
||||
{"title": "Open calendar"},
|
||||
{"title": "Notify attendees"},
|
||||
],
|
||||
},
|
||||
"intent": "status",
|
||||
"status": "success",
|
||||
"title": "日程已创建",
|
||||
"body": "本次创建已成功完成。",
|
||||
"items": [
|
||||
{"key": "title", "label": "主题", "value": "Q1 规划会议"},
|
||||
{"key": "time", "label": "时间", "value": "2026-03-15 14:00"},
|
||||
],
|
||||
"actions": [
|
||||
{
|
||||
"label": "Open calendar",
|
||||
"label": "查看详情",
|
||||
"style": "primary",
|
||||
"action": {"type": "navigation", "path": "/calendar"},
|
||||
}
|
||||
"action": {
|
||||
"type": "navigation",
|
||||
"path": "/calendar/evt_123",
|
||||
},
|
||||
},
|
||||
{
|
||||
"label": "删除",
|
||||
"style": "danger",
|
||||
"action": {
|
||||
"type": "tool",
|
||||
"toolId": "calendar.delete",
|
||||
"params": {"eventId": "evt_123"},
|
||||
},
|
||||
},
|
||||
],
|
||||
"meta": {"source": "worker"},
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
version: str = Field(
|
||||
default="1.0",
|
||||
description="Ui hints payload version.",
|
||||
version: str = Field(default="2.1")
|
||||
|
||||
intent: UiHintIntent = Field(
|
||||
default=UiHintIntent.MESSAGE,
|
||||
description="Primary display intent.",
|
||||
)
|
||||
status: UiHintStatus = Field(
|
||||
default=UiHintStatus.INFO,
|
||||
description="Overall semantic status for the full ui_hints payload.",
|
||||
description="Overall status.",
|
||||
)
|
||||
title: str | None = Field(
|
||||
default=None,
|
||||
description="Optional top-level semantic title.",
|
||||
|
||||
title: str | None = Field(default=None, description="Top-level title.")
|
||||
description: str | None = Field(default=None, description="Top-level description.")
|
||||
|
||||
body: str | None = Field(default=None, description="Top-level main body text.")
|
||||
body_format: UiHintTextFormat = Field(
|
||||
default=UiHintTextFormat.PLAIN,
|
||||
alias="bodyFormat",
|
||||
description="Body text format.",
|
||||
)
|
||||
description: str | None = Field(
|
||||
default=None,
|
||||
description="Optional top-level semantic description.",
|
||||
)
|
||||
blocks: list[UiHintBlock] = Field(
|
||||
|
||||
items: list[UiHintKvItem] = Field(
|
||||
default_factory=list,
|
||||
description="Main semantic content blocks.",
|
||||
description="Top-level key-value items.",
|
||||
)
|
||||
list_items: list[UiHintListItem] = Field(
|
||||
default_factory=list,
|
||||
alias="listItems",
|
||||
description="Top-level list items.",
|
||||
)
|
||||
sections: list[UiHintSection] = Field(
|
||||
default_factory=list,
|
||||
description="Grouped sections.",
|
||||
)
|
||||
actions: list[UiHintAction] = Field(
|
||||
default_factory=list,
|
||||
description="Optional top-level actions, recommended up to 3.",
|
||||
description="Top-level actions.",
|
||||
)
|
||||
|
||||
icon: UiHintIcon | None = Field(
|
||||
default=None,
|
||||
description="Top-level icon.",
|
||||
)
|
||||
meta: dict[str, Any] = Field(
|
||||
default_factory=dict,
|
||||
description="Optional non-visual metadata for tracing and integration.",
|
||||
description="Extra meta, e.g. requestId/toolId/traceId/userId.",
|
||||
)
|
||||
|
||||
|
||||
UiHintCardBlock.model_rebuild()
|
||||
UiHintContainerBlock.model_rebuild()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from typing import ClassVar
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
from schemas.agent.runtime_models import RouterAgentOutput, WorkerAgentOutputRich
|
||||
|
||||
from ..agent import AgentType, ToolAgentOutput, WorkerAgentOutput
|
||||
from ..agent import AgentType, ToolAgentOutput
|
||||
|
||||
|
||||
class UserMessageAttachments(BaseModel):
|
||||
@@ -22,8 +24,9 @@ class AgentChatMessageMetadata(BaseModel):
|
||||
run_id: str
|
||||
agent_type: AgentType | None = None
|
||||
user_message_attachments: UserMessageAttachments | None = None
|
||||
router_agent_output: RouterAgentOutput | None = None
|
||||
tool_agent_output: ToolAgentOutput | None = None
|
||||
worker_agent_output: WorkerAgentOutput | None = None
|
||||
worker_agent_output: WorkerAgentOutputRich | None = None
|
||||
|
||||
|
||||
class AgentChatMessage(BaseModel):
|
||||
@@ -35,5 +38,11 @@ class AgentChatMessage(BaseModel):
|
||||
seq: int
|
||||
role: str
|
||||
content: str
|
||||
model_code: str | None = None
|
||||
tool_name: str | None = None
|
||||
input_tokens: int = Field(default=0, ge=0)
|
||||
output_tokens: int = Field(default=0, ge=0)
|
||||
cost: Decimal = Field(default=Decimal("0"))
|
||||
latency_ms: int | None = Field(default=None, ge=0)
|
||||
metadata: AgentChatMessageMetadata | dict[str, object] | None = None
|
||||
timestamp: datetime
|
||||
|
||||
Reference in New Issue
Block a user