From 0414fc0bd1a21102d37fabb9f60476064160c481 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Wed, 3 Sep 2025 11:20:39 -0700 Subject: [PATCH 1/9] Update Guides and Python API reference --- content/Guides/agent-communication.mdx | 35 +++++++++----- content/Guides/key-value.mdx | 66 ++++++++++++++++---------- content/SDKs/python/api-reference.mdx | 5 +- 3 files changed, 66 insertions(+), 40 deletions(-) diff --git a/content/Guides/agent-communication.mdx b/content/Guides/agent-communication.mdx index 072521ed..4d33ba32 100644 --- a/content/Guides/agent-communication.mdx +++ b/content/Guides/agent-communication.mdx @@ -39,7 +39,7 @@ Inter organization communication is the most advanced form of agent-to-agent com #### Communication Methods -Agents has two primary methods of communication with other agents: +Agents have two primary methods of communication with other agents: | Type | Description | |-----------|-------------| @@ -81,7 +81,10 @@ export default async function Agent( resp: AgentResponse, ctx: AgentContext ) { - return resp.handoff({name: 'My Other Agent'}, "would you please do this?"); + return resp.handoff( + {name: 'My Other Agent'}, + { data: "would you please do this?", contentType: "text/plain" } + ); }`} py={`from agentuity import AgentRequest, AgentResponse, AgentContext async def run(request: AgentRequest, response: AgentResponse, context: AgentContext): @@ -90,11 +93,11 @@ async def run(request: AgentRequest, response: AgentResponse, context: AgentCont ##### Invocation -When an agent needs to invoke another agent to complete a task and wants to wait for the result, it can do so by using the SDK `getAgents` method on `AgentContext`. The `getAgents` will perform resolution to determine the target agent location and return a handle to the target agent that can be used to `run` the target agent. +When an agent needs to invoke another agent to complete a task and wants to wait for the result, it can do so by using the SDK `getAgent` method on `AgentContext`. The `getAgent` will perform resolution to determine the target agent location and return a handle to the target agent that can be used to `run` the target agent. -If the target agent is local (intra project), the `getAgents` method will return a handle to an internal agent which can be used to `run` the target agent. +If the target agent is local (intra project), the `getAgent` method will return a handle to an internal agent which can be used to `run` the target agent. -If the target agent is remote (inter project or inter organization), the `getAgents` method will return a handle to an external agent which can be used to `run` the target agent. In addition, the SDK internally will use the authorization token to authenticate the source agent to the target agent. +If the target agent is remote (inter project or inter organization), the `getAgent` method will return a handle to an external agent which can be used to `run` the target agent. In addition, the SDK internally will use the authorization token to authenticate the source agent to the target agent. @@ -145,8 +154,8 @@ export default async function Agent( const agent1 = await ctx.getAgent({name: 'My First Agent'}); const agent2 = await ctx.getAgent({name: 'My Second Agent'}); await Promise.all([ - agent1.run({task: 'My First Task'}), - agent2.run({task: 'My Second Task'}), + agent1.run({ data: { task: 'My First Task' }, contentType: 'application/json' }), + agent2.run({ data: { task: 'My Second Task' }, contentType: 'application/json' }), ]); return resp.text('OK'); }`} py={`from agentuity import AgentRequest, AgentResponse, AgentContext @@ -158,8 +167,8 @@ async def run(request: AgentRequest, response: AgentResponse, context: AgentCont agent2 = await context.getAgent({"name":"My Second Agent"}) await asyncio.gather( - agent1.run({"task":"My First Task"}), - agent2.run({"task":"My Second Task"}), + agent1.run({"task": "My First Task"}), # content type inferred as JSON + agent2.run({"task": "My Second Task"}), # content type inferred as JSON ) return response.text('OK') @@ -175,15 +184,15 @@ sequenceDiagram actor Agentuity actor Agent 2 actor Agent 3 - Agent 1-->>Agentuity: Get Agent 1 Agent 1-->>Agentuity: Get Agent 2 + Agent 1-->>Agentuity: Get Agent 3 Agent 1->>Agent 2: Run Agent 1->>Agent 3: Run "/> #### Agent Resolution -How do we resolve the target agent? There are two main ways to do this: +How do we resolve the target agent? There are three main ways to do this: | Type | Description | |-----------|-------------| diff --git a/content/Guides/key-value.mdx b/content/Guides/key-value.mdx index 2e293507..5ab9ca5b 100644 --- a/content/Guides/key-value.mdx +++ b/content/Guides/key-value.mdx @@ -38,14 +38,14 @@ Both JavaScript and Python SDKs automatically create key-value storage when you { - // Storage is created automatically on first use - await context.kv.set('user-sessions', 'user-123', { +const handler: AgentHandler = async (req, resp, ctx) => { + // Buckets are auto-created if they don't exist + await ctx.kv.set('user-sessions', 'user-123', { lastSeen: new Date().toISOString(), preferences: { theme: 'dark' } }); - return response.json({ message: 'Session stored' }); + return resp.json({ message: 'Session stored' }); }; export default handler;`} py={`# Python @@ -66,46 +66,59 @@ async def run(request: AgentRequest, response: AgentResponse, context: AgentCont The key-value API provides three core operations: `get`, `set`, and `delete`. All operations are asynchronous and support various data types. +The first parameter in all operations is the storage bucket name (also called "name" or "namespace"). Buckets are automatically created when you first use them. + ### Storing Data -Store strings, objects, or binary data with optional TTL (time-to-live): +Store strings, objects, or binary data. Keys persist indefinitely by default, or you can set a TTL (time-to-live) for automatic expiration: - +# Store feature flags (no TTL - persistent config) +await context.kv.set("feature-flags", "beta-features", { + "darkMode": True, + "aiAssistant": False, + "newDashboard": True +})`} /> ### Retrieving Data Retrieve stored values with automatic deserialization: Remove keys when they're no longer needed: @@ -155,13 +168,13 @@ Use hierarchical, descriptive keys to organize your data: Always handle potential storage errors gracefully: Date: Fri, 5 Sep 2025 15:52:04 -0700 Subject: [PATCH 2/9] More Guides, API ref updates - Add `vector.get()` usage to API reference, examples in Guides - Fix code formatting for Vector DB guide - Clean up Guides headings - Fix Python agent communication examples (should use `get_agent`) --- content/Guides/agent-communication.mdx | 56 ++++----- content/Guides/agent-data-handling.mdx | 4 +- content/Guides/agent-streaming.mdx | 2 +- content/Guides/agent-tracing.mdx | 2 + content/Guides/ai-gateway.mdx | 2 +- content/Guides/vector-db.mdx | 136 ++++++++++++++++------ content/SDKs/javascript/api-reference.mdx | 30 +++++ content/SDKs/python/api-reference.mdx | 29 +++++ 8 files changed, 196 insertions(+), 65 deletions(-) diff --git a/content/Guides/agent-communication.mdx b/content/Guides/agent-communication.mdx index 4d33ba32..1ed56ff8 100644 --- a/content/Guides/agent-communication.mdx +++ b/content/Guides/agent-communication.mdx @@ -7,15 +7,13 @@ import Image from "next/image"; Agent-to-AgentCommunication -### How do agents communicate with each other? +## Overview -In most advanced agentic scenarios, agents need to communicate with other agents to achieve their goals. - -In fact, our recommendation is that you build agents with highly specialized roles and skills and use agent-to-agent communication to achieve the overall goal. +In most advanced agentic scenarios, agents need to communicate with other agents to achieve their goals. In fact, our recommendation is that you build agents with highly specialized roles and skills and use agent-to-agent communication to achieve the overall goal. There are a number of ways to achieve agent-to-agent communication natively in Agentuity. -#### Communication Types +## Communication Types Agents can communicate with each other in a number of ways in the Agentuity platform. The following are the different types of communication that are supported: @@ -25,19 +23,19 @@ Agents can communicate with each other in a number of ways in the Agentuity plat | **Inter Project** | Agents can communicate with each other across projects within the same organization across the internal network | | **Inter Organization** | Agents can communicate with each other across organizations across the internal network | -##### Intra Project +### Intra Project Intra project communication is the simplest form of agent-to-agent communication. Agents within the same project can communicate with each other locally without leaving the local network. -##### Inter Project +### Inter Project Inter project communication is a more advanced form of agent-to-agent communication. Agents can communicate with each other across projects within the same organization but will communicate over the internal network. -##### Inter Organization +### Inter Organization Inter organization communication is the most advanced form of agent-to-agent communication. Agents can communicate with each other across organizations. Currently, Agentuity only supports inter organization agent communication if the target agent is public and the source agent has been given the agent ID by the other organization. For inter organization communication, the source agent will communicate over the internal network. -#### Communication Methods +## Communication Methods Agents have two primary methods of communication with other agents: @@ -46,7 +44,7 @@ Agents have two primary methods of communication with other agents: | Handoff | Agents can handoff a request to another agent to complete | | Invocation | Agents can invoke another agent to complete a task and wait for the result | -##### Handoff +### Handoff When an agent needs to handoff a request to another agent, it can do so by using the SDK `handoff` method. The `handoff` method will send the request to another agent and the other agent will be responsible for completing the request. @@ -91,7 +89,7 @@ async def run(request: AgentRequest, response: AgentResponse, context: AgentCont return response.handoff({"name":"My Other Agent"}, "would you please do this?") `} /> -##### Invocation +### Invocation When an agent needs to invoke another agent to complete a task and wants to wait for the result, it can do so by using the SDK `getAgent` method on `AgentContext`. The `getAgent` will perform resolution to determine the target agent location and return a handle to the target agent that can be used to `run` the target agent. @@ -118,16 +116,16 @@ export default async function Agent( ctx: AgentContext ) { const agent = await ctx.getAgent({name: 'My Other Agent'}); - const agentResponse = await agent.run({ - data: "would you please do this?", - contentType: "text/plain" - }); + // Basic usage - perfect for simple string data + const agentResponse = await agent.run({ data: "would you please do this?" }); + // Explicit control when needed: + // const agentResponse = await agent.run({ data: "would you please do this?", contentType: "text/plain" }); const text = await agentResponse.data.text(); return resp.text(text); }`} py={`from agentuity import AgentRequest, AgentResponse, AgentContext async def run(request: AgentRequest, response: AgentResponse, context: AgentContext): - agent = await context.getAgent({"name":"My Other Agent"}) + agent = await context.get_agent({"name":"My Other Agent"}) # Send plain text (content type inferred as text/plain) agent_response = await agent.run("would you please do this?") # Or send JSON (content type inferred as application/json) @@ -140,7 +138,7 @@ In this trivial example above, the functionality is similar to the handoff examp In a real life scenario, you'll likely want to pass the appropriate data types to the target agent and wait for the result and then use the result in your own agent to perform additional tasks. -###### Parallel Execution +#### Parallel Execution Sometimes you want to send a request to multiple agents at the same time. This is an example of parallel execution. @@ -153,18 +151,24 @@ export default async function Agent( ) { const agent1 = await ctx.getAgent({name: 'My First Agent'}); const agent2 = await ctx.getAgent({name: 'My Second Agent'}); + // Basic usage - perfect for simple object data await Promise.all([ - agent1.run({ data: { task: 'My First Task' }, contentType: 'application/json' }), - agent2.run({ data: { task: 'My Second Task' }, contentType: 'application/json' }), + agent1.run({ data: { task: 'My First Task' } }), + agent2.run({ data: { task: 'My Second Task' } }), ]); + // Explicit control when needed: + // await Promise.all([ + // agent1.run({ data: { task: 'My First Task' }, contentType: 'application/json' }), + // agent2.run({ data: { task: 'My Second Task' }, contentType: 'application/json' }), + // ]); return resp.text('OK'); }`} py={`from agentuity import AgentRequest, AgentResponse, AgentContext import asyncio async def run(request: AgentRequest, response: AgentResponse, context: AgentContext): - agent1 = await context.getAgent({"name":"My First Agent"}) - agent2 = await context.getAgent({"name":"My Second Agent"}) + agent1 = await context.get_agent({"name":"My First Agent"}) + agent2 = await context.get_agent({"name":"My Second Agent"}) await asyncio.gather( agent1.run({"task": "My First Task"}), # content type inferred as JSON @@ -190,7 +194,7 @@ sequenceDiagram Agent 1->>Agent 3: Run "/> -#### Agent Resolution +## Agent Resolution How do we resolve the target agent? There are three main ways to do this: @@ -200,11 +204,11 @@ How do we resolve the target agent? There are three main ways to do this: | Agent Name | The agent name is a human readable name for an agent. It is a string that was used for the agent's name. | | Project ID | The agent project ID is specified to disambiguate agents with the same name in different projects. | -##### Intra Project Resolution +### Intra Project Resolution When calling an agent within the same project, the agent name is usually the easiest way to resolve the target agent. The agent name is a human readable name for an agent. It is a string that was used for the agent's name. -##### Inter Project Resolution +### Inter Project Resolution When calling an agent across projects within the same organization, the agent ID is typically the most reliable way to resolve the target agent. The agent ID is a unique identifier for an agent. @@ -233,10 +237,10 @@ async def run(request: AgentRequest, response: AgentResponse, context: AgentCont }) `} /> -##### Inter Organization Resolution +### Inter Organization Resolution Currently, Agentuity only supports inter organization agent communication if the target agent is public and the source agent has been given the agent ID by the other organization. When using inter organization communication, only the agent ID is required to resolve the target agent. -#### Communication Authorization +## Communication Authorization When communicating with other agents outside the local project, Agentuity will automatically generate a one-time use authorization token with a short expiration. This token is used to authenticate the source agent to the target agent automatically without the need for the source agent to pass the token to the target agent. diff --git a/content/Guides/agent-data-handling.mdx b/content/Guides/agent-data-handling.mdx index 6a1f49a7..870086ab 100644 --- a/content/Guides/agent-data-handling.mdx +++ b/content/Guides/agent-data-handling.mdx @@ -3,7 +3,9 @@ title: Agent Data Handling description: How to handle data formats in your agents --- -We provide a few different ways to handle data formats in your agents to make it easier to work with different data types. Of course, your agent can always perform its own data handling by use the raw data and the content type property. However, most common data types are supported out of the box. +## Overview + +We provide a few different ways to handle data formats in your agents to make it easier to work with different data types. Of course, your agent can always perform its own data handling by using the raw data and the content type property. However, most common data types are supported out of the box. ## How it works diff --git a/content/Guides/agent-streaming.mdx b/content/Guides/agent-streaming.mdx index f37c688b..e1f27720 100644 --- a/content/Guides/agent-streaming.mdx +++ b/content/Guides/agent-streaming.mdx @@ -26,7 +26,7 @@ description: How to use streaming in your agents └────────────────────────────────────────────────────────────────────────────────────────────┘ ``` -#### Real-World Use Cases +### Real-World Use Cases - **Live chat / customer support.** Stream the assistant's words as they are generated for a more natural feel. - **Speech-to-text.** Pipe microphone audio into a transcription agent and forward captions to the UI in real time. diff --git a/content/Guides/agent-tracing.mdx b/content/Guides/agent-tracing.mdx index 111f342e..c252d1b4 100644 --- a/content/Guides/agent-tracing.mdx +++ b/content/Guides/agent-tracing.mdx @@ -3,6 +3,8 @@ title: Agent Tracing description: Understanding how to use tracing in your agents --- +## Overview + Agent tracing provides deep visibility into your agent's execution flow, performance, and behavior using OpenTelemetry. This enables debugging, performance monitoring, and understanding complex agent workflows. **Key benefits:** diff --git a/content/Guides/ai-gateway.mdx b/content/Guides/ai-gateway.mdx index 5e51106d..614bafad 100644 --- a/content/Guides/ai-gateway.mdx +++ b/content/Guides/ai-gateway.mdx @@ -1,6 +1,6 @@ --- title: Using AI Gateway -description: Using AI Gateway in your Agents +description: Using the AI Gateway in your Agents --- ## What is the AI Gateway? diff --git a/content/Guides/vector-db.mdx b/content/Guides/vector-db.mdx index 900be0d4..5bec17c8 100644 --- a/content/Guides/vector-db.mdx +++ b/content/Guides/vector-db.mdx @@ -3,8 +3,16 @@ title: Using Vector DB description: Using the Vector DB for search and retrieval --- +## When to Use Vector Storage + Vector storage enables semantic search for your agents, allowing them to find information by meaning rather than keywords. Ideal for knowledge bases, RAG systems, and persistent agent memory. +Choose the right storage for your use case: + +- **Vector Storage**: Semantic search, embeddings, similarity matching +- **[Key-Value Storage](/Cloud/key-value-memory)**: Fast lookups, simple data, temporary state +- **[Object Storage](/Cloud/object-storage)**: Large files, media, backups + ## Understanding Vector Storage Vector storage works by converting text into high-dimensional numerical representations (embeddings) that capture semantic meaning. When you search, the system finds documents with similar meanings rather than just keyword matches. @@ -58,9 +66,7 @@ The `upsert` operation inserts new documents or updates existing ones. You can p **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 + +ids = await context.vector.upsert("custom-embeddings", embedding_docs)`} /> ### Searching Vector Storage Search operations find semantically similar documents based on a text query. You can control the number of results, similarity threshold, and filter by metadata. - -```javascript -// JavaScript/TypeScript + { - console.log(`Found: ${result.metadata.source}`); - console.log(`Similarity: ${result.similarity}`); -}); -``` - -```python -# Python + console.log(\`Found: \${result.metadata.source}\`); + console.log(\`Similarity: \${result.similarity}\`); +});`} py={`# Python # Semantic search with parameters results = await context.vector.search( "knowledge-base", @@ -154,9 +148,7 @@ results = await context.vector.search( # Process results for result in results: print(f"Found: {result.metadata['source']}") - print(f"Similarity: {result.similarity}") -``` - + print(f"Similarity: {result.similarity}")`} /> **Search Parameters:** - `query` (required): Text query to search for @@ -168,33 +160,105 @@ for result in results: - **Both SDKs**: Return results with `similarity` field (1.0 = perfect match, 0.0 = no match) - **Note**: The JavaScript SDK also returns a `distance` field for backward compatibility; prefer `similarity` +### Retrieving Vectors by Key + +The `get` method retrieves a specific vector directly using its key, without performing a similarity search. + + + +**When to use `get` vs `search`:** +- Use `get` when you know the exact key (like a database primary key lookup) +- Use `search` when finding vectors by semantic similarity +- `get` is faster for single lookups since it doesn't compute similarities +- `get` returns `null` if not found, never throws an error + ### Deleting Vectors Remove specific vectors from storage using their keys. - -```javascript -// JavaScript/TypeScript + +# For bulk operations, call delete multiple times`} /> ## Practical Examples diff --git a/content/SDKs/javascript/api-reference.mdx b/content/SDKs/javascript/api-reference.mdx index 20b96e56..d7092958 100644 --- a/content/SDKs/javascript/api-reference.mdx +++ b/content/SDKs/javascript/api-reference.mdx @@ -270,6 +270,36 @@ for (const result of results) { } ``` +#### get + +`get(name: string, key: string): Promise` + +Retrieves a specific vector from the vector storage using its key. + +**Parameters** + +- `name`: The name of the vector storage +- `key`: The unique key of the vector to retrieve + +**Return Value** + +Returns a Promise that resolves to a `VectorSearchResult` object if found, or `null` if the key doesn't exist. + +**Example** + +```typescript +// Retrieve a specific vector by key +const vector = await context.vector.get('product-descriptions', 'chair-001'); + +if (vector) { + console.log(`Found vector: ${vector.id}`); + console.log(`Key: ${vector.key}`); + console.log(`Metadata:`, vector.metadata); +} else { + console.log('Vector not found'); +} +``` + #### delete `delete(name: string, ...keys: string[]): Promise` diff --git a/content/SDKs/python/api-reference.mdx b/content/SDKs/python/api-reference.mdx index d80cef2a..f330e99b 100644 --- a/content/SDKs/python/api-reference.mdx +++ b/content/SDKs/python/api-reference.mdx @@ -493,6 +493,35 @@ except Exception as e: # Handle the error appropriately ``` +#### get + +`async get(name: str, key: str) -> VectorSearchResult | None` + +Retrieves a specific vector from the vector storage using its key. + +**Parameters** + +- `name`: The name of the vector storage +- `key`: The unique key of the vector to retrieve + +**Return Value** + +Returns a `VectorSearchResult` object if found, or `None` if the key doesn't exist. + +**Example** + +```python +# Retrieve a specific vector by key +vector = await context.vector.get("product-descriptions", "chair-001") + +if vector: + print(f"Found vector: {vector.id}") + print(f"Key: {vector.key}") + print(f"Metadata: {vector.metadata}") +else: + print("Vector not found") +``` + #### delete `async delete(name: str, key: str) -> int` From b776f08df023428c4676cb8287f66b4a48a42fd4 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Mon, 8 Sep 2025 09:31:56 -0700 Subject: [PATCH 3/9] CodeRabbit suggestions --- content/Guides/agent-communication.mdx | 4 ++- content/Guides/agent-data-handling.mdx | 22 ++++++++-------- content/Guides/agent-streaming.mdx | 2 +- content/Guides/agent-tracing.mdx | 2 +- content/Guides/key-value.mdx | 2 +- content/Guides/vector-db.mdx | 36 +++++++++++++++----------- content/SDKs/python/api-reference.mdx | 14 +++++----- 7 files changed, 45 insertions(+), 37 deletions(-) diff --git a/content/Guides/agent-communication.mdx b/content/Guides/agent-communication.mdx index 1ed56ff8..4b4af084 100644 --- a/content/Guides/agent-communication.mdx +++ b/content/Guides/agent-communication.mdx @@ -5,7 +5,7 @@ description: Agent-to-Agent communication patterns, usage and best practices import Image from "next/image"; -Agent-to-AgentCommunication +Agent-to-Agent Communication ## Overview @@ -134,6 +134,8 @@ async def run(request: AgentRequest, response: AgentResponse, context: AgentCont return response.text(text) `} /> +> **Note:** JavaScript uses `{ data, contentType }` format while Python infers content type from the raw payload passed directly. + In this trivial example above, the functionality is similar to the handoff example above. The source agent is sending a request to the `My Other Agent` agent and passing a message to the other agent. The `My Other Agent` agent will receive the request, perform an operation and return the result to the source agent. The source agent will simply return the result as a text result. In a real life scenario, you'll likely want to pass the appropriate data types to the target agent and wait for the result and then use the result in your own agent to perform additional tasks. diff --git a/content/Guides/agent-data-handling.mdx b/content/Guides/agent-data-handling.mdx index 870086ab..b5fa7c20 100644 --- a/content/Guides/agent-data-handling.mdx +++ b/content/Guides/agent-data-handling.mdx @@ -39,16 +39,16 @@ export default async function Agent( }`} py={`from agentuity import AgentRequest, AgentResponse, AgentContext async def run(request: AgentRequest, response: AgentResponse, context: AgentContext): - contentType = request.data.contentType - if contentType == 'text/plain': - text = await request.data.text() - # do something with the text - elif contentType == 'application/json': - json = await request.data.json() - # do something with the json - else: - # do something with the data - pass + contentType = request.data.contentType + if contentType == 'text/plain': + text = await request.data.text() + # do something with the text + elif contentType == 'application/json': + json = await request.data.json() + # do something with the json + else: + # do something with the data + pass `} /> ## Request Data Formats @@ -57,7 +57,7 @@ The following request data formats are supported out of the box: ### Text -You use use the `text` method on the `Data` object to get the raw text data. +You can use the `text` method on the `Data` object to get the raw text data. { return context.tracer.startActiveSpan('agent-request', async (parentSpan) => { try { - parentSpan.setAttribute('trigger', request.trigger()); + parentSpan.setAttribute('trigger', request.trigger); const data = await request.data.json(); // Create child span for data processing diff --git a/content/Guides/key-value.mdx b/content/Guides/key-value.mdx index 5ab9ca5b..ed8ea58d 100644 --- a/content/Guides/key-value.mdx +++ b/content/Guides/key-value.mdx @@ -192,7 +192,7 @@ Keys persist indefinitely by default unless you specify a TTL (time-to-live) val Use TTL for temporary data to prevent storage bloat: - **Session data**: 24-48 hours - **API cache**: 5-60 minutes -- **Rate limiting counters**: Until period reset +- **Rate-limiting counters**: Until period reset - **Permanent config**: No TTL (keys persist forever) ### Data Size Considerations diff --git a/content/Guides/vector-db.mdx b/content/Guides/vector-db.mdx index 5bec17c8..d64c994c 100644 --- a/content/Guides/vector-db.mdx +++ b/content/Guides/vector-db.mdx @@ -70,26 +70,30 @@ The upsert operation is idempotent - upserting with an existing key updates the // Upsert documents with text (automatic embedding) const ids = await context.vector.upsert( 'knowledge-base', - { - key: 'doc-1', - document: 'Agentuity is an agent-native cloud platform', - metadata: { category: 'platform', source: 'docs' } - }, - { - key: 'doc-2', - document: 'Vector storage enables semantic search capabilities', - metadata: { category: 'features', source: 'docs' } - } + [ + { + key: 'doc-1', + document: 'Agentuity is an agent-native cloud platform', + metadata: { category: 'platform', source: 'docs' } + }, + { + key: 'doc-2', + document: 'Vector storage enables semantic search capabilities', + metadata: { category: 'features', source: 'docs' } + } + ] ); // Upsert with pre-computed embeddings const embeddingIds = await context.vector.upsert( 'custom-embeddings', - { - key: 'embedding-1', - embeddings: [0.1, 0.2, 0.3, 0.4], - metadata: { id: 'doc-1', type: 'custom' } - } + [ + { + key: 'embedding-1', + embeddings: [0.1, 0.2, 0.3, 0.4], + metadata: { id: 'doc-1', type: 'custom' } + } + ] );`} py={`# Python # Upsert documents with text documents = [ @@ -200,6 +204,8 @@ if (searchResults[0]) { const fullDetails = await context.vector.get('products', searchResults[0].key); console.log('Full metadata:', fullDetails?.metadata); }`} py={`# Python +import time + # Direct lookup by key vector = await context.vector.get("knowledge-base", "doc-1") diff --git a/content/SDKs/python/api-reference.mdx b/content/SDKs/python/api-reference.mdx index f330e99b..99a4eff1 100644 --- a/content/SDKs/python/api-reference.mdx +++ b/content/SDKs/python/api-reference.mdx @@ -625,7 +625,7 @@ user_data = {"name": "John", "age": 30} await context.objectstore.put("users", "user-123.json", user_data) # Store binary data -image_data = bytes([/* image bytes */]) +image_data = b"\x00\x01..." # example bytes await context.objectstore.put( "images", "photo.jpg", @@ -786,8 +786,8 @@ agent2 = await context.get_agent({ # Invoke the agent with error handling try: - # Just pass the data (content type is inferred) - result = await agent.run({"data": "process this"}) + # Pass raw payload (content type inferred) + result = await agent.run("process this") # Process the result print(f"Agent response: {result}") except Exception as e: @@ -1049,7 +1049,7 @@ Returns the request payload as a string. **Example** ```python -text = request.data.text +text = await request.data.text() print(f"Request text: {text}") ``` @@ -1066,7 +1066,7 @@ Returns the request payload as bytes. **Example** ```python -binary_data = request.binary() +binary_data = await request.data.binary() print(f"Binary data size: {len(binary_data)} bytes") ``` @@ -1090,11 +1090,11 @@ Each method returns the request payload as bytes with the appropriate content ty ```python # Get an image from the request -image = request.png() +image = await request.data.png() # Process the image... # Get audio from the request -audio = request.mp3() +audio = await request.data.mp3() # Process the audio... ``` From 11fcd421394fe8a052cb1514b5392e928d959624 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Mon, 8 Sep 2025 10:50:47 -0700 Subject: [PATCH 4/9] More fixes --- content/Guides/agent-communication.mdx | 9 ++++--- content/Guides/vector-db.mdx | 36 ++++++++++++-------------- content/SDKs/python/api-reference.mdx | 34 ++++++++++++------------ 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/content/Guides/agent-communication.mdx b/content/Guides/agent-communication.mdx index 4b4af084..186dafad 100644 --- a/content/Guides/agent-communication.mdx +++ b/content/Guides/agent-communication.mdx @@ -86,6 +86,7 @@ export default async function Agent( }`} py={`from agentuity import AgentRequest, AgentResponse, AgentContext async def run(request: AgentRequest, response: AgentResponse, context: AgentContext): + # Python infers: string → text/plain, dict → application/json return response.handoff({"name":"My Other Agent"}, "would you please do this?") `} /> @@ -226,16 +227,16 @@ export default async function Agent( ctx: AgentContext ) { return resp.handoff({ - id: 'agent_123456789abcedef', - projectId: 'project_123456789abcedef', + id: 'agent-123456789abcedef', + projectId: 'project-123456789abcedef', }); }`} py={` from agentuity import AgentRequest, AgentResponse, AgentContext async def run(request: AgentRequest, response: AgentResponse, context: AgentContext): return response.handoff({ - "id": "agent_123456789abcedef", - "projectId": "project_123456789abcedef" + "id": "agent-123456789abcedef", + "projectId": "project-123456789abcedef" }) `} /> diff --git a/content/Guides/vector-db.mdx b/content/Guides/vector-db.mdx index d64c994c..21337fe5 100644 --- a/content/Guides/vector-db.mdx +++ b/content/Guides/vector-db.mdx @@ -70,30 +70,26 @@ The upsert operation is idempotent - upserting with an existing key updates the // Upsert documents with text (automatic embedding) const ids = await context.vector.upsert( 'knowledge-base', - [ - { - key: 'doc-1', - document: 'Agentuity is an agent-native cloud platform', - metadata: { category: 'platform', source: 'docs' } - }, - { - key: 'doc-2', - document: 'Vector storage enables semantic search capabilities', - metadata: { category: 'features', source: 'docs' } - } - ] + { + key: 'doc-1', + document: 'Agentuity is an agent-native cloud platform', + metadata: { category: 'platform', source: 'docs' } + }, + { + key: 'doc-2', + document: 'Vector storage enables semantic search capabilities', + metadata: { category: 'features', source: 'docs' } + } ); // Upsert with pre-computed embeddings const embeddingIds = await context.vector.upsert( 'custom-embeddings', - [ - { - key: 'embedding-1', - embeddings: [0.1, 0.2, 0.3, 0.4], - metadata: { id: 'doc-1', type: 'custom' } - } - ] + { + key: 'embedding-1', + embeddings: [0.1, 0.2, 0.3, 0.4], + metadata: { id: 'doc-1', type: 'custom' } + } );`} py={`# Python # Upsert documents with text documents = [ @@ -245,7 +241,7 @@ if search_results: - Use `get` when you know the exact key (like a database primary key lookup) - Use `search` when finding vectors by semantic similarity - `get` is faster for single lookups since it doesn't compute similarities -- `get` returns `null` if not found, never throws an error +- `get` returns `null` (JS) / `None` (Python) if the key is not found, but may throw errors for other failures ### Deleting Vectors diff --git a/content/SDKs/python/api-reference.mdx b/content/SDKs/python/api-reference.mdx index 99a4eff1..a3f75940 100644 --- a/content/SDKs/python/api-reference.mdx +++ b/content/SDKs/python/api-reference.mdx @@ -827,11 +827,11 @@ Returns an `AgentRedirectResponse` object. ```python # Handoff to another agent return response.handoff( - {"name": "data-processing-agent"}, - {"data": "process this"}, - "application/json", - {"source": "web-agent"} + {"name": "data-processing-agent"}, # params + "process this", # args (inferred as text/plain) + {"source": "web-agent"} # metadata ) +# Note: Python infers content-type from data (string→text/plain, dict→application/json) ``` ## Response Types @@ -1021,7 +1021,7 @@ print(f"User ID: {user_id}") #### json -`json() -> dict` +`async json() -> dict` Gets the payload of the request as a JSON object. @@ -1038,7 +1038,7 @@ print(f"Request data: {data}") #### text -`text() -> str` +`async text() -> str` Gets the payload of the request as a string. @@ -1055,7 +1055,7 @@ print(f"Request text: {text}") #### binary -`binary() -> bytes` +`async binary() -> bytes` Gets the payload of the request as bytes. @@ -1074,15 +1074,15 @@ print(f"Binary data size: {len(binary_data)} bytes") The SDK provides specialized methods for various media types: -- `pdf() -> bytes` -- `png() -> bytes` -- `jpeg() -> bytes` -- `gif() -> bytes` -- `webp() -> bytes` -- `mp3() -> bytes` -- `wav() -> bytes` -- `ogg() -> bytes` -- `email() -> Email` +- `async pdf() -> bytes` +- `async png() -> bytes` +- `async jpeg() -> bytes` +- `async gif() -> bytes` +- `async webp() -> bytes` +- `async mp3() -> bytes` +- `async wav() -> bytes` +- `async ogg() -> bytes` +- `async email() -> Email` Each method returns the request payload as bytes with the appropriate content type validation, except for `email()` which returns an `Email` object. @@ -1100,7 +1100,7 @@ audio = await request.data.mp3() #### email -`email() -> Email` +`async email() -> Email` Gets the payload of the request as an Email object. This method validates that the content type is `message/rfc822` before parsing. From cdd3cb4d507f16f917c58ef7d59b9ce4a0e2ad77 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Mon, 8 Sep 2025 19:08:44 -0700 Subject: [PATCH 5/9] Update Object Storage examples --- content/Guides/object-storage.mdx | 81 ++++++++++++++++++------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/content/Guides/object-storage.mdx b/content/Guides/object-storage.mdx index 94ffbe6f..5d1c500c 100644 --- a/content/Guides/object-storage.mdx +++ b/content/Guides/object-storage.mdx @@ -43,9 +43,8 @@ const handler: AgentHandler = async (request, response, context) => { // Bucket is created automatically on first use const imageData = Buffer.from(await request.data.binary()); - await context.objectstore.put('user-uploads', 'profile-123.jpg', imageData, { - contentType: 'image/jpeg' - }); + # Auto-detect content type (simplest approach) + await context.objectstore.put('user-uploads', 'profile-123.jpg', imageData) return response.json({ message: 'Image uploaded successfully' }); }; @@ -57,9 +56,8 @@ async def run(request: AgentRequest, response: AgentResponse, context: AgentCont # Bucket is created automatically on first use image_data = await request.data.binary() - await context.objectstore.put("user-uploads", "profile-123.jpg", image_data, { - "content_type": "image/jpeg" - }) + # Auto-detect content type (simplest approach) + await context.objectstore.put("user-uploads", "profile-123.jpg", image_data) return response.json({"message": "Image uploaded successfully"}) `} /> @@ -70,7 +68,10 @@ The object storage API provides four core operations: `get`, `put`, `delete`, an ### Storing Objects -Store files with automatic content type detection or explicit metadata: +Object storage supports two approaches for storing files: + +1. **Automatic content type detection** (recommended for most cases) - The SDK detects the content type from the data +2. **Explicit parameters** - Specify content type, metadata, and other options manually +# Text file with encoding +params = ObjectStorePutParams( + content_type="text/plain", + content_encoding="utf-8" +) +await context.objectstore.put("logs", "agent.log", log_content, params)`} /> ### Retrieving Objects @@ -257,6 +262,9 @@ await context.objectstore.put('uploads', filename, data, { contentType });`} py={`import os +# Auto-detect or use explicit params +from agentuity.server.objectstore import ObjectStorePutParams + content_types = { ".jpg": "image/jpeg", ".png": "image/png", @@ -268,9 +276,8 @@ content_types = { extension = os.path.splitext(filename)[1] content_type = content_types.get(extension, "application/octet-stream") -await context.objectstore.put("uploads", filename, data, { - "contentType": content_type -})`} /> +params = ObjectStorePutParams(content_type=content_type) +await context.objectstore.put("uploads", filename, data, params)`} /> ### Public URL Security @@ -360,13 +367,17 @@ Create a robust file upload handler: file_data = await request.data.binary() key = f"uploads/{int(time.time())}-{file_name}" - await context.objectstore.put("user-files", key, file_data, { - "content_type": content_type, - "metadata": { + # Using explicit params for metadata + from agentuity.server.objectstore import ObjectStorePutParams + + params = ObjectStorePutParams( + content_type=content_type, + metadata={ "original-name": file_name, "upload-time": datetime.now().isoformat() } - }) + ) + await context.objectstore.put("user-files", key, file_data, params) # Generate access URL url = await context.objectstore.create_public_url( From f49841f84da2d7f06535b0db15e4e1c714a6e758 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Mon, 8 Sep 2025 19:29:09 -0700 Subject: [PATCH 6/9] Add full metadata back to examples --- content/Guides/object-storage.mdx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/content/Guides/object-storage.mdx b/content/Guides/object-storage.mdx index 5d1c500c..3d0d047d 100644 --- a/content/Guides/object-storage.mdx +++ b/content/Guides/object-storage.mdx @@ -81,9 +81,12 @@ await context.objectstore.put('images', 'photo.jpg', imageBuffer, { contentType: 'image/jpeg' }); -// Store with metadata +// Store with full metadata +// These optional parameters control how the object is served await context.objectstore.put('uploads', 'document.pdf', pdfData, { contentType: 'application/pdf', + contentDisposition: 'attachment; filename="report.pdf"', // Download as 'report.pdf' + cacheControl: 'max-age=3600', // Browser caches for 1 hour metadata: { 'uploaded-by': userId, 'processed': 'false' @@ -108,9 +111,12 @@ from agentuity.server.objectstore import ObjectStorePutParams params = ObjectStorePutParams(content_type="image/jpeg") await context.objectstore.put("images", "photo.jpg", image_buffer, params) -# With metadata +# With full metadata +# These optional parameters control how the object is served via public URLs params = ObjectStorePutParams( content_type="application/pdf", + content_disposition='attachment; filename="report.pdf"', # Download as 'report.pdf' + cache_control="max-age=3600", # Browser caches for 1 hour metadata={ "uploaded-by": user_id, "processed": "false" From 903fa1bd6d99450ad5a53732109d33e35a587b2d Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Tue, 9 Sep 2025 07:52:32 -0700 Subject: [PATCH 7/9] More fixes --- content/Guides/agent-data-handling.mdx | 2 +- content/Guides/object-storage.mdx | 2 +- content/Guides/vector-db.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/Guides/agent-data-handling.mdx b/content/Guides/agent-data-handling.mdx index b5fa7c20..de491e2f 100644 --- a/content/Guides/agent-data-handling.mdx +++ b/content/Guides/agent-data-handling.mdx @@ -444,7 +444,7 @@ async def run(request: AgentRequest, response: AgentResponse, context: AgentCont chat_completion = client.chat.completions.create( messages=[ {"role": "system", "content": "You are a friendly assistant!"}, - {"role": "user", "content": request.data.text or "Why is the sky blue?"}, + {"role": "user", "content": (await request.data.text()) or "Why is the sky blue?"}, ], model="gpt-4o", stream=True, diff --git a/content/Guides/object-storage.mdx b/content/Guides/object-storage.mdx index 3d0d047d..f4639c1e 100644 --- a/content/Guides/object-storage.mdx +++ b/content/Guides/object-storage.mdx @@ -43,7 +43,7 @@ const handler: AgentHandler = async (request, response, context) => { // Bucket is created automatically on first use const imageData = Buffer.from(await request.data.binary()); - # Auto-detect content type (simplest approach) + // Auto-detect content type (simplest approach) await context.objectstore.put('user-uploads', 'profile-123.jpg', imageData) return response.json({ message: 'Image uploaded successfully' }); diff --git a/content/Guides/vector-db.mdx b/content/Guides/vector-db.mdx index 21337fe5..c2c7a367 100644 --- a/content/Guides/vector-db.mdx +++ b/content/Guides/vector-db.mdx @@ -185,7 +185,7 @@ if (existing) { await context.vector.upsert('products', { key: 'product-123', document: 'Updated product description', - metadata: { ...existing.metadata, lastUpdated: Date.now() } + metadata: { ...(existing.metadata ?? {}), lastUpdated: Date.now() } }); } From af405358bc97ee36787a1565ba21cf7b24c99513 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Wed, 10 Sep 2025 17:59:00 -0700 Subject: [PATCH 8/9] Fix Python log info, agent logging guide --- content/Guides/agent-logging.mdx | 236 ++++++++++++++-------- content/SDKs/javascript/api-reference.mdx | 2 +- content/SDKs/python/api-reference.mdx | 71 +++---- 3 files changed, 182 insertions(+), 127 deletions(-) diff --git a/content/Guides/agent-logging.mdx b/content/Guides/agent-logging.mdx index e916aebf..ff748acc 100644 --- a/content/Guides/agent-logging.mdx +++ b/content/Guides/agent-logging.mdx @@ -45,30 +45,75 @@ Each log entry provides comprehensive context and can be expanded for full detai ## Logging Best Practices + +**Language Differences:** JavaScript supports structured data objects in logging, while Python uses the standard `logging.Logger` interface. + + ### 1. Use Appropriate Log Levels +error_msg = str(err) +context.logger.error(f"Failed to fetch data error={error_msg}")`} /> + +### 2. Use Structured Data + +Use structured data to provide context and make logs easier to parse and analyze: + + + +### 3. Include Relevant Context Log enough information to understand what happened without re-running: -### 3. Log Decision Points +### 4. Include Agentuity-Specific Information + +Add Agentuity-specific information to help with debugging and monitoring: + + + +### 5. Log Decision Points Help future debugging by logging key decisions: + key = "user_123" + reason = "expired" + context.logger.info(f"Cache miss, fetching fresh data cache_key={key} reason={reason}") +`} /> -### 4. Avoid Logging Sensitive Data +### 6. Avoid Logging Sensitive Data Never log passwords, tokens, or personal information: - -### 5. Use Child Loggers for Request Context - -Create child loggers to automatically include context in all related logs: - - - -## Structured Logging - -Use structured data for easier parsing and analysis: - - +user_id = "user123" +context.logger.info(f"User authenticated user_id={user_id}") + +# Not this - Never log passwords! +login_name = "john" +user_password = "secret123" +context.logger.info(f"Login attempt username={login_name} password={user_password}") # Never do this! +`} /> + +### 7. Use Child Loggers for Different Tasks + +Create child loggers to organize logging for different parts of your workflow: + + For more observability features, see [Agent Telemetry](/Guides/agent-telemetry) and [Agent Tracing](/Guides/agent-tracing). \ No newline at end of file diff --git a/content/SDKs/javascript/api-reference.mdx b/content/SDKs/javascript/api-reference.mdx index d7092958..13bd5ca0 100644 --- a/content/SDKs/javascript/api-reference.mdx +++ b/content/SDKs/javascript/api-reference.mdx @@ -1481,7 +1481,7 @@ Returns a new `Logger` instance with the additional context. ```typescript const requestLogger = context.logger.child({ requestId: '123', userId: '456' }); -requestLogger.info('Processing request'); // Includes requestId and userId +requestLogger.info('Processing request'); ``` ## Welcome Function diff --git a/content/SDKs/python/api-reference.mdx b/content/SDKs/python/api-reference.mdx index a3f75940..4e3ac1be 100644 --- a/content/SDKs/python/api-reference.mdx +++ b/content/SDKs/python/api-reference.mdx @@ -1255,97 +1255,98 @@ The Agentuity SDK provides logging functionality through the `context.logger` ob ### Logger Interface -The `Logger` class defines the following methods: +The Python SDK provides a standard `logging.Logger` instance through `context.logger`: ```python -class Logger: +class Logger(logging.Logger): """ Logger for agent execution. """ - def debug(self, message: str, *args, **kwargs) -> None: + def debug(self, message: str, *args) -> None: """Log a debug message.""" pass - def info(self, message: str, *args, **kwargs) -> None: + def info(self, message: str, *args) -> None: """Log an informational message.""" pass - def warn(self, message: str, *args, **kwargs) -> None: + def warning(self, message: str, *args) -> None: """Log a warning message.""" pass - def error(self, message: str, *args, **kwargs) -> None: + def error(self, message: str, *args) -> None: """Log an error message.""" pass - def child(self, **kwargs) -> 'Logger': - """Create a child logger with additional context.""" - pass + # Note: child() method coming soon for API consistency with JavaScript SDK ``` ### Logging Methods #### debug -`debug(message: str, *args, **kwargs) -> None` +`debug(message: str, *args) -> None` Logs a debug message. **Parameters** - `message`: The message to log -- `args`, `kwargs`: Additional arguments to include in the log +- `args`: Additional arguments to include in the log **Example** ```python -context.logger.debug("Processing request", request_id="123") +request_id = "123" +context.logger.debug(f"Processing request request_id={request_id}") ``` #### info -`info(message: str, *args, **kwargs) -> None` +`info(message: str, *args) -> None` Logs an informational message. **Parameters** - `message`: The message to log -- `args`, `kwargs`: Additional arguments to include in the log +- `args`: Additional arguments to include in the log **Example** ```python -context.logger.info("Request processed successfully", request_id="123") +request_id = "123" +context.logger.info(f"Request processed successfully request_id={request_id}") ``` -#### warn +#### warning -`warn(message: str, *args, **kwargs) -> None` +`warning(message: str, *args) -> None` Logs a warning message. **Parameters** - `message`: The message to log -- `args`, `kwargs`: Additional arguments to include in the log +- `args`: Additional arguments to include in the log **Example** ```python -context.logger.warn("Resource not found", resource_id="456") +resource_id = "456" +context.logger.warning(f"Resource not found resource_id={resource_id}") ``` #### error -`error(message: str, *args, **kwargs) -> None` +`error(message: str, *args) -> None` Logs an error message. **Parameters** - `message`: The message to log -- `args`, `kwargs`: Additional arguments to include in the log +- `args`: Additional arguments to include in the log **Example** @@ -1354,30 +1355,24 @@ try: # Some code that might raise an exception result = process_data() except Exception as e: - context.logger.error("Failed to process request", error=str(e)) + context.logger.error(f"Failed to process request: {str(e)}") ``` ### Creating Child Loggers -#### child - -`child(**kwargs) -> Logger` - -Creates a child logger with additional context. - -**Parameters** - -- `kwargs`: Additional context to include in all logs from the child logger - -**Return Value** +Child logger functionality is coming soon for API consistency with the JavaScript SDK. -Returns a new `Logger` instance with the additional context. - -**Example** +**Current approach (manual context):** ```python -request_logger = context.logger.child(request_id="123", user_id="456") -request_logger.info("Processing request") # Includes request_id and user_id +# Python: Include context in each log message +request_id = "123" +user_id = "456" +endpoint = "/api/users" + +context.logger.info(f"Starting request processing request_id={request_id} endpoint={endpoint}") +context.logger.info(f"User authenticated request_id={request_id} user_id={user_id}") +context.logger.error(f"Failed to fetch user data request_id={request_id} error={str(error)}") ``` ## Telemetry From 67c33ae2550bae69e9d453d67dea4dff4d5de9b4 Mon Sep 17 00:00:00 2001 From: parteeksingh24 Date: Wed, 10 Sep 2025 19:04:04 -0700 Subject: [PATCH 9/9] Implement suggestions --- content/Guides/agent-logging.mdx | 15 +++++++++++---- content/Guides/vector-db.mdx | 5 +++-- content/SDKs/javascript/api-reference.mdx | 10 +++++----- content/SDKs/python/api-reference.mdx | 4 ++-- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/content/Guides/agent-logging.mdx b/content/Guides/agent-logging.mdx index ff748acc..fec1553b 100644 --- a/content/Guides/agent-logging.mdx +++ b/content/Guides/agent-logging.mdx @@ -46,7 +46,7 @@ Each log entry provides comprehensive context and can be expanded for full detai ## Logging Best Practices -**Language Differences:** JavaScript supports structured data objects in logging, while Python uses the standard `logging.Logger` interface. +**Language Differences:** JavaScript supports structured data objects directly, while Python uses the standard `logging.Logger` interface (with structured data via `extra` parameters). ### 1. Use Appropriate Log Levels @@ -68,8 +68,12 @@ remaining_requests = 5 context.logger.warning(f"Rate limit approaching remaining={remaining_requests}") # ERROR: Failures requiring attention -error_msg = str(err) -context.logger.error(f"Failed to fetch data error={error_msg}")`} /> +try: + # Operation that might fail + data = fetch_some_data() +except Exception as err: + error_msg = str(err) + context.logger.error(f"Failed to fetch data error={error_msg}")`} /> ### 2. Use Structured Data @@ -106,7 +110,10 @@ order_id = order.id item_count = len(order.items) total_amount = order.total -context.logger.info(f"Order processed order_id={order_id} item_count={item_count} total={total_amount}")`} /> +context.logger.info(f"Order processed order_id={order_id} item_count={item_count} total={total_amount}") + +# For structured logging, extra parameters are also supported +context.logger.info("Order processed", extra={"order_id": order_id, "item_count": item_count})`} /> ### 3. Include Relevant Context diff --git a/content/Guides/vector-db.mdx b/content/Guides/vector-db.mdx index c2c7a367..4ff49d1f 100644 --- a/content/Guides/vector-db.mdx +++ b/content/Guides/vector-db.mdx @@ -218,10 +218,11 @@ else: existing = await context.vector.get("products", "product-123") if existing: # Update with merged metadata + metadata = existing.metadata or {} await context.vector.upsert("products", [{ - "key": "product-123", + "key": "product-123", "document": "Updated product description", - "metadata": {**existing.metadata, "lastUpdated": int(time.time())} + "metadata": {**metadata, "lastUpdated": int(time.time() * 1000)} }]) # 2. Retrieve full metadata after search diff --git a/content/SDKs/javascript/api-reference.mdx b/content/SDKs/javascript/api-reference.mdx index 13bd5ca0..7c599c7f 100644 --- a/content/SDKs/javascript/api-reference.mdx +++ b/content/SDKs/javascript/api-reference.mdx @@ -318,20 +318,20 @@ Returns a Promise that resolves to the number of vectors that were deleted. **Examples** ```typescript -// Delete a single vector -const deletedCount = await context.vector.delete('product-descriptions', 'id1'); +// Delete a single vector by key +const deletedCount = await context.vector.delete('product-descriptions', 'chair-001'); console.log(`Deleted ${deletedCount} vector(s)`); // Output: Deleted 1 vector(s) // Delete multiple vectors in bulk (more efficient than individual calls) -const deletedCount = await context.vector.delete('product-descriptions', 'id1', 'id2', 'id3'); +const deletedCount = await context.vector.delete('product-descriptions', 'chair-001', 'headphones-001', 'desk-002'); console.log(`Deleted ${deletedCount} vector(s)`); // Output: Deleted 3 vector(s) // Delete with array spread -const keysToDelete = ['id1', 'id2', 'id3']; +const keysToDelete = ['chair-001', 'headphones-001', 'desk-002']; const deletedCount = await context.vector.delete('product-descriptions', ...keysToDelete); // Handle cases where some vectors might not exist -const deletedCount = await context.vector.delete('product-descriptions', 'existing-id', 'non-existent-id'); +const deletedCount = await context.vector.delete('product-descriptions', 'existing-key', 'non-existent-key'); console.log(`Deleted ${deletedCount} vector(s)`); // Output: Deleted 1 vector(s) ``` diff --git a/content/SDKs/python/api-reference.mdx b/content/SDKs/python/api-reference.mdx index 4e3ac1be..82b510b1 100644 --- a/content/SDKs/python/api-reference.mdx +++ b/content/SDKs/python/api-reference.mdx @@ -828,8 +828,8 @@ Returns an `AgentRedirectResponse` object. # Handoff to another agent return response.handoff( {"name": "data-processing-agent"}, # params - "process this", # args (inferred as text/plain) - {"source": "web-agent"} # metadata + "process this", # payload (inferred as text/plain) + metadata={"source": "web-agent"} # metadata (keyword arg) ) # Note: Python infers content-type from data (string→text/plain, dict→application/json) ```