Skip to content

Commit 2fe7af7

Browse files
committed
LCORE-390: Update documentation for /query endpoint handler module
1 parent 8cf5462 commit 2fe7af7

File tree

1 file changed

+115
-9
lines changed

1 file changed

+115
-9
lines changed

src/app/endpoints/query.py

Lines changed: 115 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,18 @@ async def query_endpoint_handler(
152152
auth: Annotated[AuthTuple, Depends(auth_dependency)],
153153
mcp_headers: dict[str, dict[str, str]] = Depends(mcp_headers_dependency),
154154
) -> QueryResponse:
155-
"""Handle request to the /query endpoint."""
155+
"""
156+
Handle request to the /query endpoint.
157+
158+
Processes a POST request to the /query endpoint, forwarding the
159+
user's query to a selected Llama Stack LLM or agent and
160+
returning the generated response.
161+
162+
Validates configuration and authentication, selects the appropriate model and provider, retrieves the LLM response, updates metrics, and optionally stores a transcript of the interaction. Handles connection errors to the Llama Stack service by returning an HTTP 500 error.
163+
164+
Returns:
165+
QueryResponse: Contains the conversation ID and the LLM-generated response.
166+
"""
156167
check_configuration_loaded(configuration)
157168

158169
llama_stack_config = configuration.llama_stack_configuration
@@ -242,7 +253,20 @@ async def query_endpoint_handler(
242253
def select_model_and_provider_id(
243254
models: ModelListResponse, model_id: str | None, provider_id: str | None
244255
) -> tuple[str, str, str]:
245-
"""Select the model ID and provider ID based on the request or available models."""
256+
"""
257+
Select the model ID and provider ID based on the request or available models.
258+
259+
Determine and return the appropriate model and provider IDs for
260+
a query request.
261+
262+
If the request specifies both model and provider IDs, those are used. Otherwise, defaults from configuration are applied. If neither is available, selects the first available LLM model from the provided model list. Validates that the selected model exists among the available models.
263+
264+
Returns:
265+
A tuple containing the combined model ID (in the format "provider/model") and the provider ID.
266+
267+
Raises:
268+
HTTPException: If no suitable LLM model is found or the selected model is not available.
269+
"""
246270
# If model_id and provider_id are provided in the request, use them
247271

248272
# If model_id is not provided in the request, check the configuration
@@ -303,16 +327,44 @@ def select_model_and_provider_id(
303327

304328

305329
def _is_inout_shield(shield: Shield) -> bool:
330+
"""
331+
Determine if the shield identifier indicates an input/output shield.
332+
333+
Parameters:
334+
shield (Shield): The shield to check.
335+
336+
Returns:
337+
bool: True if the shield identifier starts with "inout_", otherwise False.
338+
"""
306339
return shield.identifier.startswith("inout_")
307340

308341

309342
def is_output_shield(shield: Shield) -> bool:
310-
"""Determine if the shield is for monitoring output."""
343+
"""
344+
Determine if the shield is for monitoring output.
345+
346+
Return True if the given shield is classified as an output or
347+
inout shield.
348+
349+
A shield is considered an output shield if its identifier
350+
starts with "output_" or "inout_".
351+
"""
311352
return _is_inout_shield(shield) or shield.identifier.startswith("output_")
312353

313354

314355
def is_input_shield(shield: Shield) -> bool:
315-
"""Determine if the shield is for monitoring input."""
356+
"""
357+
Determine if the shield is for monitoring input.
358+
359+
Return True if the shield is classified as an input or inout
360+
shield.
361+
362+
Parameters:
363+
shield (Shield): The shield identifier to classify.
364+
365+
Returns:
366+
bool: True if the shield is for input or both input/output monitoring; False otherwise.
367+
"""
316368
return _is_inout_shield(shield) or not is_output_shield(shield)
317369

318370

@@ -323,7 +375,30 @@ async def retrieve_response( # pylint: disable=too-many-locals
323375
token: str,
324376
mcp_headers: dict[str, dict[str, str]] | None = None,
325377
) -> tuple[str, str]:
326-
"""Retrieve response from LLMs and agents."""
378+
"""
379+
Retrieve response from LLMs and agents.
380+
381+
Retrieves a response from the Llama Stack LLM or agent for a
382+
given query, handling shield configuration, tool usage, and
383+
attachment validation.
384+
385+
This function configures input/output shields, system prompts,
386+
and toolgroups (including RAG and MCP integration) as needed
387+
based on the query request and system configuration. It
388+
validates attachments, manages conversation and session
389+
context, and processes MCP headers for multi-component
390+
processing. Shield violations in the response are detected and
391+
corresponding metrics are updated.
392+
393+
Parameters:
394+
model_id (str): The identifier of the LLM model to use.
395+
query_request (QueryRequest): The user's query and associated metadata.
396+
token (str): The authentication token for authorization.
397+
mcp_headers (dict[str, dict[str, str]], optional): Headers for multi-component processing.
398+
399+
Returns:
400+
tuple[str, str]: A tuple containing the LLM or agent's response content and the conversation ID.
401+
"""
327402
available_input_shields = [
328403
shield.identifier
329404
for shield in filter(is_input_shield, await client.shields.list())
@@ -416,7 +491,8 @@ async def retrieve_response( # pylint: disable=too-many-locals
416491
def validate_attachments_metadata(attachments: list[Attachment]) -> None:
417492
"""Validate the attachments metadata provided in the request.
418493
419-
Raises HTTPException if any attachment has an improper type or content type.
494+
Raises:
495+
HTTPException: If any attachment has an invalid type or content type, an HTTP 422 error is raised.
420496
"""
421497
for attachment in attachments:
422498
if attachment.attachment_type not in constants.ATTACHMENT_TYPES:
@@ -444,7 +520,19 @@ def validate_attachments_metadata(attachments: list[Attachment]) -> None:
444520

445521

446522
def construct_transcripts_path(user_id: str, conversation_id: str) -> Path:
447-
"""Construct path to transcripts."""
523+
"""
524+
Construct path to transcripts.
525+
526+
Constructs a sanitized filesystem path for storing transcripts
527+
based on the user ID and conversation ID.
528+
529+
Parameters:
530+
user_id (str): The user identifier, which will be normalized and sanitized.
531+
conversation_id (str): The conversation identifier, which will be normalized and sanitized.
532+
533+
Returns:
534+
Path: The constructed path for storing transcripts for the specified user and conversation.
535+
"""
448536
# these two normalizations are required by Snyk as it detects
449537
# this Path sanitization pattern
450538
uid = os.path.normpath("/" + user_id).lstrip("/")
@@ -468,7 +556,14 @@ def store_transcript( # pylint: disable=too-many-arguments,too-many-positional-
468556
truncated: bool,
469557
attachments: list[Attachment],
470558
) -> None:
471-
"""Store transcript in the local filesystem.
559+
"""
560+
Store transcript in the local filesystem.
561+
562+
Constructs a sanitized filesystem path for storing transcripts
563+
based on the user ID and conversation ID.
564+
565+
Returns:
566+
Path: The constructed path for storing transcripts for the specified user and conversation.
472567
473568
Args:
474569
user_id: The user ID (UUID).
@@ -513,7 +608,18 @@ def store_transcript( # pylint: disable=too-many-arguments,too-many-positional-
513608
def get_rag_toolgroups(
514609
vector_db_ids: list[str],
515610
) -> list[Toolgroup] | None:
516-
"""Return a list of RAG Tool groups if the given vector DB list is not empty."""
611+
"""
612+
Return a list of RAG Tool groups if the given vector DB list is not empty.
613+
614+
Generate a list containing a RAG knowledge search toolgroup if
615+
vector database IDs are provided.
616+
617+
Parameters:
618+
vector_db_ids (list[str]): List of vector database identifiers to include in the toolgroup.
619+
620+
Returns:
621+
list[Toolgroup] | None: A list with a single RAG toolgroup if vector_db_ids is non-empty; otherwise, None.
622+
"""
517623
return (
518624
[
519625
ToolgroupAgentToolGroupWithArgs(

0 commit comments

Comments
 (0)