autobyteus 1.1.8__py3-none-any.whl → 1.2.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.
- autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +6 -2
- autobyteus/agent/handlers/inter_agent_message_event_handler.py +17 -19
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +6 -3
- autobyteus/agent/handlers/tool_result_event_handler.py +61 -18
- autobyteus/agent/handlers/user_input_message_event_handler.py +19 -10
- autobyteus/agent/hooks/base_phase_hook.py +17 -0
- autobyteus/agent/hooks/hook_registry.py +15 -27
- autobyteus/agent/input_processor/base_user_input_processor.py +17 -1
- autobyteus/agent/input_processor/processor_registry.py +15 -27
- autobyteus/agent/llm_response_processor/base_processor.py +17 -1
- autobyteus/agent/llm_response_processor/processor_registry.py +15 -24
- autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +14 -0
- autobyteus/agent/message/agent_input_user_message.py +15 -2
- autobyteus/agent/message/send_message_to.py +1 -1
- autobyteus/agent/processor_option.py +17 -0
- autobyteus/agent/sender_type.py +1 -0
- autobyteus/agent/system_prompt_processor/base_processor.py +17 -1
- autobyteus/agent/system_prompt_processor/processor_registry.py +15 -27
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +10 -0
- autobyteus/agent/tool_execution_result_processor/base_processor.py +17 -1
- autobyteus/agent/tool_execution_result_processor/processor_registry.py +15 -1
- autobyteus/agent/workspace/base_workspace.py +1 -1
- autobyteus/agent/workspace/workspace_definition.py +1 -1
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +1 -1
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +2 -2
- autobyteus/agent_team/task_notification/__init__.py +4 -0
- autobyteus/agent_team/task_notification/activation_policy.py +70 -0
- autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +56 -122
- autobyteus/agent_team/task_notification/task_activator.py +66 -0
- autobyteus/cli/agent_team_tui/state.py +17 -20
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +1 -1
- autobyteus/cli/agent_team_tui/widgets/task_board_panel.py +1 -1
- autobyteus/clients/__init__.py +10 -0
- autobyteus/clients/autobyteus_client.py +318 -0
- autobyteus/clients/cert_utils.py +105 -0
- autobyteus/clients/certificates/cert.pem +34 -0
- autobyteus/events/event_types.py +2 -2
- autobyteus/llm/api/autobyteus_llm.py +1 -1
- autobyteus/llm/api/gemini_llm.py +45 -54
- autobyteus/llm/api/qwen_llm.py +25 -0
- autobyteus/llm/api/zhipu_llm.py +26 -0
- autobyteus/llm/autobyteus_provider.py +9 -3
- autobyteus/llm/llm_factory.py +39 -0
- autobyteus/llm/ollama_provider_resolver.py +1 -0
- autobyteus/llm/providers.py +1 -0
- autobyteus/llm/token_counter/token_counter_factory.py +3 -0
- autobyteus/llm/token_counter/zhipu_token_counter.py +24 -0
- autobyteus/multimedia/audio/api/autobyteus_audio_client.py +5 -2
- autobyteus/multimedia/audio/api/gemini_audio_client.py +84 -153
- autobyteus/multimedia/audio/audio_client_factory.py +47 -22
- autobyteus/multimedia/audio/audio_model.py +13 -6
- autobyteus/multimedia/audio/autobyteus_audio_provider.py +9 -3
- autobyteus/multimedia/audio/base_audio_client.py +3 -1
- autobyteus/multimedia/image/api/autobyteus_image_client.py +13 -6
- autobyteus/multimedia/image/api/gemini_image_client.py +72 -130
- autobyteus/multimedia/image/api/openai_image_client.py +4 -2
- autobyteus/multimedia/image/autobyteus_image_provider.py +9 -3
- autobyteus/multimedia/image/base_image_client.py +6 -2
- autobyteus/multimedia/image/image_client_factory.py +20 -19
- autobyteus/multimedia/image/image_model.py +13 -6
- autobyteus/multimedia/providers.py +1 -0
- autobyteus/task_management/__init__.py +10 -10
- autobyteus/task_management/base_task_board.py +14 -6
- autobyteus/task_management/converters/__init__.py +0 -2
- autobyteus/task_management/converters/task_board_converter.py +7 -16
- autobyteus/task_management/events.py +6 -6
- autobyteus/task_management/in_memory_task_board.py +48 -38
- autobyteus/task_management/schemas/__init__.py +2 -2
- autobyteus/task_management/schemas/{plan_definition.py → task_definition.py} +6 -7
- autobyteus/task_management/schemas/task_status_report.py +1 -2
- autobyteus/task_management/task.py +60 -0
- autobyteus/task_management/tools/__init__.py +6 -2
- autobyteus/task_management/tools/assign_task_to.py +125 -0
- autobyteus/task_management/tools/get_my_tasks.py +80 -0
- autobyteus/task_management/tools/get_task_board_status.py +3 -3
- autobyteus/task_management/tools/publish_task.py +77 -0
- autobyteus/task_management/tools/publish_tasks.py +74 -0
- autobyteus/task_management/tools/update_task_status.py +5 -5
- autobyteus/tools/__init__.py +54 -16
- autobyteus/tools/base_tool.py +4 -4
- autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +1 -1
- autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +1 -1
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +1 -1
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +1 -1
- autobyteus/tools/browser/standalone/navigate_to.py +1 -1
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +1 -1
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +1 -1
- autobyteus/tools/browser/standalone/webpage_reader.py +1 -1
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +1 -1
- autobyteus/tools/download_media_tool.py +136 -0
- autobyteus/tools/file/file_editor.py +200 -0
- autobyteus/tools/functional_tool.py +1 -1
- autobyteus/tools/google_search.py +1 -1
- autobyteus/tools/mcp/factory.py +1 -1
- autobyteus/tools/mcp/schema_mapper.py +1 -1
- autobyteus/tools/mcp/tool.py +1 -1
- autobyteus/tools/multimedia/__init__.py +2 -0
- autobyteus/tools/multimedia/audio_tools.py +10 -20
- autobyteus/tools/multimedia/image_tools.py +21 -22
- autobyteus/tools/multimedia/media_reader_tool.py +117 -0
- autobyteus/tools/pydantic_schema_converter.py +1 -1
- autobyteus/tools/registry/tool_definition.py +1 -1
- autobyteus/tools/timer.py +1 -1
- autobyteus/tools/tool_meta.py +1 -1
- autobyteus/tools/usage/formatters/default_json_example_formatter.py +1 -1
- autobyteus/tools/usage/formatters/default_xml_example_formatter.py +1 -1
- autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +59 -3
- autobyteus/tools/usage/formatters/gemini_json_example_formatter.py +1 -1
- autobyteus/tools/usage/formatters/google_json_example_formatter.py +1 -1
- autobyteus/tools/usage/formatters/openai_json_example_formatter.py +1 -1
- autobyteus/tools/usage/parsers/_string_decoders.py +18 -0
- autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +9 -1
- autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +15 -1
- autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +4 -1
- autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +4 -1
- autobyteus/{tools → utils}/parameter_schema.py +1 -1
- {autobyteus-1.1.8.dist-info → autobyteus-1.2.0.dist-info}/METADATA +4 -3
- {autobyteus-1.1.8.dist-info → autobyteus-1.2.0.dist-info}/RECORD +122 -108
- examples/run_poem_writer.py +1 -1
- autobyteus/task_management/converters/task_plan_converter.py +0 -48
- autobyteus/task_management/task_plan.py +0 -110
- autobyteus/task_management/tools/publish_task_plan.py +0 -101
- autobyteus/tools/image_downloader.py +0 -99
- autobyteus/tools/pdf_downloader.py +0 -89
- {autobyteus-1.1.8.dist-info → autobyteus-1.2.0.dist-info}/WHEEL +0 -0
- {autobyteus-1.1.8.dist-info → autobyteus-1.2.0.dist-info}/licenses/LICENSE +0 -0
- {autobyteus-1.1.8.dist-info → autobyteus-1.2.0.dist-info}/top_level.txt +0 -0
autobyteus/llm/api/gemini_llm.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Dict, List, AsyncGenerator, Any
|
|
3
|
-
|
|
2
|
+
from typing import Dict, Optional, List, AsyncGenerator, Any
|
|
3
|
+
from google import genai
|
|
4
|
+
from google.genai import types as genai_types
|
|
4
5
|
import os
|
|
5
6
|
from autobyteus.llm.models import LLMModel
|
|
6
7
|
from autobyteus.llm.base_llm import BaseLLM
|
|
@@ -13,66 +14,60 @@ from autobyteus.llm.user_message import LLMUserMessage
|
|
|
13
14
|
logger = logging.getLogger(__name__)
|
|
14
15
|
|
|
15
16
|
def _format_gemini_history(messages: List[Message]) -> List[Dict[str, Any]]:
|
|
16
|
-
"""
|
|
17
|
-
Formats internal message history for the Gemini API.
|
|
18
|
-
This function remains compatible with the older library.
|
|
19
|
-
"""
|
|
17
|
+
"""Formats internal message history for the Gemini API."""
|
|
20
18
|
history = []
|
|
21
|
-
# System message is handled separately in the
|
|
19
|
+
# System message is handled separately in the new API
|
|
22
20
|
for msg in messages:
|
|
23
21
|
if msg.role in [MessageRole.USER, MessageRole.ASSISTANT]:
|
|
22
|
+
# NOTE: This history conversion will need to be updated for multimodal messages
|
|
24
23
|
role = 'model' if msg.role == MessageRole.ASSISTANT else 'user'
|
|
24
|
+
# The `parts` must be a list of dictionaries (Part objects), not a list of strings.
|
|
25
25
|
history.append({"role": role, "parts": [{"text": msg.content}]})
|
|
26
26
|
return history
|
|
27
27
|
|
|
28
28
|
class GeminiLLM(BaseLLM):
|
|
29
29
|
def __init__(self, model: LLMModel = None, llm_config: LLMConfig = None):
|
|
30
|
+
self.generation_config_dict = {
|
|
31
|
+
"response_mime_type": "text/plain",
|
|
32
|
+
}
|
|
33
|
+
|
|
30
34
|
if model is None:
|
|
31
|
-
model = LLMModel['gemini-2.5-flash']
|
|
35
|
+
model = LLMModel['gemini-2.5-flash']
|
|
32
36
|
if llm_config is None:
|
|
33
37
|
llm_config = LLMConfig()
|
|
34
|
-
|
|
38
|
+
|
|
35
39
|
super().__init__(model=model, llm_config=llm_config)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
self.initialize()
|
|
39
|
-
|
|
40
|
-
system_instruction = self.system_message if self.system_message else None
|
|
41
|
-
|
|
42
|
-
self.model = genai.GenerativeModel(
|
|
43
|
-
model_name=self.model.value,
|
|
44
|
-
system_instruction=system_instruction
|
|
45
|
-
)
|
|
40
|
+
self.client = self.initialize()
|
|
41
|
+
self.async_client = self.client.aio
|
|
46
42
|
|
|
47
|
-
@
|
|
48
|
-
def initialize():
|
|
49
|
-
"""
|
|
50
|
-
CHANGED: This method now configures the genai library with the API key
|
|
51
|
-
instead of creating a client instance.
|
|
52
|
-
"""
|
|
43
|
+
@classmethod
|
|
44
|
+
def initialize(cls) -> genai.client.Client:
|
|
53
45
|
api_key = os.environ.get("GEMINI_API_KEY")
|
|
54
46
|
if not api_key:
|
|
55
47
|
logger.error("GEMINI_API_KEY environment variable is not set.")
|
|
56
48
|
raise ValueError("GEMINI_API_KEY environment variable is not set.")
|
|
57
49
|
try:
|
|
58
|
-
genai.
|
|
50
|
+
return genai.Client()
|
|
59
51
|
except Exception as e:
|
|
60
|
-
logger.error(f"Failed to
|
|
61
|
-
raise ValueError(f"Failed to
|
|
52
|
+
logger.error(f"Failed to initialize Gemini client: {str(e)}")
|
|
53
|
+
raise ValueError(f"Failed to initialize Gemini client: {str(e)}")
|
|
62
54
|
|
|
63
|
-
def _get_generation_config(self) ->
|
|
64
|
-
"""
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
""
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
55
|
+
def _get_generation_config(self) -> genai_types.GenerateContentConfig:
|
|
56
|
+
"""Builds the generation config, handling special cases like 'thinking'."""
|
|
57
|
+
config = self.generation_config_dict.copy()
|
|
58
|
+
|
|
59
|
+
thinking_config = None
|
|
60
|
+
if "flash" in self.model.value:
|
|
61
|
+
thinking_config = genai_types.ThinkingConfig(thinking_budget=0)
|
|
62
|
+
|
|
63
|
+
# System instruction is now part of the config
|
|
64
|
+
system_instruction = self.system_message if self.system_message else None
|
|
65
|
+
|
|
66
|
+
return genai_types.GenerateContentConfig(
|
|
67
|
+
**config,
|
|
68
|
+
thinking_config=thinking_config,
|
|
69
|
+
system_instruction=system_instruction
|
|
70
|
+
)
|
|
76
71
|
|
|
77
72
|
async def _send_user_message_to_llm(self, user_message: LLMUserMessage, **kwargs) -> CompleteResponse:
|
|
78
73
|
self.add_user_message(user_message)
|
|
@@ -81,20 +76,19 @@ class GeminiLLM(BaseLLM):
|
|
|
81
76
|
history = _format_gemini_history(self.messages)
|
|
82
77
|
generation_config = self._get_generation_config()
|
|
83
78
|
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
response = await self.async_client.models.generate_content(
|
|
80
|
+
model=f"models/{self.model.value}",
|
|
86
81
|
contents=history,
|
|
87
|
-
|
|
82
|
+
config=generation_config,
|
|
88
83
|
)
|
|
89
84
|
|
|
90
85
|
assistant_message = response.text
|
|
91
86
|
self.add_assistant_message(assistant_message)
|
|
92
87
|
|
|
93
|
-
# CHANGED: Token usage is extracted from 'usage_metadata'.
|
|
94
88
|
token_usage = TokenUsage(
|
|
95
|
-
prompt_tokens=
|
|
96
|
-
completion_tokens=
|
|
97
|
-
total_tokens=
|
|
89
|
+
prompt_tokens=0,
|
|
90
|
+
completion_tokens=0,
|
|
91
|
+
total_tokens=0
|
|
98
92
|
)
|
|
99
93
|
|
|
100
94
|
return CompleteResponse(
|
|
@@ -113,11 +107,10 @@ class GeminiLLM(BaseLLM):
|
|
|
113
107
|
history = _format_gemini_history(self.messages)
|
|
114
108
|
generation_config = self._get_generation_config()
|
|
115
109
|
|
|
116
|
-
|
|
117
|
-
|
|
110
|
+
response_stream = await self.async_client.models.generate_content_stream(
|
|
111
|
+
model=f"models/{self.model.value}",
|
|
118
112
|
contents=history,
|
|
119
|
-
|
|
120
|
-
stream=True
|
|
113
|
+
config=generation_config,
|
|
121
114
|
)
|
|
122
115
|
|
|
123
116
|
async for chunk in response_stream:
|
|
@@ -130,8 +123,6 @@ class GeminiLLM(BaseLLM):
|
|
|
130
123
|
|
|
131
124
|
self.add_assistant_message(complete_response)
|
|
132
125
|
|
|
133
|
-
# NOTE: The old library's async stream does not easily expose token usage.
|
|
134
|
-
# Keeping it at 0, consistent with your original implementation.
|
|
135
126
|
token_usage = TokenUsage(
|
|
136
127
|
prompt_tokens=0,
|
|
137
128
|
completion_tokens=0,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from autobyteus.llm.models import LLMModel
|
|
4
|
+
from autobyteus.llm.utils.llm_config import LLMConfig
|
|
5
|
+
from autobyteus.llm.api.openai_compatible_llm import OpenAICompatibleLLM
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
class QwenLLM(OpenAICompatibleLLM):
|
|
10
|
+
def __init__(self, model: LLMModel = None, llm_config: LLMConfig = None):
|
|
11
|
+
if model is None:
|
|
12
|
+
model = LLMModel['qwen3-max-preview']
|
|
13
|
+
if llm_config is None:
|
|
14
|
+
llm_config = LLMConfig()
|
|
15
|
+
|
|
16
|
+
super().__init__(
|
|
17
|
+
model=model,
|
|
18
|
+
llm_config=llm_config,
|
|
19
|
+
api_key_env_var="DASHSCOPE_API_KEY",
|
|
20
|
+
base_url="https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
|
21
|
+
)
|
|
22
|
+
logger.info(f"QwenLLM initialized with model: {self.model}")
|
|
23
|
+
|
|
24
|
+
async def cleanup(self):
|
|
25
|
+
await super().cleanup()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from autobyteus.llm.models import LLMModel
|
|
4
|
+
from autobyteus.llm.utils.llm_config import LLMConfig
|
|
5
|
+
from autobyteus.llm.api.openai_compatible_llm import OpenAICompatibleLLM
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
class ZhipuLLM(OpenAICompatibleLLM):
|
|
10
|
+
def __init__(self, model: LLMModel = None, llm_config: LLMConfig = None):
|
|
11
|
+
# Provide defaults if not specified
|
|
12
|
+
if model is None:
|
|
13
|
+
model = LLMModel['glm-4.6']
|
|
14
|
+
if llm_config is None:
|
|
15
|
+
llm_config = LLMConfig()
|
|
16
|
+
|
|
17
|
+
super().__init__(
|
|
18
|
+
model=model,
|
|
19
|
+
llm_config=llm_config,
|
|
20
|
+
api_key_env_var="ZHIPU_API_KEY",
|
|
21
|
+
base_url="https://open.bigmodel.cn/api/paas/v4/"
|
|
22
|
+
)
|
|
23
|
+
logger.info(f"ZhipuLLM initialized with model: {self.model}")
|
|
24
|
+
|
|
25
|
+
async def cleanup(self):
|
|
26
|
+
await super().cleanup()
|
|
@@ -7,7 +7,7 @@ from typing import Dict, Any, TYPE_CHECKING, List, Optional
|
|
|
7
7
|
import os
|
|
8
8
|
import logging
|
|
9
9
|
from urllib.parse import urlparse
|
|
10
|
-
from
|
|
10
|
+
from autobyteus.clients import AutobyteusClient
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from autobyteus.llm.llm_factory import LLMFactory
|
|
@@ -19,7 +19,9 @@ class AutobyteusModelProvider:
|
|
|
19
19
|
|
|
20
20
|
@staticmethod
|
|
21
21
|
def _get_hosts() -> List[str]:
|
|
22
|
-
"""
|
|
22
|
+
"""
|
|
23
|
+
Gets Autobyteus LLM server hosts from env vars. Skips discovery if no host is configured.
|
|
24
|
+
"""
|
|
23
25
|
hosts_str = os.getenv('AUTOBYTEUS_LLM_SERVER_HOSTS')
|
|
24
26
|
if hosts_str:
|
|
25
27
|
return [host.strip() for host in hosts_str.split(',')]
|
|
@@ -28,7 +30,7 @@ class AutobyteusModelProvider:
|
|
|
28
30
|
if legacy_host:
|
|
29
31
|
return [legacy_host]
|
|
30
32
|
|
|
31
|
-
return [
|
|
33
|
+
return []
|
|
32
34
|
|
|
33
35
|
@staticmethod
|
|
34
36
|
def discover_and_register():
|
|
@@ -37,6 +39,10 @@ class AutobyteusModelProvider:
|
|
|
37
39
|
from autobyteus.llm.llm_factory import LLMFactory
|
|
38
40
|
|
|
39
41
|
hosts = AutobyteusModelProvider._get_hosts()
|
|
42
|
+
if not hosts:
|
|
43
|
+
logger.info("No Autobyteus LLM server hosts configured. Skipping Autobyteus LLM model discovery.")
|
|
44
|
+
return
|
|
45
|
+
|
|
40
46
|
total_registered_count = 0
|
|
41
47
|
|
|
42
48
|
for host_url in hosts:
|
autobyteus/llm/llm_factory.py
CHANGED
|
@@ -17,6 +17,8 @@ from autobyteus.llm.api.deepseek_llm import DeepSeekLLM
|
|
|
17
17
|
from autobyteus.llm.api.gemini_llm import GeminiLLM
|
|
18
18
|
from autobyteus.llm.api.grok_llm import GrokLLM
|
|
19
19
|
from autobyteus.llm.api.kimi_llm import KimiLLM
|
|
20
|
+
from autobyteus.llm.api.qwen_llm import QwenLLM
|
|
21
|
+
from autobyteus.llm.api.zhipu_llm import ZhipuLLM
|
|
20
22
|
from autobyteus.llm.ollama_provider import OllamaModelProvider
|
|
21
23
|
from autobyteus.llm.lmstudio_provider import LMStudioModelProvider
|
|
22
24
|
from autobyteus.utils.singleton import SingletonMeta
|
|
@@ -344,6 +346,43 @@ class LLMFactory(metaclass=SingletonMeta):
|
|
|
344
346
|
pricing_config=TokenPricingConfig(27.59, 27.59)
|
|
345
347
|
)
|
|
346
348
|
),
|
|
349
|
+
# QWEN Provider Models
|
|
350
|
+
LLMModel(
|
|
351
|
+
name="qwen3-max",
|
|
352
|
+
value="qwen-max",
|
|
353
|
+
provider=LLMProvider.QWEN,
|
|
354
|
+
llm_class=QwenLLM,
|
|
355
|
+
canonical_name="qwen3-max",
|
|
356
|
+
default_config=LLMConfig(
|
|
357
|
+
token_limit=262144,
|
|
358
|
+
pricing_config=TokenPricingConfig(
|
|
359
|
+
input_token_pricing=2.4,
|
|
360
|
+
output_token_pricing=12.0
|
|
361
|
+
)
|
|
362
|
+
)
|
|
363
|
+
),
|
|
364
|
+
# ZHIPU Provider Models
|
|
365
|
+
LLMModel(
|
|
366
|
+
name="glm-4.6",
|
|
367
|
+
value="glm-4.6",
|
|
368
|
+
provider=LLMProvider.ZHIPU,
|
|
369
|
+
llm_class=ZhipuLLM,
|
|
370
|
+
canonical_name="glm-4.6",
|
|
371
|
+
default_config=LLMConfig(
|
|
372
|
+
pricing_config=TokenPricingConfig(13.8, 13.8)
|
|
373
|
+
)
|
|
374
|
+
),
|
|
375
|
+
LLMModel(
|
|
376
|
+
name="glm-4.6-thinking",
|
|
377
|
+
value="glm-4.6",
|
|
378
|
+
provider=LLMProvider.ZHIPU,
|
|
379
|
+
llm_class=ZhipuLLM,
|
|
380
|
+
canonical_name="glm-4.6-thinking",
|
|
381
|
+
default_config=LLMConfig(
|
|
382
|
+
pricing_config=TokenPricingConfig(13.8, 13.8),
|
|
383
|
+
extra_params={ "extra_body": { "thinking": { "type": "enabled" } } }
|
|
384
|
+
)
|
|
385
|
+
),
|
|
347
386
|
]
|
|
348
387
|
for model in supported_models:
|
|
349
388
|
LLMFactory.register_model(model)
|
autobyteus/llm/providers.py
CHANGED
|
@@ -4,6 +4,7 @@ from autobyteus.llm.token_counter.claude_token_counter import ClaudeTokenCounter
|
|
|
4
4
|
from autobyteus.llm.token_counter.mistral_token_counter import MistralTokenCounter
|
|
5
5
|
from autobyteus.llm.token_counter.deepseek_token_counter import DeepSeekTokenCounter
|
|
6
6
|
from autobyteus.llm.token_counter.kimi_token_counter import KimiTokenCounter
|
|
7
|
+
from autobyteus.llm.token_counter.zhipu_token_counter import ZhipuTokenCounter
|
|
7
8
|
from autobyteus.llm.token_counter.base_token_counter import BaseTokenCounter
|
|
8
9
|
from autobyteus.llm.models import LLMModel
|
|
9
10
|
from autobyteus.llm.providers import LLMProvider
|
|
@@ -42,6 +43,8 @@ def get_token_counter(model: LLMModel, llm: 'BaseLLM') -> BaseTokenCounter:
|
|
|
42
43
|
return OpenAITokenCounter(model, llm)
|
|
43
44
|
elif model.provider == LLMProvider.GEMINI:
|
|
44
45
|
return OpenAITokenCounter(model, llm)
|
|
46
|
+
elif model.provider == LLMProvider.ZHIPU:
|
|
47
|
+
return ZhipuTokenCounter(model, llm)
|
|
45
48
|
else:
|
|
46
49
|
# For models that do not have a specialized counter, raise a NotImplementedError
|
|
47
50
|
raise NotImplementedError(f"No token counter available for model {model.value}")
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
from autobyteus.llm.token_counter.openai_token_counter import OpenAITokenCounter
|
|
3
|
+
from autobyteus.llm.models import LLMModel
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from autobyteus.llm.base_llm import BaseLLM
|
|
7
|
+
|
|
8
|
+
class ZhipuTokenCounter(OpenAITokenCounter):
|
|
9
|
+
"""
|
|
10
|
+
Token counter for Zhipu models. Uses the same token counting implementation as OpenAI.
|
|
11
|
+
|
|
12
|
+
This implementation inherits from OpenAITokenCounter as Zhipu uses a similar tokenization
|
|
13
|
+
approach as OpenAI's models.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, model: LLMModel, llm: 'BaseLLM' = None):
|
|
17
|
+
"""
|
|
18
|
+
Initialize the Zhipu token counter.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
model (LLMModel): The Zhipu model to count tokens for.
|
|
22
|
+
llm (BaseLLM, optional): The LLM instance. Defaults to None.
|
|
23
|
+
"""
|
|
24
|
+
super().__init__(model, llm)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from typing import Optional, List, Dict, Any, TYPE_CHECKING
|
|
3
|
-
from
|
|
3
|
+
from autobyteus.clients import AutobyteusClient
|
|
4
4
|
from autobyteus.multimedia.audio.base_audio_client import BaseAudioClient
|
|
5
5
|
from autobyteus.multimedia.utils.response_types import SpeechGenerationResponse
|
|
6
6
|
|
|
@@ -26,7 +26,8 @@ class AutobyteusAudioClient(BaseAudioClient):
|
|
|
26
26
|
async def generate_speech(
|
|
27
27
|
self,
|
|
28
28
|
prompt: str,
|
|
29
|
-
generation_config: Optional[Dict[str, Any]] = None
|
|
29
|
+
generation_config: Optional[Dict[str, Any]] = None,
|
|
30
|
+
**kwargs
|
|
30
31
|
) -> SpeechGenerationResponse:
|
|
31
32
|
"""
|
|
32
33
|
Generates speech by calling the generate_speech endpoint on the remote Autobyteus server.
|
|
@@ -36,6 +37,8 @@ class AutobyteusAudioClient(BaseAudioClient):
|
|
|
36
37
|
|
|
37
38
|
model_name_for_server = self.model.name
|
|
38
39
|
|
|
40
|
+
# Note: The underlying autobyteus_client.generate_speech does not currently accept **kwargs.
|
|
41
|
+
# They are accepted here for interface consistency and future-proofing.
|
|
39
42
|
response_data = await self.autobyteus_client.generate_speech(
|
|
40
43
|
model_name=model_name_for_server,
|
|
41
44
|
prompt=prompt,
|