Skip to content

Validate /goal objective length in TUI#20746

Merged
etraut-openai merged 4 commits into
mainfrom
etraut/limit-goal-length
May 5, 2026
Merged

Validate /goal objective length in TUI#20746
etraut-openai merged 4 commits into
mainfrom
etraut/limit-goal-length

Conversation

@etraut-openai
Copy link
Copy Markdown
Collaborator

@etraut-openai etraut-openai commented May 2, 2026

Why

Long /goal definitions currently reach lower-level goal validation and can produce an opaque failure. This bug was reported by a user. Pasted instruction blocks are especially confusing because the composer can still contain a paste placeholder before expansion, which may otherwise fall into the generic prompt-size error path.

There was also a related paste edge case where /goal followed by a multiline block whose first pasted line was blank looked like a bare /goal command. That showed the goal usage/summary instead of setting the pasted objective.

What Changed

This adds TUI-side preflight validation for /goal <objective> using the shared MAX_THREAD_GOAL_OBJECTIVE_CHARS limit. Oversized typed, queued, and pasted goal objectives now fail locally with a goal-specific message that recommends putting longer instructions in a file and referencing that file from the goal.

The TUI now also lets inline-argument slash commands consume later-line arguments before treating the first line as a bare command, so /goal followed by blank lines and then objective text sets the goal instead of opening the bare /goal flow.

Manual Testing

  1. Start the TUI with goals enabled and an active session.
  2. Submit /goal followed by exactly 4,000 objective characters. It should continue through the normal goal-setting path.
  3. Submit /goal followed by 4,001 objective characters. It should not set a goal, and should show Goal objective is too long: 4,001 characters. Limit: 4,000 characters. followed by the guidance to put longer instructions in a file and reference that file from the goal.
  4. Type /goal , paste a large block that becomes a [Pasted Content ... chars] placeholder, then submit. It should validate the expanded pasted text and show the goal-specific file guidance rather than the generic prompt-size error.
  5. Type /goal , paste a multiline block whose first line is blank, then submit. It should set the objective from the non-blank pasted content instead of showing Usage: /goal <objective> or the bare goal summary.
  6. While a turn is running, queue an oversized /goal command. When the queue drains, it should show the same goal-specific error and should not emit a goal-setting request.

Copy link
Copy Markdown
Contributor

@fcoury-oai fcoury-oai left a comment

Choose a reason for hiding this comment

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

Confirmed working as intended with a minor optional finding.

Code looks good 👍

SlashCommandDispatchSource::Live => GoalObjectiveValidationSource::Live,
SlashCommandDispatchSource::Queued => GoalObjectiveValidationSource::Queued,
};
if !self.goal_objective_is_allowed(objective, validation_source) {
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.

I was able to replicate a potential minor issue here. To replicate do the following:

  • send a normal message that take a little while to complete (eg., "send 4 large paragraphs for testing")
  • queue a /goal with more than 4000 characters with Tab
  • queue continue with Tab

Expected: once the first message completes, /goal is sent and the error message is displayed, then continue to the continue message.

Actual: we stop at the /goal error with the continue message still queue.

I think this is more an "unexpected behavior" than an error. So I will leave the decision to fix it or not at your discretion.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, good catch. Fixed.

@etraut-openai etraut-openai merged commit f09e193 into main May 5, 2026
26 checks passed
@etraut-openai etraut-openai deleted the etraut/limit-goal-length branch May 5, 2026 16:55
@github-actions github-actions Bot locked and limited conversation to collaborators May 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants