Skip to content

fix(server,web): bound image prompts, name provider on consent, render generated images - #460

Open
leoisadev1 wants to merge 4 commits into
mainfrom
devin/1791305508-image-privacy-consent
Open

leoisadev1 wants to merge 4 commits into
mainfrom
devin/1791305508-image-privacy-consent

Conversation

@leoisadev1

@leoisadev1 leoisadev1 commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

What Changed

Bounds image-tool content before it reaches sinks outside the caller's chat transcript, names the provider on the consent card, and fixes generated images not rendering on web.

  • GenerateImage tool events and persisted activities no longer carry prompt or inputImages. boundedImageToolArgs strips them from item.started args, request.opened args, and persisted approval.requested activities (routing fields like operation, provider, allowProvider, count, quality, aspectRatio stay). The event store stays clean, which covers analytics and logs; observational memory (processOutputResult and the rollback restore) scrubs tool-invocation parts via boundedImageToolMessage.
  • Crossing providers during an edit used to depend on the model retrying with allowProvider after needs-consent, with nothing recording the user's agreement. The retried call now opens the existing one-shot approval card with a provider-aware detail — "Send the chat images to Grok?" — so the persisted request.resolved (actor: "user") records real consent, and the approval.requested activity keeps the bounded args so the record stays machine-readable.
  • Web render fix: AssistantMessageRow never mounted BotMessageAttachments and visibleBotChatMessages kept only the last settled assistant record per turn, so a generated image posted mid-turn never rendered on web/desktop. Attachment posts now stay visible next to the final reply, and the row renders them like mobile already does.
  • Tests: sink coverage for tool events, approval activities, observational memory, and entity memory (asserts no writes); consent-card detail and bounded persisted args; a server-side test that renders a finished image in a group chat; visibleBotChatMessages coverage for attachment posts.

Refs #450. The one item not covered here is a real generation through each supported subscription path (ChatGPT and Grok) — it needs live provider credentials, which this environment doesn't have; the fake-adapter tests cover both routing paths.

Why

The remaining #450 acceptance items: keep prompts/images out of analytics, memory, logs, and feedback; record user confirmation before crossing providers on edit; and render a finished image in a group chat. Verification surfaced the web render gap — the feature was invisible on the main client, so fixing it is part of exposing image generation.

UI Changes

Before — assistant message rendered text only; the image attachment never appeared:

before

After — the image paints inline under the assistant reply, and the consent card names the provider:

after

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I linked the accepted plugin or provider proposal in Why, or this PR does not add one
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Link to Devin session: https://app.devin.ai/sessions/462eb37e238e43b69e896a94c638a5a9
Open in Devin Desktop: https://app.devin.ai/desktop/session/462eb37e238e43b69e896a94c638a5a9?variant=devin
Requested by: @leoisadev1


Devin Review

…t for provider crossing

Image tool calls carried the prompt and input-image references on
item.started args, request.opened args, approval activities, and
observational memory. Bound GenerateImage tool content so only routing
fields (operation, provider, allowProvider, count, quality, aspectRatio)
persist; prompts and image references never reach the event store,
analytics, observational memory, or logs.

Crossing providers during an edit relied on the model retrying with
allowProvider after a needs-consent result, but nothing recorded the
user's agreement. The retried call now opens a one-shot approval card
naming the receiving provider, and the persisted approval activity keeps
the bounded args so the consent record is machine-readable.

Adds a server-side test that renders a finished image in a group chat
and coverage for the bounded sinks and the consent card.

Model: Devin (Cognition AI), #450
Assistant rows never mounted BotMessageAttachments, and
visibleBotChatMessages kept only the last settled assistant record per
turn, so a generated image posted mid-turn was shadowed by the final
reply. Attachment posts are artifacts: they stay visible next to the
answer, and the row now renders them like mobile already does.

Model: Devin (Cognition AI), #450
@devin-ai-integration

Copy link
Copy Markdown

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@vercel

vercel Bot commented Oct 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
akeru-bot-landing Ignored Ignored Oct 6, 2026 5:51pm UTC

Request Review

@github-actions github-actions Bot added type:provider Agent provider contribution. area:connectors Plugin and MCP connector runtime. vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Oct 6, 2026

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Devin Review

Comment thread apps/server/src/image-generation/toolContent.ts Outdated
@greptile-apps

greptile-apps Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium risk] Image generation prompts and consent flow changes.

The changes since the last review appear safe to merge.

Summary

This PR keeps image prompts and input-image references out of tool events and saved memory, names the provider on approval cards, and shows generated attachments in chat.

  • Since the last review, only BotThreadLanding.markdown.test.ts changed. Its checks now match the code that shows turn details once.
  • No new actionable issues were found.
  • Both earlier Greptile threads were manually resolved without explanatory replies. Neither supplied a comment number.

Reviews (3) · Last reviewed commit: "test(web): assert step meters land on th..."

Comment thread apps/server/src/image-generation/toolContent.ts Outdated
Comment thread apps/web/src/components/roster/botConversationPresentation.ts
…details

imageConsentDetail preferred allowProvider over an explicit provider pin,
but imageRoutePlan honors the pin first, so a retry carrying both showed
a card for one provider while another received the images. The card now
names the pin.

Keeping an attachment post beside the final answer also repeated the
turn's step meter and plugin cards on both rows. Turn details now land
on the last visible assistant row of the turn in bot and group chats.

Model: Devin (Cognition AI), #460
@devin-ai-integration

Copy link
Copy Markdown

Fixed in d355d3c. imageRoutePlan honors an explicit provider as the pin (consented order only reorders within candidates), so the card now names provider ?? allowProvider. Added toolContent.test.ts covering both the consent retry and the mismatch case.

@devin-ai-integration

Copy link
Copy Markdown

Fixed in d355d3c — same root cause as the Devin Review thread: the card now names provider ?? allowProvider, matching imageRoutePlan's pin. On the fallback half of the finding: a consented provider failing and falling back to the originally intended provider is the defined fallback path — the intended provider was never consent-gated since the images were addressed to it from the start. Only the naming mismatch was a real bug.

@devin-ai-integration

Copy link
Copy Markdown

Fixed in d355d3c. New lastAssistantMessageIdByTurn helper in botConversationPresentation.ts picks the one assistant row per turn that carries shared details; stepMeter and pluginResults are gated on it in both BotThreadLanding and GroupThreadLanding. Behavior test added in ThreadLanding.delegations.test.tsx ("renders turn details once, on the last assistant row of the turn").

@devin-ai-integration

Copy link
Copy Markdown

Covered on two levels in d355d3c and the earlier web commit: visibleBotChatMessages has unit tests proving attachment posts stay visible next to the final answer, and ThreadLanding.delegations.test.tsx now renders BotThreadLanding and asserts the attachment row + final row both mount AssistantMessageRow (attachments render inside it since 10a90a2). Verified end to end with a seeded fixture — the generated JPEG paints inline under the assistant reply (screenshots in the PR body). A live provider e2e is out of scope for CI (no real subscriptions).

The source check pinned the old stepMeters.get(message.turnId) lookup.
It now asserts the once-per-turn gating alongside the meter render.

Model: Devin (Cognition AI), #460

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

area:connectors Plugin and MCP connector runtime. size:L type:provider Agent provider contribution. vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant