pygeai 0.1.51b3__py3-none-any.whl → 0.6.0b15__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.
Potentially problematic release.
This version of pygeai might be problematic. Click here for more details.
- pygeai/__init__.py +9 -1
- pygeai/_docs/Makefile +20 -0
- pygeai/_docs/make.bat +35 -0
- pygeai/_docs/source/conf.py +117 -0
- pygeai/_docs/source/content/ai_lab/cli.rst +747 -0
- pygeai/_docs/source/content/ai_lab/models.rst +1734 -0
- pygeai/_docs/source/content/ai_lab/runner.rst +253 -0
- pygeai/_docs/source/content/ai_lab/spec.rst +431 -0
- pygeai/_docs/source/content/ai_lab/usage.rst +1011 -0
- pygeai/_docs/source/content/ai_lab.rst +102 -0
- pygeai/_docs/source/content/analytics.rst +598 -0
- pygeai/_docs/source/content/api_reference/admin.rst +161 -0
- pygeai/_docs/source/content/api_reference/assistant.rst +326 -0
- pygeai/_docs/source/content/api_reference/auth.rst +379 -0
- pygeai/_docs/source/content/api_reference/chat.rst +754 -0
- pygeai/_docs/source/content/api_reference/embeddings.rst +154 -0
- pygeai/_docs/source/content/api_reference/evaluation.rst +590 -0
- pygeai/_docs/source/content/api_reference/feedback.rst +237 -0
- pygeai/_docs/source/content/api_reference/files.rst +592 -0
- pygeai/_docs/source/content/api_reference/gam.rst +401 -0
- pygeai/_docs/source/content/api_reference/health.rst +58 -0
- pygeai/_docs/source/content/api_reference/project.rst +738 -0
- pygeai/_docs/source/content/api_reference/proxy.rst +318 -0
- pygeai/_docs/source/content/api_reference/rag.rst +710 -0
- pygeai/_docs/source/content/api_reference/rerank.rst +94 -0
- pygeai/_docs/source/content/api_reference/secrets.rst +495 -0
- pygeai/_docs/source/content/api_reference/usage_limits.rst +390 -0
- pygeai/_docs/source/content/api_reference.rst +58 -0
- pygeai/_docs/source/content/authentication.rst +295 -0
- pygeai/_docs/source/content/chat_gui.rst +121 -0
- pygeai/_docs/source/content/cli.rst +203 -0
- pygeai/_docs/source/content/debugger.rst +651 -0
- pygeai/_docs/source/content/intro.rst +67 -0
- pygeai/_docs/source/content/migration.rst +929 -0
- pygeai/_docs/source/content/modules.rst +7 -0
- pygeai/_docs/source/content/quickstart.rst +143 -0
- pygeai/_docs/source/content/samples.rst +394 -0
- pygeai/_docs/source/index.rst +75 -0
- pygeai/_docs/source/modules.rst +7 -0
- pygeai/_docs/source/pygeai.admin.rst +29 -0
- pygeai/_docs/source/pygeai.analytics.rst +53 -0
- pygeai/_docs/source/pygeai.assistant.data.rst +21 -0
- pygeai/_docs/source/pygeai.assistant.data_analyst.rst +29 -0
- pygeai/_docs/source/pygeai.assistant.rag.rst +53 -0
- pygeai/_docs/source/pygeai.assistant.rst +55 -0
- pygeai/_docs/source/pygeai.auth.rst +29 -0
- pygeai/_docs/source/pygeai.chat.rst +69 -0
- pygeai/_docs/source/pygeai.cli.commands.flows.rst +10 -0
- pygeai/_docs/source/pygeai.cli.commands.lab.rst +53 -0
- pygeai/_docs/source/pygeai.cli.commands.rst +222 -0
- pygeai/_docs/source/pygeai.cli.rst +62 -0
- pygeai/_docs/source/pygeai.cli.texts.rst +21 -0
- pygeai/_docs/source/pygeai.core.base.rst +53 -0
- pygeai/_docs/source/pygeai.core.common.rst +37 -0
- pygeai/_docs/source/pygeai.core.embeddings.rst +61 -0
- pygeai/_docs/source/pygeai.core.feedback.rst +37 -0
- pygeai/_docs/source/pygeai.core.files.rst +61 -0
- pygeai/_docs/source/pygeai.core.llm.rst +29 -0
- pygeai/_docs/source/pygeai.core.plugins.rst +37 -0
- pygeai/_docs/source/pygeai.core.rerank.rst +53 -0
- pygeai/_docs/source/pygeai.core.rst +63 -0
- pygeai/_docs/source/pygeai.core.secrets.rst +29 -0
- pygeai/_docs/source/pygeai.core.services.llm.rst +29 -0
- pygeai/_docs/source/pygeai.core.services.rst +37 -0
- pygeai/_docs/source/pygeai.core.utils.rst +37 -0
- pygeai/_docs/source/pygeai.dbg.rst +21 -0
- pygeai/_docs/source/pygeai.evaluation.dataset.rst +29 -0
- pygeai/_docs/source/pygeai.evaluation.plan.rst +29 -0
- pygeai/_docs/source/pygeai.evaluation.result.rst +29 -0
- pygeai/_docs/source/pygeai.evaluation.rst +31 -0
- pygeai/_docs/source/pygeai.flows.rst +29 -0
- pygeai/_docs/source/pygeai.gam.rst +29 -0
- pygeai/_docs/source/pygeai.health.rst +29 -0
- pygeai/_docs/source/pygeai.lab.agents.rst +37 -0
- pygeai/_docs/source/pygeai.lab.processes.rst +37 -0
- pygeai/_docs/source/pygeai.lab.rst +65 -0
- pygeai/_docs/source/pygeai.lab.spec.rst +29 -0
- pygeai/_docs/source/pygeai.lab.strategies.rst +37 -0
- pygeai/_docs/source/pygeai.lab.tools.rst +37 -0
- pygeai/_docs/source/pygeai.man.man1.rst +10 -0
- pygeai/_docs/source/pygeai.man.rst +18 -0
- pygeai/_docs/source/pygeai.migration.rst +29 -0
- pygeai/_docs/source/pygeai.organization.limits.rst +45 -0
- pygeai/_docs/source/pygeai.organization.rst +61 -0
- pygeai/_docs/source/pygeai.proxy.rst +53 -0
- pygeai/_docs/source/pygeai.rst +35 -0
- pygeai/_docs/source/pygeai.tests.admin.rst +21 -0
- pygeai/_docs/source/pygeai.tests.analytics.rst +45 -0
- pygeai/_docs/source/pygeai.tests.assistants.rag.rst +37 -0
- pygeai/_docs/source/pygeai.tests.assistants.rst +45 -0
- pygeai/_docs/source/pygeai.tests.auth.rst +29 -0
- pygeai/_docs/source/pygeai.tests.chat.rst +45 -0
- pygeai/_docs/source/pygeai.tests.cli.commands.lab.rst +37 -0
- pygeai/_docs/source/pygeai.tests.cli.commands.rst +165 -0
- pygeai/_docs/source/pygeai.tests.cli.docker.rst +10 -0
- pygeai/_docs/source/pygeai.tests.cli.rst +46 -0
- pygeai/_docs/source/pygeai.tests.core.base.data.rst +29 -0
- pygeai/_docs/source/pygeai.tests.core.base.rst +45 -0
- pygeai/_docs/source/pygeai.tests.core.common.data.rst +10 -0
- pygeai/_docs/source/pygeai.tests.core.common.rst +37 -0
- pygeai/_docs/source/pygeai.tests.core.embeddings.rst +37 -0
- pygeai/_docs/source/pygeai.tests.core.feedback.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.files.rst +53 -0
- pygeai/_docs/source/pygeai.tests.core.llm.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.plugins.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.rerank.rst +37 -0
- pygeai/_docs/source/pygeai.tests.core.rst +39 -0
- pygeai/_docs/source/pygeai.tests.core.secrets.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.services.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.utils.rst +21 -0
- pygeai/_docs/source/pygeai.tests.dbg.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.dataset.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.plan.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.result.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.rst +20 -0
- pygeai/_docs/source/pygeai.tests.gam.rst +21 -0
- pygeai/_docs/source/pygeai.tests.health.rst +21 -0
- pygeai/_docs/source/pygeai.tests.integration.assistants.rag.rst +21 -0
- pygeai/_docs/source/pygeai.tests.integration.assistants.rst +18 -0
- pygeai/_docs/source/pygeai.tests.integration.chat.rst +21 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.agents.rst +69 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.processes.rst +77 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.reasoning_strategies.rst +37 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.rst +21 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.tools.rst +77 -0
- pygeai/_docs/source/pygeai.tests.integration.rst +20 -0
- pygeai/_docs/source/pygeai.tests.lab.agents.rst +29 -0
- pygeai/_docs/source/pygeai.tests.lab.processes.rst +29 -0
- pygeai/_docs/source/pygeai.tests.lab.rst +49 -0
- pygeai/_docs/source/pygeai.tests.lab.spec.rst +29 -0
- pygeai/_docs/source/pygeai.tests.lab.strategies.rst +29 -0
- pygeai/_docs/source/pygeai.tests.lab.tools.rst +29 -0
- pygeai/_docs/source/pygeai.tests.migration.rst +29 -0
- pygeai/_docs/source/pygeai.tests.organization.limits.rst +29 -0
- pygeai/_docs/source/pygeai.tests.organization.rst +53 -0
- pygeai/_docs/source/pygeai.tests.proxy.rst +61 -0
- pygeai/_docs/source/pygeai.tests.rst +33 -0
- pygeai/admin/clients.py +14 -11
- pygeai/admin/endpoints.py +2 -2
- pygeai/analytics/clients.py +505 -0
- pygeai/analytics/endpoints.py +35 -0
- pygeai/analytics/managers.py +606 -0
- pygeai/analytics/mappers.py +207 -0
- pygeai/analytics/responses.py +240 -0
- pygeai/assistant/clients.py +18 -45
- pygeai/assistant/data/clients.py +1 -0
- pygeai/assistant/data_analyst/clients.py +8 -12
- pygeai/assistant/managers.py +195 -157
- pygeai/assistant/mappers.py +4 -2
- pygeai/assistant/rag/clients.py +27 -67
- pygeai/assistant/rag/mappers.py +12 -6
- pygeai/assistant/rag/models.py +301 -159
- pygeai/auth/__init__.py +0 -0
- pygeai/auth/clients.py +129 -0
- pygeai/auth/endpoints.py +6 -0
- pygeai/chat/clients.py +308 -37
- pygeai/chat/endpoints.py +3 -0
- pygeai/chat/iris.py +2 -8
- pygeai/chat/managers.py +9 -6
- pygeai/chat/session.py +38 -0
- pygeai/chat/settings.py +6 -0
- pygeai/chat/ui.py +678 -0
- pygeai/cli/__init__.py +0 -1
- pygeai/cli/commands/admin.py +7 -10
- pygeai/cli/commands/analytics.py +533 -0
- pygeai/cli/commands/assistant.py +9 -9
- pygeai/cli/commands/auth.py +299 -0
- pygeai/cli/commands/base.py +71 -9
- pygeai/cli/commands/chat.py +676 -19
- pygeai/cli/commands/common.py +28 -24
- pygeai/cli/commands/configuration.py +66 -13
- pygeai/cli/commands/docs.py +105 -0
- pygeai/cli/commands/embeddings.py +58 -11
- pygeai/cli/commands/evaluation.py +38 -38
- pygeai/cli/commands/feedback.py +3 -4
- pygeai/cli/commands/files.py +7 -8
- pygeai/cli/commands/gam.py +85 -10
- pygeai/cli/commands/lab/ai_lab.py +340 -484
- pygeai/cli/commands/lab/options.py +8 -0
- pygeai/cli/commands/lab/spec.py +273 -0
- pygeai/cli/commands/lab/utils.py +13 -0
- pygeai/cli/commands/llm.py +6 -7
- pygeai/cli/commands/migrate.py +1064 -436
- pygeai/cli/commands/organization.py +516 -11
- pygeai/cli/commands/rag.py +13 -14
- pygeai/cli/commands/rerank.py +3 -5
- pygeai/cli/commands/secrets.py +8 -9
- pygeai/cli/commands/usage_limits.py +18 -20
- pygeai/cli/commands/validators.py +144 -1
- pygeai/cli/commands/version.py +4 -5
- pygeai/cli/error_handler.py +151 -0
- pygeai/cli/geai.py +170 -31
- pygeai/cli/geai_proxy.py +86 -25
- pygeai/cli/install_man.py +93 -22
- pygeai/cli/parsers.py +75 -25
- pygeai/cli/texts/help.py +265 -28
- pygeai/core/base/clients.py +53 -12
- pygeai/core/base/mappers.py +11 -2
- pygeai/core/base/session.py +95 -11
- pygeai/core/common/config.py +78 -14
- pygeai/core/common/exceptions.py +96 -6
- pygeai/core/embeddings/__init__.py +19 -0
- pygeai/core/embeddings/clients.py +23 -5
- pygeai/core/embeddings/managers.py +9 -4
- pygeai/core/embeddings/mappers.py +16 -2
- pygeai/core/embeddings/responses.py +9 -2
- pygeai/core/feedback/clients.py +8 -3
- pygeai/core/files/clients.py +23 -24
- pygeai/core/files/managers.py +121 -30
- pygeai/core/files/responses.py +4 -3
- pygeai/core/handlers.py +10 -1
- pygeai/core/llm/clients.py +22 -29
- pygeai/core/models.py +127 -11
- pygeai/core/plugins/clients.py +6 -6
- pygeai/core/rerank/clients.py +9 -3
- pygeai/core/rerank/managers.py +22 -5
- pygeai/core/secrets/clients.py +16 -37
- pygeai/core/services/response.py +18 -0
- pygeai/core/services/rest.py +159 -49
- pygeai/core/utils/__init__.py +0 -0
- pygeai/core/utils/console.py +83 -0
- pygeai/core/utils/parsers.py +32 -0
- pygeai/core/utils/validators.py +10 -0
- pygeai/dbg/__init__.py +3 -0
- pygeai/dbg/debugger.py +854 -14
- pygeai/evaluation/clients.py +7 -4
- pygeai/evaluation/dataset/clients.py +46 -44
- pygeai/evaluation/plan/clients.py +28 -26
- pygeai/evaluation/result/clients.py +38 -5
- pygeai/gam/clients.py +50 -28
- pygeai/gam/endpoints.py +2 -1
- pygeai/health/__init__.py +0 -0
- pygeai/health/clients.py +24 -0
- pygeai/health/endpoints.py +1 -0
- pygeai/lab/__init__.py +0 -90
- pygeai/lab/agents/clients.py +203 -162
- pygeai/lab/agents/endpoints.py +4 -0
- pygeai/lab/agents/mappers.py +57 -7
- pygeai/lab/clients.py +24 -0
- pygeai/lab/constants.py +3 -0
- pygeai/lab/managers.py +571 -541
- pygeai/lab/models.py +108 -19
- pygeai/lab/processes/clients.py +332 -340
- pygeai/lab/processes/mappers.py +3 -3
- pygeai/lab/runners.py +90 -0
- pygeai/lab/spec/__init__.py +0 -0
- pygeai/lab/spec/loader.py +24 -0
- pygeai/lab/spec/parsers.py +39 -0
- pygeai/lab/strategies/clients.py +67 -63
- pygeai/lab/strategies/mappers.py +1 -1
- pygeai/lab/tools/clients.py +85 -118
- pygeai/lab/tools/endpoints.py +4 -0
- pygeai/lab/tools/mappers.py +5 -5
- pygeai/man/man1/geai-proxy.1 +116 -0
- pygeai/man/man1/geai.1 +2580 -66
- pygeai/migration/__init__.py +33 -0
- pygeai/migration/strategies.py +468 -146
- pygeai/migration/tools.py +170 -3
- pygeai/organization/clients.py +245 -50
- pygeai/organization/endpoints.py +17 -8
- pygeai/organization/limits/clients.py +34 -32
- pygeai/organization/limits/managers.py +108 -49
- pygeai/organization/managers.py +347 -53
- pygeai/organization/mappers.py +102 -2
- pygeai/organization/responses.py +58 -1
- pygeai/proxy/clients.py +6 -3
- pygeai/proxy/config.py +14 -1
- pygeai/proxy/managers.py +61 -33
- pygeai/proxy/servers.py +196 -51
- pygeai/proxy/tool.py +33 -16
- pygeai/tests/admin/__init__.py +0 -0
- pygeai/tests/admin/test_clients.py +148 -0
- pygeai/tests/analytics/__init__.py +0 -0
- pygeai/tests/analytics/test_clients.py +86 -0
- pygeai/tests/analytics/test_managers.py +94 -0
- pygeai/tests/analytics/test_mappers.py +84 -0
- pygeai/tests/analytics/test_responses.py +73 -0
- pygeai/tests/assistants/rag/test_clients.py +346 -0
- pygeai/tests/assistants/rag/test_models.py +292 -0
- pygeai/tests/assistants/test_clients.py +176 -82
- pygeai/tests/assistants/test_managers.py +191 -57
- pygeai/tests/auth/__init__.py +0 -0
- pygeai/tests/auth/test_clients.py +289 -0
- pygeai/tests/auth/test_oauth.py +172 -0
- pygeai/tests/auth/test_session_logging.py +150 -0
- pygeai/tests/chat/__init__.py +0 -0
- pygeai/tests/chat/test_clients.py +393 -0
- pygeai/tests/chat/test_iris.py +38 -0
- pygeai/tests/chat/test_session.py +62 -0
- pygeai/tests/chat/test_ui.py +224 -0
- pygeai/tests/cli/commands/__init__.py +0 -0
- pygeai/tests/cli/commands/lab/__init__.py +0 -0
- pygeai/tests/cli/commands/lab/test_ai_lab.py +786 -0
- pygeai/tests/cli/commands/lab/test_common.py +208 -0
- pygeai/tests/cli/commands/lab/test_spec.py +246 -0
- pygeai/tests/cli/commands/test_assistant.py +202 -0
- pygeai/tests/cli/commands/test_chat.py +130 -0
- pygeai/tests/cli/commands/test_common.py +350 -0
- pygeai/tests/cli/commands/test_embeddings.py +132 -0
- pygeai/tests/cli/commands/test_evaluation.py +656 -0
- pygeai/tests/cli/commands/test_feedback.py +65 -0
- pygeai/tests/cli/commands/test_files.py +161 -0
- pygeai/tests/cli/commands/test_gam.py +201 -0
- pygeai/tests/cli/commands/test_llm.py +114 -0
- pygeai/tests/cli/commands/test_migrate.py +176 -0
- pygeai/tests/cli/commands/test_organization.py +276 -0
- pygeai/tests/cli/commands/test_rag.py +266 -0
- pygeai/tests/cli/commands/test_rerank.py +110 -0
- pygeai/tests/cli/commands/test_secrets.py +171 -0
- pygeai/tests/cli/commands/test_show_help.py +41 -0
- pygeai/tests/cli/commands/test_usage_limits.py +412 -0
- pygeai/tests/cli/commands/test_validators.py +160 -0
- pygeai/tests/cli/commands/test_version.py +81 -0
- pygeai/tests/cli/docker/__init__.py +0 -0
- pygeai/tests/cli/test_credentials_flag.py +316 -0
- pygeai/tests/cli/test_error_handler.py +225 -0
- pygeai/tests/cli/test_geai_driver.py +154 -0
- pygeai/tests/cli/test_parsers.py +5 -5
- pygeai/tests/core/base/data/models.py +7 -0
- pygeai/tests/core/base/test_mappers.py +43 -11
- pygeai/tests/core/base/test_models.py +3 -1
- pygeai/tests/core/base/test_responses.py +53 -0
- pygeai/tests/core/common/__init__.py +0 -0
- pygeai/tests/core/common/data/__init__.py +0 -0
- pygeai/tests/core/common/test_config.py +186 -0
- pygeai/tests/core/common/test_decorators.py +69 -0
- pygeai/tests/core/embeddings/__init__.py +0 -0
- pygeai/tests/core/embeddings/test_clients.py +225 -0
- pygeai/tests/core/embeddings/test_managers.py +171 -0
- pygeai/tests/core/embeddings/test_mappers.py +142 -0
- pygeai/tests/core/feedback/__init__.py +0 -0
- pygeai/tests/core/feedback/test_clients.py +64 -0
- pygeai/tests/core/files/test_clients.py +128 -0
- pygeai/tests/core/files/test_managers.py +124 -78
- pygeai/tests/core/files/test_mappers.py +137 -0
- pygeai/tests/core/files/test_models.py +103 -0
- pygeai/tests/core/files/test_responses.py +122 -0
- pygeai/tests/core/llm/__init__.py +0 -0
- pygeai/tests/core/llm/test_clients.py +142 -0
- pygeai/tests/core/plugins/__init__.py +0 -0
- pygeai/tests/core/plugins/test_clients.py +66 -0
- pygeai/tests/core/rerank/test_clients.py +76 -0
- pygeai/tests/core/rerank/test_managers.py +61 -39
- pygeai/tests/core/secrets/__init__.py +0 -0
- pygeai/tests/core/secrets/test_clients.py +264 -0
- pygeai/tests/core/services/__init__.py +0 -0
- pygeai/tests/core/services/test_rest.py +273 -0
- pygeai/tests/core/test_handlers.py +66 -0
- pygeai/tests/core/utils/__init__.py +0 -0
- pygeai/tests/core/utils/test_console.py +80 -0
- pygeai/tests/dbg/__init__.py +0 -0
- pygeai/tests/dbg/test_debugger.py +591 -0
- pygeai/tests/evaluation/__init__.py +0 -0
- pygeai/tests/evaluation/dataset/__init__.py +0 -0
- pygeai/tests/evaluation/dataset/test_clients.py +265 -0
- pygeai/tests/evaluation/plan/__init__.py +0 -0
- pygeai/tests/evaluation/plan/test_clients.py +195 -0
- pygeai/tests/evaluation/result/__init__.py +0 -0
- pygeai/tests/evaluation/result/test_clients.py +66 -0
- pygeai/tests/gam/__init__.py +0 -0
- pygeai/tests/gam/test_clients.py +195 -0
- pygeai/tests/health/__init__.py +0 -0
- pygeai/tests/health/test_clients.py +41 -0
- pygeai/tests/integration/__init__.py +0 -0
- pygeai/tests/integration/assistants/__init__.py +0 -0
- pygeai/tests/integration/assistants/rag/__init__.py +0 -0
- pygeai/tests/integration/assistants/rag/test_create_rag.py +91 -0
- pygeai/tests/integration/chat/__init__.py +0 -0
- pygeai/tests/integration/chat/test_generate_image.py +158 -0
- pygeai/tests/integration/lab/__init__.py +0 -0
- pygeai/tests/integration/lab/agents/__init__.py +0 -0
- pygeai/tests/integration/lab/agents/test_agents_list.py +106 -0
- pygeai/tests/integration/lab/agents/test_create_agent.py +319 -0
- pygeai/tests/integration/lab/agents/test_create_sharing_link.py +70 -0
- pygeai/tests/integration/lab/agents/test_delete_agent.py +75 -0
- pygeai/tests/integration/lab/agents/test_get_agent.py +94 -0
- pygeai/tests/integration/lab/agents/test_publish_agent_revision.py +127 -0
- pygeai/tests/integration/lab/agents/test_update_agent.py +250 -0
- pygeai/tests/integration/lab/processes/__init__.py +0 -0
- pygeai/tests/integration/lab/processes/test_create_process.py +345 -0
- pygeai/tests/integration/lab/processes/test_create_task.py +211 -0
- pygeai/tests/integration/lab/processes/test_delete_process.py +111 -0
- pygeai/tests/integration/lab/processes/test_get_process.py +201 -0
- pygeai/tests/integration/lab/processes/test_list_process_instances.py +91 -0
- pygeai/tests/integration/lab/processes/test_list_processes.py +138 -0
- pygeai/tests/integration/lab/processes/test_publish_process_revision.py +232 -0
- pygeai/tests/integration/lab/processes/test_update_process.py +289 -0
- pygeai/tests/integration/lab/reasoning_strategies/__init__.py +0 -0
- pygeai/tests/integration/lab/reasoning_strategies/test_get_reasoning_strategy.py +70 -0
- pygeai/tests/integration/lab/reasoning_strategies/test_list_reasoning_strategies.py +93 -0
- pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +149 -0
- pygeai/tests/integration/lab/tools/__init__.py +0 -0
- pygeai/tests/integration/lab/tools/test_create_tool.py +288 -0
- pygeai/tests/integration/lab/tools/test_delete_tool.py +87 -0
- pygeai/tests/integration/lab/tools/test_get_parameter.py +98 -0
- pygeai/tests/integration/lab/tools/test_get_tool.py +91 -0
- pygeai/tests/integration/lab/tools/test_list_tools.py +106 -0
- pygeai/tests/integration/lab/tools/test_publish_tool_revision.py +119 -0
- pygeai/tests/integration/lab/tools/test_set_parameter.py +114 -0
- pygeai/tests/integration/lab/tools/test_update_tool.py +267 -0
- pygeai/tests/lab/agents/__init__.py +0 -0
- pygeai/tests/lab/agents/test_clients.py +481 -0
- pygeai/tests/lab/agents/test_mappers.py +440 -0
- pygeai/tests/lab/processes/__init__.py +0 -0
- pygeai/tests/lab/processes/test_clients.py +1416 -0
- pygeai/tests/lab/processes/test_mappers.py +1092 -0
- pygeai/tests/lab/spec/__init__.py +0 -0
- pygeai/tests/lab/spec/test_loader.py +59 -0
- pygeai/tests/lab/spec/test_parsers.py +182 -0
- pygeai/tests/lab/strategies/__init__.py +0 -0
- pygeai/tests/lab/strategies/test_clients.py +241 -0
- pygeai/tests/lab/strategies/test_mappers.py +132 -0
- pygeai/tests/lab/test_managers.py +553 -0
- pygeai/tests/lab/test_models.py +500 -3
- pygeai/tests/lab/tools/__init__.py +0 -0
- pygeai/tests/lab/tools/test_clients.py +521 -0
- pygeai/tests/lab/tools/test_mappers.py +198 -0
- pygeai/tests/migration/__init__.py +0 -0
- pygeai/tests/migration/test_strategies.py +405 -0
- pygeai/tests/migration/test_tools.py +159 -0
- pygeai/tests/organization/limits/test_clients.py +567 -0
- pygeai/tests/organization/limits/test_managers.py +298 -56
- pygeai/tests/organization/test_clients.py +600 -30
- pygeai/tests/organization/test_managers.py +424 -0
- pygeai/tests/organization/test_mappers.py +153 -0
- pygeai/tests/organization/test_responses.py +137 -0
- pygeai/tests/proxy/__init__.py +1 -0
- pygeai/tests/proxy/test_clients.py +397 -0
- pygeai/tests/proxy/test_config.py +171 -0
- pygeai/tests/proxy/test_integration.py +305 -0
- pygeai/tests/proxy/test_managers.py +312 -0
- pygeai/tests/proxy/test_servers.py +387 -0
- pygeai/tests/proxy/test_tool.py +176 -0
- pygeai/tests/snippets/analytics/__init__.py +0 -0
- pygeai/tests/snippets/analytics/get_agent_usage_per_user.py +16 -0
- pygeai/tests/snippets/analytics/get_agents_created_and_modified.py +11 -0
- pygeai/tests/snippets/analytics/get_average_cost_per_request.py +10 -0
- pygeai/tests/snippets/analytics/get_overall_error_rate.py +10 -0
- pygeai/tests/snippets/analytics/get_top_10_agents_by_requests.py +12 -0
- pygeai/tests/snippets/analytics/get_total_active_users.py +10 -0
- pygeai/tests/snippets/analytics/get_total_cost.py +10 -0
- pygeai/tests/snippets/analytics/get_total_requests_per_day.py +12 -0
- pygeai/tests/snippets/analytics/get_total_tokens.py +12 -0
- pygeai/tests/snippets/auth/__init__.py +0 -0
- pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
- pygeai/tests/snippets/chat/get_response.py +15 -0
- pygeai/tests/snippets/chat/get_response_complete_example.py +67 -0
- pygeai/tests/snippets/chat/get_response_streaming.py +20 -0
- pygeai/tests/snippets/chat/get_response_with_files.py +16 -0
- pygeai/tests/snippets/chat/get_response_with_instructions.py +19 -0
- pygeai/tests/snippets/chat/get_response_with_metadata.py +24 -0
- pygeai/tests/snippets/chat/get_response_with_parallel_tools.py +58 -0
- pygeai/tests/snippets/chat/get_response_with_reasoning.py +21 -0
- pygeai/tests/snippets/chat/get_response_with_store.py +38 -0
- pygeai/tests/snippets/chat/get_response_with_tools.py +36 -0
- pygeai/tests/snippets/chat/get_response_with_truncation.py +24 -0
- pygeai/tests/snippets/dbg/__init__.py +0 -0
- pygeai/tests/snippets/dbg/basic_debugging.py +32 -0
- pygeai/tests/snippets/dbg/breakpoint_management.py +48 -0
- pygeai/tests/snippets/dbg/file_debugging.py +72 -0
- pygeai/tests/snippets/dbg/module_debugging.py +61 -0
- pygeai/tests/snippets/dbg/stack_navigation.py +45 -0
- pygeai/tests/snippets/dbg/stepping_example.py +40 -0
- pygeai/tests/snippets/embeddings/cache_example.py +31 -0
- pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
- pygeai/tests/snippets/embeddings/openai_base64_example.py +27 -0
- pygeai/tests/snippets/embeddings/openai_example.py +30 -0
- pygeai/tests/snippets/embeddings/similarity_example.py +42 -0
- pygeai/tests/snippets/evaluation/dataset/__init__.py +0 -0
- pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +195 -0
- pygeai/tests/snippets/evaluation/dataset/create_dataset.py +26 -0
- pygeai/tests/snippets/evaluation/dataset/create_dataset_from_file.py +11 -0
- pygeai/tests/snippets/evaluation/dataset/create_dataset_row.py +17 -0
- pygeai/tests/snippets/evaluation/dataset/create_expected_source.py +18 -0
- pygeai/tests/snippets/evaluation/dataset/create_filter_variable.py +19 -0
- pygeai/tests/snippets/evaluation/dataset/delete_dataset.py +9 -0
- pygeai/tests/snippets/evaluation/dataset/delete_dataset_row.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/delete_expected_source.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/delete_filter_variable.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/get_dataset.py +9 -0
- pygeai/tests/snippets/evaluation/dataset/get_dataset_row.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/get_expected_source.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/get_filter_variable.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/list_dataset_rows.py +9 -0
- pygeai/tests/snippets/evaluation/dataset/list_datasets.py +6 -0
- pygeai/tests/snippets/evaluation/dataset/list_expected_sources.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/list_filter_variables.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/update_dataset.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/update_dataset_row.py +20 -0
- pygeai/tests/snippets/evaluation/dataset/update_expected_source.py +18 -0
- pygeai/tests/snippets/evaluation/dataset/update_filter_variable.py +19 -0
- pygeai/tests/snippets/evaluation/dataset/upload_dataset_rows_file.py +10 -0
- pygeai/tests/snippets/evaluation/plan/__init__.py +0 -0
- pygeai/tests/snippets/evaluation/plan/add_plan_system_metric.py +13 -0
- pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +136 -0
- pygeai/tests/snippets/evaluation/plan/create_evaluation_plan.py +24 -0
- pygeai/tests/snippets/evaluation/plan/create_rag_evaluation_plan.py +22 -0
- pygeai/tests/snippets/evaluation/plan/delete_evaluation_plan.py +9 -0
- pygeai/tests/snippets/evaluation/plan/delete_plan_system_metric.py +13 -0
- pygeai/tests/snippets/evaluation/plan/execute_evaluation_plan.py +11 -0
- pygeai/tests/snippets/evaluation/plan/get_evaluation_plan.py +9 -0
- pygeai/tests/snippets/evaluation/plan/get_plan_system_metric.py +13 -0
- pygeai/tests/snippets/evaluation/plan/get_system_metric.py +9 -0
- pygeai/tests/snippets/evaluation/plan/list_evaluation_plans.py +7 -0
- pygeai/tests/snippets/evaluation/plan/list_plan_system_metrics.py +9 -0
- pygeai/tests/snippets/evaluation/plan/list_system_metrics.py +7 -0
- pygeai/tests/snippets/evaluation/plan/update_evaluation_plan.py +22 -0
- pygeai/tests/snippets/evaluation/plan/update_plan_system_metric.py +14 -0
- pygeai/tests/snippets/evaluation/result/__init__.py +0 -0
- pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +150 -0
- pygeai/tests/snippets/evaluation/result/get_evaluation_result.py +26 -0
- pygeai/tests/snippets/evaluation/result/list_evaluation_results.py +17 -0
- pygeai/tests/snippets/files/delete_file.py +1 -4
- pygeai/tests/snippets/files/get_file_content.py +2 -4
- pygeai/tests/snippets/files/get_file_data.py +1 -4
- pygeai/tests/snippets/files/get_file_list.py +1 -6
- pygeai/tests/snippets/files/upload_file.py +1 -5
- pygeai/tests/snippets/gam/gam_access_token.py +87 -0
- pygeai/tests/snippets/lab/agentic_flow_example_1.py +25 -23
- pygeai/tests/snippets/lab/agentic_flow_example_4.py +23 -23
- pygeai/tests/snippets/lab/agents/create_agent.py +5 -8
- pygeai/tests/snippets/lab/agents/create_agent_2.py +1 -5
- pygeai/tests/snippets/lab/agents/create_agent_edge_case.py +48 -0
- pygeai/tests/snippets/lab/agents/create_agent_with_permissions.py +39 -0
- pygeai/tests/snippets/lab/agents/create_agent_with_properties.py +46 -0
- pygeai/tests/snippets/lab/agents/create_agent_without_instructions.py +48 -0
- pygeai/tests/snippets/lab/agents/delete_agent.py +1 -5
- pygeai/tests/snippets/lab/agents/get_agent.py +2 -11
- pygeai/tests/snippets/lab/agents/get_agent_with_new_fields.py +62 -0
- pygeai/tests/snippets/lab/agents/get_sharing_link.py +2 -7
- pygeai/tests/snippets/lab/agents/list_agents.py +4 -7
- pygeai/tests/snippets/lab/agents/publish_agent_revision.py +2 -6
- pygeai/tests/snippets/lab/agents/update_agent.py +1 -5
- pygeai/tests/snippets/lab/agents/update_agent_properties.py +50 -0
- pygeai/tests/snippets/lab/assistant_to_agent.py +191 -0
- pygeai/tests/snippets/lab/crud_ui.py +462 -0
- pygeai/tests/snippets/lab/processes/create_process.py +3 -5
- pygeai/tests/snippets/lab/processes/create_task.py +3 -5
- pygeai/tests/snippets/lab/processes/jobs/list_jobs.py +10 -19
- pygeai/tests/snippets/lab/processes/kbs/create_kb.py +2 -5
- pygeai/tests/snippets/lab/processes/kbs/get_kb.py +10 -16
- pygeai/tests/snippets/lab/processes/kbs/list_kbs.py +13 -20
- pygeai/tests/snippets/lab/processes/kbs/try_all.py +5 -7
- pygeai/tests/snippets/lab/processes/list_processes.py +5 -7
- pygeai/tests/snippets/lab/runner_1.py +1 -1
- pygeai/tests/snippets/lab/samples/summarize_files.py +3 -3
- pygeai/tests/snippets/lab/strategies/create_reasoning_strategy.py +2 -5
- pygeai/tests/snippets/lab/strategies/get_reasoning_strategy.py +2 -5
- pygeai/tests/snippets/lab/strategies/list_reasoning_strategies.py +3 -6
- pygeai/tests/snippets/lab/strategies/update_reasoning_strategy.py +2 -5
- pygeai/tests/snippets/lab/tools/create_tool.py +4 -10
- pygeai/tests/snippets/lab/tools/create_tool_edge_case.py +50 -0
- pygeai/tests/snippets/lab/tools/delete_tool.py +2 -6
- pygeai/tests/snippets/lab/tools/get_parameter.py +5 -7
- pygeai/tests/snippets/lab/tools/get_tool.py +5 -7
- pygeai/tests/snippets/lab/tools/list_tools.py +3 -7
- pygeai/tests/snippets/lab/tools/publish_tool_revision.py +3 -5
- pygeai/tests/snippets/lab/tools/set_parameters.py +4 -9
- pygeai/tests/snippets/lab/tools/update_tool.py +4 -8
- pygeai/tests/snippets/lab/use_cases/__init__.py +0 -0
- pygeai/tests/snippets/lab/use_cases/create_cli_expert.py +1640 -0
- pygeai/tests/snippets/lab/use_cases/create_lab_expert.py +4541 -0
- pygeai/tests/snippets/lab/use_cases/create_tool_headless_web_browser.py +133 -0
- pygeai/tests/snippets/lab/use_cases/create_web_designer.py +189 -0
- pygeai/tests/snippets/lab/use_cases/create_web_reader.py +185 -0
- pygeai/tests/snippets/lab/{file_summarizer_example.py → use_cases/file_summarizer_example.py} +3 -3
- pygeai/tests/snippets/lab/{file_summarizer_example_2.py → use_cases/file_summarizer_example_2.py} +12 -12
- pygeai/tests/snippets/lab/use_cases/update_cli_expert.py +1773 -0
- pygeai/tests/snippets/lab/use_cases/update_lab_expert.py +4541 -0
- pygeai/tests/snippets/lab/use_cases/update_web_designer.py +188 -0
- pygeai/tests/snippets/lab/use_cases/update_web_reader.py +195 -0
- pygeai/tests/snippets/lab/use_cases/update_web_reader_with_tool.py +210 -0
- pygeai/tests/snippets/migrate/__init__.py +45 -0
- pygeai/tests/snippets/migrate/agent_migration.py +110 -0
- pygeai/tests/snippets/migrate/assistant_migration.py +64 -0
- pygeai/tests/snippets/migrate/orchestrator_examples.py +179 -0
- pygeai/tests/snippets/migrate/process_migration.py +64 -0
- pygeai/tests/snippets/migrate/project_migration.py +42 -0
- pygeai/tests/snippets/migrate/tool_migration.py +64 -0
- pygeai/tests/snippets/organization/add_project_member.py +10 -0
- pygeai/tests/snippets/organization/add_project_member_batch.py +44 -0
- pygeai/tests/snippets/organization/create_project.py +2 -2
- pygeai/tests/snippets/organization/get_memberships.py +12 -0
- pygeai/tests/snippets/organization/get_organization_members.py +6 -0
- pygeai/tests/snippets/organization/get_project_members.py +6 -0
- pygeai/tests/snippets/organization/get_project_memberships.py +12 -0
- pygeai/tests/snippets/organization/get_project_roles.py +6 -0
- pygeai/vendor/a2a/__init__.py +1 -0
- pygeai/vendor/a2a/auth/__init__.py +0 -0
- pygeai/vendor/a2a/auth/user.py +31 -0
- pygeai/vendor/a2a/client/__init__.py +19 -0
- pygeai/vendor/a2a/client/client.py +425 -0
- pygeai/vendor/a2a/client/errors.py +33 -0
- pygeai/vendor/a2a/client/helpers.py +22 -0
- pygeai/vendor/a2a/py.typed +0 -0
- pygeai/vendor/a2a/server/__init__.py +1 -0
- pygeai/vendor/a2a/server/agent_execution/__init__.py +18 -0
- pygeai/vendor/a2a/server/agent_execution/agent_executor.py +44 -0
- pygeai/vendor/a2a/server/agent_execution/context.py +155 -0
- pygeai/vendor/a2a/server/agent_execution/request_context_builder.py +20 -0
- pygeai/vendor/a2a/server/agent_execution/simple_request_context_builder.py +77 -0
- pygeai/vendor/a2a/server/apps/__init__.py +16 -0
- pygeai/vendor/a2a/server/apps/jsonrpc/__init__.py +16 -0
- pygeai/vendor/a2a/server/apps/jsonrpc/fastapi_app.py +88 -0
- pygeai/vendor/a2a/server/apps/jsonrpc/jsonrpc_app.py +426 -0
- pygeai/vendor/a2a/server/apps/jsonrpc/starlette_app.py +123 -0
- pygeai/vendor/a2a/server/context.py +23 -0
- pygeai/vendor/a2a/server/events/__init__.py +21 -0
- pygeai/vendor/a2a/server/events/event_consumer.py +149 -0
- pygeai/vendor/a2a/server/events/event_queue.py +156 -0
- pygeai/vendor/a2a/server/events/in_memory_queue_manager.py +85 -0
- pygeai/vendor/a2a/server/events/queue_manager.py +35 -0
- pygeai/vendor/a2a/server/request_handlers/__init__.py +20 -0
- pygeai/vendor/a2a/server/request_handlers/default_request_handler.py +435 -0
- pygeai/vendor/a2a/server/request_handlers/jsonrpc_handler.py +327 -0
- pygeai/vendor/a2a/server/request_handlers/request_handler.py +161 -0
- pygeai/vendor/a2a/server/request_handlers/response_helpers.py +133 -0
- pygeai/vendor/a2a/server/tasks/__init__.py +20 -0
- pygeai/vendor/a2a/server/tasks/inmemory_push_notifier.py +62 -0
- pygeai/vendor/a2a/server/tasks/inmemory_task_store.py +51 -0
- pygeai/vendor/a2a/server/tasks/push_notifier.py +25 -0
- pygeai/vendor/a2a/server/tasks/result_aggregator.py +151 -0
- pygeai/vendor/a2a/server/tasks/task_manager.py +253 -0
- pygeai/vendor/a2a/server/tasks/task_store.py +22 -0
- pygeai/vendor/a2a/server/tasks/task_updater.py +155 -0
- pygeai/vendor/a2a/types.py +1624 -0
- pygeai/vendor/a2a/utils/__init__.py +40 -0
- pygeai/vendor/a2a/utils/artifact.py +72 -0
- pygeai/vendor/a2a/utils/errors.py +69 -0
- pygeai/vendor/a2a/utils/helpers.py +176 -0
- pygeai/vendor/a2a/utils/message.py +83 -0
- pygeai/vendor/a2a/utils/task.py +57 -0
- pygeai/vendor/a2a/utils/telemetry.py +299 -0
- pygeai-0.6.0b15.dist-info/METADATA +205 -0
- pygeai-0.6.0b15.dist-info/RECORD +799 -0
- {pygeai-0.1.51b3.dist-info → pygeai-0.6.0b15.dist-info}/WHEEL +1 -1
- {pygeai-0.1.51b3.dist-info → pygeai-0.6.0b15.dist-info}/entry_points.txt +2 -1
- {pygeai-0.1.51b3.dist-info → pygeai-0.6.0b15.dist-info}/licenses/LICENSE +13 -1
- pygeai-0.6.0b15.dist-info/top_level.txt +1 -0
- docs/geai-proxy/README.md +0 -145
- docs/source/conf.py +0 -45
- pygeai/tests/core/test_managers.py +0 -233
- pygeai-0.1.51b3.dist-info/METADATA +0 -130
- pygeai-0.1.51b3.dist-info/RECORD +0 -324
- pygeai-0.1.51b3.dist-info/top_level.txt +0 -3
- scripts/bump_beta_version.py +0 -56
- {scripts → pygeai/analytics}/__init__.py +0 -0
- /pygeai/tests/snippets/lab/{c_code_fixer_agent_flow.py → use_cases/c_code_fixer_agent_flow.py} +0 -0
pygeai/organization/responses.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from pydantic.main import BaseModel
|
|
2
2
|
|
|
3
3
|
from pygeai.core.models import Assistant, Project, ProjectToken, \
|
|
4
|
-
RequestItem
|
|
4
|
+
RequestItem, Role, Member, OrganizationMembership, ProjectMembership, Organization
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class AssistantListResponse(BaseModel):
|
|
@@ -22,3 +22,60 @@ class ProjectTokensResponse(BaseModel):
|
|
|
22
22
|
|
|
23
23
|
class ProjectItemListResponse(BaseModel):
|
|
24
24
|
items: list[RequestItem]
|
|
25
|
+
|
|
26
|
+
def to_list(self):
|
|
27
|
+
return [item.to_dict() for item in self.items] if self.items else []
|
|
28
|
+
|
|
29
|
+
def __getitem__(self, index: int) -> RequestItem:
|
|
30
|
+
if self.items is None:
|
|
31
|
+
raise IndexError("ProjectItemListResponse is empty")
|
|
32
|
+
return self.items[index]
|
|
33
|
+
|
|
34
|
+
def __len__(self) -> int:
|
|
35
|
+
return len(self.items) if self.items else 0
|
|
36
|
+
|
|
37
|
+
def __iter__(self):
|
|
38
|
+
"""Make ProjectItemListResponse iterable over its items."""
|
|
39
|
+
if self.items is None:
|
|
40
|
+
return iter([])
|
|
41
|
+
return iter(self.items)
|
|
42
|
+
|
|
43
|
+
def append(self, item: RequestItem) -> None:
|
|
44
|
+
"""Append an Agent instance to the items list."""
|
|
45
|
+
if self.items is None:
|
|
46
|
+
self.items = []
|
|
47
|
+
self.items.append(item)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class MembershipsResponse(BaseModel):
|
|
51
|
+
count: int
|
|
52
|
+
pages: int
|
|
53
|
+
organizations: list[OrganizationMembership]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ProjectMembershipsResponse(BaseModel):
|
|
57
|
+
count: int
|
|
58
|
+
pages: int
|
|
59
|
+
projects: list[ProjectMembership]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ProjectRolesResponse(BaseModel):
|
|
63
|
+
roles: list[Role]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class ProjectMembersResponse(BaseModel):
|
|
67
|
+
members: list[Member]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class OrganizationMembersResponse(BaseModel):
|
|
71
|
+
members: list[Member]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class OrganizationListResponse(BaseModel):
|
|
75
|
+
count: int
|
|
76
|
+
pages: int
|
|
77
|
+
organizations: list[Organization]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class OrganizationDataResponse(BaseModel):
|
|
81
|
+
organization: Organization
|
pygeai/proxy/clients.py
CHANGED
|
@@ -3,7 +3,9 @@ from typing import Optional, Dict, Any, List
|
|
|
3
3
|
import uuid
|
|
4
4
|
import requests
|
|
5
5
|
from urllib3.exceptions import MaxRetryError
|
|
6
|
-
from pygeai.proxy.tool import
|
|
6
|
+
from pygeai.proxy.tool import ProxiedTool
|
|
7
|
+
from pygeai.core.utils.validators import validate_status_code
|
|
8
|
+
from pygeai.core.utils.parsers import parse_json_response
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
@dataclass
|
|
@@ -21,7 +23,7 @@ class ToolProxyData:
|
|
|
21
23
|
name: Optional[str] = None
|
|
22
24
|
description: Optional[str] = None
|
|
23
25
|
affinity: Optional[uuid.UUID] = None
|
|
24
|
-
tools: Optional[List[
|
|
26
|
+
tools: Optional[List[ProxiedTool]] = None
|
|
25
27
|
|
|
26
28
|
def to_dict(self) -> Dict[str, Any]:
|
|
27
29
|
"""
|
|
@@ -150,7 +152,8 @@ class ProxyClient:
|
|
|
150
152
|
response = self.session.request(method, url, **kwargs)
|
|
151
153
|
response.raise_for_status()
|
|
152
154
|
try:
|
|
153
|
-
|
|
155
|
+
validate_status_code(response)
|
|
156
|
+
return parse_json_response(response, "unknown operation")
|
|
154
157
|
except ValueError:
|
|
155
158
|
return response.text
|
|
156
159
|
except requests.exceptions.Timeout:
|
pygeai/proxy/config.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from pygeai.core.common.config import SettingsManager
|
|
2
2
|
from typing import Optional
|
|
3
3
|
import uuid
|
|
4
|
-
|
|
4
|
+
import os
|
|
5
5
|
|
|
6
6
|
class ProxySettingsManager(SettingsManager):
|
|
7
7
|
"""
|
|
@@ -100,6 +100,19 @@ class ProxySettingsManager(SettingsManager):
|
|
|
100
100
|
"""
|
|
101
101
|
self.set_setting_value("PROXY_AFFINITY", str(affinity), alias)
|
|
102
102
|
|
|
103
|
+
def get_setting_value(self, setting_key: str, alias: str):
|
|
104
|
+
"""
|
|
105
|
+
Get the value of a specific setting for a specific alias.
|
|
106
|
+
|
|
107
|
+
:param setting_key: str - Key of the setting to get
|
|
108
|
+
:param alias: str - Alias for the settings section. Defaults to DEFAULT_ALIAS.
|
|
109
|
+
"""
|
|
110
|
+
env_var_name = setting_key.upper()
|
|
111
|
+
if os.getenv(env_var_name) and alias == self.DEFAULT_ALIAS:
|
|
112
|
+
return os.getenv(env_var_name)
|
|
113
|
+
else:
|
|
114
|
+
return super().get_setting_value(setting_key, alias)
|
|
115
|
+
|
|
103
116
|
def get_proxy_config(self, alias: str = DEFAULT_ALIAS) -> dict:
|
|
104
117
|
"""
|
|
105
118
|
Get the complete proxy configuration for a specific alias.
|
pygeai/proxy/managers.py
CHANGED
|
@@ -6,10 +6,11 @@ import sys
|
|
|
6
6
|
import requests
|
|
7
7
|
from urllib3.exceptions import MaxRetryError
|
|
8
8
|
import mcp.types as types
|
|
9
|
-
|
|
9
|
+
import a2a.types as a2a_types
|
|
10
|
+
from pygeai.proxy.servers import MCPServer, ToolServer, ProxiedTool, A2AServer
|
|
10
11
|
from pygeai.proxy.config import ProxySettingsManager
|
|
11
12
|
from pygeai.proxy.clients import ProxyClient, ToolProxyData, ToolProxyJobResult
|
|
12
|
-
|
|
13
|
+
from pygeai.core.utils.console import Console
|
|
13
14
|
|
|
14
15
|
class ServerManager:
|
|
15
16
|
"""
|
|
@@ -28,8 +29,8 @@ class ServerManager:
|
|
|
28
29
|
"""
|
|
29
30
|
self.servers_cfg = servers_cfg
|
|
30
31
|
self.settings = settings
|
|
31
|
-
self.servers: Dict[str,
|
|
32
|
-
self.tools: Dict[str,
|
|
32
|
+
self.servers: Dict[str, ToolServer] = {}
|
|
33
|
+
self.tools: Dict[str, ProxiedTool] = {}
|
|
33
34
|
self.exit_stack: AsyncExitStack = AsyncExitStack()
|
|
34
35
|
|
|
35
36
|
async def _initialize_servers(self) -> None:
|
|
@@ -40,23 +41,34 @@ class ServerManager:
|
|
|
40
41
|
:raises: Exception - If server initialization fails
|
|
41
42
|
"""
|
|
42
43
|
for server_cfg in self.servers_cfg:
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
Console.write_stdout(f"Initializing server {server_cfg['name']} type: {server_cfg['type']}")
|
|
45
|
+
if server_cfg['type'] == 'mcp':
|
|
46
|
+
server = MCPServer(server_cfg['name'], server_cfg, self.settings)
|
|
47
|
+
elif server_cfg['type'] == 'a2a':
|
|
48
|
+
server = A2AServer(server_cfg['name'], server_cfg, self.settings)
|
|
49
|
+
else:
|
|
50
|
+
raise ValueError(f"Invalid server type: {server_cfg['type']}")
|
|
45
51
|
try:
|
|
46
52
|
await self.exit_stack.enter_async_context(server.exit_stack)
|
|
47
53
|
await server.initialize()
|
|
48
54
|
self.servers[server.name] = server
|
|
49
|
-
|
|
55
|
+
Console.write_stdout(f"\nServer {server.name} initialized successfully", end="\n\n")
|
|
50
56
|
except Exception as e:
|
|
51
|
-
|
|
57
|
+
Console.write_exception(f"Failed to initialize server {server.name}:", e)
|
|
52
58
|
raise
|
|
53
59
|
|
|
54
60
|
for server in self.servers.values():
|
|
55
|
-
|
|
61
|
+
Console.write_stdout(f"Listing tools for server {server.name}", end="")
|
|
62
|
+
if server.public_prefix:
|
|
63
|
+
Console.write_stdout(f" | access scope:public prefix: {server.public_prefix}")
|
|
64
|
+
else:
|
|
65
|
+
Console.write_stdout(" ! access scope:private")
|
|
66
|
+
|
|
56
67
|
tools = await server.list_tools()
|
|
57
68
|
for tool in tools:
|
|
58
69
|
self.tools[tool.get_full_name()] = tool
|
|
59
|
-
|
|
70
|
+
Console.write_stdout(f"\tTool {tool.get_full_name()} added to server {server.name}")
|
|
71
|
+
|
|
60
72
|
async def _initialize_client(self) -> ProxyClient:
|
|
61
73
|
"""
|
|
62
74
|
Initialize the client.
|
|
@@ -68,17 +80,29 @@ class ServerManager:
|
|
|
68
80
|
try:
|
|
69
81
|
alias = self.settings.get_current_alias()
|
|
70
82
|
client = ProxyClient(self.settings.get_api_key(alias), self.settings.get_base_url(alias), self.settings.get_proxy_id(alias))
|
|
71
|
-
|
|
72
|
-
client.register(proxy_data=ToolProxyData(
|
|
83
|
+
Console.write_stdout(f"\nRegistering proxy {self.settings.get_proxy_id(alias)} with name {self.settings.get_proxy_name(alias)} and description {self.settings.get_proxy_description(alias)}")
|
|
84
|
+
result = client.register(proxy_data=ToolProxyData(
|
|
73
85
|
id=self.settings.get_proxy_id(alias),
|
|
74
86
|
name=self.settings.get_proxy_name(alias),
|
|
75
87
|
description=self.settings.get_proxy_description(alias),
|
|
76
88
|
affinity=self.settings.get_proxy_affinity(alias),
|
|
77
89
|
tools=list(self.tools.values())
|
|
78
90
|
))
|
|
79
|
-
|
|
91
|
+
Console.write_stdout("----------------------------------")
|
|
92
|
+
Console.write_stdout(f"Proxy registered successfully:")
|
|
93
|
+
if isinstance(result, dict) and isinstance(result.get("Messages"), list):
|
|
94
|
+
for message in result["Messages"]:
|
|
95
|
+
description = message.get("Description", "")
|
|
96
|
+
message_type = message.get("Type", None)
|
|
97
|
+
|
|
98
|
+
if message_type == 1:
|
|
99
|
+
Console.write_stderr(description)
|
|
100
|
+
elif message_type == 2:
|
|
101
|
+
Console.write_stdout(description)
|
|
102
|
+
Console.write_stdout("----------------------------------")
|
|
80
103
|
return client
|
|
81
104
|
except (ConnectionError, MaxRetryError):
|
|
105
|
+
Console.write_exception(f"Error registering proxy {self.settings.get_proxy_id(alias)}:")
|
|
82
106
|
raise
|
|
83
107
|
|
|
84
108
|
async def execute_tool(
|
|
@@ -126,7 +150,7 @@ class ServerManager:
|
|
|
126
150
|
data = json.loads(raw_json)
|
|
127
151
|
return data['function']['name'], data['function']['arguments']
|
|
128
152
|
except (json.JSONDecodeError, KeyError) as e:
|
|
129
|
-
|
|
153
|
+
Console.write_stdout(f"Error extracting function call info: {e}")
|
|
130
154
|
return None, None
|
|
131
155
|
|
|
132
156
|
async def start(self) -> None:
|
|
@@ -143,17 +167,16 @@ class ServerManager:
|
|
|
143
167
|
try:
|
|
144
168
|
client = await self._initialize_client()
|
|
145
169
|
except (ConnectionError, TimeoutError, RuntimeError) as e:
|
|
146
|
-
|
|
170
|
+
Console.write_exception(f"Error during client initialization:", e)
|
|
147
171
|
for i in range(15, 0, -1):
|
|
148
|
-
|
|
149
|
-
sys.stdout.flush()
|
|
172
|
+
Console.write_stdout(f"\rRetrying in {i} seconds... ",'')
|
|
150
173
|
await asyncio.sleep(1)
|
|
151
|
-
|
|
174
|
+
Console.write_stdout("\rRetrying now... ")
|
|
152
175
|
retry_count += 1
|
|
153
176
|
continue
|
|
154
177
|
|
|
155
178
|
retry_count = 0
|
|
156
|
-
|
|
179
|
+
Console.write_stdout(f"Waiting for jobs...")
|
|
157
180
|
while True:
|
|
158
181
|
try:
|
|
159
182
|
jobs = client.dequeue()
|
|
@@ -161,24 +184,24 @@ class ServerManager:
|
|
|
161
184
|
except requests.exceptions.RequestException as e:
|
|
162
185
|
retry_count += 1
|
|
163
186
|
if retry_count >= MAX_RETRIES:
|
|
164
|
-
|
|
187
|
+
Console.write_stderr(f"Failed to dequeue jobs after {MAX_RETRIES} retries.")
|
|
188
|
+
Console.write_exception(f"Exception:", e, "\nExiting...")
|
|
165
189
|
return
|
|
166
|
-
|
|
190
|
+
Console.write_stderr(f"Failed to dequeue jobs (attempt {retry_count}/{MAX_RETRIES}):")
|
|
167
191
|
for i in range(15, 0, -1):
|
|
168
|
-
|
|
169
|
-
sys.stdout.flush()
|
|
192
|
+
Console.write_stdout(f"\rRetrying in {i} seconds... ",'')
|
|
170
193
|
await asyncio.sleep(1)
|
|
171
|
-
|
|
194
|
+
Console.write_stdout("\rRetrying now... ")
|
|
172
195
|
continue
|
|
173
196
|
for job in jobs:
|
|
174
|
-
|
|
197
|
+
Console.write_stdout(f"----------------------------------Job: {job.id}----------------------------------")
|
|
175
198
|
tool_name, arguments = self.extract_function_call_info(job.input)
|
|
176
199
|
if tool_name:
|
|
177
|
-
|
|
200
|
+
Console.write_stdout(f"Executing tool {job.server}/{tool_name} with arguments {arguments}")
|
|
178
201
|
try:
|
|
179
202
|
result = await self.execute_tool(job.server, tool_name, json.loads(arguments))
|
|
180
|
-
except (
|
|
181
|
-
|
|
203
|
+
except (Exception) as e:
|
|
204
|
+
Console.write_exception(f"Error executing tool {tool_name}:", e)
|
|
182
205
|
continue
|
|
183
206
|
|
|
184
207
|
if isinstance(result.content, list):
|
|
@@ -186,19 +209,24 @@ class ServerManager:
|
|
|
186
209
|
for item in result.content:
|
|
187
210
|
if isinstance(item, types.TextContent):
|
|
188
211
|
text_parts.append(item.text)
|
|
212
|
+
elif isinstance(item, a2a_types.Part):
|
|
213
|
+
if isinstance(item.root, a2a_types.TextPart):
|
|
214
|
+
text_parts.append(item.root.text)
|
|
215
|
+
else:
|
|
216
|
+
Console.write_stdout(f"Unknown content type {type(item.root)}")
|
|
189
217
|
else:
|
|
190
|
-
|
|
218
|
+
Console.write_stdout(f"Unknown content type {type(item)}")
|
|
191
219
|
|
|
192
220
|
if text_parts:
|
|
193
221
|
job.output = "\n".join(text_parts)
|
|
194
|
-
|
|
222
|
+
Console.write_stdout(f"result: {job.output} success: {not result.isError}")
|
|
195
223
|
try:
|
|
196
224
|
client.send_result(ToolProxyJobResult(success=result.isError, job=job))
|
|
197
225
|
except (ConnectionError, TimeoutError, RuntimeError) as e:
|
|
198
|
-
|
|
226
|
+
Console.write_exception("Error sending result:", e)
|
|
199
227
|
else:
|
|
200
|
-
|
|
228
|
+
Console.write_stdout(f"{result}")
|
|
201
229
|
await asyncio.sleep(1)
|
|
202
230
|
finally:
|
|
203
|
-
|
|
231
|
+
Console.write_stdout("Proxy stopped")
|
|
204
232
|
await self.exit_stack.aclose()
|
pygeai/proxy/servers.py
CHANGED
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
"""Server module for managing MCP server connections and tool execution."""
|
|
2
|
-
|
|
3
2
|
import asyncio
|
|
4
3
|
import os
|
|
5
4
|
import shutil
|
|
6
|
-
import
|
|
5
|
+
import httpx
|
|
6
|
+
from types import SimpleNamespace
|
|
7
|
+
from uuid import uuid4
|
|
7
8
|
from contextlib import AsyncExitStack
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
8
10
|
from typing import Any, Dict
|
|
9
11
|
from mcp import ClientSession, StdioServerParameters
|
|
10
12
|
from mcp.client.stdio import stdio_client
|
|
11
13
|
from mcp.client.sse import sse_client
|
|
12
|
-
from pygeai.proxy.tool import
|
|
14
|
+
from pygeai.proxy.tool import ProxiedTool
|
|
13
15
|
from pygeai.proxy.config import ProxySettingsManager
|
|
16
|
+
from a2a.client import A2AClient, A2ACardResolver
|
|
17
|
+
from a2a.types import (
|
|
18
|
+
AgentCard, SendMessageRequest, MessageSendParams,
|
|
19
|
+
Message, Task, SendMessageSuccessResponse
|
|
20
|
+
)
|
|
14
21
|
|
|
22
|
+
from pygeai.core.utils.console import Console
|
|
15
23
|
|
|
16
|
-
class
|
|
24
|
+
class ToolServer(ABC):
|
|
17
25
|
"""
|
|
18
|
-
|
|
26
|
+
Interface for tool servers like MCP and A2A.
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
:param settings: ProxySettingsManager - Proxy settings manager
|
|
28
|
+
Subclasses must implement methods to initialize the server,
|
|
29
|
+
list available tools, and execute a tool.
|
|
23
30
|
"""
|
|
24
|
-
|
|
31
|
+
|
|
25
32
|
def __init__(self, sever_name: str, config: Dict[str, Any], settings: ProxySettingsManager):
|
|
26
33
|
"""
|
|
27
34
|
Initialize the server.
|
|
@@ -33,11 +40,10 @@ class Server:
|
|
|
33
40
|
self.config = config
|
|
34
41
|
self.settings = settings
|
|
35
42
|
self.name: str = sever_name
|
|
36
|
-
self.
|
|
37
|
-
self.session: ClientSession | None = None
|
|
43
|
+
self.public_prefix: str | None = None
|
|
38
44
|
self.exit_stack: AsyncExitStack = AsyncExitStack()
|
|
39
|
-
self.publicpreffix: str | None = None
|
|
40
45
|
|
|
46
|
+
@abstractmethod
|
|
41
47
|
async def initialize(self) -> None:
|
|
42
48
|
"""
|
|
43
49
|
Initialize the server connection.
|
|
@@ -47,8 +53,155 @@ class Server:
|
|
|
47
53
|
:raises: RuntimeError - If server initialization fails
|
|
48
54
|
:raises: ConnectionError - If connection to server fails
|
|
49
55
|
"""
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
@abstractmethod
|
|
59
|
+
async def list_tools(self) -> list[ProxiedTool]:
|
|
60
|
+
"""
|
|
61
|
+
List available tools from the server.
|
|
62
|
+
|
|
63
|
+
:return: list[Tool] - List of available tools
|
|
64
|
+
:raises: RuntimeError - If server is not initialized
|
|
65
|
+
"""
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
@abstractmethod
|
|
69
|
+
async def execute_tool(
|
|
70
|
+
self,
|
|
71
|
+
tool_name: str,
|
|
72
|
+
arguments: dict[str, Any],
|
|
73
|
+
retries: int = 2,
|
|
74
|
+
delay: float = 1.0,
|
|
75
|
+
) -> Any:
|
|
76
|
+
"""
|
|
77
|
+
Execute a tool with retry mechanism.
|
|
78
|
+
|
|
79
|
+
:param tool_name: str - Name of the tool to execute
|
|
80
|
+
:param arguments: dict[str, Any] - Tool arguments
|
|
81
|
+
:param retries: int - Number of retry attempts
|
|
82
|
+
:param delay: float - Delay between retries in seconds
|
|
83
|
+
:return: Any - Tool execution result
|
|
84
|
+
:raises: RuntimeError - If server is not initialized
|
|
85
|
+
:raises: ConnectionError - If connection to server fails
|
|
86
|
+
:raises: ValueError - If tool execution fails
|
|
87
|
+
"""
|
|
88
|
+
pass
|
|
89
|
+
|
|
90
|
+
class A2AServer(ToolServer):
|
|
91
|
+
"""
|
|
92
|
+
Manages A2A server connections and tool execution.
|
|
93
|
+
"""
|
|
94
|
+
def __init__(self, sever_name: str, config: Dict[str, Any], settings: ProxySettingsManager):
|
|
95
|
+
super().__init__(sever_name, config, settings)
|
|
96
|
+
self.client: A2AClient | None = None
|
|
97
|
+
self.card_url: str = self.config["url"]
|
|
98
|
+
self.agent_card: AgentCard | None = None
|
|
99
|
+
self.httpx_client: httpx.AsyncClient | None = None
|
|
100
|
+
|
|
101
|
+
async def initialize(self) -> None:
|
|
102
|
+
"""
|
|
103
|
+
Initialize the A2A client from the agent card and convert agent skills into tools
|
|
104
|
+
compatible with OpenAI function call format.
|
|
105
|
+
"""
|
|
106
|
+
try:
|
|
107
|
+
self.httpx_client = httpx.AsyncClient(timeout=60.0)
|
|
108
|
+
self.public_prefix = self.config.get("public_prefix")
|
|
109
|
+
headers = self.config.get("headers")
|
|
110
|
+
if headers:
|
|
111
|
+
self.httpx_client.headers.update(headers)
|
|
112
|
+
resolver = A2ACardResolver(httpx_client=self.httpx_client, base_url=self.card_url)
|
|
113
|
+
self.agent_card = await resolver.get_agent_card()
|
|
114
|
+
self.client = A2AClient(httpx_client=self.httpx_client, agent_card=self.agent_card)
|
|
115
|
+
|
|
116
|
+
except httpx.HTTPError as e:
|
|
117
|
+
Console.write_exception(f"HTTP error initializing A2A server {self.name}:", e)
|
|
118
|
+
raise ConnectionError(f"Failed to connect to A2A server: {e}") from e
|
|
119
|
+
except ValueError as e:
|
|
120
|
+
Console.write_exception(f"Invalid configuration for A2A server {self.name}:" ,e)
|
|
121
|
+
raise ValueError(f"Invalid A2A server configuration: {e}") from e
|
|
122
|
+
except RuntimeError as e:
|
|
123
|
+
Console.write_exception(f"Runtime error initializing A2A server {self.name}:", e)
|
|
124
|
+
raise RuntimeError(f"A2A server initialization failed: {e}") from e
|
|
125
|
+
|
|
126
|
+
async def list_tools(self) -> list[ProxiedTool]:
|
|
127
|
+
if not self.client:
|
|
128
|
+
raise RuntimeError(f"Server {self.name} not initialized")
|
|
129
|
+
input_schema = {
|
|
130
|
+
"type": "object",
|
|
131
|
+
"properties": {
|
|
132
|
+
"input-text": {
|
|
133
|
+
"type": "string",
|
|
134
|
+
"description": "The input text to send to the agent for execution."
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"required": ["input-text"]
|
|
138
|
+
}
|
|
139
|
+
tools = []
|
|
140
|
+
for skill in self.agent_card.skills:
|
|
141
|
+
tools.append(ProxiedTool(self.name, skill.id, skill.description, self.public_prefix, input_schema))
|
|
142
|
+
return tools
|
|
143
|
+
|
|
144
|
+
async def execute_tool(
|
|
145
|
+
self,
|
|
146
|
+
tool_name: str,
|
|
147
|
+
arguments: dict[str, Any],
|
|
148
|
+
retries: int = 2,
|
|
149
|
+
delay: float = 1.0,
|
|
150
|
+
) -> Any:
|
|
151
|
+
Console.write_stdout(f"Executing {tool_name}...")
|
|
152
|
+
message_id = uuid4().hex
|
|
153
|
+
send_message_payload: dict[str, Any] = {
|
|
154
|
+
'message': {
|
|
155
|
+
'role': 'user',
|
|
156
|
+
'parts': [
|
|
157
|
+
{
|
|
158
|
+
'kind': 'text',
|
|
159
|
+
'text': (
|
|
160
|
+
'Use your skill:' + tool_name +
|
|
161
|
+
' with this input:' + arguments["input-text"]
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
'messageId': message_id,
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
request = SendMessageRequest(
|
|
169
|
+
id=message_id,
|
|
170
|
+
params=MessageSendParams(**send_message_payload)
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
response = await self.client.send_message(request)
|
|
174
|
+
result = []
|
|
175
|
+
if isinstance(response.root, SendMessageSuccessResponse):
|
|
176
|
+
if isinstance(response.root.result, Message):
|
|
177
|
+
result = response.root.result.parts
|
|
178
|
+
elif isinstance(response.root, Task):
|
|
179
|
+
Console.write_stderr(f"Task response: {response.root.result}")
|
|
180
|
+
else:
|
|
181
|
+
Console.write_stderr(f"Unknown response type: {type(response.root)}")
|
|
182
|
+
raise ValueError(f"Unknown response type: {type(response.root)}")
|
|
183
|
+
|
|
184
|
+
return SimpleNamespace(content=result, isError=False)
|
|
185
|
+
|
|
186
|
+
class MCPServer(ToolServer):
|
|
187
|
+
"""
|
|
188
|
+
Manages MCP server connections and tool execution.
|
|
189
|
+
|
|
190
|
+
:param sever_name: str - Name of the server
|
|
191
|
+
:param config: Dict[str, Any] - Server configuration
|
|
192
|
+
:param settings: ProxySettingsManager - Proxy settings manager
|
|
193
|
+
"""
|
|
194
|
+
def __init__(self, sever_name: str, config: Dict[str, Any], settings: ProxySettingsManager):
|
|
195
|
+
super().__init__(sever_name, config, settings)
|
|
196
|
+
self.public_prefix = config.get("public_prefix")
|
|
197
|
+
self.stdio_context: Any | None = None
|
|
198
|
+
self.session: ClientSession | None = None
|
|
199
|
+
|
|
200
|
+
async def initialize(self) -> None:
|
|
201
|
+
self.public_prefix = self.config.get("public_prefix")
|
|
202
|
+
transport = self.config.get("transport") or (
|
|
203
|
+
"sse" if ("uri" in self.config or "url" in self.config) else "stdio"
|
|
204
|
+
)
|
|
52
205
|
try:
|
|
53
206
|
if transport == "stdio":
|
|
54
207
|
command = (
|
|
@@ -62,9 +215,11 @@ class Server:
|
|
|
62
215
|
server_params = StdioServerParameters(
|
|
63
216
|
command=command,
|
|
64
217
|
args=self.config["args"],
|
|
65
|
-
env=
|
|
66
|
-
|
|
67
|
-
|
|
218
|
+
env=(
|
|
219
|
+
{**os.environ, **self.config["env"]}
|
|
220
|
+
if self.config.get("env")
|
|
221
|
+
else None
|
|
222
|
+
),
|
|
68
223
|
)
|
|
69
224
|
|
|
70
225
|
stdio_transport = await self.exit_stack.enter_async_context(
|
|
@@ -72,17 +227,19 @@ class Server:
|
|
|
72
227
|
)
|
|
73
228
|
read, write = stdio_transport
|
|
74
229
|
elif transport == "sse":
|
|
75
|
-
uri = self.config.get("uri")
|
|
230
|
+
uri = self.config.get("uri", self.config["url"])
|
|
76
231
|
if not uri:
|
|
77
232
|
raise ValueError("Missing 'uri' for sse transport")
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
233
|
+
try:
|
|
234
|
+
sse_transport = await self.exit_stack.enter_async_context(
|
|
235
|
+
sse_client(
|
|
236
|
+
url=uri,
|
|
237
|
+
headers=self.config.get("headers")
|
|
238
|
+
)
|
|
83
239
|
)
|
|
84
|
-
|
|
85
|
-
|
|
240
|
+
read, write = sse_transport
|
|
241
|
+
except httpx.HTTPStatusError as e:
|
|
242
|
+
Console.write_exception(f"HTTP error initializing MCP server {self.name}:", e)
|
|
86
243
|
else:
|
|
87
244
|
raise ValueError(f"Unsupported transport: {transport}")
|
|
88
245
|
|
|
@@ -92,16 +249,10 @@ class Server:
|
|
|
92
249
|
await session.initialize()
|
|
93
250
|
self.session = session
|
|
94
251
|
except (RuntimeError, ConnectionError, ValueError) as e:
|
|
95
|
-
|
|
252
|
+
Console.write_exception(f"Error initializing server {self.name}:", e)
|
|
96
253
|
raise
|
|
97
254
|
|
|
98
|
-
async def list_tools(self) -> list[
|
|
99
|
-
"""
|
|
100
|
-
List available tools from the server.
|
|
101
|
-
|
|
102
|
-
:return: list[Tool] - List of available tools
|
|
103
|
-
:raises: RuntimeError - If server is not initialized
|
|
104
|
-
"""
|
|
255
|
+
async def list_tools(self) -> list[ProxiedTool]:
|
|
105
256
|
if not self.session:
|
|
106
257
|
raise RuntimeError(f"Server {self.name} not initialized")
|
|
107
258
|
|
|
@@ -112,7 +263,13 @@ class Server:
|
|
|
112
263
|
if isinstance(item, tuple) and item[0] == "tools":
|
|
113
264
|
for tool in item[1]:
|
|
114
265
|
tools.append(
|
|
115
|
-
|
|
266
|
+
ProxiedTool(
|
|
267
|
+
self.name,
|
|
268
|
+
tool.name,
|
|
269
|
+
tool.description,
|
|
270
|
+
self.public_prefix,
|
|
271
|
+
tool.inputSchema
|
|
272
|
+
)
|
|
116
273
|
)
|
|
117
274
|
|
|
118
275
|
return tools
|
|
@@ -124,36 +281,24 @@ class Server:
|
|
|
124
281
|
retries: int = 2,
|
|
125
282
|
delay: float = 1.0,
|
|
126
283
|
) -> Any:
|
|
127
|
-
"""
|
|
128
|
-
Execute a tool with retry mechanism.
|
|
129
|
-
|
|
130
|
-
:param tool_name: str - Name of the tool to execute
|
|
131
|
-
:param arguments: dict[str, Any] - Tool arguments
|
|
132
|
-
:param retries: int - Number of retry attempts
|
|
133
|
-
:param delay: float - Delay between retries in seconds
|
|
134
|
-
:return: Any - Tool execution result
|
|
135
|
-
:raises: RuntimeError - If server is not initialized
|
|
136
|
-
:raises: ConnectionError - If connection to server fails
|
|
137
|
-
:raises: ValueError - If tool execution fails
|
|
138
|
-
"""
|
|
139
284
|
if not self.session:
|
|
140
285
|
raise RuntimeError(f"Server {self.name} not initialized")
|
|
141
286
|
|
|
142
287
|
attempt = 0
|
|
143
288
|
while attempt < retries:
|
|
144
289
|
try:
|
|
145
|
-
|
|
290
|
+
Console.write_stdout(f"Executing {tool_name}...")
|
|
146
291
|
result = await self.session.call_tool(tool_name, arguments)
|
|
147
292
|
return result
|
|
148
293
|
|
|
149
294
|
except (RuntimeError, ConnectionError, ValueError) as e:
|
|
150
295
|
attempt += 1
|
|
151
|
-
|
|
152
|
-
|
|
296
|
+
Console.write_exception(
|
|
297
|
+
"Error executing tool:", e, f". Attempt {attempt} of {retries}.\n"
|
|
153
298
|
)
|
|
154
299
|
if attempt < retries:
|
|
155
|
-
|
|
300
|
+
Console.write_stdout(f"Retrying in {delay} seconds...")
|
|
156
301
|
await asyncio.sleep(delay)
|
|
157
302
|
else:
|
|
158
|
-
|
|
303
|
+
Console.write_stdout("Max retries reached. Failing.")
|
|
159
304
|
raise
|