symbolicai 0.20.2__py3-none-any.whl → 1.0.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 (123) hide show
  1. symai/__init__.py +96 -64
  2. symai/backend/base.py +93 -80
  3. symai/backend/engines/drawing/engine_bfl.py +12 -11
  4. symai/backend/engines/drawing/engine_gpt_image.py +108 -87
  5. symai/backend/engines/embedding/engine_llama_cpp.py +25 -28
  6. symai/backend/engines/embedding/engine_openai.py +3 -5
  7. symai/backend/engines/execute/engine_python.py +6 -5
  8. symai/backend/engines/files/engine_io.py +74 -67
  9. symai/backend/engines/imagecaptioning/engine_blip2.py +3 -3
  10. symai/backend/engines/imagecaptioning/engine_llavacpp_client.py +54 -38
  11. symai/backend/engines/index/engine_pinecone.py +23 -24
  12. symai/backend/engines/index/engine_vectordb.py +16 -14
  13. symai/backend/engines/lean/engine_lean4.py +38 -34
  14. symai/backend/engines/neurosymbolic/__init__.py +41 -13
  15. symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_chat.py +262 -182
  16. symai/backend/engines/neurosymbolic/engine_anthropic_claudeX_reasoning.py +263 -191
  17. symai/backend/engines/neurosymbolic/engine_deepseekX_reasoning.py +53 -49
  18. symai/backend/engines/neurosymbolic/engine_google_geminiX_reasoning.py +212 -211
  19. symai/backend/engines/neurosymbolic/engine_groq.py +87 -63
  20. symai/backend/engines/neurosymbolic/engine_huggingface.py +21 -24
  21. symai/backend/engines/neurosymbolic/engine_llama_cpp.py +117 -48
  22. symai/backend/engines/neurosymbolic/engine_openai_gptX_chat.py +256 -229
  23. symai/backend/engines/neurosymbolic/engine_openai_gptX_reasoning.py +270 -150
  24. symai/backend/engines/ocr/engine_apilayer.py +6 -8
  25. symai/backend/engines/output/engine_stdout.py +1 -4
  26. symai/backend/engines/search/engine_openai.py +7 -7
  27. symai/backend/engines/search/engine_perplexity.py +5 -5
  28. symai/backend/engines/search/engine_serpapi.py +12 -14
  29. symai/backend/engines/speech_to_text/engine_local_whisper.py +20 -27
  30. symai/backend/engines/symbolic/engine_wolframalpha.py +3 -3
  31. symai/backend/engines/text_to_speech/engine_openai.py +5 -7
  32. symai/backend/engines/text_vision/engine_clip.py +7 -11
  33. symai/backend/engines/userinput/engine_console.py +3 -3
  34. symai/backend/engines/webscraping/engine_requests.py +81 -48
  35. symai/backend/mixin/__init__.py +13 -0
  36. symai/backend/mixin/anthropic.py +4 -2
  37. symai/backend/mixin/deepseek.py +2 -0
  38. symai/backend/mixin/google.py +2 -0
  39. symai/backend/mixin/openai.py +11 -3
  40. symai/backend/settings.py +83 -16
  41. symai/chat.py +101 -78
  42. symai/collect/__init__.py +7 -1
  43. symai/collect/dynamic.py +77 -69
  44. symai/collect/pipeline.py +35 -27
  45. symai/collect/stats.py +75 -63
  46. symai/components.py +198 -169
  47. symai/constraints.py +15 -12
  48. symai/core.py +698 -359
  49. symai/core_ext.py +32 -34
  50. symai/endpoints/api.py +80 -73
  51. symai/extended/.DS_Store +0 -0
  52. symai/extended/__init__.py +46 -12
  53. symai/extended/api_builder.py +11 -8
  54. symai/extended/arxiv_pdf_parser.py +13 -12
  55. symai/extended/bibtex_parser.py +2 -3
  56. symai/extended/conversation.py +101 -90
  57. symai/extended/document.py +17 -10
  58. symai/extended/file_merger.py +18 -13
  59. symai/extended/graph.py +18 -13
  60. symai/extended/html_style_template.py +2 -4
  61. symai/extended/interfaces/blip_2.py +1 -2
  62. symai/extended/interfaces/clip.py +1 -2
  63. symai/extended/interfaces/console.py +7 -1
  64. symai/extended/interfaces/dall_e.py +1 -1
  65. symai/extended/interfaces/flux.py +1 -1
  66. symai/extended/interfaces/gpt_image.py +1 -1
  67. symai/extended/interfaces/input.py +1 -1
  68. symai/extended/interfaces/llava.py +0 -1
  69. symai/extended/interfaces/naive_vectordb.py +7 -8
  70. symai/extended/interfaces/naive_webscraping.py +1 -1
  71. symai/extended/interfaces/ocr.py +1 -1
  72. symai/extended/interfaces/pinecone.py +6 -5
  73. symai/extended/interfaces/serpapi.py +1 -1
  74. symai/extended/interfaces/terminal.py +2 -3
  75. symai/extended/interfaces/tts.py +1 -1
  76. symai/extended/interfaces/whisper.py +1 -1
  77. symai/extended/interfaces/wolframalpha.py +1 -1
  78. symai/extended/metrics/__init__.py +11 -1
  79. symai/extended/metrics/similarity.py +11 -13
  80. symai/extended/os_command.py +17 -16
  81. symai/extended/packages/__init__.py +29 -3
  82. symai/extended/packages/symdev.py +19 -16
  83. symai/extended/packages/sympkg.py +12 -9
  84. symai/extended/packages/symrun.py +21 -19
  85. symai/extended/repo_cloner.py +11 -10
  86. symai/extended/seo_query_optimizer.py +1 -2
  87. symai/extended/solver.py +20 -23
  88. symai/extended/summarizer.py +4 -3
  89. symai/extended/taypan_interpreter.py +10 -12
  90. symai/extended/vectordb.py +99 -82
  91. symai/formatter/__init__.py +9 -1
  92. symai/formatter/formatter.py +12 -16
  93. symai/formatter/regex.py +62 -63
  94. symai/functional.py +176 -122
  95. symai/imports.py +136 -127
  96. symai/interfaces.py +56 -27
  97. symai/memory.py +14 -13
  98. symai/misc/console.py +49 -39
  99. symai/misc/loader.py +5 -3
  100. symai/models/__init__.py +17 -1
  101. symai/models/base.py +269 -181
  102. symai/models/errors.py +0 -1
  103. symai/ops/__init__.py +32 -22
  104. symai/ops/measures.py +11 -15
  105. symai/ops/primitives.py +348 -228
  106. symai/post_processors.py +32 -28
  107. symai/pre_processors.py +39 -41
  108. symai/processor.py +6 -4
  109. symai/prompts.py +59 -45
  110. symai/server/huggingface_server.py +23 -20
  111. symai/server/llama_cpp_server.py +7 -5
  112. symai/shell.py +3 -4
  113. symai/shellsv.py +499 -375
  114. symai/strategy.py +517 -287
  115. symai/symbol.py +111 -116
  116. symai/utils.py +42 -36
  117. {symbolicai-0.20.2.dist-info → symbolicai-1.0.0.dist-info}/METADATA +4 -2
  118. symbolicai-1.0.0.dist-info/RECORD +163 -0
  119. symbolicai-0.20.2.dist-info/RECORD +0 -162
  120. {symbolicai-0.20.2.dist-info → symbolicai-1.0.0.dist-info}/WHEEL +0 -0
  121. {symbolicai-0.20.2.dist-info → symbolicai-1.0.0.dist-info}/entry_points.txt +0 -0
  122. {symbolicai-0.20.2.dist-info → symbolicai-1.0.0.dist-info}/licenses/LICENSE +0 -0
  123. {symbolicai-0.20.2.dist-info → symbolicai-1.0.0.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,15 @@
1
- import os
2
1
  import subprocess
2
+ import tempfile
3
+ from pathlib import Path
4
+ from typing import Any
5
+
3
6
  import docker
4
7
  import paramiko
5
- import tempfile
6
- from typing import Any, List, Tuple, Optional, Dict
7
- from ...base import Engine
8
+
8
9
  from ....symbol import Result
10
+ from ....utils import UserMessage
11
+ from ...base import Engine
12
+
9
13
 
10
14
  class LeanResult(Result):
11
15
  """
@@ -14,7 +18,7 @@ class LeanResult(Result):
14
18
  Attributes:
15
19
  _value (Dict[str, str]): A dictionary containing the output of the Lean execution.
16
20
  """
17
- def __init__(self, value: Dict[str, str]) -> None:
21
+ def __init__(self, value: dict[str, str]) -> None:
18
22
  """
19
23
  Initializes a new LeanResult instance.
20
24
 
@@ -57,7 +61,7 @@ class LeanEngine(Engine):
57
61
  self.ssh_host: str = ssh_host
58
62
  self.ssh_port: int = ssh_port
59
63
  self.ssh_user: str = ssh_user
60
- self.ssh_key_path: str = os.path.expanduser(ssh_key_path)
64
+ self.ssh_key_path: Path = Path(ssh_key_path).expanduser()
61
65
  self.docker_client: docker.DockerClient = docker.from_env()
62
66
  self.container: docker.models.containers.Container = self._ensure_container()
63
67
  self.name = self.__class__.__name__
@@ -85,7 +89,7 @@ class LeanEngine(Engine):
85
89
  existing_container: docker.models.containers.Container = self.docker_client.containers.get(container_name)
86
90
  existing_container.remove(force=True)
87
91
  except docker.errors.NotFound:
88
- print(f"No existing container named '{container_name}' found. Proceeding to create a new one.")
92
+ UserMessage(f"No existing container named '{container_name}' found. Proceeding to create a new one.")
89
93
 
90
94
  dockerfile: str = """
91
95
  FROM buildpack-deps:buster
@@ -110,11 +114,11 @@ class LeanEngine(Engine):
110
114
  """
111
115
  with tempfile.NamedTemporaryFile("w", delete=False) as temp_dockerfile:
112
116
  temp_dockerfile.write(dockerfile)
113
- dockerfile_path: str = temp_dockerfile.name
117
+ dockerfile_path = Path(temp_dockerfile.name)
114
118
 
115
119
  image: docker.models.images.Image
116
- image, _ = self.docker_client.images.build(path=os.path.dirname(dockerfile_path), dockerfile=dockerfile_path, tag="lean4-container-image")
117
- os.remove(dockerfile_path)
120
+ image, _ = self.docker_client.images.build(path=str(dockerfile_path.parent), dockerfile=str(dockerfile_path), tag="lean4-container-image")
121
+ dockerfile_path.unlink()
118
122
 
119
123
  container: docker.models.containers.Container = self.docker_client.containers.run(
120
124
  image.id,
@@ -129,15 +133,16 @@ class LeanEngine(Engine):
129
133
  Sets up SSH access to the Docker container, including generating an SSH key pair if necessary,
130
134
  and configuring the container to accept SSH connections using the generated key.
131
135
  """
132
- if not os.path.exists(self.ssh_key_path):
133
- subprocess.run(['ssh-keygen', '-t', 'rsa', '-b', '2048', '-f', self.ssh_key_path, '-N', ''], check=True)
136
+ if not self.ssh_key_path.exists():
137
+ subprocess.run(['ssh-keygen', '-t', 'rsa', '-b', '2048', '-f', str(self.ssh_key_path), '-N', ''], check=True)
134
138
 
135
139
  subprocess.run(['docker', 'exec', self.container.id, 'mkdir', '-p', '/root/.ssh'], check=True)
136
- subprocess.run(['docker', 'cp', f'{self.ssh_key_path}.pub', f'{self.container.id}:/root/.ssh/authorized_keys'], check=True)
140
+ public_key_path = self.ssh_key_path.parent / f'{self.ssh_key_path.name}.pub'
141
+ subprocess.run(['docker', 'cp', str(public_key_path), f'{self.container.id}:/root/.ssh/authorized_keys'], check=True)
137
142
  subprocess.run(['docker', 'exec', self.container.id, 'chmod', '600', '/root/.ssh/authorized_keys'], check=True)
138
143
  subprocess.run(['docker', 'exec', self.container.id, 'chown', 'root:root', '/root/.ssh/authorized_keys'], check=True)
139
144
 
140
- def forward(self, argument: Any) -> Tuple[List[LeanResult], dict]:
145
+ def forward(self, argument: Any) -> tuple[list[LeanResult], dict]:
141
146
  """
142
147
  Executes Lean code provided as a string or as an object property.
143
148
 
@@ -149,14 +154,14 @@ class LeanEngine(Engine):
149
154
  """
150
155
  code: str = argument if isinstance(argument, str) else argument.prop.prepared_input
151
156
 
152
- rsp: Optional[LeanResult] = None
153
- err: Optional[str] = None
154
- tmpfile_path: Optional[str] = None
155
- metadata: Dict[str, Any] = {}
157
+ rsp: LeanResult | None = None
158
+ err: str | None = None
159
+ tmpfile_path: Path | None = None
160
+ metadata: dict[str, Any] = {}
156
161
  try:
157
162
  with tempfile.NamedTemporaryFile(delete=False, suffix=".lean") as tmpfile:
158
163
  tmpfile.write(code.encode())
159
- tmpfile_path = tmpfile.name
164
+ tmpfile_path = Path(tmpfile.name)
160
165
 
161
166
  output, exec_metadata = self._execute_lean(tmpfile_path)
162
167
  metadata.update(exec_metadata)
@@ -168,17 +173,17 @@ class LeanEngine(Engine):
168
173
  except Exception as e:
169
174
  err = str(e)
170
175
  metadata.update({'status': 'error', 'message': err})
171
- print(f"Error during Lean execution: {err}")
176
+ UserMessage(f"Error during Lean execution: {err}")
172
177
  finally:
173
- if tmpfile_path and os.path.exists(tmpfile_path):
174
- os.remove(tmpfile_path)
178
+ if tmpfile_path and tmpfile_path.exists():
179
+ tmpfile_path.unlink()
175
180
  if self.container:
176
- print(f"Killing Docker container '{self.container.id}'...")
181
+ UserMessage(f"Killing Docker container '{self.container.id}'...")
177
182
  self.container.remove(force=True)
178
183
 
179
184
  return [rsp] if rsp else [], metadata
180
185
 
181
- def _execute_lean(self, filepath: str) -> Tuple[str, dict]:
186
+ def _execute_lean(self, filepath: str) -> tuple[str, dict]:
182
187
  """
183
188
  Executes a Lean script within the Docker container via SSH.
184
189
 
@@ -191,23 +196,23 @@ class LeanEngine(Engine):
191
196
  try:
192
197
  ssh = paramiko.SSHClient()
193
198
  ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
194
- ssh.connect(self.ssh_host, port=self.ssh_port, username=self.ssh_user, key_filename=self.ssh_key_path)
199
+ ssh.connect(self.ssh_host, port=self.ssh_port, username=self.ssh_user, key_filename=str(self.ssh_key_path))
195
200
 
196
201
  elan_path: str = "/usr/local/elan/bin/elan"
197
202
  lean_path: str = "/usr/local/elan/bin/lean"
198
203
 
199
- stdin, stdout, stderr = ssh.exec_command(f"{elan_path} default stable && {lean_path} --version")
204
+ _stdin, stdout, stderr = ssh.exec_command(f"{elan_path} default stable && {lean_path} --version")
200
205
  output: str = stdout.read().decode()
201
206
  error: str = stderr.read().decode()
202
- print("SSH Command Output:", output)
203
- print("SSH Command Error:", error)
207
+ UserMessage(f"SSH Command Output: {output}")
208
+ UserMessage(f"SSH Command Error: {error}")
204
209
 
205
210
  sftp = ssh.open_sftp()
206
- remote_path: str = f"/root/{os.path.basename(filepath)}"
211
+ remote_path: str = f"/root/{Path(filepath).name}"
207
212
  sftp.put(filepath, remote_path)
208
213
  sftp.close()
209
214
 
210
- stdin, stdout, stderr = ssh.exec_command(f"{lean_path} {remote_path}")
215
+ _stdin, stdout, stderr = ssh.exec_command(f"{lean_path} {remote_path}")
211
216
  output = stdout.read().decode()
212
217
  error = stderr.read().decode()
213
218
 
@@ -216,13 +221,12 @@ class LeanEngine(Engine):
216
221
 
217
222
  if "error" in output.lower() or "error" in error.lower():
218
223
  return output, {'status': 'failure'}
219
- elif not output and not error:
224
+ if not output and not error:
220
225
  return "Lean program halted successfully with no output.", {'status': 'success'}
221
- else:
222
- return output, {'status': 'success'}
226
+ return output, {'status': 'success'}
223
227
 
224
228
  except Exception as e:
225
- raise RuntimeError(f"SSH command execution failed: {str(e)}")
229
+ UserMessage(f"SSH command execution failed: {e!s}", raise_with=RuntimeError)
226
230
 
227
231
  def prepare(self, argument: Any) -> None:
228
232
  """
@@ -1,8 +1,15 @@
1
- from ...mixin import (ANTHROPIC_CHAT_MODELS, ANTHROPIC_REASONING_MODELS,
2
- DEEPSEEK_CHAT_MODELS, DEEPSEEK_REASONING_MODELS,
3
- GOOGLE_CHAT_MODELS, GOOGLE_REASONING_MODELS,
4
- GROQ_CHAT_MODELS, GROQ_REASONING_MODELS,
5
- OPENAI_CHAT_MODELS, OPENAI_REASONING_MODELS)
1
+ from ...mixin import (
2
+ ANTHROPIC_CHAT_MODELS,
3
+ ANTHROPIC_REASONING_MODELS,
4
+ DEEPSEEK_CHAT_MODELS,
5
+ DEEPSEEK_REASONING_MODELS,
6
+ GOOGLE_CHAT_MODELS,
7
+ GOOGLE_REASONING_MODELS,
8
+ GROQ_CHAT_MODELS,
9
+ GROQ_REASONING_MODELS,
10
+ OPENAI_CHAT_MODELS,
11
+ OPENAI_REASONING_MODELS,
12
+ )
6
13
  from .engine_anthropic_claudeX_chat import ClaudeXChatEngine
7
14
  from .engine_anthropic_claudeX_reasoning import ClaudeXReasoningEngine
8
15
  from .engine_deepseekX_reasoning import DeepSeekXReasoningEngine
@@ -13,12 +20,33 @@ from .engine_openai_gptX_reasoning import GPTXReasoningEngine
13
20
 
14
21
  # create the mapping
15
22
  ENGINE_MAPPING = {
16
- **{model_name: ClaudeXChatEngine for model_name in ANTHROPIC_CHAT_MODELS},
17
- **{model_name: ClaudeXReasoningEngine for model_name in ANTHROPIC_REASONING_MODELS},
18
- **{model_name: DeepSeekXReasoningEngine for model_name in DEEPSEEK_REASONING_MODELS},
19
- **{model_name: GeminiXReasoningEngine for model_name in GOOGLE_REASONING_MODELS},
20
- **{model_name: GPTXChatEngine for model_name in OPENAI_CHAT_MODELS},
21
- **{model_name: GPTXReasoningEngine for model_name in OPENAI_REASONING_MODELS},
22
- **{model_name: GroqEngine for model_name in GROQ_CHAT_MODELS},
23
- **{model_name: GroqEngine for model_name in GROQ_REASONING_MODELS},
23
+ **dict.fromkeys(ANTHROPIC_CHAT_MODELS, ClaudeXChatEngine),
24
+ **dict.fromkeys(ANTHROPIC_REASONING_MODELS, ClaudeXReasoningEngine),
25
+ **dict.fromkeys(DEEPSEEK_REASONING_MODELS, DeepSeekXReasoningEngine),
26
+ **dict.fromkeys(GOOGLE_REASONING_MODELS, GeminiXReasoningEngine),
27
+ **dict.fromkeys(OPENAI_CHAT_MODELS, GPTXChatEngine),
28
+ **dict.fromkeys(OPENAI_REASONING_MODELS, GPTXReasoningEngine),
29
+ **dict.fromkeys(GROQ_CHAT_MODELS, GroqEngine),
30
+ **dict.fromkeys(GROQ_REASONING_MODELS, GroqEngine),
24
31
  }
32
+
33
+ __all__ = [
34
+ "ANTHROPIC_CHAT_MODELS",
35
+ "ANTHROPIC_REASONING_MODELS",
36
+ "DEEPSEEK_CHAT_MODELS",
37
+ "DEEPSEEK_REASONING_MODELS",
38
+ "ENGINE_MAPPING",
39
+ "GOOGLE_CHAT_MODELS",
40
+ "GOOGLE_REASONING_MODELS",
41
+ "GROQ_CHAT_MODELS",
42
+ "GROQ_REASONING_MODELS",
43
+ "OPENAI_CHAT_MODELS",
44
+ "OPENAI_REASONING_MODELS",
45
+ "ClaudeXChatEngine",
46
+ "ClaudeXReasoningEngine",
47
+ "DeepSeekXReasoningEngine",
48
+ "GPTXChatEngine",
49
+ "GPTXReasoningEngine",
50
+ "GeminiXReasoningEngine",
51
+ "GroqEngine",
52
+ ]