maximem-synap-semantic-kernel 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: maximem-synap-semantic-kernel
3
+ Version: 0.1.1
4
+ Summary: Synap memory integration for Microsoft Semantic Kernel
5
+ License-Expression: Apache-2.0
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: maximem-synap>=0.2.0
8
+ Requires-Dist: synap-integrations-common>=0.1.0
9
+ Requires-Dist: semantic-kernel>=1.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest>=7.0; extra == "dev"
12
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: maximem-synap-semantic-kernel
3
+ Version: 0.1.1
4
+ Summary: Synap memory integration for Microsoft Semantic Kernel
5
+ License-Expression: Apache-2.0
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: maximem-synap>=0.2.0
8
+ Requires-Dist: synap-integrations-common>=0.1.0
9
+ Requires-Dist: semantic-kernel>=1.0
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest>=7.0; extra == "dev"
12
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
@@ -0,0 +1,9 @@
1
+ pyproject.toml
2
+ maximem_synap_semantic_kernel.egg-info/PKG-INFO
3
+ maximem_synap_semantic_kernel.egg-info/SOURCES.txt
4
+ maximem_synap_semantic_kernel.egg-info/dependency_links.txt
5
+ maximem_synap_semantic_kernel.egg-info/requires.txt
6
+ maximem_synap_semantic_kernel.egg-info/top_level.txt
7
+ synap_semantic_kernel/__init__.py
8
+ synap_semantic_kernel/plugin.py
9
+ tests/test_plugin.py
@@ -0,0 +1,7 @@
1
+ maximem-synap>=0.2.0
2
+ synap-integrations-common>=0.1.0
3
+ semantic-kernel>=1.0
4
+
5
+ [dev]
6
+ pytest>=7.0
7
+ pytest-asyncio>=0.21
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "maximem-synap-semantic-kernel"
7
+ version = "0.1.1"
8
+ description = "Synap memory integration for Microsoft Semantic Kernel"
9
+ requires-python = ">=3.11"
10
+ license = "Apache-2.0"
11
+ dependencies = ["maximem-synap>=0.2.0", "synap-integrations-common>=0.1.0", "semantic-kernel>=1.0"]
12
+
13
+ [project.optional-dependencies]
14
+ dev = ["pytest>=7.0", "pytest-asyncio>=0.21"]
15
+
16
+ [tool.setuptools.packages.find]
17
+ where = ["."]
18
+ include = ["synap_semantic_kernel*"]
19
+
20
+ [tool.pytest.ini_options]
21
+ testpaths = ["tests"]
22
+ asyncio_mode = "auto"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ """Synap memory integration for Microsoft Semantic Kernel."""
2
+
3
+ from synap_semantic_kernel.plugin import SynapPlugin
4
+
5
+ __all__ = ["SynapPlugin"]
@@ -0,0 +1,93 @@
1
+ """Synap plugin for Microsoft Semantic Kernel.
2
+
3
+ Exposes Synap memory as kernel functions (search_memory, store_memory)
4
+ that can be registered with a Semantic Kernel instance.
5
+ """
6
+
7
+ import logging
8
+ from typing import Annotated, Optional
9
+
10
+ from semantic_kernel.functions import kernel_function
11
+
12
+ from maximem_synap import MaximemSynapSDK
13
+ from synap_integrations_common import wrap_sdk_errors_async
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class SynapPlugin:
19
+ """Semantic Kernel plugin for Synap memory operations.
20
+
21
+ Example::
22
+
23
+ from semantic_kernel import Kernel
24
+ from synap_semantic_kernel import SynapPlugin
25
+
26
+ kernel = Kernel()
27
+ kernel.add_plugin(
28
+ SynapPlugin(sdk=sdk, user_id="u1"),
29
+ plugin_name="synap",
30
+ )
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ sdk: MaximemSynapSDK,
36
+ user_id: str,
37
+ customer_id: str = "",
38
+ conversation_id: Optional[str] = None,
39
+ ):
40
+ if sdk is None:
41
+ raise ValueError("SynapPlugin requires a non-None sdk")
42
+ if not user_id:
43
+ raise ValueError("SynapPlugin requires a non-empty user_id")
44
+
45
+ self._sdk = sdk
46
+ self._user_id = user_id
47
+ self._customer_id = customer_id
48
+ self._conversation_id = conversation_id
49
+
50
+ @kernel_function(
51
+ name="search_memory",
52
+ description=(
53
+ "Search the user's memory for relevant context. Use when you need "
54
+ "to recall past conversations, preferences, or facts about the user."
55
+ ),
56
+ )
57
+ async def search_memory(
58
+ self,
59
+ query: Annotated[str, "Natural language search query"],
60
+ ) -> str:
61
+ async with wrap_sdk_errors_async(
62
+ "semantic_kernel.search_memory", logger, user_id=self._user_id,
63
+ ):
64
+ response = await self._sdk.fetch(
65
+ conversation_id=self._conversation_id,
66
+ user_id=self._user_id,
67
+ customer_id=self._customer_id or None,
68
+ search_query=[query],
69
+ mode="accurate",
70
+ include_conversation_context=False,
71
+ )
72
+ return response.formatted_context or "No relevant memories found."
73
+
74
+ @kernel_function(
75
+ name="store_memory",
76
+ description=(
77
+ "Store an important fact, preference, or event about the user "
78
+ "for future reference."
79
+ ),
80
+ )
81
+ async def store_memory(
82
+ self,
83
+ content: Annotated[str, "Information to remember about the user"],
84
+ ) -> str:
85
+ async with wrap_sdk_errors_async(
86
+ "semantic_kernel.store_memory", logger, user_id=self._user_id,
87
+ ):
88
+ result = await self._sdk.memories.create(
89
+ document=content,
90
+ user_id=self._user_id,
91
+ customer_id=self._customer_id,
92
+ )
93
+ return f"Memory stored (ingestion_id: {result.ingestion_id})"
@@ -0,0 +1,53 @@
1
+ """Tests for SynapPlugin."""
2
+
3
+ import pytest
4
+ from unittest.mock import AsyncMock, MagicMock
5
+
6
+ from synap_semantic_kernel.plugin import SynapPlugin
7
+
8
+
9
+ @pytest.fixture
10
+ def mock_sdk():
11
+ sdk = MagicMock()
12
+ sdk.fetch = AsyncMock()
13
+ sdk.memories.create = AsyncMock()
14
+ return sdk
15
+
16
+
17
+ @pytest.fixture
18
+ def plugin(mock_sdk):
19
+ return SynapPlugin(sdk=mock_sdk, user_id="u1")
20
+
21
+
22
+ def test_import():
23
+ from synap_semantic_kernel import SynapPlugin
24
+ assert SynapPlugin is not None
25
+
26
+
27
+ @pytest.mark.asyncio
28
+ async def test_search_memory(plugin, mock_sdk):
29
+ mock_sdk.fetch.return_value = MagicMock(formatted_context="likes coffee")
30
+
31
+ result = await plugin.search_memory(query="coffee")
32
+
33
+ assert result == "likes coffee"
34
+ mock_sdk.fetch.assert_awaited_once()
35
+ assert mock_sdk.fetch.call_args.kwargs["search_query"] == ["coffee"]
36
+
37
+
38
+ @pytest.mark.asyncio
39
+ async def test_search_memory_no_results(plugin, mock_sdk):
40
+ mock_sdk.fetch.return_value = MagicMock(formatted_context=None)
41
+
42
+ result = await plugin.search_memory(query="nothing")
43
+ assert result == "No relevant memories found."
44
+
45
+
46
+ @pytest.mark.asyncio
47
+ async def test_store_memory(plugin, mock_sdk):
48
+ mock_sdk.memories.create.return_value = MagicMock(ingestion_id="ing-1")
49
+
50
+ result = await plugin.store_memory(content="prefers dark mode")
51
+
52
+ assert "ing-1" in result
53
+ mock_sdk.memories.create.assert_awaited_once()