Skip to content

CLI providers generate session titles from prompt wrapper instead of user content #7990

@mholtzer-max

Description

@mholtzer-max

Bug Description

When using CLI-based providers (gemini-cli, claude_code, codex, cursor_agent), all new chat sessions are titled ---BEGIN USER MESSAGES--- (or a variation like ---BEGIN USER MESSAGE) instead of a meaningful generated title.

Root Cause

The bug is in the interaction between generate_session_name() in base.rs and generate_simple_session_description() in cli_common.rs.

Step 1generate_session_name() (base.rs line ~662) wraps the user messages in markers before calling the LLM:

let user_text = format!(
    "---BEGIN USER MESSAGES---\n{}\n---END USER MESSAGES---\n\nGenerate a short title for the above messages.",
    context.join("\n")
);
let message = Message::user().with_text(&user_text);

Step 2 — CLI providers short-circuit the LLM call via is_session_description_request() (which matches "four words or less" in the system prompt) and dispatch to generate_simple_session_description() instead.

Step 3generate_simple_session_description() (cli_common.rs line ~43) naively takes the first 4 words of the first user message:

text.split_whitespace()
    .take(4)
    .collect::<Vec<_>>()
    .join(" ")

Since the first user message is the wrapped prompt ("---BEGIN USER MESSAGES---\n<actual content>..."), the first 4 words are "---BEGIN USER MESSAGES--- <first_real_word>" — producing the broken title.

Affected Providers

All CLI-based providers that use cli_common::generate_simple_session_description:

  • gemini_cli.rs (line ~211)
  • claude_code.rs (line ~697)
  • codex.rs (lines ~683, ~1157, ~1177)
  • cursor_agent.rs (line ~337)

Suggested Fix

In cli_common.rs, update generate_simple_session_description to extract the actual user content from within the markers before taking the first 4 words:

.map(|text| {
    // Extract actual content from between the session-naming markers if present
    let actual_text = if let Some(start_idx) = text.find("---BEGIN USER MESSAGES---\n") {
        let after = &text[start_idx + "---BEGIN USER MESSAGES---\n".len()..];
        if let Some(end_idx) = after.find("\n---END USER MESSAGES---") {
            &after[..end_idx]
        } else {
            after
        }
    } else {
        text.as_str()
    };

    actual_text
        .split_whitespace()
        .take(4)
        .collect::<Vec<_>>()
        .join(" ")
})

This fix is isolated to a single function and corrects the behavior for all affected providers simultaneously.

Steps to Reproduce

  1. Configure Goose to use any CLI-based provider (gemini-cli, claude_code, codex, or cursor_agent)
  2. Start a new chat session
  3. Observe that the session title is set to ---BEGIN USER MESSAGES--- instead of a descriptive title

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions