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
symai/prompts.py CHANGED
@@ -1,12 +1,13 @@
1
1
  import threading
2
- from abc import ABC
2
+ from collections.abc import Callable
3
3
  from enum import Enum
4
- from typing import Any, Callable, List
4
+ from typing import Any
5
5
 
6
6
  from .exceptions import TemplatePropertyException
7
+ from .utils import UserMessage
7
8
 
8
9
 
9
- class Prompt(ABC):
10
+ class Prompt:
10
11
  stop_token = 'EOF'
11
12
 
12
13
  def __init__(self, value, **format_kwargs):
@@ -21,22 +22,26 @@ class Prompt(ABC):
21
22
  elif isinstance(v, Prompt):
22
23
  self._value += v.value
23
24
  else:
24
- raise ValueError(f"List of values must be strings or Prompts, not {type(v)}")
25
+ msg = f"List of values must be strings or Prompts, not {type(v)}"
26
+ UserMessage(msg)
27
+ raise ValueError(msg)
25
28
  elif isinstance(value, Prompt):
26
29
  self._value += value.value
27
30
  elif isinstance(value, Callable):
28
31
  res = value()
29
32
  self._value += res.value
30
33
  else:
31
- raise TypeError(f"Prompt value must be of type str, List[str], Prompt, or List[Prompt], not {type(value)}")
34
+ msg = f"Prompt value must be of type str, List[str], Prompt, or List[Prompt], not {type(value)}"
35
+ UserMessage(msg)
36
+ raise TypeError(msg)
32
37
  self.dynamic_value = []
33
38
  self.format_kwargs = format_kwargs
34
39
 
35
40
  @property
36
- def value(self) -> List[str]:
41
+ def value(self) -> list[str]:
37
42
  return self._value
38
43
 
39
- def __call__(self, *args: Any, **kwds: Any) -> List["Prompt"]:
44
+ def __call__(self, *_args: Any, **_kwds: Any) -> list["Prompt"]:
40
45
  return self.value
41
46
 
42
47
  def __str__(self) -> str:
@@ -48,11 +53,17 @@ class Prompt(ABC):
48
53
  template_ = '{'+k+'}'
49
54
  count = val_.count(template_)
50
55
  if count <= 0:
51
- raise TemplatePropertyException(f"Template property `{k}` not found.")
52
- elif count > 1:
53
- raise TemplatePropertyException(f"Template property {k} found multiple times ({count}), expected only once.")
56
+ msg = f"Template property `{k}` not found."
57
+ UserMessage(msg)
58
+ raise TemplatePropertyException(msg)
59
+ if count > 1:
60
+ msg = f"Template property {k} found multiple times ({count}), expected only once."
61
+ UserMessage(msg)
62
+ raise TemplatePropertyException(msg)
54
63
  if v is None:
55
- raise TemplatePropertyException(f"Invalid value: Template property {k} is None.")
64
+ msg = f"Invalid value: Template property {k} is None."
65
+ UserMessage(msg)
66
+ raise TemplatePropertyException(msg)
56
67
  val_ = val_.replace(template_, v)
57
68
  return val_
58
69
 
@@ -99,7 +110,7 @@ class PromptRegistry:
99
110
  if cls._instance is None:
100
111
  with cls._lock:
101
112
  if cls._instance is None:
102
- cls._instance = super(PromptRegistry, cls).__new__(cls)
113
+ cls._instance = super().__new__(cls)
103
114
  cls._instance._default_language = PromptLanguage.ENGLISH
104
115
  cls._instance._default_model = ModelName.ALL
105
116
  cls._instance._model_fallback = True
@@ -164,12 +175,15 @@ class PromptRegistry:
164
175
  and key in dictionary[model][lang]
165
176
  ):
166
177
  return dictionary[model][lang][key]
167
- elif self._model_fallback and model != ModelName.ALL:
178
+ if self._model_fallback and model != ModelName.ALL:
168
179
  return self._retrieve_value(dictionary, ModelName.ALL, lang, key)
169
180
 
170
- raise ValueError(
171
- f"Prompt value {key} not found for language {lang} and model {model} (fallback: {self._model_fallback})"
181
+ msg = (
182
+ f"Prompt value {key} not found for language {lang} and model {model} "
183
+ f"(fallback: {self._model_fallback})"
172
184
  )
185
+ UserMessage(msg)
186
+ raise ValueError(msg)
173
187
 
174
188
  def register_value(
175
189
  self,
@@ -222,13 +236,11 @@ class PromptRegistry:
222
236
  if format:
223
237
  prefix, suffix = tag_data['delimiters']
224
238
  return f"{prefix}{tag_value}{suffix}"
225
- else:
226
- return tag_value
239
+ return tag_value
227
240
 
228
241
  if format:
229
242
  return f"{self._tag_prefix}{tag_data}{self._tag_suffix}"
230
- else:
231
- return tag_data
243
+ return tag_data
232
244
 
233
245
  def has_value(
234
246
  self, key, model: ModelName = ModelName.ALL, lang: PromptLanguage = None
@@ -260,24 +272,26 @@ class PromptRegistry:
260
272
 
261
273
  class JsonPromptTemplate(Prompt):
262
274
  def __init__(self, query: str, json_format: dict):
263
- super().__init__(["""Process the query over the data to create a Json format: <data_query> => [JSON_BEGIN]<json_output>[JSON_END].
264
- --------------------------
265
- The json format is:
266
- {json_format}
267
- --------------------------
268
- The generated output must follow the <json_output> formatting, however the keys and values must be replaced with the requested user data query results. Definition of the <data_query> := {query}
269
- --------------------------
270
- Do not return anything other than a valid json format.
271
- Your first character must always be a""" \
272
- """'{' and your last character must always be a '}', everything else follows the user specified instructions.
273
- Only use double quotes " for the keys and values.
274
- Start the generation process after [JSON_BEGIN] and end it with [JSON_END].
275
- Every key that has no semantic placeholder brackets around it (e.g. {placeholder}, {entity}, {attribute}, etc.) must be available in the generated json output.
276
- All semantic placeholders (e.g. {placeholder}, {entity}, {attribute}, etc.) must be replaced according to their wheather or not they are found in the data query results.
277
- DO NOT WRITE the semantic placeholders (e.g. {placeholder}, {entity}, {attribute}, etc.) in the generated json output.
278
- --------------------------
279
-
280
- """], query=query, json_format=str(json_format))
275
+ json_format_str = str(json_format)
276
+ prompt_template = (
277
+ "Process the query over the data to create a Json format: <data_query> => [JSON_BEGIN]<json_output>[JSON_END].\n"
278
+ "--------------------------\n"
279
+ "The json format is:\n"
280
+ f"{json_format_str}\n"
281
+ "--------------------------\n"
282
+ "The generated output must follow the <json_output> formatting, however the keys and values must be replaced with the requested user data query results. "
283
+ f"Definition of the <data_query> := {query}\n"
284
+ "--------------------------\n"
285
+ "Do not return anything other than a valid json format.\n"
286
+ "Your first character must always be a '{{' and your last character must always be a '}}', everything else follows the user specified instructions.\n"
287
+ 'Only use double quotes " for the keys and values.\n'
288
+ "Start the generation process after [JSON_BEGIN] and end it with [JSON_END].\n"
289
+ "Every key that has no semantic placeholder brackets around it (e.g. {placeholder}, {entity}, {attribute}, etc.) must be available in the generated json output.\n"
290
+ "All semantic placeholders (e.g. {placeholder}, {entity}, {attribute}, etc.) must be replaced according to their wheather or not they are found in the data query results.\n"
291
+ "DO NOT WRITE the semantic placeholders (e.g. {placeholder}, {entity}, {attribute}, etc.) in the generated json output.\n"
292
+ "--------------------------\n\n"
293
+ )
294
+ super().__init__([prompt_template], query=query, json_format=json_format_str)
281
295
 
282
296
 
283
297
  class FuzzyEquals(Prompt):
@@ -314,7 +328,7 @@ class FuzzyEquals(Prompt):
314
328
  "['zz', 'yy', 'xx'] == 'ZZ | YY | XX' =>True",
315
329
  "'House, Mouse, CARS' == 'house | mouse | cars' =>True",
316
330
  "'we hav teh most efective systeem in the citi.' == 'We have the most effective system in the city.' =>True",
317
- "【Semantic░programming】 == 'semantic programming' =>True",
331
+ "'[SEMANTIC_PROGRAMMING]' == 'semantic programming' =>True",
318
332
  "'e' == 'constant' =>True",
319
333
  "'e' == '2.718...' =>True",
320
334
  "1/3 == '0.30...' =>False"
@@ -585,7 +599,7 @@ class FewShotPattern(Prompt):
585
599
  class StartsWith(Prompt):
586
600
  def __init__(self):
587
601
  super().__init__([
588
- # Semantic examples understanding concepts (positive cases)
602
+ # Semantic examples - understanding concepts (positive cases)
589
603
  "'The apple fell from the tree.' startswith 'fruit' =>True",
590
604
  "'The red rose bloomed in spring.' startswith 'flower' =>True",
591
605
  "'My dog loves to play fetch.' startswith 'animal' =>True",
@@ -601,7 +615,7 @@ class StartsWith(Prompt):
601
615
  "'The earthquake shook the entire city.' startswith 'natural disaster' =>True",
602
616
  "'She invested in stocks and bonds.' startswith 'finance' =>True",
603
617
  "'The police officer directed traffic.' startswith 'law enforcement' =>True",
604
- # Semantic examples negative cases
618
+ # Semantic examples - negative cases
605
619
  "'The book was very interesting.' startswith 'vehicle' =>False",
606
620
  "'The mountain peak was covered in snow.' startswith 'ocean' =>False",
607
621
  "'She played the piano beautifully.' startswith 'sports' =>False",
@@ -614,7 +628,7 @@ class StartsWith(Prompt):
614
628
  class EndsWith(Prompt):
615
629
  def __init__(self):
616
630
  super().__init__([
617
- # Semantic examples understanding concepts (positive cases)
631
+ # Semantic examples - understanding concepts (positive cases)
618
632
  "'She sliced a ripe banana.' endswith 'fruit' =>True",
619
633
  "'He adopted a small puppy.' endswith 'animal' =>True",
620
634
  "'They commuted by train.' endswith 'vehicle' =>True",
@@ -625,7 +639,7 @@ class EndsWith(Prompt):
625
639
  "'He flew to Spain.' endswith 'country' =>True",
626
640
  "'The chef baked fresh bread.' endswith 'food' =>True",
627
641
  "'They filmed a documentary about dolphins.' endswith 'animal' =>True",
628
- # Semantic examples negative cases
642
+ # Semantic examples - negative cases
629
643
  "'The sun set behind the mountains.' endswith 'vehicle' =>False",
630
644
  "'He repaired the motorcycle.' endswith 'instrument' =>False",
631
645
  "'They enjoyed a salad.' endswith 'building' =>False",
@@ -700,7 +714,7 @@ class SimpleSymbolicExpression(Prompt):
700
714
  '"x² = 9" or "x = 4" =>Either x² = 9 or x = 4.',
701
715
  '"x² = 9" xor "x = 4" =>Exactly one of x² = 9 or x = 4, but not both.',
702
716
  '"x² = 9" implies "x = ±3" =>If x² = 9, then x = ±3.',
703
- '"f(x) = 0" ++ "f has a local extremum" =>A critical point indicates f has a local extremum.',
717
+ '"f prime (x) = 0" ++ "f has a local extremum" =>A critical point indicates f has a local extremum.',
704
718
  '"a² + b² = c²" * "c = 13" =>In the right-triangle where c = 13, a² + b² = 169.',
705
719
  '"limₓ→0 sin x / x = 1" and "x approaches 0" =>As x approaches 0, sin x / x tends to 1.',
706
720
  """"SELECT name FROM customers" + "WHERE city = 'Paris'" =>SELECT name FROM customers WHERE city = 'Paris'.""",
@@ -709,7 +723,7 @@ class SimpleSymbolicExpression(Prompt):
709
723
  """"x > 3" and "x < 7" =>3 < x < 7.""",
710
724
  """"a divides b" implies "b mod a = 0" =>If a divides b, then b mod a = 0.""",
711
725
  """"p" xor "not p" =>Exactly one of p or not p, but not both.""",
712
- """"f(x) exists" ++ "f(x) continuous" =>A differentiable function is necessarily continuous.""",
726
+ """"f prime (x) exists" ++ "f(x) continuous" =>A differentiable function is necessarily continuous.""",
713
727
  """"SELECT * FROM orders" / "status = 'PENDING'" =>If status = 'PENDING', SELECT * FROM orders.""",
714
728
  """"x = 2" + "y = 3" * "z = x + y" =>With x = 2 and y = 3, z = 5.""",
715
729
  """"temperature rises" >> "ice melts" =>Because temperature rises, ice melts."""
@@ -734,7 +748,7 @@ class LogicExpression(Prompt):
734
748
  # AND
735
749
  "expr 'All humans are mortal' and 'Socrates is a human' =>'Therefore, Socrates is mortal.'",
736
750
  "expr 'If it rains, the ground gets wet' and 'It is raining' =>'Therefore, the ground gets wet.'",
737
- "expr 'The sky is blue' and 'The sky is not blue' =>'Contradiction both cannot be true together.'",
751
+ "expr 'The sky is blue' and 'The sky is not blue' =>'Contradiction - both cannot be true together.'",
738
752
  # OR
739
753
  "expr 'It is Monday' or 'It is a holiday' =>'Either it is Monday, a holiday, or possibly both.'",
740
754
  "expr 'Alice is at home' or 'Bob is at home' =>'Alice or Bob is at home, perhaps both.'",
@@ -1,14 +1,17 @@
1
1
  import argparse
2
2
  import random
3
- from typing import List, Optional
4
3
 
5
4
  import numpy as np
6
5
  import torch
7
- from fastapi import FastAPI, Request
6
+ from fastapi import FastAPI
8
7
  from pydantic import BaseModel
9
- from transformers import (AutoModelForCausalLM, AutoTokenizer,
10
- BitsAndBytesConfig, StoppingCriteria,
11
- StoppingCriteriaList)
8
+ from transformers import (
9
+ AutoModelForCausalLM,
10
+ AutoTokenizer,
11
+ BitsAndBytesConfig,
12
+ StoppingCriteria,
13
+ StoppingCriteriaList,
14
+ )
12
15
 
13
16
  # General arguments
14
17
  parser = argparse.ArgumentParser(description="FastAPI server for Hugging Face models")
@@ -84,7 +87,7 @@ class StoppingCriteriaSub(StoppingCriteria):
84
87
  self.stop_words = stop_words
85
88
  self.tokenizer = tokenizer
86
89
 
87
- def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor, **kwargs) -> bool:
90
+ def __call__(self, input_ids: torch.LongTensor, _scores: torch.FloatTensor, **_kwargs) -> bool:
88
91
  for stop_word in self.stop_words:
89
92
  if self.tokenizer.decode(input_ids[0][-len(self.tokenizer.encode(stop_word)):]).strip() == stop_word:
90
93
  return True
@@ -92,26 +95,26 @@ class StoppingCriteriaSub(StoppingCriteria):
92
95
 
93
96
  class TokenizeRequest(BaseModel):
94
97
  input: str
95
- add_special_tokens: Optional[bool] = False
98
+ add_special_tokens: bool | None = False
96
99
 
97
100
  class DetokenizeRequest(BaseModel):
98
- tokens: List[int]
99
- skip_special_tokens: Optional[bool] = True
101
+ tokens: list[int]
102
+ skip_special_tokens: bool | None = True
100
103
 
101
104
  class ChatCompletionRequest(BaseModel):
102
- messages: List[dict]
105
+ messages: list[dict]
103
106
  temperature: float = 1.
104
107
  top_p: float = 1.
105
- stop: Optional[List[str]] = None
106
- seed: Optional[int] = None
107
- max_tokens: Optional[int] = 2048
108
- max_tokens_forcing: Optional[int] = None
108
+ stop: list[str] | None = None
109
+ seed: int | None = None
110
+ max_tokens: int | None = 2048
111
+ max_tokens_forcing: int | None = None
109
112
  top_k: int = 50
110
113
  logprobs: bool = False
111
114
  do_sample: bool = True
112
115
  num_beams: int = 1
113
116
  num_beam_groups: int = 1
114
- eos_token_id: Optional[int] = None
117
+ eos_token_id: int | None = None
115
118
 
116
119
  @app.post("/chat")
117
120
  def chat_completions(request: ChatCompletionRequest):
@@ -145,7 +148,7 @@ def chat_completions(request: ChatCompletionRequest):
145
148
  new_tokens = outputs.sequences[0][inputs.input_ids.shape[-1]:]
146
149
  generated_text = tokenizer.decode(new_tokens, skip_special_tokens=True)
147
150
 
148
- response = {
151
+ return {
149
152
  "choices": [
150
153
  {
151
154
  "message": {
@@ -175,8 +178,6 @@ def chat_completions(request: ChatCompletionRequest):
175
178
  }
176
179
  }
177
180
 
178
- return response
179
-
180
181
  @app.post("/tokenize")
181
182
  def tokenize(request: TokenizeRequest):
182
183
  tokens = tokenizer.encode(request.input, add_special_tokens=request.add_special_tokens)
@@ -188,7 +189,9 @@ def detokenize(request: DetokenizeRequest):
188
189
  return {"text": text}
189
190
 
190
191
  def huggingface_server():
191
- import uvicorn
192
- from functools import partial
192
+ # Lazy imports keep optional server dependencies out of module import path.
193
+ from functools import partial # noqa
194
+ import uvicorn # noqa
195
+
193
196
  command = partial(uvicorn.run, app)
194
197
  return command, args
@@ -1,9 +1,11 @@
1
1
  import argparse
2
2
  import subprocess
3
3
  import sys
4
- import os
4
+ from pathlib import Path
5
+
5
6
  from loguru import logger
6
7
 
8
+
7
9
  def llama_cpp_server():
8
10
  parser = argparse.ArgumentParser(description="A wrapper for llama_cpp.", add_help=False)
9
11
  parser.add_argument("--help", action="store_true", help="Show available options for llama_cpp server.")
@@ -16,23 +18,23 @@ def llama_cpp_server():
16
18
  if main_args.help:
17
19
  if main_args.env == 'python':
18
20
  command = [sys.executable, "-m", "llama_cpp.server", "--help"]
19
- subprocess.run(command)
21
+ subprocess.run(command, check=False)
20
22
  else:
21
23
  if not main_args.cpp_server_path:
22
24
  logger.error("Error: --cpp-server-path is required when using cpp environment")
23
25
  sys.exit(1)
24
- if not os.path.exists(main_args.cpp_server_path):
26
+ if not Path(main_args.cpp_server_path).exists():
25
27
  logger.error(f"Error: Executable not found at {main_args.cpp_server_path}")
26
28
  sys.exit(1)
27
29
  command = [main_args.cpp_server_path, "--help"]
28
- subprocess.run(command)
30
+ subprocess.run(command, check=False)
29
31
  sys.exit(0)
30
32
 
31
33
  if main_args.env == 'cpp':
32
34
  if not main_args.cpp_server_path:
33
35
  logger.error("Error: --cpp-server-path is required when using cpp environment")
34
36
  sys.exit(1)
35
- if not os.path.exists(main_args.cpp_server_path):
37
+ if not Path(main_args.cpp_server_path).exists():
36
38
  logger.error(f"Error: Executable not found at {main_args.cpp_server_path}")
37
39
  sys.exit(1)
38
40
  command = [
symai/shell.py CHANGED
@@ -1,16 +1,15 @@
1
1
  import argparse
2
2
  import os
3
3
 
4
+ from . import SYMAI_VERSION
4
5
  from .components import Lambda, Try
5
6
  from .core import few_shot
6
7
  from .misc.console import ConsoleStyle
7
8
  from .misc.loader import Loader
8
9
  from .post_processors import StripPostProcessor
9
10
  from .pre_processors import PreProcessor
10
- from .symbol import Expression
11
11
  from .shellsv import run as shellsv_run
12
- from . import SYMAI_VERSION
13
-
12
+ from .symbol import Expression
14
13
 
15
14
  SHELL_CONTEXT = """[Description]
16
15
  This shell program is the command interpreter on the Linux systems, MacOS and Windows PowerShell.
@@ -47,7 +46,7 @@ $> New-Item -ItemType Directory -Path <path> EOF
47
46
 
48
47
  class ShellPreProcessor(PreProcessor):
49
48
  def __call__(self, argument):
50
- return '// {}\n$>'.format(str(argument.prop.instance))
49
+ return f'// {argument.prop.instance!s}\n$>'
51
50
 
52
51
 
53
52
  class Shell(Expression):