Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Python: [Bug]: UserMessage/AgentMessage return different shapes from WorkflowState and DeclarativeWorkflowState

未关闭
#9,041 1 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

维护者通常 1 天内回复

@eavanvalkenburg 已经在做这个了。

开始于 2026年10月5日。

  • #9101 来自 @he-yufeng —— 未关闭

评估

难度
4/5
预计耗时
3-5 天
新手友好度
48/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
python

调研方向

Compare the two evaluation paths in _powerfx_functions.py and _declarative_base.py, then trace how each MessageText implementation reads messages. The issue leaves the canonical shape to a maintainer, so get that direction before changing code. Done means both evaluation paths produce the agreed shape and both MessageText implementations read it consistently.

由索引模型根据 Issue 内容生成。

描述

python vnext
Language

Python

What happened?

The same declarative formula produces two different message shapes depending on which public state class evaluates it:

from agent_framework_declarative._workflows._state import WorkflowState

WorkflowState().eval('=UserMessage("hi")')
# {'role': 'user', 'content': 'hi'}

WorkflowState (standalone) routes to _powerfx_functions.user_message, which returns a flat content key (python/packages/declarative/agent_framework_declarative/_workflows/_powerfx_functions.py:107, same for assistant_message / agent_message / system_message).

DeclarativeWorkflowState (what factory-created workflows use) routes to _eval_custom_function, which returns a flat text key for UserMessage / AgentMessage:

return {"role": "user", "text": str(text) if text else ""}  # _declarative_base.py:755

The two MessageText implementations each read only their own side's shape, so a message that crosses paths silently extracts nothing:

  • _declarative_base._eval_and_replace_message_text reads text first, then a contents list; it never reads content (_declarative_base.py:858-885). A content-shaped message yields "".
  • _powerfx_functions.message_text reads content, so on a text-shaped message it returns "":
from agent_framework_declarative._workflows._powerfx_functions import message_text

message_text([{"role": "user", "text": "hi"}])     # ''
message_text([{"role": "user", "content": "hi"}])  # 'hi'

The agent-side consumer is more tolerant (_executors_agents.py:716 reads content then text), which papers over the split for agent invocations but not for MessageText.

For reference, the .NET canonical shape is a structured record (dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PowerFx/Functions/MessageFunction.cs): {__type__, Role, Content: [{Type: "Text", Value: ...}]}, i.e. neither flat Python shape. Feeding that shape to the fallback message_text today stringifies the content table:

message_text([{"role": "user", "content": [{"type": "text", "value": "hi"}]}])
# "[{'type': 'text', 'value': 'hi'}]"

Verified on current main (e9857bd75a21843803431a2e7dfa41ee9b017ac7) with agent-framework-declarative installed from source; the .NET shape was read from the in-repo dotnet sources.

What should happen?

One canonical message shape for the Python package, with both eval paths producing it and both MessageText implementations reading it. Which key wins (flat text, flat content, or the structured .NET-style content list) looks like a maintainer call; happy to send the PR once there is a direction.

主要语言
Python
星标
13.9k
派生
2.4k
平均合并
1 天 19 小时
30 天内合并 PR
439

环境准备

在 Codespaces 中打开

在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

microsoft/agent-framework 的其他 Issue

查看 microsoft/agent-framework 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。