Skip to content

Delete four orphaned input-screen feature flags - #9453

Merged
malmstein merged 1 commit into
developfrom
chore/david/delete_orphaned_input_screen_flags
Aug 10, 2026
Merged

Delete four orphaned input-screen feature flags#9453
malmstein merged 1 commit into
developfrom
chore/david/delete_orphaned_input_screen_flags

Conversation

@malmstein

@malmstein malmstein commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Task/Issue URL: https://app.asana.com/1/137249556945/project/1211654189969294/task/1215377998399622
Tech Design URL (if applicable):
API Proposals URL(s) (if applicable): Pending — see note below.

Description

Deletes four input-screen feature flags that were already orphaned: the flag was still cached into state in RealDuckChat, but nothing read that state once the fullscreen Input Screen was removed (Steps 2 and 3).

Flags removed, with their production reader count before this PR:

Flag Backing state Production readers
inputScreenBottomBarSupport DuckChatInternal.inputScreenBottomBarEnabled 0
showMainButtonsInInputScreen DuckChatInternal.showMainButtonsInInputScreen 0
showInputScreenAutomaticallyOnNewTab DuckAiFeatureState.showInputScreenAutomaticallyOnNewTab 0
showInputScreenOnSystemSearchLaunch DuckAiFeatureState.showInputScreenOnSystemSearchLaunch 0

"Production readers" excludes RealDuckChat itself and tests. Note SystemSearchViewModel no longer reads showInputScreenOnSystemSearchLaunch despite the name, and inputScreenMainButtonsEnabled was assigned in cacheConfig() and never read anywhere.

Also removes the backing MutableStateFlows, the cached fields, the cacheConfig() / cacheUserSettings() reads, the DuckChatInternal declarations, the FakeDuckChatInternal overrides, and the eight RealDuckChatTest tests that only covered these flags.

167 deletions, no additions. No behaviour change — every deleted path was unreachable.

Two of the four flags were surfaced on DuckAiFeatureState in duckchat-api, so this is a deletion-only public API change. Flagging for a decision on whether a removal-only -api delta needs its own API Proposal or can ride along; happy to file one if the team wants it.

Deliberately not in scope, because they still have live readers — these are Step 6b:

  • nativeInputField — needs hardcoding to native-on, not deleting
  • duckAiInputScreen — still read by DuckChatSettingsViewModel
  • DuckAiFeatureState.showInputScreen — still read by BrowserTabViewModel, CtaViewModel and InputScreenDiscoveryFunnel

Steps to test this PR

Nothing should change — this is a regression check

  • Build and install the internal variant
  • Focus the omnibar and confirm the native input field appears and behaves as before, in both top and bottom omnibar positions
  • Open a new tab and confirm the same behaviour as before this PR
  • Launch the app from the search widget and confirm the same behaviour as before this PR
  • Open Settings > Duck.ai and confirm the input screen toggle still shows and works (duckAiInputScreen is untouched by this PR)

Automated

  • ./gradlew :duckchat-impl:testDebugUnitTest — 1850 tests, 0 failures
  • ./gradlew :app:compilePlayDebugUnitTestKotlin — confirms no consumer depended on the removed duckchat-api fields

UI changes

Before After
No UI changes No UI changes

Note

Low Risk
Deletion-only cleanup of dead flags and API surface; no reachable code paths or security/data logic changed.

Overview
Removes four orphaned Duck.ai input-screen remote flags and all code that only fed unreachable state after the fullscreen Input Screen was removed. No new behavior is introduced.

Remote toggles removed from DuckChatFeature: showInputScreenAutomaticallyOnNewTab, showInputScreenOnSystemSearchLaunch, inputScreenBottomBarSupport, and showMainButtonsInInputScreen.

Public API (duckchat-api): DuckAiFeatureState no longer exposes showInputScreenAutomaticallyOnNewTab or showInputScreenOnSystemSearchLaunch.

Implementation: DuckChatInternal drops inputScreenBottomBarEnabled and showMainButtonsInInputScreen; RealDuckChat removes the matching StateFlows, cached fields, and cacheConfig / cacheUserSettings wiring. Tests and FakeDuckChatInternal are updated accordingly.

Runtime impact: None — production had zero readers of these flags outside RealDuckChat and tests.

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

inputScreenBottomBarSupport, showMainButtonsInInputScreen,
showInputScreenAutomaticallyOnNewTab and showInputScreenOnSystemSearchLaunch
were still cached into state in RealDuckChat, but nothing read that state
after the fullscreen Input Screen was removed. Delete the toggles, the
backing flows and cached fields, the two DuckAiFeatureState fields, and
the tests that only covered them.

No behaviour change: each flag had zero production readers.

https://app.asana.com/1/137249556945/project/1211654189969294/task/1215377998399622

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ API Proposal reminder

This PR changes the public surface of one or more -api modules, but the API Proposals field of the PR description is empty. This is a non-blocking reminder — please double-check whether a proposal is needed.

Changed -api source files:

  • duckchat/duckchat-api/src/main/java/com/duckduckgo/duckchat/api/DuckAiFeatureState.kt

To clear this reminder, edit the PR description and either:

  • add the approved API Proposal link(s) in the API Proposals field (one per line), or
  • write None there if this PR does not change the public API (e.g. KDoc, comments, tests).

See the API Proposals section in .claude/docs/contributions.md for details.

@joshliebe joshliebe 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.

Nice cleanup, LGTM!

@joshliebe joshliebe self-assigned this Aug 10, 2026
@malmstein

Copy link
Copy Markdown
Contributor Author

Thanks @joshliebe !

@malmstein
malmstein merged commit 3846515 into develop Aug 10, 2026
22 of 24 checks passed
@malmstein
malmstein deleted the chore/david/delete_orphaned_input_screen_flags branch August 10, 2026 16:12
malmstein added a commit that referenced this pull request Aug 10, 2026
Task/Issue URL:
https://app.asana.com/1/137249556945/project/1204556816597738/task/1217328291440141
Tech Design URL (if applicable):
API Proposals URL(s) (if applicable): None

### Description

> Stacked on #9453 — review that one first. Base is
`chore/david/delete_orphaned_input_screen_flags`.

Flips `nativeInputField` and `nativeChatInput` from
`@Toggle.DefaultValue(INTERNAL)` to `TRUE`, so native input ships on by
default for play users. `nativeInputField` keeps
`@InternalAlwaysEnabled`, so internal builds are unchanged, and both
flags stay remotely killable.

**This is the ship decision for native input on play**, so it wants
rollout sign-off rather than only a code review. What changes for a play
user with no remote config entry:

- the native address bar input field replaces the web-based input
- Duck.ai uses the native chat input: `native-input=true` is appended to
Duck.ai URLs, and the `supportsNativeChatInput` / `supportsNativePrompt`
JS capabilities are signalled
- `DuckAiFeatureState.showInputScreen` is derived with `&&
!isNativeInputFieldEnabled`, so the fullscreen input screen path becomes
unreachable by default

That last point is why this PR deletes nothing. A default flip is a
rollout, not a retirement: the flag stays overridable, so every branch
behind it stays reachable. Deleting the flags and resolving the four
`showInputScreen` call sites moved to [Step
9](https://app.asana.com/1/137249556945/project/1211654189969294/task/1216509602671179).

`RealDuckChatTest.setup()` pins both flags off, so each test opts in
explicitly the way it did under the old default. Without that, 18 tests
fail: 15 URL/launch assertions (the `native-input=true` param is now
appended by default) and 3 input-screen assertions. The enabled paths
were already covered by dedicated tests that set the flags themselves,
so no assertion was rewritten to match the new default. One new test
asserts both flags default to enabled with no stored state.

Also fixes a now-stale comment in `NativeInputToggleSeederPlugin` that
documented the old `INTERNAL` default.

### Steps to test this PR

_Play build gets native input with no remote config_
- [ ] Build and install the play variant with no Duck.ai remote config
override
- [ ] Focus the address bar and confirm the native input field appears
- [ ] Open Duck.ai, send a prompt, and confirm the native chat input is
used (URL carries `native-input=true`)

_Remote kill switch still works_
- [ ] Serve remote config with `nativeInputField` disabled
- [ ] Confirm the play build falls back to the web-based input and the
fullscreen input screen path is reachable again

_Internal build unchanged_
- [ ] Build and install the internal variant and confirm native input
behaves exactly as before this PR

_Automated_
- [ ] `./gradlew :duckchat-impl:testDebugUnitTest` — 1851 tests, 0
failures
- [ ] `./gradlew :app:testPlayDebugUnitTest` — 4197 tests, 0 failures

### UI changes

No new UI is added by this PR, but play users do see a different address
bar: the flip surfaces the existing native input UI to them by default.
Screenshots to be added.

| Before  | After |
| ------ | ----- |
| Play: web-based input | Play: native input field |

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Default-on changes omnibar and Duck.ai input for all play users
without remote config; flags can still be disabled remotely, but rollout
affects a core browsing surface.
> 
> **Overview**
> **Ships native Duck.ai input on play by default** when remote config
omits these flags: `nativeInputField` and `nativeChatInput` now default
to **true** (was `INTERNAL`). `nativeInputField` still has
`@InternalAlwaysEnabled`; both remain remotely killable.
> 
> For play users with no override, the **native address bar field**
replaces the web input, Duck.ai gets **`native-input=true`** on URLs and
native chat-input JS capabilities, and **`showInputScreen`** stays off
because it is gated on `!isNativeInputFieldEnabled`.
> 
> **Tests:** `RealDuckChatTest` setup pins both flags off so existing
cases still opt in explicitly; adds
`whenNoRemoteConfigThenNativeInputFlagsDefaultToEnabled`.
**`NativeInputToggleSeederPlugin`** comment updated to reflect the new
default.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a0b2435. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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