amd-gaia 0.15.0__py3-none-any.whl → 0.15.1__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.1.dist-info}/METADATA +223 -223
- amd_gaia-0.15.1.dist-info/RECORD +178 -0
- {amd_gaia-0.15.0.dist-info → amd_gaia-0.15.1.dist-info}/entry_points.txt +1 -0
- {amd_gaia-0.15.0.dist-info → amd_gaia-0.15.1.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 +2177 -2177
- gaia/agents/base/api_agent.py +120 -120
- gaia/agents/base/console.py +1841 -1841
- gaia/agents/base/errors.py +237 -237
- gaia/agents/base/mcp_agent.py +86 -86
- gaia/agents/base/tools.py +83 -83
- gaia/agents/blender/agent.py +556 -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 +835 -835
- gaia/agents/chat/app.py +1058 -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 +1729 -1729
- gaia/agents/chat/tools/shell_tools.py +436 -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 +2036 -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 +642 -642
- gaia/agents/emr/__init__.py +8 -8
- gaia/agents/emr/agent.py +1506 -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 +1974 -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 +173 -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 +430 -430
- gaia/chat/prompts.py +522 -522
- gaia/chat/sdk.py +1228 -1225
- gaia/cli.py +5481 -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/llm/__init__.py +9 -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 +3236 -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 +120 -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 +163 -163
- gaia/talk/app.py +289 -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.1.dist-info}/WHEEL +0 -0
- {amd_gaia-0.15.0.dist-info → amd_gaia-0.15.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Prompts and styles for the SummarizerAgent.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# Summary styles
|
|
9
|
+
SUMMARY_STYLES = {
|
|
10
|
+
"brief": """Write a VERY concise summary.
|
|
11
|
+
STRICT RULES:
|
|
12
|
+
- Limit to at most 3 sentences.
|
|
13
|
+
- Do not use bullet points.
|
|
14
|
+
- Avoid lists of any kind.
|
|
15
|
+
- Highlight only the 2–3 most essential takeaways.
|
|
16
|
+
- Exclude filler phrases (e.g., "Overall", "In summary", "This document discusses…").""",
|
|
17
|
+
"detailed": """Write a COMPREHENSIVE, richly detailed summary with metric-focused extraction.
|
|
18
|
+
STRICT RULES:
|
|
19
|
+
- At least 10 sentences or 250+ words.
|
|
20
|
+
- Extract and include ALL quantitative data: numbers, percentages, dollar amounts, dates, metrics, KPIs
|
|
21
|
+
- For business documents, structure as: Current Performance → Financial Projections → Market Analysis → Strategy
|
|
22
|
+
- Identify and name: competitors, partners, target customers, specific technologies
|
|
23
|
+
- Include complete financial breakdowns when present (fund allocation, revenue projections, cost structure)
|
|
24
|
+
- Capture traction indicators: customer count, revenue, growth rates, retention metrics, market validation
|
|
25
|
+
- Cover complete context, motivations, decisions, reasoning, and implications.
|
|
26
|
+
- Retain all key technical details, timelines, and constraints.
|
|
27
|
+
- Structure the content into clear, coherent paragraphs.
|
|
28
|
+
- Do not use bullet points.""",
|
|
29
|
+
"bullets": """Write the ENTIRE summary as bullet points.
|
|
30
|
+
STRICT RULES:
|
|
31
|
+
- Use no more than 3 bullets for the whole summary.
|
|
32
|
+
- Start every line with "- ".
|
|
33
|
+
- Do not include paragraphs.
|
|
34
|
+
- Keep each sentence under 20 words.
|
|
35
|
+
- Express exactly one clear idea per bullet.
|
|
36
|
+
- Emphasize actionable insights, decisions, and major facts.""",
|
|
37
|
+
"executive": """Write a high-level EXECUTIVE SUMMARY with strict prioritization.
|
|
38
|
+
STRICT RULES:
|
|
39
|
+
- Limit to a maximum of 5 sentences.
|
|
40
|
+
- PRIORITIZE in this exact order:
|
|
41
|
+
1. Quantitative metrics (revenue, customers, growth rates, retention)
|
|
42
|
+
2. Financial data (funding amounts, projections, valuations, ROI)
|
|
43
|
+
3. Strategic outcomes and business impact
|
|
44
|
+
4. Key differentiators and competitive advantages
|
|
45
|
+
- ALWAYS include specific numbers when present: revenue, customers, percentages, dollar amounts, timelines
|
|
46
|
+
- For business proposals/investor documents: MUST include current traction, funding ask/allocation, and projections
|
|
47
|
+
- Exclude qualitative marketing descriptions unless no metrics exist
|
|
48
|
+
- Maintain a formal, board-ready, outcome-focused tone.
|
|
49
|
+
- Do not use bullet points.""",
|
|
50
|
+
"participants": """Extract ONLY meeting participants.
|
|
51
|
+
STRICT RULES:
|
|
52
|
+
- Produce a bullet list as the only output.
|
|
53
|
+
- Format every line exactly as: "- Name — Role".
|
|
54
|
+
- If the role is unclear, infer only when safe; otherwise use "Role not specified".
|
|
55
|
+
- Do not add any narrative or summary.
|
|
56
|
+
- Do not mention actions or outcomes.""",
|
|
57
|
+
"action_items": """Extract ONLY action items.
|
|
58
|
+
STRICT RULES:
|
|
59
|
+
- Output only a bullet list.
|
|
60
|
+
- Use this exact format for each bullet:
|
|
61
|
+
"- Action: <description>; Owner: <person or team>; Deadline: <date or 'Not specified'>"
|
|
62
|
+
- Do not include any additional text.
|
|
63
|
+
- Include items that are explicitly stated or clearly implied.
|
|
64
|
+
- Avoid any inference beyond what is safely justified.""",
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# System prompts for different input types
|
|
68
|
+
SYSTEM_PROMPTS = {
|
|
69
|
+
"transcript": """You are a professional meeting summarizer. Analyze meeting transcripts to extract key information,
|
|
70
|
+
decisions, and action items. Be precise and comprehensive.""",
|
|
71
|
+
"email": """You are a professional email summarizer. Analyze emails to extract key information, requests, and
|
|
72
|
+
required actions. Focus on the sender's intent and recipient's needed response.""",
|
|
73
|
+
"pdf": """You are a professional document summarizer specializing in extracting critical quantitative data.
|
|
74
|
+
|
|
75
|
+
DOCUMENT TYPE AWARENESS:
|
|
76
|
+
- For business proposals/investor decks: Prioritize traction metrics (customers, revenue, ARR, growth rates, retention),
|
|
77
|
+
financial projections, fund allocation, market sizing, competitive landscape, and exit strategy
|
|
78
|
+
- For financial reports: Focus on revenue, expenses, margins, projections, and key performance indicators
|
|
79
|
+
- For technical specs: Emphasize capabilities, performance metrics, implementation details, and requirements
|
|
80
|
+
|
|
81
|
+
EXTRACTION PRIORITIES:
|
|
82
|
+
1. All numbers: revenue, customers, percentages, dollar amounts, growth rates, metrics
|
|
83
|
+
2. Named entities: competitors, partners, customers, products, technologies
|
|
84
|
+
3. Financial data: projections, allocations, valuations, ROI, costs
|
|
85
|
+
4. Strategic information: market size, competitive advantages, timelines
|
|
86
|
+
5. Qualitative descriptions: only after all quantitative data is captured
|
|
87
|
+
|
|
88
|
+
Never sacrifice metrics for marketing language. Investors need proof, not promises.""",
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
# Templates for different operations
|
|
92
|
+
ITERATIVE_SUMMARY_TEMPLATE = """You are updating a cumulative summary of a long document.
|
|
93
|
+
|
|
94
|
+
CRITICAL INSTRUCTIONS:
|
|
95
|
+
- Read the existing summary and the new chunk carefully.
|
|
96
|
+
- Identify NEW facts, details, or information in the new chunk that are NOT already present in the existing summary.
|
|
97
|
+
- Do NOT repeat, restate, rephrase, or copy ANY information already in the existing summary.
|
|
98
|
+
- Output ONLY the new sentences to be appended (no preamble, no reformulation of existing content).
|
|
99
|
+
- Do NOT include transition phrases like "Additionally" or "Furthermore" - just the raw new facts.
|
|
100
|
+
|
|
101
|
+
MAINTAIN THE STYLE:
|
|
102
|
+
{style_instruction}
|
|
103
|
+
|
|
104
|
+
Existing summary (DO NOT MODIFY OR REPEAT):
|
|
105
|
+
{previous_summary}
|
|
106
|
+
|
|
107
|
+
New Chunk:
|
|
108
|
+
{new_chunk}
|
|
109
|
+
|
|
110
|
+
Output ONLY the new sentences to append to the summary:
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
DOCUMENT_SUMMARY_TEMPLATE = """{style_instruction}
|
|
114
|
+
|
|
115
|
+
Please summarize the following document text:
|
|
116
|
+
|
|
117
|
+
{document_text}"""
|
|
118
|
+
|
|
119
|
+
DETECTION_PROMPT_TEMPLATE = """You are a strict classifier. Read the text and classify it as either an email or a meeting transcript.
|
|
120
|
+
|
|
121
|
+
Definitions:
|
|
122
|
+
- transcript: multiple speakers/dialogue, timestamps or speaker labels, conversational flow.
|
|
123
|
+
- email: From/To/Subject headers or email-like structure, greeting/closing, single author perspective.
|
|
124
|
+
|
|
125
|
+
Output requirement:
|
|
126
|
+
Respond with EXACTLY one lowercase word and nothing else: transcript OR email.
|
|
127
|
+
|
|
128
|
+
Text:
|
|
129
|
+
{text_excerpt}"""
|
gaia/api/__init__.py
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
"""
|
|
4
|
-
GAIA OpenAI-Compatible API
|
|
5
|
-
|
|
6
|
-
This module provides an OpenAI-compatible REST API for GAIA agents.
|
|
7
|
-
Agents can be accessed via standard OpenAI client libraries.
|
|
8
|
-
|
|
9
|
-
Usage:
|
|
10
|
-
# Start server
|
|
11
|
-
gaia api start --port 8080
|
|
12
|
-
|
|
13
|
-
# Use with OpenAI client
|
|
14
|
-
from openai import OpenAI
|
|
15
|
-
client = OpenAI(base_url="http://localhost:8080/v1", api_key="dummy")
|
|
16
|
-
|
|
17
|
-
response = client.chat.completions.create(
|
|
18
|
-
model="gaia-code-agent",
|
|
19
|
-
messages=[{"role": "user", "content": "Write hello world"}]
|
|
20
|
-
)
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
__version__ = "1.0.0"
|
|
1
|
+
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
"""
|
|
4
|
+
GAIA OpenAI-Compatible API
|
|
5
|
+
|
|
6
|
+
This module provides an OpenAI-compatible REST API for GAIA agents.
|
|
7
|
+
Agents can be accessed via standard OpenAI client libraries.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
# Start server
|
|
11
|
+
gaia api start --port 8080
|
|
12
|
+
|
|
13
|
+
# Use with OpenAI client
|
|
14
|
+
from openai import OpenAI
|
|
15
|
+
client = OpenAI(base_url="http://localhost:8080/v1", api_key="dummy")
|
|
16
|
+
|
|
17
|
+
response = client.chat.completions.create(
|
|
18
|
+
model="gaia-code-agent",
|
|
19
|
+
messages=[{"role": "user", "content": "Write hello world"}]
|
|
20
|
+
)
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
__version__ = "1.0.0"
|
gaia/api/agent_registry.py
CHANGED
|
@@ -1,238 +1,238 @@
|
|
|
1
|
-
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
"""
|
|
4
|
-
Agent Registry - Exposes GAIA agents as OpenAI "models"
|
|
5
|
-
|
|
6
|
-
GAIA doesn't manage LLM models (Lemonade does that). Instead, we expose
|
|
7
|
-
GAIA agents as "models" in the OpenAI API, allowing users to select which
|
|
8
|
-
agent type they want to use.
|
|
9
|
-
|
|
10
|
-
Example:
|
|
11
|
-
User selects "gaia-code" model -> Routes to CodeAgent
|
|
12
|
-
User selects "gaia-jira" model -> Routes to JiraAgent
|
|
13
|
-
|
|
14
|
-
This is a simple hardcoded mapping for users to select agent types.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
import logging
|
|
18
|
-
import os
|
|
19
|
-
import time
|
|
20
|
-
from typing import Any, Dict, List
|
|
21
|
-
|
|
22
|
-
from gaia.agents.base.agent import Agent
|
|
23
|
-
from gaia.agents.base.api_agent import ApiAgent
|
|
24
|
-
from gaia.api.sse_handler import SSEOutputHandler
|
|
25
|
-
|
|
26
|
-
logger = logging.getLogger(__name__)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
# Hardcoded agent mappings: "model" name -> (Agent class, init params)
|
|
30
|
-
# These are the "models" exposed in /v1/models and selectable in VSCode
|
|
31
|
-
AGENT_MODELS = {
|
|
32
|
-
"gaia-code": {
|
|
33
|
-
"class_name": "gaia.agents.routing.agent.RoutingAgent",
|
|
34
|
-
"init_params": {
|
|
35
|
-
"api_mode": True, # Skip interactive questions, use defaults/best-guess
|
|
36
|
-
"silent_mode": True,
|
|
37
|
-
"streaming": False,
|
|
38
|
-
"max_steps": 100,
|
|
39
|
-
},
|
|
40
|
-
"description": "Intelligent routing agent that detects language/project type and routes to CodeAgent",
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# Apply environment variable overrides to all agent init_params
|
|
46
|
-
# These are set by app.py when starting the API server with debug flags
|
|
47
|
-
def _apply_env_overrides():
|
|
48
|
-
"""
|
|
49
|
-
Read environment variables set by `gaia api start` and override agent init_params.
|
|
50
|
-
|
|
51
|
-
Environment variables:
|
|
52
|
-
GAIA_API_DEBUG: Enable debug logging and console output
|
|
53
|
-
GAIA_API_SHOW_PROMPTS: Display prompts sent to LLM
|
|
54
|
-
GAIA_API_STREAMING: Enable real-time streaming of LLM responses
|
|
55
|
-
GAIA_API_STEP_THROUGH: Enable step-through debugging mode
|
|
56
|
-
"""
|
|
57
|
-
debug = os.environ.get("GAIA_API_DEBUG") == "1"
|
|
58
|
-
show_prompts = os.environ.get("GAIA_API_SHOW_PROMPTS") == "1"
|
|
59
|
-
streaming = os.environ.get("GAIA_API_STREAMING") == "1"
|
|
60
|
-
|
|
61
|
-
# Apply overrides to all agents
|
|
62
|
-
for model_id, config in AGENT_MODELS.items():
|
|
63
|
-
init_params = config["init_params"]
|
|
64
|
-
|
|
65
|
-
# When debug is enabled, disable silent_mode to show console output
|
|
66
|
-
if debug:
|
|
67
|
-
init_params["debug"] = True
|
|
68
|
-
init_params["silent_mode"] = False
|
|
69
|
-
logger.info(f"Debug mode enabled for {model_id}")
|
|
70
|
-
|
|
71
|
-
if show_prompts:
|
|
72
|
-
init_params["show_prompts"] = True
|
|
73
|
-
logger.info(f"Show prompts enabled for {model_id}")
|
|
74
|
-
|
|
75
|
-
if streaming:
|
|
76
|
-
init_params["streaming"] = True
|
|
77
|
-
logger.info(f"Streaming enabled for {model_id}")
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# Apply environment overrides at module import time
|
|
81
|
-
_apply_env_overrides()
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
class AgentRegistry:
|
|
85
|
-
"""
|
|
86
|
-
Registry that exposes GAIA agents as OpenAI-compatible "models".
|
|
87
|
-
|
|
88
|
-
Note: These aren't LLM models - they're GAIA agent types.
|
|
89
|
-
Lemonade handles the actual LLM models underneath.
|
|
90
|
-
"""
|
|
91
|
-
|
|
92
|
-
def __init__(self):
|
|
93
|
-
"""Initialize registry with hardcoded agents"""
|
|
94
|
-
self._loaded_classes: Dict[str, type] = {}
|
|
95
|
-
|
|
96
|
-
def _load_agent_class(self, class_path: str) -> type:
|
|
97
|
-
"""
|
|
98
|
-
Dynamically load agent class from module path.
|
|
99
|
-
|
|
100
|
-
Args:
|
|
101
|
-
class_path: Full module path (e.g., "gaia.agents.code.agent.CodeAgent")
|
|
102
|
-
|
|
103
|
-
Returns:
|
|
104
|
-
Agent class
|
|
105
|
-
"""
|
|
106
|
-
if class_path in self._loaded_classes:
|
|
107
|
-
return self._loaded_classes[class_path]
|
|
108
|
-
|
|
109
|
-
module_path, class_name = class_path.rsplit(".", 1)
|
|
110
|
-
module = __import__(module_path, fromlist=[class_name])
|
|
111
|
-
cls = getattr(module, class_name)
|
|
112
|
-
|
|
113
|
-
self._loaded_classes[class_path] = cls
|
|
114
|
-
return cls
|
|
115
|
-
|
|
116
|
-
def get_agent(self, model_id: str) -> Agent:
|
|
117
|
-
"""
|
|
118
|
-
Instantiate and return agent for model ID with SSE output handler.
|
|
119
|
-
|
|
120
|
-
Args:
|
|
121
|
-
model_id: Model ID (e.g., "gaia-code", "gaia-jira")
|
|
122
|
-
|
|
123
|
-
Returns:
|
|
124
|
-
Agent instance configured for API streaming
|
|
125
|
-
|
|
126
|
-
Raises:
|
|
127
|
-
ValueError: If model_id not found
|
|
128
|
-
|
|
129
|
-
Example:
|
|
130
|
-
>>> registry = AgentRegistry()
|
|
131
|
-
>>> agent = registry.get_agent("gaia-code")
|
|
132
|
-
>>> result = agent.process_query("Write hello world")
|
|
133
|
-
"""
|
|
134
|
-
if model_id not in AGENT_MODELS:
|
|
135
|
-
available = ", ".join(AGENT_MODELS.keys())
|
|
136
|
-
raise ValueError(
|
|
137
|
-
f"Model '{model_id}' not found. " f"Available models: {available}"
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
config = AGENT_MODELS[model_id]
|
|
141
|
-
|
|
142
|
-
try:
|
|
143
|
-
agent_class = self._load_agent_class(config["class_name"])
|
|
144
|
-
init_params = config["init_params"].copy()
|
|
145
|
-
|
|
146
|
-
# Check if debug mode is enabled
|
|
147
|
-
debug_mode = os.environ.get("GAIA_API_DEBUG") == "1"
|
|
148
|
-
|
|
149
|
-
# API layer always uses SSEOutputHandler for streaming to clients
|
|
150
|
-
# Pass debug_mode flag to control verbosity
|
|
151
|
-
init_params["output_handler"] = SSEOutputHandler(debug_mode=debug_mode)
|
|
152
|
-
|
|
153
|
-
if debug_mode:
|
|
154
|
-
logger.debug(f"Creating agent {model_id} with debug mode enabled")
|
|
155
|
-
|
|
156
|
-
return agent_class(**init_params)
|
|
157
|
-
except ImportError as e:
|
|
158
|
-
logger.error(f"Failed to load agent {model_id}: {e}")
|
|
159
|
-
raise ValueError(f"Agent {model_id} not available: {e}")
|
|
160
|
-
|
|
161
|
-
def list_models(self) -> List[Dict[str, Any]]:
|
|
162
|
-
"""
|
|
163
|
-
Return OpenAI-compatible model list.
|
|
164
|
-
|
|
165
|
-
Note: These are GAIA agents exposed as "models", not LLM models.
|
|
166
|
-
|
|
167
|
-
Returns:
|
|
168
|
-
List of model metadata dicts for /v1/models endpoint
|
|
169
|
-
|
|
170
|
-
Example:
|
|
171
|
-
>>> registry = AgentRegistry()
|
|
172
|
-
>>> models = registry.list_models()
|
|
173
|
-
>>> [m["id"] for m in models]
|
|
174
|
-
['gaia-code', 'gaia-jira']
|
|
175
|
-
"""
|
|
176
|
-
models = []
|
|
177
|
-
|
|
178
|
-
for model_id, config in AGENT_MODELS.items():
|
|
179
|
-
try:
|
|
180
|
-
# Try to load agent to get metadata (if it implements ApiAgent)
|
|
181
|
-
agent_class = self._load_agent_class(config["class_name"])
|
|
182
|
-
agent = agent_class(**config["init_params"])
|
|
183
|
-
|
|
184
|
-
# Get model info (custom if ApiAgent, default otherwise)
|
|
185
|
-
if isinstance(agent, ApiAgent):
|
|
186
|
-
model_info = agent.get_model_info()
|
|
187
|
-
logger.debug(
|
|
188
|
-
f"Agent {model_id} provides custom model info: {model_info}"
|
|
189
|
-
)
|
|
190
|
-
else:
|
|
191
|
-
model_info = {
|
|
192
|
-
"max_input_tokens": 8192,
|
|
193
|
-
"max_output_tokens": 4096,
|
|
194
|
-
}
|
|
195
|
-
logger.debug(f"Agent {model_id} using default model info")
|
|
196
|
-
except Exception as e:
|
|
197
|
-
# Agent not available or initialization failed, use defaults
|
|
198
|
-
logger.warning(f"Agent {model_id} not available ({e}), using defaults")
|
|
199
|
-
model_info = {
|
|
200
|
-
"max_input_tokens": 8192,
|
|
201
|
-
"max_output_tokens": 4096,
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
models.append(
|
|
205
|
-
{
|
|
206
|
-
"id": model_id,
|
|
207
|
-
"object": "model",
|
|
208
|
-
"created": int(time.time()),
|
|
209
|
-
"owned_by": "amd-gaia",
|
|
210
|
-
"description": config.get("description", ""),
|
|
211
|
-
**model_info,
|
|
212
|
-
}
|
|
213
|
-
)
|
|
214
|
-
|
|
215
|
-
return models
|
|
216
|
-
|
|
217
|
-
def model_exists(self, model_id: str) -> bool:
|
|
218
|
-
"""
|
|
219
|
-
Check if model ID exists.
|
|
220
|
-
|
|
221
|
-
Args:
|
|
222
|
-
model_id: Model ID to check
|
|
223
|
-
|
|
224
|
-
Returns:
|
|
225
|
-
True if model exists, False otherwise
|
|
226
|
-
|
|
227
|
-
Example:
|
|
228
|
-
>>> registry = AgentRegistry()
|
|
229
|
-
>>> registry.model_exists("gaia-code")
|
|
230
|
-
True
|
|
231
|
-
>>> registry.model_exists("nonexistent")
|
|
232
|
-
False
|
|
233
|
-
"""
|
|
234
|
-
return model_id in AGENT_MODELS
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
# Global registry instance
|
|
238
|
-
registry = AgentRegistry()
|
|
1
|
+
# Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
"""
|
|
4
|
+
Agent Registry - Exposes GAIA agents as OpenAI "models"
|
|
5
|
+
|
|
6
|
+
GAIA doesn't manage LLM models (Lemonade does that). Instead, we expose
|
|
7
|
+
GAIA agents as "models" in the OpenAI API, allowing users to select which
|
|
8
|
+
agent type they want to use.
|
|
9
|
+
|
|
10
|
+
Example:
|
|
11
|
+
User selects "gaia-code" model -> Routes to CodeAgent
|
|
12
|
+
User selects "gaia-jira" model -> Routes to JiraAgent
|
|
13
|
+
|
|
14
|
+
This is a simple hardcoded mapping for users to select agent types.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import logging
|
|
18
|
+
import os
|
|
19
|
+
import time
|
|
20
|
+
from typing import Any, Dict, List
|
|
21
|
+
|
|
22
|
+
from gaia.agents.base.agent import Agent
|
|
23
|
+
from gaia.agents.base.api_agent import ApiAgent
|
|
24
|
+
from gaia.api.sse_handler import SSEOutputHandler
|
|
25
|
+
|
|
26
|
+
logger = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Hardcoded agent mappings: "model" name -> (Agent class, init params)
|
|
30
|
+
# These are the "models" exposed in /v1/models and selectable in VSCode
|
|
31
|
+
AGENT_MODELS = {
|
|
32
|
+
"gaia-code": {
|
|
33
|
+
"class_name": "gaia.agents.routing.agent.RoutingAgent",
|
|
34
|
+
"init_params": {
|
|
35
|
+
"api_mode": True, # Skip interactive questions, use defaults/best-guess
|
|
36
|
+
"silent_mode": True,
|
|
37
|
+
"streaming": False,
|
|
38
|
+
"max_steps": 100,
|
|
39
|
+
},
|
|
40
|
+
"description": "Intelligent routing agent that detects language/project type and routes to CodeAgent",
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Apply environment variable overrides to all agent init_params
|
|
46
|
+
# These are set by app.py when starting the API server with debug flags
|
|
47
|
+
def _apply_env_overrides():
|
|
48
|
+
"""
|
|
49
|
+
Read environment variables set by `gaia api start` and override agent init_params.
|
|
50
|
+
|
|
51
|
+
Environment variables:
|
|
52
|
+
GAIA_API_DEBUG: Enable debug logging and console output
|
|
53
|
+
GAIA_API_SHOW_PROMPTS: Display prompts sent to LLM
|
|
54
|
+
GAIA_API_STREAMING: Enable real-time streaming of LLM responses
|
|
55
|
+
GAIA_API_STEP_THROUGH: Enable step-through debugging mode
|
|
56
|
+
"""
|
|
57
|
+
debug = os.environ.get("GAIA_API_DEBUG") == "1"
|
|
58
|
+
show_prompts = os.environ.get("GAIA_API_SHOW_PROMPTS") == "1"
|
|
59
|
+
streaming = os.environ.get("GAIA_API_STREAMING") == "1"
|
|
60
|
+
|
|
61
|
+
# Apply overrides to all agents
|
|
62
|
+
for model_id, config in AGENT_MODELS.items():
|
|
63
|
+
init_params = config["init_params"]
|
|
64
|
+
|
|
65
|
+
# When debug is enabled, disable silent_mode to show console output
|
|
66
|
+
if debug:
|
|
67
|
+
init_params["debug"] = True
|
|
68
|
+
init_params["silent_mode"] = False
|
|
69
|
+
logger.info(f"Debug mode enabled for {model_id}")
|
|
70
|
+
|
|
71
|
+
if show_prompts:
|
|
72
|
+
init_params["show_prompts"] = True
|
|
73
|
+
logger.info(f"Show prompts enabled for {model_id}")
|
|
74
|
+
|
|
75
|
+
if streaming:
|
|
76
|
+
init_params["streaming"] = True
|
|
77
|
+
logger.info(f"Streaming enabled for {model_id}")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# Apply environment overrides at module import time
|
|
81
|
+
_apply_env_overrides()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class AgentRegistry:
|
|
85
|
+
"""
|
|
86
|
+
Registry that exposes GAIA agents as OpenAI-compatible "models".
|
|
87
|
+
|
|
88
|
+
Note: These aren't LLM models - they're GAIA agent types.
|
|
89
|
+
Lemonade handles the actual LLM models underneath.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
def __init__(self):
|
|
93
|
+
"""Initialize registry with hardcoded agents"""
|
|
94
|
+
self._loaded_classes: Dict[str, type] = {}
|
|
95
|
+
|
|
96
|
+
def _load_agent_class(self, class_path: str) -> type:
|
|
97
|
+
"""
|
|
98
|
+
Dynamically load agent class from module path.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
class_path: Full module path (e.g., "gaia.agents.code.agent.CodeAgent")
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Agent class
|
|
105
|
+
"""
|
|
106
|
+
if class_path in self._loaded_classes:
|
|
107
|
+
return self._loaded_classes[class_path]
|
|
108
|
+
|
|
109
|
+
module_path, class_name = class_path.rsplit(".", 1)
|
|
110
|
+
module = __import__(module_path, fromlist=[class_name])
|
|
111
|
+
cls = getattr(module, class_name)
|
|
112
|
+
|
|
113
|
+
self._loaded_classes[class_path] = cls
|
|
114
|
+
return cls
|
|
115
|
+
|
|
116
|
+
def get_agent(self, model_id: str) -> Agent:
|
|
117
|
+
"""
|
|
118
|
+
Instantiate and return agent for model ID with SSE output handler.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
model_id: Model ID (e.g., "gaia-code", "gaia-jira")
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Agent instance configured for API streaming
|
|
125
|
+
|
|
126
|
+
Raises:
|
|
127
|
+
ValueError: If model_id not found
|
|
128
|
+
|
|
129
|
+
Example:
|
|
130
|
+
>>> registry = AgentRegistry()
|
|
131
|
+
>>> agent = registry.get_agent("gaia-code")
|
|
132
|
+
>>> result = agent.process_query("Write hello world")
|
|
133
|
+
"""
|
|
134
|
+
if model_id not in AGENT_MODELS:
|
|
135
|
+
available = ", ".join(AGENT_MODELS.keys())
|
|
136
|
+
raise ValueError(
|
|
137
|
+
f"Model '{model_id}' not found. " f"Available models: {available}"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
config = AGENT_MODELS[model_id]
|
|
141
|
+
|
|
142
|
+
try:
|
|
143
|
+
agent_class = self._load_agent_class(config["class_name"])
|
|
144
|
+
init_params = config["init_params"].copy()
|
|
145
|
+
|
|
146
|
+
# Check if debug mode is enabled
|
|
147
|
+
debug_mode = os.environ.get("GAIA_API_DEBUG") == "1"
|
|
148
|
+
|
|
149
|
+
# API layer always uses SSEOutputHandler for streaming to clients
|
|
150
|
+
# Pass debug_mode flag to control verbosity
|
|
151
|
+
init_params["output_handler"] = SSEOutputHandler(debug_mode=debug_mode)
|
|
152
|
+
|
|
153
|
+
if debug_mode:
|
|
154
|
+
logger.debug(f"Creating agent {model_id} with debug mode enabled")
|
|
155
|
+
|
|
156
|
+
return agent_class(**init_params)
|
|
157
|
+
except ImportError as e:
|
|
158
|
+
logger.error(f"Failed to load agent {model_id}: {e}")
|
|
159
|
+
raise ValueError(f"Agent {model_id} not available: {e}")
|
|
160
|
+
|
|
161
|
+
def list_models(self) -> List[Dict[str, Any]]:
|
|
162
|
+
"""
|
|
163
|
+
Return OpenAI-compatible model list.
|
|
164
|
+
|
|
165
|
+
Note: These are GAIA agents exposed as "models", not LLM models.
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
List of model metadata dicts for /v1/models endpoint
|
|
169
|
+
|
|
170
|
+
Example:
|
|
171
|
+
>>> registry = AgentRegistry()
|
|
172
|
+
>>> models = registry.list_models()
|
|
173
|
+
>>> [m["id"] for m in models]
|
|
174
|
+
['gaia-code', 'gaia-jira']
|
|
175
|
+
"""
|
|
176
|
+
models = []
|
|
177
|
+
|
|
178
|
+
for model_id, config in AGENT_MODELS.items():
|
|
179
|
+
try:
|
|
180
|
+
# Try to load agent to get metadata (if it implements ApiAgent)
|
|
181
|
+
agent_class = self._load_agent_class(config["class_name"])
|
|
182
|
+
agent = agent_class(**config["init_params"])
|
|
183
|
+
|
|
184
|
+
# Get model info (custom if ApiAgent, default otherwise)
|
|
185
|
+
if isinstance(agent, ApiAgent):
|
|
186
|
+
model_info = agent.get_model_info()
|
|
187
|
+
logger.debug(
|
|
188
|
+
f"Agent {model_id} provides custom model info: {model_info}"
|
|
189
|
+
)
|
|
190
|
+
else:
|
|
191
|
+
model_info = {
|
|
192
|
+
"max_input_tokens": 8192,
|
|
193
|
+
"max_output_tokens": 4096,
|
|
194
|
+
}
|
|
195
|
+
logger.debug(f"Agent {model_id} using default model info")
|
|
196
|
+
except Exception as e:
|
|
197
|
+
# Agent not available or initialization failed, use defaults
|
|
198
|
+
logger.warning(f"Agent {model_id} not available ({e}), using defaults")
|
|
199
|
+
model_info = {
|
|
200
|
+
"max_input_tokens": 8192,
|
|
201
|
+
"max_output_tokens": 4096,
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
models.append(
|
|
205
|
+
{
|
|
206
|
+
"id": model_id,
|
|
207
|
+
"object": "model",
|
|
208
|
+
"created": int(time.time()),
|
|
209
|
+
"owned_by": "amd-gaia",
|
|
210
|
+
"description": config.get("description", ""),
|
|
211
|
+
**model_info,
|
|
212
|
+
}
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
return models
|
|
216
|
+
|
|
217
|
+
def model_exists(self, model_id: str) -> bool:
|
|
218
|
+
"""
|
|
219
|
+
Check if model ID exists.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
model_id: Model ID to check
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
True if model exists, False otherwise
|
|
226
|
+
|
|
227
|
+
Example:
|
|
228
|
+
>>> registry = AgentRegistry()
|
|
229
|
+
>>> registry.model_exists("gaia-code")
|
|
230
|
+
True
|
|
231
|
+
>>> registry.model_exists("nonexistent")
|
|
232
|
+
False
|
|
233
|
+
"""
|
|
234
|
+
return model_id in AGENT_MODELS
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
# Global registry instance
|
|
238
|
+
registry = AgentRegistry()
|