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/dbg/debugger.py
ADDED
|
@@ -0,0 +1,870 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
import inspect
|
|
4
|
+
import readline
|
|
5
|
+
import pprint
|
|
6
|
+
import argparse
|
|
7
|
+
from types import FrameType
|
|
8
|
+
from typing import Optional, Any, Callable, Set, Dict, List, Tuple
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
|
|
11
|
+
from pygeai.cli.geai import main as geai
|
|
12
|
+
from pygeai.core.utils.console import Console
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class Breakpoint:
|
|
17
|
+
"""Represents a breakpoint with optional conditions."""
|
|
18
|
+
module: Optional[str] = None
|
|
19
|
+
function_name: Optional[str] = None
|
|
20
|
+
condition: Optional[str] = None
|
|
21
|
+
enabled: bool = True
|
|
22
|
+
hit_count: int = 0
|
|
23
|
+
|
|
24
|
+
def __hash__(self):
|
|
25
|
+
return hash((self.module, self.function_name))
|
|
26
|
+
|
|
27
|
+
def __eq__(self, other):
|
|
28
|
+
if not isinstance(other, Breakpoint):
|
|
29
|
+
return False
|
|
30
|
+
return self.module == other.module and self.function_name == other.function_name
|
|
31
|
+
|
|
32
|
+
def matches(self, module: str, func_name: str) -> bool:
|
|
33
|
+
"""Check if this breakpoint matches the given module and function."""
|
|
34
|
+
if not self.enabled:
|
|
35
|
+
return False
|
|
36
|
+
module_match = self.module is None or self.module == module
|
|
37
|
+
func_match = self.function_name is None or self.function_name == func_name
|
|
38
|
+
return module_match and func_match
|
|
39
|
+
|
|
40
|
+
def __str__(self):
|
|
41
|
+
status = "enabled" if self.enabled else "disabled"
|
|
42
|
+
cond = f" [if {self.condition}]" if self.condition else ""
|
|
43
|
+
return f"{self.module or '*'}:{self.function_name or '*'} ({status}, hits: {self.hit_count}){cond}"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Debugger:
|
|
47
|
+
"""
|
|
48
|
+
A debugger for the GEAI application to trace and control execution flow.
|
|
49
|
+
|
|
50
|
+
This class implements a custom debugging mechanism using Python's `sys.settrace` to intercept function calls
|
|
51
|
+
and pause execution at specified breakpoints. Breakpoints can be set for specific modules or functions, allowing
|
|
52
|
+
developers to inspect local variables, execute arbitrary code in the current context, and control program flow
|
|
53
|
+
through an interactive command interface.
|
|
54
|
+
|
|
55
|
+
Features:
|
|
56
|
+
- Module filtering for performance (only traces pygeai modules by default)
|
|
57
|
+
- Breakpoint management (add, list, remove, enable/disable, conditional)
|
|
58
|
+
- Stack navigation (up/down frames)
|
|
59
|
+
- Stepping (step-into, step-over, step-out)
|
|
60
|
+
- Variable inspection with pretty-printing
|
|
61
|
+
- Source code display
|
|
62
|
+
- Stack trace viewing
|
|
63
|
+
- Readline support for command history
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __init__(self, target: Optional[Callable] = None, module_filter: str = "pygeai", verbose: bool = False, log_level: str = 'DEBUG'):
|
|
67
|
+
"""
|
|
68
|
+
Initialize the debugger.
|
|
69
|
+
|
|
70
|
+
:param target: Optional[Callable] - The callable to debug. If None, defaults to pygeai.cli.geai.main (optional).
|
|
71
|
+
:param module_filter: str - Only trace modules starting with this prefix (for performance). Empty string traces all modules. Use '__main__' to trace only the main script (default is 'pygeai').
|
|
72
|
+
:param verbose: bool - If True, enable logging for pygeai modules (default is False).
|
|
73
|
+
:param log_level: str - Log level for verbose mode: 'DEBUG', 'INFO', 'WARNING', 'ERROR' (default is 'DEBUG').
|
|
74
|
+
"""
|
|
75
|
+
self.target = target or geai
|
|
76
|
+
self.module_filter = module_filter
|
|
77
|
+
self.verbose = verbose
|
|
78
|
+
self.log_level = getattr(logging, log_level.upper(), logging.DEBUG)
|
|
79
|
+
self._setup_logging()
|
|
80
|
+
self.logger = logging.getLogger('geai.dbg')
|
|
81
|
+
|
|
82
|
+
self.breakpoints: Dict[Tuple[Optional[str], Optional[str]], Breakpoint] = {}
|
|
83
|
+
self.paused: bool = False
|
|
84
|
+
self.current_frame: Optional[FrameType] = None
|
|
85
|
+
self.frame_stack: List[FrameType] = []
|
|
86
|
+
self.current_frame_index: int = 0
|
|
87
|
+
|
|
88
|
+
# Stepping state
|
|
89
|
+
self.step_mode: Optional[str] = None # 'step', 'next', 'return', 'until'
|
|
90
|
+
self.step_frame: Optional[FrameType] = None
|
|
91
|
+
self.step_depth: int = 0
|
|
92
|
+
self.current_depth: int = 0
|
|
93
|
+
|
|
94
|
+
# Setup readline for command history
|
|
95
|
+
self._setup_readline()
|
|
96
|
+
|
|
97
|
+
self.logger.info("GEAI debugger started.")
|
|
98
|
+
self.logger.debug(f"Module filter: {self.module_filter}")
|
|
99
|
+
|
|
100
|
+
def _setup_logging(self):
|
|
101
|
+
"""Setup logging configuration, avoiding duplicate handlers."""
|
|
102
|
+
logger = logging.getLogger('geai.dbg')
|
|
103
|
+
|
|
104
|
+
# Only setup if not already configured
|
|
105
|
+
if not logger.handlers:
|
|
106
|
+
logger.setLevel(logging.DEBUG)
|
|
107
|
+
console_handler = logging.StreamHandler()
|
|
108
|
+
console_handler.setLevel(logging.DEBUG)
|
|
109
|
+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
110
|
+
console_handler.setFormatter(formatter)
|
|
111
|
+
logger.addHandler(console_handler)
|
|
112
|
+
logger.propagate = False
|
|
113
|
+
|
|
114
|
+
# If verbose mode, enable logging for pygeai modules at specified level
|
|
115
|
+
if self.verbose:
|
|
116
|
+
# Configure root logger to show at specified log level
|
|
117
|
+
root_logger = logging.getLogger()
|
|
118
|
+
if not root_logger.handlers:
|
|
119
|
+
root_logger.setLevel(self.log_level)
|
|
120
|
+
console_handler = logging.StreamHandler()
|
|
121
|
+
console_handler.setLevel(self.log_level)
|
|
122
|
+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
123
|
+
console_handler.setFormatter(formatter)
|
|
124
|
+
root_logger.addHandler(console_handler)
|
|
125
|
+
|
|
126
|
+
# Ensure pygeai logger propagates to root
|
|
127
|
+
pygeai_logger = logging.getLogger('pygeai')
|
|
128
|
+
pygeai_logger.setLevel(self.log_level)
|
|
129
|
+
pygeai_logger.propagate = True
|
|
130
|
+
|
|
131
|
+
def _setup_readline(self):
|
|
132
|
+
"""Setup readline for command history and tab completion."""
|
|
133
|
+
try:
|
|
134
|
+
import os
|
|
135
|
+
histfile = os.path.expanduser("~/.geai_dbg_history")
|
|
136
|
+
try:
|
|
137
|
+
readline.read_history_file(histfile)
|
|
138
|
+
readline.set_history_length(1000)
|
|
139
|
+
except FileNotFoundError:
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
import atexit
|
|
143
|
+
atexit.register(readline.write_history_file, histfile)
|
|
144
|
+
except Exception as e:
|
|
145
|
+
self.logger.debug(f"Could not setup readline: {e}")
|
|
146
|
+
|
|
147
|
+
def reset(self):
|
|
148
|
+
"""Reset debugger state."""
|
|
149
|
+
self.breakpoints.clear()
|
|
150
|
+
self.paused = False
|
|
151
|
+
self.current_frame = None
|
|
152
|
+
self.frame_stack.clear()
|
|
153
|
+
self.current_frame_index = 0
|
|
154
|
+
self.step_mode = None
|
|
155
|
+
self.step_frame = None
|
|
156
|
+
self.step_depth = 0
|
|
157
|
+
self.current_depth = 0
|
|
158
|
+
self.logger.info("Debugger state reset.")
|
|
159
|
+
|
|
160
|
+
def add_breakpoint(
|
|
161
|
+
self,
|
|
162
|
+
module: Optional[str] = None,
|
|
163
|
+
function_name: Optional[str] = None,
|
|
164
|
+
condition: Optional[str] = None
|
|
165
|
+
) -> Breakpoint:
|
|
166
|
+
"""
|
|
167
|
+
Add a breakpoint by module and/or function name.
|
|
168
|
+
|
|
169
|
+
:param module: Optional[str] - Module name to break on. None for any module (optional).
|
|
170
|
+
:param function_name: Optional[str] - Function name to break on. None for any function (optional).
|
|
171
|
+
:param condition: Optional[str] - Optional condition expression in Python code. Breakpoint only triggers if condition evaluates to True (optional).
|
|
172
|
+
:return: Breakpoint - The created Breakpoint object.
|
|
173
|
+
"""
|
|
174
|
+
key = (module, function_name)
|
|
175
|
+
if key in self.breakpoints:
|
|
176
|
+
bp = self.breakpoints[key]
|
|
177
|
+
self.logger.warning(f"Breakpoint already exists: {bp}")
|
|
178
|
+
return bp
|
|
179
|
+
|
|
180
|
+
bp = Breakpoint(module=module, function_name=function_name, condition=condition)
|
|
181
|
+
self.breakpoints[key] = bp
|
|
182
|
+
self.logger.info(f"Breakpoint added: {bp}")
|
|
183
|
+
return bp
|
|
184
|
+
|
|
185
|
+
def remove_breakpoint(self, module: Optional[str] = None, function_name: Optional[str] = None) -> bool:
|
|
186
|
+
"""Remove a breakpoint."""
|
|
187
|
+
key = (module, function_name)
|
|
188
|
+
if key in self.breakpoints:
|
|
189
|
+
bp = self.breakpoints.pop(key)
|
|
190
|
+
self.logger.info(f"Breakpoint removed: {bp}")
|
|
191
|
+
return True
|
|
192
|
+
self.logger.warning(f"Breakpoint not found: {module or '*'}:{function_name or '*'}")
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
def list_breakpoints(self) -> List[Breakpoint]:
|
|
196
|
+
"""List all breakpoints."""
|
|
197
|
+
return list(self.breakpoints.values())
|
|
198
|
+
|
|
199
|
+
def enable_breakpoint(self, module: Optional[str] = None, function_name: Optional[str] = None) -> bool:
|
|
200
|
+
"""Enable a breakpoint."""
|
|
201
|
+
key = (module, function_name)
|
|
202
|
+
if key in self.breakpoints:
|
|
203
|
+
self.breakpoints[key].enabled = True
|
|
204
|
+
self.logger.info(f"Breakpoint enabled: {self.breakpoints[key]}")
|
|
205
|
+
return True
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
def disable_breakpoint(self, module: Optional[str] = None, function_name: Optional[str] = None) -> bool:
|
|
209
|
+
"""Disable a breakpoint."""
|
|
210
|
+
key = (module, function_name)
|
|
211
|
+
if key in self.breakpoints:
|
|
212
|
+
self.breakpoints[key].enabled = False
|
|
213
|
+
self.logger.info(f"Breakpoint disabled: {self.breakpoints[key]}")
|
|
214
|
+
return True
|
|
215
|
+
return False
|
|
216
|
+
|
|
217
|
+
def clear_breakpoints(self):
|
|
218
|
+
"""Clear all breakpoints."""
|
|
219
|
+
count = len(self.breakpoints)
|
|
220
|
+
self.breakpoints.clear()
|
|
221
|
+
self.logger.info(f"Cleared {count} breakpoint(s).")
|
|
222
|
+
|
|
223
|
+
def _should_trace_module(self, module: Optional[str]) -> bool:
|
|
224
|
+
"""Check if we should trace this module based on filter."""
|
|
225
|
+
if not module:
|
|
226
|
+
return False
|
|
227
|
+
if not self.module_filter:
|
|
228
|
+
return True
|
|
229
|
+
return module.startswith(self.module_filter)
|
|
230
|
+
|
|
231
|
+
def _check_condition(self, bp: Breakpoint, frame: FrameType) -> bool:
|
|
232
|
+
"""Check if breakpoint condition is met."""
|
|
233
|
+
if not bp.condition:
|
|
234
|
+
return True
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
result = eval(bp.condition, frame.f_globals, frame.f_locals)
|
|
238
|
+
return bool(result)
|
|
239
|
+
except Exception as e:
|
|
240
|
+
self.logger.error(f"Error evaluating breakpoint condition '{bp.condition}': {e}")
|
|
241
|
+
return False
|
|
242
|
+
|
|
243
|
+
def _build_frame_stack(self, frame: FrameType) -> List[FrameType]:
|
|
244
|
+
"""Build a list of frames from current to top of stack."""
|
|
245
|
+
stack = []
|
|
246
|
+
current = frame
|
|
247
|
+
while current is not None:
|
|
248
|
+
stack.append(current)
|
|
249
|
+
current = current.f_back
|
|
250
|
+
return stack
|
|
251
|
+
|
|
252
|
+
def trace_function(self, frame: FrameType, event: str, arg: Any) -> Optional[Callable]:
|
|
253
|
+
"""Trace function calls to intercept execution."""
|
|
254
|
+
module = frame.f_globals.get('__name__')
|
|
255
|
+
|
|
256
|
+
if not self._should_trace_module(module):
|
|
257
|
+
return None
|
|
258
|
+
|
|
259
|
+
function_name = frame.f_code.co_name
|
|
260
|
+
|
|
261
|
+
if event == 'call':
|
|
262
|
+
self.current_depth += 1
|
|
263
|
+
|
|
264
|
+
should_break = False
|
|
265
|
+
for bp in self.breakpoints.values():
|
|
266
|
+
if bp.matches(module, function_name):
|
|
267
|
+
if self._check_condition(bp, frame):
|
|
268
|
+
bp.hit_count += 1
|
|
269
|
+
self.logger.info(f"Breakpoint hit at {module}.{function_name} (hit #{bp.hit_count})")
|
|
270
|
+
should_break = True
|
|
271
|
+
break
|
|
272
|
+
|
|
273
|
+
if should_break:
|
|
274
|
+
self.paused = True
|
|
275
|
+
self.current_frame = frame
|
|
276
|
+
self.frame_stack = self._build_frame_stack(frame)
|
|
277
|
+
self.current_frame_index = 0
|
|
278
|
+
self.handle_breakpoint(frame)
|
|
279
|
+
self.paused = False
|
|
280
|
+
|
|
281
|
+
elif event == 'return':
|
|
282
|
+
self.current_depth -= 1
|
|
283
|
+
|
|
284
|
+
if self.step_mode == 'return' and frame == self.step_frame:
|
|
285
|
+
self.step_mode = None
|
|
286
|
+
self.paused = True
|
|
287
|
+
self.current_frame = frame
|
|
288
|
+
self.frame_stack = self._build_frame_stack(frame)
|
|
289
|
+
self.current_frame_index = 0
|
|
290
|
+
self.handle_breakpoint(frame)
|
|
291
|
+
self.paused = False
|
|
292
|
+
|
|
293
|
+
elif event == 'line':
|
|
294
|
+
if self.step_mode == 'step':
|
|
295
|
+
self.step_mode = None
|
|
296
|
+
self.paused = True
|
|
297
|
+
self.current_frame = frame
|
|
298
|
+
self.frame_stack = self._build_frame_stack(frame)
|
|
299
|
+
self.current_frame_index = 0
|
|
300
|
+
self.handle_breakpoint(frame)
|
|
301
|
+
self.paused = False
|
|
302
|
+
elif self.step_mode == 'next' and self.current_depth <= self.step_depth:
|
|
303
|
+
self.step_mode = None
|
|
304
|
+
self.paused = True
|
|
305
|
+
self.current_frame = frame
|
|
306
|
+
self.frame_stack = self._build_frame_stack(frame)
|
|
307
|
+
self.current_frame_index = 0
|
|
308
|
+
self.handle_breakpoint(frame)
|
|
309
|
+
self.paused = False
|
|
310
|
+
|
|
311
|
+
return self.trace_function
|
|
312
|
+
|
|
313
|
+
def _get_source_lines(self, frame: FrameType, context: int = 5) -> Optional[List[Tuple[int, str]]]:
|
|
314
|
+
"""Get source code lines around the current line."""
|
|
315
|
+
try:
|
|
316
|
+
filename = frame.f_code.co_filename
|
|
317
|
+
lineno = frame.f_lineno
|
|
318
|
+
|
|
319
|
+
with open(filename, 'r') as f:
|
|
320
|
+
lines = f.readlines()
|
|
321
|
+
|
|
322
|
+
start = max(0, lineno - context - 1)
|
|
323
|
+
end = min(len(lines), lineno + context)
|
|
324
|
+
|
|
325
|
+
return [(i + 1, lines[i].rstrip()) for i in range(start, end)]
|
|
326
|
+
except Exception as e:
|
|
327
|
+
self.logger.debug(f"Could not get source: {e}")
|
|
328
|
+
return None
|
|
329
|
+
|
|
330
|
+
def _print_source(self, frame: FrameType, context: int = 5):
|
|
331
|
+
"""Print source code around current line."""
|
|
332
|
+
lines = self._get_source_lines(frame, context)
|
|
333
|
+
if not lines:
|
|
334
|
+
Console.write_stdout("Source code not available.")
|
|
335
|
+
return
|
|
336
|
+
|
|
337
|
+
lineno = frame.f_lineno
|
|
338
|
+
Console.write_stdout(f"\nSource ({frame.f_code.co_filename}):")
|
|
339
|
+
for num, line in lines:
|
|
340
|
+
marker = "-> " if num == lineno else " "
|
|
341
|
+
Console.write_stdout(f"{marker}{num:4d} {line}")
|
|
342
|
+
|
|
343
|
+
def _print_stack_trace(self):
|
|
344
|
+
"""Print stack trace."""
|
|
345
|
+
Console.write_stdout("\nStack trace (most recent call last):")
|
|
346
|
+
for i, frame in enumerate(reversed(self.frame_stack)):
|
|
347
|
+
marker = ">" if i == len(self.frame_stack) - 1 - self.current_frame_index else " "
|
|
348
|
+
module = frame.f_globals.get('__name__', '?')
|
|
349
|
+
func = frame.f_code.co_name
|
|
350
|
+
lineno = frame.f_lineno
|
|
351
|
+
filename = frame.f_code.co_filename
|
|
352
|
+
Console.write_stdout(f" {marker} #{i:2d} {module}.{func} at {filename}:{lineno}")
|
|
353
|
+
|
|
354
|
+
def _move_frame(self, direction: int) -> bool:
|
|
355
|
+
"""Move up or down the frame stack."""
|
|
356
|
+
new_index = self.current_frame_index + direction
|
|
357
|
+
if 0 <= new_index < len(self.frame_stack):
|
|
358
|
+
self.current_frame_index = new_index
|
|
359
|
+
self.current_frame = self.frame_stack[new_index]
|
|
360
|
+
Console.write_stdout(f"Frame #{len(self.frame_stack) - 1 - new_index}: "
|
|
361
|
+
f"{self.current_frame.f_globals.get('__name__', '?')}."
|
|
362
|
+
f"{self.current_frame.f_code.co_name}")
|
|
363
|
+
return True
|
|
364
|
+
else:
|
|
365
|
+
Console.write_stdout(f"Cannot move {direction} (at {'top' if direction < 0 else 'bottom'} of stack)")
|
|
366
|
+
return False
|
|
367
|
+
|
|
368
|
+
def handle_breakpoint(self, frame: FrameType):
|
|
369
|
+
"""Handle a breakpoint by prompting for interactive commands."""
|
|
370
|
+
module = frame.f_globals.get('__name__')
|
|
371
|
+
func = frame.f_code.co_name
|
|
372
|
+
|
|
373
|
+
Console.write_stdout(f"\n{'='*60}")
|
|
374
|
+
Console.write_stdout(f"Paused at {module}.{func} (line {frame.f_lineno})")
|
|
375
|
+
self._print_source(frame, context=3)
|
|
376
|
+
Console.write_stdout(f"{'='*60}")
|
|
377
|
+
Console.write_stdout("Type 'h' for help, 'c' to continue")
|
|
378
|
+
|
|
379
|
+
while True:
|
|
380
|
+
try:
|
|
381
|
+
command = input("(geai-dbg) ").strip()
|
|
382
|
+
if not command:
|
|
383
|
+
continue
|
|
384
|
+
|
|
385
|
+
parts = command.split(None, 1)
|
|
386
|
+
cmd = parts[0]
|
|
387
|
+
args = parts[1] if len(parts) > 1 else ""
|
|
388
|
+
|
|
389
|
+
if cmd in ('continue', 'c'):
|
|
390
|
+
break
|
|
391
|
+
elif cmd in ('quit', 'q'):
|
|
392
|
+
self.logger.info("Debugger terminated by user.")
|
|
393
|
+
sys.exit(0)
|
|
394
|
+
elif cmd in ('run', 'r'):
|
|
395
|
+
self.logger.info("Running program without further pauses.")
|
|
396
|
+
sys.settrace(None)
|
|
397
|
+
break
|
|
398
|
+
|
|
399
|
+
elif cmd in ('step', 's'):
|
|
400
|
+
self.step_mode = 'step'
|
|
401
|
+
self.step_depth = self.current_depth
|
|
402
|
+
break
|
|
403
|
+
elif cmd in ('next', 'n'):
|
|
404
|
+
self.step_mode = 'next'
|
|
405
|
+
self.step_depth = self.current_depth
|
|
406
|
+
break
|
|
407
|
+
elif cmd in ('return', 'ret'):
|
|
408
|
+
self.step_mode = 'return'
|
|
409
|
+
self.step_frame = frame
|
|
410
|
+
break
|
|
411
|
+
|
|
412
|
+
elif cmd in ('up', 'u'):
|
|
413
|
+
self._move_frame(1)
|
|
414
|
+
elif cmd in ('down', 'd'):
|
|
415
|
+
self._move_frame(-1)
|
|
416
|
+
elif cmd in ('where', 'w', 'bt', 'backtrace'):
|
|
417
|
+
self._print_stack_trace()
|
|
418
|
+
|
|
419
|
+
elif cmd in ('list', 'l'):
|
|
420
|
+
context = int(args) if args.isdigit() else 10
|
|
421
|
+
self._print_source(self.current_frame, context)
|
|
422
|
+
|
|
423
|
+
elif cmd in ('print', 'p'):
|
|
424
|
+
if not args:
|
|
425
|
+
Console.write_stdout("Usage: p <expression>")
|
|
426
|
+
else:
|
|
427
|
+
try:
|
|
428
|
+
result = eval(args, self.current_frame.f_globals, self.current_frame.f_locals)
|
|
429
|
+
Console.write_stdout(repr(result))
|
|
430
|
+
except Exception as e:
|
|
431
|
+
Console.write_stdout(f"Error: {e}")
|
|
432
|
+
|
|
433
|
+
elif cmd in ('pp',):
|
|
434
|
+
if not args:
|
|
435
|
+
Console.write_stdout("Usage: pp <expression>")
|
|
436
|
+
else:
|
|
437
|
+
try:
|
|
438
|
+
result = eval(args, self.current_frame.f_globals, self.current_frame.f_locals)
|
|
439
|
+
pprint.pprint(result)
|
|
440
|
+
except Exception as e:
|
|
441
|
+
Console.write_stdout(f"Error: {e}")
|
|
442
|
+
|
|
443
|
+
elif cmd in ('locals', 'loc'):
|
|
444
|
+
Console.write_stdout("\nLocal variables:")
|
|
445
|
+
pprint.pprint(dict(self.current_frame.f_locals))
|
|
446
|
+
|
|
447
|
+
elif cmd in ('globals', 'glob'):
|
|
448
|
+
Console.write_stdout("\nGlobal variables:")
|
|
449
|
+
filtered = {k: v for k, v in self.current_frame.f_globals.items()
|
|
450
|
+
if not k.startswith('__')}
|
|
451
|
+
pprint.pprint(filtered)
|
|
452
|
+
|
|
453
|
+
elif cmd in ('args', 'a'):
|
|
454
|
+
Console.write_stdout("\nFunction arguments:")
|
|
455
|
+
arginfo = inspect.getargvalues(self.current_frame)
|
|
456
|
+
for arg in arginfo.args:
|
|
457
|
+
Console.write_stdout(f" {arg} = {repr(self.current_frame.f_locals.get(arg))}")
|
|
458
|
+
|
|
459
|
+
elif cmd in ('break', 'b'):
|
|
460
|
+
if not args:
|
|
461
|
+
bps = self.list_breakpoints()
|
|
462
|
+
if bps:
|
|
463
|
+
Console.write_stdout("\nBreakpoints:")
|
|
464
|
+
for i, bp in enumerate(bps, 1):
|
|
465
|
+
Console.write_stdout(f" {i}. {bp}")
|
|
466
|
+
else:
|
|
467
|
+
Console.write_stdout("No breakpoints set.")
|
|
468
|
+
else:
|
|
469
|
+
if ':' in args:
|
|
470
|
+
mod, func = args.split(':', 1)
|
|
471
|
+
mod = mod.strip() or None
|
|
472
|
+
func = func.strip() or None
|
|
473
|
+
else:
|
|
474
|
+
mod = None
|
|
475
|
+
func = args.strip()
|
|
476
|
+
self.add_breakpoint(module=mod, function_name=func)
|
|
477
|
+
|
|
478
|
+
elif cmd in ('tbreak', 'tb'):
|
|
479
|
+
Console.write_stdout("Temporary breakpoints not yet implemented.")
|
|
480
|
+
|
|
481
|
+
elif cmd in ('clear', 'cl'):
|
|
482
|
+
if args:
|
|
483
|
+
if ':' in args:
|
|
484
|
+
mod, func = args.split(':', 1)
|
|
485
|
+
mod = mod.strip() or None
|
|
486
|
+
func = func.strip() or None
|
|
487
|
+
else:
|
|
488
|
+
mod = None
|
|
489
|
+
func = args.strip()
|
|
490
|
+
self.remove_breakpoint(module=mod, function_name=func)
|
|
491
|
+
else:
|
|
492
|
+
Console.write_stdout("Usage: cl <breakpoint> or 'clearall' to remove all")
|
|
493
|
+
|
|
494
|
+
elif cmd in ('clearall', 'cla'):
|
|
495
|
+
self.clear_breakpoints()
|
|
496
|
+
|
|
497
|
+
elif cmd in ('enable', 'en'):
|
|
498
|
+
if ':' in args:
|
|
499
|
+
mod, func = args.split(':', 1)
|
|
500
|
+
mod = mod.strip() or None
|
|
501
|
+
func = func.strip() or None
|
|
502
|
+
else:
|
|
503
|
+
mod = None
|
|
504
|
+
func = args.strip()
|
|
505
|
+
self.enable_breakpoint(module=mod, function_name=func)
|
|
506
|
+
|
|
507
|
+
elif cmd in ('disable', 'dis'):
|
|
508
|
+
if ':' in args:
|
|
509
|
+
mod, func = args.split(':', 1)
|
|
510
|
+
mod = mod.strip() or None
|
|
511
|
+
func = func.strip() or None
|
|
512
|
+
else:
|
|
513
|
+
mod = None
|
|
514
|
+
func = args.strip()
|
|
515
|
+
self.disable_breakpoint(module=mod, function_name=func)
|
|
516
|
+
|
|
517
|
+
elif cmd in ('breakpoint-module', 'bm'):
|
|
518
|
+
self.logger.info("Adding breakpoint on module")
|
|
519
|
+
module_name = input("(geai-dbg) Enter module name (or press Enter for any module): ").strip()
|
|
520
|
+
module_name = module_name if module_name else None
|
|
521
|
+
self.add_breakpoint(module=module_name)
|
|
522
|
+
|
|
523
|
+
elif cmd in ('breakpoint-function', 'bf'):
|
|
524
|
+
self.logger.info("Adding breakpoint on function name")
|
|
525
|
+
function_name = input("(geai-dbg) Enter function name (or press Enter for any function): ").strip()
|
|
526
|
+
function_name = function_name if function_name else None
|
|
527
|
+
module_name = input("(geai-dbg) Enter module name (optional, press Enter to skip): ").strip()
|
|
528
|
+
module_name = module_name if module_name else None
|
|
529
|
+
self.add_breakpoint(module=module_name, function_name=function_name)
|
|
530
|
+
|
|
531
|
+
elif cmd in ('list-modules', 'lm'):
|
|
532
|
+
self.logger.info("Listing available modules")
|
|
533
|
+
modules = [m for m in sys.modules if m.startswith(self.module_filter)]
|
|
534
|
+
Console.write_stdout(f"\nAvailable modules ({len(modules)}):")
|
|
535
|
+
for mod in sorted(modules)[:50]:
|
|
536
|
+
Console.write_stdout(f" {mod}")
|
|
537
|
+
if len(modules) > 50:
|
|
538
|
+
Console.write_stdout(f" ... and {len(modules) - 50} more")
|
|
539
|
+
|
|
540
|
+
elif cmd in ('help', 'h', '?'):
|
|
541
|
+
self._print_help()
|
|
542
|
+
|
|
543
|
+
else:
|
|
544
|
+
self.logger.info(f"Executing interactive command: {command}")
|
|
545
|
+
try:
|
|
546
|
+
try:
|
|
547
|
+
exec(command, self.current_frame.f_globals, self.current_frame.f_locals)
|
|
548
|
+
except SyntaxError:
|
|
549
|
+
result = eval(command, self.current_frame.f_globals, self.current_frame.f_locals)
|
|
550
|
+
Console.write_stdout(repr(result))
|
|
551
|
+
except Exception as e:
|
|
552
|
+
self.logger.error(f"Command execution failed: {e}")
|
|
553
|
+
Console.write_stdout(f"Error: {e}")
|
|
554
|
+
|
|
555
|
+
except EOFError:
|
|
556
|
+
self.logger.info("Debugger terminated by user (EOF).")
|
|
557
|
+
sys.exit(0)
|
|
558
|
+
except KeyboardInterrupt:
|
|
559
|
+
self.logger.info("Keyboard interrupt received. Continuing execution.")
|
|
560
|
+
break
|
|
561
|
+
|
|
562
|
+
def _print_help(self):
|
|
563
|
+
"""Print help message."""
|
|
564
|
+
help_text = """
|
|
565
|
+
Available commands:
|
|
566
|
+
|
|
567
|
+
Flow Control:
|
|
568
|
+
continue, c Resume execution until next breakpoint
|
|
569
|
+
step, s Step into function calls
|
|
570
|
+
next, n Step over function calls (same level)
|
|
571
|
+
return, ret Continue until current function returns
|
|
572
|
+
run, r Run program to completion (disable tracing)
|
|
573
|
+
quit, q Exit the debugger
|
|
574
|
+
|
|
575
|
+
Stack Navigation:
|
|
576
|
+
where, w, bt Show stack trace
|
|
577
|
+
up, u Move up one stack frame
|
|
578
|
+
down, d Move down one stack frame
|
|
579
|
+
|
|
580
|
+
Source Display:
|
|
581
|
+
list, l [n] Show source code (n lines of context, default 10)
|
|
582
|
+
|
|
583
|
+
Variable Inspection:
|
|
584
|
+
print, p <expr> Evaluate and print expression
|
|
585
|
+
pp <expr> Pretty-print expression
|
|
586
|
+
locals, loc Show local variables
|
|
587
|
+
globals, glob Show global variables
|
|
588
|
+
args, a Show function arguments
|
|
589
|
+
|
|
590
|
+
Breakpoints:
|
|
591
|
+
break, b List all breakpoints
|
|
592
|
+
b <func> Set breakpoint on function
|
|
593
|
+
b <module>:<func> Set breakpoint on module:function
|
|
594
|
+
clear, cl <bp> Remove breakpoint
|
|
595
|
+
clearall, cla Remove all breakpoints
|
|
596
|
+
enable, en <bp> Enable breakpoint
|
|
597
|
+
disable, dis <bp> Disable breakpoint
|
|
598
|
+
|
|
599
|
+
Legacy Commands:
|
|
600
|
+
breakpoint-module, bm Add module breakpoint (interactive)
|
|
601
|
+
breakpoint-function, bf Add function breakpoint (interactive)
|
|
602
|
+
list-modules, lm List available modules
|
|
603
|
+
|
|
604
|
+
Other:
|
|
605
|
+
help, h, ? Show this help
|
|
606
|
+
<Python code> Execute arbitrary Python code
|
|
607
|
+
|
|
608
|
+
Examples:
|
|
609
|
+
p sys.argv Print command-line arguments
|
|
610
|
+
b main Set breakpoint on any 'main' function
|
|
611
|
+
b pygeai.cli:main Set breakpoint on pygeai.cli.main
|
|
612
|
+
pp locals() Pretty-print all local variables
|
|
613
|
+
"""
|
|
614
|
+
Console.write_stdout(help_text)
|
|
615
|
+
|
|
616
|
+
def run(self):
|
|
617
|
+
"""Run the target callable under the debugger."""
|
|
618
|
+
self.logger.info("Setting trace and running target")
|
|
619
|
+
sys.settrace(self.trace_function)
|
|
620
|
+
try:
|
|
621
|
+
self.target()
|
|
622
|
+
except Exception as e:
|
|
623
|
+
self.logger.error(f"Target execution failed: {e}")
|
|
624
|
+
raise
|
|
625
|
+
finally:
|
|
626
|
+
self.logger.info("Cleaning up trace")
|
|
627
|
+
sys.settrace(None)
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
def debug_file(
|
|
631
|
+
filepath: str,
|
|
632
|
+
args: Optional[List[str]] = None,
|
|
633
|
+
module_filter: Optional[str] = None,
|
|
634
|
+
breakpoint_specs: Optional[List[Tuple[Optional[str], Optional[str]]]] = None,
|
|
635
|
+
verbose: bool = False,
|
|
636
|
+
log_level: str = 'DEBUG'
|
|
637
|
+
) -> Debugger:
|
|
638
|
+
"""
|
|
639
|
+
Debug a Python file by executing it under the debugger.
|
|
640
|
+
|
|
641
|
+
:param filepath: str - Path to the Python file to debug (required).
|
|
642
|
+
:param args: Optional[List[str]] - Command-line arguments to pass to the script (optional).
|
|
643
|
+
:param module_filter: Optional[str] - Module prefix to trace. None auto-detects based on file content (optional).
|
|
644
|
+
:param breakpoint_specs: Optional[List[Tuple[Optional[str], Optional[str]]]] - List of (module, function) tuples for initial breakpoints (optional).
|
|
645
|
+
:param verbose: bool - Enable verbose logging (default False).
|
|
646
|
+
:param log_level: str - Log level for verbose mode: 'DEBUG', 'INFO', 'WARNING', 'ERROR' (default 'DEBUG').
|
|
647
|
+
:return: Debugger - Configured Debugger instance ready to run.
|
|
648
|
+
:raises FileNotFoundError: If the specified file doesn't exist.
|
|
649
|
+
"""
|
|
650
|
+
import os
|
|
651
|
+
|
|
652
|
+
if not os.path.isfile(filepath):
|
|
653
|
+
raise FileNotFoundError(f"File not found: {filepath}")
|
|
654
|
+
|
|
655
|
+
import runpy
|
|
656
|
+
|
|
657
|
+
old_argv = sys.argv.copy()
|
|
658
|
+
sys.argv = [filepath] + (args or [])
|
|
659
|
+
|
|
660
|
+
def target():
|
|
661
|
+
try:
|
|
662
|
+
# Use runpy to properly execute as __main__ module
|
|
663
|
+
# This ensures unittest.main() and similar tools work correctly
|
|
664
|
+
runpy.run_path(filepath, run_name='__main__')
|
|
665
|
+
finally:
|
|
666
|
+
sys.argv = old_argv
|
|
667
|
+
|
|
668
|
+
# Auto-detect module filter based on file content
|
|
669
|
+
if module_filter is None:
|
|
670
|
+
with open(filepath, 'r') as f:
|
|
671
|
+
content = f.read()
|
|
672
|
+
if 'pygeai' in content or 'from pygeai' in content or 'import pygeai' in content:
|
|
673
|
+
module_filter = ''
|
|
674
|
+
else:
|
|
675
|
+
module_filter = '__main__'
|
|
676
|
+
|
|
677
|
+
dbg = Debugger(target=target, module_filter=module_filter, verbose=verbose, log_level=log_level)
|
|
678
|
+
|
|
679
|
+
if breakpoint_specs:
|
|
680
|
+
for module, function in breakpoint_specs:
|
|
681
|
+
dbg.add_breakpoint(module=module, function_name=function)
|
|
682
|
+
|
|
683
|
+
return dbg
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
def debug_module(
|
|
687
|
+
module_name: str,
|
|
688
|
+
function_name: str = 'main',
|
|
689
|
+
args: Optional[List[str]] = None,
|
|
690
|
+
module_filter: Optional[str] = None
|
|
691
|
+
) -> Debugger:
|
|
692
|
+
"""
|
|
693
|
+
Debug a specific module and function by importing and executing it under the debugger.
|
|
694
|
+
|
|
695
|
+
:param module_name: str - Fully qualified module name, e.g., 'pygeai.cli.geai' (required).
|
|
696
|
+
:param function_name: str - Function to call within the module (default is 'main').
|
|
697
|
+
:param args: Optional[List[str]] - Command-line arguments to pass (optional).
|
|
698
|
+
:param module_filter: Optional[str] - Module prefix to trace. None defaults to first part of module_name (optional).
|
|
699
|
+
:return: Debugger - Configured Debugger instance with an automatic breakpoint on the target function.
|
|
700
|
+
:raises ImportError: If the module or function cannot be imported.
|
|
701
|
+
"""
|
|
702
|
+
import importlib
|
|
703
|
+
|
|
704
|
+
old_argv = sys.argv.copy()
|
|
705
|
+
sys.argv = [module_name] + (args or [])
|
|
706
|
+
|
|
707
|
+
try:
|
|
708
|
+
module = importlib.import_module(module_name)
|
|
709
|
+
func = getattr(module, function_name)
|
|
710
|
+
except (ImportError, AttributeError) as e:
|
|
711
|
+
raise ImportError(f"Cannot import {module_name}.{function_name}: {e}")
|
|
712
|
+
|
|
713
|
+
def target():
|
|
714
|
+
try:
|
|
715
|
+
func()
|
|
716
|
+
finally:
|
|
717
|
+
sys.argv = old_argv
|
|
718
|
+
|
|
719
|
+
if module_filter is None:
|
|
720
|
+
module_filter = module_name.split('.')[0]
|
|
721
|
+
|
|
722
|
+
dbg = Debugger(target=target, module_filter=module_filter)
|
|
723
|
+
dbg.add_breakpoint(module=module_name, function_name=function_name)
|
|
724
|
+
|
|
725
|
+
return dbg
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
def main():
|
|
729
|
+
"""
|
|
730
|
+
Entry point for geai-dbg command.
|
|
731
|
+
|
|
732
|
+
Usage:
|
|
733
|
+
geai-dbg Debug geai CLI (default)
|
|
734
|
+
geai-dbg script.py [args...] Debug a Python file
|
|
735
|
+
geai-dbg -m module:func [args...] Debug a module function
|
|
736
|
+
geai-dbg -h Show help
|
|
737
|
+
"""
|
|
738
|
+
parser = argparse.ArgumentParser(
|
|
739
|
+
prog='geai-dbg',
|
|
740
|
+
description='Interactive debugger for PyGEAI applications',
|
|
741
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
742
|
+
epilog="""
|
|
743
|
+
Examples:
|
|
744
|
+
geai-dbg Debug the geai CLI
|
|
745
|
+
geai-dbg script.py arg1 arg2 Debug a Python file with arguments
|
|
746
|
+
geai-dbg -v script.py Debug with verbose logging (DEBUG level)
|
|
747
|
+
geai-dbg -v --log-level INFO script.py Debug with INFO level logging
|
|
748
|
+
geai-dbg -m pygeai.cli.geai:main Debug a specific module function
|
|
749
|
+
geai-dbg -b main script.py Break on 'main' function
|
|
750
|
+
geai-dbg --filter pygeai script.py Only trace pygeai modules
|
|
751
|
+
"""
|
|
752
|
+
)
|
|
753
|
+
|
|
754
|
+
parser.add_argument(
|
|
755
|
+
'target',
|
|
756
|
+
nargs='?',
|
|
757
|
+
default=None,
|
|
758
|
+
help='Python file to debug (omit to debug geai CLI)'
|
|
759
|
+
)
|
|
760
|
+
|
|
761
|
+
parser.add_argument(
|
|
762
|
+
'args',
|
|
763
|
+
nargs='*',
|
|
764
|
+
help='Arguments to pass to the target'
|
|
765
|
+
)
|
|
766
|
+
|
|
767
|
+
parser.add_argument(
|
|
768
|
+
'-m', '--module',
|
|
769
|
+
metavar='MODULE:FUNC',
|
|
770
|
+
help='Debug a module function (format: module.path:function_name)'
|
|
771
|
+
)
|
|
772
|
+
|
|
773
|
+
parser.add_argument(
|
|
774
|
+
'-b', '--break',
|
|
775
|
+
dest='breakpoints',
|
|
776
|
+
action='append',
|
|
777
|
+
metavar='BREAKPOINT',
|
|
778
|
+
help='Set initial breakpoint (format: [module:]function, can be repeated)'
|
|
779
|
+
)
|
|
780
|
+
|
|
781
|
+
parser.add_argument(
|
|
782
|
+
'--filter',
|
|
783
|
+
metavar='PREFIX',
|
|
784
|
+
help='Module prefix to trace (default: auto-detect)'
|
|
785
|
+
)
|
|
786
|
+
|
|
787
|
+
parser.add_argument(
|
|
788
|
+
'--trace-all',
|
|
789
|
+
action='store_true',
|
|
790
|
+
help='Trace all modules (warning: may be slow)'
|
|
791
|
+
)
|
|
792
|
+
|
|
793
|
+
parser.add_argument(
|
|
794
|
+
'-v', '--verbose',
|
|
795
|
+
action='store_true',
|
|
796
|
+
help='Enable verbose logging for pygeai modules'
|
|
797
|
+
)
|
|
798
|
+
|
|
799
|
+
parser.add_argument(
|
|
800
|
+
'--log-level',
|
|
801
|
+
choices=['DEBUG', 'INFO', 'WARNING', 'ERROR'],
|
|
802
|
+
default='DEBUG',
|
|
803
|
+
help='Log level for verbose mode (default: DEBUG)'
|
|
804
|
+
)
|
|
805
|
+
|
|
806
|
+
parsed_args = parser.parse_args()
|
|
807
|
+
|
|
808
|
+
try:
|
|
809
|
+
if parsed_args.module:
|
|
810
|
+
if ':' in parsed_args.module:
|
|
811
|
+
module_name, func_name = parsed_args.module.split(':', 1)
|
|
812
|
+
else:
|
|
813
|
+
module_name = parsed_args.module
|
|
814
|
+
func_name = 'main'
|
|
815
|
+
|
|
816
|
+
dbg = debug_module(
|
|
817
|
+
module_name=module_name,
|
|
818
|
+
function_name=func_name,
|
|
819
|
+
args=parsed_args.args,
|
|
820
|
+
module_filter='' if parsed_args.trace_all else parsed_args.filter
|
|
821
|
+
)
|
|
822
|
+
|
|
823
|
+
elif parsed_args.target:
|
|
824
|
+
breakpoint_specs = []
|
|
825
|
+
if parsed_args.breakpoints:
|
|
826
|
+
for bp in parsed_args.breakpoints:
|
|
827
|
+
if ':' in bp:
|
|
828
|
+
mod, func = bp.split(':', 1)
|
|
829
|
+
breakpoint_specs.append((mod or None, func or None))
|
|
830
|
+
else:
|
|
831
|
+
breakpoint_specs.append((None, bp))
|
|
832
|
+
|
|
833
|
+
dbg = debug_file(
|
|
834
|
+
filepath=parsed_args.target,
|
|
835
|
+
args=parsed_args.args,
|
|
836
|
+
module_filter='' if parsed_args.trace_all else parsed_args.filter,
|
|
837
|
+
breakpoint_specs=breakpoint_specs if breakpoint_specs else None,
|
|
838
|
+
verbose=parsed_args.verbose,
|
|
839
|
+
log_level=parsed_args.log_level
|
|
840
|
+
)
|
|
841
|
+
|
|
842
|
+
else:
|
|
843
|
+
dbg = Debugger(module_filter='pygeai')
|
|
844
|
+
dbg.add_breakpoint(module='pygeai.cli.geai', function_name='main')
|
|
845
|
+
|
|
846
|
+
if parsed_args.breakpoints and not parsed_args.target:
|
|
847
|
+
for bp in parsed_args.breakpoints:
|
|
848
|
+
if ':' in bp:
|
|
849
|
+
mod, func = bp.split(':', 1)
|
|
850
|
+
dbg.add_breakpoint(module=mod or None, function_name=func or None)
|
|
851
|
+
else:
|
|
852
|
+
dbg.add_breakpoint(function_name=bp)
|
|
853
|
+
|
|
854
|
+
Console.write_stdout("GEAI Debugger started. Type 'h' for help, 'c' to continue, 'q' to quit.")
|
|
855
|
+
|
|
856
|
+
dbg.run()
|
|
857
|
+
|
|
858
|
+
except FileNotFoundError as e:
|
|
859
|
+
Console.write_stdout(f"Error: {e}")
|
|
860
|
+
sys.exit(1)
|
|
861
|
+
except ImportError as e:
|
|
862
|
+
Console.write_stdout(f"Error: {e}")
|
|
863
|
+
sys.exit(1)
|
|
864
|
+
except Exception as e:
|
|
865
|
+
logging.getLogger('geai.dbg').error(f"Debugger failed: {e}", exc_info=True)
|
|
866
|
+
sys.exit(1)
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
if __name__ == "__main__":
|
|
870
|
+
main()
|