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