From 72b2937103efe620c042ca7d7d4bee6941423533 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Tue, 19 Aug 2025 12:16:45 -0700 Subject: [PATCH 1/4] fix: Python SDK and Cloud docs improvements - Update vector storage (`upsert`, `search`) signatures - Document required "key" field in vector storage - Fix async/await consistency in email examples - Add parameter defaults and improve vector storage examples - Clarify email source trigger behavior in Agents console page --- content/Cloud/agents.mdx | 2 +- content/SDKs/python/api-reference.mdx | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/content/Cloud/agents.mdx b/content/Cloud/agents.mdx index 1951c397..5a7a5ea1 100644 --- a/content/Cloud/agents.mdx +++ b/content/Cloud/agents.mdx @@ -156,7 +156,7 @@ For Email sources, you can configure your agent at a unique agent email address. An email source can only be triggered by an email sent to the agent's email address and not via the API. -The response from the API will contain an informational message if successful. Additionally, the `Location` header will contain the URL that can be used to read the agent output. This URL will block until the agent has started streaming the output response. +After an email is received, the platform will enqueue processing and your agent will handle the message asynchronously. Any replies will be delivered via the configured destination(s). #### Discord Source diff --git a/content/SDKs/python/api-reference.mdx b/content/SDKs/python/api-reference.mdx index 56037a46..dc693f3e 100644 --- a/content/SDKs/python/api-reference.mdx +++ b/content/SDKs/python/api-reference.mdx @@ -105,7 +105,6 @@ from agentuity.io.email import EmailAttachment async def handler(request: AgentRequest, response: AgentResponse, context: AgentContext): # Get the incoming email - email = request.data.email() email = await request.data.email() # Create an attachment attachment = EmailAttachment( @@ -368,14 +367,14 @@ The Vector Storage API provides a way to store and search for data using vector #### upsert -`async upsert(name: str, *documents: VectorUpsertParams) -> list[str]` +`async upsert(name: str, documents: List[VectorUpsertParams]) -> list[str]` Inserts or updates vectors in the vector storage. **Parameters** - `name`: The name of the vector storage -- `documents`: An array of documents to upsert, each with either embeddings or text +- `documents`: A list of documents to upsert. Each document must include a unique `key` and either `document` (text) or `embeddings` **Return Value** @@ -402,6 +401,7 @@ async def index_products(context: AgentContext, products: List[Dict[str, Any]]) documents = [] for product in products: documents.append({ + "key": product["id"], # REQUIRED: unique key for each document "document": product["description"], "metadata": { "product_id": product["id"], @@ -442,14 +442,17 @@ ids2 = await context.vector.upsert( #### search -`async search(name: str, query: str, limit: int, similarity: float, metadata: Optional[dict]) -> list[VectorSearchResult]` +`async search(name: str, query: str, limit: int = 10, similarity: float = 0.5, metadata: Optional[dict] = None) -> list[VectorSearchResult]` Searches for vectors in the vector storage. **Parameters** - `name`: The name of the vector storage -- `params`: Search parameters including query, limit, similarity threshold, and metadata filters +- `query`: The query text to search against +- `limit`: (optional) Maximum number of results to return. Defaults to 10 +- `similarity`: (optional) Minimum similarity threshold (0.0-1.0). Defaults to 0.5 +- `metadata`: (optional) Exact-match metadata filters applied at search time. Defaults to None **Return Value** @@ -463,8 +466,9 @@ from typing import List, Dict, Any # Search for similar products with error handling try: - results = await context.vector.search("product-descriptions", - query="comfortable office chair", + results = await context.vector.search( + "product-descriptions", + "comfortable office chair", limit=5, similarity=0.7, metadata={"category": "furniture"} @@ -505,7 +509,7 @@ from agentuity.sdk import AgentContext # Delete a single vector with error handling try: - deleted_count = await context.vector.delete("product-descriptions", "id1") + deleted_count = await context.vector.delete("product-descriptions", "key_123") context.logger.info(f"Deleted {deleted_count} vector(s)") except Exception as e: context.logger.error(f"Failed to delete vector: {str(e)}") From d9ea4975d75ccdcbc5283c0cee6377f5a7d0ff67 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Tue, 19 Aug 2025 12:45:14 -0700 Subject: [PATCH 2/4] Fix vector search example to use `similarity` attribute --- content/SDKs/python/examples/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/SDKs/python/examples/index.mdx b/content/SDKs/python/examples/index.mdx index 09689990..7c4891ee 100644 --- a/content/SDKs/python/examples/index.mdx +++ b/content/SDKs/python/examples/index.mdx @@ -199,7 +199,7 @@ async def run(request: AgentRequest, response: AgentResponse, context: AgentCont { "id": result.id, "key": result.key, - "similarity": 1.0 - result.distance, + "similarity": result.similarity, "metadata": result.metadata } for result in results From 6e1d09e45ba5a84431d7acf70262cfadcc69a273 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Tue, 19 Aug 2025 16:46:45 -0700 Subject: [PATCH 3/4] fix: correct vector storage docs, implement some suggestions - Remove incorrect unpacking operator in Vector DB guide - Document that Python SDK requires "key" field, JavaScript doesn't - Clarify Python returns `similarity`, JavaScript returns `distance` - Discuss idempotent behavior in Vector DB guide - Update return value descriptions to note internal system IDs --- content/Guides/vector-db.mdx | 17 +++++++++++++---- content/SDKs/python/api-reference.mdx | 14 ++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/content/Guides/vector-db.mdx b/content/Guides/vector-db.mdx index 103e3e76..4aeface8 100644 --- a/content/Guides/vector-db.mdx +++ b/content/Guides/vector-db.mdx @@ -48,6 +48,13 @@ Vector storage is created automatically when your agent first calls `context.vec The `upsert` operation inserts new documents or updates existing ones. You can provide either text (which gets automatically converted to embeddings) or pre-computed embeddings. +**SDK Differences:** +- **JavaScript SDK**: No key field required, search returns `distance` (0 = perfect match) +- **Python SDK**: Requires `key` field for each document, search returns `similarity` (1.0 = perfect match) + +**Idempotent Behavior:** +The upsert operation is idempotent - upserting with an existing key updates the existing vector rather than creating a duplicate. The same internal vector ID is reused, ensuring your vector storage remains clean and efficient. + ```javascript // JavaScript/TypeScript @@ -79,26 +86,29 @@ const embeddingIds = await context.vector.upsert( # Upsert documents with text documents = [ { + "key": "doc_1", # Required: unique identifier for this vector "document": "Agentuity is an agent-native cloud platform", "metadata": {"category": "platform", "source": "docs"} }, { + "key": "doc_2", # Required: unique identifier for this vector "document": "Vector storage enables semantic search capabilities", "metadata": {"category": "features", "source": "docs"} } ] -ids = await context.vector.upsert("knowledge-base", *documents) +ids = await context.vector.upsert("knowledge-base", documents) # Upsert with embeddings embedding_docs = [ { + "key": "embedding_1", # Required: unique identifier for this vector "embeddings": [0.1, 0.2, 0.3, 0.4], "metadata": {"id": "doc-1", "type": "custom"} } ] -ids = await context.vector.upsert("custom-embeddings", *embedding_docs) +ids = await context.vector.upsert("custom-embeddings", embedding_docs) ``` @@ -137,9 +147,8 @@ results = await context.vector.search( # Process results for result in results: - similarity_score = 1.0 - result.distance print(f"Found: {result.metadata['source']}") - print(f"Similarity: {similarity_score}") + print(f"Similarity: {result.similarity}") ``` diff --git a/content/SDKs/python/api-reference.mdx b/content/SDKs/python/api-reference.mdx index dc693f3e..a8624310 100644 --- a/content/SDKs/python/api-reference.mdx +++ b/content/SDKs/python/api-reference.mdx @@ -378,7 +378,9 @@ Inserts or updates vectors in the vector storage. **Return Value** -Returns a list of string IDs for the upserted vectors. +Returns a list of string IDs for the upserted vectors (internal system IDs, not your provided keys). + +Note: Upserting with an existing `key` updates that vector (idempotent operation). **Example** @@ -456,7 +458,11 @@ Searches for vectors in the vector storage. **Return Value** -Returns a list of search results, each containing an ID, metadata, and distance score. +Returns a list of search results with the following attributes: +- `id`: Internal vector ID (e.g., "vector_94c98660c8afa3a2") +- `key`: The unique key for this vector +- `similarity`: Similarity score from 0.0 to 1.0 (1.0 = perfect match) +- `metadata`: The associated metadata dictionary **Example** @@ -478,7 +484,7 @@ try: if results: context.logger.info(f"Found {len(results)} matching products") for result in results: - print(f"Product ID: {result.id}, Similarity: {result.distance}") + print(f"Product ID: {result.id}, Similarity: {result.similarity}") print(f"Metadata: {result.metadata}") else: context.logger.info("No matching products found") @@ -500,7 +506,7 @@ Deletes a vector from the vector storage. **Return Value** -Returns the number of vectors that were deleted (0 or 1). +Returns the number of vectors that were deleted (0 if the key didn't exist, 1 if successfully deleted). **Example** From 978123331030355ec2253c88a02c0bd010a95e4c Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Tue, 19 Aug 2025 17:51:06 -0700 Subject: [PATCH 4/4] Fix Vector DB delete example (Python uses ID only) --- content/Guides/vector-db.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/Guides/vector-db.mdx b/content/Guides/vector-db.mdx index 4aeface8..ffa5173c 100644 --- a/content/Guides/vector-db.mdx +++ b/content/Guides/vector-db.mdx @@ -160,7 +160,7 @@ for result in results: ### Deleting Vectors -Remove specific vectors from storage using their IDs. +Remove specific vectors from storage using their IDs (JavaScript) or keys (Python). ```javascript @@ -178,7 +178,7 @@ const bulkDeleteCount = await context.vector.delete( ```python # Python # Delete single vector -count = await context.vector.delete("knowledge-base", "vector-id-1") +count = await context.vector.delete("knowledge-base", "doc_1") # Note: Python SDK currently supports single deletion # For bulk operations, call delete multiple times