yaicli 0.6.0__py3-none-any.whl → 0.6.2__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.
- pyproject.toml +1 -1
- yaicli/llms/provider.py +12 -9
- yaicli/llms/providers/ai21_provider.py +13 -4
- yaicli/llms/providers/chatglm_provider.py +6 -1
- yaicli/llms/providers/chutes_provider.py +17 -0
- yaicli/llms/providers/deepseek_provider.py +6 -3
- yaicli/llms/providers/doubao_provider.py +24 -22
- yaicli/llms/providers/groq_provider.py +27 -5
- yaicli/llms/providers/infiniai_provider.py +7 -1
- yaicli/llms/providers/minimax_provider.py +21 -0
- yaicli/llms/providers/modelscope_provider.py +6 -3
- yaicli/llms/providers/openai_provider.py +84 -26
- yaicli/llms/providers/openrouter_provider.py +14 -3
- yaicli/llms/providers/sambanova_provider.py +37 -6
- yaicli/llms/providers/siliconflow_provider.py +6 -3
- yaicli/llms/providers/targon_provider.py +22 -0
- yaicli/llms/providers/xai_provider.py +7 -0
- yaicli/llms/providers/yi_provider.py +16 -1
- {yaicli-0.6.0.dist-info → yaicli-0.6.2.dist-info}/METADATA +11 -3
- yaicli-0.6.2.dist-info/RECORD +44 -0
- yaicli-0.6.0.dist-info/RECORD +0 -41
- {yaicli-0.6.0.dist-info → yaicli-0.6.2.dist-info}/WHEEL +0 -0
- {yaicli-0.6.0.dist-info → yaicli-0.6.2.dist-info}/entry_points.txt +0 -0
- {yaicli-0.6.0.dist-info → yaicli-0.6.2.dist-info}/licenses/LICENSE +0 -0
pyproject.toml
CHANGED
yaicli/llms/provider.py
CHANGED
@@ -9,7 +9,7 @@ class Provider(ABC):
|
|
9
9
|
"""Base abstract class for LLM providers"""
|
10
10
|
|
11
11
|
APP_NAME = "yaicli"
|
12
|
-
|
12
|
+
APP_REFERER = "https://github.com/halfrost/yaicli"
|
13
13
|
|
14
14
|
@abstractmethod
|
15
15
|
def completion(
|
@@ -39,21 +39,24 @@ class ProviderFactory:
|
|
39
39
|
"""Factory to create LLM provider instances"""
|
40
40
|
|
41
41
|
providers_map = {
|
42
|
-
"
|
43
|
-
"modelscope": (".providers.modelscope_provider", "ModelScopeProvider"),
|
42
|
+
"ai21": (".providers.ai21_provider", "AI21Provider"),
|
44
43
|
"chatglm": (".providers.chatglm_provider", "ChatglmProvider"),
|
45
|
-
"openrouter": (".providers.openrouter_provider", "OpenRouterProvider"),
|
46
|
-
"siliconflow": (".providers.siliconflow_provider", "SiliconFlowProvider"),
|
47
44
|
"chutes": (".providers.chutes_provider", "ChutesProvider"),
|
48
|
-
"
|
49
|
-
"yi": (".providers.yi_provider", "YiProvider"),
|
45
|
+
"cohere": (".providers.cohere_provider", "CohereProvider"),
|
50
46
|
"deepseek": (".providers.deepseek_provider", "DeepSeekProvider"),
|
51
47
|
"doubao": (".providers.doubao_provider", "DoubaoProvider"),
|
52
48
|
"groq": (".providers.groq_provider", "GroqProvider"),
|
53
|
-
"
|
49
|
+
"infini-ai": (".providers.infiniai_provider", "InfiniAIProvider"),
|
50
|
+
"minimax": (".providers.minimax_provider", "MinimaxProvider"),
|
51
|
+
"modelscope": (".providers.modelscope_provider", "ModelScopeProvider"),
|
54
52
|
"ollama": (".providers.ollama_provider", "OllamaProvider"),
|
55
|
-
"
|
53
|
+
"openai": (".providers.openai_provider", "OpenAIProvider"),
|
54
|
+
"openrouter": (".providers.openrouter_provider", "OpenRouterProvider"),
|
56
55
|
"sambanova": (".providers.sambanova_provider", "SambanovaProvider"),
|
56
|
+
"siliconflow": (".providers.siliconflow_provider", "SiliconFlowProvider"),
|
57
|
+
"targon": (".providers.targon_provider", "TargonProvider"),
|
58
|
+
"xai": (".providers.xai_provider", "XaiProvider"),
|
59
|
+
"yi": (".providers.yi_provider", "YiProvider"),
|
57
60
|
}
|
58
61
|
|
59
62
|
@classmethod
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Generator, Optional
|
1
|
+
from typing import Dict, Generator, Optional
|
2
2
|
|
3
3
|
from openai._streaming import Stream
|
4
4
|
from openai.types.chat.chat_completion_chunk import ChatCompletionChunk
|
@@ -12,9 +12,18 @@ class AI21Provider(OpenAIProvider):
|
|
12
12
|
|
13
13
|
DEFAULT_BASE_URL = "https://api.ai21.com/studio/v1"
|
14
14
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
15
|
+
def get_completion_params_keys(self) -> Dict[str, str]:
|
16
|
+
"""
|
17
|
+
Customize completion parameter keys for AI21 API.
|
18
|
+
Maps 'max_completion_tokens' to 'max_tokens' for compatibility.
|
19
|
+
|
20
|
+
Returns:
|
21
|
+
Dict[str, str]: Modified parameter mapping dictionary
|
22
|
+
"""
|
23
|
+
keys = super().get_completion_params_keys()
|
24
|
+
if "max_completion_tokens" in keys:
|
25
|
+
keys["max_tokens"] = keys.pop("max_completion_tokens")
|
26
|
+
return keys
|
18
27
|
|
19
28
|
def _handle_stream_response(self, response: Stream[ChatCompletionChunk]) -> Generator[LLMResponse, None, None]:
|
20
29
|
"""Handle streaming response from AI21 models
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import json
|
2
|
-
from typing import Generator, Optional
|
2
|
+
from typing import Any, Dict, Generator, Optional
|
3
3
|
|
4
4
|
from openai._streaming import Stream
|
5
5
|
from openai.types.chat.chat_completion import ChatCompletion, Choice
|
@@ -14,6 +14,11 @@ class ChatglmProvider(OpenAIProvider):
|
|
14
14
|
|
15
15
|
DEFAULT_BASE_URL = "https://open.bigmodel.cn/api/paas/v4/"
|
16
16
|
|
17
|
+
def get_completion_params(self) -> Dict[str, Any]:
|
18
|
+
params = super().get_completion_params()
|
19
|
+
params["max_tokens"] = params.pop("max_completion_tokens")
|
20
|
+
return params
|
21
|
+
|
17
22
|
def _handle_normal_response(self, response: ChatCompletion) -> Generator[LLMResponse, None, None]:
|
18
23
|
"""Handle normal (non-streaming) response
|
19
24
|
Support both openai capabilities and chatglm
|
@@ -5,3 +5,20 @@ class ChutesProvider(OpenAIProvider):
|
|
5
5
|
"""Chutes provider implementation based on openai-compatible API"""
|
6
6
|
|
7
7
|
DEFAULT_BASE_URL = "https://llm.chutes.ai/v1"
|
8
|
+
|
9
|
+
def get_completion_params_keys(self) -> dict:
|
10
|
+
"""
|
11
|
+
Customize completion parameter keys for Chutes API.
|
12
|
+
Maps 'max_completion_tokens' to 'max_tokens' and removes 'reasoning_effort'
|
13
|
+
which is not supported by this provider.
|
14
|
+
|
15
|
+
Returns:
|
16
|
+
dict: Modified parameter mapping dictionary
|
17
|
+
"""
|
18
|
+
keys = super().get_completion_params_keys()
|
19
|
+
# Replace max_completion_tokens with max_tokens in the API
|
20
|
+
if "max_completion_tokens" in keys:
|
21
|
+
keys["max_tokens"] = keys.pop("max_completion_tokens")
|
22
|
+
# Remove unsupported parameters
|
23
|
+
keys.pop("reasoning_effort", None)
|
24
|
+
return keys
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
1
3
|
from .openai_provider import OpenAIProvider
|
2
4
|
|
3
5
|
|
@@ -6,6 +8,7 @@ class DeepSeekProvider(OpenAIProvider):
|
|
6
8
|
|
7
9
|
DEFAULT_BASE_URL = "https://api.deepseek.com/v1"
|
8
10
|
|
9
|
-
def
|
10
|
-
super().
|
11
|
-
|
11
|
+
def get_completion_params(self) -> Dict[str, Any]:
|
12
|
+
params = super().get_completion_params()
|
13
|
+
params["max_tokens"] = params.pop("max_completion_tokens")
|
14
|
+
return params
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
1
3
|
from volcenginesdkarkruntime import Ark
|
2
4
|
|
3
5
|
from ...config import cfg
|
@@ -9,43 +11,43 @@ class DoubaoProvider(OpenAIProvider):
|
|
9
11
|
"""Doubao provider implementation based on openai-compatible API"""
|
10
12
|
|
11
13
|
DEFAULT_BASE_URL = "https://ark.cn-beijing.volces.com/api/v3"
|
14
|
+
CLIENT_CLS = Ark
|
12
15
|
|
13
16
|
def __init__(self, config: dict = cfg, **kwargs):
|
14
17
|
self.config = config
|
15
18
|
self.enable_function = self.config["ENABLE_FUNCTIONS"]
|
19
|
+
self.client_params = self.get_client_params()
|
20
|
+
|
21
|
+
# Initialize client
|
22
|
+
self.client = self.CLIENT_CLS(**self.client_params)
|
23
|
+
self.console = get_console()
|
24
|
+
|
25
|
+
# Store completion params
|
26
|
+
self.completion_params = self.get_completion_params()
|
27
|
+
|
28
|
+
def get_client_params(self) -> Dict[str, Any]:
|
16
29
|
# Initialize client params
|
17
|
-
|
30
|
+
client_params = {"base_url": self.DEFAULT_BASE_URL}
|
18
31
|
if self.config.get("API_KEY", None):
|
19
|
-
|
32
|
+
client_params["api_key"] = self.config["API_KEY"]
|
20
33
|
if self.config.get("BASE_URL", None):
|
21
|
-
|
34
|
+
client_params["base_url"] = self.config["BASE_URL"]
|
22
35
|
if self.config.get("AK", None):
|
23
|
-
|
36
|
+
client_params["ak"] = self.config["AK"]
|
24
37
|
if self.config.get("SK", None):
|
25
|
-
|
38
|
+
client_params["sk"] = self.config["SK"]
|
26
39
|
if self.config.get("REGION", None):
|
27
|
-
|
40
|
+
client_params["region"] = self.config["REGION"]
|
41
|
+
return client_params
|
28
42
|
|
29
|
-
|
30
|
-
|
31
|
-
self.console = get_console()
|
32
|
-
|
33
|
-
# Store completion params
|
34
|
-
self.completion_params = {
|
43
|
+
def get_completion_params(self) -> Dict[str, Any]:
|
44
|
+
params = {
|
35
45
|
"model": self.config["MODEL"],
|
36
46
|
"temperature": self.config["TEMPERATURE"],
|
37
47
|
"top_p": self.config["TOP_P"],
|
38
48
|
"max_tokens": self.config["MAX_TOKENS"],
|
39
49
|
"timeout": self.config["TIMEOUT"],
|
40
50
|
}
|
41
|
-
# Add extra headers if set
|
42
|
-
if self.config.get("EXTRA_HEADERS", None):
|
43
|
-
self.completion_params["extra_headers"] = {
|
44
|
-
**self.config["EXTRA_HEADERS"],
|
45
|
-
"X-Title": self.APP_NAME,
|
46
|
-
"HTTP-Referer": self.APPA_REFERER,
|
47
|
-
}
|
48
|
-
|
49
|
-
# Add extra body params if set
|
50
51
|
if self.config.get("EXTRA_BODY", None):
|
51
|
-
|
52
|
+
params["extra_body"] = self.config["EXTRA_BODY"]
|
53
|
+
return params
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
1
3
|
from .openai_provider import OpenAIProvider
|
2
4
|
|
3
5
|
|
@@ -6,9 +8,29 @@ class GroqProvider(OpenAIProvider):
|
|
6
8
|
|
7
9
|
DEFAULT_BASE_URL = "https://api.groq.com/openai/v1"
|
8
10
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
11
|
+
def get_completion_params_keys(self) -> Dict[str, str]:
|
12
|
+
"""
|
13
|
+
Customize completion parameter keys for Groq API.
|
14
|
+
Maps 'max_completion_tokens' to 'max_tokens' for compatibility.
|
15
|
+
|
16
|
+
Returns:
|
17
|
+
Dict[str, str]: Modified parameter mapping dictionary
|
18
|
+
"""
|
19
|
+
keys = super().get_completion_params_keys()
|
20
|
+
if "max_completion_tokens" in keys:
|
21
|
+
keys["max_tokens"] = keys.pop("max_completion_tokens")
|
22
|
+
return keys
|
23
|
+
|
24
|
+
def get_completion_params(self) -> Dict[str, Any]:
|
25
|
+
"""
|
26
|
+
Get completion parameters with Groq-specific adjustments.
|
27
|
+
Enforce N=1 as Groq doesn't support multiple completions.
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
Dict[str, Any]: Parameters for completion API call
|
31
|
+
"""
|
32
|
+
params = super().get_completion_params()
|
33
|
+
if self.config["EXTRA_BODY"] and "N" in self.config["EXTRA_BODY"] and self.config["EXTRA_BODY"]["N"] != 1:
|
12
34
|
self.console.print("Groq does not support N parameter, setting N to 1 as Groq default", style="yellow")
|
13
|
-
|
14
|
-
|
35
|
+
params["extra_body"]["N"] = 1
|
36
|
+
return params
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
1
3
|
from .openai_provider import OpenAIProvider
|
2
4
|
|
3
5
|
|
@@ -11,4 +13,8 @@ class InfiniAIProvider(OpenAIProvider):
|
|
11
13
|
if self.enable_function:
|
12
14
|
self.console.print("InfiniAI does not support functions, disabled", style="yellow")
|
13
15
|
self.enable_function = False
|
14
|
-
|
16
|
+
|
17
|
+
def get_completion_params(self) -> Dict[str, Any]:
|
18
|
+
params = super().get_completion_params()
|
19
|
+
params["max_tokens"] = params.pop("max_completion_tokens")
|
20
|
+
return params
|
@@ -0,0 +1,21 @@
|
|
1
|
+
from .openai_provider import OpenAIProvider
|
2
|
+
|
3
|
+
|
4
|
+
class MinimaxProvider(OpenAIProvider):
|
5
|
+
"""Minimax provider implementation based on openai-compatible API"""
|
6
|
+
|
7
|
+
DEFAULT_BASE_URL = "https://api.minimaxi.com/v1"
|
8
|
+
|
9
|
+
def get_completion_params_keys(self) -> dict:
|
10
|
+
"""
|
11
|
+
Customize completion parameter keys for Minimax API.
|
12
|
+
Maps 'max_completion_tokens' to 'max_tokens' for compatibility.
|
13
|
+
|
14
|
+
Returns:
|
15
|
+
dict: Modified parameter mapping dictionary
|
16
|
+
"""
|
17
|
+
keys = super().get_completion_params_keys()
|
18
|
+
# Replace max_completion_tokens with max_tokens in the API
|
19
|
+
if "max_completion_tokens" in keys:
|
20
|
+
keys["max_tokens"] = keys.pop("max_completion_tokens")
|
21
|
+
return keys
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
1
3
|
from .openai_provider import OpenAIProvider
|
2
4
|
|
3
5
|
|
@@ -6,6 +8,7 @@ class ModelScopeProvider(OpenAIProvider):
|
|
6
8
|
|
7
9
|
DEFAULT_BASE_URL = "https://api-inference.modelscope.cn/v1/"
|
8
10
|
|
9
|
-
def
|
10
|
-
super().
|
11
|
-
|
11
|
+
def get_completion_params(self) -> Dict[str, Any]:
|
12
|
+
params = super().get_completion_params()
|
13
|
+
params["max_tokens"] = params.pop("max_completion_tokens")
|
14
|
+
return params
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import json
|
1
2
|
from typing import Any, Dict, Generator, List, Optional
|
2
3
|
|
3
4
|
import openai
|
@@ -16,41 +17,73 @@ class OpenAIProvider(Provider):
|
|
16
17
|
"""OpenAI provider implementation based on openai library"""
|
17
18
|
|
18
19
|
DEFAULT_BASE_URL = "https://api.openai.com/v1"
|
20
|
+
CLIENT_CLS = openai.OpenAI
|
21
|
+
# Base mapping between config keys and API parameter names
|
22
|
+
_BASE_COMPLETION_PARAMS_KEYS = {
|
23
|
+
"model": "MODEL",
|
24
|
+
"temperature": "TEMPERATURE",
|
25
|
+
"top_p": "TOP_P",
|
26
|
+
"max_completion_tokens": "MAX_TOKENS",
|
27
|
+
"timeout": "TIMEOUT",
|
28
|
+
"extra_body": "EXTRA_BODY",
|
29
|
+
"reasoning_effort": "REASONING_EFFORT",
|
30
|
+
}
|
19
31
|
|
20
32
|
def __init__(self, config: dict = cfg, verbose: bool = False, **kwargs):
|
21
33
|
self.config = config
|
34
|
+
if not self.config.get("API_KEY"):
|
35
|
+
raise ValueError("API_KEY is required")
|
22
36
|
self.enable_function = self.config["ENABLE_FUNCTIONS"]
|
23
37
|
self.verbose = verbose
|
38
|
+
|
39
|
+
# Initialize client
|
40
|
+
self.client_params = self.get_client_params()
|
41
|
+
self.client = self.CLIENT_CLS(**self.client_params)
|
42
|
+
self.console = get_console()
|
43
|
+
|
44
|
+
# Store completion params
|
45
|
+
self.completion_params = self.get_completion_params()
|
46
|
+
|
47
|
+
def get_client_params(self) -> Dict[str, Any]:
|
48
|
+
"""Get the client parameters"""
|
24
49
|
# Initialize client params
|
25
|
-
|
50
|
+
client_params = {
|
26
51
|
"api_key": self.config["API_KEY"],
|
27
52
|
"base_url": self.config["BASE_URL"] or self.DEFAULT_BASE_URL,
|
28
53
|
}
|
29
54
|
|
30
55
|
# Add extra headers if set
|
31
56
|
if self.config["EXTRA_HEADERS"]:
|
32
|
-
|
57
|
+
client_params["default_headers"] = {
|
33
58
|
**self.config["EXTRA_HEADERS"],
|
34
59
|
"X-Title": self.APP_NAME,
|
35
|
-
"HTTP-Referer": self.
|
60
|
+
"HTTP-Referer": self.APP_REFERER,
|
36
61
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
62
|
+
return client_params
|
63
|
+
|
64
|
+
def get_completion_params_keys(self) -> Dict[str, str]:
|
65
|
+
"""
|
66
|
+
Get the mapping between completion parameter keys and config keys.
|
67
|
+
Subclasses can override this method to customize parameter mapping.
|
68
|
+
|
69
|
+
Returns:
|
70
|
+
Dict[str, str]: Mapping from API parameter names to config keys
|
71
|
+
"""
|
72
|
+
return self._BASE_COMPLETION_PARAMS_KEYS.copy()
|
73
|
+
|
74
|
+
def get_completion_params(self) -> Dict[str, Any]:
|
75
|
+
"""
|
76
|
+
Get the completion parameters based on config and parameter mapping.
|
77
|
+
|
78
|
+
Returns:
|
79
|
+
Dict[str, Any]: Parameters for completion API call
|
80
|
+
"""
|
81
|
+
completion_params = {}
|
82
|
+
params_keys = self.get_completion_params_keys()
|
83
|
+
for api_key, config_key in params_keys.items():
|
84
|
+
if self.config.get(config_key, None) is not None:
|
85
|
+
completion_params[api_key] = self.config[config_key]
|
86
|
+
return completion_params
|
54
87
|
|
55
88
|
def _convert_messages(self, messages: List[ChatMessage]) -> List[Dict[str, Any]]:
|
56
89
|
"""Convert a list of ChatMessage objects to a list of OpenAI message dicts."""
|
@@ -79,7 +112,20 @@ class OpenAIProvider(Provider):
|
|
79
112
|
messages: List[ChatMessage],
|
80
113
|
stream: bool = False,
|
81
114
|
) -> Generator[LLMResponse, None, None]:
|
82
|
-
"""
|
115
|
+
"""
|
116
|
+
Send completion request to OpenAI and return responses.
|
117
|
+
|
118
|
+
Args:
|
119
|
+
messages: List of chat messages to send
|
120
|
+
stream: Whether to stream the response
|
121
|
+
|
122
|
+
Yields:
|
123
|
+
LLMResponse: Response objects containing content, tool calls, etc.
|
124
|
+
|
125
|
+
Raises:
|
126
|
+
ValueError: If messages is empty or invalid
|
127
|
+
openai.APIError: If API request fails
|
128
|
+
"""
|
83
129
|
openai_messages = self._convert_messages(messages)
|
84
130
|
if self.verbose:
|
85
131
|
self.console.print("Messages:")
|
@@ -103,6 +149,11 @@ class OpenAIProvider(Provider):
|
|
103
149
|
|
104
150
|
def _handle_normal_response(self, response: ChatCompletion) -> Generator[LLMResponse, None, None]:
|
105
151
|
"""Handle normal (non-streaming) response"""
|
152
|
+
if not response.choices:
|
153
|
+
yield LLMResponse(
|
154
|
+
content=json.dumps(getattr(response, "base_resp", None) or response.to_dict()), finish_reason="stop"
|
155
|
+
)
|
156
|
+
return
|
106
157
|
choice = response.choices[0]
|
107
158
|
content = choice.message.content or "" # type: ignore
|
108
159
|
reasoning = choice.message.reasoning_content # type: ignore
|
@@ -124,15 +175,22 @@ class OpenAIProvider(Provider):
|
|
124
175
|
"""Handle streaming response from OpenAI API"""
|
125
176
|
# Initialize tool call object to accumulate tool call data across chunks
|
126
177
|
tool_call: Optional[ToolCall] = None
|
127
|
-
|
178
|
+
started = False
|
128
179
|
# Process each chunk in the response stream
|
129
180
|
for chunk in response:
|
130
|
-
if not chunk.choices:
|
181
|
+
if not chunk.choices and not started:
|
182
|
+
# Some api could return error message in the first chunk, no choices to handle, return raw response to show the message
|
183
|
+
yield LLMResponse(
|
184
|
+
content=json.dumps(getattr(chunk, "base_resp", None) or chunk.to_dict()), finish_reason="stop"
|
185
|
+
)
|
186
|
+
started = True
|
131
187
|
continue
|
132
188
|
|
133
|
-
|
134
|
-
|
135
|
-
|
189
|
+
if not chunk.choices:
|
190
|
+
continue
|
191
|
+
started = True
|
192
|
+
delta = chunk.choices[0].delta
|
193
|
+
finish_reason = chunk.choices[0].finish_reason
|
136
194
|
|
137
195
|
# Extract content from current chunk
|
138
196
|
content = delta.content or ""
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Dict
|
2
|
+
|
1
3
|
from .openai_provider import OpenAIProvider
|
2
4
|
|
3
5
|
|
@@ -6,6 +8,15 @@ class OpenRouterProvider(OpenAIProvider):
|
|
6
8
|
|
7
9
|
DEFAULT_BASE_URL = "https://openrouter.ai/api/v1"
|
8
10
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
11
|
+
def get_completion_params_keys(self) -> Dict[str, str]:
|
12
|
+
"""
|
13
|
+
Customize completion parameter keys for OpenRouter API.
|
14
|
+
Maps 'max_completion_tokens' to 'max_tokens' for compatibility.
|
15
|
+
|
16
|
+
Returns:
|
17
|
+
Dict[str, str]: Modified parameter mapping dictionary
|
18
|
+
"""
|
19
|
+
keys = super().get_completion_params_keys()
|
20
|
+
if "max_completion_tokens" in keys:
|
21
|
+
keys["max_tokens"] = keys.pop("max_completion_tokens")
|
22
|
+
return keys
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
1
3
|
from ...const import DEFAULT_TEMPERATURE
|
2
4
|
from .openai_provider import OpenAIProvider
|
3
5
|
|
@@ -14,15 +16,44 @@ class SambanovaProvider(OpenAIProvider):
|
|
14
16
|
"DeepSeek-V3-0324",
|
15
17
|
)
|
16
18
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def get_completion_params_keys(self) -> Dict[str, str]:
|
20
|
+
"""
|
21
|
+
Customize completion parameter keys for Sambanova API.
|
22
|
+
Maps 'max_completion_tokens' to 'max_tokens' for compatibility
|
23
|
+
and removes parameters not supported by Sambanova.
|
24
|
+
|
25
|
+
Returns:
|
26
|
+
Dict[str, str]: Modified parameter mapping dictionary
|
27
|
+
"""
|
28
|
+
keys = super().get_completion_params_keys()
|
29
|
+
# Replace max_completion_tokens with max_tokens
|
30
|
+
if "max_completion_tokens" in keys:
|
31
|
+
keys["max_tokens"] = keys.pop("max_completion_tokens")
|
32
|
+
# Remove unsupported parameters
|
33
|
+
keys.pop("presence_penalty", None)
|
34
|
+
keys.pop("frequency_penalty", None)
|
35
|
+
return keys
|
36
|
+
|
37
|
+
def get_completion_params(self) -> Dict[str, Any]:
|
38
|
+
"""
|
39
|
+
Get completion parameters with Sambanova-specific adjustments.
|
40
|
+
Validate temperature range and check for function call compatibility.
|
41
|
+
|
42
|
+
Returns:
|
43
|
+
Dict[str, Any]: Parameters for completion API call
|
44
|
+
"""
|
45
|
+
params = super().get_completion_params()
|
46
|
+
|
47
|
+
# Validate temperature
|
48
|
+
if params.get("temperature") is not None and (params["temperature"] < 0 or params["temperature"] > 1):
|
22
49
|
self.console.print("Sambanova temperature must be between 0 and 1, setting to 0.4", style="yellow")
|
23
|
-
|
50
|
+
params["temperature"] = DEFAULT_TEMPERATURE
|
51
|
+
|
52
|
+
# Check function call compatibility
|
24
53
|
if self.enable_function and self.config["MODEL"] not in self.SUPPORT_FUNCTION_CALL_MOELS:
|
25
54
|
self.console.print(
|
26
55
|
f"Sambanova supports function call models: {', '.join(self.SUPPORT_FUNCTION_CALL_MOELS)}",
|
27
56
|
style="yellow",
|
28
57
|
)
|
58
|
+
|
59
|
+
return params
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
1
3
|
from .openai_provider import OpenAIProvider
|
2
4
|
|
3
5
|
|
@@ -6,6 +8,7 @@ class SiliconFlowProvider(OpenAIProvider):
|
|
6
8
|
|
7
9
|
DEFAULT_BASE_URL = "https://api.siliconflow.cn/v1"
|
8
10
|
|
9
|
-
def
|
10
|
-
super().
|
11
|
-
|
11
|
+
def get_completion_params(self) -> Dict[str, Any]:
|
12
|
+
params = super().get_completion_params()
|
13
|
+
params["max_tokens"] = params.pop("max_completion_tokens")
|
14
|
+
return params
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from typing import Dict
|
2
|
+
|
3
|
+
from .openai_provider import OpenAIProvider
|
4
|
+
|
5
|
+
|
6
|
+
class TargonProvider(OpenAIProvider):
|
7
|
+
"""Targon provider implementation based on openai-compatible API"""
|
8
|
+
|
9
|
+
DEFAULT_BASE_URL = "https://api.targon.com/v1"
|
10
|
+
|
11
|
+
def get_completion_params_keys(self) -> Dict[str, str]:
|
12
|
+
"""
|
13
|
+
Customize completion parameter keys for Targon API.
|
14
|
+
Maps 'max_completion_tokens' to 'max_tokens' for compatibility.
|
15
|
+
|
16
|
+
Returns:
|
17
|
+
Dict[str, str]: Modified parameter mapping dictionary
|
18
|
+
"""
|
19
|
+
keys = super().get_completion_params_keys()
|
20
|
+
if "max_completion_tokens" in keys:
|
21
|
+
keys["max_tokens"] = keys.pop("max_completion_tokens")
|
22
|
+
return keys
|
@@ -1,7 +1,22 @@
|
|
1
|
+
from typing import Dict
|
2
|
+
|
1
3
|
from .openai_provider import OpenAIProvider
|
2
4
|
|
3
5
|
|
4
6
|
class YiProvider(OpenAIProvider):
|
5
|
-
"""
|
7
|
+
"""Lingyiwanwu provider implementation based on openai-compatible API"""
|
6
8
|
|
7
9
|
DEFAULT_BASE_URL = "https://api.lingyiwanwu.com/v1"
|
10
|
+
|
11
|
+
def get_completion_params_keys(self) -> Dict[str, str]:
|
12
|
+
"""
|
13
|
+
Customize completion parameter keys for Yi API.
|
14
|
+
Maps 'max_completion_tokens' to 'max_tokens' for compatibility.
|
15
|
+
|
16
|
+
Returns:
|
17
|
+
Dict[str, str]: Modified parameter mapping dictionary
|
18
|
+
"""
|
19
|
+
keys = super().get_completion_params_keys()
|
20
|
+
if "max_completion_tokens" in keys:
|
21
|
+
keys["max_tokens"] = keys.pop("max_completion_tokens")
|
22
|
+
return keys
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: yaicli
|
3
|
-
Version: 0.6.
|
3
|
+
Version: 0.6.2
|
4
4
|
Summary: A simple CLI tool to interact with LLM
|
5
5
|
Project-URL: Homepage, https://github.com/belingud/yaicli
|
6
6
|
Project-URL: Repository, https://github.com/belingud/yaicli
|
@@ -375,7 +375,7 @@ settings, just as below:
|
|
375
375
|
```ini
|
376
376
|
[core]
|
377
377
|
PROVIDER=openai
|
378
|
-
BASE_URL=
|
378
|
+
BASE_URL=
|
379
379
|
API_KEY=
|
380
380
|
MODEL=gpt-4o
|
381
381
|
|
@@ -387,7 +387,7 @@ OS_NAME=auto
|
|
387
387
|
STREAM=true
|
388
388
|
|
389
389
|
# LLM parameters
|
390
|
-
TEMPERATURE=0.
|
390
|
+
TEMPERATURE=0.3
|
391
391
|
TOP_P=1.0
|
392
392
|
MAX_TOKENS=1024
|
393
393
|
TIMEOUT=60
|
@@ -518,6 +518,14 @@ API_KEY=
|
|
518
518
|
MODEL=llama-3.3-70b-versatile
|
519
519
|
```
|
520
520
|
|
521
|
+
#### XAI
|
522
|
+
|
523
|
+
```ini
|
524
|
+
PROVIDER=xai
|
525
|
+
API_KEY=
|
526
|
+
MODEL=grok-3
|
527
|
+
```
|
528
|
+
|
521
529
|
#### Chatglm
|
522
530
|
|
523
531
|
```ini
|
@@ -0,0 +1,44 @@
|
|
1
|
+
pyproject.toml,sha256=xXPLxBBTEBHwusE6ko3ASXLhV3a5FV26eHNRAzkQzwc,2434
|
2
|
+
yaicli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
yaicli/chat.py,sha256=_emvZEdgMBth2nQGaNWPf0P45oW2k3bpuIwqsxFcM5A,13676
|
4
|
+
yaicli/cli.py,sha256=YUKbtvRcNbe6iTmm0dx-38QDzzrAP4cOYaOChxpJ2wg,23673
|
5
|
+
yaicli/config.py,sha256=HrWYcelLXE61XX719eVcuuo3292xxf1BNQznWdvjQFQ,6535
|
6
|
+
yaicli/console.py,sha256=vARPJd-3lafutsQWrGntQVjLrYqaJD3qisN82pmuhjU,1973
|
7
|
+
yaicli/const.py,sha256=jC01jLLuuYJ7K_QaekXkIN7j1bIKCoGwJeTpquJy55Q,8178
|
8
|
+
yaicli/entry.py,sha256=Q1eqLE7tcHide7ooyPO7OCJpKE2YVuxR-NNFA2Pt2Hw,8693
|
9
|
+
yaicli/exceptions.py,sha256=WBYg8OTJJzaj7lt6HE7ZyBoe5T6A3yZRNCRfWd4iN0c,372
|
10
|
+
yaicli/history.py,sha256=s-57X9FMsaQHF7XySq1gGH_jpd_cHHTYafYu2ECuG6M,2472
|
11
|
+
yaicli/printer.py,sha256=g1TS7aDSQlWlSrQRhvNhNqoQKlsaf1lVOyUSK6LQLNQ,7945
|
12
|
+
yaicli/render.py,sha256=k8o2P8fI44PJlyQbs7gmMiu2x2prwajdWn5JIt15BIA,505
|
13
|
+
yaicli/role.py,sha256=PfwiVJIlzg7EzlvMM-kIy6vBK0d5d_J4M1I_fIZGnWk,7399
|
14
|
+
yaicli/schemas.py,sha256=Ty2ybCvld-ritgBZoI3RR93vYfw9LUNqkR8xk8VRZ2A,762
|
15
|
+
yaicli/tools.py,sha256=xw8KEs_xlSf79A2Aq1rAsUWahS6A_e5QMLt7QDXL5bs,5086
|
16
|
+
yaicli/utils.py,sha256=bpo3Xhozpxsaci3FtEIKZ32l4ZdyWMsrHjYGX0tB4J4,4541
|
17
|
+
yaicli/functions/__init__.py,sha256=_FJooQ9GkijG8xLwuU0cr5GBrGnC9Nc6bnCeUjrsT0k,1271
|
18
|
+
yaicli/functions/buildin/execute_shell_command.py,sha256=unl1-F8p6QZajeHdA0u5UpURMJM0WhdWMUWCCCHVRcI,1320
|
19
|
+
yaicli/llms/__init__.py,sha256=cN54nu-YalZipXjLW0YAAe0rRv0tXAQ8lLi1ohuTpao,363
|
20
|
+
yaicli/llms/client.py,sha256=mkE9KHSuPcJfpNQXbzF2YXGkel3jrOW8KfQ3YYpaK4M,4453
|
21
|
+
yaicli/llms/provider.py,sha256=ey8PCq5IS6E9YleErVw_j6GtudtOawhFVBt3X8Be51U,3017
|
22
|
+
yaicli/llms/providers/ai21_provider.py,sha256=SvgGj9_87KEqmxCMLbtsSkT8J3rUD7Mb21UF7pMWsks,3035
|
23
|
+
yaicli/llms/providers/chatglm_provider.py,sha256=1xP4KVAi6SDKZ-lMi2wdzywtDydsTf6jDzh3jBBGMfA,6437
|
24
|
+
yaicli/llms/providers/chutes_provider.py,sha256=mtvWvRRfHPH3JFfzym87wXtPNiMpLnur3805N9acx7E,882
|
25
|
+
yaicli/llms/providers/cohere_provider.py,sha256=hc6vQxbCHz9kM2tNKK-kGkuOf4-gkskXW9ctr9V4Cxk,10837
|
26
|
+
yaicli/llms/providers/deepseek_provider.py,sha256=VjGes_jFin5WGYNFxYKMoHwgAQX_eYbYhQKfjeh-9eI,438
|
27
|
+
yaicli/llms/providers/doubao_provider.py,sha256=4eOdE91ITUn3uo3mvYAzdrHsuFIIBwZWib21mtZn8OY,1938
|
28
|
+
yaicli/llms/providers/groq_provider.py,sha256=EiS1Yxw5jbAUBFCRYsJ57KYgZPk6oH-_gD72OfW8Oik,1358
|
29
|
+
yaicli/llms/providers/infiniai_provider.py,sha256=1dseUIZiXsxYRATRtk_obFclyXMwi4glsP7l_tVtnv8,710
|
30
|
+
yaicli/llms/providers/minimax_provider.py,sha256=W-j3dzrYMEv14bYt2pCPvPUxvxsUs-iMAcGB9yXakFs,744
|
31
|
+
yaicli/llms/providers/modelscope_provider.py,sha256=BzBhYixiDEWB7gujQ0rcG__7nsv0psJRxdtYCYXBhdM,454
|
32
|
+
yaicli/llms/providers/ollama_provider.py,sha256=pjpYjfnHWnExweZi1KGbT07JGkcxzKPhqICo8dD82D0,6967
|
33
|
+
yaicli/llms/providers/openai_provider.py,sha256=qEvzi4UHCQzwK4FQp1m2Ioahenp2uCQdFftTjUa6PvI,9739
|
34
|
+
yaicli/llms/providers/openrouter_provider.py,sha256=R-7FrUrCAKPZ3gbnuo0M6rPlVw1mvSBjbLGs_FtZWM0,732
|
35
|
+
yaicli/llms/providers/sambanova_provider.py,sha256=FFLrsvARt1UPAFWWgiuB6zvGzGKdtehKL58HdE1fo_M,2254
|
36
|
+
yaicli/llms/providers/siliconflow_provider.py,sha256=7Ir73me9jGMO5TAZDjrAbX7tbb_QBmLjTGywY0yliqc,446
|
37
|
+
yaicli/llms/providers/targon_provider.py,sha256=RQ808eS9lvsyvlzyKaQYcN0NimbpoNWgjHUzY1gLNs4,717
|
38
|
+
yaicli/llms/providers/xai_provider.py,sha256=Q6iOvJZOXIAwRiiHMKEBgq8-W6SGVZ9QD1_532bNYfo,199
|
39
|
+
yaicli/llms/providers/yi_provider.py,sha256=EnTm9qTxHPnzERsKqgGnzRIVhXFcAEdYqtOra65pGmY,719
|
40
|
+
yaicli-0.6.2.dist-info/METADATA,sha256=rD4n886cYaYpdEyBugcrnJcKm6oiUIOMXLFczByLDiQ,53546
|
41
|
+
yaicli-0.6.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
42
|
+
yaicli-0.6.2.dist-info/entry_points.txt,sha256=iYVyQP0PJIm9tQnlQheqT435kK_xdGoi5j9aswGV9hA,66
|
43
|
+
yaicli-0.6.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
44
|
+
yaicli-0.6.2.dist-info/RECORD,,
|
yaicli-0.6.0.dist-info/RECORD
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
pyproject.toml,sha256=vPeQggLMvO9RDn7BRhQjn5sAf0HyANCd0CFkLZ0a_uE,2434
|
2
|
-
yaicli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
-
yaicli/chat.py,sha256=_emvZEdgMBth2nQGaNWPf0P45oW2k3bpuIwqsxFcM5A,13676
|
4
|
-
yaicli/cli.py,sha256=YUKbtvRcNbe6iTmm0dx-38QDzzrAP4cOYaOChxpJ2wg,23673
|
5
|
-
yaicli/config.py,sha256=HrWYcelLXE61XX719eVcuuo3292xxf1BNQznWdvjQFQ,6535
|
6
|
-
yaicli/console.py,sha256=vARPJd-3lafutsQWrGntQVjLrYqaJD3qisN82pmuhjU,1973
|
7
|
-
yaicli/const.py,sha256=jC01jLLuuYJ7K_QaekXkIN7j1bIKCoGwJeTpquJy55Q,8178
|
8
|
-
yaicli/entry.py,sha256=Q1eqLE7tcHide7ooyPO7OCJpKE2YVuxR-NNFA2Pt2Hw,8693
|
9
|
-
yaicli/exceptions.py,sha256=WBYg8OTJJzaj7lt6HE7ZyBoe5T6A3yZRNCRfWd4iN0c,372
|
10
|
-
yaicli/history.py,sha256=s-57X9FMsaQHF7XySq1gGH_jpd_cHHTYafYu2ECuG6M,2472
|
11
|
-
yaicli/printer.py,sha256=g1TS7aDSQlWlSrQRhvNhNqoQKlsaf1lVOyUSK6LQLNQ,7945
|
12
|
-
yaicli/render.py,sha256=k8o2P8fI44PJlyQbs7gmMiu2x2prwajdWn5JIt15BIA,505
|
13
|
-
yaicli/role.py,sha256=PfwiVJIlzg7EzlvMM-kIy6vBK0d5d_J4M1I_fIZGnWk,7399
|
14
|
-
yaicli/schemas.py,sha256=Ty2ybCvld-ritgBZoI3RR93vYfw9LUNqkR8xk8VRZ2A,762
|
15
|
-
yaicli/tools.py,sha256=xw8KEs_xlSf79A2Aq1rAsUWahS6A_e5QMLt7QDXL5bs,5086
|
16
|
-
yaicli/utils.py,sha256=bpo3Xhozpxsaci3FtEIKZ32l4ZdyWMsrHjYGX0tB4J4,4541
|
17
|
-
yaicli/functions/__init__.py,sha256=_FJooQ9GkijG8xLwuU0cr5GBrGnC9Nc6bnCeUjrsT0k,1271
|
18
|
-
yaicli/functions/buildin/execute_shell_command.py,sha256=unl1-F8p6QZajeHdA0u5UpURMJM0WhdWMUWCCCHVRcI,1320
|
19
|
-
yaicli/llms/__init__.py,sha256=cN54nu-YalZipXjLW0YAAe0rRv0tXAQ8lLi1ohuTpao,363
|
20
|
-
yaicli/llms/client.py,sha256=mkE9KHSuPcJfpNQXbzF2YXGkel3jrOW8KfQ3YYpaK4M,4453
|
21
|
-
yaicli/llms/provider.py,sha256=gRPMVC_gTmR1-zm65ErmO5mZWr3HFcexQIEgEQvpymo,2820
|
22
|
-
yaicli/llms/providers/ai21_provider.py,sha256=kOXGuxh1tu-G1MbxSWnDLFDE8gP73YvM7G6i7K5WzbM,2744
|
23
|
-
yaicli/llms/providers/chatglm_provider.py,sha256=Oa9cQTF1x2durkfqNwO2LbC_ofr-8lVRrf63vINxPxY,6232
|
24
|
-
yaicli/llms/providers/chutes_provider.py,sha256=JYStbkf5RqamcAjWkz9S9WtlDsK5gUtpCxCqm6_A1x4,207
|
25
|
-
yaicli/llms/providers/cohere_provider.py,sha256=hc6vQxbCHz9kM2tNKK-kGkuOf4-gkskXW9ctr9V4Cxk,10837
|
26
|
-
yaicli/llms/providers/deepseek_provider.py,sha256=1-ucumH7gEGmebauuq1AvTfEYLFFIefBRqV7OCg_qAU,411
|
27
|
-
yaicli/llms/providers/doubao_provider.py,sha256=hh4VkJYJVwS34Tk2E09zwjoL-ar27X-ldnPg0Q4gemE,1999
|
28
|
-
yaicli/llms/providers/groq_provider.py,sha256=ntwZ7qHv1AEiarHw5gUE0o6jJtTdhg03y5PRpSx_mM4,659
|
29
|
-
yaicli/llms/providers/infiniai_provider.py,sha256=ftpmf7DJ25RklJX0RptGuyEQT1I5Zat8JE9a8gCm9SI,585
|
30
|
-
yaicli/llms/providers/modelscope_provider.py,sha256=ndX59VpVKkYmJJYAfxHrjKkyaoqICpXrbQyQtJMT3LA,427
|
31
|
-
yaicli/llms/providers/ollama_provider.py,sha256=pjpYjfnHWnExweZi1KGbT07JGkcxzKPhqICo8dD82D0,6967
|
32
|
-
yaicli/llms/providers/openai_provider.py,sha256=9pI0tF1cui2NkoKWIKzdrKDfWaokv-s9yeAi5gydQvY,7521
|
33
|
-
yaicli/llms/providers/openrouter_provider.py,sha256=32ZIjbyECecUGhP2iz42UsdHXfm5OT4_Utb62D4RYLI,416
|
34
|
-
yaicli/llms/providers/sambanova_provider.py,sha256=tmesO0H6WEieD0EFKKDF2r2w7oPXSAjneuqaMCBCi-s,1302
|
35
|
-
yaicli/llms/providers/siliconflow_provider.py,sha256=VxTjjXlbqqNRJ0C-maUOV1Pw-HUDtpbmgFniuppCHHk,419
|
36
|
-
yaicli/llms/providers/yi_provider.py,sha256=D8dKLV0mTOPmRkS-Gb59N5u0UWXBJ5ZIfwoaNHM7hvA,205
|
37
|
-
yaicli-0.6.0.dist-info/METADATA,sha256=Yh-4suoENNVLljgQFgOZmtJQuIR-xIUV_fxOeDQWCRU,53514
|
38
|
-
yaicli-0.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
39
|
-
yaicli-0.6.0.dist-info/entry_points.txt,sha256=iYVyQP0PJIm9tQnlQheqT435kK_xdGoi5j9aswGV9hA,66
|
40
|
-
yaicli-0.6.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
41
|
-
yaicli-0.6.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|