pygeai 0.1.6__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 +11 -2
- 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 +48 -57
- pygeai/assistant/data/__init__.py +0 -0
- pygeai/assistant/data/clients.py +15 -0
- pygeai/assistant/data_analyst/__init__.py +0 -0
- pygeai/assistant/data_analyst/clients.py +75 -0
- pygeai/assistant/data_analyst/endpoints.py +2 -0
- pygeai/assistant/endpoints.py +0 -2
- pygeai/assistant/managers.py +738 -0
- pygeai/assistant/mappers.py +153 -0
- pygeai/assistant/rag/clients.py +132 -21
- pygeai/assistant/rag/mappers.py +228 -0
- pygeai/assistant/rag/models.py +396 -0
- pygeai/assistant/rag/responses.py +10 -0
- pygeai/auth/__init__.py +0 -0
- pygeai/auth/clients.py +129 -0
- pygeai/auth/endpoints.py +6 -0
- pygeai/chat/clients.py +406 -31
- pygeai/chat/endpoints.py +3 -0
- pygeai/chat/iris.py +17 -0
- pygeai/chat/managers.py +64 -0
- 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 +9 -12
- pygeai/cli/commands/analytics.py +533 -0
- pygeai/cli/commands/assistant.py +11 -11
- pygeai/cli/commands/auth.py +299 -0
- pygeai/cli/commands/base.py +201 -7
- pygeai/cli/commands/chat.py +875 -14
- pygeai/cli/commands/common.py +30 -26
- pygeai/cli/commands/configuration.py +84 -9
- pygeai/cli/commands/docs.py +105 -0
- pygeai/cli/commands/embeddings.py +187 -0
- pygeai/cli/commands/evaluation.py +2069 -0
- pygeai/cli/commands/feedback.py +93 -0
- pygeai/cli/commands/files.py +312 -0
- pygeai/cli/commands/flows/__init__.py +0 -0
- pygeai/cli/commands/gam.py +349 -0
- pygeai/cli/commands/lab/__init__.py +0 -0
- pygeai/cli/commands/lab/ai_lab.py +4110 -0
- pygeai/cli/commands/lab/common.py +135 -0
- 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 +164 -0
- pygeai/cli/commands/migrate.py +1198 -0
- pygeai/cli/commands/options.py +86 -0
- pygeai/cli/commands/organization.py +560 -98
- pygeai/cli/commands/rag.py +306 -10
- pygeai/cli/commands/rerank.py +108 -0
- pygeai/cli/commands/secrets.py +357 -0
- pygeai/cli/commands/usage_limits.py +583 -0
- pygeai/cli/commands/validators.py +209 -0
- pygeai/cli/commands/version.py +44 -0
- pygeai/cli/error_handler.py +151 -0
- pygeai/cli/geai.py +171 -30
- pygeai/cli/geai_proxy.py +318 -0
- pygeai/cli/install_man.py +107 -0
- pygeai/cli/parsers.py +78 -25
- pygeai/cli/texts/help.py +712 -55
- pygeai/core/__init__.py +9 -1
- pygeai/core/base/clients.py +61 -10
- pygeai/core/base/mappers.py +208 -30
- pygeai/core/base/models.py +8 -308
- pygeai/core/base/responses.py +18 -1
- pygeai/core/base/session.py +110 -17
- pygeai/core/common/config.py +98 -16
- pygeai/core/common/decorators.py +44 -0
- pygeai/core/common/exceptions.py +104 -4
- pygeai/core/embeddings/__init__.py +19 -0
- pygeai/core/embeddings/clients.py +93 -0
- pygeai/core/embeddings/endpoints.py +1 -0
- pygeai/core/embeddings/managers.py +62 -0
- pygeai/core/embeddings/mappers.py +52 -0
- pygeai/core/embeddings/models.py +14 -0
- pygeai/core/embeddings/responses.py +31 -0
- pygeai/core/feedback/__init__.py +0 -0
- pygeai/core/feedback/clients.py +50 -0
- pygeai/core/feedback/endpoints.py +1 -0
- pygeai/core/feedback/models.py +10 -0
- pygeai/core/files/__init__.py +0 -0
- pygeai/core/files/clients.py +156 -0
- pygeai/core/files/endpoints.py +5 -0
- pygeai/core/files/managers.py +224 -0
- pygeai/core/files/mappers.py +44 -0
- pygeai/core/files/models.py +24 -0
- pygeai/core/files/responses.py +19 -0
- pygeai/core/handlers.py +32 -0
- pygeai/core/llm/__init__.py +0 -0
- pygeai/core/llm/clients.py +53 -0
- pygeai/core/llm/endpoints.py +4 -0
- pygeai/core/models.py +799 -0
- pygeai/core/plugins/__init__.py +0 -0
- pygeai/core/plugins/clients.py +32 -0
- pygeai/core/plugins/endpoints.py +1 -0
- pygeai/core/plugins/models.py +86 -0
- pygeai/core/rerank/__init__.py +0 -0
- pygeai/core/rerank/clients.py +35 -0
- pygeai/core/rerank/endpoints.py +1 -0
- pygeai/core/rerank/managers.py +47 -0
- pygeai/core/rerank/mappers.py +23 -0
- pygeai/core/rerank/models.py +27 -0
- pygeai/core/responses.py +104 -0
- pygeai/core/secrets/__init__.py +0 -0
- pygeai/core/secrets/clients.py +212 -0
- pygeai/core/secrets/endpoints.py +7 -0
- pygeai/core/services/llm/__init__.py +0 -0
- pygeai/core/services/llm/model.py +186 -0
- pygeai/core/services/llm/providers.py +15 -0
- pygeai/core/services/response.py +18 -0
- pygeai/core/services/rest.py +311 -89
- 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 +870 -0
- pygeai/evaluation/__init__.py +0 -0
- pygeai/evaluation/clients.py +19 -0
- pygeai/evaluation/dataset/__init__.py +0 -0
- pygeai/evaluation/dataset/clients.py +514 -0
- pygeai/evaluation/dataset/endpoints.py +26 -0
- pygeai/evaluation/plan/__init__.py +0 -0
- pygeai/evaluation/plan/clients.py +302 -0
- pygeai/evaluation/plan/endpoints.py +16 -0
- pygeai/evaluation/result/__init__.py +0 -0
- pygeai/evaluation/result/clients.py +70 -0
- pygeai/evaluation/result/endpoints.py +2 -0
- pygeai/flows/__init__.py +0 -0
- pygeai/flows/endpoints.py +362 -0
- pygeai/flows/models.py +1304 -0
- pygeai/gam/__init__.py +0 -0
- pygeai/gam/clients.py +178 -0
- pygeai/gam/endpoints.py +4 -0
- pygeai/health/__init__.py +0 -0
- pygeai/health/clients.py +24 -0
- pygeai/health/endpoints.py +1 -0
- pygeai/lab/__init__.py +0 -0
- pygeai/lab/agents/__init__.py +0 -0
- pygeai/lab/agents/clients.py +426 -0
- pygeai/lab/agents/endpoints.py +12 -0
- pygeai/lab/agents/mappers.py +319 -0
- pygeai/lab/clients.py +24 -0
- pygeai/lab/constants.py +3 -0
- pygeai/lab/managers.py +1558 -0
- pygeai/lab/models.py +1719 -0
- pygeai/lab/processes/__init__.py +0 -0
- pygeai/lab/processes/clients.py +1051 -0
- pygeai/lab/processes/endpoints.py +26 -0
- pygeai/lab/processes/mappers.py +395 -0
- 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/__init__.py +0 -0
- pygeai/lab/strategies/clients.py +212 -0
- pygeai/lab/strategies/endpoints.py +5 -0
- pygeai/lab/strategies/mappers.py +58 -0
- pygeai/lab/tools/__init__.py +0 -0
- pygeai/lab/tools/clients.py +465 -0
- pygeai/lab/tools/endpoints.py +13 -0
- pygeai/lab/tools/mappers.py +131 -0
- pygeai/man/__init__.py +1 -0
- pygeai/man/man1/__init__.py +1 -0
- pygeai/man/man1/geai-proxy.1 +246 -0
- pygeai/man/man1/geai.1 +2615 -0
- pygeai/migration/__init__.py +33 -0
- pygeai/migration/strategies.py +603 -0
- pygeai/migration/tools.py +180 -0
- pygeai/organization/clients.py +246 -18
- pygeai/organization/endpoints.py +17 -8
- pygeai/organization/limits/__init__.py +0 -0
- pygeai/organization/limits/clients.py +281 -0
- pygeai/organization/limits/endpoints.py +15 -0
- pygeai/organization/limits/managers.py +331 -0
- pygeai/organization/limits/mappers.py +21 -0
- pygeai/organization/managers.py +537 -0
- pygeai/organization/mappers.py +111 -46
- pygeai/organization/responses.py +61 -11
- pygeai/proxy/__init__.py +0 -0
- pygeai/proxy/clients.py +216 -0
- pygeai/proxy/config.py +128 -0
- pygeai/proxy/managers.py +232 -0
- pygeai/proxy/servers.py +304 -0
- pygeai/proxy/tool.py +69 -0
- 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/__init__.py +0 -0
- pygeai/tests/assistants/rag/test_clients.py +346 -0
- pygeai/tests/assistants/rag/test_mappers.py +189 -0
- pygeai/tests/assistants/rag/test_models.py +292 -0
- pygeai/tests/assistants/test_clients.py +176 -80
- pygeai/tests/assistants/test_managers.py +198 -0
- pygeai/tests/assistants/test_mappers.py +111 -0
- 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/__init__.py +0 -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 +154 -0
- pygeai/tests/core/base/__init__.py +0 -0
- pygeai/tests/core/base/data/__init__.py +0 -0
- pygeai/tests/core/base/data/mappers.py +117 -0
- pygeai/tests/core/base/data/models.py +312 -0
- pygeai/tests/core/base/test_mappers.py +569 -0
- pygeai/tests/core/base/test_models.py +261 -0
- 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/__init__.py +0 -0
- pygeai/tests/core/files/test_clients.py +128 -0
- pygeai/tests/core/files/test_managers.py +219 -0
- 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/__init__.py +0 -0
- pygeai/tests/core/rerank/test_clients.py +76 -0
- pygeai/tests/core/rerank/test_managers.py +99 -0
- pygeai/tests/core/rerank/test_mappers.py +54 -0
- 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/__init__.py +0 -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_mappers.py +245 -0
- pygeai/tests/lab/test_models.py +1154 -0
- 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/__init__.py +0 -0
- pygeai/tests/organization/limits/test_clients.py +567 -0
- pygeai/tests/organization/limits/test_managers.py +402 -0
- pygeai/tests/organization/test_clients.py +615 -64
- 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/__init__.py +0 -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/assistants/__init__.py +0 -0
- pygeai/tests/snippets/assistants/create_chat_assistant.py +54 -0
- pygeai/tests/snippets/assistants/create_text_assistant.py +51 -0
- pygeai/tests/snippets/assistants/data_analyst/__init__.py +0 -0
- pygeai/tests/snippets/assistants/data_analyst/extend_and_check.py +100 -0
- pygeai/tests/snippets/assistants/data_analyst/extend_dataset.py +9 -0
- pygeai/tests/snippets/assistants/data_analyst/get_status.py +9 -0
- pygeai/tests/snippets/assistants/file_summarizer_assistant.py +149 -0
- pygeai/tests/snippets/assistants/get_assistant_data.py +8 -0
- pygeai/tests/snippets/assistants/get_assistant_list.py +7 -0
- pygeai/tests/snippets/assistants/rag/__init__.py +0 -0
- pygeai/tests/snippets/assistants/rag/create_rag_assistant.py +65 -0
- pygeai/tests/snippets/assistants/rag/delete_al_documents.py +7 -0
- pygeai/tests/snippets/assistants/rag/delete_document.py +10 -0
- pygeai/tests/snippets/assistants/rag/delete_rag_assistant.py +8 -0
- pygeai/tests/snippets/assistants/rag/get_document.py +10 -0
- pygeai/tests/snippets/assistants/rag/get_documents.py +7 -0
- pygeai/tests/snippets/assistants/rag/get_rag_assistant_data.py +8 -0
- pygeai/tests/snippets/assistants/rag/update_rag_assistant.py +48 -0
- pygeai/tests/snippets/assistants/rag/upload_document.py +19 -0
- pygeai/tests/snippets/assistants/send_feedback.py +14 -0
- pygeai/tests/snippets/assistants/update_chat_assistant.py +63 -0
- pygeai/tests/snippets/auth/__init__.py +0 -0
- pygeai/tests/snippets/chat/__init__.py +0 -0
- pygeai/tests/snippets/chat/cancel_request.py +7 -0
- pygeai/tests/snippets/chat/chat_completion.py +28 -0
- pygeai/tests/snippets/chat/chat_completion_1.py +40 -0
- pygeai/tests/snippets/chat/chat_completion_2.py +60 -0
- pygeai/tests/snippets/chat/chat_completion_3.py +27 -0
- pygeai/tests/snippets/chat/chat_completion_4.py +67 -0
- pygeai/tests/snippets/chat/chat_completion_streaming.py +63 -0
- pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
- pygeai/tests/snippets/chat/get_request_status.py +7 -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/chat/send_chat_request.py +33 -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/__init__.py +0 -0
- pygeai/tests/snippets/embeddings/cache_example.py +31 -0
- pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
- pygeai/tests/snippets/embeddings/generate_embeddings.py +26 -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/__init__.py +0 -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/__init__.py +0 -0
- pygeai/tests/snippets/files/delete_file.py +9 -0
- pygeai/tests/snippets/files/get_file_content.py +10 -0
- pygeai/tests/snippets/files/get_file_data.py +9 -0
- pygeai/tests/snippets/files/get_file_list.py +6 -0
- pygeai/tests/snippets/files/upload_file.py +13 -0
- pygeai/tests/snippets/gam/__init__.py +0 -0
- pygeai/tests/snippets/gam/gam_access_token.py +87 -0
- pygeai/tests/snippets/lab/__init__.py +0 -0
- pygeai/tests/snippets/lab/agentic_flow_example_1.py +326 -0
- pygeai/tests/snippets/lab/agentic_flow_example_2.py +206 -0
- pygeai/tests/snippets/lab/agentic_flow_example_3.py +486 -0
- pygeai/tests/snippets/lab/agentic_flow_example_4.py +446 -0
- pygeai/tests/snippets/lab/agents/__init__.py +0 -0
- pygeai/tests/snippets/lab/agents/create_agent.py +48 -0
- pygeai/tests/snippets/lab/agents/create_agent_2.py +48 -0
- 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 +12 -0
- pygeai/tests/snippets/lab/agents/get_agent.py +24 -0
- pygeai/tests/snippets/lab/agents/get_agent_with_new_fields.py +62 -0
- pygeai/tests/snippets/lab/agents/get_sharing_link.py +13 -0
- pygeai/tests/snippets/lab/agents/list_agents.py +18 -0
- pygeai/tests/snippets/lab/agents/publish_agent_revision.py +12 -0
- pygeai/tests/snippets/lab/agents/update_agent.py +50 -0
- 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/__init__.py +0 -0
- pygeai/tests/snippets/lab/processes/create_process.py +24 -0
- pygeai/tests/snippets/lab/processes/create_task.py +8 -0
- pygeai/tests/snippets/lab/processes/jobs/__init__.py +0 -0
- pygeai/tests/snippets/lab/processes/jobs/list_jobs.py +21 -0
- pygeai/tests/snippets/lab/processes/kbs/__init__.py +0 -0
- pygeai/tests/snippets/lab/processes/kbs/create_kb.py +18 -0
- pygeai/tests/snippets/lab/processes/kbs/get_kb.py +26 -0
- pygeai/tests/snippets/lab/processes/kbs/list_kbs.py +30 -0
- pygeai/tests/snippets/lab/processes/kbs/try_all.py +73 -0
- pygeai/tests/snippets/lab/processes/list_processes.py +10 -0
- pygeai/tests/snippets/lab/runner_1.py +212 -0
- pygeai/tests/snippets/lab/samples/__init__.py +0 -0
- pygeai/tests/snippets/lab/samples/summarize_files.py +162 -0
- pygeai/tests/snippets/lab/strategies/__init__.py +0 -0
- pygeai/tests/snippets/lab/strategies/create_reasoning_strategy.py +22 -0
- pygeai/tests/snippets/lab/strategies/get_reasoning_strategy.py +10 -0
- pygeai/tests/snippets/lab/strategies/list_reasoning_strategies.py +16 -0
- pygeai/tests/snippets/lab/strategies/update_reasoning_strategy.py +26 -0
- pygeai/tests/snippets/lab/tools/__init__.py +0 -0
- pygeai/tests/snippets/lab/tools/create_tool.py +48 -0
- pygeai/tests/snippets/lab/tools/create_tool_edge_case.py +50 -0
- pygeai/tests/snippets/lab/tools/delete_tool.py +21 -0
- pygeai/tests/snippets/lab/tools/get_parameter.py +21 -0
- pygeai/tests/snippets/lab/tools/get_tool.py +22 -0
- pygeai/tests/snippets/lab/tools/list_tools.py +23 -0
- pygeai/tests/snippets/lab/tools/publish_tool_revision.py +13 -0
- pygeai/tests/snippets/lab/tools/set_parameters.py +33 -0
- pygeai/tests/snippets/lab/tools/update_tool.py +52 -0
- pygeai/tests/snippets/lab/use_cases/__init__.py +0 -0
- pygeai/tests/snippets/lab/use_cases/c_code_fixer_agent_flow.py +238 -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/use_cases/file_summarizer_example.py +157 -0
- pygeai/tests/snippets/lab/use_cases/file_summarizer_example_2.py +157 -0
- 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/__init__.py +0 -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 +23 -0
- pygeai/tests/snippets/organization/delete_project.py +7 -0
- pygeai/tests/snippets/organization/export_request_data.py +7 -0
- 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_data.py +7 -0
- pygeai/tests/snippets/organization/get_project_list.py +8 -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/tests/snippets/organization/get_project_tokens.py +7 -0
- pygeai/tests/snippets/organization/update_project.py +14 -0
- pygeai/tests/snippets/rerank/__init__.py +0 -0
- pygeai/tests/snippets/rerank/rerank_chunks.py +19 -0
- pygeai/tests/snippets/secrets/__init__.py +0 -0
- pygeai/tests/snippets/usage_limit/__init__.py +0 -0
- pygeai/tests/snippets/usage_limit/delete_usage_limit.py +16 -0
- pygeai/tests/snippets/usage_limit/get_all_usage_limit_from_organization.py +12 -0
- pygeai/tests/snippets/usage_limit/get_usage_limit_from_organization.py +11 -0
- pygeai/tests/snippets/usage_limit/get_usage_limit_from_project.py +13 -0
- pygeai/tests/snippets/usage_limit/set_usage_limit_organization.py +22 -0
- pygeai/tests/snippets/usage_limit/set_usage_limit_project.py +23 -0
- pygeai/tests/snippets/usage_limit/update_usage_limit_organization.py +23 -0
- pygeai/tests/snippets/usage_limit/update_usage_limit_project.py +24 -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.6.dist-info → pygeai-0.6.0b15.dist-info}/WHEEL +1 -1
- pygeai-0.6.0b15.dist-info/entry_points.txt +5 -0
- {pygeai-0.1.6.dist-info → pygeai-0.6.0b15.dist-info/licenses}/LICENSE +13 -1
- {pygeai-0.1.6.dist-info → pygeai-0.6.0b15.dist-info}/top_level.txt +0 -1
- docs/source/conf.py +0 -45
- pygeai/core/clients.py +0 -240
- pygeai/tests/core/test_clients.py +0 -49
- pygeai-0.1.6.dist-info/METADATA +0 -92
- pygeai-0.1.6.dist-info/RECORD +0 -65
- pygeai-0.1.6.dist-info/SOURCES.sync-conflict-20241223-145950-3QD4F42.txt +0 -41
- pygeai-0.1.6.dist-info/entry_points.txt +0 -2
- /pygeai/{agent → analytics}/__init__.py +0 -0
pygeai/cli/geai_proxy.py
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
import json
|
|
3
|
+
import asyncio
|
|
4
|
+
import sys
|
|
5
|
+
from typing import Final
|
|
6
|
+
import argparse
|
|
7
|
+
import uuid
|
|
8
|
+
import yaml
|
|
9
|
+
from pygeai import logger
|
|
10
|
+
from pygeai.proxy.managers import ServerManager
|
|
11
|
+
from pygeai.proxy.config import ProxySettingsManager
|
|
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())
|
|
44
|
+
|
|
45
|
+
def load_config(path: str) -> list:
|
|
46
|
+
"""
|
|
47
|
+
Load server configuration from YAML or JSON file.
|
|
48
|
+
|
|
49
|
+
:param path: str - Path to configuration file
|
|
50
|
+
:return: list - List of server configurations
|
|
51
|
+
:raises: FileNotFoundError - If the configuration file doesn't exist
|
|
52
|
+
:raises: ValueError - If the file format is invalid or missing mcpServers key
|
|
53
|
+
"""
|
|
54
|
+
try:
|
|
55
|
+
with open(path, 'r', encoding='utf-8') as f:
|
|
56
|
+
config = yaml.safe_load(f) if path.endswith(('.yaml', '.yml')) else json.load(f)
|
|
57
|
+
servers = []
|
|
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
|
+
|
|
73
|
+
return servers
|
|
74
|
+
except FileNotFoundError as exc:
|
|
75
|
+
raise FileNotFoundError(f"Configuration file '{path}' not found") from exc
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def configure_proxy_settings(settings: ProxySettingsManager, args: argparse.Namespace, only_missing: bool = False):
|
|
79
|
+
"""
|
|
80
|
+
Configure proxy settings interactively or from command line arguments.
|
|
81
|
+
|
|
82
|
+
:param settings: ProxySettingsManager - Settings manager instance
|
|
83
|
+
:param args: argparse.Namespace - Command line arguments
|
|
84
|
+
:param only_missing: bool - Whether to only configure missing settings
|
|
85
|
+
:return: None
|
|
86
|
+
"""
|
|
87
|
+
if not args.alias:
|
|
88
|
+
alias = input("-> Insert alias for settings section (Leave empty for default): ") or ProxySettingsManager.DEFAULT_ALIAS
|
|
89
|
+
else:
|
|
90
|
+
alias = args.alias
|
|
91
|
+
|
|
92
|
+
current_id = settings.get_proxy_id(alias)
|
|
93
|
+
current_name = settings.get_proxy_name(alias)
|
|
94
|
+
current_description = settings.get_proxy_description(alias)
|
|
95
|
+
#current_affinity = settings.get_proxy_affinity(alias)
|
|
96
|
+
current_api_key = settings.get_api_key(alias)
|
|
97
|
+
current_base_url = settings.get_base_url(alias)
|
|
98
|
+
|
|
99
|
+
#first_time = all(not x for x in [ current_id, current_name, current_description, current_api_key, current_base_url])
|
|
100
|
+
|
|
101
|
+
if not only_missing or any(not x for x in [current_id, current_name, current_description, current_api_key, current_base_url]):
|
|
102
|
+
Console.write_stdout("# Configuring GEAI proxy settings...")
|
|
103
|
+
|
|
104
|
+
if not current_id:
|
|
105
|
+
current_id = uuid.uuid4()
|
|
106
|
+
settings.set_proxy_id(current_id, alias)
|
|
107
|
+
Console.write_stdout(f"Generated new proxy ID: {current_id}")
|
|
108
|
+
|
|
109
|
+
if not only_missing or not current_id:
|
|
110
|
+
server_id = input(f"-> Insert proxy ID (UUID) (Current: {current_id}, Leave empty to keep): ")
|
|
111
|
+
if server_id:
|
|
112
|
+
try:
|
|
113
|
+
settings.set_proxy_id(uuid.UUID(server_id), alias)
|
|
114
|
+
except ValueError:
|
|
115
|
+
Console.write_stdout("Error: Invalid UUID format")
|
|
116
|
+
return
|
|
117
|
+
if not only_missing or not current_api_key:
|
|
118
|
+
if current_api_key:
|
|
119
|
+
server_api_key = input(f"-> Insert proxy API key (Current: {current_api_key}, Leave empty to keep): ")
|
|
120
|
+
else:
|
|
121
|
+
server_api_key = input("-> Insert proxy API key: ")
|
|
122
|
+
if server_api_key:
|
|
123
|
+
settings.set_api_key(server_api_key, alias)
|
|
124
|
+
|
|
125
|
+
if not only_missing or not current_base_url:
|
|
126
|
+
if current_base_url:
|
|
127
|
+
server_base_url = input(f"-> Insert proxy base URL (Current: {current_base_url}, Leave empty to keep): ")
|
|
128
|
+
else:
|
|
129
|
+
server_base_url = input("-> Insert proxy base URL: ")
|
|
130
|
+
if server_base_url:
|
|
131
|
+
settings.set_base_url(server_base_url, alias)
|
|
132
|
+
|
|
133
|
+
if not only_missing or not current_name:
|
|
134
|
+
if current_name:
|
|
135
|
+
server_name = input(f"-> Insert proxy name (Current: {current_name}, Leave empty to keep): ")
|
|
136
|
+
else:
|
|
137
|
+
server_name = input("-> Insert proxy name: ")
|
|
138
|
+
if server_name:
|
|
139
|
+
settings.set_proxy_name(server_name, alias)
|
|
140
|
+
|
|
141
|
+
if not only_missing or not current_description:
|
|
142
|
+
if current_description:
|
|
143
|
+
server_description = input("-> Insert proxy description (Leave empty to keep): ")
|
|
144
|
+
else:
|
|
145
|
+
server_description = input("-> Insert proxy description: ")
|
|
146
|
+
if server_description:
|
|
147
|
+
settings.set_proxy_description(server_description, alias)
|
|
148
|
+
|
|
149
|
+
# if not only_missing or (not current_affinity and first_time):
|
|
150
|
+
# if current_affinity:
|
|
151
|
+
# server_affinity = input("-> Insert proxy affinity (UUID) (Leave empty to keep): ")
|
|
152
|
+
# else:
|
|
153
|
+
# server_affinity = input("-> Insert proxy affinity (UUID): ")
|
|
154
|
+
# if server_affinity:
|
|
155
|
+
# try:
|
|
156
|
+
# settings.set_proxy_affinity(uuid.UUID(server_affinity), alias)
|
|
157
|
+
# except ValueError:
|
|
158
|
+
# sys.stderr.write("Error: Invalid UUID format\n")
|
|
159
|
+
# return
|
|
160
|
+
else:
|
|
161
|
+
# Command line mode
|
|
162
|
+
if args.proxy_id:
|
|
163
|
+
try:
|
|
164
|
+
settings.set_proxy_id(uuid.UUID(args.proxy_id), alias)
|
|
165
|
+
except ValueError:
|
|
166
|
+
Console.write_stderr("Error: Invalid UUID format for proxy ID")
|
|
167
|
+
return
|
|
168
|
+
elif not only_missing or not settings.get_proxy_id(alias):
|
|
169
|
+
# Generate new UUID if no ID is provided
|
|
170
|
+
current_id = settings.get_proxy_id(alias)
|
|
171
|
+
if not current_id:
|
|
172
|
+
current_id = uuid.uuid4()
|
|
173
|
+
settings.set_proxy_id(current_id, alias)
|
|
174
|
+
Console.write_stdout(f"Generated new proxy ID: {current_id}")
|
|
175
|
+
|
|
176
|
+
if args.proxy_name:
|
|
177
|
+
settings.set_proxy_name(args.proxy_name, alias)
|
|
178
|
+
elif not only_missing or not settings.get_proxy_name(alias):
|
|
179
|
+
pass # Name is not requested if not in args and only_missing is True
|
|
180
|
+
|
|
181
|
+
if args.proxy_desc:
|
|
182
|
+
settings.set_proxy_description(args.proxy_desc, alias)
|
|
183
|
+
elif not only_missing or not settings.get_proxy_description(alias):
|
|
184
|
+
pass # Description is not requested if not in args and only_missing is True
|
|
185
|
+
|
|
186
|
+
#if args.proxy_affinity:
|
|
187
|
+
# try:
|
|
188
|
+
# settings.set_proxy_affinity(uuid.UUID(args.proxy_affinity), alias)
|
|
189
|
+
# except ValueError:
|
|
190
|
+
# sys.stderr.write("Error: Invalid UUID format for proxy affinity\n")
|
|
191
|
+
# return
|
|
192
|
+
#elif not only_missing or not settings.get_proxy_affinity(alias):
|
|
193
|
+
# pass # Affinity is not requested if not in args and only_missing is True
|
|
194
|
+
|
|
195
|
+
Console.write_stdout(f"Proxy settings for alias '{alias}' saved successfully!")
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
async def main():
|
|
199
|
+
"""
|
|
200
|
+
Main entry point for the GEAI proxy CLI.
|
|
201
|
+
|
|
202
|
+
:return: int - Exit code (0 for success, 1 for error)
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
logger.info("Starting GEAI proxy CLI")
|
|
206
|
+
parser = argparse.ArgumentParser(
|
|
207
|
+
description="Proxy CLI between GEAI and MCP servers",
|
|
208
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
209
|
+
epilog="INSTALL MAN PAGES:\n To install the manual pages, run:\n sudo geai-install-man\n (requires superuser privileges)"
|
|
210
|
+
)
|
|
211
|
+
parser.add_argument("config", type=str, nargs="?", help="Path to the configuration file (JSON/YAML)")
|
|
212
|
+
parser.add_argument("--list-tools", action="store_true", help="List all available tools")
|
|
213
|
+
parser.add_argument("--invoke", type=str, help="Invoke a specific tool in JSON format")
|
|
214
|
+
parser.add_argument("--configure", action="store_true", help="Configure proxy settings")
|
|
215
|
+
parser.add_argument("--proxy-id", type=str, help="Set proxy server ID (UUID)")
|
|
216
|
+
parser.add_argument("--proxy-name", type=str, help="Set proxy server name")
|
|
217
|
+
parser.add_argument("--proxy-desc", type=str, help="Set proxy server description")
|
|
218
|
+
parser.add_argument("--proxy-affinity", type=str, help="Set proxy server affinity (UUID)")
|
|
219
|
+
parser.add_argument("--alias", type=str, help="Set alias for settings section")
|
|
220
|
+
args = parser.parse_args()
|
|
221
|
+
|
|
222
|
+
settings = ProxySettingsManager()
|
|
223
|
+
if not args.alias:
|
|
224
|
+
args.alias = ProxySettingsManager.DEFAULT_ALIAS
|
|
225
|
+
else:
|
|
226
|
+
settings.set_current_alias(args.alias)
|
|
227
|
+
|
|
228
|
+
Console.write_stdout(f"Using alias: {args.alias}")
|
|
229
|
+
|
|
230
|
+
only_configure = args.configure
|
|
231
|
+
while True:
|
|
232
|
+
if args.configure or not all([
|
|
233
|
+
settings.get_proxy_id(args.alias),
|
|
234
|
+
settings.get_proxy_name(args.alias),
|
|
235
|
+
settings.get_proxy_description(args.alias),
|
|
236
|
+
settings.get_api_key(args.alias),
|
|
237
|
+
settings.get_base_url(args.alias)
|
|
238
|
+
]):
|
|
239
|
+
|
|
240
|
+
if args.alias not in settings.config:
|
|
241
|
+
Console.write_stdout(f"Created new alias '{args.alias}' in the configuration file.","\n\n")
|
|
242
|
+
settings.config.add_section(args.alias)
|
|
243
|
+
else:
|
|
244
|
+
if not args.configure:
|
|
245
|
+
Console.write_stdout("\nProxy configuration required. Please complete all required fields.","\n\n")
|
|
246
|
+
else:
|
|
247
|
+
Console.write_stdout("\nProxy configuration.","\n\n")
|
|
248
|
+
|
|
249
|
+
if (key := settings.get_api_key(args.alias)):
|
|
250
|
+
Console.write_stdout(f"API_KEY: {key}")
|
|
251
|
+
if (url := settings.get_base_url(args.alias)):
|
|
252
|
+
Console.write_stdout(f"BASE_URL: {url}")
|
|
253
|
+
|
|
254
|
+
Console.write_stdout("")
|
|
255
|
+
configure_proxy_settings(settings, args, only_missing=not args.configure)
|
|
256
|
+
args.configure = False
|
|
257
|
+
else:
|
|
258
|
+
break
|
|
259
|
+
|
|
260
|
+
if only_configure:
|
|
261
|
+
Console.write_stdout("Proxy configuration completed successfully!")
|
|
262
|
+
return 0
|
|
263
|
+
|
|
264
|
+
if not args.config:
|
|
265
|
+
Console.write_stderr("Error: MCP servers Configuration file path is required")
|
|
266
|
+
return 1
|
|
267
|
+
|
|
268
|
+
servers_cfg = load_config(args.config)
|
|
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
|
+
|
|
289
|
+
await server_manager.start()
|
|
290
|
+
|
|
291
|
+
return 0
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def cli_entry() -> int:
|
|
295
|
+
"""
|
|
296
|
+
CLI entry point.
|
|
297
|
+
|
|
298
|
+
:return: int - Exit code (0 for success, 1 for error)
|
|
299
|
+
"""
|
|
300
|
+
try:
|
|
301
|
+
return asyncio.run(main())
|
|
302
|
+
except KeyboardInterrupt:
|
|
303
|
+
Console.write_stdout("\nExiting...")
|
|
304
|
+
return 0
|
|
305
|
+
except (RuntimeError, ConnectionError, ValueError) as e:
|
|
306
|
+
Console.write_exception("Error:", e, "\n")
|
|
307
|
+
return 1
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
if __name__ == "__main__":
|
|
311
|
+
if len(sys.argv) == 1:
|
|
312
|
+
import os
|
|
313
|
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
314
|
+
config_path = os.path.join(os.path.dirname(script_dir), "proxy", "sample-mcp-config.json")
|
|
315
|
+
Console.write_stdout(f"Config file path: {config_path}")
|
|
316
|
+
|
|
317
|
+
sys.argv.extend([config_path])
|
|
318
|
+
sys.exit(cli_entry())
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
import subprocess
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from importlib import resources
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_man_dir() -> Path | None:
|
|
11
|
+
"""Locate the pygeai/man/man1 directory within the installed package."""
|
|
12
|
+
try:
|
|
13
|
+
# Use importlib.resources to find the man/man1 directory in pygeai package
|
|
14
|
+
with resources.path("pygeai.man", "man1") as man_path:
|
|
15
|
+
man_dir = Path(man_path)
|
|
16
|
+
if man_dir.is_dir():
|
|
17
|
+
return man_dir
|
|
18
|
+
return None
|
|
19
|
+
except (ImportError, FileNotFoundError):
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def validate_man_file(file_path: Path) -> bool:
|
|
24
|
+
"""Validate if a file is a likely man page (ends with .1 or .1.gz)."""
|
|
25
|
+
return file_path.suffix in ('.1', '.gz') and (file_path.name.endswith('.1') or file_path.name.endswith('.1.gz'))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def install_man_pages(system_wide: bool) -> int:
|
|
29
|
+
"""Install man pages from pygeai/man/man1 to local or system-wide man directory."""
|
|
30
|
+
# Locate source directory
|
|
31
|
+
source_path = get_man_dir()
|
|
32
|
+
if not source_path:
|
|
33
|
+
print("Error: Could not locate 'pygeai/man/man1' directory in the installed pygeai package.")
|
|
34
|
+
return 1
|
|
35
|
+
|
|
36
|
+
# Determine destination directory
|
|
37
|
+
if system_wide:
|
|
38
|
+
dest_path = Path("/usr/local/share/man/man1")
|
|
39
|
+
else:
|
|
40
|
+
dest_path = Path.home() / "share" / "man" / "man1"
|
|
41
|
+
|
|
42
|
+
# Ensure destination directory exists
|
|
43
|
+
try:
|
|
44
|
+
dest_path.mkdir(parents=True, exist_ok=True)
|
|
45
|
+
except PermissionError:
|
|
46
|
+
print(f"Error: Permission denied creating '{dest_path}'. Try running with sudo for system-wide installation.")
|
|
47
|
+
return 1
|
|
48
|
+
|
|
49
|
+
# Collect man page files
|
|
50
|
+
man_files = [f for f in source_path.iterdir() if validate_man_file(f)]
|
|
51
|
+
if not man_files:
|
|
52
|
+
print(f"Warning: No valid man page files found in '{source_path}'.")
|
|
53
|
+
return 0
|
|
54
|
+
|
|
55
|
+
# Copy man page files
|
|
56
|
+
for man_file in man_files:
|
|
57
|
+
dest_file = dest_path / man_file.name
|
|
58
|
+
try:
|
|
59
|
+
shutil.copy2(man_file, dest_file)
|
|
60
|
+
print(f"Installed: {dest_file}")
|
|
61
|
+
# Set permissions (644)
|
|
62
|
+
dest_file.chmod(0o644)
|
|
63
|
+
except PermissionError:
|
|
64
|
+
print(f"Error: Permission denied copying '{man_file}' to '{dest_file}'. Try running with sudo.")
|
|
65
|
+
return 1
|
|
66
|
+
except OSError as e:
|
|
67
|
+
print(f"Error: Failed to copy '{man_file}' to '{dest_file}': {e}")
|
|
68
|
+
return 1
|
|
69
|
+
|
|
70
|
+
# Update man database for system-wide installation
|
|
71
|
+
if system_wide:
|
|
72
|
+
try:
|
|
73
|
+
subprocess.run(["mandb"], check=True, capture_output=True, text=True)
|
|
74
|
+
print("Updated man page database.")
|
|
75
|
+
except subprocess.CalledProcessError as e:
|
|
76
|
+
print(f"Warning: Failed to update man database: {e.stderr}")
|
|
77
|
+
except FileNotFoundError:
|
|
78
|
+
print("Warning: 'mandb' command not found. Man pages installed but database not updated.")
|
|
79
|
+
|
|
80
|
+
# For local installation, remind user to update MANPATH
|
|
81
|
+
if not system_wide:
|
|
82
|
+
manpath_cmd = f'export MANPATH={Path.home() / "share" / "man"}:$MANPATH'
|
|
83
|
+
print(f"Local installation complete. Add to ~/.bashrc to update MANPATH:")
|
|
84
|
+
print(f" {manpath_cmd}")
|
|
85
|
+
|
|
86
|
+
return 0
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def main():
|
|
90
|
+
parser = argparse.ArgumentParser(description="Install man pages from pygeai/man/man1.")
|
|
91
|
+
parser.add_argument(
|
|
92
|
+
"--system",
|
|
93
|
+
action="store_true",
|
|
94
|
+
help="Install man pages system-wide to /usr/local/share/man/man1 (requires sudo).",
|
|
95
|
+
)
|
|
96
|
+
args = parser.parse_args()
|
|
97
|
+
|
|
98
|
+
# Check if running as root for system-wide installation
|
|
99
|
+
if args.system and os.geteuid() != 0:
|
|
100
|
+
print("Error: System-wide installation requires root privileges. Run with sudo.")
|
|
101
|
+
sys.exit(1)
|
|
102
|
+
|
|
103
|
+
sys.exit(install_man_pages(args.system))
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
if __name__ == "__main__":
|
|
107
|
+
main()
|
pygeai/cli/parsers.py
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
|
+
from typing import List, Tuple, Optional
|
|
2
|
+
|
|
3
|
+
from pygeai import logger
|
|
1
4
|
from pygeai.cli.commands.base import base_options
|
|
2
5
|
from pygeai.cli.commands import Command, Option
|
|
3
|
-
from pygeai.core.common.exceptions import UnknownArgumentError
|
|
6
|
+
from pygeai.core.common.exceptions import UnknownArgumentError, MissingRequirementException
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
class CommandParser:
|
|
7
10
|
|
|
8
|
-
def __init__(
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
available_commands: Optional[List[Command]],
|
|
14
|
+
available_options: Optional[List[Option]]
|
|
15
|
+
) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Initialize a CommandParser with available commands and options.
|
|
18
|
+
|
|
19
|
+
:param available_commands: Optional[List[Command]] - List of valid commands, or None.
|
|
20
|
+
:param available_options: Optional[List[Option]] - List of valid options, or None.
|
|
21
|
+
"""
|
|
9
22
|
self.available_commands = available_commands
|
|
10
23
|
self.available_options = available_options
|
|
11
24
|
|
|
@@ -13,23 +26,34 @@ class CommandParser:
|
|
|
13
26
|
"""
|
|
14
27
|
Analyzes the first argument and checks if it's a valid command.
|
|
15
28
|
|
|
16
|
-
:param
|
|
17
|
-
:return: The command
|
|
29
|
+
:param arg: str - The argument to be analyzed.
|
|
30
|
+
:return: Command - The identified command object.
|
|
31
|
+
:raises UnknownArgumentError: If the argument is not a valid command.
|
|
18
32
|
"""
|
|
33
|
+
logger.debug(f"Searching for command matching: {arg}")
|
|
19
34
|
command = self._get_associated_command(arg)
|
|
20
35
|
if not command:
|
|
21
|
-
|
|
22
|
-
|
|
36
|
+
logger.debug(f"No command found for: {arg}")
|
|
37
|
+
raise UnknownArgumentError(
|
|
38
|
+
f"'{arg}' is not a valid command.",
|
|
39
|
+
arg=arg,
|
|
40
|
+
available_commands=self.available_commands
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
logger.debug(f"Command found: {command.name} (identifiers: {command.identifiers})")
|
|
23
44
|
return command
|
|
24
45
|
|
|
25
|
-
def extract_option_list(self, arguments:
|
|
46
|
+
def extract_option_list(self, arguments: List[str]) -> List[Tuple[Option, str]]:
|
|
26
47
|
"""
|
|
27
|
-
Parses a list of arguments and returns the
|
|
48
|
+
Parses a list of arguments and returns the options being invoked.
|
|
28
49
|
|
|
29
|
-
:param arguments:
|
|
30
|
-
:return:
|
|
50
|
+
:param arguments: List[str] - The list of arguments received by the CLI utility.
|
|
51
|
+
:return: List[Tuple[Option, str]] - A list of tuples containing Option objects and their values.
|
|
52
|
+
:raises UnknownArgumentError: If an unknown option is provided.
|
|
53
|
+
:raises MissingRequirementException: If a required option argument is missing.
|
|
31
54
|
"""
|
|
32
|
-
|
|
55
|
+
logger.debug(f"Extracting options from arguments: {arguments}")
|
|
56
|
+
flag_list: List[Tuple[Option, str]] = []
|
|
33
57
|
|
|
34
58
|
complementary_arg = False
|
|
35
59
|
for i, arg in enumerate(arguments):
|
|
@@ -39,30 +63,59 @@ class CommandParser:
|
|
|
39
63
|
|
|
40
64
|
flag = self._get_associated_option(arg)
|
|
41
65
|
if not flag:
|
|
42
|
-
|
|
66
|
+
logger.debug(f"Unknown option: {arg}")
|
|
67
|
+
raise UnknownArgumentError(
|
|
68
|
+
f"'{arg}' is not a valid option.",
|
|
69
|
+
arg=arg,
|
|
70
|
+
available_options=self.available_options
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
logger.debug(f"Option found: {flag.name} (identifiers: {flag.identifiers})")
|
|
43
74
|
|
|
44
75
|
if flag.requires_args:
|
|
45
76
|
complementary_arg = True
|
|
46
|
-
|
|
77
|
+
try:
|
|
78
|
+
value = arguments[i + 1]
|
|
79
|
+
logger.debug(f"Option {flag.name} has value: {value}")
|
|
80
|
+
flag_list.append((flag, value))
|
|
81
|
+
except IndexError:
|
|
82
|
+
logger.debug(f"Missing required argument for option: {flag.name}")
|
|
83
|
+
raise MissingRequirementException(f"'{flag.name}' requires an argument.")
|
|
47
84
|
else:
|
|
48
|
-
|
|
85
|
+
logger.debug(f"Option {flag.name} is a flag (no value required)")
|
|
86
|
+
flag_list.append((flag, ""))
|
|
49
87
|
|
|
88
|
+
logger.debug(f"Total options parsed: {len(flag_list)}")
|
|
50
89
|
return flag_list
|
|
51
90
|
|
|
52
|
-
def _get_associated_command(self, arg: str) -> Command:
|
|
53
|
-
|
|
91
|
+
def _get_associated_command(self, arg: str) -> Optional[Command]:
|
|
92
|
+
"""
|
|
93
|
+
Finds the command associated with the given argument.
|
|
94
|
+
|
|
95
|
+
:param arg: str - The argument to search for.
|
|
96
|
+
:return: Optional[Command] - The associated command if found, None otherwise.
|
|
97
|
+
"""
|
|
98
|
+
if not self.available_commands:
|
|
99
|
+
return None
|
|
100
|
+
|
|
54
101
|
for command in self.available_commands:
|
|
55
102
|
if arg in command.identifiers:
|
|
56
|
-
|
|
57
|
-
|
|
103
|
+
return command
|
|
104
|
+
|
|
105
|
+
return None
|
|
58
106
|
|
|
59
|
-
|
|
107
|
+
def _get_associated_option(self, arg: str) -> Optional[Option]:
|
|
108
|
+
"""
|
|
109
|
+
Finds the option associated with the given argument.
|
|
60
110
|
|
|
61
|
-
|
|
62
|
-
|
|
111
|
+
:param arg: str - The argument to search for.
|
|
112
|
+
:return: Optional[Option] - The associated option if found, None otherwise.
|
|
113
|
+
"""
|
|
114
|
+
if not self.available_options:
|
|
115
|
+
return None
|
|
116
|
+
|
|
63
117
|
for option in self.available_options:
|
|
64
118
|
if arg in option.identifiers:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return associated_option
|
|
119
|
+
return option
|
|
120
|
+
|
|
121
|
+
return None
|