Skip to content

Conversation

@codefromthecrypt
Copy link
Collaborator

@codefromthecrypt codefromthecrypt commented Nov 7, 2025

Summary

Wrap session name generation task in session_context so that session ID injection works via api_client.rs.

Without this, rename task requests lacked the goose-session-id header despite having the session ID as a parameter.

This means you wouldn't get all requests grouped by the same ID, as the rename task is orphaned. By backfilling tests on this, we also pave the way to test more difficult otel trace propagation.

Type of Change

  • Feature
  • Bug fix
  • Refactor / Code quality
  • Performance improvement
  • Documentation
  • Tests
  • Security fix
  • Build / Release
  • Other (specify below)

AI Assistance

  • This PR was created or reviewed with AI assistance

I know what I want, but still struggle with rust, so I used an agent to investigate the several ways of how to do what I want. I also used it to adapt some similar mermaid diagrams to this, so it is easy to understand the mechanics.

Testing

Unit test matrix covers success, error, and panic cases. Integration test verifies
goose-session-id header appears in rename task's LLM requests without timing dependencies.

Sets foundation for future trace context propagation tests.

Screenshots/Demos (for UX changes)

Before: ApiClient cannot see the session ID on rename

sequenceDiagram
    participant Agent
    participant ReplyInternal
    participant NamingTask
    participant ApiClient
    participant LLM

    Agent->>ReplyInternal: reply(session_id=abc-123)

    rect rgb(255, 200, 200)
    Note over ReplyInternal,LLM: Before: rename task missing session header
    ReplyInternal->>NamingTask: tokio::spawn(without context)
    NamingTask->>ApiClient: generate_session_name()
    Note over ApiClient: current_session_id() → None
    ApiClient->>LLM: POST /chat (no goose-session-id)
    LLM-->>NamingTask: "Generated Name"
    end

    Note over NamingTask: Testing requires sleep-based timing
Loading

After: ApiClient can see the session ID on rename

sequenceDiagram
    participant Agent
    participant ReplyInternal
    participant NamingTask
    participant ApiClient
    participant LLM

    Agent->>ReplyInternal: reply(session_id=abc-123)

    rect rgb(191, 223, 255)
    Note over ReplyInternal,LLM: After: session ID injected in headers
    ReplyInternal->>NamingTask: tokio::spawn(with_session_id(abc-123))
    NamingTask->>ApiClient: generate_session_name()
    Note over ApiClient: current_session_id() → abc-123
    ApiClient->>LLM: POST /chat (goose-session-id: abc-123)
    LLM-->>NamingTask: "Generated Name"
    end

    Note over ReplyInternal: Process messages...
    ReplyInternal->>NamingTask: await handle
    NamingTask-->>ReplyInternal: complete
    Note over Agent: Task completion verified (deterministic)
Loading

Related

Follows up #5165

Copilot AI review requested due to automatic review settings November 7, 2025 01:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements conditional session naming to avoid overwriting user-provided session names with auto-generated ones. The key change is to check if the user has explicitly set a session name before spawning the automatic naming task, ensuring user preferences are preserved.

  • Adds a check for user_set_name flag before spawning the naming task
  • Waits for the naming task to complete before returning from the reply stream
  • Includes comprehensive test coverage for both user-provided and auto-generated names

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings November 7, 2025 01:58
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codefromthecrypt
Copy link
Collaborator Author

marking draft as I didn't realize we have copilot now, will undraft when done satisfying it.

@codefromthecrypt codefromthecrypt marked this pull request as draft November 7, 2025 02:02
@codefromthecrypt codefromthecrypt force-pushed the perf/skip-session-naming-when-user-provided branch from 3e15d21 to 0e33d76 Compare November 7, 2025 02:07
}

// Wait for naming task to complete if it was spawned
// We don't propagate panics since session naming is a low-value background task
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I added this to satisfy the bot even though it isn't typical in this project to spam the user on things that don't matter. open to advice from a human on it

Copy link
Collaborator

Choose a reason for hiding this comment

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

I disagree with the bot. these warning just go to the log, we won't be looking into it.

@codefromthecrypt codefromthecrypt marked this pull request as ready for review November 7, 2025 02:14
Copilot AI review requested due to automatic review settings November 7, 2025 02:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Collaborator

@DOsinga DOsinga left a comment

Choose a reason for hiding this comment

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

Thanks for doing this. I am not sure I understand the fix though.

you check:
let naming_handle = if !session.user_set_name {

but in the maybe_update_name we have the same check already:

if session.user_set_name {
            return Ok(());
        }

so in which conditions does this not work?

}

// Wait for naming task to complete if it was spawned
// We don't propagate panics since session naming is a low-value background task
Copy link
Collaborator

Choose a reason for hiding this comment

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

I disagree with the bot. these warning just go to the log, we won't be looking into it.

@codefromthecrypt
Copy link
Collaborator Author

@DOsinga good point about the check being internal there. I think probably in the process of trying to make a black box test I may have goofed about this improving the opt-out of the llm call, where it just opts out of spawning a task which could outlive the calling function.

I had several things in progress since several weeks ago on a local branch, and got things mixed up.

So TL;DR: this doesn't obviate the expensive LLM call (already done) all it does is ensure the task doesn't escape the closure of the calling function, which you could argue is a helpful or not. If you want it to escape, it makes things a bit harder to do with replay tests. The fact that there are none yet, that I'm aware of, might reduce the impact on this point.

Over to you.

@codefromthecrypt codefromthecrypt force-pushed the perf/skip-session-naming-when-user-provided branch from 0e33d76 to 0241d55 Compare November 8, 2025 23:01
@codefromthecrypt codefromthecrypt changed the title fix: honor user-provided session names fix: propagate session ID to LLM request headers in rename task Nov 8, 2025
@codefromthecrypt
Copy link
Collaborator Author

@DOsinga so, I chopped this off a pending otel propagation PR, and lost some signal in doing so. I redid this PR for the essentials which are not about whether rename happens or not.

  1. make rename testable without sleeps (bind the task to the outer closure)
  2. fix the missing session ID propagation when renaming the session (Propagate session ID in LLM and MCP requests #5165 missed this)
  3. backfill missing tests so that when we go back for otel, there's an example of how to reach this part.

}
});
let naming_handle = tokio::spawn(
crate::session_context::with_session_id(Some(session_id.clone()), async move {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

without this, even though the session id is propagated manually, it is not available to api_client which looks for it in context, this is the missing piece and also a place for folks to look at when they get around to otel. Any async seams need a hard look or things like session or in the future trace propagation will break.

// Verifies session ID is visible in generate_session_name when user hasn't provided a name.
// When user provides name, maybe_update_name early-returns and session ID isn't captured.
#[test_case(NamingBehavior::Success, None, "Generated Name", true)]
#[test_case(NamingBehavior::Error, None, "initial", true)]
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

error and panic cases here are just to make sure our ignoring the same doesn't accidentally crash the critical code. we didn't have a problem so far, but it is easy to create one, so these cases help IMHO

Wrap session name generation task in session_context to inject session ID header
into LLM requests via api_client.rs. Without this, rename task requests lacked the
goose-session-id header despite having the session ID as a parameter.

Follows up block#5165 by extending session ID propagation to the rename task.

```mermaid
sequenceDiagram
    participant Agent
    participant ReplyInternal
    participant NamingTask
    participant ApiClient
    participant LLM

    Agent->>ReplyInternal: reply(session_id=abc-123)

    rect rgb(255, 200, 200)
    Note over ReplyInternal,LLM: Before: rename task missing session header
    ReplyInternal->>NamingTask: tokio::spawn(without context)
    NamingTask->>ApiClient: generate_session_name()
    Note over ApiClient: current_session_id() → None
    ApiClient->>LLM: POST /chat (no goose-session-id)
    LLM-->>NamingTask: "Generated Name"
    end

    Note over NamingTask: Testing requires sleep-based timing
```

```mermaid
sequenceDiagram
    participant Agent
    participant ReplyInternal
    participant NamingTask
    participant ApiClient
    participant LLM

    Agent->>ReplyInternal: reply(session_id=abc-123)

    rect rgb(191, 223, 255)
    Note over ReplyInternal,LLM: After: session ID injected in headers
    ReplyInternal->>NamingTask: tokio::spawn(with_session_id(abc-123))
    NamingTask->>ApiClient: generate_session_name()
    Note over ApiClient: current_session_id() → abc-123
    ApiClient->>LLM: POST /chat (goose-session-id: abc-123)
    LLM-->>NamingTask: "Generated Name"
    end

    Note over ReplyInternal: Process messages...
    ReplyInternal->>NamingTask: await handle
    NamingTask-->>ReplyInternal: complete
    Note over Agent: Task completion verified (deterministic)
```

Unit test matrix covers success, error, and panic cases. Integration test verifies
goose-session-id header appears in rename task's LLM requests without timing dependencies.

Sets foundation for future trace context propagation tests.

Signed-off-by: Adrian Cole <[email protected]>
@codefromthecrypt codefromthecrypt force-pushed the perf/skip-session-naming-when-user-provided branch from 0241d55 to cf757c7 Compare November 10, 2025 12:26
Copilot AI review requested due to automatic review settings November 10, 2025 12:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codefromthecrypt
Copy link
Collaborator Author

opened #5649 as especially as even trivial workflows need approval, it is annoying to find one missed then repeat the rebase drift loop again. I think we can make it easier to not fail

warn!("Failed to generate session description: {}", e);
}
});
let naming_handle = tokio::spawn(crate::session_context::with_session_id(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@alexhancock so this code and the test below makes sure the session rename task is also grouped by the session.id, which ack is not something people always care about, but if you think systemically there's probably no value in intentionally orphaning it. I noticed your ACP pr, if it top-levels the session ID stuff, will end up needing a similar line in spawn. #5657

@codefromthecrypt
Copy link
Collaborator Author

gonna save our time on this. Anyone who wants to harvest tests or approach here at the point it becomes relevant, do so. Meanwhile I think review and rebase duty is better spent elsewhere.

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