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.
Files changed (134) hide show
  1. symai/__init__.py +269 -173
  2. symai/backend/base.py +123 -110
  3. symai/backend/engines/drawing/engine_bfl.py +45 -44
  4. symai/backend/engines/drawing/engine_gpt_image.py +112 -97
  5. symai/backend/engines/embedding/engine_llama_cpp.py +63 -52
  6. symai/backend/engines/embedding/engine_openai.py +25 -21
  7. symai/backend/engines/execute/engine_python.py +19 -18
  8. symai/backend/engines/files/engine_io.py +104 -95
  9. symai/backend/engines/imagecaptioning/engine_blip2.py +28 -24
  10. symai/backend/engines/imagecaptioning/engine_llavacpp_client.py +102 -79
  11. symai/backend/engines/index/engine_pinecone.py +124 -97
  12. symai/backend/engines/index/engine_qdrant.py +1011 -0
  13. symai/backend/engines/index/engine_vectordb.py +84 -56
  14. symai/backend/engines/lean/engine_lean4.py +96 -52
  15. symai/backend/engines/neurosymbolic/__init__.py +41 -13
  16. symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py +330 -248
  17. symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py +329 -264
  18. symai/backend/engines/neurosymbolic/engine_cerebras.py +328 -0
  19. symai/backend/engines/neurosymbolic/engine_deepseekX_reasoning.py +118 -88
  20. symai/backend/engines/neurosymbolic/engine_google_geminiX_reasoning.py +344 -299
  21. symai/backend/engines/neurosymbolic/engine_groq.py +173 -115
  22. symai/backend/engines/neurosymbolic/engine_huggingface.py +114 -84
  23. symai/backend/engines/neurosymbolic/engine_llama_cpp.py +144 -118
  24. symai/backend/engines/neurosymbolic/engine_openai_gptX_chat.py +415 -307
  25. symai/backend/engines/neurosymbolic/engine_openai_gptX_reasoning.py +394 -231
  26. symai/backend/engines/ocr/engine_apilayer.py +23 -27
  27. symai/backend/engines/output/engine_stdout.py +10 -13
  28. symai/backend/engines/{webscraping → scrape}/engine_requests.py +101 -54
  29. symai/backend/engines/search/engine_openai.py +100 -88
  30. symai/backend/engines/search/engine_parallel.py +665 -0
  31. symai/backend/engines/search/engine_perplexity.py +44 -45
  32. symai/backend/engines/search/engine_serpapi.py +37 -34
  33. symai/backend/engines/speech_to_text/engine_local_whisper.py +54 -51
  34. symai/backend/engines/symbolic/engine_wolframalpha.py +15 -9
  35. symai/backend/engines/text_to_speech/engine_openai.py +20 -26
  36. symai/backend/engines/text_vision/engine_clip.py +39 -37
  37. symai/backend/engines/userinput/engine_console.py +5 -6
  38. symai/backend/mixin/__init__.py +13 -0
  39. symai/backend/mixin/anthropic.py +48 -38
  40. symai/backend/mixin/deepseek.py +6 -5
  41. symai/backend/mixin/google.py +7 -4
  42. symai/backend/mixin/groq.py +2 -4
  43. symai/backend/mixin/openai.py +140 -110
  44. symai/backend/settings.py +87 -20
  45. symai/chat.py +216 -123
  46. symai/collect/__init__.py +7 -1
  47. symai/collect/dynamic.py +80 -70
  48. symai/collect/pipeline.py +67 -51
  49. symai/collect/stats.py +161 -109
  50. symai/components.py +707 -360
  51. symai/constraints.py +24 -12
  52. symai/core.py +1857 -1233
  53. symai/core_ext.py +83 -80
  54. symai/endpoints/api.py +166 -104
  55. symai/extended/.DS_Store +0 -0
  56. symai/extended/__init__.py +46 -12
  57. symai/extended/api_builder.py +29 -21
  58. symai/extended/arxiv_pdf_parser.py +23 -14
  59. symai/extended/bibtex_parser.py +9 -6
  60. symai/extended/conversation.py +156 -126
  61. symai/extended/document.py +50 -30
  62. symai/extended/file_merger.py +57 -14
  63. symai/extended/graph.py +51 -32
  64. symai/extended/html_style_template.py +18 -14
  65. symai/extended/interfaces/blip_2.py +2 -3
  66. symai/extended/interfaces/clip.py +4 -3
  67. symai/extended/interfaces/console.py +9 -1
  68. symai/extended/interfaces/dall_e.py +4 -2
  69. symai/extended/interfaces/file.py +2 -0
  70. symai/extended/interfaces/flux.py +4 -2
  71. symai/extended/interfaces/gpt_image.py +16 -7
  72. symai/extended/interfaces/input.py +2 -1
  73. symai/extended/interfaces/llava.py +1 -2
  74. symai/extended/interfaces/{naive_webscraping.py → naive_scrape.py} +4 -3
  75. symai/extended/interfaces/naive_vectordb.py +9 -10
  76. symai/extended/interfaces/ocr.py +5 -3
  77. symai/extended/interfaces/openai_search.py +2 -0
  78. symai/extended/interfaces/parallel.py +30 -0
  79. symai/extended/interfaces/perplexity.py +2 -0
  80. symai/extended/interfaces/pinecone.py +12 -9
  81. symai/extended/interfaces/python.py +2 -0
  82. symai/extended/interfaces/serpapi.py +3 -1
  83. symai/extended/interfaces/terminal.py +2 -4
  84. symai/extended/interfaces/tts.py +3 -2
  85. symai/extended/interfaces/whisper.py +3 -2
  86. symai/extended/interfaces/wolframalpha.py +2 -1
  87. symai/extended/metrics/__init__.py +11 -1
  88. symai/extended/metrics/similarity.py +14 -13
  89. symai/extended/os_command.py +39 -29
  90. symai/extended/packages/__init__.py +29 -3
  91. symai/extended/packages/symdev.py +51 -43
  92. symai/extended/packages/sympkg.py +41 -35
  93. symai/extended/packages/symrun.py +63 -50
  94. symai/extended/repo_cloner.py +14 -12
  95. symai/extended/seo_query_optimizer.py +15 -13
  96. symai/extended/solver.py +116 -91
  97. symai/extended/summarizer.py +12 -10
  98. symai/extended/taypan_interpreter.py +17 -18
  99. symai/extended/vectordb.py +122 -92
  100. symai/formatter/__init__.py +9 -1
  101. symai/formatter/formatter.py +51 -47
  102. symai/formatter/regex.py +70 -69
  103. symai/functional.py +325 -176
  104. symai/imports.py +190 -147
  105. symai/interfaces.py +57 -28
  106. symai/memory.py +45 -35
  107. symai/menu/screen.py +28 -19
  108. symai/misc/console.py +66 -56
  109. symai/misc/loader.py +8 -5
  110. symai/models/__init__.py +17 -1
  111. symai/models/base.py +395 -236
  112. symai/models/errors.py +1 -2
  113. symai/ops/__init__.py +32 -22
  114. symai/ops/measures.py +24 -25
  115. symai/ops/primitives.py +1149 -731
  116. symai/post_processors.py +58 -50
  117. symai/pre_processors.py +86 -82
  118. symai/processor.py +21 -13
  119. symai/prompts.py +764 -685
  120. symai/server/huggingface_server.py +135 -49
  121. symai/server/llama_cpp_server.py +21 -11
  122. symai/server/qdrant_server.py +206 -0
  123. symai/shell.py +100 -42
  124. symai/shellsv.py +700 -492
  125. symai/strategy.py +630 -346
  126. symai/symbol.py +368 -322
  127. symai/utils.py +100 -78
  128. {symbolicai-0.21.0.dist-info → symbolicai-1.1.0.dist-info}/METADATA +22 -10
  129. symbolicai-1.1.0.dist-info/RECORD +168 -0
  130. symbolicai-0.21.0.dist-info/RECORD +0 -162
  131. {symbolicai-0.21.0.dist-info → symbolicai-1.1.0.dist-info}/WHEEL +0 -0
  132. {symbolicai-0.21.0.dist-info → symbolicai-1.1.0.dist-info}/entry_points.txt +0 -0
  133. {symbolicai-0.21.0.dist-info → symbolicai-1.1.0.dist-info}/licenses/LICENSE +0 -0
  134. {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 = ['Sorry, failed to interact with index. Please check index name and try again later:', str(e)]
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 = {'matches': [{'metadata': {'text': '\n'.join(message)}}]}
43
- return [v['metadata']['text'] for v in res['matches']]
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
- match = match.strip()
51
- if match.startswith('# ----[FILE_START]') and '# ----[FILE_END]' in match:
52
- m = match.split('[FILE_CONTENT]:')[-1].strip()
53
- splits = m.split('# ----[FILE_END]')
54
- assert len(splits) >= 2, 'Invalid file format: {}'.format(splits)
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 = ','.join(splits[1:]) # TODO: check why there are multiple file names
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, match
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
- content = '\n'.join([' ' + line for line in content.split('\n')])
66
- str_view += f'* {filename}\n{content}\n\n'
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
- {'-=-' * 13}
71
+ {"-=-" * 13}
70
72
 
71
73
  Query: {self._query}
72
74
 
73
- {'-=-' * 13}
75
+ {"-=-" * 13}
74
76
 
75
77
  Matches:
76
78
 
77
79
  {str_view}
78
- {'-=-' * 13}
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'<ul>{doc_str}</ul>'
88
+ return f"<ul>{doc_str}</ul>"
87
89
 
88
90
 
89
91
  class PineconeIndexEngine(Engine):
90
- _default_api_key = SYMAI_CONFIG['INDEXING_ENGINE_API_KEY']
91
- _default_environment = SYMAI_CONFIG['INDEXING_ENGINE_ENVIRONMENT']
92
- _default_index_name = 'dataindex'
93
- _default_index_dims = 1536
94
- _default_index_top_k = 5
95
- _default_index_metric = 'cosine'
96
- _default_index_values = True
97
- _default_index_metadata = True
98
- _default_retry_tries = 20
99
- _default_retry_delay = 0.5
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 = 1
102
- _default_retry_jitter = 0
103
+ _default_retry_backoff = 1
104
+ _default_retry_jitter = 0
103
105
 
104
106
  def __init__(
105
- self,
106
- api_key=_default_api_key,
107
- environment=_default_environment,
108
- index_name=_default_index_name,
109
- index_dims=_default_index_dims,
110
- index_top_k=_default_index_top_k,
111
- index_metric=_default_index_metric,
112
- index_values=_default_index_values,
113
- index_metadata=_default_index_metadata,
114
- tries=_default_retry_tries,
115
- delay=_default_retry_delay,
116
- max_delay=_default_retry_max_delay,
117
- backoff=_default_retry_backoff,
118
- jitter=_default_retry_jitter,
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['INDEXING_ENGINE_API_KEY']:
141
+ if SYMAI_CONFIG["INDEXING_ENGINE_API_KEY"]:
140
142
  if Pinecone is None:
141
- print('Pinecone is not installed. Please install it with `pip install symbolicai[pinecone]`.')
142
- return 'index'
143
- return super().id() # default to unregistered
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 'INDEXING_ENGINE_API_KEY' in kwargs:
148
- self.api_key = kwargs['INDEXING_ENGINE_API_KEY']
149
- if 'INDEXING_ENGINE_ENVIRONMENT' in kwargs:
150
- self.environment = kwargs['INDEXING_ENGINE_ENVIRONMENT']
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['index_name'] if 'index_name' in kwargs else self.index_name
157
+ index_name = kwargs.get("index_name", self.index_name)
154
158
 
155
- del_ = kwargs['index_del'] if 'index_del' in kwargs else False
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['index_get'] if 'index_get' in kwargs else False
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, 'Please set the API key for Pinecone indexing engine.'
165
- assert self.environment, 'Please set the environment for Pinecone indexing engine.'
166
- assert self.index_name, 'Please set the index name for Pinecone indexing engine.'
167
-
168
- kwargs = argument.kwargs
169
- embedding = argument.prop.prepared_input
170
- query = argument.prop.ori_query
171
- operation = argument.prop.operation
172
- index_name = argument.prop.index_name if argument.prop.index_name else self.index_name
173
- index_dims = argument.prop.index_dims if argument.prop.index_dims else self.index_dims
174
- rsp = None
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(index_name=index_name, index_dims=index_dims, index_metric=self.index_metric)
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, 'Please set a valid index name for Pinecone indexing engine.'
186
+ assert index_name, "Please set a valid index name for Pinecone indexing engine."
181
187
  # switch index
182
- self.index_name = index_name
183
- kwargs['index_get'] = True
188
+ self.index_name = index_name
189
+ kwargs["index_get"] = True
184
190
  self._configure_index(**kwargs)
185
191
 
186
- if operation == 'search':
187
- index_top_k = kwargs['index_top_k'] if 'index_top_k' in kwargs else self.index_top_k
188
- index_values = kwargs['index_values'] if 'index_values' in kwargs else self.index_values
189
- index_metadata = kwargs['index_metadata'] if 'index_metadata' in kwargs else self.index_metadata
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 == 'add':
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 == 'config':
202
+ elif operation == "config":
197
203
  self._configure_index(**kwargs)
198
204
 
199
205
  else:
200
- raise ValueError('Invalid operation')
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, 'Pinecone indexing engine does not support 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(name=index_name, dimension=index_dims, metric=index_metric, spec=ServerlessSpec(
216
- cloud='aws',
217
- region=self.environment
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(tries=self.tries, delay=self.delay, max_delay=self.max_delay, backoff=self.backoff, jitter=self.jitter)
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(tries=self.tries, delay=self.delay, max_delay=self.max_delay, backoff=self.backoff, jitter=self.jitter)
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(vector=query, top_k=index_top_k, include_values=index_values, include_metadata=index_metadata)
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()