PraisonAI 3.0.0__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.
- praisonai/__init__.py +54 -0
- praisonai/__main__.py +15 -0
- praisonai/acp/__init__.py +54 -0
- praisonai/acp/config.py +159 -0
- praisonai/acp/server.py +587 -0
- praisonai/acp/session.py +219 -0
- praisonai/adapters/__init__.py +50 -0
- praisonai/adapters/readers.py +395 -0
- praisonai/adapters/rerankers.py +315 -0
- praisonai/adapters/retrievers.py +394 -0
- praisonai/adapters/vector_stores.py +409 -0
- praisonai/agent_scheduler.py +337 -0
- praisonai/agents_generator.py +903 -0
- praisonai/api/call.py +292 -0
- praisonai/auto.py +1197 -0
- praisonai/capabilities/__init__.py +275 -0
- praisonai/capabilities/a2a.py +140 -0
- praisonai/capabilities/assistants.py +283 -0
- praisonai/capabilities/audio.py +320 -0
- praisonai/capabilities/batches.py +469 -0
- praisonai/capabilities/completions.py +336 -0
- praisonai/capabilities/container_files.py +155 -0
- praisonai/capabilities/containers.py +93 -0
- praisonai/capabilities/embeddings.py +158 -0
- praisonai/capabilities/files.py +467 -0
- praisonai/capabilities/fine_tuning.py +293 -0
- praisonai/capabilities/guardrails.py +182 -0
- praisonai/capabilities/images.py +330 -0
- praisonai/capabilities/mcp.py +190 -0
- praisonai/capabilities/messages.py +270 -0
- praisonai/capabilities/moderations.py +154 -0
- praisonai/capabilities/ocr.py +217 -0
- praisonai/capabilities/passthrough.py +204 -0
- praisonai/capabilities/rag.py +207 -0
- praisonai/capabilities/realtime.py +160 -0
- praisonai/capabilities/rerank.py +165 -0
- praisonai/capabilities/responses.py +266 -0
- praisonai/capabilities/search.py +109 -0
- praisonai/capabilities/skills.py +133 -0
- praisonai/capabilities/vector_store_files.py +334 -0
- praisonai/capabilities/vector_stores.py +304 -0
- praisonai/capabilities/videos.py +141 -0
- praisonai/chainlit_ui.py +304 -0
- praisonai/chat/__init__.py +106 -0
- praisonai/chat/app.py +125 -0
- praisonai/cli/__init__.py +26 -0
- praisonai/cli/app.py +213 -0
- praisonai/cli/commands/__init__.py +75 -0
- praisonai/cli/commands/acp.py +70 -0
- praisonai/cli/commands/completion.py +333 -0
- praisonai/cli/commands/config.py +166 -0
- praisonai/cli/commands/debug.py +142 -0
- praisonai/cli/commands/diag.py +55 -0
- praisonai/cli/commands/doctor.py +166 -0
- praisonai/cli/commands/environment.py +179 -0
- praisonai/cli/commands/lsp.py +112 -0
- praisonai/cli/commands/mcp.py +210 -0
- praisonai/cli/commands/profile.py +457 -0
- praisonai/cli/commands/run.py +228 -0
- praisonai/cli/commands/schedule.py +150 -0
- praisonai/cli/commands/serve.py +97 -0
- praisonai/cli/commands/session.py +212 -0
- praisonai/cli/commands/traces.py +145 -0
- praisonai/cli/commands/version.py +101 -0
- praisonai/cli/configuration/__init__.py +18 -0
- praisonai/cli/configuration/loader.py +353 -0
- praisonai/cli/configuration/paths.py +114 -0
- praisonai/cli/configuration/schema.py +164 -0
- praisonai/cli/features/__init__.py +268 -0
- praisonai/cli/features/acp.py +236 -0
- praisonai/cli/features/action_orchestrator.py +546 -0
- praisonai/cli/features/agent_scheduler.py +773 -0
- praisonai/cli/features/agent_tools.py +474 -0
- praisonai/cli/features/agents.py +375 -0
- praisonai/cli/features/at_mentions.py +471 -0
- praisonai/cli/features/auto_memory.py +182 -0
- praisonai/cli/features/autonomy_mode.py +490 -0
- praisonai/cli/features/background.py +356 -0
- praisonai/cli/features/base.py +168 -0
- praisonai/cli/features/capabilities.py +1326 -0
- praisonai/cli/features/checkpoints.py +338 -0
- praisonai/cli/features/code_intelligence.py +652 -0
- praisonai/cli/features/compaction.py +294 -0
- praisonai/cli/features/compare.py +534 -0
- praisonai/cli/features/cost_tracker.py +514 -0
- praisonai/cli/features/debug.py +810 -0
- praisonai/cli/features/deploy.py +517 -0
- praisonai/cli/features/diag.py +289 -0
- praisonai/cli/features/doctor/__init__.py +63 -0
- praisonai/cli/features/doctor/checks/__init__.py +24 -0
- praisonai/cli/features/doctor/checks/acp_checks.py +240 -0
- praisonai/cli/features/doctor/checks/config_checks.py +366 -0
- praisonai/cli/features/doctor/checks/db_checks.py +366 -0
- praisonai/cli/features/doctor/checks/env_checks.py +543 -0
- praisonai/cli/features/doctor/checks/lsp_checks.py +199 -0
- praisonai/cli/features/doctor/checks/mcp_checks.py +349 -0
- praisonai/cli/features/doctor/checks/memory_checks.py +268 -0
- praisonai/cli/features/doctor/checks/network_checks.py +251 -0
- praisonai/cli/features/doctor/checks/obs_checks.py +328 -0
- praisonai/cli/features/doctor/checks/performance_checks.py +235 -0
- praisonai/cli/features/doctor/checks/permissions_checks.py +259 -0
- praisonai/cli/features/doctor/checks/selftest_checks.py +322 -0
- praisonai/cli/features/doctor/checks/serve_checks.py +426 -0
- praisonai/cli/features/doctor/checks/skills_checks.py +231 -0
- praisonai/cli/features/doctor/checks/tools_checks.py +371 -0
- praisonai/cli/features/doctor/engine.py +266 -0
- praisonai/cli/features/doctor/formatters.py +310 -0
- praisonai/cli/features/doctor/handler.py +397 -0
- praisonai/cli/features/doctor/models.py +264 -0
- praisonai/cli/features/doctor/registry.py +239 -0
- praisonai/cli/features/endpoints.py +1019 -0
- praisonai/cli/features/eval.py +560 -0
- praisonai/cli/features/external_agents.py +231 -0
- praisonai/cli/features/fast_context.py +410 -0
- praisonai/cli/features/flow_display.py +566 -0
- praisonai/cli/features/git_integration.py +651 -0
- praisonai/cli/features/guardrail.py +171 -0
- praisonai/cli/features/handoff.py +185 -0
- praisonai/cli/features/hooks.py +583 -0
- praisonai/cli/features/image.py +384 -0
- praisonai/cli/features/interactive_runtime.py +585 -0
- praisonai/cli/features/interactive_tools.py +380 -0
- praisonai/cli/features/interactive_tui.py +603 -0
- praisonai/cli/features/jobs.py +632 -0
- praisonai/cli/features/knowledge.py +531 -0
- praisonai/cli/features/lite.py +244 -0
- praisonai/cli/features/lsp_cli.py +225 -0
- praisonai/cli/features/mcp.py +169 -0
- praisonai/cli/features/message_queue.py +587 -0
- praisonai/cli/features/metrics.py +211 -0
- praisonai/cli/features/n8n.py +673 -0
- praisonai/cli/features/observability.py +293 -0
- praisonai/cli/features/ollama.py +361 -0
- praisonai/cli/features/output_style.py +273 -0
- praisonai/cli/features/package.py +631 -0
- praisonai/cli/features/performance.py +308 -0
- praisonai/cli/features/persistence.py +636 -0
- praisonai/cli/features/profile.py +226 -0
- praisonai/cli/features/profiler/__init__.py +81 -0
- praisonai/cli/features/profiler/core.py +558 -0
- praisonai/cli/features/profiler/optimizations.py +652 -0
- praisonai/cli/features/profiler/suite.py +386 -0
- praisonai/cli/features/profiling.py +350 -0
- praisonai/cli/features/queue/__init__.py +73 -0
- praisonai/cli/features/queue/manager.py +395 -0
- praisonai/cli/features/queue/models.py +286 -0
- praisonai/cli/features/queue/persistence.py +564 -0
- praisonai/cli/features/queue/scheduler.py +484 -0
- praisonai/cli/features/queue/worker.py +372 -0
- praisonai/cli/features/recipe.py +1723 -0
- praisonai/cli/features/recipes.py +449 -0
- praisonai/cli/features/registry.py +229 -0
- praisonai/cli/features/repo_map.py +860 -0
- praisonai/cli/features/router.py +466 -0
- praisonai/cli/features/sandbox_executor.py +515 -0
- praisonai/cli/features/serve.py +829 -0
- praisonai/cli/features/session.py +222 -0
- praisonai/cli/features/skills.py +856 -0
- praisonai/cli/features/slash_commands.py +650 -0
- praisonai/cli/features/telemetry.py +179 -0
- praisonai/cli/features/templates.py +1384 -0
- praisonai/cli/features/thinking.py +305 -0
- praisonai/cli/features/todo.py +334 -0
- praisonai/cli/features/tools.py +680 -0
- praisonai/cli/features/tui/__init__.py +83 -0
- praisonai/cli/features/tui/app.py +580 -0
- praisonai/cli/features/tui/cli.py +566 -0
- praisonai/cli/features/tui/debug.py +511 -0
- praisonai/cli/features/tui/events.py +99 -0
- praisonai/cli/features/tui/mock_provider.py +328 -0
- praisonai/cli/features/tui/orchestrator.py +652 -0
- praisonai/cli/features/tui/screens/__init__.py +50 -0
- praisonai/cli/features/tui/screens/main.py +245 -0
- praisonai/cli/features/tui/screens/queue.py +174 -0
- praisonai/cli/features/tui/screens/session.py +124 -0
- praisonai/cli/features/tui/screens/settings.py +148 -0
- praisonai/cli/features/tui/widgets/__init__.py +56 -0
- praisonai/cli/features/tui/widgets/chat.py +261 -0
- praisonai/cli/features/tui/widgets/composer.py +224 -0
- praisonai/cli/features/tui/widgets/queue_panel.py +200 -0
- praisonai/cli/features/tui/widgets/status.py +167 -0
- praisonai/cli/features/tui/widgets/tool_panel.py +248 -0
- praisonai/cli/features/workflow.py +720 -0
- praisonai/cli/legacy.py +236 -0
- praisonai/cli/main.py +5559 -0
- praisonai/cli/schedule_cli.py +54 -0
- praisonai/cli/state/__init__.py +31 -0
- praisonai/cli/state/identifiers.py +161 -0
- praisonai/cli/state/sessions.py +313 -0
- praisonai/code/__init__.py +93 -0
- praisonai/code/agent_tools.py +344 -0
- praisonai/code/diff/__init__.py +21 -0
- praisonai/code/diff/diff_strategy.py +432 -0
- praisonai/code/tools/__init__.py +27 -0
- praisonai/code/tools/apply_diff.py +221 -0
- praisonai/code/tools/execute_command.py +275 -0
- praisonai/code/tools/list_files.py +274 -0
- praisonai/code/tools/read_file.py +206 -0
- praisonai/code/tools/search_replace.py +248 -0
- praisonai/code/tools/write_file.py +217 -0
- praisonai/code/utils/__init__.py +46 -0
- praisonai/code/utils/file_utils.py +307 -0
- praisonai/code/utils/ignore_utils.py +308 -0
- praisonai/code/utils/text_utils.py +276 -0
- praisonai/db/__init__.py +64 -0
- praisonai/db/adapter.py +531 -0
- praisonai/deploy/__init__.py +62 -0
- praisonai/deploy/api.py +231 -0
- praisonai/deploy/docker.py +454 -0
- praisonai/deploy/doctor.py +367 -0
- praisonai/deploy/main.py +327 -0
- praisonai/deploy/models.py +179 -0
- praisonai/deploy/providers/__init__.py +33 -0
- praisonai/deploy/providers/aws.py +331 -0
- praisonai/deploy/providers/azure.py +358 -0
- praisonai/deploy/providers/base.py +101 -0
- praisonai/deploy/providers/gcp.py +314 -0
- praisonai/deploy/schema.py +208 -0
- praisonai/deploy.py +185 -0
- praisonai/endpoints/__init__.py +53 -0
- praisonai/endpoints/a2u_server.py +410 -0
- praisonai/endpoints/discovery.py +165 -0
- praisonai/endpoints/providers/__init__.py +28 -0
- praisonai/endpoints/providers/a2a.py +253 -0
- praisonai/endpoints/providers/a2u.py +208 -0
- praisonai/endpoints/providers/agents_api.py +171 -0
- praisonai/endpoints/providers/base.py +231 -0
- praisonai/endpoints/providers/mcp.py +263 -0
- praisonai/endpoints/providers/recipe.py +206 -0
- praisonai/endpoints/providers/tools_mcp.py +150 -0
- praisonai/endpoints/registry.py +131 -0
- praisonai/endpoints/server.py +161 -0
- praisonai/inbuilt_tools/__init__.py +24 -0
- praisonai/inbuilt_tools/autogen_tools.py +117 -0
- praisonai/inc/__init__.py +2 -0
- praisonai/inc/config.py +96 -0
- praisonai/inc/models.py +155 -0
- praisonai/integrations/__init__.py +56 -0
- praisonai/integrations/base.py +303 -0
- praisonai/integrations/claude_code.py +270 -0
- praisonai/integrations/codex_cli.py +255 -0
- praisonai/integrations/cursor_cli.py +195 -0
- praisonai/integrations/gemini_cli.py +222 -0
- praisonai/jobs/__init__.py +67 -0
- praisonai/jobs/executor.py +425 -0
- praisonai/jobs/models.py +230 -0
- praisonai/jobs/router.py +314 -0
- praisonai/jobs/server.py +186 -0
- praisonai/jobs/store.py +203 -0
- praisonai/llm/__init__.py +66 -0
- praisonai/llm/registry.py +382 -0
- praisonai/mcp_server/__init__.py +152 -0
- praisonai/mcp_server/adapters/__init__.py +74 -0
- praisonai/mcp_server/adapters/agents.py +128 -0
- praisonai/mcp_server/adapters/capabilities.py +168 -0
- praisonai/mcp_server/adapters/cli_tools.py +568 -0
- praisonai/mcp_server/adapters/extended_capabilities.py +462 -0
- praisonai/mcp_server/adapters/knowledge.py +93 -0
- praisonai/mcp_server/adapters/memory.py +104 -0
- praisonai/mcp_server/adapters/prompts.py +306 -0
- praisonai/mcp_server/adapters/resources.py +124 -0
- praisonai/mcp_server/adapters/tools_bridge.py +280 -0
- praisonai/mcp_server/auth/__init__.py +48 -0
- praisonai/mcp_server/auth/api_key.py +291 -0
- praisonai/mcp_server/auth/oauth.py +460 -0
- praisonai/mcp_server/auth/oidc.py +289 -0
- praisonai/mcp_server/auth/scopes.py +260 -0
- praisonai/mcp_server/cli.py +852 -0
- praisonai/mcp_server/elicitation.py +445 -0
- praisonai/mcp_server/icons.py +302 -0
- praisonai/mcp_server/recipe_adapter.py +573 -0
- praisonai/mcp_server/recipe_cli.py +824 -0
- praisonai/mcp_server/registry.py +703 -0
- praisonai/mcp_server/sampling.py +422 -0
- praisonai/mcp_server/server.py +490 -0
- praisonai/mcp_server/tasks.py +443 -0
- praisonai/mcp_server/transports/__init__.py +18 -0
- praisonai/mcp_server/transports/http_stream.py +376 -0
- praisonai/mcp_server/transports/stdio.py +132 -0
- praisonai/persistence/__init__.py +84 -0
- praisonai/persistence/config.py +238 -0
- praisonai/persistence/conversation/__init__.py +25 -0
- praisonai/persistence/conversation/async_mysql.py +427 -0
- praisonai/persistence/conversation/async_postgres.py +410 -0
- praisonai/persistence/conversation/async_sqlite.py +371 -0
- praisonai/persistence/conversation/base.py +151 -0
- praisonai/persistence/conversation/json_store.py +250 -0
- praisonai/persistence/conversation/mysql.py +387 -0
- praisonai/persistence/conversation/postgres.py +401 -0
- praisonai/persistence/conversation/singlestore.py +240 -0
- praisonai/persistence/conversation/sqlite.py +341 -0
- praisonai/persistence/conversation/supabase.py +203 -0
- praisonai/persistence/conversation/surrealdb.py +287 -0
- praisonai/persistence/factory.py +301 -0
- praisonai/persistence/hooks/__init__.py +18 -0
- praisonai/persistence/hooks/agent_hooks.py +297 -0
- praisonai/persistence/knowledge/__init__.py +26 -0
- praisonai/persistence/knowledge/base.py +144 -0
- praisonai/persistence/knowledge/cassandra.py +232 -0
- praisonai/persistence/knowledge/chroma.py +295 -0
- praisonai/persistence/knowledge/clickhouse.py +242 -0
- praisonai/persistence/knowledge/cosmosdb_vector.py +438 -0
- praisonai/persistence/knowledge/couchbase.py +286 -0
- praisonai/persistence/knowledge/lancedb.py +216 -0
- praisonai/persistence/knowledge/langchain_adapter.py +291 -0
- praisonai/persistence/knowledge/lightrag_adapter.py +212 -0
- praisonai/persistence/knowledge/llamaindex_adapter.py +256 -0
- praisonai/persistence/knowledge/milvus.py +277 -0
- praisonai/persistence/knowledge/mongodb_vector.py +306 -0
- praisonai/persistence/knowledge/pgvector.py +335 -0
- praisonai/persistence/knowledge/pinecone.py +253 -0
- praisonai/persistence/knowledge/qdrant.py +301 -0
- praisonai/persistence/knowledge/redis_vector.py +291 -0
- praisonai/persistence/knowledge/singlestore_vector.py +299 -0
- praisonai/persistence/knowledge/surrealdb_vector.py +309 -0
- praisonai/persistence/knowledge/upstash_vector.py +266 -0
- praisonai/persistence/knowledge/weaviate.py +223 -0
- praisonai/persistence/migrations/__init__.py +10 -0
- praisonai/persistence/migrations/manager.py +251 -0
- praisonai/persistence/orchestrator.py +406 -0
- praisonai/persistence/state/__init__.py +21 -0
- praisonai/persistence/state/async_mongodb.py +200 -0
- praisonai/persistence/state/base.py +107 -0
- praisonai/persistence/state/dynamodb.py +226 -0
- praisonai/persistence/state/firestore.py +175 -0
- praisonai/persistence/state/gcs.py +155 -0
- praisonai/persistence/state/memory.py +245 -0
- praisonai/persistence/state/mongodb.py +158 -0
- praisonai/persistence/state/redis.py +190 -0
- praisonai/persistence/state/upstash.py +144 -0
- praisonai/persistence/tests/__init__.py +3 -0
- praisonai/persistence/tests/test_all_backends.py +633 -0
- praisonai/profiler.py +1214 -0
- praisonai/recipe/__init__.py +134 -0
- praisonai/recipe/bridge.py +278 -0
- praisonai/recipe/core.py +893 -0
- praisonai/recipe/exceptions.py +54 -0
- praisonai/recipe/history.py +402 -0
- praisonai/recipe/models.py +266 -0
- praisonai/recipe/operations.py +440 -0
- praisonai/recipe/policy.py +422 -0
- praisonai/recipe/registry.py +849 -0
- praisonai/recipe/runtime.py +214 -0
- praisonai/recipe/security.py +711 -0
- praisonai/recipe/serve.py +859 -0
- praisonai/recipe/server.py +613 -0
- praisonai/scheduler/__init__.py +45 -0
- praisonai/scheduler/agent_scheduler.py +552 -0
- praisonai/scheduler/base.py +124 -0
- praisonai/scheduler/daemon_manager.py +225 -0
- praisonai/scheduler/state_manager.py +155 -0
- praisonai/scheduler/yaml_loader.py +193 -0
- praisonai/scheduler.py +194 -0
- praisonai/setup/__init__.py +1 -0
- praisonai/setup/build.py +21 -0
- praisonai/setup/post_install.py +23 -0
- praisonai/setup/setup_conda_env.py +25 -0
- praisonai/setup.py +16 -0
- praisonai/templates/__init__.py +116 -0
- praisonai/templates/cache.py +364 -0
- praisonai/templates/dependency_checker.py +358 -0
- praisonai/templates/discovery.py +391 -0
- praisonai/templates/loader.py +564 -0
- praisonai/templates/registry.py +511 -0
- praisonai/templates/resolver.py +206 -0
- praisonai/templates/security.py +327 -0
- praisonai/templates/tool_override.py +498 -0
- praisonai/templates/tools_doctor.py +256 -0
- praisonai/test.py +105 -0
- praisonai/train.py +562 -0
- praisonai/train_vision.py +306 -0
- praisonai/ui/agents.py +824 -0
- praisonai/ui/callbacks.py +57 -0
- praisonai/ui/chainlit_compat.py +246 -0
- praisonai/ui/chat.py +532 -0
- praisonai/ui/code.py +717 -0
- praisonai/ui/colab.py +474 -0
- praisonai/ui/colab_chainlit.py +81 -0
- praisonai/ui/components/aicoder.py +284 -0
- praisonai/ui/context.py +283 -0
- praisonai/ui/database_config.py +56 -0
- praisonai/ui/db.py +294 -0
- praisonai/ui/realtime.py +488 -0
- praisonai/ui/realtimeclient/__init__.py +756 -0
- praisonai/ui/realtimeclient/tools.py +242 -0
- praisonai/ui/sql_alchemy.py +710 -0
- praisonai/upload_vision.py +140 -0
- praisonai/version.py +1 -0
- praisonai-3.0.0.dist-info/METADATA +3493 -0
- praisonai-3.0.0.dist-info/RECORD +393 -0
- praisonai-3.0.0.dist-info/WHEEL +5 -0
- praisonai-3.0.0.dist-info/entry_points.txt +4 -0
- praisonai-3.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Videos Capabilities Module
|
|
3
|
+
|
|
4
|
+
Provides video generation functionality via LiteLLM.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from typing import Optional, List, Any, Dict
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class VideoResult:
|
|
13
|
+
"""Result from video generation."""
|
|
14
|
+
url: Optional[str] = None
|
|
15
|
+
id: Optional[str] = None
|
|
16
|
+
status: Optional[str] = None
|
|
17
|
+
model: Optional[str] = None
|
|
18
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def video_generate(
|
|
22
|
+
prompt: str,
|
|
23
|
+
model: str = "runway/gen3a_turbo",
|
|
24
|
+
duration: int = 5,
|
|
25
|
+
aspect_ratio: str = "16:9",
|
|
26
|
+
timeout: float = 600.0,
|
|
27
|
+
api_key: Optional[str] = None,
|
|
28
|
+
api_base: Optional[str] = None,
|
|
29
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
30
|
+
**kwargs
|
|
31
|
+
) -> VideoResult:
|
|
32
|
+
"""
|
|
33
|
+
Generate a video from a text prompt.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
prompt: Text description of the video to generate
|
|
37
|
+
model: Model name (e.g., "runway/gen3a_turbo")
|
|
38
|
+
duration: Video duration in seconds
|
|
39
|
+
aspect_ratio: Aspect ratio (e.g., "16:9", "9:16", "1:1")
|
|
40
|
+
timeout: Request timeout in seconds
|
|
41
|
+
api_key: Optional API key override
|
|
42
|
+
api_base: Optional API base URL override
|
|
43
|
+
metadata: Optional metadata for tracing
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
VideoResult with video URL or ID
|
|
47
|
+
|
|
48
|
+
Example:
|
|
49
|
+
>>> result = video_generate("A sunset over the ocean")
|
|
50
|
+
>>> print(result.url)
|
|
51
|
+
"""
|
|
52
|
+
import litellm
|
|
53
|
+
|
|
54
|
+
call_kwargs = {
|
|
55
|
+
'model': model,
|
|
56
|
+
'prompt': prompt,
|
|
57
|
+
'duration': duration,
|
|
58
|
+
'aspect_ratio': aspect_ratio,
|
|
59
|
+
'timeout': timeout,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if api_key:
|
|
63
|
+
call_kwargs['api_key'] = api_key
|
|
64
|
+
if api_base:
|
|
65
|
+
call_kwargs['api_base'] = api_base
|
|
66
|
+
|
|
67
|
+
call_kwargs.update(kwargs)
|
|
68
|
+
|
|
69
|
+
if metadata:
|
|
70
|
+
call_kwargs['metadata'] = metadata
|
|
71
|
+
|
|
72
|
+
# Try to use video generation if available
|
|
73
|
+
try:
|
|
74
|
+
response = litellm.video_generation(**call_kwargs)
|
|
75
|
+
|
|
76
|
+
return VideoResult(
|
|
77
|
+
url=getattr(response, 'url', None),
|
|
78
|
+
id=getattr(response, 'id', None),
|
|
79
|
+
status=getattr(response, 'status', 'completed'),
|
|
80
|
+
model=model,
|
|
81
|
+
metadata=metadata or {},
|
|
82
|
+
)
|
|
83
|
+
except AttributeError:
|
|
84
|
+
# Fallback if video_generation not available
|
|
85
|
+
raise NotImplementedError(
|
|
86
|
+
"Video generation is not yet fully supported. "
|
|
87
|
+
"Please check LiteLLM documentation for available video models."
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
async def avideo_generate(
|
|
92
|
+
prompt: str,
|
|
93
|
+
model: str = "runway/gen3a_turbo",
|
|
94
|
+
duration: int = 5,
|
|
95
|
+
aspect_ratio: str = "16:9",
|
|
96
|
+
timeout: float = 600.0,
|
|
97
|
+
api_key: Optional[str] = None,
|
|
98
|
+
api_base: Optional[str] = None,
|
|
99
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
100
|
+
**kwargs
|
|
101
|
+
) -> VideoResult:
|
|
102
|
+
"""
|
|
103
|
+
Async: Generate a video from a text prompt.
|
|
104
|
+
|
|
105
|
+
See video_generate() for full documentation.
|
|
106
|
+
"""
|
|
107
|
+
import litellm
|
|
108
|
+
|
|
109
|
+
call_kwargs = {
|
|
110
|
+
'model': model,
|
|
111
|
+
'prompt': prompt,
|
|
112
|
+
'duration': duration,
|
|
113
|
+
'aspect_ratio': aspect_ratio,
|
|
114
|
+
'timeout': timeout,
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if api_key:
|
|
118
|
+
call_kwargs['api_key'] = api_key
|
|
119
|
+
if api_base:
|
|
120
|
+
call_kwargs['api_base'] = api_base
|
|
121
|
+
|
|
122
|
+
call_kwargs.update(kwargs)
|
|
123
|
+
|
|
124
|
+
if metadata:
|
|
125
|
+
call_kwargs['metadata'] = metadata
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
response = await litellm.avideo_generation(**call_kwargs)
|
|
129
|
+
|
|
130
|
+
return VideoResult(
|
|
131
|
+
url=getattr(response, 'url', None),
|
|
132
|
+
id=getattr(response, 'id', None),
|
|
133
|
+
status=getattr(response, 'status', 'completed'),
|
|
134
|
+
model=model,
|
|
135
|
+
metadata=metadata or {},
|
|
136
|
+
)
|
|
137
|
+
except AttributeError:
|
|
138
|
+
raise NotImplementedError(
|
|
139
|
+
"Video generation is not yet fully supported. "
|
|
140
|
+
"Please check LiteLLM documentation for available video models."
|
|
141
|
+
)
|
praisonai/chainlit_ui.py
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# praisonai/chainlit_ui.py
|
|
2
|
+
from praisonai.agents_generator import AgentsGenerator
|
|
3
|
+
from praisonai.auto import AutoGenerator
|
|
4
|
+
import chainlit as cl
|
|
5
|
+
import os
|
|
6
|
+
from chainlit.types import ThreadDict
|
|
7
|
+
from chainlit.input_widget import Select, TextInput
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from dotenv import load_dotenv
|
|
10
|
+
load_dotenv()
|
|
11
|
+
from contextlib import redirect_stdout
|
|
12
|
+
from io import StringIO
|
|
13
|
+
import logging
|
|
14
|
+
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO').upper(), format='%(asctime)s - %(levelname)s - %(message)s')
|
|
15
|
+
|
|
16
|
+
framework = "crewai"
|
|
17
|
+
config_list = [
|
|
18
|
+
{
|
|
19
|
+
'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-5-nano"),
|
|
20
|
+
'base_url': os.environ.get("OPENAI_API_BASE", "https://api.openai.com/v1"),
|
|
21
|
+
'api_key': os.environ.get("OPENAI_API_KEY", "")
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
agent_file = "test.yaml"
|
|
25
|
+
|
|
26
|
+
actions=[
|
|
27
|
+
cl.Action(name="run", payload={"value": "run"}, label="run"),
|
|
28
|
+
cl.Action(name="modify", payload={"value": "modify"}, label="Modify"),
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
@cl.action_callback("run")
|
|
32
|
+
async def on_run(action):
|
|
33
|
+
await main(cl.Message(content=""))
|
|
34
|
+
|
|
35
|
+
@cl.action_callback("modify")
|
|
36
|
+
async def on_modify(action):
|
|
37
|
+
await cl.Message(content="Modify the agents and tools from below settings").send()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@cl.set_chat_profiles
|
|
41
|
+
async def set_profiles(current_user: cl.User):
|
|
42
|
+
return [
|
|
43
|
+
cl.ChatProfile(
|
|
44
|
+
name="Auto",
|
|
45
|
+
markdown_description="Automatically generate agents and tasks based on your input.",
|
|
46
|
+
starters=[
|
|
47
|
+
cl.Starter(
|
|
48
|
+
label="Create a movie script",
|
|
49
|
+
message="Create a movie script about a futuristic society where AI and humans coexist, focusing on the conflict and resolution between them. Start with an intriguing opening scene.",
|
|
50
|
+
icon="/public/movie.svg",
|
|
51
|
+
),
|
|
52
|
+
cl.Starter(
|
|
53
|
+
label="Design a fantasy world",
|
|
54
|
+
message="Design a detailed fantasy world with unique geography, cultures, and magical systems. Start by describing the main continent and its inhabitants.",
|
|
55
|
+
icon="/public/fantasy.svg",
|
|
56
|
+
),
|
|
57
|
+
cl.Starter(
|
|
58
|
+
label="Write a futuristic political thriller",
|
|
59
|
+
message="Write a futuristic political thriller involving a conspiracy within a global government. Start with a high-stakes meeting that sets the plot in motion.",
|
|
60
|
+
icon="/public/thriller.svg",
|
|
61
|
+
),
|
|
62
|
+
cl.Starter(
|
|
63
|
+
label="Develop a new board game",
|
|
64
|
+
message="Develop a new, innovative board game. Describe the game's objective, rules, and unique mechanics. Create a scenario to illustrate gameplay.",
|
|
65
|
+
icon="/public/game.svg",
|
|
66
|
+
),
|
|
67
|
+
]
|
|
68
|
+
),
|
|
69
|
+
cl.ChatProfile(
|
|
70
|
+
name="Manual",
|
|
71
|
+
markdown_description="Manually define your agents and tasks using a YAML file.",
|
|
72
|
+
),
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@cl.on_chat_start
|
|
77
|
+
async def start_chat():
|
|
78
|
+
cl.user_session.set(
|
|
79
|
+
"message_history",
|
|
80
|
+
[{"role": "system", "content": "You are a helpful assistant."}],
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# Create tools.py if it doesn't exist
|
|
84
|
+
if not os.path.exists("tools.py"):
|
|
85
|
+
with open("tools.py", "w") as f:
|
|
86
|
+
f.write("# Add your custom tools here\n")
|
|
87
|
+
|
|
88
|
+
settings = await cl.ChatSettings(
|
|
89
|
+
[
|
|
90
|
+
TextInput(id="Model", label="OpenAI - Model", initial=config_list[0]['model']),
|
|
91
|
+
TextInput(id="BaseUrl", label="OpenAI - Base URL", initial=config_list[0]['base_url']),
|
|
92
|
+
TextInput(id="ApiKey", label="OpenAI - API Key", initial=config_list[0]['api_key']),
|
|
93
|
+
Select(
|
|
94
|
+
id="Framework",
|
|
95
|
+
label="Framework",
|
|
96
|
+
values=["crewai", "autogen"],
|
|
97
|
+
initial_index=0,
|
|
98
|
+
),
|
|
99
|
+
]
|
|
100
|
+
).send()
|
|
101
|
+
cl.user_session.set("settings", settings)
|
|
102
|
+
chat_profile = cl.user_session.get("chat_profile")
|
|
103
|
+
if chat_profile=="Manual":
|
|
104
|
+
|
|
105
|
+
agent_file = "agents.yaml"
|
|
106
|
+
full_agent_file_path = os.path.abspath(agent_file) # Get full path
|
|
107
|
+
if os.path.exists(full_agent_file_path):
|
|
108
|
+
with open(full_agent_file_path, 'r') as f:
|
|
109
|
+
yaml_content = f.read()
|
|
110
|
+
msg = cl.Message(content=yaml_content, language="yaml")
|
|
111
|
+
await msg.send()
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
full_tools_file_path = os.path.abspath("tools.py") # Get full path
|
|
115
|
+
if os.path.exists(full_tools_file_path):
|
|
116
|
+
with open(full_tools_file_path, 'r') as f:
|
|
117
|
+
tools_content = f.read()
|
|
118
|
+
msg = cl.Message(content=tools_content, language="python")
|
|
119
|
+
await msg.send()
|
|
120
|
+
|
|
121
|
+
settings = await cl.ChatSettings(
|
|
122
|
+
[
|
|
123
|
+
TextInput(id="Model", label="OpenAI - Model", initial=config_list[0]['model']),
|
|
124
|
+
TextInput(id="BaseUrl", label="OpenAI - Base URL", initial=config_list[0]['base_url']),
|
|
125
|
+
TextInput(id="ApiKey", label="OpenAI - API Key", initial=config_list[0]['api_key']),
|
|
126
|
+
Select(
|
|
127
|
+
id="Framework",
|
|
128
|
+
label="Framework",
|
|
129
|
+
values=["crewai", "autogen"],
|
|
130
|
+
initial_index=0,
|
|
131
|
+
),
|
|
132
|
+
TextInput(id="agents", label="agents.yaml", initial=yaml_content, multiline=True),
|
|
133
|
+
TextInput(id="tools", label="tools.py", initial=tools_content, multiline=True),
|
|
134
|
+
]
|
|
135
|
+
).send()
|
|
136
|
+
cl.user_session.set("settings", settings)
|
|
137
|
+
|
|
138
|
+
res = await cl.AskActionMessage(
|
|
139
|
+
content="Pick an action!",
|
|
140
|
+
actions=actions,
|
|
141
|
+
).send()
|
|
142
|
+
if res and res.get("value") == "modify":
|
|
143
|
+
await cl.Message(content="Modify the agents and tools from below settings", actions=actions).send()
|
|
144
|
+
elif res and res.get("value") == "run":
|
|
145
|
+
await main(cl.Message(content="", actions=actions))
|
|
146
|
+
|
|
147
|
+
await on_settings_update(settings)
|
|
148
|
+
|
|
149
|
+
@cl.on_settings_update
|
|
150
|
+
async def on_settings_update(settings):
|
|
151
|
+
"""Handle updates to the ChatSettings form."""
|
|
152
|
+
global config_list, framework
|
|
153
|
+
config_list[0]['model'] = settings["Model"]
|
|
154
|
+
config_list[0]['base_url'] = settings["BaseUrl"]
|
|
155
|
+
config_list[0]['api_key'] = settings["ApiKey"]
|
|
156
|
+
os.environ["OPENAI_API_KEY"] = config_list[0]['api_key']
|
|
157
|
+
os.environ["OPENAI_MODEL_NAME"] = config_list[0]['model']
|
|
158
|
+
os.environ["OPENAI_API_BASE"] = config_list[0]['base_url']
|
|
159
|
+
framework = settings["Framework"]
|
|
160
|
+
|
|
161
|
+
if "agents" in settings:
|
|
162
|
+
with open("agents.yaml", "w") as f:
|
|
163
|
+
f.write(settings["agents"])
|
|
164
|
+
if "tools" in settings:
|
|
165
|
+
with open("tools.py", "w") as f:
|
|
166
|
+
f.write(settings["tools"])
|
|
167
|
+
|
|
168
|
+
print("Settings updated")
|
|
169
|
+
|
|
170
|
+
@cl.on_chat_resume
|
|
171
|
+
async def on_chat_resume(thread: ThreadDict):
|
|
172
|
+
message_history = cl.user_session.get("message_history", [])
|
|
173
|
+
root_messages = [m for m in thread["steps"] if m["parentId"] is None]
|
|
174
|
+
for message in root_messages:
|
|
175
|
+
if message["type"] == "user_message":
|
|
176
|
+
message_history.append({"role": "user", "content": message["output"]})
|
|
177
|
+
elif message["type"] == "ai_message":
|
|
178
|
+
message_history.append({"role": "assistant", "content": message["content"]})
|
|
179
|
+
cl.user_session.set("message_history", message_history)
|
|
180
|
+
|
|
181
|
+
# @cl.step(type="tool")
|
|
182
|
+
# async def tool(data: Optional[str] = None, language: Optional[str] = None):
|
|
183
|
+
# return cl.Message(content=data, language=language)
|
|
184
|
+
|
|
185
|
+
@cl.step(type="tool", show_input=False)
|
|
186
|
+
async def run_agents(agent_file: str, framework: str):
|
|
187
|
+
"""Runs the agents and returns the result."""
|
|
188
|
+
agents_generator = AgentsGenerator(agent_file, framework, config_list)
|
|
189
|
+
current_step = cl.context.current_step
|
|
190
|
+
print("Current Step:", current_step)
|
|
191
|
+
|
|
192
|
+
stdout_buffer = StringIO()
|
|
193
|
+
with redirect_stdout(stdout_buffer):
|
|
194
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
195
|
+
|
|
196
|
+
complete_output = stdout_buffer.getvalue()
|
|
197
|
+
|
|
198
|
+
async with cl.Step(name="gpt4", type="llm", show_input=True) as step:
|
|
199
|
+
step.input = ""
|
|
200
|
+
|
|
201
|
+
for line in stdout_buffer.getvalue().splitlines():
|
|
202
|
+
print(line)
|
|
203
|
+
await step.stream_token(line)
|
|
204
|
+
|
|
205
|
+
tool_res = await output(complete_output)
|
|
206
|
+
|
|
207
|
+
yield result
|
|
208
|
+
|
|
209
|
+
@cl.step(type="tool", show_input=False, language="yaml")
|
|
210
|
+
async def output(output):
|
|
211
|
+
return output
|
|
212
|
+
|
|
213
|
+
@cl.step(type="tool", show_input=False, language="yaml")
|
|
214
|
+
def agent(output):
|
|
215
|
+
return(f"""
|
|
216
|
+
Agent Step Completed!
|
|
217
|
+
Output: {output}
|
|
218
|
+
""")
|
|
219
|
+
|
|
220
|
+
@cl.step(type="tool", show_input=False, language="yaml")
|
|
221
|
+
def task(output):
|
|
222
|
+
return(f"""
|
|
223
|
+
Task Completed!
|
|
224
|
+
Task: {output.description}
|
|
225
|
+
Output: {output.raw_output}
|
|
226
|
+
{output}
|
|
227
|
+
""")
|
|
228
|
+
|
|
229
|
+
@cl.on_message
|
|
230
|
+
async def main(message: cl.Message):
|
|
231
|
+
"""Run PraisonAI with the provided message as the topic."""
|
|
232
|
+
message_history = cl.user_session.get("message_history")
|
|
233
|
+
if message_history is None:
|
|
234
|
+
message_history = []
|
|
235
|
+
cl.user_session.set("message_history", message_history)
|
|
236
|
+
message_history.append({"role": "user", "content": message.content})
|
|
237
|
+
topic = message.content
|
|
238
|
+
chat_profile = cl.user_session.get("chat_profile")
|
|
239
|
+
|
|
240
|
+
if chat_profile == "Auto":
|
|
241
|
+
agent_file = "agents.yaml"
|
|
242
|
+
generator = AutoGenerator(topic=topic, agent_file=agent_file, framework=framework, config_list=config_list)
|
|
243
|
+
await cl.sleep(2)
|
|
244
|
+
agent_file = generator.generate()
|
|
245
|
+
agents_generator = AgentsGenerator(
|
|
246
|
+
agent_file,
|
|
247
|
+
framework,
|
|
248
|
+
config_list,
|
|
249
|
+
# agent_callback=agent,
|
|
250
|
+
# task_callback=task
|
|
251
|
+
)
|
|
252
|
+
# Capture stdout
|
|
253
|
+
stdout_buffer = StringIO()
|
|
254
|
+
with redirect_stdout(stdout_buffer):
|
|
255
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
256
|
+
|
|
257
|
+
complete_output = stdout_buffer.getvalue()
|
|
258
|
+
tool_res = await output(complete_output)
|
|
259
|
+
msg = cl.Message(content=result)
|
|
260
|
+
await msg.send()
|
|
261
|
+
message_history.append({"role": "assistant", "content": message.content})
|
|
262
|
+
else: # chat_profile == "Manual"
|
|
263
|
+
agent_file = "agents.yaml"
|
|
264
|
+
full_agent_file_path = os.path.abspath(agent_file) # Get full path
|
|
265
|
+
full_tools_file_path = os.path.abspath("tools.py")
|
|
266
|
+
if os.path.exists(full_agent_file_path):
|
|
267
|
+
with open(full_agent_file_path, 'r') as f:
|
|
268
|
+
yaml_content = f.read()
|
|
269
|
+
# tool_res = await tool()
|
|
270
|
+
msg_agents = cl.Message(content=yaml_content, language="yaml")
|
|
271
|
+
await msg_agents.send()
|
|
272
|
+
if os.path.exists(full_tools_file_path):
|
|
273
|
+
with open(full_tools_file_path, 'r') as f:
|
|
274
|
+
tools_content = f.read()
|
|
275
|
+
msg_tools = cl.Message(content=tools_content, language="python")
|
|
276
|
+
await msg_tools.send()
|
|
277
|
+
else:
|
|
278
|
+
# If the file doesn't exist, follow the same process as "Auto"
|
|
279
|
+
generator = AutoGenerator(topic=topic, agent_file=agent_file, framework=framework, config_list=config_list)
|
|
280
|
+
agent_file = generator.generate()
|
|
281
|
+
|
|
282
|
+
agents_generator = AgentsGenerator(agent_file, framework, config_list)
|
|
283
|
+
result = agents_generator.generate_crew_and_kickoff()
|
|
284
|
+
msg = cl.Message(content=result, actions=actions)
|
|
285
|
+
await msg.send()
|
|
286
|
+
message_history.append({"role": "assistant", "content": message.content})
|
|
287
|
+
|
|
288
|
+
# Load environment variables from .env file
|
|
289
|
+
load_dotenv()
|
|
290
|
+
|
|
291
|
+
# Get username and password from environment variables
|
|
292
|
+
username = os.getenv("CHAINLIT_USERNAME", "admin") # Default to "admin" if not found
|
|
293
|
+
password = os.getenv("CHAINLIT_PASSWORD", "admin") # Default to "admin" if not found
|
|
294
|
+
|
|
295
|
+
@cl.password_auth_callback
|
|
296
|
+
def auth_callback(username: str, password: str):
|
|
297
|
+
# Fetch the user matching username from your database
|
|
298
|
+
# and compare the hashed password with the value stored in the database
|
|
299
|
+
if (username, password) == (username, password):
|
|
300
|
+
return cl.User(
|
|
301
|
+
identifier=username, metadata={"role": "ADMIN", "provider": "credentials"}
|
|
302
|
+
)
|
|
303
|
+
else:
|
|
304
|
+
return None
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PraisonAI Chat Module
|
|
3
|
+
|
|
4
|
+
This module provides the chat UI integration for PraisonAI agents.
|
|
5
|
+
It uses the PraisonAI Chat (based on Chainlit) for the frontend.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Optional, Any
|
|
9
|
+
|
|
10
|
+
__all__ = ["start_chat_server", "ChatConfig"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ChatConfig:
|
|
14
|
+
"""Configuration for the PraisonAI Chat server."""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
host: str = "0.0.0.0",
|
|
19
|
+
port: int = 8000,
|
|
20
|
+
debug: bool = False,
|
|
21
|
+
auth_enabled: bool = False,
|
|
22
|
+
session_id: Optional[str] = None,
|
|
23
|
+
):
|
|
24
|
+
self.host = host
|
|
25
|
+
self.port = port
|
|
26
|
+
self.debug = debug
|
|
27
|
+
self.auth_enabled = auth_enabled
|
|
28
|
+
self.session_id = session_id
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def start_chat_server(
|
|
32
|
+
agent: Optional[Any] = None,
|
|
33
|
+
agents: Optional[list] = None,
|
|
34
|
+
config: Optional[ChatConfig] = None,
|
|
35
|
+
port: int = 8000,
|
|
36
|
+
host: str = "0.0.0.0",
|
|
37
|
+
debug: bool = False,
|
|
38
|
+
) -> None:
|
|
39
|
+
"""
|
|
40
|
+
Start the PraisonAI Chat server.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
agent: A single PraisonAI agent to use in the chat.
|
|
44
|
+
agents: A list of PraisonAI agents for multi-agent chat.
|
|
45
|
+
config: ChatConfig object with server settings.
|
|
46
|
+
port: Port to run the server on (default: 8000).
|
|
47
|
+
host: Host to bind to (default: 0.0.0.0).
|
|
48
|
+
debug: Enable debug mode (default: False).
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
>>> from praisonaiagents import Agent
|
|
52
|
+
>>> from praisonai.chat import start_chat_server
|
|
53
|
+
>>>
|
|
54
|
+
>>> agent = Agent(name="Assistant", instructions="You are helpful.")
|
|
55
|
+
>>> start_chat_server(agent=agent, port=8000)
|
|
56
|
+
"""
|
|
57
|
+
# Lazy import to avoid loading chainlit unless needed
|
|
58
|
+
try:
|
|
59
|
+
from chainlit.cli import run_chainlit
|
|
60
|
+
except ImportError:
|
|
61
|
+
raise ImportError(
|
|
62
|
+
"PraisonAI Chat requires the 'praisonai-chat' package. "
|
|
63
|
+
"Install it with: pip install praisonai-chat"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
if config is None:
|
|
67
|
+
config = ChatConfig(host=host, port=port, debug=debug)
|
|
68
|
+
|
|
69
|
+
# Store agents in a way accessible to the chainlit app
|
|
70
|
+
import os
|
|
71
|
+
os.environ["PRAISONAI_CHAT_MODE"] = "true"
|
|
72
|
+
|
|
73
|
+
if agent is not None:
|
|
74
|
+
# Single agent mode
|
|
75
|
+
_register_agent(agent)
|
|
76
|
+
elif agents is not None:
|
|
77
|
+
# Multi-agent mode
|
|
78
|
+
for a in agents:
|
|
79
|
+
_register_agent(a)
|
|
80
|
+
|
|
81
|
+
# Start the chainlit server
|
|
82
|
+
from pathlib import Path
|
|
83
|
+
|
|
84
|
+
# Use the built-in app file
|
|
85
|
+
app_file = Path(__file__).parent / "app.py"
|
|
86
|
+
|
|
87
|
+
# Set environment variables for chainlit
|
|
88
|
+
os.environ["CHAINLIT_HOST"] = config.host
|
|
89
|
+
os.environ["CHAINLIT_PORT"] = str(config.port)
|
|
90
|
+
|
|
91
|
+
run_chainlit(str(app_file))
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# Global registry for agents
|
|
95
|
+
_REGISTERED_AGENTS: dict = {}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _register_agent(agent: Any) -> None:
|
|
99
|
+
"""Register an agent for use in the chat UI."""
|
|
100
|
+
agent_name = getattr(agent, "name", None) or getattr(agent, "role", "Agent")
|
|
101
|
+
_REGISTERED_AGENTS[agent_name] = agent
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def get_registered_agents() -> dict:
|
|
105
|
+
"""Get all registered agents."""
|
|
106
|
+
return _REGISTERED_AGENTS
|
praisonai/chat/app.py
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PraisonAI Chat - Default Chainlit Application
|
|
3
|
+
|
|
4
|
+
This is the default chat application that runs when using `praisonai chat`.
|
|
5
|
+
It integrates with PraisonAI agents for multi-agent conversations.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import chainlit as cl
|
|
10
|
+
|
|
11
|
+
# Check if we're in PraisonAI Chat mode with registered agents
|
|
12
|
+
PRAISONAI_CHAT_MODE = os.environ.get("PRAISONAI_CHAT_MODE", "false").lower() == "true"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_agents():
|
|
16
|
+
"""Get registered agents from the chat module."""
|
|
17
|
+
try:
|
|
18
|
+
from praisonai.chat import get_registered_agents
|
|
19
|
+
return get_registered_agents()
|
|
20
|
+
except ImportError:
|
|
21
|
+
return {}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@cl.on_chat_start
|
|
25
|
+
async def on_chat_start():
|
|
26
|
+
"""Initialize the chat session."""
|
|
27
|
+
agents = get_agents()
|
|
28
|
+
|
|
29
|
+
if agents:
|
|
30
|
+
agent_names = list(agents.keys())
|
|
31
|
+
cl.user_session.set("agents", agents)
|
|
32
|
+
cl.user_session.set("current_agent", agent_names[0] if agent_names else None)
|
|
33
|
+
|
|
34
|
+
await cl.Message(
|
|
35
|
+
content=f"Welcome to PraisonAI Chat! Available agents: {', '.join(agent_names)}"
|
|
36
|
+
).send()
|
|
37
|
+
else:
|
|
38
|
+
await cl.Message(
|
|
39
|
+
content="Welcome to PraisonAI Chat! No agents configured. "
|
|
40
|
+
"Use the API to register agents or configure via YAML."
|
|
41
|
+
).send()
|
|
42
|
+
|
|
43
|
+
cl.user_session.set("message_history", [])
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@cl.on_message
|
|
47
|
+
async def on_message(message: cl.Message):
|
|
48
|
+
"""Handle incoming messages."""
|
|
49
|
+
agents = cl.user_session.get("agents", {})
|
|
50
|
+
current_agent_name = cl.user_session.get("current_agent")
|
|
51
|
+
message_history = cl.user_session.get("message_history", [])
|
|
52
|
+
|
|
53
|
+
# Add user message to history
|
|
54
|
+
message_history.append({"role": "user", "content": message.content})
|
|
55
|
+
|
|
56
|
+
if not agents or not current_agent_name:
|
|
57
|
+
# No agents configured - use a simple echo response
|
|
58
|
+
response = f"Echo: {message.content}\n\n(No agents configured. Register agents to enable AI responses.)"
|
|
59
|
+
await cl.Message(content=response).send()
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
agent = agents.get(current_agent_name)
|
|
63
|
+
if agent is None:
|
|
64
|
+
await cl.Message(content=f"Agent '{current_agent_name}' not found.").send()
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
# Create a step for the agent response
|
|
68
|
+
async with cl.Step(name=current_agent_name, type="llm") as step:
|
|
69
|
+
step.input = message.content
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
# Try to call the agent
|
|
73
|
+
if hasattr(agent, "chat"):
|
|
74
|
+
# PraisonAI Agent with chat method
|
|
75
|
+
response = await _call_agent_async(agent, message.content)
|
|
76
|
+
elif hasattr(agent, "run"):
|
|
77
|
+
# Agent with run method
|
|
78
|
+
response = await _call_agent_async(agent, message.content, method="run")
|
|
79
|
+
elif callable(agent):
|
|
80
|
+
# Callable agent
|
|
81
|
+
response = agent(message.content)
|
|
82
|
+
else:
|
|
83
|
+
response = f"Agent '{current_agent_name}' does not have a callable interface."
|
|
84
|
+
|
|
85
|
+
step.output = str(response)
|
|
86
|
+
|
|
87
|
+
except Exception as e:
|
|
88
|
+
response = f"Error calling agent: {str(e)}"
|
|
89
|
+
step.output = response
|
|
90
|
+
|
|
91
|
+
# Add assistant response to history
|
|
92
|
+
message_history.append({"role": "assistant", "content": str(response)})
|
|
93
|
+
cl.user_session.set("message_history", message_history)
|
|
94
|
+
|
|
95
|
+
# Send the response
|
|
96
|
+
await cl.Message(content=str(response)).send()
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
async def _call_agent_async(agent, message: str, method: str = "chat"):
|
|
100
|
+
"""Call an agent method, handling both sync and async."""
|
|
101
|
+
import asyncio
|
|
102
|
+
|
|
103
|
+
func = getattr(agent, method)
|
|
104
|
+
|
|
105
|
+
if asyncio.iscoroutinefunction(func):
|
|
106
|
+
return await func(message)
|
|
107
|
+
else:
|
|
108
|
+
# Run sync function in thread pool
|
|
109
|
+
loop = asyncio.get_event_loop()
|
|
110
|
+
return await loop.run_in_executor(None, func, message)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@cl.on_chat_resume
|
|
114
|
+
async def on_chat_resume(thread):
|
|
115
|
+
"""Resume a chat session."""
|
|
116
|
+
message_history = []
|
|
117
|
+
|
|
118
|
+
root_messages = [m for m in thread.get("steps", []) if m.get("parentId") is None]
|
|
119
|
+
for msg in root_messages:
|
|
120
|
+
if msg.get("type") == "user_message":
|
|
121
|
+
message_history.append({"role": "user", "content": msg.get("output", "")})
|
|
122
|
+
elif msg.get("type") == "assistant_message":
|
|
123
|
+
message_history.append({"role": "assistant", "content": msg.get("output", "")})
|
|
124
|
+
|
|
125
|
+
cl.user_session.set("message_history", message_history)
|