Skip to content

fix(formatter): offload media conversion from event loop - #2725

Open
wangtaotaotao95 wants to merge 7 commits into
agentscope-ai:mainfrom
wangtaotaotao95:fix/formatter-remote-media-async
Open

wangtaotaotao95 wants to merge 7 commits into
agentscope-ai:mainfrom
wangtaotaotao95:fix/formatter-remote-media-async

Conversation

@wangtaotaotao95

@wangtaotaotao95 wangtaotaotao95 commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

AgentScope Version

2.0.8 (main at 5ff52f87)

Description

Fixes #2724.

AgentScope's formatter methods are async, but media conversion could perform synchronous downloads or local file reads on the event-loop thread. A slow image, audio, or PDF operation could therefore stall unrelated coroutines for up to the request timeout.

This PR offloads existing synchronous DataBlock conversion helpers through asyncio.to_thread in the OpenAI Chat/Responses, Anthropic, Gemini, Moonshot, Ollama, and xAI formatters. It preserves the current helper APIs and output schemas while moving blocking downloads and file reads away from the event loop.

Regression coverage includes:

  • a parametrized remote-download test across six formatter families, which schedules an event-loop callback while a mocked download waits;
  • an xAI local-image test proving the file read runs outside the event-loop thread.

Verification:

  • Original related formatter suites: 91 passed, 4 subtests passed
  • xAI and async regression suites: 23 passed
  • All pre-commit hooks on changed files passed, including mypy, black, flake8, and pylint
  • No public API or documentation changes

The patch and tests were prepared with AI assistance and manually reviewed and verified.

Checklist

  • An issue has been created for this PR
  • I have read the CONTRIBUTING.md
  • Docstrings are in Google style
  • Related documentation update is not applicable; no public API or documented behavior changed
  • Code is ready for review

Current-head validation (2026-10-01)

Merged main 72f3f6fa into this branch and resolved the Moonshot import conflict, retaining asynchronous media conversion and all current main behavior. At adc464f8, all formatter suites passed: 150 tests and 4 subtests. All pre-commit hooks on the conflict-resolved Moonshot file passed, and git diff --check passed.

Claim coordination: the previous claimant explicitly released #2724 in favor of this PR: #2724 (comment) . The remaining assignment/guard metadata needs maintainer cleanup.

@wangtaotaotao95
wangtaotaotao95 force-pushed the fix/formatter-remote-media-async branch from 93618ed to 202c165 Compare September 25, 2026 05:59
@wangtaotaotao95

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (head 202c165) and reconciled the xAI helper extraction with the async local-file read path.

Validation:

  • formatter_remote_media_async_test.py and formatter_xai_test.py — 26 tests passed
  • pre-commit on all changed files — all hooks passed
  • git diff --check — passed

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for the pull request. One thing worth sorting out before it is reviewed:

If you think it belongs here anyway, say so and a maintainer will take a look.

@wangtaotaotao95

Copy link
Copy Markdown
Contributor Author

Following up on the PR guard: @ZxlDragonDoctor explicitly released the claim on #2724 after checking this existing PR and confirmed that they have no competing PR for the issue: #2724 (comment) .

The issue still appears assigned to them, so the guard is reading stale claim metadata. Could a maintainer clear the released claim and re-evaluate the guard for this PR? This change continues the existing fix; it does not compete with an active claim.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr/awaiting-review Waiting for maintainers to review this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Remote media downloads in async formatters block the event loop

1 participant