Compare commits

...
Author SHA1 Message Date
Nicolò Boschi aaaa207c15 feat: add operation_id to retain response 2026-01-08 16:30:05 +01:00
5 changed files with 92 additions and 1 deletions
+5
View File
@@ -381,6 +381,10 @@ class RetainResponse(BaseModel):
is_async: bool = Field(
alias="async", serialization_alias="async", description="Whether the operation was processed asynchronously"
)
operation_id: str | None = Field(
default=None,
description="Operation ID for tracking async operations. Use GET /v1/default/banks/{bank_id}/operations to list operations and find this ID. Only present when async=true.",
)
usage: TokenUsage | None = Field(
default=None,
description="Token usage metrics for LLM calls during fact extraction (only present for synchronous operations)",
@@ -2034,6 +2038,7 @@ def _register_routes(app: FastAPI):
"bank_id": bank_id,
"items_count": result["items_count"],
"async": True,
"operation_id": result["operation_id"],
}
)
else:
@@ -31,8 +31,9 @@ class RetainResponse(BaseModel):
bank_id: StrictStr
items_count: StrictInt
var_async: StrictBool = Field(description="Whether the operation was processed asynchronously", alias="async")
operation_id: Optional[StrictStr] = None
usage: Optional[TokenUsage] = None
__properties: ClassVar[List[str]] = ["success", "bank_id", "items_count", "async", "usage"]
__properties: ClassVar[List[str]] = ["success", "bank_id", "items_count", "async", "operation_id", "usage"]
model_config = ConfigDict(
populate_by_name=True,
@@ -76,6 +77,11 @@ class RetainResponse(BaseModel):
# override the default output from pydantic by calling `to_dict()` of usage
if self.usage:
_dict['usage'] = self.usage.to_dict()
# set to None if operation_id (nullable) is None
# and model_fields_set contains the field
if self.operation_id is None and "operation_id" in self.model_fields_set:
_dict['operation_id'] = None
# set to None if usage (nullable) is None
# and model_fields_set contains the field
if self.usage is None and "usage" in self.model_fields_set:
@@ -97,6 +103,7 @@ class RetainResponse(BaseModel):
"bank_id": obj.get("bank_id"),
"items_count": obj.get("items_count"),
"async": obj.get("async"),
"operation_id": obj.get("operation_id"),
"usage": TokenUsage.from_dict(obj["usage"]) if obj.get("usage") is not None else None
})
return _obj
@@ -1018,6 +1018,12 @@ export type RetainResponse = {
* Whether the operation was processed asynchronously
*/
async: boolean;
/**
* Operation Id
*
* Operation ID for tracking async operations. Use GET /v1/default/banks/{bank_id}/operations to list operations and find this ID. Only present when async=true.
*/
operation_id?: string | null;
/**
* Token usage metrics for LLM calls during fact extraction (only present for synchronous operations)
*/
@@ -30,6 +30,67 @@ Support for external streaming platforms like Kafka for scale-out processing is
| **access_count_update** | After `recall` | Tracks which memories are accessed for relevance scoring |
| **regenerate_observations** | Bank profile update | Regenerates entity observations when disposition changes |
## Async Retain Example
When retaining large batches of memories, use `async=true` to process in the background. The response includes an `operation_id` that you can use to poll for completion.
### 1. Submit async retain request
```bash
curl -X POST "http://localhost:8000/v1/default/banks/my-bank/memories" \
-H "Content-Type: application/json" \
-d '{
"items": [
{"content": "Alice joined Google in 2023"},
{"content": "Bob prefers Python over JavaScript"}
],
"async": true
}'
```
Response:
```json
{
"success": true,
"bank_id": "my-bank",
"items_count": 2,
"async": true,
"operation_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
### 2. Poll for operation status
```bash
curl "http://localhost:8000/v1/default/banks/my-bank/operations"
```
Response:
```json
{
"bank_id": "my-bank",
"operations": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"task_type": "retain",
"items_count": 2,
"document_id": null,
"created_at": "2024-01-15T10:30:00Z",
"status": "completed",
"error_message": null
}
]
}
```
### Operation Status Values
| Status | Description |
|--------|-------------|
| `pending` | Operation is queued and waiting to be processed |
| `completed` | Operation finished successfully |
| `failed` | Operation failed (check `error_message` for details) |
## Next Steps
- [**Documents**](./documents) — Track document sources
+12
View File
@@ -3524,6 +3524,18 @@
"title": "Async",
"description": "Whether the operation was processed asynchronously"
},
"operation_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Operation Id",
"description": "Operation ID for tracking async operations. Use GET /v1/default/banks/{bank_id}/operations to list operations and find this ID. Only present when async=true."
},
"usage": {
"anyOf": [
{