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.
- 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
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import traceback
|
|
2
|
+
from difflib import SequenceMatcher
|
|
3
|
+
from typing import List, Optional, Tuple
|
|
4
|
+
|
|
5
|
+
from pygeai import logger
|
|
6
|
+
from pygeai.cli.commands import Command, Option
|
|
7
|
+
from pygeai.core.utils.console import Console
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
FUZZY_MATCH_THRESHOLD = 0.6
|
|
11
|
+
MAX_FUZZY_SUGGESTIONS = 3
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ExitCode:
|
|
15
|
+
SUCCESS = 0
|
|
16
|
+
USER_INPUT_ERROR = 1
|
|
17
|
+
MISSING_REQUIREMENT = 2
|
|
18
|
+
SERVICE_ERROR = 3
|
|
19
|
+
KEYBOARD_INTERRUPT = 130
|
|
20
|
+
UNEXPECTED_ERROR = 255
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ErrorHandler:
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def format_error(
|
|
27
|
+
error_type: str,
|
|
28
|
+
message: str,
|
|
29
|
+
suggestion: Optional[str] = None,
|
|
30
|
+
show_help: bool = True,
|
|
31
|
+
example: Optional[str] = None
|
|
32
|
+
) -> str:
|
|
33
|
+
"""
|
|
34
|
+
Formats an error message with optional suggestion and example.
|
|
35
|
+
|
|
36
|
+
:param error_type: str - Type of error (e.g., "Unknown Command").
|
|
37
|
+
:param message: str - The error message.
|
|
38
|
+
:param suggestion: Optional[str] - Suggested fix or next steps.
|
|
39
|
+
:param show_help: bool - Whether to show help command hint.
|
|
40
|
+
:param example: Optional[str] - Example of correct usage.
|
|
41
|
+
:return: str - Formatted error message.
|
|
42
|
+
"""
|
|
43
|
+
output = f"ERROR [{error_type}]: {message}"
|
|
44
|
+
|
|
45
|
+
if suggestion:
|
|
46
|
+
output += f"\n → {suggestion}"
|
|
47
|
+
|
|
48
|
+
if example:
|
|
49
|
+
output += f"\n\n Example:\n {example}"
|
|
50
|
+
|
|
51
|
+
if show_help:
|
|
52
|
+
output += "\n\nRun 'geai help' for usage information."
|
|
53
|
+
|
|
54
|
+
return output
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def find_similar_items(
|
|
58
|
+
item: str,
|
|
59
|
+
available_items: List[str],
|
|
60
|
+
threshold: float = FUZZY_MATCH_THRESHOLD
|
|
61
|
+
) -> List[str]:
|
|
62
|
+
"""
|
|
63
|
+
Finds similar items using fuzzy string matching.
|
|
64
|
+
|
|
65
|
+
:param item: str - The item to match against.
|
|
66
|
+
:param available_items: List[str] - List of available items.
|
|
67
|
+
:param threshold: float - Minimum similarity ratio (0.0 to 1.0).
|
|
68
|
+
:return: List[str] - List of similar items, up to MAX_FUZZY_SUGGESTIONS.
|
|
69
|
+
"""
|
|
70
|
+
similarities: List[Tuple[str, float]] = []
|
|
71
|
+
for available in available_items:
|
|
72
|
+
ratio = SequenceMatcher(None, item.lower(), available.lower()).ratio()
|
|
73
|
+
if ratio >= threshold:
|
|
74
|
+
similarities.append((available, ratio))
|
|
75
|
+
|
|
76
|
+
similarities.sort(key=lambda x: x[1], reverse=True)
|
|
77
|
+
return [item[0] for item in similarities[:MAX_FUZZY_SUGGESTIONS]]
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def get_available_commands(commands: List[Command]) -> List[str]:
|
|
81
|
+
all_identifiers = []
|
|
82
|
+
for cmd in commands:
|
|
83
|
+
all_identifiers.extend(cmd.identifiers)
|
|
84
|
+
return all_identifiers
|
|
85
|
+
|
|
86
|
+
@staticmethod
|
|
87
|
+
def get_available_options(options: List[Option]) -> List[str]:
|
|
88
|
+
all_identifiers = []
|
|
89
|
+
for opt in options:
|
|
90
|
+
all_identifiers.extend(opt.identifiers)
|
|
91
|
+
return all_identifiers
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def handle_unknown_command(command: str, available_commands: List[Command]) -> str:
|
|
95
|
+
cmd_identifiers = ErrorHandler.get_available_commands(available_commands)
|
|
96
|
+
similar = ErrorHandler.find_similar_items(command, cmd_identifiers)
|
|
97
|
+
|
|
98
|
+
message = f"'{command}' is not a valid command."
|
|
99
|
+
|
|
100
|
+
if similar:
|
|
101
|
+
suggestion = f"Did you mean: {', '.join(similar)}?"
|
|
102
|
+
else:
|
|
103
|
+
suggestion = f"Available commands: {', '.join(sorted(set([cmd.identifiers[0] for cmd in available_commands])))}"
|
|
104
|
+
|
|
105
|
+
return ErrorHandler.format_error("Unknown Command", message, suggestion)
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
def handle_unknown_option(option: str, available_options: List[Option]) -> str:
|
|
109
|
+
opt_identifiers = ErrorHandler.get_available_options(available_options)
|
|
110
|
+
similar = ErrorHandler.find_similar_items(option, opt_identifiers)
|
|
111
|
+
|
|
112
|
+
message = f"'{option}' is not a valid option."
|
|
113
|
+
|
|
114
|
+
if similar:
|
|
115
|
+
suggestion = f"Did you mean: {', '.join(similar)}?"
|
|
116
|
+
else:
|
|
117
|
+
suggestion = f"Available options: {', '.join(sorted(set([opt.identifiers[0] for opt in available_options])))}"
|
|
118
|
+
|
|
119
|
+
return ErrorHandler.format_error("Unknown Option", message, suggestion)
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def handle_missing_requirement(requirement_message: str) -> str:
|
|
123
|
+
message = requirement_message
|
|
124
|
+
suggestion = "Please provide all required parameters."
|
|
125
|
+
return ErrorHandler.format_error("Missing Requirement", message, suggestion)
|
|
126
|
+
|
|
127
|
+
@staticmethod
|
|
128
|
+
def handle_invalid_agent(error_message: str) -> str:
|
|
129
|
+
message = f"Failed to retrieve or validate the agent.\n Details: {error_message}"
|
|
130
|
+
suggestion = "Check your agent configuration and ensure the agent exists."
|
|
131
|
+
return ErrorHandler.format_error("Invalid Agent", message, suggestion)
|
|
132
|
+
|
|
133
|
+
@staticmethod
|
|
134
|
+
def handle_wrong_argument(error_message: str, usage: str) -> str:
|
|
135
|
+
Console.write_stderr(f"usage: {usage}")
|
|
136
|
+
message = error_message
|
|
137
|
+
suggestion = "Check the command syntax and try again."
|
|
138
|
+
return ErrorHandler.format_error("Invalid Argument", message, suggestion)
|
|
139
|
+
|
|
140
|
+
@staticmethod
|
|
141
|
+
def handle_keyboard_interrupt() -> str:
|
|
142
|
+
return "\n\nOperation cancelled by user."
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
def handle_unexpected_error(exception: Exception) -> str:
|
|
146
|
+
logger.error(f"Unexpected error occurred: {exception}")
|
|
147
|
+
logger.error(traceback.format_exc())
|
|
148
|
+
|
|
149
|
+
message = "An unexpected error occurred. This may be a bug."
|
|
150
|
+
suggestion = f"Please report this issue to geai-sdk@globant.com with the following details:\n Error: {str(exception)}\n Run with geai-dbg for more details."
|
|
151
|
+
return ErrorHandler.format_error("Critical Error", message, suggestion, show_help=False)
|
pygeai/cli/geai.py
CHANGED
|
@@ -1,37 +1,104 @@
|
|
|
1
1
|
import sys
|
|
2
|
+
import logging
|
|
3
|
+
from typing import List, Optional
|
|
2
4
|
|
|
3
5
|
from pygeai import logger
|
|
4
6
|
from pygeai.cli.commands.base import base_commands, base_options
|
|
5
7
|
from pygeai.cli.commands import ArgumentsEnum, Command
|
|
6
8
|
from pygeai.cli.parsers import CommandParser
|
|
7
9
|
from pygeai.cli.texts.help import CLI_USAGE
|
|
10
|
+
from pygeai.cli.error_handler import ErrorHandler, ExitCode
|
|
8
11
|
from pygeai.core.base.session import get_session
|
|
9
|
-
from pygeai.core.common.exceptions import UnknownArgumentError, MissingRequirementException, WrongArgumentError
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
from pygeai.core.common.exceptions import UnknownArgumentError, MissingRequirementException, WrongArgumentError, \
|
|
13
|
+
InvalidAgentException
|
|
14
|
+
from pygeai.core.utils.console import Console
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def setup_verbose_logging() -> None:
|
|
18
|
+
"""
|
|
19
|
+
Configure verbose logging for the CLI.
|
|
20
|
+
|
|
21
|
+
Sets up a console handler with DEBUG level logging and a formatted output
|
|
22
|
+
that includes timestamp, logger name, level, and message.
|
|
23
|
+
"""
|
|
24
|
+
if logger.handlers:
|
|
25
|
+
for handler in logger.handlers:
|
|
26
|
+
if not isinstance(handler, logging.NullHandler):
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
logger.setLevel(logging.DEBUG)
|
|
30
|
+
console_handler = logging.StreamHandler(sys.stderr)
|
|
31
|
+
console_handler.setLevel(logging.DEBUG)
|
|
32
|
+
formatter = logging.Formatter(
|
|
33
|
+
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
34
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
|
35
|
+
)
|
|
36
|
+
console_handler.setFormatter(formatter)
|
|
37
|
+
logger.addHandler(console_handler)
|
|
38
|
+
logger.propagate = False
|
|
39
|
+
logger.debug("Verbose mode enabled")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def main() -> int:
|
|
43
|
+
"""
|
|
44
|
+
Main entry point for the GEAI CLI application.
|
|
45
|
+
|
|
46
|
+
:return: int - Exit code indicating success or error.
|
|
47
|
+
"""
|
|
48
|
+
try:
|
|
49
|
+
driver = CLIDriver()
|
|
50
|
+
return driver.main()
|
|
51
|
+
except MissingRequirementException as e:
|
|
52
|
+
error_msg = ErrorHandler.handle_missing_requirement(str(e))
|
|
53
|
+
Console.write_stderr(error_msg)
|
|
54
|
+
return ExitCode.MISSING_REQUIREMENT
|
|
15
55
|
|
|
16
56
|
|
|
17
57
|
class CLIDriver:
|
|
18
|
-
|
|
19
|
-
|
|
58
|
+
"""
|
|
59
|
+
Main CLI driver for the GEAI command-line interface.
|
|
60
|
+
|
|
61
|
+
The CLIDriver orchestrates command parsing, execution, and error handling
|
|
62
|
+
for all GEAI CLI operations. It supports multi-profile session management
|
|
63
|
+
via the --alias flag and provides comprehensive error handling with
|
|
64
|
+
user-friendly messages.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
def __init__(self, session=None, credentials_file=None) -> None:
|
|
20
68
|
"""
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
69
|
+
Initialize the CLI driver with optional session and credentials file.
|
|
70
|
+
|
|
71
|
+
Sets up the session to be used while running commands, either with a
|
|
72
|
+
specified alias, environment variables, or function parameters.
|
|
73
|
+
Once the session is defined, it won't change during the execution.
|
|
74
|
+
|
|
75
|
+
:param session: Optional session object. If None, uses 'default' or
|
|
76
|
+
alias-specified session from command-line arguments.
|
|
77
|
+
:param credentials_file: Optional path to custom credentials file.
|
|
24
78
|
"""
|
|
79
|
+
from pygeai.core.common.config import get_settings
|
|
80
|
+
|
|
25
81
|
arguments = sys.argv
|
|
82
|
+
|
|
83
|
+
if credentials_file or "--credentials" in arguments or "--creds" in arguments:
|
|
84
|
+
if not credentials_file:
|
|
85
|
+
credentials_file = self._get_credentials_file(arguments)
|
|
86
|
+
get_settings(credentials_file=credentials_file)
|
|
87
|
+
logger.debug(f"Using custom credentials file: {credentials_file}")
|
|
88
|
+
|
|
26
89
|
if "-a" in arguments or "--alias" in arguments:
|
|
27
90
|
alias = self._get_alias(arguments)
|
|
28
91
|
session = get_session(alias)
|
|
29
92
|
|
|
30
|
-
self.session = get_session() if session is None else session
|
|
93
|
+
self.session = get_session("default") if session is None else session
|
|
31
94
|
|
|
32
|
-
def _get_alias(self, arguments:
|
|
95
|
+
def _get_alias(self, arguments: List[str]) -> str:
|
|
33
96
|
"""
|
|
34
|
-
Retrieves and removes alias and alias flag from argument list
|
|
97
|
+
Retrieves and removes alias and alias flag from argument list.
|
|
98
|
+
|
|
99
|
+
:param arguments: List[str] - Command line arguments.
|
|
100
|
+
:return: str - The alias value.
|
|
101
|
+
:raises ValueError: If alias flag is present but no value provided.
|
|
35
102
|
"""
|
|
36
103
|
alias_index = None
|
|
37
104
|
|
|
@@ -43,64 +110,136 @@ class CLIDriver:
|
|
|
43
110
|
_ = arguments.pop(alias_index)
|
|
44
111
|
alias = arguments.pop(alias_index)
|
|
45
112
|
return alias
|
|
113
|
+
|
|
114
|
+
def _get_credentials_file(self, arguments: List[str]) -> str:
|
|
115
|
+
"""
|
|
116
|
+
Retrieves and removes credentials file path and flag from argument list.
|
|
117
|
+
|
|
118
|
+
:param arguments: List[str] - Command line arguments.
|
|
119
|
+
:return: str - The credentials file path.
|
|
120
|
+
:raises ValueError: If credentials flag is present but no value provided.
|
|
121
|
+
"""
|
|
122
|
+
creds_index = None
|
|
46
123
|
|
|
47
|
-
|
|
124
|
+
if "--credentials" in arguments:
|
|
125
|
+
creds_index = arguments.index("--credentials")
|
|
126
|
+
elif "--creds" in arguments:
|
|
127
|
+
creds_index = arguments.index("--creds")
|
|
128
|
+
|
|
129
|
+
_ = arguments.pop(creds_index)
|
|
130
|
+
credentials_file = arguments.pop(creds_index)
|
|
131
|
+
return credentials_file
|
|
132
|
+
|
|
133
|
+
def main(self, args: Optional[List[str]] = None) -> int:
|
|
48
134
|
"""
|
|
49
|
-
|
|
135
|
+
Execute the CLI command based on provided arguments.
|
|
136
|
+
|
|
137
|
+
If no argument is received, it defaults to help (first command in base_command list).
|
|
50
138
|
Otherwise, it parses the arguments received to identify the appropriate command and either
|
|
51
139
|
execute it or parse it again to detect subcommands.
|
|
140
|
+
|
|
141
|
+
:param args: Optional[List[str]] - Command line arguments. If None, uses sys.argv.
|
|
142
|
+
:return: int - Exit code (0 for success, non-zero for errors).
|
|
52
143
|
"""
|
|
53
144
|
try:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
145
|
+
argv = sys.argv if args is None else args
|
|
146
|
+
|
|
147
|
+
if "--verbose" in argv or "-v" in argv:
|
|
148
|
+
setup_verbose_logging()
|
|
149
|
+
argv_copy = [a for a in argv if a not in ("--verbose", "-v")]
|
|
150
|
+
if args is None:
|
|
151
|
+
sys.argv = argv_copy
|
|
152
|
+
else:
|
|
153
|
+
args = argv_copy
|
|
154
|
+
argv = argv_copy
|
|
155
|
+
|
|
156
|
+
logger.debug(f"Running geai with: {' '.join(a for a in argv)}")
|
|
157
|
+
logger.debug(f"Session: {self.session.alias if hasattr(self.session, 'alias') else 'default'}")
|
|
158
|
+
|
|
159
|
+
if len(argv) > 1:
|
|
160
|
+
arg = argv[1] if args is None else args[1]
|
|
161
|
+
arguments = argv[2:] if args is None else args[2:]
|
|
162
|
+
|
|
163
|
+
logger.debug(f"Identifying command for argument: {arg}")
|
|
59
164
|
command = CommandParser(base_commands, base_options).identify_command(arg)
|
|
165
|
+
logger.debug(f"Command identified: {command.name}")
|
|
60
166
|
else:
|
|
167
|
+
logger.debug("No arguments provided, defaulting to help command")
|
|
61
168
|
command = base_commands[0]
|
|
62
169
|
arguments = []
|
|
63
170
|
|
|
64
171
|
self.process_command(command, arguments)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
172
|
+
logger.debug(f"Command completed successfully")
|
|
173
|
+
return ExitCode.SUCCESS
|
|
174
|
+
except UnknownArgumentError as e:
|
|
175
|
+
if hasattr(e, 'available_commands') and e.available_commands:
|
|
176
|
+
error_msg = ErrorHandler.handle_unknown_command(e.arg, e.available_commands)
|
|
177
|
+
elif hasattr(e, 'available_options') and e.available_options:
|
|
178
|
+
error_msg = ErrorHandler.handle_unknown_option(e.arg, e.available_options)
|
|
179
|
+
else:
|
|
180
|
+
error_msg = ErrorHandler.format_error("Unknown Argument", str(e))
|
|
181
|
+
|
|
182
|
+
Console.write_stderr(error_msg)
|
|
183
|
+
return ExitCode.USER_INPUT_ERROR
|
|
184
|
+
except WrongArgumentError as e:
|
|
185
|
+
error_msg = ErrorHandler.handle_wrong_argument(str(e), CLI_USAGE)
|
|
186
|
+
Console.write_stderr(error_msg)
|
|
187
|
+
return ExitCode.USER_INPUT_ERROR
|
|
69
188
|
except MissingRequirementException as e:
|
|
70
|
-
|
|
189
|
+
error_msg = ErrorHandler.handle_missing_requirement(str(e))
|
|
190
|
+
Console.write_stderr(error_msg)
|
|
191
|
+
return ExitCode.MISSING_REQUIREMENT
|
|
192
|
+
except InvalidAgentException as e:
|
|
193
|
+
error_msg = ErrorHandler.handle_invalid_agent(str(e))
|
|
194
|
+
Console.write_stderr(error_msg)
|
|
195
|
+
return ExitCode.SERVICE_ERROR
|
|
71
196
|
except KeyboardInterrupt:
|
|
72
|
-
|
|
197
|
+
message = ErrorHandler.handle_keyboard_interrupt()
|
|
198
|
+
Console.write_stdout(message)
|
|
199
|
+
return ExitCode.KEYBOARD_INTERRUPT
|
|
73
200
|
except Exception as e:
|
|
74
|
-
|
|
75
|
-
|
|
201
|
+
error_msg = ErrorHandler.handle_unexpected_error(e)
|
|
202
|
+
Console.write_stderr(error_msg)
|
|
203
|
+
return ExitCode.UNEXPECTED_ERROR
|
|
76
204
|
|
|
77
205
|
def process_command(self, command: Command, arguments: list[str]):
|
|
78
206
|
"""
|
|
79
207
|
If the command has no action associated with it, it means it has subcommands, so it must be parsed again
|
|
80
208
|
to identify it.
|
|
81
209
|
"""
|
|
210
|
+
logger.debug(f"Processing command: {command.name}, arguments: {arguments}")
|
|
211
|
+
|
|
82
212
|
if command.action:
|
|
83
213
|
if command.additional_args == ArgumentsEnum.NOT_AVAILABLE:
|
|
214
|
+
logger.debug(f"Executing command {command.name} without arguments")
|
|
84
215
|
command.action()
|
|
85
216
|
else:
|
|
217
|
+
logger.debug(f"Extracting options for command {command.name}")
|
|
86
218
|
option_list = CommandParser(base_commands, command.options).extract_option_list(arguments)
|
|
219
|
+
logger.debug(f"Options extracted: {len(option_list)} items")
|
|
87
220
|
command.action(option_list)
|
|
88
221
|
elif command.subcommands:
|
|
89
222
|
subcommand_arg = arguments[0] if len(arguments) > 0 else None
|
|
90
223
|
subcommand_arguments = arguments[1:] if len(arguments) > 1 else []
|
|
91
|
-
|
|
224
|
+
|
|
225
|
+
logger.debug(f"Command has subcommands, identifying: {subcommand_arg}")
|
|
226
|
+
|
|
92
227
|
available_commands = command.subcommands
|
|
93
228
|
available_options = command.options
|
|
94
229
|
parser = CommandParser(available_commands, available_options)
|
|
95
230
|
|
|
96
231
|
if not subcommand_arg:
|
|
232
|
+
logger.debug(f"No subcommand specified, using default: {command.subcommands[0].name}")
|
|
97
233
|
subcommand = command.subcommands[0]
|
|
98
234
|
else:
|
|
99
235
|
subcommand = parser.identify_command(subcommand_arg)
|
|
236
|
+
logger.debug(f"Subcommand identified: {subcommand.name}")
|
|
100
237
|
|
|
101
238
|
if subcommand.additional_args == ArgumentsEnum.NOT_AVAILABLE:
|
|
239
|
+
logger.debug(f"Executing subcommand {subcommand.name} without arguments")
|
|
102
240
|
subcommand.action()
|
|
103
241
|
else:
|
|
242
|
+
logger.debug(f"Extracting options for subcommand {subcommand.name}")
|
|
104
243
|
option_list = CommandParser(None, subcommand.options).extract_option_list(subcommand_arguments)
|
|
244
|
+
logger.debug(f"Options extracted: {len(option_list)} items")
|
|
105
245
|
subcommand.action(option_list)
|
|
106
|
-
|
pygeai/cli/geai_proxy.py
CHANGED
|
@@ -2,13 +2,45 @@
|
|
|
2
2
|
import json
|
|
3
3
|
import asyncio
|
|
4
4
|
import sys
|
|
5
|
+
from typing import Final
|
|
5
6
|
import argparse
|
|
6
7
|
import uuid
|
|
7
8
|
import yaml
|
|
8
9
|
from pygeai import logger
|
|
9
10
|
from pygeai.proxy.managers import ServerManager
|
|
10
11
|
from pygeai.proxy.config import ProxySettingsManager
|
|
11
|
-
|
|
12
|
+
from pygeai.admin.clients import AdminClient
|
|
13
|
+
from pygeai.core.utils.console import Console, StreamWriter
|
|
14
|
+
class CustomProxyStream(StreamWriter):
|
|
15
|
+
"""
|
|
16
|
+
Custom stream writer for proxy output with color support for TTY terminals.
|
|
17
|
+
"""
|
|
18
|
+
IS_TTY: Final[bool] = sys.stderr.isatty()
|
|
19
|
+
RED: Final[str] = "\033[91m" if IS_TTY else ""
|
|
20
|
+
RESET: Final[str] = "\033[0m" if IS_TTY else ""
|
|
21
|
+
|
|
22
|
+
def write_stdout(self, message: str, end: str = "\n"):
|
|
23
|
+
"""
|
|
24
|
+
Write message to stdout and log as info.
|
|
25
|
+
"""
|
|
26
|
+
sys.stdout.write(f"{message}{end}")
|
|
27
|
+
logger.info(f"{message}{end}")
|
|
28
|
+
|
|
29
|
+
def write_stderr(self, message: str, end: str = "\n"):
|
|
30
|
+
"""
|
|
31
|
+
Write message to stderr with red color and log as error.
|
|
32
|
+
"""
|
|
33
|
+
sys.stderr.write(f"{self.RED}{message}{self.RESET}{end}")
|
|
34
|
+
logger.error(f"{message}{end}")
|
|
35
|
+
|
|
36
|
+
def write_exception(self, message: str, exception: Exception, end: str = "\n"):
|
|
37
|
+
"""
|
|
38
|
+
Write exception message to stderr with red color and log as exception.
|
|
39
|
+
"""
|
|
40
|
+
sys.stderr.write(f"{self.RED}{message}{self.RESET} {str(exception)}{end}")
|
|
41
|
+
logger.exception(f"{message}{end}", exception)
|
|
42
|
+
|
|
43
|
+
Console.set_writer(CustomProxyStream())
|
|
12
44
|
|
|
13
45
|
def load_config(path: str) -> list:
|
|
14
46
|
"""
|
|
@@ -22,13 +54,22 @@ def load_config(path: str) -> list:
|
|
|
22
54
|
try:
|
|
23
55
|
with open(path, 'r', encoding='utf-8') as f:
|
|
24
56
|
config = yaml.safe_load(f) if path.endswith(('.yaml', '.yml')) else json.load(f)
|
|
25
|
-
if 'mcpServers' not in config:
|
|
26
|
-
raise ValueError(f"Config file '{path}' must contain 'mcpServers' key")
|
|
27
|
-
|
|
28
57
|
servers = []
|
|
29
|
-
|
|
30
|
-
server_cfg['
|
|
31
|
-
|
|
58
|
+
if 'mcpServers' in config:
|
|
59
|
+
for name, server_cfg in config['mcpServers'].items():
|
|
60
|
+
server_cfg['name'] = name
|
|
61
|
+
server_cfg['type'] = 'mcp'
|
|
62
|
+
servers.append(server_cfg)
|
|
63
|
+
|
|
64
|
+
if 'a2aServers' in config:
|
|
65
|
+
for name, server_cfg in config['a2aServers'].items():
|
|
66
|
+
server_cfg['name'] = name
|
|
67
|
+
server_cfg['type'] = 'a2a'
|
|
68
|
+
servers.append(server_cfg)
|
|
69
|
+
|
|
70
|
+
if not 'a2aServers' in config and not 'mcpServers' in config:
|
|
71
|
+
Console.write_stderr("Error: MCP servers or A2A servers are required")
|
|
72
|
+
|
|
32
73
|
return servers
|
|
33
74
|
except FileNotFoundError as exc:
|
|
34
75
|
raise FileNotFoundError(f"Configuration file '{path}' not found") from exc
|
|
@@ -58,12 +99,12 @@ def configure_proxy_settings(settings: ProxySettingsManager, args: argparse.Name
|
|
|
58
99
|
#first_time = all(not x for x in [ current_id, current_name, current_description, current_api_key, current_base_url])
|
|
59
100
|
|
|
60
101
|
if not only_missing or any(not x for x in [current_id, current_name, current_description, current_api_key, current_base_url]):
|
|
61
|
-
|
|
102
|
+
Console.write_stdout("# Configuring GEAI proxy settings...")
|
|
62
103
|
|
|
63
104
|
if not current_id:
|
|
64
105
|
current_id = uuid.uuid4()
|
|
65
106
|
settings.set_proxy_id(current_id, alias)
|
|
66
|
-
|
|
107
|
+
Console.write_stdout(f"Generated new proxy ID: {current_id}")
|
|
67
108
|
|
|
68
109
|
if not only_missing or not current_id:
|
|
69
110
|
server_id = input(f"-> Insert proxy ID (UUID) (Current: {current_id}, Leave empty to keep): ")
|
|
@@ -71,7 +112,7 @@ def configure_proxy_settings(settings: ProxySettingsManager, args: argparse.Name
|
|
|
71
112
|
try:
|
|
72
113
|
settings.set_proxy_id(uuid.UUID(server_id), alias)
|
|
73
114
|
except ValueError:
|
|
74
|
-
|
|
115
|
+
Console.write_stdout("Error: Invalid UUID format")
|
|
75
116
|
return
|
|
76
117
|
if not only_missing or not current_api_key:
|
|
77
118
|
if current_api_key:
|
|
@@ -122,7 +163,7 @@ def configure_proxy_settings(settings: ProxySettingsManager, args: argparse.Name
|
|
|
122
163
|
try:
|
|
123
164
|
settings.set_proxy_id(uuid.UUID(args.proxy_id), alias)
|
|
124
165
|
except ValueError:
|
|
125
|
-
|
|
166
|
+
Console.write_stderr("Error: Invalid UUID format for proxy ID")
|
|
126
167
|
return
|
|
127
168
|
elif not only_missing or not settings.get_proxy_id(alias):
|
|
128
169
|
# Generate new UUID if no ID is provided
|
|
@@ -130,7 +171,7 @@ def configure_proxy_settings(settings: ProxySettingsManager, args: argparse.Name
|
|
|
130
171
|
if not current_id:
|
|
131
172
|
current_id = uuid.uuid4()
|
|
132
173
|
settings.set_proxy_id(current_id, alias)
|
|
133
|
-
|
|
174
|
+
Console.write_stdout(f"Generated new proxy ID: {current_id}")
|
|
134
175
|
|
|
135
176
|
if args.proxy_name:
|
|
136
177
|
settings.set_proxy_name(args.proxy_name, alias)
|
|
@@ -151,7 +192,7 @@ def configure_proxy_settings(settings: ProxySettingsManager, args: argparse.Name
|
|
|
151
192
|
#elif not only_missing or not settings.get_proxy_affinity(alias):
|
|
152
193
|
# pass # Affinity is not requested if not in args and only_missing is True
|
|
153
194
|
|
|
154
|
-
|
|
195
|
+
Console.write_stdout(f"Proxy settings for alias '{alias}' saved successfully!")
|
|
155
196
|
|
|
156
197
|
|
|
157
198
|
async def main():
|
|
@@ -160,6 +201,7 @@ async def main():
|
|
|
160
201
|
|
|
161
202
|
:return: int - Exit code (0 for success, 1 for error)
|
|
162
203
|
"""
|
|
204
|
+
|
|
163
205
|
logger.info("Starting GEAI proxy CLI")
|
|
164
206
|
parser = argparse.ArgumentParser(
|
|
165
207
|
description="Proxy CLI between GEAI and MCP servers",
|
|
@@ -183,7 +225,7 @@ async def main():
|
|
|
183
225
|
else:
|
|
184
226
|
settings.set_current_alias(args.alias)
|
|
185
227
|
|
|
186
|
-
|
|
228
|
+
Console.write_stdout(f"Using alias: {args.alias}")
|
|
187
229
|
|
|
188
230
|
only_configure = args.configure
|
|
189
231
|
while True:
|
|
@@ -196,35 +238,54 @@ async def main():
|
|
|
196
238
|
]):
|
|
197
239
|
|
|
198
240
|
if args.alias not in settings.config:
|
|
199
|
-
|
|
241
|
+
Console.write_stdout(f"Created new alias '{args.alias}' in the configuration file.","\n\n")
|
|
200
242
|
settings.config.add_section(args.alias)
|
|
201
243
|
else:
|
|
202
244
|
if not args.configure:
|
|
203
|
-
|
|
245
|
+
Console.write_stdout("\nProxy configuration required. Please complete all required fields.","\n\n")
|
|
204
246
|
else:
|
|
205
|
-
|
|
247
|
+
Console.write_stdout("\nProxy configuration.","\n\n")
|
|
206
248
|
|
|
207
249
|
if (key := settings.get_api_key(args.alias)):
|
|
208
|
-
|
|
250
|
+
Console.write_stdout(f"API_KEY: {key}")
|
|
209
251
|
if (url := settings.get_base_url(args.alias)):
|
|
210
|
-
|
|
252
|
+
Console.write_stdout(f"BASE_URL: {url}")
|
|
211
253
|
|
|
212
|
-
|
|
254
|
+
Console.write_stdout("")
|
|
213
255
|
configure_proxy_settings(settings, args, only_missing=not args.configure)
|
|
214
256
|
args.configure = False
|
|
215
257
|
else:
|
|
216
258
|
break
|
|
217
259
|
|
|
218
260
|
if only_configure:
|
|
219
|
-
|
|
261
|
+
Console.write_stdout("Proxy configuration completed successfully!")
|
|
220
262
|
return 0
|
|
221
263
|
|
|
222
264
|
if not args.config:
|
|
223
|
-
|
|
265
|
+
Console.write_stderr("Error: MCP servers Configuration file path is required")
|
|
224
266
|
return 1
|
|
225
267
|
|
|
226
268
|
servers_cfg = load_config(args.config)
|
|
227
269
|
server_manager = ServerManager(servers_cfg, settings)
|
|
270
|
+
|
|
271
|
+
try:
|
|
272
|
+
Console.write_stdout(f"Contacting Globant Enteprise AI at {settings.get_base_url(args.alias)}...","")
|
|
273
|
+
admin_client = AdminClient(api_key=settings.get_api_key(args.alias), base_url=settings.get_base_url(args.alias))
|
|
274
|
+
result = admin_client.validate_api_token()
|
|
275
|
+
if result.get('errors'):
|
|
276
|
+
Console.write_stdout("Invalid API token")
|
|
277
|
+
for error in result.get('errors'):
|
|
278
|
+
Console.write_stderr(f"{error.get('description')}")
|
|
279
|
+
|
|
280
|
+
return 1
|
|
281
|
+
else:
|
|
282
|
+
Console.write_stdout(f" Done!")
|
|
283
|
+
Console.write_stdout(f"Organization: {result.get('organizationName')}")
|
|
284
|
+
Console.write_stdout(f"Project: {result.get('projectName')}")
|
|
285
|
+
except Exception as e:
|
|
286
|
+
Console.write_exception("Error:", e, "\n")
|
|
287
|
+
return 1
|
|
288
|
+
|
|
228
289
|
await server_manager.start()
|
|
229
290
|
|
|
230
291
|
return 0
|
|
@@ -239,10 +300,10 @@ def cli_entry() -> int:
|
|
|
239
300
|
try:
|
|
240
301
|
return asyncio.run(main())
|
|
241
302
|
except KeyboardInterrupt:
|
|
242
|
-
|
|
303
|
+
Console.write_stdout("\nExiting...")
|
|
243
304
|
return 0
|
|
244
305
|
except (RuntimeError, ConnectionError, ValueError) as e:
|
|
245
|
-
|
|
306
|
+
Console.write_exception("Error:", e, "\n")
|
|
246
307
|
return 1
|
|
247
308
|
|
|
248
309
|
|
|
@@ -251,7 +312,7 @@ if __name__ == "__main__":
|
|
|
251
312
|
import os
|
|
252
313
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
253
314
|
config_path = os.path.join(os.path.dirname(script_dir), "proxy", "sample-mcp-config.json")
|
|
254
|
-
|
|
315
|
+
Console.write_stdout(f"Config file path: {config_path}")
|
|
255
316
|
|
|
256
317
|
sys.argv.extend([config_path])
|
|
257
318
|
sys.exit(cli_entry())
|