Skip to content

feat(agent): image input in an agent turn + MCP 2025-11-25 - #407

Open
DenisovAV wants to merge 3 commits into
mainfrom
feat/agent-image-turn
Open

feat(agent): image input in an agent turn + MCP 2025-11-25#407
DenisovAV wants to merge 3 commits into
mainfrom
feat/agent-image-turn

Conversation

@DenisovAV

Copy link
Copy Markdown
Owner

What

  • AgentLoop.run(chat, userMessage, {Uint8List? imageBytes}) and AgentSession.ask(userMessage, {imageBytes}) now accept an optional image. When present, the turn is built with Message.withImage instead of a plain text Message, so the model sees the photo alongside the text and can dispatch skills based on what it saw.
  • McpClient advertises MCP protocol revision 2025-11-25 (was 2025-06-18), pinned by a test that asserts what goes out in the initialize request.

Requirements

The image only reaches the model when the chat is multimodal — build the session with supportImage: true (see AgentSession.fromModel) and back it with a vision-capable model. Without that the image is ignored downstream; this is documented on both new parameters.

Notes

  • The fake MCP server in tests still replies with 2025-06-18. That is deliberate: the client advertises a revision and the server may negotiate down, so the test asserts the outgoing value, not the reply.
  • flutter_gemma_agent bumped 0.1.0 → 0.2.0.

Verification

  • flutter test in packages/flutter_gemma_agent: 198 passed.
  • flutter analyze: no issues.

AgentLoop.run / AgentSession.ask take optional imageBytes and build the
turn with Message.withImage, so a multimodal chat (supportImage: true)
can dispatch skills based on what the model saw.

McpClient now advertises protocol revision 2025-11-25, pinned by a test.
- AgentLoop.run throws when imageBytes is passed to a chat without image
  support, or when the bytes are empty. The engines disagreed on this
  case: FFI, mobile MediaPipe and built-in AI dropped the image and
  answered text-only, web MediaPipe threw. A silent drop is the worse
  half — the model answers confidently about a photo it never saw.
- McpClient verifies the revision the server echoes in initialize and
  throws on a downgrade, instead of proceeding blind.
- McpClient sends MCP-Protocol-Version on every request after initialize;
  without it a stateless server must assume 2025-03-26, so advertising a
  newer revision in the handshake alone changed nothing on the wire.
- _notify surfaces a rejected notifications/initialized instead of
  swallowing it (and its HTTP status).
- clientVersion follows the package to 0.2.0; example lock and the
  CLAUDE.md version line updated.
- Tests: guard cases, negotiated-revision mismatch, and the header on
  post-initialize requests. The fixture now echoes the client's revision
  rather than silently downgrading it.
agent.md had no coverage of ask(imageBytes:) — including the
supportImage: true precondition and the ArgumentError it now throws.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant