Skip to content

DuckAi/ChatTab: Add New Image from + menu - #9773

Open
karlenDimla wants to merge 3 commits into
feature/karl/duckai-sidebar/plusmenuchangesfrom
feature/feature/karl/duckai-sidebar/plus-newimage
Open

DuckAi/ChatTab: Add New Image from + menu #9773
karlenDimla wants to merge 3 commits into
feature/karl/duckai-sidebar/plusmenuchangesfrom
feature/feature/karl/duckai-sidebar/plus-newimage

Conversation

@karlenDimla

@karlenDimla karlenDimla commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Task/Issue URL: https://app.asana.com/1/137249556945/project/1212087397361015/task/1218350178023317?focus=true
Tech Design URL (if applicable):
API Proposals URL(s) (if applicable): https://app.asana.com/1/137249556945/project/1201462763415876/task/1218365860196482?focus=true

Description

  • New Image (DuckChat.openDuckChatImageGeneration) switches the global model to an accessible image-capable model when needed, falling back to a normal new chat if none support image generation.

Steps to test this PR

nativeDuckAiSidebar enabled — entry visibility

  • Open the "+" chat menu — New Image entry IS visible (with the image icon)
  • The entry below the divider now reads New Search

nativeDuckAiSidebar enabled, currently selected model already supports image generation

  • Start a duck.ai chat from the NTP and set the Duck.ai model to one that supports image generation
  • Tap + and select New Image
  • A new Duck.ai chat tab opens (new session, not the existing chat)
  • The native input is auto-focused on open
  • The Image generation tool is preselected on the input
  • The selected model is unchanged (no model switch occurs) - You might need to submit to see the model

nativeDuckAiSidebar enabled, selected model does NOT support image generation but another accessible model does

  • Start a duck.ai chat from the NTP and set the Duck.ai model to one WITHOUT image-generation support
  • Tap + and select New Image
  • A new Duck.ai chat tab opens (new session, not the existing chat)
  • The selected model is switched to an accessible image-capable model - You might need to submit to see the model
  • The Image generation tool is preselected on the input
  • The native input is auto-focused on open

nativeDuckAiSidebar disabled (via FF inventory)

  • Open the "+" chat menu — New Image entry is NOT visible
  • The entry below the divider still reads New Tab (not "New Search")

Note

Medium Risk
Changes global Duck.ai model selection and new-tab launch plumbing; behavior is gated on model capabilities but affects core chat entry flows.

Overview
Wires the Duck.ai + menu New Image action to open a fresh Duck.ai tab with image generation ready to use, instead of leaving a TODO.

DuckChat.openDuckChatImageGeneration picks an accessible image-capable model when the current one cannot generate images, then launches a new session via BrowserNav with a one-shot forceImageGeneration intent extra. BrowserActivity holds that flag until the new tab’s fragment consumes it on first native input show; the native input stack preselects the image-generation tool and auto-focuses the field when the flag is set. If no suitable model exists, it still opens a normal new chat without forcing the tool.

BrowserTabViewModel.openNewImageDuckChat routes analytics entry points for NTP vs in-page Duck.ai. Tests cover model-switch behavior, navigation flags, widget configuration, and menu handlers.

Reviewed by Cursor Bugbot for commit 8534163. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5f564fc. Configure here.

Comment thread app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt
Fixes a conflicting-overloads compile error in duckchat-impl tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uild

The force-image-generation flag was consumed on every showDuckAI, even
when showNativeInput early-returns because the widget is already attached.
That let an already-open Duck.ai tab (whose widget is shown) clear the
one-shot before the new tab could apply it, so the target tab never
preselected image generation. Gate the consume on isNativeInputShown() so
the flag is only spent when the input will actually be built.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@malmstein malmstein left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Works as expected. I have two comments about the keyboard and the persistent flag stored in the Activity. None are blocker but worth discussing it.

We could leverage the native input state to store those flags if necessary, as opposed to keep flags at the activity / fragment level. In the end we are reading those from the input manager which is able to access the state.

At the bare minimum, we could have a config repository for these things that can be interfaced, injected and tested.

// finishes before the enter morph.
pendingEnterOwnsAnimating = enterStarted

if (forceImageGeneration) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is there a reason we don't do that for all modes? There's a bug report about the keyboard https://app.asana.com/1/137249556945/project/1213881875984009/task/1218357434084408?focus=true I wonder if we can fix it here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can do this as a follow up 👍

// One-shot carried from an "open Duck.ai for image generation" launch. The Duck.ai tab this
// launch creates doesn't exist yet, so the flag is held here and consumed by that tab's fragment
// the first time it shows the native input (see BrowserTabFragment.consumeDuckAiForceImageGeneration).
private var pendingDuckChatForceImageGeneration: Boolean = false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should this live in the native input state instead? not a blocker, but wonder if we can avoid adding flags to represent state outside of the native input

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.

2 participants