langbot-plugin 0.7.6__tar.gz → 0.7.8__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.7.6 → langbot_plugin-0.7.8}/PKG-INFO +1 -1
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/pyproject.toml +1 -1
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/app.py +12 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/context.py +120 -3
- langbot_plugin-0.7.8/src/langbot_plugin/runtime/ops_metrics.py +172 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/plugin/dependency_environment.py +38 -8
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/plugin/mgr.py +25 -3
- langbot_plugin-0.7.8/src/langbot_plugin/version.py +1 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/packaging/test_release_metadata.py +2 -2
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/handlers/test_control_handler.py +11 -14
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_installation_manager.py +136 -0
- langbot_plugin-0.7.8/tests/runtime/test_ops_metrics.py +91 -0
- langbot_plugin-0.7.6/src/langbot_plugin/version.py +0 -1
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/.github/workflows/cla.yml +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/.github/workflows/publish-pypi.yaml +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/.github/workflows/publish.yml +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/.github/workflows/test.yml +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/.gitignore +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/.python-version +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/AGENTS.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/ARCHITECTURE.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/CLAUDE.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/CONTRIBUTING.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/LICENSE +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/README.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/README_CN.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/data/.env.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/Message.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/PluginPages.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/agent-runner-interactions.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/agent-runner-pluginization/PROTOCOL_V1.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/agent-runner-pluginization/README.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/agent-runner-pluginization/SDK_RUNTIME_PLAN.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/certified-plugins.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/communication/apis/lb2rt.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/communication/runtime_plugin.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/dependency-management.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/langbot-plugin-social.png +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/runner.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/docs/stateless-components.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/local_e2e/acceptance.json +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/local_e2e/registration_fanin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/local_e2e/run_acceptance.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/mypy.ini +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/scripts/check_action_consistency.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/scripts/runtime_resource_probe.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/asset_gateway.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/daemon.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/decorators.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/external_tools.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/mcp_access.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/mcp_bridge.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/mcp_config.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/mcp_protocol.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/agent_tools/mcp_stdio.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/abstract/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/abstract/platform/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/abstract/platform/adapter.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/abstract/platform/event_logger.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/base.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/command/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/command/command.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/common/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/common/event_listener.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/knowledge_engine/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/knowledge_engine/engine.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/manifest.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/page/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/parser/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/parser/parser.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/runner/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/runner/runner.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/tool/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/components/tool/tool.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/definition/plugin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/command/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/command/context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/command/errors.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/pipeline/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/pipeline/query.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/platform/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/platform/entities.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/platform/errors.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/platform/events.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/platform/logger.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/platform/message.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/provider/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/provider/message.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/provider/prompt.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/provider/reasoning.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/provider/session.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/rag/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/rag/context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/rag/enums.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/rag/errors.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/rag/models.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/resource/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/resource/tool.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/box.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/capabilities.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/compat.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/context_access.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/delivery.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/errors.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/event.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/input.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/interaction.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/manifest.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/page_results.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/permissions.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/resources.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/result.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/run_ledger.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/runtime.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/runtime_registry.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/state.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/stats.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/steering.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/transcript.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/builtin/runner/trigger.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/events.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/entities/execution.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/base.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/event_context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/execute_context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/invocation.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/langbot_api.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/query_based_api.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/admin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/api.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/box.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/common.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/ledger.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/platform.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/reply_stream.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/resources.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/state.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/api/proxies/runner/tracing.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/langbot-page-sdk.js +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/.env.example.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/.github/workflows/release.yml.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/.gitignore.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/.vscode/launch.json.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/README.md.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/assets/icon.svg.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/commands/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.py.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.yaml.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/event_listener/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/event_listener/default.py.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/event_listener/default.yaml.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/knowledge_engine/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.py.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.yaml.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/pages/{page_name}.html.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/pages/{page_name}.yaml.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/parser/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.py.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.yaml.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/runner/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/runner/{runner_name}.py.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/runner/{runner_name}.yaml.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/tools/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.py.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.yaml.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/main.py.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/manifest.yaml.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/readme/README_zh_Hans.md.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/assets/templates/requirements.txt.example +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/actions.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/backend.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/client.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/e2b_backend.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/errors.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/host_backend.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/models.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/nsjail_backend.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/runtime.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/security.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/server.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/skill_store.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/box/tenancy.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/certification.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/__main__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/commands/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/commands/buildplugin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/commands/gencomponent.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/commands/initplugin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/commands/login.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/commands/logout.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/commands/publish.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/commands/runplugin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/gen/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/gen/renderer.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/i18n.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/locales/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/locales/en_US.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/locales/es_ES.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/locales/ja_JP.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/locales/th_TH.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/locales/vi_VN.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/locales/zh_Hans.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/locales/zh_Hant.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/run/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/run/controller.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/run/handler.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/run/hotreload.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/utils/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/utils/cloudsv.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/utils/form.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/cli/utils/page_components.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/entities/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/entities/io/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/entities/io/actions/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/entities/io/actions/enums.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/entities/io/context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/entities/io/errors.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/entities/io/req.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/entities/io/resp.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/entities/marketplace.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/LICENSE +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/README.md +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/bounded_executor.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/event_loop_monitor.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/helper/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/helper/marketplace.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/helper/pkgmgr.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/connection.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/connections/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/connections/stdio.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/connections/ws.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/controller.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/controllers/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/controllers/stdio/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/controllers/stdio/client.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/controllers/stdio/server.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/controllers/ws/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/controllers/ws/client.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/controllers/ws/server.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/handler.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/handlers/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/handlers/control.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/io/handlers/plugin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/plugin/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/plugin/artifact.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/plugin/container.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/plugin/logbuffer.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/plugin/restart_coordinator.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/plugin/runner_service.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/plugin/worker_launcher.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/security.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/runtime/settings.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/storage.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/utils/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/utils/deadline.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/utils/discover/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/utils/discover/engine.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/utils/importutil.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/utils/log.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/src/langbot_plugin/utils/platform.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/definition/components/test_components.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/definition/components/test_imports.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/definition/test_manifest.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/builtin/runner/test_context_result.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/builtin/runner/test_history_event_entities.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/builtin/runner/test_interaction.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/builtin/runner/test_run_ledger_entities.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/builtin/test_command_context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/builtin/test_platform_logger.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/builtin/test_provider_message.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/builtin/test_rag_models.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/test_context.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/entities/test_events.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/proxies/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/proxies/test_agent_run_api_proxy.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/proxies/test_base.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/proxies/test_box_api.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/proxies/test_history_event_api_proxy.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/proxies/test_langbot_api.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/proxies/test_query_based_api.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/proxies/test_reasoning_parameter.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/test_agent_tools_mcp_bridge.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/test_runner_handlers.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/test_runner_handlers_matrix.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/api/test_runner_public_apis.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_admission.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_backend.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_backend_selection.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_client.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_e2b_backend.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_host_backend.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_nsjail_backend.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_runtime.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_server.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_skill_store.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/box/test_storage_analysis.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/run/test_controller.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/run/test_hotreload.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/run/test_runtime_handler.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_buildplugin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_gencomponent.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_i18n_form.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_initplugin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_login.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_logout_publish.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_page_components.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_renderer.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_runner_usages.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/cli/test_runplugin.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/e2e/standalone_runtime_eba_probe.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/entities/io/test_dependency_errors.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/entities/io/test_protocol.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/fixtures/eba_event_probe_plugin/.gitignore +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/fixtures/eba_event_probe_plugin/assets/icon.svg +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/fixtures/eba_event_probe_plugin/components/event_listener/default.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/fixtures/eba_event_probe_plugin/components/event_listener/default.yaml +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/fixtures/eba_event_probe_plugin/main.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/fixtures/eba_event_probe_plugin/manifest.yaml +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/helpers/__init__.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/helpers/protocol.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/packaging/test_installed_cli_blackbox.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/helper/test_marketplace.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/helper/test_pkgmgr.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/handlers/test_import_contracts.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/handlers/test_legacy_file_chunk.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/handlers/test_plugin_handler.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/test_action_consistency.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/test_connections.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/test_controllers.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/test_handler.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/test_heartbeat_admission.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/test_stdio_server.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_artifact_store.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_container.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_dependency_environment.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_exact_dify_real_worker.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_exact_legacy_sdk_compat.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_legacy_shadow.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_manager.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_mgr_runner.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_restart_coordinator.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_shared_worker_subprocess.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_worker_launcher.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/plugin/test_workload_isolation.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/test_app.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/test_bounded_executor.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/test_event_loop_monitor.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/test_pull_api_handlers.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/test_certification.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/test_log.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/test_message.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/test_plugin_logbuffer.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/test_storage.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/utils/test_deadline.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/utils/test_discovery.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/utils/test_importutil.py +0 -0
- {langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/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.7.
|
|
3
|
+
Version: 0.7.8
|
|
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
|
|
@@ -23,6 +23,8 @@ from langbot_plugin.runtime.bounded_executor import (
|
|
|
23
23
|
configure_bounded_default_executor_from_env,
|
|
24
24
|
)
|
|
25
25
|
from langbot_plugin.runtime.event_loop_monitor import EventLoopLagMonitor
|
|
26
|
+
from langbot_plugin.runtime import ops_metrics as ops_metrics_module
|
|
27
|
+
from langbot_plugin.version import __version__ as runtime_version
|
|
26
28
|
|
|
27
29
|
from langbot_plugin.runtime.security import (
|
|
28
30
|
PLUGIN_DEBUG_KEY_HEADER,
|
|
@@ -110,8 +112,18 @@ class RuntimeApplication:
|
|
|
110
112
|
def _health_snapshot(self) -> dict[str, object]:
|
|
111
113
|
"""Return public aggregate health without credentials or tenant IDs."""
|
|
112
114
|
|
|
115
|
+
ops_metrics = getattr(self.context.plugin_mgr, "ops_metrics", None)
|
|
116
|
+
process = ops_metrics_module.sample_process_resources() if ops_metrics else {}
|
|
117
|
+
runtime: dict[str, object] = {
|
|
118
|
+
"version": runtime_version,
|
|
119
|
+
"profile": self.context.runtime_profile or "unknown",
|
|
120
|
+
}
|
|
121
|
+
if ops_metrics is not None:
|
|
122
|
+
runtime["uptime_seconds"] = ops_metrics.uptime_seconds
|
|
123
|
+
runtime.update(process)
|
|
113
124
|
return {
|
|
114
125
|
"live": not self._closing,
|
|
126
|
+
"runtime": runtime,
|
|
115
127
|
"resources": self.context.get_runtime_resource_stats(),
|
|
116
128
|
}
|
|
117
129
|
|
|
@@ -61,7 +61,12 @@ class RuntimeContext:
|
|
|
61
61
|
self.workspace_debug_tokens = WorkspaceDebugTokenStore()
|
|
62
62
|
|
|
63
63
|
def get_runtime_resource_stats(self) -> dict[str, Any]:
|
|
64
|
-
"""Return aggregate O(1) counters safe for public health probes.
|
|
64
|
+
"""Return aggregate O(1) counters safe for public health probes.
|
|
65
|
+
|
|
66
|
+
The Cloud ops dashboard and the soak gate poll this payload, so every
|
|
67
|
+
value stays process-wide: no installation UUID, Workspace UUID, plugin
|
|
68
|
+
identity or artifact digest is ever reported here.
|
|
69
|
+
"""
|
|
65
70
|
|
|
66
71
|
plugin_manager = self.plugin_mgr
|
|
67
72
|
handlers = getattr(
|
|
@@ -75,11 +80,91 @@ class RuntimeContext:
|
|
|
75
80
|
"starting": 0,
|
|
76
81
|
"failed": 0,
|
|
77
82
|
"disabled": 0,
|
|
83
|
+
# Unknown lifecycle states are counted instead of dropped, so a new
|
|
84
|
+
# state can never silently disappear from the health payload.
|
|
85
|
+
"other": 0,
|
|
78
86
|
}
|
|
87
|
+
installations_by_mode: dict[str, int] = {}
|
|
79
88
|
for runtime in getattr(plugin_manager, "_installations", {}).values():
|
|
80
89
|
state = str(getattr(runtime, "state", "disabled"))
|
|
81
|
-
|
|
82
|
-
|
|
90
|
+
installation_state_counts[
|
|
91
|
+
state if state in installation_state_counts else "other"
|
|
92
|
+
] += 1
|
|
93
|
+
execution_mode = getattr(
|
|
94
|
+
getattr(runtime, "execution_mode", None),
|
|
95
|
+
"value",
|
|
96
|
+
None,
|
|
97
|
+
)
|
|
98
|
+
mode_key = str(execution_mode or "dedicated")
|
|
99
|
+
installations_by_mode[mode_key] = installations_by_mode.get(mode_key, 0) + 1
|
|
100
|
+
|
|
101
|
+
shared_workers = getattr(plugin_manager, "_shared_workers", {})
|
|
102
|
+
shared_ready = 0
|
|
103
|
+
shared_draining = 0
|
|
104
|
+
shared_slots = 0
|
|
105
|
+
for worker in shared_workers.values():
|
|
106
|
+
worker_slots = getattr(worker, "slots", {})
|
|
107
|
+
shared_slots += len(worker_slots)
|
|
108
|
+
ready_event = getattr(worker, "ready_event", None)
|
|
109
|
+
if ready_event is not None and ready_event.is_set():
|
|
110
|
+
shared_ready += 1
|
|
111
|
+
if getattr(worker, "draining", False):
|
|
112
|
+
shared_draining += 1
|
|
113
|
+
|
|
114
|
+
ops_metrics = getattr(plugin_manager, "ops_metrics", None)
|
|
115
|
+
worker_policy = self.worker_policy
|
|
116
|
+
shared_pool: dict[str, Any] = {
|
|
117
|
+
"workers": len(shared_workers),
|
|
118
|
+
"capacity": (
|
|
119
|
+
int(getattr(worker_policy, "max_workers", 0)) if worker_policy else 0
|
|
120
|
+
),
|
|
121
|
+
"ready": shared_ready,
|
|
122
|
+
"draining": shared_draining,
|
|
123
|
+
"slots": shared_slots,
|
|
124
|
+
}
|
|
125
|
+
if ops_metrics is not None:
|
|
126
|
+
counters = ops_metrics.snapshot()
|
|
127
|
+
shared_pool.update(
|
|
128
|
+
{
|
|
129
|
+
"processes_started_total": counters[
|
|
130
|
+
"shared_worker_processes_started_total"
|
|
131
|
+
],
|
|
132
|
+
"registrations_total": counters[
|
|
133
|
+
"shared_worker_registrations_total"
|
|
134
|
+
],
|
|
135
|
+
"launch_failures_total": counters[
|
|
136
|
+
"shared_worker_launch_failures_total"
|
|
137
|
+
],
|
|
138
|
+
"transport_timeouts_total": counters[
|
|
139
|
+
"shared_worker_transport_timeouts_total"
|
|
140
|
+
],
|
|
141
|
+
"capacity_rejections_total": counters[
|
|
142
|
+
"shared_worker_capacity_rejections_total"
|
|
143
|
+
],
|
|
144
|
+
"stops_total": counters["shared_worker_stops_total"],
|
|
145
|
+
"slot_attach_total": counters["shared_slot_attach_total"],
|
|
146
|
+
"slot_attach_success_total": counters[
|
|
147
|
+
"shared_slot_attach_success_total"
|
|
148
|
+
],
|
|
149
|
+
"slot_attach_failures_total": counters[
|
|
150
|
+
"shared_slot_attach_failures_total"
|
|
151
|
+
],
|
|
152
|
+
"slot_attach_timeouts_total": counters[
|
|
153
|
+
"shared_slot_attach_timeouts_total"
|
|
154
|
+
],
|
|
155
|
+
"slot_detach_total": counters["shared_slot_detach_total"],
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Expired registration capabilities are pruned before counting, so the
|
|
160
|
+
# gauge reflects capabilities that can still be redeemed.
|
|
161
|
+
prune_registrations = getattr(
|
|
162
|
+
plugin_manager,
|
|
163
|
+
"_prune_expired_registration_capabilities",
|
|
164
|
+
None,
|
|
165
|
+
)
|
|
166
|
+
if callable(prune_registrations):
|
|
167
|
+
prune_registrations()
|
|
83
168
|
|
|
84
169
|
return {
|
|
85
170
|
"event_loop": (
|
|
@@ -96,6 +181,38 @@ class RuntimeContext:
|
|
|
96
181
|
),
|
|
97
182
|
"installation_runtimes": len(getattr(plugin_manager, "_installations", ())),
|
|
98
183
|
"installation_states": installation_state_counts,
|
|
184
|
+
"installations_by_mode": installations_by_mode,
|
|
185
|
+
"installation_watermarks": len(
|
|
186
|
+
getattr(self, "_installation_watermarks", {})
|
|
187
|
+
),
|
|
188
|
+
"shared_pool": shared_pool,
|
|
189
|
+
"dependency_environment": (
|
|
190
|
+
{
|
|
191
|
+
"cache_hits_total": ops_metrics.dependency_cache_hits_total,
|
|
192
|
+
"misses_total": ops_metrics.dependency_cache_misses_total,
|
|
193
|
+
"failures_total": ops_metrics.dependency_prepare_failures_total,
|
|
194
|
+
"prepare_seconds_total": (
|
|
195
|
+
ops_metrics.dependency_prepare_seconds_total
|
|
196
|
+
),
|
|
197
|
+
"prepare_seconds_last": ops_metrics.dependency_prepare_seconds_last,
|
|
198
|
+
}
|
|
199
|
+
if ops_metrics is not None
|
|
200
|
+
else {}
|
|
201
|
+
),
|
|
202
|
+
"restart_backoff": (
|
|
203
|
+
{
|
|
204
|
+
"shared_current_seconds": ops_metrics.shared_backoff_current_seconds,
|
|
205
|
+
"shared_total_seconds": ops_metrics.shared_backoff_total_seconds,
|
|
206
|
+
"dedicated_current_seconds": (
|
|
207
|
+
ops_metrics.dedicated_backoff_current_seconds
|
|
208
|
+
),
|
|
209
|
+
"dedicated_total_seconds": (
|
|
210
|
+
ops_metrics.dedicated_backoff_total_seconds
|
|
211
|
+
),
|
|
212
|
+
}
|
|
213
|
+
if ops_metrics is not None
|
|
214
|
+
else {}
|
|
215
|
+
),
|
|
99
216
|
"pending_registrations": len(
|
|
100
217
|
getattr(plugin_manager, "_pending_registrations", ())
|
|
101
218
|
),
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import time
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def sample_process_resources() -> dict[str, int | float]:
|
|
9
|
+
"""Return this process' pid, RSS and CPU time, or ``{}`` off Linux.
|
|
10
|
+
|
|
11
|
+
``/proc`` is read on demand: the probe endpoint is polled by the Cloud ops
|
|
12
|
+
dashboard and by the soak gate, so sampling stays out of the hot path and no
|
|
13
|
+
background task is added.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
if not hasattr(os, "sysconf"):
|
|
17
|
+
return {}
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
with open("/proc/self/statm", "r", encoding="ascii") as handle:
|
|
21
|
+
resident_pages = int(handle.read().split()[1])
|
|
22
|
+
page_size = int(os.sysconf("SC_PAGE_SIZE"))
|
|
23
|
+
except (OSError, ValueError, IndexError):
|
|
24
|
+
return {}
|
|
25
|
+
|
|
26
|
+
snapshot: dict[str, int | float] = {
|
|
27
|
+
"pid": os.getpid(),
|
|
28
|
+
"rss_bytes": resident_pages * page_size,
|
|
29
|
+
}
|
|
30
|
+
try:
|
|
31
|
+
with open("/proc/self/stat", "rb") as handle:
|
|
32
|
+
raw = handle.read()
|
|
33
|
+
# ``comm`` may contain spaces and parentheses, so only the fields after
|
|
34
|
+
# the final ')' are positional: utime/stime are fields 14 and 15.
|
|
35
|
+
tail = raw[raw.rindex(b")") + 2 :].split()
|
|
36
|
+
clock_ticks = int(os.sysconf("SC_CLK_TCK"))
|
|
37
|
+
snapshot["cpu_seconds"] = (int(tail[11]) + int(tail[12])) / clock_ticks
|
|
38
|
+
except (OSError, ValueError, IndexError):
|
|
39
|
+
pass
|
|
40
|
+
return snapshot
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class RuntimeOpsMetrics:
|
|
44
|
+
"""Process-lifetime counters for the Cloud Plugin Runtime ops dashboard.
|
|
45
|
+
|
|
46
|
+
Every value is an aggregate over the whole Runtime process. No
|
|
47
|
+
installation UUID, Workspace UUID, plugin identity or artifact digest is
|
|
48
|
+
ever recorded here, which keeps the payload safe for the unauthenticated
|
|
49
|
+
``/healthz`` probe that the Cloud ops dashboard and the soak gate poll.
|
|
50
|
+
|
|
51
|
+
Counters are incremented on lifecycle paths that already exist; nothing in
|
|
52
|
+
this module starts a task, timer, or background sampler.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
__slots__ = (
|
|
56
|
+
"started_at",
|
|
57
|
+
"shared_processes_started_total",
|
|
58
|
+
"shared_registrations_total",
|
|
59
|
+
"shared_launch_failures_total",
|
|
60
|
+
"shared_transport_timeouts_total",
|
|
61
|
+
"shared_capacity_rejections_total",
|
|
62
|
+
"shared_stops_total",
|
|
63
|
+
"shared_slot_attach_total",
|
|
64
|
+
"shared_slot_attach_success_total",
|
|
65
|
+
"shared_slot_attach_failures_total",
|
|
66
|
+
"shared_slot_attach_timeouts_total",
|
|
67
|
+
"shared_slot_detach_total",
|
|
68
|
+
"shared_backoff_current_seconds",
|
|
69
|
+
"shared_backoff_total_seconds",
|
|
70
|
+
"dedicated_backoff_current_seconds",
|
|
71
|
+
"dedicated_backoff_total_seconds",
|
|
72
|
+
"dependency_cache_hits_total",
|
|
73
|
+
"dependency_cache_misses_total",
|
|
74
|
+
"dependency_prepare_failures_total",
|
|
75
|
+
"dependency_prepare_seconds_total",
|
|
76
|
+
"dependency_prepare_seconds_last",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
def __init__(self) -> None:
|
|
80
|
+
self.started_at = time.monotonic()
|
|
81
|
+
self.shared_processes_started_total = 0
|
|
82
|
+
self.shared_registrations_total = 0
|
|
83
|
+
self.shared_launch_failures_total = 0
|
|
84
|
+
self.shared_transport_timeouts_total = 0
|
|
85
|
+
self.shared_capacity_rejections_total = 0
|
|
86
|
+
self.shared_stops_total = 0
|
|
87
|
+
self.shared_slot_attach_total = 0
|
|
88
|
+
self.shared_slot_attach_success_total = 0
|
|
89
|
+
self.shared_slot_attach_failures_total = 0
|
|
90
|
+
self.shared_slot_attach_timeouts_total = 0
|
|
91
|
+
self.shared_slot_detach_total = 0
|
|
92
|
+
self.shared_backoff_current_seconds = 0.0
|
|
93
|
+
self.shared_backoff_total_seconds = 0.0
|
|
94
|
+
self.dedicated_backoff_current_seconds = 0.0
|
|
95
|
+
self.dedicated_backoff_total_seconds = 0.0
|
|
96
|
+
self.dependency_cache_hits_total = 0
|
|
97
|
+
self.dependency_cache_misses_total = 0
|
|
98
|
+
self.dependency_prepare_failures_total = 0
|
|
99
|
+
self.dependency_prepare_seconds_total = 0.0
|
|
100
|
+
self.dependency_prepare_seconds_last = 0.0
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def uptime_seconds(self) -> float:
|
|
104
|
+
return max(time.monotonic() - self.started_at, 0.0)
|
|
105
|
+
|
|
106
|
+
def record_shared_backoff(self, delay_seconds: float) -> None:
|
|
107
|
+
"""Record one shared-worker restart delay before it is slept off."""
|
|
108
|
+
|
|
109
|
+
delay = max(float(delay_seconds), 0.0)
|
|
110
|
+
self.shared_backoff_current_seconds = delay
|
|
111
|
+
self.shared_backoff_total_seconds += delay
|
|
112
|
+
|
|
113
|
+
def record_dedicated_backoff(self, delay_seconds: float) -> None:
|
|
114
|
+
"""Record one dedicated-worker restart delay before it is slept off."""
|
|
115
|
+
|
|
116
|
+
delay = max(float(delay_seconds), 0.0)
|
|
117
|
+
self.dedicated_backoff_current_seconds = delay
|
|
118
|
+
self.dedicated_backoff_total_seconds += delay
|
|
119
|
+
|
|
120
|
+
def clear_shared_backoff(self) -> None:
|
|
121
|
+
self.shared_backoff_current_seconds = 0.0
|
|
122
|
+
|
|
123
|
+
def clear_dedicated_backoff(self) -> None:
|
|
124
|
+
self.dedicated_backoff_current_seconds = 0.0
|
|
125
|
+
|
|
126
|
+
def snapshot(self) -> dict[str, Any]:
|
|
127
|
+
"""Return identity-free counters and gauges."""
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
"started_at_monotonic": self.started_at,
|
|
131
|
+
"uptime_seconds": self.uptime_seconds,
|
|
132
|
+
"shared_worker_processes_started_total": (
|
|
133
|
+
self.shared_processes_started_total
|
|
134
|
+
),
|
|
135
|
+
"shared_worker_registrations_total": self.shared_registrations_total,
|
|
136
|
+
"shared_worker_launch_failures_total": self.shared_launch_failures_total,
|
|
137
|
+
"shared_worker_transport_timeouts_total": (
|
|
138
|
+
self.shared_transport_timeouts_total
|
|
139
|
+
),
|
|
140
|
+
"shared_worker_capacity_rejections_total": (
|
|
141
|
+
self.shared_capacity_rejections_total
|
|
142
|
+
),
|
|
143
|
+
"shared_worker_stops_total": self.shared_stops_total,
|
|
144
|
+
"shared_slot_attach_total": self.shared_slot_attach_total,
|
|
145
|
+
"shared_slot_attach_success_total": self.shared_slot_attach_success_total,
|
|
146
|
+
"shared_slot_attach_failures_total": (
|
|
147
|
+
self.shared_slot_attach_failures_total
|
|
148
|
+
),
|
|
149
|
+
"shared_slot_attach_timeouts_total": (
|
|
150
|
+
self.shared_slot_attach_timeouts_total
|
|
151
|
+
),
|
|
152
|
+
"shared_slot_detach_total": self.shared_slot_detach_total,
|
|
153
|
+
"shared_backoff_current_seconds": self.shared_backoff_current_seconds,
|
|
154
|
+
"shared_backoff_total_seconds": self.shared_backoff_total_seconds,
|
|
155
|
+
"dedicated_backoff_current_seconds": self.dedicated_backoff_current_seconds,
|
|
156
|
+
"dedicated_backoff_total_seconds": self.dedicated_backoff_total_seconds,
|
|
157
|
+
"dependency_environment_cache_hits_total": (
|
|
158
|
+
self.dependency_cache_hits_total
|
|
159
|
+
),
|
|
160
|
+
"dependency_environment_cache_misses_total": (
|
|
161
|
+
self.dependency_cache_misses_total
|
|
162
|
+
),
|
|
163
|
+
"dependency_environment_prepare_failures_total": (
|
|
164
|
+
self.dependency_prepare_failures_total
|
|
165
|
+
),
|
|
166
|
+
"dependency_environment_prepare_seconds_total": (
|
|
167
|
+
self.dependency_prepare_seconds_total
|
|
168
|
+
),
|
|
169
|
+
"dependency_environment_prepare_seconds_last": (
|
|
170
|
+
self.dependency_prepare_seconds_last
|
|
171
|
+
),
|
|
172
|
+
}
|
|
@@ -10,6 +10,8 @@ import re
|
|
|
10
10
|
import shutil
|
|
11
11
|
import stat
|
|
12
12
|
import tempfile
|
|
13
|
+
import time
|
|
14
|
+
import typing
|
|
13
15
|
import weakref
|
|
14
16
|
from collections.abc import Awaitable, Callable, Iterator, Sequence
|
|
15
17
|
from dataclasses import dataclass
|
|
@@ -120,9 +122,15 @@ DependencyInstaller = Callable[
|
|
|
120
122
|
class PluginDependencyEnvironmentStore:
|
|
121
123
|
"""Atomically prepare and publish immutable per-artifact dependency trees."""
|
|
122
124
|
|
|
123
|
-
def __init__(
|
|
125
|
+
def __init__(
|
|
126
|
+
self,
|
|
127
|
+
base_path: str | os.PathLike = "data/plugin-runtime",
|
|
128
|
+
*,
|
|
129
|
+
metrics: typing.Any | None = None,
|
|
130
|
+
):
|
|
124
131
|
self.base_path = pathlib.Path(base_path)
|
|
125
132
|
self.environments_path = self.base_path / "environments" / "sha256"
|
|
133
|
+
self.metrics = metrics
|
|
126
134
|
self._prepare_locks: weakref.WeakValueDictionary[str, asyncio.Lock] = (
|
|
127
135
|
weakref.WeakValueDictionary()
|
|
128
136
|
)
|
|
@@ -152,20 +160,42 @@ class PluginDependencyEnvironmentStore:
|
|
|
152
160
|
|
|
153
161
|
ready = self.get_ready(digest, expected=expected)
|
|
154
162
|
if ready is not None:
|
|
163
|
+
self._record_cache_hit()
|
|
155
164
|
return ready
|
|
156
165
|
|
|
157
166
|
lock = self._prepare_locks.setdefault(digest, asyncio.Lock())
|
|
158
167
|
async with lock:
|
|
159
168
|
ready = self.get_ready(digest, expected=expected)
|
|
160
169
|
if ready is not None:
|
|
170
|
+
self._record_cache_hit()
|
|
161
171
|
return ready
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
172
|
+
self._record_cache_miss()
|
|
173
|
+
started_at = time.monotonic()
|
|
174
|
+
try:
|
|
175
|
+
return await self._prepare_locked(
|
|
176
|
+
artifact,
|
|
177
|
+
digest=digest,
|
|
178
|
+
expected=expected,
|
|
179
|
+
requirements=requirements,
|
|
180
|
+
installer=installer,
|
|
181
|
+
)
|
|
182
|
+
except BaseException:
|
|
183
|
+
if self.metrics is not None:
|
|
184
|
+
self.metrics.dependency_prepare_failures_total += 1
|
|
185
|
+
raise
|
|
186
|
+
finally:
|
|
187
|
+
elapsed = max(time.monotonic() - started_at, 0.0)
|
|
188
|
+
if self.metrics is not None:
|
|
189
|
+
self.metrics.dependency_prepare_seconds_total += elapsed
|
|
190
|
+
self.metrics.dependency_prepare_seconds_last = elapsed
|
|
191
|
+
|
|
192
|
+
def _record_cache_hit(self) -> None:
|
|
193
|
+
if self.metrics is not None:
|
|
194
|
+
self.metrics.dependency_cache_hits_total += 1
|
|
195
|
+
|
|
196
|
+
def _record_cache_miss(self) -> None:
|
|
197
|
+
if self.metrics is not None:
|
|
198
|
+
self.metrics.dependency_cache_misses_total += 1
|
|
169
199
|
|
|
170
200
|
def get_ready(
|
|
171
201
|
self,
|
|
@@ -32,6 +32,7 @@ from langbot_plugin.runtime.plugin import container as runtime_plugin_container
|
|
|
32
32
|
from langbot_plugin.runtime.io.handlers import plugin as runtime_plugin_handler_cls
|
|
33
33
|
from langbot_plugin.runtime import context as context_module
|
|
34
34
|
from langbot_plugin.runtime import bounded_executor
|
|
35
|
+
from langbot_plugin.runtime import ops_metrics as ops_metrics_module
|
|
35
36
|
from langbot_plugin.api.entities.context import EventContext
|
|
36
37
|
from langbot_plugin.api.definition.components.manifest import ComponentManifest
|
|
37
38
|
from langbot_plugin.api.definition.components.tool.tool import Tool
|
|
@@ -250,8 +251,10 @@ class PluginManager:
|
|
|
250
251
|
self._reconcile_operation_lock = asyncio.Lock()
|
|
251
252
|
self._installation_lifecycle_limiter: asyncio.Semaphore | None = None
|
|
252
253
|
self.artifact_store = PluginArtifactStore()
|
|
254
|
+
self.ops_metrics = ops_metrics_module.RuntimeOpsMetrics()
|
|
253
255
|
self.dependency_environment_store = PluginDependencyEnvironmentStore(
|
|
254
|
-
self.artifact_store.base_path
|
|
256
|
+
self.artifact_store.base_path,
|
|
257
|
+
metrics=self.ops_metrics,
|
|
255
258
|
)
|
|
256
259
|
self.worker_launcher = PluginWorkerLauncher()
|
|
257
260
|
self.restart_coordinator = PluginRestartCoordinator()
|
|
@@ -1099,7 +1102,10 @@ class PluginManager:
|
|
|
1099
1102
|
# construction; dependency state must follow that same
|
|
1100
1103
|
# Runtime-owned volume.
|
|
1101
1104
|
self.dependency_environment_store = (
|
|
1102
|
-
PluginDependencyEnvironmentStore(
|
|
1105
|
+
PluginDependencyEnvironmentStore(
|
|
1106
|
+
self.artifact_store.base_path,
|
|
1107
|
+
metrics=self.ops_metrics,
|
|
1108
|
+
)
|
|
1103
1109
|
)
|
|
1104
1110
|
try:
|
|
1105
1111
|
current.dependency_environment = (
|
|
@@ -1379,6 +1385,7 @@ class PluginManager:
|
|
|
1379
1385
|
if policy is None:
|
|
1380
1386
|
raise ValueError("Plugin worker policy is unavailable")
|
|
1381
1387
|
if len(self._shared_workers) >= policy.max_workers:
|
|
1388
|
+
self.ops_metrics.shared_capacity_rejections_total += 1
|
|
1382
1389
|
raise RuntimeError("Shared plugin worker capacity reached")
|
|
1383
1390
|
worker = SharedPluginWorkerRuntime(
|
|
1384
1391
|
artifact=runtime.artifact,
|
|
@@ -1451,6 +1458,7 @@ class PluginManager:
|
|
|
1451
1458
|
await permit.abandon()
|
|
1452
1459
|
raise
|
|
1453
1460
|
except Exception as exc:
|
|
1461
|
+
self.ops_metrics.shared_launch_failures_total += 1
|
|
1454
1462
|
self._record_shared_worker_failure(worker, exc)
|
|
1455
1463
|
logger.exception("Shared plugin worker failed: %s", digest)
|
|
1456
1464
|
if (
|
|
@@ -1466,7 +1474,10 @@ class PluginManager:
|
|
|
1466
1474
|
if uptime >= _PLUGIN_STABLE_WINDOW_SEC:
|
|
1467
1475
|
delay = _PLUGIN_RESTART_INITIAL_DELAY_SEC
|
|
1468
1476
|
worker.ready_event.clear()
|
|
1469
|
-
|
|
1477
|
+
restart_delay = delay * random.uniform(0.8, 1.2)
|
|
1478
|
+
self.ops_metrics.record_shared_backoff(restart_delay)
|
|
1479
|
+
await asyncio.sleep(restart_delay)
|
|
1480
|
+
self.ops_metrics.clear_shared_backoff()
|
|
1470
1481
|
delay = min(delay * 2, _PLUGIN_RESTART_MAX_DELAY_SEC)
|
|
1471
1482
|
|
|
1472
1483
|
async def _run_shared_worker_attempt(
|
|
@@ -1493,6 +1504,7 @@ class PluginManager:
|
|
|
1493
1504
|
raise RuntimeError(
|
|
1494
1505
|
"Shared plugin worker exited before registration"
|
|
1495
1506
|
)
|
|
1507
|
+
self.ops_metrics.shared_transport_timeouts_total += 1
|
|
1496
1508
|
raise TimeoutError(
|
|
1497
1509
|
"Shared plugin worker did not register within "
|
|
1498
1510
|
f"{_SHARED_TRANSPORT_READY_TIMEOUT_SEC:.0f} seconds"
|
|
@@ -1571,6 +1583,7 @@ class PluginManager:
|
|
|
1571
1583
|
task = asyncio.create_task(self._initialize_shared_slot(runtime, handler))
|
|
1572
1584
|
worker.attach_tasks[runtime.binding] = task
|
|
1573
1585
|
self.plugin_run_tasks.append(task)
|
|
1586
|
+
self.ops_metrics.shared_slot_attach_total += 1
|
|
1574
1587
|
|
|
1575
1588
|
def attach_done(completed: asyncio.Task[None]) -> None:
|
|
1576
1589
|
if worker.attach_tasks.get(runtime.binding) is completed:
|
|
@@ -1597,6 +1610,7 @@ class PluginManager:
|
|
|
1597
1610
|
runtime.state = "failed"
|
|
1598
1611
|
runtime.error_code = "slot_attach_failed"
|
|
1599
1612
|
runtime.error_message = str(exc) or type(exc).__name__
|
|
1613
|
+
self.ops_metrics.shared_slot_attach_failures_total += 1
|
|
1600
1614
|
logger.error(
|
|
1601
1615
|
"Shared plugin slot attach failed: %s",
|
|
1602
1616
|
runtime.binding.installation_uuid,
|
|
@@ -1626,6 +1640,7 @@ class PluginManager:
|
|
|
1626
1640
|
timeout=_SHARED_SLOT_ATTACH_TIMEOUT_SEC,
|
|
1627
1641
|
)
|
|
1628
1642
|
except TimeoutError as exc:
|
|
1643
|
+
self.ops_metrics.shared_slot_attach_timeouts_total += 1
|
|
1629
1644
|
raise TimeoutError(
|
|
1630
1645
|
"Shared plugin slot did not initialize within "
|
|
1631
1646
|
f"{_SHARED_SLOT_ATTACH_TIMEOUT_SEC:.0f} seconds"
|
|
@@ -1715,6 +1730,7 @@ class PluginManager:
|
|
|
1715
1730
|
runtime.error_code = None
|
|
1716
1731
|
runtime.error_message = None
|
|
1717
1732
|
runtime.ready_event.set()
|
|
1733
|
+
self.ops_metrics.shared_slot_attach_success_total += 1
|
|
1718
1734
|
|
|
1719
1735
|
async def _detach_shared_worker_slot(
|
|
1720
1736
|
self,
|
|
@@ -1733,6 +1749,7 @@ class PluginManager:
|
|
|
1733
1749
|
with contextlib.suppress(Exception):
|
|
1734
1750
|
await handler.detach_plugin_slot(runtime.binding)
|
|
1735
1751
|
worker.slots.pop(runtime.binding, None)
|
|
1752
|
+
self.ops_metrics.shared_slot_detach_total += 1
|
|
1736
1753
|
if handler is not None:
|
|
1737
1754
|
handler.set_shared_pool_bindings(worker.artifact.digest, worker.slots)
|
|
1738
1755
|
runtime.shared_worker = None
|
|
@@ -1752,6 +1769,7 @@ class PluginManager:
|
|
|
1752
1769
|
self._shared_workers.pop(worker.artifact.digest, None)
|
|
1753
1770
|
|
|
1754
1771
|
async def _stop_shared_worker(self, worker: SharedPluginWorkerRuntime) -> None:
|
|
1772
|
+
self.ops_metrics.shared_stops_total += 1
|
|
1755
1773
|
handler = worker.plugin_handler
|
|
1756
1774
|
if handler is not None:
|
|
1757
1775
|
handler.cancel_inflight_messages()
|
|
@@ -1883,7 +1901,9 @@ class PluginManager:
|
|
|
1883
1901
|
binding.installation_uuid,
|
|
1884
1902
|
restart_delay,
|
|
1885
1903
|
)
|
|
1904
|
+
self.ops_metrics.record_dedicated_backoff(restart_delay)
|
|
1886
1905
|
await asyncio.sleep(restart_delay)
|
|
1906
|
+
self.ops_metrics.clear_dedicated_backoff()
|
|
1887
1907
|
delay = min(delay * 2, _PLUGIN_RESTART_MAX_DELAY_SEC)
|
|
1888
1908
|
attempt_number += 1
|
|
1889
1909
|
|
|
@@ -2017,6 +2037,7 @@ class PluginManager:
|
|
|
2017
2037
|
dependency_environment=worker.dependency_environment,
|
|
2018
2038
|
)
|
|
2019
2039
|
)
|
|
2040
|
+
self.ops_metrics.shared_processes_started_total += 1
|
|
2020
2041
|
worker.controller = controller
|
|
2021
2042
|
|
|
2022
2043
|
async def new_plugin_connection_callback(connection: Connection):
|
|
@@ -2700,6 +2721,7 @@ class PluginManager:
|
|
|
2700
2721
|
# take the lifecycle lock separately and revalidate identity.
|
|
2701
2722
|
worker.pending_plugin_handler = None
|
|
2702
2723
|
worker.plugin_handler = handler
|
|
2724
|
+
self.ops_metrics.shared_registrations_total += 1
|
|
2703
2725
|
attach_runtimes = []
|
|
2704
2726
|
for slot_runtime in tuple(worker.slots.values()):
|
|
2705
2727
|
if (
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.7.7"
|
|
@@ -11,5 +11,5 @@ def test_stable_release_metadata_is_consistent() -> None:
|
|
|
11
11
|
(root / "src/langbot_plugin/version.py").read_text(encoding="utf-8").strip()
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
-
assert project["project"]["version"] == "0.7.
|
|
15
|
-
assert source_version == '__version__ = "0.7.
|
|
14
|
+
assert project["project"]["version"] == "0.7.7"
|
|
15
|
+
assert source_version == '__version__ = "0.7.7"'
|
{langbot_plugin-0.7.6 → langbot_plugin-0.7.8}/tests/runtime/io/handlers/test_control_handler.py
RENAMED
|
@@ -450,21 +450,18 @@ async def test_control_handler_get_debug_info_returns_workspace_token():
|
|
|
450
450
|
assert len(response["data"]["plugin_debug_key"]) >= 32
|
|
451
451
|
assert response["data"]["expires_at"].endswith("Z")
|
|
452
452
|
assert response["data"]["ws_debug_port"] == 5401
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
"
|
|
456
|
-
"
|
|
457
|
-
"
|
|
458
|
-
"
|
|
459
|
-
"
|
|
460
|
-
"running": 0,
|
|
461
|
-
"starting": 0,
|
|
462
|
-
"failed": 0,
|
|
463
|
-
"disabled": 0,
|
|
464
|
-
},
|
|
465
|
-
"pending_registrations": 0,
|
|
466
|
-
"restart_coordinator": {"configured": False},
|
|
453
|
+
resources = response["data"]["resources"]
|
|
454
|
+
assert resources["installation_states"] == {
|
|
455
|
+
"running": 0,
|
|
456
|
+
"starting": 0,
|
|
457
|
+
"failed": 0,
|
|
458
|
+
"disabled": 0,
|
|
459
|
+
"other": 0,
|
|
467
460
|
}
|
|
461
|
+
assert resources["shared_pool"]["workers"] == 0
|
|
462
|
+
assert resources["shared_pool"]["slots"] == 0
|
|
463
|
+
assert resources["restart_coordinator"] == {"configured": False}
|
|
464
|
+
assert "workspace-a" not in str(resources)
|
|
468
465
|
|
|
469
466
|
|
|
470
467
|
async def test_control_handler_rejects_tenant_action_without_complete_binding():
|