amd-gaia 0.15.0__py3-none-any.whl → 0.15.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.
- {amd_gaia-0.15.0.dist-info → amd_gaia-0.15.2.dist-info}/METADATA +222 -223
- amd_gaia-0.15.2.dist-info/RECORD +182 -0
- {amd_gaia-0.15.0.dist-info → amd_gaia-0.15.2.dist-info}/WHEEL +1 -1
- {amd_gaia-0.15.0.dist-info → amd_gaia-0.15.2.dist-info}/entry_points.txt +1 -0
- {amd_gaia-0.15.0.dist-info → amd_gaia-0.15.2.dist-info}/licenses/LICENSE.md +20 -20
- gaia/__init__.py +29 -29
- gaia/agents/__init__.py +19 -19
- gaia/agents/base/__init__.py +9 -9
- gaia/agents/base/agent.py +2132 -2177
- gaia/agents/base/api_agent.py +119 -120
- gaia/agents/base/console.py +1967 -1841
- gaia/agents/base/errors.py +237 -237
- gaia/agents/base/mcp_agent.py +86 -86
- gaia/agents/base/tools.py +88 -83
- gaia/agents/blender/__init__.py +7 -0
- gaia/agents/blender/agent.py +553 -556
- gaia/agents/blender/agent_simple.py +133 -135
- gaia/agents/blender/app.py +211 -211
- gaia/agents/blender/app_simple.py +41 -41
- gaia/agents/blender/core/__init__.py +16 -16
- gaia/agents/blender/core/materials.py +506 -506
- gaia/agents/blender/core/objects.py +316 -316
- gaia/agents/blender/core/rendering.py +225 -225
- gaia/agents/blender/core/scene.py +220 -220
- gaia/agents/blender/core/view.py +146 -146
- gaia/agents/chat/__init__.py +9 -9
- gaia/agents/chat/agent.py +809 -835
- gaia/agents/chat/app.py +1065 -1058
- gaia/agents/chat/session.py +508 -508
- gaia/agents/chat/tools/__init__.py +15 -15
- gaia/agents/chat/tools/file_tools.py +96 -96
- gaia/agents/chat/tools/rag_tools.py +1744 -1729
- gaia/agents/chat/tools/shell_tools.py +437 -436
- gaia/agents/code/__init__.py +7 -7
- gaia/agents/code/agent.py +549 -549
- gaia/agents/code/cli.py +377 -0
- gaia/agents/code/models.py +135 -135
- gaia/agents/code/orchestration/__init__.py +24 -24
- gaia/agents/code/orchestration/checklist_executor.py +1763 -1763
- gaia/agents/code/orchestration/checklist_generator.py +713 -713
- gaia/agents/code/orchestration/factories/__init__.py +9 -9
- gaia/agents/code/orchestration/factories/base.py +63 -63
- gaia/agents/code/orchestration/factories/nextjs_factory.py +118 -118
- gaia/agents/code/orchestration/factories/python_factory.py +106 -106
- gaia/agents/code/orchestration/orchestrator.py +841 -841
- gaia/agents/code/orchestration/project_analyzer.py +391 -391
- gaia/agents/code/orchestration/steps/__init__.py +67 -67
- gaia/agents/code/orchestration/steps/base.py +188 -188
- gaia/agents/code/orchestration/steps/error_handler.py +314 -314
- gaia/agents/code/orchestration/steps/nextjs.py +828 -828
- gaia/agents/code/orchestration/steps/python.py +307 -307
- gaia/agents/code/orchestration/template_catalog.py +469 -469
- gaia/agents/code/orchestration/workflows/__init__.py +14 -14
- gaia/agents/code/orchestration/workflows/base.py +80 -80
- gaia/agents/code/orchestration/workflows/nextjs.py +186 -186
- gaia/agents/code/orchestration/workflows/python.py +94 -94
- gaia/agents/code/prompts/__init__.py +11 -11
- gaia/agents/code/prompts/base_prompt.py +77 -77
- gaia/agents/code/prompts/code_patterns.py +2034 -2036
- gaia/agents/code/prompts/nextjs_prompt.py +40 -40
- gaia/agents/code/prompts/python_prompt.py +109 -109
- gaia/agents/code/schema_inference.py +365 -365
- gaia/agents/code/system_prompt.py +41 -41
- gaia/agents/code/tools/__init__.py +42 -42
- gaia/agents/code/tools/cli_tools.py +1138 -1138
- gaia/agents/code/tools/code_formatting.py +319 -319
- gaia/agents/code/tools/code_tools.py +769 -769
- gaia/agents/code/tools/error_fixing.py +1347 -1347
- gaia/agents/code/tools/external_tools.py +180 -180
- gaia/agents/code/tools/file_io.py +845 -845
- gaia/agents/code/tools/prisma_tools.py +190 -190
- gaia/agents/code/tools/project_management.py +1016 -1016
- gaia/agents/code/tools/testing.py +321 -321
- gaia/agents/code/tools/typescript_tools.py +122 -122
- gaia/agents/code/tools/validation_parsing.py +461 -461
- gaia/agents/code/tools/validation_tools.py +806 -806
- gaia/agents/code/tools/web_dev_tools.py +1758 -1758
- gaia/agents/code/validators/__init__.py +16 -16
- gaia/agents/code/validators/antipattern_checker.py +241 -241
- gaia/agents/code/validators/ast_analyzer.py +197 -197
- gaia/agents/code/validators/requirements_validator.py +145 -145
- gaia/agents/code/validators/syntax_validator.py +171 -171
- gaia/agents/docker/__init__.py +7 -7
- gaia/agents/docker/agent.py +643 -642
- gaia/agents/emr/__init__.py +8 -8
- gaia/agents/emr/agent.py +1504 -1506
- gaia/agents/emr/cli.py +1322 -1322
- gaia/agents/emr/constants.py +475 -475
- gaia/agents/emr/dashboard/__init__.py +4 -4
- gaia/agents/emr/dashboard/server.py +1972 -1974
- gaia/agents/jira/__init__.py +11 -11
- gaia/agents/jira/agent.py +894 -894
- gaia/agents/jira/jql_templates.py +299 -299
- gaia/agents/routing/__init__.py +7 -7
- gaia/agents/routing/agent.py +567 -570
- gaia/agents/routing/system_prompt.py +75 -75
- gaia/agents/summarize/__init__.py +11 -0
- gaia/agents/summarize/agent.py +885 -0
- gaia/agents/summarize/prompts.py +129 -0
- gaia/api/__init__.py +23 -23
- gaia/api/agent_registry.py +238 -238
- gaia/api/app.py +305 -305
- gaia/api/openai_server.py +575 -575
- gaia/api/schemas.py +186 -186
- gaia/api/sse_handler.py +373 -373
- gaia/apps/__init__.py +4 -4
- gaia/apps/llm/__init__.py +6 -6
- gaia/apps/llm/app.py +184 -169
- gaia/apps/summarize/app.py +116 -633
- gaia/apps/summarize/html_viewer.py +133 -133
- gaia/apps/summarize/pdf_formatter.py +284 -284
- gaia/audio/__init__.py +2 -2
- gaia/audio/audio_client.py +439 -439
- gaia/audio/audio_recorder.py +269 -269
- gaia/audio/kokoro_tts.py +599 -599
- gaia/audio/whisper_asr.py +432 -432
- gaia/chat/__init__.py +16 -16
- gaia/chat/app.py +428 -430
- gaia/chat/prompts.py +522 -522
- gaia/chat/sdk.py +1228 -1225
- gaia/cli.py +5659 -5632
- gaia/database/__init__.py +10 -10
- gaia/database/agent.py +176 -176
- gaia/database/mixin.py +290 -290
- gaia/database/testing.py +64 -64
- gaia/eval/batch_experiment.py +2332 -2332
- gaia/eval/claude.py +542 -542
- gaia/eval/config.py +37 -37
- gaia/eval/email_generator.py +512 -512
- gaia/eval/eval.py +3179 -3179
- gaia/eval/groundtruth.py +1130 -1130
- gaia/eval/transcript_generator.py +582 -582
- gaia/eval/webapp/README.md +167 -167
- gaia/eval/webapp/package-lock.json +875 -875
- gaia/eval/webapp/package.json +20 -20
- gaia/eval/webapp/public/app.js +3402 -3402
- gaia/eval/webapp/public/index.html +87 -87
- gaia/eval/webapp/public/styles.css +3661 -3661
- gaia/eval/webapp/server.js +415 -415
- gaia/eval/webapp/test-setup.js +72 -72
- gaia/installer/__init__.py +23 -0
- gaia/installer/init_command.py +1275 -0
- gaia/installer/lemonade_installer.py +619 -0
- gaia/llm/__init__.py +10 -2
- gaia/llm/base_client.py +60 -0
- gaia/llm/exceptions.py +12 -0
- gaia/llm/factory.py +70 -0
- gaia/llm/lemonade_client.py +3421 -3221
- gaia/llm/lemonade_manager.py +294 -294
- gaia/llm/providers/__init__.py +9 -0
- gaia/llm/providers/claude.py +108 -0
- gaia/llm/providers/lemonade.py +118 -0
- gaia/llm/providers/openai_provider.py +79 -0
- gaia/llm/vlm_client.py +382 -382
- gaia/logger.py +189 -189
- gaia/mcp/agent_mcp_server.py +245 -245
- gaia/mcp/blender_mcp_client.py +138 -138
- gaia/mcp/blender_mcp_server.py +648 -648
- gaia/mcp/context7_cache.py +332 -332
- gaia/mcp/external_services.py +518 -518
- gaia/mcp/mcp_bridge.py +811 -550
- gaia/mcp/servers/__init__.py +6 -6
- gaia/mcp/servers/docker_mcp.py +83 -83
- gaia/perf_analysis.py +361 -0
- gaia/rag/__init__.py +10 -10
- gaia/rag/app.py +293 -293
- gaia/rag/demo.py +304 -304
- gaia/rag/pdf_utils.py +235 -235
- gaia/rag/sdk.py +2194 -2194
- gaia/security.py +183 -163
- gaia/talk/app.py +287 -289
- gaia/talk/sdk.py +538 -538
- gaia/testing/__init__.py +87 -87
- gaia/testing/assertions.py +330 -330
- gaia/testing/fixtures.py +333 -333
- gaia/testing/mocks.py +493 -493
- gaia/util.py +46 -46
- gaia/utils/__init__.py +33 -33
- gaia/utils/file_watcher.py +675 -675
- gaia/utils/parsing.py +223 -223
- gaia/version.py +100 -100
- amd_gaia-0.15.0.dist-info/RECORD +0 -168
- gaia/agents/code/app.py +0 -266
- gaia/llm/llm_client.py +0 -723
- {amd_gaia-0.15.0.dist-info → amd_gaia-0.15.2.dist-info}/top_level.txt +0 -0
gaia/agents/base/errors.py
CHANGED
|
@@ -1,237 +1,237 @@
|
|
|
1
|
-
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
|
|
4
|
-
"""Generic error formatting for user-facing error messages.
|
|
5
|
-
|
|
6
|
-
This module provides utilities to format exceptions in a user-friendly way,
|
|
7
|
-
showing the user's code with a visual pointer to the error line while
|
|
8
|
-
filtering out framework internals.
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
import json
|
|
12
|
-
import linecache
|
|
13
|
-
import textwrap
|
|
14
|
-
import traceback
|
|
15
|
-
from typing import List, Optional, Set
|
|
16
|
-
|
|
17
|
-
# Paths to filter out (framework internals)
|
|
18
|
-
FRAMEWORK_PATHS: Set[str] = {
|
|
19
|
-
"gaia/agents/base",
|
|
20
|
-
"gaia/agents/blender",
|
|
21
|
-
"gaia/agents/chat",
|
|
22
|
-
"gaia/agents/code",
|
|
23
|
-
"gaia/agents/docker",
|
|
24
|
-
"gaia/agents/jira",
|
|
25
|
-
"gaia/agents/routing",
|
|
26
|
-
"gaia/agents/tools",
|
|
27
|
-
"site-packages/",
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def format_user_error(
|
|
32
|
-
exception: Exception,
|
|
33
|
-
context_lines: int = 2,
|
|
34
|
-
) -> str:
|
|
35
|
-
"""
|
|
36
|
-
Format an exception to show user's code with visual pointer.
|
|
37
|
-
|
|
38
|
-
Filters out framework internals, shows only user code frames
|
|
39
|
-
with source context around the error line.
|
|
40
|
-
|
|
41
|
-
Args:
|
|
42
|
-
exception: The caught exception
|
|
43
|
-
context_lines: Lines of code context before/after error
|
|
44
|
-
|
|
45
|
-
Returns:
|
|
46
|
-
Formatted error string with traceback and code pointer
|
|
47
|
-
|
|
48
|
-
Example output:
|
|
49
|
-
KeyError: 'data'
|
|
50
|
-
|
|
51
|
-
Traceback (most recent call last):
|
|
52
|
-
File "my_agent.py", line 39, in get_big_llms
|
|
53
|
-
37 | url = f"{base_url}/models?show_all=true"
|
|
54
|
-
38 | response = requests.get(url, timeout=60)
|
|
55
|
-
>>> 39 | models = response.json()["data"]
|
|
56
|
-
40 |
|
|
57
|
-
41 | top_5_models = sorted(
|
|
58
|
-
"""
|
|
59
|
-
lines = []
|
|
60
|
-
lines.append(f"{type(exception).__name__}: {exception}")
|
|
61
|
-
lines.append("")
|
|
62
|
-
|
|
63
|
-
# Extract traceback frames
|
|
64
|
-
tb = traceback.extract_tb(exception.__traceback__)
|
|
65
|
-
user_frames = _filter_user_frames(tb)
|
|
66
|
-
|
|
67
|
-
if not user_frames:
|
|
68
|
-
# No user frames found, show last frame as fallback
|
|
69
|
-
if tb:
|
|
70
|
-
user_frames = [tb[-1]]
|
|
71
|
-
else:
|
|
72
|
-
return "\n".join(lines)
|
|
73
|
-
|
|
74
|
-
lines.append("Traceback (most recent call last):")
|
|
75
|
-
|
|
76
|
-
for frame in user_frames:
|
|
77
|
-
lines.append(f' File "{frame.filename}", line {frame.lineno}, in {frame.name}')
|
|
78
|
-
|
|
79
|
-
# Show code context
|
|
80
|
-
code_context = _get_code_context(frame.filename, frame.lineno, context_lines)
|
|
81
|
-
if code_context:
|
|
82
|
-
lines.append(code_context)
|
|
83
|
-
|
|
84
|
-
return "\n".join(lines)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def format_execution_trace(
|
|
88
|
-
exception: Exception,
|
|
89
|
-
query: Optional[str] = None,
|
|
90
|
-
plan_step: Optional[int] = None,
|
|
91
|
-
total_steps: Optional[int] = None,
|
|
92
|
-
tool_name: Optional[str] = None,
|
|
93
|
-
tool_args: Optional[dict] = None,
|
|
94
|
-
context_lines: int = 5,
|
|
95
|
-
) -> str:
|
|
96
|
-
"""
|
|
97
|
-
Format an exception with full execution trace for debugging.
|
|
98
|
-
|
|
99
|
-
Shows the agent's execution path (Query → Plan → Tool → Error)
|
|
100
|
-
along with the user's code context.
|
|
101
|
-
|
|
102
|
-
Args:
|
|
103
|
-
exception: The caught exception
|
|
104
|
-
query: The original user query
|
|
105
|
-
plan_step: Current step number in the plan (1-based)
|
|
106
|
-
total_steps: Total number of steps in the plan
|
|
107
|
-
tool_name: Name of the tool that failed
|
|
108
|
-
tool_args: Arguments passed to the tool
|
|
109
|
-
context_lines: Lines of code context before/after error
|
|
110
|
-
|
|
111
|
-
Returns:
|
|
112
|
-
Formatted error string with execution trace and code pointer
|
|
113
|
-
"""
|
|
114
|
-
sep = "═" * 63
|
|
115
|
-
lines = []
|
|
116
|
-
|
|
117
|
-
# Header
|
|
118
|
-
lines.append(sep)
|
|
119
|
-
lines.append("AGENT ERROR - Tool execution failed")
|
|
120
|
-
lines.append(sep)
|
|
121
|
-
lines.append("")
|
|
122
|
-
|
|
123
|
-
# Execution trace section
|
|
124
|
-
lines.append("Execution Trace:")
|
|
125
|
-
if query:
|
|
126
|
-
# Truncate long queries
|
|
127
|
-
display_query = query[:80] + "..." if len(query) > 80 else query
|
|
128
|
-
lines.append(f' Query: "{display_query}"')
|
|
129
|
-
if plan_step is not None and total_steps is not None:
|
|
130
|
-
lines.append(f" Plan Step: {plan_step}/{total_steps}")
|
|
131
|
-
if tool_name:
|
|
132
|
-
lines.append(f" Tool: {tool_name}")
|
|
133
|
-
if tool_args:
|
|
134
|
-
args_str = _truncate_args(tool_args)
|
|
135
|
-
lines.append(f" Args: {args_str}")
|
|
136
|
-
lines.append("")
|
|
137
|
-
|
|
138
|
-
# Error section
|
|
139
|
-
lines.append("Error:")
|
|
140
|
-
error_msg = f"{type(exception).__name__}: {exception}"
|
|
141
|
-
# Word wrap long error messages (word-aware wrapping)
|
|
142
|
-
wrapped_lines = textwrap.wrap(error_msg, width=70)
|
|
143
|
-
for line in wrapped_lines:
|
|
144
|
-
lines.append(f" {line}")
|
|
145
|
-
lines.append("")
|
|
146
|
-
|
|
147
|
-
# Your Code section
|
|
148
|
-
tb = traceback.extract_tb(exception.__traceback__)
|
|
149
|
-
user_frames = _filter_user_frames(tb)
|
|
150
|
-
|
|
151
|
-
if not user_frames and tb:
|
|
152
|
-
# No user frames found, use last frame as fallback
|
|
153
|
-
user_frames = [tb[-1]]
|
|
154
|
-
|
|
155
|
-
if user_frames:
|
|
156
|
-
lines.append("Your Code:")
|
|
157
|
-
for frame in user_frames:
|
|
158
|
-
lines.append(
|
|
159
|
-
f' File "{frame.filename}", line {frame.lineno}, in {frame.name}'
|
|
160
|
-
)
|
|
161
|
-
lines.append("")
|
|
162
|
-
|
|
163
|
-
# Show code context with more lines
|
|
164
|
-
code_context = _get_code_context(
|
|
165
|
-
frame.filename, frame.lineno, context_lines
|
|
166
|
-
)
|
|
167
|
-
if code_context:
|
|
168
|
-
lines.append(code_context)
|
|
169
|
-
|
|
170
|
-
lines.append("")
|
|
171
|
-
lines.append(sep)
|
|
172
|
-
|
|
173
|
-
return "\n".join(lines)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
def _filter_user_frames(
|
|
177
|
-
frames: List[traceback.FrameSummary],
|
|
178
|
-
) -> List[traceback.FrameSummary]:
|
|
179
|
-
"""Filter out framework internal frames, keep user code."""
|
|
180
|
-
return [
|
|
181
|
-
f for f in frames if not any(path in f.filename for path in FRAMEWORK_PATHS)
|
|
182
|
-
]
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
def _get_code_context(
|
|
186
|
-
filename: str,
|
|
187
|
-
error_line: int,
|
|
188
|
-
context: int = 2,
|
|
189
|
-
) -> Optional[str]:
|
|
190
|
-
"""Get source code context around error line with pointer."""
|
|
191
|
-
lines = []
|
|
192
|
-
|
|
193
|
-
for line_num in range(error_line - context, error_line + context + 1):
|
|
194
|
-
if line_num < 1:
|
|
195
|
-
continue
|
|
196
|
-
|
|
197
|
-
code = linecache.getline(filename, line_num).rstrip()
|
|
198
|
-
if not code and line_num != error_line:
|
|
199
|
-
continue
|
|
200
|
-
|
|
201
|
-
if line_num == error_line:
|
|
202
|
-
# Visual pointer to error line
|
|
203
|
-
lines.append(f" >>> {line_num:4d} | {code}")
|
|
204
|
-
else:
|
|
205
|
-
lines.append(f" {line_num:4d} | {code}")
|
|
206
|
-
|
|
207
|
-
return "\n".join(lines) if lines else None
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
def _truncate_args(tool_args: Optional[dict], max_length: int = 100) -> str:
|
|
211
|
-
"""Truncate tool args while preserving structure where possible.
|
|
212
|
-
|
|
213
|
-
Uses JSON formatting for cleaner output and truncates at character
|
|
214
|
-
boundary with ellipsis indicator.
|
|
215
|
-
|
|
216
|
-
Args:
|
|
217
|
-
tool_args: Dictionary of tool arguments
|
|
218
|
-
max_length: Maximum string length before truncation
|
|
219
|
-
|
|
220
|
-
Returns:
|
|
221
|
-
Formatted string representation of the arguments
|
|
222
|
-
"""
|
|
223
|
-
if not tool_args:
|
|
224
|
-
return "{}"
|
|
225
|
-
|
|
226
|
-
try:
|
|
227
|
-
# Use JSON for cleaner, more readable output
|
|
228
|
-
args_str = json.dumps(tool_args, default=str)
|
|
229
|
-
except (TypeError, ValueError):
|
|
230
|
-
# Fallback to str() if JSON fails
|
|
231
|
-
args_str = str(tool_args)
|
|
232
|
-
|
|
233
|
-
if len(args_str) <= max_length:
|
|
234
|
-
return args_str
|
|
235
|
-
|
|
236
|
-
# Truncate but indicate it's truncated
|
|
237
|
-
return args_str[: max_length - 3] + "..."
|
|
1
|
+
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
"""Generic error formatting for user-facing error messages.
|
|
5
|
+
|
|
6
|
+
This module provides utilities to format exceptions in a user-friendly way,
|
|
7
|
+
showing the user's code with a visual pointer to the error line while
|
|
8
|
+
filtering out framework internals.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
import linecache
|
|
13
|
+
import textwrap
|
|
14
|
+
import traceback
|
|
15
|
+
from typing import List, Optional, Set
|
|
16
|
+
|
|
17
|
+
# Paths to filter out (framework internals)
|
|
18
|
+
FRAMEWORK_PATHS: Set[str] = {
|
|
19
|
+
"gaia/agents/base",
|
|
20
|
+
"gaia/agents/blender",
|
|
21
|
+
"gaia/agents/chat",
|
|
22
|
+
"gaia/agents/code",
|
|
23
|
+
"gaia/agents/docker",
|
|
24
|
+
"gaia/agents/jira",
|
|
25
|
+
"gaia/agents/routing",
|
|
26
|
+
"gaia/agents/tools",
|
|
27
|
+
"site-packages/",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def format_user_error(
|
|
32
|
+
exception: Exception,
|
|
33
|
+
context_lines: int = 2,
|
|
34
|
+
) -> str:
|
|
35
|
+
"""
|
|
36
|
+
Format an exception to show user's code with visual pointer.
|
|
37
|
+
|
|
38
|
+
Filters out framework internals, shows only user code frames
|
|
39
|
+
with source context around the error line.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
exception: The caught exception
|
|
43
|
+
context_lines: Lines of code context before/after error
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
Formatted error string with traceback and code pointer
|
|
47
|
+
|
|
48
|
+
Example output:
|
|
49
|
+
KeyError: 'data'
|
|
50
|
+
|
|
51
|
+
Traceback (most recent call last):
|
|
52
|
+
File "my_agent.py", line 39, in get_big_llms
|
|
53
|
+
37 | url = f"{base_url}/models?show_all=true"
|
|
54
|
+
38 | response = requests.get(url, timeout=60)
|
|
55
|
+
>>> 39 | models = response.json()["data"]
|
|
56
|
+
40 |
|
|
57
|
+
41 | top_5_models = sorted(
|
|
58
|
+
"""
|
|
59
|
+
lines = []
|
|
60
|
+
lines.append(f"{type(exception).__name__}: {exception}")
|
|
61
|
+
lines.append("")
|
|
62
|
+
|
|
63
|
+
# Extract traceback frames
|
|
64
|
+
tb = traceback.extract_tb(exception.__traceback__)
|
|
65
|
+
user_frames = _filter_user_frames(tb)
|
|
66
|
+
|
|
67
|
+
if not user_frames:
|
|
68
|
+
# No user frames found, show last frame as fallback
|
|
69
|
+
if tb:
|
|
70
|
+
user_frames = [tb[-1]]
|
|
71
|
+
else:
|
|
72
|
+
return "\n".join(lines)
|
|
73
|
+
|
|
74
|
+
lines.append("Traceback (most recent call last):")
|
|
75
|
+
|
|
76
|
+
for frame in user_frames:
|
|
77
|
+
lines.append(f' File "{frame.filename}", line {frame.lineno}, in {frame.name}')
|
|
78
|
+
|
|
79
|
+
# Show code context
|
|
80
|
+
code_context = _get_code_context(frame.filename, frame.lineno, context_lines)
|
|
81
|
+
if code_context:
|
|
82
|
+
lines.append(code_context)
|
|
83
|
+
|
|
84
|
+
return "\n".join(lines)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def format_execution_trace(
|
|
88
|
+
exception: Exception,
|
|
89
|
+
query: Optional[str] = None,
|
|
90
|
+
plan_step: Optional[int] = None,
|
|
91
|
+
total_steps: Optional[int] = None,
|
|
92
|
+
tool_name: Optional[str] = None,
|
|
93
|
+
tool_args: Optional[dict] = None,
|
|
94
|
+
context_lines: int = 5,
|
|
95
|
+
) -> str:
|
|
96
|
+
"""
|
|
97
|
+
Format an exception with full execution trace for debugging.
|
|
98
|
+
|
|
99
|
+
Shows the agent's execution path (Query → Plan → Tool → Error)
|
|
100
|
+
along with the user's code context.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
exception: The caught exception
|
|
104
|
+
query: The original user query
|
|
105
|
+
plan_step: Current step number in the plan (1-based)
|
|
106
|
+
total_steps: Total number of steps in the plan
|
|
107
|
+
tool_name: Name of the tool that failed
|
|
108
|
+
tool_args: Arguments passed to the tool
|
|
109
|
+
context_lines: Lines of code context before/after error
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
Formatted error string with execution trace and code pointer
|
|
113
|
+
"""
|
|
114
|
+
sep = "═" * 63
|
|
115
|
+
lines = []
|
|
116
|
+
|
|
117
|
+
# Header
|
|
118
|
+
lines.append(sep)
|
|
119
|
+
lines.append("AGENT ERROR - Tool execution failed")
|
|
120
|
+
lines.append(sep)
|
|
121
|
+
lines.append("")
|
|
122
|
+
|
|
123
|
+
# Execution trace section
|
|
124
|
+
lines.append("Execution Trace:")
|
|
125
|
+
if query:
|
|
126
|
+
# Truncate long queries
|
|
127
|
+
display_query = query[:80] + "..." if len(query) > 80 else query
|
|
128
|
+
lines.append(f' Query: "{display_query}"')
|
|
129
|
+
if plan_step is not None and total_steps is not None:
|
|
130
|
+
lines.append(f" Plan Step: {plan_step}/{total_steps}")
|
|
131
|
+
if tool_name:
|
|
132
|
+
lines.append(f" Tool: {tool_name}")
|
|
133
|
+
if tool_args:
|
|
134
|
+
args_str = _truncate_args(tool_args)
|
|
135
|
+
lines.append(f" Args: {args_str}")
|
|
136
|
+
lines.append("")
|
|
137
|
+
|
|
138
|
+
# Error section
|
|
139
|
+
lines.append("Error:")
|
|
140
|
+
error_msg = f"{type(exception).__name__}: {exception}"
|
|
141
|
+
# Word wrap long error messages (word-aware wrapping)
|
|
142
|
+
wrapped_lines = textwrap.wrap(error_msg, width=70)
|
|
143
|
+
for line in wrapped_lines:
|
|
144
|
+
lines.append(f" {line}")
|
|
145
|
+
lines.append("")
|
|
146
|
+
|
|
147
|
+
# Your Code section
|
|
148
|
+
tb = traceback.extract_tb(exception.__traceback__)
|
|
149
|
+
user_frames = _filter_user_frames(tb)
|
|
150
|
+
|
|
151
|
+
if not user_frames and tb:
|
|
152
|
+
# No user frames found, use last frame as fallback
|
|
153
|
+
user_frames = [tb[-1]]
|
|
154
|
+
|
|
155
|
+
if user_frames:
|
|
156
|
+
lines.append("Your Code:")
|
|
157
|
+
for frame in user_frames:
|
|
158
|
+
lines.append(
|
|
159
|
+
f' File "{frame.filename}", line {frame.lineno}, in {frame.name}'
|
|
160
|
+
)
|
|
161
|
+
lines.append("")
|
|
162
|
+
|
|
163
|
+
# Show code context with more lines
|
|
164
|
+
code_context = _get_code_context(
|
|
165
|
+
frame.filename, frame.lineno, context_lines
|
|
166
|
+
)
|
|
167
|
+
if code_context:
|
|
168
|
+
lines.append(code_context)
|
|
169
|
+
|
|
170
|
+
lines.append("")
|
|
171
|
+
lines.append(sep)
|
|
172
|
+
|
|
173
|
+
return "\n".join(lines)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _filter_user_frames(
|
|
177
|
+
frames: List[traceback.FrameSummary],
|
|
178
|
+
) -> List[traceback.FrameSummary]:
|
|
179
|
+
"""Filter out framework internal frames, keep user code."""
|
|
180
|
+
return [
|
|
181
|
+
f for f in frames if not any(path in f.filename for path in FRAMEWORK_PATHS)
|
|
182
|
+
]
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _get_code_context(
|
|
186
|
+
filename: str,
|
|
187
|
+
error_line: int,
|
|
188
|
+
context: int = 2,
|
|
189
|
+
) -> Optional[str]:
|
|
190
|
+
"""Get source code context around error line with pointer."""
|
|
191
|
+
lines = []
|
|
192
|
+
|
|
193
|
+
for line_num in range(error_line - context, error_line + context + 1):
|
|
194
|
+
if line_num < 1:
|
|
195
|
+
continue
|
|
196
|
+
|
|
197
|
+
code = linecache.getline(filename, line_num).rstrip()
|
|
198
|
+
if not code and line_num != error_line:
|
|
199
|
+
continue
|
|
200
|
+
|
|
201
|
+
if line_num == error_line:
|
|
202
|
+
# Visual pointer to error line
|
|
203
|
+
lines.append(f" >>> {line_num:4d} | {code}")
|
|
204
|
+
else:
|
|
205
|
+
lines.append(f" {line_num:4d} | {code}")
|
|
206
|
+
|
|
207
|
+
return "\n".join(lines) if lines else None
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _truncate_args(tool_args: Optional[dict], max_length: int = 100) -> str:
|
|
211
|
+
"""Truncate tool args while preserving structure where possible.
|
|
212
|
+
|
|
213
|
+
Uses JSON formatting for cleaner output and truncates at character
|
|
214
|
+
boundary with ellipsis indicator.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
tool_args: Dictionary of tool arguments
|
|
218
|
+
max_length: Maximum string length before truncation
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
Formatted string representation of the arguments
|
|
222
|
+
"""
|
|
223
|
+
if not tool_args:
|
|
224
|
+
return "{}"
|
|
225
|
+
|
|
226
|
+
try:
|
|
227
|
+
# Use JSON for cleaner, more readable output
|
|
228
|
+
args_str = json.dumps(tool_args, default=str)
|
|
229
|
+
except (TypeError, ValueError):
|
|
230
|
+
# Fallback to str() if JSON fails
|
|
231
|
+
args_str = str(tool_args)
|
|
232
|
+
|
|
233
|
+
if len(args_str) <= max_length:
|
|
234
|
+
return args_str
|
|
235
|
+
|
|
236
|
+
# Truncate but indicate it's truncated
|
|
237
|
+
return args_str[: max_length - 3] + "..."
|
gaia/agents/base/mcp_agent.py
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
MCP-Capable Agent Base Class
|
|
6
|
-
Intermediate class for agents that support Model Context Protocol (MCP)
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from abc import abstractmethod
|
|
10
|
-
from typing import Any, Dict, List
|
|
11
|
-
|
|
12
|
-
from .agent import Agent
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class MCPAgent(Agent):
|
|
16
|
-
"""
|
|
17
|
-
Base class for agents that support MCP.
|
|
18
|
-
|
|
19
|
-
Agents that inherit from MCPAgent can be exposed via MCP servers,
|
|
20
|
-
allowing external tools (like VSCode) to interact with them.
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
@abstractmethod
|
|
24
|
-
def get_mcp_tool_definitions(self) -> List[Dict[str, Any]]:
|
|
25
|
-
"""
|
|
26
|
-
Return MCP tool definitions for this agent.
|
|
27
|
-
|
|
28
|
-
Each tool definition should include:
|
|
29
|
-
- name: Tool name (lowercase, dashes allowed)
|
|
30
|
-
- description: What the tool does
|
|
31
|
-
- inputSchema: JSON schema for parameters
|
|
32
|
-
|
|
33
|
-
Returns:
|
|
34
|
-
List of tool definition dictionaries
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
@abstractmethod
|
|
38
|
-
def execute_mcp_tool(
|
|
39
|
-
self, tool_name: str, arguments: Dict[str, Any]
|
|
40
|
-
) -> Dict[str, Any]:
|
|
41
|
-
"""
|
|
42
|
-
Execute an MCP tool call.
|
|
43
|
-
|
|
44
|
-
Args:
|
|
45
|
-
tool_name: Name of the tool to execute
|
|
46
|
-
arguments: Tool arguments from MCP client
|
|
47
|
-
|
|
48
|
-
Returns:
|
|
49
|
-
Result dictionary (will be JSON-serialized)
|
|
50
|
-
|
|
51
|
-
Raises:
|
|
52
|
-
ValueError: If tool_name is unknown
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
def get_mcp_prompts(self) -> List[Dict[str, Any]]:
|
|
56
|
-
"""
|
|
57
|
-
Optional: Return MCP prompts.
|
|
58
|
-
|
|
59
|
-
Prompts are pre-defined templates that clients can use.
|
|
60
|
-
Override this method if your agent provides prompts.
|
|
61
|
-
|
|
62
|
-
Returns:
|
|
63
|
-
List of prompt definitions (empty by default)
|
|
64
|
-
"""
|
|
65
|
-
return []
|
|
66
|
-
|
|
67
|
-
def get_mcp_resources(self) -> List[Dict[str, Any]]:
|
|
68
|
-
"""
|
|
69
|
-
Optional: Return MCP resources.
|
|
70
|
-
|
|
71
|
-
Resources are data sources the agent can provide.
|
|
72
|
-
Override this method if your agent exposes resources.
|
|
73
|
-
|
|
74
|
-
Returns:
|
|
75
|
-
List of resource definitions (empty by default)
|
|
76
|
-
"""
|
|
77
|
-
return []
|
|
78
|
-
|
|
79
|
-
def get_mcp_server_info(self) -> Dict[str, Any]:
|
|
80
|
-
"""
|
|
81
|
-
Get MCP server metadata for this agent.
|
|
82
|
-
|
|
83
|
-
Returns:
|
|
84
|
-
Server info dictionary with name and version
|
|
85
|
-
"""
|
|
86
|
-
return {"name": f"GAIA {self.__class__.__name__}", "version": "2.0.0"}
|
|
1
|
+
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
MCP-Capable Agent Base Class
|
|
6
|
+
Intermediate class for agents that support Model Context Protocol (MCP)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from abc import abstractmethod
|
|
10
|
+
from typing import Any, Dict, List
|
|
11
|
+
|
|
12
|
+
from .agent import Agent
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class MCPAgent(Agent):
|
|
16
|
+
"""
|
|
17
|
+
Base class for agents that support MCP.
|
|
18
|
+
|
|
19
|
+
Agents that inherit from MCPAgent can be exposed via MCP servers,
|
|
20
|
+
allowing external tools (like VSCode) to interact with them.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
@abstractmethod
|
|
24
|
+
def get_mcp_tool_definitions(self) -> List[Dict[str, Any]]:
|
|
25
|
+
"""
|
|
26
|
+
Return MCP tool definitions for this agent.
|
|
27
|
+
|
|
28
|
+
Each tool definition should include:
|
|
29
|
+
- name: Tool name (lowercase, dashes allowed)
|
|
30
|
+
- description: What the tool does
|
|
31
|
+
- inputSchema: JSON schema for parameters
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
List of tool definition dictionaries
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
@abstractmethod
|
|
38
|
+
def execute_mcp_tool(
|
|
39
|
+
self, tool_name: str, arguments: Dict[str, Any]
|
|
40
|
+
) -> Dict[str, Any]:
|
|
41
|
+
"""
|
|
42
|
+
Execute an MCP tool call.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
tool_name: Name of the tool to execute
|
|
46
|
+
arguments: Tool arguments from MCP client
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Result dictionary (will be JSON-serialized)
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
ValueError: If tool_name is unknown
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def get_mcp_prompts(self) -> List[Dict[str, Any]]:
|
|
56
|
+
"""
|
|
57
|
+
Optional: Return MCP prompts.
|
|
58
|
+
|
|
59
|
+
Prompts are pre-defined templates that clients can use.
|
|
60
|
+
Override this method if your agent provides prompts.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
List of prompt definitions (empty by default)
|
|
64
|
+
"""
|
|
65
|
+
return []
|
|
66
|
+
|
|
67
|
+
def get_mcp_resources(self) -> List[Dict[str, Any]]:
|
|
68
|
+
"""
|
|
69
|
+
Optional: Return MCP resources.
|
|
70
|
+
|
|
71
|
+
Resources are data sources the agent can provide.
|
|
72
|
+
Override this method if your agent exposes resources.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
List of resource definitions (empty by default)
|
|
76
|
+
"""
|
|
77
|
+
return []
|
|
78
|
+
|
|
79
|
+
def get_mcp_server_info(self) -> Dict[str, Any]:
|
|
80
|
+
"""
|
|
81
|
+
Get MCP server metadata for this agent.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
Server info dictionary with name and version
|
|
85
|
+
"""
|
|
86
|
+
return {"name": f"GAIA {self.__class__.__name__}", "version": "2.0.0"}
|