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
praisonai/acp/server.py
ADDED
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ACP Server implementation for PraisonAI.
|
|
3
|
+
|
|
4
|
+
This module implements the Agent Client Protocol server that allows
|
|
5
|
+
IDEs/editors to communicate with PraisonAI agents.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import logging
|
|
10
|
+
import sys
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Any, Dict, List, Optional, Union
|
|
13
|
+
|
|
14
|
+
from .config import ACPConfig
|
|
15
|
+
from .session import ACPSession, SessionStore
|
|
16
|
+
|
|
17
|
+
# Configure logging to stderr only (stdout reserved for JSON-RPC)
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _setup_stderr_logging(debug: bool = False) -> None:
|
|
22
|
+
"""Configure logging to stderr only."""
|
|
23
|
+
handler = logging.StreamHandler(sys.stderr)
|
|
24
|
+
handler.setFormatter(logging.Formatter(
|
|
25
|
+
"%(asctime)s [%(levelname)s] %(name)s: %(message)s"
|
|
26
|
+
))
|
|
27
|
+
|
|
28
|
+
root_logger = logging.getLogger("praisonai.acp")
|
|
29
|
+
root_logger.handlers.clear()
|
|
30
|
+
root_logger.addHandler(handler)
|
|
31
|
+
root_logger.setLevel(logging.DEBUG if debug else logging.INFO)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ACPServer:
|
|
35
|
+
"""
|
|
36
|
+
ACP Server that exposes PraisonAI agents to IDE clients.
|
|
37
|
+
|
|
38
|
+
Implements the Agent Client Protocol (JSON-RPC 2.0 over stdio).
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
config: Optional[ACPConfig] = None,
|
|
44
|
+
agent: Optional[Any] = None,
|
|
45
|
+
agents: Optional[Any] = None,
|
|
46
|
+
):
|
|
47
|
+
"""
|
|
48
|
+
Initialize ACP server.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
config: ACP configuration
|
|
52
|
+
agent: Optional pre-configured Agent instance
|
|
53
|
+
agents: Optional pre-configured PraisonAIAgents instance
|
|
54
|
+
"""
|
|
55
|
+
self.config = config or ACPConfig()
|
|
56
|
+
self._agent = agent
|
|
57
|
+
self._agents = agents
|
|
58
|
+
self._session_store = SessionStore()
|
|
59
|
+
self._sessions: Dict[str, ACPSession] = {}
|
|
60
|
+
self._client = None # ACP client connection
|
|
61
|
+
self._cancelled_sessions: set = set()
|
|
62
|
+
|
|
63
|
+
_setup_stderr_logging(self.config.debug)
|
|
64
|
+
|
|
65
|
+
def _get_agent(self):
|
|
66
|
+
"""Lazy load or create agent."""
|
|
67
|
+
if self._agent is not None:
|
|
68
|
+
return self._agent
|
|
69
|
+
|
|
70
|
+
if self._agents is not None:
|
|
71
|
+
return self._agents
|
|
72
|
+
|
|
73
|
+
# Create default agent
|
|
74
|
+
try:
|
|
75
|
+
from praisonaiagents import Agent
|
|
76
|
+
self._agent = Agent(
|
|
77
|
+
name="PraisonAI",
|
|
78
|
+
instructions="You are a helpful AI coding assistant.",
|
|
79
|
+
model=self.config.model or "gpt-4o-mini",
|
|
80
|
+
)
|
|
81
|
+
return self._agent
|
|
82
|
+
except ImportError:
|
|
83
|
+
logger.error("praisonaiagents not installed")
|
|
84
|
+
raise RuntimeError("praisonaiagents package required")
|
|
85
|
+
|
|
86
|
+
def on_connect(self, client) -> None:
|
|
87
|
+
"""Called when client connects."""
|
|
88
|
+
self._client = client
|
|
89
|
+
logger.info("Client connected")
|
|
90
|
+
|
|
91
|
+
async def initialize(
|
|
92
|
+
self,
|
|
93
|
+
protocol_version: int,
|
|
94
|
+
client_capabilities: Optional[Dict[str, Any]] = None,
|
|
95
|
+
client_info: Optional[Dict[str, Any]] = None,
|
|
96
|
+
**kwargs: Any,
|
|
97
|
+
) -> Dict[str, Any]:
|
|
98
|
+
"""
|
|
99
|
+
Handle initialize request.
|
|
100
|
+
|
|
101
|
+
Negotiate protocol version and exchange capabilities.
|
|
102
|
+
"""
|
|
103
|
+
logger.info(f"Initialize: protocol_version={protocol_version}, client_info={client_info}")
|
|
104
|
+
|
|
105
|
+
# Import here to avoid circular imports and check availability
|
|
106
|
+
try:
|
|
107
|
+
from acp import PROTOCOL_VERSION
|
|
108
|
+
except ImportError:
|
|
109
|
+
PROTOCOL_VERSION = 1
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
"protocolVersion": min(protocol_version, PROTOCOL_VERSION),
|
|
113
|
+
"agentCapabilities": {
|
|
114
|
+
"loadSession": True,
|
|
115
|
+
"promptCapabilities": {
|
|
116
|
+
"image": False,
|
|
117
|
+
"audio": False,
|
|
118
|
+
"embeddedContext": True,
|
|
119
|
+
},
|
|
120
|
+
"mcpCapabilities": {
|
|
121
|
+
"http": False,
|
|
122
|
+
"sse": False,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
"agentInfo": {
|
|
126
|
+
"name": "praisonai",
|
|
127
|
+
"title": "PraisonAI",
|
|
128
|
+
"version": self._get_version(),
|
|
129
|
+
},
|
|
130
|
+
"authMethods": [],
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async def authenticate(self, method_id: str, **kwargs: Any) -> Optional[Dict[str, Any]]:
|
|
134
|
+
"""Handle authenticate request (optional)."""
|
|
135
|
+
logger.info(f"Authenticate: method_id={method_id}")
|
|
136
|
+
return {}
|
|
137
|
+
|
|
138
|
+
async def new_session(
|
|
139
|
+
self,
|
|
140
|
+
cwd: str,
|
|
141
|
+
mcp_servers: List[Dict[str, Any]],
|
|
142
|
+
**kwargs: Any,
|
|
143
|
+
) -> Dict[str, Any]:
|
|
144
|
+
"""
|
|
145
|
+
Create a new conversation session.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
cwd: Working directory for the session
|
|
149
|
+
mcp_servers: List of MCP server configurations
|
|
150
|
+
"""
|
|
151
|
+
logger.info(f"New session: cwd={cwd}")
|
|
152
|
+
|
|
153
|
+
workspace = Path(cwd).resolve()
|
|
154
|
+
session = ACPSession.create(
|
|
155
|
+
workspace=workspace,
|
|
156
|
+
agent_id=self.config.agent,
|
|
157
|
+
)
|
|
158
|
+
session.mcp_servers = mcp_servers
|
|
159
|
+
|
|
160
|
+
self._sessions[session.session_id] = session
|
|
161
|
+
self._session_store.save(session)
|
|
162
|
+
|
|
163
|
+
logger.info(f"Created session: {session.session_id}")
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
"sessionId": session.session_id,
|
|
167
|
+
"modes": self._get_available_modes(),
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async def load_session(
|
|
171
|
+
self,
|
|
172
|
+
cwd: str,
|
|
173
|
+
mcp_servers: List[Dict[str, Any]],
|
|
174
|
+
session_id: str,
|
|
175
|
+
**kwargs: Any,
|
|
176
|
+
) -> Optional[Dict[str, Any]]:
|
|
177
|
+
"""
|
|
178
|
+
Load an existing session.
|
|
179
|
+
|
|
180
|
+
Replays conversation history via session/update notifications.
|
|
181
|
+
"""
|
|
182
|
+
logger.info(f"Load session: session_id={session_id}")
|
|
183
|
+
|
|
184
|
+
# Try to load from store
|
|
185
|
+
session = self._session_store.load(session_id)
|
|
186
|
+
if session is None:
|
|
187
|
+
logger.warning(f"Session not found: {session_id}")
|
|
188
|
+
return None
|
|
189
|
+
|
|
190
|
+
# Update workspace and MCP servers
|
|
191
|
+
session.workspace = Path(cwd).resolve()
|
|
192
|
+
session.mcp_servers = mcp_servers
|
|
193
|
+
session.update_activity()
|
|
194
|
+
|
|
195
|
+
self._sessions[session_id] = session
|
|
196
|
+
|
|
197
|
+
# Replay conversation history
|
|
198
|
+
await self._replay_session_history(session)
|
|
199
|
+
|
|
200
|
+
return {}
|
|
201
|
+
|
|
202
|
+
async def list_sessions(
|
|
203
|
+
self,
|
|
204
|
+
cursor: Optional[str] = None,
|
|
205
|
+
cwd: Optional[str] = None,
|
|
206
|
+
**kwargs: Any,
|
|
207
|
+
) -> Dict[str, Any]:
|
|
208
|
+
"""List available sessions."""
|
|
209
|
+
sessions = self._session_store.list_sessions()
|
|
210
|
+
|
|
211
|
+
# Filter by cwd if provided
|
|
212
|
+
if cwd:
|
|
213
|
+
cwd_path = Path(cwd).resolve()
|
|
214
|
+
sessions = [s for s in sessions if s.workspace == cwd_path]
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
"sessions": [
|
|
218
|
+
{
|
|
219
|
+
"sessionId": s.session_id,
|
|
220
|
+
"createdAt": s.created_at,
|
|
221
|
+
"lastActivity": s.last_activity,
|
|
222
|
+
}
|
|
223
|
+
for s in sessions
|
|
224
|
+
],
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async def set_session_mode(
|
|
228
|
+
self,
|
|
229
|
+
mode_id: str,
|
|
230
|
+
session_id: str,
|
|
231
|
+
**kwargs: Any,
|
|
232
|
+
) -> Optional[Dict[str, Any]]:
|
|
233
|
+
"""Set the operating mode for a session."""
|
|
234
|
+
logger.info(f"Set session mode: session_id={session_id}, mode_id={mode_id}")
|
|
235
|
+
|
|
236
|
+
session = self._sessions.get(session_id)
|
|
237
|
+
if session:
|
|
238
|
+
session.mode = mode_id
|
|
239
|
+
self._session_store.save(session)
|
|
240
|
+
|
|
241
|
+
return {}
|
|
242
|
+
|
|
243
|
+
async def set_session_model(
|
|
244
|
+
self,
|
|
245
|
+
model_id: str,
|
|
246
|
+
session_id: str,
|
|
247
|
+
**kwargs: Any,
|
|
248
|
+
) -> Optional[Dict[str, Any]]:
|
|
249
|
+
"""Set the LLM model for a session."""
|
|
250
|
+
logger.info(f"Set session model: session_id={session_id}, model_id={model_id}")
|
|
251
|
+
|
|
252
|
+
session = self._sessions.get(session_id)
|
|
253
|
+
if session:
|
|
254
|
+
session.model = model_id
|
|
255
|
+
self._session_store.save(session)
|
|
256
|
+
|
|
257
|
+
return {}
|
|
258
|
+
|
|
259
|
+
async def prompt(
|
|
260
|
+
self,
|
|
261
|
+
prompt: List[Dict[str, Any]],
|
|
262
|
+
session_id: str,
|
|
263
|
+
**kwargs: Any,
|
|
264
|
+
) -> Dict[str, Any]:
|
|
265
|
+
"""
|
|
266
|
+
Handle user prompt.
|
|
267
|
+
|
|
268
|
+
This is the main interaction method where the user sends a message
|
|
269
|
+
and the agent processes it.
|
|
270
|
+
"""
|
|
271
|
+
logger.info(f"Prompt: session_id={session_id}")
|
|
272
|
+
|
|
273
|
+
session = self._sessions.get(session_id)
|
|
274
|
+
if session is None:
|
|
275
|
+
logger.error(f"Session not found: {session_id}")
|
|
276
|
+
return {"stopReason": "refusal"}
|
|
277
|
+
|
|
278
|
+
# Check if cancelled
|
|
279
|
+
if session_id in self._cancelled_sessions:
|
|
280
|
+
self._cancelled_sessions.discard(session_id)
|
|
281
|
+
return {"stopReason": "cancelled"}
|
|
282
|
+
|
|
283
|
+
# Extract text from prompt blocks
|
|
284
|
+
user_message = self._extract_prompt_text(prompt)
|
|
285
|
+
session.add_message("user", user_message)
|
|
286
|
+
|
|
287
|
+
try:
|
|
288
|
+
# Get agent response
|
|
289
|
+
agent = self._get_agent()
|
|
290
|
+
|
|
291
|
+
# Send thinking update
|
|
292
|
+
await self._send_thought(session_id, "Processing your request...")
|
|
293
|
+
|
|
294
|
+
# Generate response
|
|
295
|
+
response = await self._generate_response(agent, user_message, session)
|
|
296
|
+
|
|
297
|
+
# Send response as agent message chunks
|
|
298
|
+
await self._send_agent_message(session_id, response)
|
|
299
|
+
|
|
300
|
+
# Save session
|
|
301
|
+
session.add_message("assistant", response)
|
|
302
|
+
self._session_store.save(session)
|
|
303
|
+
|
|
304
|
+
return {"stopReason": "end_turn"}
|
|
305
|
+
|
|
306
|
+
except asyncio.CancelledError:
|
|
307
|
+
return {"stopReason": "cancelled"}
|
|
308
|
+
except Exception as e:
|
|
309
|
+
logger.exception(f"Error processing prompt: {e}")
|
|
310
|
+
await self._send_agent_message(session_id, f"Error: {str(e)}")
|
|
311
|
+
return {"stopReason": "refusal"}
|
|
312
|
+
|
|
313
|
+
async def fork_session(
|
|
314
|
+
self,
|
|
315
|
+
cwd: str,
|
|
316
|
+
session_id: str,
|
|
317
|
+
mcp_servers: Optional[List[Dict[str, Any]]] = None,
|
|
318
|
+
**kwargs: Any,
|
|
319
|
+
) -> Dict[str, Any]:
|
|
320
|
+
"""Fork an existing session."""
|
|
321
|
+
logger.info(f"Fork session: session_id={session_id}")
|
|
322
|
+
|
|
323
|
+
original = self._sessions.get(session_id)
|
|
324
|
+
if original is None:
|
|
325
|
+
original = self._session_store.load(session_id)
|
|
326
|
+
|
|
327
|
+
if original is None:
|
|
328
|
+
# Create new session if original not found
|
|
329
|
+
return await self.new_session(cwd, mcp_servers or [])
|
|
330
|
+
|
|
331
|
+
# Create forked session
|
|
332
|
+
forked = ACPSession.create(
|
|
333
|
+
workspace=Path(cwd).resolve(),
|
|
334
|
+
agent_id=original.agent_id,
|
|
335
|
+
)
|
|
336
|
+
forked.messages = original.messages.copy()
|
|
337
|
+
forked.mcp_servers = mcp_servers or original.mcp_servers
|
|
338
|
+
|
|
339
|
+
self._sessions[forked.session_id] = forked
|
|
340
|
+
self._session_store.save(forked)
|
|
341
|
+
|
|
342
|
+
return {"sessionId": forked.session_id}
|
|
343
|
+
|
|
344
|
+
async def resume_session(
|
|
345
|
+
self,
|
|
346
|
+
cwd: str,
|
|
347
|
+
session_id: str,
|
|
348
|
+
mcp_servers: Optional[List[Dict[str, Any]]] = None,
|
|
349
|
+
**kwargs: Any,
|
|
350
|
+
) -> Dict[str, Any]:
|
|
351
|
+
"""Resume an existing session."""
|
|
352
|
+
return await self.load_session(cwd, mcp_servers or [], session_id)
|
|
353
|
+
|
|
354
|
+
async def cancel(self, session_id: str, **kwargs: Any) -> None:
|
|
355
|
+
"""Cancel ongoing operations for a session."""
|
|
356
|
+
logger.info(f"Cancel: session_id={session_id}")
|
|
357
|
+
self._cancelled_sessions.add(session_id)
|
|
358
|
+
|
|
359
|
+
async def ext_method(self, method: str, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
360
|
+
"""Handle extension method calls."""
|
|
361
|
+
logger.info(f"Extension method: {method}")
|
|
362
|
+
return {"error": f"Unknown extension method: {method}"}
|
|
363
|
+
|
|
364
|
+
async def ext_notification(self, method: str, params: Dict[str, Any]) -> None:
|
|
365
|
+
"""Handle extension notifications."""
|
|
366
|
+
logger.info(f"Extension notification: {method}")
|
|
367
|
+
|
|
368
|
+
# Helper methods
|
|
369
|
+
|
|
370
|
+
def _get_version(self) -> str:
|
|
371
|
+
"""Get PraisonAI version."""
|
|
372
|
+
try:
|
|
373
|
+
from praisonai.version import __version__
|
|
374
|
+
return __version__
|
|
375
|
+
except ImportError:
|
|
376
|
+
return "0.0.0"
|
|
377
|
+
|
|
378
|
+
def _get_available_modes(self) -> Optional[List[Dict[str, Any]]]:
|
|
379
|
+
"""Get available operating modes."""
|
|
380
|
+
return [
|
|
381
|
+
{
|
|
382
|
+
"id": "manual",
|
|
383
|
+
"name": "Manual",
|
|
384
|
+
"description": "Requires approval for all actions",
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"id": "auto",
|
|
388
|
+
"name": "Auto",
|
|
389
|
+
"description": "Auto-approve within workspace",
|
|
390
|
+
},
|
|
391
|
+
]
|
|
392
|
+
|
|
393
|
+
def _extract_prompt_text(self, prompt: List[Dict[str, Any]]) -> str:
|
|
394
|
+
"""Extract text content from prompt blocks."""
|
|
395
|
+
texts = []
|
|
396
|
+
for block in prompt:
|
|
397
|
+
if isinstance(block, dict):
|
|
398
|
+
block_type = block.get("type", "")
|
|
399
|
+
if block_type == "text":
|
|
400
|
+
texts.append(block.get("text", ""))
|
|
401
|
+
elif block_type == "resource":
|
|
402
|
+
resource = block.get("resource", {})
|
|
403
|
+
if "text" in resource:
|
|
404
|
+
texts.append(f"[File: {resource.get('uri', 'unknown')}]\n{resource['text']}")
|
|
405
|
+
return "\n".join(texts)
|
|
406
|
+
|
|
407
|
+
async def _generate_response(
|
|
408
|
+
self,
|
|
409
|
+
agent: Any,
|
|
410
|
+
message: str,
|
|
411
|
+
session: ACPSession,
|
|
412
|
+
) -> str:
|
|
413
|
+
"""Generate agent response."""
|
|
414
|
+
try:
|
|
415
|
+
# Try async chat first
|
|
416
|
+
if hasattr(agent, "achat"):
|
|
417
|
+
response = await agent.achat(message)
|
|
418
|
+
elif hasattr(agent, "chat"):
|
|
419
|
+
# Run sync chat in executor
|
|
420
|
+
loop = asyncio.get_event_loop()
|
|
421
|
+
response = await loop.run_in_executor(None, agent.chat, message)
|
|
422
|
+
else:
|
|
423
|
+
response = "Agent does not support chat interface"
|
|
424
|
+
|
|
425
|
+
return str(response) if response else ""
|
|
426
|
+
except Exception as e:
|
|
427
|
+
logger.exception(f"Error generating response: {e}")
|
|
428
|
+
return f"Error generating response: {str(e)}"
|
|
429
|
+
|
|
430
|
+
async def _send_agent_message(self, session_id: str, text: str) -> None:
|
|
431
|
+
"""Send agent message chunk to client."""
|
|
432
|
+
if self._client is None:
|
|
433
|
+
return
|
|
434
|
+
|
|
435
|
+
try:
|
|
436
|
+
from acp import update_agent_message_text
|
|
437
|
+
update = update_agent_message_text(text)
|
|
438
|
+
await self._client.session_update(session_id=session_id, update=update)
|
|
439
|
+
except ImportError:
|
|
440
|
+
# Fallback without ACP SDK
|
|
441
|
+
logger.debug(f"Agent message: {text[:100]}...")
|
|
442
|
+
|
|
443
|
+
async def _send_thought(self, session_id: str, text: str) -> None:
|
|
444
|
+
"""Send agent thought to client."""
|
|
445
|
+
if self._client is None:
|
|
446
|
+
return
|
|
447
|
+
|
|
448
|
+
try:
|
|
449
|
+
from acp import update_agent_thought_text
|
|
450
|
+
update = update_agent_thought_text(text)
|
|
451
|
+
await self._client.session_update(session_id=session_id, update=update)
|
|
452
|
+
except ImportError:
|
|
453
|
+
logger.debug(f"Agent thought: {text}")
|
|
454
|
+
|
|
455
|
+
async def _replay_session_history(self, session: ACPSession) -> None:
|
|
456
|
+
"""Replay session history to client."""
|
|
457
|
+
if self._client is None:
|
|
458
|
+
return
|
|
459
|
+
|
|
460
|
+
try:
|
|
461
|
+
from acp import update_user_message_text, update_agent_message_text
|
|
462
|
+
|
|
463
|
+
for msg in session.messages:
|
|
464
|
+
role = msg.get("role", "")
|
|
465
|
+
content = msg.get("content", "")
|
|
466
|
+
|
|
467
|
+
if role == "user":
|
|
468
|
+
update = update_user_message_text(str(content))
|
|
469
|
+
elif role == "assistant":
|
|
470
|
+
update = update_agent_message_text(str(content))
|
|
471
|
+
else:
|
|
472
|
+
continue
|
|
473
|
+
|
|
474
|
+
await self._client.session_update(
|
|
475
|
+
session_id=session.session_id,
|
|
476
|
+
update=update,
|
|
477
|
+
)
|
|
478
|
+
except ImportError:
|
|
479
|
+
logger.debug("Skipping history replay (ACP SDK not available)")
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
async def _run_server(config: ACPConfig) -> None:
|
|
483
|
+
"""Run the ACP server."""
|
|
484
|
+
try:
|
|
485
|
+
from acp import Agent as ACPAgent, run_agent
|
|
486
|
+
except ImportError:
|
|
487
|
+
logger.error(
|
|
488
|
+
"agent-client-protocol package not installed.\n"
|
|
489
|
+
"Install with: pip install praisonai[acp]\n"
|
|
490
|
+
"Or: pip install agent-client-protocol"
|
|
491
|
+
)
|
|
492
|
+
sys.exit(1)
|
|
493
|
+
|
|
494
|
+
server = ACPServer(config=config)
|
|
495
|
+
|
|
496
|
+
# Create ACP-compatible agent wrapper
|
|
497
|
+
class PraisonACPAgent(ACPAgent):
|
|
498
|
+
def on_connect(self, conn):
|
|
499
|
+
server.on_connect(conn)
|
|
500
|
+
|
|
501
|
+
async def initialize(self, protocol_version, client_capabilities=None, client_info=None, **kwargs):
|
|
502
|
+
return await server.initialize(protocol_version, client_capabilities, client_info, **kwargs)
|
|
503
|
+
|
|
504
|
+
async def authenticate(self, method_id, **kwargs):
|
|
505
|
+
return await server.authenticate(method_id, **kwargs)
|
|
506
|
+
|
|
507
|
+
async def new_session(self, cwd, mcp_servers, **kwargs):
|
|
508
|
+
return await server.new_session(cwd, mcp_servers, **kwargs)
|
|
509
|
+
|
|
510
|
+
async def load_session(self, cwd, mcp_servers, session_id, **kwargs):
|
|
511
|
+
return await server.load_session(cwd, mcp_servers, session_id, **kwargs)
|
|
512
|
+
|
|
513
|
+
async def list_sessions(self, cursor=None, cwd=None, **kwargs):
|
|
514
|
+
return await server.list_sessions(cursor, cwd, **kwargs)
|
|
515
|
+
|
|
516
|
+
async def set_session_mode(self, mode_id, session_id, **kwargs):
|
|
517
|
+
return await server.set_session_mode(mode_id, session_id, **kwargs)
|
|
518
|
+
|
|
519
|
+
async def set_session_model(self, model_id, session_id, **kwargs):
|
|
520
|
+
return await server.set_session_model(model_id, session_id, **kwargs)
|
|
521
|
+
|
|
522
|
+
async def prompt(self, prompt, session_id, **kwargs):
|
|
523
|
+
return await server.prompt(prompt, session_id, **kwargs)
|
|
524
|
+
|
|
525
|
+
async def fork_session(self, cwd, session_id, mcp_servers=None, **kwargs):
|
|
526
|
+
return await server.fork_session(cwd, session_id, mcp_servers, **kwargs)
|
|
527
|
+
|
|
528
|
+
async def resume_session(self, cwd, session_id, mcp_servers=None, **kwargs):
|
|
529
|
+
return await server.resume_session(cwd, session_id, mcp_servers, **kwargs)
|
|
530
|
+
|
|
531
|
+
async def cancel(self, session_id, **kwargs):
|
|
532
|
+
return await server.cancel(session_id, **kwargs)
|
|
533
|
+
|
|
534
|
+
async def ext_method(self, method, params):
|
|
535
|
+
return await server.ext_method(method, params)
|
|
536
|
+
|
|
537
|
+
async def ext_notification(self, method, params):
|
|
538
|
+
return await server.ext_notification(method, params)
|
|
539
|
+
|
|
540
|
+
logger.info("Starting PraisonAI ACP server...")
|
|
541
|
+
await run_agent(PraisonACPAgent(), use_unstable_protocol=True)
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
def serve(
|
|
545
|
+
workspace: Union[str, Path] = ".",
|
|
546
|
+
agent: str = "default",
|
|
547
|
+
model: Optional[str] = None,
|
|
548
|
+
resume: Optional[str] = None,
|
|
549
|
+
resume_last: bool = False,
|
|
550
|
+
debug: bool = False,
|
|
551
|
+
read_only: bool = True,
|
|
552
|
+
allow_write: bool = False,
|
|
553
|
+
allow_shell: bool = False,
|
|
554
|
+
approval_mode: str = "manual",
|
|
555
|
+
**kwargs: Any,
|
|
556
|
+
) -> None:
|
|
557
|
+
"""
|
|
558
|
+
Start the ACP server.
|
|
559
|
+
|
|
560
|
+
This is the main entry point for running PraisonAI as an ACP agent.
|
|
561
|
+
|
|
562
|
+
Args:
|
|
563
|
+
workspace: Working directory for the session
|
|
564
|
+
agent: Agent name or configuration
|
|
565
|
+
model: LLM model to use
|
|
566
|
+
resume: Session ID to resume
|
|
567
|
+
resume_last: Resume the last session
|
|
568
|
+
debug: Enable debug logging
|
|
569
|
+
read_only: Read-only mode (default True)
|
|
570
|
+
allow_write: Allow file writes
|
|
571
|
+
allow_shell: Allow shell commands
|
|
572
|
+
approval_mode: Approval mode (manual, auto, scoped)
|
|
573
|
+
"""
|
|
574
|
+
config = ACPConfig(
|
|
575
|
+
workspace=Path(workspace).resolve(),
|
|
576
|
+
agent=agent,
|
|
577
|
+
model=model,
|
|
578
|
+
resume_session=resume,
|
|
579
|
+
resume_last=resume_last,
|
|
580
|
+
debug=debug,
|
|
581
|
+
read_only=read_only,
|
|
582
|
+
allow_write=allow_write,
|
|
583
|
+
allow_shell=allow_shell,
|
|
584
|
+
approval_mode=approval_mode,
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
asyncio.run(_run_server(config))
|