symbolicai 0.21.0__py3-none-any.whl → 1.1.0__py3-none-any.whl
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.
- symai/__init__.py +269 -173
- symai/backend/base.py +123 -110
- symai/backend/engines/drawing/engine_bfl.py +45 -44
- symai/backend/engines/drawing/engine_gpt_image.py +112 -97
- symai/backend/engines/embedding/engine_llama_cpp.py +63 -52
- symai/backend/engines/embedding/engine_openai.py +25 -21
- symai/backend/engines/execute/engine_python.py +19 -18
- symai/backend/engines/files/engine_io.py +104 -95
- symai/backend/engines/imagecaptioning/engine_blip2.py +28 -24
- symai/backend/engines/imagecaptioning/engine_llavacpp_client.py +102 -79
- symai/backend/engines/index/engine_pinecone.py +124 -97
- symai/backend/engines/index/engine_qdrant.py +1011 -0
- symai/backend/engines/index/engine_vectordb.py +84 -56
- symai/backend/engines/lean/engine_lean4.py +96 -52
- symai/backend/engines/neurosymbolic/__init__.py +41 -13
- symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py +330 -248
- symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py +329 -264
- symai/backend/engines/neurosymbolic/engine_cerebras.py +328 -0
- symai/backend/engines/neurosymbolic/engine_deepseekX_reasoning.py +118 -88
- symai/backend/engines/neurosymbolic/engine_google_geminiX_reasoning.py +344 -299
- symai/backend/engines/neurosymbolic/engine_groq.py +173 -115
- symai/backend/engines/neurosymbolic/engine_huggingface.py +114 -84
- symai/backend/engines/neurosymbolic/engine_llama_cpp.py +144 -118
- symai/backend/engines/neurosymbolic/engine_openai_gptX_chat.py +415 -307
- symai/backend/engines/neurosymbolic/engine_openai_gptX_reasoning.py +394 -231
- symai/backend/engines/ocr/engine_apilayer.py +23 -27
- symai/backend/engines/output/engine_stdout.py +10 -13
- symai/backend/engines/{webscraping → scrape}/engine_requests.py +101 -54
- symai/backend/engines/search/engine_openai.py +100 -88
- symai/backend/engines/search/engine_parallel.py +665 -0
- symai/backend/engines/search/engine_perplexity.py +44 -45
- symai/backend/engines/search/engine_serpapi.py +37 -34
- symai/backend/engines/speech_to_text/engine_local_whisper.py +54 -51
- symai/backend/engines/symbolic/engine_wolframalpha.py +15 -9
- symai/backend/engines/text_to_speech/engine_openai.py +20 -26
- symai/backend/engines/text_vision/engine_clip.py +39 -37
- symai/backend/engines/userinput/engine_console.py +5 -6
- symai/backend/mixin/__init__.py +13 -0
- symai/backend/mixin/anthropic.py +48 -38
- symai/backend/mixin/deepseek.py +6 -5
- symai/backend/mixin/google.py +7 -4
- symai/backend/mixin/groq.py +2 -4
- symai/backend/mixin/openai.py +140 -110
- symai/backend/settings.py +87 -20
- symai/chat.py +216 -123
- symai/collect/__init__.py +7 -1
- symai/collect/dynamic.py +80 -70
- symai/collect/pipeline.py +67 -51
- symai/collect/stats.py +161 -109
- symai/components.py +707 -360
- symai/constraints.py +24 -12
- symai/core.py +1857 -1233
- symai/core_ext.py +83 -80
- symai/endpoints/api.py +166 -104
- symai/extended/.DS_Store +0 -0
- symai/extended/__init__.py +46 -12
- symai/extended/api_builder.py +29 -21
- symai/extended/arxiv_pdf_parser.py +23 -14
- symai/extended/bibtex_parser.py +9 -6
- symai/extended/conversation.py +156 -126
- symai/extended/document.py +50 -30
- symai/extended/file_merger.py +57 -14
- symai/extended/graph.py +51 -32
- symai/extended/html_style_template.py +18 -14
- symai/extended/interfaces/blip_2.py +2 -3
- symai/extended/interfaces/clip.py +4 -3
- symai/extended/interfaces/console.py +9 -1
- symai/extended/interfaces/dall_e.py +4 -2
- symai/extended/interfaces/file.py +2 -0
- symai/extended/interfaces/flux.py +4 -2
- symai/extended/interfaces/gpt_image.py +16 -7
- symai/extended/interfaces/input.py +2 -1
- symai/extended/interfaces/llava.py +1 -2
- symai/extended/interfaces/{naive_webscraping.py → naive_scrape.py} +4 -3
- symai/extended/interfaces/naive_vectordb.py +9 -10
- symai/extended/interfaces/ocr.py +5 -3
- symai/extended/interfaces/openai_search.py +2 -0
- symai/extended/interfaces/parallel.py +30 -0
- symai/extended/interfaces/perplexity.py +2 -0
- symai/extended/interfaces/pinecone.py +12 -9
- symai/extended/interfaces/python.py +2 -0
- symai/extended/interfaces/serpapi.py +3 -1
- symai/extended/interfaces/terminal.py +2 -4
- symai/extended/interfaces/tts.py +3 -2
- symai/extended/interfaces/whisper.py +3 -2
- symai/extended/interfaces/wolframalpha.py +2 -1
- symai/extended/metrics/__init__.py +11 -1
- symai/extended/metrics/similarity.py +14 -13
- symai/extended/os_command.py +39 -29
- symai/extended/packages/__init__.py +29 -3
- symai/extended/packages/symdev.py +51 -43
- symai/extended/packages/sympkg.py +41 -35
- symai/extended/packages/symrun.py +63 -50
- symai/extended/repo_cloner.py +14 -12
- symai/extended/seo_query_optimizer.py +15 -13
- symai/extended/solver.py +116 -91
- symai/extended/summarizer.py +12 -10
- symai/extended/taypan_interpreter.py +17 -18
- symai/extended/vectordb.py +122 -92
- symai/formatter/__init__.py +9 -1
- symai/formatter/formatter.py +51 -47
- symai/formatter/regex.py +70 -69
- symai/functional.py +325 -176
- symai/imports.py +190 -147
- symai/interfaces.py +57 -28
- symai/memory.py +45 -35
- symai/menu/screen.py +28 -19
- symai/misc/console.py +66 -56
- symai/misc/loader.py +8 -5
- symai/models/__init__.py +17 -1
- symai/models/base.py +395 -236
- symai/models/errors.py +1 -2
- symai/ops/__init__.py +32 -22
- symai/ops/measures.py +24 -25
- symai/ops/primitives.py +1149 -731
- symai/post_processors.py +58 -50
- symai/pre_processors.py +86 -82
- symai/processor.py +21 -13
- symai/prompts.py +764 -685
- symai/server/huggingface_server.py +135 -49
- symai/server/llama_cpp_server.py +21 -11
- symai/server/qdrant_server.py +206 -0
- symai/shell.py +100 -42
- symai/shellsv.py +700 -492
- symai/strategy.py +630 -346
- symai/symbol.py +368 -322
- symai/utils.py +100 -78
- {symbolicai-0.21.0.dist-info → symbolicai-1.1.0.dist-info}/METADATA +22 -10
- symbolicai-1.1.0.dist-info/RECORD +168 -0
- symbolicai-0.21.0.dist-info/RECORD +0 -162
- {symbolicai-0.21.0.dist-info → symbolicai-1.1.0.dist-info}/WHEEL +0 -0
- {symbolicai-0.21.0.dist-info → symbolicai-1.1.0.dist-info}/entry_points.txt +0 -0
- {symbolicai-0.21.0.dist-info → symbolicai-1.1.0.dist-info}/licenses/LICENSE +0 -0
- {symbolicai-0.21.0.dist-info → symbolicai-1.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,17 +1,16 @@
|
|
|
1
|
+
import contextlib
|
|
1
2
|
import itertools
|
|
2
3
|
import warnings
|
|
3
|
-
import numpy as np
|
|
4
4
|
|
|
5
|
-
warnings.filterwarnings('ignore', module='pinecone')
|
|
6
|
-
try:
|
|
7
|
-
from pinecone import Pinecone, ServerlessSpec
|
|
8
|
-
except:
|
|
9
|
-
pass
|
|
10
|
-
|
|
11
|
-
from ...base import Engine
|
|
12
|
-
from ...settings import SYMAI_CONFIG
|
|
13
5
|
from .... import core_ext
|
|
14
6
|
from ....symbol import Result
|
|
7
|
+
from ....utils import UserMessage
|
|
8
|
+
from ...base import Engine
|
|
9
|
+
from ...settings import SYMAI_CONFIG
|
|
10
|
+
|
|
11
|
+
warnings.filterwarnings("ignore", module="pinecone")
|
|
12
|
+
with contextlib.suppress(BaseException):
|
|
13
|
+
from pinecone import Pinecone, ServerlessSpec
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
def chunks(iterable, batch_size=100):
|
|
@@ -37,86 +36,89 @@ class PineconeResult(Result):
|
|
|
37
36
|
try:
|
|
38
37
|
res = self._to_symbol(res).ast()
|
|
39
38
|
except Exception as e:
|
|
40
|
-
message = [
|
|
39
|
+
message = [
|
|
40
|
+
"Sorry, failed to interact with index. Please check index name and try again later:",
|
|
41
|
+
str(e),
|
|
42
|
+
]
|
|
41
43
|
# package the message for the IndexResult class
|
|
42
|
-
res = {
|
|
43
|
-
return [v[
|
|
44
|
+
res = {"matches": [{"metadata": {"text": "\n".join(message)}}]}
|
|
45
|
+
return [v["metadata"]["text"] for v in res["matches"]]
|
|
44
46
|
|
|
45
47
|
def _unpack_matches(self):
|
|
46
48
|
if not self.value:
|
|
47
49
|
return
|
|
48
50
|
|
|
49
51
|
for i, match in enumerate(self.value):
|
|
50
|
-
|
|
51
|
-
if
|
|
52
|
-
m =
|
|
53
|
-
splits = m.split(
|
|
54
|
-
assert len(splits) >= 2,
|
|
52
|
+
match_value = match.strip()
|
|
53
|
+
if match_value.startswith("# ----[FILE_START]") and "# ----[FILE_END]" in match_value:
|
|
54
|
+
m = match_value.split("[FILE_CONTENT]:")[-1].strip()
|
|
55
|
+
splits = m.split("# ----[FILE_END]")
|
|
56
|
+
assert len(splits) >= 2, f"Invalid file format: {splits}"
|
|
55
57
|
content = splits[0]
|
|
56
|
-
file_name =
|
|
58
|
+
file_name = ",".join(splits[1:]) # TODO: check why there are multiple file names
|
|
57
59
|
yield file_name.strip(), content.strip()
|
|
58
60
|
else:
|
|
59
|
-
yield i+1,
|
|
61
|
+
yield i + 1, match_value
|
|
60
62
|
|
|
61
63
|
def __str__(self):
|
|
62
|
-
str_view =
|
|
64
|
+
str_view = ""
|
|
63
65
|
for filename, content in self._unpack_matches():
|
|
64
66
|
# indent each line of the content
|
|
65
|
-
|
|
66
|
-
str_view += f
|
|
67
|
-
return f
|
|
67
|
+
content_view = "\n".join([" " + line for line in content.split("\n")])
|
|
68
|
+
str_view += f"* {filename}\n{content_view}\n\n"
|
|
69
|
+
return f"""
|
|
68
70
|
[RESULT]
|
|
69
|
-
{
|
|
71
|
+
{"-=-" * 13}
|
|
70
72
|
|
|
71
73
|
Query: {self._query}
|
|
72
74
|
|
|
73
|
-
{
|
|
75
|
+
{"-=-" * 13}
|
|
74
76
|
|
|
75
77
|
Matches:
|
|
76
78
|
|
|
77
79
|
{str_view}
|
|
78
|
-
{
|
|
79
|
-
|
|
80
|
+
{"-=-" * 13}
|
|
81
|
+
"""
|
|
80
82
|
|
|
81
83
|
def _repr_html_(self) -> str:
|
|
82
84
|
# return a nicely styled HTML list results based on retrieved documents
|
|
83
|
-
doc_str =
|
|
85
|
+
doc_str = ""
|
|
84
86
|
for filename, content in self._unpack_matches():
|
|
85
87
|
doc_str += f'<li><a href="{filename}"><b>{filename}</a></b><br>{content}</li>\n'
|
|
86
|
-
return f
|
|
88
|
+
return f"<ul>{doc_str}</ul>"
|
|
87
89
|
|
|
88
90
|
|
|
89
91
|
class PineconeIndexEngine(Engine):
|
|
90
|
-
_default_api_key
|
|
91
|
-
_default_environment
|
|
92
|
-
_default_index_name
|
|
93
|
-
_default_index_dims
|
|
94
|
-
_default_index_top_k
|
|
95
|
-
_default_index_metric
|
|
96
|
-
_default_index_values
|
|
97
|
-
_default_index_metadata
|
|
98
|
-
_default_retry_tries
|
|
99
|
-
_default_retry_delay
|
|
92
|
+
_default_api_key = SYMAI_CONFIG["INDEXING_ENGINE_API_KEY"]
|
|
93
|
+
_default_environment = SYMAI_CONFIG["INDEXING_ENGINE_ENVIRONMENT"]
|
|
94
|
+
_default_index_name = "dataindex"
|
|
95
|
+
_default_index_dims = 1536
|
|
96
|
+
_default_index_top_k = 5
|
|
97
|
+
_default_index_metric = "cosine"
|
|
98
|
+
_default_index_values = True
|
|
99
|
+
_default_index_metadata = True
|
|
100
|
+
_default_retry_tries = 20
|
|
101
|
+
_default_retry_delay = 0.5
|
|
100
102
|
_default_retry_max_delay = -1
|
|
101
|
-
_default_retry_backoff
|
|
102
|
-
_default_retry_jitter
|
|
103
|
+
_default_retry_backoff = 1
|
|
104
|
+
_default_retry_jitter = 0
|
|
103
105
|
|
|
104
106
|
def __init__(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
107
|
+
self,
|
|
108
|
+
api_key=_default_api_key,
|
|
109
|
+
environment=_default_environment,
|
|
110
|
+
index_name=_default_index_name,
|
|
111
|
+
index_dims=_default_index_dims,
|
|
112
|
+
index_top_k=_default_index_top_k,
|
|
113
|
+
index_metric=_default_index_metric,
|
|
114
|
+
index_values=_default_index_values,
|
|
115
|
+
index_metadata=_default_index_metadata,
|
|
116
|
+
tries=_default_retry_tries,
|
|
117
|
+
delay=_default_retry_delay,
|
|
118
|
+
max_delay=_default_retry_max_delay,
|
|
119
|
+
backoff=_default_retry_backoff,
|
|
120
|
+
jitter=_default_retry_jitter,
|
|
121
|
+
):
|
|
120
122
|
super().__init__()
|
|
121
123
|
self.index_name = index_name
|
|
122
124
|
self.index_dims = index_dims
|
|
@@ -136,68 +138,72 @@ class PineconeIndexEngine(Engine):
|
|
|
136
138
|
self.name = self.__class__.__name__
|
|
137
139
|
|
|
138
140
|
def id(self) -> str:
|
|
139
|
-
if SYMAI_CONFIG[
|
|
141
|
+
if SYMAI_CONFIG["INDEXING_ENGINE_API_KEY"]:
|
|
140
142
|
if Pinecone is None:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
UserMessage(
|
|
144
|
+
"Pinecone is not installed. Please install it with `pip install symbolicai[pinecone]`."
|
|
145
|
+
)
|
|
146
|
+
return "index"
|
|
147
|
+
return super().id() # default to unregistered
|
|
144
148
|
|
|
145
149
|
def command(self, *args, **kwargs):
|
|
146
150
|
super().command(*args, **kwargs)
|
|
147
|
-
if
|
|
148
|
-
self.api_key = kwargs[
|
|
149
|
-
if
|
|
150
|
-
self.environment = kwargs[
|
|
151
|
+
if "INDEXING_ENGINE_API_KEY" in kwargs:
|
|
152
|
+
self.api_key = kwargs["INDEXING_ENGINE_API_KEY"]
|
|
153
|
+
if "INDEXING_ENGINE_ENVIRONMENT" in kwargs:
|
|
154
|
+
self.environment = kwargs["INDEXING_ENGINE_ENVIRONMENT"]
|
|
151
155
|
|
|
152
156
|
def _configure_index(self, **kwargs):
|
|
153
|
-
index_name = kwargs
|
|
157
|
+
index_name = kwargs.get("index_name", self.index_name)
|
|
154
158
|
|
|
155
|
-
del_ = kwargs
|
|
159
|
+
del_ = kwargs.get("index_del", False)
|
|
156
160
|
if self.index is not None and del_:
|
|
157
161
|
self.pinecone.delete_index(index_name)
|
|
158
162
|
|
|
159
|
-
get_ = kwargs
|
|
163
|
+
get_ = kwargs.get("index_get", False)
|
|
160
164
|
if self.index is not None and get_:
|
|
161
165
|
self.index = self.pinecone.Index(name=index_name)
|
|
162
166
|
|
|
163
167
|
def forward(self, argument):
|
|
164
|
-
assert self.api_key,
|
|
165
|
-
assert self.environment,
|
|
166
|
-
assert self.index_name,
|
|
167
|
-
|
|
168
|
-
kwargs
|
|
169
|
-
embedding
|
|
170
|
-
query
|
|
171
|
-
operation
|
|
172
|
-
index_name
|
|
173
|
-
index_dims
|
|
174
|
-
rsp
|
|
168
|
+
assert self.api_key, "Please set the API key for Pinecone indexing engine."
|
|
169
|
+
assert self.environment, "Please set the environment for Pinecone indexing engine."
|
|
170
|
+
assert self.index_name, "Please set the index name for Pinecone indexing engine."
|
|
171
|
+
|
|
172
|
+
kwargs = argument.kwargs
|
|
173
|
+
embedding = argument.prop.prepared_input
|
|
174
|
+
query = argument.prop.ori_query
|
|
175
|
+
operation = argument.prop.operation
|
|
176
|
+
index_name = argument.prop.index_name if argument.prop.index_name else self.index_name
|
|
177
|
+
index_dims = argument.prop.index_dims if argument.prop.index_dims else self.index_dims
|
|
178
|
+
rsp = None
|
|
175
179
|
|
|
176
180
|
if self.index is None:
|
|
177
|
-
self._init_index_engine(
|
|
181
|
+
self._init_index_engine(
|
|
182
|
+
index_name=index_name, index_dims=index_dims, index_metric=self.index_metric
|
|
183
|
+
)
|
|
178
184
|
|
|
179
185
|
if index_name != self.index_name:
|
|
180
|
-
assert index_name,
|
|
186
|
+
assert index_name, "Please set a valid index name for Pinecone indexing engine."
|
|
181
187
|
# switch index
|
|
182
|
-
self.index_name
|
|
183
|
-
kwargs[
|
|
188
|
+
self.index_name = index_name
|
|
189
|
+
kwargs["index_get"] = True
|
|
184
190
|
self._configure_index(**kwargs)
|
|
185
191
|
|
|
186
|
-
if operation ==
|
|
187
|
-
index_top_k
|
|
188
|
-
index_values
|
|
189
|
-
index_metadata = kwargs
|
|
192
|
+
if operation == "search":
|
|
193
|
+
index_top_k = kwargs.get("index_top_k", self.index_top_k)
|
|
194
|
+
index_values = kwargs.get("index_values", self.index_values)
|
|
195
|
+
index_metadata = kwargs.get("index_metadata", self.index_metadata)
|
|
190
196
|
rsp = self._query(embedding, index_top_k, index_values, index_metadata)
|
|
191
197
|
|
|
192
|
-
elif operation ==
|
|
198
|
+
elif operation == "add":
|
|
193
199
|
for ids_vectors_chunk in chunks(embedding, batch_size=100):
|
|
194
200
|
self._upsert(ids_vectors_chunk)
|
|
195
201
|
|
|
196
|
-
elif operation ==
|
|
202
|
+
elif operation == "config":
|
|
197
203
|
self._configure_index(**kwargs)
|
|
198
204
|
|
|
199
205
|
else:
|
|
200
|
-
|
|
206
|
+
UserMessage("Invalid operation", raise_with=ValueError)
|
|
201
207
|
|
|
202
208
|
metadata = {}
|
|
203
209
|
|
|
@@ -205,30 +211,51 @@ class PineconeIndexEngine(Engine):
|
|
|
205
211
|
return [rsp], metadata
|
|
206
212
|
|
|
207
213
|
def prepare(self, argument):
|
|
208
|
-
assert not argument.prop.processed_input,
|
|
214
|
+
assert not argument.prop.processed_input, (
|
|
215
|
+
"Pinecone indexing engine does not support processed_input."
|
|
216
|
+
)
|
|
209
217
|
argument.prop.prepared_input = argument.prop.prompt
|
|
210
218
|
|
|
211
219
|
def _init_index_engine(self, index_name, index_dims, index_metric):
|
|
212
220
|
self.pinecone = Pinecone(api_key=self.api_key)
|
|
213
221
|
|
|
214
222
|
if index_name is not None and index_name not in str(self.pinecone.list_indexes()):
|
|
215
|
-
self.pinecone.create_index(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
223
|
+
self.pinecone.create_index(
|
|
224
|
+
name=index_name,
|
|
225
|
+
dimension=index_dims,
|
|
226
|
+
metric=index_metric,
|
|
227
|
+
spec=ServerlessSpec(cloud="aws", region=self.environment),
|
|
228
|
+
)
|
|
219
229
|
|
|
220
230
|
self.index = self.pinecone.Index(name=index_name)
|
|
221
231
|
|
|
222
232
|
def _upsert(self, vectors):
|
|
223
|
-
@core_ext.retry(
|
|
233
|
+
@core_ext.retry(
|
|
234
|
+
tries=self.tries,
|
|
235
|
+
delay=self.delay,
|
|
236
|
+
max_delay=self.max_delay,
|
|
237
|
+
backoff=self.backoff,
|
|
238
|
+
jitter=self.jitter,
|
|
239
|
+
)
|
|
224
240
|
def _func():
|
|
225
241
|
return self.index.upsert(vectors=vectors)
|
|
226
242
|
|
|
227
243
|
return _func()
|
|
228
244
|
|
|
229
245
|
def _query(self, query, index_top_k, index_values, index_metadata):
|
|
230
|
-
@core_ext.retry(
|
|
246
|
+
@core_ext.retry(
|
|
247
|
+
tries=self.tries,
|
|
248
|
+
delay=self.delay,
|
|
249
|
+
max_delay=self.max_delay,
|
|
250
|
+
backoff=self.backoff,
|
|
251
|
+
jitter=self.jitter,
|
|
252
|
+
)
|
|
231
253
|
def _func():
|
|
232
|
-
return self.index.query(
|
|
254
|
+
return self.index.query(
|
|
255
|
+
vector=query,
|
|
256
|
+
top_k=index_top_k,
|
|
257
|
+
include_values=index_values,
|
|
258
|
+
include_metadata=index_metadata,
|
|
259
|
+
)
|
|
233
260
|
|
|
234
261
|
return _func()
|