Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/openai-sdk-python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -15,18 +15,20 @@ 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",
"Programming Language :: Python :: 3.12",
"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",
]
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
25 changes: 14 additions & 11 deletions packages/openai-sdk-python/src/supermemory_openai/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
ChatCompletionFunctionToolParam,
ChatCompletionMessageToolCall,
ChatCompletionToolMessageParam,
ChatCompletionToolParam,
)
from supermemory.types import (
MemoryAddResponse,
MemoryGetResponse,
AddResponse,
DocumentGetResponse,
SearchExecuteResponse,
)
from supermemory.types.search_execute_response import Result
Expand All @@ -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):
Expand All @@ -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]


Expand Down Expand Up @@ -221,12 +224,12 @@ async def add_memory(self, memory: str) -> MemoryAddResult:
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,
Expand Down
60 changes: 60 additions & 0 deletions packages/openai-sdk-python/tests/test_import_compat.py
Original file line number Diff line number Diff line change
@@ -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
Loading