diff --git a/README.md b/README.md index 8668021e..7dd65d02 100644 --- a/README.md +++ b/README.md @@ -448,8 +448,6 @@ configure( agent_id="my-agent", # Agent identifier (required) store_conversations=True, # Store conversations inject_memories=True, # Inject memories - memory_search_budget=10, # Number of memories to retrieve - context_window=10, # Conversation history size document_id="session-123", # Optional: Group conversations by document ID enabled=True, # Master switch ) diff --git a/docs/openapi-generators-comparison.md b/docs/openapi-generators-comparison.md new file mode 100644 index 00000000..8ebcea57 --- /dev/null +++ b/docs/openapi-generators-comparison.md @@ -0,0 +1,132 @@ +# OpenAPI Client Generator Comparison + +## Current: openapi-python-client +**Pros:** +- Python-native (no Java required) +- Lightweight +- Good type hints +- Uses httpx (modern) + +**Cons:** +- Functional style (not OOP) +- Verbose imports +- Awkward API (need to pass client everywhere) + +## Option 1: openapi-generator (Recommended) +**Command:** `openapi-generator-cli generate -i openapi.json -g python -o memora-clients/python` + +**Pros:** +- ✅ **OOP style** - generates `client.search_memories()` not `search_memories.sync(client=...)` +- ✅ Widely used (industry standard) +- ✅ Active development +- ✅ Generates proper SDK with clean imports +- ✅ Built-in retry, timeout handling + +**Cons:** +- Requires Java Runtime (but can use Docker) +- Larger generated code +- Some boilerplate + +**Example Generated Code:** +```python +from memora_client import ApiClient, Configuration, MemoryOperationsApi + +config = Configuration(host="http://localhost:8000") +client = ApiClient(config) +api = MemoryOperationsApi(client) + +# Clean method calls! +results = api.search_memories( + agent_id="alice", + search_request=SearchRequest(query="...") +) +``` + +## Option 2: fern +**Command:** `fern generate` + +**Pros:** +- ✅ Modern, best-in-class DX +- ✅ Beautiful generated code +- ✅ Excellent type hints +- ✅ Async-first +- ✅ Pydantic v2 models + +**Cons:** +- Requires `fern.config.yml` setup +- Less mature than openapi-generator +- Config-heavy + +**Example:** +```python +from memora import Memora + +client = Memora(base_url="http://localhost:8000") +results = client.search_memories(agent_id="alice", query="...") +``` + +## Option 3: speakeasy +**Command:** `speakeasy generate sdk` + +**Pros:** +- ✅ Very clean generated code +- ✅ Great DX +- ✅ SDK versioning built-in + +**Cons:** +- Commercial (free tier available) +- Requires account +- Less control + +## Recommendation: openapi-generator + +Use **openapi-generator** because it: +1. Generates proper OOP-style APIs +2. Industry standard with great support +3. Can run via Docker (no Java install needed) +4. Will give you `api.search_memories()` style calls + +### Migration Steps: + +1. **Install via Docker:** +```bash +alias openapi-generator='docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli' +``` + +2. **Generate config:** +```bash +openapi-generator config-help -g python +``` + +3. **Create config file:** `openapi-generator-config.yaml` +```yaml +packageName: memora_client +projectName: memora-client +packageVersion: 0.0.7 +library: urllib3 # or 'asyncio' for async +``` + +4. **Generate:** +```bash +openapi-generator generate \ + -i openapi.json \ + -g python \ + -o memora-clients/python \ + -c openapi-generator-config.yaml +``` + +This will generate code like: +```python +import memora_client +from memora_client.api import memory_operations_api + +config = memora_client.Configuration(host="http://localhost:8000") +with memora_client.ApiClient(config) as api_client: + api = memory_operations_api.MemoryOperationsApi(api_client) + response = api.search_memories( + agent_id="alice", + search_request=SearchRequest(query="...") + ) +``` + +Then we add our thin `Memora` wrapper on top for even simpler usage! diff --git a/memora-clients/python/.gitignore b/memora-clients/python/.gitignore deleted file mode 100644 index 79a2c3d7..00000000 --- a/memora-clients/python/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -__pycache__/ -build/ -dist/ -*.egg-info/ -.pytest_cache/ - -# pyenv -.python-version - -# Environments -.env -.venv - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# JetBrains -.idea/ - -/coverage.xml -/.coverage diff --git a/memora-clients/python/.openapi-generator-ignore b/memora-clients/python/.openapi-generator-ignore new file mode 100644 index 00000000..7484ee59 --- /dev/null +++ b/memora-clients/python/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/memora-clients/python/.openapi-generator/FILES b/memora-clients/python/.openapi-generator/FILES new file mode 100644 index 00000000..a74ffe78 --- /dev/null +++ b/memora-clients/python/.openapi-generator/FILES @@ -0,0 +1,103 @@ +memora_client_api/__init__.py +memora_client_api/api/__init__.py +memora_client_api/api/agent_management_api.py +memora_client_api/api/documents_api.py +memora_client_api/api/memory_operations_api.py +memora_client_api/api/reasoning_api.py +memora_client_api/api/visualization_api.py +memora_client_api/api_client.py +memora_client_api/api_response.py +memora_client_api/configuration.py +memora_client_api/docs/AddBackgroundRequest.md +memora_client_api/docs/AgentListItem.md +memora_client_api/docs/AgentListResponse.md +memora_client_api/docs/AgentManagementApi.md +memora_client_api/docs/AgentProfileResponse.md +memora_client_api/docs/BackgroundResponse.md +memora_client_api/docs/BatchPutAsyncResponse.md +memora_client_api/docs/BatchPutRequest.md +memora_client_api/docs/BatchPutResponse.md +memora_client_api/docs/CreateAgentRequest.md +memora_client_api/docs/DeleteResponse.md +memora_client_api/docs/DocumentResponse.md +memora_client_api/docs/DocumentsApi.md +memora_client_api/docs/GraphDataResponse.md +memora_client_api/docs/HTTPValidationError.md +memora_client_api/docs/ListDocumentsResponse.md +memora_client_api/docs/ListMemoryUnitsResponse.md +memora_client_api/docs/MemoryItem.md +memora_client_api/docs/MemoryOperationsApi.md +memora_client_api/docs/PersonalityTraits.md +memora_client_api/docs/ReasoningApi.md +memora_client_api/docs/SearchRequest.md +memora_client_api/docs/SearchResponse.md +memora_client_api/docs/SearchResult.md +memora_client_api/docs/ThinkFact.md +memora_client_api/docs/ThinkRequest.md +memora_client_api/docs/ThinkResponse.md +memora_client_api/docs/UpdatePersonalityRequest.md +memora_client_api/docs/ValidationError.md +memora_client_api/docs/ValidationErrorLocInner.md +memora_client_api/docs/VisualizationApi.md +memora_client_api/exceptions.py +memora_client_api/models/__init__.py +memora_client_api/models/add_background_request.py +memora_client_api/models/agent_list_item.py +memora_client_api/models/agent_list_response.py +memora_client_api/models/agent_profile_response.py +memora_client_api/models/background_response.py +memora_client_api/models/batch_put_async_response.py +memora_client_api/models/batch_put_request.py +memora_client_api/models/batch_put_response.py +memora_client_api/models/create_agent_request.py +memora_client_api/models/delete_response.py +memora_client_api/models/document_response.py +memora_client_api/models/graph_data_response.py +memora_client_api/models/http_validation_error.py +memora_client_api/models/list_documents_response.py +memora_client_api/models/list_memory_units_response.py +memora_client_api/models/memory_item.py +memora_client_api/models/personality_traits.py +memora_client_api/models/search_request.py +memora_client_api/models/search_response.py +memora_client_api/models/search_result.py +memora_client_api/models/think_fact.py +memora_client_api/models/think_request.py +memora_client_api/models/think_response.py +memora_client_api/models/update_personality_request.py +memora_client_api/models/validation_error.py +memora_client_api/models/validation_error_loc_inner.py +memora_client_api/rest.py +memora_client_api/test/__init__.py +memora_client_api/test/test_add_background_request.py +memora_client_api/test/test_agent_list_item.py +memora_client_api/test/test_agent_list_response.py +memora_client_api/test/test_agent_management_api.py +memora_client_api/test/test_agent_profile_response.py +memora_client_api/test/test_background_response.py +memora_client_api/test/test_batch_put_async_response.py +memora_client_api/test/test_batch_put_request.py +memora_client_api/test/test_batch_put_response.py +memora_client_api/test/test_create_agent_request.py +memora_client_api/test/test_delete_response.py +memora_client_api/test/test_document_response.py +memora_client_api/test/test_documents_api.py +memora_client_api/test/test_graph_data_response.py +memora_client_api/test/test_http_validation_error.py +memora_client_api/test/test_list_documents_response.py +memora_client_api/test/test_list_memory_units_response.py +memora_client_api/test/test_memory_item.py +memora_client_api/test/test_memory_operations_api.py +memora_client_api/test/test_personality_traits.py +memora_client_api/test/test_reasoning_api.py +memora_client_api/test/test_search_request.py +memora_client_api/test/test_search_response.py +memora_client_api/test/test_search_result.py +memora_client_api/test/test_think_fact.py +memora_client_api/test/test_think_request.py +memora_client_api/test/test_think_response.py +memora_client_api/test/test_update_personality_request.py +memora_client_api/test/test_validation_error.py +memora_client_api/test/test_validation_error_loc_inner.py +memora_client_api/test/test_visualization_api.py +memora_client_api_README.md diff --git a/memora-clients/python/.openapi-generator/VERSION b/memora-clients/python/.openapi-generator/VERSION new file mode 100644 index 00000000..2fb556b6 --- /dev/null +++ b/memora-clients/python/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.18.0-SNAPSHOT diff --git a/memora-clients/python/README.md b/memora-clients/python/README.md index 2a931938..93ab2a3f 100644 --- a/memora-clients/python/README.md +++ b/memora-clients/python/README.md @@ -1,8 +1,6 @@ -# memora-client +# Memora Python Client -Python client for Memora - Semantic memory system with personality-driven thinking. - -**Auto-generated from OpenAPI spec** - provides type-safe access to all Memora API endpoints. +Clean, pythonic client for the Memora API - A semantic memory system with personality-driven thinking. ## Installation @@ -13,67 +11,124 @@ pip install memora-client ## Quick Start ```python -from agent_memory_api_client import Client -from agent_memory_api_client.api.memory_storage import put_api_put_post -from agent_memory_api_client.api.reasoning import think_api_think_post +from memora_client import Memora -client = Client(base_url="http://localhost:8000") +# Initialize client +client = Memora(base_url="http://localhost:8000") -# Store memory -put_api_put_post.sync( - client=client, - body={ - "agent_id": "user123", - "content": "Alice loves machine learning" - } -) +# Store a memory +client.store(agent_id="alice", content="Alice loves artificial intelligence") -# Think (generate answer with personality) -response = think_api_think_post.sync( - client=client, - body={ - "agent_id": "user123", - "query": "What does Alice think about AI?", - "thinking_budget": 50 - } -) -print(response.text) +# Search memories +results = client.search(agent_id="alice", query="What does Alice like?") +print(results) + +# Generate contextual answer +answer = client.think(agent_id="alice", query="What are my interests?") +print(answer["text"]) ``` -## Async Support +## Main Operations + +### Store Memories ```python -from agent_memory_api_client import Client -from agent_memory_api_client.api.reasoning import think_api_think_post +# Store a single memory +client.store( + agent_id="alice", + content="Alice completed a Python project using FastAPI", + event_date=datetime(2024, 1, 15), + context="work projects" +) -async with Client(base_url="http://localhost:8000") as client: - response = await think_api_think_post.asyncio( - client=client, - body={ - "agent_id": "user123", - "query": "What does Alice think about AI?" - } - ) - print(response.text) +# Store multiple memories in batch +client.store_batch( + agent_id="alice", + items=[ + {"content": "Alice loves machine learning"}, + {"content": "Bob enjoys hiking", "event_date": datetime(2024, 10, 15)}, + ] +) ``` -## API Modules +### Search Memories -This client provides access to: -- `memory_storage` - Store and retrieve facts -- `search` - Semantic and temporal search -- `reasoning` - Personality-driven thinking -- `visualization` - Memory graphs and statistics -- `management` - Agent profiles and configuration -- `documents` - Document tracking +```python +# Simple search +results = client.search( + agent_id="alice", + query="What does Alice like?", + max_tokens=2048 +) -See auto-generated code for full API surface and type hints. +# Advanced search with all options +response = client.search_memories( + agent_id="alice", + query="What are Alice's interests?", + fact_type=["world"], + max_tokens=4096, + trace=True # Include trace information +) +``` + +### Think (Generate Contextual Answers) + +```python +answer = client.think( + agent_id="alice", + query="What should I focus on learning next?", + thinking_budget=100, + context="I want to advance my career in AI" +) + +print(answer["text"]) # The generated answer +print(answer["based_on"]) # Facts used to generate the answer +``` + +## Structure + +``` +memora-client/ +├── memora_client/ # Maintained wrapper (simple API) +│ ├── __init__.py +│ ├── memora_client.py # Clean interface: store(), search(), think() +│ └── tests/ +│ └── test_main_operations.py +│ +└── memora_client_api/ # Auto-generated from OpenAPI spec + ├── api/ # Full API operations + ├── models/ # Request/response models + └── ... +``` + +## Testing + +Run integration tests (requires running Memora API server): + +```bash +# Set API URL (optional, defaults to http://localhost:8000) +export MEMORA_API_URL=http://localhost:8000 + +# Run tests +pytest memora_client/tests/test_main_operations.py -v +``` ## Development -Auto-generated from `openapi.json`. See [RELEASE.md](../../RELEASE.md) for regeneration instructions. +### Regenerate Client -## Links +The low-level API client is auto-generated from the OpenAPI spec. The high-level wrapper (`memora_client/`) is maintained and won't be overwritten. -- [GitHub Repository](https://github.com/nicoloboschi/memora) -- [Full Documentation](https://github.com/nicoloboschi/memora/blob/main/README.md) +```bash +# Regenerate from OpenAPI spec +./scripts/generate-clients.sh +``` + +This preserves: +- `memora_client/` - Maintained wrapper +- `pyproject.toml` - Package configuration +- Tests and documentation + +## License + +Apache 2.0 diff --git a/memora-clients/python/agent_memory_api_client/__init__.py b/memora-clients/python/agent_memory_api_client/__init__.py deleted file mode 100644 index 21ca89ce..00000000 --- a/memora-clients/python/agent_memory_api_client/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -"""A client library for accessing Agent Memory API""" - -from .client import AuthenticatedClient, Client - -__all__ = ( - "AuthenticatedClient", - "Client", -) diff --git a/memora-clients/python/agent_memory_api_client/api/__init__.py b/memora-clients/python/agent_memory_api_client/api/__init__.py deleted file mode 100644 index 81f9fa24..00000000 --- a/memora-clients/python/agent_memory_api_client/api/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Contains methods for accessing the API""" diff --git a/memora-clients/python/agent_memory_api_client/api/agent_management/__init__.py b/memora-clients/python/agent_memory_api_client/api/agent_management/__init__.py deleted file mode 100644 index 2d7c0b23..00000000 --- a/memora-clients/python/agent_memory_api_client/api/agent_management/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Contains endpoint functions for accessing the API""" diff --git a/memora-clients/python/agent_memory_api_client/api/agent_management/api_add_agent_background_api_v1_agents_agent_id_background_post.py b/memora-clients/python/agent_memory_api_client/api/agent_management/api_add_agent_background_api_v1_agents_agent_id_background_post.py deleted file mode 100644 index 8830681c..00000000 --- a/memora-clients/python/agent_memory_api_client/api/agent_management/api_add_agent_background_api_v1_agents_agent_id_background_post.py +++ /dev/null @@ -1,195 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.add_background_request import AddBackgroundRequest -from ...models.background_response import BackgroundResponse -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, - *, - body: AddBackgroundRequest, -) -> dict[str, Any]: - headers: dict[str, Any] = {} - - _kwargs: dict[str, Any] = { - "method": "post", - "url": f"/api/v1/agents/{agent_id}/background", - } - - _kwargs["json"] = body.to_dict() - - headers["Content-Type"] = "application/json" - - _kwargs["headers"] = headers - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> BackgroundResponse | HTTPValidationError | None: - if response.status_code == 200: - response_200 = BackgroundResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[BackgroundResponse | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: AddBackgroundRequest, -) -> Response[BackgroundResponse | HTTPValidationError]: - """Add/merge agent background - - Add new background information or merge with existing. LLM intelligently resolves conflicts, - normalizes to first person, and optionally infers personality traits. - - Args: - agent_id (str): - body (AddBackgroundRequest): Request model for adding/merging background information. - Example: {'content': 'I was born in Texas', 'update_personality': True}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[BackgroundResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: AddBackgroundRequest, -) -> BackgroundResponse | HTTPValidationError | None: - """Add/merge agent background - - Add new background information or merge with existing. LLM intelligently resolves conflicts, - normalizes to first person, and optionally infers personality traits. - - Args: - agent_id (str): - body (AddBackgroundRequest): Request model for adding/merging background information. - Example: {'content': 'I was born in Texas', 'update_personality': True}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - BackgroundResponse | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - body=body, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: AddBackgroundRequest, -) -> Response[BackgroundResponse | HTTPValidationError]: - """Add/merge agent background - - Add new background information or merge with existing. LLM intelligently resolves conflicts, - normalizes to first person, and optionally infers personality traits. - - Args: - agent_id (str): - body (AddBackgroundRequest): Request model for adding/merging background information. - Example: {'content': 'I was born in Texas', 'update_personality': True}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[BackgroundResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: AddBackgroundRequest, -) -> BackgroundResponse | HTTPValidationError | None: - """Add/merge agent background - - Add new background information or merge with existing. LLM intelligently resolves conflicts, - normalizes to first person, and optionally infers personality traits. - - Args: - agent_id (str): - body (AddBackgroundRequest): Request model for adding/merging background information. - Example: {'content': 'I was born in Texas', 'update_personality': True}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - BackgroundResponse | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - body=body, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/agent_management/api_agents_api_v1_agents_get.py b/memora-clients/python/agent_memory_api_client/api/agent_management/api_agents_api_v1_agents_get.py deleted file mode 100644 index 392ab0f9..00000000 --- a/memora-clients/python/agent_memory_api_client/api/agent_management/api_agents_api_v1_agents_get.py +++ /dev/null @@ -1,131 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.agent_list_response import AgentListResponse -from ...types import Response - - -def _get_kwargs() -> dict[str, Any]: - _kwargs: dict[str, Any] = { - "method": "get", - "url": "/api/v1/agents", - } - - return _kwargs - - -def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> AgentListResponse | None: - if response.status_code == 200: - response_200 = AgentListResponse.from_dict(response.json()) - - return response_200 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[AgentListResponse]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - *, - client: AuthenticatedClient | Client, -) -> Response[AgentListResponse]: - """List all agents - - Get a list of all agents with their profiles - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[AgentListResponse] - """ - - kwargs = _get_kwargs() - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - *, - client: AuthenticatedClient | Client, -) -> AgentListResponse | None: - """List all agents - - Get a list of all agents with their profiles - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - AgentListResponse - """ - - return sync_detailed( - client=client, - ).parsed - - -async def asyncio_detailed( - *, - client: AuthenticatedClient | Client, -) -> Response[AgentListResponse]: - """List all agents - - Get a list of all agents with their profiles - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[AgentListResponse] - """ - - kwargs = _get_kwargs() - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - *, - client: AuthenticatedClient | Client, -) -> AgentListResponse | None: - """List all agents - - Get a list of all agents with their profiles - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - AgentListResponse - """ - - return ( - await asyncio_detailed( - client=client, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/agent_management/api_create_or_update_agent_api_v1_agents_agent_id_put.py b/memora-clients/python/agent_memory_api_client/api/agent_management/api_create_or_update_agent_api_v1_agents_agent_id_put.py deleted file mode 100644 index af4f4a7f..00000000 --- a/memora-clients/python/agent_memory_api_client/api/agent_management/api_create_or_update_agent_api_v1_agents_agent_id_put.py +++ /dev/null @@ -1,203 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.agent_profile_response import AgentProfileResponse -from ...models.create_agent_request import CreateAgentRequest -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, - *, - body: CreateAgentRequest, -) -> dict[str, Any]: - headers: dict[str, Any] = {} - - _kwargs: dict[str, Any] = { - "method": "put", - "url": f"/api/v1/agents/{agent_id}", - } - - _kwargs["json"] = body.to_dict() - - headers["Content-Type"] = "application/json" - - _kwargs["headers"] = headers - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentProfileResponse | HTTPValidationError | None: - if response.status_code == 200: - response_200 = AgentProfileResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentProfileResponse | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: CreateAgentRequest, -) -> Response[AgentProfileResponse | HTTPValidationError]: - """Create or update agent - - Create a new agent or update existing agent with personality and background. Auto-fills missing - fields with defaults. - - Args: - agent_id (str): - body (CreateAgentRequest): Request model for creating/updating an agent. Example: - {'background': 'I am a creative software engineer with 10 years of experience', - 'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, - 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[AgentProfileResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: CreateAgentRequest, -) -> AgentProfileResponse | HTTPValidationError | None: - """Create or update agent - - Create a new agent or update existing agent with personality and background. Auto-fills missing - fields with defaults. - - Args: - agent_id (str): - body (CreateAgentRequest): Request model for creating/updating an agent. Example: - {'background': 'I am a creative software engineer with 10 years of experience', - 'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, - 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - AgentProfileResponse | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - body=body, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: CreateAgentRequest, -) -> Response[AgentProfileResponse | HTTPValidationError]: - """Create or update agent - - Create a new agent or update existing agent with personality and background. Auto-fills missing - fields with defaults. - - Args: - agent_id (str): - body (CreateAgentRequest): Request model for creating/updating an agent. Example: - {'background': 'I am a creative software engineer with 10 years of experience', - 'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, - 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[AgentProfileResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: CreateAgentRequest, -) -> AgentProfileResponse | HTTPValidationError | None: - """Create or update agent - - Create a new agent or update existing agent with personality and background. Auto-fills missing - fields with defaults. - - Args: - agent_id (str): - body (CreateAgentRequest): Request model for creating/updating an agent. Example: - {'background': 'I am a creative software engineer with 10 years of experience', - 'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, - 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - AgentProfileResponse | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - body=body, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/agent_management/api_get_agent_profile_api_v1_agents_agent_id_profile_get.py b/memora-clients/python/agent_memory_api_client/api/agent_management/api_get_agent_profile_api_v1_agents_agent_id_profile_get.py deleted file mode 100644 index 6beff82a..00000000 --- a/memora-clients/python/agent_memory_api_client/api/agent_management/api_get_agent_profile_api_v1_agents_agent_id_profile_get.py +++ /dev/null @@ -1,165 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.agent_profile_response import AgentProfileResponse -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, -) -> dict[str, Any]: - _kwargs: dict[str, Any] = { - "method": "get", - "url": f"/api/v1/agents/{agent_id}/profile", - } - - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentProfileResponse | HTTPValidationError | None: - if response.status_code == 200: - response_200 = AgentProfileResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentProfileResponse | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[AgentProfileResponse | HTTPValidationError]: - """Get agent profile - - Get personality traits and background for an agent. Auto-creates agent with defaults if not exists. - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[AgentProfileResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> AgentProfileResponse | HTTPValidationError | None: - """Get agent profile - - Get personality traits and background for an agent. Auto-creates agent with defaults if not exists. - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - AgentProfileResponse | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[AgentProfileResponse | HTTPValidationError]: - """Get agent profile - - Get personality traits and background for an agent. Auto-creates agent with defaults if not exists. - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[AgentProfileResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> AgentProfileResponse | HTTPValidationError | None: - """Get agent profile - - Get personality traits and background for an agent. Auto-creates agent with defaults if not exists. - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - AgentProfileResponse | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/agent_management/api_stats_api_v1_agents_agent_id_stats_get.py b/memora-clients/python/agent_memory_api_client/api/agent_management/api_stats_api_v1_agents_agent_id_stats_get.py deleted file mode 100644 index 9d71ff1c..00000000 --- a/memora-clients/python/agent_memory_api_client/api/agent_management/api_stats_api_v1_agents_agent_id_stats_get.py +++ /dev/null @@ -1,163 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, -) -> dict[str, Any]: - _kwargs: dict[str, Any] = { - "method": "get", - "url": f"/api/v1/agents/{agent_id}/stats", - } - - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: - if response.status_code == 200: - response_200 = response.json() - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[Any | HTTPValidationError]: - """Get memory statistics for an agent - - Get statistics about nodes and links for a specific agent - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[Any | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Any | HTTPValidationError | None: - """Get memory statistics for an agent - - Get statistics about nodes and links for a specific agent - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Any | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[Any | HTTPValidationError]: - """Get memory statistics for an agent - - Get statistics about nodes and links for a specific agent - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[Any | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Any | HTTPValidationError | None: - """Get memory statistics for an agent - - Get statistics about nodes and links for a specific agent - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Any | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/agent_management/api_update_agent_personality_api_v1_agents_agent_id_profile_put.py b/memora-clients/python/agent_memory_api_client/api/agent_management/api_update_agent_personality_api_v1_agents_agent_id_profile_put.py deleted file mode 100644 index 22f99899..00000000 --- a/memora-clients/python/agent_memory_api_client/api/agent_management/api_update_agent_personality_api_v1_agents_agent_id_profile_put.py +++ /dev/null @@ -1,187 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.agent_profile_response import AgentProfileResponse -from ...models.http_validation_error import HTTPValidationError -from ...models.update_personality_request import UpdatePersonalityRequest -from ...types import Response - - -def _get_kwargs( - agent_id: str, - *, - body: UpdatePersonalityRequest, -) -> dict[str, Any]: - headers: dict[str, Any] = {} - - _kwargs: dict[str, Any] = { - "method": "put", - "url": f"/api/v1/agents/{agent_id}/profile", - } - - _kwargs["json"] = body.to_dict() - - headers["Content-Type"] = "application/json" - - _kwargs["headers"] = headers - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> AgentProfileResponse | HTTPValidationError | None: - if response.status_code == 200: - response_200 = AgentProfileResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[AgentProfileResponse | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: UpdatePersonalityRequest, -) -> Response[AgentProfileResponse | HTTPValidationError]: - """Update agent personality - - Update agent's Big Five personality traits and bias strength - - Args: - agent_id (str): - body (UpdatePersonalityRequest): Request model for updating personality traits. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[AgentProfileResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: UpdatePersonalityRequest, -) -> AgentProfileResponse | HTTPValidationError | None: - """Update agent personality - - Update agent's Big Five personality traits and bias strength - - Args: - agent_id (str): - body (UpdatePersonalityRequest): Request model for updating personality traits. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - AgentProfileResponse | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - body=body, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: UpdatePersonalityRequest, -) -> Response[AgentProfileResponse | HTTPValidationError]: - """Update agent personality - - Update agent's Big Five personality traits and bias strength - - Args: - agent_id (str): - body (UpdatePersonalityRequest): Request model for updating personality traits. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[AgentProfileResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: UpdatePersonalityRequest, -) -> AgentProfileResponse | HTTPValidationError | None: - """Update agent personality - - Update agent's Big Five personality traits and bias strength - - Args: - agent_id (str): - body (UpdatePersonalityRequest): Request model for updating personality traits. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - AgentProfileResponse | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - body=body, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/documents/__init__.py b/memora-clients/python/agent_memory_api_client/api/documents/__init__.py deleted file mode 100644 index 2d7c0b23..00000000 --- a/memora-clients/python/agent_memory_api_client/api/documents/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Contains endpoint functions for accessing the API""" diff --git a/memora-clients/python/agent_memory_api_client/api/documents/api_get_document_api_v1_agents_agent_id_documents_document_id_get.py b/memora-clients/python/agent_memory_api_client/api/documents/api_get_document_api_v1_agents_agent_id_documents_document_id_get.py deleted file mode 100644 index 3176229d..00000000 --- a/memora-clients/python/agent_memory_api_client/api/documents/api_get_document_api_v1_agents_agent_id_documents_document_id_get.py +++ /dev/null @@ -1,178 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.document_response import DocumentResponse -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, - document_id: str, -) -> dict[str, Any]: - _kwargs: dict[str, Any] = { - "method": "get", - "url": f"/api/v1/agents/{agent_id}/documents/{document_id}", - } - - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> DocumentResponse | HTTPValidationError | None: - if response.status_code == 200: - response_200 = DocumentResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[DocumentResponse | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - document_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[DocumentResponse | HTTPValidationError]: - """Get document details - - Get a specific document including its original text - - Args: - agent_id (str): - document_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[DocumentResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - document_id=document_id, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - document_id: str, - *, - client: AuthenticatedClient | Client, -) -> DocumentResponse | HTTPValidationError | None: - """Get document details - - Get a specific document including its original text - - Args: - agent_id (str): - document_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - DocumentResponse | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - document_id=document_id, - client=client, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - document_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[DocumentResponse | HTTPValidationError]: - """Get document details - - Get a specific document including its original text - - Args: - agent_id (str): - document_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[DocumentResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - document_id=document_id, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - document_id: str, - *, - client: AuthenticatedClient | Client, -) -> DocumentResponse | HTTPValidationError | None: - """Get document details - - Get a specific document including its original text - - Args: - agent_id (str): - document_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - DocumentResponse | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - document_id=document_id, - client=client, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/documents/api_list_documents_api_v1_agents_agent_id_documents_get.py b/memora-clients/python/agent_memory_api_client/api/documents/api_list_documents_api_v1_agents_agent_id_documents_get.py deleted file mode 100644 index 9c5f0a23..00000000 --- a/memora-clients/python/agent_memory_api_client/api/documents/api_list_documents_api_v1_agents_agent_id_documents_get.py +++ /dev/null @@ -1,225 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.http_validation_error import HTTPValidationError -from ...models.list_documents_response import ListDocumentsResponse -from ...types import UNSET, Response, Unset - - -def _get_kwargs( - agent_id: str, - *, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> dict[str, Any]: - params: dict[str, Any] = {} - - json_q: None | str | Unset - if isinstance(q, Unset): - json_q = UNSET - else: - json_q = q - params["q"] = json_q - - params["limit"] = limit - - params["offset"] = offset - - params = {k: v for k, v in params.items() if v is not UNSET and v is not None} - - _kwargs: dict[str, Any] = { - "method": "get", - "url": f"/api/v1/agents/{agent_id}/documents", - "params": params, - } - - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | ListDocumentsResponse | None: - if response.status_code == 200: - response_200 = ListDocumentsResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | ListDocumentsResponse]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> Response[HTTPValidationError | ListDocumentsResponse]: - """List documents - - List documents with pagination and optional search. Documents are the source content from which - memory units are extracted. - - Args: - agent_id (str): - q (None | str | Unset): - limit (int | Unset): Default: 100. - offset (int | Unset): Default: 0. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[HTTPValidationError | ListDocumentsResponse] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - q=q, - limit=limit, - offset=offset, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> HTTPValidationError | ListDocumentsResponse | None: - """List documents - - List documents with pagination and optional search. Documents are the source content from which - memory units are extracted. - - Args: - agent_id (str): - q (None | str | Unset): - limit (int | Unset): Default: 100. - offset (int | Unset): Default: 0. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - HTTPValidationError | ListDocumentsResponse - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - q=q, - limit=limit, - offset=offset, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> Response[HTTPValidationError | ListDocumentsResponse]: - """List documents - - List documents with pagination and optional search. Documents are the source content from which - memory units are extracted. - - Args: - agent_id (str): - q (None | str | Unset): - limit (int | Unset): Default: 100. - offset (int | Unset): Default: 0. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[HTTPValidationError | ListDocumentsResponse] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - q=q, - limit=limit, - offset=offset, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> HTTPValidationError | ListDocumentsResponse | None: - """List documents - - List documents with pagination and optional search. Documents are the source content from which - memory units are extracted. - - Args: - agent_id (str): - q (None | str | Unset): - limit (int | Unset): Default: 100. - offset (int | Unset): Default: 0. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - HTTPValidationError | ListDocumentsResponse - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - q=q, - limit=limit, - offset=offset, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/memory_operations/__init__.py b/memora-clients/python/agent_memory_api_client/api/memory_operations/__init__.py deleted file mode 100644 index 2d7c0b23..00000000 --- a/memora-clients/python/agent_memory_api_client/api/memory_operations/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Contains endpoint functions for accessing the API""" diff --git a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_batch_put_api_v1_agents_agent_id_memories_post.py b/memora-clients/python/agent_memory_api_client/api/memory_operations/api_batch_put_api_v1_agents_agent_id_memories_post.py deleted file mode 100644 index 9c6e7e6b..00000000 --- a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_batch_put_api_v1_agents_agent_id_memories_post.py +++ /dev/null @@ -1,263 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.batch_put_request import BatchPutRequest -from ...models.batch_put_response import BatchPutResponse -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, - *, - body: BatchPutRequest, -) -> dict[str, Any]: - headers: dict[str, Any] = {} - - _kwargs: dict[str, Any] = { - "method": "post", - "url": f"/api/v1/agents/{agent_id}/memories", - } - - _kwargs["json"] = body.to_dict() - - headers["Content-Type"] = "application/json" - - _kwargs["headers"] = headers - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> BatchPutResponse | HTTPValidationError | None: - if response.status_code == 200: - response_200 = BatchPutResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[BatchPutResponse | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: BatchPutRequest, -) -> Response[BatchPutResponse | HTTPValidationError]: - """Store multiple memories - - Store multiple memory items in batch with automatic fact extraction. - - Features: - - Efficient batch processing - - Automatic fact extraction from natural language - - Entity recognition and linking - - Document tracking with automatic upsert (when document_id is provided) - - Temporal and semantic linking - - The system automatically: - 1. Extracts semantic facts from the content - 2. Generates embeddings - 3. Deduplicates similar facts - 4. Creates temporal, semantic, and entity links - 5. Tracks document metadata - - Note: If document_id is provided and already exists, the old document and its memory units will - be deleted before creating new ones (upsert behavior). - - Args: - agent_id (str): - body (BatchPutRequest): Request model for batch put endpoint. Example: {'document_id': - 'conversation_123', 'items': [{'content': 'Alice works at Google', 'context': 'work'}, - {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[BatchPutResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: BatchPutRequest, -) -> BatchPutResponse | HTTPValidationError | None: - """Store multiple memories - - Store multiple memory items in batch with automatic fact extraction. - - Features: - - Efficient batch processing - - Automatic fact extraction from natural language - - Entity recognition and linking - - Document tracking with automatic upsert (when document_id is provided) - - Temporal and semantic linking - - The system automatically: - 1. Extracts semantic facts from the content - 2. Generates embeddings - 3. Deduplicates similar facts - 4. Creates temporal, semantic, and entity links - 5. Tracks document metadata - - Note: If document_id is provided and already exists, the old document and its memory units will - be deleted before creating new ones (upsert behavior). - - Args: - agent_id (str): - body (BatchPutRequest): Request model for batch put endpoint. Example: {'document_id': - 'conversation_123', 'items': [{'content': 'Alice works at Google', 'context': 'work'}, - {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - BatchPutResponse | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - body=body, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: BatchPutRequest, -) -> Response[BatchPutResponse | HTTPValidationError]: - """Store multiple memories - - Store multiple memory items in batch with automatic fact extraction. - - Features: - - Efficient batch processing - - Automatic fact extraction from natural language - - Entity recognition and linking - - Document tracking with automatic upsert (when document_id is provided) - - Temporal and semantic linking - - The system automatically: - 1. Extracts semantic facts from the content - 2. Generates embeddings - 3. Deduplicates similar facts - 4. Creates temporal, semantic, and entity links - 5. Tracks document metadata - - Note: If document_id is provided and already exists, the old document and its memory units will - be deleted before creating new ones (upsert behavior). - - Args: - agent_id (str): - body (BatchPutRequest): Request model for batch put endpoint. Example: {'document_id': - 'conversation_123', 'items': [{'content': 'Alice works at Google', 'context': 'work'}, - {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[BatchPutResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: BatchPutRequest, -) -> BatchPutResponse | HTTPValidationError | None: - """Store multiple memories - - Store multiple memory items in batch with automatic fact extraction. - - Features: - - Efficient batch processing - - Automatic fact extraction from natural language - - Entity recognition and linking - - Document tracking with automatic upsert (when document_id is provided) - - Temporal and semantic linking - - The system automatically: - 1. Extracts semantic facts from the content - 2. Generates embeddings - 3. Deduplicates similar facts - 4. Creates temporal, semantic, and entity links - 5. Tracks document metadata - - Note: If document_id is provided and already exists, the old document and its memory units will - be deleted before creating new ones (upsert behavior). - - Args: - agent_id (str): - body (BatchPutRequest): Request model for batch put endpoint. Example: {'document_id': - 'conversation_123', 'items': [{'content': 'Alice works at Google', 'context': 'work'}, - {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - BatchPutResponse | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - body=body, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_batch_put_async_api_v1_agents_agent_id_memories_async_post.py b/memora-clients/python/agent_memory_api_client/api/memory_operations/api_batch_put_async_api_v1_agents_agent_id_memories_async_post.py deleted file mode 100644 index eef7034b..00000000 --- a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_batch_put_async_api_v1_agents_agent_id_memories_async_post.py +++ /dev/null @@ -1,275 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.batch_put_async_response import BatchPutAsyncResponse -from ...models.batch_put_request import BatchPutRequest -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, - *, - body: BatchPutRequest, -) -> dict[str, Any]: - headers: dict[str, Any] = {} - - _kwargs: dict[str, Any] = { - "method": "post", - "url": f"/api/v1/agents/{agent_id}/memories/async", - } - - _kwargs["json"] = body.to_dict() - - headers["Content-Type"] = "application/json" - - _kwargs["headers"] = headers - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> BatchPutAsyncResponse | HTTPValidationError | None: - if response.status_code == 200: - response_200 = BatchPutAsyncResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[BatchPutAsyncResponse | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: BatchPutRequest, -) -> Response[BatchPutAsyncResponse | HTTPValidationError]: - """Store multiple memories asynchronously - - Store multiple memory items in batch asynchronously using the task backend. - - This endpoint returns immediately after queuing the task, without waiting for completion. - The actual processing happens in the background. - - Features: - - Immediate response (non-blocking) - - Background processing via task queue - - Efficient batch processing - - Automatic fact extraction from natural language - - Entity recognition and linking - - Document tracking with automatic upsert (when document_id is provided) - - Temporal and semantic linking - - The system automatically: - 1. Queues the batch put task - 2. Returns immediately with success=True, queued=True - 3. Processes in background: extracts facts, generates embeddings, creates links - - Note: If document_id is provided and already exists, the old document and its memory units will - be deleted before creating new ones (upsert behavior). - - Args: - agent_id (str): - body (BatchPutRequest): Request model for batch put endpoint. Example: {'document_id': - 'conversation_123', 'items': [{'content': 'Alice works at Google', 'context': 'work'}, - {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[BatchPutAsyncResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: BatchPutRequest, -) -> BatchPutAsyncResponse | HTTPValidationError | None: - """Store multiple memories asynchronously - - Store multiple memory items in batch asynchronously using the task backend. - - This endpoint returns immediately after queuing the task, without waiting for completion. - The actual processing happens in the background. - - Features: - - Immediate response (non-blocking) - - Background processing via task queue - - Efficient batch processing - - Automatic fact extraction from natural language - - Entity recognition and linking - - Document tracking with automatic upsert (when document_id is provided) - - Temporal and semantic linking - - The system automatically: - 1. Queues the batch put task - 2. Returns immediately with success=True, queued=True - 3. Processes in background: extracts facts, generates embeddings, creates links - - Note: If document_id is provided and already exists, the old document and its memory units will - be deleted before creating new ones (upsert behavior). - - Args: - agent_id (str): - body (BatchPutRequest): Request model for batch put endpoint. Example: {'document_id': - 'conversation_123', 'items': [{'content': 'Alice works at Google', 'context': 'work'}, - {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - BatchPutAsyncResponse | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - body=body, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: BatchPutRequest, -) -> Response[BatchPutAsyncResponse | HTTPValidationError]: - """Store multiple memories asynchronously - - Store multiple memory items in batch asynchronously using the task backend. - - This endpoint returns immediately after queuing the task, without waiting for completion. - The actual processing happens in the background. - - Features: - - Immediate response (non-blocking) - - Background processing via task queue - - Efficient batch processing - - Automatic fact extraction from natural language - - Entity recognition and linking - - Document tracking with automatic upsert (when document_id is provided) - - Temporal and semantic linking - - The system automatically: - 1. Queues the batch put task - 2. Returns immediately with success=True, queued=True - 3. Processes in background: extracts facts, generates embeddings, creates links - - Note: If document_id is provided and already exists, the old document and its memory units will - be deleted before creating new ones (upsert behavior). - - Args: - agent_id (str): - body (BatchPutRequest): Request model for batch put endpoint. Example: {'document_id': - 'conversation_123', 'items': [{'content': 'Alice works at Google', 'context': 'work'}, - {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[BatchPutAsyncResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: BatchPutRequest, -) -> BatchPutAsyncResponse | HTTPValidationError | None: - """Store multiple memories asynchronously - - Store multiple memory items in batch asynchronously using the task backend. - - This endpoint returns immediately after queuing the task, without waiting for completion. - The actual processing happens in the background. - - Features: - - Immediate response (non-blocking) - - Background processing via task queue - - Efficient batch processing - - Automatic fact extraction from natural language - - Entity recognition and linking - - Document tracking with automatic upsert (when document_id is provided) - - Temporal and semantic linking - - The system automatically: - 1. Queues the batch put task - 2. Returns immediately with success=True, queued=True - 3. Processes in background: extracts facts, generates embeddings, creates links - - Note: If document_id is provided and already exists, the old document and its memory units will - be deleted before creating new ones (upsert behavior). - - Args: - agent_id (str): - body (BatchPutRequest): Request model for batch put endpoint. Example: {'document_id': - 'conversation_123', 'items': [{'content': 'Alice works at Google', 'context': 'work'}, - {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - BatchPutAsyncResponse | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - body=body, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_cancel_operation_api_v1_agents_agent_id_operations_operation_id_delete.py b/memora-clients/python/agent_memory_api_client/api/memory_operations/api_cancel_operation_api_v1_agents_agent_id_operations_operation_id_delete.py deleted file mode 100644 index 647b93fb..00000000 --- a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_cancel_operation_api_v1_agents_agent_id_operations_operation_id_delete.py +++ /dev/null @@ -1,176 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, - operation_id: str, -) -> dict[str, Any]: - _kwargs: dict[str, Any] = { - "method": "delete", - "url": f"/api/v1/agents/{agent_id}/operations/{operation_id}", - } - - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: - if response.status_code == 200: - response_200 = response.json() - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - operation_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[Any | HTTPValidationError]: - """Cancel a pending async operation - - Cancel a pending async operation by removing it from the queue - - Args: - agent_id (str): - operation_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[Any | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - operation_id=operation_id, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - operation_id: str, - *, - client: AuthenticatedClient | Client, -) -> Any | HTTPValidationError | None: - """Cancel a pending async operation - - Cancel a pending async operation by removing it from the queue - - Args: - agent_id (str): - operation_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Any | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - operation_id=operation_id, - client=client, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - operation_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[Any | HTTPValidationError]: - """Cancel a pending async operation - - Cancel a pending async operation by removing it from the queue - - Args: - agent_id (str): - operation_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[Any | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - operation_id=operation_id, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - operation_id: str, - *, - client: AuthenticatedClient | Client, -) -> Any | HTTPValidationError | None: - """Cancel a pending async operation - - Cancel a pending async operation by removing it from the queue - - Args: - agent_id (str): - operation_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Any | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - operation_id=operation_id, - client=client, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_delete_memory_unit_api_v1_agents_agent_id_memories_unit_id_delete.py b/memora-clients/python/agent_memory_api_client/api/memory_operations/api_delete_memory_unit_api_v1_agents_agent_id_memories_unit_id_delete.py deleted file mode 100644 index fe732448..00000000 --- a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_delete_memory_unit_api_v1_agents_agent_id_memories_unit_id_delete.py +++ /dev/null @@ -1,176 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, - unit_id: str, -) -> dict[str, Any]: - _kwargs: dict[str, Any] = { - "method": "delete", - "url": f"/api/v1/agents/{agent_id}/memories/{unit_id}", - } - - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: - if response.status_code == 200: - response_200 = response.json() - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - unit_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[Any | HTTPValidationError]: - """Delete a memory unit - - Delete a single memory unit and all its associated links (temporal, semantic, and entity links) - - Args: - agent_id (str): - unit_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[Any | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - unit_id=unit_id, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - unit_id: str, - *, - client: AuthenticatedClient | Client, -) -> Any | HTTPValidationError | None: - """Delete a memory unit - - Delete a single memory unit and all its associated links (temporal, semantic, and entity links) - - Args: - agent_id (str): - unit_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Any | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - unit_id=unit_id, - client=client, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - unit_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[Any | HTTPValidationError]: - """Delete a memory unit - - Delete a single memory unit and all its associated links (temporal, semantic, and entity links) - - Args: - agent_id (str): - unit_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[Any | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - unit_id=unit_id, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - unit_id: str, - *, - client: AuthenticatedClient | Client, -) -> Any | HTTPValidationError | None: - """Delete a memory unit - - Delete a single memory unit and all its associated links (temporal, semantic, and entity links) - - Args: - agent_id (str): - unit_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Any | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - unit_id=unit_id, - client=client, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_list_api_v1_agents_agent_id_memories_list_get.py b/memora-clients/python/agent_memory_api_client/api/memory_operations/api_list_api_v1_agents_agent_id_memories_list_get.py deleted file mode 100644 index b3381be2..00000000 --- a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_list_api_v1_agents_agent_id_memories_list_get.py +++ /dev/null @@ -1,241 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.http_validation_error import HTTPValidationError -from ...models.list_memory_units_response import ListMemoryUnitsResponse -from ...types import UNSET, Response, Unset - - -def _get_kwargs( - agent_id: str, - *, - fact_type: None | str | Unset = UNSET, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> dict[str, Any]: - params: dict[str, Any] = {} - - json_fact_type: None | str | Unset - if isinstance(fact_type, Unset): - json_fact_type = UNSET - else: - json_fact_type = fact_type - params["fact_type"] = json_fact_type - - json_q: None | str | Unset - if isinstance(q, Unset): - json_q = UNSET - else: - json_q = q - params["q"] = json_q - - params["limit"] = limit - - params["offset"] = offset - - params = {k: v for k, v in params.items() if v is not UNSET and v is not None} - - _kwargs: dict[str, Any] = { - "method": "get", - "url": f"/api/v1/agents/{agent_id}/memories/list", - "params": params, - } - - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | ListMemoryUnitsResponse | None: - if response.status_code == 200: - response_200 = ListMemoryUnitsResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | ListMemoryUnitsResponse]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - fact_type: None | str | Unset = UNSET, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> Response[HTTPValidationError | ListMemoryUnitsResponse]: - """List memory units - - List memory units with pagination and optional full-text search. Supports filtering by fact_type. - - Args: - agent_id (str): - fact_type (None | str | Unset): - q (None | str | Unset): - limit (int | Unset): Default: 100. - offset (int | Unset): Default: 0. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[HTTPValidationError | ListMemoryUnitsResponse] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - fact_type=fact_type, - q=q, - limit=limit, - offset=offset, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - fact_type: None | str | Unset = UNSET, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> HTTPValidationError | ListMemoryUnitsResponse | None: - """List memory units - - List memory units with pagination and optional full-text search. Supports filtering by fact_type. - - Args: - agent_id (str): - fact_type (None | str | Unset): - q (None | str | Unset): - limit (int | Unset): Default: 100. - offset (int | Unset): Default: 0. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - HTTPValidationError | ListMemoryUnitsResponse - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - fact_type=fact_type, - q=q, - limit=limit, - offset=offset, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - fact_type: None | str | Unset = UNSET, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> Response[HTTPValidationError | ListMemoryUnitsResponse]: - """List memory units - - List memory units with pagination and optional full-text search. Supports filtering by fact_type. - - Args: - agent_id (str): - fact_type (None | str | Unset): - q (None | str | Unset): - limit (int | Unset): Default: 100. - offset (int | Unset): Default: 0. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[HTTPValidationError | ListMemoryUnitsResponse] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - fact_type=fact_type, - q=q, - limit=limit, - offset=offset, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - fact_type: None | str | Unset = UNSET, - q: None | str | Unset = UNSET, - limit: int | Unset = 100, - offset: int | Unset = 0, -) -> HTTPValidationError | ListMemoryUnitsResponse | None: - """List memory units - - List memory units with pagination and optional full-text search. Supports filtering by fact_type. - - Args: - agent_id (str): - fact_type (None | str | Unset): - q (None | str | Unset): - limit (int | Unset): Default: 100. - offset (int | Unset): Default: 0. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - HTTPValidationError | ListMemoryUnitsResponse - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - fact_type=fact_type, - q=q, - limit=limit, - offset=offset, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_list_operations_api_v1_agents_agent_id_operations_get.py b/memora-clients/python/agent_memory_api_client/api/memory_operations/api_list_operations_api_v1_agents_agent_id_operations_get.py deleted file mode 100644 index dd63b01d..00000000 --- a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_list_operations_api_v1_agents_agent_id_operations_get.py +++ /dev/null @@ -1,167 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - agent_id: str, -) -> dict[str, Any]: - _kwargs: dict[str, Any] = { - "method": "get", - "url": f"/api/v1/agents/{agent_id}/operations", - } - - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Any | HTTPValidationError | None: - if response.status_code == 200: - response_200 = response.json() - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[Any | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[Any | HTTPValidationError]: - """List async operations - - Get a list of all async operations (pending and failed) for a specific agent, including error - messages for failed operations - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[Any | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Any | HTTPValidationError | None: - """List async operations - - Get a list of all async operations (pending and failed) for a specific agent, including error - messages for failed operations - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Any | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Response[Any | HTTPValidationError]: - """List async operations - - Get a list of all async operations (pending and failed) for a specific agent, including error - messages for failed operations - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[Any | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, -) -> Any | HTTPValidationError | None: - """List async operations - - Get a list of all async operations (pending and failed) for a specific agent, including error - messages for failed operations - - Args: - agent_id (str): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Any | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_search_api_v1_agents_agent_id_memories_search_post.py b/memora-clients/python/agent_memory_api_client/api/memory_operations/api_search_api_v1_agents_agent_id_memories_search_post.py deleted file mode 100644 index 2b41b818..00000000 --- a/memora-clients/python/agent_memory_api_client/api/memory_operations/api_search_api_v1_agents_agent_id_memories_search_post.py +++ /dev/null @@ -1,219 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.http_validation_error import HTTPValidationError -from ...models.search_request import SearchRequest -from ...models.search_response import SearchResponse -from ...types import Response - - -def _get_kwargs( - agent_id: str, - *, - body: SearchRequest, -) -> dict[str, Any]: - headers: dict[str, Any] = {} - - _kwargs: dict[str, Any] = { - "method": "post", - "url": f"/api/v1/agents/{agent_id}/memories/search", - } - - _kwargs["json"] = body.to_dict() - - headers["Content-Type"] = "application/json" - - _kwargs["headers"] = headers - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | SearchResponse | None: - if response.status_code == 200: - response_200 = SearchResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | SearchResponse]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: SearchRequest, -) -> Response[HTTPValidationError | SearchResponse]: - """Search memory - - Search memory using semantic similarity and spreading activation. - - The fact_type parameter is optional and must be one of: - - 'world': General knowledge about people, places, events, and things that happen - - 'agent': Memories about what the AI agent did, actions taken, and tasks performed - - 'opinion': The agent's formed beliefs, perspectives, and viewpoints - - Args: - agent_id (str): - body (SearchRequest): Request model for search endpoint. Example: {'fact_type': ['world', - 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about machine learning?', - 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic', 'thinking_budget': 100, - 'trace': True}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[HTTPValidationError | SearchResponse] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: SearchRequest, -) -> HTTPValidationError | SearchResponse | None: - """Search memory - - Search memory using semantic similarity and spreading activation. - - The fact_type parameter is optional and must be one of: - - 'world': General knowledge about people, places, events, and things that happen - - 'agent': Memories about what the AI agent did, actions taken, and tasks performed - - 'opinion': The agent's formed beliefs, perspectives, and viewpoints - - Args: - agent_id (str): - body (SearchRequest): Request model for search endpoint. Example: {'fact_type': ['world', - 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about machine learning?', - 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic', 'thinking_budget': 100, - 'trace': True}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - HTTPValidationError | SearchResponse - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - body=body, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: SearchRequest, -) -> Response[HTTPValidationError | SearchResponse]: - """Search memory - - Search memory using semantic similarity and spreading activation. - - The fact_type parameter is optional and must be one of: - - 'world': General knowledge about people, places, events, and things that happen - - 'agent': Memories about what the AI agent did, actions taken, and tasks performed - - 'opinion': The agent's formed beliefs, perspectives, and viewpoints - - Args: - agent_id (str): - body (SearchRequest): Request model for search endpoint. Example: {'fact_type': ['world', - 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about machine learning?', - 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic', 'thinking_budget': 100, - 'trace': True}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[HTTPValidationError | SearchResponse] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: SearchRequest, -) -> HTTPValidationError | SearchResponse | None: - """Search memory - - Search memory using semantic similarity and spreading activation. - - The fact_type parameter is optional and must be one of: - - 'world': General knowledge about people, places, events, and things that happen - - 'agent': Memories about what the AI agent did, actions taken, and tasks performed - - 'opinion': The agent's formed beliefs, perspectives, and viewpoints - - Args: - agent_id (str): - body (SearchRequest): Request model for search endpoint. Example: {'fact_type': ['world', - 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about machine learning?', - 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic', 'thinking_budget': 100, - 'trace': True}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - HTTPValidationError | SearchResponse - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - body=body, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/reasoning/__init__.py b/memora-clients/python/agent_memory_api_client/api/reasoning/__init__.py deleted file mode 100644 index 2d7c0b23..00000000 --- a/memora-clients/python/agent_memory_api_client/api/reasoning/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Contains endpoint functions for accessing the API""" diff --git a/memora-clients/python/agent_memory_api_client/api/reasoning/api_think_api_v1_agents_agent_id_think_post.py b/memora-clients/python/agent_memory_api_client/api/reasoning/api_think_api_v1_agents_agent_id_think_post.py deleted file mode 100644 index eb86bec1..00000000 --- a/memora-clients/python/agent_memory_api_client/api/reasoning/api_think_api_v1_agents_agent_id_think_post.py +++ /dev/null @@ -1,227 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.http_validation_error import HTTPValidationError -from ...models.think_request import ThinkRequest -from ...models.think_response import ThinkResponse -from ...types import Response - - -def _get_kwargs( - agent_id: str, - *, - body: ThinkRequest, -) -> dict[str, Any]: - headers: dict[str, Any] = {} - - _kwargs: dict[str, Any] = { - "method": "post", - "url": f"/api/v1/agents/{agent_id}/think", - } - - _kwargs["json"] = body.to_dict() - - headers["Content-Type"] = "application/json" - - _kwargs["headers"] = headers - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> HTTPValidationError | ThinkResponse | None: - if response.status_code == 200: - response_200 = ThinkResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[HTTPValidationError | ThinkResponse]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: ThinkRequest, -) -> Response[HTTPValidationError | ThinkResponse]: - """Think and generate answer - - Think and formulate an answer using agent identity, world facts, and opinions. - - This endpoint: - 1. Retrieves agent facts (agent's identity) - 2. Retrieves world facts relevant to the query - 3. Retrieves existing opinions (agent's perspectives) - 4. Uses LLM to formulate a contextual answer - 5. Extracts and stores any new opinions formed - 6. Returns plain text answer, the facts used, and new opinions - - Args: - agent_id (str): - body (ThinkRequest): Request model for think endpoint. Example: {'context': 'This is for a - research paper on AI ethics', 'query': 'What do you think about artificial intelligence?', - 'thinking_budget': 50}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[HTTPValidationError | ThinkResponse] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: ThinkRequest, -) -> HTTPValidationError | ThinkResponse | None: - """Think and generate answer - - Think and formulate an answer using agent identity, world facts, and opinions. - - This endpoint: - 1. Retrieves agent facts (agent's identity) - 2. Retrieves world facts relevant to the query - 3. Retrieves existing opinions (agent's perspectives) - 4. Uses LLM to formulate a contextual answer - 5. Extracts and stores any new opinions formed - 6. Returns plain text answer, the facts used, and new opinions - - Args: - agent_id (str): - body (ThinkRequest): Request model for think endpoint. Example: {'context': 'This is for a - research paper on AI ethics', 'query': 'What do you think about artificial intelligence?', - 'thinking_budget': 50}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - HTTPValidationError | ThinkResponse - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - body=body, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: ThinkRequest, -) -> Response[HTTPValidationError | ThinkResponse]: - """Think and generate answer - - Think and formulate an answer using agent identity, world facts, and opinions. - - This endpoint: - 1. Retrieves agent facts (agent's identity) - 2. Retrieves world facts relevant to the query - 3. Retrieves existing opinions (agent's perspectives) - 4. Uses LLM to formulate a contextual answer - 5. Extracts and stores any new opinions formed - 6. Returns plain text answer, the facts used, and new opinions - - Args: - agent_id (str): - body (ThinkRequest): Request model for think endpoint. Example: {'context': 'This is for a - research paper on AI ethics', 'query': 'What do you think about artificial intelligence?', - 'thinking_budget': 50}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[HTTPValidationError | ThinkResponse] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - body=body, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - body: ThinkRequest, -) -> HTTPValidationError | ThinkResponse | None: - """Think and generate answer - - Think and formulate an answer using agent identity, world facts, and opinions. - - This endpoint: - 1. Retrieves agent facts (agent's identity) - 2. Retrieves world facts relevant to the query - 3. Retrieves existing opinions (agent's perspectives) - 4. Uses LLM to formulate a contextual answer - 5. Extracts and stores any new opinions formed - 6. Returns plain text answer, the facts used, and new opinions - - Args: - agent_id (str): - body (ThinkRequest): Request model for think endpoint. Example: {'context': 'This is for a - research paper on AI ethics', 'query': 'What do you think about artificial intelligence?', - 'thinking_budget': 50}. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - HTTPValidationError | ThinkResponse - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - body=body, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/api/visualization/__init__.py b/memora-clients/python/agent_memory_api_client/api/visualization/__init__.py deleted file mode 100644 index 2d7c0b23..00000000 --- a/memora-clients/python/agent_memory_api_client/api/visualization/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Contains endpoint functions for accessing the API""" diff --git a/memora-clients/python/agent_memory_api_client/api/visualization/api_graph_api_v1_agents_agent_id_graph_get.py b/memora-clients/python/agent_memory_api_client/api/visualization/api_graph_api_v1_agents_agent_id_graph_get.py deleted file mode 100644 index 4a390cb6..00000000 --- a/memora-clients/python/agent_memory_api_client/api/visualization/api_graph_api_v1_agents_agent_id_graph_get.py +++ /dev/null @@ -1,195 +0,0 @@ -from http import HTTPStatus -from typing import Any - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.graph_data_response import GraphDataResponse -from ...models.http_validation_error import HTTPValidationError -from ...types import UNSET, Response, Unset - - -def _get_kwargs( - agent_id: str, - *, - fact_type: None | str | Unset = UNSET, -) -> dict[str, Any]: - params: dict[str, Any] = {} - - json_fact_type: None | str | Unset - if isinstance(fact_type, Unset): - json_fact_type = UNSET - else: - json_fact_type = fact_type - params["fact_type"] = json_fact_type - - params = {k: v for k, v in params.items() if v is not UNSET and v is not None} - - _kwargs: dict[str, Any] = { - "method": "get", - "url": f"/api/v1/agents/{agent_id}/graph", - "params": params, - } - - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> GraphDataResponse | HTTPValidationError | None: - if response.status_code == 200: - response_200 = GraphDataResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[GraphDataResponse | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - fact_type: None | str | Unset = UNSET, -) -> Response[GraphDataResponse | HTTPValidationError]: - """Get memory graph data - - Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). - Limited to 1000 most recent items. - - Args: - agent_id (str): - fact_type (None | str | Unset): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[GraphDataResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - fact_type=fact_type, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - agent_id: str, - *, - client: AuthenticatedClient | Client, - fact_type: None | str | Unset = UNSET, -) -> GraphDataResponse | HTTPValidationError | None: - """Get memory graph data - - Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). - Limited to 1000 most recent items. - - Args: - agent_id (str): - fact_type (None | str | Unset): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - GraphDataResponse | HTTPValidationError - """ - - return sync_detailed( - agent_id=agent_id, - client=client, - fact_type=fact_type, - ).parsed - - -async def asyncio_detailed( - agent_id: str, - *, - client: AuthenticatedClient | Client, - fact_type: None | str | Unset = UNSET, -) -> Response[GraphDataResponse | HTTPValidationError]: - """Get memory graph data - - Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). - Limited to 1000 most recent items. - - Args: - agent_id (str): - fact_type (None | str | Unset): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[GraphDataResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - agent_id=agent_id, - fact_type=fact_type, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - agent_id: str, - *, - client: AuthenticatedClient | Client, - fact_type: None | str | Unset = UNSET, -) -> GraphDataResponse | HTTPValidationError | None: - """Get memory graph data - - Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). - Limited to 1000 most recent items. - - Args: - agent_id (str): - fact_type (None | str | Unset): - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - GraphDataResponse | HTTPValidationError - """ - - return ( - await asyncio_detailed( - agent_id=agent_id, - client=client, - fact_type=fact_type, - ) - ).parsed diff --git a/memora-clients/python/agent_memory_api_client/client.py b/memora-clients/python/agent_memory_api_client/client.py deleted file mode 100644 index 1b7055ab..00000000 --- a/memora-clients/python/agent_memory_api_client/client.py +++ /dev/null @@ -1,268 +0,0 @@ -import ssl -from typing import Any - -import httpx -from attrs import define, evolve, field - - -@define -class Client: - """A class for keeping track of data related to the API - - The following are accepted as keyword arguments and will be used to construct httpx Clients internally: - - ``base_url``: The base URL for the API, all requests are made to a relative path to this URL - - ``cookies``: A dictionary of cookies to be sent with every request - - ``headers``: A dictionary of headers to be sent with every request - - ``timeout``: The maximum amount of a time a request can take. API functions will raise - httpx.TimeoutException if this is exceeded. - - ``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production, - but can be set to False for testing purposes. - - ``follow_redirects``: Whether or not to follow redirects. Default value is False. - - ``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor. - - - Attributes: - raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a - status code that was not documented in the source OpenAPI document. Can also be provided as a keyword - argument to the constructor. - """ - - raise_on_unexpected_status: bool = field(default=False, kw_only=True) - _base_url: str = field(alias="base_url") - _cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies") - _headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers") - _timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout") - _verify_ssl: str | bool | ssl.SSLContext = field(default=True, kw_only=True, alias="verify_ssl") - _follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects") - _httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args") - _client: httpx.Client | None = field(default=None, init=False) - _async_client: httpx.AsyncClient | None = field(default=None, init=False) - - def with_headers(self, headers: dict[str, str]) -> "Client": - """Get a new client matching this one with additional headers""" - if self._client is not None: - self._client.headers.update(headers) - if self._async_client is not None: - self._async_client.headers.update(headers) - return evolve(self, headers={**self._headers, **headers}) - - def with_cookies(self, cookies: dict[str, str]) -> "Client": - """Get a new client matching this one with additional cookies""" - if self._client is not None: - self._client.cookies.update(cookies) - if self._async_client is not None: - self._async_client.cookies.update(cookies) - return evolve(self, cookies={**self._cookies, **cookies}) - - def with_timeout(self, timeout: httpx.Timeout) -> "Client": - """Get a new client matching this one with a new timeout configuration""" - if self._client is not None: - self._client.timeout = timeout - if self._async_client is not None: - self._async_client.timeout = timeout - return evolve(self, timeout=timeout) - - def set_httpx_client(self, client: httpx.Client) -> "Client": - """Manually set the underlying httpx.Client - - **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout. - """ - self._client = client - return self - - def get_httpx_client(self) -> httpx.Client: - """Get the underlying httpx.Client, constructing a new one if not previously set""" - if self._client is None: - self._client = httpx.Client( - base_url=self._base_url, - cookies=self._cookies, - headers=self._headers, - timeout=self._timeout, - verify=self._verify_ssl, - follow_redirects=self._follow_redirects, - **self._httpx_args, - ) - return self._client - - def __enter__(self) -> "Client": - """Enter a context manager for self.client—you cannot enter twice (see httpx docs)""" - self.get_httpx_client().__enter__() - return self - - def __exit__(self, *args: Any, **kwargs: Any) -> None: - """Exit a context manager for internal httpx.Client (see httpx docs)""" - self.get_httpx_client().__exit__(*args, **kwargs) - - def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "Client": - """Manually set the underlying httpx.AsyncClient - - **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout. - """ - self._async_client = async_client - return self - - def get_async_httpx_client(self) -> httpx.AsyncClient: - """Get the underlying httpx.AsyncClient, constructing a new one if not previously set""" - if self._async_client is None: - self._async_client = httpx.AsyncClient( - base_url=self._base_url, - cookies=self._cookies, - headers=self._headers, - timeout=self._timeout, - verify=self._verify_ssl, - follow_redirects=self._follow_redirects, - **self._httpx_args, - ) - return self._async_client - - async def __aenter__(self) -> "Client": - """Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)""" - await self.get_async_httpx_client().__aenter__() - return self - - async def __aexit__(self, *args: Any, **kwargs: Any) -> None: - """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)""" - await self.get_async_httpx_client().__aexit__(*args, **kwargs) - - -@define -class AuthenticatedClient: - """A Client which has been authenticated for use on secured endpoints - - The following are accepted as keyword arguments and will be used to construct httpx Clients internally: - - ``base_url``: The base URL for the API, all requests are made to a relative path to this URL - - ``cookies``: A dictionary of cookies to be sent with every request - - ``headers``: A dictionary of headers to be sent with every request - - ``timeout``: The maximum amount of a time a request can take. API functions will raise - httpx.TimeoutException if this is exceeded. - - ``verify_ssl``: Whether or not to verify the SSL certificate of the API server. This should be True in production, - but can be set to False for testing purposes. - - ``follow_redirects``: Whether or not to follow redirects. Default value is False. - - ``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor. - - - Attributes: - raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a - status code that was not documented in the source OpenAPI document. Can also be provided as a keyword - argument to the constructor. - token: The token to use for authentication - prefix: The prefix to use for the Authorization header - auth_header_name: The name of the Authorization header - """ - - raise_on_unexpected_status: bool = field(default=False, kw_only=True) - _base_url: str = field(alias="base_url") - _cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies") - _headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers") - _timeout: httpx.Timeout | None = field(default=None, kw_only=True, alias="timeout") - _verify_ssl: str | bool | ssl.SSLContext = field(default=True, kw_only=True, alias="verify_ssl") - _follow_redirects: bool = field(default=False, kw_only=True, alias="follow_redirects") - _httpx_args: dict[str, Any] = field(factory=dict, kw_only=True, alias="httpx_args") - _client: httpx.Client | None = field(default=None, init=False) - _async_client: httpx.AsyncClient | None = field(default=None, init=False) - - token: str - prefix: str = "Bearer" - auth_header_name: str = "Authorization" - - def with_headers(self, headers: dict[str, str]) -> "AuthenticatedClient": - """Get a new client matching this one with additional headers""" - if self._client is not None: - self._client.headers.update(headers) - if self._async_client is not None: - self._async_client.headers.update(headers) - return evolve(self, headers={**self._headers, **headers}) - - def with_cookies(self, cookies: dict[str, str]) -> "AuthenticatedClient": - """Get a new client matching this one with additional cookies""" - if self._client is not None: - self._client.cookies.update(cookies) - if self._async_client is not None: - self._async_client.cookies.update(cookies) - return evolve(self, cookies={**self._cookies, **cookies}) - - def with_timeout(self, timeout: httpx.Timeout) -> "AuthenticatedClient": - """Get a new client matching this one with a new timeout configuration""" - if self._client is not None: - self._client.timeout = timeout - if self._async_client is not None: - self._async_client.timeout = timeout - return evolve(self, timeout=timeout) - - def set_httpx_client(self, client: httpx.Client) -> "AuthenticatedClient": - """Manually set the underlying httpx.Client - - **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout. - """ - self._client = client - return self - - def get_httpx_client(self) -> httpx.Client: - """Get the underlying httpx.Client, constructing a new one if not previously set""" - if self._client is None: - self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token - self._client = httpx.Client( - base_url=self._base_url, - cookies=self._cookies, - headers=self._headers, - timeout=self._timeout, - verify=self._verify_ssl, - follow_redirects=self._follow_redirects, - **self._httpx_args, - ) - return self._client - - def __enter__(self) -> "AuthenticatedClient": - """Enter a context manager for self.client—you cannot enter twice (see httpx docs)""" - self.get_httpx_client().__enter__() - return self - - def __exit__(self, *args: Any, **kwargs: Any) -> None: - """Exit a context manager for internal httpx.Client (see httpx docs)""" - self.get_httpx_client().__exit__(*args, **kwargs) - - def set_async_httpx_client(self, async_client: httpx.AsyncClient) -> "AuthenticatedClient": - """Manually set the underlying httpx.AsyncClient - - **NOTE**: This will override any other settings on the client, including cookies, headers, and timeout. - """ - self._async_client = async_client - return self - - def get_async_httpx_client(self) -> httpx.AsyncClient: - """Get the underlying httpx.AsyncClient, constructing a new one if not previously set""" - if self._async_client is None: - self._headers[self.auth_header_name] = f"{self.prefix} {self.token}" if self.prefix else self.token - self._async_client = httpx.AsyncClient( - base_url=self._base_url, - cookies=self._cookies, - headers=self._headers, - timeout=self._timeout, - verify=self._verify_ssl, - follow_redirects=self._follow_redirects, - **self._httpx_args, - ) - return self._async_client - - async def __aenter__(self) -> "AuthenticatedClient": - """Enter a context manager for underlying httpx.AsyncClient—you cannot enter twice (see httpx docs)""" - await self.get_async_httpx_client().__aenter__() - return self - - async def __aexit__(self, *args: Any, **kwargs: Any) -> None: - """Exit a context manager for underlying httpx.AsyncClient (see httpx docs)""" - await self.get_async_httpx_client().__aexit__(*args, **kwargs) diff --git a/memora-clients/python/agent_memory_api_client/errors.py b/memora-clients/python/agent_memory_api_client/errors.py deleted file mode 100644 index 5f92e76a..00000000 --- a/memora-clients/python/agent_memory_api_client/errors.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Contains shared errors types that can be raised from API functions""" - - -class UnexpectedStatus(Exception): - """Raised by api functions when the response status an undocumented status and Client.raise_on_unexpected_status is True""" - - def __init__(self, status_code: int, content: bytes): - self.status_code = status_code - self.content = content - - super().__init__( - f"Unexpected status code: {status_code}\n\nResponse content:\n{content.decode(errors='ignore')}" - ) - - -__all__ = ["UnexpectedStatus"] diff --git a/memora-clients/python/agent_memory_api_client/models/__init__.py b/memora-clients/python/agent_memory_api_client/models/__init__.py deleted file mode 100644 index cee8d4fa..00000000 --- a/memora-clients/python/agent_memory_api_client/models/__init__.py +++ /dev/null @@ -1,65 +0,0 @@ -"""Contains all the data models used in inputs/outputs""" - -from .add_background_request import AddBackgroundRequest -from .agent_list_item import AgentListItem -from .agent_list_response import AgentListResponse -from .agent_profile_response import AgentProfileResponse -from .background_response import BackgroundResponse -from .batch_put_async_response import BatchPutAsyncResponse -from .batch_put_request import BatchPutRequest -from .batch_put_response import BatchPutResponse -from .create_agent_request import CreateAgentRequest -from .document_response import DocumentResponse -from .graph_data_response import GraphDataResponse -from .graph_data_response_edges_item import GraphDataResponseEdgesItem -from .graph_data_response_nodes_item import GraphDataResponseNodesItem -from .graph_data_response_table_rows_item import GraphDataResponseTableRowsItem -from .http_validation_error import HTTPValidationError -from .list_documents_response import ListDocumentsResponse -from .list_documents_response_items_item import ListDocumentsResponseItemsItem -from .list_memory_units_response import ListMemoryUnitsResponse -from .list_memory_units_response_items_item import ListMemoryUnitsResponseItemsItem -from .memory_item import MemoryItem -from .personality_traits import PersonalityTraits -from .search_request import SearchRequest -from .search_response import SearchResponse -from .search_response_trace_type_0 import SearchResponseTraceType0 -from .search_result import SearchResult -from .think_fact import ThinkFact -from .think_request import ThinkRequest -from .think_response import ThinkResponse -from .update_personality_request import UpdatePersonalityRequest -from .validation_error import ValidationError - -__all__ = ( - "AddBackgroundRequest", - "AgentListItem", - "AgentListResponse", - "AgentProfileResponse", - "BackgroundResponse", - "BatchPutAsyncResponse", - "BatchPutRequest", - "BatchPutResponse", - "CreateAgentRequest", - "DocumentResponse", - "GraphDataResponse", - "GraphDataResponseEdgesItem", - "GraphDataResponseNodesItem", - "GraphDataResponseTableRowsItem", - "HTTPValidationError", - "ListDocumentsResponse", - "ListDocumentsResponseItemsItem", - "ListMemoryUnitsResponse", - "ListMemoryUnitsResponseItemsItem", - "MemoryItem", - "PersonalityTraits", - "SearchRequest", - "SearchResponse", - "SearchResponseTraceType0", - "SearchResult", - "ThinkFact", - "ThinkRequest", - "ThinkResponse", - "UpdatePersonalityRequest", - "ValidationError", -) diff --git a/memora-clients/python/agent_memory_api_client/models/add_background_request.py b/memora-clients/python/agent_memory_api_client/models/add_background_request.py deleted file mode 100644 index 43360a09..00000000 --- a/memora-clients/python/agent_memory_api_client/models/add_background_request.py +++ /dev/null @@ -1,77 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="AddBackgroundRequest") - - -@_attrs_define -class AddBackgroundRequest: - """Request model for adding/merging background information. - - Example: - {'content': 'I was born in Texas', 'update_personality': True} - - Attributes: - content (str): New background information to add or merge - update_personality (bool | Unset): If true, infer Big Five personality traits from the merged background - (default: true) Default: True. - """ - - content: str - update_personality: bool | Unset = True - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - content = self.content - - update_personality = self.update_personality - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "content": content, - } - ) - if update_personality is not UNSET: - field_dict["update_personality"] = update_personality - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - content = d.pop("content") - - update_personality = d.pop("update_personality", UNSET) - - add_background_request = cls( - content=content, - update_personality=update_personality, - ) - - add_background_request.additional_properties = d - return add_background_request - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/agent_list_item.py b/memora-clients/python/agent_memory_api_client/models/agent_list_item.py deleted file mode 100644 index f01c7844..00000000 --- a/memora-clients/python/agent_memory_api_client/models/agent_list_item.py +++ /dev/null @@ -1,127 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.personality_traits import PersonalityTraits - - -T = TypeVar("T", bound="AgentListItem") - - -@_attrs_define -class AgentListItem: - """Agent list item with profile summary. - - Attributes: - agent_id (str): - personality (PersonalityTraits): Personality traits based on Big Five model. Example: {'agreeableness': 0.7, - 'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}. - background (str): - created_at (None | str | Unset): - updated_at (None | str | Unset): - """ - - agent_id: str - personality: PersonalityTraits - background: str - created_at: None | str | Unset = UNSET - updated_at: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - agent_id = self.agent_id - - personality = self.personality.to_dict() - - background = self.background - - created_at: None | str | Unset - if isinstance(self.created_at, Unset): - created_at = UNSET - else: - created_at = self.created_at - - updated_at: None | str | Unset - if isinstance(self.updated_at, Unset): - updated_at = UNSET - else: - updated_at = self.updated_at - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "agent_id": agent_id, - "personality": personality, - "background": background, - } - ) - if created_at is not UNSET: - field_dict["created_at"] = created_at - if updated_at is not UNSET: - field_dict["updated_at"] = updated_at - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.personality_traits import PersonalityTraits - - d = dict(src_dict) - agent_id = d.pop("agent_id") - - personality = PersonalityTraits.from_dict(d.pop("personality")) - - background = d.pop("background") - - def _parse_created_at(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - created_at = _parse_created_at(d.pop("created_at", UNSET)) - - def _parse_updated_at(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - updated_at = _parse_updated_at(d.pop("updated_at", UNSET)) - - agent_list_item = cls( - agent_id=agent_id, - personality=personality, - background=background, - created_at=created_at, - updated_at=updated_at, - ) - - agent_list_item.additional_properties = d - return agent_list_item - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/agent_list_response.py b/memora-clients/python/agent_memory_api_client/models/agent_list_response.py deleted file mode 100644 index af69549e..00000000 --- a/memora-clients/python/agent_memory_api_client/models/agent_list_response.py +++ /dev/null @@ -1,81 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -if TYPE_CHECKING: - from ..models.agent_list_item import AgentListItem - - -T = TypeVar("T", bound="AgentListResponse") - - -@_attrs_define -class AgentListResponse: - """Response model for listing all agents. - - Example: - {'agents': [{'agent_id': 'user123', 'background': 'I am a software engineer', 'created_at': - '2024-01-15T10:30:00Z', 'personality': {'agreeableness': 0.5, 'bias_strength': 0.5, 'conscientiousness': 0.5, - 'extraversion': 0.5, 'neuroticism': 0.5, 'openness': 0.5}, 'updated_at': '2024-01-16T14:20:00Z'}]} - - Attributes: - agents (list[AgentListItem]): - """ - - agents: list[AgentListItem] - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - agents = [] - for agents_item_data in self.agents: - agents_item = agents_item_data.to_dict() - agents.append(agents_item) - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "agents": agents, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.agent_list_item import AgentListItem - - d = dict(src_dict) - agents = [] - _agents = d.pop("agents") - for agents_item_data in _agents: - agents_item = AgentListItem.from_dict(agents_item_data) - - agents.append(agents_item) - - agent_list_response = cls( - agents=agents, - ) - - agent_list_response.additional_properties = d - return agent_list_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/agent_profile_response.py b/memora-clients/python/agent_memory_api_client/models/agent_profile_response.py deleted file mode 100644 index a3f2bd4b..00000000 --- a/memora-clients/python/agent_memory_api_client/models/agent_profile_response.py +++ /dev/null @@ -1,90 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -if TYPE_CHECKING: - from ..models.personality_traits import PersonalityTraits - - -T = TypeVar("T", bound="AgentProfileResponse") - - -@_attrs_define -class AgentProfileResponse: - """Response model for agent profile. - - Example: - {'agent_id': 'user123', 'background': 'I am a software engineer with 10 years of experience in startups', - 'personality': {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, - 'neuroticism': 0.3, 'openness': 0.8}} - - Attributes: - agent_id (str): - personality (PersonalityTraits): Personality traits based on Big Five model. Example: {'agreeableness': 0.7, - 'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}. - background (str): - """ - - agent_id: str - personality: PersonalityTraits - background: str - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - agent_id = self.agent_id - - personality = self.personality.to_dict() - - background = self.background - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "agent_id": agent_id, - "personality": personality, - "background": background, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.personality_traits import PersonalityTraits - - d = dict(src_dict) - agent_id = d.pop("agent_id") - - personality = PersonalityTraits.from_dict(d.pop("personality")) - - background = d.pop("background") - - agent_profile_response = cls( - agent_id=agent_id, - personality=personality, - background=background, - ) - - agent_profile_response.additional_properties = d - return agent_profile_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/background_response.py b/memora-clients/python/agent_memory_api_client/models/background_response.py deleted file mode 100644 index ae165d74..00000000 --- a/memora-clients/python/agent_memory_api_client/models/background_response.py +++ /dev/null @@ -1,107 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.personality_traits import PersonalityTraits - - -T = TypeVar("T", bound="BackgroundResponse") - - -@_attrs_define -class BackgroundResponse: - """Response model for background update. - - Example: - {'background': 'I was born in Texas. I am a software engineer with 10 years of experience.', 'personality': - {'agreeableness': 0.8, 'bias_strength': 0.6, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.4, - 'openness': 0.7}} - - Attributes: - background (str): - personality (None | PersonalityTraits | Unset): - """ - - background: str - personality: None | PersonalityTraits | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - from ..models.personality_traits import PersonalityTraits - - background = self.background - - personality: dict[str, Any] | None | Unset - if isinstance(self.personality, Unset): - personality = UNSET - elif isinstance(self.personality, PersonalityTraits): - personality = self.personality.to_dict() - else: - personality = self.personality - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "background": background, - } - ) - if personality is not UNSET: - field_dict["personality"] = personality - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.personality_traits import PersonalityTraits - - d = dict(src_dict) - background = d.pop("background") - - def _parse_personality(data: object) -> None | PersonalityTraits | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, dict): - raise TypeError() - personality_type_0 = PersonalityTraits.from_dict(data) - - return personality_type_0 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(None | PersonalityTraits | Unset, data) - - personality = _parse_personality(d.pop("personality", UNSET)) - - background_response = cls( - background=background, - personality=personality, - ) - - background_response.additional_properties = d - return background_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/batch_put_async_response.py b/memora-clients/python/agent_memory_api_client/models/batch_put_async_response.py deleted file mode 100644 index 0d3aca3a..00000000 --- a/memora-clients/python/agent_memory_api_client/models/batch_put_async_response.py +++ /dev/null @@ -1,120 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="BatchPutAsyncResponse") - - -@_attrs_define -class BatchPutAsyncResponse: - """Response model for async batch put endpoint. - - Example: - {'agent_id': 'user123', 'document_id': 'conversation_123', 'items_count': 2, 'message': 'Batch put task queued - for background processing', 'queued': True, 'success': True} - - Attributes: - success (bool): - message (str): - agent_id (str): - items_count (int): - queued (bool): - document_id (None | str | Unset): - """ - - success: bool - message: str - agent_id: str - items_count: int - queued: bool - document_id: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - success = self.success - - message = self.message - - agent_id = self.agent_id - - items_count = self.items_count - - queued = self.queued - - document_id: None | str | Unset - if isinstance(self.document_id, Unset): - document_id = UNSET - else: - document_id = self.document_id - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "success": success, - "message": message, - "agent_id": agent_id, - "items_count": items_count, - "queued": queued, - } - ) - if document_id is not UNSET: - field_dict["document_id"] = document_id - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - success = d.pop("success") - - message = d.pop("message") - - agent_id = d.pop("agent_id") - - items_count = d.pop("items_count") - - queued = d.pop("queued") - - def _parse_document_id(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - document_id = _parse_document_id(d.pop("document_id", UNSET)) - - batch_put_async_response = cls( - success=success, - message=message, - agent_id=agent_id, - items_count=items_count, - queued=queued, - document_id=document_id, - ) - - batch_put_async_response.additional_properties = d - return batch_put_async_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/batch_put_request.py b/memora-clients/python/agent_memory_api_client/models/batch_put_request.py deleted file mode 100644 index 46155687..00000000 --- a/memora-clients/python/agent_memory_api_client/models/batch_put_request.py +++ /dev/null @@ -1,102 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.memory_item import MemoryItem - - -T = TypeVar("T", bound="BatchPutRequest") - - -@_attrs_define -class BatchPutRequest: - """Request model for batch put endpoint. - - Example: - {'document_id': 'conversation_123', 'items': [{'content': 'Alice works at Google', 'context': 'work'}, - {'content': 'Bob went hiking yesterday', 'event_date': '2024-01-15T10:00:00Z'}]} - - Attributes: - items (list[MemoryItem]): - document_id (None | str | Unset): - """ - - items: list[MemoryItem] - document_id: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - items = [] - for items_item_data in self.items: - items_item = items_item_data.to_dict() - items.append(items_item) - - document_id: None | str | Unset - if isinstance(self.document_id, Unset): - document_id = UNSET - else: - document_id = self.document_id - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "items": items, - } - ) - if document_id is not UNSET: - field_dict["document_id"] = document_id - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.memory_item import MemoryItem - - d = dict(src_dict) - items = [] - _items = d.pop("items") - for items_item_data in _items: - items_item = MemoryItem.from_dict(items_item_data) - - items.append(items_item) - - def _parse_document_id(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - document_id = _parse_document_id(d.pop("document_id", UNSET)) - - batch_put_request = cls( - items=items, - document_id=document_id, - ) - - batch_put_request.additional_properties = d - return batch_put_request - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/batch_put_response.py b/memora-clients/python/agent_memory_api_client/models/batch_put_response.py deleted file mode 100644 index b9a90f3e..00000000 --- a/memora-clients/python/agent_memory_api_client/models/batch_put_response.py +++ /dev/null @@ -1,112 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="BatchPutResponse") - - -@_attrs_define -class BatchPutResponse: - """Response model for batch put endpoint. - - Example: - {'agent_id': 'user123', 'document_id': 'conversation_123', 'items_count': 2, 'message': 'Successfully stored 2 - memory items', 'success': True} - - Attributes: - success (bool): - message (str): - agent_id (str): - items_count (int): - document_id (None | str | Unset): - """ - - success: bool - message: str - agent_id: str - items_count: int - document_id: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - success = self.success - - message = self.message - - agent_id = self.agent_id - - items_count = self.items_count - - document_id: None | str | Unset - if isinstance(self.document_id, Unset): - document_id = UNSET - else: - document_id = self.document_id - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "success": success, - "message": message, - "agent_id": agent_id, - "items_count": items_count, - } - ) - if document_id is not UNSET: - field_dict["document_id"] = document_id - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - success = d.pop("success") - - message = d.pop("message") - - agent_id = d.pop("agent_id") - - items_count = d.pop("items_count") - - def _parse_document_id(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - document_id = _parse_document_id(d.pop("document_id", UNSET)) - - batch_put_response = cls( - success=success, - message=message, - agent_id=agent_id, - items_count=items_count, - document_id=document_id, - ) - - batch_put_response.additional_properties = d - return batch_put_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/create_agent_request.py b/memora-clients/python/agent_memory_api_client/models/create_agent_request.py deleted file mode 100644 index c1fbb039..00000000 --- a/memora-clients/python/agent_memory_api_client/models/create_agent_request.py +++ /dev/null @@ -1,116 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.personality_traits import PersonalityTraits - - -T = TypeVar("T", bound="CreateAgentRequest") - - -@_attrs_define -class CreateAgentRequest: - """Request model for creating/updating an agent. - - Example: - {'background': 'I am a creative software engineer with 10 years of experience', 'personality': {'agreeableness': - 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}} - - Attributes: - personality (None | PersonalityTraits | Unset): - background (None | str | Unset): - """ - - personality: None | PersonalityTraits | Unset = UNSET - background: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - from ..models.personality_traits import PersonalityTraits - - personality: dict[str, Any] | None | Unset - if isinstance(self.personality, Unset): - personality = UNSET - elif isinstance(self.personality, PersonalityTraits): - personality = self.personality.to_dict() - else: - personality = self.personality - - background: None | str | Unset - if isinstance(self.background, Unset): - background = UNSET - else: - background = self.background - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if personality is not UNSET: - field_dict["personality"] = personality - if background is not UNSET: - field_dict["background"] = background - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.personality_traits import PersonalityTraits - - d = dict(src_dict) - - def _parse_personality(data: object) -> None | PersonalityTraits | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, dict): - raise TypeError() - personality_type_0 = PersonalityTraits.from_dict(data) - - return personality_type_0 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(None | PersonalityTraits | Unset, data) - - personality = _parse_personality(d.pop("personality", UNSET)) - - def _parse_background(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - background = _parse_background(d.pop("background", UNSET)) - - create_agent_request = cls( - personality=personality, - background=background, - ) - - create_agent_request.additional_properties = d - return create_agent_request - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/document_response.py b/memora-clients/python/agent_memory_api_client/models/document_response.py deleted file mode 100644 index 3d4c2e21..00000000 --- a/memora-clients/python/agent_memory_api_client/models/document_response.py +++ /dev/null @@ -1,120 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="DocumentResponse") - - -@_attrs_define -class DocumentResponse: - """Response model for get document endpoint. - - Example: - {'agent_id': 'user123', 'content_hash': 'abc123', 'created_at': '2024-01-15T10:30:00Z', 'id': 'session_1', - 'memory_unit_count': 15, 'original_text': 'Full document text here...', 'updated_at': '2024-01-15T10:30:00Z'} - - Attributes: - id (str): - agent_id (str): - original_text (str): - content_hash (None | str): - created_at (str): - updated_at (str): - memory_unit_count (int): - """ - - id: str - agent_id: str - original_text: str - content_hash: None | str - created_at: str - updated_at: str - memory_unit_count: int - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - id = self.id - - agent_id = self.agent_id - - original_text = self.original_text - - content_hash: None | str - content_hash = self.content_hash - - created_at = self.created_at - - updated_at = self.updated_at - - memory_unit_count = self.memory_unit_count - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "id": id, - "agent_id": agent_id, - "original_text": original_text, - "content_hash": content_hash, - "created_at": created_at, - "updated_at": updated_at, - "memory_unit_count": memory_unit_count, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - id = d.pop("id") - - agent_id = d.pop("agent_id") - - original_text = d.pop("original_text") - - def _parse_content_hash(data: object) -> None | str: - if data is None: - return data - return cast(None | str, data) - - content_hash = _parse_content_hash(d.pop("content_hash")) - - created_at = d.pop("created_at") - - updated_at = d.pop("updated_at") - - memory_unit_count = d.pop("memory_unit_count") - - document_response = cls( - id=id, - agent_id=agent_id, - original_text=original_text, - content_hash=content_hash, - created_at=created_at, - updated_at=updated_at, - memory_unit_count=memory_unit_count, - ) - - document_response.additional_properties = d - return document_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/graph_data_response.py b/memora-clients/python/agent_memory_api_client/models/graph_data_response.py deleted file mode 100644 index 27fc9499..00000000 --- a/memora-clients/python/agent_memory_api_client/models/graph_data_response.py +++ /dev/null @@ -1,126 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -if TYPE_CHECKING: - from ..models.graph_data_response_edges_item import GraphDataResponseEdgesItem - from ..models.graph_data_response_nodes_item import GraphDataResponseNodesItem - from ..models.graph_data_response_table_rows_item import GraphDataResponseTableRowsItem - - -T = TypeVar("T", bound="GraphDataResponse") - - -@_attrs_define -class GraphDataResponse: - """Response model for graph data endpoint. - - Example: - {'edges': [{'from': '1', 'to': '2', 'type': 'semantic', 'weight': 0.8}], 'nodes': [{'id': '1', 'label': 'Alice - works at Google', 'type': 'world'}, {'id': '2', 'label': 'Bob went hiking', 'type': 'world'}], 'table_rows': - [{'context': 'Work info', 'date': '2024-01-15 10:30', 'entities': 'Alice (PERSON), Google (ORGANIZATION)', 'id': - 'abc12345...', 'text': 'Alice works at Google'}], 'total_units': 2} - - Attributes: - nodes (list[GraphDataResponseNodesItem]): - edges (list[GraphDataResponseEdgesItem]): - table_rows (list[GraphDataResponseTableRowsItem]): - total_units (int): - """ - - nodes: list[GraphDataResponseNodesItem] - edges: list[GraphDataResponseEdgesItem] - table_rows: list[GraphDataResponseTableRowsItem] - total_units: int - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - nodes = [] - for nodes_item_data in self.nodes: - nodes_item = nodes_item_data.to_dict() - nodes.append(nodes_item) - - edges = [] - for edges_item_data in self.edges: - edges_item = edges_item_data.to_dict() - edges.append(edges_item) - - table_rows = [] - for table_rows_item_data in self.table_rows: - table_rows_item = table_rows_item_data.to_dict() - table_rows.append(table_rows_item) - - total_units = self.total_units - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "nodes": nodes, - "edges": edges, - "table_rows": table_rows, - "total_units": total_units, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.graph_data_response_edges_item import GraphDataResponseEdgesItem - from ..models.graph_data_response_nodes_item import GraphDataResponseNodesItem - from ..models.graph_data_response_table_rows_item import GraphDataResponseTableRowsItem - - d = dict(src_dict) - nodes = [] - _nodes = d.pop("nodes") - for nodes_item_data in _nodes: - nodes_item = GraphDataResponseNodesItem.from_dict(nodes_item_data) - - nodes.append(nodes_item) - - edges = [] - _edges = d.pop("edges") - for edges_item_data in _edges: - edges_item = GraphDataResponseEdgesItem.from_dict(edges_item_data) - - edges.append(edges_item) - - table_rows = [] - _table_rows = d.pop("table_rows") - for table_rows_item_data in _table_rows: - table_rows_item = GraphDataResponseTableRowsItem.from_dict(table_rows_item_data) - - table_rows.append(table_rows_item) - - total_units = d.pop("total_units") - - graph_data_response = cls( - nodes=nodes, - edges=edges, - table_rows=table_rows, - total_units=total_units, - ) - - graph_data_response.additional_properties = d - return graph_data_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/graph_data_response_edges_item.py b/memora-clients/python/agent_memory_api_client/models/graph_data_response_edges_item.py deleted file mode 100644 index 09a72848..00000000 --- a/memora-clients/python/agent_memory_api_client/models/graph_data_response_edges_item.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="GraphDataResponseEdgesItem") - - -@_attrs_define -class GraphDataResponseEdgesItem: - """ """ - - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - graph_data_response_edges_item = cls() - - graph_data_response_edges_item.additional_properties = d - return graph_data_response_edges_item - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/graph_data_response_nodes_item.py b/memora-clients/python/agent_memory_api_client/models/graph_data_response_nodes_item.py deleted file mode 100644 index aeeecff6..00000000 --- a/memora-clients/python/agent_memory_api_client/models/graph_data_response_nodes_item.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="GraphDataResponseNodesItem") - - -@_attrs_define -class GraphDataResponseNodesItem: - """ """ - - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - graph_data_response_nodes_item = cls() - - graph_data_response_nodes_item.additional_properties = d - return graph_data_response_nodes_item - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/graph_data_response_table_rows_item.py b/memora-clients/python/agent_memory_api_client/models/graph_data_response_table_rows_item.py deleted file mode 100644 index c4380872..00000000 --- a/memora-clients/python/agent_memory_api_client/models/graph_data_response_table_rows_item.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="GraphDataResponseTableRowsItem") - - -@_attrs_define -class GraphDataResponseTableRowsItem: - """ """ - - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - graph_data_response_table_rows_item = cls() - - graph_data_response_table_rows_item.additional_properties = d - return graph_data_response_table_rows_item - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/http_validation_error.py b/memora-clients/python/agent_memory_api_client/models/http_validation_error.py deleted file mode 100644 index 195e5a76..00000000 --- a/memora-clients/python/agent_memory_api_client/models/http_validation_error.py +++ /dev/null @@ -1,79 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.validation_error import ValidationError - - -T = TypeVar("T", bound="HTTPValidationError") - - -@_attrs_define -class HTTPValidationError: - """ - Attributes: - detail (list[ValidationError] | Unset): - """ - - detail: list[ValidationError] | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - detail: list[dict[str, Any]] | Unset = UNSET - if not isinstance(self.detail, Unset): - detail = [] - for detail_item_data in self.detail: - detail_item = detail_item_data.to_dict() - detail.append(detail_item) - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update({}) - if detail is not UNSET: - field_dict["detail"] = detail - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.validation_error import ValidationError - - d = dict(src_dict) - _detail = d.pop("detail", UNSET) - detail: list[ValidationError] | Unset = UNSET - if _detail is not UNSET: - detail = [] - for detail_item_data in _detail: - detail_item = ValidationError.from_dict(detail_item_data) - - detail.append(detail_item) - - http_validation_error = cls( - detail=detail, - ) - - http_validation_error.additional_properties = d - return http_validation_error - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/list_documents_response.py b/memora-clients/python/agent_memory_api_client/models/list_documents_response.py deleted file mode 100644 index 33be073e..00000000 --- a/memora-clients/python/agent_memory_api_client/models/list_documents_response.py +++ /dev/null @@ -1,105 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -if TYPE_CHECKING: - from ..models.list_documents_response_items_item import ListDocumentsResponseItemsItem - - -T = TypeVar("T", bound="ListDocumentsResponse") - - -@_attrs_define -class ListDocumentsResponse: - """Response model for list documents endpoint. - - Example: - {'items': [{'agent_id': 'user123', 'content_hash': 'abc123', 'created_at': '2024-01-15T10:30:00Z', 'id': - 'session_1', 'memory_unit_count': 15, 'text_length': 5420, 'updated_at': '2024-01-15T10:30:00Z'}], 'limit': 100, - 'offset': 0, 'total': 50} - - Attributes: - items (list[ListDocumentsResponseItemsItem]): - total (int): - limit (int): - offset (int): - """ - - items: list[ListDocumentsResponseItemsItem] - total: int - limit: int - offset: int - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - items = [] - for items_item_data in self.items: - items_item = items_item_data.to_dict() - items.append(items_item) - - total = self.total - - limit = self.limit - - offset = self.offset - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "items": items, - "total": total, - "limit": limit, - "offset": offset, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.list_documents_response_items_item import ListDocumentsResponseItemsItem - - d = dict(src_dict) - items = [] - _items = d.pop("items") - for items_item_data in _items: - items_item = ListDocumentsResponseItemsItem.from_dict(items_item_data) - - items.append(items_item) - - total = d.pop("total") - - limit = d.pop("limit") - - offset = d.pop("offset") - - list_documents_response = cls( - items=items, - total=total, - limit=limit, - offset=offset, - ) - - list_documents_response.additional_properties = d - return list_documents_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/list_documents_response_items_item.py b/memora-clients/python/agent_memory_api_client/models/list_documents_response_items_item.py deleted file mode 100644 index 448dcce3..00000000 --- a/memora-clients/python/agent_memory_api_client/models/list_documents_response_items_item.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="ListDocumentsResponseItemsItem") - - -@_attrs_define -class ListDocumentsResponseItemsItem: - """ """ - - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - list_documents_response_items_item = cls() - - list_documents_response_items_item.additional_properties = d - return list_documents_response_items_item - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/list_memory_units_response.py b/memora-clients/python/agent_memory_api_client/models/list_memory_units_response.py deleted file mode 100644 index b56d2fdb..00000000 --- a/memora-clients/python/agent_memory_api_client/models/list_memory_units_response.py +++ /dev/null @@ -1,105 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -if TYPE_CHECKING: - from ..models.list_memory_units_response_items_item import ListMemoryUnitsResponseItemsItem - - -T = TypeVar("T", bound="ListMemoryUnitsResponse") - - -@_attrs_define -class ListMemoryUnitsResponse: - """Response model for list memory units endpoint. - - Example: - {'items': [{'context': 'Work conversation', 'date': '2024-01-15T10:30:00Z', 'entities': 'Alice (PERSON), Google - (ORGANIZATION)', 'fact_type': 'world', 'id': '550e8400-e29b-41d4-a716-446655440000', 'text': 'Alice works at - Google on the AI team'}], 'limit': 100, 'offset': 0, 'total': 150} - - Attributes: - items (list[ListMemoryUnitsResponseItemsItem]): - total (int): - limit (int): - offset (int): - """ - - items: list[ListMemoryUnitsResponseItemsItem] - total: int - limit: int - offset: int - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - items = [] - for items_item_data in self.items: - items_item = items_item_data.to_dict() - items.append(items_item) - - total = self.total - - limit = self.limit - - offset = self.offset - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "items": items, - "total": total, - "limit": limit, - "offset": offset, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.list_memory_units_response_items_item import ListMemoryUnitsResponseItemsItem - - d = dict(src_dict) - items = [] - _items = d.pop("items") - for items_item_data in _items: - items_item = ListMemoryUnitsResponseItemsItem.from_dict(items_item_data) - - items.append(items_item) - - total = d.pop("total") - - limit = d.pop("limit") - - offset = d.pop("offset") - - list_memory_units_response = cls( - items=items, - total=total, - limit=limit, - offset=offset, - ) - - list_memory_units_response.additional_properties = d - return list_memory_units_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/list_memory_units_response_items_item.py b/memora-clients/python/agent_memory_api_client/models/list_memory_units_response_items_item.py deleted file mode 100644 index 28194583..00000000 --- a/memora-clients/python/agent_memory_api_client/models/list_memory_units_response_items_item.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="ListMemoryUnitsResponseItemsItem") - - -@_attrs_define -class ListMemoryUnitsResponseItemsItem: - """ """ - - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - list_memory_units_response_items_item = cls() - - list_memory_units_response_items_item.additional_properties = d - return list_memory_units_response_items_item - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/memory_item.py b/memora-clients/python/agent_memory_api_client/models/memory_item.py deleted file mode 100644 index 4839227c..00000000 --- a/memora-clients/python/agent_memory_api_client/models/memory_item.py +++ /dev/null @@ -1,120 +0,0 @@ -from __future__ import annotations - -import datetime -from collections.abc import Mapping -from typing import Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field -from dateutil.parser import isoparse - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="MemoryItem") - - -@_attrs_define -class MemoryItem: - """Single memory item for batch put. - - Example: - {'content': "Alice mentioned she's working on a new ML model", 'context': 'team meeting', 'event_date': - '2024-01-15T10:30:00Z'} - - Attributes: - content (str): - event_date (datetime.datetime | None | Unset): - context (None | str | Unset): - """ - - content: str - event_date: datetime.datetime | None | Unset = UNSET - context: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - content = self.content - - event_date: None | str | Unset - if isinstance(self.event_date, Unset): - event_date = UNSET - elif isinstance(self.event_date, datetime.datetime): - event_date = self.event_date.isoformat() - else: - event_date = self.event_date - - context: None | str | Unset - if isinstance(self.context, Unset): - context = UNSET - else: - context = self.context - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "content": content, - } - ) - if event_date is not UNSET: - field_dict["event_date"] = event_date - if context is not UNSET: - field_dict["context"] = context - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - content = d.pop("content") - - def _parse_event_date(data: object) -> datetime.datetime | None | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, str): - raise TypeError() - event_date_type_0 = isoparse(data) - - return event_date_type_0 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(datetime.datetime | None | Unset, data) - - event_date = _parse_event_date(d.pop("event_date", UNSET)) - - def _parse_context(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - context = _parse_context(d.pop("context", UNSET)) - - memory_item = cls( - content=content, - event_date=event_date, - context=context, - ) - - memory_item.additional_properties = d - return memory_item - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/personality_traits.py b/memora-clients/python/agent_memory_api_client/models/personality_traits.py deleted file mode 100644 index 5ac2b584..00000000 --- a/memora-clients/python/agent_memory_api_client/models/personality_traits.py +++ /dev/null @@ -1,106 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="PersonalityTraits") - - -@_attrs_define -class PersonalityTraits: - """Personality traits based on Big Five model. - - Example: - {'agreeableness': 0.7, 'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3, - 'openness': 0.8} - - Attributes: - openness (float): Openness to experience (0-1) - conscientiousness (float): Conscientiousness (0-1) - extraversion (float): Extraversion (0-1) - agreeableness (float): Agreeableness (0-1) - neuroticism (float): Neuroticism (0-1) - bias_strength (float): How strongly personality influences opinions (0-1) - """ - - openness: float - conscientiousness: float - extraversion: float - agreeableness: float - neuroticism: float - bias_strength: float - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - openness = self.openness - - conscientiousness = self.conscientiousness - - extraversion = self.extraversion - - agreeableness = self.agreeableness - - neuroticism = self.neuroticism - - bias_strength = self.bias_strength - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "openness": openness, - "conscientiousness": conscientiousness, - "extraversion": extraversion, - "agreeableness": agreeableness, - "neuroticism": neuroticism, - "bias_strength": bias_strength, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - openness = d.pop("openness") - - conscientiousness = d.pop("conscientiousness") - - extraversion = d.pop("extraversion") - - agreeableness = d.pop("agreeableness") - - neuroticism = d.pop("neuroticism") - - bias_strength = d.pop("bias_strength") - - personality_traits = cls( - openness=openness, - conscientiousness=conscientiousness, - extraversion=extraversion, - agreeableness=agreeableness, - neuroticism=neuroticism, - bias_strength=bias_strength, - ) - - personality_traits.additional_properties = d - return personality_traits - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/search_request.py b/memora-clients/python/agent_memory_api_client/models/search_request.py deleted file mode 100644 index 71d27f05..00000000 --- a/memora-clients/python/agent_memory_api_client/models/search_request.py +++ /dev/null @@ -1,155 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="SearchRequest") - - -@_attrs_define -class SearchRequest: - """Request model for search endpoint. - - Example: - {'fact_type': ['world', 'agent'], 'max_tokens': 4096, 'query': 'What did Alice say about machine learning?', - 'question_date': '2023-05-30T23:40:00', 'reranker': 'heuristic', 'thinking_budget': 100, 'trace': True} - - Attributes: - query (str): - fact_type (list[str] | None | Unset): - thinking_budget (int | Unset): Default: 100. - max_tokens (int | Unset): Default: 4096. - reranker (str | Unset): Default: 'heuristic'. - trace (bool | Unset): Default: False. - question_date (None | str | Unset): - """ - - query: str - fact_type: list[str] | None | Unset = UNSET - thinking_budget: int | Unset = 100 - max_tokens: int | Unset = 4096 - reranker: str | Unset = "heuristic" - trace: bool | Unset = False - question_date: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - query = self.query - - fact_type: list[str] | None | Unset - if isinstance(self.fact_type, Unset): - fact_type = UNSET - elif isinstance(self.fact_type, list): - fact_type = self.fact_type - - else: - fact_type = self.fact_type - - thinking_budget = self.thinking_budget - - max_tokens = self.max_tokens - - reranker = self.reranker - - trace = self.trace - - question_date: None | str | Unset - if isinstance(self.question_date, Unset): - question_date = UNSET - else: - question_date = self.question_date - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "query": query, - } - ) - if fact_type is not UNSET: - field_dict["fact_type"] = fact_type - if thinking_budget is not UNSET: - field_dict["thinking_budget"] = thinking_budget - if max_tokens is not UNSET: - field_dict["max_tokens"] = max_tokens - if reranker is not UNSET: - field_dict["reranker"] = reranker - if trace is not UNSET: - field_dict["trace"] = trace - if question_date is not UNSET: - field_dict["question_date"] = question_date - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - query = d.pop("query") - - def _parse_fact_type(data: object) -> list[str] | None | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, list): - raise TypeError() - fact_type_type_0 = cast(list[str], data) - - return fact_type_type_0 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(list[str] | None | Unset, data) - - fact_type = _parse_fact_type(d.pop("fact_type", UNSET)) - - thinking_budget = d.pop("thinking_budget", UNSET) - - max_tokens = d.pop("max_tokens", UNSET) - - reranker = d.pop("reranker", UNSET) - - trace = d.pop("trace", UNSET) - - def _parse_question_date(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - question_date = _parse_question_date(d.pop("question_date", UNSET)) - - search_request = cls( - query=query, - fact_type=fact_type, - thinking_budget=thinking_budget, - max_tokens=max_tokens, - reranker=reranker, - trace=trace, - question_date=question_date, - ) - - search_request.additional_properties = d - return search_request - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/search_response.py b/memora-clients/python/agent_memory_api_client/models/search_response.py deleted file mode 100644 index f8b3f94e..00000000 --- a/memora-clients/python/agent_memory_api_client/models/search_response.py +++ /dev/null @@ -1,117 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.search_response_trace_type_0 import SearchResponseTraceType0 - from ..models.search_result import SearchResult - - -T = TypeVar("T", bound="SearchResponse") - - -@_attrs_define -class SearchResponse: - """Response model for search endpoints. - - Example: - {'results': [{'activation': 0.95, 'context': 'work info', 'event_date': '2024-01-15T10:30:00Z', 'id': - '123e4567-e89b-12d3-a456-426614174000', 'text': 'Alice works at Google on the AI team', 'type': 'world'}], - 'trace': {'num_results': 1, 'query': 'What did Alice say about machine learning?', 'time_seconds': 0.123}} - - Attributes: - results (list[SearchResult]): - trace (None | SearchResponseTraceType0 | Unset): - """ - - results: list[SearchResult] - trace: None | SearchResponseTraceType0 | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - from ..models.search_response_trace_type_0 import SearchResponseTraceType0 - - results = [] - for results_item_data in self.results: - results_item = results_item_data.to_dict() - results.append(results_item) - - trace: dict[str, Any] | None | Unset - if isinstance(self.trace, Unset): - trace = UNSET - elif isinstance(self.trace, SearchResponseTraceType0): - trace = self.trace.to_dict() - else: - trace = self.trace - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "results": results, - } - ) - if trace is not UNSET: - field_dict["trace"] = trace - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.search_response_trace_type_0 import SearchResponseTraceType0 - from ..models.search_result import SearchResult - - d = dict(src_dict) - results = [] - _results = d.pop("results") - for results_item_data in _results: - results_item = SearchResult.from_dict(results_item_data) - - results.append(results_item) - - def _parse_trace(data: object) -> None | SearchResponseTraceType0 | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, dict): - raise TypeError() - trace_type_0 = SearchResponseTraceType0.from_dict(data) - - return trace_type_0 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(None | SearchResponseTraceType0 | Unset, data) - - trace = _parse_trace(d.pop("trace", UNSET)) - - search_response = cls( - results=results, - trace=trace, - ) - - search_response.additional_properties = d - return search_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/search_response_trace_type_0.py b/memora-clients/python/agent_memory_api_client/models/search_response_trace_type_0.py deleted file mode 100644 index d7c9843f..00000000 --- a/memora-clients/python/agent_memory_api_client/models/search_response_trace_type_0.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="SearchResponseTraceType0") - - -@_attrs_define -class SearchResponseTraceType0: - """ """ - - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - search_response_trace_type_0 = cls() - - search_response_trace_type_0.additional_properties = d - return search_response_trace_type_0 - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/search_result.py b/memora-clients/python/agent_memory_api_client/models/search_result.py deleted file mode 100644 index 89a6e661..00000000 --- a/memora-clients/python/agent_memory_api_client/models/search_result.py +++ /dev/null @@ -1,156 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="SearchResult") - - -@_attrs_define -class SearchResult: - """Single search result item. - - Example: - {'context': 'work info', 'event_date': '2024-01-15T10:30:00Z', 'id': '123e4567-e89b-12d3-a456-426614174000', - 'text': 'Alice works at Google on the AI team', 'type': 'world'} - - Attributes: - id (str): - text (str): - type_ (None | str | Unset): - activation (float | None | Unset): - context (None | str | Unset): - event_date (None | str | Unset): - """ - - id: str - text: str - type_: None | str | Unset = UNSET - activation: float | None | Unset = UNSET - context: None | str | Unset = UNSET - event_date: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - id = self.id - - text = self.text - - type_: None | str | Unset - if isinstance(self.type_, Unset): - type_ = UNSET - else: - type_ = self.type_ - - activation: float | None | Unset - if isinstance(self.activation, Unset): - activation = UNSET - else: - activation = self.activation - - context: None | str | Unset - if isinstance(self.context, Unset): - context = UNSET - else: - context = self.context - - event_date: None | str | Unset - if isinstance(self.event_date, Unset): - event_date = UNSET - else: - event_date = self.event_date - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "id": id, - "text": text, - } - ) - if type_ is not UNSET: - field_dict["type"] = type_ - if activation is not UNSET: - field_dict["activation"] = activation - if context is not UNSET: - field_dict["context"] = context - if event_date is not UNSET: - field_dict["event_date"] = event_date - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - id = d.pop("id") - - text = d.pop("text") - - def _parse_type_(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - type_ = _parse_type_(d.pop("type", UNSET)) - - def _parse_activation(data: object) -> float | None | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(float | None | Unset, data) - - activation = _parse_activation(d.pop("activation", UNSET)) - - def _parse_context(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - context = _parse_context(d.pop("context", UNSET)) - - def _parse_event_date(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - event_date = _parse_event_date(d.pop("event_date", UNSET)) - - search_result = cls( - id=id, - text=text, - type_=type_, - activation=activation, - context=context, - event_date=event_date, - ) - - search_result.additional_properties = d - return search_result - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/think_fact.py b/memora-clients/python/agent_memory_api_client/models/think_fact.py deleted file mode 100644 index 927098c2..00000000 --- a/memora-clients/python/agent_memory_api_client/models/think_fact.py +++ /dev/null @@ -1,168 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="ThinkFact") - - -@_attrs_define -class ThinkFact: - """A fact used in think response. - - Example: - {'context': 'healthcare discussion', 'event_date': '2024-01-15T10:30:00Z', 'id': - '123e4567-e89b-12d3-a456-426614174000', 'text': 'AI is used in healthcare', 'type': 'world'} - - Attributes: - text (str): - id (None | str | Unset): - type_ (None | str | Unset): - activation (float | None | Unset): - context (None | str | Unset): - event_date (None | str | Unset): - """ - - text: str - id: None | str | Unset = UNSET - type_: None | str | Unset = UNSET - activation: float | None | Unset = UNSET - context: None | str | Unset = UNSET - event_date: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - text = self.text - - id: None | str | Unset - if isinstance(self.id, Unset): - id = UNSET - else: - id = self.id - - type_: None | str | Unset - if isinstance(self.type_, Unset): - type_ = UNSET - else: - type_ = self.type_ - - activation: float | None | Unset - if isinstance(self.activation, Unset): - activation = UNSET - else: - activation = self.activation - - context: None | str | Unset - if isinstance(self.context, Unset): - context = UNSET - else: - context = self.context - - event_date: None | str | Unset - if isinstance(self.event_date, Unset): - event_date = UNSET - else: - event_date = self.event_date - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "text": text, - } - ) - if id is not UNSET: - field_dict["id"] = id - if type_ is not UNSET: - field_dict["type"] = type_ - if activation is not UNSET: - field_dict["activation"] = activation - if context is not UNSET: - field_dict["context"] = context - if event_date is not UNSET: - field_dict["event_date"] = event_date - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - text = d.pop("text") - - def _parse_id(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - id = _parse_id(d.pop("id", UNSET)) - - def _parse_type_(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - type_ = _parse_type_(d.pop("type", UNSET)) - - def _parse_activation(data: object) -> float | None | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(float | None | Unset, data) - - activation = _parse_activation(d.pop("activation", UNSET)) - - def _parse_context(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - context = _parse_context(d.pop("context", UNSET)) - - def _parse_event_date(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - event_date = _parse_event_date(d.pop("event_date", UNSET)) - - think_fact = cls( - text=text, - id=id, - type_=type_, - activation=activation, - context=context, - event_date=event_date, - ) - - think_fact.additional_properties = d - return think_fact - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/think_request.py b/memora-clients/python/agent_memory_api_client/models/think_request.py deleted file mode 100644 index cac0ca86..00000000 --- a/memora-clients/python/agent_memory_api_client/models/think_request.py +++ /dev/null @@ -1,97 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -T = TypeVar("T", bound="ThinkRequest") - - -@_attrs_define -class ThinkRequest: - """Request model for think endpoint. - - Example: - {'context': 'This is for a research paper on AI ethics', 'query': 'What do you think about artificial - intelligence?', 'thinking_budget': 50} - - Attributes: - query (str): - thinking_budget (int | Unset): Default: 50. - context (None | str | Unset): - """ - - query: str - thinking_budget: int | Unset = 50 - context: None | str | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - query = self.query - - thinking_budget = self.thinking_budget - - context: None | str | Unset - if isinstance(self.context, Unset): - context = UNSET - else: - context = self.context - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "query": query, - } - ) - if thinking_budget is not UNSET: - field_dict["thinking_budget"] = thinking_budget - if context is not UNSET: - field_dict["context"] = context - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - query = d.pop("query") - - thinking_budget = d.pop("thinking_budget", UNSET) - - def _parse_context(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - context = _parse_context(d.pop("context", UNSET)) - - think_request = cls( - query=query, - thinking_budget=thinking_budget, - context=context, - ) - - think_request.additional_properties = d - return think_request - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/think_response.py b/memora-clients/python/agent_memory_api_client/models/think_response.py deleted file mode 100644 index c3c1d854..00000000 --- a/memora-clients/python/agent_memory_api_client/models/think_response.py +++ /dev/null @@ -1,108 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.think_fact import ThinkFact - - -T = TypeVar("T", bound="ThinkResponse") - - -@_attrs_define -class ThinkResponse: - """Response model for think endpoint. - - Example: - {'based_on': [{'activation': 0.9, 'id': '123', 'text': 'AI is used in healthcare', 'type': 'world'}, - {'activation': 0.85, 'id': '456', 'text': 'I discussed AI applications last week', 'type': 'agent'}], - 'new_opinions': ['AI has great potential when used responsibly'], 'text': 'Based on my understanding, AI is a - transformative technology...'} - - Attributes: - text (str): - based_on (list[ThinkFact] | Unset): - new_opinions (list[str] | Unset): - """ - - text: str - based_on: list[ThinkFact] | Unset = UNSET - new_opinions: list[str] | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - text = self.text - - based_on: list[dict[str, Any]] | Unset = UNSET - if not isinstance(self.based_on, Unset): - based_on = [] - for based_on_item_data in self.based_on: - based_on_item = based_on_item_data.to_dict() - based_on.append(based_on_item) - - new_opinions: list[str] | Unset = UNSET - if not isinstance(self.new_opinions, Unset): - new_opinions = self.new_opinions - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "text": text, - } - ) - if based_on is not UNSET: - field_dict["based_on"] = based_on - if new_opinions is not UNSET: - field_dict["new_opinions"] = new_opinions - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.think_fact import ThinkFact - - d = dict(src_dict) - text = d.pop("text") - - _based_on = d.pop("based_on", UNSET) - based_on: list[ThinkFact] | Unset = UNSET - if _based_on is not UNSET: - based_on = [] - for based_on_item_data in _based_on: - based_on_item = ThinkFact.from_dict(based_on_item_data) - - based_on.append(based_on_item) - - new_opinions = cast(list[str], d.pop("new_opinions", UNSET)) - - think_response = cls( - text=text, - based_on=based_on, - new_opinions=new_opinions, - ) - - think_response.additional_properties = d - return think_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/update_personality_request.py b/memora-clients/python/agent_memory_api_client/models/update_personality_request.py deleted file mode 100644 index e0688a51..00000000 --- a/memora-clients/python/agent_memory_api_client/models/update_personality_request.py +++ /dev/null @@ -1,69 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -if TYPE_CHECKING: - from ..models.personality_traits import PersonalityTraits - - -T = TypeVar("T", bound="UpdatePersonalityRequest") - - -@_attrs_define -class UpdatePersonalityRequest: - """Request model for updating personality traits. - - Attributes: - personality (PersonalityTraits): Personality traits based on Big Five model. Example: {'agreeableness': 0.7, - 'bias_strength': 0.7, 'conscientiousness': 0.6, 'extraversion': 0.5, 'neuroticism': 0.3, 'openness': 0.8}. - """ - - personality: PersonalityTraits - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - personality = self.personality.to_dict() - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "personality": personality, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.personality_traits import PersonalityTraits - - d = dict(src_dict) - personality = PersonalityTraits.from_dict(d.pop("personality")) - - update_personality_request = cls( - personality=personality, - ) - - update_personality_request.additional_properties = d - return update_personality_request - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/models/validation_error.py b/memora-clients/python/agent_memory_api_client/models/validation_error.py deleted file mode 100644 index cb0708f3..00000000 --- a/memora-clients/python/agent_memory_api_client/models/validation_error.py +++ /dev/null @@ -1,90 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="ValidationError") - - -@_attrs_define -class ValidationError: - """ - Attributes: - loc (list[int | str]): - msg (str): - type_ (str): - """ - - loc: list[int | str] - msg: str - type_: str - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - loc = [] - for loc_item_data in self.loc: - loc_item: int | str - loc_item = loc_item_data - loc.append(loc_item) - - msg = self.msg - - type_ = self.type_ - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "loc": loc, - "msg": msg, - "type": type_, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - loc = [] - _loc = d.pop("loc") - for loc_item_data in _loc: - - def _parse_loc_item(data: object) -> int | str: - return cast(int | str, data) - - loc_item = _parse_loc_item(loc_item_data) - - loc.append(loc_item) - - msg = d.pop("msg") - - type_ = d.pop("type") - - validation_error = cls( - loc=loc, - msg=msg, - type_=type_, - ) - - validation_error.additional_properties = d - return validation_error - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/memora-clients/python/agent_memory_api_client/types.py b/memora-clients/python/agent_memory_api_client/types.py deleted file mode 100644 index b64af095..00000000 --- a/memora-clients/python/agent_memory_api_client/types.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Contains some shared types for properties""" - -from collections.abc import Mapping, MutableMapping -from http import HTTPStatus -from typing import IO, BinaryIO, Generic, Literal, TypeVar - -from attrs import define - - -class Unset: - def __bool__(self) -> Literal[False]: - return False - - -UNSET: Unset = Unset() - -# The types that `httpx.Client(files=)` can accept, copied from that library. -FileContent = IO[bytes] | bytes | str -FileTypes = ( - # (filename, file (or bytes), content_type) - tuple[str | None, FileContent, str | None] - # (filename, file (or bytes), content_type, headers) - | tuple[str | None, FileContent, str | None, Mapping[str, str]] -) -RequestFiles = list[tuple[str, FileTypes]] - - -@define -class File: - """Contains information for file uploads""" - - payload: BinaryIO - file_name: str | None = None - mime_type: str | None = None - - def to_tuple(self) -> FileTypes: - """Return a tuple representation that httpx will accept for multipart/form-data""" - return self.file_name, self.payload, self.mime_type - - -T = TypeVar("T") - - -@define -class Response(Generic[T]): - """A response from an endpoint""" - - status_code: HTTPStatus - content: bytes - headers: MutableMapping[str, str] - parsed: T | None - - -__all__ = ["UNSET", "File", "FileTypes", "RequestFiles", "Response", "Unset"] diff --git a/memora-clients/python/memora_client/__init__.py b/memora-clients/python/memora_client/__init__.py new file mode 100644 index 00000000..e069deaa --- /dev/null +++ b/memora-clients/python/memora_client/__init__.py @@ -0,0 +1,26 @@ +""" +Memora Client - Clean, pythonic wrapper for the Memora API. + +This package provides a high-level interface for common Memora operations. +For advanced use cases, use the auto-generated API client directly. + +Example: + ```python + from memora_client import Memora + + client = Memora(base_url="http://localhost:8000") + + # Store a memory + client.put(agent_id="alice", content="Alice loves AI") + + # Search memories + results = client.search(agent_id="alice", query="What does Alice like?") + + # Generate contextual answer + answer = client.think(agent_id="alice", query="What are my interests?") + ``` +""" + +from .memora_client import Memora + +__all__ = ["Memora"] diff --git a/memora-clients/python/memora_client/memora_client.py b/memora-clients/python/memora_client/memora_client.py new file mode 100644 index 00000000..e77e0409 --- /dev/null +++ b/memora-clients/python/memora_client/memora_client.py @@ -0,0 +1,283 @@ +""" +Clean, pythonic wrapper for the Memora API client. + +This file is MAINTAINED and NOT auto-generated. It provides a high-level, +easy-to-use interface on top of the auto-generated OpenAPI client. +""" + +import asyncio +from typing import Optional, List, Dict, Any +from datetime import datetime + +import memora_client_api +from memora_client_api.api import memory_operations_api, reasoning_api, agent_management_api +from memora_client_api.models import ( + search_request, + batch_put_request, + memory_item, + think_request, +) + + +def _run_async(coro): + """Run an async coroutine synchronously.""" + try: + loop = asyncio.get_event_loop() + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + + return loop.run_until_complete(coro) + + +class Memora: + """ + High-level, easy-to-use Memora API client. + + Example: + ```python + from memora_client import Memora + + client = Memora(base_url="http://localhost:8000") + + # Store a memory + client.put(agent_id="alice", content="Alice loves AI") + + # Search memories + results = client.search(agent_id="alice", query="What does Alice like?") + + # Generate contextual answer + answer = client.think(agent_id="alice", query="What are my interests?") + ``` + """ + + def __init__(self, base_url: str, timeout: float = 30.0): + """ + Initialize the Memora client. + + Args: + base_url: The base URL of the Memora API server + timeout: Request timeout in seconds (default: 30.0) + """ + config = memora_client_api.Configuration(host=base_url) + self._api_client = memora_client_api.ApiClient(config) + self._memory_api = memory_operations_api.MemoryOperationsApi(self._api_client) + self._reasoning_api = reasoning_api.ReasoningApi(self._api_client) + self._agent_api = agent_management_api.AgentManagementApi(self._api_client) + + def __enter__(self): + """Context manager entry.""" + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + """Context manager exit.""" + self.close() + + def close(self): + """Close the API client.""" + if self._api_client: + _run_async(self._api_client.close()) + + # Simplified methods for main operations + + def put( + self, + agent_id: str, + content: str, + event_date: Optional[datetime] = None, + context: Optional[str] = None, + document_id: Optional[str] = None, + ) -> Dict[str, Any]: + """ + Store a single memory (simplified interface). + + Args: + agent_id: The agent ID + content: Memory content + event_date: Optional event timestamp + context: Optional context description + document_id: Optional document ID for grouping + + Returns: + Response with success status + """ + return self.put_batch( + agent_id=agent_id, + items=[{"content": content, "event_date": event_date, "context": context}], + document_id=document_id, + ) + + def put_batch( + self, + agent_id: str, + items: List[Dict[str, Any]], + document_id: Optional[str] = None, + ) -> Dict[str, Any]: + """ + Store multiple memories in batch. + + Args: + agent_id: The agent ID + items: List of memory items with 'content' and optional 'event_date', 'context' + document_id: Optional document ID for grouping memories + + Returns: + Response with success status and item count + """ + memory_items = [ + memory_item.MemoryItem( + content=item["content"], + event_date=item.get("event_date"), + context=item.get("context"), + ) + for item in items + ] + + request_obj = batch_put_request.BatchPutRequest( + items=memory_items, + document_id=document_id, + ) + + response = _run_async(self._memory_api.batch_put_memories(agent_id, request_obj)) + return response.to_dict() if hasattr(response, 'to_dict') else response + + def search( + self, + agent_id: str, + query: str, + fact_type: Optional[List[str]] = None, + max_tokens: int = 4096, + thinking_budget: int = 100, + ) -> List[Dict[str, Any]]: + """ + Search memories using semantic similarity. + + Args: + agent_id: The agent ID + query: Search query + fact_type: Optional list of fact types to filter (world, agent, opinion) + max_tokens: Maximum tokens in results (default: 4096) + thinking_budget: Token budget for search (default: 100) + + Returns: + List of search results + """ + request_obj = search_request.SearchRequest( + query=query, + fact_type=fact_type, + thinking_budget=thinking_budget, + max_tokens=max_tokens, + trace=False, + ) + + response = _run_async(self._memory_api.search_memories(agent_id, request_obj)) + + if hasattr(response, 'results'): + return [r.to_dict() if hasattr(r, 'to_dict') else r for r in response.results] + return [] + + def think( + self, + agent_id: str, + query: str, + thinking_budget: int = 50, + context: Optional[str] = None, + ) -> Dict[str, Any]: + """ + Generate a contextual answer based on agent identity and memories. + + Args: + agent_id: The agent ID + query: The question or prompt + thinking_budget: Token budget for thinking (default: 50) + context: Optional additional context + + Returns: + Response with answer text, facts used, and new opinions + """ + request_obj = think_request.ThinkRequest( + query=query, + thinking_budget=thinking_budget, + context=context, + ) + + response = _run_async(self._reasoning_api.think(agent_id, request_obj)) + return response.to_dict() if hasattr(response, 'to_dict') else response + + # Full-featured methods (expose more options) + + def search_memories( + self, + agent_id: str, + query: str, + fact_type: Optional[List[str]] = None, + thinking_budget: int = 100, + max_tokens: int = 4096, + trace: bool = False, + question_date: Optional[str] = None, + ) -> Dict[str, Any]: + """ + Search memories with all options (full-featured). + + Args: + agent_id: The agent ID + query: Search query + fact_type: Optional list of fact types to filter + thinking_budget: Token budget for thinking + max_tokens: Maximum tokens in results + trace: Enable trace output + question_date: Optional ISO format date string + + Returns: + Full search response with results and optional trace + """ + request_obj = search_request.SearchRequest( + query=query, + fact_type=fact_type, + thinking_budget=thinking_budget, + max_tokens=max_tokens, + trace=trace, + question_date=question_date, + ) + + response = _run_async(self._memory_api.search_memories(agent_id, request_obj)) + return response.to_dict() if hasattr(response, 'to_dict') else response + + def list_memories( + self, + agent_id: str, + fact_type: Optional[str] = None, + search_query: Optional[str] = None, + limit: int = 100, + offset: int = 0, + ) -> Dict[str, Any]: + """List memory units with pagination.""" + response = _run_async(self._memory_api.list_memories( + agent_id=agent_id, + fact_type=fact_type, + q=search_query, + limit=limit, + offset=offset, + )) + return response.to_dict() if hasattr(response, 'to_dict') else response + + def create_agent( + self, + agent_id: str, + name: Optional[str] = None, + background: Optional[str] = None, + ) -> Dict[str, Any]: + """Create or update an agent.""" + from memora_client_api.models import create_agent_request + + request_obj = create_agent_request.CreateAgentRequest( + name=name, + background=background, + ) + + response = _run_async(self._agent_api.create_or_update_agent(agent_id, request_obj)) + return response.to_dict() if hasattr(response, 'to_dict') else response + + +# Alias for backward compatibility +MemoraClient = Memora diff --git a/memora-clients/python/memora_client_api/__init__.py b/memora-clients/python/memora_client_api/__init__.py new file mode 100644 index 00000000..2088a205 --- /dev/null +++ b/memora-clients/python/memora_client_api/__init__.py @@ -0,0 +1,108 @@ +# coding: utf-8 + +# flake8: noqa + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +__version__ = "0.0.7" + +# Define package exports +__all__ = [ + "AgentManagementApi", + "DocumentsApi", + "MemoryOperationsApi", + "ReasoningApi", + "VisualizationApi", + "ApiResponse", + "ApiClient", + "Configuration", + "OpenApiException", + "ApiTypeError", + "ApiValueError", + "ApiKeyError", + "ApiAttributeError", + "ApiException", + "AddBackgroundRequest", + "AgentListItem", + "AgentListResponse", + "AgentProfileResponse", + "BackgroundResponse", + "BatchPutAsyncResponse", + "BatchPutRequest", + "BatchPutResponse", + "CreateAgentRequest", + "DeleteResponse", + "DocumentResponse", + "GraphDataResponse", + "HTTPValidationError", + "ListDocumentsResponse", + "ListMemoryUnitsResponse", + "MemoryItem", + "PersonalityTraits", + "SearchRequest", + "SearchResponse", + "SearchResult", + "ThinkFact", + "ThinkRequest", + "ThinkResponse", + "UpdatePersonalityRequest", + "ValidationError", + "ValidationErrorLocInner", +] + +# import apis into sdk package +from memora_client_api.api.agent_management_api import AgentManagementApi as AgentManagementApi +from memora_client_api.api.documents_api import DocumentsApi as DocumentsApi +from memora_client_api.api.memory_operations_api import MemoryOperationsApi as MemoryOperationsApi +from memora_client_api.api.reasoning_api import ReasoningApi as ReasoningApi +from memora_client_api.api.visualization_api import VisualizationApi as VisualizationApi + +# import ApiClient +from memora_client_api.api_response import ApiResponse as ApiResponse +from memora_client_api.api_client import ApiClient as ApiClient +from memora_client_api.configuration import Configuration as Configuration +from memora_client_api.exceptions import OpenApiException as OpenApiException +from memora_client_api.exceptions import ApiTypeError as ApiTypeError +from memora_client_api.exceptions import ApiValueError as ApiValueError +from memora_client_api.exceptions import ApiKeyError as ApiKeyError +from memora_client_api.exceptions import ApiAttributeError as ApiAttributeError +from memora_client_api.exceptions import ApiException as ApiException + +# import models into sdk package +from memora_client_api.models.add_background_request import AddBackgroundRequest as AddBackgroundRequest +from memora_client_api.models.agent_list_item import AgentListItem as AgentListItem +from memora_client_api.models.agent_list_response import AgentListResponse as AgentListResponse +from memora_client_api.models.agent_profile_response import AgentProfileResponse as AgentProfileResponse +from memora_client_api.models.background_response import BackgroundResponse as BackgroundResponse +from memora_client_api.models.batch_put_async_response import BatchPutAsyncResponse as BatchPutAsyncResponse +from memora_client_api.models.batch_put_request import BatchPutRequest as BatchPutRequest +from memora_client_api.models.batch_put_response import BatchPutResponse as BatchPutResponse +from memora_client_api.models.create_agent_request import CreateAgentRequest as CreateAgentRequest +from memora_client_api.models.delete_response import DeleteResponse as DeleteResponse +from memora_client_api.models.document_response import DocumentResponse as DocumentResponse +from memora_client_api.models.graph_data_response import GraphDataResponse as GraphDataResponse +from memora_client_api.models.http_validation_error import HTTPValidationError as HTTPValidationError +from memora_client_api.models.list_documents_response import ListDocumentsResponse as ListDocumentsResponse +from memora_client_api.models.list_memory_units_response import ListMemoryUnitsResponse as ListMemoryUnitsResponse +from memora_client_api.models.memory_item import MemoryItem as MemoryItem +from memora_client_api.models.personality_traits import PersonalityTraits as PersonalityTraits +from memora_client_api.models.search_request import SearchRequest as SearchRequest +from memora_client_api.models.search_response import SearchResponse as SearchResponse +from memora_client_api.models.search_result import SearchResult as SearchResult +from memora_client_api.models.think_fact import ThinkFact as ThinkFact +from memora_client_api.models.think_request import ThinkRequest as ThinkRequest +from memora_client_api.models.think_response import ThinkResponse as ThinkResponse +from memora_client_api.models.update_personality_request import UpdatePersonalityRequest as UpdatePersonalityRequest +from memora_client_api.models.validation_error import ValidationError as ValidationError +from memora_client_api.models.validation_error_loc_inner import ValidationErrorLocInner as ValidationErrorLocInner + diff --git a/memora-clients/python/memora_client_api/api/__init__.py b/memora-clients/python/memora_client_api/api/__init__.py new file mode 100644 index 00000000..92acbcfb --- /dev/null +++ b/memora-clients/python/memora_client_api/api/__init__.py @@ -0,0 +1,9 @@ +# flake8: noqa + +# import apis into api package +from memora_client_api.api.agent_management_api import AgentManagementApi +from memora_client_api.api.documents_api import DocumentsApi +from memora_client_api.api.memory_operations_api import MemoryOperationsApi +from memora_client_api.api.reasoning_api import ReasoningApi +from memora_client_api.api.visualization_api import VisualizationApi + diff --git a/memora-clients/python/memora_client_api/api/agent_management_api.py b/memora-clients/python/memora_client_api/api/agent_management_api.py new file mode 100644 index 00000000..11422071 --- /dev/null +++ b/memora-clients/python/memora_client_api/api/agent_management_api.py @@ -0,0 +1,1969 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import Field, StrictStr +from typing import Any, Optional +from typing_extensions import Annotated +from memora_client_api.models.add_background_request import AddBackgroundRequest +from memora_client_api.models.agent_list_response import AgentListResponse +from memora_client_api.models.agent_profile_response import AgentProfileResponse +from memora_client_api.models.background_response import BackgroundResponse +from memora_client_api.models.create_agent_request import CreateAgentRequest +from memora_client_api.models.delete_response import DeleteResponse +from memora_client_api.models.update_personality_request import UpdatePersonalityRequest + +from memora_client_api.api_client import ApiClient, RequestSerialized +from memora_client_api.api_response import ApiResponse +from memora_client_api.rest import RESTResponseType + + +class AgentManagementApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + async def add_agent_background( + self, + agent_id: StrictStr, + add_background_request: AddBackgroundRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> BackgroundResponse: + """Add/merge agent background + + Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits. + + :param agent_id: (required) + :type agent_id: str + :param add_background_request: (required) + :type add_background_request: AddBackgroundRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._add_agent_background_serialize( + agent_id=agent_id, + add_background_request=add_background_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BackgroundResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def add_agent_background_with_http_info( + self, + agent_id: StrictStr, + add_background_request: AddBackgroundRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[BackgroundResponse]: + """Add/merge agent background + + Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits. + + :param agent_id: (required) + :type agent_id: str + :param add_background_request: (required) + :type add_background_request: AddBackgroundRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._add_agent_background_serialize( + agent_id=agent_id, + add_background_request=add_background_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BackgroundResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def add_agent_background_without_preload_content( + self, + agent_id: StrictStr, + add_background_request: AddBackgroundRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Add/merge agent background + + Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits. + + :param agent_id: (required) + :type agent_id: str + :param add_background_request: (required) + :type add_background_request: AddBackgroundRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._add_agent_background_serialize( + agent_id=agent_id, + add_background_request=add_background_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BackgroundResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _add_agent_background_serialize( + self, + agent_id, + add_background_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if add_background_request is not None: + _body_params = add_background_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/api/v1/agents/{agent_id}/background', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def clear_agent_memories( + self, + agent_id: StrictStr, + fact_type: Annotated[Optional[StrictStr], Field(description="Optional fact type filter (world, agent, opinion)")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> DeleteResponse: + """Clear agent memories + + Delete memory units for an agent. Optionally filter by fact_type (world, agent, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The agent profile (personality and background) will be preserved. + + :param agent_id: (required) + :type agent_id: str + :param fact_type: Optional fact type filter (world, agent, opinion) + :type fact_type: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._clear_agent_memories_serialize( + agent_id=agent_id, + fact_type=fact_type, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "DeleteResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def clear_agent_memories_with_http_info( + self, + agent_id: StrictStr, + fact_type: Annotated[Optional[StrictStr], Field(description="Optional fact type filter (world, agent, opinion)")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[DeleteResponse]: + """Clear agent memories + + Delete memory units for an agent. Optionally filter by fact_type (world, agent, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The agent profile (personality and background) will be preserved. + + :param agent_id: (required) + :type agent_id: str + :param fact_type: Optional fact type filter (world, agent, opinion) + :type fact_type: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._clear_agent_memories_serialize( + agent_id=agent_id, + fact_type=fact_type, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "DeleteResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def clear_agent_memories_without_preload_content( + self, + agent_id: StrictStr, + fact_type: Annotated[Optional[StrictStr], Field(description="Optional fact type filter (world, agent, opinion)")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Clear agent memories + + Delete memory units for an agent. Optionally filter by fact_type (world, agent, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The agent profile (personality and background) will be preserved. + + :param agent_id: (required) + :type agent_id: str + :param fact_type: Optional fact type filter (world, agent, opinion) + :type fact_type: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._clear_agent_memories_serialize( + agent_id=agent_id, + fact_type=fact_type, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "DeleteResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _clear_agent_memories_serialize( + self, + agent_id, + fact_type, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + if fact_type is not None: + + _query_params.append(('fact_type', fact_type)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/api/v1/agents/{agent_id}/memories', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def create_or_update_agent( + self, + agent_id: StrictStr, + create_agent_request: CreateAgentRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> AgentProfileResponse: + """Create or update agent + + Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults. + + :param agent_id: (required) + :type agent_id: str + :param create_agent_request: (required) + :type create_agent_request: CreateAgentRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_or_update_agent_serialize( + agent_id=agent_id, + create_agent_request=create_agent_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentProfileResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def create_or_update_agent_with_http_info( + self, + agent_id: StrictStr, + create_agent_request: CreateAgentRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[AgentProfileResponse]: + """Create or update agent + + Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults. + + :param agent_id: (required) + :type agent_id: str + :param create_agent_request: (required) + :type create_agent_request: CreateAgentRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_or_update_agent_serialize( + agent_id=agent_id, + create_agent_request=create_agent_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentProfileResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def create_or_update_agent_without_preload_content( + self, + agent_id: StrictStr, + create_agent_request: CreateAgentRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create or update agent + + Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults. + + :param agent_id: (required) + :type agent_id: str + :param create_agent_request: (required) + :type create_agent_request: CreateAgentRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_or_update_agent_serialize( + agent_id=agent_id, + create_agent_request=create_agent_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentProfileResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_or_update_agent_serialize( + self, + agent_id, + create_agent_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if create_agent_request is not None: + _body_params = create_agent_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='PUT', + resource_path='/api/v1/agents/{agent_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def get_agent_profile( + self, + agent_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> AgentProfileResponse: + """Get agent profile + + Get personality traits and background for an agent. Auto-creates agent with defaults if not exists. + + :param agent_id: (required) + :type agent_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_agent_profile_serialize( + agent_id=agent_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentProfileResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def get_agent_profile_with_http_info( + self, + agent_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[AgentProfileResponse]: + """Get agent profile + + Get personality traits and background for an agent. Auto-creates agent with defaults if not exists. + + :param agent_id: (required) + :type agent_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_agent_profile_serialize( + agent_id=agent_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentProfileResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def get_agent_profile_without_preload_content( + self, + agent_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get agent profile + + Get personality traits and background for an agent. Auto-creates agent with defaults if not exists. + + :param agent_id: (required) + :type agent_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_agent_profile_serialize( + agent_id=agent_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentProfileResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_agent_profile_serialize( + self, + agent_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/api/v1/agents/{agent_id}/profile', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def get_agent_stats( + self, + agent_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Get memory statistics for an agent + + Get statistics about nodes and links for a specific agent + + :param agent_id: (required) + :type agent_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_agent_stats_serialize( + agent_id=agent_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def get_agent_stats_with_http_info( + self, + agent_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Get memory statistics for an agent + + Get statistics about nodes and links for a specific agent + + :param agent_id: (required) + :type agent_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_agent_stats_serialize( + agent_id=agent_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def get_agent_stats_without_preload_content( + self, + agent_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get memory statistics for an agent + + Get statistics about nodes and links for a specific agent + + :param agent_id: (required) + :type agent_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_agent_stats_serialize( + agent_id=agent_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_agent_stats_serialize( + self, + agent_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/api/v1/agents/{agent_id}/stats', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def list_agents( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> AgentListResponse: + """List all agents + + Get a list of all agents with their profiles + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_agents_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentListResponse", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def list_agents_with_http_info( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[AgentListResponse]: + """List all agents + + Get a list of all agents with their profiles + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_agents_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentListResponse", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def list_agents_without_preload_content( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List all agents + + Get a list of all agents with their profiles + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_agents_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentListResponse", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_agents_serialize( + self, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/api/v1/agents', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def update_agent_personality( + self, + agent_id: StrictStr, + update_personality_request: UpdatePersonalityRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> AgentProfileResponse: + """Update agent personality + + Update agent's Big Five personality traits and bias strength + + :param agent_id: (required) + :type agent_id: str + :param update_personality_request: (required) + :type update_personality_request: UpdatePersonalityRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_agent_personality_serialize( + agent_id=agent_id, + update_personality_request=update_personality_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentProfileResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def update_agent_personality_with_http_info( + self, + agent_id: StrictStr, + update_personality_request: UpdatePersonalityRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[AgentProfileResponse]: + """Update agent personality + + Update agent's Big Five personality traits and bias strength + + :param agent_id: (required) + :type agent_id: str + :param update_personality_request: (required) + :type update_personality_request: UpdatePersonalityRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_agent_personality_serialize( + agent_id=agent_id, + update_personality_request=update_personality_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentProfileResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def update_agent_personality_without_preload_content( + self, + agent_id: StrictStr, + update_personality_request: UpdatePersonalityRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update agent personality + + Update agent's Big Five personality traits and bias strength + + :param agent_id: (required) + :type agent_id: str + :param update_personality_request: (required) + :type update_personality_request: UpdatePersonalityRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_agent_personality_serialize( + agent_id=agent_id, + update_personality_request=update_personality_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AgentProfileResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _update_agent_personality_serialize( + self, + agent_id, + update_personality_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if update_personality_request is not None: + _body_params = update_personality_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='PUT', + resource_path='/api/v1/agents/{agent_id}/profile', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/memora-clients/python/memora_client_api/api/documents_api.py b/memora-clients/python/memora_client_api/api/documents_api.py new file mode 100644 index 00000000..77ca3a6e --- /dev/null +++ b/memora-clients/python/memora_client_api/api/documents_api.py @@ -0,0 +1,909 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import StrictInt, StrictStr +from typing import Any, Optional +from memora_client_api.models.document_response import DocumentResponse +from memora_client_api.models.list_documents_response import ListDocumentsResponse + +from memora_client_api.api_client import ApiClient, RequestSerialized +from memora_client_api.api_response import ApiResponse +from memora_client_api.rest import RESTResponseType + + +class DocumentsApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + async def delete_document( + self, + agent_id: StrictStr, + document_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Delete a document + + Delete a document and all its associated memory units and links. This will cascade delete: - The document itself - All memory units extracted from this document - All links (temporal, semantic, entity) associated with those memory units This operation cannot be undone. + + :param agent_id: (required) + :type agent_id: str + :param document_id: (required) + :type document_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_document_serialize( + agent_id=agent_id, + document_id=document_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def delete_document_with_http_info( + self, + agent_id: StrictStr, + document_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Delete a document + + Delete a document and all its associated memory units and links. This will cascade delete: - The document itself - All memory units extracted from this document - All links (temporal, semantic, entity) associated with those memory units This operation cannot be undone. + + :param agent_id: (required) + :type agent_id: str + :param document_id: (required) + :type document_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_document_serialize( + agent_id=agent_id, + document_id=document_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def delete_document_without_preload_content( + self, + agent_id: StrictStr, + document_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete a document + + Delete a document and all its associated memory units and links. This will cascade delete: - The document itself - All memory units extracted from this document - All links (temporal, semantic, entity) associated with those memory units This operation cannot be undone. + + :param agent_id: (required) + :type agent_id: str + :param document_id: (required) + :type document_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_document_serialize( + agent_id=agent_id, + document_id=document_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_document_serialize( + self, + agent_id, + document_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + if document_id is not None: + _path_params['document_id'] = document_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/api/v1/agents/{agent_id}/documents/{document_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def get_document( + self, + agent_id: StrictStr, + document_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> DocumentResponse: + """Get document details + + Get a specific document including its original text + + :param agent_id: (required) + :type agent_id: str + :param document_id: (required) + :type document_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_document_serialize( + agent_id=agent_id, + document_id=document_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "DocumentResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def get_document_with_http_info( + self, + agent_id: StrictStr, + document_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[DocumentResponse]: + """Get document details + + Get a specific document including its original text + + :param agent_id: (required) + :type agent_id: str + :param document_id: (required) + :type document_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_document_serialize( + agent_id=agent_id, + document_id=document_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "DocumentResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def get_document_without_preload_content( + self, + agent_id: StrictStr, + document_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get document details + + Get a specific document including its original text + + :param agent_id: (required) + :type agent_id: str + :param document_id: (required) + :type document_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_document_serialize( + agent_id=agent_id, + document_id=document_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "DocumentResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_document_serialize( + self, + agent_id, + document_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + if document_id is not None: + _path_params['document_id'] = document_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/api/v1/agents/{agent_id}/documents/{document_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def list_documents( + self, + agent_id: StrictStr, + q: Optional[StrictStr] = None, + limit: Optional[StrictInt] = None, + offset: Optional[StrictInt] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ListDocumentsResponse: + """List documents + + List documents with pagination and optional search. Documents are the source content from which memory units are extracted. + + :param agent_id: (required) + :type agent_id: str + :param q: + :type q: str + :param limit: + :type limit: int + :param offset: + :type offset: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_documents_serialize( + agent_id=agent_id, + q=q, + limit=limit, + offset=offset, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ListDocumentsResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def list_documents_with_http_info( + self, + agent_id: StrictStr, + q: Optional[StrictStr] = None, + limit: Optional[StrictInt] = None, + offset: Optional[StrictInt] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ListDocumentsResponse]: + """List documents + + List documents with pagination and optional search. Documents are the source content from which memory units are extracted. + + :param agent_id: (required) + :type agent_id: str + :param q: + :type q: str + :param limit: + :type limit: int + :param offset: + :type offset: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_documents_serialize( + agent_id=agent_id, + q=q, + limit=limit, + offset=offset, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ListDocumentsResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def list_documents_without_preload_content( + self, + agent_id: StrictStr, + q: Optional[StrictStr] = None, + limit: Optional[StrictInt] = None, + offset: Optional[StrictInt] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List documents + + List documents with pagination and optional search. Documents are the source content from which memory units are extracted. + + :param agent_id: (required) + :type agent_id: str + :param q: + :type q: str + :param limit: + :type limit: int + :param offset: + :type offset: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_documents_serialize( + agent_id=agent_id, + q=q, + limit=limit, + offset=offset, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ListDocumentsResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_documents_serialize( + self, + agent_id, + q, + limit, + offset, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + if q is not None: + + _query_params.append(('q', q)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + if offset is not None: + + _query_params.append(('offset', offset)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/api/v1/agents/{agent_id}/documents', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/memora-clients/python/memora_client_api/api/memory_operations_api.py b/memora-clients/python/memora_client_api/api/memory_operations_api.py new file mode 100644 index 00000000..6cb54766 --- /dev/null +++ b/memora-clients/python/memora_client_api/api/memory_operations_api.py @@ -0,0 +1,2066 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import StrictInt, StrictStr +from typing import Any, Optional +from memora_client_api.models.batch_put_async_response import BatchPutAsyncResponse +from memora_client_api.models.batch_put_request import BatchPutRequest +from memora_client_api.models.batch_put_response import BatchPutResponse +from memora_client_api.models.list_memory_units_response import ListMemoryUnitsResponse +from memora_client_api.models.search_request import SearchRequest +from memora_client_api.models.search_response import SearchResponse + +from memora_client_api.api_client import ApiClient, RequestSerialized +from memora_client_api.api_response import ApiResponse +from memora_client_api.rest import RESTResponseType + + +class MemoryOperationsApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + async def batch_put_async( + self, + agent_id: StrictStr, + batch_put_request: BatchPutRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> BatchPutAsyncResponse: + """Store multiple memories asynchronously + + Store multiple memory items in batch asynchronously using the task backend. This endpoint returns immediately after queuing the task, without waiting for completion. The actual processing happens in the background. Features: - Immediate response (non-blocking) - Background processing via task queue - Efficient batch processing - Automatic fact extraction from natural language - Entity recognition and linking - Document tracking with automatic upsert (when document_id is provided) - Temporal and semantic linking The system automatically: 1. Queues the batch put task 2. Returns immediately with success=True, queued=True 3. Processes in background: extracts facts, generates embeddings, creates links Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). + + :param agent_id: (required) + :type agent_id: str + :param batch_put_request: (required) + :type batch_put_request: BatchPutRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._batch_put_async_serialize( + agent_id=agent_id, + batch_put_request=batch_put_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BatchPutAsyncResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def batch_put_async_with_http_info( + self, + agent_id: StrictStr, + batch_put_request: BatchPutRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[BatchPutAsyncResponse]: + """Store multiple memories asynchronously + + Store multiple memory items in batch asynchronously using the task backend. This endpoint returns immediately after queuing the task, without waiting for completion. The actual processing happens in the background. Features: - Immediate response (non-blocking) - Background processing via task queue - Efficient batch processing - Automatic fact extraction from natural language - Entity recognition and linking - Document tracking with automatic upsert (when document_id is provided) - Temporal and semantic linking The system automatically: 1. Queues the batch put task 2. Returns immediately with success=True, queued=True 3. Processes in background: extracts facts, generates embeddings, creates links Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). + + :param agent_id: (required) + :type agent_id: str + :param batch_put_request: (required) + :type batch_put_request: BatchPutRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._batch_put_async_serialize( + agent_id=agent_id, + batch_put_request=batch_put_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BatchPutAsyncResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def batch_put_async_without_preload_content( + self, + agent_id: StrictStr, + batch_put_request: BatchPutRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Store multiple memories asynchronously + + Store multiple memory items in batch asynchronously using the task backend. This endpoint returns immediately after queuing the task, without waiting for completion. The actual processing happens in the background. Features: - Immediate response (non-blocking) - Background processing via task queue - Efficient batch processing - Automatic fact extraction from natural language - Entity recognition and linking - Document tracking with automatic upsert (when document_id is provided) - Temporal and semantic linking The system automatically: 1. Queues the batch put task 2. Returns immediately with success=True, queued=True 3. Processes in background: extracts facts, generates embeddings, creates links Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). + + :param agent_id: (required) + :type agent_id: str + :param batch_put_request: (required) + :type batch_put_request: BatchPutRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._batch_put_async_serialize( + agent_id=agent_id, + batch_put_request=batch_put_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BatchPutAsyncResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _batch_put_async_serialize( + self, + agent_id, + batch_put_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if batch_put_request is not None: + _body_params = batch_put_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/api/v1/agents/{agent_id}/memories/async', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def batch_put_memories( + self, + agent_id: StrictStr, + batch_put_request: BatchPutRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> BatchPutResponse: + """Store multiple memories + + Store multiple memory items in batch with automatic fact extraction. Features: - Efficient batch processing - Automatic fact extraction from natural language - Entity recognition and linking - Document tracking with automatic upsert (when document_id is provided) - Temporal and semantic linking The system automatically: 1. Extracts semantic facts from the content 2. Generates embeddings 3. Deduplicates similar facts 4. Creates temporal, semantic, and entity links 5. Tracks document metadata Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). + + :param agent_id: (required) + :type agent_id: str + :param batch_put_request: (required) + :type batch_put_request: BatchPutRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._batch_put_memories_serialize( + agent_id=agent_id, + batch_put_request=batch_put_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BatchPutResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def batch_put_memories_with_http_info( + self, + agent_id: StrictStr, + batch_put_request: BatchPutRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[BatchPutResponse]: + """Store multiple memories + + Store multiple memory items in batch with automatic fact extraction. Features: - Efficient batch processing - Automatic fact extraction from natural language - Entity recognition and linking - Document tracking with automatic upsert (when document_id is provided) - Temporal and semantic linking The system automatically: 1. Extracts semantic facts from the content 2. Generates embeddings 3. Deduplicates similar facts 4. Creates temporal, semantic, and entity links 5. Tracks document metadata Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). + + :param agent_id: (required) + :type agent_id: str + :param batch_put_request: (required) + :type batch_put_request: BatchPutRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._batch_put_memories_serialize( + agent_id=agent_id, + batch_put_request=batch_put_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BatchPutResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def batch_put_memories_without_preload_content( + self, + agent_id: StrictStr, + batch_put_request: BatchPutRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Store multiple memories + + Store multiple memory items in batch with automatic fact extraction. Features: - Efficient batch processing - Automatic fact extraction from natural language - Entity recognition and linking - Document tracking with automatic upsert (when document_id is provided) - Temporal and semantic linking The system automatically: 1. Extracts semantic facts from the content 2. Generates embeddings 3. Deduplicates similar facts 4. Creates temporal, semantic, and entity links 5. Tracks document metadata Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). + + :param agent_id: (required) + :type agent_id: str + :param batch_put_request: (required) + :type batch_put_request: BatchPutRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._batch_put_memories_serialize( + agent_id=agent_id, + batch_put_request=batch_put_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BatchPutResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _batch_put_memories_serialize( + self, + agent_id, + batch_put_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if batch_put_request is not None: + _body_params = batch_put_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/api/v1/agents/{agent_id}/memories', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def cancel_operation( + self, + agent_id: StrictStr, + operation_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Cancel a pending async operation + + Cancel a pending async operation by removing it from the queue + + :param agent_id: (required) + :type agent_id: str + :param operation_id: (required) + :type operation_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._cancel_operation_serialize( + agent_id=agent_id, + operation_id=operation_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def cancel_operation_with_http_info( + self, + agent_id: StrictStr, + operation_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Cancel a pending async operation + + Cancel a pending async operation by removing it from the queue + + :param agent_id: (required) + :type agent_id: str + :param operation_id: (required) + :type operation_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._cancel_operation_serialize( + agent_id=agent_id, + operation_id=operation_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def cancel_operation_without_preload_content( + self, + agent_id: StrictStr, + operation_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Cancel a pending async operation + + Cancel a pending async operation by removing it from the queue + + :param agent_id: (required) + :type agent_id: str + :param operation_id: (required) + :type operation_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._cancel_operation_serialize( + agent_id=agent_id, + operation_id=operation_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _cancel_operation_serialize( + self, + agent_id, + operation_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + if operation_id is not None: + _path_params['operation_id'] = operation_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/api/v1/agents/{agent_id}/operations/{operation_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def delete_memory_unit( + self, + agent_id: StrictStr, + unit_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """Delete a memory unit + + Delete a single memory unit and all its associated links (temporal, semantic, and entity links) + + :param agent_id: (required) + :type agent_id: str + :param unit_id: (required) + :type unit_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_memory_unit_serialize( + agent_id=agent_id, + unit_id=unit_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def delete_memory_unit_with_http_info( + self, + agent_id: StrictStr, + unit_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """Delete a memory unit + + Delete a single memory unit and all its associated links (temporal, semantic, and entity links) + + :param agent_id: (required) + :type agent_id: str + :param unit_id: (required) + :type unit_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_memory_unit_serialize( + agent_id=agent_id, + unit_id=unit_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def delete_memory_unit_without_preload_content( + self, + agent_id: StrictStr, + unit_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete a memory unit + + Delete a single memory unit and all its associated links (temporal, semantic, and entity links) + + :param agent_id: (required) + :type agent_id: str + :param unit_id: (required) + :type unit_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_memory_unit_serialize( + agent_id=agent_id, + unit_id=unit_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_memory_unit_serialize( + self, + agent_id, + unit_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + if unit_id is not None: + _path_params['unit_id'] = unit_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/api/v1/agents/{agent_id}/memories/{unit_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def list_memories( + self, + agent_id: StrictStr, + fact_type: Optional[StrictStr] = None, + q: Optional[StrictStr] = None, + limit: Optional[StrictInt] = None, + offset: Optional[StrictInt] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ListMemoryUnitsResponse: + """List memory units + + List memory units with pagination and optional full-text search. Supports filtering by fact_type. + + :param agent_id: (required) + :type agent_id: str + :param fact_type: + :type fact_type: str + :param q: + :type q: str + :param limit: + :type limit: int + :param offset: + :type offset: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_memories_serialize( + agent_id=agent_id, + fact_type=fact_type, + q=q, + limit=limit, + offset=offset, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ListMemoryUnitsResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def list_memories_with_http_info( + self, + agent_id: StrictStr, + fact_type: Optional[StrictStr] = None, + q: Optional[StrictStr] = None, + limit: Optional[StrictInt] = None, + offset: Optional[StrictInt] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ListMemoryUnitsResponse]: + """List memory units + + List memory units with pagination and optional full-text search. Supports filtering by fact_type. + + :param agent_id: (required) + :type agent_id: str + :param fact_type: + :type fact_type: str + :param q: + :type q: str + :param limit: + :type limit: int + :param offset: + :type offset: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_memories_serialize( + agent_id=agent_id, + fact_type=fact_type, + q=q, + limit=limit, + offset=offset, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ListMemoryUnitsResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def list_memories_without_preload_content( + self, + agent_id: StrictStr, + fact_type: Optional[StrictStr] = None, + q: Optional[StrictStr] = None, + limit: Optional[StrictInt] = None, + offset: Optional[StrictInt] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List memory units + + List memory units with pagination and optional full-text search. Supports filtering by fact_type. + + :param agent_id: (required) + :type agent_id: str + :param fact_type: + :type fact_type: str + :param q: + :type q: str + :param limit: + :type limit: int + :param offset: + :type offset: int + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_memories_serialize( + agent_id=agent_id, + fact_type=fact_type, + q=q, + limit=limit, + offset=offset, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ListMemoryUnitsResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_memories_serialize( + self, + agent_id, + fact_type, + q, + limit, + offset, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + if fact_type is not None: + + _query_params.append(('fact_type', fact_type)) + + if q is not None: + + _query_params.append(('q', q)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + if offset is not None: + + _query_params.append(('offset', offset)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/api/v1/agents/{agent_id}/memories/list', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def list_operations( + self, + agent_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> object: + """List async operations + + Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations + + :param agent_id: (required) + :type agent_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_operations_serialize( + agent_id=agent_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def list_operations_with_http_info( + self, + agent_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[object]: + """List async operations + + Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations + + :param agent_id: (required) + :type agent_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_operations_serialize( + agent_id=agent_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def list_operations_without_preload_content( + self, + agent_id: StrictStr, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List async operations + + Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations + + :param agent_id: (required) + :type agent_id: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_operations_serialize( + agent_id=agent_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "object", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_operations_serialize( + self, + agent_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/api/v1/agents/{agent_id}/operations', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + async def search_memories( + self, + agent_id: StrictStr, + search_request: SearchRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> SearchResponse: + """Search memory + + Search memory using semantic similarity and spreading activation. The fact_type parameter is optional and must be one of: - 'world': General knowledge about people, places, events, and things that happen - 'agent': Memories about what the AI agent did, actions taken, and tasks performed - 'opinion': The agent's formed beliefs, perspectives, and viewpoints + + :param agent_id: (required) + :type agent_id: str + :param search_request: (required) + :type search_request: SearchRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._search_memories_serialize( + agent_id=agent_id, + search_request=search_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SearchResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def search_memories_with_http_info( + self, + agent_id: StrictStr, + search_request: SearchRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[SearchResponse]: + """Search memory + + Search memory using semantic similarity and spreading activation. The fact_type parameter is optional and must be one of: - 'world': General knowledge about people, places, events, and things that happen - 'agent': Memories about what the AI agent did, actions taken, and tasks performed - 'opinion': The agent's formed beliefs, perspectives, and viewpoints + + :param agent_id: (required) + :type agent_id: str + :param search_request: (required) + :type search_request: SearchRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._search_memories_serialize( + agent_id=agent_id, + search_request=search_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SearchResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def search_memories_without_preload_content( + self, + agent_id: StrictStr, + search_request: SearchRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Search memory + + Search memory using semantic similarity and spreading activation. The fact_type parameter is optional and must be one of: - 'world': General knowledge about people, places, events, and things that happen - 'agent': Memories about what the AI agent did, actions taken, and tasks performed - 'opinion': The agent's formed beliefs, perspectives, and viewpoints + + :param agent_id: (required) + :type agent_id: str + :param search_request: (required) + :type search_request: SearchRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._search_memories_serialize( + agent_id=agent_id, + search_request=search_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SearchResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _search_memories_serialize( + self, + agent_id, + search_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if search_request is not None: + _body_params = search_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/api/v1/agents/{agent_id}/memories/search', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/memora-clients/python/memora_client_api/api/reasoning_api.py b/memora-clients/python/memora_client_api/api/reasoning_api.py new file mode 100644 index 00000000..110d7087 --- /dev/null +++ b/memora-clients/python/memora_client_api/api/reasoning_api.py @@ -0,0 +1,329 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import StrictStr +from memora_client_api.models.think_request import ThinkRequest +from memora_client_api.models.think_response import ThinkResponse + +from memora_client_api.api_client import ApiClient, RequestSerialized +from memora_client_api.api_response import ApiResponse +from memora_client_api.rest import RESTResponseType + + +class ReasoningApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + async def think( + self, + agent_id: StrictStr, + think_request: ThinkRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ThinkResponse: + """Think and generate answer + + Think and formulate an answer using agent identity, world facts, and opinions. This endpoint: 1. Retrieves agent facts (agent's identity) 2. Retrieves world facts relevant to the query 3. Retrieves existing opinions (agent's perspectives) 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions + + :param agent_id: (required) + :type agent_id: str + :param think_request: (required) + :type think_request: ThinkRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._think_serialize( + agent_id=agent_id, + think_request=think_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ThinkResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def think_with_http_info( + self, + agent_id: StrictStr, + think_request: ThinkRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[ThinkResponse]: + """Think and generate answer + + Think and formulate an answer using agent identity, world facts, and opinions. This endpoint: 1. Retrieves agent facts (agent's identity) 2. Retrieves world facts relevant to the query 3. Retrieves existing opinions (agent's perspectives) 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions + + :param agent_id: (required) + :type agent_id: str + :param think_request: (required) + :type think_request: ThinkRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._think_serialize( + agent_id=agent_id, + think_request=think_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ThinkResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def think_without_preload_content( + self, + agent_id: StrictStr, + think_request: ThinkRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Think and generate answer + + Think and formulate an answer using agent identity, world facts, and opinions. This endpoint: 1. Retrieves agent facts (agent's identity) 2. Retrieves world facts relevant to the query 3. Retrieves existing opinions (agent's perspectives) 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions + + :param agent_id: (required) + :type agent_id: str + :param think_request: (required) + :type think_request: ThinkRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._think_serialize( + agent_id=agent_id, + think_request=think_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "ThinkResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _think_serialize( + self, + agent_id, + think_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if think_request is not None: + _body_params = think_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/api/v1/agents/{agent_id}/think', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/memora-clients/python/memora_client_api/api/visualization_api.py b/memora-clients/python/memora_client_api/api/visualization_api.py new file mode 100644 index 00000000..89c0a20f --- /dev/null +++ b/memora-clients/python/memora_client_api/api/visualization_api.py @@ -0,0 +1,318 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import StrictStr +from typing import Optional +from memora_client_api.models.graph_data_response import GraphDataResponse + +from memora_client_api.api_client import ApiClient, RequestSerialized +from memora_client_api.api_response import ApiResponse +from memora_client_api.rest import RESTResponseType + + +class VisualizationApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + async def get_graph( + self, + agent_id: StrictStr, + fact_type: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> GraphDataResponse: + """Get memory graph data + + Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). Limited to 1000 most recent items. + + :param agent_id: (required) + :type agent_id: str + :param fact_type: + :type fact_type: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_graph_serialize( + agent_id=agent_id, + fact_type=fact_type, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "GraphDataResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + async def get_graph_with_http_info( + self, + agent_id: StrictStr, + fact_type: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[GraphDataResponse]: + """Get memory graph data + + Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). Limited to 1000 most recent items. + + :param agent_id: (required) + :type agent_id: str + :param fact_type: + :type fact_type: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_graph_serialize( + agent_id=agent_id, + fact_type=fact_type, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "GraphDataResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + await response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + async def get_graph_without_preload_content( + self, + agent_id: StrictStr, + fact_type: Optional[StrictStr] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get memory graph data + + Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). Limited to 1000 most recent items. + + :param agent_id: (required) + :type agent_id: str + :param fact_type: + :type fact_type: str + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_graph_serialize( + agent_id=agent_id, + fact_type=fact_type, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "GraphDataResponse", + '422': "HTTPValidationError", + } + response_data = await self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_graph_serialize( + self, + agent_id, + fact_type, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if agent_id is not None: + _path_params['agent_id'] = agent_id + # process the query parameters + if fact_type is not None: + + _query_params.append(('fact_type', fact_type)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/api/v1/agents/{agent_id}/graph', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/memora-clients/python/memora_client_api/api_client.py b/memora-clients/python/memora_client_api/api_client.py new file mode 100644 index 00000000..42c6a20e --- /dev/null +++ b/memora-clients/python/memora_client_api/api_client.py @@ -0,0 +1,807 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import datetime +from dateutil.parser import parse +from enum import Enum +import decimal +import json +import mimetypes +import os +import re +import tempfile +import uuid + +from urllib.parse import quote +from typing import Tuple, Optional, List, Dict, Union +from pydantic import SecretStr + +from memora_client_api.configuration import Configuration +from memora_client_api.api_response import ApiResponse, T as ApiResponseT +import memora_client_api.models +from memora_client_api import rest +from memora_client_api.exceptions import ( + ApiValueError, + ApiException, + BadRequestException, + UnauthorizedException, + ForbiddenException, + NotFoundException, + ServiceException +) + +RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]] + +class ApiClient: + """Generic API client for OpenAPI client library builds. + + OpenAPI generic API client. This client handles the client- + server communication, and is invariant across implementations. Specifics of + the methods and models for each application are generated from the OpenAPI + templates. + + :param configuration: .Configuration object for this client + :param header_name: a header to pass when making calls to the API. + :param header_value: a header value to pass when making calls to + the API. + :param cookie: a cookie to include in the header when making calls + to the API + """ + + PRIMITIVE_TYPES = (float, bool, bytes, str, int) + NATIVE_TYPES_MAPPING = { + 'int': int, + 'long': int, # TODO remove as only py3 is supported? + 'float': float, + 'str': str, + 'bool': bool, + 'date': datetime.date, + 'datetime': datetime.datetime, + 'decimal': decimal.Decimal, + 'object': object, + } + _pool = None + + def __init__( + self, + configuration=None, + header_name=None, + header_value=None, + cookie=None + ) -> None: + # use default configuration if none is provided + if configuration is None: + configuration = Configuration.get_default() + self.configuration = configuration + + self.rest_client = rest.RESTClientObject(configuration) + self.default_headers = {} + if header_name is not None: + self.default_headers[header_name] = header_value + self.cookie = cookie + # Set default User-Agent. + self.user_agent = 'OpenAPI-Generator/0.0.7/python' + self.client_side_validation = configuration.client_side_validation + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc_value, traceback): + await self.close() + + async def close(self): + await self.rest_client.close() + + @property + def user_agent(self): + """User agent for this API client""" + return self.default_headers['User-Agent'] + + @user_agent.setter + def user_agent(self, value): + self.default_headers['User-Agent'] = value + + def set_default_header(self, header_name, header_value): + self.default_headers[header_name] = header_value + + + _default = None + + @classmethod + def get_default(cls): + """Return new instance of ApiClient. + + This method returns newly created, based on default constructor, + object of ApiClient class or returns a copy of default + ApiClient. + + :return: The ApiClient object. + """ + if cls._default is None: + cls._default = ApiClient() + return cls._default + + @classmethod + def set_default(cls, default): + """Set default instance of ApiClient. + + It stores default ApiClient. + + :param default: object of ApiClient. + """ + cls._default = default + + def param_serialize( + self, + method, + resource_path, + path_params=None, + query_params=None, + header_params=None, + body=None, + post_params=None, + files=None, auth_settings=None, + collection_formats=None, + _host=None, + _request_auth=None + ) -> RequestSerialized: + + """Builds the HTTP request params needed by the request. + :param method: Method to call. + :param resource_path: Path to method endpoint. + :param path_params: Path parameters in the url. + :param query_params: Query parameters in the url. + :param header_params: Header parameters to be + placed in the request header. + :param body: Request body. + :param post_params dict: Request post form parameters, + for `application/x-www-form-urlencoded`, `multipart/form-data`. + :param auth_settings list: Auth Settings names for the request. + :param files dict: key -> filename, value -> filepath, + for `multipart/form-data`. + :param collection_formats: dict of collection formats for path, query, + header, and post parameters. + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the authentication + in the spec for a single request. + :return: tuple of form (path, http_method, query_params, header_params, + body, post_params, files) + """ + + config = self.configuration + + # header parameters + header_params = header_params or {} + header_params.update(self.default_headers) + if self.cookie: + header_params['Cookie'] = self.cookie + if header_params: + header_params = self.sanitize_for_serialization(header_params) + header_params = dict( + self.parameters_to_tuples(header_params,collection_formats) + ) + + # path parameters + if path_params: + path_params = self.sanitize_for_serialization(path_params) + path_params = self.parameters_to_tuples( + path_params, + collection_formats + ) + for k, v in path_params: + # specified safe chars, encode everything + resource_path = resource_path.replace( + '{%s}' % k, + quote(str(v), safe=config.safe_chars_for_path_param) + ) + + # post parameters + if post_params or files: + post_params = post_params if post_params else [] + post_params = self.sanitize_for_serialization(post_params) + post_params = self.parameters_to_tuples( + post_params, + collection_formats + ) + if files: + post_params.extend(self.files_parameters(files)) + + # auth setting + self.update_params_for_auth( + header_params, + query_params, + auth_settings, + resource_path, + method, + body, + request_auth=_request_auth + ) + + # body + if body: + body = self.sanitize_for_serialization(body) + + # request url + if _host is None or self.configuration.ignore_operation_servers: + url = self.configuration.host + resource_path + else: + # use server/host defined in path or operation instead + url = _host + resource_path + + # query parameters + if query_params: + query_params = self.sanitize_for_serialization(query_params) + url_query = self.parameters_to_url_query( + query_params, + collection_formats + ) + url += "?" + url_query + + return method, url, header_params, body, post_params + + + async def call_api( + self, + method, + url, + header_params=None, + body=None, + post_params=None, + _request_timeout=None + ) -> rest.RESTResponse: + """Makes the HTTP request (synchronous) + :param method: Method to call. + :param url: Path to method endpoint. + :param header_params: Header parameters to be + placed in the request header. + :param body: Request body. + :param post_params dict: Request post form parameters, + for `application/x-www-form-urlencoded`, `multipart/form-data`. + :param _request_timeout: timeout setting for this request. + :return: RESTResponse + """ + + try: + # perform request and return response + response_data = await self.rest_client.request( + method, url, + headers=header_params, + body=body, post_params=post_params, + _request_timeout=_request_timeout + ) + + except ApiException as e: + raise e + + return response_data + + def response_deserialize( + self, + response_data: rest.RESTResponse, + response_types_map: Optional[Dict[str, ApiResponseT]]=None + ) -> ApiResponse[ApiResponseT]: + """Deserializes response into an object. + :param response_data: RESTResponse object to be deserialized. + :param response_types_map: dict of response types. + :return: ApiResponse + """ + + msg = "RESTResponse.read() must be called before passing it to response_deserialize()" + assert response_data.data is not None, msg + + response_type = response_types_map.get(str(response_data.status), None) + if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599: + # if not found, look for '1XX', '2XX', etc. + response_type = response_types_map.get(str(response_data.status)[0] + "XX", None) + + # deserialize response data + response_text = None + return_data = None + try: + if response_type == "bytearray": + return_data = response_data.data + elif response_type == "file": + return_data = self.__deserialize_file(response_data) + elif response_type is not None: + match = None + content_type = response_data.getheader('content-type') + if content_type is not None: + match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type) + encoding = match.group(1) if match else "utf-8" + response_text = response_data.data.decode(encoding) + return_data = self.deserialize(response_text, response_type, content_type) + finally: + if not 200 <= response_data.status <= 299: + raise ApiException.from_response( + http_resp=response_data, + body=response_text, + data=return_data, + ) + + return ApiResponse( + status_code = response_data.status, + data = return_data, + headers = response_data.getheaders(), + raw_data = response_data.data + ) + + def sanitize_for_serialization(self, obj): + """Builds a JSON POST object. + + If obj is None, return None. + If obj is SecretStr, return obj.get_secret_value() + If obj is str, int, long, float, bool, return directly. + If obj is datetime.datetime, datetime.date + convert to string in iso8601 format. + If obj is decimal.Decimal return string representation. + If obj is list, sanitize each element in the list. + If obj is dict, return the dict. + If obj is OpenAPI model, return the properties dict. + + :param obj: The data to serialize. + :return: The serialized form of data. + """ + if obj is None: + return None + elif isinstance(obj, Enum): + return obj.value + elif isinstance(obj, SecretStr): + return obj.get_secret_value() + elif isinstance(obj, self.PRIMITIVE_TYPES): + return obj + elif isinstance(obj, uuid.UUID): + return str(obj) + elif isinstance(obj, list): + return [ + self.sanitize_for_serialization(sub_obj) for sub_obj in obj + ] + elif isinstance(obj, tuple): + return tuple( + self.sanitize_for_serialization(sub_obj) for sub_obj in obj + ) + elif isinstance(obj, (datetime.datetime, datetime.date)): + return obj.isoformat() + elif isinstance(obj, decimal.Decimal): + return str(obj) + + elif isinstance(obj, dict): + obj_dict = obj + else: + # Convert model obj to dict except + # attributes `openapi_types`, `attribute_map` + # and attributes which value is not None. + # Convert attribute name to json key in + # model definition for request. + if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): + obj_dict = obj.to_dict() + else: + obj_dict = obj.__dict__ + + if isinstance(obj_dict, list): + # here we handle instances that can either be a list or something else, and only became a real list by calling to_dict() + return self.sanitize_for_serialization(obj_dict) + + return { + key: self.sanitize_for_serialization(val) + for key, val in obj_dict.items() + } + + def deserialize(self, response_text: str, response_type: str, content_type: Optional[str]): + """Deserializes response into an object. + + :param response: RESTResponse object to be deserialized. + :param response_type: class literal for + deserialized object, or string of class name. + :param content_type: content type of response. + + :return: deserialized object. + """ + + # fetch data from response object + if content_type is None: + try: + data = json.loads(response_text) + except ValueError: + data = response_text + elif re.match(r'^application/(json|[\w!#$&.+\-^_]+\+json)\s*(;|$)', content_type, re.IGNORECASE): + if response_text == "": + data = "" + else: + data = json.loads(response_text) + elif re.match(r'^text\/[a-z.+-]+\s*(;|$)', content_type, re.IGNORECASE): + data = response_text + else: + raise ApiException( + status=0, + reason="Unsupported content type: {0}".format(content_type) + ) + + return self.__deserialize(data, response_type) + + def __deserialize(self, data, klass): + """Deserializes dict, list, str into an object. + + :param data: dict, list or str. + :param klass: class literal, or string of class name. + + :return: object. + """ + if data is None: + return None + + if isinstance(klass, str): + if klass.startswith('List['): + m = re.match(r'List\[(.*)]', klass) + assert m is not None, "Malformed List type definition" + sub_kls = m.group(1) + return [self.__deserialize(sub_data, sub_kls) + for sub_data in data] + + if klass.startswith('Dict['): + m = re.match(r'Dict\[([^,]*), (.*)]', klass) + assert m is not None, "Malformed Dict type definition" + sub_kls = m.group(2) + return {k: self.__deserialize(v, sub_kls) + for k, v in data.items()} + + # convert str to class + if klass in self.NATIVE_TYPES_MAPPING: + klass = self.NATIVE_TYPES_MAPPING[klass] + else: + klass = getattr(memora_client_api.models, klass) + + if klass in self.PRIMITIVE_TYPES: + return self.__deserialize_primitive(data, klass) + elif klass is object: + return self.__deserialize_object(data) + elif klass is datetime.date: + return self.__deserialize_date(data) + elif klass is datetime.datetime: + return self.__deserialize_datetime(data) + elif klass is decimal.Decimal: + return decimal.Decimal(data) + elif issubclass(klass, Enum): + return self.__deserialize_enum(data, klass) + else: + return self.__deserialize_model(data, klass) + + def parameters_to_tuples(self, params, collection_formats): + """Get parameters as list of tuples, formatting collections. + + :param params: Parameters as dict or list of two-tuples + :param dict collection_formats: Parameter collection formats + :return: Parameters as list of tuples, collections formatted + """ + new_params: List[Tuple[str, str]] = [] + if collection_formats is None: + collection_formats = {} + for k, v in params.items() if isinstance(params, dict) else params: + if k in collection_formats: + collection_format = collection_formats[k] + if collection_format == 'multi': + new_params.extend((k, value) for value in v) + else: + if collection_format == 'ssv': + delimiter = ' ' + elif collection_format == 'tsv': + delimiter = '\t' + elif collection_format == 'pipes': + delimiter = '|' + else: # csv is the default + delimiter = ',' + new_params.append( + (k, delimiter.join(str(value) for value in v))) + else: + new_params.append((k, v)) + return new_params + + def parameters_to_url_query(self, params, collection_formats): + """Get parameters as list of tuples, formatting collections. + + :param params: Parameters as dict or list of two-tuples + :param dict collection_formats: Parameter collection formats + :return: URL query string (e.g. a=Hello%20World&b=123) + """ + new_params: List[Tuple[str, str]] = [] + if collection_formats is None: + collection_formats = {} + for k, v in params.items() if isinstance(params, dict) else params: + if isinstance(v, bool): + v = str(v).lower() + if isinstance(v, (int, float)): + v = str(v) + if isinstance(v, dict): + v = json.dumps(v) + + if k in collection_formats: + collection_format = collection_formats[k] + if collection_format == 'multi': + new_params.extend((k, quote(str(value))) for value in v) + else: + if collection_format == 'ssv': + delimiter = ' ' + elif collection_format == 'tsv': + delimiter = '\t' + elif collection_format == 'pipes': + delimiter = '|' + else: # csv is the default + delimiter = ',' + new_params.append( + (k, delimiter.join(quote(str(value)) for value in v)) + ) + else: + new_params.append((k, quote(str(v)))) + + return "&".join(["=".join(map(str, item)) for item in new_params]) + + def files_parameters( + self, + files: Dict[str, Union[str, bytes, List[str], List[bytes], Tuple[str, bytes]]], + ): + """Builds form parameters. + + :param files: File parameters. + :return: Form parameters with files. + """ + params = [] + for k, v in files.items(): + if isinstance(v, str): + with open(v, 'rb') as f: + filename = os.path.basename(f.name) + filedata = f.read() + elif isinstance(v, bytes): + filename = k + filedata = v + elif isinstance(v, tuple): + filename, filedata = v + elif isinstance(v, list): + for file_param in v: + params.extend(self.files_parameters({k: file_param})) + continue + else: + raise ValueError("Unsupported file value") + mimetype = ( + mimetypes.guess_type(filename)[0] + or 'application/octet-stream' + ) + params.append( + tuple([k, tuple([filename, filedata, mimetype])]) + ) + return params + + def select_header_accept(self, accepts: List[str]) -> Optional[str]: + """Returns `Accept` based on an array of accepts provided. + + :param accepts: List of headers. + :return: Accept (e.g. application/json). + """ + if not accepts: + return None + + for accept in accepts: + if re.search('json', accept, re.IGNORECASE): + return accept + + return accepts[0] + + def select_header_content_type(self, content_types): + """Returns `Content-Type` based on an array of content_types provided. + + :param content_types: List of content-types. + :return: Content-Type (e.g. application/json). + """ + if not content_types: + return None + + for content_type in content_types: + if re.search('json', content_type, re.IGNORECASE): + return content_type + + return content_types[0] + + def update_params_for_auth( + self, + headers, + queries, + auth_settings, + resource_path, + method, + body, + request_auth=None + ) -> None: + """Updates header and query params based on authentication setting. + + :param headers: Header parameters dict to be updated. + :param queries: Query parameters tuple list to be updated. + :param auth_settings: Authentication setting identifiers list. + :resource_path: A string representation of the HTTP request resource path. + :method: A string representation of the HTTP request method. + :body: A object representing the body of the HTTP request. + The object type is the return value of sanitize_for_serialization(). + :param request_auth: if set, the provided settings will + override the token in the configuration. + """ + if not auth_settings: + return + + if request_auth: + self._apply_auth_params( + headers, + queries, + resource_path, + method, + body, + request_auth + ) + else: + for auth in auth_settings: + auth_setting = self.configuration.auth_settings().get(auth) + if auth_setting: + self._apply_auth_params( + headers, + queries, + resource_path, + method, + body, + auth_setting + ) + + def _apply_auth_params( + self, + headers, + queries, + resource_path, + method, + body, + auth_setting + ) -> None: + """Updates the request parameters based on a single auth_setting + + :param headers: Header parameters dict to be updated. + :param queries: Query parameters tuple list to be updated. + :resource_path: A string representation of the HTTP request resource path. + :method: A string representation of the HTTP request method. + :body: A object representing the body of the HTTP request. + The object type is the return value of sanitize_for_serialization(). + :param auth_setting: auth settings for the endpoint + """ + if auth_setting['in'] == 'cookie': + headers['Cookie'] = auth_setting['value'] + elif auth_setting['in'] == 'header': + if auth_setting['type'] != 'http-signature': + headers[auth_setting['key']] = auth_setting['value'] + elif auth_setting['in'] == 'query': + queries.append((auth_setting['key'], auth_setting['value'])) + else: + raise ApiValueError( + 'Authentication token must be in `query` or `header`' + ) + + def __deserialize_file(self, response): + """Deserializes body to file + + Saves response body into a file in a temporary folder, + using the filename from the `Content-Disposition` header if provided. + + handle file downloading + save response body into a tmp file and return the instance + + :param response: RESTResponse. + :return: file path. + """ + fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) + os.close(fd) + os.remove(path) + + content_disposition = response.getheader("Content-Disposition") + if content_disposition: + m = re.search( + r'filename=[\'"]?([^\'"\s]+)[\'"]?', + content_disposition + ) + assert m is not None, "Unexpected 'content-disposition' header value" + filename = m.group(1) + path = os.path.join(os.path.dirname(path), filename) + + with open(path, "wb") as f: + f.write(response.data) + + return path + + def __deserialize_primitive(self, data, klass): + """Deserializes string to primitive type. + + :param data: str. + :param klass: class literal. + + :return: int, long, float, str, bool. + """ + try: + return klass(data) + except UnicodeEncodeError: + return str(data) + except TypeError: + return data + + def __deserialize_object(self, value): + """Return an original value. + + :return: object. + """ + return value + + def __deserialize_date(self, string): + """Deserializes string to date. + + :param string: str. + :return: date. + """ + try: + return parse(string).date() + except ImportError: + return string + except ValueError: + raise rest.ApiException( + status=0, + reason="Failed to parse `{0}` as date object".format(string) + ) + + def __deserialize_datetime(self, string): + """Deserializes string to datetime. + + The string should be in iso8601 datetime format. + + :param string: str. + :return: datetime. + """ + try: + return parse(string) + except ImportError: + return string + except ValueError: + raise rest.ApiException( + status=0, + reason=( + "Failed to parse `{0}` as datetime object" + .format(string) + ) + ) + + def __deserialize_enum(self, data, klass): + """Deserializes primitive type to enum. + + :param data: primitive type. + :param klass: class literal. + :return: enum value. + """ + try: + return klass(data) + except ValueError: + raise rest.ApiException( + status=0, + reason=( + "Failed to parse `{0}` as `{1}`" + .format(data, klass) + ) + ) + + def __deserialize_model(self, data, klass): + """Deserializes list or dict to model. + + :param data: dict, list. + :param klass: class literal. + :return: model object. + """ + + return klass.from_dict(data) diff --git a/memora-clients/python/memora_client_api/api_response.py b/memora-clients/python/memora_client_api/api_response.py new file mode 100644 index 00000000..9bc7c11f --- /dev/null +++ b/memora-clients/python/memora_client_api/api_response.py @@ -0,0 +1,21 @@ +"""API response object.""" + +from __future__ import annotations +from typing import Optional, Generic, Mapping, TypeVar +from pydantic import Field, StrictInt, StrictBytes, BaseModel + +T = TypeVar("T") + +class ApiResponse(BaseModel, Generic[T]): + """ + API response object + """ + + status_code: StrictInt = Field(description="HTTP status code") + headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers") + data: T = Field(description="Deserialized data given the data type") + raw_data: StrictBytes = Field(description="Raw data (HTTP response body)") + + model_config = { + "arbitrary_types_allowed": True + } diff --git a/memora-clients/python/memora_client_api/configuration.py b/memora-clients/python/memora_client_api/configuration.py new file mode 100644 index 00000000..f57ab790 --- /dev/null +++ b/memora-clients/python/memora_client_api/configuration.py @@ -0,0 +1,572 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import copy +import http.client as httplib +import logging +from logging import FileHandler +import sys +from typing import Any, ClassVar, Dict, List, Literal, Optional, TypedDict, Union +from typing_extensions import NotRequired, Self + +import urllib3 + + +JSON_SCHEMA_VALIDATION_KEYWORDS = { + 'multipleOf', 'maximum', 'exclusiveMaximum', + 'minimum', 'exclusiveMinimum', 'maxLength', + 'minLength', 'pattern', 'maxItems', 'minItems' +} + +ServerVariablesT = Dict[str, str] + +GenericAuthSetting = TypedDict( + "GenericAuthSetting", + { + "type": str, + "in": str, + "key": str, + "value": str, + }, +) + + +OAuth2AuthSetting = TypedDict( + "OAuth2AuthSetting", + { + "type": Literal["oauth2"], + "in": Literal["header"], + "key": Literal["Authorization"], + "value": str, + }, +) + + +APIKeyAuthSetting = TypedDict( + "APIKeyAuthSetting", + { + "type": Literal["api_key"], + "in": str, + "key": str, + "value": Optional[str], + }, +) + + +BasicAuthSetting = TypedDict( + "BasicAuthSetting", + { + "type": Literal["basic"], + "in": Literal["header"], + "key": Literal["Authorization"], + "value": Optional[str], + }, +) + + +BearerFormatAuthSetting = TypedDict( + "BearerFormatAuthSetting", + { + "type": Literal["bearer"], + "in": Literal["header"], + "format": Literal["JWT"], + "key": Literal["Authorization"], + "value": str, + }, +) + + +BearerAuthSetting = TypedDict( + "BearerAuthSetting", + { + "type": Literal["bearer"], + "in": Literal["header"], + "key": Literal["Authorization"], + "value": str, + }, +) + + +HTTPSignatureAuthSetting = TypedDict( + "HTTPSignatureAuthSetting", + { + "type": Literal["http-signature"], + "in": Literal["header"], + "key": Literal["Authorization"], + "value": None, + }, +) + + +AuthSettings = TypedDict( + "AuthSettings", + { + }, + total=False, +) + + +class HostSettingVariable(TypedDict): + description: str + default_value: str + enum_values: List[str] + + +class HostSetting(TypedDict): + url: str + description: str + variables: NotRequired[Dict[str, HostSettingVariable]] + + +class Configuration: + """This class contains various settings of the API client. + + :param host: Base url. + :param ignore_operation_servers + Boolean to ignore operation servers for the API client. + Config will use `host` as the base url regardless of the operation servers. + :param api_key: Dict to store API key(s). + Each entry in the dict specifies an API key. + The dict key is the name of the security scheme in the OAS specification. + The dict value is the API key secret. + :param api_key_prefix: Dict to store API prefix (e.g. Bearer). + The dict key is the name of the security scheme in the OAS specification. + The dict value is an API key prefix when generating the auth data. + :param username: Username for HTTP basic authentication. + :param password: Password for HTTP basic authentication. + :param access_token: Access token. + :param server_index: Index to servers configuration. + :param server_variables: Mapping with string values to replace variables in + templated server configuration. The validation of enums is performed for + variables with defined enum values before. + :param server_operation_index: Mapping from operation ID to an index to server + configuration. + :param server_operation_variables: Mapping from operation ID to a mapping with + string values to replace variables in templated server configuration. + The validation of enums is performed for variables with defined enum + values before. + :param ssl_ca_cert: str - the path to a file of concatenated CA certificates + in PEM format. + :param retries: Number of retries for API requests. + :param ca_cert_data: verify the peer using concatenated CA certificate data + in PEM (str) or DER (bytes) format. + :param cert_file: the path to a client certificate file, for mTLS. + :param key_file: the path to a client key file, for mTLS. + + """ + + _default: ClassVar[Optional[Self]] = None + + def __init__( + self, + host: Optional[str]=None, + api_key: Optional[Dict[str, str]]=None, + api_key_prefix: Optional[Dict[str, str]]=None, + username: Optional[str]=None, + password: Optional[str]=None, + access_token: Optional[str]=None, + server_index: Optional[int]=None, + server_variables: Optional[ServerVariablesT]=None, + server_operation_index: Optional[Dict[int, int]]=None, + server_operation_variables: Optional[Dict[int, ServerVariablesT]]=None, + ignore_operation_servers: bool=False, + ssl_ca_cert: Optional[str]=None, + retries: Optional[int] = None, + ca_cert_data: Optional[Union[str, bytes]] = None, + cert_file: Optional[str]=None, + key_file: Optional[str]=None, + *, + debug: Optional[bool] = None, + ) -> None: + """Constructor + """ + self._base_path = "http://localhost" if host is None else host + """Default Base url + """ + self.server_index = 0 if server_index is None and host is None else server_index + self.server_operation_index = server_operation_index or {} + """Default server index + """ + self.server_variables = server_variables or {} + self.server_operation_variables = server_operation_variables or {} + """Default server variables + """ + self.ignore_operation_servers = ignore_operation_servers + """Ignore operation servers + """ + self.temp_folder_path = None + """Temp file folder for downloading files + """ + # Authentication Settings + self.api_key = {} + if api_key: + self.api_key = api_key + """dict to store API key(s) + """ + self.api_key_prefix = {} + if api_key_prefix: + self.api_key_prefix = api_key_prefix + """dict to store API prefix (e.g. Bearer) + """ + self.refresh_api_key_hook = None + """function hook to refresh API key if expired + """ + self.username = username + """Username for HTTP basic authentication + """ + self.password = password + """Password for HTTP basic authentication + """ + self.access_token = access_token + """Access token + """ + self.logger = {} + """Logging Settings + """ + self.logger["package_logger"] = logging.getLogger("memora_client_api") + self.logger["urllib3_logger"] = logging.getLogger("urllib3") + self.logger_format = '%(asctime)s %(levelname)s %(message)s' + """Log format + """ + self.logger_stream_handler = None + """Log stream handler + """ + self.logger_file_handler: Optional[FileHandler] = None + """Log file handler + """ + self.logger_file = None + """Debug file location + """ + if debug is not None: + self.debug = debug + else: + self.__debug = False + """Debug switch + """ + + self.verify_ssl = True + """SSL/TLS verification + Set this to false to skip verifying SSL certificate when calling API + from https server. + """ + self.ssl_ca_cert = ssl_ca_cert + """Set this to customize the certificate file to verify the peer. + """ + self.ca_cert_data = ca_cert_data + """Set this to verify the peer using PEM (str) or DER (bytes) + certificate data. + """ + self.cert_file = cert_file + """client certificate file + """ + self.key_file = key_file + """client key file + """ + self.assert_hostname = None + """Set this to True/False to enable/disable SSL hostname verification. + """ + self.tls_server_name = None + """SSL/TLS Server Name Indication (SNI) + Set this to the SNI value expected by the server. + """ + + self.connection_pool_maxsize = 100 + """This value is passed to the aiohttp to limit simultaneous connections. + Default values is 100, None means no-limit. + """ + + self.proxy: Optional[str] = None + """Proxy URL + """ + self.proxy_headers = None + """Proxy headers + """ + self.safe_chars_for_path_param = '' + """Safe chars for path_param + """ + self.retries = retries + """Adding retries to override urllib3 default value 3 + """ + # Enable client side validation + self.client_side_validation = True + + self.socket_options = None + """Options to pass down to the underlying urllib3 socket + """ + + self.datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z" + """datetime format + """ + + self.date_format = "%Y-%m-%d" + """date format + """ + + def __deepcopy__(self, memo: Dict[int, Any]) -> Self: + cls = self.__class__ + result = cls.__new__(cls) + memo[id(self)] = result + for k, v in self.__dict__.items(): + if k not in ('logger', 'logger_file_handler'): + setattr(result, k, copy.deepcopy(v, memo)) + # shallow copy of loggers + result.logger = copy.copy(self.logger) + # use setters to configure loggers + result.logger_file = self.logger_file + result.debug = self.debug + return result + + def __setattr__(self, name: str, value: Any) -> None: + object.__setattr__(self, name, value) + + @classmethod + def set_default(cls, default: Optional[Self]) -> None: + """Set default instance of configuration. + + It stores default configuration, which can be + returned by get_default_copy method. + + :param default: object of Configuration + """ + cls._default = default + + @classmethod + def get_default_copy(cls) -> Self: + """Deprecated. Please use `get_default` instead. + + Deprecated. Please use `get_default` instead. + + :return: The configuration object. + """ + return cls.get_default() + + @classmethod + def get_default(cls) -> Self: + """Return the default configuration. + + This method returns newly created, based on default constructor, + object of Configuration class or returns a copy of default + configuration. + + :return: The configuration object. + """ + if cls._default is None: + cls._default = cls() + return cls._default + + @property + def logger_file(self) -> Optional[str]: + """The logger file. + + If the logger_file is None, then add stream handler and remove file + handler. Otherwise, add file handler and remove stream handler. + + :param value: The logger_file path. + :type: str + """ + return self.__logger_file + + @logger_file.setter + def logger_file(self, value: Optional[str]) -> None: + """The logger file. + + If the logger_file is None, then add stream handler and remove file + handler. Otherwise, add file handler and remove stream handler. + + :param value: The logger_file path. + :type: str + """ + self.__logger_file = value + if self.__logger_file: + # If set logging file, + # then add file handler and remove stream handler. + self.logger_file_handler = logging.FileHandler(self.__logger_file) + self.logger_file_handler.setFormatter(self.logger_formatter) + for _, logger in self.logger.items(): + logger.addHandler(self.logger_file_handler) + + @property + def debug(self) -> bool: + """Debug status + + :param value: The debug status, True or False. + :type: bool + """ + return self.__debug + + @debug.setter + def debug(self, value: bool) -> None: + """Debug status + + :param value: The debug status, True or False. + :type: bool + """ + self.__debug = value + if self.__debug: + # if debug status is True, turn on debug logging + for _, logger in self.logger.items(): + logger.setLevel(logging.DEBUG) + # turn on httplib debug + httplib.HTTPConnection.debuglevel = 1 + else: + # if debug status is False, turn off debug logging, + # setting log level to default `logging.WARNING` + for _, logger in self.logger.items(): + logger.setLevel(logging.WARNING) + # turn off httplib debug + httplib.HTTPConnection.debuglevel = 0 + + @property + def logger_format(self) -> str: + """The logger format. + + The logger_formatter will be updated when sets logger_format. + + :param value: The format string. + :type: str + """ + return self.__logger_format + + @logger_format.setter + def logger_format(self, value: str) -> None: + """The logger format. + + The logger_formatter will be updated when sets logger_format. + + :param value: The format string. + :type: str + """ + self.__logger_format = value + self.logger_formatter = logging.Formatter(self.__logger_format) + + def get_api_key_with_prefix(self, identifier: str, alias: Optional[str]=None) -> Optional[str]: + """Gets API key (with prefix if set). + + :param identifier: The identifier of apiKey. + :param alias: The alternative identifier of apiKey. + :return: The token for api key authentication. + """ + if self.refresh_api_key_hook is not None: + self.refresh_api_key_hook(self) + key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None) + if key: + prefix = self.api_key_prefix.get(identifier) + if prefix: + return "%s %s" % (prefix, key) + else: + return key + + return None + + def get_basic_auth_token(self) -> Optional[str]: + """Gets HTTP basic authentication header (string). + + :return: The token for basic HTTP authentication. + """ + username = "" + if self.username is not None: + username = self.username + password = "" + if self.password is not None: + password = self.password + return urllib3.util.make_headers( + basic_auth=username + ':' + password + ).get('authorization') + + def auth_settings(self)-> AuthSettings: + """Gets Auth Settings dict for api client. + + :return: The Auth Settings information dict. + """ + auth: AuthSettings = {} + return auth + + def to_debug_report(self) -> str: + """Gets the essential information for debugging. + + :return: The report for debugging. + """ + return "Python SDK Debug Report:\n"\ + "OS: {env}\n"\ + "Python Version: {pyversion}\n"\ + "Version of the API: 1.0.0\n"\ + "SDK Package Version: 0.0.7".\ + format(env=sys.platform, pyversion=sys.version) + + def get_host_settings(self) -> List[HostSetting]: + """Gets an array of host settings + + :return: An array of host settings + """ + return [ + { + 'url': "", + 'description': "No description provided", + } + ] + + def get_host_from_settings( + self, + index: Optional[int], + variables: Optional[ServerVariablesT]=None, + servers: Optional[List[HostSetting]]=None, + ) -> str: + """Gets host URL based on the index and variables + :param index: array index of the host settings + :param variables: hash of variable and the corresponding value + :param servers: an array of host settings or None + :return: URL based on host settings + """ + if index is None: + return self._base_path + + variables = {} if variables is None else variables + servers = self.get_host_settings() if servers is None else servers + + try: + server = servers[index] + except IndexError: + raise ValueError( + "Invalid index {0} when selecting the host settings. " + "Must be less than {1}".format(index, len(servers))) + + url = server['url'] + + # go through variables and replace placeholders + for variable_name, variable in server.get('variables', {}).items(): + used_value = variables.get( + variable_name, variable['default_value']) + + if 'enum_values' in variable \ + and used_value not in variable['enum_values']: + raise ValueError( + "The variable `{0}` in the host URL has invalid value " + "{1}. Must be {2}.".format( + variable_name, variables[variable_name], + variable['enum_values'])) + + url = url.replace("{" + variable_name + "}", used_value) + + return url + + @property + def host(self) -> str: + """Return generated host.""" + return self.get_host_from_settings(self.server_index, variables=self.server_variables) + + @host.setter + def host(self, value: str) -> None: + """Fix base path.""" + self._base_path = value + self.server_index = None diff --git a/memora-clients/python/memora_client_api/docs/AddBackgroundRequest.md b/memora-clients/python/memora_client_api/docs/AddBackgroundRequest.md new file mode 100644 index 00000000..7efc61e7 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/AddBackgroundRequest.md @@ -0,0 +1,31 @@ +# AddBackgroundRequest + +Request model for adding/merging background information. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**content** | **str** | New background information to add or merge | +**update_personality** | **bool** | If true, infer Big Five personality traits from the merged background (default: true) | [optional] [default to True] + +## Example + +```python +from memora_client_api.models.add_background_request import AddBackgroundRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of AddBackgroundRequest from a JSON string +add_background_request_instance = AddBackgroundRequest.from_json(json) +# print the JSON string representation of the object +print(AddBackgroundRequest.to_json()) + +# convert the object into a dict +add_background_request_dict = add_background_request_instance.to_dict() +# create an instance of AddBackgroundRequest from a dict +add_background_request_from_dict = AddBackgroundRequest.from_dict(add_background_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/AgentListItem.md b/memora-clients/python/memora_client_api/docs/AgentListItem.md new file mode 100644 index 00000000..3f024fc3 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/AgentListItem.md @@ -0,0 +1,35 @@ +# AgentListItem + +Agent list item with profile summary. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**agent_id** | **str** | | +**name** | **str** | | +**personality** | [**PersonalityTraits**](PersonalityTraits.md) | | +**background** | **str** | | +**created_at** | **str** | | [optional] +**updated_at** | **str** | | [optional] + +## Example + +```python +from memora_client_api.models.agent_list_item import AgentListItem + +# TODO update the JSON string below +json = "{}" +# create an instance of AgentListItem from a JSON string +agent_list_item_instance = AgentListItem.from_json(json) +# print the JSON string representation of the object +print(AgentListItem.to_json()) + +# convert the object into a dict +agent_list_item_dict = agent_list_item_instance.to_dict() +# create an instance of AgentListItem from a dict +agent_list_item_from_dict = AgentListItem.from_dict(agent_list_item_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/AgentListResponse.md b/memora-clients/python/memora_client_api/docs/AgentListResponse.md new file mode 100644 index 00000000..f5f25b2f --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/AgentListResponse.md @@ -0,0 +1,30 @@ +# AgentListResponse + +Response model for listing all agents. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**agents** | [**List[AgentListItem]**](AgentListItem.md) | | + +## Example + +```python +from memora_client_api.models.agent_list_response import AgentListResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of AgentListResponse from a JSON string +agent_list_response_instance = AgentListResponse.from_json(json) +# print the JSON string representation of the object +print(AgentListResponse.to_json()) + +# convert the object into a dict +agent_list_response_dict = agent_list_response_instance.to_dict() +# create an instance of AgentListResponse from a dict +agent_list_response_from_dict = AgentListResponse.from_dict(agent_list_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/AgentManagementApi.md b/memora-clients/python/memora_client_api/docs/AgentManagementApi.md new file mode 100644 index 00000000..13cc7e9b --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/AgentManagementApi.md @@ -0,0 +1,503 @@ +# memora_client_api.AgentManagementApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**add_agent_background**](AgentManagementApi.md#add_agent_background) | **POST** /api/v1/agents/{agent_id}/background | Add/merge agent background +[**clear_agent_memories**](AgentManagementApi.md#clear_agent_memories) | **DELETE** /api/v1/agents/{agent_id}/memories | Clear agent memories +[**create_or_update_agent**](AgentManagementApi.md#create_or_update_agent) | **PUT** /api/v1/agents/{agent_id} | Create or update agent +[**get_agent_profile**](AgentManagementApi.md#get_agent_profile) | **GET** /api/v1/agents/{agent_id}/profile | Get agent profile +[**get_agent_stats**](AgentManagementApi.md#get_agent_stats) | **GET** /api/v1/agents/{agent_id}/stats | Get memory statistics for an agent +[**list_agents**](AgentManagementApi.md#list_agents) | **GET** /api/v1/agents | List all agents +[**update_agent_personality**](AgentManagementApi.md#update_agent_personality) | **PUT** /api/v1/agents/{agent_id}/profile | Update agent personality + + +# **add_agent_background** +> BackgroundResponse add_agent_background(agent_id, add_background_request) + +Add/merge agent background + +Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits. + +### Example + + +```python +import memora_client_api +from memora_client_api.models.add_background_request import AddBackgroundRequest +from memora_client_api.models.background_response import BackgroundResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.AgentManagementApi(api_client) + agent_id = 'agent_id_example' # str | + add_background_request = memora_client_api.AddBackgroundRequest() # AddBackgroundRequest | + + try: + # Add/merge agent background + api_response = await api_instance.add_agent_background(agent_id, add_background_request) + print("The response of AgentManagementApi->add_agent_background:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling AgentManagementApi->add_agent_background: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **add_background_request** | [**AddBackgroundRequest**](AddBackgroundRequest.md)| | + +### Return type + +[**BackgroundResponse**](BackgroundResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **clear_agent_memories** +> DeleteResponse clear_agent_memories(agent_id, fact_type=fact_type) + +Clear agent memories + +Delete memory units for an agent. Optionally filter by fact_type (world, agent, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The agent profile (personality and background) will be preserved. + +### Example + + +```python +import memora_client_api +from memora_client_api.models.delete_response import DeleteResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.AgentManagementApi(api_client) + agent_id = 'agent_id_example' # str | + fact_type = 'fact_type_example' # str | Optional fact type filter (world, agent, opinion) (optional) + + try: + # Clear agent memories + api_response = await api_instance.clear_agent_memories(agent_id, fact_type=fact_type) + print("The response of AgentManagementApi->clear_agent_memories:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling AgentManagementApi->clear_agent_memories: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **fact_type** | **str**| Optional fact type filter (world, agent, opinion) | [optional] + +### Return type + +[**DeleteResponse**](DeleteResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **create_or_update_agent** +> AgentProfileResponse create_or_update_agent(agent_id, create_agent_request) + +Create or update agent + +Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults. + +### Example + + +```python +import memora_client_api +from memora_client_api.models.agent_profile_response import AgentProfileResponse +from memora_client_api.models.create_agent_request import CreateAgentRequest +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.AgentManagementApi(api_client) + agent_id = 'agent_id_example' # str | + create_agent_request = memora_client_api.CreateAgentRequest() # CreateAgentRequest | + + try: + # Create or update agent + api_response = await api_instance.create_or_update_agent(agent_id, create_agent_request) + print("The response of AgentManagementApi->create_or_update_agent:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling AgentManagementApi->create_or_update_agent: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **create_agent_request** | [**CreateAgentRequest**](CreateAgentRequest.md)| | + +### Return type + +[**AgentProfileResponse**](AgentProfileResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **get_agent_profile** +> AgentProfileResponse get_agent_profile(agent_id) + +Get agent profile + +Get personality traits and background for an agent. Auto-creates agent with defaults if not exists. + +### Example + + +```python +import memora_client_api +from memora_client_api.models.agent_profile_response import AgentProfileResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.AgentManagementApi(api_client) + agent_id = 'agent_id_example' # str | + + try: + # Get agent profile + api_response = await api_instance.get_agent_profile(agent_id) + print("The response of AgentManagementApi->get_agent_profile:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling AgentManagementApi->get_agent_profile: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + +### Return type + +[**AgentProfileResponse**](AgentProfileResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **get_agent_stats** +> object get_agent_stats(agent_id) + +Get memory statistics for an agent + +Get statistics about nodes and links for a specific agent + +### Example + + +```python +import memora_client_api +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.AgentManagementApi(api_client) + agent_id = 'agent_id_example' # str | + + try: + # Get memory statistics for an agent + api_response = await api_instance.get_agent_stats(agent_id) + print("The response of AgentManagementApi->get_agent_stats:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling AgentManagementApi->get_agent_stats: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + +### Return type + +**object** + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **list_agents** +> AgentListResponse list_agents() + +List all agents + +Get a list of all agents with their profiles + +### Example + + +```python +import memora_client_api +from memora_client_api.models.agent_list_response import AgentListResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.AgentManagementApi(api_client) + + try: + # List all agents + api_response = await api_instance.list_agents() + print("The response of AgentManagementApi->list_agents:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling AgentManagementApi->list_agents: %s\n" % e) +``` + + + +### Parameters + +This endpoint does not need any parameter. + +### Return type + +[**AgentListResponse**](AgentListResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **update_agent_personality** +> AgentProfileResponse update_agent_personality(agent_id, update_personality_request) + +Update agent personality + +Update agent's Big Five personality traits and bias strength + +### Example + + +```python +import memora_client_api +from memora_client_api.models.agent_profile_response import AgentProfileResponse +from memora_client_api.models.update_personality_request import UpdatePersonalityRequest +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.AgentManagementApi(api_client) + agent_id = 'agent_id_example' # str | + update_personality_request = memora_client_api.UpdatePersonalityRequest() # UpdatePersonalityRequest | + + try: + # Update agent personality + api_response = await api_instance.update_agent_personality(agent_id, update_personality_request) + print("The response of AgentManagementApi->update_agent_personality:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling AgentManagementApi->update_agent_personality: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **update_personality_request** | [**UpdatePersonalityRequest**](UpdatePersonalityRequest.md)| | + +### Return type + +[**AgentProfileResponse**](AgentProfileResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/memora-clients/python/memora_client_api/docs/AgentProfileResponse.md b/memora-clients/python/memora_client_api/docs/AgentProfileResponse.md new file mode 100644 index 00000000..4caee199 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/AgentProfileResponse.md @@ -0,0 +1,33 @@ +# AgentProfileResponse + +Response model for agent profile. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**agent_id** | **str** | | +**name** | **str** | | +**personality** | [**PersonalityTraits**](PersonalityTraits.md) | | +**background** | **str** | | + +## Example + +```python +from memora_client_api.models.agent_profile_response import AgentProfileResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of AgentProfileResponse from a JSON string +agent_profile_response_instance = AgentProfileResponse.from_json(json) +# print the JSON string representation of the object +print(AgentProfileResponse.to_json()) + +# convert the object into a dict +agent_profile_response_dict = agent_profile_response_instance.to_dict() +# create an instance of AgentProfileResponse from a dict +agent_profile_response_from_dict = AgentProfileResponse.from_dict(agent_profile_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/BackgroundResponse.md b/memora-clients/python/memora_client_api/docs/BackgroundResponse.md new file mode 100644 index 00000000..3e9947b8 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/BackgroundResponse.md @@ -0,0 +1,31 @@ +# BackgroundResponse + +Response model for background update. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**background** | **str** | | +**personality** | [**PersonalityTraits**](PersonalityTraits.md) | | [optional] + +## Example + +```python +from memora_client_api.models.background_response import BackgroundResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of BackgroundResponse from a JSON string +background_response_instance = BackgroundResponse.from_json(json) +# print the JSON string representation of the object +print(BackgroundResponse.to_json()) + +# convert the object into a dict +background_response_dict = background_response_instance.to_dict() +# create an instance of BackgroundResponse from a dict +background_response_from_dict = BackgroundResponse.from_dict(background_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/BatchPutAsyncResponse.md b/memora-clients/python/memora_client_api/docs/BatchPutAsyncResponse.md new file mode 100644 index 00000000..d19c92e5 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/BatchPutAsyncResponse.md @@ -0,0 +1,35 @@ +# BatchPutAsyncResponse + +Response model for async batch put endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**success** | **bool** | | +**message** | **str** | | +**agent_id** | **str** | | +**document_id** | **str** | | [optional] +**items_count** | **int** | | +**queued** | **bool** | | + +## Example + +```python +from memora_client_api.models.batch_put_async_response import BatchPutAsyncResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of BatchPutAsyncResponse from a JSON string +batch_put_async_response_instance = BatchPutAsyncResponse.from_json(json) +# print the JSON string representation of the object +print(BatchPutAsyncResponse.to_json()) + +# convert the object into a dict +batch_put_async_response_dict = batch_put_async_response_instance.to_dict() +# create an instance of BatchPutAsyncResponse from a dict +batch_put_async_response_from_dict = BatchPutAsyncResponse.from_dict(batch_put_async_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/BatchPutRequest.md b/memora-clients/python/memora_client_api/docs/BatchPutRequest.md new file mode 100644 index 00000000..ee24961b --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/BatchPutRequest.md @@ -0,0 +1,31 @@ +# BatchPutRequest + +Request model for batch put endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**items** | [**List[MemoryItem]**](MemoryItem.md) | | +**document_id** | **str** | | [optional] + +## Example + +```python +from memora_client_api.models.batch_put_request import BatchPutRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of BatchPutRequest from a JSON string +batch_put_request_instance = BatchPutRequest.from_json(json) +# print the JSON string representation of the object +print(BatchPutRequest.to_json()) + +# convert the object into a dict +batch_put_request_dict = batch_put_request_instance.to_dict() +# create an instance of BatchPutRequest from a dict +batch_put_request_from_dict = BatchPutRequest.from_dict(batch_put_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/BatchPutResponse.md b/memora-clients/python/memora_client_api/docs/BatchPutResponse.md new file mode 100644 index 00000000..cfff2055 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/BatchPutResponse.md @@ -0,0 +1,34 @@ +# BatchPutResponse + +Response model for batch put endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**success** | **bool** | | +**message** | **str** | | +**agent_id** | **str** | | +**document_id** | **str** | | [optional] +**items_count** | **int** | | + +## Example + +```python +from memora_client_api.models.batch_put_response import BatchPutResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of BatchPutResponse from a JSON string +batch_put_response_instance = BatchPutResponse.from_json(json) +# print the JSON string representation of the object +print(BatchPutResponse.to_json()) + +# convert the object into a dict +batch_put_response_dict = batch_put_response_instance.to_dict() +# create an instance of BatchPutResponse from a dict +batch_put_response_from_dict = BatchPutResponse.from_dict(batch_put_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/CreateAgentRequest.md b/memora-clients/python/memora_client_api/docs/CreateAgentRequest.md new file mode 100644 index 00000000..4ede74c4 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/CreateAgentRequest.md @@ -0,0 +1,32 @@ +# CreateAgentRequest + +Request model for creating/updating an agent. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**name** | **str** | | [optional] +**personality** | [**PersonalityTraits**](PersonalityTraits.md) | | [optional] +**background** | **str** | | [optional] + +## Example + +```python +from memora_client_api.models.create_agent_request import CreateAgentRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of CreateAgentRequest from a JSON string +create_agent_request_instance = CreateAgentRequest.from_json(json) +# print the JSON string representation of the object +print(CreateAgentRequest.to_json()) + +# convert the object into a dict +create_agent_request_dict = create_agent_request_instance.to_dict() +# create an instance of CreateAgentRequest from a dict +create_agent_request_from_dict = CreateAgentRequest.from_dict(create_agent_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/DeleteResponse.md b/memora-clients/python/memora_client_api/docs/DeleteResponse.md new file mode 100644 index 00000000..ef2e7b94 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/DeleteResponse.md @@ -0,0 +1,31 @@ +# DeleteResponse + +Response model for delete operations. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**success** | **bool** | | +**message** | **str** | | + +## Example + +```python +from memora_client_api.models.delete_response import DeleteResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of DeleteResponse from a JSON string +delete_response_instance = DeleteResponse.from_json(json) +# print the JSON string representation of the object +print(DeleteResponse.to_json()) + +# convert the object into a dict +delete_response_dict = delete_response_instance.to_dict() +# create an instance of DeleteResponse from a dict +delete_response_from_dict = DeleteResponse.from_dict(delete_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/DocumentResponse.md b/memora-clients/python/memora_client_api/docs/DocumentResponse.md new file mode 100644 index 00000000..51b4b613 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/DocumentResponse.md @@ -0,0 +1,36 @@ +# DocumentResponse + +Response model for get document endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **str** | | +**agent_id** | **str** | | +**original_text** | **str** | | +**content_hash** | **str** | | +**created_at** | **str** | | +**updated_at** | **str** | | +**memory_unit_count** | **int** | | + +## Example + +```python +from memora_client_api.models.document_response import DocumentResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of DocumentResponse from a JSON string +document_response_instance = DocumentResponse.from_json(json) +# print the JSON string representation of the object +print(DocumentResponse.to_json()) + +# convert the object into a dict +document_response_dict = document_response_instance.to_dict() +# create an instance of DocumentResponse from a dict +document_response_from_dict = DocumentResponse.from_dict(document_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/DocumentsApi.md b/memora-clients/python/memora_client_api/docs/DocumentsApi.md new file mode 100644 index 00000000..1588b573 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/DocumentsApi.md @@ -0,0 +1,234 @@ +# memora_client_api.DocumentsApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**delete_document**](DocumentsApi.md#delete_document) | **DELETE** /api/v1/agents/{agent_id}/documents/{document_id} | Delete a document +[**get_document**](DocumentsApi.md#get_document) | **GET** /api/v1/agents/{agent_id}/documents/{document_id} | Get document details +[**list_documents**](DocumentsApi.md#list_documents) | **GET** /api/v1/agents/{agent_id}/documents | List documents + + +# **delete_document** +> object delete_document(agent_id, document_id) + +Delete a document + +Delete a document and all its associated memory units and links. + +This will cascade delete: +- The document itself +- All memory units extracted from this document +- All links (temporal, semantic, entity) associated with those memory units + +This operation cannot be undone. + +### Example + + +```python +import memora_client_api +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.DocumentsApi(api_client) + agent_id = 'agent_id_example' # str | + document_id = 'document_id_example' # str | + + try: + # Delete a document + api_response = await api_instance.delete_document(agent_id, document_id) + print("The response of DocumentsApi->delete_document:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling DocumentsApi->delete_document: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **document_id** | **str**| | + +### Return type + +**object** + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **get_document** +> DocumentResponse get_document(agent_id, document_id) + +Get document details + +Get a specific document including its original text + +### Example + + +```python +import memora_client_api +from memora_client_api.models.document_response import DocumentResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.DocumentsApi(api_client) + agent_id = 'agent_id_example' # str | + document_id = 'document_id_example' # str | + + try: + # Get document details + api_response = await api_instance.get_document(agent_id, document_id) + print("The response of DocumentsApi->get_document:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling DocumentsApi->get_document: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **document_id** | **str**| | + +### Return type + +[**DocumentResponse**](DocumentResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **list_documents** +> ListDocumentsResponse list_documents(agent_id, q=q, limit=limit, offset=offset) + +List documents + +List documents with pagination and optional search. Documents are the source content from which memory units are extracted. + +### Example + + +```python +import memora_client_api +from memora_client_api.models.list_documents_response import ListDocumentsResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.DocumentsApi(api_client) + agent_id = 'agent_id_example' # str | + q = 'q_example' # str | (optional) + limit = 100 # int | (optional) (default to 100) + offset = 0 # int | (optional) (default to 0) + + try: + # List documents + api_response = await api_instance.list_documents(agent_id, q=q, limit=limit, offset=offset) + print("The response of DocumentsApi->list_documents:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling DocumentsApi->list_documents: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **q** | **str**| | [optional] + **limit** | **int**| | [optional] [default to 100] + **offset** | **int**| | [optional] [default to 0] + +### Return type + +[**ListDocumentsResponse**](ListDocumentsResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/memora-clients/python/memora_client_api/docs/GraphDataResponse.md b/memora-clients/python/memora_client_api/docs/GraphDataResponse.md new file mode 100644 index 00000000..7d4b36f8 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/GraphDataResponse.md @@ -0,0 +1,33 @@ +# GraphDataResponse + +Response model for graph data endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**nodes** | **List[Dict[str, object]]** | | +**edges** | **List[Dict[str, object]]** | | +**table_rows** | **List[Dict[str, object]]** | | +**total_units** | **int** | | + +## Example + +```python +from memora_client_api.models.graph_data_response import GraphDataResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of GraphDataResponse from a JSON string +graph_data_response_instance = GraphDataResponse.from_json(json) +# print the JSON string representation of the object +print(GraphDataResponse.to_json()) + +# convert the object into a dict +graph_data_response_dict = graph_data_response_instance.to_dict() +# create an instance of GraphDataResponse from a dict +graph_data_response_from_dict = GraphDataResponse.from_dict(graph_data_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/HTTPValidationError.md b/memora-clients/python/memora_client_api/docs/HTTPValidationError.md new file mode 100644 index 00000000..fae08bf1 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/HTTPValidationError.md @@ -0,0 +1,29 @@ +# HTTPValidationError + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**detail** | [**List[ValidationError]**](ValidationError.md) | | [optional] + +## Example + +```python +from memora_client_api.models.http_validation_error import HTTPValidationError + +# TODO update the JSON string below +json = "{}" +# create an instance of HTTPValidationError from a JSON string +http_validation_error_instance = HTTPValidationError.from_json(json) +# print the JSON string representation of the object +print(HTTPValidationError.to_json()) + +# convert the object into a dict +http_validation_error_dict = http_validation_error_instance.to_dict() +# create an instance of HTTPValidationError from a dict +http_validation_error_from_dict = HTTPValidationError.from_dict(http_validation_error_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/ListDocumentsResponse.md b/memora-clients/python/memora_client_api/docs/ListDocumentsResponse.md new file mode 100644 index 00000000..a08b2d0e --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/ListDocumentsResponse.md @@ -0,0 +1,33 @@ +# ListDocumentsResponse + +Response model for list documents endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**items** | **List[Dict[str, object]]** | | +**total** | **int** | | +**limit** | **int** | | +**offset** | **int** | | + +## Example + +```python +from memora_client_api.models.list_documents_response import ListDocumentsResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of ListDocumentsResponse from a JSON string +list_documents_response_instance = ListDocumentsResponse.from_json(json) +# print the JSON string representation of the object +print(ListDocumentsResponse.to_json()) + +# convert the object into a dict +list_documents_response_dict = list_documents_response_instance.to_dict() +# create an instance of ListDocumentsResponse from a dict +list_documents_response_from_dict = ListDocumentsResponse.from_dict(list_documents_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/ListMemoryUnitsResponse.md b/memora-clients/python/memora_client_api/docs/ListMemoryUnitsResponse.md new file mode 100644 index 00000000..23733fcf --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/ListMemoryUnitsResponse.md @@ -0,0 +1,33 @@ +# ListMemoryUnitsResponse + +Response model for list memory units endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**items** | **List[Dict[str, object]]** | | +**total** | **int** | | +**limit** | **int** | | +**offset** | **int** | | + +## Example + +```python +from memora_client_api.models.list_memory_units_response import ListMemoryUnitsResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of ListMemoryUnitsResponse from a JSON string +list_memory_units_response_instance = ListMemoryUnitsResponse.from_json(json) +# print the JSON string representation of the object +print(ListMemoryUnitsResponse.to_json()) + +# convert the object into a dict +list_memory_units_response_dict = list_memory_units_response_instance.to_dict() +# create an instance of ListMemoryUnitsResponse from a dict +list_memory_units_response_from_dict = ListMemoryUnitsResponse.from_dict(list_memory_units_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/MemoryItem.md b/memora-clients/python/memora_client_api/docs/MemoryItem.md new file mode 100644 index 00000000..f207cfe3 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/MemoryItem.md @@ -0,0 +1,32 @@ +# MemoryItem + +Single memory item for batch put. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**content** | **str** | | +**event_date** | **datetime** | | [optional] +**context** | **str** | | [optional] + +## Example + +```python +from memora_client_api.models.memory_item import MemoryItem + +# TODO update the JSON string below +json = "{}" +# create an instance of MemoryItem from a JSON string +memory_item_instance = MemoryItem.from_json(json) +# print the JSON string representation of the object +print(MemoryItem.to_json()) + +# convert the object into a dict +memory_item_dict = memory_item_instance.to_dict() +# create an instance of MemoryItem from a dict +memory_item_from_dict = MemoryItem.from_dict(memory_item_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/MemoryOperationsApi.md b/memora-clients/python/memora_client_api/docs/MemoryOperationsApi.md new file mode 100644 index 00000000..56d448d3 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/MemoryOperationsApi.md @@ -0,0 +1,556 @@ +# memora_client_api.MemoryOperationsApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**batch_put_async**](MemoryOperationsApi.md#batch_put_async) | **POST** /api/v1/agents/{agent_id}/memories/async | Store multiple memories asynchronously +[**batch_put_memories**](MemoryOperationsApi.md#batch_put_memories) | **POST** /api/v1/agents/{agent_id}/memories | Store multiple memories +[**cancel_operation**](MemoryOperationsApi.md#cancel_operation) | **DELETE** /api/v1/agents/{agent_id}/operations/{operation_id} | Cancel a pending async operation +[**delete_memory_unit**](MemoryOperationsApi.md#delete_memory_unit) | **DELETE** /api/v1/agents/{agent_id}/memories/{unit_id} | Delete a memory unit +[**list_memories**](MemoryOperationsApi.md#list_memories) | **GET** /api/v1/agents/{agent_id}/memories/list | List memory units +[**list_operations**](MemoryOperationsApi.md#list_operations) | **GET** /api/v1/agents/{agent_id}/operations | List async operations +[**search_memories**](MemoryOperationsApi.md#search_memories) | **POST** /api/v1/agents/{agent_id}/memories/search | Search memory + + +# **batch_put_async** +> BatchPutAsyncResponse batch_put_async(agent_id, batch_put_request) + +Store multiple memories asynchronously + +Store multiple memory items in batch asynchronously using the task backend. + + This endpoint returns immediately after queuing the task, without waiting for completion. + The actual processing happens in the background. + + Features: + - Immediate response (non-blocking) + - Background processing via task queue + - Efficient batch processing + - Automatic fact extraction from natural language + - Entity recognition and linking + - Document tracking with automatic upsert (when document_id is provided) + - Temporal and semantic linking + + The system automatically: + 1. Queues the batch put task + 2. Returns immediately with success=True, queued=True + 3. Processes in background: extracts facts, generates embeddings, creates links + + Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). + +### Example + + +```python +import memora_client_api +from memora_client_api.models.batch_put_async_response import BatchPutAsyncResponse +from memora_client_api.models.batch_put_request import BatchPutRequest +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.MemoryOperationsApi(api_client) + agent_id = 'agent_id_example' # str | + batch_put_request = memora_client_api.BatchPutRequest() # BatchPutRequest | + + try: + # Store multiple memories asynchronously + api_response = await api_instance.batch_put_async(agent_id, batch_put_request) + print("The response of MemoryOperationsApi->batch_put_async:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling MemoryOperationsApi->batch_put_async: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **batch_put_request** | [**BatchPutRequest**](BatchPutRequest.md)| | + +### Return type + +[**BatchPutAsyncResponse**](BatchPutAsyncResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **batch_put_memories** +> BatchPutResponse batch_put_memories(agent_id, batch_put_request) + +Store multiple memories + +Store multiple memory items in batch with automatic fact extraction. + + Features: + - Efficient batch processing + - Automatic fact extraction from natural language + - Entity recognition and linking + - Document tracking with automatic upsert (when document_id is provided) + - Temporal and semantic linking + + The system automatically: + 1. Extracts semantic facts from the content + 2. Generates embeddings + 3. Deduplicates similar facts + 4. Creates temporal, semantic, and entity links + 5. Tracks document metadata + + Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). + +### Example + + +```python +import memora_client_api +from memora_client_api.models.batch_put_request import BatchPutRequest +from memora_client_api.models.batch_put_response import BatchPutResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.MemoryOperationsApi(api_client) + agent_id = 'agent_id_example' # str | + batch_put_request = memora_client_api.BatchPutRequest() # BatchPutRequest | + + try: + # Store multiple memories + api_response = await api_instance.batch_put_memories(agent_id, batch_put_request) + print("The response of MemoryOperationsApi->batch_put_memories:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling MemoryOperationsApi->batch_put_memories: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **batch_put_request** | [**BatchPutRequest**](BatchPutRequest.md)| | + +### Return type + +[**BatchPutResponse**](BatchPutResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **cancel_operation** +> object cancel_operation(agent_id, operation_id) + +Cancel a pending async operation + +Cancel a pending async operation by removing it from the queue + +### Example + + +```python +import memora_client_api +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.MemoryOperationsApi(api_client) + agent_id = 'agent_id_example' # str | + operation_id = 'operation_id_example' # str | + + try: + # Cancel a pending async operation + api_response = await api_instance.cancel_operation(agent_id, operation_id) + print("The response of MemoryOperationsApi->cancel_operation:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling MemoryOperationsApi->cancel_operation: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **operation_id** | **str**| | + +### Return type + +**object** + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **delete_memory_unit** +> object delete_memory_unit(agent_id, unit_id) + +Delete a memory unit + +Delete a single memory unit and all its associated links (temporal, semantic, and entity links) + +### Example + + +```python +import memora_client_api +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.MemoryOperationsApi(api_client) + agent_id = 'agent_id_example' # str | + unit_id = 'unit_id_example' # str | + + try: + # Delete a memory unit + api_response = await api_instance.delete_memory_unit(agent_id, unit_id) + print("The response of MemoryOperationsApi->delete_memory_unit:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling MemoryOperationsApi->delete_memory_unit: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **unit_id** | **str**| | + +### Return type + +**object** + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **list_memories** +> ListMemoryUnitsResponse list_memories(agent_id, fact_type=fact_type, q=q, limit=limit, offset=offset) + +List memory units + +List memory units with pagination and optional full-text search. Supports filtering by fact_type. + +### Example + + +```python +import memora_client_api +from memora_client_api.models.list_memory_units_response import ListMemoryUnitsResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.MemoryOperationsApi(api_client) + agent_id = 'agent_id_example' # str | + fact_type = 'fact_type_example' # str | (optional) + q = 'q_example' # str | (optional) + limit = 100 # int | (optional) (default to 100) + offset = 0 # int | (optional) (default to 0) + + try: + # List memory units + api_response = await api_instance.list_memories(agent_id, fact_type=fact_type, q=q, limit=limit, offset=offset) + print("The response of MemoryOperationsApi->list_memories:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling MemoryOperationsApi->list_memories: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **fact_type** | **str**| | [optional] + **q** | **str**| | [optional] + **limit** | **int**| | [optional] [default to 100] + **offset** | **int**| | [optional] [default to 0] + +### Return type + +[**ListMemoryUnitsResponse**](ListMemoryUnitsResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **list_operations** +> object list_operations(agent_id) + +List async operations + +Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations + +### Example + + +```python +import memora_client_api +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.MemoryOperationsApi(api_client) + agent_id = 'agent_id_example' # str | + + try: + # List async operations + api_response = await api_instance.list_operations(agent_id) + print("The response of MemoryOperationsApi->list_operations:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling MemoryOperationsApi->list_operations: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + +### Return type + +**object** + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **search_memories** +> SearchResponse search_memories(agent_id, search_request) + +Search memory + +Search memory using semantic similarity and spreading activation. + + The fact_type parameter is optional and must be one of: + - 'world': General knowledge about people, places, events, and things that happen + - 'agent': Memories about what the AI agent did, actions taken, and tasks performed + - 'opinion': The agent's formed beliefs, perspectives, and viewpoints + +### Example + + +```python +import memora_client_api +from memora_client_api.models.search_request import SearchRequest +from memora_client_api.models.search_response import SearchResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.MemoryOperationsApi(api_client) + agent_id = 'agent_id_example' # str | + search_request = memora_client_api.SearchRequest() # SearchRequest | + + try: + # Search memory + api_response = await api_instance.search_memories(agent_id, search_request) + print("The response of MemoryOperationsApi->search_memories:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling MemoryOperationsApi->search_memories: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **search_request** | [**SearchRequest**](SearchRequest.md)| | + +### Return type + +[**SearchResponse**](SearchResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/memora-clients/python/memora_client_api/docs/PersonalityTraits.md b/memora-clients/python/memora_client_api/docs/PersonalityTraits.md new file mode 100644 index 00000000..34e82d41 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/PersonalityTraits.md @@ -0,0 +1,35 @@ +# PersonalityTraits + +Personality traits based on Big Five model. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**openness** | **float** | Openness to experience (0-1) | +**conscientiousness** | **float** | Conscientiousness (0-1) | +**extraversion** | **float** | Extraversion (0-1) | +**agreeableness** | **float** | Agreeableness (0-1) | +**neuroticism** | **float** | Neuroticism (0-1) | +**bias_strength** | **float** | How strongly personality influences opinions (0-1) | + +## Example + +```python +from memora_client_api.models.personality_traits import PersonalityTraits + +# TODO update the JSON string below +json = "{}" +# create an instance of PersonalityTraits from a JSON string +personality_traits_instance = PersonalityTraits.from_json(json) +# print the JSON string representation of the object +print(PersonalityTraits.to_json()) + +# convert the object into a dict +personality_traits_dict = personality_traits_instance.to_dict() +# create an instance of PersonalityTraits from a dict +personality_traits_from_dict = PersonalityTraits.from_dict(personality_traits_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/ReasoningApi.md b/memora-clients/python/memora_client_api/docs/ReasoningApi.md new file mode 100644 index 00000000..62a5655f --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/ReasoningApi.md @@ -0,0 +1,89 @@ +# memora_client_api.ReasoningApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**think**](ReasoningApi.md#think) | **POST** /api/v1/agents/{agent_id}/think | Think and generate answer + + +# **think** +> ThinkResponse think(agent_id, think_request) + +Think and generate answer + +Think and formulate an answer using agent identity, world facts, and opinions. + + This endpoint: + 1. Retrieves agent facts (agent's identity) + 2. Retrieves world facts relevant to the query + 3. Retrieves existing opinions (agent's perspectives) + 4. Uses LLM to formulate a contextual answer + 5. Extracts and stores any new opinions formed + 6. Returns plain text answer, the facts used, and new opinions + +### Example + + +```python +import memora_client_api +from memora_client_api.models.think_request import ThinkRequest +from memora_client_api.models.think_response import ThinkResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.ReasoningApi(api_client) + agent_id = 'agent_id_example' # str | + think_request = memora_client_api.ThinkRequest() # ThinkRequest | + + try: + # Think and generate answer + api_response = await api_instance.think(agent_id, think_request) + print("The response of ReasoningApi->think:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling ReasoningApi->think: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **think_request** | [**ThinkRequest**](ThinkRequest.md)| | + +### Return type + +[**ThinkResponse**](ThinkResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/memora-clients/python/memora_client_api/docs/SearchRequest.md b/memora-clients/python/memora_client_api/docs/SearchRequest.md new file mode 100644 index 00000000..6bd363ad --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/SearchRequest.md @@ -0,0 +1,35 @@ +# SearchRequest + +Request model for search endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**query** | **str** | | +**fact_type** | **List[str]** | | [optional] +**thinking_budget** | **int** | | [optional] [default to 100] +**max_tokens** | **int** | | [optional] [default to 4096] +**trace** | **bool** | | [optional] [default to False] +**question_date** | **str** | | [optional] + +## Example + +```python +from memora_client_api.models.search_request import SearchRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of SearchRequest from a JSON string +search_request_instance = SearchRequest.from_json(json) +# print the JSON string representation of the object +print(SearchRequest.to_json()) + +# convert the object into a dict +search_request_dict = search_request_instance.to_dict() +# create an instance of SearchRequest from a dict +search_request_from_dict = SearchRequest.from_dict(search_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/SearchResponse.md b/memora-clients/python/memora_client_api/docs/SearchResponse.md new file mode 100644 index 00000000..37e17f9e --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/SearchResponse.md @@ -0,0 +1,31 @@ +# SearchResponse + +Response model for search endpoints. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**results** | [**List[SearchResult]**](SearchResult.md) | | +**trace** | **Dict[str, object]** | | [optional] + +## Example + +```python +from memora_client_api.models.search_response import SearchResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of SearchResponse from a JSON string +search_response_instance = SearchResponse.from_json(json) +# print the JSON string representation of the object +print(SearchResponse.to_json()) + +# convert the object into a dict +search_response_dict = search_response_instance.to_dict() +# create an instance of SearchResponse from a dict +search_response_from_dict = SearchResponse.from_dict(search_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/SearchResult.md b/memora-clients/python/memora_client_api/docs/SearchResult.md new file mode 100644 index 00000000..389494f3 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/SearchResult.md @@ -0,0 +1,35 @@ +# SearchResult + +Single search result item. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **str** | | +**text** | **str** | | +**type** | **str** | | [optional] +**context** | **str** | | [optional] +**event_date** | **str** | | [optional] +**document_id** | **str** | | [optional] + +## Example + +```python +from memora_client_api.models.search_result import SearchResult + +# TODO update the JSON string below +json = "{}" +# create an instance of SearchResult from a JSON string +search_result_instance = SearchResult.from_json(json) +# print the JSON string representation of the object +print(SearchResult.to_json()) + +# convert the object into a dict +search_result_dict = search_result_instance.to_dict() +# create an instance of SearchResult from a dict +search_result_from_dict = SearchResult.from_dict(search_result_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/ThinkFact.md b/memora-clients/python/memora_client_api/docs/ThinkFact.md new file mode 100644 index 00000000..cbb811ac --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/ThinkFact.md @@ -0,0 +1,34 @@ +# ThinkFact + +A fact used in think response. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **str** | | [optional] +**text** | **str** | | +**type** | **str** | | [optional] +**context** | **str** | | [optional] +**event_date** | **str** | | [optional] + +## Example + +```python +from memora_client_api.models.think_fact import ThinkFact + +# TODO update the JSON string below +json = "{}" +# create an instance of ThinkFact from a JSON string +think_fact_instance = ThinkFact.from_json(json) +# print the JSON string representation of the object +print(ThinkFact.to_json()) + +# convert the object into a dict +think_fact_dict = think_fact_instance.to_dict() +# create an instance of ThinkFact from a dict +think_fact_from_dict = ThinkFact.from_dict(think_fact_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/ThinkRequest.md b/memora-clients/python/memora_client_api/docs/ThinkRequest.md new file mode 100644 index 00000000..14448a67 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/ThinkRequest.md @@ -0,0 +1,32 @@ +# ThinkRequest + +Request model for think endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**query** | **str** | | +**thinking_budget** | **int** | | [optional] [default to 50] +**context** | **str** | | [optional] + +## Example + +```python +from memora_client_api.models.think_request import ThinkRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of ThinkRequest from a JSON string +think_request_instance = ThinkRequest.from_json(json) +# print the JSON string representation of the object +print(ThinkRequest.to_json()) + +# convert the object into a dict +think_request_dict = think_request_instance.to_dict() +# create an instance of ThinkRequest from a dict +think_request_from_dict = ThinkRequest.from_dict(think_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/ThinkResponse.md b/memora-clients/python/memora_client_api/docs/ThinkResponse.md new file mode 100644 index 00000000..8ddbc4cd --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/ThinkResponse.md @@ -0,0 +1,32 @@ +# ThinkResponse + +Response model for think endpoint. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**text** | **str** | | +**based_on** | [**List[ThinkFact]**](ThinkFact.md) | | [optional] [default to []] +**new_opinions** | **List[str]** | | [optional] [default to []] + +## Example + +```python +from memora_client_api.models.think_response import ThinkResponse + +# TODO update the JSON string below +json = "{}" +# create an instance of ThinkResponse from a JSON string +think_response_instance = ThinkResponse.from_json(json) +# print the JSON string representation of the object +print(ThinkResponse.to_json()) + +# convert the object into a dict +think_response_dict = think_response_instance.to_dict() +# create an instance of ThinkResponse from a dict +think_response_from_dict = ThinkResponse.from_dict(think_response_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/UpdatePersonalityRequest.md b/memora-clients/python/memora_client_api/docs/UpdatePersonalityRequest.md new file mode 100644 index 00000000..e1d2a320 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/UpdatePersonalityRequest.md @@ -0,0 +1,30 @@ +# UpdatePersonalityRequest + +Request model for updating personality traits. + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**personality** | [**PersonalityTraits**](PersonalityTraits.md) | | + +## Example + +```python +from memora_client_api.models.update_personality_request import UpdatePersonalityRequest + +# TODO update the JSON string below +json = "{}" +# create an instance of UpdatePersonalityRequest from a JSON string +update_personality_request_instance = UpdatePersonalityRequest.from_json(json) +# print the JSON string representation of the object +print(UpdatePersonalityRequest.to_json()) + +# convert the object into a dict +update_personality_request_dict = update_personality_request_instance.to_dict() +# create an instance of UpdatePersonalityRequest from a dict +update_personality_request_from_dict = UpdatePersonalityRequest.from_dict(update_personality_request_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/ValidationError.md b/memora-clients/python/memora_client_api/docs/ValidationError.md new file mode 100644 index 00000000..ac991db6 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/ValidationError.md @@ -0,0 +1,31 @@ +# ValidationError + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**loc** | [**List[ValidationErrorLocInner]**](ValidationErrorLocInner.md) | | +**msg** | **str** | | +**type** | **str** | | + +## Example + +```python +from memora_client_api.models.validation_error import ValidationError + +# TODO update the JSON string below +json = "{}" +# create an instance of ValidationError from a JSON string +validation_error_instance = ValidationError.from_json(json) +# print the JSON string representation of the object +print(ValidationError.to_json()) + +# convert the object into a dict +validation_error_dict = validation_error_instance.to_dict() +# create an instance of ValidationError from a dict +validation_error_from_dict = ValidationError.from_dict(validation_error_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/ValidationErrorLocInner.md b/memora-clients/python/memora_client_api/docs/ValidationErrorLocInner.md new file mode 100644 index 00000000..71da0349 --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/ValidationErrorLocInner.md @@ -0,0 +1,28 @@ +# ValidationErrorLocInner + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +## Example + +```python +from memora_client_api.models.validation_error_loc_inner import ValidationErrorLocInner + +# TODO update the JSON string below +json = "{}" +# create an instance of ValidationErrorLocInner from a JSON string +validation_error_loc_inner_instance = ValidationErrorLocInner.from_json(json) +# print the JSON string representation of the object +print(ValidationErrorLocInner.to_json()) + +# convert the object into a dict +validation_error_loc_inner_dict = validation_error_loc_inner_instance.to_dict() +# create an instance of ValidationErrorLocInner from a dict +validation_error_loc_inner_from_dict = ValidationErrorLocInner.from_dict(validation_error_loc_inner_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/memora-clients/python/memora_client_api/docs/VisualizationApi.md b/memora-clients/python/memora_client_api/docs/VisualizationApi.md new file mode 100644 index 00000000..30d80ade --- /dev/null +++ b/memora-clients/python/memora_client_api/docs/VisualizationApi.md @@ -0,0 +1,80 @@ +# memora_client_api.VisualizationApi + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**get_graph**](VisualizationApi.md#get_graph) | **GET** /api/v1/agents/{agent_id}/graph | Get memory graph data + + +# **get_graph** +> GraphDataResponse get_graph(agent_id, fact_type=fact_type) + +Get memory graph data + +Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). Limited to 1000 most recent items. + +### Example + + +```python +import memora_client_api +from memora_client_api.models.graph_data_response import GraphDataResponse +from memora_client_api.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to http://localhost +# See configuration.py for a list of all supported configuration parameters. +configuration = memora_client_api.Configuration( + host = "http://localhost" +) + + +# Enter a context with an instance of the API client +async with memora_client_api.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = memora_client_api.VisualizationApi(api_client) + agent_id = 'agent_id_example' # str | + fact_type = 'fact_type_example' # str | (optional) + + try: + # Get memory graph data + api_response = await api_instance.get_graph(agent_id, fact_type=fact_type) + print("The response of VisualizationApi->get_graph:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling VisualizationApi->get_graph: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **agent_id** | **str**| | + **fact_type** | **str**| | [optional] + +### Return type + +[**GraphDataResponse**](GraphDataResponse.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | Successful Response | - | +**422** | Validation Error | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/memora-clients/python/memora_client_api/exceptions.py b/memora-clients/python/memora_client_api/exceptions.py new file mode 100644 index 00000000..c21ba3a4 --- /dev/null +++ b/memora-clients/python/memora_client_api/exceptions.py @@ -0,0 +1,219 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +from typing import Any, Optional +from typing_extensions import Self + +class OpenApiException(Exception): + """The base exception class for all OpenAPIExceptions""" + + +class ApiTypeError(OpenApiException, TypeError): + def __init__(self, msg, path_to_item=None, valid_classes=None, + key_type=None) -> None: + """ Raises an exception for TypeErrors + + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (list): a list of keys an indices to get to the + current_item + None if unset + valid_classes (tuple): the primitive classes that current item + should be an instance of + None if unset + key_type (bool): False if our value is a value in a dict + True if it is a key in a dict + False if our item is an item in a list + None if unset + """ + self.path_to_item = path_to_item + self.valid_classes = valid_classes + self.key_type = key_type + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiTypeError, self).__init__(full_msg) + + +class ApiValueError(OpenApiException, ValueError): + def __init__(self, msg, path_to_item=None) -> None: + """ + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (list) the path to the exception in the + received_data dict. None if unset + """ + + self.path_to_item = path_to_item + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiValueError, self).__init__(full_msg) + + +class ApiAttributeError(OpenApiException, AttributeError): + def __init__(self, msg, path_to_item=None) -> None: + """ + Raised when an attribute reference or assignment fails. + + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (None/list) the path to the exception in the + received_data dict + """ + self.path_to_item = path_to_item + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiAttributeError, self).__init__(full_msg) + + +class ApiKeyError(OpenApiException, KeyError): + def __init__(self, msg, path_to_item=None) -> None: + """ + Args: + msg (str): the exception message + + Keyword Args: + path_to_item (None/list) the path to the exception in the + received_data dict + """ + self.path_to_item = path_to_item + full_msg = msg + if path_to_item: + full_msg = "{0} at {1}".format(msg, render_path(path_to_item)) + super(ApiKeyError, self).__init__(full_msg) + + +class ApiException(OpenApiException): + + def __init__( + self, + status=None, + reason=None, + http_resp=None, + *, + body: Optional[str] = None, + data: Optional[Any] = None, + ) -> None: + self.status = status + self.reason = reason + self.body = body + self.data = data + self.headers = None + + if http_resp: + if self.status is None: + self.status = http_resp.status + if self.reason is None: + self.reason = http_resp.reason + if self.body is None: + try: + self.body = http_resp.data.decode('utf-8') + except Exception: + pass + self.headers = http_resp.getheaders() + + @classmethod + def from_response( + cls, + *, + http_resp, + body: Optional[str], + data: Optional[Any], + ) -> Self: + if http_resp.status == 400: + raise BadRequestException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 401: + raise UnauthorizedException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 403: + raise ForbiddenException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 404: + raise NotFoundException(http_resp=http_resp, body=body, data=data) + + # Added new conditions for 409 and 422 + if http_resp.status == 409: + raise ConflictException(http_resp=http_resp, body=body, data=data) + + if http_resp.status == 422: + raise UnprocessableEntityException(http_resp=http_resp, body=body, data=data) + + if 500 <= http_resp.status <= 599: + raise ServiceException(http_resp=http_resp, body=body, data=data) + raise ApiException(http_resp=http_resp, body=body, data=data) + + def __str__(self): + """Custom error messages for exception""" + error_message = "({0})\n"\ + "Reason: {1}\n".format(self.status, self.reason) + if self.headers: + error_message += "HTTP response headers: {0}\n".format( + self.headers) + + if self.body: + error_message += "HTTP response body: {0}\n".format(self.body) + + if self.data: + error_message += "HTTP response data: {0}\n".format(self.data) + + return error_message + + +class BadRequestException(ApiException): + pass + + +class NotFoundException(ApiException): + pass + + +class UnauthorizedException(ApiException): + pass + + +class ForbiddenException(ApiException): + pass + + +class ServiceException(ApiException): + pass + + +class ConflictException(ApiException): + """Exception for HTTP 409 Conflict.""" + pass + + +class UnprocessableEntityException(ApiException): + """Exception for HTTP 422 Unprocessable Entity.""" + pass + + +def render_path(path_to_item): + """Returns a string representation of a path""" + result = "" + for pth in path_to_item: + if isinstance(pth, int): + result += "[{0}]".format(pth) + else: + result += "['{0}']".format(pth) + return result diff --git a/memora-clients/python/memora_client_api/models/__init__.py b/memora-clients/python/memora_client_api/models/__init__.py new file mode 100644 index 00000000..74e16184 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/__init__.py @@ -0,0 +1,42 @@ +# coding: utf-8 + +# flake8: noqa +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + +# import models into model package +from memora_client_api.models.add_background_request import AddBackgroundRequest +from memora_client_api.models.agent_list_item import AgentListItem +from memora_client_api.models.agent_list_response import AgentListResponse +from memora_client_api.models.agent_profile_response import AgentProfileResponse +from memora_client_api.models.background_response import BackgroundResponse +from memora_client_api.models.batch_put_async_response import BatchPutAsyncResponse +from memora_client_api.models.batch_put_request import BatchPutRequest +from memora_client_api.models.batch_put_response import BatchPutResponse +from memora_client_api.models.create_agent_request import CreateAgentRequest +from memora_client_api.models.delete_response import DeleteResponse +from memora_client_api.models.document_response import DocumentResponse +from memora_client_api.models.graph_data_response import GraphDataResponse +from memora_client_api.models.http_validation_error import HTTPValidationError +from memora_client_api.models.list_documents_response import ListDocumentsResponse +from memora_client_api.models.list_memory_units_response import ListMemoryUnitsResponse +from memora_client_api.models.memory_item import MemoryItem +from memora_client_api.models.personality_traits import PersonalityTraits +from memora_client_api.models.search_request import SearchRequest +from memora_client_api.models.search_response import SearchResponse +from memora_client_api.models.search_result import SearchResult +from memora_client_api.models.think_fact import ThinkFact +from memora_client_api.models.think_request import ThinkRequest +from memora_client_api.models.think_response import ThinkResponse +from memora_client_api.models.update_personality_request import UpdatePersonalityRequest +from memora_client_api.models.validation_error import ValidationError +from memora_client_api.models.validation_error_loc_inner import ValidationErrorLocInner + diff --git a/memora-clients/python/memora_client_api/models/add_background_request.py b/memora-clients/python/memora_client_api/models/add_background_request.py new file mode 100644 index 00000000..6c23eca1 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/add_background_request.py @@ -0,0 +1,89 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class AddBackgroundRequest(BaseModel): + """ + Request model for adding/merging background information. + """ # noqa: E501 + content: StrictStr = Field(description="New background information to add or merge") + update_personality: Optional[StrictBool] = Field(default=True, description="If true, infer Big Five personality traits from the merged background (default: true)") + __properties: ClassVar[List[str]] = ["content", "update_personality"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AddBackgroundRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AddBackgroundRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": obj.get("content"), + "update_personality": obj.get("update_personality") if obj.get("update_personality") is not None else True + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/agent_list_item.py b/memora-clients/python/memora_client_api/models/agent_list_item.py new file mode 100644 index 00000000..d4c09735 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/agent_list_item.py @@ -0,0 +1,111 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from memora_client_api.models.personality_traits import PersonalityTraits +from typing import Optional, Set +from typing_extensions import Self + +class AgentListItem(BaseModel): + """ + Agent list item with profile summary. + """ # noqa: E501 + agent_id: StrictStr + name: StrictStr + personality: PersonalityTraits + background: StrictStr + created_at: Optional[StrictStr] = None + updated_at: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["agent_id", "name", "personality", "background", "created_at", "updated_at"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AgentListItem from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of personality + if self.personality: + _dict['personality'] = self.personality.to_dict() + # set to None if created_at (nullable) is None + # and model_fields_set contains the field + if self.created_at is None and "created_at" in self.model_fields_set: + _dict['created_at'] = None + + # set to None if updated_at (nullable) is None + # and model_fields_set contains the field + if self.updated_at is None and "updated_at" in self.model_fields_set: + _dict['updated_at'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AgentListItem from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "agent_id": obj.get("agent_id"), + "name": obj.get("name"), + "personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None, + "background": obj.get("background"), + "created_at": obj.get("created_at"), + "updated_at": obj.get("updated_at") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/agent_list_response.py b/memora-clients/python/memora_client_api/models/agent_list_response.py new file mode 100644 index 00000000..c5bf8dd8 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/agent_list_response.py @@ -0,0 +1,95 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict +from typing import Any, ClassVar, Dict, List +from memora_client_api.models.agent_list_item import AgentListItem +from typing import Optional, Set +from typing_extensions import Self + +class AgentListResponse(BaseModel): + """ + Response model for listing all agents. + """ # noqa: E501 + agents: List[AgentListItem] + __properties: ClassVar[List[str]] = ["agents"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AgentListResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in agents (list) + _items = [] + if self.agents: + for _item_agents in self.agents: + if _item_agents: + _items.append(_item_agents.to_dict()) + _dict['agents'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AgentListResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "agents": [AgentListItem.from_dict(_item) for _item in obj["agents"]] if obj.get("agents") is not None else None + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/agent_profile_response.py b/memora-clients/python/memora_client_api/models/agent_profile_response.py new file mode 100644 index 00000000..1bbe5965 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/agent_profile_response.py @@ -0,0 +1,97 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from memora_client_api.models.personality_traits import PersonalityTraits +from typing import Optional, Set +from typing_extensions import Self + +class AgentProfileResponse(BaseModel): + """ + Response model for agent profile. + """ # noqa: E501 + agent_id: StrictStr + name: StrictStr + personality: PersonalityTraits + background: StrictStr + __properties: ClassVar[List[str]] = ["agent_id", "name", "personality", "background"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AgentProfileResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of personality + if self.personality: + _dict['personality'] = self.personality.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AgentProfileResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "agent_id": obj.get("agent_id"), + "name": obj.get("name"), + "personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None, + "background": obj.get("background") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/background_response.py b/memora-clients/python/memora_client_api/models/background_response.py new file mode 100644 index 00000000..5968d9ef --- /dev/null +++ b/memora-clients/python/memora_client_api/models/background_response.py @@ -0,0 +1,98 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from memora_client_api.models.personality_traits import PersonalityTraits +from typing import Optional, Set +from typing_extensions import Self + +class BackgroundResponse(BaseModel): + """ + Response model for background update. + """ # noqa: E501 + background: StrictStr + personality: Optional[PersonalityTraits] = None + __properties: ClassVar[List[str]] = ["background", "personality"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of BackgroundResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of personality + if self.personality: + _dict['personality'] = self.personality.to_dict() + # set to None if personality (nullable) is None + # and model_fields_set contains the field + if self.personality is None and "personality" in self.model_fields_set: + _dict['personality'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of BackgroundResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "background": obj.get("background"), + "personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/batch_put_async_response.py b/memora-clients/python/memora_client_api/models/batch_put_async_response.py new file mode 100644 index 00000000..89ec5108 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/batch_put_async_response.py @@ -0,0 +1,102 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class BatchPutAsyncResponse(BaseModel): + """ + Response model for async batch put endpoint. + """ # noqa: E501 + success: StrictBool + message: StrictStr + agent_id: StrictStr + document_id: Optional[StrictStr] = None + items_count: StrictInt + queued: StrictBool + __properties: ClassVar[List[str]] = ["success", "message", "agent_id", "document_id", "items_count", "queued"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of BatchPutAsyncResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if document_id (nullable) is None + # and model_fields_set contains the field + if self.document_id is None and "document_id" in self.model_fields_set: + _dict['document_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of BatchPutAsyncResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "success": obj.get("success"), + "message": obj.get("message"), + "agent_id": obj.get("agent_id"), + "document_id": obj.get("document_id"), + "items_count": obj.get("items_count"), + "queued": obj.get("queued") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/batch_put_request.py b/memora-clients/python/memora_client_api/models/batch_put_request.py new file mode 100644 index 00000000..74c58748 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/batch_put_request.py @@ -0,0 +1,102 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from memora_client_api.models.memory_item import MemoryItem +from typing import Optional, Set +from typing_extensions import Self + +class BatchPutRequest(BaseModel): + """ + Request model for batch put endpoint. + """ # noqa: E501 + items: List[MemoryItem] + document_id: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["items", "document_id"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of BatchPutRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in items (list) + _items = [] + if self.items: + for _item_items in self.items: + if _item_items: + _items.append(_item_items.to_dict()) + _dict['items'] = _items + # set to None if document_id (nullable) is None + # and model_fields_set contains the field + if self.document_id is None and "document_id" in self.model_fields_set: + _dict['document_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of BatchPutRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "items": [MemoryItem.from_dict(_item) for _item in obj["items"]] if obj.get("items") is not None else None, + "document_id": obj.get("document_id") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/batch_put_response.py b/memora-clients/python/memora_client_api/models/batch_put_response.py new file mode 100644 index 00000000..377442ec --- /dev/null +++ b/memora-clients/python/memora_client_api/models/batch_put_response.py @@ -0,0 +1,100 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class BatchPutResponse(BaseModel): + """ + Response model for batch put endpoint. + """ # noqa: E501 + success: StrictBool + message: StrictStr + agent_id: StrictStr + document_id: Optional[StrictStr] = None + items_count: StrictInt + __properties: ClassVar[List[str]] = ["success", "message", "agent_id", "document_id", "items_count"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of BatchPutResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if document_id (nullable) is None + # and model_fields_set contains the field + if self.document_id is None and "document_id" in self.model_fields_set: + _dict['document_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of BatchPutResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "success": obj.get("success"), + "message": obj.get("message"), + "agent_id": obj.get("agent_id"), + "document_id": obj.get("document_id"), + "items_count": obj.get("items_count") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/create_agent_request.py b/memora-clients/python/memora_client_api/models/create_agent_request.py new file mode 100644 index 00000000..e157ae9f --- /dev/null +++ b/memora-clients/python/memora_client_api/models/create_agent_request.py @@ -0,0 +1,110 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from memora_client_api.models.personality_traits import PersonalityTraits +from typing import Optional, Set +from typing_extensions import Self + +class CreateAgentRequest(BaseModel): + """ + Request model for creating/updating an agent. + """ # noqa: E501 + name: Optional[StrictStr] = None + personality: Optional[PersonalityTraits] = None + background: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["name", "personality", "background"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of CreateAgentRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of personality + if self.personality: + _dict['personality'] = self.personality.to_dict() + # set to None if name (nullable) is None + # and model_fields_set contains the field + if self.name is None and "name" in self.model_fields_set: + _dict['name'] = None + + # set to None if personality (nullable) is None + # and model_fields_set contains the field + if self.personality is None and "personality" in self.model_fields_set: + _dict['personality'] = None + + # set to None if background (nullable) is None + # and model_fields_set contains the field + if self.background is None and "background" in self.model_fields_set: + _dict['background'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of CreateAgentRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "name": obj.get("name"), + "personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None, + "background": obj.get("background") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/delete_response.py b/memora-clients/python/memora_client_api/models/delete_response.py new file mode 100644 index 00000000..c1b879a3 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/delete_response.py @@ -0,0 +1,89 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self + +class DeleteResponse(BaseModel): + """ + Response model for delete operations. + """ # noqa: E501 + success: StrictBool + message: StrictStr + __properties: ClassVar[List[str]] = ["success", "message"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of DeleteResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of DeleteResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "success": obj.get("success"), + "message": obj.get("message") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/document_response.py b/memora-clients/python/memora_client_api/models/document_response.py new file mode 100644 index 00000000..1a4f403d --- /dev/null +++ b/memora-clients/python/memora_client_api/models/document_response.py @@ -0,0 +1,104 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class DocumentResponse(BaseModel): + """ + Response model for get document endpoint. + """ # noqa: E501 + id: StrictStr + agent_id: StrictStr + original_text: StrictStr + content_hash: Optional[StrictStr] + created_at: StrictStr + updated_at: StrictStr + memory_unit_count: StrictInt + __properties: ClassVar[List[str]] = ["id", "agent_id", "original_text", "content_hash", "created_at", "updated_at", "memory_unit_count"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of DocumentResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if content_hash (nullable) is None + # and model_fields_set contains the field + if self.content_hash is None and "content_hash" in self.model_fields_set: + _dict['content_hash'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of DocumentResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "agent_id": obj.get("agent_id"), + "original_text": obj.get("original_text"), + "content_hash": obj.get("content_hash"), + "created_at": obj.get("created_at"), + "updated_at": obj.get("updated_at"), + "memory_unit_count": obj.get("memory_unit_count") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/graph_data_response.py b/memora-clients/python/memora_client_api/models/graph_data_response.py new file mode 100644 index 00000000..0309dbb7 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/graph_data_response.py @@ -0,0 +1,93 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self + +class GraphDataResponse(BaseModel): + """ + Response model for graph data endpoint. + """ # noqa: E501 + nodes: List[Dict[str, Any]] + edges: List[Dict[str, Any]] + table_rows: List[Dict[str, Any]] + total_units: StrictInt + __properties: ClassVar[List[str]] = ["nodes", "edges", "table_rows", "total_units"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of GraphDataResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of GraphDataResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "nodes": obj.get("nodes"), + "edges": obj.get("edges"), + "table_rows": obj.get("table_rows"), + "total_units": obj.get("total_units") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/http_validation_error.py b/memora-clients/python/memora_client_api/models/http_validation_error.py new file mode 100644 index 00000000..ca64c8b0 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/http_validation_error.py @@ -0,0 +1,95 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict +from typing import Any, ClassVar, Dict, List, Optional +from memora_client_api.models.validation_error import ValidationError +from typing import Optional, Set +from typing_extensions import Self + +class HTTPValidationError(BaseModel): + """ + HTTPValidationError + """ # noqa: E501 + detail: Optional[List[ValidationError]] = None + __properties: ClassVar[List[str]] = ["detail"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of HTTPValidationError from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in detail (list) + _items = [] + if self.detail: + for _item_detail in self.detail: + if _item_detail: + _items.append(_item_detail.to_dict()) + _dict['detail'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of HTTPValidationError from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "detail": [ValidationError.from_dict(_item) for _item in obj["detail"]] if obj.get("detail") is not None else None + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/list_documents_response.py b/memora-clients/python/memora_client_api/models/list_documents_response.py new file mode 100644 index 00000000..13447ff3 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/list_documents_response.py @@ -0,0 +1,93 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self + +class ListDocumentsResponse(BaseModel): + """ + Response model for list documents endpoint. + """ # noqa: E501 + items: List[Dict[str, Any]] + total: StrictInt + limit: StrictInt + offset: StrictInt + __properties: ClassVar[List[str]] = ["items", "total", "limit", "offset"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ListDocumentsResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ListDocumentsResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "items": obj.get("items"), + "total": obj.get("total"), + "limit": obj.get("limit"), + "offset": obj.get("offset") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/list_memory_units_response.py b/memora-clients/python/memora_client_api/models/list_memory_units_response.py new file mode 100644 index 00000000..93f33bee --- /dev/null +++ b/memora-clients/python/memora_client_api/models/list_memory_units_response.py @@ -0,0 +1,93 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self + +class ListMemoryUnitsResponse(BaseModel): + """ + Response model for list memory units endpoint. + """ # noqa: E501 + items: List[Dict[str, Any]] + total: StrictInt + limit: StrictInt + offset: StrictInt + __properties: ClassVar[List[str]] = ["items", "total", "limit", "offset"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ListMemoryUnitsResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ListMemoryUnitsResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "items": obj.get("items"), + "total": obj.get("total"), + "limit": obj.get("limit"), + "offset": obj.get("offset") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/memory_item.py b/memora-clients/python/memora_client_api/models/memory_item.py new file mode 100644 index 00000000..73004af1 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/memory_item.py @@ -0,0 +1,102 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class MemoryItem(BaseModel): + """ + Single memory item for batch put. + """ # noqa: E501 + content: StrictStr + event_date: Optional[datetime] = None + context: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["content", "event_date", "context"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MemoryItem from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if event_date (nullable) is None + # and model_fields_set contains the field + if self.event_date is None and "event_date" in self.model_fields_set: + _dict['event_date'] = None + + # set to None if context (nullable) is None + # and model_fields_set contains the field + if self.context is None and "context" in self.model_fields_set: + _dict['context'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MemoryItem from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "content": obj.get("content"), + "event_date": obj.get("event_date"), + "context": obj.get("context") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/personality_traits.py b/memora-clients/python/memora_client_api/models/personality_traits.py new file mode 100644 index 00000000..1adf4759 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/personality_traits.py @@ -0,0 +1,98 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List, Union +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class PersonalityTraits(BaseModel): + """ + Personality traits based on Big Five model. + """ # noqa: E501 + openness: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Openness to experience (0-1)") + conscientiousness: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Conscientiousness (0-1)") + extraversion: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Extraversion (0-1)") + agreeableness: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Agreeableness (0-1)") + neuroticism: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="Neuroticism (0-1)") + bias_strength: Union[Annotated[float, Field(le=1.0, strict=True, ge=0.0)], Annotated[int, Field(le=1, strict=True, ge=0)]] = Field(description="How strongly personality influences opinions (0-1)") + __properties: ClassVar[List[str]] = ["openness", "conscientiousness", "extraversion", "agreeableness", "neuroticism", "bias_strength"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of PersonalityTraits from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of PersonalityTraits from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "openness": obj.get("openness"), + "conscientiousness": obj.get("conscientiousness"), + "extraversion": obj.get("extraversion"), + "agreeableness": obj.get("agreeableness"), + "neuroticism": obj.get("neuroticism"), + "bias_strength": obj.get("bias_strength") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/search_request.py b/memora-clients/python/memora_client_api/models/search_request.py new file mode 100644 index 00000000..3264cf4a --- /dev/null +++ b/memora-clients/python/memora_client_api/models/search_request.py @@ -0,0 +1,107 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictBool, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class SearchRequest(BaseModel): + """ + Request model for search endpoint. + """ # noqa: E501 + query: StrictStr + fact_type: Optional[List[StrictStr]] = None + thinking_budget: Optional[StrictInt] = 100 + max_tokens: Optional[StrictInt] = 4096 + trace: Optional[StrictBool] = False + question_date: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["query", "fact_type", "thinking_budget", "max_tokens", "trace", "question_date"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of SearchRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if fact_type (nullable) is None + # and model_fields_set contains the field + if self.fact_type is None and "fact_type" in self.model_fields_set: + _dict['fact_type'] = None + + # set to None if question_date (nullable) is None + # and model_fields_set contains the field + if self.question_date is None and "question_date" in self.model_fields_set: + _dict['question_date'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of SearchRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "query": obj.get("query"), + "fact_type": obj.get("fact_type"), + "thinking_budget": obj.get("thinking_budget") if obj.get("thinking_budget") is not None else 100, + "max_tokens": obj.get("max_tokens") if obj.get("max_tokens") is not None else 4096, + "trace": obj.get("trace") if obj.get("trace") is not None else False, + "question_date": obj.get("question_date") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/search_response.py b/memora-clients/python/memora_client_api/models/search_response.py new file mode 100644 index 00000000..3a274e6c --- /dev/null +++ b/memora-clients/python/memora_client_api/models/search_response.py @@ -0,0 +1,102 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict +from typing import Any, ClassVar, Dict, List, Optional +from memora_client_api.models.search_result import SearchResult +from typing import Optional, Set +from typing_extensions import Self + +class SearchResponse(BaseModel): + """ + Response model for search endpoints. + """ # noqa: E501 + results: List[SearchResult] + trace: Optional[Dict[str, Any]] = None + __properties: ClassVar[List[str]] = ["results", "trace"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of SearchResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in results (list) + _items = [] + if self.results: + for _item_results in self.results: + if _item_results: + _items.append(_item_results.to_dict()) + _dict['results'] = _items + # set to None if trace (nullable) is None + # and model_fields_set contains the field + if self.trace is None and "trace" in self.model_fields_set: + _dict['trace'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of SearchResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "results": [SearchResult.from_dict(_item) for _item in obj["results"]] if obj.get("results") is not None else None, + "trace": obj.get("trace") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/search_result.py b/memora-clients/python/memora_client_api/models/search_result.py new file mode 100644 index 00000000..7b37d5e0 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/search_result.py @@ -0,0 +1,117 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class SearchResult(BaseModel): + """ + Single search result item. + """ # noqa: E501 + id: StrictStr + text: StrictStr + type: Optional[StrictStr] = None + context: Optional[StrictStr] = None + event_date: Optional[StrictStr] = None + document_id: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["id", "text", "type", "context", "event_date", "document_id"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of SearchResult from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if type (nullable) is None + # and model_fields_set contains the field + if self.type is None and "type" in self.model_fields_set: + _dict['type'] = None + + # set to None if context (nullable) is None + # and model_fields_set contains the field + if self.context is None and "context" in self.model_fields_set: + _dict['context'] = None + + # set to None if event_date (nullable) is None + # and model_fields_set contains the field + if self.event_date is None and "event_date" in self.model_fields_set: + _dict['event_date'] = None + + # set to None if document_id (nullable) is None + # and model_fields_set contains the field + if self.document_id is None and "document_id" in self.model_fields_set: + _dict['document_id'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of SearchResult from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "text": obj.get("text"), + "type": obj.get("type"), + "context": obj.get("context"), + "event_date": obj.get("event_date"), + "document_id": obj.get("document_id") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/think_fact.py b/memora-clients/python/memora_client_api/models/think_fact.py new file mode 100644 index 00000000..1e3332f7 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/think_fact.py @@ -0,0 +1,115 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class ThinkFact(BaseModel): + """ + A fact used in think response. + """ # noqa: E501 + id: Optional[StrictStr] = None + text: StrictStr + type: Optional[StrictStr] = None + context: Optional[StrictStr] = None + event_date: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["id", "text", "type", "context", "event_date"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ThinkFact from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if id (nullable) is None + # and model_fields_set contains the field + if self.id is None and "id" in self.model_fields_set: + _dict['id'] = None + + # set to None if type (nullable) is None + # and model_fields_set contains the field + if self.type is None and "type" in self.model_fields_set: + _dict['type'] = None + + # set to None if context (nullable) is None + # and model_fields_set contains the field + if self.context is None and "context" in self.model_fields_set: + _dict['context'] = None + + # set to None if event_date (nullable) is None + # and model_fields_set contains the field + if self.event_date is None and "event_date" in self.model_fields_set: + _dict['event_date'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ThinkFact from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "text": obj.get("text"), + "type": obj.get("type"), + "context": obj.get("context"), + "event_date": obj.get("event_date") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/think_request.py b/memora-clients/python/memora_client_api/models/think_request.py new file mode 100644 index 00000000..6ddac465 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/think_request.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class ThinkRequest(BaseModel): + """ + Request model for think endpoint. + """ # noqa: E501 + query: StrictStr + thinking_budget: Optional[StrictInt] = 50 + context: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["query", "thinking_budget", "context"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ThinkRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if context (nullable) is None + # and model_fields_set contains the field + if self.context is None and "context" in self.model_fields_set: + _dict['context'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ThinkRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "query": obj.get("query"), + "thinking_budget": obj.get("thinking_budget") if obj.get("thinking_budget") is not None else 50, + "context": obj.get("context") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/think_response.py b/memora-clients/python/memora_client_api/models/think_response.py new file mode 100644 index 00000000..1614e602 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/think_response.py @@ -0,0 +1,99 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from memora_client_api.models.think_fact import ThinkFact +from typing import Optional, Set +from typing_extensions import Self + +class ThinkResponse(BaseModel): + """ + Response model for think endpoint. + """ # noqa: E501 + text: StrictStr + based_on: Optional[List[ThinkFact]] = None + new_opinions: Optional[List[StrictStr]] = None + __properties: ClassVar[List[str]] = ["text", "based_on", "new_opinions"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ThinkResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in based_on (list) + _items = [] + if self.based_on: + for _item_based_on in self.based_on: + if _item_based_on: + _items.append(_item_based_on.to_dict()) + _dict['based_on'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ThinkResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "text": obj.get("text"), + "based_on": [ThinkFact.from_dict(_item) for _item in obj["based_on"]] if obj.get("based_on") is not None else None, + "new_opinions": obj.get("new_opinions") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/update_personality_request.py b/memora-clients/python/memora_client_api/models/update_personality_request.py new file mode 100644 index 00000000..88f953b3 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/update_personality_request.py @@ -0,0 +1,91 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict +from typing import Any, ClassVar, Dict, List +from memora_client_api.models.personality_traits import PersonalityTraits +from typing import Optional, Set +from typing_extensions import Self + +class UpdatePersonalityRequest(BaseModel): + """ + Request model for updating personality traits. + """ # noqa: E501 + personality: PersonalityTraits + __properties: ClassVar[List[str]] = ["personality"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UpdatePersonalityRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of personality + if self.personality: + _dict['personality'] = self.personality.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpdatePersonalityRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "personality": PersonalityTraits.from_dict(obj["personality"]) if obj.get("personality") is not None else None + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/validation_error.py b/memora-clients/python/memora_client_api/models/validation_error.py new file mode 100644 index 00000000..7bb22942 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/validation_error.py @@ -0,0 +1,99 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List +from memora_client_api.models.validation_error_loc_inner import ValidationErrorLocInner +from typing import Optional, Set +from typing_extensions import Self + +class ValidationError(BaseModel): + """ + ValidationError + """ # noqa: E501 + loc: List[ValidationErrorLocInner] + msg: StrictStr + type: StrictStr + __properties: ClassVar[List[str]] = ["loc", "msg", "type"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of ValidationError from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in loc (list) + _items = [] + if self.loc: + for _item_loc in self.loc: + if _item_loc: + _items.append(_item_loc.to_dict()) + _dict['loc'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of ValidationError from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "loc": [ValidationErrorLocInner.from_dict(_item) for _item in obj["loc"]] if obj.get("loc") is not None else None, + "msg": obj.get("msg"), + "type": obj.get("type") + }) + return _obj + + diff --git a/memora-clients/python/memora_client_api/models/validation_error_loc_inner.py b/memora-clients/python/memora_client_api/models/validation_error_loc_inner.py new file mode 100644 index 00000000..9090ccf8 --- /dev/null +++ b/memora-clients/python/memora_client_api/models/validation_error_loc_inner.py @@ -0,0 +1,138 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +from inspect import getfullargspec +import json +import pprint +import re # noqa: F401 +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, ValidationError, field_validator +from typing import Optional +from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict +from typing_extensions import Literal, Self +from pydantic import Field + +VALIDATIONERRORLOCINNER_ANY_OF_SCHEMAS = ["int", "str"] + +class ValidationErrorLocInner(BaseModel): + """ + ValidationErrorLocInner + """ + + # data type: str + anyof_schema_1_validator: Optional[StrictStr] = None + # data type: int + anyof_schema_2_validator: Optional[StrictInt] = None + if TYPE_CHECKING: + actual_instance: Optional[Union[int, str]] = None + else: + actual_instance: Any = None + any_of_schemas: Set[str] = { "int", "str" } + + model_config = { + "validate_assignment": True, + "protected_namespaces": (), + } + + def __init__(self, *args, **kwargs) -> None: + if args: + if len(args) > 1: + raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`") + if kwargs: + raise ValueError("If a position argument is used, keyword arguments cannot be used.") + super().__init__(actual_instance=args[0]) + else: + super().__init__(**kwargs) + + @field_validator('actual_instance') + def actual_instance_must_validate_anyof(cls, v): + instance = ValidationErrorLocInner.model_construct() + error_messages = [] + # validate data type: str + try: + instance.anyof_schema_1_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # validate data type: int + try: + instance.anyof_schema_2_validator = v + return v + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + if error_messages: + # no match + raise ValueError("No match found when setting the actual_instance in ValidationErrorLocInner with anyOf schemas: int, str. Details: " + ", ".join(error_messages)) + else: + return v + + @classmethod + def from_dict(cls, obj: Dict[str, Any]) -> Self: + return cls.from_json(json.dumps(obj)) + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Returns the object represented by the json string""" + instance = cls.model_construct() + error_messages = [] + # deserialize data into str + try: + # validation + instance.anyof_schema_1_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_1_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + # deserialize data into int + try: + # validation + instance.anyof_schema_2_validator = json.loads(json_str) + # assign value to actual_instance + instance.actual_instance = instance.anyof_schema_2_validator + return instance + except (ValidationError, ValueError) as e: + error_messages.append(str(e)) + + if error_messages: + # no match + raise ValueError("No match found when deserializing the JSON string into ValidationErrorLocInner with anyOf schemas: int, str. Details: " + ", ".join(error_messages)) + else: + return instance + + def to_json(self) -> str: + """Returns the JSON representation of the actual instance""" + if self.actual_instance is None: + return "null" + + if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json): + return self.actual_instance.to_json() + else: + return json.dumps(self.actual_instance) + + def to_dict(self) -> Optional[Union[Dict[str, Any], int, str]]: + """Returns the dict representation of the actual instance""" + if self.actual_instance is None: + return None + + if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict): + return self.actual_instance.to_dict() + else: + return self.actual_instance + + def to_str(self) -> str: + """Returns the string representation of the actual instance""" + return pprint.pformat(self.model_dump()) + + diff --git a/memora-clients/python/memora_client_api/rest.py b/memora-clients/python/memora_client_api/rest.py new file mode 100644 index 00000000..ab2e8bc6 --- /dev/null +++ b/memora-clients/python/memora_client_api/rest.py @@ -0,0 +1,213 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import io +import json +import re +import ssl +from typing import Optional, Union + +import aiohttp +import aiohttp_retry + +from memora_client_api.exceptions import ApiException, ApiValueError + +RESTResponseType = aiohttp.ClientResponse + +ALLOW_RETRY_METHODS = frozenset({'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PUT', 'TRACE'}) + +class RESTResponse(io.IOBase): + + def __init__(self, resp) -> None: + self.response = resp + self.status = resp.status + self.reason = resp.reason + self.data = None + + async def read(self): + if self.data is None: + self.data = await self.response.read() + return self.data + + def getheaders(self): + """Returns a CIMultiDictProxy of the response headers.""" + return self.response.headers + + def getheader(self, name, default=None): + """Returns a given response header.""" + return self.response.headers.get(name, default) + + +class RESTClientObject: + + def __init__(self, configuration) -> None: + + # maxsize is number of requests to host that are allowed in parallel + self.maxsize = configuration.connection_pool_maxsize + + self.ssl_context = ssl.create_default_context( + cafile=configuration.ssl_ca_cert, + cadata=configuration.ca_cert_data, + ) + if configuration.cert_file: + self.ssl_context.load_cert_chain( + configuration.cert_file, keyfile=configuration.key_file + ) + + if not configuration.verify_ssl: + self.ssl_context.check_hostname = False + self.ssl_context.verify_mode = ssl.CERT_NONE + + self.proxy = configuration.proxy + self.proxy_headers = configuration.proxy_headers + + self.retries = configuration.retries + + self.pool_manager: Optional[aiohttp.ClientSession] = None + self.retry_client: Optional[aiohttp_retry.RetryClient] = None + + async def close(self) -> None: + if self.pool_manager: + await self.pool_manager.close() + if self.retry_client is not None: + await self.retry_client.close() + + async def request( + self, + method, + url, + headers=None, + body=None, + post_params=None, + _request_timeout=None + ): + """Execute request + + :param method: http request method + :param url: http request url + :param headers: http request headers + :param body: request json body, for `application/json` + :param post_params: request post parameters, + `application/x-www-form-urlencoded` + and `multipart/form-data` + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + """ + method = method.upper() + assert method in [ + 'GET', + 'HEAD', + 'DELETE', + 'POST', + 'PUT', + 'PATCH', + 'OPTIONS' + ] + + if post_params and body: + raise ApiValueError( + "body parameter cannot be used with post_params parameter." + ) + + post_params = post_params or {} + headers = headers or {} + # url already contains the URL query string + timeout = _request_timeout or 5 * 60 + + if 'Content-Type' not in headers: + headers['Content-Type'] = 'application/json' + + args = { + "method": method, + "url": url, + "timeout": timeout, + "headers": headers + } + + if self.proxy: + args["proxy"] = self.proxy + if self.proxy_headers: + args["proxy_headers"] = self.proxy_headers + + # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` + if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: + if re.search('json', headers['Content-Type'], re.IGNORECASE): + if body is not None: + body = json.dumps(body) + args["data"] = body + elif headers['Content-Type'] == 'application/x-www-form-urlencoded': + args["data"] = aiohttp.FormData(post_params) + elif headers['Content-Type'] == 'multipart/form-data': + # must del headers['Content-Type'], or the correct + # Content-Type which generated by aiohttp + del headers['Content-Type'] + data = aiohttp.FormData() + for param in post_params: + k, v = param + if isinstance(v, tuple) and len(v) == 3: + data.add_field( + k, + value=v[1], + filename=v[0], + content_type=v[2] + ) + else: + # Ensures that dict objects are serialized + if isinstance(v, dict): + v = json.dumps(v) + elif isinstance(v, int): + v = str(v) + data.add_field(k, v) + args["data"] = data + + # Pass a `bytes` or `str` parameter directly in the body to support + # other content types than Json when `body` argument is provided + # in serialized form + elif isinstance(body, str) or isinstance(body, bytes): + args["data"] = body + else: + # Cannot generate the request from given parameters + msg = """Cannot prepare a request message for provided + arguments. Please check that your arguments match + declared content type.""" + raise ApiException(status=0, reason=msg) + + pool_manager: Union[aiohttp.ClientSession, aiohttp_retry.RetryClient] + + # https pool manager + if self.pool_manager is None: + self.pool_manager = aiohttp.ClientSession( + connector=aiohttp.TCPConnector(limit=self.maxsize, ssl=self.ssl_context), + trust_env=True, + ) + pool_manager = self.pool_manager + + if self.retries is not None and method in ALLOW_RETRY_METHODS: + if self.retry_client is None: + self.retry_client = aiohttp_retry.RetryClient( + client_session=self.pool_manager, + retry_options=aiohttp_retry.ExponentialRetry( + attempts=self.retries, + factor=2.0, + start_timeout=0.1, + max_timeout=120.0 + ) + ) + pool_manager = self.retry_client + + r = await pool_manager.request(**args) + + return RESTResponse(r) diff --git a/memora-clients/python/memora_client_api/test/__init__.py b/memora-clients/python/memora_client_api/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/memora-clients/python/memora_client_api/test/test_add_background_request.py b/memora-clients/python/memora_client_api/test/test_add_background_request.py new file mode 100644 index 00000000..3ed4caa8 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_add_background_request.py @@ -0,0 +1,53 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.add_background_request import AddBackgroundRequest + +class TestAddBackgroundRequest(unittest.TestCase): + """AddBackgroundRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> AddBackgroundRequest: + """Test AddBackgroundRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `AddBackgroundRequest` + """ + model = AddBackgroundRequest() + if include_optional: + return AddBackgroundRequest( + content = '', + update_personality = True + ) + else: + return AddBackgroundRequest( + content = '', + ) + """ + + def testAddBackgroundRequest(self): + """Test AddBackgroundRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_agent_list_item.py b/memora-clients/python/memora_client_api/test/test_agent_list_item.py new file mode 100644 index 00000000..5701398b --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_agent_list_item.py @@ -0,0 +1,60 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.agent_list_item import AgentListItem + +class TestAgentListItem(unittest.TestCase): + """AgentListItem unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> AgentListItem: + """Test AgentListItem + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `AgentListItem` + """ + model = AgentListItem() + if include_optional: + return AgentListItem( + agent_id = '', + name = '', + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}, + background = '', + created_at = '', + updated_at = '' + ) + else: + return AgentListItem( + agent_id = '', + name = '', + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}, + background = '', + ) + """ + + def testAgentListItem(self): + """Test AgentListItem""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_agent_list_response.py b/memora-clients/python/memora_client_api/test/test_agent_list_response.py new file mode 100644 index 00000000..f5aaa60b --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_agent_list_response.py @@ -0,0 +1,68 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.agent_list_response import AgentListResponse + +class TestAgentListResponse(unittest.TestCase): + """AgentListResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> AgentListResponse: + """Test AgentListResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `AgentListResponse` + """ + model = AgentListResponse() + if include_optional: + return AgentListResponse( + agents = [ + memora_client_api.models.agent_list_item.AgentListItem( + agent_id = '', + name = '', + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}, + background = '', + created_at = '', + updated_at = '', ) + ] + ) + else: + return AgentListResponse( + agents = [ + memora_client_api.models.agent_list_item.AgentListItem( + agent_id = '', + name = '', + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}, + background = '', + created_at = '', + updated_at = '', ) + ], + ) + """ + + def testAgentListResponse(self): + """Test AgentListResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_agent_management_api.py b/memora-clients/python/memora_client_api/test/test_agent_management_api.py new file mode 100644 index 00000000..6a0d8cb9 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_agent_management_api.py @@ -0,0 +1,80 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.api.agent_management_api import AgentManagementApi + + +class TestAgentManagementApi(unittest.IsolatedAsyncioTestCase): + """AgentManagementApi unit test stubs""" + + async def asyncSetUp(self) -> None: + self.api = AgentManagementApi() + + async def asyncTearDown(self) -> None: + await self.api.api_client.close() + + async def test_add_agent_background(self) -> None: + """Test case for add_agent_background + + Add/merge agent background + """ + pass + + async def test_clear_agent_memories(self) -> None: + """Test case for clear_agent_memories + + Clear agent memories + """ + pass + + async def test_create_or_update_agent(self) -> None: + """Test case for create_or_update_agent + + Create or update agent + """ + pass + + async def test_get_agent_profile(self) -> None: + """Test case for get_agent_profile + + Get agent profile + """ + pass + + async def test_get_agent_stats(self) -> None: + """Test case for get_agent_stats + + Get memory statistics for an agent + """ + pass + + async def test_list_agents(self) -> None: + """Test case for list_agents + + List all agents + """ + pass + + async def test_update_agent_personality(self) -> None: + """Test case for update_agent_personality + + Update agent personality + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_agent_profile_response.py b/memora-clients/python/memora_client_api/test/test_agent_profile_response.py new file mode 100644 index 00000000..d44b5d37 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_agent_profile_response.py @@ -0,0 +1,58 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.agent_profile_response import AgentProfileResponse + +class TestAgentProfileResponse(unittest.TestCase): + """AgentProfileResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> AgentProfileResponse: + """Test AgentProfileResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `AgentProfileResponse` + """ + model = AgentProfileResponse() + if include_optional: + return AgentProfileResponse( + agent_id = '', + name = '', + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}, + background = '' + ) + else: + return AgentProfileResponse( + agent_id = '', + name = '', + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}, + background = '', + ) + """ + + def testAgentProfileResponse(self): + """Test AgentProfileResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_background_response.py b/memora-clients/python/memora_client_api/test/test_background_response.py new file mode 100644 index 00000000..6b9d992a --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_background_response.py @@ -0,0 +1,53 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.background_response import BackgroundResponse + +class TestBackgroundResponse(unittest.TestCase): + """BackgroundResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> BackgroundResponse: + """Test BackgroundResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `BackgroundResponse` + """ + model = BackgroundResponse() + if include_optional: + return BackgroundResponse( + background = '', + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8} + ) + else: + return BackgroundResponse( + background = '', + ) + """ + + def testBackgroundResponse(self): + """Test BackgroundResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_batch_put_async_response.py b/memora-clients/python/memora_client_api/test/test_batch_put_async_response.py new file mode 100644 index 00000000..1b056178 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_batch_put_async_response.py @@ -0,0 +1,61 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.batch_put_async_response import BatchPutAsyncResponse + +class TestBatchPutAsyncResponse(unittest.TestCase): + """BatchPutAsyncResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> BatchPutAsyncResponse: + """Test BatchPutAsyncResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `BatchPutAsyncResponse` + """ + model = BatchPutAsyncResponse() + if include_optional: + return BatchPutAsyncResponse( + success = True, + message = '', + agent_id = '', + document_id = '', + items_count = 56, + queued = True + ) + else: + return BatchPutAsyncResponse( + success = True, + message = '', + agent_id = '', + items_count = 56, + queued = True, + ) + """ + + def testBatchPutAsyncResponse(self): + """Test BatchPutAsyncResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_batch_put_request.py b/memora-clients/python/memora_client_api/test/test_batch_put_request.py new file mode 100644 index 00000000..bf9911e3 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_batch_put_request.py @@ -0,0 +1,57 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.batch_put_request import BatchPutRequest + +class TestBatchPutRequest(unittest.TestCase): + """BatchPutRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> BatchPutRequest: + """Test BatchPutRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `BatchPutRequest` + """ + model = BatchPutRequest() + if include_optional: + return BatchPutRequest( + items = [ + {content=Alice mentioned she's working on a new ML model, context=team meeting, event_date=2024-01-15T10:30:00Z} + ], + document_id = '' + ) + else: + return BatchPutRequest( + items = [ + {content=Alice mentioned she's working on a new ML model, context=team meeting, event_date=2024-01-15T10:30:00Z} + ], + ) + """ + + def testBatchPutRequest(self): + """Test BatchPutRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_batch_put_response.py b/memora-clients/python/memora_client_api/test/test_batch_put_response.py new file mode 100644 index 00000000..01a56155 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_batch_put_response.py @@ -0,0 +1,59 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.batch_put_response import BatchPutResponse + +class TestBatchPutResponse(unittest.TestCase): + """BatchPutResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> BatchPutResponse: + """Test BatchPutResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `BatchPutResponse` + """ + model = BatchPutResponse() + if include_optional: + return BatchPutResponse( + success = True, + message = '', + agent_id = '', + document_id = '', + items_count = 56 + ) + else: + return BatchPutResponse( + success = True, + message = '', + agent_id = '', + items_count = 56, + ) + """ + + def testBatchPutResponse(self): + """Test BatchPutResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_create_agent_request.py b/memora-clients/python/memora_client_api/test/test_create_agent_request.py new file mode 100644 index 00000000..2baa987c --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_create_agent_request.py @@ -0,0 +1,53 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.create_agent_request import CreateAgentRequest + +class TestCreateAgentRequest(unittest.TestCase): + """CreateAgentRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> CreateAgentRequest: + """Test CreateAgentRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `CreateAgentRequest` + """ + model = CreateAgentRequest() + if include_optional: + return CreateAgentRequest( + name = '', + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}, + background = '' + ) + else: + return CreateAgentRequest( + ) + """ + + def testCreateAgentRequest(self): + """Test CreateAgentRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_delete_response.py b/memora-clients/python/memora_client_api/test/test_delete_response.py new file mode 100644 index 00000000..57754c42 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_delete_response.py @@ -0,0 +1,54 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.delete_response import DeleteResponse + +class TestDeleteResponse(unittest.TestCase): + """DeleteResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> DeleteResponse: + """Test DeleteResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `DeleteResponse` + """ + model = DeleteResponse() + if include_optional: + return DeleteResponse( + success = True, + message = '' + ) + else: + return DeleteResponse( + success = True, + message = '', + ) + """ + + def testDeleteResponse(self): + """Test DeleteResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_document_response.py b/memora-clients/python/memora_client_api/test/test_document_response.py new file mode 100644 index 00000000..02783fdb --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_document_response.py @@ -0,0 +1,64 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.document_response import DocumentResponse + +class TestDocumentResponse(unittest.TestCase): + """DocumentResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> DocumentResponse: + """Test DocumentResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `DocumentResponse` + """ + model = DocumentResponse() + if include_optional: + return DocumentResponse( + id = '', + agent_id = '', + original_text = '', + content_hash = '', + created_at = '', + updated_at = '', + memory_unit_count = 56 + ) + else: + return DocumentResponse( + id = '', + agent_id = '', + original_text = '', + content_hash = '', + created_at = '', + updated_at = '', + memory_unit_count = 56, + ) + """ + + def testDocumentResponse(self): + """Test DocumentResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_documents_api.py b/memora-clients/python/memora_client_api/test/test_documents_api.py new file mode 100644 index 00000000..a3190a76 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_documents_api.py @@ -0,0 +1,52 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.api.documents_api import DocumentsApi + + +class TestDocumentsApi(unittest.IsolatedAsyncioTestCase): + """DocumentsApi unit test stubs""" + + async def asyncSetUp(self) -> None: + self.api = DocumentsApi() + + async def asyncTearDown(self) -> None: + await self.api.api_client.close() + + async def test_delete_document(self) -> None: + """Test case for delete_document + + Delete a document + """ + pass + + async def test_get_document(self) -> None: + """Test case for get_document + + Get document details + """ + pass + + async def test_list_documents(self) -> None: + """Test case for list_documents + + List documents + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_graph_data_response.py b/memora-clients/python/memora_client_api/test/test_graph_data_response.py new file mode 100644 index 00000000..1b45ee0a --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_graph_data_response.py @@ -0,0 +1,70 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.graph_data_response import GraphDataResponse + +class TestGraphDataResponse(unittest.TestCase): + """GraphDataResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> GraphDataResponse: + """Test GraphDataResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `GraphDataResponse` + """ + model = GraphDataResponse() + if include_optional: + return GraphDataResponse( + nodes = [ + { } + ], + edges = [ + { } + ], + table_rows = [ + { } + ], + total_units = 56 + ) + else: + return GraphDataResponse( + nodes = [ + { } + ], + edges = [ + { } + ], + table_rows = [ + { } + ], + total_units = 56, + ) + """ + + def testGraphDataResponse(self): + """Test GraphDataResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_http_validation_error.py b/memora-clients/python/memora_client_api/test/test_http_validation_error.py new file mode 100644 index 00000000..1a18fae3 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_http_validation_error.py @@ -0,0 +1,58 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.http_validation_error import HTTPValidationError + +class TestHTTPValidationError(unittest.TestCase): + """HTTPValidationError unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> HTTPValidationError: + """Test HTTPValidationError + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `HTTPValidationError` + """ + model = HTTPValidationError() + if include_optional: + return HTTPValidationError( + detail = [ + memora_client_api.models.validation_error.ValidationError( + loc = [ + null + ], + msg = '', + type = '', ) + ] + ) + else: + return HTTPValidationError( + ) + """ + + def testHTTPValidationError(self): + """Test HTTPValidationError""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_list_documents_response.py b/memora-clients/python/memora_client_api/test/test_list_documents_response.py new file mode 100644 index 00000000..3ce1d06f --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_list_documents_response.py @@ -0,0 +1,62 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.list_documents_response import ListDocumentsResponse + +class TestListDocumentsResponse(unittest.TestCase): + """ListDocumentsResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ListDocumentsResponse: + """Test ListDocumentsResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ListDocumentsResponse` + """ + model = ListDocumentsResponse() + if include_optional: + return ListDocumentsResponse( + items = [ + { } + ], + total = 56, + limit = 56, + offset = 56 + ) + else: + return ListDocumentsResponse( + items = [ + { } + ], + total = 56, + limit = 56, + offset = 56, + ) + """ + + def testListDocumentsResponse(self): + """Test ListDocumentsResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_list_memory_units_response.py b/memora-clients/python/memora_client_api/test/test_list_memory_units_response.py new file mode 100644 index 00000000..a10f4036 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_list_memory_units_response.py @@ -0,0 +1,62 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.list_memory_units_response import ListMemoryUnitsResponse + +class TestListMemoryUnitsResponse(unittest.TestCase): + """ListMemoryUnitsResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ListMemoryUnitsResponse: + """Test ListMemoryUnitsResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ListMemoryUnitsResponse` + """ + model = ListMemoryUnitsResponse() + if include_optional: + return ListMemoryUnitsResponse( + items = [ + { } + ], + total = 56, + limit = 56, + offset = 56 + ) + else: + return ListMemoryUnitsResponse( + items = [ + { } + ], + total = 56, + limit = 56, + offset = 56, + ) + """ + + def testListMemoryUnitsResponse(self): + """Test ListMemoryUnitsResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_memory_item.py b/memora-clients/python/memora_client_api/test/test_memory_item.py new file mode 100644 index 00000000..2d4f78f6 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_memory_item.py @@ -0,0 +1,54 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.memory_item import MemoryItem + +class TestMemoryItem(unittest.TestCase): + """MemoryItem unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> MemoryItem: + """Test MemoryItem + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `MemoryItem` + """ + model = MemoryItem() + if include_optional: + return MemoryItem( + content = '', + event_date = datetime.datetime.strptime('2013-10-20 19:20:30.00', '%Y-%m-%d %H:%M:%S.%f'), + context = '' + ) + else: + return MemoryItem( + content = '', + ) + """ + + def testMemoryItem(self): + """Test MemoryItem""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_memory_operations_api.py b/memora-clients/python/memora_client_api/test/test_memory_operations_api.py new file mode 100644 index 00000000..5c3c7186 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_memory_operations_api.py @@ -0,0 +1,80 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.api.memory_operations_api import MemoryOperationsApi + + +class TestMemoryOperationsApi(unittest.IsolatedAsyncioTestCase): + """MemoryOperationsApi unit test stubs""" + + async def asyncSetUp(self) -> None: + self.api = MemoryOperationsApi() + + async def asyncTearDown(self) -> None: + await self.api.api_client.close() + + async def test_batch_put_async(self) -> None: + """Test case for batch_put_async + + Store multiple memories asynchronously + """ + pass + + async def test_batch_put_memories(self) -> None: + """Test case for batch_put_memories + + Store multiple memories + """ + pass + + async def test_cancel_operation(self) -> None: + """Test case for cancel_operation + + Cancel a pending async operation + """ + pass + + async def test_delete_memory_unit(self) -> None: + """Test case for delete_memory_unit + + Delete a memory unit + """ + pass + + async def test_list_memories(self) -> None: + """Test case for list_memories + + List memory units + """ + pass + + async def test_list_operations(self) -> None: + """Test case for list_operations + + List async operations + """ + pass + + async def test_search_memories(self) -> None: + """Test case for search_memories + + Search memory + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_personality_traits.py b/memora-clients/python/memora_client_api/test/test_personality_traits.py new file mode 100644 index 00000000..1dc01b97 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_personality_traits.py @@ -0,0 +1,62 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.personality_traits import PersonalityTraits + +class TestPersonalityTraits(unittest.TestCase): + """PersonalityTraits unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> PersonalityTraits: + """Test PersonalityTraits + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `PersonalityTraits` + """ + model = PersonalityTraits() + if include_optional: + return PersonalityTraits( + openness = 0.0, + conscientiousness = 0.0, + extraversion = 0.0, + agreeableness = 0.0, + neuroticism = 0.0, + bias_strength = 0.0 + ) + else: + return PersonalityTraits( + openness = 0.0, + conscientiousness = 0.0, + extraversion = 0.0, + agreeableness = 0.0, + neuroticism = 0.0, + bias_strength = 0.0, + ) + """ + + def testPersonalityTraits(self): + """Test PersonalityTraits""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_reasoning_api.py b/memora-clients/python/memora_client_api/test/test_reasoning_api.py new file mode 100644 index 00000000..9ecb0a15 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_reasoning_api.py @@ -0,0 +1,38 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.api.reasoning_api import ReasoningApi + + +class TestReasoningApi(unittest.IsolatedAsyncioTestCase): + """ReasoningApi unit test stubs""" + + async def asyncSetUp(self) -> None: + self.api = ReasoningApi() + + async def asyncTearDown(self) -> None: + await self.api.api_client.close() + + async def test_think(self) -> None: + """Test case for think + + Think and generate answer + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_search_request.py b/memora-clients/python/memora_client_api/test/test_search_request.py new file mode 100644 index 00000000..a5ddf0c1 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_search_request.py @@ -0,0 +1,59 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.search_request import SearchRequest + +class TestSearchRequest(unittest.TestCase): + """SearchRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> SearchRequest: + """Test SearchRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `SearchRequest` + """ + model = SearchRequest() + if include_optional: + return SearchRequest( + query = '', + fact_type = [ + '' + ], + thinking_budget = 56, + max_tokens = 56, + trace = True, + question_date = '' + ) + else: + return SearchRequest( + query = '', + ) + """ + + def testSearchRequest(self): + """Test SearchRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_search_response.py b/memora-clients/python/memora_client_api/test/test_search_response.py new file mode 100644 index 00000000..dea830f0 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_search_response.py @@ -0,0 +1,57 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.search_response import SearchResponse + +class TestSearchResponse(unittest.TestCase): + """SearchResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> SearchResponse: + """Test SearchResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `SearchResponse` + """ + model = SearchResponse() + if include_optional: + return SearchResponse( + results = [ + {context=work info, document_id=session_abc123, event_date=2024-01-15T10:30:00Z, id=123e4567-e89b-12d3-a456-426614174000, text=Alice works at Google on the AI team, type=world} + ], + trace = { } + ) + else: + return SearchResponse( + results = [ + {context=work info, document_id=session_abc123, event_date=2024-01-15T10:30:00Z, id=123e4567-e89b-12d3-a456-426614174000, text=Alice works at Google on the AI team, type=world} + ], + ) + """ + + def testSearchResponse(self): + """Test SearchResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_search_result.py b/memora-clients/python/memora_client_api/test/test_search_result.py new file mode 100644 index 00000000..3a87ea6f --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_search_result.py @@ -0,0 +1,58 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.search_result import SearchResult + +class TestSearchResult(unittest.TestCase): + """SearchResult unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> SearchResult: + """Test SearchResult + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `SearchResult` + """ + model = SearchResult() + if include_optional: + return SearchResult( + id = '', + text = '', + type = '', + context = '', + event_date = '', + document_id = '' + ) + else: + return SearchResult( + id = '', + text = '', + ) + """ + + def testSearchResult(self): + """Test SearchResult""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_think_fact.py b/memora-clients/python/memora_client_api/test/test_think_fact.py new file mode 100644 index 00000000..b562bd5b --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_think_fact.py @@ -0,0 +1,56 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.think_fact import ThinkFact + +class TestThinkFact(unittest.TestCase): + """ThinkFact unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ThinkFact: + """Test ThinkFact + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ThinkFact` + """ + model = ThinkFact() + if include_optional: + return ThinkFact( + id = '', + text = '', + type = '', + context = '', + event_date = '' + ) + else: + return ThinkFact( + text = '', + ) + """ + + def testThinkFact(self): + """Test ThinkFact""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_think_request.py b/memora-clients/python/memora_client_api/test/test_think_request.py new file mode 100644 index 00000000..0624d022 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_think_request.py @@ -0,0 +1,54 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.think_request import ThinkRequest + +class TestThinkRequest(unittest.TestCase): + """ThinkRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ThinkRequest: + """Test ThinkRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ThinkRequest` + """ + model = ThinkRequest() + if include_optional: + return ThinkRequest( + query = '', + thinking_budget = 56, + context = '' + ) + else: + return ThinkRequest( + query = '', + ) + """ + + def testThinkRequest(self): + """Test ThinkRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_think_response.py b/memora-clients/python/memora_client_api/test/test_think_response.py new file mode 100644 index 00000000..e3f7e056 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_think_response.py @@ -0,0 +1,58 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.think_response import ThinkResponse + +class TestThinkResponse(unittest.TestCase): + """ThinkResponse unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ThinkResponse: + """Test ThinkResponse + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ThinkResponse` + """ + model = ThinkResponse() + if include_optional: + return ThinkResponse( + text = '', + based_on = [ + {context=healthcare discussion, event_date=2024-01-15T10:30:00Z, id=123e4567-e89b-12d3-a456-426614174000, text=AI is used in healthcare, type=world} + ], + new_opinions = [ + '' + ] + ) + else: + return ThinkResponse( + text = '', + ) + """ + + def testThinkResponse(self): + """Test ThinkResponse""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_update_personality_request.py b/memora-clients/python/memora_client_api/test/test_update_personality_request.py new file mode 100644 index 00000000..f2b8533f --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_update_personality_request.py @@ -0,0 +1,52 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.update_personality_request import UpdatePersonalityRequest + +class TestUpdatePersonalityRequest(unittest.TestCase): + """UpdatePersonalityRequest unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> UpdatePersonalityRequest: + """Test UpdatePersonalityRequest + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `UpdatePersonalityRequest` + """ + model = UpdatePersonalityRequest() + if include_optional: + return UpdatePersonalityRequest( + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8} + ) + else: + return UpdatePersonalityRequest( + personality = {agreeableness=0.7, bias_strength=0.7, conscientiousness=0.6, extraversion=0.5, neuroticism=0.3, openness=0.8}, + ) + """ + + def testUpdatePersonalityRequest(self): + """Test UpdatePersonalityRequest""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_validation_error.py b/memora-clients/python/memora_client_api/test/test_validation_error.py new file mode 100644 index 00000000..db1f1331 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_validation_error.py @@ -0,0 +1,60 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.validation_error import ValidationError + +class TestValidationError(unittest.TestCase): + """ValidationError unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ValidationError: + """Test ValidationError + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ValidationError` + """ + model = ValidationError() + if include_optional: + return ValidationError( + loc = [ + null + ], + msg = '', + type = '' + ) + else: + return ValidationError( + loc = [ + null + ], + msg = '', + type = '', + ) + """ + + def testValidationError(self): + """Test ValidationError""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_validation_error_loc_inner.py b/memora-clients/python/memora_client_api/test/test_validation_error_loc_inner.py new file mode 100644 index 00000000..36128264 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_validation_error_loc_inner.py @@ -0,0 +1,50 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.models.validation_error_loc_inner import ValidationErrorLocInner + +class TestValidationErrorLocInner(unittest.TestCase): + """ValidationErrorLocInner unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def make_instance(self, include_optional) -> ValidationErrorLocInner: + """Test ValidationErrorLocInner + include_optional is a boolean, when False only required + params are included, when True both required and + optional params are included """ + # uncomment below to create an instance of `ValidationErrorLocInner` + """ + model = ValidationErrorLocInner() + if include_optional: + return ValidationErrorLocInner( + ) + else: + return ValidationErrorLocInner( + ) + """ + + def testValidationErrorLocInner(self): + """Test ValidationErrorLocInner""" + # inst_req_only = self.make_instance(include_optional=False) + # inst_req_and_optional = self.make_instance(include_optional=True) + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/memora_client_api/test/test_visualization_api.py b/memora-clients/python/memora_client_api/test/test_visualization_api.py new file mode 100644 index 00000000..9ea1c990 --- /dev/null +++ b/memora-clients/python/memora_client_api/test/test_visualization_api.py @@ -0,0 +1,38 @@ +# coding: utf-8 + +""" + Agent Memory API + + A temporal-semantic memory system for AI agents that stores, retrieves, and reasons over memories. ## Features * **Batch Memory Storage**: Store multiple memories efficiently with automatic fact extraction * **Semantic Search**: Find relevant memories using natural language queries * **Fact Type Filtering**: Search across world facts, agent actions, and opinions separately * **Think Endpoint**: Generate contextual answers based on agent identity and memories * **Graph Visualization**: Interactive memory graph visualization * **Document Tracking**: Track and manage memory documents with upsert support ## Architecture The system uses: - **Temporal Links**: Connect memories that are close in time - **Semantic Links**: Connect semantically similar memories - **Entity Links**: Connect memories that mention the same entities - **Spreading Activation**: Intelligent traversal for memory retrieval + + The version of the OpenAPI document: 1.0.0 + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import unittest + +from memora_client_api.api.visualization_api import VisualizationApi + + +class TestVisualizationApi(unittest.IsolatedAsyncioTestCase): + """VisualizationApi unit test stubs""" + + async def asyncSetUp(self) -> None: + self.api = VisualizationApi() + + async def asyncTearDown(self) -> None: + await self.api.api_client.close() + + async def test_get_graph(self) -> None: + """Test case for get_graph + + Get memory graph data + """ + pass + + +if __name__ == '__main__': + unittest.main() diff --git a/memora-clients/python/openapi-generator-config.yaml b/memora-clients/python/openapi-generator-config.yaml new file mode 100644 index 00000000..23ced19d --- /dev/null +++ b/memora-clients/python/openapi-generator-config.yaml @@ -0,0 +1,5 @@ +packageName: memora_client_api +projectName: memora-client +packageVersion: 0.0.7 +library: asyncio +generateSourceCodeOnly: true diff --git a/memora-clients/python/pyproject.toml b/memora-clients/python/pyproject.toml index 6c7ba057..233f059b 100644 --- a/memora-clients/python/pyproject.toml +++ b/memora-clients/python/pyproject.toml @@ -8,18 +8,26 @@ authors = [ requires-python = ">=3.10" readme = "README.md" dependencies = [ - "httpx>=0.23.0,<0.29.0", - "attrs>=22.2.0", - "python-dateutil>=2.8.0,<3", + "urllib3 (>=2.1.0,<3.0.0)", + "python-dateutil (>=2.8.2)", + "aiohttp (>=3.8.4)", + "aiohttp-retry (>=2.8.3)", + "pydantic (>=2)", + "typing-extensions (>=4.7.1)", ] -[tool.uv.build-backend] -module-name = "agent_memory_api_client" -module-root = "" +[project.optional-dependencies] +test = [ + "pytest>=7.0.0", + "pytest-asyncio>=0.21.0", +] [build-system] -requires = ["uv_build>=0.9.0,<0.10.0"] -build-backend = "uv_build" +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["memora_client", "memora_client_api"] [tool.ruff] line-length = 120 diff --git a/memora-clients/python/tests/__init__.py b/memora-clients/python/tests/__init__.py new file mode 100644 index 00000000..a6bce47a --- /dev/null +++ b/memora-clients/python/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for Memora client.""" diff --git a/memora-clients/python/tests/test_main_operations.py b/memora-clients/python/tests/test_main_operations.py new file mode 100644 index 00000000..18ada818 --- /dev/null +++ b/memora-clients/python/tests/test_main_operations.py @@ -0,0 +1,265 @@ +""" +Integration tests for main Memora operations. + +These tests require a running Memora API server. +""" + +import os +import pytest +from datetime import datetime +from memora_client import Memora + + +# Test configuration +MEMORA_API_URL = os.getenv("MEMORA_API_URL", "http://localhost:8080") +TEST_AGENT_ID = "test_agent_" + datetime.now().strftime("%Y%m%d_%H%M%S") + + +@pytest.fixture +def client(): + """Create a Memora client for testing.""" + with Memora(base_url=MEMORA_API_URL) as client: + yield client + + +@pytest.fixture +def agent_id(): + """Provide a unique test agent ID.""" + return TEST_AGENT_ID + + +class TestStore: + """Tests for storing memories.""" + + def test_put_single_memory(self, client, agent_id): + """Test storing a single memory.""" + response = client.put( + agent_id=agent_id, + content="Alice loves artificial intelligence and machine learning", + ) + + assert response is not None + assert response.get("success") is True + assert response.get("items_count") == 1 + + def test_put_memory_with_context(self, client, agent_id): + """Test storing a memory with context and event date.""" + response = client.put( + agent_id=agent_id, + content="Bob went hiking in the mountains", + event_date=datetime(2024, 1, 15, 10, 30), + context="outdoor activities", + ) + + assert response is not None + assert response.get("success") is True + + def test_put_batch_memories(self, client, agent_id): + """Test storing multiple memories in batch.""" + items = [ + {"content": "Charlie enjoys reading science fiction books"}, + {"content": "Diana is learning to play the guitar", "context": "hobbies"}, + { + "content": "Eve completed a marathon last month", + "event_date": datetime(2024, 10, 15), + }, + ] + + response = client.put_batch( + agent_id=agent_id, + items=items, + ) + + assert response is not None + assert response.get("success") is True + assert response.get("items_count") == 3 + + +class TestSearch: + """Tests for searching memories.""" + + @pytest.fixture(autouse=True) + def setup_memories(self, client, agent_id): + """Setup: Store some test memories before search tests.""" + client.put_batch( + agent_id=agent_id, + items=[ + {"content": "Alice loves programming in Python"}, + {"content": "Bob enjoys hiking and outdoor adventures"}, + {"content": "Charlie is interested in quantum physics"}, + {"content": "Diana plays the violin beautifully"}, + ], + ) + + def test_search_basic(self, client, agent_id): + """Test basic memory search.""" + results = client.search( + agent_id=agent_id, + query="What does Alice like?", + ) + + assert results is not None + assert len(results) > 0 + + # Check that at least one result contains relevant information + result_texts = [r.get("text", "") for r in results] + assert any("Alice" in text or "Python" in text or "programming" in text for text in result_texts) + + def test_search_with_max_tokens(self, client, agent_id): + """Test search with token limit.""" + results = client.search( + agent_id=agent_id, + query="outdoor activities", + max_tokens=1024, + ) + + assert results is not None + assert isinstance(results, list) + + def test_search_full_featured(self, client, agent_id): + """Test search_memories with all features.""" + response = client.search_memories( + agent_id=agent_id, + query="What are people's hobbies?", + fact_type=["world"], + max_tokens=2048, + trace=True, + ) + + assert response is not None + assert "results" in response + # Trace should be included when enabled + if response.get("trace"): + assert isinstance(response["trace"], dict) + + +class TestThink: + """Tests for thinking/reasoning operations.""" + + @pytest.fixture(autouse=True) + def setup_memories(self, client, agent_id): + """Setup: Store some test memories and agent background.""" + client.create_agent( + agent_id=agent_id, + name="Test Agent", + background="I am a helpful AI assistant interested in technology and science.", + ) + + client.put_batch( + agent_id=agent_id, + items=[ + {"content": "The Python programming language is great for data science"}, + {"content": "Machine learning models can recognize patterns in data"}, + {"content": "Neural networks are inspired by biological neurons"}, + ], + ) + + def test_think_basic(self, client, agent_id): + """Test basic think operation.""" + response = client.think( + agent_id=agent_id, + query="What do you think about artificial intelligence?", + ) + + assert response is not None + assert "text" in response + assert len(response["text"]) > 0 + + # Should include facts that were used + if "based_on" in response: + assert isinstance(response["based_on"], list) + + def test_think_with_context(self, client, agent_id): + """Test think with additional context.""" + response = client.think( + agent_id=agent_id, + query="Should I learn Python?", + context="I'm interested in starting a career in data science", + thinking_budget=100, + ) + + assert response is not None + assert "text" in response + assert len(response["text"]) > 0 + + +class TestListMemories: + """Tests for listing memories.""" + + @pytest.fixture(autouse=True) + def setup_memories(self, client, agent_id): + """Setup: Store some test memories.""" + client.put_batch( + agent_id=agent_id, + items=[ + {"content": f"Test memory {i}"} for i in range(5) + ], + ) + + def test_list_all_memories(self, client, agent_id): + """Test listing all memories.""" + response = client.list_memories(agent_id=agent_id) + + assert response is not None + assert "items" in response + assert "total" in response + assert len(response["items"]) > 0 + + def test_list_with_pagination(self, client, agent_id): + """Test listing with pagination.""" + response = client.list_memories( + agent_id=agent_id, + limit=2, + offset=0, + ) + + assert response is not None + assert "items" in response + assert len(response["items"]) <= 2 + + +@pytest.mark.integration +class TestEndToEndWorkflow: + """End-to-end workflow tests.""" + + def test_complete_workflow(self, client): + """Test a complete workflow: create agent, store, search, think.""" + workflow_agent_id = "workflow_test_" + datetime.now().strftime("%Y%m%d_%H%M%S") + + # 1. Create agent + client.create_agent( + agent_id=workflow_agent_id, + name="Alice", + background="I am a software engineer who loves Python programming.", + ) + + # 2. Store memories + store_response = client.put_batch( + agent_id=workflow_agent_id, + items=[ + {"content": "I completed a project using FastAPI"}, + {"content": "I learned about async programming in Python"}, + {"content": "I enjoy working on open source projects"}, + ], + ) + assert store_response.get("success") is True + + # 3. Search for relevant memories + search_results = client.search( + agent_id=workflow_agent_id, + query="What programming technologies do I use?", + ) + assert len(search_results) > 0 + + # 4. Generate contextual answer + think_response = client.think( + agent_id=workflow_agent_id, + query="What are my professional interests?", + ) + assert "text" in think_response + assert len(think_response["text"]) > 0 + + +if __name__ == "__main__": + # Run tests with pytest + pytest.main([__file__, "-v", "-s"]) diff --git a/memora-clients/typescript/index.ts b/memora-clients/typescript/index.ts index 2586de2c..b6c169a8 100644 --- a/memora-clients/typescript/index.ts +++ b/memora-clients/typescript/index.ts @@ -16,6 +16,7 @@ export type { BatchPutAsyncResponse } from './models/BatchPutAsyncResponse'; export type { BatchPutRequest } from './models/BatchPutRequest'; export type { BatchPutResponse } from './models/BatchPutResponse'; export type { CreateAgentRequest } from './models/CreateAgentRequest'; +export type { DeleteResponse } from './models/DeleteResponse'; export type { DocumentResponse } from './models/DocumentResponse'; export type { GraphDataResponse } from './models/GraphDataResponse'; export type { HTTPValidationError } from './models/HTTPValidationError'; diff --git a/memora-clients/typescript/models/AgentListItem.ts b/memora-clients/typescript/models/AgentListItem.ts index 21f810b9..51a9c612 100644 --- a/memora-clients/typescript/models/AgentListItem.ts +++ b/memora-clients/typescript/models/AgentListItem.ts @@ -8,6 +8,7 @@ import type { PersonalityTraits } from './PersonalityTraits'; */ export type AgentListItem = { agent_id: string; + name: string; personality: PersonalityTraits; background: string; created_at?: (string | null); diff --git a/memora-clients/typescript/models/AgentProfileResponse.ts b/memora-clients/typescript/models/AgentProfileResponse.ts index ee376a13..addad64a 100644 --- a/memora-clients/typescript/models/AgentProfileResponse.ts +++ b/memora-clients/typescript/models/AgentProfileResponse.ts @@ -8,6 +8,7 @@ import type { PersonalityTraits } from './PersonalityTraits'; */ export type AgentProfileResponse = { agent_id: string; + name: string; personality: PersonalityTraits; background: string; }; diff --git a/memora-clients/typescript/models/CreateAgentRequest.ts b/memora-clients/typescript/models/CreateAgentRequest.ts index 25f5a0b9..d7605b86 100644 --- a/memora-clients/typescript/models/CreateAgentRequest.ts +++ b/memora-clients/typescript/models/CreateAgentRequest.ts @@ -7,6 +7,7 @@ import type { PersonalityTraits } from './PersonalityTraits'; * Request model for creating/updating an agent. */ export type CreateAgentRequest = { + name?: (string | null); personality?: (PersonalityTraits | null); background?: (string | null); }; diff --git a/memora-clients/typescript/models/DeleteResponse.ts b/memora-clients/typescript/models/DeleteResponse.ts new file mode 100644 index 00000000..7c7107a3 --- /dev/null +++ b/memora-clients/typescript/models/DeleteResponse.ts @@ -0,0 +1,12 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +/** + * Response model for delete operations. + */ +export type DeleteResponse = { + success: boolean; + message: string; +}; + diff --git a/memora-clients/typescript/models/SearchRequest.ts b/memora-clients/typescript/models/SearchRequest.ts index 0af0346d..d279674e 100644 --- a/memora-clients/typescript/models/SearchRequest.ts +++ b/memora-clients/typescript/models/SearchRequest.ts @@ -10,7 +10,6 @@ export type SearchRequest = { fact_type?: (Array | null); thinking_budget?: number; max_tokens?: number; - reranker?: string; trace?: boolean; question_date?: (string | null); }; diff --git a/memora-clients/typescript/models/SearchResult.ts b/memora-clients/typescript/models/SearchResult.ts index a2e33780..52579761 100644 --- a/memora-clients/typescript/models/SearchResult.ts +++ b/memora-clients/typescript/models/SearchResult.ts @@ -9,8 +9,8 @@ export type SearchResult = { id: string; text: string; type?: (string | null); - activation?: (number | null); context?: (string | null); event_date?: (string | null); + document_id?: (string | null); }; diff --git a/memora-clients/typescript/models/ThinkFact.ts b/memora-clients/typescript/models/ThinkFact.ts index e1067f85..dd460cb9 100644 --- a/memora-clients/typescript/models/ThinkFact.ts +++ b/memora-clients/typescript/models/ThinkFact.ts @@ -9,7 +9,6 @@ export type ThinkFact = { id?: (string | null); text: string; type?: (string | null); - activation?: (number | null); context?: (string | null); event_date?: (string | null); }; diff --git a/memora-clients/typescript/services/AgentManagementService.ts b/memora-clients/typescript/services/AgentManagementService.ts index 68724037..63a9b3e7 100644 --- a/memora-clients/typescript/services/AgentManagementService.ts +++ b/memora-clients/typescript/services/AgentManagementService.ts @@ -7,6 +7,7 @@ import type { AgentListResponse } from '../models/AgentListResponse'; import type { AgentProfileResponse } from '../models/AgentProfileResponse'; import type { BackgroundResponse } from '../models/BackgroundResponse'; import type { CreateAgentRequest } from '../models/CreateAgentRequest'; +import type { DeleteResponse } from '../models/DeleteResponse'; import type { UpdatePersonalityRequest } from '../models/UpdatePersonalityRequest'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -18,7 +19,7 @@ export class AgentManagementService { * @returns AgentListResponse Successful Response * @throws ApiError */ - public static apiAgentsApiV1AgentsGet(): CancelablePromise { + public static listAgents(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/api/v1/agents', @@ -30,7 +31,7 @@ export class AgentManagementService { * @returns any Successful Response * @throws ApiError */ - public static apiStatsApiV1AgentsAgentIdStatsGet({ + public static getAgentStats({ agentId, }: { agentId: string, @@ -46,13 +47,43 @@ export class AgentManagementService { }, }); } + /** + * Clear agent memories + * Delete memory units for an agent. Optionally filter by fact_type (world, agent, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The agent profile (personality and background) will be preserved. + * @returns DeleteResponse Successful Response + * @throws ApiError + */ + public static clearAgentMemories({ + agentId, + factType, + }: { + agentId: string, + /** + * Optional fact type filter (world, agent, opinion) + */ + factType?: (string | null), + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/agents/{agent_id}/memories', + path: { + 'agent_id': agentId, + }, + query: { + 'fact_type': factType, + }, + errors: { + 422: `Validation Error`, + }, + }); + } /** * Get agent profile * Get personality traits and background for an agent. Auto-creates agent with defaults if not exists. * @returns AgentProfileResponse Successful Response * @throws ApiError */ - public static apiGetAgentProfileApiV1AgentsAgentIdProfileGet({ + public static getAgentProfile({ agentId, }: { agentId: string, @@ -74,7 +105,7 @@ export class AgentManagementService { * @returns AgentProfileResponse Successful Response * @throws ApiError */ - public static apiUpdateAgentPersonalityApiV1AgentsAgentIdProfilePut({ + public static updateAgentPersonality({ agentId, requestBody, }: { @@ -100,7 +131,7 @@ export class AgentManagementService { * @returns BackgroundResponse Successful Response * @throws ApiError */ - public static apiAddAgentBackgroundApiV1AgentsAgentIdBackgroundPost({ + public static addAgentBackground({ agentId, requestBody, }: { @@ -126,7 +157,7 @@ export class AgentManagementService { * @returns AgentProfileResponse Successful Response * @throws ApiError */ - public static apiCreateOrUpdateAgentApiV1AgentsAgentIdPut({ + public static createOrUpdateAgent({ agentId, requestBody, }: { diff --git a/memora-clients/typescript/services/DocumentsService.ts b/memora-clients/typescript/services/DocumentsService.ts index 5d988b0f..f97fcf62 100644 --- a/memora-clients/typescript/services/DocumentsService.ts +++ b/memora-clients/typescript/services/DocumentsService.ts @@ -14,7 +14,7 @@ export class DocumentsService { * @returns ListDocumentsResponse Successful Response * @throws ApiError */ - public static apiListDocumentsApiV1AgentsAgentIdDocumentsGet({ + public static listDocuments({ agentId, q, limit = 100, @@ -47,7 +47,7 @@ export class DocumentsService { * @returns DocumentResponse Successful Response * @throws ApiError */ - public static apiGetDocumentApiV1AgentsAgentIdDocumentsDocumentIdGet({ + public static getDocument({ agentId, documentId, }: { @@ -66,4 +66,36 @@ export class DocumentsService { }, }); } + /** + * Delete a document + * Delete a document and all its associated memory units and links. + * + * This will cascade delete: + * - The document itself + * - All memory units extracted from this document + * - All links (temporal, semantic, entity) associated with those memory units + * + * This operation cannot be undone. + * @returns any Successful Response + * @throws ApiError + */ + public static deleteDocument({ + agentId, + documentId, + }: { + agentId: string, + documentId: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/api/v1/agents/{agent_id}/documents/{document_id}', + path: { + 'agent_id': agentId, + 'document_id': documentId, + }, + errors: { + 422: `Validation Error`, + }, + }); + } } diff --git a/memora-clients/typescript/services/MemoryOperationsService.ts b/memora-clients/typescript/services/MemoryOperationsService.ts index cfa64580..e54e4de5 100644 --- a/memora-clients/typescript/services/MemoryOperationsService.ts +++ b/memora-clients/typescript/services/MemoryOperationsService.ts @@ -18,7 +18,7 @@ export class MemoryOperationsService { * @returns ListMemoryUnitsResponse Successful Response * @throws ApiError */ - public static apiListApiV1AgentsAgentIdMemoriesListGet({ + public static listMemories({ agentId, factType, q, @@ -59,7 +59,7 @@ export class MemoryOperationsService { * @returns SearchResponse Successful Response * @throws ApiError */ - public static apiSearchApiV1AgentsAgentIdMemoriesSearchPost({ + public static searchMemories({ agentId, requestBody, }: { @@ -101,7 +101,7 @@ export class MemoryOperationsService { * @returns BatchPutResponse Successful Response * @throws ApiError */ - public static apiBatchPutApiV1AgentsAgentIdMemoriesPost({ + public static batchPutMemories({ agentId, requestBody, }: { @@ -146,7 +146,7 @@ export class MemoryOperationsService { * @returns BatchPutAsyncResponse Successful Response * @throws ApiError */ - public static apiBatchPutAsyncApiV1AgentsAgentIdMemoriesAsyncPost({ + public static batchPutAsync({ agentId, requestBody, }: { @@ -172,7 +172,7 @@ export class MemoryOperationsService { * @returns any Successful Response * @throws ApiError */ - public static apiListOperationsApiV1AgentsAgentIdOperationsGet({ + public static listOperations({ agentId, }: { agentId: string, @@ -194,7 +194,7 @@ export class MemoryOperationsService { * @returns any Successful Response * @throws ApiError */ - public static apiCancelOperationApiV1AgentsAgentIdOperationsOperationIdDelete({ + public static cancelOperation({ agentId, operationId, }: { @@ -219,7 +219,7 @@ export class MemoryOperationsService { * @returns any Successful Response * @throws ApiError */ - public static apiDeleteMemoryUnitApiV1AgentsAgentIdMemoriesUnitIdDelete({ + public static deleteMemoryUnit({ agentId, unitId, }: { diff --git a/memora-clients/typescript/services/ReasoningService.ts b/memora-clients/typescript/services/ReasoningService.ts index 5c3c4ad4..6201200c 100644 --- a/memora-clients/typescript/services/ReasoningService.ts +++ b/memora-clients/typescript/services/ReasoningService.ts @@ -22,7 +22,7 @@ export class ReasoningService { * @returns ThinkResponse Successful Response * @throws ApiError */ - public static apiThinkApiV1AgentsAgentIdThinkPost({ + public static think({ agentId, requestBody, }: { diff --git a/memora-clients/typescript/services/VisualizationService.ts b/memora-clients/typescript/services/VisualizationService.ts index 81bdf22a..0d4a7573 100644 --- a/memora-clients/typescript/services/VisualizationService.ts +++ b/memora-clients/typescript/services/VisualizationService.ts @@ -13,7 +13,7 @@ export class VisualizationService { * @returns GraphDataResponse Successful Response * @throws ApiError */ - public static apiGraphApiV1AgentsAgentIdGraphGet({ + public static getGraph({ agentId, factType, }: { diff --git a/memora-langmem/.ipynb_checkpoints/tutorial-checkpoint.ipynb b/memora-langmem/.ipynb_checkpoints/tutorial-checkpoint.ipynb new file mode 100644 index 00000000..bae41e77 --- /dev/null +++ b/memora-langmem/.ipynb_checkpoints/tutorial-checkpoint.ipynb @@ -0,0 +1,256 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Memora-LangMem: Drop-in Semantic Memory for LangGraph\n", + "\n", + "Replace your LangGraph memory store in one line and get advanced semantic capabilities." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What is Memora-LangMem?\n", + "\n", + "`memora-langmem` implements LangGraph's `BaseStore` interface using Memora as the backend.\n", + "\n", + "### What You Get vs Standard LangGraph Memory\n", + "\n", + "| Feature | Standard Memory | Memora-LangMem |\n", + "|---------|-----------------|----------------|\n", + "| Basic Key-Value Storage | ✅ | ✅ |\n", + "| Semantic Search | ✅ Basic | ✅ **Enhanced with spreading activation** |\n", + "| Namespace Support | ✅ | ✅ |\n", + "| **Personality-Driven Retrieval** | ❌ | ✅ |\n", + "| **Automatic Fact Extraction** | ❌ | ✅ |\n", + "| **Entity Recognition** | ❌ | ✅ |\n", + "| **Temporal Reasoning** | ❌ | ✅ |\n", + "| **Opinion Formation** | ❌ | ✅ |\n", + "| **Background Knowledge** | ❌ | ✅ |\n", + "| **Thinking/Reasoning API** | ❌ | ✅ |\n", + "\n", + "### When to Use\n", + "- Conversational agents needing long-term memory\n", + "- Personalized AI with context-aware responses \n", + "- Multi-agent systems with distinct personalities\n", + "- Knowledge management with semantic search" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Installation\n", + "\n", + "```bash\n", + "uv pip install -e /path/to/memora-langmem\n", + "export MEMORA_API_URL=http://localhost:8000\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Drop-in Replacement\n", + "\n", + "### Before: Standard LangGraph Memory" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from langmem import create_manage_memory_tool, create_search_memory_tool\n", + "from langgraph.prebuilt import create_react_agent\n", + "from langgraph.store.memory import InMemoryStore\n", + "\n", + "# Standard store - basic key-value with optional vector search\n", + "store = InMemoryStore()\n", + "\n", + "agent = create_react_agent(\n", + " \"anthropic:claude-3-5-sonnet-latest\",\n", + " tools=[\n", + " create_manage_memory_tool(namespace=(\"memories\",)),\n", + " create_search_memory_tool(namespace=(\"memories\",)),\n", + " ],\n", + " store=store\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### After: With Memora-LangMem\n", + "\n", + "**Just change one line!**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "from langmem import create_manage_memory_tool, create_search_memory_tool\n", + "from langgraph.prebuilt import create_react_agent\n", + "from memora_langmem import MemoraStore # ← Only import change!\n", + "\n", + "# Replace InMemoryStore with MemoraStore\n", + "base_url = os.getenv(\"MEMORA_API_URL\", \"http://localhost:8000\")\n", + "store = MemoraStore(base_url=base_url, default_agent_id=\"my_agent\") # ← One line change!\n", + "\n", + "# Everything else stays exactly the same\n", + "agent = create_react_agent(\n", + " \"anthropic:claude-3-5-sonnet-latest\",\n", + " tools=[\n", + " create_manage_memory_tool(namespace=(\"memories\",)),\n", + " create_search_memory_tool(namespace=(\"memories\",)),\n", + " ],\n", + " store=store # ← Now using Memora with enhanced capabilities!\n", + ")\n", + "\n", + "print(\"✅ Agent created with Memora-powered memory\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example: Conversational Memory in Action" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "\n", + "# Store information\n", + "result1 = agent.invoke({\n", + " \"messages\": [{\n", + " \"role\": \"user\",\n", + " \"content\": \"\"\"Remember: I'm David, a software engineer working on AI projects. \n", + " I love Python and machine learning. Currently building a chatbot with LangGraph.\"\"\"\n", + " }]\n", + "})\n", + "print(\"Agent:\", result1[\"messages\"][-1].content)\n", + "\n", + "time.sleep(2)\n", + "\n", + "# Recall information\n", + "result2 = agent.invoke({\n", + " \"messages\": [{\"role\": \"user\", \"content\": \"What do you remember about me?\"}]\n", + "})\n", + "print(\"\\nAgent:\", result2[\"messages\"][-1].content)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## What Happens Behind the Scenes\n", + "\n", + "When your agent stores memories with Memora, automatically:\n", + "\n", + "1. **Fact Extraction**: Natural language → structured facts\n", + "2. **Entity Recognition**: Identifies people, places, concepts\n", + "3. **Semantic Indexing**: Spreading activation for better retrieval\n", + "4. **Temporal Awareness**: Event dates tracked for time queries\n", + "5. **Opinion Formation**: Agent develops perspectives over time\n", + "6. **Personality Influence**: Memory retrieval shaped by personality traits\n", + "\n", + "**You use the standard LangGraph API - Memora does the rest!**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Multi-Agent Support\n", + "\n", + "Each agent gets isolated memory and can develop unique personality:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Different agents with different personalities\n", + "creative_store = MemoraStore(base_url=base_url, default_agent_id=\"creative_writer\")\n", + "analyst_store = MemoraStore(base_url=base_url, default_agent_id=\"data_analyst\")\n", + "\n", + "creative_agent = create_react_agent(\n", + " \"anthropic:claude-3-5-sonnet-latest\",\n", + " tools=[\n", + " create_manage_memory_tool(namespace=(\"creative\",)),\n", + " create_search_memory_tool(namespace=(\"creative\",))\n", + " ],\n", + " store=creative_store\n", + ")\n", + "\n", + "analyst_agent = create_react_agent(\n", + " \"anthropic:claude-3-5-sonnet-latest\",\n", + " tools=[\n", + " create_manage_memory_tool(namespace=(\"analysis\",)),\n", + " create_search_memory_tool(namespace=(\"analysis\",))\n", + " ],\n", + " store=analyst_store\n", + ")\n", + "\n", + "print(\"✅ Two agents with isolated memories and distinct personalities\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "### The Change\n", + "```python\n", + "# Before\n", + "store = InMemoryStore()\n", + "\n", + "# After \n", + "store = MemoraStore(base_url=\"http://localhost:8000\", default_agent_id=\"my_agent\")\n", + "```\n", + "\n", + "### What You Get\n", + "- ✅ Semantic search with spreading activation\n", + "- ✅ Automatic fact extraction from conversations\n", + "- ✅ Entity recognition and linking\n", + "- ✅ Temporal reasoning (time-aware queries)\n", + "- ✅ Personality-driven memory retrieval\n", + "- ✅ Opinion formation over time\n", + "- ✅ Multi-agent support with isolated memories\n", + "\n", + "**Same LangGraph API. Smarter memory. Zero code changes (except the store line).**" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/memora-langmem/memora_langmem/store.py b/memora-langmem/memora_langmem/store.py index f2809437..db79de5a 100644 --- a/memora-langmem/memora_langmem/store.py +++ b/memora-langmem/memora_langmem/store.py @@ -3,18 +3,7 @@ import json from typing import Any, Iterable -from agent_memory_api_client import Client -from agent_memory_api_client.api.agent_management import ( - api_agents_api_v1_agents_get, - api_create_or_update_agent_api_v1_agents_agent_id_put, -) -from agent_memory_api_client.api.memory_operations import ( - api_batch_put_api_v1_agents_agent_id_memories_post, - api_delete_memory_unit_api_v1_agents_agent_id_memories_unit_id_delete, - api_list_api_v1_agents_agent_id_memories_list_get, - api_search_api_v1_agents_agent_id_memories_search_post, -) -from agent_memory_api_client.models import BatchPutRequest, CreateAgentRequest, MemoryItem, SearchRequest +from memora_client import Memora from langgraph.store.base import ( BaseStore, GetOp, @@ -48,7 +37,7 @@ class MemoraStore(BaseStore): default_agent_id: Default agent ID when namespace is empty """ super().__init__() - self.client = Client(base_url=base_url) + self.client = Memora(base_url=base_url) self.default_agent_id = default_agent_id or "default" self._ensure_agent_exists(self.default_agent_id) @@ -61,20 +50,11 @@ class MemoraStore(BaseStore): def _ensure_agent_exists(self, agent_id: str) -> None: """Ensure an agent exists, create if it doesn't.""" try: - response = api_agents_api_v1_agents_get.sync_detailed(client=self.client) - if response.parsed and hasattr(response.parsed, "items"): - existing_ids = [agent.agent_id for agent in response.parsed.items] - if agent_id not in existing_ids: - self._create_agent(agent_id) + # Try to create agent (idempotent operation) + self.client.create_agent(agent_id=agent_id) except Exception: - self._create_agent(agent_id) - - def _create_agent(self, agent_id: str) -> None: - """Create a new agent.""" - request = CreateAgentRequest() - api_create_or_update_agent_api_v1_agents_agent_id_put.sync_detailed( - agent_id=agent_id, client=self.client, body=request - ) + # Agent likely already exists + pass def _serialize_value(self, value: dict[str, Any]) -> str: """Serialize a value to JSON string.""" @@ -115,11 +95,11 @@ class MemoraStore(BaseStore): value_with_key = {"__key__": op.key, **op.value} content = self._serialize_value(value_with_key) - memory_item = MemoryItem(content=content, context=f"key:{op.key}") - request = BatchPutRequest(items=[memory_item], document_id=op.key) - - api_batch_put_api_v1_agents_agent_id_memories_post.sync_detailed( - agent_id=agent_id, client=self.client, body=request + self.client.put( + agent_id=agent_id, + content=content, + context=f"key:{op.key}", + document_id=op.key, ) return None @@ -128,30 +108,25 @@ class MemoraStore(BaseStore): agent_id = self._namespace_to_agent_id(op.namespace) try: - response = api_list_api_v1_agents_agent_id_memories_list_get.sync_detailed( - agent_id=agent_id, client=self.client, limit=1000 - ) + response = self.client.get_document(agent_id=agent_id, document_id=op.key) - if not response.parsed or not hasattr(response.parsed, "items"): + if not response or not response.get("original_text"): return None - for memory_unit in response.parsed.items: - if hasattr(memory_unit, "document_id") and memory_unit.document_id == op.key: - try: - value = self._deserialize_value(memory_unit.content or "{}") - stored_key = value.pop("__key__", op.key) - if stored_key == op.key: - return Item( - namespace=op.namespace, - key=op.key, - value=value, - created_at=getattr(memory_unit, "created_at", None), - updated_at=getattr(memory_unit, "updated_at", None), - ) - except Exception: - continue + # Parse the original text to get the value + value = self._deserialize_value(response["original_text"]) + stored_key = value.pop("__key__", op.key) - return None + if stored_key != op.key: + return None + + return Item( + namespace=op.namespace, + key=op.key, + value=value, + created_at=response.get("created_at"), + updated_at=response.get("updated_at"), + ) except Exception: return None @@ -160,72 +135,52 @@ class MemoraStore(BaseStore): agent_id = self._namespace_to_agent_id(op.namespace_prefix) try: - search_request = SearchRequest(query=op.query or "", max_tokens=op.limit * 100) - - response = api_search_api_v1_agents_agent_id_memories_search_post.sync_detailed( - agent_id=agent_id, client=self.client, body=search_request + results = self.client.search( + agent_id=agent_id, + query=op.query or "", + max_tokens=op.limit * 100, ) - if not response.parsed or not hasattr(response.parsed, "results"): + if not results: return [] - results: list[SearchItem] = [] + items: list[SearchItem] = [] seen_keys = set() - for result in response.parsed.results[op.offset : op.offset + op.limit]: + for result in results[op.offset : op.offset + op.limit]: try: - value = self._deserialize_value(result.fact or "{}") - key = value.pop("__key__", result.fact_id) + text = result.get("text", "") + value = self._deserialize_value(text) + key = value.pop("__key__", result.get("id")) if key in seen_keys: continue seen_keys.add(key) - results.append( + items.append( SearchItem( namespace=op.namespace_prefix, key=key, value=value, - score=getattr(result, "score", 1.0), - created_at=getattr(result, "created_at", None), - updated_at=getattr(result, "updated_at", None), + score=1.0, + created_at=None, + updated_at=None, ) ) - if len(results) >= op.limit: + if len(items) >= op.limit: break except Exception: continue - return results + return items except Exception: return [] def _list_namespaces(self, op: ListNamespacesOp) -> list[tuple[str, ...]]: """List all namespaces.""" - try: - response = api_agents_api_v1_agents_get.sync_detailed(client=self.client) - - if not response.parsed or not hasattr(response.parsed, "items"): - return [] - - namespaces = [] - for agent in response.parsed.items: - if hasattr(agent, "agent_id"): - namespace = tuple(agent.agent_id.split("__")) - - if op.prefix and not self._matches_prefix(namespace, op.prefix): - continue - if op.suffix and not self._matches_suffix(namespace, op.suffix): - continue - if op.max_depth is not None and len(namespace) > op.max_depth: - continue - - namespaces.append(namespace) - - return namespaces[op.offset : op.offset + op.limit] - except Exception: - return [] + # Not fully implemented - would need to list all agents + return [] def _matches_prefix(self, namespace: tuple[str, ...], prefix: tuple[str, ...]) -> bool: """Check if namespace matches prefix.""" @@ -268,21 +223,11 @@ class MemoraStore(BaseStore): return self.get(namespace, key) def delete(self, namespace: tuple[str, ...], key: str) -> None: - """Delete an item.""" + """Delete an item by deleting the document.""" agent_id = self._namespace_to_agent_id(namespace) try: - response = api_list_api_v1_agents_agent_id_memories_list_get.sync_detailed( - agent_id=agent_id, client=self.client, limit=1000 - ) - - if response.parsed and hasattr(response.parsed, "items"): - for memory_unit in response.parsed.items: - if hasattr(memory_unit, "document_id") and memory_unit.document_id == key: - if hasattr(memory_unit, "unit_id"): - api_delete_memory_unit_api_v1_agents_agent_id_memories_unit_id_delete.sync_detailed( - agent_id=agent_id, unit_id=memory_unit.unit_id, client=self.client - ) + self.client.delete_document(agent_id=agent_id, document_id=key) except Exception: pass diff --git a/memora-langmem/pyproject.toml b/memora-langmem/pyproject.toml index 49fa2a29..3fb90175 100644 --- a/memora-langmem/pyproject.toml +++ b/memora-langmem/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ ] [tool.uv.sources] -memora-client = { path = "../memora-clients/python", editable = true } +memora-client = { workspace = true } [project.optional-dependencies] test = [ diff --git a/memora-langmem/tutorial.ipynb b/memora-langmem/tutorial.ipynb index 40537c28..6e8c7722 100644 --- a/memora-langmem/tutorial.ipynb +++ b/memora-langmem/tutorial.ipynb @@ -4,9 +4,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Memora-LangMem: Semantic Memory with Personality-Driven Thinking for LangGraph\n", + "# Memora-LangMem: Drop-in Semantic Memory for LangGraph\n", "\n", - "This notebook provides a comprehensive tutorial on using `memora-langmem`, a drop-in replacement for LangGraph's standard memory stores that adds advanced semantic memory capabilities powered by Memora." + "Replace your LangGraph memory store in one line and get advanced semantic capabilities." ] }, { @@ -15,267 +15,136 @@ "source": [ "## What is Memora-LangMem?\n", "\n", - "`memora-langmem` is a Python package that implements LangGraph's `BaseStore` interface using Memora as the backend. It provides:\n", - "\n", - "### Core Features\n", - "\n", - "1. **Drop-in Replacement**: Fully compatible with LangGraph's memory system - just swap the store!\n", - "2. **Semantic Memory**: Advanced semantic search with spreading activation algorithms\n", - "3. **Personality-Driven Thinking**: Memory retrieval influenced by configurable agent personalities\n", - "4. **Fact Extraction**: Automatic extraction and structuring of facts from conversations\n", - "5. **Temporal Reasoning**: Time-aware memory with event date tracking\n", - "6. **Entity Linking**: Automatic recognition and linking of entities across memories\n", - "7. **Multi-Agent Support**: Each namespace can represent a different agent with unique personality traits\n", + "`memora-langmem` implements LangGraph's `BaseStore` interface using Memora as the backend.\n", "\n", "### What You Get vs Standard LangGraph Memory\n", "\n", - "| Feature | Standard LangGraph Memory | Memora-LangMem |\n", - "|---------|---------------------------|----------------|\n", + "| Feature | Standard Memory | Memora-LangMem |\n", + "|---------|-----------------|----------------|\n", "| Basic Key-Value Storage | ✅ | ✅ |\n", - "| Semantic Search | ✅ (with index config) | ✅ Enhanced with spreading activation |\n", + "| Semantic Search | ✅ Basic | ✅ **Enhanced with spreading activation** |\n", "| Namespace Support | ✅ | ✅ |\n", - "| Personality-Driven Retrieval | ❌ | ✅ Configurable personality traits |\n", - "| Automatic Fact Extraction | ❌ | ✅ NLP-powered extraction |\n", - "| Entity Recognition | ❌ | ✅ Automatic entity linking |\n", - "| Temporal Reasoning | ❌ | ✅ Time-aware queries |\n", - "| Opinion Formation | ❌ | ✅ Agent forms opinions over time |\n", - "| Background Knowledge | ❌ | ✅ Agent-specific background context |\n", - "| Thinking/Reasoning API | ❌ | ✅ Explicit reasoning with memory |\n", + "| **Personality-Driven Retrieval** | ❌ | ✅ |\n", + "| **Automatic Fact Extraction** | ❌ | ✅ |\n", + "| **Entity Recognition** | ❌ | ✅ |\n", + "| **Temporal Reasoning** | ❌ | ✅ |\n", + "| **Opinion Formation** | ❌ | ✅ |\n", + "| **Background Knowledge** | ❌ | ✅ |\n", + "| **Thinking/Reasoning API** | ❌ | ✅ |\n", "\n", - "### When to Use Memora-LangMem\n", - "\n", - "- **Conversational Agents**: When you need agents to remember context across long conversations\n", - "- **Personalized AI**: When agent responses should be influenced by personality and past interactions\n", - "- **Knowledge Management**: When you need to extract and organize facts from unstructured text\n", - "- **Multi-Agent Systems**: When different agents need isolated memory with distinct personalities\n", - "- **Research & Analysis**: When you need semantic search over large knowledge bases" + "### When to Use\n", + "- Conversational agents needing long-term memory\n", + "- Personalized AI with context-aware responses \n", + "- Multi-agent systems with distinct personalities\n", + "- Knowledge management with semantic search" ] }, { "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Installation\n", - "\n", - "```bash\n", - "# Install from local path (development)\n", - "uv pip install -e /path/to/memora-langmem\n", - "\n", - "# Or with pip\n", - "pip install -e /path/to/memora-langmem\n", - "```\n", - "\n", - "### Prerequisites\n", - "\n", - "You need a running Memora API server. Set the URL via environment variable:\n", - "\n", - "```bash\n", - "export MEMORA_API_URL=http://localhost:8000\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Part 1: Basic Usage - Direct Store API\n", - "\n", - "Let's start with the basic `BaseStore` interface that's compatible with LangGraph." - ] + "source": "## Installation\n\nRun this cell to install dependencies:", + "metadata": {} }, { "cell_type": "code", - "execution_count": null, + "source": "!pip install langgraph langmem", "metadata": {}, - "outputs": [], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": "Make sure Memora API is running at `http://localhost:8000`", + "metadata": {} + }, + { + "cell_type": "markdown", + "source": "## Setup API Keys\n\nSet up your OpenAI API key and Memora URL:", + "metadata": {} + }, + { + "cell_type": "code", + "source": "import os\nimport getpass\n\n# Set OpenAI API key\nif \"OPENAI_API_KEY\" not in os.environ:\n os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter your OpenAI API key: \")\n\n# Set Memora API URL\nif \"MEMORA_API_URL\" not in os.environ:\n os.environ[\"MEMORA_API_URL\"] = input(\"Enter Memora API URL (default: http://localhost:8000): \") or \"http://localhost:8000\"\n\nprint(\"✅ API keys configured\")", + "metadata": {}, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## The Drop-in Replacement\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "source": "### Before: Standard LangGraph Memory", + "metadata": {} + }, + { + "cell_type": "code", + "source": "from langmem import create_manage_memory_tool, create_search_memory_tool\nfrom langgraph.prebuilt import create_react_agent\nfrom langgraph.store.memory import InMemoryStore\n\n# Standard store - basic key-value with optional vector search\nstore = InMemoryStore()\n\nagent = create_react_agent(\n \"openai:gpt-4o\",\n tools=[\n create_manage_memory_tool(namespace=(\"memories\",)),\n create_search_memory_tool(namespace=(\"memories\",)),\n ],\n store=store\n)", + "metadata": {}, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": "### After: With Memora-LangMem\n\n**Just change one line!**", + "metadata": {}, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": {}, + "source": "import os\nfrom langmem import create_manage_memory_tool, create_search_memory_tool\nfrom langgraph.prebuilt import create_react_agent\nfrom memora_langmem import MemoraStore # ← Only import change!\n\n# Replace InMemoryStore with MemoraStore\nbase_url = os.getenv(\"MEMORA_API_URL\", \"http://localhost:8000\")\nstore = MemoraStore(base_url=base_url, default_agent_id=\"my_agent\") # ← One line change!\n\n# Everything else stays exactly the same\nagent = create_react_agent(\n \"openai:gpt-4o\", # ← Use OpenAI\n tools=[\n create_manage_memory_tool(namespace=(\"memories\",)),\n create_search_memory_tool(namespace=(\"memories\",)),\n ],\n store=store # ← Now using Memora with enhanced capabilities!\n)\n\nprint(\"✅ Agent created with Memora-powered memory\")" + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "ename": "ModuleNotFoundError", + "evalue": "No module named 'langmem'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mModuleNotFoundError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mos\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mlangmem\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m create_manage_memory_tool, create_search_memory_tool\n\u001b[32m 3\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mlanggraph\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01mprebuilt\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m create_react_agent\n\u001b[32m 4\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mmemora_langmem\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m MemoraStore \u001b[38;5;66;03m# ← Only import change!\u001b[39;00m\n", + "\u001b[31mModuleNotFoundError\u001b[39m: No module named 'langmem'" + ] + } + ], "source": [ "import os\n", - "from memora_langmem import MemoraStore\n", - "\n", - "# Initialize the store\n", - "base_url = os.getenv(\"MEMORA_API_URL\", \"http://localhost:8000\")\n", - "store = MemoraStore(base_url=base_url, default_agent_id=\"tutorial_agent\")\n", - "\n", - "print(\"✅ MemoraStore initialized\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Storing and Retrieving Memories\n", - "\n", - "The store uses a namespace-key-value structure:\n", - "- **Namespace**: A tuple of strings representing a hierarchical path (e.g., `(\"user\", \"alice\")`)\n", - "- **Key**: A unique identifier within the namespace\n", - "- **Value**: A dictionary containing your data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Store a memory\n", - "namespace = (\"user\", \"alice\")\n", - "key = \"preferences\"\n", - "value = {\n", - " \"theme\": \"dark\",\n", - " \"language\": \"python\",\n", - " \"notifications\": True,\n", - " \"interests\": [\"machine learning\", \"data science\", \"artificial intelligence\"]\n", - "}\n", - "\n", - "store.put(namespace, key, value)\n", - "print(f\"✅ Stored preferences for {namespace}\")\n", - "\n", - "# Retrieve the memory\n", - "import time\n", - "time.sleep(1) # Brief pause for processing\n", - "\n", - "retrieved = store.get(namespace, key)\n", - "if retrieved:\n", - " print(f\"\\n📦 Retrieved memory:\")\n", - " print(f\" Namespace: {retrieved.namespace}\")\n", - " print(f\" Key: {retrieved.key}\")\n", - " print(f\" Value: {retrieved.value}\")\n", - " print(f\" Created: {retrieved.created_at}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Semantic Search - The Power of Memora\n", - "\n", - "Unlike simple key-value retrieval, Memora provides semantic search with spreading activation. This means:\n", - "- Search by natural language queries\n", - "- Find semantically related memories\n", - "- Memories are ranked by relevance" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Add more memories to demonstrate search\n", - "memories = [\n", - " (\"notes\", \"ml_project\", {\n", - " \"title\": \"Machine Learning Project Ideas\",\n", - " \"content\": \"Working on a neural network for image classification. Interested in transformers and attention mechanisms.\"\n", - " }),\n", - " (\"notes\", \"data_tools\", {\n", - " \"title\": \"Favorite Data Tools\",\n", - " \"content\": \"Love using pandas for data manipulation, scikit-learn for ML, and PyTorch for deep learning.\"\n", - " }),\n", - " (\"notes\", \"meeting_summary\", {\n", - " \"title\": \"Team Meeting Notes\",\n", - " \"content\": \"Discussed the new AI assistant project. Team decided to use LangGraph for orchestration.\"\n", - " })\n", - "]\n", - "\n", - "for ns, k, v in memories:\n", - " store.put((\"user\", \"alice\", ns), k, v)\n", - "\n", - "time.sleep(2) # Allow time for indexing\n", - "\n", - "# Now search semantically\n", - "print(\"🔍 Searching for 'machine learning projects'...\\n\")\n", - "results = store.search(\n", - " namespace_prefix=(\"user\", \"alice\"),\n", - " query=\"machine learning projects\",\n", - " limit=5\n", - ")\n", - "\n", - "for i, result in enumerate(results, 1):\n", - " print(f\"{i}. Score: {result.score:.3f}\")\n", - " print(f\" Key: {result.key}\")\n", - " print(f\" Value: {result.value}\")\n", - " print()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Namespace Management\n", - "\n", - "Namespaces allow you to organize memories hierarchically. In Memora, each unique namespace combination maps to a separate agent." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Create memories in different namespaces\n", - "store.put((\"user\", \"bob\", \"preferences\"), \"theme\", {\"theme\": \"light\", \"language\": \"javascript\"})\n", - "store.put((\"user\", \"charlie\", \"preferences\"), \"theme\", {\"theme\": \"auto\", \"language\": \"rust\"})\n", - "\n", - "time.sleep(1)\n", - "\n", - "# List all namespaces\n", - "print(\"📁 All namespaces:\")\n", - "namespaces = store.list_namespaces(prefix=(\"user\",), limit=10)\n", - "for ns in namespaces:\n", - " print(f\" - {ns}\")\n", - "\n", - "# List namespaces with specific prefix\n", - "print(\"\\n📁 Namespaces for alice:\")\n", - "alice_namespaces = store.list_namespaces(prefix=(\"user\", \"alice\"), limit=10)\n", - "for ns in alice_namespaces:\n", - " print(f\" - {ns}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Part 2: Integration with LangGraph Memory Tools\n", - "\n", - "The real power comes from using MemoraStore with LangGraph's memory tools and agents." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ "from langmem import create_manage_memory_tool, create_search_memory_tool\n", "from langgraph.prebuilt import create_react_agent\n", + "from memora_langmem import MemoraStore # ← Only import change!\n", "\n", - "# Create a fresh store for the agent\n", - "agent_store = MemoraStore(\n", - " base_url=base_url,\n", - " default_agent_id=\"intelligent_assistant\"\n", - ")\n", + "# Replace InMemoryStore with MemoraStore\n", + "base_url = os.getenv(\"MEMORA_API_URL\", \"http://localhost:8080\")\n", + "store = MemoraStore(base_url=base_url, default_agent_id=\"my_agent\") # ← One line change!\n", "\n", - "# Create memory tools\n", - "manage_tool = create_manage_memory_tool(namespace=(\"conversations\",))\n", - "search_tool = create_search_memory_tool(namespace=(\"conversations\",))\n", - "\n", - "# Create a LangGraph agent with Memora-backed memory\n", + "# Everything else stays exactly the same\n", "agent = create_react_agent(\n", " \"anthropic:claude-3-5-sonnet-latest\",\n", - " tools=[manage_tool, search_tool],\n", - " store=agent_store # This is where MemoraStore plugs in!\n", + " tools=[\n", + " create_manage_memory_tool(namespace=(\"memories\",)),\n", + " create_search_memory_tool(namespace=(\"memories\",)),\n", + " ],\n", + " store=store # ← Now using Memora with enhanced capabilities!\n", ")\n", "\n", - "print(\"✅ Agent created with Memora-backed memory\")" + "print(\"✅ Agent created with Memora-powered memory\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Conversational Memory in Action\n", - "\n", - "Let's see how the agent uses Memora to remember information across conversations." + "## Example: Conversational Memory in Action" ] }, { @@ -284,75 +153,49 @@ "metadata": {}, "outputs": [], "source": [ - "# First conversation: Share information\n", - "print(\"💬 Conversation 1: Sharing preferences\\n\")\n", + "import time\n", + "\n", + "# Store information\n", "result1 = agent.invoke({\n", " \"messages\": [{\n", " \"role\": \"user\",\n", - " \"content\": \"\"\"Hi! I want you to remember some things about me:\n", - " - My name is David\n", - " - I'm a software engineer working on AI projects\n", - " - I love Python and machine learning\n", - " - I'm currently building a chatbot using LangGraph\n", - " Please remember these details for future conversations.\"\"\"\n", + " \"content\": \"\"\"Remember: I'm David, a software engineer working on AI projects. \n", + " I love Python and machine learning. Currently building a chatbot with LangGraph.\"\"\"\n", " }]\n", "})\n", + "print(\"Agent:\", result1[\"messages\"][-1].content)\n", "\n", - "print(\"Agent response:\")\n", - "print(result1[\"messages\"][-1].content)\n", - "print(\"\\n\" + \"=\"*80 + \"\\n\")\n", + "time.sleep(2)\n", "\n", - "# Second conversation: Recall information\n", - "time.sleep(2) # Brief pause\n", - "\n", - "print(\"💬 Conversation 2: Testing recall\\n\")\n", + "# Recall information\n", "result2 = agent.invoke({\n", - " \"messages\": [{\n", - " \"role\": \"user\",\n", - " \"content\": \"What do you remember about me and my work?\"\n", - " }]\n", + " \"messages\": [{\"role\": \"user\", \"content\": \"What do you remember about me?\"}]\n", "})\n", - "\n", - "print(\"Agent response:\")\n", - "print(result2[\"messages\"][-1].content)\n", - "print(\"\\n\" + \"=\"*80 + \"\\n\")\n", - "\n", - "# Third conversation: Contextual recommendations\n", - "time.sleep(2)\n", - "\n", - "print(\"💬 Conversation 3: Using memory for personalization\\n\")\n", - "result3 = agent.invoke({\n", - " \"messages\": [{\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you suggest some relevant learning resources based on what you know about me?\"\n", - " }]\n", - "})\n", - "\n", - "print(\"Agent response:\")\n", - "print(result3[\"messages\"][-1].content)" + "print(\"\\nAgent:\", result2[\"messages\"][-1].content)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Part 3: Advanced Features - Beyond Standard LangGraph\n", + "## What Happens Behind the Scenes\n", "\n", - "Memora provides capabilities beyond the standard BaseStore interface." + "When your agent stores memories with Memora, automatically:\n", + "\n", + "1. **Fact Extraction**: Natural language → structured facts\n", + "2. **Entity Recognition**: Identifies people, places, concepts\n", + "3. **Semantic Indexing**: Spreading activation for better retrieval\n", + "4. **Temporal Awareness**: Event dates tracked for time queries\n", + "5. **Opinion Formation**: Agent develops perspectives over time\n", + "6. **Personality Influence**: Memory retrieval shaped by personality traits\n", + "\n", + "**You use the standard LangGraph API - Memora does the rest!**" ] }, { - "cell_type": "markdown", + "cell_type": "code", "metadata": {}, - "source": [ - "### Automatic Fact Extraction\n", - "\n", - "When you store natural language content, Memora automatically:\n", - "- Extracts structured facts\n", - "- Identifies entities (people, places, concepts)\n", - "- Links related facts together\n", - "- Categorizes facts by type (world knowledge, agent actions, opinions)" - ] + "source": "# Different agents with different personalities\ncreative_store = MemoraStore(base_url=base_url, default_agent_id=\"creative_writer\")\nanalyst_store = MemoraStore(base_url=base_url, default_agent_id=\"data_analyst\")\n\ncreative_agent = create_react_agent(\n \"openai:gpt-4o\",\n tools=[\n create_manage_memory_tool(namespace=(\"creative\",)),\n create_search_memory_tool(namespace=(\"creative\",))\n ],\n store=creative_store\n)\n\nanalyst_agent = create_react_agent(\n \"openai:gpt-4o\",\n tools=[\n create_manage_memory_tool(namespace=(\"analysis\",)),\n create_search_memory_tool(namespace=(\"analysis\",))\n ],\n store=analyst_store\n)\n\nprint(\"✅ Two agents with isolated memories and distinct personalities\")" }, { "cell_type": "code", @@ -360,247 +203,62 @@ "metadata": {}, "outputs": [], "source": [ - "# Store rich natural language content\n", - "conversation_store = MemoraStore(base_url=base_url, default_agent_id=\"fact_extractor\")\n", + "# Different agents with different personalities\n", + "creative_store = MemoraStore(base_url=base_url, default_agent_id=\"creative_writer\")\n", + "analyst_store = MemoraStore(base_url=base_url, default_agent_id=\"data_analyst\")\n", "\n", - "conversation_content = {\n", - " \"text\": \"\"\"Yesterday I met with Sarah from the marketing team. She mentioned that our new \n", - " product launch is scheduled for next month. The team is really excited about the AI features \n", - " we've built. Sarah thinks it will revolutionize how customers interact with our platform. \n", - " I personally believe we should focus more on user experience rather than just adding features.\"\"\",\n", - " \"context\": \"team meeting\",\n", - " \"participants\": [\"self\", \"Sarah\"]\n", - "}\n", - "\n", - "conversation_store.put(\n", - " namespace=(\"meetings\", \"2024\"),\n", - " key=\"marketing_sync\",\n", - " value=conversation_content\n", + "creative_agent = create_react_agent(\n", + " \"anthropic:claude-3-5-sonnet-latest\",\n", + " tools=[\n", + " create_manage_memory_tool(namespace=(\"creative\",)),\n", + " create_search_memory_tool(namespace=(\"creative\",))\n", + " ],\n", + " store=creative_store\n", ")\n", "\n", - "print(\"✅ Stored conversation - Memora is now extracting facts...\")\n", - "print(\" Behind the scenes, Memora identifies:\")\n", - "print(\" • Entities: Sarah, marketing team, new product, AI features\")\n", - "print(\" • Events: product launch next month, meeting with Sarah\")\n", - "print(\" • Opinions: belief about UX focus vs features\")\n", - "print(\" • Relationships: Sarah works in marketing\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Temporal Reasoning\n", - "\n", - "Memora is time-aware. You can query memories with temporal context." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from datetime import datetime, timedelta\n", - "\n", - "# Store time-sensitive information\n", - "today = datetime.now()\n", - "yesterday = today - timedelta(days=1)\n", - "last_week = today - timedelta(days=7)\n", - "\n", - "events = [\n", - " (\"event_today\", {\"description\": \"Team standup meeting\", \"date\": today.isoformat()}),\n", - " (\"event_yesterday\", {\"description\": \"Product demo\", \"date\": yesterday.isoformat()}),\n", - " (\"event_last_week\", {\"description\": \"Sprint planning\", \"date\": last_week.isoformat()})\n", - "]\n", - "\n", - "for key, value in events:\n", - " conversation_store.put((\"events\",), key, value)\n", - "\n", - "time.sleep(2)\n", - "\n", - "# Search with temporal context\n", - "print(\"🗓️ Searching for recent events...\\n\")\n", - "recent_events = conversation_store.search(\n", - " namespace_prefix=(\"events\",),\n", - " query=\"meetings this week\",\n", - " limit=5\n", + "analyst_agent = create_react_agent(\n", + " \"anthropic:claude-3-5-sonnet-latest\",\n", + " tools=[\n", + " create_manage_memory_tool(namespace=(\"analysis\",)),\n", + " create_search_memory_tool(namespace=(\"analysis\",))\n", + " ],\n", + " store=analyst_store\n", ")\n", "\n", - "for event in recent_events:\n", - " print(f\"• {event.value.get('description')} - {event.value.get('date')}\")" + "print(\"✅ Two agents with isolated memories and distinct personalities\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Multi-Agent Scenarios\n", + "## Summary\n", "\n", - "Each namespace combination creates a separate agent in Memora, allowing for isolated memories and distinct personalities." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Create stores for different agent personas\n", - "store_creative = MemoraStore(base_url=base_url, default_agent_id=\"creative_writer\")\n", - "store_analyst = MemoraStore(base_url=base_url, default_agent_id=\"data_analyst\")\n", - "store_engineer = MemoraStore(base_url=base_url, default_agent_id=\"software_engineer\")\n", + "### The Change\n", + "```python\n", + "# Before\n", + "store = InMemoryStore()\n", "\n", - "# Each agent has its own perspective on the same information\n", - "shared_info = {\n", - " \"topic\": \"New AI Feature Launch\",\n", - " \"description\": \"We're launching an AI-powered recommendation system\"\n", - "}\n", + "# After \n", + "store = MemoraStore(base_url=\"http://localhost:8000\", default_agent_id=\"my_agent\")\n", + "```\n", "\n", - "# Creative writer stores with focus on narrative\n", - "store_creative.put((\"projects\",), \"ai_launch\", {\n", - " **shared_info,\n", - " \"note\": \"This is a revolutionary moment - we're changing how people discover content!\"\n", - "})\n", + "### What You Get\n", + "- ✅ Semantic search with spreading activation\n", + "- ✅ Automatic fact extraction from conversations\n", + "- ✅ Entity recognition and linking\n", + "- ✅ Temporal reasoning (time-aware queries)\n", + "- ✅ Personality-driven memory retrieval\n", + "- ✅ Opinion formation over time\n", + "- ✅ Multi-agent support with isolated memories\n", "\n", - "# Data analyst stores with focus on metrics\n", - "store_analyst.put((\"projects\",), \"ai_launch\", {\n", - " **shared_info,\n", - " \"note\": \"Need to track engagement metrics, conversion rates, and user retention\"\n", - "})\n", - "\n", - "# Software engineer stores with focus on implementation\n", - "store_engineer.put((\"projects\",), \"ai_launch\", {\n", - " **shared_info,\n", - " \"note\": \"Built using transformer models, need to optimize inference latency\"\n", - "})\n", - "\n", - "print(\"✅ Created three agents with different perspectives on the same project\")\n", - "print(\" Each agent's memory is isolated and can develop unique personality traits\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Part 4: Batch Operations for Performance\n", - "\n", - "When working with multiple memories, batch operations are more efficient." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from langgraph.store.base import PutOp, GetOp, SearchOp\n", - "\n", - "batch_store = MemoraStore(base_url=base_url, default_agent_id=\"batch_demo\")\n", - "\n", - "# Batch put operations\n", - "put_ops = [\n", - " PutOp(namespace=(\"docs\",), key=\"intro\", value={\"title\": \"Introduction\", \"content\": \"Welcome to the tutorial\"}),\n", - " PutOp(namespace=(\"docs\",), key=\"setup\", value={\"title\": \"Setup\", \"content\": \"Installation instructions\"}),\n", - " PutOp(namespace=(\"docs\",), key=\"usage\", value={\"title\": \"Usage\", \"content\": \"How to use the API\"}),\n", - "]\n", - "\n", - "print(\"📦 Performing batch PUT operations...\")\n", - "put_results = batch_store.batch(put_ops)\n", - "print(f\"✅ Stored {len(put_results)} documents\\n\")\n", - "\n", - "time.sleep(1)\n", - "\n", - "# Batch get operations\n", - "get_ops = [\n", - " GetOp(namespace=(\"docs\",), key=\"intro\"),\n", - " GetOp(namespace=(\"docs\",), key=\"setup\"),\n", - " GetOp(namespace=(\"docs\",), key=\"usage\"),\n", - "]\n", - "\n", - "print(\"📦 Performing batch GET operations...\")\n", - "get_results = batch_store.batch(get_ops)\n", - "\n", - "for item in get_results:\n", - " if item:\n", - " print(f\" • {item.value['title']}: {item.value['content']}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Part 5: Cleanup\n", - "\n", - "Clean up memories when they're no longer needed." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Delete specific memories\n", - "print(\"🗑️ Cleaning up...\\n\")\n", - "\n", - "# Delete from the docs namespace\n", - "batch_store.delete((\"docs\",), \"intro\")\n", - "print(\"✅ Deleted 'intro' document\")\n", - "\n", - "# Verify deletion\n", - "time.sleep(1)\n", - "deleted_item = batch_store.get((\"docs\",), \"intro\")\n", - "if deleted_item is None:\n", - " print(\"✅ Confirmed: document is deleted\")\n", - "else:\n", - " print(\"⚠️ Document still exists\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Summary: Why Choose Memora-LangMem?\n", - "\n", - "### Key Advantages\n", - "\n", - "1. **Zero Code Changes**: Drop-in replacement for existing LangGraph memory stores\n", - "2. **Enhanced Intelligence**: Automatic fact extraction, entity linking, and semantic understanding\n", - "3. **Personality System**: Agents can develop unique personalities that influence memory retrieval\n", - "4. **Production Ready**: Built on robust Memora backend with proper persistence\n", - "5. **Rich Context**: Beyond simple key-value, stores temporal, relational, and semantic information\n", - "6. **Research-Backed**: Implements spreading activation and advanced memory retrieval algorithms\n", - "\n", - "### Use Cases\n", - "\n", - "- **Customer Support Bots**: Remember customer preferences, history, and context\n", - "- **Personal Assistants**: Build agents that truly understand and remember user preferences\n", - "- **Knowledge Workers**: Agents that accumulate domain expertise over time\n", - "- **Research Assistants**: Semantic search over large knowledge bases\n", - "- **Team Collaboration**: Multiple agents with distinct roles and memories\n", - "\n", - "### Getting Started\n", - "\n", - "1. Install: `uv pip install -e /path/to/memora-langmem`\n", - "2. Start Memora API: Ensure server is running at `http://localhost:8000`\n", - "3. Replace store: `store = MemoraStore(base_url=base_url)`\n", - "4. Use normally: All LangGraph memory APIs work as expected\n", - "5. Enjoy enhanced memory capabilities automatically!\n", - "\n", - "### Next Steps\n", - "\n", - "- Explore the Memora API documentation for advanced features\n", - "- Configure agent personalities for different use cases\n", - "- Experiment with the thinking/reasoning API\n", - "- Build multi-agent systems with isolated memories\n", - "- Integrate with your existing LangGraph applications" + "**Same LangGraph API. Smarter memory. Zero code changes (except the store line).**" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -614,9 +272,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.11.10" } }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/memora-openai/.ipynb_checkpoints/tutorial-checkpoint.ipynb b/memora-openai/.ipynb_checkpoints/tutorial-checkpoint.ipynb new file mode 100644 index 00000000..d095be65 --- /dev/null +++ b/memora-openai/.ipynb_checkpoints/tutorial-checkpoint.ipynb @@ -0,0 +1,444 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Memora-OpenAI Tutorial\n", + "\n", + "**A drop-in replacement for the OpenAI Python client with automatic memory integration**\n", + "\n", + "## What is Memora-OpenAI?\n", + "\n", + "`memora-openai` is a transparent wrapper around the official OpenAI Python client that automatically:\n", + "\n", + "- 🧠 **Injects relevant memories** from your Memora system into conversations\n", + "- 💾 **Stores conversation history** to Memora for future retrieval \n", + "- 🔄 **Works seamlessly** with existing OpenAI code (just change the import)\n", + "- ⚡ **Supports both sync and async** clients\n", + "\n", + "## Why Use It?\n", + "\n", + "### The Problem\n", + "\n", + "AI assistants typically have no memory of previous conversations. Each interaction starts fresh, requiring you to:\n", + "- Repeat context manually\n", + "- Copy-paste relevant information\n", + "- Build custom RAG pipelines\n", + "- Manage conversation history yourself\n", + "\n", + "### The Solution\n", + "\n", + "Memora-OpenAI gives your AI **automatic long-term memory**:\n", + "- Remembers past conversations\n", + "- Recalls user preferences and facts\n", + "- Maintains context across sessions\n", + "- Zero code changes to your existing OpenAI usage\n", + "\n", + "## Prerequisites\n", + "\n", + "1. **Memora API server running** (see main Memora README)\n", + "2. **OpenAI API key** or compatible API (Groq, OpenRouter, etc.)\n", + "3. **Python >= 3.10**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup\n", + "\n", + "First, let's set up our environment and configure Memora integration:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "jupyter": { + "is_executing": true + } + }, + "outputs": [], + "source": [ + "import os\n", + "from memora_openai import configure, OpenAI\n", + "\n", + "# Set your API keys\n", + "# Option 1: Use Groq (fast and free)\n", + "GROQ_API_KEY = os.getenv(\"GROQ_API_KEY\", \"your-groq-api-key\")\n", + "\n", + "# Option 2: Use OpenAI\n", + "# OPENAI_API_KEY = os.getenv(\"OPENAI_API_KEY\", \"sk-...\")\n", + "\n", + "# Configure Memora integration\n", + "configure(\n", + " memora_api_url=\"http://localhost:8000\", # Your Memora API server\n", + " agent_id=\"tutorial-user\", # Unique ID for this user/agent\n", + " store_conversations=True, # Auto-save conversations\n", + " inject_memories=True, # Auto-inject relevant context\n", + " memory_search_budget=10, # Number of memories to retrieve\n", + ")\n", + "\n", + "print(\"✓ Memora configured successfully!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 1: Basic Usage (No Changes Needed!)\n", + "\n", + "Use the OpenAI client exactly as you normally would. Memora works transparently in the background." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Create client (using Groq's OpenAI-compatible API)\n", + "client = OpenAI(\n", + " api_key=GROQ_API_KEY,\n", + " base_url=\"https://api.groq.com/openai/v1\",\n", + ")\n", + "\n", + "# First conversation - establish some facts\n", + "print(\"=== First Conversation ===\")\n", + "response = client.chat.completions.create(\n", + " model=\"llama-3.1-8b-instant\",\n", + " messages=[\n", + " {\"role\": \"user\", \"content\": \"My name is Alice and I love Python programming!\"}\n", + " ],\n", + ")\n", + "\n", + "print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", + "print(\"→ This conversation is now stored in Memora!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 2: Memory Injection in Action\n", + "\n", + "Now ask a question that requires remembering the previous conversation:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(\"=== Second Conversation (with memory) ===\")\n", + "response = client.chat.completions.create(\n", + " model=\"llama-3.1-8b-instant\",\n", + " messages=[\n", + " {\"role\": \"user\", \"content\": \"What's my name and what do I like?\"}\n", + " ],\n", + ")\n", + "\n", + "print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", + "print(\"→ Memora automatically injected relevant memories before this request!\")\n", + "print(\"→ The AI knew your name and preferences without you repeating them.\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## How It Works\n", + "\n", + "Behind the scenes, Memora-OpenAI:\n", + "\n", + "### 1. **Memory Storage**\n", + "After each API call:\n", + "- Captures the full conversation context\n", + "- Stores it in Memora's semantic memory system\n", + "- Indexes it for fast retrieval\n", + "\n", + "### 2. **Memory Injection**\n", + "Before each API call:\n", + "- Extracts the user's query\n", + "- Searches Memora for relevant past conversations\n", + "- Injects top memories as a system message\n", + "\n", + "### What Gets Sent to OpenAI\n", + "\n", + "Without Memora:\n", + "```python\n", + "messages = [\n", + " {\"role\": \"user\", \"content\": \"What's my name?\"}\n", + "]\n", + "```\n", + "\n", + "With Memora (automatic):\n", + "```python\n", + "messages = [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": \"Relevant context from your memory:\\n\\n1. User's name is Alice\\n (Date: 2024-11-18)\\n (Type: world)\"\n", + " },\n", + " {\"role\": \"user\", \"content\": \"What's my name?\"}\n", + "]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 3: Multi-Turn Conversations\n", + "\n", + "Build up context over multiple interactions:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Conversation 1: Share a preference\n", + "print(\"=== Conversation 1: Sharing preferences ===\")\n", + "response = client.chat.completions.create(\n", + " model=\"llama-3.1-8b-instant\",\n", + " messages=[\n", + " {\"role\": \"user\", \"content\": \"I'm working on a machine learning project using PyTorch.\"}\n", + " ],\n", + ")\n", + "print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", + "\n", + "# Conversation 2: Different topic\n", + "print(\"=== Conversation 2: Different topic ===\")\n", + "response = client.chat.completions.create(\n", + " model=\"llama-3.1-8b-instant\",\n", + " messages=[\n", + " {\"role\": \"user\", \"content\": \"I prefer functional programming over OOP.\"}\n", + " ],\n", + ")\n", + "print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", + "\n", + "# Conversation 3: Ask for recommendations\n", + "print(\"=== Conversation 3: Getting personalized advice ===\")\n", + "response = client.chat.completions.create(\n", + " model=\"llama-3.1-8b-instant\",\n", + " messages=[\n", + " {\"role\": \"user\", \"content\": \"Can you recommend a good book for me based on what you know?\"}\n", + " ],\n", + ")\n", + "print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", + "print(\"→ The AI used your programming interests and preferences to make recommendations!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 4: Document Grouping\n", + "\n", + "Group related conversations using `document_id`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from memora_openai import configure\n", + "\n", + "# Configure with document ID for a specific project\n", + "configure(\n", + " memora_api_url=\"http://localhost:8000\",\n", + " agent_id=\"tutorial-user\",\n", + " document_id=\"ml-project-2024\", # All conversations tagged with this ID\n", + ")\n", + "\n", + "# All these conversations will be grouped together\n", + "conversations = [\n", + " \"I'm using ResNet for image classification\",\n", + " \"My dataset has 10,000 images\",\n", + " \"Training accuracy is stuck at 65%\",\n", + "]\n", + "\n", + "for msg in conversations:\n", + " response = client.chat.completions.create(\n", + " model=\"llama-3.1-8b-instant\",\n", + " messages=[{\"role\": \"user\", \"content\": msg}],\n", + " )\n", + " print(f\"User: {msg}\")\n", + " print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", + "\n", + "print(\"→ All these conversations are grouped under document 'ml-project-2024'\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 5: Async Support\n", + "\n", + "Works perfectly with AsyncOpenAI for high-throughput applications:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from memora_openai import AsyncOpenAI\n", + "import asyncio\n", + "\n", + "async def async_example():\n", + " # Create async client\n", + " async_client = AsyncOpenAI(\n", + " api_key=GROQ_API_KEY,\n", + " base_url=\"https://api.groq.com/openai/v1\",\n", + " )\n", + " \n", + " # Store a fact\n", + " print(\"=== Storing fact ===\")\n", + " response = await async_client.chat.completions.create(\n", + " model=\"llama-3.1-8b-instant\",\n", + " messages=[{\"role\": \"user\", \"content\": \"My favorite color is blue.\"}],\n", + " )\n", + " print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", + " \n", + " # Query with memory\n", + " print(\"=== Querying with memory ===\")\n", + " response = await async_client.chat.completions.create(\n", + " model=\"llama-3.1-8b-instant\",\n", + " messages=[{\"role\": \"user\", \"content\": \"What's my favorite color?\"}],\n", + " )\n", + " print(f\"Assistant: {response.choices[0].message.content}\\n\")\n", + "\n", + "# Run async example\n", + "await async_example()\n", + "print(\"→ Async operations work seamlessly with Memora!\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configuration Options\n", + "\n", + "Fine-tune Memora's behavior:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from memora_openai import configure\n", + "\n", + "# Full configuration example\n", + "configure(\n", + " memora_api_url=\"http://localhost:8000\", # Memora API URL\n", + " agent_id=\"my-agent\", # Agent identifier (required)\n", + " api_key=None, # Optional Memora API key\n", + " \n", + " # Features\n", + " store_conversations=True, # Store conversations automatically\n", + " inject_memories=True, # Inject memories automatically\n", + " \n", + " # Memory retrieval\n", + " memory_search_budget=10, # Number of memories to retrieve\n", + " \n", + " # Context management\n", + " context_window=10, # Recent conversation turns to store\n", + " \n", + " # Organization\n", + " document_id=\"session-123\", # Optional document grouping\n", + " event_timestamp=None, # Optional custom timestamp\n", + " \n", + " # Control\n", + " enabled=True, # Master on/off switch\n", + ")\n", + "\n", + "print(\"Configuration options explained:\")\n", + "print(\"- memory_search_budget: Higher = more context, but more tokens\")\n", + "print(\"- context_window: How many recent messages to include when storing\")\n", + "print(\"- document_id: Group related conversations together\")\n", + "print(\"- enabled=False: Disable Memora without changing code\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Use Cases\n", + "\n", + "### 1. **Personal AI Assistant**\n", + "- Remembers your preferences, work history, and interests\n", + "- Provides personalized recommendations\n", + "- Maintains context across days/weeks\n", + "\n", + "### 2. **Customer Support Chatbot**\n", + "- Recalls previous support tickets\n", + "- Knows customer preferences and history\n", + "- Provides consistent, context-aware responses\n", + "\n", + "### 3. **Research Assistant**\n", + "- Remembers documents you've discussed\n", + "- Connects related topics from different sessions\n", + "- Builds knowledge over time\n", + "\n", + "### 4. **Code Review Tool**\n", + "- Remembers project architecture decisions\n", + "- Recalls past code review comments\n", + "- Maintains consistency across reviews\n", + "\n", + "## Benefits Summary\n", + "\n", + "✅ **Zero Code Changes** - Drop-in replacement for OpenAI client \n", + "✅ **Automatic Context** - No manual RAG pipeline needed \n", + "✅ **Long-term Memory** - Conversations persist across sessions \n", + "✅ **Smart Retrieval** - Semantic search finds relevant context \n", + "✅ **Both Sync/Async** - Works with any OpenAI client pattern \n", + "✅ **Configurable** - Fine-tune behavior to your needs \n", + "✅ **Transparent** - Original OpenAI responses unchanged \n", + "\n", + "## Next Steps\n", + "\n", + "- **Explore Memora API**: Check out `memora/README.md` for advanced features\n", + "- **Customize Search**: Tune `memory_search_budget` for your use case\n", + "- **Use Document IDs**: Organize conversations by project/session\n", + "- **Try Different Models**: Works with OpenAI, Groq, Ollama, and more\n", + "\n", + "## Resources\n", + "\n", + "- [Memora Main README](../README.md) - Core memory system docs\n", + "- [Memora-OpenAI README](README.md) - Package documentation\n", + "- [OpenAI API Docs](https://platform.openai.com/docs/api-reference) - Original API reference\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/memora-openai/README.md b/memora-openai/README.md index e9c4931f..418249e3 100644 --- a/memora-openai/README.md +++ b/memora-openai/README.md @@ -12,7 +12,13 @@ Drop-in replacement for OpenAI Python client with automatic Memora integration. ## Installation +This package is part of the Memora workspace. Install from the root: + ```bash +# From repository root +uv sync + +# Or install just this package cd memora-openai uv pip install -e . ``` @@ -76,10 +82,6 @@ The `configure()` function accepts the following parameters: | `api_key` | str | `None` | Optional API key for Memora authentication | | `store_conversations` | bool | `True` | Store conversations to Memora | | `inject_memories` | bool | `True` | Inject relevant memories into prompts | -| `memory_search_budget` | int | `10` | Number of memories to retrieve for context | -| `auto_extract_facts` | bool | `False` | Automatically extract facts from responses | -| `event_timestamp` | str | `None` | Custom timestamp for memory events (ISO format) | -| `context_window` | int | `10` | Number of recent conversation turns to consider | | `document_id` | str | `None` | Optional document ID for stored conversations | | `enabled` | bool | `True` | Master switch to enable/disable Memora integration | @@ -146,16 +148,6 @@ response2 = client.chat.completions.create(...) # No Memora integration configure(memora_api_url="http://localhost:8000", agent_id="agent-1") ``` -### Custom Memory Search Budget - -```python -configure( - memora_api_url="http://localhost:8000", - agent_id="my-agent", - memory_search_budget=20, # Retrieve more memories for richer context -) -``` - ### Using Document ID Group related conversations together using a document ID: diff --git a/memora-openai/src/memora_openai/__init__.py b/memora-openai/memora_openai/__init__.py similarity index 100% rename from memora-openai/src/memora_openai/__init__.py rename to memora-openai/memora_openai/__init__.py diff --git a/memora-openai/src/memora_openai/client.py b/memora-openai/memora_openai/client.py similarity index 90% rename from memora-openai/src/memora_openai/client.py rename to memora-openai/memora_openai/client.py index 0948ff47..fe16413e 100644 --- a/memora-openai/src/memora_openai/client.py +++ b/memora-openai/memora_openai/client.py @@ -29,6 +29,20 @@ class _CompletionsWrapper: if not messages: return self._original.create(*args, **kwargs) + # Check if an event loop is already running (e.g., in Jupyter) + try: + running_loop = asyncio.get_running_loop() + # If we get here, a loop is already running + print( + "Warning: Detected running event loop (Jupyter/IPython). " + "Memora features are disabled in sync mode. " + "Please use AsyncOpenAI for full functionality in notebooks." + ) + return self._original.create(*args, **kwargs) + except RuntimeError: + # No loop running, we can create our own + pass + # Run async operations in a new event loop loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) diff --git a/memora-openai/src/memora_openai/config.py b/memora-openai/memora_openai/config.py similarity index 74% rename from memora-openai/src/memora_openai/config.py rename to memora-openai/memora_openai/config.py index 24f681cb..c446855d 100644 --- a/memora-openai/src/memora_openai/config.py +++ b/memora-openai/memora_openai/config.py @@ -14,10 +14,6 @@ class MemoraConfig: api_key: Optional API key for Memora authentication store_conversations: Whether to store conversations to Memora inject_memories: Whether to inject relevant memories into prompts - memory_search_budget: Number of memories to retrieve for context - auto_extract_facts: Whether to automatically extract facts from responses - event_timestamp: Optional timestamp for memory events (defaults to current time) - context_window: Number of recent conversation turns to consider document_id: Optional document ID for stored conversations enabled: Master switch to enable/disable Memora integration """ @@ -27,10 +23,6 @@ class MemoraConfig: api_key: Optional[str] = None store_conversations: bool = True inject_memories: bool = True - memory_search_budget: int = 10 - auto_extract_facts: bool = False - event_timestamp: Optional[str] = None - context_window: int = 10 document_id: Optional[str] = None enabled: bool = True @@ -45,10 +37,6 @@ def configure( api_key: Optional[str] = None, store_conversations: bool = True, inject_memories: bool = True, - memory_search_budget: int = 10, - auto_extract_facts: bool = False, - event_timestamp: Optional[str] = None, - context_window: int = 10, document_id: Optional[str] = None, enabled: bool = True, ) -> MemoraConfig: @@ -60,10 +48,6 @@ def configure( api_key: Optional API key for Memora authentication store_conversations: Whether to store conversations to Memora inject_memories: Whether to inject relevant memories into prompts - memory_search_budget: Number of memories to retrieve for context - auto_extract_facts: Whether to automatically extract facts from responses - event_timestamp: Optional timestamp for memory events - context_window: Number of recent conversation turns to consider document_id: Optional document ID for stored conversations enabled: Master switch to enable/disable Memora integration @@ -89,10 +73,6 @@ def configure( api_key=api_key, store_conversations=store_conversations, inject_memories=inject_memories, - memory_search_budget=memory_search_budget, - auto_extract_facts=auto_extract_facts, - event_timestamp=event_timestamp, - context_window=context_window, document_id=document_id, enabled=enabled, ) diff --git a/memora-openai/memora_openai/interceptor.py b/memora-openai/memora_openai/interceptor.py new file mode 100644 index 00000000..9339400c --- /dev/null +++ b/memora-openai/memora_openai/interceptor.py @@ -0,0 +1,246 @@ +"""Request/response interceptor for OpenAI API calls.""" + +from typing import Any, Dict, List, Optional +from datetime import datetime + +from memora_client import Memora + +from .config import get_config, MemoraConfig + + +class MemoraInterceptor: + """Intercepts OpenAI API calls to integrate with Memora.""" + + def __init__(self): + """Initialize the interceptor with a Memora client.""" + self._client: Optional[Memora] = None + + def get_client(self, config: MemoraConfig) -> Memora: + """Get or create the Memora client.""" + if self._client is None: + self._client = Memora(base_url=config.memora_api_url, timeout=30.0) + return self._client + + def close(self): + """Close the client.""" + if self._client is not None: + self._client.close() + self._client = None + + async def inject_memories( + self, + messages: List[Dict[str, Any]], + config: MemoraConfig, + ) -> List[Dict[str, Any]]: + """ + Inject relevant memories into messages before sending to OpenAI. + """ + if not config.enabled: + return messages + + try: + # Extract user query from messages + user_query = self._extract_user_query(messages) + if not user_query: + return messages + + # Get client + client = self.get_client(config) + + # Search for relevant memories + results = client.search( + agent_id=config.agent_id, + query=user_query, + max_tokens=4096, + thinking_budget=500, + ) + + if not results: + return messages + + # Format memories and add to context + memory_context = self._format_memories(results) + + # Add memory context to system message or create new one + updated_messages = self._add_memory_context(messages, memory_context) + + return updated_messages + + except Exception as e: + # Don't fail the request if memory retrieval fails + print(f"Warning: Failed to inject memories: {e}") + return messages + + async def process_request( + self, + messages: List[Dict[str, Any]], + **kwargs: Any, + ) -> List[Dict[str, Any]]: + """ + Process request before sending to OpenAI. + Retrieves relevant memories and adds them to the context. + """ + config = get_config() + return await self.inject_memories(messages, config) + + async def store_conversation( + self, + messages: List[Dict[str, Any]], + response: Any, + config: MemoraConfig, + ) -> None: + """ + Store conversation in Memora after receiving response from OpenAI. + """ + if not config.enabled or not config.store_conversations: + return + + try: + # Extract conversation context + conversation = self._extract_conversation_context(messages, response) + if not conversation: + return + + # Get client + client = self.get_client(config) + + # Store conversation as memories + items = [ + { + "content": msg["content"], + "context": f"role:{msg['role']}", + "event_date": datetime.now(), + } + for msg in conversation + ] + + # Store to Memora (async) + client.put_batch( + agent_id=config.agent_id, + items=items, + ) + + except Exception as e: + # Don't fail the request if storage fails + print(f"Warning: Failed to store conversation: {e}") + + async def process_response( + self, + messages: List[Dict[str, Any]], + response: Any, + **kwargs: Any, + ) -> None: + """ + Process response after receiving from OpenAI. + Stores the conversation in Memora. + """ + config = get_config() + await self.store_conversation(messages, response, config) + + def _extract_user_query(self, messages: List[Dict[str, Any]]) -> Optional[str]: + """Extract the user's query from messages.""" + # Get the last user message + for msg in reversed(messages): + if msg.get("role") == "user": + content = msg.get("content") + if isinstance(content, str): + return content + elif isinstance(content, list): + # Handle structured content + for item in content: + if isinstance(item, dict) and item.get("type") == "text": + return item.get("text") + return None + + def _format_memories(self, results: List[Dict[str, Any]]) -> str: + """Format memory search results into context string.""" + if not results: + return "" + + memory_lines = [] + for i, result in enumerate(results, 1): + text = result.get("text", "") + if text: + memory_lines.append(f"{i}. {text}") + + if not memory_lines: + return "" + + return ( + "# Relevant Memories\n" + "The following memories may be relevant to this conversation:\n\n" + + "\n".join(memory_lines) + ) + + def _add_memory_context( + self, + messages: List[Dict[str, Any]], + memory_context: str + ) -> List[Dict[str, Any]]: + """Add memory context to messages.""" + if not memory_context: + return messages + + # Check if there's already a system message + updated_messages = messages.copy() + + for i, msg in enumerate(updated_messages): + if msg.get("role") == "system": + # Append to existing system message + updated_messages[i] = { + **msg, + "content": f"{msg['content']}\n\n{memory_context}" + } + return updated_messages + + # No system message found, prepend one + system_message = { + "role": "system", + "content": memory_context + } + return [system_message] + updated_messages + + def _extract_conversation_context( + self, + messages: List[Dict[str, Any]], + response: Any, + ) -> List[Dict[str, str]]: + """Extract conversation context for storage.""" + conversation = [] + + # Add recent user messages + for msg in messages[-3:]: # Last 3 messages + if msg.get("role") in ("user", "assistant"): + content = msg.get("content") + if isinstance(content, str): + conversation.append({ + "role": msg["role"], + "content": content, + }) + + # Add assistant response + if hasattr(response, "choices") and response.choices: + choice = response.choices[0] + if hasattr(choice, "message"): + content = choice.message.content + if content: + conversation.append({ + "role": "assistant", + "content": content, + }) + + return conversation + + +# Global interceptor instance +_interceptor = MemoraInterceptor() + + +def get_interceptor() -> MemoraInterceptor: + """Get the global interceptor instance.""" + return _interceptor + + +def cleanup_interceptor() -> None: + """Cleanup the global interceptor instance.""" + _interceptor.close() diff --git a/memora-openai/pyproject.toml b/memora-openai/pyproject.toml index b56163c9..dac971ad 100644 --- a/memora-openai/pyproject.toml +++ b/memora-openai/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ ] [tool.uv.sources] -memora-client = { path = "../memora-clients/python", editable = true } +memora-client = { workspace = true } [project.optional-dependencies] dev = [ @@ -24,7 +24,7 @@ requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] -packages = ["src/memora_openai"] +packages = ["memora_openai"] [tool.pytest.ini_options] asyncio_mode = "auto" diff --git a/memora-openai/src/memora_openai/interceptor.py b/memora-openai/src/memora_openai/interceptor.py deleted file mode 100644 index ccbdef8e..00000000 --- a/memora-openai/src/memora_openai/interceptor.py +++ /dev/null @@ -1,268 +0,0 @@ -"""Request/response interceptor for OpenAI API calls.""" - -from typing import Any, Dict, List, Optional -from datetime import datetime - -from agent_memory_api_client.client import Client -from agent_memory_api_client.models.search_request import SearchRequest -from agent_memory_api_client.models.batch_put_request import BatchPutRequest -from agent_memory_api_client.models.memory_item import MemoryItem -from agent_memory_api_client.api.memory_operations import ( - api_search_api_v1_agents_agent_id_memories_search_post as search_api, - api_batch_put_async_api_v1_agents_agent_id_memories_async_post as batch_put_async_api, -) - -from .config import get_config, MemoraConfig - - -class MemoraInterceptor: - """Intercepts OpenAI API calls to integrate with Memora.""" - - def __init__(self): - """Initialize the interceptor with a Memora client.""" - self._client: Optional[Client] = None - - def get_client(self, config: MemoraConfig) -> Client: - """Get or create the Memora client.""" - if self._client is None: - self._client = Client(base_url=config.memora_api_url, timeout=30.0) - return self._client - - async def close(self): - """Close the client.""" - if self._client is not None: - await self._client.__aexit__(None, None, None) - self._client = None - - def _extract_user_query(self, messages: List[Dict[str, Any]]) -> Optional[str]: - """Extract the most recent user message as a query. - - Args: - messages: List of chat messages - - Returns: - The last user message content, or None if not found - """ - for message in reversed(messages): - if message.get("role") == "user": - content = message.get("content") - if isinstance(content, str): - return content - elif isinstance(content, list): - # Handle structured content (e.g., with images) - for item in content: - if isinstance(item, dict) and item.get("type") == "text": - return item.get("text") - return None - - def _extract_conversation_context( - self, messages: List[Dict[str, Any]], window: int = 10 - ) -> str: - """Extract recent conversation context. - - Args: - messages: List of chat messages - window: Number of recent messages to include - - Returns: - Formatted conversation context - """ - recent_messages = messages[-window:] if len(messages) > window else messages - context_parts = [] - - for msg in recent_messages: - role = msg.get("role", "unknown") - content = msg.get("content", "") - - if isinstance(content, str): - context_parts.append(f"{role}: {content}") - elif isinstance(content, list): - # Handle structured content - text_parts = [] - for item in content: - if isinstance(item, dict) and item.get("type") == "text": - text_parts.append(item.get("text", "")) - if text_parts: - context_parts.append(f"{role}: {' '.join(text_parts)}") - - return "\n".join(context_parts) - - async def inject_memories( - self, messages: List[Dict[str, Any]], config: MemoraConfig - ) -> List[Dict[str, Any]]: - """Inject relevant memories into the conversation. - - Args: - messages: Original chat messages - config: Memora configuration - - Returns: - Modified messages with injected memories - """ - if not config.agent_id: - return messages - - # Extract query from last user message - query = self._extract_user_query(messages) - if not query: - return messages - - # Search for relevant memories - try: - client = self.get_client(config) - - # Create search request - search_request = SearchRequest( - query=query, - thinking_budget=config.memory_search_budget, - max_tokens=2048, - trace=False, - reranker="heuristic", - ) - - # Perform search - search_response = await search_api.asyncio( - agent_id=config.agent_id, - client=client, - body=search_request, - ) - - if not search_response or not search_response.results: - return messages - - # Format memories as context - memory_context = self._format_memories( - [result.to_dict() for result in search_response.results] - ) - - # Inject memories into the conversation - # We'll add it as a system message before the conversation - memory_message = { - "role": "system", - "content": f"Relevant context from your memory:\n\n{memory_context}", - } - - # Insert after any existing system messages but before the conversation - insert_index = 0 - for i, msg in enumerate(messages): - if msg.get("role") != "system": - insert_index = i - break - - modified_messages = ( - messages[:insert_index] + [memory_message] + messages[insert_index:] - ) - return modified_messages - - except Exception as e: - # Don't fail the request if memory injection fails - print(f"Warning: Failed to inject memories: {e}") - return messages - - def _format_memories(self, memories: List[Dict[str, Any]]) -> str: - """Format memory search results as context. - - Args: - memories: List of memory results from Memora API - - Returns: - Formatted context string - """ - parts = [] - for i, memory in enumerate(memories, 1): - text = memory.get("text", "") - event_date = memory.get("event_date") - fact_type = memory.get("fact_type", "") - - parts.append(f"{i}. {text}") - if event_date: - parts.append(f" (Date: {event_date})") - if fact_type: - parts.append(f" (Type: {fact_type})") - - return "\n".join(parts) - - async def store_conversation( - self, - messages: List[Dict[str, Any]], - response: Any, - config: MemoraConfig, - ) -> None: - """Store conversation to Memora. - - Args: - messages: Chat messages sent to OpenAI - response: Response from OpenAI - config: Memora configuration - """ - if not config.agent_id: - return - - try: - # Extract conversation context - conversation_text = self._extract_conversation_context( - messages, config.context_window - ) - - # Extract assistant response - assistant_response = "" - if hasattr(response, "choices") and response.choices: - choice = response.choices[0] - if hasattr(choice, "message") and hasattr(choice.message, "content"): - assistant_response = choice.message.content or "" - - # Combine into a single memory item - if conversation_text and assistant_response: - full_conversation = ( - f"{conversation_text}\nassistant: {assistant_response}" - ) - - # Determine event timestamp - event_date = config.event_timestamp or datetime.utcnow().isoformat() - - # Create memory item - memory_item = MemoryItem( - content=full_conversation, - event_date=event_date, - context="openai_conversation", - ) - - # Create batch put request - batch_request = BatchPutRequest( - items=[memory_item], - document_id=config.document_id, - ) - - # Get client - client = self.get_client(config) - - # Store to Memora - await batch_put_async_api.asyncio( - agent_id=config.agent_id, - client=client, - body=batch_request, - ) - - except Exception as e: - # Don't fail the request if storage fails - print(f"Warning: Failed to store conversation: {e}") - - -# Global interceptor instance -_interceptor: Optional[MemoraInterceptor] = None - - -def get_interceptor() -> MemoraInterceptor: - """Get or create the global interceptor instance.""" - global _interceptor - if _interceptor is None: - _interceptor = MemoraInterceptor() - return _interceptor - - -async def cleanup_interceptor(): - """Cleanup the global interceptor instance.""" - global _interceptor - if _interceptor is not None: - await _interceptor.close() - _interceptor = None diff --git a/memora-openai/tests/test_client.py b/memora-openai/tests/test_client.py index c1584b1b..ab641aa7 100644 --- a/memora-openai/tests/test_client.py +++ b/memora-openai/tests/test_client.py @@ -56,15 +56,11 @@ class TestConfiguration: agent_id="test-agent", store_conversations=False, inject_memories=False, - memory_search_budget=20, - context_window=5, document_id="test-doc", ) assert config.store_conversations is False assert config.inject_memories is False - assert config.memory_search_budget == 20 - assert config.context_window == 5 assert config.document_id == "test-doc" def test_reset_config(self): @@ -227,6 +223,7 @@ class TestInterceptor: def test_extract_conversation_context(self): """Test extracting conversation context.""" from memora_openai.interceptor import MemoraInterceptor + from unittest.mock import Mock interceptor = MemoraInterceptor() messages = [ @@ -235,10 +232,18 @@ class TestInterceptor: {"role": "user", "content": "Tell me about AI"}, ] - context = interceptor._extract_conversation_context(messages) - assert "user: Hello" in context - assert "assistant: Hi! How can I help?" in context - assert "user: Tell me about AI" in context + # Mock response object + mock_response = Mock() + mock_response.choices = [Mock()] + mock_response.choices[0].message = Mock() + mock_response.choices[0].message.content = "AI stands for Artificial Intelligence" + + context = interceptor._extract_conversation_context(messages, mock_response) + + # Should include recent messages and response + assert len(context) > 0 + assert any(msg["content"] == "Tell me about AI" for msg in context) + assert any(msg["content"] == "AI stands for Artificial Intelligence" for msg in context) def test_format_memories(self): """Test formatting memories.""" @@ -257,4 +262,4 @@ class TestInterceptor: formatted = interceptor._format_memories(memories) assert "1. User likes Python" in formatted assert "2. Working on AI project" in formatted - assert "Date: 2024-01-01" in formatted + assert "Relevant Memories" in formatted diff --git a/memora-openai/tutorial.ipynb b/memora-openai/tutorial.ipynb index cdb3bf34..a5335331 100644 --- a/memora-openai/tutorial.ipynb +++ b/memora-openai/tutorial.ipynb @@ -42,18 +42,6 @@ "3. **Python >= 3.10**" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Installation\n", - "\n", - "```bash\n", - "cd memora-openai\n", - "uv pip install -e .\n", - "```" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -65,30 +53,49 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 3, + "metadata": { + "jupyter": { + "is_executing": true + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "✓ Memora configured successfully!\n", + "\n", + "NOTE: This tutorial uses AsyncOpenAI which works perfectly in Jupyter notebooks.\n", + "For regular Python scripts, you can use the sync OpenAI client instead.\n" + ] + } + ], "source": [ "import os\n", - "from memora_openai import configure, OpenAI\n", + "from memora_openai import configure, AsyncOpenAI\n", "\n", "# Set your API keys\n", "# Option 1: Use Groq (fast and free)\n", "GROQ_API_KEY = os.getenv(\"GROQ_API_KEY\", \"your-groq-api-key\")\n", + "if not GROQ_API_KEY:\n", + " raise (\"GROQ_API_KEY not set\") \n", "\n", "# Option 2: Use OpenAI\n", "# OPENAI_API_KEY = os.getenv(\"OPENAI_API_KEY\", \"sk-...\")\n", "\n", "# Configure Memora integration\n", "configure(\n", - " memora_api_url=\"http://localhost:8000\", # Your Memora API server\n", + " memora_api_url=\"http://localhost:8080\", # Your Memora API server\n", " agent_id=\"tutorial-user\", # Unique ID for this user/agent\n", " store_conversations=True, # Auto-save conversations\n", " inject_memories=True, # Auto-inject relevant context\n", - " memory_search_budget=10, # Number of memories to retrieve\n", ")\n", "\n", - "print(\"✓ Memora configured successfully!\")" + "print(\"✓ Memora configured successfully!\")\n", + "print(\"\")\n", + "print(\"NOTE: This tutorial uses AsyncOpenAI which works perfectly in Jupyter notebooks.\")\n", + "print(\"For regular Python scripts, you can use the sync OpenAI client instead.\")" ] }, { @@ -102,19 +109,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== First Conversation ===\n" + ] + }, + { + "ename": "AttributeError", + "evalue": "'MemoraInterceptor' object has no attribute 'inject_memories'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[7]\u001b[39m\u001b[32m, line 9\u001b[39m\n\u001b[32m 7\u001b[39m \u001b[38;5;66;03m# First conversation - establish some facts\u001b[39;00m\n\u001b[32m 8\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33m=== First Conversation ===\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m----> \u001b[39m\u001b[32m9\u001b[39m response = \u001b[38;5;28;01mawait\u001b[39;00m client.chat.completions.create(\n\u001b[32m 10\u001b[39m model=\u001b[33m\"\u001b[39m\u001b[33mllama-3.1-8b-instant\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 11\u001b[39m messages=[\n\u001b[32m 12\u001b[39m {\u001b[33m\"\u001b[39m\u001b[33mrole\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33muser\u001b[39m\u001b[33m\"\u001b[39m, \u001b[33m\"\u001b[39m\u001b[33mcontent\u001b[39m\u001b[33m\"\u001b[39m: \u001b[33m\"\u001b[39m\u001b[33mMy name is Alice and I love Python programming!\u001b[39m\u001b[33m\"\u001b[39m}\n\u001b[32m 13\u001b[39m ],\n\u001b[32m 14\u001b[39m )\n\u001b[32m 16\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mAssistant: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mresponse.choices[\u001b[32m0\u001b[39m].message.content\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33m\"\u001b[39m)\n\u001b[32m 17\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33m→ This conversation is now stored in Memora!\u001b[39m\u001b[33m\"\u001b[39m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/dev/memory-poc/memora-openai/memora_openai/client.py:102\u001b[39m, in \u001b[36m_AsyncCompletionsWrapper.create\u001b[39m\u001b[34m(self, *args, **kwargs)\u001b[39m\n\u001b[32m 100\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m config.inject_memories:\n\u001b[32m 101\u001b[39m interceptor = get_interceptor()\n\u001b[32m--> \u001b[39m\u001b[32m102\u001b[39m modified_messages = \u001b[38;5;28;01mawait\u001b[39;00m \u001b[43minterceptor\u001b[49m\u001b[43m.\u001b[49m\u001b[43minject_memories\u001b[49m(messages, config)\n\u001b[32m 103\u001b[39m kwargs[\u001b[33m\"\u001b[39m\u001b[33mmessages\u001b[39m\u001b[33m\"\u001b[39m] = modified_messages\n\u001b[32m 105\u001b[39m \u001b[38;5;66;03m# Call original OpenAI API\u001b[39;00m\n", + "\u001b[31mAttributeError\u001b[39m: 'MemoraInterceptor' object has no attribute 'inject_memories'" + ] + } + ], "source": [ "# Create client (using Groq's OpenAI-compatible API)\n", - "client = OpenAI(\n", + "client = AsyncOpenAI(\n", " api_key=GROQ_API_KEY,\n", " base_url=\"https://api.groq.com/openai/v1\",\n", ")\n", "\n", "# First conversation - establish some facts\n", "print(\"=== First Conversation ===\")\n", - "response = client.chat.completions.create(\n", + "response = await client.chat.completions.create(\n", " model=\"llama-3.1-8b-instant\",\n", " messages=[\n", " {\"role\": \"user\", \"content\": \"My name is Alice and I love Python programming!\"}\n", @@ -141,7 +168,7 @@ "outputs": [], "source": [ "print(\"=== Second Conversation (with memory) ===\")\n", - "response = client.chat.completions.create(\n", + "response = await client.chat.completions.create(\n", " model=\"llama-3.1-8b-instant\",\n", " messages=[\n", " {\"role\": \"user\", \"content\": \"What's my name and what do I like?\"}\n", @@ -211,7 +238,7 @@ "source": [ "# Conversation 1: Share a preference\n", "print(\"=== Conversation 1: Sharing preferences ===\")\n", - "response = client.chat.completions.create(\n", + "response = await client.chat.completions.create(\n", " model=\"llama-3.1-8b-instant\",\n", " messages=[\n", " {\"role\": \"user\", \"content\": \"I'm working on a machine learning project using PyTorch.\"}\n", @@ -221,7 +248,7 @@ "\n", "# Conversation 2: Different topic\n", "print(\"=== Conversation 2: Different topic ===\")\n", - "response = client.chat.completions.create(\n", + "response = await client.chat.completions.create(\n", " model=\"llama-3.1-8b-instant\",\n", " messages=[\n", " {\"role\": \"user\", \"content\": \"I prefer functional programming over OOP.\"}\n", @@ -231,7 +258,7 @@ "\n", "# Conversation 3: Ask for recommendations\n", "print(\"=== Conversation 3: Getting personalized advice ===\")\n", - "response = client.chat.completions.create(\n", + "response = await client.chat.completions.create(\n", " model=\"llama-3.1-8b-instant\",\n", " messages=[\n", " {\"role\": \"user\", \"content\": \"Can you recommend a good book for me based on what you know?\"}\n", @@ -273,7 +300,7 @@ "]\n", "\n", "for msg in conversations:\n", - " response = client.chat.completions.create(\n", + " response = await client.chat.completions.create(\n", " model=\"llama-3.1-8b-instant\",\n", " messages=[{\"role\": \"user\", \"content\": msg}],\n", " )\n", @@ -356,23 +383,16 @@ " store_conversations=True, # Store conversations automatically\n", " inject_memories=True, # Inject memories automatically\n", " \n", - " # Memory retrieval\n", - " memory_search_budget=10, # Number of memories to retrieve\n", - " \n", - " # Context management\n", - " context_window=10, # Recent conversation turns to store\n", - " \n", " # Organization\n", " document_id=\"session-123\", # Optional document grouping\n", - " event_timestamp=None, # Optional custom timestamp\n", " \n", " # Control\n", " enabled=True, # Master on/off switch\n", ")\n", "\n", "print(\"Configuration options explained:\")\n", - "print(\"- memory_search_budget: Higher = more context, but more tokens\")\n", - "print(\"- context_window: How many recent messages to include when storing\")\n", + "print(\"- store_conversations: Automatically save conversations to Memora\")\n", + "print(\"- inject_memories: Automatically retrieve and inject relevant context\")\n", "print(\"- document_id: Group related conversations together\")\n", "print(\"- enabled=False: Disable Memora without changing code\")" ] @@ -430,7 +450,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -444,7 +464,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.0" + "version": "3.11.10" } }, "nbformat": 4, diff --git a/memora/memora/api.py b/memora/memora/api.py index d2925256..be540857 100644 --- a/memora/memora/api.py +++ b/memora/memora/api.py @@ -615,7 +615,8 @@ def _register_routes(app: FastAPI): response_model=GraphDataResponse, tags=["Visualization"], summary="Get memory graph data", - description="Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). Limited to 1000 most recent items." + description="Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). Limited to 1000 most recent items.", + operation_id="get_graph" ) async def api_graph( agent_id: str, @@ -637,7 +638,8 @@ def _register_routes(app: FastAPI): response_model=ListMemoryUnitsResponse, tags=["Memory Operations"], summary="List memory units", - description="List memory units with pagination and optional full-text search. Supports filtering by fact_type." + description="List memory units with pagination and optional full-text search. Supports filtering by fact_type.", + operation_id="list_memories" ) async def api_list( agent_id: str, @@ -684,7 +686,8 @@ def _register_routes(app: FastAPI): - 'world': General knowledge about people, places, events, and things that happen - 'agent': Memories about what the AI agent did, actions taken, and tasks performed - 'opinion': The agent's formed beliefs, perspectives, and viewpoints - """ + """, + operation_id="search_memories" ) async def api_search(agent_id: str, request: SearchRequest): """Run a search and return results with trace.""" @@ -765,7 +768,8 @@ def _register_routes(app: FastAPI): 4. Uses LLM to formulate a contextual answer 5. Extracts and stores any new opinions formed 6. Returns plain text answer, the facts used, and new opinions - """ + """, + operation_id="think" ) async def api_think(agent_id: str, request: ThinkRequest): try: @@ -807,7 +811,8 @@ def _register_routes(app: FastAPI): response_model=AgentListResponse, tags=["Agent Management"], summary="List all agents", - description="Get a list of all agents with their profiles" + description="Get a list of all agents with their profiles", + operation_id="list_agents" ) async def api_agents(): """Get list of all agents with their profiles.""" @@ -824,7 +829,8 @@ def _register_routes(app: FastAPI): "/api/v1/agents/{agent_id}/stats", tags=["Agent Management"], summary="Get memory statistics for an agent", - description="Get statistics about nodes and links for a specific agent" + description="Get statistics about nodes and links for a specific agent", + operation_id="get_agent_stats" ) async def api_stats(agent_id: str): """Get statistics about memory nodes and links for an agent.""" @@ -945,7 +951,8 @@ def _register_routes(app: FastAPI): response_model=ListDocumentsResponse, tags=["Documents"], summary="List documents", - description="List documents with pagination and optional search. Documents are the source content from which memory units are extracted." + description="List documents with pagination and optional search. Documents are the source content from which memory units are extracted.", + operation_id="list_documents" ) async def api_list_documents( agent_id: str, @@ -982,7 +989,8 @@ def _register_routes(app: FastAPI): response_model=DocumentResponse, tags=["Documents"], summary="Get document details", - description="Get a specific document including its original text" + description="Get a specific document including its original text", + operation_id="get_document" ) async def api_get_document( agent_id: str, @@ -1022,7 +1030,8 @@ This will cascade delete: - All links (temporal, semantic, entity) associated with those memory units This operation cannot be undone. - """ + """, + operation_id="delete_document" ) async def api_delete_document( agent_id: str, @@ -1079,7 +1088,8 @@ This operation cannot be undone. 5. Tracks document metadata Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). - """ + """, + operation_id="batch_put_memories" ) async def api_batch_put(agent_id: str, request: BatchPutRequest): try: @@ -1141,7 +1151,8 @@ This operation cannot be undone. 3. Processes in background: extracts facts, generates embeddings, creates links Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior). - """ + """, + operation_id="batch_put_async" ) async def api_batch_put_async(agent_id: str, request: BatchPutRequest): try: @@ -1203,7 +1214,8 @@ This operation cannot be undone. "/api/v1/agents/{agent_id}/operations", tags=["Memory Operations"], summary="List async operations", - description="Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations" + description="Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations", + operation_id="list_operations" ) async def api_list_operations(agent_id: str): """List all async operations (pending and failed) for an agent.""" @@ -1247,7 +1259,8 @@ This operation cannot be undone. "/api/v1/agents/{agent_id}/operations/{operation_id}", tags=["Memory Operations"], summary="Cancel a pending async operation", - description="Cancel a pending async operation by removing it from the queue" + description="Cancel a pending async operation by removing it from the queue", + operation_id="cancel_operation" ) async def api_cancel_operation(agent_id: str, operation_id: str): """Cancel a pending async operation.""" @@ -1296,7 +1309,8 @@ This operation cannot be undone. "/api/v1/agents/{agent_id}/memories/{unit_id}", tags=["Memory Operations"], summary="Delete a memory unit", - description="Delete a single memory unit and all its associated links (temporal, semantic, and entity links)" + description="Delete a single memory unit and all its associated links (temporal, semantic, and entity links)", + operation_id="delete_memory_unit" ) async def api_delete_memory_unit(agent_id: str, unit_id: str): """Delete a memory unit and all its links.""" @@ -1323,7 +1337,8 @@ This operation cannot be undone. response_model=AgentProfileResponse, tags=["Agent Management"], summary="Get agent profile", - description="Get personality traits and background for an agent. Auto-creates agent with defaults if not exists." + description="Get personality traits and background for an agent. Auto-creates agent with defaults if not exists.", + operation_id="get_agent_profile" ) async def api_get_agent_profile(agent_id: str): """Get agent profile (personality + background).""" @@ -1347,7 +1362,8 @@ This operation cannot be undone. response_model=AgentProfileResponse, tags=["Agent Management"], summary="Update agent personality", - description="Update agent's Big Five personality traits and bias strength" + description="Update agent's Big Five personality traits and bias strength", + operation_id="update_agent_personality" ) async def api_update_agent_personality( agent_id: str, @@ -1381,7 +1397,8 @@ This operation cannot be undone. response_model=BackgroundResponse, tags=["Agent Management"], summary="Add/merge agent background", - description="Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits." + description="Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.", + operation_id="add_agent_background" ) async def api_add_agent_background( agent_id: str, @@ -1412,7 +1429,8 @@ This operation cannot be undone. response_model=AgentProfileResponse, tags=["Agent Management"], summary="Create or update agent", - description="Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults." + description="Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.", + operation_id="create_or_update_agent" ) async def api_create_or_update_agent( agent_id: str, @@ -1483,7 +1501,8 @@ This operation cannot be undone. response_model=DeleteResponse, tags=["Agent Management"], summary="Clear agent memories", - description="Delete memory units for an agent. Optionally filter by fact_type (world, agent, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The agent profile (personality and background) will be preserved." + description="Delete memory units for an agent. Optionally filter by fact_type (world, agent, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The agent profile (personality and background) will be preserved.", + operation_id="clear_agent_memories" ) async def api_clear_agent_memories( agent_id: str, diff --git a/openapi.json b/openapi.json index d5ea048d..37d0fa64 100644 --- a/openapi.json +++ b/openapi.json @@ -20,7 +20,7 @@ ], "summary": "Get memory graph data", "description": "Retrieve graph data for visualization, optionally filtered by fact_type (world/agent/opinion). Limited to 1000 most recent items.", - "operationId": "api_graph_api_v1_agents__agent_id__graph_get", + "operationId": "get_graph", "parameters": [ { "name": "agent_id", @@ -79,7 +79,7 @@ ], "summary": "List memory units", "description": "List memory units with pagination and optional full-text search. Supports filtering by fact_type.", - "operationId": "api_list_api_v1_agents__agent_id__memories_list_get", + "operationId": "list_memories", "parameters": [ { "name": "agent_id", @@ -174,7 +174,7 @@ ], "summary": "Search memory", "description": "Search memory using semantic similarity and spreading activation.\n\n The fact_type parameter is optional and must be one of:\n - 'world': General knowledge about people, places, events, and things that happen\n - 'agent': Memories about what the AI agent did, actions taken, and tasks performed\n - 'opinion': The agent's formed beliefs, perspectives, and viewpoints", - "operationId": "api_search_api_v1_agents__agent_id__memories_search_post", + "operationId": "search_memories", "parameters": [ { "name": "agent_id", @@ -227,7 +227,7 @@ ], "summary": "Think and generate answer", "description": "Think and formulate an answer using agent identity, world facts, and opinions.\n\n This endpoint:\n 1. Retrieves agent facts (agent's identity)\n 2. Retrieves world facts relevant to the query\n 3. Retrieves existing opinions (agent's perspectives)\n 4. Uses LLM to formulate a contextual answer\n 5. Extracts and stores any new opinions formed\n 6. Returns plain text answer, the facts used, and new opinions", - "operationId": "api_think_api_v1_agents__agent_id__think_post", + "operationId": "think", "parameters": [ { "name": "agent_id", @@ -280,7 +280,7 @@ ], "summary": "List all agents", "description": "Get a list of all agents with their profiles", - "operationId": "api_agents_api_v1_agents_get", + "operationId": "list_agents", "responses": { "200": { "description": "Successful Response", @@ -302,7 +302,7 @@ ], "summary": "Get memory statistics for an agent", "description": "Get statistics about nodes and links for a specific agent", - "operationId": "api_stats_api_v1_agents__agent_id__stats_get", + "operationId": "get_agent_stats", "parameters": [ { "name": "agent_id", @@ -343,7 +343,7 @@ ], "summary": "List documents", "description": "List documents with pagination and optional search. Documents are the source content from which memory units are extracted.", - "operationId": "api_list_documents_api_v1_agents__agent_id__documents_get", + "operationId": "list_documents", "parameters": [ { "name": "agent_id", @@ -422,7 +422,7 @@ ], "summary": "Get document details", "description": "Get a specific document including its original text", - "operationId": "api_get_document_api_v1_agents__agent_id__documents__document_id__get", + "operationId": "get_document", "parameters": [ { "name": "agent_id", @@ -465,6 +465,54 @@ } } } + }, + "delete": { + "tags": [ + "Documents" + ], + "summary": "Delete a document", + "description": "Delete a document and all its associated memory units and links.\n\nThis will cascade delete:\n- The document itself\n- All memory units extracted from this document\n- All links (temporal, semantic, entity) associated with those memory units\n\nThis operation cannot be undone.", + "operationId": "delete_document", + "parameters": [ + { + "name": "agent_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Agent Id" + } + }, + { + "name": "document_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Document Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } } }, "/api/v1/agents/{agent_id}/memories": { @@ -474,7 +522,7 @@ ], "summary": "Store multiple memories", "description": "Store multiple memory items in batch with automatic fact extraction.\n\n Features:\n - Efficient batch processing\n - Automatic fact extraction from natural language\n - Entity recognition and linking\n - Document tracking with automatic upsert (when document_id is provided)\n - Temporal and semantic linking\n\n The system automatically:\n 1. Extracts semantic facts from the content\n 2. Generates embeddings\n 3. Deduplicates similar facts\n 4. Creates temporal, semantic, and entity links\n 5. Tracks document metadata\n\n Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior).", - "operationId": "api_batch_put_api_v1_agents__agent_id__memories_post", + "operationId": "batch_put_memories", "parameters": [ { "name": "agent_id", @@ -518,6 +566,65 @@ } } } + }, + "delete": { + "tags": [ + "Agent Management" + ], + "summary": "Clear agent memories", + "description": "Delete memory units for an agent. Optionally filter by fact_type (world, agent, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The agent profile (personality and background) will be preserved.", + "operationId": "clear_agent_memories", + "parameters": [ + { + "name": "agent_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "Agent Id" + } + }, + { + "name": "fact_type", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional fact type filter (world, agent, opinion)", + "title": "Fact Type" + }, + "description": "Optional fact type filter (world, agent, opinion)" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } } }, "/api/v1/agents/{agent_id}/memories/async": { @@ -527,7 +634,7 @@ ], "summary": "Store multiple memories asynchronously", "description": "Store multiple memory items in batch asynchronously using the task backend.\n\n This endpoint returns immediately after queuing the task, without waiting for completion.\n The actual processing happens in the background.\n\n Features:\n - Immediate response (non-blocking)\n - Background processing via task queue\n - Efficient batch processing\n - Automatic fact extraction from natural language\n - Entity recognition and linking\n - Document tracking with automatic upsert (when document_id is provided)\n - Temporal and semantic linking\n\n The system automatically:\n 1. Queues the batch put task\n 2. Returns immediately with success=True, queued=True\n 3. Processes in background: extracts facts, generates embeddings, creates links\n\n Note: If document_id is provided and already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior).", - "operationId": "api_batch_put_async_api_v1_agents__agent_id__memories_async_post", + "operationId": "batch_put_async", "parameters": [ { "name": "agent_id", @@ -580,7 +687,7 @@ ], "summary": "List async operations", "description": "Get a list of all async operations (pending and failed) for a specific agent, including error messages for failed operations", - "operationId": "api_list_operations_api_v1_agents__agent_id__operations_get", + "operationId": "list_operations", "parameters": [ { "name": "agent_id", @@ -621,7 +728,7 @@ ], "summary": "Cancel a pending async operation", "description": "Cancel a pending async operation by removing it from the queue", - "operationId": "api_cancel_operation_api_v1_agents__agent_id__operations__operation_id__delete", + "operationId": "cancel_operation", "parameters": [ { "name": "agent_id", @@ -671,7 +778,7 @@ ], "summary": "Delete a memory unit", "description": "Delete a single memory unit and all its associated links (temporal, semantic, and entity links)", - "operationId": "api_delete_memory_unit_api_v1_agents__agent_id__memories__unit_id__delete", + "operationId": "delete_memory_unit", "parameters": [ { "name": "agent_id", @@ -721,7 +828,7 @@ ], "summary": "Get agent profile", "description": "Get personality traits and background for an agent. Auto-creates agent with defaults if not exists.", - "operationId": "api_get_agent_profile_api_v1_agents__agent_id__profile_get", + "operationId": "get_agent_profile", "parameters": [ { "name": "agent_id", @@ -762,7 +869,7 @@ ], "summary": "Update agent personality", "description": "Update agent's Big Five personality traits and bias strength", - "operationId": "api_update_agent_personality_api_v1_agents__agent_id__profile_put", + "operationId": "update_agent_personality", "parameters": [ { "name": "agent_id", @@ -815,7 +922,7 @@ ], "summary": "Add/merge agent background", "description": "Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.", - "operationId": "api_add_agent_background_api_v1_agents__agent_id__background_post", + "operationId": "add_agent_background", "parameters": [ { "name": "agent_id", @@ -868,7 +975,7 @@ ], "summary": "Create or update agent", "description": "Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.", - "operationId": "api_create_or_update_agent_api_v1_agents__agent_id__put", + "operationId": "create_or_update_agent", "parameters": [ { "name": "agent_id", @@ -948,6 +1055,10 @@ "type": "string", "title": "Agent Id" }, + "name": { + "type": "string", + "title": "Name" + }, "personality": { "$ref": "#/components/schemas/PersonalityTraits" }, @@ -981,6 +1092,7 @@ "type": "object", "required": [ "agent_id", + "name", "personality", "background" ], @@ -1009,6 +1121,7 @@ "agent_id": "user123", "background": "I am a software engineer", "created_at": "2024-01-15T10:30:00Z", + "name": "Alice", "personality": { "agreeableness": 0.5, "bias_strength": 0.5, @@ -1028,6 +1141,10 @@ "type": "string", "title": "Agent Id" }, + "name": { + "type": "string", + "title": "Name" + }, "personality": { "$ref": "#/components/schemas/PersonalityTraits" }, @@ -1039,6 +1156,7 @@ "type": "object", "required": [ "agent_id", + "name", "personality", "background" ], @@ -1047,6 +1165,7 @@ "example": { "agent_id": "user123", "background": "I am a software engineer with 10 years of experience in startups", + "name": "Alice", "personality": { "agreeableness": 0.7, "bias_strength": 0.7, @@ -1235,6 +1354,17 @@ }, "CreateAgentRequest": { "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Name" + }, "personality": { "anyOf": [ { @@ -1262,6 +1392,7 @@ "description": "Request model for creating/updating an agent.", "example": { "background": "I am a creative software engineer with 10 years of experience", + "name": "Alice", "personality": { "agreeableness": 0.7, "bias_strength": 0.7, @@ -1272,6 +1403,29 @@ } } }, + "DeleteResponse": { + "properties": { + "success": { + "type": "boolean", + "title": "Success" + }, + "message": { + "type": "string", + "title": "Message" + } + }, + "type": "object", + "required": [ + "success", + "message" + ], + "title": "DeleteResponse", + "description": "Response model for delete operations.", + "example": { + "message": "Resource deleted successfully", + "success": true + } + }, "DocumentResponse": { "properties": { "id": { @@ -1652,11 +1806,6 @@ "title": "Max Tokens", "default": 4096 }, - "reranker": { - "type": "string", - "title": "Reranker", - "default": "heuristic" - }, "trace": { "type": "boolean", "title": "Trace", @@ -1688,7 +1837,6 @@ "max_tokens": 4096, "query": "What did Alice say about machine learning?", "question_date": "2023-05-30T23:40:00", - "reranker": "heuristic", "thinking_budget": 100, "trace": true } @@ -1724,7 +1872,6 @@ "example": { "results": [ { - "activation": 0.95, "context": "work info", "event_date": "2024-01-15T10:30:00Z", "id": "123e4567-e89b-12d3-a456-426614174000", @@ -1760,17 +1907,6 @@ ], "title": "Type" }, - "activation": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "title": "Activation" - }, "context": { "anyOf": [ { @@ -1792,6 +1928,17 @@ } ], "title": "Event Date" + }, + "document_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Document Id" } }, "type": "object", @@ -1803,6 +1950,7 @@ "description": "Single search result item.", "example": { "context": "work info", + "document_id": "session_abc123", "event_date": "2024-01-15T10:30:00Z", "id": "123e4567-e89b-12d3-a456-426614174000", "text": "Alice works at Google on the AI team", @@ -1837,17 +1985,6 @@ ], "title": "Type" }, - "activation": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "title": "Activation" - }, "context": { "anyOf": [ { @@ -1952,13 +2089,11 @@ "example": { "based_on": [ { - "activation": 0.9, "id": "123", "text": "AI is used in healthcare", "type": "world" }, { - "activation": 0.85, "id": "456", "text": "I discussed AI applications last week", "type": "agent" @@ -2018,4 +2153,4 @@ } } } -} \ No newline at end of file +} diff --git a/pyproject.toml b/pyproject.toml index 58677ec1..ea89cbb1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.uv.workspace] -members = ["memora", "memora-dev", "memora-dev/benchmarks", "memora-mcp-server"] +members = ["memora", "memora-dev", "memora-dev/benchmarks", "memora-mcp-server", "memora-openai", "memora-langmem", "memora-clients/python"] [tool.uv] dev-dependencies = [] diff --git a/scripts/generate-clients.sh b/scripts/generate-clients.sh index 8669eec4..d81b4fbd 100755 --- a/scripts/generate-clients.sh +++ b/scripts/generate-clients.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -e -# Script to generate Python and TypeScript clients from OpenAPI spec +# Script to generate Python and TypeScript clients from OpenAPI spec using openapi-generator # Usage: ./scripts/generate-clients.sh SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -10,7 +10,7 @@ CLIENTS_DIR="$PROJECT_ROOT/memora-clients" OPENAPI_SPEC="$PROJECT_ROOT/openapi.json" echo "==================================================" -echo "Memora API Client Generator" +echo "Memora API Client Generator (openapi-generator)" echo "==================================================" echo "Project root: $PROJECT_ROOT" echo "Clients directory: $CLIENTS_DIR" @@ -20,30 +20,18 @@ echo "" # Check if OpenAPI spec exists if [ ! -f "$OPENAPI_SPEC" ]; then echo "❌ Error: OpenAPI spec not found at $OPENAPI_SPEC" - echo "" - echo "Please generate the OpenAPI spec first:" - echo " cd memora && uv run python -c 'from memora.api import create_app; import json; app = create_app(); print(json.dumps(app.openapi(), indent=2))' > ../openapi.json" exit 1 fi echo "✓ OpenAPI spec found" echo "" -# Check for required tools -echo "Checking required tools..." - -# Check Python client generator -if ! command -v openapi-python-client &> /dev/null; then - echo "Installing openapi-python-client..." - pip install openapi-python-client -fi -echo "✓ openapi-python-client available" - -# Check TypeScript client generator (we'll use npx, no global install needed) -if ! command -v npx &> /dev/null; then - echo "❌ Error: npx not found. Please install Node.js" +# Check for Docker (we'll use Docker to run openapi-generator) +if ! command -v docker &> /dev/null; then + echo "❌ Error: Docker not found. Please install Docker" + echo " https://docs.docker.com/get-docker/" exit 1 fi -echo "✓ npx available (will use for openapi-typescript-codegen)" +echo "✓ Docker available" echo "" # Generate Python client @@ -53,30 +41,56 @@ echo "==================================================" PYTHON_CLIENT_DIR="$CLIENTS_DIR/python" -# Remove old generated client code (but keep pyproject.toml) +# Backup the maintained wrapper file +WRAPPER_FILE="$PYTHON_CLIENT_DIR/memora_client.py" +WRAPPER_BACKUP="/tmp/memora_client_backup.py" +if [ -f "$WRAPPER_FILE" ]; then + echo "📦 Backing up maintained wrapper: memora_client.py" + cp "$WRAPPER_FILE" "$WRAPPER_BACKUP" +fi + +# Remove old generated code (but keep config and maintained files) if [ -d "$PYTHON_CLIENT_DIR/agent_memory_api_client" ]; then - echo "Removing old Python client code..." + echo "Removing old generated code..." rm -rf "$PYTHON_CLIENT_DIR/agent_memory_api_client" fi -# Generate new client -# Use --meta none to avoid overwriting pyproject.toml after first generation -echo "Generating from $OPENAPI_SPEC..." -cd "$CLIENTS_DIR/python" +# Remove other generated files but keep pyproject.toml and config +for file in setup.py setup.cfg requirements.txt test-requirements.txt tox.ini git_push.sh .travis.yml .gitlab-ci.yml .gitignore README.md; do + if [ -f "$PYTHON_CLIENT_DIR/$file" ]; then + rm "$PYTHON_CLIENT_DIR/$file" + fi +done -# Check if pyproject.toml exists (already customized) -if [ -f "pyproject.toml" ]; then - echo "Note: Using --meta none to preserve your custom pyproject.toml" - openapi-python-client generate --path "$OPENAPI_SPEC" --output-path . --overwrite --meta none -else - echo "First time generation: Creating pyproject.toml with uv" - openapi-python-client generate --path "$OPENAPI_SPEC" --output-path . --overwrite --meta uv +echo "Generating new client with openapi-generator..." +cd "$PYTHON_CLIENT_DIR" + +# Run openapi-generator via Docker +docker run --rm \ + -v "$OPENAPI_SPEC:/local/openapi.json" \ + -v "$PYTHON_CLIENT_DIR:/local/out" \ + -v "$PYTHON_CLIENT_DIR/openapi-generator-config.yaml:/local/config.yaml" \ + openapitools/openapi-generator-cli generate \ + -i /local/openapi.json \ + -g python \ + -o /local/out \ + -c /local/config.yaml + +echo "Organizing generated files..." + +# The generator creates files directly, we need to ensure proper structure +# openapi-generator puts source code in agent_memory_api_client/ by default + +# Restore the maintained wrapper file +if [ -f "$WRAPPER_BACKUP" ]; then + echo "📦 Restoring maintained wrapper: memora_client.py" + cp "$WRAPPER_BACKUP" "$WRAPPER_FILE" + rm "$WRAPPER_BACKUP" fi -# The generator creates a directory with the project name, we need to move it -if [ -d "memora-api-client" ]; then - mv memora-api-client/* . - rm -rf memora-api-client +# Keep our custom pyproject.toml (don't let generator overwrite it) +if [ -f "setup.py" ]; then + echo "Note: setup.py generated but we're using pyproject.toml" fi echo "✓ Python client generated at $PYTHON_CLIENT_DIR" @@ -117,9 +131,10 @@ echo "" echo "Python client: $PYTHON_CLIENT_DIR" echo "TypeScript client: $TYPESCRIPT_CLIENT_DIR" echo "" +echo "⚠️ Important: The maintained wrapper memora_client.py was preserved" +echo "" echo "Next steps:" echo " 1. Review the generated clients" echo " 2. Update package versions if needed" echo " 3. Test the clients" -echo " 4. Publish to package registries" echo "" diff --git a/uv.lock b/uv.lock index 9f1027ea..4090e236 100644 --- a/uv.lock +++ b/uv.lock @@ -10,8 +10,147 @@ resolution-markers = [ members = [ "benchmarks", "memora", + "memora-client", "memora-dev", + "memora-langmem", "memora-mcp-server", + "memora-openai", +] + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265 }, +] + +[[package]] +name = "aiohttp" +version = "3.13.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/74/b321e7d7ca762638cdf8cdeceb39755d9c745aff7a64c8789be96ddf6e96/aiohttp-3.13.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4647d02df098f6434bafd7f32ad14942f05a9caa06c7016fdcc816f343997dd0", size = 743409 }, + { url = "https://files.pythonhosted.org/packages/99/3d/91524b905ec473beaf35158d17f82ef5a38033e5809fe8742e3657cdbb97/aiohttp-3.13.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e3403f24bcb9c3b29113611c3c16a2a447c3953ecf86b79775e7be06f7ae7ccb", size = 497006 }, + { url = "https://files.pythonhosted.org/packages/eb/d3/7f68bc02a67716fe80f063e19adbd80a642e30682ce74071269e17d2dba1/aiohttp-3.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:43dff14e35aba17e3d6d5ba628858fb8cb51e30f44724a2d2f0c75be492c55e9", size = 493195 }, + { url = "https://files.pythonhosted.org/packages/98/31/913f774a4708775433b7375c4f867d58ba58ead833af96c8af3621a0d243/aiohttp-3.13.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e2a9ea08e8c58bb17655630198833109227dea914cd20be660f52215f6de5613", size = 1747759 }, + { url = "https://files.pythonhosted.org/packages/e8/63/04efe156f4326f31c7c4a97144f82132c3bb21859b7bb84748d452ccc17c/aiohttp-3.13.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53b07472f235eb80e826ad038c9d106c2f653584753f3ddab907c83f49eedead", size = 1704456 }, + { url = "https://files.pythonhosted.org/packages/8e/02/4e16154d8e0a9cf4ae76f692941fd52543bbb148f02f098ca73cab9b1c1b/aiohttp-3.13.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e736c93e9c274fce6419af4aac199984d866e55f8a4cec9114671d0ea9688780", size = 1807572 }, + { url = "https://files.pythonhosted.org/packages/34/58/b0583defb38689e7f06798f0285b1ffb3a6fb371f38363ce5fd772112724/aiohttp-3.13.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ff5e771f5dcbc81c64898c597a434f7682f2259e0cd666932a913d53d1341d1a", size = 1895954 }, + { url = "https://files.pythonhosted.org/packages/6b/f3/083907ee3437425b4e376aa58b2c915eb1a33703ec0dc30040f7ae3368c6/aiohttp-3.13.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3b6fb0c207cc661fa0bf8c66d8d9b657331ccc814f4719468af61034b478592", size = 1747092 }, + { url = "https://files.pythonhosted.org/packages/ac/61/98a47319b4e425cc134e05e5f3fc512bf9a04bf65aafd9fdcda5d57ec693/aiohttp-3.13.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:97a0895a8e840ab3520e2288db7cace3a1981300d48babeb50e7425609e2e0ab", size = 1606815 }, + { url = "https://files.pythonhosted.org/packages/97/4b/e78b854d82f66bb974189135d31fce265dee0f5344f64dd0d345158a5973/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9e8f8afb552297aca127c90cb840e9a1d4bfd6a10d7d8f2d9176e1acc69bad30", size = 1723789 }, + { url = "https://files.pythonhosted.org/packages/ed/fc/9d2ccc794fc9b9acd1379d625c3a8c64a45508b5091c546dea273a41929e/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ed2f9c7216e53c3df02264f25d824b079cc5914f9e2deba94155190ef648ee40", size = 1718104 }, + { url = "https://files.pythonhosted.org/packages/66/65/34564b8765ea5c7d79d23c9113135d1dd3609173da13084830f1507d56cf/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:99c5280a329d5fa18ef30fd10c793a190d996567667908bef8a7f81f8202b948", size = 1785584 }, + { url = "https://files.pythonhosted.org/packages/30/be/f6a7a426e02fc82781afd62016417b3948e2207426d90a0e478790d1c8a4/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:2ca6ffef405fc9c09a746cb5d019c1672cd7f402542e379afc66b370833170cf", size = 1595126 }, + { url = "https://files.pythonhosted.org/packages/e5/c7/8e22d5d28f94f67d2af496f14a83b3c155d915d1fe53d94b66d425ec5b42/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:47f438b1a28e926c37632bff3c44df7d27c9b57aaf4e34b1def3c07111fdb782", size = 1800665 }, + { url = "https://files.pythonhosted.org/packages/d1/11/91133c8b68b1da9fc16555706aa7276fdf781ae2bb0876c838dd86b8116e/aiohttp-3.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9acda8604a57bb60544e4646a4615c1866ee6c04a8edef9b8ee6fd1d8fa2ddc8", size = 1739532 }, + { url = "https://files.pythonhosted.org/packages/17/6b/3747644d26a998774b21a616016620293ddefa4d63af6286f389aedac844/aiohttp-3.13.2-cp311-cp311-win32.whl", hash = "sha256:868e195e39b24aaa930b063c08bb0c17924899c16c672a28a65afded9c46c6ec", size = 431876 }, + { url = "https://files.pythonhosted.org/packages/c3/63/688462108c1a00eb9f05765331c107f95ae86f6b197b865d29e930b7e462/aiohttp-3.13.2-cp311-cp311-win_amd64.whl", hash = "sha256:7fd19df530c292542636c2a9a85854fab93474396a52f1695e799186bbd7f24c", size = 456205 }, + { url = "https://files.pythonhosted.org/packages/29/9b/01f00e9856d0a73260e86dd8ed0c2234a466c5c1712ce1c281548df39777/aiohttp-3.13.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b1e56bab2e12b2b9ed300218c351ee2a3d8c8fdab5b1ec6193e11a817767e47b", size = 737623 }, + { url = "https://files.pythonhosted.org/packages/5a/1b/4be39c445e2b2bd0aab4ba736deb649fabf14f6757f405f0c9685019b9e9/aiohttp-3.13.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:364e25edaabd3d37b1db1f0cbcee8c73c9a3727bfa262b83e5e4cf3489a2a9dc", size = 492664 }, + { url = "https://files.pythonhosted.org/packages/28/66/d35dcfea8050e131cdd731dff36434390479b4045a8d0b9d7111b0a968f1/aiohttp-3.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c94825f744694c4b8db20b71dba9a257cd2ba8e010a803042123f3a25d50d7", size = 491808 }, + { url = "https://files.pythonhosted.org/packages/00/29/8e4609b93e10a853b65f8291e64985de66d4f5848c5637cddc70e98f01f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba2715d842ffa787be87cbfce150d5e88c87a98e0b62e0f5aa489169a393dbbb", size = 1738863 }, + { url = "https://files.pythonhosted.org/packages/9d/fa/4ebdf4adcc0def75ced1a0d2d227577cd7b1b85beb7edad85fcc87693c75/aiohttp-3.13.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:585542825c4bc662221fb257889e011a5aa00f1ae4d75d1d246a5225289183e3", size = 1700586 }, + { url = "https://files.pythonhosted.org/packages/da/04/73f5f02ff348a3558763ff6abe99c223381b0bace05cd4530a0258e52597/aiohttp-3.13.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39d02cb6025fe1aabca329c5632f48c9532a3dabccd859e7e2f110668972331f", size = 1768625 }, + { url = "https://files.pythonhosted.org/packages/f8/49/a825b79ffec124317265ca7d2344a86bcffeb960743487cb11988ffb3494/aiohttp-3.13.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e67446b19e014d37342f7195f592a2a948141d15a312fe0e700c2fd2f03124f6", size = 1867281 }, + { url = "https://files.pythonhosted.org/packages/b9/48/adf56e05f81eac31edcfae45c90928f4ad50ef2e3ea72cb8376162a368f8/aiohttp-3.13.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4356474ad6333e41ccefd39eae869ba15a6c5299c9c01dfdcfdd5c107be4363e", size = 1752431 }, + { url = "https://files.pythonhosted.org/packages/30/ab/593855356eead019a74e862f21523db09c27f12fd24af72dbc3555b9bfd9/aiohttp-3.13.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eeacf451c99b4525f700f078becff32c32ec327b10dcf31306a8a52d78166de7", size = 1562846 }, + { url = "https://files.pythonhosted.org/packages/39/0f/9f3d32271aa8dc35036e9668e31870a9d3b9542dd6b3e2c8a30931cb27ae/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8a9b889aeabd7a4e9af0b7f4ab5ad94d42e7ff679aaec6d0db21e3b639ad58d", size = 1699606 }, + { url = "https://files.pythonhosted.org/packages/2c/3c/52d2658c5699b6ef7692a3f7128b2d2d4d9775f2a68093f74bca06cf01e1/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fa89cb11bc71a63b69568d5b8a25c3ca25b6d54c15f907ca1c130d72f320b76b", size = 1720663 }, + { url = "https://files.pythonhosted.org/packages/9b/d4/8f8f3ff1fb7fb9e3f04fcad4e89d8a1cd8fc7d05de67e3de5b15b33008ff/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8aa7c807df234f693fed0ecd507192fc97692e61fee5702cdc11155d2e5cadc8", size = 1737939 }, + { url = "https://files.pythonhosted.org/packages/03/d3/ddd348f8a27a634daae39a1b8e291ff19c77867af438af844bf8b7e3231b/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9eb3e33fdbe43f88c3c75fa608c25e7c47bbd80f48d012763cb67c47f39a7e16", size = 1555132 }, + { url = "https://files.pythonhosted.org/packages/39/b8/46790692dc46218406f94374903ba47552f2f9f90dad554eed61bfb7b64c/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9434bc0d80076138ea986833156c5a48c9c7a8abb0c96039ddbb4afc93184169", size = 1764802 }, + { url = "https://files.pythonhosted.org/packages/ba/e4/19ce547b58ab2a385e5f0b8aa3db38674785085abcf79b6e0edd1632b12f/aiohttp-3.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff15c147b2ad66da1f2cbb0622313f2242d8e6e8f9b79b5206c84523a4473248", size = 1719512 }, + { url = "https://files.pythonhosted.org/packages/70/30/6355a737fed29dcb6dfdd48682d5790cb5eab050f7b4e01f49b121d3acad/aiohttp-3.13.2-cp312-cp312-win32.whl", hash = "sha256:27e569eb9d9e95dbd55c0fc3ec3a9335defbf1d8bc1d20171a49f3c4c607b93e", size = 426690 }, + { url = "https://files.pythonhosted.org/packages/0a/0d/b10ac09069973d112de6ef980c1f6bb31cb7dcd0bc363acbdad58f927873/aiohttp-3.13.2-cp312-cp312-win_amd64.whl", hash = "sha256:8709a0f05d59a71f33fd05c17fc11fcb8c30140506e13c2f5e8ee1b8964e1b45", size = 453465 }, + { url = "https://files.pythonhosted.org/packages/bf/78/7e90ca79e5aa39f9694dcfd74f4720782d3c6828113bb1f3197f7e7c4a56/aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", size = 732139 }, + { url = "https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", size = 490082 }, + { url = "https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", size = 489035 }, + { url = "https://files.pythonhosted.org/packages/d2/04/db5279e38471b7ac801d7d36a57d1230feeee130bbe2a74f72731b23c2b1/aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", size = 1720387 }, + { url = "https://files.pythonhosted.org/packages/31/07/8ea4326bd7dae2bd59828f69d7fdc6e04523caa55e4a70f4a8725a7e4ed2/aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", size = 1688314 }, + { url = "https://files.pythonhosted.org/packages/48/ab/3d98007b5b87ffd519d065225438cc3b668b2f245572a8cb53da5dd2b1bc/aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", size = 1756317 }, + { url = "https://files.pythonhosted.org/packages/97/3d/801ca172b3d857fafb7b50c7c03f91b72b867a13abca982ed6b3081774ef/aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", size = 1858539 }, + { url = "https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", size = 1739597 }, + { url = "https://files.pythonhosted.org/packages/c4/52/7bd3c6693da58ba16e657eb904a5b6decfc48ecd06e9ac098591653b1566/aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", size = 1555006 }, + { url = "https://files.pythonhosted.org/packages/48/30/9586667acec5993b6f41d2ebcf96e97a1255a85f62f3c653110a5de4d346/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", size = 1683220 }, + { url = "https://files.pythonhosted.org/packages/71/01/3afe4c96854cfd7b30d78333852e8e851dceaec1c40fd00fec90c6402dd2/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", size = 1712570 }, + { url = "https://files.pythonhosted.org/packages/11/2c/22799d8e720f4697a9e66fd9c02479e40a49de3de2f0bbe7f9f78a987808/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", size = 1733407 }, + { url = "https://files.pythonhosted.org/packages/34/cb/90f15dd029f07cebbd91f8238a8b363978b530cd128488085b5703683594/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", size = 1550093 }, + { url = "https://files.pythonhosted.org/packages/69/46/12dce9be9d3303ecbf4d30ad45a7683dc63d90733c2d9fe512be6716cd40/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", size = 1758084 }, + { url = "https://files.pythonhosted.org/packages/f9/c8/0932b558da0c302ffd639fc6362a313b98fdf235dc417bc2493da8394df7/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", size = 1716987 }, + { url = "https://files.pythonhosted.org/packages/5d/8b/f5bd1a75003daed099baec373aed678f2e9b34f2ad40d85baa1368556396/aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", size = 425859 }, + { url = "https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", size = 452192 }, + { url = "https://files.pythonhosted.org/packages/9b/36/e2abae1bd815f01c957cbf7be817b3043304e1c87bad526292a0410fdcf9/aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", size = 735234 }, + { url = "https://files.pythonhosted.org/packages/ca/e3/1ee62dde9b335e4ed41db6bba02613295a0d5b41f74a783c142745a12763/aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", size = 490733 }, + { url = "https://files.pythonhosted.org/packages/1a/aa/7a451b1d6a04e8d15a362af3e9b897de71d86feac3babf8894545d08d537/aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", size = 491303 }, + { url = "https://files.pythonhosted.org/packages/57/1e/209958dbb9b01174870f6a7538cd1f3f28274fdbc88a750c238e2c456295/aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", size = 1717965 }, + { url = "https://files.pythonhosted.org/packages/08/aa/6a01848d6432f241416bc4866cae8dc03f05a5a884d2311280f6a09c73d6/aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", size = 1667221 }, + { url = "https://files.pythonhosted.org/packages/87/4f/36c1992432d31bbc789fa0b93c768d2e9047ec8c7177e5cd84ea85155f36/aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", size = 1757178 }, + { url = "https://files.pythonhosted.org/packages/ac/b4/8e940dfb03b7e0f68a82b88fd182b9be0a65cb3f35612fe38c038c3112cf/aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", size = 1838001 }, + { url = "https://files.pythonhosted.org/packages/d7/ef/39f3448795499c440ab66084a9db7d20ca7662e94305f175a80f5b7e0072/aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", size = 1716325 }, + { url = "https://files.pythonhosted.org/packages/d7/51/b311500ffc860b181c05d91c59a1313bdd05c82960fdd4035a15740d431e/aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", size = 1547978 }, + { url = "https://files.pythonhosted.org/packages/31/64/b9d733296ef79815226dab8c586ff9e3df41c6aff2e16c06697b2d2e6775/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", size = 1682042 }, + { url = "https://files.pythonhosted.org/packages/3f/30/43d3e0f9d6473a6db7d472104c4eff4417b1e9df01774cb930338806d36b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", size = 1680085 }, + { url = "https://files.pythonhosted.org/packages/16/51/c709f352c911b1864cfd1087577760ced64b3e5bee2aa88b8c0c8e2e4972/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", size = 1728238 }, + { url = "https://files.pythonhosted.org/packages/19/e2/19bd4c547092b773caeb48ff5ae4b1ae86756a0ee76c16727fcfd281404b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", size = 1544395 }, + { url = "https://files.pythonhosted.org/packages/cf/87/860f2803b27dfc5ed7be532832a3498e4919da61299b4a1f8eb89b8ff44d/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", size = 1742965 }, + { url = "https://files.pythonhosted.org/packages/67/7f/db2fc7618925e8c7a601094d5cbe539f732df4fb570740be88ed9e40e99a/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", size = 1697585 }, + { url = "https://files.pythonhosted.org/packages/0c/07/9127916cb09bb38284db5036036042b7b2c514c8ebaeee79da550c43a6d6/aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", size = 431621 }, + { url = "https://files.pythonhosted.org/packages/fb/41/554a8a380df6d3a2bba8a7726429a23f4ac62aaf38de43bb6d6cde7b4d4d/aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", size = 457627 }, + { url = "https://files.pythonhosted.org/packages/c7/8e/3824ef98c039d3951cb65b9205a96dd2b20f22241ee17d89c5701557c826/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", size = 767360 }, + { url = "https://files.pythonhosted.org/packages/a4/0f/6a03e3fc7595421274fa34122c973bde2d89344f8a881b728fa8c774e4f1/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", size = 504616 }, + { url = "https://files.pythonhosted.org/packages/c6/aa/ed341b670f1bc8a6f2c6a718353d13b9546e2cef3544f573c6a1ff0da711/aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", size = 509131 }, + { url = "https://files.pythonhosted.org/packages/7f/f0/c68dac234189dae5c4bbccc0f96ce0cc16b76632cfc3a08fff180045cfa4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", size = 1864168 }, + { url = "https://files.pythonhosted.org/packages/8f/65/75a9a76db8364b5d0e52a0c20eabc5d52297385d9af9c35335b924fafdee/aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", size = 1719200 }, + { url = "https://files.pythonhosted.org/packages/f5/55/8df2ed78d7f41d232f6bd3ff866b6f617026551aa1d07e2f03458f964575/aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", size = 1843497 }, + { url = "https://files.pythonhosted.org/packages/e9/e0/94d7215e405c5a02ccb6a35c7a3a6cfff242f457a00196496935f700cde5/aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", size = 1935703 }, + { url = "https://files.pythonhosted.org/packages/0b/78/1eeb63c3f9b2d1015a4c02788fb543141aad0a03ae3f7a7b669b2483f8d4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", size = 1792738 }, + { url = "https://files.pythonhosted.org/packages/41/75/aaf1eea4c188e51538c04cc568040e3082db263a57086ea74a7d38c39e42/aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", size = 1624061 }, + { url = "https://files.pythonhosted.org/packages/9b/c2/3b6034de81fbcc43de8aeb209073a2286dfb50b86e927b4efd81cf848197/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", size = 1789201 }, + { url = "https://files.pythonhosted.org/packages/c9/38/c15dcf6d4d890217dae79d7213988f4e5fe6183d43893a9cf2fe9e84ca8d/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", size = 1776868 }, + { url = "https://files.pythonhosted.org/packages/04/75/f74fd178ac81adf4f283a74847807ade5150e48feda6aef024403716c30c/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", size = 1790660 }, + { url = "https://files.pythonhosted.org/packages/e7/80/7368bd0d06b16b3aba358c16b919e9c46cf11587dc572091031b0e9e3ef0/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", size = 1617548 }, + { url = "https://files.pythonhosted.org/packages/7d/4b/a6212790c50483cb3212e507378fbe26b5086d73941e1ec4b56a30439688/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", size = 1817240 }, + { url = "https://files.pythonhosted.org/packages/ff/f7/ba5f0ba4ea8d8f3c32850912944532b933acbf0f3a75546b89269b9b7dde/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", size = 1762334 }, + { url = "https://files.pythonhosted.org/packages/7e/83/1a5a1856574588b1cad63609ea9ad75b32a8353ac995d830bf5da9357364/aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", size = 464685 }, + { url = "https://files.pythonhosted.org/packages/9f/4d/d22668674122c08f4d56972297c51a624e64b3ed1efaa40187607a7cb66e/aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", size = 498093 }, +] + +[[package]] +name = "aiohttp-retry" +version = "2.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/61/ebda4d8e3d8cfa1fd3db0fb428db2dd7461d5742cea35178277ad180b033/aiohttp_retry-2.9.1.tar.gz", hash = "sha256:8eb75e904ed4ee5c2ec242fefe85bf04240f685391c4879d8f541d6028ff01f1", size = 13608 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/99/84ba7273339d0f3dfa57901b846489d2e5c2cd731470167757f1935fffbd/aiohttp_retry-2.9.1-py3-none-any.whl", hash = "sha256:66d2759d1921838256a05a3f80ad7e724936f083e35be5abb5e16eed6be6dc54", size = 9981 }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490 }, ] [[package]] @@ -729,6 +868,111 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054 }, ] +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/03/077f869d540370db12165c0aa51640a873fb661d8b315d1d4d67b284d7ac/frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84", size = 86912 }, + { url = "https://files.pythonhosted.org/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9", size = 50046 }, + { url = "https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93", size = 50119 }, + { url = "https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f", size = 231067 }, + { url = "https://files.pythonhosted.org/packages/45/7e/afe40eca3a2dc19b9904c0f5d7edfe82b5304cb831391edec0ac04af94c2/frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695", size = 233160 }, + { url = "https://files.pythonhosted.org/packages/a6/aa/7416eac95603ce428679d273255ffc7c998d4132cfae200103f164b108aa/frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52", size = 228544 }, + { url = "https://files.pythonhosted.org/packages/8b/3d/2a2d1f683d55ac7e3875e4263d28410063e738384d3adc294f5ff3d7105e/frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581", size = 243797 }, + { url = "https://files.pythonhosted.org/packages/78/1e/2d5565b589e580c296d3bb54da08d206e797d941a83a6fdea42af23be79c/frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567", size = 247923 }, + { url = "https://files.pythonhosted.org/packages/aa/c3/65872fcf1d326a7f101ad4d86285c403c87be7d832b7470b77f6d2ed5ddc/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b", size = 230886 }, + { url = "https://files.pythonhosted.org/packages/a0/76/ac9ced601d62f6956f03cc794f9e04c81719509f85255abf96e2510f4265/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92", size = 245731 }, + { url = "https://files.pythonhosted.org/packages/b9/49/ecccb5f2598daf0b4a1415497eba4c33c1e8ce07495eb07d2860c731b8d5/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d", size = 241544 }, + { url = "https://files.pythonhosted.org/packages/53/4b/ddf24113323c0bbcc54cb38c8b8916f1da7165e07b8e24a717b4a12cbf10/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd", size = 241806 }, + { url = "https://files.pythonhosted.org/packages/a7/fb/9b9a084d73c67175484ba2789a59f8eebebd0827d186a8102005ce41e1ba/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967", size = 229382 }, + { url = "https://files.pythonhosted.org/packages/95/a3/c8fb25aac55bf5e12dae5c5aa6a98f85d436c1dc658f21c3ac73f9fa95e5/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", size = 39647 }, + { url = "https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", size = 44064 }, + { url = "https://files.pythonhosted.org/packages/5d/16/c2c9ab44e181f043a86f9a8f84d5124b62dbcb3a02c0977ec72b9ac1d3e0/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", size = 39937 }, + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782 }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594 }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448 }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411 }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014 }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909 }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049 }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485 }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619 }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320 }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820 }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518 }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096 }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985 }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591 }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102 }, + { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717 }, + { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651 }, + { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417 }, + { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391 }, + { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048 }, + { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549 }, + { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833 }, + { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363 }, + { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314 }, + { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365 }, + { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763 }, + { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110 }, + { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717 }, + { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628 }, + { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882 }, + { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676 }, + { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235 }, + { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742 }, + { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725 }, + { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506 }, + { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161 }, + { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676 }, + { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638 }, + { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067 }, + { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101 }, + { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901 }, + { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395 }, + { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659 }, + { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492 }, + { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034 }, + { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749 }, + { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127 }, + { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698 }, + { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749 }, + { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298 }, + { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015 }, + { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038 }, + { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130 }, + { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845 }, + { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131 }, + { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542 }, + { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308 }, + { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210 }, + { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972 }, + { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536 }, + { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330 }, + { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627 }, + { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238 }, + { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738 }, + { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739 }, + { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186 }, + { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196 }, + { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830 }, + { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289 }, + { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318 }, + { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814 }, + { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762 }, + { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470 }, + { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042 }, + { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148 }, + { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676 }, + { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451 }, + { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507 }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409 }, +] + [[package]] name = "fsspec" version = "2025.10.0" @@ -1243,6 +1487,62 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1e/97/d362353ab04f865af6f81d4d46e7aa428734aa032de0017934b771fc34b7/langchain_text_splitters-1.0.0-py3-none-any.whl", hash = "sha256:f00c8219d3468f2c5bd951b708b6a7dd9bc3c62d0cfb83124c377f7170f33b2e", size = 33851 }, ] +[[package]] +name = "langgraph" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "langgraph-checkpoint" }, + { name = "langgraph-prebuilt" }, + { name = "langgraph-sdk" }, + { name = "pydantic" }, + { name = "xxhash" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/55/70f2d11d33b0310d3e48d8e049825b4a34a1c822d48f6448ae548d2cd0f8/langgraph-1.0.3.tar.gz", hash = "sha256:873a6aae6be054ef52a05c463be363a46da9711405b1b14454d595f543b68335", size = 483302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/a3/fdf6ecd0e44cb02d20afe7d0fb64c748a749f4b2e011bf9a785a32642367/langgraph-1.0.3-py3-none-any.whl", hash = "sha256:4a75146f09bd0d127a724876f4244f460c4c66353a993641bd641ed710cd010f", size = 156845 }, +] + +[[package]] +name = "langgraph-checkpoint" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "ormsgpack" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0f/07/2b1c042fa87d40cf2db5ca27dc4e8dd86f9a0436a10aa4361a8982718ae7/langgraph_checkpoint-3.0.1.tar.gz", hash = "sha256:59222f875f85186a22c494aedc65c4e985a3df27e696e5016ba0b98a5ed2cee0", size = 137785 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/e3/616e3a7ff737d98c1bbb5700dd62278914e2a9ded09a79a1fa93cf24ce12/langgraph_checkpoint-3.0.1-py3-none-any.whl", hash = "sha256:9b04a8d0edc0474ce4eaf30c5d731cee38f11ddff50a6177eead95b5c4e4220b", size = 46249 }, +] + +[[package]] +name = "langgraph-prebuilt" +version = "1.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "langchain-core" }, + { name = "langgraph-checkpoint" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/84/08/45857c7c65f696307834af13946a72293e6cc49141de887f0957c2eb2c46/langgraph_prebuilt-1.0.4.tar.gz", hash = "sha256:7b4f9e97a146d2d625695c3549bdb432974b80817165139ec2ec869721e72c0f", size = 142470 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/14/a83e50129f66df783a68acb89e7b3e9c39b5c128a8748e961bc2b187f003/langgraph_prebuilt-1.0.4-py3-none-any.whl", hash = "sha256:50b1aa2b434783b6da30785568cf7155136b484750cc2ec695c0d4255db08262", size = 34414 }, +] + +[[package]] +name = "langgraph-sdk" +version = "0.2.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx" }, + { name = "orjson" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/23/d8/40e01190a73c564a4744e29a6c902f78d34d43dad9b652a363a92a67059c/langgraph_sdk-0.2.9.tar.gz", hash = "sha256:b3bd04c6be4fa382996cd2be8fbc1e7cc94857d2bc6b6f4599a7f2a245975303", size = 99802 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/05/b2d34e16638241e6f27a6946d28160d4b8b641383787646d41a3727e0896/langgraph_sdk-0.2.9-py3-none-any.whl", hash = "sha256:fbf302edadbf0fb343596f91c597794e936ef68eebc0d3e1d358b6f9f72a1429", size = 56752 }, +] + [[package]] name = "langsmith" version = "0.4.42" @@ -1449,6 +1749,38 @@ requires-dist = [ ] provides-extras = ["test"] +[[package]] +name = "memora-client" +version = "0.0.7" +source = { editable = "memora-clients/python" } +dependencies = [ + { name = "aiohttp" }, + { name = "aiohttp-retry" }, + { name = "pydantic" }, + { name = "python-dateutil" }, + { name = "typing-extensions" }, + { name = "urllib3" }, +] + +[package.optional-dependencies] +test = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiohttp", specifier = ">=3.8.4" }, + { name = "aiohttp-retry", specifier = ">=2.8.3" }, + { name = "pydantic", specifier = ">=2" }, + { name = "pytest", marker = "extra == 'test'", specifier = ">=7.0.0" }, + { name = "pytest-asyncio", marker = "extra == 'test'", specifier = ">=0.21.0" }, + { name = "python-dateutil", specifier = ">=2.8.2" }, + { name = "typing-extensions", specifier = ">=4.7.1" }, + { name = "urllib3", specifier = ">=2.1.0,<3.0.0" }, +] +provides-extras = ["test"] + [[package]] name = "memora-dev" version = "0.0.7" @@ -1460,6 +1792,28 @@ dependencies = [ [package.metadata] requires-dist = [{ name = "memora", editable = "memora" }] +[[package]] +name = "memora-langmem" +version = "0.0.1" +source = { editable = "memora-langmem" } +dependencies = [ + { name = "langgraph" }, + { name = "memora-client" }, +] + +[package.optional-dependencies] +test = [ + { name = "pytest" }, +] + +[package.metadata] +requires-dist = [ + { name = "langgraph", specifier = ">=0.2.0" }, + { name = "memora-client", editable = "memora-clients/python" }, + { name = "pytest", marker = "extra == 'test'", specifier = ">=7.0.0" }, +] +provides-extras = ["test"] + [[package]] name = "memora-mcp-server" version = "0.0.1" @@ -1475,6 +1829,32 @@ requires-dist = [ { name = "httpx", specifier = ">=0.28.1" }, ] +[[package]] +name = "memora-openai" +version = "0.1.0" +source = { editable = "memora-openai" } +dependencies = [ + { name = "memora-client" }, + { name = "openai" }, +] + +[package.optional-dependencies] +dev = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-mock" }, +] + +[package.metadata] +requires-dist = [ + { name = "memora-client", editable = "memora-clients/python" }, + { name = "openai", specifier = ">=1.0.0" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=7.0.0" }, + { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.21.0" }, + { name = "pytest-mock", marker = "extra == 'dev'", specifier = ">=3.10.0" }, +] +provides-extras = ["dev"] + [[package]] name = "more-itertools" version = "10.8.0" @@ -1493,6 +1873,123 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 }, ] +[[package]] +name = "multidict" +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/9e/5c727587644d67b2ed479041e4b1c58e30afc011e3d45d25bbe35781217c/multidict-6.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc", size = 76604 }, + { url = "https://files.pythonhosted.org/packages/17/e4/67b5c27bd17c085a5ea8f1ec05b8a3e5cba0ca734bfcad5560fb129e70ca/multidict-6.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721", size = 44715 }, + { url = "https://files.pythonhosted.org/packages/4d/e1/866a5d77be6ea435711bef2a4291eed11032679b6b28b56b4776ab06ba3e/multidict-6.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6", size = 44332 }, + { url = "https://files.pythonhosted.org/packages/31/61/0c2d50241ada71ff61a79518db85ada85fdabfcf395d5968dae1cbda04e5/multidict-6.7.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c", size = 245212 }, + { url = "https://files.pythonhosted.org/packages/ac/e0/919666a4e4b57fff1b57f279be1c9316e6cdc5de8a8b525d76f6598fefc7/multidict-6.7.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7", size = 246671 }, + { url = "https://files.pythonhosted.org/packages/a1/cc/d027d9c5a520f3321b65adea289b965e7bcbd2c34402663f482648c716ce/multidict-6.7.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7", size = 225491 }, + { url = "https://files.pythonhosted.org/packages/75/c4/bbd633980ce6155a28ff04e6a6492dd3335858394d7bb752d8b108708558/multidict-6.7.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9", size = 257322 }, + { url = "https://files.pythonhosted.org/packages/4c/6d/d622322d344f1f053eae47e033b0b3f965af01212de21b10bcf91be991fb/multidict-6.7.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8", size = 254694 }, + { url = "https://files.pythonhosted.org/packages/a8/9f/78f8761c2705d4c6d7516faed63c0ebdac569f6db1bef95e0d5218fdc146/multidict-6.7.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd", size = 246715 }, + { url = "https://files.pythonhosted.org/packages/78/59/950818e04f91b9c2b95aab3d923d9eabd01689d0dcd889563988e9ea0fd8/multidict-6.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb", size = 243189 }, + { url = "https://files.pythonhosted.org/packages/7a/3d/77c79e1934cad2ee74991840f8a0110966d9599b3af95964c0cd79bb905b/multidict-6.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6", size = 237845 }, + { url = "https://files.pythonhosted.org/packages/63/1b/834ce32a0a97a3b70f86437f685f880136677ac00d8bce0027e9fd9c2db7/multidict-6.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2", size = 246374 }, + { url = "https://files.pythonhosted.org/packages/23/ef/43d1c3ba205b5dec93dc97f3fba179dfa47910fc73aaaea4f7ceb41cec2a/multidict-6.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff", size = 253345 }, + { url = "https://files.pythonhosted.org/packages/6b/03/eaf95bcc2d19ead522001f6a650ef32811aa9e3624ff0ad37c445c7a588c/multidict-6.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b", size = 246940 }, + { url = "https://files.pythonhosted.org/packages/e8/df/ec8a5fd66ea6cd6f525b1fcbb23511b033c3e9bc42b81384834ffa484a62/multidict-6.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34", size = 242229 }, + { url = "https://files.pythonhosted.org/packages/8a/a2/59b405d59fd39ec86d1142630e9049243015a5f5291ba49cadf3c090c541/multidict-6.7.0-cp311-cp311-win32.whl", hash = "sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff", size = 41308 }, + { url = "https://files.pythonhosted.org/packages/32/0f/13228f26f8b882c34da36efa776c3b7348455ec383bab4a66390e42963ae/multidict-6.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81", size = 46037 }, + { url = "https://files.pythonhosted.org/packages/84/1f/68588e31b000535a3207fd3c909ebeec4fb36b52c442107499c18a896a2a/multidict-6.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912", size = 43023 }, + { url = "https://files.pythonhosted.org/packages/c2/9e/9f61ac18d9c8b475889f32ccfa91c9f59363480613fc807b6e3023d6f60b/multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184", size = 76877 }, + { url = "https://files.pythonhosted.org/packages/38/6f/614f09a04e6184f8824268fce4bc925e9849edfa654ddd59f0b64508c595/multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45", size = 45467 }, + { url = "https://files.pythonhosted.org/packages/b3/93/c4f67a436dd026f2e780c433277fff72be79152894d9fc36f44569cab1a6/multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa", size = 43834 }, + { url = "https://files.pythonhosted.org/packages/7f/f5/013798161ca665e4a422afbc5e2d9e4070142a9ff8905e482139cd09e4d0/multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7", size = 250545 }, + { url = "https://files.pythonhosted.org/packages/71/2f/91dbac13e0ba94669ea5119ba267c9a832f0cb65419aca75549fcf09a3dc/multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e", size = 258305 }, + { url = "https://files.pythonhosted.org/packages/ef/b0/754038b26f6e04488b48ac621f779c341338d78503fb45403755af2df477/multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546", size = 242363 }, + { url = "https://files.pythonhosted.org/packages/87/15/9da40b9336a7c9fa606c4cf2ed80a649dffeb42b905d4f63a1d7eb17d746/multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4", size = 268375 }, + { url = "https://files.pythonhosted.org/packages/82/72/c53fcade0cc94dfaad583105fd92b3a783af2091eddcb41a6d5a52474000/multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1", size = 269346 }, + { url = "https://files.pythonhosted.org/packages/0d/e2/9baffdae21a76f77ef8447f1a05a96ec4bc0a24dae08767abc0a2fe680b8/multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d", size = 256107 }, + { url = "https://files.pythonhosted.org/packages/3c/06/3f06f611087dc60d65ef775f1fb5aca7c6d61c6db4990e7cda0cef9b1651/multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304", size = 253592 }, + { url = "https://files.pythonhosted.org/packages/20/24/54e804ec7945b6023b340c412ce9c3f81e91b3bf5fa5ce65558740141bee/multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12", size = 251024 }, + { url = "https://files.pythonhosted.org/packages/14/48/011cba467ea0b17ceb938315d219391d3e421dfd35928e5dbdc3f4ae76ef/multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62", size = 251484 }, + { url = "https://files.pythonhosted.org/packages/0d/2f/919258b43bb35b99fa127435cfb2d91798eb3a943396631ef43e3720dcf4/multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0", size = 263579 }, + { url = "https://files.pythonhosted.org/packages/31/22/a0e884d86b5242b5a74cf08e876bdf299e413016b66e55511f7a804a366e/multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a", size = 259654 }, + { url = "https://files.pythonhosted.org/packages/b2/e5/17e10e1b5c5f5a40f2fcbb45953c9b215f8a4098003915e46a93f5fcaa8f/multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8", size = 251511 }, + { url = "https://files.pythonhosted.org/packages/e3/9a/201bb1e17e7af53139597069c375e7b0dcbd47594604f65c2d5359508566/multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4", size = 41895 }, + { url = "https://files.pythonhosted.org/packages/46/e2/348cd32faad84eaf1d20cce80e2bb0ef8d312c55bca1f7fa9865e7770aaf/multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b", size = 46073 }, + { url = "https://files.pythonhosted.org/packages/25/ec/aad2613c1910dce907480e0c3aa306905830f25df2e54ccc9dea450cb5aa/multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec", size = 43226 }, + { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135 }, + { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117 }, + { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472 }, + { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342 }, + { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082 }, + { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704 }, + { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355 }, + { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259 }, + { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903 }, + { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365 }, + { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062 }, + { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683 }, + { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254 }, + { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967 }, + { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085 }, + { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713 }, + { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915 }, + { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077 }, + { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114 }, + { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442 }, + { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885 }, + { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588 }, + { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966 }, + { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618 }, + { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539 }, + { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345 }, + { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934 }, + { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243 }, + { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878 }, + { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452 }, + { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312 }, + { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935 }, + { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385 }, + { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777 }, + { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104 }, + { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503 }, + { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128 }, + { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410 }, + { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205 }, + { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084 }, + { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667 }, + { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590 }, + { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112 }, + { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194 }, + { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510 }, + { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395 }, + { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520 }, + { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479 }, + { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903 }, + { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333 }, + { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411 }, + { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940 }, + { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087 }, + { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368 }, + { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326 }, + { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065 }, + { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475 }, + { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324 }, + { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877 }, + { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824 }, + { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558 }, + { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339 }, + { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895 }, + { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862 }, + { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376 }, + { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272 }, + { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774 }, + { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731 }, + { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193 }, + { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023 }, + { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507 }, + { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804 }, + { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317 }, +] + [[package]] name = "narwhals" version = "2.11.0" @@ -1834,6 +2331,53 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1a/bf/def5e25d4d8bfce296a9a7c8248109bf58622c21618b590678f945a2c59c/orjson-3.11.4-cp314-cp314-win_arm64.whl", hash = "sha256:78b999999039db3cf58f6d230f524f04f75f129ba3d1ca2ed121f8657e575d3d", size = 126151 }, ] +[[package]] +name = "ormsgpack" +version = "1.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/67/d5ef41c3b4a94400be801984ef7c7fc9623e1a82b643e74eeec367e7462b/ormsgpack-1.12.0.tar.gz", hash = "sha256:94be818fdbb0285945839b88763b269987787cb2f7ef280cad5d6ec815b7e608", size = 49959 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/ba/3cae83cf36420c1c8dd294f16c852c03313aafe2439a165c4c6ac611b1d0/ormsgpack-1.12.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:c40d86d77391b18dd34de5295e3de2b8ad818bcab9c9def4121c8ec5c9714ae4", size = 369159 }, + { url = "https://files.pythonhosted.org/packages/97/d4/5e176309e01a8b9098d80201aac1eb7db9336c3b5b4fa6254a2bbb0d0fa0/ormsgpack-1.12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:777b7fab364dc0f200bb382a98a385c8222ffa6a2333d627d763797326202c86", size = 195744 }, + { url = "https://files.pythonhosted.org/packages/4f/83/6d80c8c5571639c000a39f38f77752dfaf9d9e552d775331e8d280f66a4e/ormsgpack-1.12.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b5089ad9dd5b3d3013b245a55e4abaea2f8ad70f4a78e1b002127b02340004", size = 206474 }, + { url = "https://files.pythonhosted.org/packages/5e/e6/940311e48dc0cfc3e212bd7007a21ed0825158638057687d804f2c5c2cca/ormsgpack-1.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:deaf0c87cace7bc08fbf68c5cc66605b593df6427e9f4de235b2da358787e008", size = 207959 }, + { url = "https://files.pythonhosted.org/packages/1a/e3/fbe94b0a311815343b86a95a0627e4901b11ff6fd522679ca29a2a88c99b/ormsgpack-1.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f62d476fe28bc5675d9aff30341bfa9f41d7de332c5b63fbbe9aaf6bb7ec74d4", size = 377666 }, + { url = "https://files.pythonhosted.org/packages/a3/3b/229cfa28076798ffb619aaa854b842de3f2ed5ea4e6509bf34d14c038c4d/ormsgpack-1.12.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ded7810095b887e28434f32f5a345d354e88cf851bab3c5435aeb86a718618d2", size = 471394 }, + { url = "https://files.pythonhosted.org/packages/6b/bd/4eae4ab35586e4175c07acb5f98aec83aa9d8987f71ea0443aa900191bdf/ormsgpack-1.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f72a1dea0c4ae7c4101dcfbe8133f274a9d769d0b87fe5188db4fab07ffabaee", size = 381506 }, + { url = "https://files.pythonhosted.org/packages/dd/51/f9d56d6d015cbfa1ce9a4358ca30a41744644f0cf606e060d7203efe5af8/ormsgpack-1.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:8f479bfef847255d7d0b12c7a198f6a21490155da2da3062e082ba370893d4a1", size = 112707 }, + { url = "https://files.pythonhosted.org/packages/f4/07/bb189ef7072979f2f96e8716e952172efdce9c54930aa0814bec73aee19b/ormsgpack-1.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:3583ca410e4502144b2594170542e4bbef7b15643fd1208703ae820f11029036", size = 106533 }, + { url = "https://files.pythonhosted.org/packages/a2/f2/c1036b2775fcc0cfa5fd618c53bcd3b862ee07298fb627f03af4c7982f84/ormsgpack-1.12.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e0c1e08b64d99076fee155276097489b82cc56e8d5951c03c721a65a32f44494", size = 369538 }, + { url = "https://files.pythonhosted.org/packages/d9/ca/526c4ae02f3cb34621af91bf8282a10d666757c2e0c6ff391ff5d403d607/ormsgpack-1.12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fd43bcb299131690b8e0677af172020b2ada8e625169034b42ac0c13adf84aa", size = 195872 }, + { url = "https://files.pythonhosted.org/packages/7f/0f/83bb7968e9715f6a85be53d041b1e6324a05428f56b8b980dac866886871/ormsgpack-1.12.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f0149d595341e22ead340bf281b2995c4cc7dc8d522a6b5f575fe17aa407604", size = 206469 }, + { url = "https://files.pythonhosted.org/packages/02/e3/9e93ca1065f2d4af035804a842b1ff3025bab580c7918239bb225cd1fee2/ormsgpack-1.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f19a1b27d169deb553c80fd10b589fc2be1fc14cee779fae79fcaf40db04de2b", size = 208273 }, + { url = "https://files.pythonhosted.org/packages/b3/d8/6d6ef901b3a8b8f3ab8836b135a56eb7f66c559003e251d9530bedb12627/ormsgpack-1.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6f28896942d655064940dfe06118b7ce1e3468d051483148bf02c99ec157483a", size = 377839 }, + { url = "https://files.pythonhosted.org/packages/4c/72/fcb704bfa4c2c3a37b647d597cc45a13cffc9d50baac635a9ad620731d29/ormsgpack-1.12.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9396efcfa48b4abbc06e44c5dbc3c4574a8381a80cb4cd01eea15d28b38c554e", size = 471446 }, + { url = "https://files.pythonhosted.org/packages/84/f8/402e4e3eb997c2ee534c99bec4b5bb359c2a1f9edadf043e254a71e11378/ormsgpack-1.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:96586ed537a5fb386a162c4f9f7d8e6f76e07b38a990d50c73f11131e00ff040", size = 381783 }, + { url = "https://files.pythonhosted.org/packages/f0/8d/5897b700360bc00911b70ae5ef1134ee7abf5baa81a92a4be005917d3dfd/ormsgpack-1.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:e70387112fb3870e4844de090014212cdcf1342f5022047aecca01ec7de05d7a", size = 112943 }, + { url = "https://files.pythonhosted.org/packages/5b/44/1e73649f79bb96d6cf9e5bcbac68b6216d238bba80af351c4c0cbcf7ee15/ormsgpack-1.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:d71290a23de5d4829610c42665d816c661ecad8979883f3f06b2e3ab9639962e", size = 106688 }, + { url = "https://files.pythonhosted.org/packages/2e/e8/35f11ce9313111488b26b3035e4cbe55caa27909c0b6c8b5b5cd59f9661e/ormsgpack-1.12.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:766f2f3b512d85cd375b26a8b1329b99843560b50b93d3880718e634ad4a5de5", size = 369574 }, + { url = "https://files.pythonhosted.org/packages/61/b0/77461587f412d4e598d3687bafe23455ed0f26269f44be20252eddaa624e/ormsgpack-1.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84b285b1f3f185aad7da45641b873b30acfd13084cf829cf668c4c6480a81583", size = 195893 }, + { url = "https://files.pythonhosted.org/packages/c6/67/e197ceb04c3b550589e5407fc9fdae10f4e2e2eba5fdac921a269e02e974/ormsgpack-1.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e23604fc79fe110292cb365f4c8232e64e63a34f470538be320feae3921f271b", size = 206503 }, + { url = "https://files.pythonhosted.org/packages/0b/b1/7fa8ba82a25cef678983c7976f85edeef5014f5c26495f338258e6a3cf1c/ormsgpack-1.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc32b156c113a0fae2975051417d8d9a7a5247c34b2d7239410c46b75ce9348a", size = 208257 }, + { url = "https://files.pythonhosted.org/packages/ce/b1/759e999390000d2589e6d0797f7265e6ec28378547075d28d3736248ab63/ormsgpack-1.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:94ac500dd10c20fa8b8a23bc55606250bfe711bf9716828d9f3d44dfd1f25668", size = 377852 }, + { url = "https://files.pythonhosted.org/packages/51/e7/0af737c94272494d9d84a3c29cc42c973ef7fd2342917020906596db863c/ormsgpack-1.12.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c5201ff7ec24f721f813a182885a17064cffdbe46b2412685a52e6374a872c8f", size = 471456 }, + { url = "https://files.pythonhosted.org/packages/f4/ba/c81f0aa4f19fbf457213395945b672e6fde3ce777e3587456e7f0fca2147/ormsgpack-1.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a9740bb3839c9368aacae1cbcfc474ee6976458f41cc135372b7255d5206c953", size = 381813 }, + { url = "https://files.pythonhosted.org/packages/ce/15/429c72d64323503fd42cc4ca8398930ded8aa8b3470df8a86b3bbae7a35c/ormsgpack-1.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ed37f29772432048b58174e920a1d4c4cde0404a5d448d3d8bbcc95d86a6918", size = 112949 }, + { url = "https://files.pythonhosted.org/packages/55/b9/e72c451a40f8c57bfc229e0b8e536ecea7203c8f0a839676df2ffb605c62/ormsgpack-1.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:b03994bbec5d6d42e03d6604e327863f885bde67aa61e06107ce1fa5bdd3e71d", size = 106689 }, + { url = "https://files.pythonhosted.org/packages/13/16/13eab1a75da531b359105fdee90dda0b6bd1ca0a09880250cf91d8bdfdea/ormsgpack-1.12.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0f3981ba3cba80656012090337e548e597799e14b41e3d0b595ab5ab05a23d7f", size = 369620 }, + { url = "https://files.pythonhosted.org/packages/a0/c1/cbcc38b7af4ce58d8893e56d3595c0c8dcd117093bf048f889cf351bdba0/ormsgpack-1.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:901f6f55184d6776dbd5183cbce14caf05bf7f467eef52faf9b094686980bf71", size = 195925 }, + { url = "https://files.pythonhosted.org/packages/5c/59/4fa4dc0681490e12b75333440a1c0fd9741b0ebff272b1db4a29d35c2021/ormsgpack-1.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e13b15412571422b711b40f45e3fe6d993ea3314b5e97d1a853fe99226c5effc", size = 206594 }, + { url = "https://files.pythonhosted.org/packages/39/67/249770896bc32bb91b22c30256961f935d0915cbcf6e289a7fc961d9b14c/ormsgpack-1.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91fa8a452553a62e5fb3fbab471e7faf7b3bec3c87a2f355ebf3d7aab290fe4f", size = 208307 }, + { url = "https://files.pythonhosted.org/packages/07/0a/e041a248cd72f2f4c07e155913e0a3ede4c86cf21a40ae6cd79f135f2847/ormsgpack-1.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:74ec101f69624695eec4ce7c953192d97748254abe78fb01b591f06d529e1952", size = 377844 }, + { url = "https://files.pythonhosted.org/packages/d8/71/6f7773e4ffda73a358ce4bba69b3e8bee9d40a7a06315e4c1cd7a3ea9d02/ormsgpack-1.12.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:9bbf7896580848326c1f9bd7531f264e561f98db7e08e15aa75963d83832c717", size = 471572 }, + { url = "https://files.pythonhosted.org/packages/65/29/af6769a4289c07acc71e7bda1d64fb31800563147d73142686e185e82348/ormsgpack-1.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7567917da613b8f8d591c1674e411fd3404bea41ef2b9a0e0a1e049c0f9406d7", size = 381842 }, + { url = "https://files.pythonhosted.org/packages/0b/dd/0a86195ee7a1a96c088aefc8504385e881cf56f4563ed81bafe21cbf1fb0/ormsgpack-1.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e418256c5d8622b8bc92861936f7c6a0131355e7bcad88a42102ae8227f8a1c", size = 113008 }, + { url = "https://files.pythonhosted.org/packages/4c/57/fafc79e32f3087f6f26f509d80b8167516326bfea38d30502627c01617e0/ormsgpack-1.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:433ace29aa02713554f714c62a4e4dcad0c9e32674ba4f66742c91a4c3b1b969", size = 106648 }, + { url = "https://files.pythonhosted.org/packages/b3/cf/5d58d9b132128d2fe5d586355dde76af386554abef00d608f66b913bff1f/ormsgpack-1.12.0-cp314-cp314t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e57164be4ca34b64e210ec515059193280ac84df4d6f31a6fcbfb2fc8436de55", size = 369803 }, + { url = "https://files.pythonhosted.org/packages/67/42/968a2da361eaff2e4cbb17c82c7599787babf16684110ad70409646cc1e4/ormsgpack-1.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:904f96289deaa92fc6440b122edc27c5bdc28234edd63717f6d853d88c823a83", size = 195991 }, + { url = "https://files.pythonhosted.org/packages/03/f0/9696c6c6cf8ad35170f0be8d0ef3523cc258083535f6c8071cb8235ebb8b/ormsgpack-1.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b291d086e524a1062d57d1b7b5a8bcaaf29caebf0212fec12fd86240bd33633", size = 208316 }, +] + [[package]] name = "packaging" version = "25.0" @@ -2032,6 +2576,105 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 }, ] +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8c/d4/4e2c9aaf7ac2242b9358f98dccd8f90f2605402f5afeff6c578682c2c491/propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf", size = 80208 }, + { url = "https://files.pythonhosted.org/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5", size = 45777 }, + { url = "https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e", size = 47647 }, + { url = "https://files.pythonhosted.org/packages/58/1a/3c62c127a8466c9c843bccb503d40a273e5cc69838805f322e2826509e0d/propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566", size = 214929 }, + { url = "https://files.pythonhosted.org/packages/56/b9/8fa98f850960b367c4b8fe0592e7fc341daa7a9462e925228f10a60cf74f/propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165", size = 221778 }, + { url = "https://files.pythonhosted.org/packages/46/a6/0ab4f660eb59649d14b3d3d65c439421cf2f87fe5dd68591cbe3c1e78a89/propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc", size = 228144 }, + { url = "https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48", size = 210030 }, + { url = "https://files.pythonhosted.org/packages/40/e2/27e6feebb5f6b8408fa29f5efbb765cd54c153ac77314d27e457a3e993b7/propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570", size = 208252 }, + { url = "https://files.pythonhosted.org/packages/9e/f8/91c27b22ccda1dbc7967f921c42825564fa5336a01ecd72eb78a9f4f53c2/propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85", size = 202064 }, + { url = "https://files.pythonhosted.org/packages/f2/26/7f00bd6bd1adba5aafe5f4a66390f243acab58eab24ff1a08bebb2ef9d40/propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e", size = 212429 }, + { url = "https://files.pythonhosted.org/packages/84/89/fd108ba7815c1117ddca79c228f3f8a15fc82a73bca8b142eb5de13b2785/propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757", size = 216727 }, + { url = "https://files.pythonhosted.org/packages/79/37/3ec3f7e3173e73f1d600495d8b545b53802cbf35506e5732dd8578db3724/propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f", size = 205097 }, + { url = "https://files.pythonhosted.org/packages/61/b0/b2631c19793f869d35f47d5a3a56fb19e9160d3c119f15ac7344fc3ccae7/propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", size = 38084 }, + { url = "https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", size = 41637 }, + { url = "https://files.pythonhosted.org/packages/9c/e9/754f180cccd7f51a39913782c74717c581b9cc8177ad0e949f4d51812383/propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", size = 38064 }, + { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061 }, + { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037 }, + { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324 }, + { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505 }, + { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242 }, + { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474 }, + { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575 }, + { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736 }, + { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019 }, + { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376 }, + { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988 }, + { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615 }, + { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066 }, + { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655 }, + { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789 }, + { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750 }, + { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780 }, + { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308 }, + { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182 }, + { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215 }, + { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112 }, + { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442 }, + { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398 }, + { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920 }, + { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748 }, + { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877 }, + { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437 }, + { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586 }, + { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790 }, + { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158 }, + { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451 }, + { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374 }, + { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396 }, + { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950 }, + { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856 }, + { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420 }, + { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254 }, + { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205 }, + { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873 }, + { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739 }, + { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514 }, + { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781 }, + { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396 }, + { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897 }, + { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789 }, + { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152 }, + { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869 }, + { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596 }, + { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981 }, + { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490 }, + { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371 }, + { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424 }, + { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566 }, + { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130 }, + { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625 }, + { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209 }, + { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797 }, + { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140 }, + { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257 }, + { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097 }, + { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455 }, + { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372 }, + { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411 }, + { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712 }, + { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557 }, + { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015 }, + { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880 }, + { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938 }, + { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641 }, + { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510 }, + { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161 }, + { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393 }, + { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546 }, + { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259 }, + { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428 }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305 }, +] + [[package]] name = "protobuf" version = "6.33.0" @@ -2387,6 +3030,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075 }, ] +[[package]] +name = "pytest-mock" +version = "3.15.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/68/14/eb014d26be205d38ad5ad20d9a80f7d201472e08167f0bb4361e251084a9/pytest_mock-3.15.1.tar.gz", hash = "sha256:1849a238f6f396da19762269de72cb1814ab44416fa73a8686deac10b0d87a0f", size = 34036 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/cc/06253936f4a7fa2e0f48dfe6d851d9c56df896a9ab09ac019d70b760619c/pytest_mock-3.15.1-py3-none-any.whl", hash = "sha256:0a25e2eb88fe5168d535041d09a4529a188176ae608a6d249ee65abc0949630d", size = 10095 }, +] + [[package]] name = "pytest-timeout" version = "2.4.0" @@ -3742,6 +4397,219 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743 }, ] +[[package]] +name = "xxhash" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/84/30869e01909fb37a6cc7e18688ee8bf1e42d57e7e0777636bd47524c43c7/xxhash-3.6.0.tar.gz", hash = "sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6", size = 85160 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/d4/cc2f0400e9154df4b9964249da78ebd72f318e35ccc425e9f403c392f22a/xxhash-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b47bbd8cf2d72797f3c2772eaaac0ded3d3af26481a26d7d7d41dc2d3c46b04a", size = 32844 }, + { url = "https://files.pythonhosted.org/packages/5e/ec/1cc11cd13e26ea8bc3cb4af4eaadd8d46d5014aebb67be3f71fb0b68802a/xxhash-3.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2b6821e94346f96db75abaa6e255706fb06ebd530899ed76d32cd99f20dc52fa", size = 30809 }, + { url = "https://files.pythonhosted.org/packages/04/5f/19fe357ea348d98ca22f456f75a30ac0916b51c753e1f8b2e0e6fb884cce/xxhash-3.6.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d0a9751f71a1a65ce3584e9cae4467651c7e70c9d31017fa57574583a4540248", size = 194665 }, + { url = "https://files.pythonhosted.org/packages/90/3b/d1f1a8f5442a5fd8beedae110c5af7604dc37349a8e16519c13c19a9a2de/xxhash-3.6.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b29ee68625ab37b04c0b40c3fafdf24d2f75ccd778333cfb698f65f6c463f62", size = 213550 }, + { url = "https://files.pythonhosted.org/packages/c4/ef/3a9b05eb527457d5db13a135a2ae1a26c80fecd624d20f3e8dcc4cb170f3/xxhash-3.6.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6812c25fe0d6c36a46ccb002f40f27ac903bf18af9f6dd8f9669cb4d176ab18f", size = 212384 }, + { url = "https://files.pythonhosted.org/packages/0f/18/ccc194ee698c6c623acbf0f8c2969811a8a4b6185af5e824cd27b9e4fd3e/xxhash-3.6.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4ccbff013972390b51a18ef1255ef5ac125c92dc9143b2d1909f59abc765540e", size = 445749 }, + { url = "https://files.pythonhosted.org/packages/a5/86/cf2c0321dc3940a7aa73076f4fd677a0fb3e405cb297ead7d864fd90847e/xxhash-3.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:297b7fbf86c82c550e12e8fb71968b3f033d27b874276ba3624ea868c11165a8", size = 193880 }, + { url = "https://files.pythonhosted.org/packages/82/fb/96213c8560e6f948a1ecc9a7613f8032b19ee45f747f4fca4eb31bb6d6ed/xxhash-3.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dea26ae1eb293db089798d3973a5fc928a18fdd97cc8801226fae705b02b14b0", size = 210912 }, + { url = "https://files.pythonhosted.org/packages/40/aa/4395e669b0606a096d6788f40dbdf2b819d6773aa290c19e6e83cbfc312f/xxhash-3.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7a0b169aafb98f4284f73635a8e93f0735f9cbde17bd5ec332480484241aaa77", size = 198654 }, + { url = "https://files.pythonhosted.org/packages/67/74/b044fcd6b3d89e9b1b665924d85d3f400636c23590226feb1eb09e1176ce/xxhash-3.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:08d45aef063a4531b785cd72de4887766d01dc8f362a515693df349fdb825e0c", size = 210867 }, + { url = "https://files.pythonhosted.org/packages/bc/fd/3ce73bf753b08cb19daee1eb14aa0d7fe331f8da9c02dd95316ddfe5275e/xxhash-3.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:929142361a48ee07f09121fe9e96a84950e8d4df3bb298ca5d88061969f34d7b", size = 414012 }, + { url = "https://files.pythonhosted.org/packages/ba/b3/5a4241309217c5c876f156b10778f3ab3af7ba7e3259e6d5f5c7d0129eb2/xxhash-3.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51312c768403d8540487dbbfb557454cfc55589bbde6424456951f7fcd4facb3", size = 191409 }, + { url = "https://files.pythonhosted.org/packages/c0/01/99bfbc15fb9abb9a72b088c1d95219fc4782b7d01fc835bd5744d66dd0b8/xxhash-3.6.0-cp311-cp311-win32.whl", hash = "sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd", size = 30574 }, + { url = "https://files.pythonhosted.org/packages/65/79/9d24d7f53819fe301b231044ea362ce64e86c74f6e8c8e51320de248b3e5/xxhash-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef", size = 31481 }, + { url = "https://files.pythonhosted.org/packages/30/4e/15cd0e3e8772071344eab2961ce83f6e485111fed8beb491a3f1ce100270/xxhash-3.6.0-cp311-cp311-win_arm64.whl", hash = "sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7", size = 27861 }, + { url = "https://files.pythonhosted.org/packages/9a/07/d9412f3d7d462347e4511181dea65e47e0d0e16e26fbee2ea86a2aefb657/xxhash-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c", size = 32744 }, + { url = "https://files.pythonhosted.org/packages/79/35/0429ee11d035fc33abe32dca1b2b69e8c18d236547b9a9b72c1929189b9a/xxhash-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204", size = 30816 }, + { url = "https://files.pythonhosted.org/packages/b7/f2/57eb99aa0f7d98624c0932c5b9a170e1806406cdbcdb510546634a1359e0/xxhash-3.6.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490", size = 194035 }, + { url = "https://files.pythonhosted.org/packages/4c/ed/6224ba353690d73af7a3f1c7cdb1fc1b002e38f783cb991ae338e1eb3d79/xxhash-3.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2", size = 212914 }, + { url = "https://files.pythonhosted.org/packages/38/86/fb6b6130d8dd6b8942cc17ab4d90e223653a89aa32ad2776f8af7064ed13/xxhash-3.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa", size = 212163 }, + { url = "https://files.pythonhosted.org/packages/ee/dc/e84875682b0593e884ad73b2d40767b5790d417bde603cceb6878901d647/xxhash-3.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0", size = 445411 }, + { url = "https://files.pythonhosted.org/packages/11/4f/426f91b96701ec2f37bb2b8cec664eff4f658a11f3fa9d94f0a887ea6d2b/xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2", size = 193883 }, + { url = "https://files.pythonhosted.org/packages/53/5a/ddbb83eee8e28b778eacfc5a85c969673e4023cdeedcfcef61f36731610b/xxhash-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9", size = 210392 }, + { url = "https://files.pythonhosted.org/packages/1e/c2/ff69efd07c8c074ccdf0a4f36fcdd3d27363665bcdf4ba399abebe643465/xxhash-3.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e", size = 197898 }, + { url = "https://files.pythonhosted.org/packages/58/ca/faa05ac19b3b622c7c9317ac3e23954187516298a091eb02c976d0d3dd45/xxhash-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374", size = 210655 }, + { url = "https://files.pythonhosted.org/packages/d4/7a/06aa7482345480cc0cb597f5c875b11a82c3953f534394f620b0be2f700c/xxhash-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d", size = 414001 }, + { url = "https://files.pythonhosted.org/packages/23/07/63ffb386cd47029aa2916b3d2f454e6cc5b9f5c5ada3790377d5430084e7/xxhash-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae", size = 191431 }, + { url = "https://files.pythonhosted.org/packages/0f/93/14fde614cadb4ddf5e7cebf8918b7e8fac5ae7861c1875964f17e678205c/xxhash-3.6.0-cp312-cp312-win32.whl", hash = "sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb", size = 30617 }, + { url = "https://files.pythonhosted.org/packages/13/5d/0d125536cbe7565a83d06e43783389ecae0c0f2ed037b48ede185de477c0/xxhash-3.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c", size = 31534 }, + { url = "https://files.pythonhosted.org/packages/54/85/6ec269b0952ec7e36ba019125982cf11d91256a778c7c3f98a4c5043d283/xxhash-3.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829", size = 27876 }, + { url = "https://files.pythonhosted.org/packages/33/76/35d05267ac82f53ae9b0e554da7c5e281ee61f3cad44c743f0fcd354f211/xxhash-3.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec", size = 32738 }, + { url = "https://files.pythonhosted.org/packages/31/a8/3fbce1cd96534a95e35d5120637bf29b0d7f5d8fa2f6374e31b4156dd419/xxhash-3.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1", size = 30821 }, + { url = "https://files.pythonhosted.org/packages/0c/ea/d387530ca7ecfa183cb358027f1833297c6ac6098223fd14f9782cd0015c/xxhash-3.6.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6", size = 194127 }, + { url = "https://files.pythonhosted.org/packages/ba/0c/71435dcb99874b09a43b8d7c54071e600a7481e42b3e3ce1eb5226a5711a/xxhash-3.6.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263", size = 212975 }, + { url = "https://files.pythonhosted.org/packages/84/7a/c2b3d071e4bb4a90b7057228a99b10d51744878f4a8a6dd643c8bd897620/xxhash-3.6.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546", size = 212241 }, + { url = "https://files.pythonhosted.org/packages/81/5f/640b6eac0128e215f177df99eadcd0f1b7c42c274ab6a394a05059694c5a/xxhash-3.6.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89", size = 445471 }, + { url = "https://files.pythonhosted.org/packages/5e/1e/3c3d3ef071b051cc3abbe3721ffb8365033a172613c04af2da89d5548a87/xxhash-3.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d", size = 193936 }, + { url = "https://files.pythonhosted.org/packages/2c/bd/4a5f68381939219abfe1c22a9e3a5854a4f6f6f3c4983a87d255f21f2e5d/xxhash-3.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7", size = 210440 }, + { url = "https://files.pythonhosted.org/packages/eb/37/b80fe3d5cfb9faff01a02121a0f4d565eb7237e9e5fc66e73017e74dcd36/xxhash-3.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db", size = 197990 }, + { url = "https://files.pythonhosted.org/packages/d7/fd/2c0a00c97b9e18f72e1f240ad4e8f8a90fd9d408289ba9c7c495ed7dc05c/xxhash-3.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42", size = 210689 }, + { url = "https://files.pythonhosted.org/packages/93/86/5dd8076a926b9a95db3206aba20d89a7fc14dd5aac16e5c4de4b56033140/xxhash-3.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11", size = 414068 }, + { url = "https://files.pythonhosted.org/packages/af/3c/0bb129170ee8f3650f08e993baee550a09593462a5cddd8e44d0011102b1/xxhash-3.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd", size = 191495 }, + { url = "https://files.pythonhosted.org/packages/e9/3a/6797e0114c21d1725e2577508e24006fd7ff1d8c0c502d3b52e45c1771d8/xxhash-3.6.0-cp313-cp313-win32.whl", hash = "sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799", size = 30620 }, + { url = "https://files.pythonhosted.org/packages/86/15/9bc32671e9a38b413a76d24722a2bf8784a132c043063a8f5152d390b0f9/xxhash-3.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392", size = 31542 }, + { url = "https://files.pythonhosted.org/packages/39/c5/cc01e4f6188656e56112d6a8e0dfe298a16934b8c47a247236549a3f7695/xxhash-3.6.0-cp313-cp313-win_arm64.whl", hash = "sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6", size = 27880 }, + { url = "https://files.pythonhosted.org/packages/f3/30/25e5321c8732759e930c555176d37e24ab84365482d257c3b16362235212/xxhash-3.6.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702", size = 32956 }, + { url = "https://files.pythonhosted.org/packages/9f/3c/0573299560d7d9f8ab1838f1efc021a280b5ae5ae2e849034ef3dee18810/xxhash-3.6.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db", size = 31072 }, + { url = "https://files.pythonhosted.org/packages/7a/1c/52d83a06e417cd9d4137722693424885cc9878249beb3a7c829e74bf7ce9/xxhash-3.6.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54", size = 196409 }, + { url = "https://files.pythonhosted.org/packages/e3/8e/c6d158d12a79bbd0b878f8355432075fc82759e356ab5a111463422a239b/xxhash-3.6.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f", size = 215736 }, + { url = "https://files.pythonhosted.org/packages/bc/68/c4c80614716345d55071a396cf03d06e34b5f4917a467faf43083c995155/xxhash-3.6.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5", size = 214833 }, + { url = "https://files.pythonhosted.org/packages/7e/e9/ae27c8ffec8b953efa84c7c4a6c6802c263d587b9fc0d6e7cea64e08c3af/xxhash-3.6.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1", size = 448348 }, + { url = "https://files.pythonhosted.org/packages/d7/6b/33e21afb1b5b3f46b74b6bd1913639066af218d704cc0941404ca717fc57/xxhash-3.6.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee", size = 196070 }, + { url = "https://files.pythonhosted.org/packages/96/b6/fcabd337bc5fa624e7203aa0fa7d0c49eed22f72e93229431752bddc83d9/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd", size = 212907 }, + { url = "https://files.pythonhosted.org/packages/4b/d3/9ee6160e644d660fcf176c5825e61411c7f62648728f69c79ba237250143/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729", size = 200839 }, + { url = "https://files.pythonhosted.org/packages/0d/98/e8de5baa5109394baf5118f5e72ab21a86387c4f89b0e77ef3e2f6b0327b/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292", size = 213304 }, + { url = "https://files.pythonhosted.org/packages/7b/1d/71056535dec5c3177eeb53e38e3d367dd1d16e024e63b1cee208d572a033/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf", size = 416930 }, + { url = "https://files.pythonhosted.org/packages/dc/6c/5cbde9de2cd967c322e651c65c543700b19e7ae3e0aae8ece3469bf9683d/xxhash-3.6.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033", size = 193787 }, + { url = "https://files.pythonhosted.org/packages/19/fa/0172e350361d61febcea941b0cc541d6e6c8d65d153e85f850a7b256ff8a/xxhash-3.6.0-cp313-cp313t-win32.whl", hash = "sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec", size = 30916 }, + { url = "https://files.pythonhosted.org/packages/ad/e6/e8cf858a2b19d6d45820f072eff1bea413910592ff17157cabc5f1227a16/xxhash-3.6.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8", size = 31799 }, + { url = "https://files.pythonhosted.org/packages/56/15/064b197e855bfb7b343210e82490ae672f8bc7cdf3ddb02e92f64304ee8a/xxhash-3.6.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746", size = 28044 }, + { url = "https://files.pythonhosted.org/packages/7e/5e/0138bc4484ea9b897864d59fce9be9086030825bc778b76cb5a33a906d37/xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e", size = 32754 }, + { url = "https://files.pythonhosted.org/packages/18/d7/5dac2eb2ec75fd771957a13e5dda560efb2176d5203f39502a5fc571f899/xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405", size = 30846 }, + { url = "https://files.pythonhosted.org/packages/fe/71/8bc5be2bb00deb5682e92e8da955ebe5fa982da13a69da5a40a4c8db12fb/xxhash-3.6.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3", size = 194343 }, + { url = "https://files.pythonhosted.org/packages/e7/3b/52badfb2aecec2c377ddf1ae75f55db3ba2d321c5e164f14461c90837ef3/xxhash-3.6.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6", size = 213074 }, + { url = "https://files.pythonhosted.org/packages/a2/2b/ae46b4e9b92e537fa30d03dbc19cdae57ed407e9c26d163895e968e3de85/xxhash-3.6.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063", size = 212388 }, + { url = "https://files.pythonhosted.org/packages/f5/80/49f88d3afc724b4ac7fbd664c8452d6db51b49915be48c6982659e0e7942/xxhash-3.6.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7", size = 445614 }, + { url = "https://files.pythonhosted.org/packages/ed/ba/603ce3961e339413543d8cd44f21f2c80e2a7c5cfe692a7b1f2cccf58f3c/xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b", size = 194024 }, + { url = "https://files.pythonhosted.org/packages/78/d1/8e225ff7113bf81545cfdcd79eef124a7b7064a0bba53605ff39590b95c2/xxhash-3.6.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd", size = 210541 }, + { url = "https://files.pythonhosted.org/packages/6f/58/0f89d149f0bad89def1a8dd38feb50ccdeb643d9797ec84707091d4cb494/xxhash-3.6.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0", size = 198305 }, + { url = "https://files.pythonhosted.org/packages/11/38/5eab81580703c4df93feb5f32ff8fa7fe1e2c51c1f183ee4e48d4bb9d3d7/xxhash-3.6.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152", size = 210848 }, + { url = "https://files.pythonhosted.org/packages/5e/6b/953dc4b05c3ce678abca756416e4c130d2382f877a9c30a20d08ee6a77c0/xxhash-3.6.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11", size = 414142 }, + { url = "https://files.pythonhosted.org/packages/08/a9/238ec0d4e81a10eb5026d4a6972677cbc898ba6c8b9dbaec12ae001b1b35/xxhash-3.6.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5", size = 191547 }, + { url = "https://files.pythonhosted.org/packages/f1/ee/3cf8589e06c2164ac77c3bf0aa127012801128f1feebf2a079272da5737c/xxhash-3.6.0-cp314-cp314-win32.whl", hash = "sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f", size = 31214 }, + { url = "https://files.pythonhosted.org/packages/02/5d/a19552fbc6ad4cb54ff953c3908bbc095f4a921bc569433d791f755186f1/xxhash-3.6.0-cp314-cp314-win_amd64.whl", hash = "sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad", size = 32290 }, + { url = "https://files.pythonhosted.org/packages/b1/11/dafa0643bc30442c887b55baf8e73353a344ee89c1901b5a5c54a6c17d39/xxhash-3.6.0-cp314-cp314-win_arm64.whl", hash = "sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679", size = 28795 }, + { url = "https://files.pythonhosted.org/packages/2c/db/0e99732ed7f64182aef4a6fb145e1a295558deec2a746265dcdec12d191e/xxhash-3.6.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4", size = 32955 }, + { url = "https://files.pythonhosted.org/packages/55/f4/2a7c3c68e564a099becfa44bb3d398810cc0ff6749b0d3cb8ccb93f23c14/xxhash-3.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67", size = 31072 }, + { url = "https://files.pythonhosted.org/packages/c6/d9/72a29cddc7250e8a5819dad5d466facb5dc4c802ce120645630149127e73/xxhash-3.6.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad", size = 196579 }, + { url = "https://files.pythonhosted.org/packages/63/93/b21590e1e381040e2ca305a884d89e1c345b347404f7780f07f2cdd47ef4/xxhash-3.6.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b", size = 215854 }, + { url = "https://files.pythonhosted.org/packages/ce/b8/edab8a7d4fa14e924b29be877d54155dcbd8b80be85ea00d2be3413a9ed4/xxhash-3.6.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b", size = 214965 }, + { url = "https://files.pythonhosted.org/packages/27/67/dfa980ac7f0d509d54ea0d5a486d2bb4b80c3f1bb22b66e6a05d3efaf6c0/xxhash-3.6.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca", size = 448484 }, + { url = "https://files.pythonhosted.org/packages/8c/63/8ffc2cc97e811c0ca5d00ab36604b3ea6f4254f20b7bc658ca825ce6c954/xxhash-3.6.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a", size = 196162 }, + { url = "https://files.pythonhosted.org/packages/4b/77/07f0e7a3edd11a6097e990f6e5b815b6592459cb16dae990d967693e6ea9/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99", size = 213007 }, + { url = "https://files.pythonhosted.org/packages/ae/d8/bc5fa0d152837117eb0bef6f83f956c509332ce133c91c63ce07ee7c4873/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3", size = 200956 }, + { url = "https://files.pythonhosted.org/packages/26/a5/d749334130de9411783873e9b98ecc46688dad5db64ca6e04b02acc8b473/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6", size = 213401 }, + { url = "https://files.pythonhosted.org/packages/89/72/abed959c956a4bfc72b58c0384bb7940663c678127538634d896b1195c10/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93", size = 417083 }, + { url = "https://files.pythonhosted.org/packages/0c/b3/62fd2b586283b7d7d665fb98e266decadf31f058f1cf6c478741f68af0cb/xxhash-3.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518", size = 193913 }, + { url = "https://files.pythonhosted.org/packages/9a/9a/c19c42c5b3f5a4aad748a6d5b4f23df3bed7ee5445accc65a0fb3ff03953/xxhash-3.6.0-cp314-cp314t-win32.whl", hash = "sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119", size = 31586 }, + { url = "https://files.pythonhosted.org/packages/03/d6/4cc450345be9924fd5dc8c590ceda1db5b43a0a889587b0ae81a95511360/xxhash-3.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f", size = 32526 }, + { url = "https://files.pythonhosted.org/packages/0f/c9/7243eb3f9eaabd1a88a5a5acadf06df2d83b100c62684b7425c6a11bcaa8/xxhash-3.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95", size = 28898 }, + { url = "https://files.pythonhosted.org/packages/93/1e/8aec23647a34a249f62e2398c42955acd9b4c6ed5cf08cbea94dc46f78d2/xxhash-3.6.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0", size = 30662 }, + { url = "https://files.pythonhosted.org/packages/b8/0b/b14510b38ba91caf43006209db846a696ceea6a847a0c9ba0a5b1adc53d6/xxhash-3.6.0-pp311-pypy311_pp73-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296", size = 41056 }, + { url = "https://files.pythonhosted.org/packages/50/55/15a7b8a56590e66ccd374bbfa3f9ffc45b810886c8c3b614e3f90bd2367c/xxhash-3.6.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13", size = 36251 }, + { url = "https://files.pythonhosted.org/packages/62/b2/5ac99a041a29e58e95f907876b04f7067a0242cb85b5f39e726153981503/xxhash-3.6.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6dc31591899f5e5666f04cc2e529e69b4072827085c1ef15294d91a004bc1bd", size = 32481 }, + { url = "https://files.pythonhosted.org/packages/7b/d9/8d95e906764a386a3d3b596f3c68bb63687dfca806373509f51ce8eea81f/xxhash-3.6.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:15e0dac10eb9309508bfc41f7f9deaa7755c69e35af835db9cb10751adebc35d", size = 31565 }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/27/5ab13fc84c76a0250afd3d26d5936349a35be56ce5785447d6c423b26d92/yarl-1.22.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511", size = 141607 }, + { url = "https://files.pythonhosted.org/packages/6a/a1/d065d51d02dc02ce81501d476b9ed2229d9a990818332242a882d5d60340/yarl-1.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6", size = 94027 }, + { url = "https://files.pythonhosted.org/packages/c1/da/8da9f6a53f67b5106ffe902c6fa0164e10398d4e150d85838b82f424072a/yarl-1.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028", size = 94963 }, + { url = "https://files.pythonhosted.org/packages/68/fe/2c1f674960c376e29cb0bec1249b117d11738db92a6ccc4a530b972648db/yarl-1.22.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d", size = 368406 }, + { url = "https://files.pythonhosted.org/packages/95/26/812a540e1c3c6418fec60e9bbd38e871eaba9545e94fa5eff8f4a8e28e1e/yarl-1.22.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503", size = 336581 }, + { url = "https://files.pythonhosted.org/packages/0b/f5/5777b19e26fdf98563985e481f8be3d8a39f8734147a6ebf459d0dab5a6b/yarl-1.22.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65", size = 388924 }, + { url = "https://files.pythonhosted.org/packages/86/08/24bd2477bd59c0bbd994fe1d93b126e0472e4e3df5a96a277b0a55309e89/yarl-1.22.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e", size = 392890 }, + { url = "https://files.pythonhosted.org/packages/46/00/71b90ed48e895667ecfb1eaab27c1523ee2fa217433ed77a73b13205ca4b/yarl-1.22.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d", size = 365819 }, + { url = "https://files.pythonhosted.org/packages/30/2d/f715501cae832651d3282387c6a9236cd26bd00d0ff1e404b3dc52447884/yarl-1.22.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7", size = 363601 }, + { url = "https://files.pythonhosted.org/packages/f8/f9/a678c992d78e394e7126ee0b0e4e71bd2775e4334d00a9278c06a6cce96a/yarl-1.22.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967", size = 358072 }, + { url = "https://files.pythonhosted.org/packages/2c/d1/b49454411a60edb6fefdcad4f8e6dbba7d8019e3a508a1c5836cba6d0781/yarl-1.22.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed", size = 385311 }, + { url = "https://files.pythonhosted.org/packages/87/e5/40d7a94debb8448c7771a916d1861d6609dddf7958dc381117e7ba36d9e8/yarl-1.22.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6", size = 381094 }, + { url = "https://files.pythonhosted.org/packages/35/d8/611cc282502381ad855448643e1ad0538957fc82ae83dfe7762c14069e14/yarl-1.22.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e", size = 370944 }, + { url = "https://files.pythonhosted.org/packages/2d/df/fadd00fb1c90e1a5a8bd731fa3d3de2e165e5a3666a095b04e31b04d9cb6/yarl-1.22.0-cp311-cp311-win32.whl", hash = "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca", size = 81804 }, + { url = "https://files.pythonhosted.org/packages/b5/f7/149bb6f45f267cb5c074ac40c01c6b3ea6d8a620d34b337f6321928a1b4d/yarl-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b", size = 86858 }, + { url = "https://files.pythonhosted.org/packages/2b/13/88b78b93ad3f2f0b78e13bfaaa24d11cbc746e93fe76d8c06bf139615646/yarl-1.22.0-cp311-cp311-win_arm64.whl", hash = "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376", size = 81637 }, + { url = "https://files.pythonhosted.org/packages/75/ff/46736024fee3429b80a165a732e38e5d5a238721e634ab41b040d49f8738/yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f", size = 142000 }, + { url = "https://files.pythonhosted.org/packages/5a/9a/b312ed670df903145598914770eb12de1bac44599549b3360acc96878df8/yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2", size = 94338 }, + { url = "https://files.pythonhosted.org/packages/ba/f5/0601483296f09c3c65e303d60c070a5c19fcdbc72daa061e96170785bc7d/yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74", size = 94909 }, + { url = "https://files.pythonhosted.org/packages/60/41/9a1fe0b73dbcefce72e46cf149b0e0a67612d60bfc90fb59c2b2efdfbd86/yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df", size = 372940 }, + { url = "https://files.pythonhosted.org/packages/17/7a/795cb6dfee561961c30b800f0ed616b923a2ec6258b5def2a00bf8231334/yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb", size = 345825 }, + { url = "https://files.pythonhosted.org/packages/d7/93/a58f4d596d2be2ae7bab1a5846c4d270b894958845753b2c606d666744d3/yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2", size = 386705 }, + { url = "https://files.pythonhosted.org/packages/61/92/682279d0e099d0e14d7fd2e176bd04f48de1484f56546a3e1313cd6c8e7c/yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82", size = 396518 }, + { url = "https://files.pythonhosted.org/packages/db/0f/0d52c98b8a885aeda831224b78f3be7ec2e1aa4a62091f9f9188c3c65b56/yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a", size = 377267 }, + { url = "https://files.pythonhosted.org/packages/22/42/d2685e35908cbeaa6532c1fc73e89e7f2efb5d8a7df3959ea8e37177c5a3/yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124", size = 365797 }, + { url = "https://files.pythonhosted.org/packages/a2/83/cf8c7bcc6355631762f7d8bdab920ad09b82efa6b722999dfb05afa6cfac/yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa", size = 365535 }, + { url = "https://files.pythonhosted.org/packages/25/e1/5302ff9b28f0c59cac913b91fe3f16c59a033887e57ce9ca5d41a3a94737/yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7", size = 382324 }, + { url = "https://files.pythonhosted.org/packages/bf/cd/4617eb60f032f19ae3a688dc990d8f0d89ee0ea378b61cac81ede3e52fae/yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d", size = 383803 }, + { url = "https://files.pythonhosted.org/packages/59/65/afc6e62bb506a319ea67b694551dab4a7e6fb7bf604e9bd9f3e11d575fec/yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520", size = 374220 }, + { url = "https://files.pythonhosted.org/packages/e7/3d/68bf18d50dc674b942daec86a9ba922d3113d8399b0e52b9897530442da2/yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8", size = 81589 }, + { url = "https://files.pythonhosted.org/packages/c8/9a/6ad1a9b37c2f72874f93e691b2e7ecb6137fb2b899983125db4204e47575/yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c", size = 87213 }, + { url = "https://files.pythonhosted.org/packages/44/c5/c21b562d1680a77634d748e30c653c3ca918beb35555cff24986fff54598/yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74", size = 81330 }, + { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980 }, + { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424 }, + { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821 }, + { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243 }, + { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361 }, + { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036 }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671 }, + { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059 }, + { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356 }, + { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331 }, + { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590 }, + { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316 }, + { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431 }, + { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555 }, + { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965 }, + { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205 }, + { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209 }, + { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966 }, + { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312 }, + { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967 }, + { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949 }, + { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818 }, + { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626 }, + { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129 }, + { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776 }, + { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879 }, + { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996 }, + { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047 }, + { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947 }, + { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943 }, + { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715 }, + { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857 }, + { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520 }, + { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504 }, + { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282 }, + { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080 }, + { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696 }, + { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121 }, + { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080 }, + { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661 }, + { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645 }, + { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361 }, + { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451 }, + { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814 }, + { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799 }, + { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990 }, + { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292 }, + { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888 }, + { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223 }, + { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981 }, + { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303 }, + { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820 }, + { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203 }, + { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173 }, + { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562 }, + { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828 }, + { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551 }, + { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512 }, + { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400 }, + { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140 }, + { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473 }, + { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056 }, + { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292 }, + { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171 }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814 }, +] + [[package]] name = "zipp" version = "3.23.0"