Skip to content

Conversation

@maorfr
Copy link
Member

@maorfr maorfr commented Jul 30, 2025

part of https://issues.redhat.com/browse/MGMT-21329

Since a conversation is mapped to a single agent, and that agent uses the convesation_id as the session_id we can simplify the flow to use a single ID.
conversation id == agent id, each agent will have a single session_id, the session id is internal detail that we can retrive using:

client.agents.session.list(agent_id=agent_id) 

Proposed flow:

User: Initial query (no conversation id)

LSC: query without conversatin id

  1. create an agent
  2. create a session
  3. serve the query
  4. return the agent_id as the conversation_id

User: query with conversation id

LSC: query with conversatin id

  1. Try to get agent from cache, if the agent isn't in the cache, retrieve the agent by conversation_id + rehydrate the agent (create a new one and override the id) + add to cache.
  2. list sessions (there should only be one)
  3. use the session to serve the query
  4. return agent_id as conversaition_id

we keep using an agent cache with @lru_cache

previous art: https://gitlab.cee.redhat.com/ask-red-hat/backend/ifd-backend-api/-/blob/develop/ifd/core/agents/llama_stack.py?ref_type=heads#L73-80

Summary by CodeRabbit

  • Refactor

    • Improved conversation and agent management by removing internal caches and mappings.
    • Session and agent IDs are now directly assigned and retrieved via client API for better session handling.
  • Tests

    • Updated unit tests to support the new session and agent retrieval approach.
    • Removed dependencies on internal caches and mappings while preserving thorough test coverage.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 30, 2025

Walkthrough

This change removes the global conversation-to-agent ID mapping and explicit TTLCache-based agent caching from the codebase. Instead, agent retrieval and session management now rely directly on client API calls. Agent IDs are assigned from conversation IDs, and session IDs are explicitly handled. All related test code is updated to eliminate references to the removed caches and mappings.

Changes

Cohort / File(s) Change Summary
Conversation Endpoint Refactor
src/app/endpoints/conversations.py
Removed global conversation_id_to_agent_id dictionary and all lookups; agent ID is now directly set from conversation ID in conversation retrieval and deletion handlers. Changed session retrieval from client.agents.session.retrieve to client.agents.session.list(...).data[0]. Updated type annotation for simplify_session_data parameter and removed redundant model_dump() call.
Query Endpoint Refactor
src/app/endpoints/query.py
Removed global TTLCache _agent_cache and mapping import; get_agent now attempts to retrieve existing agent via client API, suppressing errors; if found, deletes newly created agent and reassigns conversation ID; session ID retrieved from existing agent's sessions; if not found, creates new session and uses new agent ID as conversation ID. Updated get_agent signature to return (Agent, conversation_id, session_id). Updated /query endpoint and retrieve_response to use session ID in agent.create_turn. Removed explicit caching and mapping.
Streaming Query Endpoint Refactor
src/app/endpoints/streaming_query.py
Removed global TTLCache and mapping import; async get_agent updated to attempt retrieval of existing agent via client API, suppressing errors; deletes newly created orphan agent if existing found; reassigns conversation ID and retrieves session ID from existing agent; creates new session if none found. Updated get_agent signature to return (AsyncAgent, conversation_id, session_id). Updated retrieve_response to use session ID in agent.create_turn and logging. Removed explicit cache management.
Conversation Endpoint Tests Update
tests/unit/app/endpoints/test_conversations.py
Removed import and all references to conversation_id_to_agent_id; deleted fixture setup_conversation_mapping; removed all test code that manipulated the mapping; tests continue to patch config and mock client behaviors without explicit mapping manipulation.
Query Endpoint Tests Update
tests/unit/app/endpoints/test_query.py
Updated all calls to get_agent to unpack three return values (agent, conversation_id, session_id); removed import and references to internal _agent_cache; removed cache clearing in fixtures; deleted tests inserting or asserting agents in _agent_cache; added mocks for session retrieval; updated assertions to verify session ID usage; no other test logic changed.
Streaming Query Endpoint Tests Update
tests/unit/app/endpoints/test_streaming_query.py
Updated all calls to async get_agent to unpack three return values (agent, conversation_id, session_id); removed import and references to internal _agent_cache; removed cache clearing in fixtures; deleted all lines setting or asserting cache entries; updated assertions to verify session ID usage; tests now focus on agent behavior without internal cache checks.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant API_Endpoint
    participant Agent

    Client->>API_Endpoint: Request (with conversation_id)
    API_Endpoint->>Agent: get_agent(conversation_id) via client API
    Note right of API_Endpoint: agent_id = conversation_id\nsession_id retrieved from agent sessions
    Agent-->>API_Endpoint: Agent instance, conversation_id, session_id
    API_Endpoint->>Agent: agent.create_turn(session_id, ...)
    API_Endpoint-->>Client: Response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

In fields of code where mappings grew,
The caches fell, as logic flew.
Now agent IDs and sessions meet
Direct and swift, no need to cheat.
The tests are lighter, bugs take flight—
A rabbit hops in pure delight! 🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66daff6 and 179b027.

📒 Files selected for processing (1)
  • tests/unit/app/endpoints/test_streaming_query.py (38 hunks)
🔇 Additional comments (11)
tests/unit/app/endpoints/test_streaming_query.py (11)

317-318: LGTM: Mock updated to match new get_agent API

The mock return value correctly reflects the new 3-tuple format (agent, conversation_id, session_id) returned by the refactored get_agent function.


334-335: LGTM: Correctly using session_id in create_turn

The call to create_turn now properly uses session_id instead of conversation_id, which aligns with the refactored agent-session relationship.


1214-1237: LGTM: Test properly handles new get_agent API

The test correctly unpacks the 3-tuple return value and validates the relationship between conversation_id and agent_id. The assertion on line 1236 assumes that mock_agent._agent_id equals the conversation_id, which aligns with the PR objective of using a single ID for both conversation and agent.


1240-1287: LGTM: Proper error handling test for non-existent agent

The test correctly verifies the fallback behavior when an agent cannot be retrieved from llama stack. The mock setup with ValueError and the assertions validate that a new agent is created when the requested conversation_id doesn't exist.


1331-1344: LGTM: Correct handling of new conversation flow

The test properly validates the behavior when conversation_id=None, ensuring that a new agent is created and its agent_id becomes the conversation_id. This aligns with the PR objective of consolidating IDs.


354-355: LGTM: Consistent API updates across all test functions

All test functions have been systematically updated with the same pattern:

  • Mock get_agent returns 3-tuple (agent, conversation_id, session_id)
  • create_turn calls use session_id parameter consistently

This demonstrates thorough and consistent test maintenance following the API refactoring.

Also applies to: 404-405, 455-456, 508-509, 563-564, 616-617


371-372: LGTM: Consistent session_id usage in create_turn calls

All create_turn calls have been updated to use the explicit session_id parameter instead of deriving it from conversation_id. This correctly implements the new session management approach described in the PR objectives.

Also applies to: 419-420, 470-471, 535-536, 578-579, 631-632


1388-1400: LGTM: Comprehensive test coverage for get_agent scenarios

These test functions provide thorough coverage of different get_agent scenarios:

  • Empty shields lists
  • Multiple MCP servers
  • No-tools configuration
  • Various parameter combinations

All tests consistently use the 3-tuple unpacking pattern and validate the correct relationship between conversation_id and agent.agent_id.

Also applies to: 1447-1459, 1789-1802, 1853-1866


1560-1568: LGTM: Proper authentication token handling

The test correctly validates that authentication tokens are extracted from the auth tuple and passed through to retrieve_response. The addition of the mcp_headers parameter is consistent with the API updates.


1673-1674: LGTM: Consistent use of fake IDs in no_tools tests

The use of "fake_conversation_id" and "fake_session_id" in these specific test scenarios is appropriate and helps distinguish the no_tools functionality tests from other test cases.

Also applies to: 1685-1686, 1723-1724, 1735-1736


1-1878: Excellent refactoring execution across the entire test suite

The test file has been comprehensively updated to reflect the architectural changes:

Systematic API updates: All get_agent mocks and calls updated to handle 3-tuple returns
Consistent session management: All create_turn calls now use explicit session_id
Comprehensive coverage: Tests cover all scenarios including error cases, no-tools mode, and various configurations
Clean cache removal: No references to the removed agent cache functionality
Proper ID consolidation: Tests validate the conversation_id/agent_id relationship as intended

The changes align perfectly with the PR objectives of simplifying conversation-agent-session relationships and removing cache dependencies.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@maorfr maorfr force-pushed the agent-conversation-mapping branch from 5152a7d to 0c16c16 Compare July 30, 2025 10:42
@maorfr maorfr marked this pull request as draft July 30, 2025 11:04
Copy link
Contributor

@manstis manstis left a comment

Choose a reason for hiding this comment

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

I welcome this improvement; but wonder if we can go a step further.

See my comments.

Copy link
Contributor

@manstis manstis left a comment

Choose a reason for hiding this comment

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

LGTM 👍

But would appreciate others' reviews too.

@tisnik @umago etc

Copy link
Contributor

@eranco74 eranco74 left a comment

Choose a reason for hiding this comment

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

Looks great!
I do think we should keep the agent cache, but I guess we can start without and see if this has an impact on performance

Copy link
Contributor

@umago umago left a comment

Choose a reason for hiding this comment

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

Question inline

Copy link
Contributor

@eranco74 eranco74 left a comment

Choose a reason for hiding this comment

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

You have an issue with the session!
The conversation id you return from get_agent is later used as the session_id.
Instead you should list the agent sessions and use the one you find, if you didn't find an existing session -> create a new one.

@maorfr maorfr force-pushed the agent-conversation-mapping branch from dec00e9 to 7f61218 Compare July 30, 2025 20:58
@maorfr maorfr marked this pull request as ready for review July 30, 2025 21:01
@maorfr
Copy link
Member Author

maorfr commented Jul 30, 2025

while this code is ugly - it works.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/app/endpoints/streaming_query.py (1)

559-559: Logging shows conversation_id instead of session_id

The debug log still shows "Session ID: %s" but logs conversation_id instead of session_id. This could be confusing for debugging.

Apply this diff to fix the logging:

-    logger.debug("Session ID: %s", conversation_id)
+    logger.debug("Session ID: %s", session_id)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c16c16 and 7f61218.

📒 Files selected for processing (3)
  • src/app/endpoints/conversations.py (3 hunks)
  • src/app/endpoints/query.py (5 hunks)
  • src/app/endpoints/streaming_query.py (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app/endpoints/conversations.py
  • src/app/endpoints/query.py
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/app/endpoints/streaming_query.py (2)
src/utils/suid.py (1)
  • get_suid (6-12)
src/app/endpoints/query.py (1)
  • get_agent (73-109)
🔇 Additional comments (5)
src/app/endpoints/streaming_query.py (5)

4-4: Import added for error suppression

The suppress import is correctly added to handle the ValueError when retrieving non-existent agents.


58-58: Function signature updated for explicit session handling

The return type change from tuple[AsyncAgent, str] to tuple[AsyncAgent, str, str] correctly reflects the new explicit session ID handling, maintaining consistency with the synchronous version in query.py.


60-64: Agent retrieval logic correctly implemented

The async agent retrieval with error suppression is properly implemented. The suppress(ValueError) appropriately handles cases where the agent doesn't exist, allowing the flow to continue with new agent creation.


530-537: Function call correctly updated for three-value return

The unpacking of the get_agent return value is correctly updated to handle the new session_id parameter.


568-568: Session ID correctly used in agent.create_turn

The explicit use of session_id instead of conversation_id as the session parameter is correct and aligns with the PR objectives of proper session management.

Copy link
Contributor

@umago umago 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 the patch, a few other comments inline. Maybe I'm missing something but, the logic here seems quite confusing to me

existing_agent_id = None
if conversation_id:
with suppress(ValueError):
existing_agent_id = client.agents.retrieve(agent_id=conversation_id).agent_id
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm trying to get my head around the logic here. If conversation_id is provided and an Agent already exists that matches that conversation_id (agent_id == conversation_id). Why not return the existing agent at this point ?

Why do we need to create a new agent, replace it's agent_id with conversation_id, delete the old agent and then return ?

Copy link
Contributor

Choose a reason for hiding this comment

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

client.agents.retrieve returns the agent configuration, not an agent instance.
We need to call this method to verify that the agent exists in the llama-stack, but we still need to create the agent instance later.

if existing_agent_id and conversation_id:
orphan_agent_id = agent.agent_id
agent.agent_id = conversation_id
client.agents.delete(agent_id=orphan_agent_id)
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this delete happens before we change the ID of the newly created agent to conversation_id ? Otherwise, this delete could also affect the new agent as it's ID will now match here ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Note agent_id=orphan_agent_id, this deletes the newly created agent from the llama-stack server DB

Copy link
Contributor

Choose a reason for hiding this comment

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

@umago IDK if this could help explain: #317 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks! I was on PTO yesterday, reading thru it now. It does makes sense. Thank you

@maorfr maorfr force-pushed the agent-conversation-mapping branch from 7f61218 to 8ae4803 Compare August 4, 2025 06:01
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f61218 and 8ae4803.

📒 Files selected for processing (6)
  • src/app/endpoints/conversations.py (3 hunks)
  • src/app/endpoints/query.py (5 hunks)
  • src/app/endpoints/streaming_query.py (5 hunks)
  • tests/unit/app/endpoints/test_conversations.py (0 hunks)
  • tests/unit/app/endpoints/test_query.py (0 hunks)
  • tests/unit/app/endpoints/test_streaming_query.py (0 hunks)
💤 Files with no reviewable changes (3)
  • tests/unit/app/endpoints/test_query.py
  • tests/unit/app/endpoints/test_conversations.py
  • tests/unit/app/endpoints/test_streaming_query.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app/endpoints/conversations.py
  • src/app/endpoints/streaming_query.py
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/app/endpoints/query.py (2)
src/utils/suid.py (1)
  • get_suid (6-12)
src/app/endpoints/streaming_query.py (1)
  • get_agent (51-89)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e_tests
🔇 Additional comments (5)
src/app/endpoints/query.py (5)

3-3: LGTM: Import necessary for new error handling.

The suppress import is correctly added to support the new agent retrieval logic that gracefully handles cases where an agent doesn't exist.


81-81: LGTM: Function signature updated correctly.

The return type change to include session_id aligns with the PR objectives and is consistent with similar changes in the streaming endpoint.


83-86: LGTM: Clean agent retrieval implementation.

The logic correctly checks for existing agents using the client API instead of cache lookup. The use of suppress(ValueError) is appropriate for handling non-existent agents gracefully.


284-284: LGTM: Function call updated correctly.

The unpacking correctly handles the new return signature of get_agent that now includes session_id.


328-328: LGTM: Correct session management.

Using session_id instead of conversation_id in the create_turn call is the correct approach for explicit session management as outlined in the PR objectives.

Copy link
Contributor

@tisnik tisnik left a comment

Choose a reason for hiding this comment

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

LGTM

@maorfr maorfr force-pushed the agent-conversation-mapping branch from a15c75c to f055c77 Compare August 4, 2025 14:18
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
tests/unit/app/endpoints/test_query.py (3)

1084-1112: Consider renaming the test function for clarity.

The function name test_get_agent_cache_hit is misleading since the cache was removed in this refactor. Consider renaming to test_get_agent_existing_conversation or similar to better reflect that it tests retrieving an existing agent by conversation ID.

The test logic correctly verifies the new three-tuple return and session handling.


1114-1157: Consider renaming the test function for clarity.

The function name test_get_agent_cache_miss_with_conversation_id is misleading since the cache was removed. Consider renaming to test_get_agent_nonexistent_conversation to better reflect that it tests the fallback behavior when an agent cannot be retrieved by conversation ID.

The test logic correctly verifies that a new agent is created when the existing one is not found.


1084-1708: Consider adding test coverage for session retrieval edge cases.

While the existing test updates are comprehensive and correctly handle the new get_agent signature, consider adding test coverage for:

  1. What happens when client.agents.session.list returns empty data or multiple sessions
  2. Error handling when session retrieval fails
  3. Verification that client.agents.delete is called when reusing an existing agent (as mentioned in the relevant code snippet)

The current changes are well-executed and maintain consistency across all test functions.

tests/unit/app/endpoints/test_streaming_query.py (1)

1214-1227: Consider updating the test name for clarity.

The test name test_get_agent_cache_hit suggests cache functionality, but according to the PR objectives, the explicit caching mechanism was removed in favor of direct agent retrieval. The test logic correctly mocks AsyncAgent and unpacks the three return values, but the name might be misleading.

Consider renaming to something like test_get_agent_with_existing_conversation_id to better reflect the current functionality.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a15c75c and f055c77.

📒 Files selected for processing (5)
  • src/app/endpoints/query.py (5 hunks)
  • src/app/endpoints/streaming_query.py (5 hunks)
  • tests/unit/app/endpoints/test_conversations.py (4 hunks)
  • tests/unit/app/endpoints/test_query.py (40 hunks)
  • tests/unit/app/endpoints/test_streaming_query.py (38 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/unit/app/endpoints/test_conversations.py
  • src/app/endpoints/streaming_query.py
  • src/app/endpoints/query.py
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/unit/app/endpoints/test_query.py (1)
src/app/endpoints/query.py (1)
  • get_agent (71-110)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e_tests
🔇 Additional comments (13)
tests/unit/app/endpoints/test_query.py (5)

380-382: LGTM!

Mock correctly updated to return the new three-tuple (agent, conversation_id, session_id) matching the refactored get_agent function signature.


395-395: LGTM!

Assertions correctly updated to verify the conversation_id return value from the refactored get_agent function. All assertions consistently check for "fake_conversation_id" which matches the mock setup.

Also applies to: 430-430, 478-478, 529-529, 582-582, 637-637, 690-690, 744-744, 810-810, 884-884, 962-962


417-419: LGTM!

All mock patches consistently updated to return the new three-tuple format. The consistent use of the same mock values across all tests ensures maintainability and reduces confusion.

Also applies to: 465-467, 516-518, 569-571, 624-626, 677-679, 731-733, 797-799, 857-859, 949-951, 1499-1501, 1548-1550


1195-1207: LGTM!

Test functions correctly updated to handle the new three-tuple return from get_agent. The assertions properly verify that:

  • conversation_id equals agent.agent_id (aligning with the PR objective of using agent ID as conversation ID)
  • session_id matches the expected mock value

Also applies to: 1246-1258, 1301-1313


1611-1624: LGTM!

Test functions correctly verify the no_tools parameter functionality while properly handling the new three-tuple return from get_agent. The assertions appropriately validate both the agent creation and the return values.

Also applies to: 1670-1683

tests/unit/app/endpoints/test_streaming_query.py (8)

317-317: LGTM!

The mock return value correctly reflects the updated get_agent function signature that now returns (agent, conversation_id, session_id) instead of the previous (agent, conversation_id).


334-334: LGTM!

The test correctly uses the session_id returned by get_agent in the create_turn call, reflecting the updated session management approach.


354-354: LGTM!

All these changes consistently follow the updated pattern:

  • Mock return values for get_agent now include the third element session_id
  • create_turn calls properly use the session_id parameter

The test updates correctly reflect the refactored session management.

Also applies to: 371-371, 404-404, 419-419, 455-455, 470-470, 508-508, 535-535, 563-563, 578-578, 616-616, 631-631


1248-1250: LGTM!

The mock correctly simulates the scenario where agent retrieval fails, triggering the fallback to create a new agent. This tests the error handling path appropriately.


1275-1275: LGTM!

The test correctly implements the unified ID approach where:

  • The function returns three values as expected
  • The conversation_id is unified with the agent_id
  • The session_id is properly tracked and asserted

This aligns with the PR objective of simplifying the conversation-agent-session relationship.

Also applies to: 1286-1287


1332-1332: LGTM!

These changes consistently implement:

  • Correct unpacking of the three-value return from get_agent
  • Proper assertions validating the unified conversation_id/agent_id approach
  • Appropriate session_id handling

All changes align with the refactoring objectives.

Also applies to: 1343-1344, 1389-1389, 1400-1401, 1448-1448, 1459-1460


1561-1561: Verify the return value assignment.

The variable name result_session_id suggests the function should return a session_id, but streaming_query_endpoint_handler typically returns a StreamingResponse object. This might be an incorrect variable name or an issue with the test logic.

Please verify that the streaming_query_endpoint_handler function signature and return type are correctly reflected in this test.


1674-1674: LGTM!

These final changes maintain consistency with the refactoring approach:

  • Proper 3-tuple returns from mocked get_agent calls
  • Correct conversation_id assertions reflecting the unified ID approach
  • Appropriate session_id handling throughout

All changes support the simplified conversation-agent-session relationship as intended.

Also applies to: 1686-1686, 1724-1724, 1736-1736, 1790-1790, 1802-1803, 1854-1854, 1866-1867

@maorfr maorfr force-pushed the agent-conversation-mapping branch from eb35db5 to baab097 Compare August 4, 2025 15:20
@tisnik
Copy link
Contributor

tisnik commented Aug 4, 2025

@eranco74 also PTAL

Copy link
Contributor

@eranco74 eranco74 left a comment

Choose a reason for hiding this comment

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

just nits

assert exc_info.value.status_code == status.HTTP_503_SERVICE_UNAVAILABLE
assert "Unable to connect to Llama Stack" in exc_info.value.detail["response"]

def test_llama_stack_not_found_error(self, mocker, setup_configuration):
Copy link
Contributor

Choose a reason for hiding this comment

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

Why delete the test?



def test_get_agent_cache_hit(prepare_agent_mocks):
def test_get_agent_cache_hit(prepare_agent_mocks, mocker):
Copy link
Contributor

Choose a reason for hiding this comment

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

we no longer have cache...
yet we want to test this case (rehydration) just need to rename the test

conversation_id=conversation_id,
)

# Assert cached agent is returned
Copy link
Contributor

Choose a reason for hiding this comment

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

no cache

):
"""Test get_agent function when conversation_id is provided but agent not in cache."""
mock_client, mock_agent = prepare_agent_mocks
mock_client.agents.retrieve.side_effect = ValueError(
Copy link
Contributor

Choose a reason for hiding this comment

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

rename the test

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (3)
tests/unit/app/endpoints/test_query.py (3)

1084-1084: Rename test to reflect agent rehydration instead of cache hit

The test name still references "cache hit" but the cache has been removed from the implementation. Consider renaming to test_get_agent_rehydration or similar.


1106-1107: Update comment to remove cache reference

The comment "Assert cached agent is returned" is misleading since the cache has been removed. Update to reflect the actual behavior.


1112-1115: Rename test to remove cache miss reference

The test name references "cache miss" but caching has been removed. Consider renaming to test_get_agent_with_existing_conversation_id or similar.

🧹 Nitpick comments (1)
tests/unit/app/endpoints/test_conversations.py (1)

264-281: Inconsistent mock setup - unused mock object.

The test creates mock_session_obj with a model_dump method (lines 259-260) but then uses mock_session_data directly in the list return value. Since the implementation now uses session.list, the mock should return the raw data format that the actual API would return.

Consider removing the unused mock object:

-        # Mock session data with model_dump method
-        mock_session_obj = mocker.Mock()
-        mock_session_obj.model_dump.return_value = mock_session_data
-
         # Mock LlamaStackClientHolder
         mock_client = mocker.Mock()
         mock_client.agents.session.list.return_value = mocker.Mock(
             data=[mock_session_data]
         )
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between baab097 and 8b26367.

📒 Files selected for processing (3)
  • tests/unit/app/endpoints/test_conversations.py (6 hunks)
  • tests/unit/app/endpoints/test_query.py (40 hunks)
  • tests/unit/app/endpoints/test_streaming_query.py (38 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/unit/app/endpoints/test_streaming_query.py
🔇 Additional comments (3)
tests/unit/app/endpoints/test_conversations.py (3)

118-135: LGTM! Test updates align with function signature changes.

The changes correctly reflect the updated simplify_session_data function that now accepts dictionary data directly instead of objects with a model_dump() method. The test logic and assertions remain sound.


214-214: LGTM! Mock updated to reflect new client API usage.

The change from session.retrieve to session.list correctly aligns with the refactored implementation that switched to using the list method for session retrieval.


400-400: LGTM! Correctly reflects the new ID mapping approach.

The change from VALID_AGENT_ID to VALID_CONVERSATION_ID correctly implements the refactored architecture where conversation IDs are used directly as agent IDs, eliminating the separate mapping.

@eranco74
Copy link
Contributor

eranco74 commented Aug 4, 2025

/lgtm

Signed-off-by: Eran Cohen <[email protected]>
@eranco74 eranco74 force-pushed the agent-conversation-mapping branch from df8f5d1 to 0d5306e Compare August 4, 2025 18:58
@tisnik tisnik merged commit 1370cd6 into lightspeed-core:main Aug 5, 2025
17 of 18 checks passed
@umago
Copy link
Contributor

umago commented Aug 5, 2025

I was on PTO yesterday, but glad this has been reviewed and merged. Appreciate the explanations for my comments @eranco74 @maorfr. Thank you very much!

@maorfr
Copy link
Member Author

maorfr commented Aug 5, 2025

assisted-chat bump: rh-ecosystem-edge/assisted-chat#88

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.

5 participants