agentcrew-ai 0.8.2__py3-none-any.whl → 0.8.3__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.
- AgentCrew/__init__.py +1 -1
- AgentCrew/modules/agents/local_agent.py +11 -0
- AgentCrew/modules/browser_automation/element_extractor.py +4 -3
- AgentCrew/modules/browser_automation/js/draw_element_boxes.js +200 -0
- AgentCrew/modules/browser_automation/js/extract_clickable_elements.js +57 -23
- AgentCrew/modules/browser_automation/js/extract_elements_by_text.js +21 -19
- AgentCrew/modules/browser_automation/js/extract_input_elements.js +22 -23
- AgentCrew/modules/browser_automation/js/filter_hidden_elements.js +104 -0
- AgentCrew/modules/browser_automation/js/remove_element_boxes.js +29 -0
- AgentCrew/modules/browser_automation/js_loader.py +385 -92
- AgentCrew/modules/browser_automation/service.py +118 -347
- AgentCrew/modules/browser_automation/tool.py +28 -29
- AgentCrew/modules/chat/message/conversation.py +9 -8
- AgentCrew/modules/console/input_handler.py +2 -0
- AgentCrew/modules/console/ui_effects.py +3 -4
- AgentCrew/modules/custom_llm/service.py +25 -3
- AgentCrew/modules/file_editing/tool.py +9 -11
- AgentCrew/modules/google/native_service.py +13 -0
- AgentCrew/modules/llm/constants.py +38 -1
- AgentCrew/modules/llm/model_registry.py +9 -0
- AgentCrew/modules/llm/types.py +12 -1
- AgentCrew/modules/memory/base_service.py +2 -2
- AgentCrew/modules/memory/chroma_service.py +80 -138
- AgentCrew/modules/memory/tool.py +15 -15
- AgentCrew/modules/openai/response_service.py +19 -11
- AgentCrew/modules/openai/service.py +15 -0
- AgentCrew/modules/prompts/constants.py +27 -14
- {agentcrew_ai-0.8.2.dist-info → agentcrew_ai-0.8.3.dist-info}/METADATA +2 -2
- {agentcrew_ai-0.8.2.dist-info → agentcrew_ai-0.8.3.dist-info}/RECORD +33 -30
- {agentcrew_ai-0.8.2.dist-info → agentcrew_ai-0.8.3.dist-info}/WHEEL +0 -0
- {agentcrew_ai-0.8.2.dist-info → agentcrew_ai-0.8.3.dist-info}/entry_points.txt +0 -0
- {agentcrew_ai-0.8.2.dist-info → agentcrew_ai-0.8.3.dist-info}/licenses/LICENSE +0 -0
- {agentcrew_ai-0.8.2.dist-info → agentcrew_ai-0.8.3.dist-info}/top_level.txt +0 -0
|
@@ -52,13 +52,11 @@ def get_browser_navigate_tool_definition(provider="claude") -> Dict[str, Any]:
|
|
|
52
52
|
|
|
53
53
|
def get_browser_click_tool_definition(provider="claude") -> Dict[str, Any]:
|
|
54
54
|
"""Get tool definition for browser element clicking."""
|
|
55
|
-
tool_description =
|
|
56
|
-
"Click an element using its UUID. Get UUIDs from browser_get_content first."
|
|
57
|
-
)
|
|
55
|
+
tool_description = "Click an element using its UUID. Get UUIDs from get_browser_content tool result first."
|
|
58
56
|
tool_arguments = {
|
|
59
57
|
"element_uuid": {
|
|
60
58
|
"type": "string",
|
|
61
|
-
"description": "UUID identifier from
|
|
59
|
+
"description": "UUID identifier from get_browser_content tool result clickable elements table.",
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
tool_required = ["element_uuid"]
|
|
@@ -109,9 +107,10 @@ def get_browser_scroll_tool_definition(provider="claude") -> Dict[str, Any]:
|
|
|
109
107
|
"element_uuid": {
|
|
110
108
|
"type": "string",
|
|
111
109
|
"description": "Optional UUID for specific element to scroll. Scrolls document if not provided.",
|
|
110
|
+
"default": "document",
|
|
112
111
|
},
|
|
113
112
|
}
|
|
114
|
-
tool_required = ["direction"]
|
|
113
|
+
tool_required = ["direction", "element_uuid"]
|
|
115
114
|
|
|
116
115
|
if provider == "claude":
|
|
117
116
|
return {
|
|
@@ -142,7 +141,7 @@ def get_browser_get_content_tool_definition(provider="claude") -> Dict[str, Any]
|
|
|
142
141
|
"""Get tool definition for browser content extraction."""
|
|
143
142
|
tool_description = (
|
|
144
143
|
"Extract page content as markdown with tables of clickable, input, and scrollable elements. UUIDs reset on each call."
|
|
145
|
-
"
|
|
144
|
+
"get_browser_content tool's result is UNIQUE in whole conversation. Remember to summarize important information before calling again."
|
|
146
145
|
)
|
|
147
146
|
tool_arguments = {}
|
|
148
147
|
tool_required = []
|
|
@@ -196,7 +195,7 @@ def get_browser_get_content_tool_handler(
|
|
|
196
195
|
tool_result.append(context_image.get("screenshot", {}))
|
|
197
196
|
return tool_result
|
|
198
197
|
else:
|
|
199
|
-
raise RuntimeError(f"
|
|
198
|
+
raise RuntimeError(f"Content extraction failed: {result['error']}")
|
|
200
199
|
|
|
201
200
|
return handle_browser_get_content
|
|
202
201
|
|
|
@@ -221,9 +220,9 @@ def get_browser_navigate_tool_handler(
|
|
|
221
220
|
if result.get("profile")
|
|
222
221
|
else ""
|
|
223
222
|
)
|
|
224
|
-
return f"
|
|
223
|
+
return f"{result.get('message', 'Success')}. Call `get_browser_content` tool to read the url content.\nCurrent URL: {result.get('current_url', 'Unknown')}{profile_info}"
|
|
225
224
|
else:
|
|
226
|
-
raise RuntimeError(f"
|
|
225
|
+
raise RuntimeError(f"Navigation failed: {result['error']}")
|
|
227
226
|
|
|
228
227
|
return handle_browser_navigate
|
|
229
228
|
|
|
@@ -241,16 +240,15 @@ def get_browser_click_tool_handler(
|
|
|
241
240
|
|
|
242
241
|
result = browser_service.click_element(element_uuid)
|
|
243
242
|
|
|
244
|
-
diff_summary = _get_content_delta_changes(browser_service)
|
|
245
|
-
|
|
246
243
|
if result.get("success", True):
|
|
244
|
+
diff_summary = _get_content_delta_changes(browser_service)
|
|
247
245
|
return (
|
|
248
|
-
f"
|
|
246
|
+
f"{result.get('message', 'Success')}. Call `get_browser_content` tool to get the updated content.\n"
|
|
249
247
|
f"UUID: {element_uuid}\nClickedElement: {result.get('elementInfo', {}).get('text', 'Unknown')}.\n"
|
|
250
248
|
f"Content delta changes:\n{diff_summary}"
|
|
251
249
|
)
|
|
252
250
|
else:
|
|
253
|
-
return f"
|
|
251
|
+
return f"Click failed: {result['error']}\nUUID: {element_uuid}.\nCall `get_browser_content` tool to get the updated UUID"
|
|
254
252
|
|
|
255
253
|
return handle_browser_click
|
|
256
254
|
|
|
@@ -273,24 +271,26 @@ def get_browser_scroll_tool_handler(
|
|
|
273
271
|
"Error: Invalid scroll direction. Use 'up', 'down', 'left', or 'right'."
|
|
274
272
|
)
|
|
275
273
|
|
|
276
|
-
result = browser_service.scroll_page(
|
|
274
|
+
result = browser_service.scroll_page(
|
|
275
|
+
direction, amount, element_uuid if element_uuid != "document" else None
|
|
276
|
+
)
|
|
277
277
|
|
|
278
278
|
if result.get("success", True):
|
|
279
|
-
return f"
|
|
279
|
+
return f"{result.get('message', 'Success')}, Call `get_browser_content` tool to get the updated content."
|
|
280
280
|
else:
|
|
281
281
|
uuid_info = f"\nUUID: {element_uuid}" if element_uuid else ""
|
|
282
|
-
raise RuntimeError(f"
|
|
282
|
+
raise RuntimeError(f"Scroll failed: {result['error']}{uuid_info}")
|
|
283
283
|
|
|
284
284
|
return handle_browser_scroll
|
|
285
285
|
|
|
286
286
|
|
|
287
287
|
def get_browser_input_tool_definition(provider="claude") -> Dict[str, Any]:
|
|
288
288
|
"""Get tool definition for browser input."""
|
|
289
|
-
tool_description = "Input data into form fields using UUID. Get UUIDs from
|
|
289
|
+
tool_description = "Input data into form fields using UUID. Get UUIDs from get_browser_content tool first."
|
|
290
290
|
tool_arguments = {
|
|
291
291
|
"element_uuid": {
|
|
292
292
|
"type": "string",
|
|
293
|
-
"description": "UUID identifier from
|
|
293
|
+
"description": "UUID identifier from get_browser_content tool result's input elements table.",
|
|
294
294
|
},
|
|
295
295
|
"value": {
|
|
296
296
|
"type": "string",
|
|
@@ -340,13 +340,13 @@ def get_browser_input_tool_handler(
|
|
|
340
340
|
return "Error: No value provided for input."
|
|
341
341
|
|
|
342
342
|
result = browser_service.input_data(element_uuid, str(value))
|
|
343
|
-
diff_summary = _get_content_delta_changes(browser_service)
|
|
344
343
|
|
|
345
344
|
if result.get("success", True):
|
|
346
|
-
|
|
345
|
+
diff_summary = _get_content_delta_changes(browser_service)
|
|
346
|
+
return f"{result.get('message', 'Success')}\nUUID: {element_uuid}\nValue: {value}\nContent delta changes:\n{diff_summary}"
|
|
347
347
|
else:
|
|
348
348
|
raise RuntimeError(
|
|
349
|
-
f"
|
|
349
|
+
f"Input failed: {result['error']}\nUUID: {element_uuid}\nValue: {value}.\n Call `get_browser_content` tool to get updated UUID."
|
|
350
350
|
)
|
|
351
351
|
|
|
352
352
|
return handle_browser_input
|
|
@@ -405,16 +405,15 @@ def get_browser_get_elements_by_text_tool_handler(
|
|
|
405
405
|
if result.get("success", False):
|
|
406
406
|
elements_found = result.get("elements_found", 0)
|
|
407
407
|
if elements_found == 0:
|
|
408
|
-
return f"
|
|
408
|
+
return f"No elements found containing text: '{text}'"
|
|
409
409
|
|
|
410
410
|
content = result.get("content", "")
|
|
411
411
|
return (
|
|
412
|
-
f"
|
|
413
|
-
+ content
|
|
412
|
+
f"Found {elements_found} elements containing text: '{text}'\n" + content
|
|
414
413
|
)
|
|
415
414
|
else:
|
|
416
415
|
raise RuntimeError(
|
|
417
|
-
f"
|
|
416
|
+
f"Search failed: {result.get('error', 'Unknown error')}\nSearch text: '{text}'"
|
|
418
417
|
)
|
|
419
418
|
|
|
420
419
|
return handle_browser_get_elements_by_text
|
|
@@ -422,7 +421,7 @@ def get_browser_get_elements_by_text_tool_handler(
|
|
|
422
421
|
|
|
423
422
|
def get_browser_capture_screenshot_tool_definition(provider="claude") -> Dict[str, Any]:
|
|
424
423
|
"""Get tool definition for browser screenshot capture."""
|
|
425
|
-
tool_description = "Capture page screenshot as base64 image data. Supports different formats and full page capture."
|
|
424
|
+
tool_description = "Capture page screenshot as base64 image data with colored boxes and UUID labels drawn over all identified elements. Supports different formats and full page capture."
|
|
426
425
|
tool_arguments = {
|
|
427
426
|
"format": {
|
|
428
427
|
"type": "string",
|
|
@@ -500,7 +499,7 @@ def get_browser_capture_screenshot_tool_handler(
|
|
|
500
499
|
return [screenshot_data]
|
|
501
500
|
else:
|
|
502
501
|
raise RuntimeError(
|
|
503
|
-
f"
|
|
502
|
+
f"Screenshot capture failed: {result.get('error', 'Unknown error')}"
|
|
504
503
|
)
|
|
505
504
|
|
|
506
505
|
return handle_browser_capture_screenshot
|
|
@@ -617,13 +616,13 @@ def get_browser_send_key_tool_handler(
|
|
|
617
616
|
else ""
|
|
618
617
|
)
|
|
619
618
|
diff_summary = _get_content_delta_changes(browser_service)
|
|
620
|
-
success_msg = f"
|
|
619
|
+
success_msg = f"{result.get('message', 'Success')}. {key_info}\nContent delta changes:\n{diff_summary}"
|
|
621
620
|
if modifiers_info:
|
|
622
621
|
success_msg += f". {modifiers_info}"
|
|
623
622
|
return success_msg
|
|
624
623
|
else:
|
|
625
624
|
raise RuntimeError(
|
|
626
|
-
f"
|
|
625
|
+
f"Key send failed: {result.get('error', 'Unknown error')}"
|
|
627
626
|
)
|
|
628
627
|
|
|
629
628
|
return handle_browser_send_key
|
|
@@ -112,14 +112,6 @@ class ConversationManager:
|
|
|
112
112
|
msg["tool_call_id"] = tool_result.get("tool_use_id", "")
|
|
113
113
|
|
|
114
114
|
self.message_handler.current_conversation_id = conversation_id
|
|
115
|
-
if self.message_handler.memory_service:
|
|
116
|
-
self.message_handler.memory_service.session_id = (
|
|
117
|
-
self.message_handler.current_conversation_id
|
|
118
|
-
)
|
|
119
|
-
self.message_handler.memory_service.loaded_conversation = True
|
|
120
|
-
self.message_handler.memory_service.load_conversation_context(
|
|
121
|
-
self.message_handler.current_conversation_id
|
|
122
|
-
)
|
|
123
115
|
last_agent_name = history[-1].get("agent", "")
|
|
124
116
|
if last_agent_name and self.message_handler.agent_manager.select_agent(
|
|
125
117
|
last_agent_name
|
|
@@ -129,6 +121,15 @@ class ConversationManager:
|
|
|
129
121
|
)
|
|
130
122
|
self.message_handler._notify("agent_changed", last_agent_name)
|
|
131
123
|
|
|
124
|
+
if self.message_handler.memory_service:
|
|
125
|
+
self.message_handler.memory_service.session_id = (
|
|
126
|
+
self.message_handler.current_conversation_id
|
|
127
|
+
)
|
|
128
|
+
self.message_handler.memory_service.loaded_conversation = True
|
|
129
|
+
self.message_handler.memory_service.load_conversation_context(
|
|
130
|
+
self.message_handler.current_conversation_id, last_agent_name
|
|
131
|
+
)
|
|
132
|
+
|
|
132
133
|
self.message_handler.streamline_messages = history
|
|
133
134
|
self.message_handler.agent_manager.rebuild_agents_messages(
|
|
134
135
|
self.message_handler.streamline_messages
|
|
@@ -218,6 +218,7 @@ class InputHandler:
|
|
|
218
218
|
|
|
219
219
|
@kb.add(Keys.ControlUp)
|
|
220
220
|
@kb.add(Keys.Escape, Keys.Up)
|
|
221
|
+
@kb.add(Keys.ControlK)
|
|
221
222
|
def _(event):
|
|
222
223
|
"""Navigate to previous history entry."""
|
|
223
224
|
buffer = event.current_buffer
|
|
@@ -241,6 +242,7 @@ class InputHandler:
|
|
|
241
242
|
|
|
242
243
|
@kb.add(Keys.ControlDown)
|
|
243
244
|
@kb.add(Keys.Escape, Keys.Down)
|
|
245
|
+
@kb.add(Keys.ControlJ)
|
|
244
246
|
def _(event):
|
|
245
247
|
"""Navigate to next history entry if cursor is at last line."""
|
|
246
248
|
buffer = event.current_buffer
|
|
@@ -107,8 +107,7 @@ class UIEffects:
|
|
|
107
107
|
self.live = Live(
|
|
108
108
|
live_panel,
|
|
109
109
|
console=self.console,
|
|
110
|
-
auto_refresh=
|
|
111
|
-
refresh_per_second=8,
|
|
110
|
+
auto_refresh=False,
|
|
112
111
|
vertical_overflow="crop",
|
|
113
112
|
)
|
|
114
113
|
self.live.start()
|
|
@@ -167,10 +166,10 @@ class UIEffects:
|
|
|
167
166
|
subtitle=subtitle,
|
|
168
167
|
title_align="left",
|
|
169
168
|
expand=False,
|
|
170
|
-
height=height_limit
|
|
169
|
+
height=min(height_limit, len(lines)),
|
|
171
170
|
border_style=RICH_STYLE_GREEN,
|
|
172
171
|
)
|
|
173
|
-
self.live.update(live_panel)
|
|
172
|
+
self.live.update(live_panel, refresh=True)
|
|
174
173
|
|
|
175
174
|
def finish_live_update(self):
|
|
176
175
|
"""Stop the live update display."""
|
|
@@ -121,16 +121,38 @@ class CustomLLMService(OpenAIService):
|
|
|
121
121
|
# "max_tokens": 16000,
|
|
122
122
|
}
|
|
123
123
|
stream_params["temperature"] = self.temperature
|
|
124
|
-
stream_params["extra_body"] = {"min_p": 0.
|
|
124
|
+
stream_params["extra_body"] = {"min_p": 0.02}
|
|
125
125
|
|
|
126
|
+
full_model_id = f"{self._provider_name}/{self.model}"
|
|
127
|
+
|
|
128
|
+
forced_sample_params = ModelRegistry.get_model_sample_params(full_model_id)
|
|
129
|
+
if forced_sample_params:
|
|
130
|
+
if forced_sample_params.temperature is not None:
|
|
131
|
+
stream_params["temperature"] = forced_sample_params.temperature
|
|
132
|
+
if forced_sample_params.top_p is not None:
|
|
133
|
+
stream_params["top_p"] = forced_sample_params.top_p
|
|
134
|
+
if forced_sample_params.top_k is not None:
|
|
135
|
+
stream_params["extra_body"]["top_k"] = forced_sample_params.top_k
|
|
136
|
+
if forced_sample_params.frequency_penalty is not None:
|
|
137
|
+
stream_params["frequency_penalty"] = (
|
|
138
|
+
forced_sample_params.frequency_penalty
|
|
139
|
+
)
|
|
140
|
+
if forced_sample_params.presence_penalty is not None:
|
|
141
|
+
stream_params["presence_penalty"] = (
|
|
142
|
+
forced_sample_params.presence_penalty
|
|
143
|
+
)
|
|
144
|
+
if forced_sample_params.repetition_penalty is not None:
|
|
145
|
+
stream_params["extra_body"]["repetition_penalty"] = (
|
|
146
|
+
forced_sample_params.repetition_penalty
|
|
147
|
+
)
|
|
148
|
+
if forced_sample_params.min_p is not None:
|
|
149
|
+
stream_params["extra_body"]["min_p"] = forced_sample_params.min_p
|
|
126
150
|
# Add system message if provided
|
|
127
151
|
if self.system_prompt:
|
|
128
152
|
stream_params["messages"] = self._convert_internal_format(
|
|
129
153
|
[{"role": "system", "content": self.system_prompt}] + messages
|
|
130
154
|
)
|
|
131
155
|
|
|
132
|
-
full_model_id = f"{self._provider_name}/{self.model}"
|
|
133
|
-
|
|
134
156
|
# Add tools if available
|
|
135
157
|
if self.tools and "tool_use" in ModelRegistry.get_model_capabilities(
|
|
136
158
|
full_model_id
|
|
@@ -115,13 +115,13 @@ def get_file_write_or_edit_tool_handler(
|
|
|
115
115
|
text_or_search_replace_blocks = params.get("text_or_search_replace_blocks")
|
|
116
116
|
|
|
117
117
|
if not file_path:
|
|
118
|
-
raise ValueError("
|
|
118
|
+
raise ValueError("Error: No file path provided.")
|
|
119
119
|
|
|
120
120
|
if percentage_to_change is None:
|
|
121
|
-
raise ValueError("
|
|
121
|
+
raise ValueError("Error: No percentage_to_change provided.")
|
|
122
122
|
|
|
123
123
|
if not text_or_search_replace_blocks:
|
|
124
|
-
raise ValueError("
|
|
124
|
+
raise ValueError("Error: No content or search/replace blocks provided.")
|
|
125
125
|
|
|
126
126
|
result = file_editing_service.write_or_edit_file(
|
|
127
127
|
file_path=file_path,
|
|
@@ -130,7 +130,7 @@ def get_file_write_or_edit_tool_handler(
|
|
|
130
130
|
)
|
|
131
131
|
|
|
132
132
|
if result["status"] == "success":
|
|
133
|
-
parts = [f"
|
|
133
|
+
parts = [f"{result['file_path']}"]
|
|
134
134
|
parts.append(f"{result.get('changes_applied', 1)} change(s)")
|
|
135
135
|
if result.get("syntax_check", {}).get("is_valid"):
|
|
136
136
|
parts.append(
|
|
@@ -153,21 +153,19 @@ def get_file_write_or_edit_tool_handler(
|
|
|
153
153
|
else ""
|
|
154
154
|
)
|
|
155
155
|
restore = " | Backup restored" if result.get("backup_restored") else ""
|
|
156
|
-
return (
|
|
157
|
-
f"❌ Syntax ({result.get('language', '?')}):\n{errors}{extra}{restore}"
|
|
158
|
-
)
|
|
156
|
+
return f"Syntax ({result.get('language', '?')}):\n{errors}{extra}{restore}"
|
|
159
157
|
|
|
160
158
|
elif result["status"] in ["no_match", "ambiguous"]:
|
|
161
|
-
return f"
|
|
159
|
+
return f"{result['status'].title()}: {result.get('error', '?')} (block {result.get('block_index', '?')})"
|
|
162
160
|
|
|
163
161
|
elif result["status"] == "denied":
|
|
164
|
-
return f"
|
|
162
|
+
return f"Access denied: {result.get('error', 'Permission error')}"
|
|
165
163
|
|
|
166
164
|
elif result["status"] == "parse_error":
|
|
167
|
-
return f"
|
|
165
|
+
return f"Parse: {result.get('error', 'Invalid block format')}"
|
|
168
166
|
|
|
169
167
|
else:
|
|
170
|
-
return f"
|
|
168
|
+
return f"{result.get('error', 'Unknown error')}"
|
|
171
169
|
|
|
172
170
|
return handle_file_write_or_edit
|
|
173
171
|
|
|
@@ -393,6 +393,19 @@ class GoogleAINativeService(BaseLLMService):
|
|
|
393
393
|
top_p=0.95,
|
|
394
394
|
)
|
|
395
395
|
|
|
396
|
+
forced_sample_params = ModelRegistry.get_model_sample_params(full_model_id)
|
|
397
|
+
if forced_sample_params:
|
|
398
|
+
if forced_sample_params.temperature is not None:
|
|
399
|
+
config.temperature = forced_sample_params.temperature
|
|
400
|
+
if forced_sample_params.top_p is not None:
|
|
401
|
+
config.top_p = forced_sample_params.top_p
|
|
402
|
+
if forced_sample_params.top_k is not None:
|
|
403
|
+
config.top_k = forced_sample_params.top_k
|
|
404
|
+
if forced_sample_params.frequency_penalty is not None:
|
|
405
|
+
config.frequency_penalty = forced_sample_params.frequency_penalty
|
|
406
|
+
if forced_sample_params.presence_penalty is not None:
|
|
407
|
+
config.presence_penalty = forced_sample_params.presence_penalty
|
|
408
|
+
|
|
396
409
|
# Add system instruction if available
|
|
397
410
|
if self.system_prompt:
|
|
398
411
|
config.system_instruction = self.system_prompt
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from .types import Model
|
|
1
|
+
from .types import Model, SampleParam
|
|
2
2
|
|
|
3
3
|
_ANTHROPIC_MODELS = [
|
|
4
4
|
Model(
|
|
@@ -227,6 +227,17 @@ _GOOGLE_MODELS = [
|
|
|
227
227
|
input_token_price_1m=1.25,
|
|
228
228
|
output_token_price_1m=10,
|
|
229
229
|
),
|
|
230
|
+
Model(
|
|
231
|
+
id="gemini-3-pro-preview",
|
|
232
|
+
provider="google",
|
|
233
|
+
name="Gemini 3 Pro",
|
|
234
|
+
max_context_token=1_000_000,
|
|
235
|
+
description="Google's most intelligent model family to date, built on a foundation of state-of-the-art reasoning",
|
|
236
|
+
capabilities=["tool_use", "thinking", "vision", "structured_output"],
|
|
237
|
+
force_sample_params=SampleParam(temperature=1.0),
|
|
238
|
+
input_token_price_1m=2,
|
|
239
|
+
output_token_price_1m=12,
|
|
240
|
+
),
|
|
230
241
|
]
|
|
231
242
|
|
|
232
243
|
_DEEPINFRA_MODELS = [
|
|
@@ -254,6 +265,9 @@ _DEEPINFRA_MODELS = [
|
|
|
254
265
|
name="Qwen 3 Coder",
|
|
255
266
|
description="Qwen3-Coder-480B-A35B-Instruct is the Qwen3's most agentic code model",
|
|
256
267
|
capabilities=["tool_use", "stream", "structured_output"],
|
|
268
|
+
force_sample_params=SampleParam(
|
|
269
|
+
temperature=0.7, top_p=0.8, top_k=20, repetition_penalty=1.05
|
|
270
|
+
),
|
|
257
271
|
input_token_price_1m=0.4,
|
|
258
272
|
output_token_price_1m=1.6,
|
|
259
273
|
),
|
|
@@ -263,6 +277,9 @@ _DEEPINFRA_MODELS = [
|
|
|
263
277
|
name="Qwen 3 Coder",
|
|
264
278
|
description="Qwen3-Coder-480B-A35B-Instruct is the Qwen3's most agentic code model",
|
|
265
279
|
capabilities=["tool_use", "stream", "structured_output"],
|
|
280
|
+
force_sample_params=SampleParam(
|
|
281
|
+
temperature=0.7, top_p=0.8, top_k=20, min_p=0.0
|
|
282
|
+
),
|
|
266
283
|
input_token_price_1m=0.14,
|
|
267
284
|
output_token_price_1m=1.1,
|
|
268
285
|
),
|
|
@@ -272,6 +289,9 @@ _DEEPINFRA_MODELS = [
|
|
|
272
289
|
name="Qwen 3 MoE 235B-22B",
|
|
273
290
|
description="Qwen3 is the latest generation of large language models in Qwen series, offering a comprehensive suite of dense and mixture-of-experts (MoE) models",
|
|
274
291
|
capabilities=["tool_use", "thinking", "stream", "structured_output"],
|
|
292
|
+
force_sample_params=SampleParam(
|
|
293
|
+
temperature=0.6, top_p=0.95, top_k=20, min_p=0.0
|
|
294
|
+
),
|
|
275
295
|
input_token_price_1m=0.2,
|
|
276
296
|
output_token_price_1m=0.6,
|
|
277
297
|
),
|
|
@@ -280,6 +300,7 @@ _DEEPINFRA_MODELS = [
|
|
|
280
300
|
provider="deepinfra",
|
|
281
301
|
name="Zai GLM-4.6",
|
|
282
302
|
description="The GLM-4.6 series models are foundation models designed for intelligent agents",
|
|
303
|
+
force_sample_params=SampleParam(temperature=1, top_p=0.95, top_k=40),
|
|
283
304
|
capabilities=["tool_use", "stream", "structured_output"],
|
|
284
305
|
input_token_price_1m=0.6,
|
|
285
306
|
output_token_price_1m=2.0,
|
|
@@ -290,6 +311,9 @@ _DEEPINFRA_MODELS = [
|
|
|
290
311
|
name="Qwen 3 32B",
|
|
291
312
|
description="Qwen3 is the latest generation of large language models in Qwen series, offering a comprehensive suite of dense and mixture-of-experts (MoE) models",
|
|
292
313
|
capabilities=["tool_use", "stream", "structured_output"],
|
|
314
|
+
force_sample_params=SampleParam(
|
|
315
|
+
temperature=0.6, top_p=0.95, top_k=20, min_p=0.0
|
|
316
|
+
),
|
|
293
317
|
input_token_price_1m=0.1,
|
|
294
318
|
output_token_price_1m=0.3,
|
|
295
319
|
),
|
|
@@ -308,6 +332,7 @@ _DEEPINFRA_MODELS = [
|
|
|
308
332
|
name="DeepSeek R1 0528",
|
|
309
333
|
description="The DeepSeek R1 model has undergone a minor version upgrade, with the current version being DeepSeek-R1-0528.",
|
|
310
334
|
capabilities=["tool_use", "thinking", "stream", "structured_output"],
|
|
335
|
+
force_sample_params=SampleParam(temperature=0.6),
|
|
311
336
|
input_token_price_1m=0.5,
|
|
312
337
|
output_token_price_1m=2.18,
|
|
313
338
|
),
|
|
@@ -317,6 +342,7 @@ _DEEPINFRA_MODELS = [
|
|
|
317
342
|
name="Kimi K2 Instruct",
|
|
318
343
|
description="Kimi K2 is a large-scale Mixture-of-Experts (MoE) language model developed by Moonshot AI, featuring 1 trillion total parameters with 32 billion active per forward pass",
|
|
319
344
|
capabilities=["tool_use", "stream", "structured_output"],
|
|
345
|
+
force_sample_params=SampleParam(temperature=0.6),
|
|
320
346
|
input_token_price_1m=0.5,
|
|
321
347
|
output_token_price_1m=2.0,
|
|
322
348
|
),
|
|
@@ -342,6 +368,17 @@ _GITHUB_COPILOT_MODELS = [
|
|
|
342
368
|
input_token_price_1m=0.0,
|
|
343
369
|
output_token_price_1m=0.0,
|
|
344
370
|
),
|
|
371
|
+
Model(
|
|
372
|
+
id="gemini-3-pro-preview",
|
|
373
|
+
provider="github_copilot",
|
|
374
|
+
name="Gemini 3 Pro",
|
|
375
|
+
description="",
|
|
376
|
+
capabilities=["tool_use", "vision", "stream"],
|
|
377
|
+
default=False,
|
|
378
|
+
input_token_price_1m=0.0,
|
|
379
|
+
force_sample_params=SampleParam(temperature=1.0),
|
|
380
|
+
output_token_price_1m=0.0,
|
|
381
|
+
),
|
|
345
382
|
Model(
|
|
346
383
|
id="gpt-4.1",
|
|
347
384
|
provider="github_copilot",
|
|
@@ -46,6 +46,15 @@ class ModelRegistry:
|
|
|
46
46
|
return 128_000
|
|
47
47
|
return model.max_context_token
|
|
48
48
|
|
|
49
|
+
@classmethod
|
|
50
|
+
def get_model_sample_params(cls, mode_id):
|
|
51
|
+
registry = ModelRegistry.get_instance()
|
|
52
|
+
model = registry.get_model(mode_id)
|
|
53
|
+
if not model or not model.force_sample_params:
|
|
54
|
+
logger.warning(f"Model not found in registry: {mode_id}")
|
|
55
|
+
return None
|
|
56
|
+
return model.force_sample_params
|
|
57
|
+
|
|
49
58
|
def _load_custom_models_from_config(self):
|
|
50
59
|
"""Loads models from custom LLM provider configurations and registers them."""
|
|
51
60
|
try:
|
AgentCrew/modules/llm/types.py
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
from pydantic import BaseModel
|
|
2
|
-
from typing import List, Literal
|
|
2
|
+
from typing import List, Literal, Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class SampleParam(BaseModel):
|
|
6
|
+
temperature: Optional[float] = None
|
|
7
|
+
top_p: Optional[float] = None
|
|
8
|
+
min_p: Optional[float] = None
|
|
9
|
+
top_k: Optional[int] = None
|
|
10
|
+
frequency_penalty: Optional[float] = None
|
|
11
|
+
presence_penalty: Optional[float] = None
|
|
12
|
+
repetition_penalty: Optional[float] = None
|
|
3
13
|
|
|
4
14
|
|
|
5
15
|
class Model(BaseModel):
|
|
@@ -19,6 +29,7 @@ class Model(BaseModel):
|
|
|
19
29
|
]
|
|
20
30
|
]
|
|
21
31
|
default: bool = False
|
|
32
|
+
force_sample_params: Optional[SampleParam] = None
|
|
22
33
|
max_context_token: int = 128_000
|
|
23
34
|
input_token_price_1m: float = 0.0
|
|
24
35
|
output_token_price_1m: float = 0.0
|
|
@@ -50,7 +50,7 @@ class BaseMemoryService(ABC):
|
|
|
50
50
|
pass
|
|
51
51
|
|
|
52
52
|
@abstractmethod
|
|
53
|
-
def load_conversation_context(self, session_id: str):
|
|
53
|
+
def load_conversation_context(self, session_id: str, agent_name: str = "None"):
|
|
54
54
|
pass
|
|
55
55
|
|
|
56
56
|
@abstractmethod
|
|
@@ -88,7 +88,7 @@ class BaseMemoryService(ABC):
|
|
|
88
88
|
pass
|
|
89
89
|
|
|
90
90
|
@abstractmethod
|
|
91
|
-
def
|
|
91
|
+
def list_memory_headers(
|
|
92
92
|
self,
|
|
93
93
|
from_date: Optional[int] = None,
|
|
94
94
|
to_date: Optional[int] = None,
|