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
@@ -7,7 +7,7 @@ import openai
7
7
 
8
8
  from ....components import SelfPrompt
9
9
  from ....core_ext import retry
10
- from ....utils import CustomUserWarning
10
+ from ....utils import UserMessage
11
11
  from ...base import Engine
12
12
  from ...settings import SYMAI_CONFIG
13
13
 
@@ -18,6 +18,15 @@ logging.getLogger("httpx").setLevel(logging.ERROR)
18
18
  logging.getLogger("httpcore").setLevel(logging.ERROR)
19
19
 
20
20
 
21
+ _NON_VERBOSE_OUTPUT = (
22
+ "<META_INSTRUCTION/>\n"
23
+ "You do not output anything else, like verbose preambles or post explanation, such as "
24
+ "\"Sure, let me...\", \"Hope that was helpful...\", \"Yes, I can help you with that...\", etc. "
25
+ "Consider well formatted output, e.g. for sentences use punctuation, spaces etc. or for code use "
26
+ "indentation, etc. Never add meta instructions information to your output!\n\n"
27
+ )
28
+
29
+
21
30
  class GroqEngine(Engine):
22
31
  def __init__(self, api_key: str | None = None, model: str | None = None):
23
32
  super().__init__()
@@ -36,7 +45,7 @@ class GroqEngine(Engine):
36
45
  try:
37
46
  self.client = openai.OpenAI(api_key=openai.api_key, base_url="https://api.groq.com/openai/v1")
38
47
  except Exception as e:
39
- CustomUserWarning(f'Failed to initialize OpenAI client. Please check your OpenAI library version. Caused by: {e}', raise_with=ValueError)
48
+ UserMessage(f'Failed to initialize OpenAI client. Please check your OpenAI library version. Caused by: {e}', raise_with=ValueError)
40
49
 
41
50
  def id(self) -> str:
42
51
  if self.config.get('NEUROSYMBOLIC_ENGINE_MODEL') and \
@@ -53,11 +62,11 @@ class GroqEngine(Engine):
53
62
  if 'seed' in kwargs:
54
63
  self.seed = kwargs['seed']
55
64
 
56
- def compute_required_tokens(self, messages):
57
- raise NotImplementedError("Token counting not implemented for this engine.")
65
+ def compute_required_tokens(self, _messages):
66
+ UserMessage("Token counting not implemented for this engine.", raise_with=NotImplementedError)
58
67
 
59
- def compute_remaining_tokens(self, prompts: list) -> int:
60
- raise NotImplementedError("Token counting not implemented for this engine.")
68
+ def compute_remaining_tokens(self, _prompts: list) -> int:
69
+ UserMessage("Token counting not implemented for this engine.", raise_with=NotImplementedError)
61
70
 
62
71
  def _handle_prefix(self, model_name: str) -> str:
63
72
  """Handle prefix for model name."""
@@ -82,7 +91,7 @@ class GroqEngine(Engine):
82
91
  thinking_content = None
83
92
 
84
93
  cleaned_content = re.sub(think_pattern, '', content, flags=re.DOTALL).strip()
85
- cleaned_output = [cleaned_content] + output[1:]
94
+ cleaned_output = [cleaned_content, *output[1:]]
86
95
 
87
96
  return thinking_content, cleaned_output
88
97
 
@@ -100,9 +109,9 @@ class GroqEngine(Engine):
100
109
  except Exception as e:
101
110
  if openai.api_key is None or openai.api_key == '':
102
111
  msg = 'Groq API key is not set. Please set it in the config file or pass it as an argument to the command method.'
103
- logging.error(msg)
112
+ UserMessage(msg)
104
113
  if self.config['NEUROSYMBOLIC_ENGINE_API_KEY'] is None or self.config['NEUROSYMBOLIC_ENGINE_API_KEY'] == '':
105
- CustomUserWarning(msg, raise_with=ValueError)
114
+ UserMessage(msg, raise_with=ValueError)
106
115
  openai.api_key = self.config['NEUROSYMBOLIC_ENGINE_API_KEY']
107
116
 
108
117
  callback = self.client.chat.completions.create
@@ -111,7 +120,7 @@ class GroqEngine(Engine):
111
120
  if except_remedy is not None:
112
121
  res = except_remedy(self, e, callback, argument)
113
122
  else:
114
- CustomUserWarning(f'Error during generation. Caused by: {e}', raise_with=ValueError)
123
+ UserMessage(f'Error during generation. Caused by: {e}', raise_with=ValueError)
115
124
 
116
125
  metadata = {'raw_output': res}
117
126
  if payload.get('tools'):
@@ -126,11 +135,11 @@ class GroqEngine(Engine):
126
135
 
127
136
  def _prepare_raw_input(self, argument):
128
137
  if not argument.prop.processed_input:
129
- CustomUserWarning('Need to provide a prompt instruction to the engine if raw_input is enabled.', raise_with=ValueError)
138
+ UserMessage('Need to provide a prompt instruction to the engine if raw_input is enabled.', raise_with=ValueError)
130
139
  value = argument.prop.processed_input
131
140
  # convert to dict if not already
132
- if type(value) != list:
133
- if type(value) != dict:
141
+ if not isinstance(value, list):
142
+ if not isinstance(value, dict):
134
143
  value = {'role': 'user', 'content': str(value)}
135
144
  value = [value]
136
145
  return value
@@ -139,18 +148,32 @@ class GroqEngine(Engine):
139
148
  if argument.prop.raw_input:
140
149
  argument.prop.prepared_input = self._prepare_raw_input(argument)
141
150
  return
151
+ self._validate_response_format(argument)
142
152
 
143
- _non_verbose_output = """<META_INSTRUCTION/>\nYou do not output anything else, like verbose preambles or post explanation, such as "Sure, let me...", "Hope that was helpful...", "Yes, I can help you with that...", etc. Consider well formatted output, e.g. for sentences use punctuation, spaces etc. or for code use indentation, etc. Never add meta instructions information to your output!\n\n"""
144
- user: str = ""
145
- system: str = ""
153
+ system = self._build_system_message(argument)
154
+ user_content = self._build_user_content(argument)
155
+ user_prompt = {"role": "user", "content": user_content}
156
+ system, user_prompt = self._apply_self_prompt_if_needed(argument, system, user_prompt)
146
157
 
147
- if argument.prop.suppress_verbose_output:
148
- system += _non_verbose_output
149
- system = f'{system}\n' if system and len(system) > 0 else ''
158
+ argument.prop.prepared_input = [
159
+ { "role": "system", "content": system },
160
+ user_prompt,
161
+ ]
150
162
 
163
+ def _validate_response_format(self, argument) -> None:
151
164
  if argument.prop.response_format:
152
- _rsp_fmt = argument.prop.response_format
153
- assert _rsp_fmt.get('type') is not None, 'Expected format `{ "type": "json_object" }`! We are using the OpenAI compatible API for Groq. See more here: https://console.groq.com/docs/tool-use'
165
+ response_format = argument.prop.response_format
166
+ assert response_format.get('type') is not None, (
167
+ 'Expected format `{ "type": "json_object" }`! We are using the OpenAI compatible API for Groq. '
168
+ "See more here: https://console.groq.com/docs/tool-use"
169
+ )
170
+
171
+ def _build_system_message(self, argument) -> str:
172
+ system: str = ""
173
+ if argument.prop.suppress_verbose_output:
174
+ system += _NON_VERBOSE_OUTPUT
175
+ if system:
176
+ system = f"{system}\n"
154
177
 
155
178
  ref = argument.prop.instance
156
179
  static_ctxt, dyn_ctxt = ref.global_context
@@ -160,62 +183,61 @@ class GroqEngine(Engine):
160
183
  if len(dyn_ctxt) > 0:
161
184
  system += f"<DYNAMIC CONTEXT/>\n{dyn_ctxt}\n\n"
162
185
 
163
- payload = argument.prop.payload
164
186
  if argument.prop.payload:
165
- system += f"<ADDITIONAL CONTEXT/>\n{str(payload)}\n\n"
187
+ system += f"<ADDITIONAL CONTEXT/>\n{argument.prop.payload!s}\n\n"
166
188
 
167
189
  examples = argument.prop.examples
168
190
  if examples and len(examples) > 0:
169
- system += f"<EXAMPLES/>\n{str(examples)}\n\n"
191
+ system += f"<EXAMPLES/>\n{examples!s}\n\n"
170
192
 
171
193
  if argument.prop.prompt is not None and len(argument.prop.prompt) > 0:
172
194
  val = str(argument.prop.prompt)
173
195
  system += f"<INSTRUCTION/>\n{val}\n\n"
174
196
 
175
- suffix: str = str(argument.prop.processed_input)
176
- user += f"{suffix}"
177
-
178
197
  if argument.prop.template_suffix:
179
- system += f' You will only generate content for the placeholder `{str(argument.prop.template_suffix)}` following the instructions and the provided context information.\n\n'
198
+ system += (
199
+ " You will only generate content for the placeholder "
200
+ f"`{argument.prop.template_suffix!s}` following the instructions and the provided context information.\n\n"
201
+ )
202
+
203
+ return system
180
204
 
181
- user_prompt = { "role": "user", "content": user }
205
+ def _build_user_content(self, argument) -> str:
206
+ return str(argument.prop.processed_input)
182
207
 
183
- # First check if the `Symbol` instance has the flag set, otherwise check if it was passed as an argument to a method
208
+ def _apply_self_prompt_if_needed(self, argument, system, user_prompt):
184
209
  if argument.prop.instance._kwargs.get('self_prompt', False) or argument.prop.self_prompt:
185
210
  self_prompter = SelfPrompt()
186
-
187
- res = self_prompter({'user': user, 'system': system})
211
+ res = self_prompter({'user': user_prompt['content'], 'system': system})
188
212
  if res is None:
189
- CustomUserWarning("Self-prompting failed!", raise_with=ValueError)
190
-
191
- user_prompt = { "role": "user", "content": res['user'] }
192
- system = res['system']
193
-
194
- argument.prop.prepared_input = [
195
- { "role": "system", "content": system },
196
- user_prompt,
197
- ]
213
+ UserMessage("Self-prompting failed!", raise_with=ValueError)
214
+ return res['system'], {"role": "user", "content": res['user']}
215
+ return system, user_prompt
198
216
 
199
217
  def _process_function_calls(self, res, metadata):
200
218
  hit = False
201
- if hasattr(res, 'choices') and res.choices:
202
- choice = res.choices[0]
203
- if hasattr(choice, 'message') and choice.message:
204
- if hasattr(choice.message, 'tool_calls') and choice.message.tool_calls:
205
- for tool_call in choice.message.tool_calls:
206
- if hasattr(tool_call, 'function') and tool_call.function:
207
- if hit:
208
- CustomUserWarning("Multiple function calls detected in the response but only the first one will be processed.")
209
- break
210
- try:
211
- args_dict = json.loads(tool_call.function.arguments)
212
- except json.JSONDecodeError:
213
- args_dict = {}
214
- metadata['function_call'] = {
215
- 'name': tool_call.function.name,
216
- 'arguments': args_dict
217
- }
218
- hit = True
219
+ if (
220
+ hasattr(res, 'choices')
221
+ and res.choices
222
+ and hasattr(res.choices[0], 'message')
223
+ and res.choices[0].message
224
+ and hasattr(res.choices[0].message, 'tool_calls')
225
+ and res.choices[0].message.tool_calls
226
+ ):
227
+ for tool_call in res.choices[0].message.tool_calls:
228
+ if hasattr(tool_call, 'function') and tool_call.function:
229
+ if hit:
230
+ UserMessage("Multiple function calls detected in the response but only the first one will be processed.")
231
+ break
232
+ try:
233
+ args_dict = json.loads(tool_call.function.arguments)
234
+ except json.JSONDecodeError:
235
+ args_dict = {}
236
+ metadata['function_call'] = {
237
+ 'name': tool_call.function.name,
238
+ 'arguments': args_dict
239
+ }
240
+ hit = True
219
241
  return metadata
220
242
 
221
243
  def _prepare_request_payload(self, messages, argument):
@@ -231,12 +253,12 @@ class GroqEngine(Engine):
231
253
  "stream_options",
232
254
  ]:
233
255
  if param in kwargs:
234
- CustomUserWarning(f"The parameter {param} is not supported by the Groq API. It will be ignored.")
256
+ UserMessage(f"The parameter {param} is not supported by the Groq API. It will be ignored.")
235
257
  del kwargs[param]
236
258
 
237
259
  n = kwargs.get('n', 1)
238
260
  if n > 1:
239
- CustomUserWarning("If N is supplied, it must be equal to 1. We default to 1 to not crash your program.")
261
+ UserMessage("If N is supplied, it must be equal to 1. We default to 1 to not crash your program.")
240
262
  n = 1
241
263
 
242
264
  # Handle Groq JSON-mode quirk: JSON Object Mode internally uses a constrainer tool.
@@ -244,8 +266,10 @@ class GroqEngine(Engine):
244
266
  tool_choice = kwargs.get('tool_choice', 'auto' if kwargs.get('tools') else 'none')
245
267
  tools = kwargs.get('tools')
246
268
  if response_format and isinstance(response_format, dict) and response_format.get('type') == 'json_object':
247
- if tool_choice in (None, 'none'): tool_choice = 'auto'
248
- if tools: tools = None
269
+ if tool_choice in (None, 'none'):
270
+ tool_choice = 'auto'
271
+ if tools:
272
+ tools = None
249
273
 
250
274
  payload = {
251
275
  "messages": messages,
@@ -1,12 +1,9 @@
1
- import json
2
1
  import logging
3
- import re
4
2
  from copy import deepcopy
5
- from typing import List, Optional
6
3
 
7
4
  import requests
8
5
 
9
- from ....utils import CustomUserWarning
6
+ from ....utils import UserMessage
10
7
  from ...base import Engine
11
8
  from ...settings import SYMAI_CONFIG, SYMSERVER_CONFIG
12
9
 
@@ -20,28 +17,28 @@ class HFTokenizer:
20
17
  _server_endpoint = f"http://{SYMSERVER_CONFIG.get('host')}:{SYMSERVER_CONFIG.get('port')}"
21
18
 
22
19
  @staticmethod
23
- def encode(text: str, add_special_tokens: bool = False) -> List[int]:
20
+ def encode(text: str, add_special_tokens: bool = False) -> list[int]:
24
21
  res = requests.post(f"{HFTokenizer._server_endpoint}/tokenize", json={
25
22
  "input": text,
26
23
  "add_special_tokens": add_special_tokens,
27
24
  })
28
25
 
29
26
  if res.status_code != 200:
30
- CustomUserWarning(f"Request failed with status code: {res.status_code}", raise_with=ValueError)
27
+ UserMessage(f"Request failed with status code: {res.status_code}", raise_with=ValueError)
31
28
 
32
29
  res = res.json()
33
30
 
34
31
  return res['tokens']
35
32
 
36
33
  @staticmethod
37
- def decode(tokens: List[int], skip_special_tokens: bool = True) -> str:
34
+ def decode(tokens: list[int], skip_special_tokens: bool = True) -> str:
38
35
  res = requests.post(f"{HFTokenizer._server_endpoint}/detokenize", json={
39
36
  "tokens": tokens,
40
37
  "skip_special_tokens": skip_special_tokens,
41
38
  })
42
39
 
43
40
  if res.status_code != 200:
44
- CustomUserWarning(f"Request failed with status code: {res.status_code}", raise_with=ValueError)
41
+ UserMessage(f"Request failed with status code: {res.status_code}", raise_with=ValueError)
45
42
 
46
43
  res = res.json()
47
44
 
@@ -49,7 +46,7 @@ class HFTokenizer:
49
46
 
50
47
 
51
48
  class HFEngine(Engine):
52
- def __init__(self, model: Optional[str] = None):
49
+ def __init__(self, model: str | None = None):
53
50
  super().__init__()
54
51
  self.config = deepcopy(SYMAI_CONFIG)
55
52
  # In case we use EngineRepository.register to inject the api_key and model => dynamically change the engine at runtime
@@ -58,7 +55,7 @@ class HFEngine(Engine):
58
55
  if self.id() != 'neurosymbolic':
59
56
  return
60
57
  if not SYMSERVER_CONFIG.get('online'):
61
- CustomUserWarning('You are using the huggingface engine, but the server endpoint is not started. Please start the server with `symserver [--args]` or run `symserver --help` to see the available options for this engine.', raise_with=ValueError)
58
+ UserMessage('You are using the huggingface engine, but the server endpoint is not started. Please start the server with `symserver [--args]` or run `symserver --help` to see the available options for this engine.', raise_with=ValueError)
62
59
  self.server_endpoint = f"http://{SYMSERVER_CONFIG.get('host')}:{SYMSERVER_CONFIG.get('port')}"
63
60
  self.tokenizer = HFTokenizer # backwards compatibility with how we handle tokenization, i.e. self.tokenizer().encode(...)
64
61
  self.name = self.__class__.__name__
@@ -77,10 +74,10 @@ class HFEngine(Engine):
77
74
  if 'except_remedy' in kwargs:
78
75
  self.except_remedy = kwargs['except_remedy']
79
76
 
80
- def compute_required_tokens(self, messages) -> int:
81
- CustomUserWarning('Not implemented for HFEngine. Please use the tokenizer directly to compute tokens.', raise_with=NotImplementedError)
82
- def compute_remaining_tokens(self, prompts: list) -> int:
83
- CustomUserWarning('Not implemented for HFEngine. Please use the tokenizer directly to compute tokens.', raise_with=NotImplementedError)
77
+ def compute_required_tokens(self, _messages) -> int:
78
+ UserMessage('Not implemented for HFEngine. Please use the tokenizer directly to compute tokens.', raise_with=NotImplementedError)
79
+ def compute_remaining_tokens(self, _prompts: list) -> int:
80
+ UserMessage('Not implemented for HFEngine. Please use the tokenizer directly to compute tokens.', raise_with=NotImplementedError)
84
81
  def forward(self, argument):
85
82
  kwargs = argument.kwargs
86
83
  prompts = argument.prop.prepared_input
@@ -117,7 +114,7 @@ class HFEngine(Engine):
117
114
  })
118
115
 
119
116
  if res.status_code != 200:
120
- CustomUserWarning(f"Request failed with status code: {res.status_code}", raise_with=ValueError)
117
+ UserMessage(f"Request failed with status code: {res.status_code}", raise_with=ValueError)
121
118
 
122
119
  res = res.json()
123
120
 
@@ -125,7 +122,7 @@ class HFEngine(Engine):
125
122
  if except_remedy is not None:
126
123
  res = except_remedy(self, e, argument)
127
124
  else:
128
- CustomUserWarning(f'Error during generation. Caused by: {e}', raise_with=ValueError)
125
+ UserMessage(f'Error during generation. Caused by: {e}', raise_with=ValueError)
129
126
 
130
127
  metadata = {'raw_output': res}
131
128
 
@@ -135,10 +132,10 @@ class HFEngine(Engine):
135
132
 
136
133
  def _prepare_raw_input(self, argument):
137
134
  if not argument.prop.processed_input:
138
- CustomUserWarning('Need to provide a prompt instruction to the engine if raw_input is enabled.', raise_with=ValueError)
135
+ UserMessage('Need to provide a prompt instruction to the engine if raw_input is enabled.', raise_with=ValueError)
139
136
  value = argument.prop.processed_input
140
- if type(value) != list:
141
- if type(value) != dict:
137
+ if not isinstance(value, list):
138
+ if not isinstance(value, dict):
142
139
  value = {'role': 'user', 'content': str(value)}
143
140
  value = [value]
144
141
  return value
@@ -167,17 +164,17 @@ class HFEngine(Engine):
167
164
 
168
165
  payload = argument.prop.payload
169
166
  if argument.prop.payload:
170
- user += f"<ADDITIONAL_CONTEXT/>\n{str(payload)}\n\n"
167
+ user += f"<ADDITIONAL_CONTEXT/>\n{payload!s}\n\n"
171
168
 
172
- examples: List[str] = argument.prop.examples
169
+ examples: list[str] = argument.prop.examples
173
170
  if examples and len(examples) > 0:
174
- user += f"<EXAMPLES/>\n{str(examples)}\n\n"
171
+ user += f"<EXAMPLES/>\n{examples!s}\n\n"
175
172
 
176
173
  if argument.prop.prompt is not None and len(argument.prop.prompt) > 0:
177
- user += f"<INSTRUCTION/>\n{str(argument.prop.prompt)}\n\n"
174
+ user += f"<INSTRUCTION/>\n{argument.prop.prompt!s}\n\n"
178
175
 
179
176
  if argument.prop.template_suffix:
180
- user += f" You will only generate content for the placeholder `{str(argument.prop.template_suffix)}` following the instructions and the provided context information.\n\n"
177
+ user += f" You will only generate content for the placeholder `{argument.prop.template_suffix!s}` following the instructions and the provided context information.\n\n"
181
178
 
182
179
  user += str(argument.prop.processed_input)
183
180