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
symai/core_ext.py
CHANGED
|
@@ -3,22 +3,20 @@ import atexit
|
|
|
3
3
|
import functools
|
|
4
4
|
import logging
|
|
5
5
|
import multiprocessing as mp
|
|
6
|
-
import os
|
|
7
6
|
import pickle
|
|
8
7
|
import random
|
|
9
|
-
import sys
|
|
10
|
-
import time
|
|
11
8
|
import threading
|
|
9
|
+
import time
|
|
12
10
|
import traceback
|
|
11
|
+
from collections.abc import Callable
|
|
13
12
|
from pathlib import Path
|
|
14
|
-
from typing import Callable, List
|
|
15
13
|
|
|
16
14
|
import dill
|
|
17
15
|
from loguru import logger
|
|
18
|
-
from pathos.multiprocessing import ProcessingPool as PPool
|
|
19
16
|
|
|
20
17
|
from . import __root_dir__
|
|
21
18
|
from .functional import EngineRepository
|
|
19
|
+
from .utils import UserMessage
|
|
22
20
|
|
|
23
21
|
logging.getLogger("multiprocessing").setLevel(logging.ERROR)
|
|
24
22
|
|
|
@@ -28,6 +26,7 @@ logging.getLogger("multiprocessing").setLevel(logging.ERROR)
|
|
|
28
26
|
_pool_registry: dict[int, mp.pool.Pool] = {}
|
|
29
27
|
_pool_lock = threading.Lock()
|
|
30
28
|
|
|
29
|
+
|
|
31
30
|
def _get_pool(workers: int) -> mp.pool.Pool:
|
|
32
31
|
pool = _pool_registry.get(workers)
|
|
33
32
|
if pool is not None:
|
|
@@ -39,66 +38,67 @@ def _get_pool(workers: int) -> mp.pool.Pool:
|
|
|
39
38
|
_pool_registry[workers] = pool
|
|
40
39
|
return pool
|
|
41
40
|
|
|
41
|
+
|
|
42
42
|
@atexit.register
|
|
43
43
|
def _shutdown_pools() -> None:
|
|
44
44
|
for pool in _pool_registry.values():
|
|
45
45
|
pool.close()
|
|
46
46
|
pool.join()
|
|
47
47
|
|
|
48
|
+
|
|
48
49
|
def _run_in_process(expr, func, args, kwargs):
|
|
49
50
|
expr = dill.loads(expr)
|
|
50
51
|
func = dill.loads(func)
|
|
51
52
|
return func(expr, *args, **kwargs)
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
|
|
55
|
+
def _parallel(func: Callable, expressions: list[Callable], worker: int = mp.cpu_count() // 2):
|
|
54
56
|
pickled_exprs = [dill.dumps(expr) for expr in expressions]
|
|
55
|
-
pickled_func
|
|
57
|
+
pickled_func = dill.dumps(func)
|
|
56
58
|
pool = _get_pool(worker)
|
|
59
|
+
|
|
57
60
|
def proxy_function(*args, **kwargs):
|
|
58
61
|
return pool.starmap(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
_run_in_process, [(expr, pickled_func, args, kwargs) for expr in pickled_exprs]
|
|
63
|
+
)
|
|
64
|
+
|
|
62
65
|
return proxy_function
|
|
63
66
|
|
|
67
|
+
|
|
64
68
|
# Decorator
|
|
65
|
-
def parallel(expressions:
|
|
69
|
+
def parallel(expressions: list[Callable], worker: int = mp.cpu_count() // 2):
|
|
66
70
|
def decorator_parallel(func):
|
|
67
71
|
@functools.wraps(func)
|
|
68
72
|
def wrapper(*args, **kwargs):
|
|
69
73
|
# Run expressions in parallel
|
|
70
74
|
parallel_func = _parallel(func, expressions, worker=worker)
|
|
71
75
|
# Call the proxy function to execute in parallel and capture results
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
return parallel_func(*args, **kwargs)
|
|
77
|
+
|
|
74
78
|
return wrapper
|
|
79
|
+
|
|
75
80
|
return decorator_parallel
|
|
76
81
|
|
|
82
|
+
|
|
77
83
|
def bind(engine: str, property: str):
|
|
78
|
-
|
|
84
|
+
"""
|
|
79
85
|
Bind to an engine and retrieve one of its properties.
|
|
80
|
-
|
|
86
|
+
"""
|
|
87
|
+
|
|
81
88
|
def decorator(func):
|
|
82
89
|
@functools.wraps(func)
|
|
83
|
-
def wrapper(*
|
|
84
|
-
return EngineRepository.bind_property(
|
|
85
|
-
|
|
86
|
-
property=property
|
|
87
|
-
)
|
|
90
|
+
def wrapper(*_args, **_kwargs):
|
|
91
|
+
return EngineRepository.bind_property(engine=engine, property=property)
|
|
92
|
+
|
|
88
93
|
return wrapper
|
|
94
|
+
|
|
89
95
|
return decorator
|
|
90
96
|
|
|
91
97
|
|
|
92
98
|
def retry(
|
|
93
|
-
exceptions=Exception,
|
|
94
|
-
tries=-1,
|
|
95
|
-
delay=0,
|
|
96
|
-
max_delay=-1,
|
|
97
|
-
backoff=1,
|
|
98
|
-
jitter=0,
|
|
99
|
-
graceful=False
|
|
99
|
+
exceptions=Exception, tries=-1, delay=0, max_delay=-1, backoff=1, jitter=0, graceful=False
|
|
100
100
|
):
|
|
101
|
-
|
|
101
|
+
"""
|
|
102
102
|
Returns a retry decorator for both async and sync functions.
|
|
103
103
|
|
|
104
104
|
:param exceptions: an exception or a tuple of exceptions to catch. default: Exception.
|
|
@@ -111,9 +111,11 @@ def retry(
|
|
|
111
111
|
:param graceful: whether to raise an exception if all attempts fail or return with None. default: False.
|
|
112
112
|
|
|
113
113
|
Credits to invlpg (https://pypi.org/project/retry)
|
|
114
|
-
|
|
114
|
+
"""
|
|
115
|
+
|
|
115
116
|
def decorator(func):
|
|
116
117
|
if asyncio.iscoroutinefunction(func):
|
|
118
|
+
|
|
117
119
|
@functools.wraps(func)
|
|
118
120
|
async def async_wrapper(*args, **kwargs):
|
|
119
121
|
return await _aretry_func(
|
|
@@ -124,23 +126,26 @@ def retry(
|
|
|
124
126
|
max_delay=max_delay,
|
|
125
127
|
backoff=backoff,
|
|
126
128
|
jitter=jitter,
|
|
127
|
-
graceful=graceful
|
|
129
|
+
graceful=graceful,
|
|
128
130
|
)
|
|
131
|
+
|
|
129
132
|
return async_wrapper
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
133
|
+
|
|
134
|
+
@functools.wraps(func)
|
|
135
|
+
def sync_wrapper(*args, **kwargs):
|
|
136
|
+
return _retry_func(
|
|
137
|
+
functools.partial(func, *args, **kwargs),
|
|
138
|
+
exceptions=exceptions,
|
|
139
|
+
tries=tries,
|
|
140
|
+
delay=delay,
|
|
141
|
+
max_delay=max_delay,
|
|
142
|
+
backoff=backoff,
|
|
143
|
+
jitter=jitter,
|
|
144
|
+
graceful=graceful,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return sync_wrapper
|
|
148
|
+
|
|
144
149
|
return decorator
|
|
145
150
|
|
|
146
151
|
|
|
@@ -152,13 +157,13 @@ def _retry_func(
|
|
|
152
157
|
max_delay: int,
|
|
153
158
|
backoff: int,
|
|
154
159
|
jitter: int,
|
|
155
|
-
graceful: bool
|
|
160
|
+
graceful: bool,
|
|
156
161
|
):
|
|
157
162
|
_tries, _delay = tries, delay
|
|
158
163
|
while _tries:
|
|
159
164
|
try:
|
|
160
165
|
return func()
|
|
161
|
-
except exceptions
|
|
166
|
+
except exceptions:
|
|
162
167
|
_tries -= 1
|
|
163
168
|
if not _tries:
|
|
164
169
|
if graceful:
|
|
@@ -175,6 +180,7 @@ def _retry_func(
|
|
|
175
180
|
|
|
176
181
|
if max_delay >= 0:
|
|
177
182
|
_delay = min(_delay, max_delay)
|
|
183
|
+
return None
|
|
178
184
|
|
|
179
185
|
|
|
180
186
|
async def _aretry_func(
|
|
@@ -185,13 +191,13 @@ async def _aretry_func(
|
|
|
185
191
|
max_delay: int,
|
|
186
192
|
backoff: int,
|
|
187
193
|
jitter: int,
|
|
188
|
-
graceful: bool
|
|
194
|
+
graceful: bool,
|
|
189
195
|
):
|
|
190
196
|
_tries, _delay = tries, delay
|
|
191
197
|
while _tries:
|
|
192
198
|
try:
|
|
193
199
|
return await func()
|
|
194
|
-
except exceptions
|
|
200
|
+
except exceptions:
|
|
195
201
|
_tries -= 1
|
|
196
202
|
if not _tries:
|
|
197
203
|
if graceful:
|
|
@@ -208,54 +214,45 @@ async def _aretry_func(
|
|
|
208
214
|
|
|
209
215
|
if max_delay >= 0:
|
|
210
216
|
_delay = min(_delay, max_delay)
|
|
217
|
+
return None
|
|
211
218
|
|
|
212
219
|
|
|
213
|
-
def cache(
|
|
214
|
-
|
|
215
|
-
cache_path: str = __root_dir__ / 'cache'
|
|
216
|
-
):
|
|
217
|
-
'''
|
|
220
|
+
def cache(in_memory: bool, cache_path: str = __root_dir__ / "cache"):
|
|
221
|
+
"""
|
|
218
222
|
Cache the result of a *any* function call. This is very useful in cost optimization (e.g. computing embeddings).
|
|
219
|
-
|
|
223
|
+
"""
|
|
224
|
+
|
|
220
225
|
def decorator(func):
|
|
221
226
|
@functools.wraps(func)
|
|
222
227
|
def wrapper(instance):
|
|
223
|
-
return _cache_registry_func(
|
|
224
|
-
in_memory,
|
|
225
|
-
cache_path,
|
|
226
|
-
func,
|
|
227
|
-
instance
|
|
228
|
-
)
|
|
229
|
-
return wrapper
|
|
230
|
-
return decorator
|
|
228
|
+
return _cache_registry_func(in_memory, cache_path, func, instance)
|
|
231
229
|
|
|
230
|
+
return wrapper
|
|
232
231
|
|
|
233
|
-
|
|
234
|
-
in_memory: bool,
|
|
235
|
-
cache_path: str,
|
|
236
|
-
func: Callable,
|
|
237
|
-
*args, **kwargs
|
|
238
|
-
):
|
|
232
|
+
return decorator
|
|
239
233
|
|
|
240
|
-
if not os.path.exists(cache_path): os.makedirs(cache_path)
|
|
241
234
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
235
|
+
def _cache_registry_func(in_memory: bool, cache_path: str, func: Callable, *args, **kwargs):
|
|
236
|
+
cache_dir = Path(cache_path)
|
|
237
|
+
cache_dir.mkdir(parents=True, exist_ok=True)
|
|
238
|
+
cache_file = cache_dir / func.__qualname__
|
|
245
239
|
|
|
246
|
-
|
|
240
|
+
if in_memory and cache_file.exists():
|
|
241
|
+
with cache_file.open("rb") as f:
|
|
242
|
+
return pickle.load(f)
|
|
247
243
|
|
|
248
244
|
call = func(*args, **kwargs)
|
|
249
|
-
with open(
|
|
250
|
-
pickle.dump(call
|
|
245
|
+
with cache_file.open("wb") as f:
|
|
246
|
+
pickle.dump(call, f)
|
|
251
247
|
|
|
252
248
|
return call
|
|
253
249
|
|
|
254
250
|
|
|
255
251
|
def error_logging(debug: bool = False):
|
|
256
|
-
|
|
252
|
+
"""
|
|
257
253
|
Log the error of a function call.
|
|
258
|
-
|
|
254
|
+
"""
|
|
255
|
+
|
|
259
256
|
def dec(func):
|
|
260
257
|
@functools.wraps(func)
|
|
261
258
|
def _dec(*args, **kwargs):
|
|
@@ -265,11 +262,13 @@ def error_logging(debug: bool = False):
|
|
|
265
262
|
logger.error(e)
|
|
266
263
|
if debug:
|
|
267
264
|
# Simple message:
|
|
268
|
-
|
|
265
|
+
UserMessage(f"Function: {func.__name__} call failed. Error: {e}")
|
|
269
266
|
# print traceback
|
|
270
267
|
traceback.print_exc()
|
|
271
268
|
raise e
|
|
269
|
+
|
|
272
270
|
return _dec
|
|
271
|
+
|
|
273
272
|
return dec
|
|
274
273
|
|
|
275
274
|
|
|
@@ -291,18 +290,21 @@ def deprecated(reason: str = ""):
|
|
|
291
290
|
@deprecated("Use new_method() instead")
|
|
292
291
|
def old_method(self): pass
|
|
293
292
|
"""
|
|
293
|
+
|
|
294
294
|
def decorator(obj):
|
|
295
295
|
if isinstance(obj, type):
|
|
296
296
|
# If obj is a class
|
|
297
297
|
original_init = obj.__init__
|
|
298
|
+
|
|
298
299
|
@functools.wraps(original_init)
|
|
299
300
|
def new_init(self, *args, **kwargs):
|
|
300
301
|
logger.warning(
|
|
301
302
|
f"{obj.__name__} is deprecated and will be removed in future versions. {reason}",
|
|
302
303
|
category=DeprecationWarning,
|
|
303
|
-
stacklevel=2
|
|
304
|
+
stacklevel=2,
|
|
304
305
|
)
|
|
305
306
|
original_init(self, *args, **kwargs)
|
|
307
|
+
|
|
306
308
|
obj.__init__ = new_init
|
|
307
309
|
return obj
|
|
308
310
|
|
|
@@ -312,9 +314,10 @@ def deprecated(reason: str = ""):
|
|
|
312
314
|
logger.warning(
|
|
313
315
|
f"{obj.__name__} is deprecated and will be removed in future versions. {reason}",
|
|
314
316
|
category=DeprecationWarning,
|
|
315
|
-
stacklevel=2
|
|
317
|
+
stacklevel=2,
|
|
316
318
|
)
|
|
317
319
|
return obj(*args, **kwargs)
|
|
320
|
+
|
|
318
321
|
return wrapper
|
|
319
322
|
|
|
320
323
|
return decorator
|