semantic-kernel 0.3.0.dev0__tar.gz → 0.3.2.dev0__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.
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/PKG-INFO +3 -1
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/pyproject.toml +12 -7
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/__init__.py +2 -0
- semantic_kernel-0.3.2.dev0/semantic_kernel/connectors/ai/chat_completion_client_base.py +52 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/chat_request_settings.py +2 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/complete_request_settings.py +1 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/hugging_face/services/hf_text_completion.py +43 -18
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/open_ai/services/open_ai_chat_completion.py +48 -14
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/open_ai/services/open_ai_text_completion.py +16 -11
- semantic_kernel-0.3.2.dev0/semantic_kernel/connectors/ai/text_completion_client_base.py +52 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/memory/chroma/chroma_memory_store.py +8 -5
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/memory/chroma/utils.py +45 -22
- semantic_kernel-0.3.2.dev0/semantic_kernel/connectors/memory/pinecone/__init__.py +7 -0
- semantic_kernel-0.3.2.dev0/semantic_kernel/connectors/memory/pinecone/pinecone_memory_store.py +401 -0
- semantic_kernel-0.3.2.dev0/semantic_kernel/connectors/memory/pinecone/utils.py +37 -0
- {semantic_kernel-0.3.0.dev0/semantic_kernel/connectors/memory → semantic_kernel-0.3.2.dev0/semantic_kernel/connectors/memory/weaviate}/weaviate_memory_store.py +30 -15
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/core_skills/file_io_skill.py +1 -1
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/core_skills/math_skill.py +1 -1
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/core_skills/text_skill.py +1 -1
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/core_skills/time_skill.py +15 -3
- semantic_kernel-0.3.2.dev0/semantic_kernel/core_skills/wait_skill.py +23 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/kernel.py +2 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/memory/memory_query_result.py +4 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/memory/memory_record.py +15 -2
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/memory/null_memory.py +7 -1
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/memory/semantic_text_memory.py +17 -6
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/memory/semantic_text_memory_base.py +2 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/orchestration/sk_function.py +5 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/planning/basic_planner.py +9 -1
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/semantic_functions/prompt_template_config.py +6 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/functions_view.py +14 -1
- semantic_kernel-0.3.2.dev0/semantic_kernel/text/text_chunker.py +333 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/utils/settings.py +36 -31
- semantic_kernel-0.3.0.dev0/semantic_kernel/connectors/ai/chat_completion_client_base.py +0 -28
- semantic_kernel-0.3.0.dev0/semantic_kernel/connectors/ai/text_completion_client_base.py +0 -30
- semantic_kernel-0.3.0.dev0/semantic_kernel/text/text_chunker.py +0 -250
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/pip/README.md +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/__init__.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/ai_exception.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/embeddings/embedding_generator_base.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/hugging_face/__init__.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/hugging_face/services/hf_text_embedding.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/open_ai/__init__.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/open_ai/services/azure_chat_completion.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/open_ai/services/azure_text_completion.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/open_ai/services/azure_text_embedding.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/ai/open_ai/services/open_ai_text_embedding.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/connectors/memory/chroma/__init__.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/core_skills/__init__.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/core_skills/conversation_summary_skill.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/core_skills/http_skill.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/core_skills/text_memory_skill.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/kernel_exception.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/memory/__init__.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/memory/memory_store_base.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/memory/volatile_memory_store.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/orchestration/context_variables.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/orchestration/delegate_handlers.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/orchestration/delegate_inference.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/orchestration/delegate_types.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/orchestration/sk_context.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/orchestration/sk_function_base.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/planning/__init__.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/planning/plan.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/reliability/pass_through_without_retry.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/reliability/retry_mechanism_base.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/semantic_functions/chat_prompt_template.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/semantic_functions/prompt_template.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/semantic_functions/prompt_template_base.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/semantic_functions/semantic_function_config.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/__init__.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/function_view.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/parameter_view.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/read_only_skill_collection.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/read_only_skill_collection_base.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/sk_function_context_parameter_decorator.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/sk_function_decorator.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/skill_collection.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/skill_definition/skill_collection_base.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/README.md +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/blocks/block.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/blocks/block_types.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/blocks/code_block.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/blocks/function_id_block.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/blocks/symbols.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/blocks/text_block.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/blocks/val_block.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/blocks/var_block.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/code_tokenizer.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/prompt_template_engine.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/protocols/code_renderer.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/protocols/prompt_templating_engine.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/protocols/text_renderer.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/template_engine/template_tokenizer.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/text/__init__.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/text/function_extension.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/utils/null_logger.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/utils/static_property.py +0 -0
- {semantic_kernel-0.3.0.dev0 → semantic_kernel-0.3.2.dev0}/semantic_kernel/utils/validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: semantic-kernel
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2.dev0
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Microsoft
|
|
6
6
|
Author-email: SK-Support@microsoft.com
|
|
@@ -13,6 +13,8 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
13
13
|
Requires-Dist: aiofiles (>=23.1.0,<24.0.0)
|
|
14
14
|
Requires-Dist: numpy (>=1.24.2,<2.0.0)
|
|
15
15
|
Requires-Dist: openai (>=0.27.0,<0.28.0)
|
|
16
|
+
Requires-Dist: python-dotenv (==1.0.0)
|
|
17
|
+
Requires-Dist: regex (>=2023.6.3,<2024.0.0)
|
|
16
18
|
Description-Content-Type: text/markdown
|
|
17
19
|
|
|
18
20
|
# About Semantic Kernel
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "semantic-kernel"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.2.dev"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = ["Microsoft <SK-Support@microsoft.com>"]
|
|
6
6
|
readme = "pip/README.md"
|
|
@@ -11,15 +11,16 @@ python = "^3.8"
|
|
|
11
11
|
numpy = "^1.24.2"
|
|
12
12
|
openai = "^0.27.0"
|
|
13
13
|
aiofiles = "^23.1.0"
|
|
14
|
+
python-dotenv = "1.0.0"
|
|
15
|
+
regex = "^2023.6.3"
|
|
14
16
|
|
|
15
17
|
[tool.poetry.group.dev.dependencies]
|
|
16
|
-
pre-commit = "
|
|
17
|
-
black = {version = "
|
|
18
|
+
pre-commit = "3.3.3"
|
|
19
|
+
black = {version = "23.3.0", allow-prereleases = true}
|
|
18
20
|
ipykernel = "^6.21.1"
|
|
19
|
-
pytest = "7.
|
|
20
|
-
ruff = "
|
|
21
|
-
pytest-asyncio = "
|
|
22
|
-
|
|
21
|
+
pytest = "7.4.0"
|
|
22
|
+
ruff = "0.0.277"
|
|
23
|
+
pytest-asyncio = "0.21.0"
|
|
23
24
|
|
|
24
25
|
[tool.poetry.group.hugging_face.dependencies]
|
|
25
26
|
transformers = "^4.28.1"
|
|
@@ -33,10 +34,14 @@ chromadb = "^0.3.23"
|
|
|
33
34
|
[tool.poetry.group.weaviate.dependencies]
|
|
34
35
|
weaviate-client = "^3.18.0"
|
|
35
36
|
|
|
37
|
+
[tool.poetry.group.pinecone.dependencies]
|
|
38
|
+
pinecone-client = "^2.2.2"
|
|
39
|
+
|
|
36
40
|
[tool.isort]
|
|
37
41
|
profile = "black"
|
|
38
42
|
|
|
39
43
|
[tool.ruff]
|
|
44
|
+
select = ["E", "F", "I"]
|
|
40
45
|
line-length = 120
|
|
41
46
|
|
|
42
47
|
[build-system]
|
|
@@ -17,6 +17,7 @@ from semantic_kernel.utils.null_logger import NullLogger
|
|
|
17
17
|
from semantic_kernel.utils.settings import (
|
|
18
18
|
azure_openai_settings_from_dot_env,
|
|
19
19
|
openai_settings_from_dot_env,
|
|
20
|
+
pinecone_settings_from_dot_env,
|
|
20
21
|
)
|
|
21
22
|
|
|
22
23
|
__all__ = [
|
|
@@ -24,6 +25,7 @@ __all__ = [
|
|
|
24
25
|
"NullLogger",
|
|
25
26
|
"openai_settings_from_dot_env",
|
|
26
27
|
"azure_openai_settings_from_dot_env",
|
|
28
|
+
"pinecone_settings_from_dot_env",
|
|
27
29
|
"PromptTemplateConfig",
|
|
28
30
|
"PromptTemplate",
|
|
29
31
|
"ChatPromptTemplate",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from logging import Logger
|
|
5
|
+
from typing import TYPE_CHECKING, List, Tuple, Union
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from semantic_kernel.connectors.ai.chat_request_settings import ChatRequestSettings
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ChatCompletionClientBase(ABC):
|
|
12
|
+
@abstractmethod
|
|
13
|
+
async def complete_chat_async(
|
|
14
|
+
self,
|
|
15
|
+
messages: List[Tuple[str, str]],
|
|
16
|
+
settings: "ChatRequestSettings",
|
|
17
|
+
logger: Logger,
|
|
18
|
+
) -> Union[str, List[str]]:
|
|
19
|
+
"""
|
|
20
|
+
This is the method that is called from the kernel to get a response from a chat-optimized LLM.
|
|
21
|
+
|
|
22
|
+
Arguments:
|
|
23
|
+
messages {List[Tuple[str, str]]} -- A list of tuples, where each tuple is
|
|
24
|
+
comprised of a speaker ID and a message.
|
|
25
|
+
settings {ChatRequestSettings} -- Settings for the request.
|
|
26
|
+
logger {Logger} -- A logger to use for logging.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Union[str, List[str]] -- A string or list of strings representing the response(s) from the LLM.
|
|
30
|
+
"""
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
@abstractmethod
|
|
34
|
+
async def complete_chat_stream_async(
|
|
35
|
+
self,
|
|
36
|
+
messages: List[Tuple[str, str]],
|
|
37
|
+
settings: "ChatRequestSettings",
|
|
38
|
+
logger: Logger,
|
|
39
|
+
):
|
|
40
|
+
"""
|
|
41
|
+
This is the method that is called from the kernel to get a stream response from a chat-optimized LLM.
|
|
42
|
+
|
|
43
|
+
Arguments:
|
|
44
|
+
messages {List[Tuple[str, str]]} -- A list of tuples, where each tuple is
|
|
45
|
+
comprised of a speaker ID and a message.
|
|
46
|
+
settings {ChatRequestSettings} -- Settings for the request.
|
|
47
|
+
logger {Logger} -- A logger to use for logging.
|
|
48
|
+
|
|
49
|
+
Yields:
|
|
50
|
+
A stream representing the response(s) from the LLM.
|
|
51
|
+
"""
|
|
52
|
+
pass
|
|
@@ -15,6 +15,7 @@ class ChatRequestSettings:
|
|
|
15
15
|
top_p: float = 1.0
|
|
16
16
|
presence_penalty: float = 0.0
|
|
17
17
|
frequency_penalty: float = 0.0
|
|
18
|
+
number_of_responses: int = 1
|
|
18
19
|
max_tokens: int = 256
|
|
19
20
|
|
|
20
21
|
def update_from_completion_config(
|
|
@@ -24,6 +25,7 @@ class ChatRequestSettings:
|
|
|
24
25
|
self.top_p = completion_config.top_p
|
|
25
26
|
self.presence_penalty = completion_config.presence_penalty
|
|
26
27
|
self.frequency_penalty = completion_config.frequency_penalty
|
|
28
|
+
self.number_of_responses = completion_config.number_of_responses
|
|
27
29
|
self.max_tokens = completion_config.max_tokens
|
|
28
30
|
|
|
29
31
|
@staticmethod
|
|
@@ -29,6 +29,7 @@ class CompleteRequestSettings:
|
|
|
29
29
|
self.frequency_penalty = completion_config.frequency_penalty
|
|
30
30
|
self.max_tokens = completion_config.max_tokens
|
|
31
31
|
self.stop_sequences = completion_config.stop_sequences
|
|
32
|
+
self.number_of_responses = completion_config.number_of_responses
|
|
32
33
|
|
|
33
34
|
@staticmethod
|
|
34
35
|
def from_completion_config(
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from logging import Logger
|
|
4
4
|
from threading import Thread
|
|
5
|
-
from typing import Optional
|
|
5
|
+
from typing import List, Optional, Union
|
|
6
6
|
|
|
7
7
|
from semantic_kernel.connectors.ai.ai_exception import AIException
|
|
8
8
|
from semantic_kernel.connectors.ai.complete_request_settings import (
|
|
@@ -64,17 +64,7 @@ class HuggingFaceTextCompletion(TextCompletionClientBase):
|
|
|
64
64
|
|
|
65
65
|
async def complete_async(
|
|
66
66
|
self, prompt: str, request_settings: CompleteRequestSettings
|
|
67
|
-
) -> str:
|
|
68
|
-
"""
|
|
69
|
-
Completes a prompt using the Hugging Face model.
|
|
70
|
-
|
|
71
|
-
Arguments:
|
|
72
|
-
prompt {str} -- Prompt to complete.
|
|
73
|
-
request_settings {CompleteRequestSettings} -- Request settings.
|
|
74
|
-
|
|
75
|
-
Returns:
|
|
76
|
-
str -- Completion result.
|
|
77
|
-
"""
|
|
67
|
+
) -> Union[str, List[str]]:
|
|
78
68
|
try:
|
|
79
69
|
import transformers
|
|
80
70
|
|
|
@@ -84,15 +74,30 @@ class HuggingFaceTextCompletion(TextCompletionClientBase):
|
|
|
84
74
|
max_new_tokens=request_settings.max_tokens,
|
|
85
75
|
pad_token_id=50256, # EOS token
|
|
86
76
|
)
|
|
87
|
-
|
|
88
|
-
|
|
77
|
+
|
|
78
|
+
results = self.generator(
|
|
79
|
+
prompt,
|
|
80
|
+
do_sample=True,
|
|
81
|
+
num_return_sequences=request_settings.number_of_responses,
|
|
82
|
+
generation_config=generation_config,
|
|
89
83
|
)
|
|
90
84
|
|
|
85
|
+
completions = list()
|
|
91
86
|
if self._task == "text-generation" or self._task == "text2text-generation":
|
|
92
|
-
|
|
87
|
+
for response in results:
|
|
88
|
+
completions.append(response["generated_text"])
|
|
89
|
+
if len(completions) == 1:
|
|
90
|
+
return completions[0]
|
|
91
|
+
else:
|
|
92
|
+
return completions
|
|
93
93
|
|
|
94
94
|
elif self._task == "summarization":
|
|
95
|
-
|
|
95
|
+
for response in results:
|
|
96
|
+
completions.append(response["summary_text"])
|
|
97
|
+
if len(completions) == 1:
|
|
98
|
+
return completions[0]
|
|
99
|
+
else:
|
|
100
|
+
return completions
|
|
96
101
|
|
|
97
102
|
else:
|
|
98
103
|
raise AIException(
|
|
@@ -107,6 +112,23 @@ class HuggingFaceTextCompletion(TextCompletionClientBase):
|
|
|
107
112
|
async def complete_stream_async(
|
|
108
113
|
self, prompt: str, request_settings: CompleteRequestSettings
|
|
109
114
|
):
|
|
115
|
+
"""
|
|
116
|
+
Streams a text completion using a Hugging Face model.
|
|
117
|
+
Note that this method does not support multiple responses.
|
|
118
|
+
|
|
119
|
+
Arguments:
|
|
120
|
+
prompt {str} -- Prompt to complete.
|
|
121
|
+
request_settings {CompleteRequestSettings} -- Request settings.
|
|
122
|
+
|
|
123
|
+
Yields:
|
|
124
|
+
str -- Completion result.
|
|
125
|
+
"""
|
|
126
|
+
if request_settings.number_of_responses > 1:
|
|
127
|
+
raise AIException(
|
|
128
|
+
AIException.ErrorCodes.InvalidConfiguration,
|
|
129
|
+
"HuggingFace TextIteratorStreamer does not stream multiple responses in a parseable format. \
|
|
130
|
+
If you need multiple responses, please use the complete_async method.",
|
|
131
|
+
)
|
|
110
132
|
try:
|
|
111
133
|
import transformers
|
|
112
134
|
|
|
@@ -116,15 +138,18 @@ class HuggingFaceTextCompletion(TextCompletionClientBase):
|
|
|
116
138
|
max_new_tokens=request_settings.max_tokens,
|
|
117
139
|
pad_token_id=50256, # EOS token
|
|
118
140
|
)
|
|
141
|
+
|
|
119
142
|
tokenizer = transformers.AutoTokenizer.from_pretrained(self._model_id)
|
|
120
143
|
streamer = transformers.TextIteratorStreamer(tokenizer)
|
|
121
|
-
args = {
|
|
144
|
+
args = {prompt}
|
|
122
145
|
kwargs = {
|
|
123
|
-
"num_return_sequences":
|
|
146
|
+
"num_return_sequences": request_settings.number_of_responses,
|
|
124
147
|
"generation_config": generation_config,
|
|
125
148
|
"streamer": streamer,
|
|
149
|
+
"do_sample": True,
|
|
126
150
|
}
|
|
127
151
|
|
|
152
|
+
# See https://github.com/huggingface/transformers/blob/main/src/transformers/generation/streamers.py#L159
|
|
128
153
|
thread = Thread(target=self.generator, args=args, kwargs=kwargs)
|
|
129
154
|
thread.start()
|
|
130
155
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Microsoft. All rights reserved.
|
|
2
2
|
|
|
3
3
|
from logging import Logger
|
|
4
|
-
from typing import Any, List, Optional, Tuple
|
|
4
|
+
from typing import Any, List, Optional, Tuple, Union
|
|
5
5
|
|
|
6
6
|
import openai
|
|
7
7
|
|
|
@@ -61,28 +61,37 @@ class OpenAIChatCompletion(ChatCompletionClientBase, TextCompletionClientBase):
|
|
|
61
61
|
|
|
62
62
|
async def complete_chat_async(
|
|
63
63
|
self, messages: List[Tuple[str, str]], request_settings: ChatRequestSettings
|
|
64
|
-
) -> str:
|
|
64
|
+
) -> Union[str, List[str]]:
|
|
65
65
|
# TODO: tracking on token counts/etc.
|
|
66
66
|
response = await self._send_chat_request(messages, request_settings, False)
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
if len(response.choices) == 1:
|
|
69
|
+
return response.choices[0].message.content
|
|
70
|
+
else:
|
|
71
|
+
return [choice.message.content for choice in response.choices]
|
|
69
72
|
|
|
70
73
|
async def complete_chat_stream_async(
|
|
71
74
|
self, messages: List[Tuple[str, str]], request_settings: ChatRequestSettings
|
|
72
75
|
):
|
|
73
76
|
response = await self._send_chat_request(messages, request_settings, True)
|
|
77
|
+
|
|
78
|
+
# parse the completion text(s) and yield them
|
|
74
79
|
async for chunk in response:
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if
|
|
78
|
-
|
|
80
|
+
text, index = _parse_choices(chunk)
|
|
81
|
+
# if multiple responses are requested, keep track of them
|
|
82
|
+
if request_settings.number_of_responses > 1:
|
|
83
|
+
completions = [""] * request_settings.number_of_responses
|
|
84
|
+
completions[index] = text
|
|
85
|
+
yield completions
|
|
86
|
+
# if only one response is requested, yield it
|
|
87
|
+
else:
|
|
88
|
+
yield text
|
|
79
89
|
|
|
80
90
|
async def complete_async(
|
|
81
91
|
self, prompt: str, request_settings: CompleteRequestSettings
|
|
82
|
-
) -> str:
|
|
92
|
+
) -> Union[str, List[str]]:
|
|
83
93
|
"""
|
|
84
|
-
Completes the given prompt.
|
|
85
|
-
Cannot return multiple completions. Cannot return logprobs.
|
|
94
|
+
Completes the given prompt.
|
|
86
95
|
|
|
87
96
|
Arguments:
|
|
88
97
|
prompt {str} -- The prompt to complete.
|
|
@@ -98,12 +107,16 @@ class OpenAIChatCompletion(ChatCompletionClientBase, TextCompletionClientBase):
|
|
|
98
107
|
presence_penalty=request_settings.presence_penalty,
|
|
99
108
|
frequency_penalty=request_settings.frequency_penalty,
|
|
100
109
|
max_tokens=request_settings.max_tokens,
|
|
110
|
+
number_of_responses=request_settings.number_of_responses,
|
|
101
111
|
)
|
|
102
112
|
response = await self._send_chat_request(
|
|
103
113
|
prompt_to_message, chat_settings, False
|
|
104
114
|
)
|
|
105
115
|
|
|
106
|
-
|
|
116
|
+
if len(response.choices) == 1:
|
|
117
|
+
return response.choices[0].message.content
|
|
118
|
+
else:
|
|
119
|
+
return [choice.message.content for choice in response.choices]
|
|
107
120
|
|
|
108
121
|
async def complete_stream_async(
|
|
109
122
|
self, prompt: str, request_settings: CompleteRequestSettings
|
|
@@ -115,12 +128,21 @@ class OpenAIChatCompletion(ChatCompletionClientBase, TextCompletionClientBase):
|
|
|
115
128
|
presence_penalty=request_settings.presence_penalty,
|
|
116
129
|
frequency_penalty=request_settings.frequency_penalty,
|
|
117
130
|
max_tokens=request_settings.max_tokens,
|
|
131
|
+
number_of_responses=request_settings.number_of_responses,
|
|
118
132
|
)
|
|
119
133
|
response = await self._send_chat_request(prompt_to_message, chat_settings, True)
|
|
120
134
|
|
|
135
|
+
# parse the completion text(s) and yield them
|
|
121
136
|
async for chunk in response:
|
|
122
|
-
|
|
123
|
-
|
|
137
|
+
text, index = _parse_choices(chunk)
|
|
138
|
+
# if multiple responses are requested, keep track of them
|
|
139
|
+
if request_settings.number_of_responses > 1:
|
|
140
|
+
completions = [""] * request_settings.number_of_responses
|
|
141
|
+
completions[index] = text
|
|
142
|
+
yield completions
|
|
143
|
+
# if only one response is requested, yield it
|
|
144
|
+
else:
|
|
145
|
+
yield text
|
|
124
146
|
|
|
125
147
|
async def _send_chat_request(
|
|
126
148
|
self,
|
|
@@ -129,7 +151,7 @@ class OpenAIChatCompletion(ChatCompletionClientBase, TextCompletionClientBase):
|
|
|
129
151
|
stream: bool,
|
|
130
152
|
):
|
|
131
153
|
"""
|
|
132
|
-
Completes the given user message
|
|
154
|
+
Completes the given user message with an asynchronous stream.
|
|
133
155
|
|
|
134
156
|
Arguments:
|
|
135
157
|
user_message {str} -- The message (from a user) to respond to.
|
|
@@ -184,6 +206,7 @@ class OpenAIChatCompletion(ChatCompletionClientBase, TextCompletionClientBase):
|
|
|
184
206
|
presence_penalty=request_settings.presence_penalty,
|
|
185
207
|
frequency_penalty=request_settings.frequency_penalty,
|
|
186
208
|
max_tokens=request_settings.max_tokens,
|
|
209
|
+
n=request_settings.number_of_responses,
|
|
187
210
|
stream=stream,
|
|
188
211
|
)
|
|
189
212
|
except Exception as ex:
|
|
@@ -196,3 +219,14 @@ class OpenAIChatCompletion(ChatCompletionClientBase, TextCompletionClientBase):
|
|
|
196
219
|
# TODO: tracking on token counts/etc.
|
|
197
220
|
|
|
198
221
|
return response
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _parse_choices(chunk):
|
|
225
|
+
message = ""
|
|
226
|
+
if "role" in chunk.choices[0].delta:
|
|
227
|
+
message += chunk.choices[0].delta.role + ": "
|
|
228
|
+
if "content" in chunk.choices[0].delta:
|
|
229
|
+
message += chunk.choices[0].delta.content
|
|
230
|
+
|
|
231
|
+
index = chunk.choices[0].index
|
|
232
|
+
return message, index
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) Microsoft. All rights reserved.
|
|
2
2
|
|
|
3
3
|
from logging import Logger
|
|
4
|
-
from typing import Any, Optional
|
|
4
|
+
from typing import Any, List, Optional, Union
|
|
5
5
|
|
|
6
6
|
import openai
|
|
7
7
|
|
|
@@ -56,10 +56,14 @@ class OpenAITextCompletion(TextCompletionClientBase):
|
|
|
56
56
|
|
|
57
57
|
async def complete_async(
|
|
58
58
|
self, prompt: str, request_settings: CompleteRequestSettings
|
|
59
|
-
) -> str:
|
|
59
|
+
) -> Union[str, List[str]]:
|
|
60
60
|
# TODO: tracking on token counts/etc.
|
|
61
61
|
response = await self._send_completion_request(prompt, request_settings, False)
|
|
62
|
-
|
|
62
|
+
|
|
63
|
+
if len(response.choices) == 1:
|
|
64
|
+
return response.choices[0].text
|
|
65
|
+
else:
|
|
66
|
+
return [choice.text for choice in response.choices]
|
|
63
67
|
|
|
64
68
|
# TODO: complete w/ multiple...
|
|
65
69
|
|
|
@@ -67,8 +71,15 @@ class OpenAITextCompletion(TextCompletionClientBase):
|
|
|
67
71
|
self, prompt: str, request_settings: CompleteRequestSettings
|
|
68
72
|
):
|
|
69
73
|
response = await self._send_completion_request(prompt, request_settings, True)
|
|
74
|
+
|
|
70
75
|
async for chunk in response:
|
|
71
|
-
|
|
76
|
+
if request_settings.number_of_responses > 1:
|
|
77
|
+
for choice in chunk.choices:
|
|
78
|
+
completions = [""] * request_settings.number_of_responses
|
|
79
|
+
completions[choice.index] = choice.text
|
|
80
|
+
yield completions
|
|
81
|
+
else:
|
|
82
|
+
yield chunk.choices[0].text
|
|
72
83
|
|
|
73
84
|
async def _send_completion_request(
|
|
74
85
|
self, prompt: str, request_settings: CompleteRequestSettings, stream: bool
|
|
@@ -96,13 +107,6 @@ class OpenAITextCompletion(TextCompletionClientBase):
|
|
|
96
107
|
f"but was {request_settings.max_tokens}",
|
|
97
108
|
)
|
|
98
109
|
|
|
99
|
-
if request_settings.number_of_responses != 1:
|
|
100
|
-
raise AIException(
|
|
101
|
-
AIException.ErrorCodes.InvalidRequest,
|
|
102
|
-
"complete_async only supports a single completion, "
|
|
103
|
-
f"but {request_settings.number_of_responses} were requested",
|
|
104
|
-
)
|
|
105
|
-
|
|
106
110
|
if request_settings.logprobs != 0:
|
|
107
111
|
raise AIException(
|
|
108
112
|
AIException.ErrorCodes.InvalidRequest,
|
|
@@ -131,6 +135,7 @@ class OpenAITextCompletion(TextCompletionClientBase):
|
|
|
131
135
|
frequency_penalty=request_settings.frequency_penalty,
|
|
132
136
|
max_tokens=request_settings.max_tokens,
|
|
133
137
|
stream=stream,
|
|
138
|
+
n=request_settings.number_of_responses,
|
|
134
139
|
stop=(
|
|
135
140
|
request_settings.stop_sequences
|
|
136
141
|
if request_settings.stop_sequences is not None
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Copyright (c) Microsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from logging import Logger
|
|
5
|
+
from typing import TYPE_CHECKING, List, Union
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from semantic_kernel.connectors.ai.complete_request_settings import (
|
|
9
|
+
CompleteRequestSettings,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TextCompletionClientBase(ABC):
|
|
14
|
+
@abstractmethod
|
|
15
|
+
async def complete_async(
|
|
16
|
+
self,
|
|
17
|
+
prompt: str,
|
|
18
|
+
settings: "CompleteRequestSettings",
|
|
19
|
+
logger: Logger,
|
|
20
|
+
) -> Union[str, List[str]]:
|
|
21
|
+
"""
|
|
22
|
+
This is the method that is called from the kernel to get a response from a text-optimized LLM.
|
|
23
|
+
|
|
24
|
+
Arguments:
|
|
25
|
+
prompt {str} -- The prompt to send to the LLM.
|
|
26
|
+
settings {CompleteRequestSettings} -- Settings for the request.
|
|
27
|
+
logger {Logger} -- A logger to use for logging.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
Union[str, List[str]] -- A string or list of strings representing the response(s) from the LLM.
|
|
31
|
+
"""
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
@abstractmethod
|
|
35
|
+
async def complete_stream_async(
|
|
36
|
+
self,
|
|
37
|
+
prompt: str,
|
|
38
|
+
settings: "CompleteRequestSettings",
|
|
39
|
+
logger: Logger,
|
|
40
|
+
):
|
|
41
|
+
"""
|
|
42
|
+
This is the method that is called from the kernel to get a stream response from a text-optimized LLM.
|
|
43
|
+
|
|
44
|
+
Arguments:
|
|
45
|
+
prompt {str} -- The prompt to send to the LLM.
|
|
46
|
+
settings {CompleteRequestSettings} -- Settings for the request.
|
|
47
|
+
logger {Logger} -- A logger to use for logging.
|
|
48
|
+
|
|
49
|
+
Yields:
|
|
50
|
+
A stream representing the response(s) from the LLM.
|
|
51
|
+
"""
|
|
52
|
+
pass
|
|
@@ -158,12 +158,14 @@ class ChromaMemoryStore(MemoryStoreBase):
|
|
|
158
158
|
if collection is None:
|
|
159
159
|
raise Exception(f"Collection '{collection_name}' does not exist")
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
record._key = record._id
|
|
162
162
|
metadata = {
|
|
163
163
|
"timestamp": record._timestamp or "",
|
|
164
164
|
"is_reference": record._is_reference,
|
|
165
165
|
"external_source_name": record._external_source_name or "",
|
|
166
166
|
"description": record._description or "",
|
|
167
|
+
"additional_metadata": record._additional_metadata or "",
|
|
168
|
+
"id": record._id or "",
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
collection.add(
|
|
@@ -171,11 +173,12 @@ class ChromaMemoryStore(MemoryStoreBase):
|
|
|
171
173
|
# by providing embeddings, we can skip the chroma's embedding function call
|
|
172
174
|
embeddings=record.embedding.tolist(),
|
|
173
175
|
documents=record._text,
|
|
174
|
-
ids=record.
|
|
176
|
+
ids=record._key,
|
|
175
177
|
)
|
|
178
|
+
|
|
176
179
|
if self._persist_directory is not None:
|
|
177
180
|
self._client.persist()
|
|
178
|
-
return record.
|
|
181
|
+
return record._key
|
|
179
182
|
|
|
180
183
|
async def upsert_batch_async(
|
|
181
184
|
self, collection_name: str, records: List[MemoryRecord]
|
|
@@ -237,7 +240,7 @@ class ChromaMemoryStore(MemoryStoreBase):
|
|
|
237
240
|
)
|
|
238
241
|
|
|
239
242
|
value = collection.get(ids=keys, include=query_includes)
|
|
240
|
-
record = query_results_to_records(value)
|
|
243
|
+
record = query_results_to_records(value, with_embeddings)
|
|
241
244
|
return record
|
|
242
245
|
|
|
243
246
|
async def remove_async(self, collection_name: str, key: str) -> None:
|
|
@@ -318,7 +321,7 @@ class ChromaMemoryStore(MemoryStoreBase):
|
|
|
318
321
|
record_list = [
|
|
319
322
|
(record, distance)
|
|
320
323
|
for record, distance in zip(
|
|
321
|
-
query_results_to_records(query_results),
|
|
324
|
+
query_results_to_records(query_results, with_embeddings),
|
|
322
325
|
similarity_score,
|
|
323
326
|
)
|
|
324
327
|
]
|
|
@@ -22,7 +22,9 @@ def camel_to_snake(camel_str):
|
|
|
22
22
|
return snake_str
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
def query_results_to_records(
|
|
25
|
+
def query_results_to_records(
|
|
26
|
+
results: "QueryResult", with_embedding: bool
|
|
27
|
+
) -> List[MemoryRecord]:
|
|
26
28
|
# if results has only one record, it will be a list instead of a nested list
|
|
27
29
|
# this is to make sure that results is always a nested list
|
|
28
30
|
# {'ids': ['test_id1'], 'embeddings': [[...]], 'documents': ['sample text1'], 'metadatas': [{...}]}
|
|
@@ -34,28 +36,49 @@ def query_results_to_records(results: "QueryResult") -> List[MemoryRecord]:
|
|
|
34
36
|
except IndexError:
|
|
35
37
|
return []
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
if with_embedding:
|
|
40
|
+
memory_records = [
|
|
41
|
+
(
|
|
42
|
+
MemoryRecord(
|
|
43
|
+
is_reference=metadata["is_reference"],
|
|
44
|
+
external_source_name=metadata["external_source_name"],
|
|
45
|
+
id=metadata["id"],
|
|
46
|
+
description=metadata["description"],
|
|
47
|
+
text=document,
|
|
48
|
+
embedding=embedding,
|
|
49
|
+
additional_metadata=metadata["additional_metadata"],
|
|
50
|
+
key=id,
|
|
51
|
+
timestamp=metadata["timestamp"],
|
|
52
|
+
)
|
|
50
53
|
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
for id, document, embedding, metadata in zip(
|
|
55
|
+
results["ids"][0],
|
|
56
|
+
results["documents"][0],
|
|
57
|
+
results["embeddings"][0],
|
|
58
|
+
results["metadatas"][0],
|
|
59
|
+
)
|
|
60
|
+
]
|
|
61
|
+
else:
|
|
62
|
+
memory_records = [
|
|
63
|
+
(
|
|
64
|
+
MemoryRecord(
|
|
65
|
+
is_reference=metadata["is_reference"],
|
|
66
|
+
external_source_name=metadata["external_source_name"],
|
|
67
|
+
id=metadata["id"],
|
|
68
|
+
description=metadata["description"],
|
|
69
|
+
text=document,
|
|
70
|
+
embedding=None,
|
|
71
|
+
additional_metadata=metadata["additional_metadata"],
|
|
72
|
+
key=id,
|
|
73
|
+
timestamp=metadata["timestamp"],
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
for id, document, metadata in zip(
|
|
77
|
+
results["ids"][0],
|
|
78
|
+
results["documents"][0],
|
|
79
|
+
results["metadatas"][0],
|
|
80
|
+
)
|
|
81
|
+
]
|
|
59
82
|
return memory_records
|
|
60
83
|
|
|
61
84
|
|