pygeai 0.1.51b3__py3-none-any.whl → 0.6.0b15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pygeai might be problematic. Click here for more details.
- pygeai/__init__.py +9 -1
- pygeai/_docs/Makefile +20 -0
- pygeai/_docs/make.bat +35 -0
- pygeai/_docs/source/conf.py +117 -0
- pygeai/_docs/source/content/ai_lab/cli.rst +747 -0
- pygeai/_docs/source/content/ai_lab/models.rst +1734 -0
- pygeai/_docs/source/content/ai_lab/runner.rst +253 -0
- pygeai/_docs/source/content/ai_lab/spec.rst +431 -0
- pygeai/_docs/source/content/ai_lab/usage.rst +1011 -0
- pygeai/_docs/source/content/ai_lab.rst +102 -0
- pygeai/_docs/source/content/analytics.rst +598 -0
- pygeai/_docs/source/content/api_reference/admin.rst +161 -0
- pygeai/_docs/source/content/api_reference/assistant.rst +326 -0
- pygeai/_docs/source/content/api_reference/auth.rst +379 -0
- pygeai/_docs/source/content/api_reference/chat.rst +754 -0
- pygeai/_docs/source/content/api_reference/embeddings.rst +154 -0
- pygeai/_docs/source/content/api_reference/evaluation.rst +590 -0
- pygeai/_docs/source/content/api_reference/feedback.rst +237 -0
- pygeai/_docs/source/content/api_reference/files.rst +592 -0
- pygeai/_docs/source/content/api_reference/gam.rst +401 -0
- pygeai/_docs/source/content/api_reference/health.rst +58 -0
- pygeai/_docs/source/content/api_reference/project.rst +738 -0
- pygeai/_docs/source/content/api_reference/proxy.rst +318 -0
- pygeai/_docs/source/content/api_reference/rag.rst +710 -0
- pygeai/_docs/source/content/api_reference/rerank.rst +94 -0
- pygeai/_docs/source/content/api_reference/secrets.rst +495 -0
- pygeai/_docs/source/content/api_reference/usage_limits.rst +390 -0
- pygeai/_docs/source/content/api_reference.rst +58 -0
- pygeai/_docs/source/content/authentication.rst +295 -0
- pygeai/_docs/source/content/chat_gui.rst +121 -0
- pygeai/_docs/source/content/cli.rst +203 -0
- pygeai/_docs/source/content/debugger.rst +651 -0
- pygeai/_docs/source/content/intro.rst +67 -0
- pygeai/_docs/source/content/migration.rst +929 -0
- pygeai/_docs/source/content/modules.rst +7 -0
- pygeai/_docs/source/content/quickstart.rst +143 -0
- pygeai/_docs/source/content/samples.rst +394 -0
- pygeai/_docs/source/index.rst +75 -0
- pygeai/_docs/source/modules.rst +7 -0
- pygeai/_docs/source/pygeai.admin.rst +29 -0
- pygeai/_docs/source/pygeai.analytics.rst +53 -0
- pygeai/_docs/source/pygeai.assistant.data.rst +21 -0
- pygeai/_docs/source/pygeai.assistant.data_analyst.rst +29 -0
- pygeai/_docs/source/pygeai.assistant.rag.rst +53 -0
- pygeai/_docs/source/pygeai.assistant.rst +55 -0
- pygeai/_docs/source/pygeai.auth.rst +29 -0
- pygeai/_docs/source/pygeai.chat.rst +69 -0
- pygeai/_docs/source/pygeai.cli.commands.flows.rst +10 -0
- pygeai/_docs/source/pygeai.cli.commands.lab.rst +53 -0
- pygeai/_docs/source/pygeai.cli.commands.rst +222 -0
- pygeai/_docs/source/pygeai.cli.rst +62 -0
- pygeai/_docs/source/pygeai.cli.texts.rst +21 -0
- pygeai/_docs/source/pygeai.core.base.rst +53 -0
- pygeai/_docs/source/pygeai.core.common.rst +37 -0
- pygeai/_docs/source/pygeai.core.embeddings.rst +61 -0
- pygeai/_docs/source/pygeai.core.feedback.rst +37 -0
- pygeai/_docs/source/pygeai.core.files.rst +61 -0
- pygeai/_docs/source/pygeai.core.llm.rst +29 -0
- pygeai/_docs/source/pygeai.core.plugins.rst +37 -0
- pygeai/_docs/source/pygeai.core.rerank.rst +53 -0
- pygeai/_docs/source/pygeai.core.rst +63 -0
- pygeai/_docs/source/pygeai.core.secrets.rst +29 -0
- pygeai/_docs/source/pygeai.core.services.llm.rst +29 -0
- pygeai/_docs/source/pygeai.core.services.rst +37 -0
- pygeai/_docs/source/pygeai.core.utils.rst +37 -0
- pygeai/_docs/source/pygeai.dbg.rst +21 -0
- pygeai/_docs/source/pygeai.evaluation.dataset.rst +29 -0
- pygeai/_docs/source/pygeai.evaluation.plan.rst +29 -0
- pygeai/_docs/source/pygeai.evaluation.result.rst +29 -0
- pygeai/_docs/source/pygeai.evaluation.rst +31 -0
- pygeai/_docs/source/pygeai.flows.rst +29 -0
- pygeai/_docs/source/pygeai.gam.rst +29 -0
- pygeai/_docs/source/pygeai.health.rst +29 -0
- pygeai/_docs/source/pygeai.lab.agents.rst +37 -0
- pygeai/_docs/source/pygeai.lab.processes.rst +37 -0
- pygeai/_docs/source/pygeai.lab.rst +65 -0
- pygeai/_docs/source/pygeai.lab.spec.rst +29 -0
- pygeai/_docs/source/pygeai.lab.strategies.rst +37 -0
- pygeai/_docs/source/pygeai.lab.tools.rst +37 -0
- pygeai/_docs/source/pygeai.man.man1.rst +10 -0
- pygeai/_docs/source/pygeai.man.rst +18 -0
- pygeai/_docs/source/pygeai.migration.rst +29 -0
- pygeai/_docs/source/pygeai.organization.limits.rst +45 -0
- pygeai/_docs/source/pygeai.organization.rst +61 -0
- pygeai/_docs/source/pygeai.proxy.rst +53 -0
- pygeai/_docs/source/pygeai.rst +35 -0
- pygeai/_docs/source/pygeai.tests.admin.rst +21 -0
- pygeai/_docs/source/pygeai.tests.analytics.rst +45 -0
- pygeai/_docs/source/pygeai.tests.assistants.rag.rst +37 -0
- pygeai/_docs/source/pygeai.tests.assistants.rst +45 -0
- pygeai/_docs/source/pygeai.tests.auth.rst +29 -0
- pygeai/_docs/source/pygeai.tests.chat.rst +45 -0
- pygeai/_docs/source/pygeai.tests.cli.commands.lab.rst +37 -0
- pygeai/_docs/source/pygeai.tests.cli.commands.rst +165 -0
- pygeai/_docs/source/pygeai.tests.cli.docker.rst +10 -0
- pygeai/_docs/source/pygeai.tests.cli.rst +46 -0
- pygeai/_docs/source/pygeai.tests.core.base.data.rst +29 -0
- pygeai/_docs/source/pygeai.tests.core.base.rst +45 -0
- pygeai/_docs/source/pygeai.tests.core.common.data.rst +10 -0
- pygeai/_docs/source/pygeai.tests.core.common.rst +37 -0
- pygeai/_docs/source/pygeai.tests.core.embeddings.rst +37 -0
- pygeai/_docs/source/pygeai.tests.core.feedback.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.files.rst +53 -0
- pygeai/_docs/source/pygeai.tests.core.llm.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.plugins.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.rerank.rst +37 -0
- pygeai/_docs/source/pygeai.tests.core.rst +39 -0
- pygeai/_docs/source/pygeai.tests.core.secrets.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.services.rst +21 -0
- pygeai/_docs/source/pygeai.tests.core.utils.rst +21 -0
- pygeai/_docs/source/pygeai.tests.dbg.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.dataset.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.plan.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.result.rst +21 -0
- pygeai/_docs/source/pygeai.tests.evaluation.rst +20 -0
- pygeai/_docs/source/pygeai.tests.gam.rst +21 -0
- pygeai/_docs/source/pygeai.tests.health.rst +21 -0
- pygeai/_docs/source/pygeai.tests.integration.assistants.rag.rst +21 -0
- pygeai/_docs/source/pygeai.tests.integration.assistants.rst +18 -0
- pygeai/_docs/source/pygeai.tests.integration.chat.rst +21 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.agents.rst +69 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.processes.rst +77 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.reasoning_strategies.rst +37 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.rst +21 -0
- pygeai/_docs/source/pygeai.tests.integration.lab.tools.rst +77 -0
- pygeai/_docs/source/pygeai.tests.integration.rst +20 -0
- pygeai/_docs/source/pygeai.tests.lab.agents.rst +29 -0
- pygeai/_docs/source/pygeai.tests.lab.processes.rst +29 -0
- pygeai/_docs/source/pygeai.tests.lab.rst +49 -0
- pygeai/_docs/source/pygeai.tests.lab.spec.rst +29 -0
- pygeai/_docs/source/pygeai.tests.lab.strategies.rst +29 -0
- pygeai/_docs/source/pygeai.tests.lab.tools.rst +29 -0
- pygeai/_docs/source/pygeai.tests.migration.rst +29 -0
- pygeai/_docs/source/pygeai.tests.organization.limits.rst +29 -0
- pygeai/_docs/source/pygeai.tests.organization.rst +53 -0
- pygeai/_docs/source/pygeai.tests.proxy.rst +61 -0
- pygeai/_docs/source/pygeai.tests.rst +33 -0
- pygeai/admin/clients.py +14 -11
- pygeai/admin/endpoints.py +2 -2
- pygeai/analytics/clients.py +505 -0
- pygeai/analytics/endpoints.py +35 -0
- pygeai/analytics/managers.py +606 -0
- pygeai/analytics/mappers.py +207 -0
- pygeai/analytics/responses.py +240 -0
- pygeai/assistant/clients.py +18 -45
- pygeai/assistant/data/clients.py +1 -0
- pygeai/assistant/data_analyst/clients.py +8 -12
- pygeai/assistant/managers.py +195 -157
- pygeai/assistant/mappers.py +4 -2
- pygeai/assistant/rag/clients.py +27 -67
- pygeai/assistant/rag/mappers.py +12 -6
- pygeai/assistant/rag/models.py +301 -159
- pygeai/auth/__init__.py +0 -0
- pygeai/auth/clients.py +129 -0
- pygeai/auth/endpoints.py +6 -0
- pygeai/chat/clients.py +308 -37
- pygeai/chat/endpoints.py +3 -0
- pygeai/chat/iris.py +2 -8
- pygeai/chat/managers.py +9 -6
- pygeai/chat/session.py +38 -0
- pygeai/chat/settings.py +6 -0
- pygeai/chat/ui.py +678 -0
- pygeai/cli/__init__.py +0 -1
- pygeai/cli/commands/admin.py +7 -10
- pygeai/cli/commands/analytics.py +533 -0
- pygeai/cli/commands/assistant.py +9 -9
- pygeai/cli/commands/auth.py +299 -0
- pygeai/cli/commands/base.py +71 -9
- pygeai/cli/commands/chat.py +676 -19
- pygeai/cli/commands/common.py +28 -24
- pygeai/cli/commands/configuration.py +66 -13
- pygeai/cli/commands/docs.py +105 -0
- pygeai/cli/commands/embeddings.py +58 -11
- pygeai/cli/commands/evaluation.py +38 -38
- pygeai/cli/commands/feedback.py +3 -4
- pygeai/cli/commands/files.py +7 -8
- pygeai/cli/commands/gam.py +85 -10
- pygeai/cli/commands/lab/ai_lab.py +340 -484
- pygeai/cli/commands/lab/options.py +8 -0
- pygeai/cli/commands/lab/spec.py +273 -0
- pygeai/cli/commands/lab/utils.py +13 -0
- pygeai/cli/commands/llm.py +6 -7
- pygeai/cli/commands/migrate.py +1064 -436
- pygeai/cli/commands/organization.py +516 -11
- pygeai/cli/commands/rag.py +13 -14
- pygeai/cli/commands/rerank.py +3 -5
- pygeai/cli/commands/secrets.py +8 -9
- pygeai/cli/commands/usage_limits.py +18 -20
- pygeai/cli/commands/validators.py +144 -1
- pygeai/cli/commands/version.py +4 -5
- pygeai/cli/error_handler.py +151 -0
- pygeai/cli/geai.py +170 -31
- pygeai/cli/geai_proxy.py +86 -25
- pygeai/cli/install_man.py +93 -22
- pygeai/cli/parsers.py +75 -25
- pygeai/cli/texts/help.py +265 -28
- pygeai/core/base/clients.py +53 -12
- pygeai/core/base/mappers.py +11 -2
- pygeai/core/base/session.py +95 -11
- pygeai/core/common/config.py +78 -14
- pygeai/core/common/exceptions.py +96 -6
- pygeai/core/embeddings/__init__.py +19 -0
- pygeai/core/embeddings/clients.py +23 -5
- pygeai/core/embeddings/managers.py +9 -4
- pygeai/core/embeddings/mappers.py +16 -2
- pygeai/core/embeddings/responses.py +9 -2
- pygeai/core/feedback/clients.py +8 -3
- pygeai/core/files/clients.py +23 -24
- pygeai/core/files/managers.py +121 -30
- pygeai/core/files/responses.py +4 -3
- pygeai/core/handlers.py +10 -1
- pygeai/core/llm/clients.py +22 -29
- pygeai/core/models.py +127 -11
- pygeai/core/plugins/clients.py +6 -6
- pygeai/core/rerank/clients.py +9 -3
- pygeai/core/rerank/managers.py +22 -5
- pygeai/core/secrets/clients.py +16 -37
- pygeai/core/services/response.py +18 -0
- pygeai/core/services/rest.py +159 -49
- pygeai/core/utils/__init__.py +0 -0
- pygeai/core/utils/console.py +83 -0
- pygeai/core/utils/parsers.py +32 -0
- pygeai/core/utils/validators.py +10 -0
- pygeai/dbg/__init__.py +3 -0
- pygeai/dbg/debugger.py +854 -14
- pygeai/evaluation/clients.py +7 -4
- pygeai/evaluation/dataset/clients.py +46 -44
- pygeai/evaluation/plan/clients.py +28 -26
- pygeai/evaluation/result/clients.py +38 -5
- pygeai/gam/clients.py +50 -28
- pygeai/gam/endpoints.py +2 -1
- pygeai/health/__init__.py +0 -0
- pygeai/health/clients.py +24 -0
- pygeai/health/endpoints.py +1 -0
- pygeai/lab/__init__.py +0 -90
- pygeai/lab/agents/clients.py +203 -162
- pygeai/lab/agents/endpoints.py +4 -0
- pygeai/lab/agents/mappers.py +57 -7
- pygeai/lab/clients.py +24 -0
- pygeai/lab/constants.py +3 -0
- pygeai/lab/managers.py +571 -541
- pygeai/lab/models.py +108 -19
- pygeai/lab/processes/clients.py +332 -340
- pygeai/lab/processes/mappers.py +3 -3
- pygeai/lab/runners.py +90 -0
- pygeai/lab/spec/__init__.py +0 -0
- pygeai/lab/spec/loader.py +24 -0
- pygeai/lab/spec/parsers.py +39 -0
- pygeai/lab/strategies/clients.py +67 -63
- pygeai/lab/strategies/mappers.py +1 -1
- pygeai/lab/tools/clients.py +85 -118
- pygeai/lab/tools/endpoints.py +4 -0
- pygeai/lab/tools/mappers.py +5 -5
- pygeai/man/man1/geai-proxy.1 +116 -0
- pygeai/man/man1/geai.1 +2580 -66
- pygeai/migration/__init__.py +33 -0
- pygeai/migration/strategies.py +468 -146
- pygeai/migration/tools.py +170 -3
- pygeai/organization/clients.py +245 -50
- pygeai/organization/endpoints.py +17 -8
- pygeai/organization/limits/clients.py +34 -32
- pygeai/organization/limits/managers.py +108 -49
- pygeai/organization/managers.py +347 -53
- pygeai/organization/mappers.py +102 -2
- pygeai/organization/responses.py +58 -1
- pygeai/proxy/clients.py +6 -3
- pygeai/proxy/config.py +14 -1
- pygeai/proxy/managers.py +61 -33
- pygeai/proxy/servers.py +196 -51
- pygeai/proxy/tool.py +33 -16
- pygeai/tests/admin/__init__.py +0 -0
- pygeai/tests/admin/test_clients.py +148 -0
- pygeai/tests/analytics/__init__.py +0 -0
- pygeai/tests/analytics/test_clients.py +86 -0
- pygeai/tests/analytics/test_managers.py +94 -0
- pygeai/tests/analytics/test_mappers.py +84 -0
- pygeai/tests/analytics/test_responses.py +73 -0
- pygeai/tests/assistants/rag/test_clients.py +346 -0
- pygeai/tests/assistants/rag/test_models.py +292 -0
- pygeai/tests/assistants/test_clients.py +176 -82
- pygeai/tests/assistants/test_managers.py +191 -57
- pygeai/tests/auth/__init__.py +0 -0
- pygeai/tests/auth/test_clients.py +289 -0
- pygeai/tests/auth/test_oauth.py +172 -0
- pygeai/tests/auth/test_session_logging.py +150 -0
- pygeai/tests/chat/__init__.py +0 -0
- pygeai/tests/chat/test_clients.py +393 -0
- pygeai/tests/chat/test_iris.py +38 -0
- pygeai/tests/chat/test_session.py +62 -0
- pygeai/tests/chat/test_ui.py +224 -0
- pygeai/tests/cli/commands/__init__.py +0 -0
- pygeai/tests/cli/commands/lab/__init__.py +0 -0
- pygeai/tests/cli/commands/lab/test_ai_lab.py +786 -0
- pygeai/tests/cli/commands/lab/test_common.py +208 -0
- pygeai/tests/cli/commands/lab/test_spec.py +246 -0
- pygeai/tests/cli/commands/test_assistant.py +202 -0
- pygeai/tests/cli/commands/test_chat.py +130 -0
- pygeai/tests/cli/commands/test_common.py +350 -0
- pygeai/tests/cli/commands/test_embeddings.py +132 -0
- pygeai/tests/cli/commands/test_evaluation.py +656 -0
- pygeai/tests/cli/commands/test_feedback.py +65 -0
- pygeai/tests/cli/commands/test_files.py +161 -0
- pygeai/tests/cli/commands/test_gam.py +201 -0
- pygeai/tests/cli/commands/test_llm.py +114 -0
- pygeai/tests/cli/commands/test_migrate.py +176 -0
- pygeai/tests/cli/commands/test_organization.py +276 -0
- pygeai/tests/cli/commands/test_rag.py +266 -0
- pygeai/tests/cli/commands/test_rerank.py +110 -0
- pygeai/tests/cli/commands/test_secrets.py +171 -0
- pygeai/tests/cli/commands/test_show_help.py +41 -0
- pygeai/tests/cli/commands/test_usage_limits.py +412 -0
- pygeai/tests/cli/commands/test_validators.py +160 -0
- pygeai/tests/cli/commands/test_version.py +81 -0
- pygeai/tests/cli/docker/__init__.py +0 -0
- pygeai/tests/cli/test_credentials_flag.py +316 -0
- pygeai/tests/cli/test_error_handler.py +225 -0
- pygeai/tests/cli/test_geai_driver.py +154 -0
- pygeai/tests/cli/test_parsers.py +5 -5
- pygeai/tests/core/base/data/models.py +7 -0
- pygeai/tests/core/base/test_mappers.py +43 -11
- pygeai/tests/core/base/test_models.py +3 -1
- pygeai/tests/core/base/test_responses.py +53 -0
- pygeai/tests/core/common/__init__.py +0 -0
- pygeai/tests/core/common/data/__init__.py +0 -0
- pygeai/tests/core/common/test_config.py +186 -0
- pygeai/tests/core/common/test_decorators.py +69 -0
- pygeai/tests/core/embeddings/__init__.py +0 -0
- pygeai/tests/core/embeddings/test_clients.py +225 -0
- pygeai/tests/core/embeddings/test_managers.py +171 -0
- pygeai/tests/core/embeddings/test_mappers.py +142 -0
- pygeai/tests/core/feedback/__init__.py +0 -0
- pygeai/tests/core/feedback/test_clients.py +64 -0
- pygeai/tests/core/files/test_clients.py +128 -0
- pygeai/tests/core/files/test_managers.py +124 -78
- pygeai/tests/core/files/test_mappers.py +137 -0
- pygeai/tests/core/files/test_models.py +103 -0
- pygeai/tests/core/files/test_responses.py +122 -0
- pygeai/tests/core/llm/__init__.py +0 -0
- pygeai/tests/core/llm/test_clients.py +142 -0
- pygeai/tests/core/plugins/__init__.py +0 -0
- pygeai/tests/core/plugins/test_clients.py +66 -0
- pygeai/tests/core/rerank/test_clients.py +76 -0
- pygeai/tests/core/rerank/test_managers.py +61 -39
- pygeai/tests/core/secrets/__init__.py +0 -0
- pygeai/tests/core/secrets/test_clients.py +264 -0
- pygeai/tests/core/services/__init__.py +0 -0
- pygeai/tests/core/services/test_rest.py +273 -0
- pygeai/tests/core/test_handlers.py +66 -0
- pygeai/tests/core/utils/__init__.py +0 -0
- pygeai/tests/core/utils/test_console.py +80 -0
- pygeai/tests/dbg/__init__.py +0 -0
- pygeai/tests/dbg/test_debugger.py +591 -0
- pygeai/tests/evaluation/__init__.py +0 -0
- pygeai/tests/evaluation/dataset/__init__.py +0 -0
- pygeai/tests/evaluation/dataset/test_clients.py +265 -0
- pygeai/tests/evaluation/plan/__init__.py +0 -0
- pygeai/tests/evaluation/plan/test_clients.py +195 -0
- pygeai/tests/evaluation/result/__init__.py +0 -0
- pygeai/tests/evaluation/result/test_clients.py +66 -0
- pygeai/tests/gam/__init__.py +0 -0
- pygeai/tests/gam/test_clients.py +195 -0
- pygeai/tests/health/__init__.py +0 -0
- pygeai/tests/health/test_clients.py +41 -0
- pygeai/tests/integration/__init__.py +0 -0
- pygeai/tests/integration/assistants/__init__.py +0 -0
- pygeai/tests/integration/assistants/rag/__init__.py +0 -0
- pygeai/tests/integration/assistants/rag/test_create_rag.py +91 -0
- pygeai/tests/integration/chat/__init__.py +0 -0
- pygeai/tests/integration/chat/test_generate_image.py +158 -0
- pygeai/tests/integration/lab/__init__.py +0 -0
- pygeai/tests/integration/lab/agents/__init__.py +0 -0
- pygeai/tests/integration/lab/agents/test_agents_list.py +106 -0
- pygeai/tests/integration/lab/agents/test_create_agent.py +319 -0
- pygeai/tests/integration/lab/agents/test_create_sharing_link.py +70 -0
- pygeai/tests/integration/lab/agents/test_delete_agent.py +75 -0
- pygeai/tests/integration/lab/agents/test_get_agent.py +94 -0
- pygeai/tests/integration/lab/agents/test_publish_agent_revision.py +127 -0
- pygeai/tests/integration/lab/agents/test_update_agent.py +250 -0
- pygeai/tests/integration/lab/processes/__init__.py +0 -0
- pygeai/tests/integration/lab/processes/test_create_process.py +345 -0
- pygeai/tests/integration/lab/processes/test_create_task.py +211 -0
- pygeai/tests/integration/lab/processes/test_delete_process.py +111 -0
- pygeai/tests/integration/lab/processes/test_get_process.py +201 -0
- pygeai/tests/integration/lab/processes/test_list_process_instances.py +91 -0
- pygeai/tests/integration/lab/processes/test_list_processes.py +138 -0
- pygeai/tests/integration/lab/processes/test_publish_process_revision.py +232 -0
- pygeai/tests/integration/lab/processes/test_update_process.py +289 -0
- pygeai/tests/integration/lab/reasoning_strategies/__init__.py +0 -0
- pygeai/tests/integration/lab/reasoning_strategies/test_get_reasoning_strategy.py +70 -0
- pygeai/tests/integration/lab/reasoning_strategies/test_list_reasoning_strategies.py +93 -0
- pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +149 -0
- pygeai/tests/integration/lab/tools/__init__.py +0 -0
- pygeai/tests/integration/lab/tools/test_create_tool.py +288 -0
- pygeai/tests/integration/lab/tools/test_delete_tool.py +87 -0
- pygeai/tests/integration/lab/tools/test_get_parameter.py +98 -0
- pygeai/tests/integration/lab/tools/test_get_tool.py +91 -0
- pygeai/tests/integration/lab/tools/test_list_tools.py +106 -0
- pygeai/tests/integration/lab/tools/test_publish_tool_revision.py +119 -0
- pygeai/tests/integration/lab/tools/test_set_parameter.py +114 -0
- pygeai/tests/integration/lab/tools/test_update_tool.py +267 -0
- pygeai/tests/lab/agents/__init__.py +0 -0
- pygeai/tests/lab/agents/test_clients.py +481 -0
- pygeai/tests/lab/agents/test_mappers.py +440 -0
- pygeai/tests/lab/processes/__init__.py +0 -0
- pygeai/tests/lab/processes/test_clients.py +1416 -0
- pygeai/tests/lab/processes/test_mappers.py +1092 -0
- pygeai/tests/lab/spec/__init__.py +0 -0
- pygeai/tests/lab/spec/test_loader.py +59 -0
- pygeai/tests/lab/spec/test_parsers.py +182 -0
- pygeai/tests/lab/strategies/__init__.py +0 -0
- pygeai/tests/lab/strategies/test_clients.py +241 -0
- pygeai/tests/lab/strategies/test_mappers.py +132 -0
- pygeai/tests/lab/test_managers.py +553 -0
- pygeai/tests/lab/test_models.py +500 -3
- pygeai/tests/lab/tools/__init__.py +0 -0
- pygeai/tests/lab/tools/test_clients.py +521 -0
- pygeai/tests/lab/tools/test_mappers.py +198 -0
- pygeai/tests/migration/__init__.py +0 -0
- pygeai/tests/migration/test_strategies.py +405 -0
- pygeai/tests/migration/test_tools.py +159 -0
- pygeai/tests/organization/limits/test_clients.py +567 -0
- pygeai/tests/organization/limits/test_managers.py +298 -56
- pygeai/tests/organization/test_clients.py +600 -30
- pygeai/tests/organization/test_managers.py +424 -0
- pygeai/tests/organization/test_mappers.py +153 -0
- pygeai/tests/organization/test_responses.py +137 -0
- pygeai/tests/proxy/__init__.py +1 -0
- pygeai/tests/proxy/test_clients.py +397 -0
- pygeai/tests/proxy/test_config.py +171 -0
- pygeai/tests/proxy/test_integration.py +305 -0
- pygeai/tests/proxy/test_managers.py +312 -0
- pygeai/tests/proxy/test_servers.py +387 -0
- pygeai/tests/proxy/test_tool.py +176 -0
- pygeai/tests/snippets/analytics/__init__.py +0 -0
- pygeai/tests/snippets/analytics/get_agent_usage_per_user.py +16 -0
- pygeai/tests/snippets/analytics/get_agents_created_and_modified.py +11 -0
- pygeai/tests/snippets/analytics/get_average_cost_per_request.py +10 -0
- pygeai/tests/snippets/analytics/get_overall_error_rate.py +10 -0
- pygeai/tests/snippets/analytics/get_top_10_agents_by_requests.py +12 -0
- pygeai/tests/snippets/analytics/get_total_active_users.py +10 -0
- pygeai/tests/snippets/analytics/get_total_cost.py +10 -0
- pygeai/tests/snippets/analytics/get_total_requests_per_day.py +12 -0
- pygeai/tests/snippets/analytics/get_total_tokens.py +12 -0
- pygeai/tests/snippets/auth/__init__.py +0 -0
- pygeai/tests/snippets/chat/chat_completion_with_reasoning_effort.py +18 -0
- pygeai/tests/snippets/chat/get_response.py +15 -0
- pygeai/tests/snippets/chat/get_response_complete_example.py +67 -0
- pygeai/tests/snippets/chat/get_response_streaming.py +20 -0
- pygeai/tests/snippets/chat/get_response_with_files.py +16 -0
- pygeai/tests/snippets/chat/get_response_with_instructions.py +19 -0
- pygeai/tests/snippets/chat/get_response_with_metadata.py +24 -0
- pygeai/tests/snippets/chat/get_response_with_parallel_tools.py +58 -0
- pygeai/tests/snippets/chat/get_response_with_reasoning.py +21 -0
- pygeai/tests/snippets/chat/get_response_with_store.py +38 -0
- pygeai/tests/snippets/chat/get_response_with_tools.py +36 -0
- pygeai/tests/snippets/chat/get_response_with_truncation.py +24 -0
- pygeai/tests/snippets/dbg/__init__.py +0 -0
- pygeai/tests/snippets/dbg/basic_debugging.py +32 -0
- pygeai/tests/snippets/dbg/breakpoint_management.py +48 -0
- pygeai/tests/snippets/dbg/file_debugging.py +72 -0
- pygeai/tests/snippets/dbg/module_debugging.py +61 -0
- pygeai/tests/snippets/dbg/stack_navigation.py +45 -0
- pygeai/tests/snippets/dbg/stepping_example.py +40 -0
- pygeai/tests/snippets/embeddings/cache_example.py +31 -0
- pygeai/tests/snippets/embeddings/cohere_example.py +41 -0
- pygeai/tests/snippets/embeddings/openai_base64_example.py +27 -0
- pygeai/tests/snippets/embeddings/openai_example.py +30 -0
- pygeai/tests/snippets/embeddings/similarity_example.py +42 -0
- pygeai/tests/snippets/evaluation/dataset/__init__.py +0 -0
- pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +195 -0
- pygeai/tests/snippets/evaluation/dataset/create_dataset.py +26 -0
- pygeai/tests/snippets/evaluation/dataset/create_dataset_from_file.py +11 -0
- pygeai/tests/snippets/evaluation/dataset/create_dataset_row.py +17 -0
- pygeai/tests/snippets/evaluation/dataset/create_expected_source.py +18 -0
- pygeai/tests/snippets/evaluation/dataset/create_filter_variable.py +19 -0
- pygeai/tests/snippets/evaluation/dataset/delete_dataset.py +9 -0
- pygeai/tests/snippets/evaluation/dataset/delete_dataset_row.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/delete_expected_source.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/delete_filter_variable.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/get_dataset.py +9 -0
- pygeai/tests/snippets/evaluation/dataset/get_dataset_row.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/get_expected_source.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/get_filter_variable.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/list_dataset_rows.py +9 -0
- pygeai/tests/snippets/evaluation/dataset/list_datasets.py +6 -0
- pygeai/tests/snippets/evaluation/dataset/list_expected_sources.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/list_filter_variables.py +10 -0
- pygeai/tests/snippets/evaluation/dataset/update_dataset.py +15 -0
- pygeai/tests/snippets/evaluation/dataset/update_dataset_row.py +20 -0
- pygeai/tests/snippets/evaluation/dataset/update_expected_source.py +18 -0
- pygeai/tests/snippets/evaluation/dataset/update_filter_variable.py +19 -0
- pygeai/tests/snippets/evaluation/dataset/upload_dataset_rows_file.py +10 -0
- pygeai/tests/snippets/evaluation/plan/__init__.py +0 -0
- pygeai/tests/snippets/evaluation/plan/add_plan_system_metric.py +13 -0
- pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +136 -0
- pygeai/tests/snippets/evaluation/plan/create_evaluation_plan.py +24 -0
- pygeai/tests/snippets/evaluation/plan/create_rag_evaluation_plan.py +22 -0
- pygeai/tests/snippets/evaluation/plan/delete_evaluation_plan.py +9 -0
- pygeai/tests/snippets/evaluation/plan/delete_plan_system_metric.py +13 -0
- pygeai/tests/snippets/evaluation/plan/execute_evaluation_plan.py +11 -0
- pygeai/tests/snippets/evaluation/plan/get_evaluation_plan.py +9 -0
- pygeai/tests/snippets/evaluation/plan/get_plan_system_metric.py +13 -0
- pygeai/tests/snippets/evaluation/plan/get_system_metric.py +9 -0
- pygeai/tests/snippets/evaluation/plan/list_evaluation_plans.py +7 -0
- pygeai/tests/snippets/evaluation/plan/list_plan_system_metrics.py +9 -0
- pygeai/tests/snippets/evaluation/plan/list_system_metrics.py +7 -0
- pygeai/tests/snippets/evaluation/plan/update_evaluation_plan.py +22 -0
- pygeai/tests/snippets/evaluation/plan/update_plan_system_metric.py +14 -0
- pygeai/tests/snippets/evaluation/result/__init__.py +0 -0
- pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +150 -0
- pygeai/tests/snippets/evaluation/result/get_evaluation_result.py +26 -0
- pygeai/tests/snippets/evaluation/result/list_evaluation_results.py +17 -0
- pygeai/tests/snippets/files/delete_file.py +1 -4
- pygeai/tests/snippets/files/get_file_content.py +2 -4
- pygeai/tests/snippets/files/get_file_data.py +1 -4
- pygeai/tests/snippets/files/get_file_list.py +1 -6
- pygeai/tests/snippets/files/upload_file.py +1 -5
- pygeai/tests/snippets/gam/gam_access_token.py +87 -0
- pygeai/tests/snippets/lab/agentic_flow_example_1.py +25 -23
- pygeai/tests/snippets/lab/agentic_flow_example_4.py +23 -23
- pygeai/tests/snippets/lab/agents/create_agent.py +5 -8
- pygeai/tests/snippets/lab/agents/create_agent_2.py +1 -5
- pygeai/tests/snippets/lab/agents/create_agent_edge_case.py +48 -0
- pygeai/tests/snippets/lab/agents/create_agent_with_permissions.py +39 -0
- pygeai/tests/snippets/lab/agents/create_agent_with_properties.py +46 -0
- pygeai/tests/snippets/lab/agents/create_agent_without_instructions.py +48 -0
- pygeai/tests/snippets/lab/agents/delete_agent.py +1 -5
- pygeai/tests/snippets/lab/agents/get_agent.py +2 -11
- pygeai/tests/snippets/lab/agents/get_agent_with_new_fields.py +62 -0
- pygeai/tests/snippets/lab/agents/get_sharing_link.py +2 -7
- pygeai/tests/snippets/lab/agents/list_agents.py +4 -7
- pygeai/tests/snippets/lab/agents/publish_agent_revision.py +2 -6
- pygeai/tests/snippets/lab/agents/update_agent.py +1 -5
- pygeai/tests/snippets/lab/agents/update_agent_properties.py +50 -0
- pygeai/tests/snippets/lab/assistant_to_agent.py +191 -0
- pygeai/tests/snippets/lab/crud_ui.py +462 -0
- pygeai/tests/snippets/lab/processes/create_process.py +3 -5
- pygeai/tests/snippets/lab/processes/create_task.py +3 -5
- pygeai/tests/snippets/lab/processes/jobs/list_jobs.py +10 -19
- pygeai/tests/snippets/lab/processes/kbs/create_kb.py +2 -5
- pygeai/tests/snippets/lab/processes/kbs/get_kb.py +10 -16
- pygeai/tests/snippets/lab/processes/kbs/list_kbs.py +13 -20
- pygeai/tests/snippets/lab/processes/kbs/try_all.py +5 -7
- pygeai/tests/snippets/lab/processes/list_processes.py +5 -7
- pygeai/tests/snippets/lab/runner_1.py +1 -1
- pygeai/tests/snippets/lab/samples/summarize_files.py +3 -3
- pygeai/tests/snippets/lab/strategies/create_reasoning_strategy.py +2 -5
- pygeai/tests/snippets/lab/strategies/get_reasoning_strategy.py +2 -5
- pygeai/tests/snippets/lab/strategies/list_reasoning_strategies.py +3 -6
- pygeai/tests/snippets/lab/strategies/update_reasoning_strategy.py +2 -5
- pygeai/tests/snippets/lab/tools/create_tool.py +4 -10
- pygeai/tests/snippets/lab/tools/create_tool_edge_case.py +50 -0
- pygeai/tests/snippets/lab/tools/delete_tool.py +2 -6
- pygeai/tests/snippets/lab/tools/get_parameter.py +5 -7
- pygeai/tests/snippets/lab/tools/get_tool.py +5 -7
- pygeai/tests/snippets/lab/tools/list_tools.py +3 -7
- pygeai/tests/snippets/lab/tools/publish_tool_revision.py +3 -5
- pygeai/tests/snippets/lab/tools/set_parameters.py +4 -9
- pygeai/tests/snippets/lab/tools/update_tool.py +4 -8
- pygeai/tests/snippets/lab/use_cases/__init__.py +0 -0
- pygeai/tests/snippets/lab/use_cases/create_cli_expert.py +1640 -0
- pygeai/tests/snippets/lab/use_cases/create_lab_expert.py +4541 -0
- pygeai/tests/snippets/lab/use_cases/create_tool_headless_web_browser.py +133 -0
- pygeai/tests/snippets/lab/use_cases/create_web_designer.py +189 -0
- pygeai/tests/snippets/lab/use_cases/create_web_reader.py +185 -0
- pygeai/tests/snippets/lab/{file_summarizer_example.py → use_cases/file_summarizer_example.py} +3 -3
- pygeai/tests/snippets/lab/{file_summarizer_example_2.py → use_cases/file_summarizer_example_2.py} +12 -12
- pygeai/tests/snippets/lab/use_cases/update_cli_expert.py +1773 -0
- pygeai/tests/snippets/lab/use_cases/update_lab_expert.py +4541 -0
- pygeai/tests/snippets/lab/use_cases/update_web_designer.py +188 -0
- pygeai/tests/snippets/lab/use_cases/update_web_reader.py +195 -0
- pygeai/tests/snippets/lab/use_cases/update_web_reader_with_tool.py +210 -0
- pygeai/tests/snippets/migrate/__init__.py +45 -0
- pygeai/tests/snippets/migrate/agent_migration.py +110 -0
- pygeai/tests/snippets/migrate/assistant_migration.py +64 -0
- pygeai/tests/snippets/migrate/orchestrator_examples.py +179 -0
- pygeai/tests/snippets/migrate/process_migration.py +64 -0
- pygeai/tests/snippets/migrate/project_migration.py +42 -0
- pygeai/tests/snippets/migrate/tool_migration.py +64 -0
- pygeai/tests/snippets/organization/add_project_member.py +10 -0
- pygeai/tests/snippets/organization/add_project_member_batch.py +44 -0
- pygeai/tests/snippets/organization/create_project.py +2 -2
- pygeai/tests/snippets/organization/get_memberships.py +12 -0
- pygeai/tests/snippets/organization/get_organization_members.py +6 -0
- pygeai/tests/snippets/organization/get_project_members.py +6 -0
- pygeai/tests/snippets/organization/get_project_memberships.py +12 -0
- pygeai/tests/snippets/organization/get_project_roles.py +6 -0
- pygeai/vendor/a2a/__init__.py +1 -0
- pygeai/vendor/a2a/auth/__init__.py +0 -0
- pygeai/vendor/a2a/auth/user.py +31 -0
- pygeai/vendor/a2a/client/__init__.py +19 -0
- pygeai/vendor/a2a/client/client.py +425 -0
- pygeai/vendor/a2a/client/errors.py +33 -0
- pygeai/vendor/a2a/client/helpers.py +22 -0
- pygeai/vendor/a2a/py.typed +0 -0
- pygeai/vendor/a2a/server/__init__.py +1 -0
- pygeai/vendor/a2a/server/agent_execution/__init__.py +18 -0
- pygeai/vendor/a2a/server/agent_execution/agent_executor.py +44 -0
- pygeai/vendor/a2a/server/agent_execution/context.py +155 -0
- pygeai/vendor/a2a/server/agent_execution/request_context_builder.py +20 -0
- pygeai/vendor/a2a/server/agent_execution/simple_request_context_builder.py +77 -0
- pygeai/vendor/a2a/server/apps/__init__.py +16 -0
- pygeai/vendor/a2a/server/apps/jsonrpc/__init__.py +16 -0
- pygeai/vendor/a2a/server/apps/jsonrpc/fastapi_app.py +88 -0
- pygeai/vendor/a2a/server/apps/jsonrpc/jsonrpc_app.py +426 -0
- pygeai/vendor/a2a/server/apps/jsonrpc/starlette_app.py +123 -0
- pygeai/vendor/a2a/server/context.py +23 -0
- pygeai/vendor/a2a/server/events/__init__.py +21 -0
- pygeai/vendor/a2a/server/events/event_consumer.py +149 -0
- pygeai/vendor/a2a/server/events/event_queue.py +156 -0
- pygeai/vendor/a2a/server/events/in_memory_queue_manager.py +85 -0
- pygeai/vendor/a2a/server/events/queue_manager.py +35 -0
- pygeai/vendor/a2a/server/request_handlers/__init__.py +20 -0
- pygeai/vendor/a2a/server/request_handlers/default_request_handler.py +435 -0
- pygeai/vendor/a2a/server/request_handlers/jsonrpc_handler.py +327 -0
- pygeai/vendor/a2a/server/request_handlers/request_handler.py +161 -0
- pygeai/vendor/a2a/server/request_handlers/response_helpers.py +133 -0
- pygeai/vendor/a2a/server/tasks/__init__.py +20 -0
- pygeai/vendor/a2a/server/tasks/inmemory_push_notifier.py +62 -0
- pygeai/vendor/a2a/server/tasks/inmemory_task_store.py +51 -0
- pygeai/vendor/a2a/server/tasks/push_notifier.py +25 -0
- pygeai/vendor/a2a/server/tasks/result_aggregator.py +151 -0
- pygeai/vendor/a2a/server/tasks/task_manager.py +253 -0
- pygeai/vendor/a2a/server/tasks/task_store.py +22 -0
- pygeai/vendor/a2a/server/tasks/task_updater.py +155 -0
- pygeai/vendor/a2a/types.py +1624 -0
- pygeai/vendor/a2a/utils/__init__.py +40 -0
- pygeai/vendor/a2a/utils/artifact.py +72 -0
- pygeai/vendor/a2a/utils/errors.py +69 -0
- pygeai/vendor/a2a/utils/helpers.py +176 -0
- pygeai/vendor/a2a/utils/message.py +83 -0
- pygeai/vendor/a2a/utils/task.py +57 -0
- pygeai/vendor/a2a/utils/telemetry.py +299 -0
- pygeai-0.6.0b15.dist-info/METADATA +205 -0
- pygeai-0.6.0b15.dist-info/RECORD +799 -0
- {pygeai-0.1.51b3.dist-info → pygeai-0.6.0b15.dist-info}/WHEEL +1 -1
- {pygeai-0.1.51b3.dist-info → pygeai-0.6.0b15.dist-info}/entry_points.txt +2 -1
- {pygeai-0.1.51b3.dist-info → pygeai-0.6.0b15.dist-info}/licenses/LICENSE +13 -1
- pygeai-0.6.0b15.dist-info/top_level.txt +1 -0
- docs/geai-proxy/README.md +0 -145
- docs/source/conf.py +0 -45
- pygeai/tests/core/test_managers.py +0 -233
- pygeai-0.1.51b3.dist-info/METADATA +0 -130
- pygeai-0.1.51b3.dist-info/RECORD +0 -324
- pygeai-0.1.51b3.dist-info/top_level.txt +0 -3
- scripts/bump_beta_version.py +0 -56
- {scripts → pygeai/analytics}/__init__.py +0 -0
- /pygeai/tests/snippets/lab/{c_code_fixer_agent_flow.py → use_cases/c_code_fixer_agent_flow.py} +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
import sys
|
|
3
|
+
from unittest import TestCase
|
|
4
|
+
from unittest.mock import patch
|
|
5
|
+
from io import StringIO
|
|
6
|
+
|
|
7
|
+
from pygeai.cli.geai import CLIDriver
|
|
8
|
+
from pygeai.cli.error_handler import ExitCode
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestCLIDriver(TestCase):
|
|
12
|
+
"""
|
|
13
|
+
Test suite for CLIDriver error handling integration.
|
|
14
|
+
Run with: python -m unittest pygeai.tests.cli.test_geai_driver.TestCLIDriver
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def setUp(self):
|
|
18
|
+
"""Set up test fixtures"""
|
|
19
|
+
self.driver = CLIDriver()
|
|
20
|
+
|
|
21
|
+
@patch('sys.stderr', new_callable=StringIO)
|
|
22
|
+
def test_unknown_command_exit_code(self, mock_stderr):
|
|
23
|
+
"""Test that unknown command returns correct exit code"""
|
|
24
|
+
sys.argv = ['geai', 'unknown_command_xyz']
|
|
25
|
+
exit_code = self.driver.main()
|
|
26
|
+
self.assertEqual(exit_code, ExitCode.USER_INPUT_ERROR)
|
|
27
|
+
output = mock_stderr.getvalue()
|
|
28
|
+
self.assertIn("'unknown_command_xyz' is not a valid command", output)
|
|
29
|
+
|
|
30
|
+
@patch('sys.stderr', new_callable=StringIO)
|
|
31
|
+
def test_unknown_command_with_fuzzy_match(self, mock_stderr):
|
|
32
|
+
"""Test unknown command with fuzzy matching suggestion"""
|
|
33
|
+
sys.argv = ['geai', 'halp']
|
|
34
|
+
exit_code = self.driver.main()
|
|
35
|
+
self.assertEqual(exit_code, ExitCode.USER_INPUT_ERROR)
|
|
36
|
+
output = mock_stderr.getvalue()
|
|
37
|
+
self.assertIn("'halp' is not a valid command", output)
|
|
38
|
+
self.assertIn("Did you mean", output)
|
|
39
|
+
|
|
40
|
+
@patch('sys.stdout', new_callable=StringIO)
|
|
41
|
+
def test_help_command_exit_code(self, mock_stdout):
|
|
42
|
+
"""Test that help command returns success exit code"""
|
|
43
|
+
sys.argv = ['geai', 'help']
|
|
44
|
+
exit_code = self.driver.main()
|
|
45
|
+
self.assertEqual(exit_code, ExitCode.SUCCESS)
|
|
46
|
+
|
|
47
|
+
@patch('sys.stdout', new_callable=StringIO)
|
|
48
|
+
def test_version_command_exit_code(self, mock_stdout):
|
|
49
|
+
"""Test that version command returns success exit code"""
|
|
50
|
+
sys.argv = ['geai', 'version']
|
|
51
|
+
exit_code = self.driver.main()
|
|
52
|
+
self.assertEqual(exit_code, ExitCode.SUCCESS)
|
|
53
|
+
|
|
54
|
+
@patch('sys.stderr', new_callable=StringIO)
|
|
55
|
+
def test_invalid_option_exit_code(self, mock_stderr):
|
|
56
|
+
"""Test that invalid option returns correct exit code"""
|
|
57
|
+
sys.argv = ['geai', 'configure', '--invalid-option-xyz']
|
|
58
|
+
exit_code = self.driver.main()
|
|
59
|
+
self.assertEqual(exit_code, ExitCode.USER_INPUT_ERROR)
|
|
60
|
+
output = mock_stderr.getvalue()
|
|
61
|
+
self.assertIn("'--invalid-option-xyz' is not a valid option", output)
|
|
62
|
+
|
|
63
|
+
@patch('sys.stderr', new_callable=StringIO)
|
|
64
|
+
def test_error_message_format(self, mock_stderr):
|
|
65
|
+
"""Test that error messages follow the standard format"""
|
|
66
|
+
sys.argv = ['geai', 'invalidcmd']
|
|
67
|
+
exit_code = self.driver.main()
|
|
68
|
+
output = mock_stderr.getvalue()
|
|
69
|
+
|
|
70
|
+
# Check for standard error format
|
|
71
|
+
self.assertIn("ERROR [", output)
|
|
72
|
+
self.assertIn("→", output)
|
|
73
|
+
self.assertIn("Run 'geai help' for usage information", output)
|
|
74
|
+
|
|
75
|
+
@patch('sys.stderr', new_callable=StringIO)
|
|
76
|
+
def test_available_commands_shown(self, mock_stderr):
|
|
77
|
+
"""Test that available commands are shown for unknown command"""
|
|
78
|
+
sys.argv = ['geai', 'xyz123']
|
|
79
|
+
exit_code = self.driver.main()
|
|
80
|
+
output = mock_stderr.getvalue()
|
|
81
|
+
|
|
82
|
+
# Should show available commands
|
|
83
|
+
self.assertIn("Available commands:", output)
|
|
84
|
+
self.assertIn("help", output)
|
|
85
|
+
self.assertIn("version", output)
|
|
86
|
+
|
|
87
|
+
@patch('sys.stderr', new_callable=StringIO)
|
|
88
|
+
def test_similar_command_suggestion(self, mock_stderr):
|
|
89
|
+
"""Test that similar commands are suggested"""
|
|
90
|
+
sys.argv = ['geai', 'versoin'] # Typo in 'version'
|
|
91
|
+
exit_code = self.driver.main()
|
|
92
|
+
output = mock_stderr.getvalue()
|
|
93
|
+
|
|
94
|
+
self.assertIn("Did you mean", output)
|
|
95
|
+
self.assertIn("version", output)
|
|
96
|
+
|
|
97
|
+
@patch('sys.stdout', new_callable=StringIO)
|
|
98
|
+
def test_keyboard_interrupt_exit_code(self, mock_stdout):
|
|
99
|
+
"""Test keyboard interrupt handling"""
|
|
100
|
+
sys.argv = ['geai', 'help']
|
|
101
|
+
|
|
102
|
+
with patch.object(self.driver, 'process_command', side_effect=KeyboardInterrupt):
|
|
103
|
+
exit_code = self.driver.main()
|
|
104
|
+
self.assertEqual(exit_code, ExitCode.KEYBOARD_INTERRUPT)
|
|
105
|
+
output = mock_stdout.getvalue()
|
|
106
|
+
self.assertIn("Operation cancelled", output)
|
|
107
|
+
|
|
108
|
+
@patch('sys.stderr', new_callable=StringIO)
|
|
109
|
+
def test_unexpected_error_exit_code(self, mock_stderr):
|
|
110
|
+
"""Test unexpected error handling"""
|
|
111
|
+
sys.argv = ['geai', 'help']
|
|
112
|
+
|
|
113
|
+
with patch.object(self.driver, 'process_command', side_effect=RuntimeError("Test error")):
|
|
114
|
+
exit_code = self.driver.main()
|
|
115
|
+
self.assertEqual(exit_code, ExitCode.UNEXPECTED_ERROR)
|
|
116
|
+
output = mock_stderr.getvalue()
|
|
117
|
+
self.assertIn("unexpected error", output)
|
|
118
|
+
self.assertIn("Test error", output)
|
|
119
|
+
|
|
120
|
+
@patch('sys.stderr', new_callable=StringIO)
|
|
121
|
+
def test_configure_with_typo_in_option(self, mock_stderr):
|
|
122
|
+
"""Test configure command with typo in option"""
|
|
123
|
+
sys.argv = ['geai', 'configure', '--kee'] # Typo in '--key'
|
|
124
|
+
exit_code = self.driver.main()
|
|
125
|
+
self.assertEqual(exit_code, ExitCode.USER_INPUT_ERROR)
|
|
126
|
+
output = mock_stderr.getvalue()
|
|
127
|
+
self.assertIn("'--kee' is not a valid option", output)
|
|
128
|
+
|
|
129
|
+
@patch('sys.stdout', new_callable=StringIO)
|
|
130
|
+
def test_default_to_help_when_no_args(self, mock_stdout):
|
|
131
|
+
"""Test that CLI defaults to help when no arguments provided"""
|
|
132
|
+
sys.argv = ['geai']
|
|
133
|
+
exit_code = self.driver.main()
|
|
134
|
+
self.assertEqual(exit_code, ExitCode.SUCCESS)
|
|
135
|
+
output = mock_stdout.getvalue()
|
|
136
|
+
self.assertIn("GEAI CLI", output)
|
|
137
|
+
|
|
138
|
+
def test_exit_codes_are_different(self):
|
|
139
|
+
"""Test that different error types have different exit codes"""
|
|
140
|
+
exit_codes = [
|
|
141
|
+
ExitCode.SUCCESS,
|
|
142
|
+
ExitCode.USER_INPUT_ERROR,
|
|
143
|
+
ExitCode.MISSING_REQUIREMENT,
|
|
144
|
+
ExitCode.SERVICE_ERROR,
|
|
145
|
+
ExitCode.KEYBOARD_INTERRUPT,
|
|
146
|
+
ExitCode.UNEXPECTED_ERROR,
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
# All exit codes should be unique
|
|
150
|
+
self.assertEqual(len(exit_codes), len(set(exit_codes)))
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
if __name__ == '__main__':
|
|
154
|
+
unittest.main()
|
pygeai/tests/cli/test_parsers.py
CHANGED
|
@@ -35,7 +35,7 @@ class TestCommandParser(TestCase):
|
|
|
35
35
|
def test_identify_command_invalid(self):
|
|
36
36
|
with self.assertRaises(UnknownArgumentError) as context:
|
|
37
37
|
self.parser.identify_command('invalid')
|
|
38
|
-
self.assertEqual(str(context.exception), "'invalid' is not a valid command.
|
|
38
|
+
self.assertEqual(str(context.exception), "'invalid' is not a valid command.")
|
|
39
39
|
|
|
40
40
|
def test_extract_option_list_valid(self):
|
|
41
41
|
args = ['--detail', 'full', '--name', 'Project1']
|
|
@@ -51,7 +51,7 @@ class TestCommandParser(TestCase):
|
|
|
51
51
|
with self.assertRaises(UnknownArgumentError) as context:
|
|
52
52
|
self.parser.extract_option_list(args)
|
|
53
53
|
self.assertEqual(str(context.exception),
|
|
54
|
-
"'--invalid' is not a valid option.
|
|
54
|
+
"'--invalid' is not a valid option.")
|
|
55
55
|
|
|
56
56
|
def test_identify_command_valid_multiple_identifiers(self):
|
|
57
57
|
command = self.parser.identify_command('organization')
|
|
@@ -77,7 +77,7 @@ class TestCommandParser(TestCase):
|
|
|
77
77
|
def test_identify_command_empty_string(self):
|
|
78
78
|
with self.assertRaises(UnknownArgumentError) as context:
|
|
79
79
|
self.parser.identify_command('')
|
|
80
|
-
self.assertEqual(str(context.exception), "'' is not a valid command.
|
|
80
|
+
self.assertEqual(str(context.exception), "'' is not a valid command.")
|
|
81
81
|
|
|
82
82
|
def test_extract_option_list_empty_arguments(self):
|
|
83
83
|
args = []
|
|
@@ -122,7 +122,7 @@ class TestCommandParser(TestCase):
|
|
|
122
122
|
with self.assertRaises(UnknownArgumentError) as context:
|
|
123
123
|
self.parser.extract_option_list(args)
|
|
124
124
|
self.assertEqual(str(context.exception),
|
|
125
|
-
"'--invalid' is not a valid option.
|
|
125
|
+
"'--invalid' is not a valid option.")
|
|
126
126
|
|
|
127
127
|
def test_identify_command_subcommand(self):
|
|
128
128
|
command_with_subcommands = Command(
|
|
@@ -151,4 +151,4 @@ class TestCommandParser(TestCase):
|
|
|
151
151
|
with self.assertRaises(UnknownArgumentError) as context:
|
|
152
152
|
self.parser.identify_command('nonexistent')
|
|
153
153
|
self.assertEqual(str(context.exception),
|
|
154
|
-
"'nonexistent' is not a valid command.
|
|
154
|
+
"'nonexistent' is not a valid command.")
|
|
@@ -149,12 +149,19 @@ LLM_SETTINGS_5 = {
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
REQUEST_ITEM = {
|
|
152
|
+
"apiToken": "test-api-token",
|
|
152
153
|
"assistant": "N/D",
|
|
154
|
+
"cost": 0.001,
|
|
155
|
+
"elapsedTimeMs": 1500,
|
|
156
|
+
"endTimestamp": "2025-02-25T15:03:15.144",
|
|
153
157
|
"intent": None,
|
|
154
158
|
"timestamp": "2025-02-25T15:03:13.644",
|
|
155
159
|
"prompt": None,
|
|
156
160
|
"output": None,
|
|
157
161
|
"inputText": None,
|
|
162
|
+
"module": "test-module",
|
|
163
|
+
"sessionId": "test-session-id",
|
|
164
|
+
"startTimestamp": "2025-02-25T15:03:13.644",
|
|
158
165
|
"status": "succeeded"
|
|
159
166
|
}
|
|
160
167
|
|
|
@@ -351,8 +351,22 @@ class TestModelMapper(TestCase):
|
|
|
351
351
|
self.assertEqual(usage_limit.remaining_usage, 50)
|
|
352
352
|
|
|
353
353
|
def test_map_to_item(self):
|
|
354
|
-
data = {
|
|
355
|
-
|
|
354
|
+
data = {
|
|
355
|
+
"apiToken": "test-token",
|
|
356
|
+
"assistant": "Assistant 1",
|
|
357
|
+
"cost": 0.5,
|
|
358
|
+
"elapsedTimeMs": 100,
|
|
359
|
+
"endTimestamp": "2025-02-05T12:00:05Z",
|
|
360
|
+
"intent": "Intent 1",
|
|
361
|
+
"module": "test-module",
|
|
362
|
+
"timestamp": "2025-02-05T12:00:00Z",
|
|
363
|
+
"prompt": "Test prompt",
|
|
364
|
+
"output": "Test output",
|
|
365
|
+
"inputText": "Test input",
|
|
366
|
+
"sessionId": "test-session",
|
|
367
|
+
"startTimestamp": "2025-02-05T12:00:00Z",
|
|
368
|
+
"status": "succeeded"
|
|
369
|
+
}
|
|
356
370
|
item = ModelMapper.map_to_item(data)
|
|
357
371
|
|
|
358
372
|
self.assertTrue(isinstance(item, RequestItem))
|
|
@@ -472,45 +486,65 @@ class TestModelMapper(TestCase):
|
|
|
472
486
|
|
|
473
487
|
def test_map_to_project_item(self):
|
|
474
488
|
data = {
|
|
489
|
+
"apiToken": "test-token",
|
|
475
490
|
"assistant": "Test Assistant",
|
|
491
|
+
"cost": 0.5,
|
|
492
|
+
"elapsedTimeMs": 100,
|
|
493
|
+
"endTimestamp": "2025-02-05T12:00:05Z",
|
|
476
494
|
"intent": "Test Intent",
|
|
495
|
+
"module": "test-module",
|
|
477
496
|
"timestamp": "2025-02-05T12:00:00Z",
|
|
478
497
|
"prompt": "Test prompt",
|
|
479
498
|
"output": "Test output",
|
|
480
499
|
"inputText": "Test input text",
|
|
481
|
-
"
|
|
500
|
+
"sessionId": "test-session-id",
|
|
501
|
+
"startTimestamp": "2025-02-05T12:00:00Z",
|
|
502
|
+
"status": "succeeded"
|
|
482
503
|
}
|
|
483
504
|
item = ModelMapper.map_to_item(data)
|
|
484
505
|
|
|
485
506
|
self.assertTrue(isinstance(item, RequestItem))
|
|
486
507
|
self.assertEqual(item.assistant, "Test Assistant")
|
|
487
508
|
self.assertEqual(item.intent, "Test Intent")
|
|
488
|
-
self.assertEqual(item.timestamp, "2025-02-05T12:00:00Z")
|
|
489
509
|
self.assertEqual(item.prompt, "Test prompt")
|
|
490
510
|
self.assertEqual(item.output, "Test output")
|
|
491
511
|
self.assertEqual(item.input_text, "Test input text")
|
|
492
|
-
self.assertEqual(item.status, "
|
|
512
|
+
self.assertEqual(item.status, "succeeded")
|
|
493
513
|
|
|
494
514
|
def test_map_to_item_list(self):
|
|
495
515
|
data = {
|
|
496
516
|
"items": [
|
|
497
517
|
{
|
|
518
|
+
"apiToken": "test-token-1",
|
|
498
519
|
"assistant": "Assistant 1",
|
|
520
|
+
"cost": 0.5,
|
|
521
|
+
"elapsedTimeMs": 100,
|
|
522
|
+
"endTimestamp": "2025-02-05T12:00:05Z",
|
|
499
523
|
"intent": "Intent 1",
|
|
524
|
+
"module": "test-module",
|
|
500
525
|
"timestamp": "2025-02-05T12:00:00Z",
|
|
501
526
|
"prompt": "Prompt 1",
|
|
502
527
|
"output": "Output 1",
|
|
503
528
|
"inputText": "Input Text 1",
|
|
504
|
-
"
|
|
529
|
+
"sessionId": "test-session-1",
|
|
530
|
+
"startTimestamp": "2025-02-05T12:00:00Z",
|
|
531
|
+
"status": "succeeded"
|
|
505
532
|
},
|
|
506
533
|
{
|
|
534
|
+
"apiToken": "test-token-2",
|
|
507
535
|
"assistant": "Assistant 2",
|
|
536
|
+
"cost": 0.7,
|
|
537
|
+
"elapsedTimeMs": 150,
|
|
538
|
+
"endTimestamp": "2025-02-05T12:05:10Z",
|
|
508
539
|
"intent": "Intent 2",
|
|
540
|
+
"module": "test-module",
|
|
509
541
|
"timestamp": "2025-02-05T12:05:00Z",
|
|
510
542
|
"prompt": "Prompt 2",
|
|
511
543
|
"output": "Output 2",
|
|
512
544
|
"inputText": "Input Text 2",
|
|
513
|
-
"
|
|
545
|
+
"sessionId": "test-session-2",
|
|
546
|
+
"startTimestamp": "2025-02-05T12:05:00Z",
|
|
547
|
+
"status": "succeeded"
|
|
514
548
|
}
|
|
515
549
|
]
|
|
516
550
|
}
|
|
@@ -522,16 +556,14 @@ class TestModelMapper(TestCase):
|
|
|
522
556
|
|
|
523
557
|
self.assertEqual(items[0].assistant, "Assistant 1")
|
|
524
558
|
self.assertEqual(items[0].intent, "Intent 1")
|
|
525
|
-
self.assertEqual(items[0].timestamp, "2025-02-05T12:00:00Z")
|
|
526
559
|
self.assertEqual(items[0].prompt, "Prompt 1")
|
|
527
560
|
self.assertEqual(items[0].output, "Output 1")
|
|
528
561
|
self.assertEqual(items[0].input_text, "Input Text 1")
|
|
529
|
-
self.assertEqual(items[0].status, "
|
|
562
|
+
self.assertEqual(items[0].status, "succeeded")
|
|
530
563
|
|
|
531
564
|
self.assertEqual(items[1].assistant, "Assistant 2")
|
|
532
565
|
self.assertEqual(items[1].intent, "Intent 2")
|
|
533
|
-
self.assertEqual(items[1].timestamp, "2025-02-05T12:05:00Z")
|
|
534
566
|
self.assertEqual(items[1].prompt, "Prompt 2")
|
|
535
567
|
self.assertEqual(items[1].output, "Output 2")
|
|
536
568
|
self.assertEqual(items[1].input_text, "Input Text 2")
|
|
537
|
-
self.assertEqual(items[1].status, "
|
|
569
|
+
self.assertEqual(items[1].status, "succeeded")
|
|
@@ -192,7 +192,9 @@ class TestModels(TestCase):
|
|
|
192
192
|
request_item = RequestItem.model_validate(request_item_data)
|
|
193
193
|
self.assertEqual(request_item.assistant, request_item_data.get("assistant"))
|
|
194
194
|
self.assertEqual(request_item.intent, request_item_data.get("intent"))
|
|
195
|
-
|
|
195
|
+
# Compare timestamps by checking that the string representation starts with the expected value
|
|
196
|
+
expected_timestamp = request_item_data.get("timestamp").replace("Z", "+00:00") if request_item_data.get("timestamp").endswith("Z") else request_item_data.get("timestamp")
|
|
197
|
+
self.assertTrue(request_item.timestamp.isoformat().startswith(expected_timestamp))
|
|
196
198
|
self.assertEqual(request_item.prompt, request_item_data.get("prompt"))
|
|
197
199
|
self.assertEqual(request_item.output, request_item_data.get("output"))
|
|
198
200
|
self.assertEqual(request_item.input_text, request_item_data.get("inputText"))
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest.mock import MagicMock
|
|
3
|
+
|
|
4
|
+
from pygeai.core.base.responses import ErrorListResponse, EmptyResponse
|
|
5
|
+
from pygeai.core.base.models import Error
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestCoreBaseResponses(unittest.TestCase):
|
|
9
|
+
"""
|
|
10
|
+
python -m unittest pygeai.tests.core.base.test_responses.TestCoreBaseResponses
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def test_error_list_response_to_dict(self):
|
|
14
|
+
error1 = MagicMock(spec=Error)
|
|
15
|
+
error1.to_dict.return_value = {"code": "E001", "message": "Error 1"}
|
|
16
|
+
error2 = MagicMock(spec=Error)
|
|
17
|
+
error2.to_dict.return_value = {"code": "E002", "message": "Error 2"}
|
|
18
|
+
|
|
19
|
+
response = ErrorListResponse(errors=[error1, error2])
|
|
20
|
+
result = response.to_dict()
|
|
21
|
+
|
|
22
|
+
self.assertEqual(len(result), 2)
|
|
23
|
+
self.assertEqual(result[0], {"code": "E001", "message": "Error 1"})
|
|
24
|
+
self.assertEqual(result[1], {"code": "E002", "message": "Error 2"})
|
|
25
|
+
|
|
26
|
+
def test_empty_response_with_dict_content(self):
|
|
27
|
+
response = EmptyResponse(content={"key": "value"})
|
|
28
|
+
result = response.to_dict()
|
|
29
|
+
|
|
30
|
+
self.assertEqual(result, {"content": {"key": "value"}})
|
|
31
|
+
|
|
32
|
+
def test_empty_response_with_string_content(self):
|
|
33
|
+
response = EmptyResponse(content="test message")
|
|
34
|
+
result = response.to_dict()
|
|
35
|
+
|
|
36
|
+
self.assertEqual(result, {"content": "test message"})
|
|
37
|
+
|
|
38
|
+
def test_empty_response_with_none_content(self):
|
|
39
|
+
response = EmptyResponse(content=None)
|
|
40
|
+
result = response.to_dict()
|
|
41
|
+
|
|
42
|
+
self.assertEqual(result, {})
|
|
43
|
+
|
|
44
|
+
def test_empty_response_str(self):
|
|
45
|
+
response = EmptyResponse(content={"test": "data"})
|
|
46
|
+
result = str(response)
|
|
47
|
+
|
|
48
|
+
self.assertIn("content", result)
|
|
49
|
+
self.assertIn("test", result)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if __name__ == '__main__':
|
|
53
|
+
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest import TestCase
|
|
3
|
+
from unittest.mock import patch, mock_open
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from pygeai.core.common.config import SettingsManager, get_settings
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestSettingsManager(TestCase):
|
|
10
|
+
"""
|
|
11
|
+
python -m unittest pygeai.tests.core.common.test_config.TestSettingsManager
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def setUp(self):
|
|
15
|
+
# Mock the credentials file path to use a sample file for testing
|
|
16
|
+
self.sample_creds_path = Path("pygeai/tests/core/common/data/credentials")
|
|
17
|
+
self.creds_content = """
|
|
18
|
+
[default]
|
|
19
|
+
GEAI_API_KEY = test_api_key
|
|
20
|
+
GEAI_API_BASE_URL = https://api.test.com
|
|
21
|
+
GEAI_API_EVAL_URL = https://eval.test.com
|
|
22
|
+
|
|
23
|
+
[alias1]
|
|
24
|
+
GEAI_API_KEY = alias1_key
|
|
25
|
+
GEAI_API_BASE_URL = https://api.alias1.com
|
|
26
|
+
"""
|
|
27
|
+
# Mock file existence and content to avoid touching real filesystem
|
|
28
|
+
self.file_patch = patch('pathlib.Path.exists', return_value=True)
|
|
29
|
+
self.file_patch.start()
|
|
30
|
+
self.open_patch = patch('pathlib.Path.open', mock_open(read_data=self.creds_content))
|
|
31
|
+
self.open_patch.start()
|
|
32
|
+
self.touch_patch = patch('pathlib.Path.touch', return_value=None)
|
|
33
|
+
self.touch_patch.start()
|
|
34
|
+
|
|
35
|
+
# Mock configparser read to enforce our test content
|
|
36
|
+
self.config_read_patch = patch('configparser.ConfigParser.read')
|
|
37
|
+
self.mock_config_read = self.config_read_patch.start()
|
|
38
|
+
self.mock_config_read.return_value = None # We'll set up config manually in tests if needed
|
|
39
|
+
|
|
40
|
+
# Mock environment variables to be empty initially
|
|
41
|
+
self.env_patch = patch.dict('os.environ', {}, clear=True)
|
|
42
|
+
self.env_patch.start()
|
|
43
|
+
|
|
44
|
+
# Mock sys.stdout.write to capture output
|
|
45
|
+
self.stdout_patch = patch('sys.stdout.write')
|
|
46
|
+
self.mock_stdout = self.stdout_patch.start()
|
|
47
|
+
|
|
48
|
+
# Initialize SettingsManager with mocked settings dir and creds file
|
|
49
|
+
self.settings = SettingsManager()
|
|
50
|
+
|
|
51
|
+
# Manually set up config with test content for consistency
|
|
52
|
+
self.settings.config.clear()
|
|
53
|
+
self.settings.config.read_string(self.creds_content)
|
|
54
|
+
|
|
55
|
+
def tearDown(self):
|
|
56
|
+
self.file_patch.stop()
|
|
57
|
+
self.open_patch.stop()
|
|
58
|
+
self.touch_patch.stop()
|
|
59
|
+
self.env_patch.stop()
|
|
60
|
+
self.stdout_patch.stop()
|
|
61
|
+
self.config_read_patch.stop()
|
|
62
|
+
|
|
63
|
+
def test_init_with_existing_file(self):
|
|
64
|
+
self.assertTrue("default" in self.settings.config)
|
|
65
|
+
self.assertTrue("alias1" in self.settings.config)
|
|
66
|
+
self.assertEqual(self.settings.config["default"]["GEAI_API_KEY"], "test_api_key")
|
|
67
|
+
self.mock_stdout.assert_not_called() # No message since file exists
|
|
68
|
+
|
|
69
|
+
def test_init_with_non_existing_file(self):
|
|
70
|
+
with patch('pathlib.Path.exists', return_value=False):
|
|
71
|
+
settings = SettingsManager()
|
|
72
|
+
self.assertEqual(len(settings.config.sections()), 0) # No sections in empty config
|
|
73
|
+
self.mock_stdout.assert_called()
|
|
74
|
+
self.assertTrue(any("Credentials file not found" in str(call) for call in self.mock_stdout.call_args_list))
|
|
75
|
+
|
|
76
|
+
def test_has_value_existing(self):
|
|
77
|
+
result = self.settings.has_value("GEAI_API_KEY", "default")
|
|
78
|
+
self.assertTrue(result)
|
|
79
|
+
|
|
80
|
+
def test_has_value_non_existing_key(self):
|
|
81
|
+
result = self.settings.has_value("INVALID_KEY", "default")
|
|
82
|
+
self.assertFalse(result)
|
|
83
|
+
|
|
84
|
+
def test_has_value_non_existing_alias(self):
|
|
85
|
+
result = self.settings.has_value("GEAI_API_KEY", "invalid_alias")
|
|
86
|
+
self.assertFalse(result)
|
|
87
|
+
|
|
88
|
+
def test_get_setting_value_existing(self):
|
|
89
|
+
value = self.settings.get_setting_value("GEAI_API_KEY", "default")
|
|
90
|
+
self.assertEqual(value, "test_api_key")
|
|
91
|
+
|
|
92
|
+
def test_get_setting_value_non_existing_alias(self):
|
|
93
|
+
value = self.settings.get_setting_value("GEAI_API_KEY", "invalid_alias")
|
|
94
|
+
self.assertIsNone(value)
|
|
95
|
+
|
|
96
|
+
def test_get_setting_value_non_existing_key(self):
|
|
97
|
+
with patch('sys.stdout.write') as mock_write:
|
|
98
|
+
value = self.settings.get_setting_value("INVALID_KEY", "default")
|
|
99
|
+
self.assertEqual(value, "")
|
|
100
|
+
mock_write.assert_called()
|
|
101
|
+
self.assertIn("'INVALID_KEY' not found in alias 'default'", str(mock_write.call_args))
|
|
102
|
+
|
|
103
|
+
def test_get_setting_value_non_existing_key_eval_url(self):
|
|
104
|
+
with patch('sys.stdout.write') as mock_write:
|
|
105
|
+
with patch.object(self.settings, 'set_eval_url') as mock_set_eval:
|
|
106
|
+
value = self.settings.get_setting_value("GEAI_API_EVAL_URL", "default")
|
|
107
|
+
self.assertEqual(value, "https://eval.test.com") # From mocked content
|
|
108
|
+
mock_write.assert_not_called() # No message since it's in creds file
|
|
109
|
+
mock_set_eval.assert_not_called() # Not called since value exists
|
|
110
|
+
|
|
111
|
+
def test_set_setting_value_new_alias(self):
|
|
112
|
+
with patch('pathlib.Path.open', mock_open()) as mock_file:
|
|
113
|
+
self.settings.set_setting_value("NEW_KEY", "new_value", "new_alias")
|
|
114
|
+
self.assertTrue("new_alias" in self.settings.config)
|
|
115
|
+
self.assertEqual(self.settings.config["new_alias"]["NEW_KEY"], "new_value")
|
|
116
|
+
mock_file.assert_called_once()
|
|
117
|
+
|
|
118
|
+
def test_set_setting_value_existing_alias(self):
|
|
119
|
+
with patch('pathlib.Path.open', mock_open()) as mock_file:
|
|
120
|
+
self.settings.set_setting_value("GEAI_API_KEY", "updated_key", "default")
|
|
121
|
+
self.assertEqual(self.settings.config["default"]["GEAI_API_KEY"], "updated_key")
|
|
122
|
+
mock_file.assert_called_once()
|
|
123
|
+
|
|
124
|
+
def test_get_api_key_from_env(self):
|
|
125
|
+
with patch.dict('os.environ', {'GEAI_API_KEY': 'env_api_key'}, clear=True):
|
|
126
|
+
api_key = self.settings.get_api_key("default")
|
|
127
|
+
self.assertEqual(api_key, "env_api_key")
|
|
128
|
+
|
|
129
|
+
def test_get_api_key_from_file(self):
|
|
130
|
+
api_key = self.settings.get_api_key("default")
|
|
131
|
+
self.assertEqual(api_key, "test_api_key")
|
|
132
|
+
|
|
133
|
+
def test_get_api_key_alias(self):
|
|
134
|
+
api_key = self.settings.get_api_key("alias1")
|
|
135
|
+
self.assertEqual(api_key, "alias1_key")
|
|
136
|
+
|
|
137
|
+
def test_set_api_key(self):
|
|
138
|
+
with patch('pathlib.Path.open', mock_open()) as mock_file:
|
|
139
|
+
self.settings.set_api_key("new_api_key", "default")
|
|
140
|
+
self.assertEqual(self.settings.config["default"]["GEAI_API_KEY"], "new_api_key")
|
|
141
|
+
mock_file.assert_called_once()
|
|
142
|
+
|
|
143
|
+
def test_get_base_url_from_env(self):
|
|
144
|
+
with patch.dict('os.environ', {'GEAI_API_BASE_URL': 'https://env.test.com'}, clear=True):
|
|
145
|
+
base_url = self.settings.get_base_url("default")
|
|
146
|
+
self.assertEqual(base_url, "https://env.test.com")
|
|
147
|
+
|
|
148
|
+
def test_get_base_url_from_file(self):
|
|
149
|
+
base_url = self.settings.get_base_url("default")
|
|
150
|
+
self.assertEqual(base_url, "https://api.test.com")
|
|
151
|
+
|
|
152
|
+
def test_get_base_url_alias(self):
|
|
153
|
+
base_url = self.settings.get_base_url("alias1")
|
|
154
|
+
self.assertEqual(base_url, "https://api.alias1.com")
|
|
155
|
+
|
|
156
|
+
def test_set_base_url(self):
|
|
157
|
+
with patch('pathlib.Path.open', mock_open()) as mock_file:
|
|
158
|
+
self.settings.set_base_url("https://new.test.com", "default")
|
|
159
|
+
self.assertEqual(self.settings.config["default"]["GEAI_API_BASE_URL"], "https://new.test.com")
|
|
160
|
+
mock_file.assert_called_once()
|
|
161
|
+
|
|
162
|
+
def test_get_eval_url_from_env(self):
|
|
163
|
+
with patch.dict('os.environ', {'GEAI_API_EVAL_URL': 'https://env.eval.test.com'}, clear=True):
|
|
164
|
+
eval_url = self.settings.get_eval_url("default")
|
|
165
|
+
self.assertEqual(eval_url, "https://env.eval.test.com")
|
|
166
|
+
|
|
167
|
+
def test_get_eval_url_from_file(self):
|
|
168
|
+
eval_url = self.settings.get_eval_url("default")
|
|
169
|
+
self.assertEqual(eval_url, "https://eval.test.com")
|
|
170
|
+
|
|
171
|
+
def test_set_eval_url(self):
|
|
172
|
+
with patch('pathlib.Path.open', mock_open()) as mock_file:
|
|
173
|
+
self.settings.set_eval_url("https://new.eval.test.com", "default")
|
|
174
|
+
self.assertEqual(self.settings.config["default"]["GEAI_API_EVAL_URL"], "https://new.eval.test.com")
|
|
175
|
+
mock_file.assert_called_once()
|
|
176
|
+
|
|
177
|
+
def test_list_aliases(self):
|
|
178
|
+
aliases = self.settings.list_aliases()
|
|
179
|
+
self.assertEqual(len(aliases), 2)
|
|
180
|
+
self.assertEqual(aliases["default"], "https://api.test.com")
|
|
181
|
+
self.assertEqual(aliases["alias1"], "https://api.alias1.com")
|
|
182
|
+
|
|
183
|
+
def test_get_settings_lru_cache(self):
|
|
184
|
+
settings1 = get_settings()
|
|
185
|
+
settings2 = get_settings()
|
|
186
|
+
self.assertIs(settings1, settings2) # Should return the same instance due to lru_cache
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
import io
|
|
3
|
+
import sys
|
|
4
|
+
from unittest.mock import patch
|
|
5
|
+
from pygeai.core.common.decorators import measure_execution_time, handler_server_error
|
|
6
|
+
from pygeai.core.common.exceptions import ServerResponseError
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestDecorators(unittest.TestCase):
|
|
10
|
+
"""
|
|
11
|
+
python -m unittest pygeai.tests.core.common.test_decorators.TestDecorators
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def test_measure_execution_time_success(self):
|
|
15
|
+
@measure_execution_time
|
|
16
|
+
def sample_function():
|
|
17
|
+
return "Success"
|
|
18
|
+
|
|
19
|
+
# Capture stdout to verify printed messages
|
|
20
|
+
captured_output = io.StringIO()
|
|
21
|
+
sys.stdout = captured_output
|
|
22
|
+
|
|
23
|
+
result = sample_function()
|
|
24
|
+
|
|
25
|
+
sys.stdout = sys.__stdout__ # Restore stdout
|
|
26
|
+
output = captured_output.getvalue()
|
|
27
|
+
self.assertIn("Measuring execution time for: sample_function", output)
|
|
28
|
+
self.assertIn("Function sample_function executed in", output)
|
|
29
|
+
self.assertEqual(result, "Success")
|
|
30
|
+
|
|
31
|
+
def test_measure_execution_time_with_exception(self):
|
|
32
|
+
@measure_execution_time
|
|
33
|
+
def failing_function():
|
|
34
|
+
raise ValueError("Test error")
|
|
35
|
+
|
|
36
|
+
# Capture stdout to verify printed messages
|
|
37
|
+
captured_output = io.StringIO()
|
|
38
|
+
sys.stdout = captured_output
|
|
39
|
+
|
|
40
|
+
result = None
|
|
41
|
+
try:
|
|
42
|
+
result = failing_function()
|
|
43
|
+
except ValueError:
|
|
44
|
+
pass # The decorator catches the exception, so this won't be reached
|
|
45
|
+
|
|
46
|
+
sys.stdout = sys.__stdout__ # Restore stdout
|
|
47
|
+
output = captured_output.getvalue()
|
|
48
|
+
self.assertIn("Measuring execution time for: failing_function", output)
|
|
49
|
+
self.assertIn("Error measuring execution time: Test error", output)
|
|
50
|
+
self.assertIsNone(result) # No return value since exception was caught
|
|
51
|
+
|
|
52
|
+
def test_handler_server_error_no_error(self):
|
|
53
|
+
@handler_server_error
|
|
54
|
+
def successful_function():
|
|
55
|
+
return {"data": "Success"}
|
|
56
|
+
|
|
57
|
+
result = successful_function()
|
|
58
|
+
self.assertEqual(result, {"data": "Success"})
|
|
59
|
+
|
|
60
|
+
def test_handler_server_error_with_error(self):
|
|
61
|
+
@handler_server_error
|
|
62
|
+
def error_function():
|
|
63
|
+
return {"error": "Server error message"}
|
|
64
|
+
|
|
65
|
+
with self.assertRaises(ServerResponseError) as context:
|
|
66
|
+
error_function()
|
|
67
|
+
|
|
68
|
+
self.assertIn("There was an error communicating with the server: Server error message", str(context.exception))
|
|
69
|
+
|
|
File without changes
|