[spec] Configurable running-state behavior for st.chat_input#14682
[spec] Configurable running-state behavior for st.chat_input#14682lukasmasuch wants to merge 4 commits intodevelopfrom
st.chat_input#14682Conversation
Add product spec for a new `submit_mode` parameter that controls widget behavior after submission during script execution. Enables three modes: - `None` (default): current behavior, input stays enabled - `"disabled"`: disables input during script run - `"stoppable"`: transforms submit button into stop button Addresses user requests: - #8323 - Impossible to disable st.chat_input while writing response - #11854 - Turn submit button into stop button Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Spec PR Validation✅ All checks passed! |
There was a problem hiding this comment.
Pull request overview
Adds a product spec proposing a new submit_mode parameter for st.chat_input to control post-submit behavior while the script is running, addressing common chat/LLM UX issues (preventing mid-stream re-submits and enabling a stop button).
Changes:
- Introduces the proposed
submit_modeAPI (None/"disabled"/"stoppable") and expected behavior during a running script. - Documents UX behavior, scoping rules (only the triggering
st.chat_input), edge cases, and alternatives considered. - Adds examples and a rollout checklist for the feature.
| | Name | Example | Pros | Cons | | ||
| |------|---------|------|------| | ||
| | `submit_mode` | `submit_mode="stoppable"` | Focuses on what changes (submit button), concise | Doesn't explicitly mention "during run" | | ||
| | `running` | `running="disabled"` | Short, indicates timing | Ambiguous ("running what?") | | ||
| | `while_running` | `while_running="stoppable"` | Most explicit about timing | Longer, slightly awkward | | ||
| | `busy` | `busy="disabled"` | Shortest, intuitive | Generic, doesn't indicate when it applies | | ||
| | `processing` | `processing="stoppable"` | Clear intent | Implies CPU work specifically | | ||
| | `on_submit_running` | `on_submit_running="disabled"` | Explicit about trigger+state | Very long | | ||
|
|
There was a problem hiding this comment.
The “Parameter Name Options” table also starts rows with ||, which will render an extra empty column in GitHub Markdown. Switch to single | delimiters so the comparison table renders properly.
There was a problem hiding this comment.
Already fixed in ce4c067 - the Parameter Name Options table now uses correct single | delimiters.
There was a problem hiding this comment.
Summary
This PR adds a product spec for a new submit_mode parameter on st.chat_input that controls widget behavior after submission during script execution. Three modes are proposed: None (current default — input stays enabled), "disabled" (disables input during the run), and "stoppable" (transforms the submit button into a stop button). The PR contains no code changes — only the new spec document at specs/2026-04-08-chat-input-submit-mode/product-spec.md. The spec addresses two well-upvoted community issues (#8323, #11854).
All three reviewers (claude-4.6-opus-high-thinking, gemini-3.1-pro, gpt-5.3-codex-high) completed their reviews and reached unanimous agreement on approval.
Code Quality
The spec is well-structured and follows the established template (specs/YYYY-MM-DD-template/product-spec.md) closely, with all required sections: frontmatter, Summary, Problem, Proposal, Alternatives Considered, Out of Scope, and Checklist. All reviewers agreed the quality and depth are consistent with other recent specs in the repository.
The proposed API design aligns well with Streamlit's API design principles:
- Uses
Literaltypes over booleans (Principle #16) - Follows the emerging
*_modenaming pattern (Principle #11) - Defaults to
Nonefor backward compatibility (Principles #3, #26) - Keyword-only parameter after
*separator (Principle #17)
The problem section is thorough, with concrete workaround examples and linked issues showing real user demand. The alternatives section is well-reasoned, covering multiple naming options and API shape alternatives with clear pros/cons.
Test Coverage
No code changes — not applicable for this spec PR. All reviewers agreed this is appropriate. For the implementation PR, reviewers collectively recommend:
- Frontend unit tests for state transitions (
None/disabled/stoppable) and multi-chat-input scoping - E2E coverage for stop-button behavior during
st.write_streamand rerun completion transitions - Test cases for interruption behavior, partial-stream output handling, and re-enable timing
Backwards Compatibility
All reviewers confirmed no breaking changes. The spec explicitly designs for backward compatibility: submit_mode=None preserves current behavior exactly. This is a new optional parameter with no changes to existing API signatures.
Security & Risk
No code changes, so no direct security risk. The spec notes that submit_mode="stoppable" reuses the existing stop_script BackMsg mechanism. The stop mechanism doesn't introduce new server-side capabilities. Security-sensitive behavior (e.g., stop message transport and session binding) should be reviewed in the implementation PR.
External test recommendation
- Recommend external_test: No
- Triggered categories: None
- Evidence:
specs/2026-04-08-chat-input-submit-mode/product-spec.md: Spec document only — no code changes to routing, auth, WebSocket, embedding, assets, CORS, storage, or security headers
- Suggested external_test focus areas:
- None for this PR. External test coverage should be assessed when the implementation PR is submitted, particularly around
stop_scriptBackMsg behavior in embedded/SiS contexts and run-state transitions in Cloud/SiS-like environments.
- None for this PR. External test coverage should be assessed when the implementation PR is submitted, particularly around
- Confidence: High
- Assumptions and gaps: Assessment is based on the spec document containing zero code changes. The implementation PR will need its own external test risk assessment.
Accessibility
No frontend code changes. The spec mentions that in "disabled" mode "The text area and all buttons (submit, file upload, voice) are disabled" and that "focus is preserved," which is good for accessibility. For the implementation PR, reviewers recommend ensuring:
- Proper
aria-disabledand focus management - Stop-button semantics include accessible name/state
- Keyboard operability parity between submit and stop buttons
Recommendations
-
Clarify
disabled=True+submit_modeinteraction: The spec doesn't explicitly address what happens whendisabled=Trueandsubmit_modeare both set. Add an edge case entry to prevent ambiguity during implementation (e.g.,disabled=Truetakes precedence). (Raised by claude-4.6-opus-high-thinking; not addressed by other reviewers but a valid spec gap.) -
Specify button states for
"stoppable"mode: The"disabled"section explicitly lists which buttons are disabled, but the"stoppable"section only mentions the text area. Clarify whether file upload and voice buttons are also disabled in stoppable mode. (Raised by claude-4.6-opus-high-thinking.) -
Avoid exposing implementation details in spec: The edge case for "Stop during streaming" references
StopExceptionby name. Consider rephrasing to describe user-observable behavior, keeping the spec implementation-agnostic. (Raised by claude-4.6-opus-high-thinking.) -
Implementation PR should include thorough test coverage: All reviewers agreed that the eventual implementation needs comprehensive unit and E2E tests covering state transitions, multi-widget scoping, fragment reruns, and interruption behavior. (Consensus across all three reviewers.)
Verdict
APPROVED: Unanimous approval from all three reviewers. This is a well-structured product spec that follows Streamlit conventions, addresses real user pain points with a clean and extensible API design, and thoroughly documents behavior, edge cases, and alternatives. Minor spec clarifications around disabled/submit_mode interaction and "stoppable" button states are recommended but are not blocking — they can be resolved during implementation.
This is a consolidated AI review by claude-4.6-opus-high-thinking, synthesizing reviews from claude-4.6-opus-high-thinking, gemini-3.1-pro, and gpt-5.3-codex-high.
This review also includes 4 inline comment(s) on specific code lines.
st.chat_input
- Initialize session_state.disabled in workaround example - Fix CSS selector to use correct attribute (data-test-script-state) - Clarify focus restoration behavior after widget re-enables - Explicitly list which sub-controls are disabled vs enabled in stoppable mode - Add edge case for disabled=True interaction with submit_mode - Rephrase StopException to describe user-observable behavior Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Summary
This PR adds a product spec for a new submit_mode parameter on st.chat_input that controls widget behavior after submission during script execution. The spec proposes three modes: None (current behavior, preserving backward compatibility), "disabled" (disables input during the run), and "stoppable" (transforms the submit button into a stop button). This is a spec-only PR — a single markdown file is added at specs/2026-04-08-chat-input-submit-mode/product-spec.md with no code changes.
Reviewer consensus: All three reviewers (claude-4.6-opus-high-thinking, gemini-3.1-pro, gpt-5.3-codex-high) approved the PR unanimously. No critical or blocking issues were raised.
Code Quality
Not applicable — this PR contains only a product spec document. All reviewers agree the spec is well-structured, clearly defines the problem, proposes a thoughtful API, and covers edge cases and alternatives.
The spec follows good practices from specs/AGENTS.md and aligns with the Streamlit API Design Principles:
- Problem First, Solution Second: Links two GitHub issues, describes user pain points with concrete workaround examples.
- Present Options, Not Edicts: Compares 6 parameter name options and 3 API shape alternatives with tradeoffs.
- Start Minimal, Document Out-of-Scope: Explicitly defers "custom running indicator" to future work.
- Show Code, Not Just Words: Includes concrete code examples for both modes.
- Uses
Literaltypes over booleans (Principle #16), keyword-only parameter placement (Principle #17), extends an existing command (Principle #18), andNonedefault preserves backward compatibility (Principles #3, #26).
Test Coverage
Not applicable — this is a spec-only PR with no code changes to test. All reviewers agree that when the feature is implemented, the following coverage will be needed:
- Python unit tests for
submit_modeparameter validation and protobuf serialization - Frontend unit tests for disabled/stoppable state transitions and stop button behavior
- E2E tests for both
submit_mode="disabled"andsubmit_mode="stoppable"end-to-end flows (including stop interruption and rerun completion)
Backwards Compatibility
All reviewers agree the proposed API is additive and fully backward-compatible. The submit_mode parameter defaults to None, which preserves the current behavior of st.chat_input. Existing code is unaffected.
Security & Risk
No security concerns. All reviewers agree this is a documentation-only change. When implemented, the "stoppable" mode reuses the existing stop_script BackMsg mechanism and does not introduce new server endpoints, authentication changes, or external dependencies.
External test recommendation
- Recommend external_test: No
- Triggered categories: None
- Evidence:
specs/2026-04-08-chat-input-submit-mode/product-spec.md: Spec-only change; no backend, frontend, proto, or runtime files changed.
- Suggested external_test focus areas: None for this PR. For the future implementation PR, the
stop_scriptBackMsg behavior should be validated on SiS/Cloud and in embedded setups. - Confidence: High (all three reviewers unanimously agree)
- Assumptions and gaps: None — spec-only PRs carry zero external test risk.
Accessibility
Not applicable for this spec-only PR. All reviewers agree the future implementation should address:
- Accessible name (
aria-label) on the stop button (e.g., "Stop generation") aria-disabledand live region announcements for state transitions- Focus management when transitioning between states
- Keyboard operability of the stop button
Recommendations
-
Clarify fragment interaction edge cases (raised by claude-4.6-opus-high-thinking): The spec mentions fragment reruns scoping but does not detail what happens when
chat_inputis at the page level while a fragment is running, or when a fragment-scopedchat_inputtriggers a fragment rerun while the full script continues. A sentence or two of clarification would strengthen the Edge Cases section. -
Clean up the "Generating..." indicator mention (raised by claude-4.6-opus-high-thinking): Line 116 mentions a spinner/indicator as a "may be deferred" implementation detail, but this is already covered in the Out of Scope section (line 225). Consider removing the inline mention or explicitly cross-referencing the Out of Scope item to keep the proposal boundary clean.
-
Consider the parameter name discoverability (raised by claude-4.6-opus-high-thinking, acknowledged in the spec):
submit_modecould be interpreted as controlling how submission works rather than what happens after submission. The alternatives table already acknowledges this ("Doesn't explicitly mention 'during run'"). This is a design judgment call, but worth a second look given Streamlit's emphasis on discoverability (Principle #35). -
Ensure implementation PR includes comprehensive E2E coverage (raised by gpt-5.3-codex-high): The follow-up implementation PR should explicitly cover
submit_mode="stoppable"andsubmit_mode="disabled"across rerun completion and stop interruption flows, as well as telemetry and stop semantics.
Verdict
APPROVED: All three reviewers unanimously approved this well-written product spec. It follows the template conventions, presents alternatives with tradeoffs, addresses edge cases, aligns with Streamlit API design principles, and is ready for design discussion. No code changes to review — minor spec clarifications are suggested but not blocking.
This is a consolidated AI review by claude-4.6-opus-high-thinking, synthesizing reviews from claude-4.6-opus-high-thinking, gemini-3.1-pro, and gpt-5.3-codex-high.
This review also includes 2 inline comment(s) on specific code lines.
| - **Multiple chat inputs**: Only the widget that triggered the run is affected; others remain in their default state. | ||
| - **Fragment reruns**: If the `chat_input` is inside a fragment, the behavior scopes to the fragment rerun, not the full app. | ||
| - **Already running**: If a script is running from a different trigger (button click, etc.), `chat_input` behaves normally per its `disabled` parameter. | ||
| - **`disabled=True` with `submit_mode`**: When `disabled=True` is explicitly set by the developer, the `disabled` parameter takes precedence and `submit_mode` has no effect (the widget is always disabled regardless of run state). |
There was a problem hiding this comment.
question: What should happen when chat_input is at the page level (not inside a fragment) but a fragment is currently running? Conversely, if a fragment-scoped chat_input triggers a fragment rerun, does submit_mode re-enable when the fragment finishes even though the full script may still be running? A sentence or two clarifying these cross-scope interactions would strengthen this section.
There was a problem hiding this comment.
Clarified in 4a54115 - expanded the "Fragment reruns" edge case to describe both scenarios: when a page-level chat_input triggers a full rerun while a fragment is running (fragment continues, chat_input re-enables after full script), and when a fragment-scoped chat_input triggers a fragment rerun (submit_mode behavior scopes to fragment lifecycle).
| +------------------------------------------------------------------+ | ||
| ``` | ||
|
|
||
| ### Examples |
There was a problem hiding this comment.
suggestion: This "Generating..." indicator note is an implementation detail that blurs the proposal boundary. Consider moving it to the "Out of Scope (Future Work)" section alongside the existing running_placeholder bullet (line 225), or removing it here since it is already covered there.
There was a problem hiding this comment.
Already addressed in 2e07cad - the "Generating..." indicator note was removed from the Visual Design section. It was already covered in the "Out of Scope (Future Work)" section as the running_placeholder bullet point.
…mode Expanded the "Fragment reruns" edge case to address review feedback about cross-scope interactions: what happens when a page-level chat_input triggers a run while a fragment is running, and vice versa. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Describe your changes
Product spec for a new
submit_modeparameter onst.chat_inputthat controls widget behavior after submission during script execution:submit_mode=None(default): current behavior, input stays enabledsubmit_mode="disabled": disables input during script runsubmit_mode="stoppable": transforms submit button into stop buttonGitHub Issue Link (if applicable)
st.chat_inputinto stop button #11854 - Turn submit button into stop buttonTesting Plan
Agent metrics