feat: query param validation block label, name, and search (#6397)
* add block label, name, and search query param validation * finishing touches on blocks * remove default for blocks * query changes to api spec * openapi changes * change descriptions
This commit is contained in:
@@ -10045,16 +10045,20 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50,
|
||||||
|
"pattern": "^[a-zA-Z0-9_-]+$"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Labels to include (e.g. human, persona)",
|
"description": "Label to include (alphanumeric, hyphens, underscores only)",
|
||||||
|
"examples": ["human", "persona", "the_label_of-a-block"],
|
||||||
"title": "Label"
|
"title": "Label"
|
||||||
},
|
},
|
||||||
"description": "Labels to include (e.g. human, persona)"
|
"description": "Label to include (alphanumeric, hyphens, underscores only)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "templates_only",
|
"name": "templates_only",
|
||||||
@@ -10075,16 +10079,20 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"pattern": "^[a-zA-Z0-9 _-]+$"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Name of the block",
|
"description": "Name filter (alphanumeric, spaces, hyphens, underscores)",
|
||||||
|
"examples": ["My Agent", "test_tool", "default-config"],
|
||||||
"title": "Name"
|
"title": "Name"
|
||||||
},
|
},
|
||||||
"description": "Name of the block"
|
"description": "Name filter (alphanumeric, spaces, hyphens, underscores)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "identity_id",
|
"name": "identity_id",
|
||||||
@@ -10093,16 +10101,20 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 45,
|
||||||
|
"maxLength": 45,
|
||||||
|
"pattern": "^identity-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Search agents by identifier id",
|
"description": "The ID of the identity in the format 'identity-<uuid4>'",
|
||||||
|
"examples": ["identity-123e4567-e89b-42d3-8456-426614174000"],
|
||||||
"title": "Identity Id"
|
"title": "Identity Id"
|
||||||
},
|
},
|
||||||
"description": "Search agents by identifier id"
|
"description": "The ID of the identity in the format 'identity-<uuid4>'"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "identifier_keys",
|
"name": "identifier_keys",
|
||||||
@@ -10231,16 +10243,20 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50,
|
||||||
|
"pattern": "^[a-zA-Z0-9_-]+$"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Search blocks by label. If provided, returns blocks that match this label. This is a full-text search on labels.",
|
"description": "Search blocks by label. If provided, returns blocks whose label matches the search query. This is a full-text search on block labels.",
|
||||||
|
"examples": ["human", "persona", "the_label_of-a-block"],
|
||||||
"title": "Label Search"
|
"title": "Label Search"
|
||||||
},
|
},
|
||||||
"description": "Search blocks by label. If provided, returns blocks that match this label. This is a full-text search on labels."
|
"description": "Search blocks by label. If provided, returns blocks whose label matches the search query. This is a full-text search on block labels."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "description_search",
|
"name": "description_search",
|
||||||
@@ -10249,16 +10265,18 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Search blocks by description. If provided, returns blocks that match this description. This is a full-text search on block descriptions.",
|
"description": "Search blocks by description. If provided, returns blocks whose description matches the search query. This is a full-text search on block descriptions.",
|
||||||
"title": "Description Search"
|
"title": "Description Search"
|
||||||
},
|
},
|
||||||
"description": "Search blocks by description. If provided, returns blocks that match this description. This is a full-text search on block descriptions."
|
"description": "Search blocks by description. If provided, returns blocks whose description matches the search query. This is a full-text search on block descriptions."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "value_search",
|
"name": "value_search",
|
||||||
@@ -10267,16 +10285,18 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Search blocks by value. If provided, returns blocks that match this value.",
|
"description": "Search blocks by value. If provided, returns blocks whose value matches the search query. This is a full-text search on block values.",
|
||||||
"title": "Value Search"
|
"title": "Value Search"
|
||||||
},
|
},
|
||||||
"description": "Search blocks by value. If provided, returns blocks that match this value."
|
"description": "Search blocks by value. If provided, returns blocks whose value matches the search query. This is a full-text search on block values."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "connected_to_agents_count_gt",
|
"name": "connected_to_agents_count_gt",
|
||||||
@@ -11939,16 +11959,20 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50,
|
||||||
|
"pattern": "^[a-zA-Z0-9_-]+$"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Labels to include (e.g. human, persona)",
|
"description": "Label to include (alphanumeric, hyphens, underscores only)",
|
||||||
|
"examples": ["human", "persona", "the_label_of-a-block"],
|
||||||
"title": "Label"
|
"title": "Label"
|
||||||
},
|
},
|
||||||
"description": "Labels to include (e.g. human, persona)"
|
"description": "Label to include (alphanumeric, hyphens, underscores only)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "templates_only",
|
"name": "templates_only",
|
||||||
@@ -11969,16 +11993,20 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 100,
|
||||||
|
"pattern": "^[a-zA-Z0-9 _-]+$"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Name of the block",
|
"description": "Name filter (alphanumeric, spaces, hyphens, underscores)",
|
||||||
|
"examples": ["My Agent", "test_tool", "default-config"],
|
||||||
"title": "Name"
|
"title": "Name"
|
||||||
},
|
},
|
||||||
"description": "Name of the block"
|
"description": "Name filter (alphanumeric, spaces, hyphens, underscores)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "identity_id",
|
"name": "identity_id",
|
||||||
@@ -11987,16 +12015,20 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 45,
|
||||||
|
"maxLength": 45,
|
||||||
|
"pattern": "^identity-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Search agents by identifier id",
|
"description": "The ID of the identity in the format 'identity-<uuid4>'",
|
||||||
|
"examples": ["identity-123e4567-e89b-42d3-8456-426614174000"],
|
||||||
"title": "Identity Id"
|
"title": "Identity Id"
|
||||||
},
|
},
|
||||||
"description": "Search agents by identifier id"
|
"description": "The ID of the identity in the format 'identity-<uuid4>'"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "identifier_keys",
|
"name": "identifier_keys",
|
||||||
@@ -12125,16 +12157,20 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50,
|
||||||
|
"pattern": "^[a-zA-Z0-9_-]+$"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Search blocks by label. If provided, returns blocks that match this label. This is a full-text search on labels.",
|
"description": "Search blocks by label. If provided, returns blocks whose label matches the search query. This is a full-text search on block labels.",
|
||||||
|
"examples": ["human", "persona", "the_label_of-a-block"],
|
||||||
"title": "Label Search"
|
"title": "Label Search"
|
||||||
},
|
},
|
||||||
"description": "Search blocks by label. If provided, returns blocks that match this label. This is a full-text search on labels."
|
"description": "Search blocks by label. If provided, returns blocks whose label matches the search query. This is a full-text search on block labels."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "description_search",
|
"name": "description_search",
|
||||||
@@ -12143,16 +12179,18 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Search blocks by description. If provided, returns blocks that match this description. This is a full-text search on block descriptions.",
|
"description": "Search blocks by description. If provided, returns blocks whose description matches the search query. This is a full-text search on block descriptions.",
|
||||||
"title": "Description Search"
|
"title": "Description Search"
|
||||||
},
|
},
|
||||||
"description": "Search blocks by description. If provided, returns blocks that match this description. This is a full-text search on block descriptions."
|
"description": "Search blocks by description. If provided, returns blocks whose description matches the search query. This is a full-text search on block descriptions."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "value_search",
|
"name": "value_search",
|
||||||
@@ -12161,16 +12199,18 @@
|
|||||||
"schema": {
|
"schema": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 200
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "null"
|
"type": "null"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Search blocks by value. If provided, returns blocks that match this value.",
|
"description": "Search blocks by value. If provided, returns blocks whose value matches the search query. This is a full-text search on block values.",
|
||||||
"title": "Value Search"
|
"title": "Value Search"
|
||||||
},
|
},
|
||||||
"description": "Search blocks by value. If provided, returns blocks that match this value."
|
"description": "Search blocks by value. If provided, returns blocks whose value matches the search query. This is a full-text search on block values."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "connected_to_agents_count_gt",
|
"name": "connected_to_agents_count_gt",
|
||||||
|
|||||||
@@ -8,7 +8,15 @@ from letta.schemas.block import BaseBlock, Block, BlockResponse, BlockUpdate, Cr
|
|||||||
from letta.server.rest_api.dependencies import HeaderParams, get_headers, get_letta_server
|
from letta.server.rest_api.dependencies import HeaderParams, get_headers, get_letta_server
|
||||||
from letta.server.server import SyncServer
|
from letta.server.server import SyncServer
|
||||||
from letta.utils import is_1_0_sdk_version
|
from letta.utils import is_1_0_sdk_version
|
||||||
from letta.validators import BlockId
|
from letta.validators import (
|
||||||
|
BlockDescriptionSearchQuery,
|
||||||
|
BlockId,
|
||||||
|
BlockLabelQuery,
|
||||||
|
BlockLabelSearchQuery,
|
||||||
|
BlockNameQuery,
|
||||||
|
BlockValueSearchQuery,
|
||||||
|
IdentityIdQuery,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
pass
|
pass
|
||||||
@@ -19,10 +27,10 @@ router = APIRouter(prefix="/blocks", tags=["blocks"])
|
|||||||
@router.get("/", response_model=List[BlockResponse], operation_id="list_blocks")
|
@router.get("/", response_model=List[BlockResponse], operation_id="list_blocks")
|
||||||
async def list_blocks(
|
async def list_blocks(
|
||||||
# query parameters
|
# query parameters
|
||||||
label: Optional[str] = Query(None, description="Labels to include (e.g. human, persona)"),
|
label: BlockLabelQuery = None,
|
||||||
templates_only: bool = Query(False, description="Whether to include only templates"),
|
templates_only: bool = Query(False, description="Whether to include only templates"),
|
||||||
name: Optional[str] = Query(None, description="Name of the block"),
|
name: BlockNameQuery = None,
|
||||||
identity_id: Optional[str] = Query(None, description="Search agents by identifier id"),
|
identity_id: IdentityIdQuery = None,
|
||||||
identifier_keys: Optional[List[str]] = Query(None, description="Search agents by identifier keys"),
|
identifier_keys: Optional[List[str]] = Query(None, description="Search agents by identifier keys"),
|
||||||
project_id: Optional[str] = Query(None, description="Search blocks by project id"),
|
project_id: Optional[str] = Query(None, description="Search blocks by project id"),
|
||||||
limit: Optional[int] = Query(50, description="Number of blocks to return"),
|
limit: Optional[int] = Query(50, description="Number of blocks to return"),
|
||||||
@@ -38,21 +46,9 @@ async def list_blocks(
|
|||||||
"asc", description="Sort order for blocks by creation time. 'asc' for oldest first, 'desc' for newest first"
|
"asc", description="Sort order for blocks by creation time. 'asc' for oldest first, 'desc' for newest first"
|
||||||
),
|
),
|
||||||
order_by: Literal["created_at"] = Query("created_at", description="Field to sort by"),
|
order_by: Literal["created_at"] = Query("created_at", description="Field to sort by"),
|
||||||
label_search: Optional[str] = Query(
|
label_search: BlockLabelSearchQuery = None,
|
||||||
None,
|
description_search: BlockDescriptionSearchQuery = None,
|
||||||
description=("Search blocks by label. If provided, returns blocks that match this label. This is a full-text search on labels."),
|
value_search: BlockValueSearchQuery = None,
|
||||||
),
|
|
||||||
description_search: Optional[str] = Query(
|
|
||||||
None,
|
|
||||||
description=(
|
|
||||||
"Search blocks by description. If provided, returns blocks that match this description. "
|
|
||||||
"This is a full-text search on block descriptions."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
value_search: Optional[str] = Query(
|
|
||||||
None,
|
|
||||||
description=("Search blocks by value. If provided, returns blocks that match this value."),
|
|
||||||
),
|
|
||||||
connected_to_agents_count_gt: Optional[int] = Query(
|
connected_to_agents_count_gt: Optional[int] = Query(
|
||||||
None,
|
None,
|
||||||
description=(
|
description=(
|
||||||
|
|||||||
@@ -7,7 +7,15 @@ from letta.schemas.block import Block, CreateBlock
|
|||||||
from letta.server.rest_api.dependencies import HeaderParams, get_headers, get_letta_server
|
from letta.server.rest_api.dependencies import HeaderParams, get_headers, get_letta_server
|
||||||
from letta.server.server import SyncServer
|
from letta.server.server import SyncServer
|
||||||
from letta.utils import is_1_0_sdk_version
|
from letta.utils import is_1_0_sdk_version
|
||||||
from letta.validators import BlockId
|
from letta.validators import (
|
||||||
|
BlockDescriptionSearchQuery,
|
||||||
|
BlockId,
|
||||||
|
BlockLabelQuery,
|
||||||
|
BlockLabelSearchQuery,
|
||||||
|
BlockNameQuery,
|
||||||
|
BlockValueSearchQuery,
|
||||||
|
IdentityIdQuery,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
pass
|
pass
|
||||||
@@ -18,10 +26,10 @@ router = APIRouter(prefix="/_internal_blocks", tags=["_internal_blocks"])
|
|||||||
@router.get("/", response_model=List[Block], operation_id="list_internal_blocks")
|
@router.get("/", response_model=List[Block], operation_id="list_internal_blocks")
|
||||||
async def list_blocks(
|
async def list_blocks(
|
||||||
# query parameters
|
# query parameters
|
||||||
label: Optional[str] = Query(None, description="Labels to include (e.g. human, persona)"),
|
label: BlockLabelQuery = None,
|
||||||
templates_only: bool = Query(False, description="Whether to include only templates"),
|
templates_only: bool = Query(False, description="Whether to include only templates"),
|
||||||
name: Optional[str] = Query(None, description="Name of the block"),
|
name: BlockNameQuery = None,
|
||||||
identity_id: Optional[str] = Query(None, description="Search agents by identifier id"),
|
identity_id: IdentityIdQuery = None,
|
||||||
identifier_keys: Optional[List[str]] = Query(None, description="Search agents by identifier keys"),
|
identifier_keys: Optional[List[str]] = Query(None, description="Search agents by identifier keys"),
|
||||||
project_id: Optional[str] = Query(None, description="Search blocks by project id"),
|
project_id: Optional[str] = Query(None, description="Search blocks by project id"),
|
||||||
limit: Optional[int] = Query(50, description="Number of blocks to return"),
|
limit: Optional[int] = Query(50, description="Number of blocks to return"),
|
||||||
@@ -37,21 +45,9 @@ async def list_blocks(
|
|||||||
"asc", description="Sort order for blocks by creation time. 'asc' for oldest first, 'desc' for newest first"
|
"asc", description="Sort order for blocks by creation time. 'asc' for oldest first, 'desc' for newest first"
|
||||||
),
|
),
|
||||||
order_by: Literal["created_at"] = Query("created_at", description="Field to sort by"),
|
order_by: Literal["created_at"] = Query("created_at", description="Field to sort by"),
|
||||||
label_search: Optional[str] = Query(
|
label_search: BlockLabelSearchQuery = None,
|
||||||
None,
|
description_search: BlockDescriptionSearchQuery = None,
|
||||||
description=("Search blocks by label. If provided, returns blocks that match this label. This is a full-text search on labels."),
|
value_search: BlockValueSearchQuery = None,
|
||||||
),
|
|
||||||
description_search: Optional[str] = Query(
|
|
||||||
None,
|
|
||||||
description=(
|
|
||||||
"Search blocks by description. If provided, returns blocks that match this description. "
|
|
||||||
"This is a full-text search on block descriptions."
|
|
||||||
),
|
|
||||||
),
|
|
||||||
value_search: Optional[str] = Query(
|
|
||||||
None,
|
|
||||||
description=("Search blocks by value. If provided, returns blocks that match this value."),
|
|
||||||
),
|
|
||||||
connected_to_agents_count_gt: Optional[int] = Query(
|
connected_to_agents_count_gt: Optional[int] = Query(
|
||||||
None,
|
None,
|
||||||
description=(
|
description=(
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import inspect
|
import inspect
|
||||||
import re
|
import re
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import Annotated
|
from typing import Annotated, Optional
|
||||||
|
|
||||||
from fastapi import Path
|
from fastapi import Path, Query
|
||||||
|
|
||||||
from letta.errors import LettaInvalidArgumentError
|
from letta.errors import LettaInvalidArgumentError
|
||||||
from letta.schemas.enums import PrimitiveType # PrimitiveType is now in schemas.enums
|
from letta.schemas.enums import PrimitiveType # PrimitiveType is now in schemas.enums
|
||||||
@@ -124,3 +124,101 @@ def raise_on_invalid_id(param_name: str, expected_prefix: PrimitiveType):
|
|||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Query Parameter Validators
|
||||||
|
# =============================================================================
|
||||||
|
# Format validators for common query parameters to match frontend constraints
|
||||||
|
|
||||||
|
|
||||||
|
def _create_id_query_validator(primitive: str):
|
||||||
|
"""
|
||||||
|
Creates a Query validator for ID parameters with format validation.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
primitive: The primitive type prefix (e.g., "agent", "tool")
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A Query validator with pattern matching
|
||||||
|
"""
|
||||||
|
return Query(
|
||||||
|
description=f"The ID of the {primitive} in the format '{primitive}-<uuid4>'",
|
||||||
|
pattern=PRIMITIVE_ID_PATTERNS[primitive].pattern,
|
||||||
|
examples=[f"{primitive}-123e4567-e89b-42d3-8456-426614174000"],
|
||||||
|
min_length=len(primitive) + 1 + 36,
|
||||||
|
max_length=len(primitive) + 1 + 36,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Query parameter ID validators with format checking
|
||||||
|
AgentIdQuery = Annotated[Optional[str], _create_id_query_validator(PrimitiveType.AGENT.value)]
|
||||||
|
ToolIdQuery = Annotated[Optional[str], _create_id_query_validator(PrimitiveType.TOOL.value)]
|
||||||
|
SourceIdQuery = Annotated[Optional[str], _create_id_query_validator(PrimitiveType.SOURCE.value)]
|
||||||
|
BlockIdQuery = Annotated[Optional[str], _create_id_query_validator(PrimitiveType.BLOCK.value)]
|
||||||
|
MessageIdQuery = Annotated[Optional[str], _create_id_query_validator(PrimitiveType.MESSAGE.value)]
|
||||||
|
RunIdQuery = Annotated[Optional[str], _create_id_query_validator(PrimitiveType.RUN.value)]
|
||||||
|
JobIdQuery = Annotated[Optional[str], _create_id_query_validator(PrimitiveType.JOB.value)]
|
||||||
|
GroupIdQuery = Annotated[Optional[str], _create_id_query_validator(PrimitiveType.GROUP.value)]
|
||||||
|
IdentityIdQuery = Annotated[Optional[str], _create_id_query_validator(PrimitiveType.IDENTITY.value)]
|
||||||
|
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# String Field Validators
|
||||||
|
# =============================================================================
|
||||||
|
# Format validators for common string fields
|
||||||
|
|
||||||
|
# Label validator: alphanumeric, hyphens, underscores, max 50 chars
|
||||||
|
BlockLabelQuery = Annotated[
|
||||||
|
Optional[str],
|
||||||
|
Query(
|
||||||
|
description="Label to include (alphanumeric, hyphens, underscores only)",
|
||||||
|
pattern=r"^[a-zA-Z0-9_-]+$",
|
||||||
|
min_length=1,
|
||||||
|
max_length=50,
|
||||||
|
examples=["human", "persona", "the_label_of-a-block"],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Name validator: similar to label but allows spaces, max 100 chars
|
||||||
|
BlockNameQuery = Annotated[
|
||||||
|
Optional[str],
|
||||||
|
Query(
|
||||||
|
description="Name filter (alphanumeric, spaces, hyphens, underscores)",
|
||||||
|
pattern=r"^[a-zA-Z0-9 _-]+$",
|
||||||
|
min_length=1,
|
||||||
|
max_length=100,
|
||||||
|
examples=["My Agent", "test_tool", "default-config"],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Search query validator: general text search, max 200 chars
|
||||||
|
BlockLabelSearchQuery = Annotated[
|
||||||
|
Optional[str],
|
||||||
|
Query(
|
||||||
|
description="Search blocks by label. If provided, returns blocks whose label matches the search query. This is a full-text search on block labels.",
|
||||||
|
pattern=r"^[a-zA-Z0-9_-]+$",
|
||||||
|
min_length=1,
|
||||||
|
max_length=50,
|
||||||
|
examples=["human", "persona", "the_label_of-a-block"],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
BlockValueSearchQuery = Annotated[
|
||||||
|
Optional[str],
|
||||||
|
Query(
|
||||||
|
description="Search blocks by value. If provided, returns blocks whose value matches the search query. This is a full-text search on block values.",
|
||||||
|
min_length=1,
|
||||||
|
max_length=200,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
BlockDescriptionSearchQuery = Annotated[
|
||||||
|
Optional[str],
|
||||||
|
Query(
|
||||||
|
description="Search blocks by description. If provided, returns blocks whose description matches the search query. This is a full-text search on block descriptions.",
|
||||||
|
min_length=1,
|
||||||
|
max_length=200,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user