Skip to content

Commit 8940b45

Browse files
committed
Address comments
1 parent 78c7d5f commit 8940b45

7 files changed

Lines changed: 91 additions & 8 deletions

File tree

python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,9 +1087,16 @@ def _convert_file_data(data_uri: str, filename: str | None = None) -> Content:
10871087
header, encoded = data_uri.split(";base64,", 1)
10881088
media_type = header[len("data:") :]
10891089
if media_type.startswith("text/"):
1090-
decoded_text = base64.b64decode(encoded).decode("utf-8")
1091-
prefix = f"[File: {filename}]\n" if filename else ""
1092-
return Content.from_text(f"{prefix}{decoded_text}")
1090+
try:
1091+
decoded_text = base64.b64decode(encoded).decode("utf-8")
1092+
except (ValueError, UnicodeDecodeError):
1093+
logger.warning(
1094+
"Failed to decode text/* file_data as UTF-8, falling through to URI passthrough.",
1095+
exc_info=True,
1096+
)
1097+
else:
1098+
prefix = f"[File: {filename}]\n" if filename else ""
1099+
return Content.from_text(f"{prefix}{decoded_text}")
10931100
additional_properties = {"filename": filename} if filename else None
10941101
return Content.from_uri(data_uri, additional_properties=additional_properties)
10951102

@@ -1127,6 +1134,8 @@ def _convert_message_content(content: MessageContent) -> Content:
11271134
if content.type == "input_image":
11281135
image = cast(MessageContentInputImageContent, content)
11291136
if image.image_url:
1137+
if image.image_url.startswith("data:"):
1138+
return Content.from_uri(image.image_url)
11301139
return Content.from_uri(image.image_url, media_type="image/*")
11311140
if image.file_id:
11321141
return Content.from_hosted_file(image.file_id)

python/packages/foundry_hosting/tests/test_responses.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,6 +1548,80 @@ async def test_text_and_file_data_input_single_turn(self) -> None:
15481548
assert messages[0].contents[1].type == "data"
15491549
assert messages[0].contents[1].uri == "data:application/pdf;base64,JVBERi0xLjQ="
15501550

1551+
async def test_text_mime_file_data_decoded(self) -> None:
1552+
"""Agent receives a text/* file_data that is base64-decoded to plain text."""
1553+
agent = _make_agent(
1554+
response=AgentResponse(messages=[Message(role="assistant", contents=[Content.from_text("Got it")])])
1555+
)
1556+
server = _make_server(agent)
1557+
1558+
import base64
1559+
1560+
encoded = base64.b64encode(b"Hello, world!").decode()
1561+
1562+
resp = await _post_json(
1563+
server,
1564+
{
1565+
"model": "test-model",
1566+
"input": [
1567+
{
1568+
"type": "message",
1569+
"role": "user",
1570+
"content": [
1571+
{
1572+
"type": "input_file",
1573+
"file_data": f"data:text/plain;base64,{encoded}",
1574+
"filename": "greeting.txt",
1575+
},
1576+
],
1577+
}
1578+
],
1579+
"stream": False,
1580+
},
1581+
)
1582+
1583+
assert resp.status_code == 200
1584+
1585+
messages = agent.run.call_args.kwargs["messages"]
1586+
assert len(messages) == 1
1587+
assert messages[0].contents[0].type == "text"
1588+
assert messages[0].contents[0].text == "[File: greeting.txt]\nHello, world!"
1589+
1590+
async def test_text_mime_file_data_invalid_base64_falls_through(self) -> None:
1591+
"""Invalid base64 in a text/* file_data falls through to URI passthrough."""
1592+
agent = _make_agent(
1593+
response=AgentResponse(messages=[Message(role="assistant", contents=[Content.from_text("Got it")])])
1594+
)
1595+
server = _make_server(agent)
1596+
1597+
resp = await _post_json(
1598+
server,
1599+
{
1600+
"model": "test-model",
1601+
"input": [
1602+
{
1603+
"type": "message",
1604+
"role": "user",
1605+
"content": [
1606+
{
1607+
"type": "input_file",
1608+
"file_data": "data:text/plain;base64,!!!invalid!!!",
1609+
"filename": "bad.txt",
1610+
},
1611+
],
1612+
}
1613+
],
1614+
"stream": False,
1615+
},
1616+
)
1617+
1618+
assert resp.status_code == 200
1619+
1620+
messages = agent.run.call_args.kwargs["messages"]
1621+
assert len(messages) == 1
1622+
assert messages[0].contents[0].type == "data"
1623+
assert messages[0].contents[0].uri == "data:text/plain;base64,!!!invalid!!!"
1624+
15511625
async def test_mixed_text_and_image_input(self) -> None:
15521626
"""Agent receives a single message with both text and image content."""
15531627
agent = _make_agent(

python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The agent is hosted using the [Agent Framework](https://github.com/microsoft/age
1818

1919
> Depending on how you run the agent host, you can invoke the agent using `curl` (`Invoke-WebRequest` in PowerShell) or `azd`. Please refer to the [parent README](../../README.md) for more details. Use this README for sample queries you can send to the agent.
2020
21-
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
21+
Send a POST request to the server with a JSON body containing an `"input"` field to interact with the agent. For example:
2222

2323
```bash
2424
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Hi"}'

python/samples/04-hosting/foundry-hosted-agents/responses/02_tools/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Follow the instructions in the [Running the Agent Host Locally](../../README.md#
2222

2323
> Depending on how you run the agent host, you can invoke the agent using `curl` (`Invoke-WebRequest` in PowerShell) or `azd`. Please refer to the [parent README](../../README.md) for more details. Use this README for sample queries you can send to the agent.
2424
25-
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
25+
Send a POST request to the server with a JSON body containing an `"input"` field to interact with the agent. For example:
2626

2727
```bash
2828
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "What is the weather in Seattle?"}'

python/samples/04-hosting/foundry-hosted-agents/responses/03_mcp/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Follow the instructions in the [Running the Agent Host Locally](../../README.md#
2222

2323
> Depending on how you run the agent host, you can invoke the agent using `curl` (`Invoke-WebRequest` in PowerShell) or `azd`. Please refer to the [parent README](../../README.md) for more details. Use this README for sample queries you can send to the agent.
2424
25-
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
25+
Send a POST request to the server with a JSON body containing an `"input"` field to interact with the agent. For example:
2626

2727
```bash
2828
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "List all the repositories I own on GitHub."}'

python/samples/04-hosting/foundry-hosted-agents/responses/04_foundry_toolbox/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Follow the instructions in the [Running the Agent Host Locally](../../README.md#
3232

3333
> Depending on how you run the agent host, you can invoke the agent using `curl` (`Invoke-WebRequest` in PowerShell) or `azd`. Please refer to the [parent README](../../README.md) for more details. Use this README for sample queries you can send to the agent.
3434
35-
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
35+
Send a POST request to the server with a JSON body containing an `"input"` field to interact with the agent. For example:
3636

3737
```bash
3838
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "What tools do you have?"}'

python/samples/04-hosting/foundry-hosted-agents/responses/05_workflows/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Follow the instructions in the [Running the Agent Host Locally](../../README.md#
2626

2727
> Depending on how you run the agent host, you can invoke the agent using `curl` (`Invoke-WebRequest` in PowerShell) or `azd`. Please refer to the [parent README](../../README.md) for more details. Use this README for sample queries you can send to the agent.
2828
29-
Send a POST request to the server with a JSON body containing a "message" field to interact with the agent. For example:
29+
Send a POST request to the server with a JSON body containing an `"input"` field to interact with the agent. For example:
3030

3131
```bash
3232
curl -X POST http://localhost:8088/responses -H "Content-Type: application/json" -d '{"input": "Create a slogan for a new electric SUV that is affordable and fun to drive."}'

0 commit comments

Comments
 (0)