praisonAI 2.3.78__tar.gz → 2.3.80__tar.gz
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.
- {praisonai-2.3.78 → praisonai-2.3.80}/PKG-INFO +1 -1
- {praisonai-2.3.78 → praisonai-2.3.80}/PraisonAI.egg-info/PKG-INFO +1 -1
- {praisonai-2.3.78 → praisonai-2.3.80}/PraisonAI.egg-info/SOURCES.txt +1 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/compare.py +27 -2
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/eval.py +54 -3
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/fast_context.py +46 -10
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/handoff.py +35 -16
- praisonai-2.3.80/praisonai/cli/features/image.py +376 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/metrics.py +44 -0
- praisonai-2.3.80/praisonai/cli/features/profile.py +226 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/main.py +54 -6
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/deploy.py +1 -1
- praisonai-2.3.80/praisonai/version.py +1 -0
- praisonai-2.3.78/praisonai/cli/features/image.py +0 -207
- praisonai-2.3.78/praisonai/version.py +0 -1
- {praisonai-2.3.78 → praisonai-2.3.80}/PraisonAI.egg-info/dependency_links.txt +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/PraisonAI.egg-info/entry_points.txt +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/PraisonAI.egg-info/requires.txt +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/PraisonAI.egg-info/top_level.txt +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/README.md +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/__main__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/agent_scheduler.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/agents_generator.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/api/call.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/auto.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/chainlit_ui.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/agent_scheduler.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/at_mentions.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/auto_memory.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/autonomy_mode.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/base.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/cost_tracker.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/external_agents.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/flow_display.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/git_integration.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/guardrail.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/interactive_tui.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/knowledge.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/mcp.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/message_queue.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/n8n.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/profiling.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/repo_map.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/router.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/sandbox_executor.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/session.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/skills.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/slash_commands.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/telemetry.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/todo.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/tools.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/features/workflow.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/cli/schedule_cli.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/agent_tools.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/diff/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/diff/diff_strategy.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/tools/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/tools/apply_diff.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/tools/execute_command.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/tools/list_files.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/tools/read_file.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/tools/search_replace.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/tools/write_file.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/utils/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/utils/file_utils.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/utils/ignore_utils.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/code/utils/text_utils.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/inbuilt_tools/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/inbuilt_tools/autogen_tools.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/inc/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/inc/config.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/inc/models.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/integrations/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/integrations/base.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/integrations/claude_code.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/integrations/codex_cli.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/integrations/cursor_cli.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/integrations/gemini_cli.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/profiler.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/scheduler/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/scheduler/agent_scheduler.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/scheduler/base.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/scheduler/daemon_manager.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/scheduler/state_manager.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/scheduler/yaml_loader.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/scheduler.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/setup/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/setup/build.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/setup/post_install.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/setup/setup_conda_env.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/setup.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/test.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/train.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/train_vision.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/agents.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/callbacks.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/chat.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/code.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/colab.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/colab_chainlit.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/components/aicoder.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/context.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/database_config.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/db.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/realtime.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/realtimeclient/__init__.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/realtimeclient/tools.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/ui/sql_alchemy.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/praisonai/upload_vision.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/pyproject.toml +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/setup.cfg +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test_agents_playbook.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test_approval_system.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test_basic.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test_cli_features.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test_custom_tools_fix.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test_double_api_fix.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test_n8n_integration.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test_phase2_refactor.py +0 -0
- {praisonai-2.3.78 → praisonai-2.3.80}/tests/test_runner.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PraisonAI
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.80
|
|
4
4
|
Summary: PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration.
|
|
5
5
|
Author: Mervin Praison
|
|
6
6
|
License: MIT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PraisonAI
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.80
|
|
4
4
|
Summary: PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human-agent collaboration.
|
|
5
5
|
Author: Mervin Praison
|
|
6
6
|
License: MIT
|
|
@@ -47,6 +47,7 @@ praisonai/cli/features/mcp.py
|
|
|
47
47
|
praisonai/cli/features/message_queue.py
|
|
48
48
|
praisonai/cli/features/metrics.py
|
|
49
49
|
praisonai/cli/features/n8n.py
|
|
50
|
+
praisonai/cli/features/profile.py
|
|
50
51
|
praisonai/cli/features/profiling.py
|
|
51
52
|
praisonai/cli/features/repo_map.py
|
|
52
53
|
praisonai/cli/features/router.py
|
|
@@ -177,12 +177,13 @@ def save_compare_result(result: CompareResult, path: str) -> bool:
|
|
|
177
177
|
return False
|
|
178
178
|
|
|
179
179
|
|
|
180
|
-
def format_comparison_table(result: CompareResult) -> str:
|
|
180
|
+
def format_comparison_table(result: CompareResult, show_responses: bool = True) -> str:
|
|
181
181
|
"""
|
|
182
|
-
Format comparison result as a table string.
|
|
182
|
+
Format comparison result as a table string with optional response display.
|
|
183
183
|
|
|
184
184
|
Args:
|
|
185
185
|
result: CompareResult to format
|
|
186
|
+
show_responses: Whether to show actual responses from each mode
|
|
186
187
|
|
|
187
188
|
Returns:
|
|
188
189
|
Formatted table string
|
|
@@ -190,10 +191,12 @@ def format_comparison_table(result: CompareResult) -> str:
|
|
|
190
191
|
try:
|
|
191
192
|
from rich.console import Console
|
|
192
193
|
from rich.table import Table
|
|
194
|
+
from rich.panel import Panel
|
|
193
195
|
from io import StringIO
|
|
194
196
|
|
|
195
197
|
console = Console(file=StringIO(), force_terminal=True)
|
|
196
198
|
|
|
199
|
+
# Main comparison table
|
|
197
200
|
table = Table(title=f"Comparison: {result.query[:50]}...")
|
|
198
201
|
table.add_column("Mode", style="cyan")
|
|
199
202
|
table.add_column("Time (ms)", style="green")
|
|
@@ -224,6 +227,26 @@ def format_comparison_table(result: CompareResult) -> str:
|
|
|
224
227
|
)
|
|
225
228
|
|
|
226
229
|
console.print(table)
|
|
230
|
+
|
|
231
|
+
# Show responses if enabled
|
|
232
|
+
if show_responses:
|
|
233
|
+
console.print("\n[bold cyan]📝 Responses:[/bold cyan]")
|
|
234
|
+
for c in result.comparisons:
|
|
235
|
+
if c.error is None:
|
|
236
|
+
# Truncate long responses
|
|
237
|
+
response_preview = c.output[:500] + "..." if len(c.output) > 500 else c.output
|
|
238
|
+
console.print(Panel(
|
|
239
|
+
response_preview,
|
|
240
|
+
title=f"[bold]{c.mode}[/bold] ({c.execution_time_ms:.0f}ms)",
|
|
241
|
+
border_style="cyan"
|
|
242
|
+
))
|
|
243
|
+
else:
|
|
244
|
+
console.print(Panel(
|
|
245
|
+
f"[red]Error: {c.error}[/red]",
|
|
246
|
+
title=f"[bold]{c.mode}[/bold]",
|
|
247
|
+
border_style="red"
|
|
248
|
+
))
|
|
249
|
+
|
|
227
250
|
return console.file.getvalue()
|
|
228
251
|
except ImportError:
|
|
229
252
|
lines = [f"Comparison: {result.query}"]
|
|
@@ -231,6 +254,8 @@ def format_comparison_table(result: CompareResult) -> str:
|
|
|
231
254
|
for c in result.comparisons:
|
|
232
255
|
status = "OK" if c.error is None else f"ERROR: {c.error}"
|
|
233
256
|
lines.append(f"{c.mode}: {c.execution_time_ms:.1f}ms - {status}")
|
|
257
|
+
if show_responses and c.error is None:
|
|
258
|
+
lines.append(f" Response: {c.output[:200]}...")
|
|
234
259
|
return "\n".join(lines)
|
|
235
260
|
|
|
236
261
|
|
|
@@ -347,13 +347,36 @@ class EvalHandler:
|
|
|
347
347
|
return batch_result
|
|
348
348
|
|
|
349
349
|
|
|
350
|
-
def handle_eval_command(args) ->
|
|
350
|
+
def handle_eval_command(args) -> int:
|
|
351
351
|
"""
|
|
352
352
|
Handle the eval CLI command.
|
|
353
353
|
|
|
354
354
|
Args:
|
|
355
|
-
args:
|
|
355
|
+
args: Command line arguments (list or parsed namespace)
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
Exit code
|
|
356
359
|
"""
|
|
360
|
+
import argparse
|
|
361
|
+
|
|
362
|
+
# If args is a list, parse it first
|
|
363
|
+
if isinstance(args, list):
|
|
364
|
+
parser = argparse.ArgumentParser(prog="praisonai eval")
|
|
365
|
+
subparsers = parser.add_subparsers(dest='eval_type')
|
|
366
|
+
add_eval_parser_subcommands(subparsers)
|
|
367
|
+
|
|
368
|
+
try:
|
|
369
|
+
args = parser.parse_args(args)
|
|
370
|
+
except SystemExit:
|
|
371
|
+
return 1
|
|
372
|
+
|
|
373
|
+
if not args.eval_type:
|
|
374
|
+
parser.print_help()
|
|
375
|
+
print("\n[bold]Examples:[/bold]")
|
|
376
|
+
print(" praisonai eval accuracy --prompt \"What is 2+2?\" --expected \"4\"")
|
|
377
|
+
print(" praisonai eval performance --agent agents.yaml --input \"Hello\"")
|
|
378
|
+
return 0
|
|
379
|
+
|
|
357
380
|
handler = EvalHandler(verbose=getattr(args, 'verbose', False))
|
|
358
381
|
|
|
359
382
|
eval_type = getattr(args, 'eval_type', 'accuracy')
|
|
@@ -420,12 +443,40 @@ def handle_eval_command(args) -> None:
|
|
|
420
443
|
)
|
|
421
444
|
else:
|
|
422
445
|
print(f"Unknown evaluation type: {eval_type}")
|
|
423
|
-
return
|
|
446
|
+
return 1
|
|
424
447
|
|
|
425
448
|
if 'error' in result:
|
|
426
449
|
print(f"Error: {result['error']}")
|
|
450
|
+
return 1
|
|
427
451
|
elif not getattr(args, 'quiet', False):
|
|
428
452
|
print(json.dumps(result, indent=2))
|
|
453
|
+
|
|
454
|
+
return 0
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
def add_eval_parser_subcommands(subparsers) -> None:
|
|
458
|
+
"""Add eval subcommand parsers to an existing subparsers object."""
|
|
459
|
+
accuracy_parser = subparsers.add_parser('accuracy', help='Run accuracy evaluation')
|
|
460
|
+
accuracy_parser.add_argument('--agent', '-a', help='Agent config file (optional if --prompt used)')
|
|
461
|
+
accuracy_parser.add_argument('--prompt', '-p', type=str, help='Direct prompt (alternative to --agent)')
|
|
462
|
+
accuracy_parser.add_argument('--llm', help='LLM model for agent (when using --prompt)')
|
|
463
|
+
accuracy_parser.add_argument('--input', '-i', help='Input text (defaults to --prompt if not provided)')
|
|
464
|
+
accuracy_parser.add_argument('--expected', '-e', required=True, help='Expected output')
|
|
465
|
+
accuracy_parser.add_argument('--iterations', '-n', type=int, default=1, help='Number of iterations')
|
|
466
|
+
accuracy_parser.add_argument('--model', '-m', help='Judge model')
|
|
467
|
+
accuracy_parser.add_argument('--output', '-o', help='Output file')
|
|
468
|
+
accuracy_parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output')
|
|
469
|
+
accuracy_parser.add_argument('--quiet', '-q', action='store_true', help='Suppress JSON output')
|
|
470
|
+
|
|
471
|
+
perf_parser = subparsers.add_parser('performance', help='Run performance evaluation')
|
|
472
|
+
perf_parser.add_argument('--agent', '-a', default='agents.yaml', help='Agent config file')
|
|
473
|
+
perf_parser.add_argument('--input', '-i', default='Hello', help='Input text')
|
|
474
|
+
perf_parser.add_argument('--iterations', '-n', type=int, default=10, help='Number of iterations')
|
|
475
|
+
perf_parser.add_argument('--warmup', '-w', type=int, default=2, help='Warmup runs')
|
|
476
|
+
perf_parser.add_argument('--memory', action='store_true', default=True, help='Track memory')
|
|
477
|
+
perf_parser.add_argument('--output', '-o', help='Output file')
|
|
478
|
+
perf_parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output')
|
|
479
|
+
perf_parser.add_argument('--quiet', '-q', action='store_true', help='Suppress JSON output')
|
|
429
480
|
|
|
430
481
|
|
|
431
482
|
def add_eval_parser(subparsers) -> None:
|
|
@@ -70,17 +70,46 @@ class FastContextHandler(FlagHandler):
|
|
|
70
70
|
|
|
71
71
|
return True, ""
|
|
72
72
|
|
|
73
|
+
def _count_files_quick(self, path: str, max_count: int = 1000) -> int:
|
|
74
|
+
"""Quickly count files in directory, stopping at max_count."""
|
|
75
|
+
count = 0
|
|
76
|
+
ignore_dirs = {'.git', '__pycache__', 'node_modules', '.venv', 'venv', '.cache', 'dist', 'build'}
|
|
77
|
+
|
|
78
|
+
for root, dirs, files in os.walk(path):
|
|
79
|
+
dirs[:] = [d for d in dirs if d not in ignore_dirs and not d.startswith('.')]
|
|
80
|
+
count += len(files)
|
|
81
|
+
if count >= max_count:
|
|
82
|
+
return count
|
|
83
|
+
return count
|
|
84
|
+
|
|
73
85
|
def _get_folder_tree(self, path: str, max_depth: int = 2) -> str:
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
path = os.path.abspath(path)
|
|
86
|
+
"""
|
|
87
|
+
Get a compact folder tree structure for context.
|
|
77
88
|
|
|
78
|
-
|
|
79
|
-
|
|
89
|
+
Optimized for large directories:
|
|
90
|
+
- Limits depth to max_depth (default 2)
|
|
91
|
+
- Shows max 10 files per directory
|
|
92
|
+
- Truncates total output to 50 lines
|
|
93
|
+
- Skips common non-code directories
|
|
94
|
+
"""
|
|
95
|
+
# Quick check for very large directories
|
|
96
|
+
file_count = self._count_files_quick(path, 500)
|
|
97
|
+
if file_count >= 500:
|
|
98
|
+
# For large directories, reduce depth and show summary
|
|
99
|
+
max_depth = 1
|
|
100
|
+
logger.debug(f"Large directory detected ({file_count}+ files), reducing tree depth")
|
|
101
|
+
|
|
102
|
+
tree_lines = []
|
|
103
|
+
ignore_dirs = {'.git', '__pycache__', 'node_modules', '.venv', 'venv', '.cache', 'dist', 'build', 'coverage', '.pytest_cache', '.mypy_cache', 'eggs', '*.egg-info'}
|
|
104
|
+
ignore_exts = {'.pyc', '.pyo', '.so', '.o', '.a', '.dylib', '.class', '.jar'}
|
|
105
|
+
total_files = 0
|
|
106
|
+
max_total_files = 100 # Stop after seeing this many files
|
|
80
107
|
|
|
81
108
|
def walk_tree(current_path, prefix="", depth=0):
|
|
82
|
-
|
|
109
|
+
nonlocal total_files
|
|
110
|
+
if depth > max_depth or total_files >= max_total_files:
|
|
83
111
|
return
|
|
112
|
+
|
|
84
113
|
try:
|
|
85
114
|
entries = sorted(os.listdir(current_path))
|
|
86
115
|
except PermissionError:
|
|
@@ -98,14 +127,21 @@ class FastContextHandler(FlagHandler):
|
|
|
98
127
|
if ext not in ignore_exts and not entry.startswith('.'):
|
|
99
128
|
files.append(entry)
|
|
100
129
|
|
|
101
|
-
|
|
102
|
-
|
|
130
|
+
# Limit directories shown at each level
|
|
131
|
+
dirs_to_show = dirs[:15]
|
|
132
|
+
for i, d in enumerate(dirs_to_show):
|
|
133
|
+
is_last = (i == len(dirs_to_show) - 1) and not files
|
|
103
134
|
tree_lines.append(f"{prefix}{'└── ' if is_last else '├── '}{d}/")
|
|
104
135
|
walk_tree(os.path.join(current_path, d),
|
|
105
136
|
prefix + (' ' if is_last else '│ '), depth + 1)
|
|
137
|
+
if len(dirs) > 15:
|
|
138
|
+
tree_lines.append(f"{prefix} ... and {len(dirs) - 15} more directories")
|
|
106
139
|
|
|
107
|
-
|
|
108
|
-
|
|
140
|
+
# Limit files shown
|
|
141
|
+
files_to_show = files[:10]
|
|
142
|
+
total_files += len(files)
|
|
143
|
+
for i, f in enumerate(files_to_show):
|
|
144
|
+
is_last = i == len(files_to_show) - 1
|
|
109
145
|
tree_lines.append(f"{prefix}{'└── ' if is_last else '├── '}{f}")
|
|
110
146
|
if len(files) > 10:
|
|
111
147
|
tree_lines.append(f"{prefix} ... and {len(files) - 10} more files")
|
|
@@ -72,11 +72,11 @@ class HandoffHandler(FlagHandler):
|
|
|
72
72
|
self.print_status(msg, "error")
|
|
73
73
|
return []
|
|
74
74
|
|
|
75
|
-
from praisonaiagents import Agent,
|
|
75
|
+
from praisonaiagents import Agent, handoff
|
|
76
76
|
|
|
77
77
|
agents = []
|
|
78
78
|
|
|
79
|
-
# Create agents
|
|
79
|
+
# First pass: Create all agents without handoffs
|
|
80
80
|
for i, name in enumerate(agent_names):
|
|
81
81
|
agent_config = {
|
|
82
82
|
"name": name.title().replace("_", " "),
|
|
@@ -91,26 +91,45 @@ class HandoffHandler(FlagHandler):
|
|
|
91
91
|
agent = Agent(**agent_config)
|
|
92
92
|
agents.append(agent)
|
|
93
93
|
|
|
94
|
-
# Set up handoffs
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
# Second pass: Set up handoffs by recreating agents with handoff config
|
|
95
|
+
final_agents = []
|
|
96
|
+
for i, name in enumerate(agent_names):
|
|
97
|
+
agent_config = {
|
|
98
|
+
"name": name.title().replace("_", " "),
|
|
99
|
+
"role": name.title().replace("_", " "),
|
|
100
|
+
"goal": f"Complete tasks as {name}",
|
|
101
|
+
"backstory": f"Expert {name} with specialized skills"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if llm:
|
|
105
|
+
agent_config["llm"] = llm
|
|
106
|
+
|
|
107
|
+
# Add handoff to next agent if not the last agent
|
|
108
|
+
if i < len(agent_names) - 1:
|
|
109
|
+
next_agent = agents[i + 1]
|
|
110
|
+
next_agent_name = agent_names[i + 1]
|
|
111
|
+
|
|
112
|
+
# Pass handoffs via constructor - this properly registers them as tools
|
|
113
|
+
agent_config["handoffs"] = [
|
|
114
|
+
handoff(
|
|
115
|
+
agent=next_agent,
|
|
116
|
+
tool_name_override=f"handoff_to_{next_agent_name}",
|
|
117
|
+
tool_description_override=f"Hand off the task to {next_agent_name}. Call this after completing your part."
|
|
118
|
+
)
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
# Add instructions to use handoff
|
|
122
|
+
agent_config["instructions"] = f"After completing your task, you MUST use the handoff_to_{next_agent_name} tool to pass your work to the next agent."
|
|
102
123
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
agent.handoffs = []
|
|
106
|
-
agent.handoffs.append(handoff)
|
|
124
|
+
final_agent = Agent(**agent_config)
|
|
125
|
+
final_agents.append(final_agent)
|
|
107
126
|
|
|
108
|
-
self.print_status(f"🤝 Created {len(
|
|
127
|
+
self.print_status(f"🤝 Created {len(final_agents)} agents with handoff chain", "success")
|
|
109
128
|
for i, name in enumerate(agent_names):
|
|
110
129
|
arrow = " → " if i < len(agent_names) - 1 else ""
|
|
111
130
|
self.print_status(f" {name}{arrow}", "info")
|
|
112
131
|
|
|
113
|
-
return
|
|
132
|
+
return final_agents
|
|
114
133
|
|
|
115
134
|
def apply_to_agent_config(self, config: Dict[str, Any], flag_value: Any) -> Dict[str, Any]:
|
|
116
135
|
"""
|