mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-10-21 05:18:00 +00:00
fix(openai-sdk-python): support supermemory 3.50 type and API renames
Fresh pip installs pull supermemory 3.50, which renamed MemoryAddResponse and MemoryGetResponse and moved document creation to client.add(). The package failed to import and memory writes used a removed API surface. Migrate tools and middleware to AddResponse/DocumentGetResponse and client.add(), pin supermemory>=3.50.0 (Python 3.9+), and add import compatibility regression tests. Fixes #1235
This commit is contained in:
parent
2cebe81512
commit
4dda55c51a
5 changed files with 166 additions and 1314 deletions
|
|
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||
|
||||
[project]
|
||||
name = "supermemory-openai-sdk"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
description = "Memory tools for OpenAI function calling with supermemory"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
|
|
@ -15,7 +15,6 @@ classifiers = [
|
|||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
|
|
@ -23,10 +22,13 @@ classifiers = [
|
|||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
||||
]
|
||||
requires-python = ">=3.8.1"
|
||||
# supermemory>=3.50 requires Python 3.9+
|
||||
requires-python = ">=3.9"
|
||||
dependencies = [
|
||||
"openai>=1.102.0",
|
||||
"supermemory>=3.1.0",
|
||||
# 3.50 renamed MemoryAddResponse/MemoryGetResponse and moved add() to the
|
||||
# top-level client. Older releases break package import and memory writes.
|
||||
"supermemory>=3.50.0",
|
||||
"typing-extensions>=4.0.0",
|
||||
"requests>=2.25.0",
|
||||
]
|
||||
|
|
@ -62,7 +64,7 @@ multi_line_output = 3
|
|||
line_length = 88
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.8"
|
||||
python_version = "3.9"
|
||||
warn_return_any = true
|
||||
warn_unused_configs = true
|
||||
disallow_untyped_defs = true
|
||||
|
|
|
|||
|
|
@ -229,8 +229,9 @@ async def add_memory_tool(
|
|||
if custom_id is not None:
|
||||
add_params["custom_id"] = custom_id
|
||||
|
||||
# Handle both sync and async supermemory clients
|
||||
result = client.memories.add(**add_params)
|
||||
# supermemory 3.x: document creation lives on the top-level add() API.
|
||||
# Handle both sync and async clients.
|
||||
result = client.add(**add_params)
|
||||
if inspect.isawaitable(result):
|
||||
response = await result
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ from openai.types.chat import (
|
|||
ChatCompletionFunctionToolParam,
|
||||
ChatCompletionMessageToolCall,
|
||||
ChatCompletionToolMessageParam,
|
||||
ChatCompletionToolParam,
|
||||
)
|
||||
from supermemory.types import (
|
||||
MemoryAddResponse,
|
||||
MemoryGetResponse,
|
||||
AddResponse,
|
||||
DocumentGetResponse,
|
||||
SearchExecuteResponse,
|
||||
)
|
||||
from supermemory.types.search_execute_response import Result
|
||||
|
|
@ -34,8 +35,10 @@ class SupermemoryToolsConfig(TypedDict, total=False):
|
|||
project_id: Optional[str]
|
||||
|
||||
|
||||
# Type aliases using inferred types from supermemory package
|
||||
MemoryObject = Union[MemoryGetResponse, MemoryAddResponse]
|
||||
# Type aliases using inferred types from supermemory package.
|
||||
# supermemory >= 3.50 renamed MemoryAddResponse/MemoryGetResponse to
|
||||
# AddResponse/DocumentGetResponse.
|
||||
MemoryObject = Union[DocumentGetResponse, AddResponse]
|
||||
|
||||
|
||||
class MemorySearchResult(TypedDict, total=False):
|
||||
|
|
@ -51,7 +54,7 @@ class MemoryAddResult(TypedDict, total=False):
|
|||
"""Result type for memory add operations."""
|
||||
|
||||
success: bool
|
||||
memory: Optional[MemoryAddResponse]
|
||||
memory: Optional[AddResponse]
|
||||
error: Optional[str]
|
||||
|
||||
|
||||
|
|
@ -221,12 +224,12 @@ class SupermemoryTools:
|
|||
MemoryAddResult
|
||||
"""
|
||||
try:
|
||||
add_params = {
|
||||
"content": memory,
|
||||
"container_tags": self.container_tags,
|
||||
}
|
||||
|
||||
response: MemoryAddResponse = await self.client.memories.add(**add_params)
|
||||
# supermemory 3.x moved document creation to the top-level client.add()
|
||||
# API (client.memories only exposes forget/update_memory now).
|
||||
response: AddResponse = await self.client.add(
|
||||
content=memory,
|
||||
container_tags=self.container_tags,
|
||||
)
|
||||
|
||||
return MemoryAddResult(
|
||||
success=True,
|
||||
|
|
|
|||
60
packages/openai-sdk-python/tests/test_import_compat.py
Normal file
60
packages/openai-sdk-python/tests/test_import_compat.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"""Regression tests for supermemory SDK compatibility (issue #1235).
|
||||
|
||||
These tests must not require SUPERMEMORY_API_KEY — the failure mode was
|
||||
an ImportError at package import time with supermemory 3.50+.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import inspect
|
||||
|
||||
|
||||
def test_package_imports_cleanly() -> None:
|
||||
"""Importing supermemory_openai must not raise with current supermemory."""
|
||||
module = importlib.import_module("supermemory_openai")
|
||||
assert hasattr(module, "SupermemoryTools")
|
||||
assert hasattr(module, "with_supermemory")
|
||||
assert hasattr(module, "MemoryObject")
|
||||
assert hasattr(module, "MemoryAddResult")
|
||||
|
||||
|
||||
def test_tools_module_uses_current_sdk_types() -> None:
|
||||
"""Tools module must import renamed supermemory 3.50 types."""
|
||||
from supermemory.types import AddResponse, DocumentGetResponse
|
||||
from supermemory_openai.tools import MemoryObject, MemoryAddResult
|
||||
|
||||
# MemoryObject is a Union of the current SDK response types
|
||||
assert AddResponse is not None
|
||||
assert DocumentGetResponse is not None
|
||||
# Runtime alias should resolve (typing.Union is fine either way)
|
||||
assert MemoryObject is not None
|
||||
assert MemoryAddResult is not None
|
||||
|
||||
|
||||
def test_add_memory_uses_client_add_not_memories_add() -> None:
|
||||
"""add_memory must call client.add (memories.add was removed in 3.50)."""
|
||||
import supermemory
|
||||
from supermemory_openai.tools import SupermemoryTools
|
||||
|
||||
client = supermemory.AsyncSupermemory(api_key="sm_test_key_for_signature_check")
|
||||
assert hasattr(client, "add")
|
||||
assert callable(client.add)
|
||||
# memories resource no longer exposes add
|
||||
assert not hasattr(client.memories, "add")
|
||||
|
||||
# Source-level guard: tools.add_memory must reference client.add
|
||||
source = inspect.getsource(SupermemoryTools.add_memory)
|
||||
assert "self.client.add(" in source
|
||||
assert "self.client.memories.add" not in source
|
||||
|
||||
|
||||
def test_middleware_add_memory_tool_uses_client_add() -> None:
|
||||
"""Middleware save path must use client.add as well."""
|
||||
from supermemory_openai.middleware import add_memory_tool
|
||||
|
||||
source = inspect.getsource(add_memory_tool)
|
||||
assert "client.add(" in source
|
||||
# Reject the removed memories resource call site (allow comments that mention it).
|
||||
assert "result = client.memories.add" not in source
|
||||
assert "client.memories.add(**" not in source
|
||||
1378
packages/openai-sdk-python/uv.lock
generated
1378
packages/openai-sdk-python/uv.lock
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue