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
|
@@ -1,39 +1,38 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
import
|
|
2
|
+
from io import BytesIO
|
|
3
3
|
|
|
4
|
+
import requests
|
|
4
5
|
import torch
|
|
5
|
-
from typing import Optional
|
|
6
6
|
from PIL import Image
|
|
7
|
-
from io import BytesIO
|
|
8
7
|
from transformers import CLIPModel, CLIPProcessor
|
|
9
8
|
|
|
9
|
+
from ....utils import UserMessage
|
|
10
10
|
from ...base import Engine
|
|
11
11
|
from ...settings import SYMAI_CONFIG
|
|
12
12
|
|
|
13
|
-
|
|
14
13
|
# supress warnings
|
|
15
14
|
logging.getLogger("PIL").setLevel(logging.WARNING)
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
class CLIPEngine(Engine):
|
|
19
|
-
def __init__(self, model:
|
|
18
|
+
def __init__(self, model: str | None = None):
|
|
20
19
|
super().__init__()
|
|
21
|
-
self.model =
|
|
22
|
-
self.preprocessor = None
|
|
20
|
+
self.model = None # lazy loading
|
|
21
|
+
self.preprocessor = None # lazy loading
|
|
23
22
|
self.config = SYMAI_CONFIG
|
|
24
|
-
self.model_id = self.config[
|
|
25
|
-
self.old_model_id = self.config[
|
|
23
|
+
self.model_id = self.config["VISION_ENGINE_MODEL"] if model is None else model
|
|
24
|
+
self.old_model_id = self.config["VISION_ENGINE_MODEL"] if model is None else model
|
|
26
25
|
self.name = self.__class__.__name__
|
|
27
26
|
|
|
28
27
|
def id(self) -> str:
|
|
29
|
-
if self.config[
|
|
30
|
-
return
|
|
31
|
-
return super().id()
|
|
28
|
+
if self.config["VISION_ENGINE_MODEL"]:
|
|
29
|
+
return "text_vision"
|
|
30
|
+
return super().id() # default to unregistered
|
|
32
31
|
|
|
33
32
|
def command(self, *args, **kwargs):
|
|
34
33
|
super().command(*args, **kwargs)
|
|
35
|
-
if
|
|
36
|
-
self.model_id
|
|
34
|
+
if "VISION_ENGINE_MODEL" in kwargs:
|
|
35
|
+
self.model_id = kwargs["VISION_ENGINE_MODEL"]
|
|
37
36
|
|
|
38
37
|
def load_images(self, image):
|
|
39
38
|
images = []
|
|
@@ -44,38 +43,41 @@ class CLIPEngine(Engine):
|
|
|
44
43
|
if isinstance(img, bytes):
|
|
45
44
|
images.append(Image.open(BytesIO(img)))
|
|
46
45
|
elif isinstance(img, str):
|
|
47
|
-
if img.startswith(
|
|
48
|
-
|
|
49
|
-
else:
|
|
50
|
-
image_ = img
|
|
51
|
-
image = Image.open(image_)
|
|
46
|
+
image_source = requests.get(img, stream=True).raw if img.startswith("http") else img
|
|
47
|
+
image = Image.open(image_source)
|
|
52
48
|
images.append(image)
|
|
53
49
|
return images
|
|
54
50
|
|
|
55
51
|
def forward(self, argument):
|
|
56
|
-
image_url, text
|
|
52
|
+
image_url, text = argument.prop.prepared_input
|
|
57
53
|
|
|
58
54
|
if self.model is None or self.model_id != self.old_model_id:
|
|
59
|
-
self.device
|
|
60
|
-
self.model
|
|
61
|
-
self.processor
|
|
55
|
+
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
|
56
|
+
self.model = CLIPModel.from_pretrained(self.model_id).to(self.device)
|
|
57
|
+
self.processor = CLIPProcessor.from_pretrained(self.model_id)
|
|
62
58
|
self.old_model_id = self.model_id
|
|
63
59
|
|
|
64
60
|
if text is None and image_url is not None:
|
|
65
|
-
image
|
|
66
|
-
inputs
|
|
67
|
-
rsp
|
|
61
|
+
image = self.load_images(image_url)
|
|
62
|
+
inputs = self.processor(images=image, return_tensors="pt").to(self.device)
|
|
63
|
+
rsp = self.model.get_image_features(**inputs)
|
|
68
64
|
elif image_url is None and text is not None:
|
|
69
|
-
inputs
|
|
70
|
-
rsp
|
|
65
|
+
inputs = self.processor(text=text, return_tensors="pt").to(self.device)
|
|
66
|
+
rsp = self.model.get_text_features(**inputs)
|
|
71
67
|
elif image_url is not None and text is not None:
|
|
72
|
-
image
|
|
73
|
-
inputs
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
image = self.load_images(image_url)
|
|
69
|
+
inputs = self.processor(text=text, images=image, return_tensors="pt", padding=True).to(
|
|
70
|
+
self.device
|
|
71
|
+
)
|
|
72
|
+
outputs = self.model(**inputs)
|
|
73
|
+
logits_per_image = outputs.logits_per_image # this is the image-text similarity score
|
|
74
|
+
rsp = logits_per_image.softmax(
|
|
75
|
+
dim=1
|
|
76
|
+
) # we can take the softmax to get the label probabilities
|
|
77
77
|
else:
|
|
78
|
-
|
|
78
|
+
UserMessage(
|
|
79
|
+
"CLIPEngine requires either image or text input.", raise_with=NotImplementedError
|
|
80
|
+
)
|
|
79
81
|
|
|
80
82
|
rsp = rsp.squeeze().detach().cpu().numpy()
|
|
81
83
|
|
|
@@ -85,7 +87,7 @@ class CLIPEngine(Engine):
|
|
|
85
87
|
|
|
86
88
|
def prepare(self, argument):
|
|
87
89
|
assert not argument.prop.processed_input, "CLIPEngine does not support processed_input."
|
|
88
|
-
kwargs
|
|
89
|
-
image_url
|
|
90
|
-
text
|
|
90
|
+
kwargs = argument.kwargs
|
|
91
|
+
image_url = argument.kwargs["image"] if "image" in kwargs else None
|
|
92
|
+
text = argument.kwargs["text"] if "text" in kwargs else None
|
|
91
93
|
argument.prop.prepared_input = (image_url, text)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
1
|
+
from ....utils import UserMessage
|
|
3
2
|
from ...base import Engine
|
|
4
3
|
|
|
5
4
|
|
|
@@ -9,15 +8,15 @@ class UserInputEngine(Engine):
|
|
|
9
8
|
self.name = self.__class__.__name__
|
|
10
9
|
|
|
11
10
|
def id(self) -> str:
|
|
12
|
-
return
|
|
11
|
+
return "userinput"
|
|
13
12
|
|
|
14
13
|
def forward(self, argument):
|
|
15
14
|
msg = argument.prop.prepared_input
|
|
16
15
|
kwargs = argument.kwargs
|
|
17
16
|
|
|
18
|
-
mock = kwargs
|
|
19
|
-
if mock:
|
|
20
|
-
|
|
17
|
+
mock = kwargs.get("mock", False)
|
|
18
|
+
if mock: # mock user input
|
|
19
|
+
UserMessage(msg)
|
|
21
20
|
rsp = mock
|
|
22
21
|
else:
|
|
23
22
|
rsp = input(msg)
|
symai/backend/mixin/__init__.py
CHANGED
|
@@ -8,3 +8,16 @@ from .groq import SUPPORTED_CHAT_MODELS as GROQ_CHAT_MODELS
|
|
|
8
8
|
from .groq import SUPPORTED_REASONING_MODELS as GROQ_REASONING_MODELS
|
|
9
9
|
from .openai import SUPPORTED_CHAT_MODELS as OPENAI_CHAT_MODELS
|
|
10
10
|
from .openai import SUPPORTED_REASONING_MODELS as OPENAI_REASONING_MODELS
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"ANTHROPIC_CHAT_MODELS",
|
|
14
|
+
"ANTHROPIC_REASONING_MODELS",
|
|
15
|
+
"DEEPSEEK_CHAT_MODELS",
|
|
16
|
+
"DEEPSEEK_REASONING_MODELS",
|
|
17
|
+
"GOOGLE_CHAT_MODELS",
|
|
18
|
+
"GOOGLE_REASONING_MODELS",
|
|
19
|
+
"GROQ_CHAT_MODELS",
|
|
20
|
+
"GROQ_REASONING_MODELS",
|
|
21
|
+
"OPENAI_CHAT_MODELS",
|
|
22
|
+
"OPENAI_REASONING_MODELS",
|
|
23
|
+
]
|
symai/backend/mixin/anthropic.py
CHANGED
|
@@ -1,56 +1,66 @@
|
|
|
1
1
|
# https://docs.anthropic.com/en/docs/about-claude/models
|
|
2
2
|
SUPPORTED_CHAT_MODELS = [
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
"claude-3-5-sonnet-latest",
|
|
4
|
+
"claude-3-5-haiku-latest",
|
|
5
|
+
"claude-3-5-sonnet-20241022",
|
|
6
|
+
"claude-3-5-sonnet-20240620",
|
|
7
|
+
"claude-3-opus-latest",
|
|
8
|
+
"claude-3-opus-20240229",
|
|
9
|
+
"claude-3-sonnet-20240229",
|
|
10
|
+
"claude-3-haiku-20240307",
|
|
11
11
|
]
|
|
12
12
|
SUPPORTED_REASONING_MODELS = [
|
|
13
13
|
"claude-opus-4-1",
|
|
14
14
|
"claude-opus-4-0",
|
|
15
15
|
"claude-sonnet-4-0",
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
"claude-3-7-sonnet-latest",
|
|
17
|
+
"claude-haiku-4-5",
|
|
18
|
+
"claude-sonnet-4-5",
|
|
19
19
|
]
|
|
20
20
|
|
|
21
|
+
|
|
21
22
|
class AnthropicMixin:
|
|
22
23
|
def api_max_context_tokens(self):
|
|
23
|
-
if
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
24
|
+
if (
|
|
25
|
+
self.model == "claude-opus-4-1"
|
|
26
|
+
or self.model == "claude-opus-4-0"
|
|
27
|
+
or self.model == "claude-sonnet-4-0"
|
|
28
|
+
or self.model == "claude-3-7-sonnet-latest"
|
|
29
|
+
or self.model == "claude-haiku-4-5"
|
|
30
|
+
or self.model == "claude-sonnet-4-5"
|
|
31
|
+
or self.model == "claude-3-5-sonnet-latest"
|
|
32
|
+
or self.model == "claude-3-5-sonnet-20241022"
|
|
33
|
+
or self.model == "claude-3-5-sonnet-20240620"
|
|
34
|
+
or self.model == "claude-3-opus-latest"
|
|
35
|
+
or self.model == "claude-3-opus-20240229"
|
|
36
|
+
or self.model == "claude-3-sonnet-20240229"
|
|
37
|
+
or self.model == "claude-3-haiku-20240307"
|
|
38
|
+
):
|
|
36
39
|
return 200_000
|
|
40
|
+
return None
|
|
37
41
|
|
|
38
42
|
def api_max_response_tokens(self):
|
|
39
|
-
if
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
if (
|
|
44
|
+
self.model == "claude-sonnet-4-0"
|
|
45
|
+
or self.model == "claude-3-7-sonnet-latest"
|
|
46
|
+
or self.model == "claude-haiku-4-5"
|
|
47
|
+
or self.model == "claude-sonnet-4-5"
|
|
48
|
+
):
|
|
43
49
|
return 64_000
|
|
44
|
-
if self.model ==
|
|
45
|
-
self.model == 'claude-opus-4-0':
|
|
50
|
+
if self.model == "claude-opus-4-1" or self.model == "claude-opus-4-0":
|
|
46
51
|
return 32_000
|
|
47
|
-
if
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
if (
|
|
53
|
+
self.model == "claude-3-5-sonnet-latest"
|
|
54
|
+
or self.model == "claude-3-5-sonnet-20241022"
|
|
55
|
+
or self.model == "claude-3-5-haiku-latest"
|
|
56
|
+
):
|
|
50
57
|
return 8_192
|
|
51
|
-
if
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
if (
|
|
59
|
+
self.model == "claude-3-5-sonnet-20240620"
|
|
60
|
+
or self.model == "claude-3-opus-latest"
|
|
61
|
+
or self.model == "clade-3-opus-20240229"
|
|
62
|
+
or self.model == "claude-3-sonnet-20240229"
|
|
63
|
+
or self.model == "claude-3-haiku-20240307"
|
|
64
|
+
):
|
|
56
65
|
return 4_096
|
|
66
|
+
return None
|
symai/backend/mixin/deepseek.py
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# https://api-docs.deepseek.com/quick_start/pricing
|
|
2
2
|
SUPPORTED_CHAT_MODELS = []
|
|
3
|
-
SUPPORTED_REASONING_MODELS = [
|
|
4
|
-
|
|
5
|
-
]
|
|
3
|
+
SUPPORTED_REASONING_MODELS = ["deepseek-reasoner"]
|
|
4
|
+
|
|
6
5
|
|
|
7
6
|
class DeepSeekMixin:
|
|
8
7
|
def api_max_context_tokens(self):
|
|
9
|
-
if self.model ==
|
|
8
|
+
if self.model == "deepseek-reasoner":
|
|
10
9
|
return 64_000
|
|
10
|
+
return None
|
|
11
11
|
|
|
12
12
|
def api_max_response_tokens(self):
|
|
13
|
-
if self.model ==
|
|
13
|
+
if self.model == "deepseek-reasoner":
|
|
14
14
|
return 8_000
|
|
15
|
+
return None
|
symai/backend/mixin/google.py
CHANGED
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
SUPPORTED_CHAT_MODELS = []
|
|
3
3
|
SUPPORTED_REASONING_MODELS = [
|
|
4
4
|
# Check the latest snapshots; ie. *-06-05, etc
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
"gemini-2.5-pro",
|
|
6
|
+
"gemini-2.5-flash",
|
|
7
7
|
]
|
|
8
8
|
|
|
9
|
+
|
|
9
10
|
class GoogleMixin:
|
|
10
11
|
def api_max_context_tokens(self):
|
|
11
|
-
if self.model.startswith(
|
|
12
|
+
if self.model.startswith("gemini-2.5-"):
|
|
12
13
|
return 1_048_576
|
|
14
|
+
return None
|
|
13
15
|
|
|
14
16
|
def api_max_response_tokens(self):
|
|
15
|
-
if self.model ==
|
|
17
|
+
if self.model == "gemini-2.5-":
|
|
16
18
|
return 65_536
|
|
19
|
+
return None
|
symai/backend/mixin/groq.py
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
SUPPORTED_CHAT_MODELS = [
|
|
2
|
-
"groq:moonshotai/kimi-k2-instruct"
|
|
3
|
-
]
|
|
1
|
+
SUPPORTED_CHAT_MODELS = ["groq:moonshotai/kimi-k2-instruct"]
|
|
4
2
|
|
|
5
3
|
SUPPORTED_REASONING_MODELS = [
|
|
6
4
|
"groq:openai/gpt-oss-120b",
|
|
7
5
|
"groq:openai/gpt-oss-20b",
|
|
8
6
|
"groq:qwen/qwen3-32b",
|
|
9
|
-
"groq:deepseek-r1-distill-llama-70b"
|
|
7
|
+
"groq:deepseek-r1-distill-llama-70b",
|
|
10
8
|
]
|
symai/backend/mixin/openai.py
CHANGED
|
@@ -1,134 +1,164 @@
|
|
|
1
|
+
from ...utils import UserMessage
|
|
2
|
+
|
|
1
3
|
SUPPORTED_COMPLETION_MODELS = [
|
|
2
|
-
|
|
4
|
+
"davinci-002",
|
|
3
5
|
]
|
|
4
6
|
SUPPORTED_CHAT_MODELS = [
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
7
|
+
"gpt-3.5-turbo",
|
|
8
|
+
"gpt-3.5-turbo-16k",
|
|
9
|
+
"gpt-3.5-turbo-1106",
|
|
10
|
+
"gpt-3.5-turbo-0613",
|
|
11
|
+
"gpt-4",
|
|
12
|
+
"gpt-4-0613",
|
|
13
|
+
"gpt-4-1106-preview", # @NOTE: probabily obsolete; same price as 'gpt-4-turbo-2024-04-09' but no vision
|
|
14
|
+
"gpt-4-turbo",
|
|
15
|
+
"gpt-4-turbo-2024-04-09",
|
|
16
|
+
"gpt-4o",
|
|
17
|
+
"gpt-4o-2024-11-20",
|
|
18
|
+
"gpt-4o-mini",
|
|
19
|
+
"chatgpt-4o-latest",
|
|
20
|
+
"gpt-4.1",
|
|
21
|
+
"gpt-4.1-mini",
|
|
22
|
+
"gpt-4.1-nano",
|
|
23
|
+
"gpt-5-chat-latest",
|
|
24
|
+
"gpt-5.1-chat-latest",
|
|
22
25
|
]
|
|
23
26
|
SUPPORTED_REASONING_MODELS = [
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
"o3-mini",
|
|
28
|
+
"o4-mini",
|
|
29
|
+
"o1",
|
|
30
|
+
"o3",
|
|
31
|
+
"gpt-5",
|
|
32
|
+
"gpt-5.1",
|
|
33
|
+
"gpt-5-mini",
|
|
34
|
+
"gpt-5-nano",
|
|
31
35
|
]
|
|
32
36
|
SUPPORTED_EMBEDDING_MODELS = [
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
"text-embedding-ada-002",
|
|
38
|
+
"text-embedding-3-small",
|
|
39
|
+
"text-embedding-3-large",
|
|
36
40
|
]
|
|
37
41
|
|
|
38
42
|
|
|
39
43
|
class OpenAIMixin:
|
|
40
44
|
def api_max_context_tokens(self):
|
|
41
|
-
if
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
45
|
+
if (
|
|
46
|
+
self.model == "text-curie-001"
|
|
47
|
+
or self.model == "text-babbage-001"
|
|
48
|
+
or self.model == "text-ada-001"
|
|
49
|
+
or self.model == "davinci"
|
|
50
|
+
or self.model == "curie"
|
|
51
|
+
or self.model == "babbage"
|
|
52
|
+
or self.model == "ada"
|
|
53
|
+
):
|
|
54
|
+
return 2_049
|
|
55
|
+
if (
|
|
56
|
+
self.model == "gpt-3.5-turbo"
|
|
57
|
+
or self.model == "gpt-3.5-turbo-0613"
|
|
58
|
+
or self.model == "gpt-3.5-turbo-1106"
|
|
59
|
+
):
|
|
60
|
+
return 4_096
|
|
61
|
+
if (
|
|
62
|
+
self.model == "gpt-4"
|
|
63
|
+
or self.model == "gpt-4-0613"
|
|
64
|
+
or self.model == "text-embedding-ada-002"
|
|
65
|
+
or self.model == "text-embedding-3-small"
|
|
66
|
+
or self.model == "text-embedding-3-large"
|
|
67
|
+
):
|
|
68
|
+
return 8_192
|
|
69
|
+
if (
|
|
70
|
+
self.model == "gpt-3.5-turbo-16k"
|
|
71
|
+
or self.model == "gpt-3.5-turbo-16k-0613"
|
|
72
|
+
or self.model == "davinci-002"
|
|
73
|
+
):
|
|
74
|
+
return 16_384
|
|
75
|
+
if self.model == "gpt-4-32k" or self.model == "gpt-4-32k-0613":
|
|
76
|
+
return 32_768
|
|
77
|
+
if (
|
|
78
|
+
self.model == "gpt-4-1106-preview"
|
|
79
|
+
or self.model == "gpt-4-turbo-2024-04-09"
|
|
80
|
+
or self.model == "gpt-4-turbo"
|
|
81
|
+
or self.model == "gpt-4-1106"
|
|
82
|
+
or self.model == "gpt-4o"
|
|
83
|
+
or self.model == "gpt-4o-2024-11-20"
|
|
84
|
+
or self.model == "gpt-4o-mini"
|
|
85
|
+
or self.model == "chatgpt-4o-latest"
|
|
86
|
+
):
|
|
87
|
+
return 128_000
|
|
88
|
+
if (
|
|
89
|
+
self.model == "o1"
|
|
90
|
+
or self.model == "o3"
|
|
91
|
+
or self.model == "o3-mini"
|
|
92
|
+
or self.model == "o4-mini"
|
|
93
|
+
or self.model == "gpt-5-chat-latest"
|
|
94
|
+
or self.model == "gpt-5.1-chat-latest"
|
|
95
|
+
):
|
|
96
|
+
return 200_000
|
|
97
|
+
if (
|
|
98
|
+
self.model == "gpt-5"
|
|
99
|
+
or self.model == "gpt-5.1"
|
|
100
|
+
or self.model == "gpt-5-mini"
|
|
101
|
+
or self.model == "gpt-5-nano"
|
|
102
|
+
):
|
|
84
103
|
return 400_000
|
|
85
|
-
if self.model ==
|
|
86
|
-
self.model == 'gpt-4.1-mini' or \
|
|
87
|
-
self.model == 'gpt-4.1-nano':
|
|
104
|
+
if self.model == "gpt-4.1" or self.model == "gpt-4.1-mini" or self.model == "gpt-4.1-nano":
|
|
88
105
|
return 1_047_576
|
|
89
|
-
|
|
106
|
+
msg = f"Unsupported model: {self.model}"
|
|
107
|
+
UserMessage(msg)
|
|
108
|
+
raise ValueError(msg)
|
|
90
109
|
|
|
91
110
|
def api_max_response_tokens(self):
|
|
92
|
-
if self.model ==
|
|
111
|
+
if self.model == "davinci-002":
|
|
93
112
|
return 2_048
|
|
94
|
-
if
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
if (
|
|
114
|
+
self.model == "gpt-4-turbo"
|
|
115
|
+
or self.model == "gpt-4-turbo-2024-04-09"
|
|
116
|
+
or self.model == "gpt-4-1106-preview"
|
|
117
|
+
or self.model == "gpt-3.5-turbo-1106"
|
|
118
|
+
or self.model == "gpt-3.5-turbo-0613"
|
|
119
|
+
or self.model == "gpt-3.5-turbo"
|
|
120
|
+
):
|
|
121
|
+
return 4_096
|
|
122
|
+
if self.model == "gpt-4-0613" or self.model == "gpt-4":
|
|
123
|
+
return 8_192
|
|
124
|
+
if (
|
|
125
|
+
self.model == "gpt-3.5-turbo-16k-0613"
|
|
126
|
+
or self.model == "gpt-3.5-turbo-16k"
|
|
127
|
+
or self.model == "gpt-4o-mini"
|
|
128
|
+
or self.model == "gpt-4o"
|
|
129
|
+
or self.model == "gpt-4o-2024-11-20"
|
|
130
|
+
or self.model == "chatgpt-4o-latest"
|
|
131
|
+
or self.model == "gpt-5-chat-latest"
|
|
132
|
+
or self.model == "gpt-5.1-chat-latest"
|
|
133
|
+
):
|
|
134
|
+
return 16_384
|
|
135
|
+
if self.model == "gpt-4.1" or self.model == "gpt-4.1-mini" or self.model == "gpt-4.1-nano":
|
|
114
136
|
return 32_768
|
|
115
|
-
if
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
137
|
+
if (
|
|
138
|
+
self.model == "o1"
|
|
139
|
+
or self.model == "o3"
|
|
140
|
+
or self.model == "o3-mini"
|
|
141
|
+
or self.model == "o4-mini"
|
|
142
|
+
):
|
|
143
|
+
return 100_000
|
|
144
|
+
if (
|
|
145
|
+
self.model == "gpt-5"
|
|
146
|
+
or self.model == "gpt-5.1"
|
|
147
|
+
or self.model == "gpt-5-mini"
|
|
148
|
+
or self.model == "gpt-5-nano"
|
|
149
|
+
):
|
|
124
150
|
return 128_000
|
|
125
|
-
|
|
151
|
+
msg = f"Unsupported model: {self.model}"
|
|
152
|
+
UserMessage(msg)
|
|
153
|
+
raise ValueError(msg)
|
|
126
154
|
|
|
127
155
|
def api_embedding_dims(self):
|
|
128
|
-
if self.model ==
|
|
156
|
+
if self.model == "text-embedding-ada-002":
|
|
129
157
|
return 1_536
|
|
130
|
-
if self.model ==
|
|
158
|
+
if self.model == "text-embedding-3-small":
|
|
131
159
|
return 1_536
|
|
132
|
-
if self.model ==
|
|
160
|
+
if self.model == "text-embedding-3-large":
|
|
133
161
|
return 3_072
|
|
134
|
-
|
|
162
|
+
msg = f"Unsupported model: {self.model}"
|
|
163
|
+
UserMessage(msg)
|
|
164
|
+
raise ValueError(msg)
|