langbot-plugin 0.5.2__tar.gz → 0.5.3__tar.gz
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.
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/PKG-INFO +1 -1
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/pyproject.toml +1 -1
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/plugin/mgr.py +74 -33
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/plugin/restart_coordinator.py +17 -10
- langbot_plugin-0.5.3/src/langbot_plugin/version.py +1 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/plugin/test_installation_manager.py +104 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/plugin/test_restart_coordinator.py +36 -0
- langbot_plugin-0.5.2/src/langbot_plugin/version.py +0 -1
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/.github/workflows/cla.yml +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/.github/workflows/publish-pypi.yaml +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/.github/workflows/publish.yml +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/.github/workflows/test.yml +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/.gitignore +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/.python-version +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/AGENTS.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/ARCHITECTURE.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/CLAUDE.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/CONTRIBUTING.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/LICENSE +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/README.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/README_CN.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/data/.env.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/docs/Message.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/docs/PluginPages.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/docs/communication/apis/lb2rt.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/docs/communication/runtime_plugin.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/docs/dependency-management.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/docs/langbot-plugin-social.png +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/scripts/check_action_consistency.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/scripts/runtime_resource_probe.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/abstract/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/abstract/platform/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/abstract/platform/adapter.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/abstract/platform/event_logger.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/base.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/command/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/command/command.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/common/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/common/event_listener.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/knowledge_engine/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/knowledge_engine/engine.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/manifest.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/page/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/parser/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/parser/parser.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/tool/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/tool/tool.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/plugin.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/command/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/command/context.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/command/errors.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/pipeline/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/pipeline/query.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/platform/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/platform/entities.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/platform/events.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/platform/logger.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/platform/message.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/provider/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/provider/message.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/provider/prompt.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/provider/session.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/rag/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/rag/context.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/rag/enums.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/rag/errors.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/rag/models.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/resource/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/resource/tool.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/context.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/events.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/execution.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/proxies/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/proxies/base.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/proxies/event_context.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/proxies/execute_context.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/proxies/langbot_api.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/proxies/query_based_api.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/langbot-page-sdk.js +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/.env.example.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/.github/workflows/release.yml.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/.gitignore.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/.vscode/launch.json.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/README.md.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/assets/icon.svg.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/commands/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.py.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.yaml.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/event_listener/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/event_listener/default.py.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/event_listener/default.yaml.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/knowledge_engine/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.py.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.yaml.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/pages/{page_name}.html.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/pages/{page_name}.yaml.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/parser/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.py.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.yaml.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/tools/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.py.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.yaml.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/main.py.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/manifest.yaml.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/readme/README_zh_Hans.md.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/requirements.txt.example +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/actions.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/backend.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/client.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/e2b_backend.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/errors.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/models.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/nsjail_backend.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/runtime.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/security.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/server.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/skill_store.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/box/tenancy.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/__main__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/commands/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/commands/buildplugin.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/commands/gencomponent.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/commands/initplugin.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/commands/login.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/commands/logout.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/commands/publish.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/commands/runplugin.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/gen/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/gen/renderer.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/i18n.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/locales/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/locales/en_US.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/locales/es_ES.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/locales/ja_JP.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/locales/th_TH.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/locales/vi_VN.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/locales/zh_Hans.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/locales/zh_Hant.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/run/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/run/controller.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/run/handler.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/run/hotreload.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/utils/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/utils/cloudsv.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/utils/form.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/cli/utils/page_components.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/entities/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/entities/io/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/entities/io/actions/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/entities/io/actions/enums.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/entities/io/context.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/entities/io/errors.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/entities/io/req.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/entities/io/resp.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/entities/marketplace.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/LICENSE +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/README.md +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/app.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/bounded_executor.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/context.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/event_loop_monitor.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/helper/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/helper/marketplace.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/helper/pkgmgr.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/connection.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/connections/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/connections/stdio.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/connections/ws.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/controller.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/controllers/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/controllers/stdio/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/controllers/stdio/client.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/controllers/stdio/server.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/controllers/ws/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/controllers/ws/client.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/controllers/ws/server.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/handler.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/handlers/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/handlers/control.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/io/handlers/plugin.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/plugin/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/plugin/artifact.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/plugin/container.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/plugin/dependency_environment.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/plugin/logbuffer.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/plugin/worker_launcher.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/security.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/runtime/settings.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/utils/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/utils/discover/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/utils/discover/engine.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/utils/importutil.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/utils/log.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/utils/platform.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/definition/components/test_components.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/definition/test_manifest.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/entities/builtin/test_command_context.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/entities/builtin/test_platform_logger.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/entities/builtin/test_provider_message.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/entities/builtin/test_rag_models.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/entities/test_context.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/entities/test_events.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/proxies/test_base.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/proxies/test_langbot_api.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/api/proxies/test_query_based_api.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/test_admission.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/test_backend.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/test_backend_selection.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/test_client.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/test_e2b_backend.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/test_nsjail_backend.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/test_runtime.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/test_server.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/box/test_skill_store.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/run/test_controller.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/run/test_hotreload.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/run/test_runtime_handler.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/test_buildplugin.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/test_gencomponent.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/test_i18n_form.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/test_initplugin.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/test_login.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/test_logout_publish.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/test_page_components.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/test_renderer.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/cli/test_runplugin.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/entities/io/test_dependency_errors.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/entities/io/test_protocol.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/helpers/__init__.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/helpers/protocol.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/packaging/test_installed_cli_blackbox.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/helper/test_marketplace.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/helper/test_pkgmgr.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/io/handlers/test_control_handler.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/io/handlers/test_import_contracts.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/io/handlers/test_plugin_handler.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/io/test_action_consistency.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/io/test_connections.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/io/test_controllers.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/io/test_handler.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/plugin/test_artifact_store.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/plugin/test_container.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/plugin/test_dependency_environment.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/plugin/test_manager.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/plugin/test_worker_launcher.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/test_app.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/test_bounded_executor.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/test_event_loop_monitor.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/test_log.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/test_message.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/test_plugin_logbuffer.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/utils/test_discovery.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/utils/test_importutil.py +0 -0
- {langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/utils/test_platform.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: langbot-plugin
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
4
4
|
Summary: This package contains the SDK, CLI for building plugins for LangBot, plus the runtime for hosting LangBot plugins
|
|
5
5
|
Project-URL: Homepage, https://langbot.app
|
|
6
6
|
Project-URL: Repository, https://github.com/langbot-app/langbot-plugin-sdk
|
|
@@ -219,6 +219,23 @@ class PluginManager:
|
|
|
219
219
|
initial_policy.max_concurrent_restarts
|
|
220
220
|
)
|
|
221
221
|
|
|
222
|
+
async def _complete_installation_transition(
|
|
223
|
+
self,
|
|
224
|
+
operation: typing.Coroutine[typing.Any, typing.Any, None],
|
|
225
|
+
) -> None:
|
|
226
|
+
"""Join one lifecycle mutation through repeated caller cancellation."""
|
|
227
|
+
|
|
228
|
+
task = asyncio.create_task(operation)
|
|
229
|
+
cancelled = False
|
|
230
|
+
while not task.done():
|
|
231
|
+
try:
|
|
232
|
+
await asyncio.shield(task)
|
|
233
|
+
except asyncio.CancelledError:
|
|
234
|
+
cancelled = True
|
|
235
|
+
task.result()
|
|
236
|
+
if cancelled:
|
|
237
|
+
raise asyncio.CancelledError
|
|
238
|
+
|
|
222
239
|
@property
|
|
223
240
|
def installation_runtimes(
|
|
224
241
|
self,
|
|
@@ -1058,11 +1075,20 @@ class PluginManager:
|
|
|
1058
1075
|
self,
|
|
1059
1076
|
binding: InstallationBinding,
|
|
1060
1077
|
) -> dict[str, typing.Any]:
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1078
|
+
async def remove() -> None:
|
|
1079
|
+
removed_binding = self.context.deactivate_installation_binding(binding)
|
|
1080
|
+
async with self._installation_lifecycle_semaphore():
|
|
1081
|
+
await self._revoke_installation_runtime(removed_binding)
|
|
1082
|
+
if (
|
|
1083
|
+
self._active_binding_by_uuid.get(removed_binding.installation_uuid)
|
|
1084
|
+
== removed_binding
|
|
1085
|
+
):
|
|
1086
|
+
self._active_binding_by_uuid.pop(
|
|
1087
|
+
removed_binding.installation_uuid,
|
|
1088
|
+
None,
|
|
1089
|
+
)
|
|
1090
|
+
|
|
1091
|
+
await self._complete_installation_transition(remove())
|
|
1066
1092
|
return {
|
|
1067
1093
|
"installation_uuid": binding.installation_uuid,
|
|
1068
1094
|
"state": "removed",
|
|
@@ -1108,22 +1134,26 @@ class PluginManager:
|
|
|
1108
1134
|
lock = self._retain_installation_operation_lock(installation_uuid)
|
|
1109
1135
|
try:
|
|
1110
1136
|
async with lock:
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
self.context.deactivate_installation_binding(
|
|
1137
|
+
|
|
1138
|
+
async def remove_current() -> None:
|
|
1139
|
+
if self.context.is_current_installation_binding(
|
|
1115
1140
|
current_binding
|
|
1116
|
-
)
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
self.
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1141
|
+
):
|
|
1142
|
+
self.context.deactivate_installation_binding(
|
|
1143
|
+
current_binding
|
|
1144
|
+
)
|
|
1145
|
+
async with self._installation_lifecycle_semaphore():
|
|
1146
|
+
await self._revoke_installation_runtime(current_binding)
|
|
1147
|
+
if (
|
|
1148
|
+
self._active_binding_by_uuid.get(installation_uuid)
|
|
1149
|
+
== current_binding
|
|
1150
|
+
):
|
|
1151
|
+
self._active_binding_by_uuid.pop(
|
|
1152
|
+
installation_uuid,
|
|
1153
|
+
None,
|
|
1154
|
+
)
|
|
1155
|
+
|
|
1156
|
+
await self._complete_installation_transition(remove_current())
|
|
1127
1157
|
removed.append(installation_uuid)
|
|
1128
1158
|
finally:
|
|
1129
1159
|
self._forget_installation_operation_lock(
|
|
@@ -1469,10 +1499,12 @@ class PluginManager:
|
|
|
1469
1499
|
binding: InstallationBinding,
|
|
1470
1500
|
) -> None:
|
|
1471
1501
|
self._revoke_registration_capabilities_for_binding(binding)
|
|
1472
|
-
runtime = self._installations.
|
|
1502
|
+
runtime = self._installations.get(binding)
|
|
1473
1503
|
if runtime is None:
|
|
1474
1504
|
return
|
|
1475
1505
|
await self._stop_installation_worker(runtime)
|
|
1506
|
+
if self._installations.get(binding) is runtime:
|
|
1507
|
+
self._installations.pop(binding, None)
|
|
1476
1508
|
|
|
1477
1509
|
async def _stop_installation_worker(
|
|
1478
1510
|
self,
|
|
@@ -1486,20 +1518,29 @@ class PluginManager:
|
|
|
1486
1518
|
except Exception as exc:
|
|
1487
1519
|
logger.warning("Failed to notify revoked plugin worker: %s", exc)
|
|
1488
1520
|
close = getattr(handler, "close", None)
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1521
|
+
try:
|
|
1522
|
+
if close is not None:
|
|
1523
|
+
await close()
|
|
1524
|
+
else:
|
|
1525
|
+
await handler.conn.close()
|
|
1526
|
+
except Exception as exc:
|
|
1527
|
+
logger.warning("Failed to close revoked plugin worker: %s", exc)
|
|
1528
|
+
finally:
|
|
1529
|
+
if handler in self.plugin_handlers:
|
|
1530
|
+
self.plugin_handlers.remove(handler)
|
|
1531
|
+
runtime.plugin_handler = None
|
|
1495
1532
|
process = handler.stdio_process
|
|
1496
1533
|
if process is not None and process.returncode is None:
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1534
|
+
try:
|
|
1535
|
+
stopped = await stdio_client_controller.stop_process(process)
|
|
1536
|
+
except Exception as exc:
|
|
1537
|
+
logger.error("Failed to stop revoked plugin worker: %s", exc)
|
|
1538
|
+
else:
|
|
1539
|
+
if not stopped:
|
|
1540
|
+
logger.error(
|
|
1541
|
+
"Plugin worker process did not exit after SIGKILL: %s",
|
|
1542
|
+
runtime.binding.installation_uuid,
|
|
1543
|
+
)
|
|
1503
1544
|
runtime.plugin_handler = None
|
|
1504
1545
|
if runtime.plugin_container is not None:
|
|
1505
1546
|
self._binding_by_container_id.pop(id(runtime.plugin_container), None)
|
|
@@ -3,14 +3,16 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import collections
|
|
5
5
|
import time
|
|
6
|
-
from collections.abc import
|
|
6
|
+
from collections.abc import Coroutine
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
from typing import Callable
|
|
9
9
|
|
|
10
10
|
from langbot_plugin.entities.io.context import PluginWorkerPolicy
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
async def _complete_state_transition(
|
|
13
|
+
async def _complete_state_transition(
|
|
14
|
+
operation: Coroutine[object, object, None],
|
|
15
|
+
) -> None:
|
|
14
16
|
"""Finish one tiny coordinator mutation even if its caller is cancelled.
|
|
15
17
|
|
|
16
18
|
A supervisor cancellation must not strand the circuit in half-open state.
|
|
@@ -19,14 +21,19 @@ async def _complete_state_transition(operation: Awaitable[None]) -> None:
|
|
|
19
21
|
"""
|
|
20
22
|
|
|
21
23
|
task = asyncio.create_task(operation)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
cancelled = False
|
|
25
|
+
while not task.done():
|
|
26
|
+
try:
|
|
27
|
+
await asyncio.shield(task)
|
|
28
|
+
except asyncio.CancelledError:
|
|
29
|
+
# A caller can be cancelled repeatedly while the mutation is
|
|
30
|
+
# waiting for the state lock. Keep joining the shielded task until
|
|
31
|
+
# the transition is complete; otherwise a half-open probe can be
|
|
32
|
+
# stranded permanently.
|
|
33
|
+
cancelled = True
|
|
34
|
+
task.result()
|
|
35
|
+
if cancelled:
|
|
36
|
+
raise asyncio.CancelledError
|
|
30
37
|
|
|
31
38
|
|
|
32
39
|
@dataclass(slots=True)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.5.3"
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/plugin/test_installation_manager.py
RENAMED
|
@@ -131,6 +131,110 @@ async def test_manager_indexes_same_artifact_installations_by_complete_binding(
|
|
|
131
131
|
assert context.is_current_installation_binding(binding_b)
|
|
132
132
|
|
|
133
133
|
|
|
134
|
+
async def test_cancelled_remove_finishes_worker_revoke_before_propagating(
|
|
135
|
+
tmp_path,
|
|
136
|
+
):
|
|
137
|
+
context, manager = _manager(tmp_path)
|
|
138
|
+
package = _package()
|
|
139
|
+
digest = hashlib.sha256(package).hexdigest()
|
|
140
|
+
binding = _binding(
|
|
141
|
+
"installation-a",
|
|
142
|
+
digest,
|
|
143
|
+
workspace_uuid="workspace-a",
|
|
144
|
+
)
|
|
145
|
+
await manager.apply_plugin_installation(
|
|
146
|
+
binding,
|
|
147
|
+
artifact_package=package,
|
|
148
|
+
enabled=False,
|
|
149
|
+
)
|
|
150
|
+
runtime = manager.installation_runtimes[binding]
|
|
151
|
+
shutdown_started = asyncio.Event()
|
|
152
|
+
allow_shutdown = asyncio.Event()
|
|
153
|
+
|
|
154
|
+
class Handler:
|
|
155
|
+
stdio_process = None
|
|
156
|
+
conn = None
|
|
157
|
+
|
|
158
|
+
def cancel_inflight_messages(self):
|
|
159
|
+
return None
|
|
160
|
+
|
|
161
|
+
async def shutdown_plugin(self):
|
|
162
|
+
shutdown_started.set()
|
|
163
|
+
await allow_shutdown.wait()
|
|
164
|
+
|
|
165
|
+
async def close(self):
|
|
166
|
+
return None
|
|
167
|
+
|
|
168
|
+
handler = Handler()
|
|
169
|
+
runtime.plugin_handler = handler
|
|
170
|
+
manager.plugin_handlers.append(handler)
|
|
171
|
+
|
|
172
|
+
remove_task = asyncio.create_task(manager.remove_plugin_installation(binding))
|
|
173
|
+
await asyncio.wait_for(shutdown_started.wait(), timeout=1)
|
|
174
|
+
remove_task.cancel()
|
|
175
|
+
await asyncio.sleep(0)
|
|
176
|
+
remove_task.cancel()
|
|
177
|
+
allow_shutdown.set()
|
|
178
|
+
|
|
179
|
+
with pytest.raises(asyncio.CancelledError):
|
|
180
|
+
await remove_task
|
|
181
|
+
assert not context.is_current_installation_binding(binding)
|
|
182
|
+
assert binding not in manager.installation_runtimes
|
|
183
|
+
assert binding.installation_uuid not in manager._active_binding_by_uuid
|
|
184
|
+
assert handler not in manager.plugin_handlers
|
|
185
|
+
assert runtime.plugin_handler is None
|
|
186
|
+
|
|
187
|
+
with pytest.raises(ValueError, match="stale"):
|
|
188
|
+
await manager.reconcile_plugin_installations(
|
|
189
|
+
(PluginInstallationDesiredState(binding=binding, enabled=False),)
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
async def test_remove_finishes_state_cleanup_when_handler_close_fails(
|
|
194
|
+
tmp_path,
|
|
195
|
+
):
|
|
196
|
+
context, manager = _manager(tmp_path)
|
|
197
|
+
package = _package()
|
|
198
|
+
digest = hashlib.sha256(package).hexdigest()
|
|
199
|
+
binding = _binding(
|
|
200
|
+
"installation-a",
|
|
201
|
+
digest,
|
|
202
|
+
workspace_uuid="workspace-a",
|
|
203
|
+
)
|
|
204
|
+
await manager.apply_plugin_installation(
|
|
205
|
+
binding,
|
|
206
|
+
artifact_package=package,
|
|
207
|
+
enabled=False,
|
|
208
|
+
)
|
|
209
|
+
runtime = manager.installation_runtimes[binding]
|
|
210
|
+
|
|
211
|
+
class Handler:
|
|
212
|
+
stdio_process = None
|
|
213
|
+
conn = None
|
|
214
|
+
|
|
215
|
+
def cancel_inflight_messages(self):
|
|
216
|
+
return None
|
|
217
|
+
|
|
218
|
+
async def shutdown_plugin(self):
|
|
219
|
+
return None
|
|
220
|
+
|
|
221
|
+
async def close(self):
|
|
222
|
+
raise RuntimeError("close failed")
|
|
223
|
+
|
|
224
|
+
handler = Handler()
|
|
225
|
+
runtime.plugin_handler = handler
|
|
226
|
+
manager.plugin_handlers.append(handler)
|
|
227
|
+
|
|
228
|
+
result = await manager.remove_plugin_installation(binding)
|
|
229
|
+
|
|
230
|
+
assert result["state"] == "removed"
|
|
231
|
+
assert not context.is_current_installation_binding(binding)
|
|
232
|
+
assert binding not in manager.installation_runtimes
|
|
233
|
+
assert binding.installation_uuid not in manager._active_binding_by_uuid
|
|
234
|
+
assert handler not in manager.plugin_handlers
|
|
235
|
+
assert runtime.plugin_handler is None
|
|
236
|
+
|
|
237
|
+
|
|
134
238
|
async def test_desired_state_does_not_reject_on_aggregate_worker_capacity(
|
|
135
239
|
tmp_path,
|
|
136
240
|
monkeypatch,
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/tests/runtime/plugin/test_restart_coordinator.py
RENAMED
|
@@ -198,6 +198,42 @@ async def test_abandoned_probe_releases_slot_without_counting_failure():
|
|
|
198
198
|
await replacement_probe.abandon()
|
|
199
199
|
|
|
200
200
|
|
|
201
|
+
async def test_repeated_cancellation_cannot_strand_half_open_probe():
|
|
202
|
+
coordinator = PluginRestartCoordinator()
|
|
203
|
+
coordinator.configure(
|
|
204
|
+
_policy(
|
|
205
|
+
max_concurrent_restarts=1,
|
|
206
|
+
restart_failure_threshold=1,
|
|
207
|
+
restart_circuit_open_seconds=0.01,
|
|
208
|
+
)
|
|
209
|
+
)
|
|
210
|
+
failed = await coordinator.acquire("installation-a")
|
|
211
|
+
await failed.record_failure()
|
|
212
|
+
probe = await asyncio.wait_for(
|
|
213
|
+
coordinator.acquire("installation-a"),
|
|
214
|
+
timeout=1,
|
|
215
|
+
)
|
|
216
|
+
assert probe.is_half_open_probe is True
|
|
217
|
+
|
|
218
|
+
await coordinator._state_lock.acquire()
|
|
219
|
+
abandon_task = asyncio.create_task(probe.abandon())
|
|
220
|
+
await asyncio.sleep(0)
|
|
221
|
+
abandon_task.cancel()
|
|
222
|
+
await asyncio.sleep(0)
|
|
223
|
+
abandon_task.cancel()
|
|
224
|
+
coordinator._state_lock.release()
|
|
225
|
+
|
|
226
|
+
with pytest.raises(asyncio.CancelledError):
|
|
227
|
+
await abandon_task
|
|
228
|
+
assert coordinator.snapshot()["half_open_probe_inflight"] is False
|
|
229
|
+
|
|
230
|
+
replacement = await asyncio.wait_for(
|
|
231
|
+
coordinator.acquire("installation-a"),
|
|
232
|
+
timeout=1,
|
|
233
|
+
)
|
|
234
|
+
await replacement.abandon()
|
|
235
|
+
|
|
236
|
+
|
|
201
237
|
async def test_cancelled_acquire_does_not_leak_launch_slot():
|
|
202
238
|
coordinator = PluginRestartCoordinator()
|
|
203
239
|
coordinator.configure(
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.5.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/abstract/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/definition/components/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/rag/context.py
RENAMED
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/rag/enums.py
RENAMED
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/rag/errors.py
RENAMED
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/entities/builtin/rag/models.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/proxies/event_context.py
RENAMED
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/proxies/execute_context.py
RENAMED
|
File without changes
|
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/api/proxies/query_based_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/.gitignore.example
RENAMED
|
File without changes
|
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/README.md.example
RENAMED
|
File without changes
|
{langbot_plugin-0.5.2 → langbot_plugin-0.5.3}/src/langbot_plugin/assets/templates/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|