amd-gaia 0.14.1__py3-none-any.whl → 0.14.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.14.2.dist-info/METADATA +220 -0
- {amd_gaia-0.14.1.dist-info → amd_gaia-0.14.2.dist-info}/RECORD +32 -32
- gaia/agents/base/agent.py +32 -4
- gaia/agents/base/console.py +1 -1
- gaia/agents/chat/agent.py +5 -28
- gaia/agents/code/orchestration/checklist_executor.py +26 -2
- gaia/agents/code/orchestration/checklist_generator.py +7 -3
- gaia/agents/code/orchestration/orchestrator.py +64 -44
- gaia/agents/code/orchestration/steps/error_handler.py +1 -1
- gaia/agents/code/orchestration/template_catalog.py +7 -1
- gaia/agents/code/prompts/code_patterns.py +128 -17
- gaia/agents/code/tools/code_formatting.py +1 -1
- gaia/agents/code/tools/code_tools.py +1 -1
- gaia/agents/code/tools/web_dev_tools.py +16 -1
- gaia/apps/summarize/pdf_formatter.py +1 -1
- gaia/audio/audio_client.py +2 -2
- gaia/audio/kokoro_tts.py +2 -2
- gaia/audio/whisper_asr.py +2 -2
- gaia/chat/sdk.py +1 -1
- gaia/cli.py +16 -16
- gaia/eval/batch_experiment.py +1 -1
- gaia/eval/claude.py +4 -4
- gaia/llm/llm_client.py +1 -1
- gaia/rag/demo.py +5 -5
- gaia/rag/pdf_utils.py +1 -1
- gaia/rag/sdk.py +2 -2
- gaia/talk/sdk.py +1 -1
- gaia/version.py +1 -1
- amd_gaia-0.14.1.dist-info/METADATA +0 -768
- {amd_gaia-0.14.1.dist-info → amd_gaia-0.14.2.dist-info}/WHEEL +0 -0
- {amd_gaia-0.14.1.dist-info → amd_gaia-0.14.2.dist-info}/entry_points.txt +0 -0
- {amd_gaia-0.14.1.dist-info → amd_gaia-0.14.2.dist-info}/licenses/LICENSE.md +0 -0
- {amd_gaia-0.14.1.dist-info → amd_gaia-0.14.2.dist-info}/top_level.txt +0 -0
|
@@ -445,7 +445,7 @@ class Orchestrator:
|
|
|
445
445
|
)
|
|
446
446
|
|
|
447
447
|
try:
|
|
448
|
-
response = self.llm_client.send(prompt, timeout=1200
|
|
448
|
+
response = self.llm_client.send(prompt, timeout=1200)
|
|
449
449
|
data = self._parse_checkpoint_response(response)
|
|
450
450
|
return CheckpointAssessment(
|
|
451
451
|
status=data.get("status", "needs_fix"),
|
|
@@ -472,7 +472,9 @@ class Orchestrator:
|
|
|
472
472
|
validation_history: List[Any],
|
|
473
473
|
) -> str:
|
|
474
474
|
"""Build the prompt for the checkpoint reviewer."""
|
|
475
|
-
validation_summary = self._format_validation_history(
|
|
475
|
+
validation_summary = self._format_validation_history(
|
|
476
|
+
validation_history, getattr(execution_result, "validation_logs", None)
|
|
477
|
+
)
|
|
476
478
|
|
|
477
479
|
outstanding = (
|
|
478
480
|
"\n".join(f"- {item}" for item in context.fix_feedback)
|
|
@@ -530,52 +532,70 @@ class Orchestrator:
|
|
|
530
532
|
logger.exception("Failed to summarize conversation history: %s", exc)
|
|
531
533
|
return None
|
|
532
534
|
|
|
533
|
-
def _format_validation_history(
|
|
534
|
-
|
|
535
|
+
def _format_validation_history(
|
|
536
|
+
self, validation_history: List[Any], latest_plan_logs: Optional[List[Any]]
|
|
537
|
+
) -> str:
|
|
538
|
+
"""Format validation logs, splitting latest plan from historical ones."""
|
|
539
|
+
|
|
535
540
|
if not validation_history:
|
|
536
541
|
return "No validation or test commands have been executed yet."
|
|
537
542
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
if
|
|
542
|
-
|
|
543
|
-
elif isinstance(entry, dict):
|
|
544
|
-
entry_data = entry
|
|
545
|
-
else:
|
|
546
|
-
entry_data = {}
|
|
543
|
+
latest_logs = latest_plan_logs or []
|
|
544
|
+
latest_count = len(latest_logs)
|
|
545
|
+
historical_logs = (
|
|
546
|
+
validation_history[:-latest_count] if latest_count else validation_history
|
|
547
|
+
)
|
|
547
548
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
)
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
549
|
+
def normalize(entry: Any) -> Dict[str, Any]:
|
|
550
|
+
if hasattr(entry, "to_dict"):
|
|
551
|
+
return entry.to_dict()
|
|
552
|
+
if isinstance(entry, dict):
|
|
553
|
+
return entry
|
|
554
|
+
return {}
|
|
555
|
+
|
|
556
|
+
def render(entries: List[Any], limit: Optional[int] = None) -> List[str]:
|
|
557
|
+
if not entries:
|
|
558
|
+
return ["None"]
|
|
559
|
+
|
|
560
|
+
selected = entries if limit is None else entries[-limit:]
|
|
561
|
+
lines: List[str] = []
|
|
562
|
+
for entry in selected:
|
|
563
|
+
data = normalize(entry)
|
|
564
|
+
template = data.get("template", "unknown")
|
|
565
|
+
description = data.get("description", "")
|
|
566
|
+
success = data.get("success", True)
|
|
567
|
+
status = "PASS" if success else "FAIL"
|
|
568
|
+
error = data.get("error")
|
|
569
|
+
output = data.get("output", {})
|
|
570
|
+
|
|
571
|
+
lines.append(f"- [{status}] {template}: {description}")
|
|
572
|
+
if error:
|
|
573
|
+
lines.append(f" Error: {error}")
|
|
574
|
+
|
|
575
|
+
snippet = ""
|
|
576
|
+
if isinstance(output, dict):
|
|
577
|
+
for key in ("stdout", "stderr", "message", "log", "details"):
|
|
578
|
+
if output.get(key):
|
|
579
|
+
snippet = str(output[key])
|
|
580
|
+
break
|
|
581
|
+
if not snippet and output:
|
|
582
|
+
snippet = json.dumps(output)[:400]
|
|
583
|
+
elif output:
|
|
584
|
+
snippet = str(output)[:400]
|
|
585
|
+
|
|
586
|
+
snippet = snippet.strip()
|
|
587
|
+
if snippet:
|
|
588
|
+
lines.append(f" Output: {snippet[:400]}")
|
|
589
|
+
return lines
|
|
590
|
+
|
|
591
|
+
sections: List[str] = []
|
|
592
|
+
sections.append("### Latest Plan Results")
|
|
593
|
+
sections.extend(render(list(latest_logs)))
|
|
594
|
+
sections.append("")
|
|
595
|
+
sections.append("### Previous Plan History")
|
|
596
|
+
sections.extend(render(list(historical_logs), limit=5))
|
|
597
|
+
|
|
598
|
+
return "\n".join(sections).strip()
|
|
579
599
|
|
|
580
600
|
def _parse_checkpoint_response(self, response: Any) -> Dict[str, Any]:
|
|
581
601
|
"""Parse JSON output from the checkpoint reviewer."""
|
|
@@ -72,7 +72,7 @@ ERROR_PATTERNS: List[ErrorPattern] = [
|
|
|
72
72
|
pattern=r"ModuleNotFoundError:\s+No module named '([^']+)'",
|
|
73
73
|
category=ErrorCategory.DEPENDENCY,
|
|
74
74
|
action=RecoveryAction.FIX_AND_RETRY,
|
|
75
|
-
fix_command="pip install {module}",
|
|
75
|
+
fix_command="uv pip install {module}",
|
|
76
76
|
max_retries=2,
|
|
77
77
|
),
|
|
78
78
|
# TypeScript compilation - escalate to LLM
|
|
@@ -257,9 +257,14 @@ TEMPLATE_CATALOG: Dict[str, TemplateDefinition] = {
|
|
|
257
257
|
),
|
|
258
258
|
"variant": ParameterSpec(
|
|
259
259
|
type=ParameterType.STRING,
|
|
260
|
-
description="Component variant: list|form|new|detail|actions",
|
|
260
|
+
description="Component variant: list|form|new|detail|actions|artifact-timer",
|
|
261
261
|
example="list",
|
|
262
262
|
),
|
|
263
|
+
"component_name": ParameterSpec(
|
|
264
|
+
type=ParameterType.STRING,
|
|
265
|
+
description="Optional explicit component name (e.g., CountdownTimer)",
|
|
266
|
+
required=False,
|
|
267
|
+
),
|
|
263
268
|
"with_checkboxes": ParameterSpec(
|
|
264
269
|
type=ParameterType.BOOLEAN,
|
|
265
270
|
description="Add checkbox UI for boolean fields (e.g., todo completion)",
|
|
@@ -275,6 +280,7 @@ TEMPLATE_CATALOG: Dict[str, TemplateDefinition] = {
|
|
|
275
280
|
"Use 'form' for reusable create/edit form component",
|
|
276
281
|
"Use 'new' for /resource/new page",
|
|
277
282
|
"Use 'detail' for /resource/[id] EDIT page with pre-populated form",
|
|
283
|
+
"Use 'artifact-timer' when the user requests a countdown; supply component_name (e.g., CountdownTimer) so pages can import the client-side timer widget",
|
|
278
284
|
"Add with_checkboxes=true for todo apps",
|
|
279
285
|
],
|
|
280
286
|
),
|
|
@@ -394,6 +394,8 @@ def _map_type_to_zod(field_type: str) -> str:
|
|
|
394
394
|
|
|
395
395
|
SERVER_COMPONENT_LIST = """import {{ prisma }} from "@/lib/prisma";
|
|
396
396
|
import Link from "next/link";
|
|
397
|
+
// EXTRA COMPONENT NOTE: Import any previously generated components/helpers as needed.
|
|
398
|
+
// import {{ AdditionalComponent }} from "@/components/AdditionalComponent";
|
|
397
399
|
|
|
398
400
|
async function get{Resource}s() {{
|
|
399
401
|
const {resource_plural} = await prisma.{resource}.findMany({{
|
|
@@ -409,16 +411,25 @@ export default async function {Resource}sPage() {{
|
|
|
409
411
|
return (
|
|
410
412
|
<div className="min-h-screen">
|
|
411
413
|
<div className="container mx-auto px-4 py-12 max-w-4xl">
|
|
412
|
-
{{/* Header */}}
|
|
413
|
-
<div className="mb-10">
|
|
414
|
-
<
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
414
|
+
{{/* Header + Custom Components */}}
|
|
415
|
+
<div className="mb-10 flex flex-col gap-6 md:flex-row md:items-center md:justify-between">
|
|
416
|
+
<div>
|
|
417
|
+
<h1 className="text-4xl font-bold bg-gradient-to-r from-indigo-400 via-purple-400 to-pink-400 bg-clip-text text-transparent mb-2">
|
|
418
|
+
{Resource}s
|
|
419
|
+
</h1>
|
|
420
|
+
<p className="text-slate-400">
|
|
421
|
+
{{{resource_plural}.length === 0
|
|
422
|
+
? "No items yet. Create your first one!"
|
|
423
|
+
: `${{({resource_plural} as any[]).filter(t => !(t as any).completed).length}} pending items`}}
|
|
424
|
+
</p>
|
|
425
|
+
</div>
|
|
426
|
+
|
|
427
|
+
{{/* EXTRA COMPONENT NOTE:
|
|
428
|
+
Check the plan for other generated components (timer, stats badge, etc.)
|
|
429
|
+
and render them here via their imports. Example:
|
|
430
|
+
<AdditionalComponent targetTimestamp={{...}} />
|
|
431
|
+
Remove this placeholder when no extra component is needed. */}}
|
|
432
|
+
{{/* <AdditionalComponent className="w-full md:w-60" /> */}}
|
|
422
433
|
</div>
|
|
423
434
|
|
|
424
435
|
{{/* Add Button */}}
|
|
@@ -458,13 +469,21 @@ export default async function {Resource}sPage() {{
|
|
|
458
469
|
) : (
|
|
459
470
|
<div className="space-y-3">
|
|
460
471
|
{{{resource_plural}.map((item) => (
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
472
|
+
<Link
|
|
473
|
+
key={{item.id}}
|
|
474
|
+
href={{`/{resource}s/${{item.id}}`}}
|
|
475
|
+
className="block p-5 rounded-xl bg-slate-800/30 border border-slate-700/30 hover:bg-slate-800/50 hover:border-indigo-500/30 transition-all duration-300"
|
|
476
|
+
>
|
|
477
|
+
<div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
|
478
|
+
<div className="flex-1">{field_display}</div>
|
|
479
|
+
{{/* EXTRA COMPONENT NOTE:
|
|
480
|
+
Check the plan for per-item components that were generated (countdown,
|
|
481
|
+
status badge, etc.) and include them here. Example:
|
|
482
|
+
<AdditionalComponent targetTimestamp={{item.missionTime}} />
|
|
483
|
+
Remove this placeholder if no extra component is needed. */}}
|
|
484
|
+
{{/* <AdditionalComponent {...item} className="w-full md:w-56" /> */}}
|
|
485
|
+
</div>
|
|
486
|
+
</Link>
|
|
468
487
|
))}}
|
|
469
488
|
</div>
|
|
470
489
|
)}}
|
|
@@ -604,6 +623,98 @@ export function {Resource}Form({{ initialData, mode = "create" }}: {Resource}For
|
|
|
604
623
|
);
|
|
605
624
|
}}"""
|
|
606
625
|
|
|
626
|
+
CLIENT_COMPONENT_TIMER = """"use client";
|
|
627
|
+
|
|
628
|
+
import {{ useEffect, useMemo, useState }} from "react";
|
|
629
|
+
|
|
630
|
+
interface {{ComponentName}}Props {{
|
|
631
|
+
targetTimestamp?: string; // ISO 8601 string that marks when the countdown ends
|
|
632
|
+
durationSeconds?: number; // Fallback duration (seconds) when no timestamp is provided
|
|
633
|
+
className?: string;
|
|
634
|
+
}}
|
|
635
|
+
|
|
636
|
+
const MS_IN_SECOND = 1000;
|
|
637
|
+
const MS_IN_MINUTE = 60 * MS_IN_SECOND;
|
|
638
|
+
const MS_IN_HOUR = 60 * MS_IN_MINUTE;
|
|
639
|
+
const MS_IN_DAY = 24 * MS_IN_HOUR;
|
|
640
|
+
|
|
641
|
+
export function {{ComponentName}}({{
|
|
642
|
+
targetTimestamp,
|
|
643
|
+
durationSeconds = 0,
|
|
644
|
+
className = "",
|
|
645
|
+
}}: {{ComponentName}}Props) {{
|
|
646
|
+
const deadlineMs = useMemo(() => {{
|
|
647
|
+
if (targetTimestamp) {{
|
|
648
|
+
const parsed = Date.parse(targetTimestamp);
|
|
649
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
650
|
+
}}
|
|
651
|
+
if (durationSeconds > 0) {{
|
|
652
|
+
return Date.now() + durationSeconds * MS_IN_SECOND;
|
|
653
|
+
}}
|
|
654
|
+
return null;
|
|
655
|
+
}}, [targetTimestamp, durationSeconds]);
|
|
656
|
+
|
|
657
|
+
const [timeLeftMs, setTimeLeftMs] = useState(() => {{
|
|
658
|
+
if (!deadlineMs) return 0;
|
|
659
|
+
return Math.max(deadlineMs - Date.now(), 0);
|
|
660
|
+
}});
|
|
661
|
+
|
|
662
|
+
useEffect(() => {{
|
|
663
|
+
if (!deadlineMs) {{
|
|
664
|
+
setTimeLeftMs(0);
|
|
665
|
+
return;
|
|
666
|
+
}}
|
|
667
|
+
|
|
668
|
+
const update = () => {{
|
|
669
|
+
setTimeLeftMs(Math.max(deadlineMs - Date.now(), 0));
|
|
670
|
+
}};
|
|
671
|
+
|
|
672
|
+
update();
|
|
673
|
+
|
|
674
|
+
const intervalId = window.setInterval(() => {{
|
|
675
|
+
update();
|
|
676
|
+
if (deadlineMs <= Date.now()) {{
|
|
677
|
+
window.clearInterval(intervalId);
|
|
678
|
+
}}
|
|
679
|
+
}}, 1000);
|
|
680
|
+
|
|
681
|
+
return () => window.clearInterval(intervalId);
|
|
682
|
+
}}, [deadlineMs]);
|
|
683
|
+
|
|
684
|
+
const isExpired = timeLeftMs <= 0;
|
|
685
|
+
|
|
686
|
+
// TIMER_NOTE: derive whichever granularity the feature demands (days, hours,
|
|
687
|
+
// minutes, seconds, milliseconds, etc.). Remove unused helpers so the final
|
|
688
|
+
// output matches the spec exactly.
|
|
689
|
+
const days = Math.floor(timeLeftMs / MS_IN_DAY);
|
|
690
|
+
const hours = Math.floor((timeLeftMs % MS_IN_DAY) / MS_IN_HOUR);
|
|
691
|
+
const minutes = Math.floor((timeLeftMs % MS_IN_HOUR) / MS_IN_MINUTE);
|
|
692
|
+
const seconds = Math.floor((timeLeftMs % MS_IN_MINUTE) / MS_IN_SECOND);
|
|
693
|
+
|
|
694
|
+
return (
|
|
695
|
+
<section
|
|
696
|
+
className={{`glass-card p-6 space-y-4 ${{className}}`.trim()}}
|
|
697
|
+
data-countdown-target={{targetTimestamp || ""}}
|
|
698
|
+
>
|
|
699
|
+
{{/* TIMER_NOTE: swap this placeholder layout for the requested display.
|
|
700
|
+
Emit only the units the user cares about (e.g., just minutes/seconds,
|
|
701
|
+
or a full days→hours→minutes breakdown). */}}
|
|
702
|
+
<div className="font-mono text-4xl text-slate-100">
|
|
703
|
+
{{seconds}}s
|
|
704
|
+
</div>
|
|
705
|
+
|
|
706
|
+
{{isExpired && (
|
|
707
|
+
<p className="text-sm text-slate-400">
|
|
708
|
+
{{/* TIMER_NOTE: replace this placeholder with the exact completion
|
|
709
|
+
copy or follow-up action the prompt describes. */}}
|
|
710
|
+
Countdown complete.
|
|
711
|
+
</p>
|
|
712
|
+
)}}
|
|
713
|
+
</section>
|
|
714
|
+
);
|
|
715
|
+
}}"""
|
|
716
|
+
|
|
717
|
+
|
|
607
718
|
CLIENT_COMPONENT_NEW_PAGE = """"use client";
|
|
608
719
|
|
|
609
720
|
import {{ {Resource}Form }} from "@/components/{Resource}Form";
|
|
@@ -148,7 +148,7 @@ class CodeFormattingMixin:
|
|
|
148
148
|
except ImportError:
|
|
149
149
|
return {
|
|
150
150
|
"status": "error",
|
|
151
|
-
"error": "black is not installed. Install with: pip install black",
|
|
151
|
+
"error": "black is not installed. Install with: uv pip install black",
|
|
152
152
|
}
|
|
153
153
|
except Exception as e:
|
|
154
154
|
return {"status": "error", "error": str(e)}
|
|
@@ -568,7 +568,7 @@ if __name__ == "__main__":
|
|
|
568
568
|
except ImportError:
|
|
569
569
|
return {
|
|
570
570
|
"status": "error",
|
|
571
|
-
"error": "pylint is not installed. Install with: pip install pylint",
|
|
571
|
+
"error": "pylint is not installed. Install with: uv pip install pylint",
|
|
572
572
|
}
|
|
573
573
|
except Exception as e:
|
|
574
574
|
return {"status": "error", "error": str(e)}
|
|
@@ -29,6 +29,7 @@ from gaia.agents.code.prompts.code_patterns import (
|
|
|
29
29
|
APP_GLOBALS_CSS,
|
|
30
30
|
APP_LAYOUT,
|
|
31
31
|
CLIENT_COMPONENT_FORM,
|
|
32
|
+
CLIENT_COMPONENT_TIMER,
|
|
32
33
|
COMPONENT_TEST_ACTIONS,
|
|
33
34
|
COMPONENT_TEST_FORM,
|
|
34
35
|
LANDING_PAGE_WITH_LINKS,
|
|
@@ -504,7 +505,7 @@ class WebToolsMixin:
|
|
|
504
505
|
# These variants always generate client components with "use client"
|
|
505
506
|
# This prevents the stub fallback when variant="form" but component_type
|
|
506
507
|
# defaults to "server"
|
|
507
|
-
if variant in ["form", "new", "detail", "actions"]:
|
|
508
|
+
if variant in ["form", "new", "detail", "actions", "artifact-timer"]:
|
|
508
509
|
component_type = "client"
|
|
509
510
|
|
|
510
511
|
# Phase 1 Fix (Issue #885): Read from Prisma schema instead of
|
|
@@ -630,6 +631,20 @@ class WebToolsMixin:
|
|
|
630
631
|
}
|
|
631
632
|
content = generate_detail_page(clean_resource_name, fields)
|
|
632
633
|
|
|
634
|
+
elif variant == "artifact-timer":
|
|
635
|
+
timer_component = component_name or (
|
|
636
|
+
f"{clean_resource_name.capitalize()}Timer"
|
|
637
|
+
if clean_resource_name
|
|
638
|
+
else "CountdownTimer"
|
|
639
|
+
)
|
|
640
|
+
timer_component = re.sub(r"[^0-9A-Za-z_]", "", timer_component)
|
|
641
|
+
if not timer_component:
|
|
642
|
+
timer_component = "CountdownTimer"
|
|
643
|
+
component_name = timer_component
|
|
644
|
+
content = CLIENT_COMPONENT_TIMER.format(
|
|
645
|
+
ComponentName=timer_component,
|
|
646
|
+
)
|
|
647
|
+
|
|
633
648
|
elif variant == "actions" and clean_resource_name:
|
|
634
649
|
# Generate actions component with delete functionality
|
|
635
650
|
content = generate_actions_component(clean_resource_name)
|
|
@@ -36,7 +36,7 @@ class PDFFormatter:
|
|
|
36
36
|
def __init__(self):
|
|
37
37
|
if not HAS_REPORTLAB:
|
|
38
38
|
raise ImportError(
|
|
39
|
-
"PDF output requires reportlab. Install with: pip install reportlab"
|
|
39
|
+
"PDF output requires reportlab. Install with: uv pip install reportlab"
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
self.styles = getSampleStyleSheet()
|
gaia/audio/audio_client.py
CHANGED
|
@@ -123,7 +123,7 @@ class AudioClient:
|
|
|
123
123
|
|
|
124
124
|
except ImportError:
|
|
125
125
|
self.log.error(
|
|
126
|
-
|
|
126
|
+
'WhisperAsr not found. Please install voice support with: uv pip install ".[talk]"'
|
|
127
127
|
)
|
|
128
128
|
raise
|
|
129
129
|
except Exception as e:
|
|
@@ -306,7 +306,7 @@ class AudioClient:
|
|
|
306
306
|
self.log.debug("TTS initialized successfully")
|
|
307
307
|
except Exception as e:
|
|
308
308
|
raise RuntimeError(
|
|
309
|
-
f
|
|
309
|
+
f'Failed to initialize TTS:\n{e}\nInstall talk dependencies with: uv pip install ".[talk]"\nYou can also use --no-tts option to disable TTS'
|
|
310
310
|
)
|
|
311
311
|
|
|
312
312
|
async def speak_text(self, text: str) -> None:
|
gaia/audio/kokoro_tts.py
CHANGED
|
@@ -43,9 +43,9 @@ class KokoroTTS:
|
|
|
43
43
|
error_msg = (
|
|
44
44
|
f"\n❌ Error: Missing required talk dependencies: {', '.join(missing)}\n\n"
|
|
45
45
|
f"Please install the talk dependencies:\n"
|
|
46
|
-
f
|
|
46
|
+
f' uv pip install -e ".[talk]"\n\n'
|
|
47
47
|
f"Or install packages directly:\n"
|
|
48
|
-
f" pip install {' '.join(missing)}\n"
|
|
48
|
+
f" uv pip install {' '.join(missing)}\n"
|
|
49
49
|
)
|
|
50
50
|
raise ImportError(error_msg)
|
|
51
51
|
|
gaia/audio/whisper_asr.py
CHANGED
|
@@ -56,9 +56,9 @@ class WhisperAsr(AudioRecorder):
|
|
|
56
56
|
error_msg = (
|
|
57
57
|
f"\n❌ Error: Missing required talk dependencies: {', '.join(missing)}\n\n"
|
|
58
58
|
f"Please install the talk dependencies:\n"
|
|
59
|
-
f
|
|
59
|
+
f' uv pip install -e ".[talk]"\n\n'
|
|
60
60
|
f"Or install packages directly:\n"
|
|
61
|
-
f" pip install {' '.join(missing)}\n"
|
|
61
|
+
f" uv pip install {' '.join(missing)}\n"
|
|
62
62
|
)
|
|
63
63
|
raise ImportError(error_msg)
|
|
64
64
|
|
gaia/chat/sdk.py
CHANGED
|
@@ -687,7 +687,7 @@ class ChatSDK:
|
|
|
687
687
|
from gaia.rag.sdk import RAGSDK, RAGConfig
|
|
688
688
|
except ImportError:
|
|
689
689
|
raise ImportError(
|
|
690
|
-
'RAG dependencies not installed. Install with: pip install ".[rag]"'
|
|
690
|
+
'RAG dependencies not installed. Install with: uv pip install -e ".[rag]"'
|
|
691
691
|
)
|
|
692
692
|
|
|
693
693
|
# Create RAG config matching chat config
|
gaia/cli.py
CHANGED
|
@@ -2109,7 +2109,7 @@ Examples:
|
|
|
2109
2109
|
print("The evaluation dependencies are not installed.")
|
|
2110
2110
|
print("")
|
|
2111
2111
|
print("To fix this, install the evaluation dependencies:")
|
|
2112
|
-
print(
|
|
2112
|
+
print(' uv pip install -e ".[eval]"')
|
|
2113
2113
|
print("")
|
|
2114
2114
|
print("This will install required packages including:")
|
|
2115
2115
|
print(" - anthropic (for Claude AI)")
|
|
@@ -2464,7 +2464,7 @@ Examples:
|
|
|
2464
2464
|
|
|
2465
2465
|
if not HAS_REPORTLAB:
|
|
2466
2466
|
print(
|
|
2467
|
-
"❌ Error: PDF output requires reportlab. Install with: pip install reportlab"
|
|
2467
|
+
"❌ Error: PDF output requires reportlab. Install with: uv pip install reportlab"
|
|
2468
2468
|
)
|
|
2469
2469
|
if args.format == "both":
|
|
2470
2470
|
print(
|
|
@@ -2542,7 +2542,7 @@ Examples:
|
|
|
2542
2542
|
pdf_formatter = PDFFormatter()
|
|
2543
2543
|
else:
|
|
2544
2544
|
print(
|
|
2545
|
-
"⚠️ Warning: PDF output requires reportlab. Install with: pip install reportlab"
|
|
2545
|
+
"⚠️ Warning: PDF output requires reportlab. Install with: uv pip install reportlab"
|
|
2546
2546
|
)
|
|
2547
2547
|
if args.format == "pdf":
|
|
2548
2548
|
print("❌ Cannot generate PDF files without reportlab.")
|
|
@@ -2660,7 +2660,7 @@ Let me know your answer!
|
|
|
2660
2660
|
log.debug("ASR initialized successfully")
|
|
2661
2661
|
except ImportError:
|
|
2662
2662
|
log.error(
|
|
2663
|
-
|
|
2663
|
+
'WhisperAsr not found. Please install voice support with: uv pip install -e ".[talk]"'
|
|
2664
2664
|
)
|
|
2665
2665
|
raise
|
|
2666
2666
|
except Exception as e:
|
|
@@ -2746,7 +2746,7 @@ Let me know your answer!
|
|
|
2746
2746
|
"❌ Error: YouTube transcript functionality requires additional dependencies."
|
|
2747
2747
|
)
|
|
2748
2748
|
print(
|
|
2749
|
-
"Please install: pip install llama-index-readers-youtube-transcript"
|
|
2749
|
+
"Please install: uv pip install llama-index-readers-youtube-transcript"
|
|
2750
2750
|
)
|
|
2751
2751
|
print(f"Import error: {e}")
|
|
2752
2752
|
sys.exit(1)
|
|
@@ -3150,7 +3150,7 @@ Let me know your answer!
|
|
|
3150
3150
|
print("The evaluation dependencies are not installed.")
|
|
3151
3151
|
print("")
|
|
3152
3152
|
print("To fix this, install the evaluation dependencies:")
|
|
3153
|
-
print(
|
|
3153
|
+
print(' uv pip install -e ".[eval]"')
|
|
3154
3154
|
print("")
|
|
3155
3155
|
print("This will install required packages including:")
|
|
3156
3156
|
print(" - anthropic (for Claude AI)")
|
|
@@ -3323,7 +3323,7 @@ Let me know your answer!
|
|
|
3323
3323
|
print("The evaluation dependencies are not installed.")
|
|
3324
3324
|
print("")
|
|
3325
3325
|
print("To fix this, install the evaluation dependencies:")
|
|
3326
|
-
print(
|
|
3326
|
+
print(' uv pip install -e ".[eval]"')
|
|
3327
3327
|
print("")
|
|
3328
3328
|
print("This will install required packages including:")
|
|
3329
3329
|
print(" - anthropic (for Claude AI)")
|
|
@@ -3363,7 +3363,7 @@ Let me know your answer!
|
|
|
3363
3363
|
print("The evaluation dependencies are not installed.")
|
|
3364
3364
|
print("")
|
|
3365
3365
|
print("To fix this, install the evaluation dependencies:")
|
|
3366
|
-
print(
|
|
3366
|
+
print(' uv pip install -e ".[eval]"')
|
|
3367
3367
|
print("")
|
|
3368
3368
|
print("This will install required packages including:")
|
|
3369
3369
|
print(" - anthropic (for Claude AI)")
|
|
@@ -3727,7 +3727,7 @@ Let me know your answer!
|
|
|
3727
3727
|
print("The evaluation dependencies are not installed.")
|
|
3728
3728
|
print("")
|
|
3729
3729
|
print("To fix this, install the evaluation dependencies:")
|
|
3730
|
-
print(
|
|
3730
|
+
print(' uv pip install -e ".[eval]"')
|
|
3731
3731
|
print("")
|
|
3732
3732
|
print("This will install required packages including:")
|
|
3733
3733
|
print(" - anthropic (for Claude AI)")
|
|
@@ -3802,7 +3802,7 @@ Let me know your answer!
|
|
|
3802
3802
|
print("The evaluation dependencies are not installed.")
|
|
3803
3803
|
print("")
|
|
3804
3804
|
print("To fix this, install the evaluation dependencies:")
|
|
3805
|
-
print(
|
|
3805
|
+
print(' uv pip install -e ".[eval]"')
|
|
3806
3806
|
print("")
|
|
3807
3807
|
print("This will install required packages including:")
|
|
3808
3808
|
print(" - anthropic (for Claude AI)")
|
|
@@ -3878,7 +3878,7 @@ Let me know your answer!
|
|
|
3878
3878
|
print("The evaluation dependencies are not installed.")
|
|
3879
3879
|
print("")
|
|
3880
3880
|
print("To fix this, install the evaluation dependencies:")
|
|
3881
|
-
print(
|
|
3881
|
+
print(' uv pip install -e ".[eval]"')
|
|
3882
3882
|
print("")
|
|
3883
3883
|
print("This will install required packages including:")
|
|
3884
3884
|
print(" - anthropic (for Claude AI)")
|
|
@@ -4495,7 +4495,7 @@ def handle_jira_command(args):
|
|
|
4495
4495
|
except ImportError as e:
|
|
4496
4496
|
log.error(f"Failed to import Jira app: {e}")
|
|
4497
4497
|
print("❌ Error: Jira app components are not available")
|
|
4498
|
-
print("Make sure GAIA is installed properly: pip install -e .")
|
|
4498
|
+
print("Make sure GAIA is installed properly: uv pip install -e .")
|
|
4499
4499
|
sys.exit(1)
|
|
4500
4500
|
except Exception as e:
|
|
4501
4501
|
log.error(f"Error running Jira app: {e}")
|
|
@@ -4546,7 +4546,7 @@ def handle_docker_command(args):
|
|
|
4546
4546
|
except ImportError as e:
|
|
4547
4547
|
log.error(f"Failed to import Docker app: {e}")
|
|
4548
4548
|
print("❌ Error: Docker app components are not available")
|
|
4549
|
-
print("Make sure GAIA is installed properly: pip install -e .")
|
|
4549
|
+
print("Make sure GAIA is installed properly: uv pip install -e .")
|
|
4550
4550
|
sys.exit(1)
|
|
4551
4551
|
except Exception as e:
|
|
4552
4552
|
log.error(f"Error running Docker app: {e}")
|
|
@@ -4624,7 +4624,7 @@ def handle_api_command(args):
|
|
|
4624
4624
|
except ImportError as e:
|
|
4625
4625
|
log.error(f"Failed to import API server: {e}")
|
|
4626
4626
|
print("❌ Error: API server components are not available")
|
|
4627
|
-
print("Make sure uvicorn is installed: pip install uvicorn")
|
|
4627
|
+
print("Make sure uvicorn is installed: uv pip install uvicorn")
|
|
4628
4628
|
sys.exit(1)
|
|
4629
4629
|
except KeyboardInterrupt:
|
|
4630
4630
|
print("\n✅ API server stopped")
|
|
@@ -4866,7 +4866,7 @@ def handle_blender_command(args):
|
|
|
4866
4866
|
# Check if Blender components are available
|
|
4867
4867
|
if not BLENDER_AVAILABLE:
|
|
4868
4868
|
print("❌ Error: Blender agent components are not available")
|
|
4869
|
-
print(
|
|
4869
|
+
print('Install blender dependencies with: uv pip install -e ".[blender]"')
|
|
4870
4870
|
sys.exit(1)
|
|
4871
4871
|
|
|
4872
4872
|
# Initialize Lemonade with blender agent profile (32768 context)
|
|
@@ -5063,7 +5063,7 @@ def handle_mcp_start(args):
|
|
|
5063
5063
|
print("❌ Error: MCP dependencies not installed.")
|
|
5064
5064
|
print("")
|
|
5065
5065
|
print("To fix this, install the MCP dependencies:")
|
|
5066
|
-
print(
|
|
5066
|
+
print(' uv pip install -e ".[mcp]"')
|
|
5067
5067
|
return
|
|
5068
5068
|
|
|
5069
5069
|
# Import and start the HTTP-native MCP bridge
|
gaia/eval/batch_experiment.py
CHANGED
gaia/eval/claude.py
CHANGED
|
@@ -41,9 +41,9 @@ class ClaudeClient:
|
|
|
41
41
|
error_msg = (
|
|
42
42
|
"\n❌ Error: Missing required package 'anthropic'\n\n"
|
|
43
43
|
"Please install the eval dependencies:\n"
|
|
44
|
-
|
|
44
|
+
' uv pip install -e ".[eval]"\n\n'
|
|
45
45
|
"Or install anthropic directly:\n"
|
|
46
|
-
" pip install anthropic\n"
|
|
46
|
+
" uv pip install anthropic\n"
|
|
47
47
|
)
|
|
48
48
|
raise ImportError(error_msg)
|
|
49
49
|
|
|
@@ -51,9 +51,9 @@ class ClaudeClient:
|
|
|
51
51
|
error_msg = (
|
|
52
52
|
"\n❌ Error: Missing required package 'bs4' (BeautifulSoup4)\n\n"
|
|
53
53
|
"Please install the eval dependencies:\n"
|
|
54
|
-
|
|
54
|
+
' uv pip install -e ".[eval]"\n\n'
|
|
55
55
|
"Or install beautifulsoup4 directly:\n"
|
|
56
|
-
" pip install beautifulsoup4\n"
|
|
56
|
+
" uv pip install beautifulsoup4\n"
|
|
57
57
|
)
|
|
58
58
|
raise ImportError(error_msg)
|
|
59
59
|
|
gaia/llm/llm_client.py
CHANGED
|
@@ -142,7 +142,7 @@ class LLMClient:
|
|
|
142
142
|
logger.debug(f"Using Claude API with model={self.default_model}")
|
|
143
143
|
elif use_claude and not CLAUDE_AVAILABLE:
|
|
144
144
|
raise ValueError(
|
|
145
|
-
"Claude support requested but anthropic library not available. Install with: pip install anthropic"
|
|
145
|
+
"Claude support requested but anthropic library not available. Install with: uv pip install anthropic"
|
|
146
146
|
)
|
|
147
147
|
elif use_openai:
|
|
148
148
|
# Use OpenAI API
|