add multimodal memory proxy and API logging
This commit is contained in:
@ -1,10 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import base64
|
||||
import hashlib
|
||||
import mimetypes
|
||||
import secrets
|
||||
import shutil
|
||||
import time
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
@ -28,6 +30,10 @@ def public_resource_uri(user_id: str, resource_id: str) -> str:
|
||||
return f"resource://{user_id}/{resource_id}"
|
||||
|
||||
|
||||
def current_timestamp_ms() -> int:
|
||||
return int(time.time() * 1000)
|
||||
|
||||
|
||||
def infer_content_type(filename: str | None, mime_type: str | None) -> str:
|
||||
mime = (mime_type or mimetypes.guess_type(filename or "")[0] or "").lower()
|
||||
suffix = Path(filename or "").suffix.lower()
|
||||
@ -249,6 +255,7 @@ class MemoryGatewayService:
|
||||
project_id: str,
|
||||
filename: str,
|
||||
) -> dict[str, Any]:
|
||||
content_item = self._build_content_item(resource=resource, filename=filename)
|
||||
return {
|
||||
"session_id": resource["session_id"],
|
||||
"app_id": app_id,
|
||||
@ -257,23 +264,43 @@ class MemoryGatewayService:
|
||||
{
|
||||
"sender_id": user_id,
|
||||
"role": "user",
|
||||
"timestamp": 1781068800000,
|
||||
"content": [
|
||||
{
|
||||
"type": resource["content_type"],
|
||||
"uri": resource["uri"],
|
||||
"name": filename,
|
||||
"ext": Path(filename).suffix.lstrip(".") or None,
|
||||
"extras": {
|
||||
"resource_id": resource["id"],
|
||||
"source": "user_upload",
|
||||
},
|
||||
}
|
||||
],
|
||||
"timestamp": current_timestamp_ms(),
|
||||
"content": [content_item],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
def _build_content_item(
|
||||
self,
|
||||
*,
|
||||
resource: dict[str, Any],
|
||||
filename: str,
|
||||
) -> dict[str, Any]:
|
||||
content_type = str(resource["content_type"])
|
||||
path = self._resource_file_path(resource)
|
||||
content = path.read_bytes()
|
||||
item = {
|
||||
"type": content_type,
|
||||
"name": filename,
|
||||
"ext": Path(filename).suffix.lstrip(".") or None,
|
||||
"extras": {
|
||||
"resource_id": resource["id"],
|
||||
"source": "user_upload",
|
||||
},
|
||||
}
|
||||
if content_type == "text":
|
||||
item["text"] = content.decode("utf-8", errors="replace")
|
||||
else:
|
||||
item["base64"] = base64.b64encode(content).decode("ascii")
|
||||
return item
|
||||
|
||||
def _resource_file_path(self, resource: dict[str, Any]) -> Path:
|
||||
uri = str(resource["uri"])
|
||||
parsed = urlparse(uri)
|
||||
if parsed.scheme != "file":
|
||||
raise ValueError(f"unsupported resource uri scheme: {parsed.scheme}")
|
||||
return Path(unquote(parsed.path)).resolve(strict=True)
|
||||
|
||||
def list_resources(self, user_id: str) -> list[dict[str, Any]]:
|
||||
return [self._resource_detail(item) for item in self.repository.list_resources(user_id)]
|
||||
|
||||
@ -395,6 +422,41 @@ class MemoryGatewayService:
|
||||
overridden = self._apply_overrides(user_id, filtered)
|
||||
return {"results": overridden}
|
||||
|
||||
async def add_memory(
|
||||
self,
|
||||
*,
|
||||
session_id: str,
|
||||
app_id: str,
|
||||
project_id: str,
|
||||
messages: list[dict[str, Any]],
|
||||
) -> dict[str, Any]:
|
||||
payload = {
|
||||
"session_id": session_id,
|
||||
"app_id": app_id,
|
||||
"project_id": project_id,
|
||||
"messages": messages,
|
||||
}
|
||||
return {
|
||||
"session_id": session_id,
|
||||
"everos": await self.everos_client.add_memory(payload),
|
||||
}
|
||||
|
||||
async def flush_memory(
|
||||
self,
|
||||
*,
|
||||
session_id: str,
|
||||
app_id: str,
|
||||
project_id: str,
|
||||
) -> dict[str, Any]:
|
||||
return {
|
||||
"session_id": session_id,
|
||||
"everos": await self.everos_client.flush_memory(
|
||||
session_id,
|
||||
app_id,
|
||||
project_id,
|
||||
),
|
||||
}
|
||||
|
||||
def _search_payload(
|
||||
self,
|
||||
*,
|
||||
|
||||
Reference in New Issue
Block a user