From 18b0f787b33a6de61988af06c6fb3398167eebec Mon Sep 17 00:00:00 2001 From: Abhijitam01 Date: Thu, 9 Apr 2026 01:10:46 +0530 Subject: [PATCH 1/2] feat: add Semantic Kernel plugin for Moss semantic search (#82) Adds a Python Semantic Kernel plugin that exposes Moss retrieval as a @kernel_function, letting any SK agent query a Moss index with 3 lines of code. Mirrors the strands-agents-moss integration pattern. Includes plugin implementation, 14 unit/integration tests, example, README with Quick Start and configuration docs, and TODOS.md for follow-up work (CI/CD pipeline, .NET design doc). --- TODOS.md | 21 ++ packages/semantic-kernel-moss/LICENSE | 25 ++ packages/semantic-kernel-moss/README.md | 98 +++++++ .../examples/moss_sk_simple.py | 28 ++ packages/semantic-kernel-moss/pyproject.toml | 55 ++++ .../src/semantic_kernel_moss/__init__.py | 22 ++ .../src/semantic_kernel_moss/moss_plugin.py | 147 ++++++++++ .../tests/test_moss_plugin.py | 252 ++++++++++++++++++ 8 files changed, 648 insertions(+) create mode 100644 TODOS.md create mode 100644 packages/semantic-kernel-moss/LICENSE create mode 100644 packages/semantic-kernel-moss/README.md create mode 100644 packages/semantic-kernel-moss/examples/moss_sk_simple.py create mode 100644 packages/semantic-kernel-moss/pyproject.toml create mode 100644 packages/semantic-kernel-moss/src/semantic_kernel_moss/__init__.py create mode 100644 packages/semantic-kernel-moss/src/semantic_kernel_moss/moss_plugin.py create mode 100644 packages/semantic-kernel-moss/tests/test_moss_plugin.py diff --git a/TODOS.md b/TODOS.md new file mode 100644 index 00000000..9d6175b6 --- /dev/null +++ b/TODOS.md @@ -0,0 +1,21 @@ +# TODOs + +## CI/CD pipeline for integration packages + +**What:** Add GitHub Actions workflows to build, test, and publish `strands-agents-moss` and `semantic-kernel-moss` to PyPI. + +**Why:** Neither integration package has a CI/CD pipeline. Code without distribution is code nobody can use. Users currently have no way to `pip install` these packages from PyPI. + +**Context:** Both packages use setuptools with `pyproject.toml`. Tests use pytest + pytest-asyncio. Linting uses ruff. A single reusable workflow could cover both packages since they share the same build system and test tooling. Consider matrix strategy for Python 3.10-3.13. + +**Depends on:** Nothing. Can be done independently. + +## .NET Semantic Kernel plugin design doc + +**What:** Write a design document for a .NET version of the Moss Semantic Kernel plugin. + +**Why:** The GitHub issue (#82) lists .NET as a stretch goal. Semantic Kernel has strong .NET adoption in enterprise shops. A design doc captures the approach (NuGet package, IKernelPlugin interface, C# async patterns) without committing to implementation. + +**Context:** The Python plugin (`semantic-kernel-moss`) is the reference implementation. The .NET version would follow the same pattern: single `Search` kernel function, constructor-configured `MossClient`, pre-loaded index. Key decisions: whether to use the .NET Moss SDK (if it exists) or wrap the Python SDK, and how to handle the async index loading lifecycle in C#. + +**Depends on:** Python plugin shipped and validated by users. diff --git a/packages/semantic-kernel-moss/LICENSE b/packages/semantic-kernel-moss/LICENSE new file mode 100644 index 00000000..8e7b3214 --- /dev/null +++ b/packages/semantic-kernel-moss/LICENSE @@ -0,0 +1,25 @@ +BSD 2-Clause License + +Copyright (c) 2025, InferEdge Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/semantic-kernel-moss/README.md b/packages/semantic-kernel-moss/README.md new file mode 100644 index 00000000..ad533054 --- /dev/null +++ b/packages/semantic-kernel-moss/README.md @@ -0,0 +1,98 @@ +# Semantic Kernel Moss Plugin + +Moss delivers sub-10ms semantic retrieval, giving your [Semantic Kernel](https://learn.microsoft.com/en-us/semantic-kernel/) agents instant access to a knowledge base during conversations. + +## Installation + +```bash +pip install semantic-kernel-moss +``` + +## Prerequisites + +- Moss project ID and project key (get them from [Moss Portal](https://portal.usemoss.dev)) +- Python 3.10+ +- A Semantic Kernel [ChatCompletion service](https://learn.microsoft.com/en-us/semantic-kernel/concepts/ai-services/chat-completion/) configured in your kernel + +## Quick Start + +```python +import asyncio +import os + +import semantic_kernel as sk +from semantic_kernel_moss import MossPlugin + + +async def main(): + # Create and pre-load the Moss plugin + moss = MossPlugin( + project_id=os.getenv("MOSS_PROJECT_ID"), + project_key=os.getenv("MOSS_PROJECT_KEY"), + index_name="my-index", + ) + await moss.load_index() + + # Register with a Semantic Kernel + kernel = sk.Kernel() + kernel.add_plugin(moss, plugin_name="moss") + + # Invoke the search function directly + result = await kernel.invoke(function_name="search", plugin_name="moss", query="What is your refund policy?") + print(result) + + +asyncio.run(main()) +``` + +## Configuration Options + +### MossPlugin + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `project_id` | `MOSS_PROJECT_ID` env var | Moss project ID | +| `project_key` | `MOSS_PROJECT_KEY` env var | Moss project key | +| `index_name` | (required) | Name of the Moss index to query | +| `top_k` | `5` | Number of results to retrieve per query | +| `alpha` | `0.8` | Blend: 1.0 = semantic only, 0.0 = keyword only | +| `result_prefix` | `Relevant knowledge base results:\n\n` | Prefix for formatted results | + +### Methods + +| Method | Description | +|--------|-------------| +| `load_index()` | Async. Pre-load the Moss index for fast first queries | +| `search(query)` | Async. Query Moss and return formatted results as a string | + +## Using with Chat Completion + +Moss works with any Semantic Kernel chat completion service. The kernel can automatically invoke the search function when the LLM decides it needs knowledge base information: + +```python +import semantic_kernel as sk +from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion +from semantic_kernel_moss import MossPlugin + +kernel = sk.Kernel() +kernel.add_service(OpenAIChatCompletion(service_id="chat")) + +moss = MossPlugin(index_name="product-docs") +await moss.load_index() +kernel.add_plugin(moss, plugin_name="moss") + +result = await kernel.invoke_prompt( + "Use the moss-search function to answer: {{$input}}", + input_vars={"input": "What are your shipping options?"}, +) +``` + +## License + +This plugin is provided under the [BSD 2-Clause License](LICENSE). + +## Support + +- [Moss Docs](https://docs.moss.dev) +- [Moss Discord](https://discord.com/invite/eMXExuafBR) +- [Semantic Kernel Docs](https://learn.microsoft.com/en-us/semantic-kernel/) diff --git a/packages/semantic-kernel-moss/examples/moss_sk_simple.py b/packages/semantic-kernel-moss/examples/moss_sk_simple.py new file mode 100644 index 00000000..4f491469 --- /dev/null +++ b/packages/semantic-kernel-moss/examples/moss_sk_simple.py @@ -0,0 +1,28 @@ +"""Minimal demo: Moss semantic search with a Semantic Kernel agent.""" + +import asyncio +import os + +import semantic_kernel as sk + +from semantic_kernel_moss import MossPlugin + + +async def main(): + """Run a Semantic Kernel agent with Moss semantic search.""" + moss = MossPlugin( + project_id=os.getenv("MOSS_PROJECT_ID"), + project_key=os.getenv("MOSS_PROJECT_KEY"), + index_name=os.getenv("MOSS_INDEX_NAME", "my-index"), + ) + await moss.load_index() + + kernel = sk.Kernel() + kernel.add_plugin(moss, plugin_name="moss") + + result = await kernel.invoke(function_name="search", plugin_name="moss", query="What are your shipping options?") + print(result) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/packages/semantic-kernel-moss/pyproject.toml b/packages/semantic-kernel-moss/pyproject.toml new file mode 100644 index 00000000..84add974 --- /dev/null +++ b/packages/semantic-kernel-moss/pyproject.toml @@ -0,0 +1,55 @@ +[project] +name = "semantic-kernel-moss" +version = "0.0.1" +description = "Moss semantic search plugin for Semantic Kernel" +readme = "README.md" +requires-python = ">=3.10,<3.14" +dependencies = [ + "inferedge-moss>=1.0.0b18", + "semantic-kernel>=1.0.0", +] + +[dependency-groups] +dev = [ + "pytest>=7.0", + "pytest-asyncio>=0.21", + "python-dotenv>=1.2.1", + "ruff>=0.1.0", +] + +[tool.ruff] +line-length = 100 +target-version = "py310" + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "B", # flake8-bugbear + "UP", # pyupgrade + "D", # pydocstyle +] +ignore = [ + "D100", # Missing docstring in public module + "D104", # Missing docstring in public package +] + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + + +[tool.setuptools.packages.find] +where = ["src"] +namespaces = false diff --git a/packages/semantic-kernel-moss/src/semantic_kernel_moss/__init__.py b/packages/semantic-kernel-moss/src/semantic_kernel_moss/__init__.py new file mode 100644 index 00000000..f82b23f3 --- /dev/null +++ b/packages/semantic-kernel-moss/src/semantic_kernel_moss/__init__.py @@ -0,0 +1,22 @@ +"""Moss semantic search plugin for Semantic Kernel.""" + +from __future__ import annotations + +from inferedge_moss import ( + DocumentInfo, + GetDocumentsOptions, + IndexInfo, + MossClient, + SearchResult, +) + +from .moss_plugin import MossPlugin + +__all__ = [ + "DocumentInfo", + "GetDocumentsOptions", + "IndexInfo", + "MossClient", + "MossPlugin", + "SearchResult", +] diff --git a/packages/semantic-kernel-moss/src/semantic_kernel_moss/moss_plugin.py b/packages/semantic-kernel-moss/src/semantic_kernel_moss/moss_plugin.py new file mode 100644 index 00000000..bc099010 --- /dev/null +++ b/packages/semantic-kernel-moss/src/semantic_kernel_moss/moss_plugin.py @@ -0,0 +1,147 @@ +# +# Copyright (c) 2025, InferEdge Inc. +# +# SPDX-License-Identifier: BSD 2-Clause License +# + +"""Semantic Kernel plugin for Moss semantic search.""" + +from __future__ import annotations + +import asyncio +import logging +from collections.abc import Sequence +from typing import Annotated, Any + +from inferedge_moss import MossClient, QueryOptions +from semantic_kernel.functions import kernel_function + +__all__ = ["MossPlugin"] + +logger = logging.getLogger("semantic_kernel_moss") + + +class MossPlugin: + """Provides Moss semantic search as a Semantic Kernel plugin. + + This class manages the MossClient lifecycle and exposes a + ``@kernel_function``-decorated ``search`` method that Semantic Kernel + discovers automatically when the plugin is registered. + + Usage:: + + import semantic_kernel as sk + from semantic_kernel_moss import MossPlugin + + moss = MossPlugin( + project_id="...", + project_key="...", + index_name="my-faq-index", + ) + await moss.load_index() + + kernel = sk.Kernel() + kernel.add_plugin(moss, plugin_name="moss") + + result = await kernel.invoke( + function_name="search", plugin_name="moss", query="What is your refund policy?" + ) + """ + + def __init__( + self, + *, + project_id: str | None = None, + project_key: str | None = None, + index_name: str, + top_k: int = 5, + alpha: float = 0.8, + result_prefix: str = "Relevant knowledge base results:\n\n", + ): + """Initialize with Moss credentials and retrieval settings. + + Args: + project_id: Moss project ID. Falls back to ``MOSS_PROJECT_ID`` env var. + project_key: Moss project key. Falls back to ``MOSS_PROJECT_KEY`` env var. + index_name: Name of the Moss index to query. + top_k: Number of results to retrieve per query. + alpha: Blend between semantic (1.0) and keyword (0.0) scoring. + result_prefix: Prefix prepended to formatted search results. + """ + self._client = MossClient(project_id=project_id, project_key=project_key) + self._index_name = index_name + self._top_k = top_k + self._alpha = alpha + self._result_prefix = result_prefix + self._index_loaded = False + self._load_lock = asyncio.Lock() + + async def load_index(self) -> None: + """Pre-load the Moss index for fast queries. + + Call this before registering the plugin with a Kernel so that + the first search invocation does not incur index-loading latency. + + This method is safe to call concurrently; only the first call + will actually load the index. + """ + async with self._load_lock: + if self._index_loaded: + return + logger.info("Loading Moss index '%s'", self._index_name) + await self._client.load_index(self._index_name) + self._index_loaded = True + logger.info("Moss index '%s' ready", self._index_name) + + @kernel_function( + name="search", + description="Search the knowledge base for documents relevant to a query", + ) + async def search( + self, + query: Annotated[str, "The search query to find relevant documents"], + ) -> str: + """Query the Moss index and return formatted results. + + Args: + query: The search query text. + + Returns: + Formatted string of search results suitable for LLM context, + or a short message if no results are found. + """ + if not self._index_loaded: + raise RuntimeError( + f"Index '{self._index_name}' not loaded. Call await load_index() first." + ) + + result = await self._client.query( + self._index_name, + query, + options=QueryOptions(top_k=self._top_k, alpha=self._alpha), + ) + logger.info( + "Moss query returned %d docs in %sms", + len(result.docs), + result.time_taken_ms, + ) + + return self._format_results(result.docs) + + def _format_results(self, documents: Sequence[Any]) -> str: + """Format Moss search results into a numbered string.""" + if not documents: + return "No relevant results found." + + lines = [self._result_prefix.rstrip(), ""] + for idx, doc in enumerate(documents, start=1): + meta = doc.metadata or {} + extras = [] + if source := meta.get("source"): + extras.append(f"source={source}") + if (score := getattr(doc, "score", None)) is not None: + extras.append(f"score={score:.3f}") + suffix = f" ({', '.join(extras)})" if extras else "" + text = getattr(doc, "text", "") or "" + lines.append(f"{idx}. {text}{suffix}") + return "\n".join(lines).strip() diff --git a/packages/semantic-kernel-moss/tests/test_moss_plugin.py b/packages/semantic-kernel-moss/tests/test_moss_plugin.py new file mode 100644 index 00000000..8236558f --- /dev/null +++ b/packages/semantic-kernel-moss/tests/test_moss_plugin.py @@ -0,0 +1,252 @@ +"""Tests for the Semantic Kernel Moss plugin.""" + +from __future__ import annotations + +from unittest.mock import AsyncMock, MagicMock, patch + +import pytest + +from semantic_kernel_moss import MossPlugin + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _make_mock_search_result(docs=None): + """Create a mock SearchResult.""" + result = MagicMock() + result.docs = docs or [] + result.time_taken_ms = 2.5 + return result + + +def _make_mock_doc(text="sample text", score=0.95, doc_id="doc-1", metadata=None): + """Create a mock DocumentInfo.""" + doc = MagicMock() + doc.text = text + doc.score = score + doc.id = doc_id + doc.metadata = metadata or {} + return doc + + +# --------------------------------------------------------------------------- +# MossPlugin – init tests +# --------------------------------------------------------------------------- + + +class TestMossPluginInit: + """Tests for MossPlugin initialization.""" + + def test_default_values(self): + """Verify default parameter values on construction.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + assert plugin._index_name == "idx" + assert plugin._top_k == 5 + assert plugin._alpha == 0.8 + assert plugin._index_loaded is False + + def test_custom_values(self): + """Verify custom parameter values are stored.""" + plugin = MossPlugin( + project_id="pid", + project_key="pkey", + index_name="idx", + top_k=10, + alpha=0.5, + ) + assert plugin._top_k == 10 + assert plugin._alpha == 0.5 + + +# --------------------------------------------------------------------------- +# MossPlugin – load_index tests +# --------------------------------------------------------------------------- + + +class TestMossPluginLoadIndex: + """Tests for load_index.""" + + @pytest.mark.asyncio + async def test_load_index_sets_flag(self): + """Verify load_index delegates to client and sets the loaded flag.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + with patch.object(plugin._client, "load_index", new_callable=AsyncMock) as mock_load: + await plugin.load_index() + mock_load.assert_called_once_with("idx") + assert plugin._index_loaded is True + + @pytest.mark.asyncio + async def test_load_index_only_loads_once(self): + """Verify concurrent load_index calls only trigger one actual load.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + with patch.object(plugin._client, "load_index", new_callable=AsyncMock) as mock_load: + await plugin.load_index() + await plugin.load_index() + mock_load.assert_called_once() + + +# --------------------------------------------------------------------------- +# MossPlugin – search tests +# --------------------------------------------------------------------------- + + +class TestMossPluginSearch: + """Tests for the search method.""" + + @pytest.mark.asyncio + async def test_search_returns_formatted_results(self): + """Verify search formats multiple docs with scores.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + plugin._index_loaded = True + + docs = [ + _make_mock_doc("First result", 0.95, "d1"), + _make_mock_doc("Second result", 0.80, "d2"), + ] + mock_result = _make_mock_search_result(docs) + + with patch.object( + plugin._client, "query", new_callable=AsyncMock, return_value=mock_result + ): + output = await plugin.search("test query") + assert "First result" in output + assert "Second result" in output + assert "score=0.950" in output + assert "score=0.800" in output + + @pytest.mark.asyncio + async def test_search_empty_results(self): + """Verify empty results produce a 'no results' message.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + plugin._index_loaded = True + + mock_result = _make_mock_search_result([]) + with patch.object( + plugin._client, "query", new_callable=AsyncMock, return_value=mock_result + ): + output = await plugin.search("test query") + assert "No relevant results found" in output + + @pytest.mark.asyncio + async def test_search_raises_if_index_not_loaded(self): + """Verify search raises RuntimeError before load_index is called.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + with pytest.raises(RuntimeError, match="not loaded"): + await plugin.search("test query") + + @pytest.mark.asyncio + async def test_search_with_metadata_source(self): + """Verify source metadata is included in formatted output.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + plugin._index_loaded = True + + docs = [_make_mock_doc("doc text", 0.9, "d1", {"source": "faq.md"})] + mock_result = _make_mock_search_result(docs) + + with patch.object( + plugin._client, "query", new_callable=AsyncMock, return_value=mock_result + ): + output = await plugin.search("q") + assert "source=faq.md" in output + + @pytest.mark.asyncio + async def test_search_propagates_client_exceptions(self): + """Verify client exceptions bubble up without being caught.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + plugin._index_loaded = True + + with patch.object( + plugin._client, + "query", + new_callable=AsyncMock, + side_effect=ConnectionError("network failure"), + ): + with pytest.raises(ConnectionError, match="network failure"): + await plugin.search("test query") + + +# --------------------------------------------------------------------------- +# Kernel integration tests +# --------------------------------------------------------------------------- + + +class TestKernelIntegration: + """Tests that verify the plugin works with a real SK Kernel.""" + + @pytest.mark.asyncio + async def test_plugin_discoverable_by_kernel(self): + """Verify kernel discovers the search function after add_plugin.""" + import semantic_kernel as sk + + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + kernel = sk.Kernel() + kernel.add_plugin(plugin, plugin_name="moss") + + moss_plugin = kernel.get_plugin("moss") + assert moss_plugin is not None + assert "search" in moss_plugin + + @pytest.mark.asyncio + async def test_kernel_invoke_returns_string(self): + """Verify full round-trip: kernel.invoke returns formatted results.""" + import semantic_kernel as sk + + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + plugin._index_loaded = True + + docs = [_make_mock_doc("kernel result", 0.92, "d1")] + mock_result = _make_mock_search_result(docs) + + kernel = sk.Kernel() + kernel.add_plugin(plugin, plugin_name="moss") + + with patch.object( + plugin._client, "query", new_callable=AsyncMock, return_value=mock_result + ): + result = await kernel.invoke(function_name="search", plugin_name="moss", query="test") + output = str(result) + assert "kernel result" in output + assert "score=0.920" in output + + +# --------------------------------------------------------------------------- +# Format results – edge cases +# --------------------------------------------------------------------------- + + +class TestFormatResults: + """Tests for _format_results edge cases.""" + + def test_format_with_no_documents(self): + """Verify empty doc list returns fallback message.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + result = plugin._format_results([]) + assert "No relevant results found" in result + + def test_format_with_custom_prefix(self): + """Verify custom result_prefix is used in output.""" + plugin = MossPlugin( + project_id="pid", + project_key="pkey", + index_name="idx", + result_prefix="Search results:\n\n", + ) + docs = [_make_mock_doc("hello", 0.99)] + result = plugin._format_results(docs) + assert result.startswith("Search results:") + assert "hello" in result + + def test_format_numbers_results(self): + """Verify docs are numbered sequentially starting at 1.""" + plugin = MossPlugin(project_id="pid", project_key="pkey", index_name="idx") + docs = [ + _make_mock_doc("first", 0.9), + _make_mock_doc("second", 0.8), + _make_mock_doc("third", 0.7), + ] + result = plugin._format_results(docs) + assert "1. first" in result + assert "2. second" in result + assert "3. third" in result From 872de475599153895d96b672c5a8be6a6660049a Mon Sep 17 00:00:00 2001 From: Abhijitam01 Date: Thu, 9 Apr 2026 01:41:02 +0530 Subject: [PATCH 2/2] fix: use moss package instead of inferedge-moss MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aligns with the rest of the repo — all other integration packages (strands-agents-moss, elevenlabs-moss, pipecat-moss, moss-cli) depend on moss and import from moss, not inferedge-moss. --- packages/semantic-kernel-moss/pyproject.toml | 2 +- .../semantic-kernel-moss/src/semantic_kernel_moss/__init__.py | 2 +- .../src/semantic_kernel_moss/moss_plugin.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/semantic-kernel-moss/pyproject.toml b/packages/semantic-kernel-moss/pyproject.toml index 84add974..a68a154d 100644 --- a/packages/semantic-kernel-moss/pyproject.toml +++ b/packages/semantic-kernel-moss/pyproject.toml @@ -5,7 +5,7 @@ description = "Moss semantic search plugin for Semantic Kernel" readme = "README.md" requires-python = ">=3.10,<3.14" dependencies = [ - "inferedge-moss>=1.0.0b18", + "moss>=1.0.0b18", "semantic-kernel>=1.0.0", ] diff --git a/packages/semantic-kernel-moss/src/semantic_kernel_moss/__init__.py b/packages/semantic-kernel-moss/src/semantic_kernel_moss/__init__.py index f82b23f3..69622e76 100644 --- a/packages/semantic-kernel-moss/src/semantic_kernel_moss/__init__.py +++ b/packages/semantic-kernel-moss/src/semantic_kernel_moss/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations -from inferedge_moss import ( +from moss import ( DocumentInfo, GetDocumentsOptions, IndexInfo, diff --git a/packages/semantic-kernel-moss/src/semantic_kernel_moss/moss_plugin.py b/packages/semantic-kernel-moss/src/semantic_kernel_moss/moss_plugin.py index bc099010..13e2436e 100644 --- a/packages/semantic-kernel-moss/src/semantic_kernel_moss/moss_plugin.py +++ b/packages/semantic-kernel-moss/src/semantic_kernel_moss/moss_plugin.py @@ -13,7 +13,7 @@ from collections.abc import Sequence from typing import Annotated, Any -from inferedge_moss import MossClient, QueryOptions +from moss import MossClient, QueryOptions from semantic_kernel.functions import kernel_function __all__ = ["MossPlugin"]