langbot-plugin 0.6.20__tar.gz → 0.7.0__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.6.20 → langbot_plugin-0.7.0}/ARCHITECTURE.md +7 -5
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/PKG-INFO +1 -1
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/certified-plugins.md +6 -4
- langbot_plugin-0.7.0/docs/stateless-components.md +59 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/local_e2e/registration_fanin.py +2 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/pyproject.toml +1 -1
- langbot_plugin-0.7.0/src/langbot_plugin/api/definition/components/base.py +45 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/manifest.py +6 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/runner/runner.py +17 -2
- langbot_plugin-0.7.0/src/langbot_plugin/api/definition/plugin.py +52 -0
- langbot_plugin-0.7.0/src/langbot_plugin/api/proxies/invocation.py +155 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/langbot_api.py +12 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/e2b_backend.py +2 -1
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/host_backend.py +1 -34
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/nsjail_backend.py +1 -31
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/security.py +18 -14
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/certification.py +50 -5
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/run/controller.py +36 -22
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/run/handler.py +41 -8
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/controllers/stdio/client.py +1 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/handler.py +124 -42
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/handlers/plugin.py +3 -1
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/plugin/container.py +12 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/plugin/mgr.py +5 -1
- langbot_plugin-0.7.0/src/langbot_plugin/version.py +1 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/definition/test_manifest.py +7 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_backend.py +21 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_e2b_backend.py +14 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/run/test_controller.py +199 -28
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/run/test_runtime_handler.py +34 -1
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/packaging/test_release_metadata.py +2 -2
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/handlers/test_plugin_handler.py +2 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/test_handler.py +75 -1
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_shared_worker_subprocess.py +83 -9
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/test_certification.py +41 -2
- langbot_plugin-0.6.20/src/langbot_plugin/api/definition/components/base.py +0 -27
- langbot_plugin-0.6.20/src/langbot_plugin/api/definition/plugin.py +0 -32
- langbot_plugin-0.6.20/src/langbot_plugin/api/proxies/invocation.py +0 -74
- langbot_plugin-0.6.20/src/langbot_plugin/version.py +0 -1
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/.github/workflows/cla.yml +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/.github/workflows/publish-pypi.yaml +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/.github/workflows/publish.yml +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/.github/workflows/test.yml +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/.gitignore +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/.python-version +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/AGENTS.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/CLAUDE.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/CONTRIBUTING.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/LICENSE +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/README.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/README_CN.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/data/.env.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/Message.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/PluginPages.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/agent-runner-interactions.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/agent-runner-pluginization/PROTOCOL_V1.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/agent-runner-pluginization/README.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/agent-runner-pluginization/SDK_RUNTIME_PLAN.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/communication/apis/lb2rt.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/communication/runtime_plugin.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/dependency-management.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/langbot-plugin-social.png +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/docs/runner.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/local_e2e/acceptance.json +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/local_e2e/run_acceptance.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/mypy.ini +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/scripts/check_action_consistency.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/scripts/runtime_resource_probe.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/asset_gateway.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/daemon.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/decorators.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/external_tools.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/mcp_access.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/mcp_bridge.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/mcp_config.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/mcp_protocol.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/agent_tools/mcp_stdio.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/abstract/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/abstract/platform/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/abstract/platform/adapter.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/abstract/platform/event_logger.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/command/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/command/command.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/common/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/common/event_listener.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/knowledge_engine/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/knowledge_engine/engine.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/page/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/parser/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/parser/parser.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/runner/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/tool/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/definition/components/tool/tool.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/command/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/command/context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/command/errors.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/pipeline/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/pipeline/query.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/platform/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/platform/entities.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/platform/errors.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/platform/events.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/platform/logger.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/platform/message.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/provider/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/provider/message.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/provider/prompt.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/provider/reasoning.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/provider/session.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/rag/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/rag/context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/rag/enums.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/rag/errors.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/rag/models.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/resource/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/resource/tool.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/box.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/capabilities.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/compat.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/context_access.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/delivery.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/errors.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/event.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/input.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/interaction.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/manifest.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/page_results.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/permissions.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/resources.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/result.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/run_ledger.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/runtime.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/runtime_registry.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/state.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/stats.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/steering.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/transcript.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/builtin/runner/trigger.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/events.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/entities/execution.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/base.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/event_context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/execute_context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/query_based_api.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/admin.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/api.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/box.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/common.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/ledger.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/platform.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/reply_stream.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/resources.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/state.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/runner/tracing.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/langbot-page-sdk.js +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/.env.example.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/.github/workflows/release.yml.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/.gitignore.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/.vscode/launch.json.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/README.md.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/assets/icon.svg.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/commands/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.py.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.yaml.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/event_listener/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/event_listener/default.py.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/event_listener/default.yaml.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/knowledge_engine/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.py.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.yaml.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/pages/{page_name}.html.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/pages/{page_name}.yaml.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/parser/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.py.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.yaml.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/runner/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/runner/{runner_name}.py.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/runner/{runner_name}.yaml.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/tools/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.py.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.yaml.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/main.py.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/manifest.yaml.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/readme/README_zh_Hans.md.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/assets/templates/requirements.txt.example +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/actions.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/backend.py +30 -30
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/client.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/errors.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/models.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/runtime.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/server.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/skill_store.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/box/tenancy.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/__main__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/commands/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/commands/buildplugin.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/commands/gencomponent.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/commands/initplugin.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/commands/login.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/commands/logout.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/commands/publish.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/commands/runplugin.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/gen/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/gen/renderer.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/i18n.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/locales/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/locales/en_US.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/locales/es_ES.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/locales/ja_JP.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/locales/th_TH.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/locales/vi_VN.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/locales/zh_Hans.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/locales/zh_Hant.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/run/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/run/hotreload.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/utils/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/utils/cloudsv.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/utils/form.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/cli/utils/page_components.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/entities/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/entities/io/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/entities/io/actions/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/entities/io/actions/enums.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/entities/io/context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/entities/io/errors.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/entities/io/req.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/entities/io/resp.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/entities/marketplace.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/LICENSE +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/README.md +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/app.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/bounded_executor.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/event_loop_monitor.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/helper/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/helper/marketplace.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/helper/pkgmgr.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/connection.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/connections/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/connections/stdio.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/connections/ws.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/controller.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/controllers/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/controllers/stdio/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/controllers/stdio/server.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/controllers/ws/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/controllers/ws/client.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/controllers/ws/server.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/handlers/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/io/handlers/control.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/plugin/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/plugin/artifact.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/plugin/dependency_environment.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/plugin/logbuffer.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/plugin/restart_coordinator.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/plugin/runner_service.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/plugin/worker_launcher.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/security.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/runtime/settings.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/storage.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/utils/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/utils/deadline.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/utils/discover/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/utils/discover/engine.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/utils/importutil.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/utils/log.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/utils/platform.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/definition/components/test_components.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/definition/components/test_imports.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/builtin/runner/test_context_result.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/builtin/runner/test_history_event_entities.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/builtin/runner/test_interaction.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/builtin/runner/test_run_ledger_entities.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/builtin/test_command_context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/builtin/test_platform_logger.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/builtin/test_provider_message.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/builtin/test_rag_models.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/test_context.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/entities/test_events.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/proxies/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/proxies/test_agent_run_api_proxy.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/proxies/test_base.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/proxies/test_box_api.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/proxies/test_history_event_api_proxy.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/proxies/test_langbot_api.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/proxies/test_query_based_api.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/proxies/test_reasoning_parameter.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/test_agent_tools_mcp_bridge.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/test_runner_handlers.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/test_runner_handlers_matrix.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/api/test_runner_public_apis.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_admission.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_backend_selection.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_client.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_host_backend.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_nsjail_backend.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_runtime.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_server.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_skill_store.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/box/test_storage_analysis.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/run/test_hotreload.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_buildplugin.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_gencomponent.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_i18n_form.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_initplugin.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_login.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_logout_publish.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_page_components.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_renderer.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_runner_usages.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/cli/test_runplugin.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/e2e/standalone_runtime_eba_probe.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/entities/io/test_dependency_errors.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/entities/io/test_protocol.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/fixtures/eba_event_probe_plugin/.gitignore +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/fixtures/eba_event_probe_plugin/assets/icon.svg +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/fixtures/eba_event_probe_plugin/components/event_listener/default.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/fixtures/eba_event_probe_plugin/components/event_listener/default.yaml +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/fixtures/eba_event_probe_plugin/main.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/fixtures/eba_event_probe_plugin/manifest.yaml +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/helpers/__init__.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/helpers/protocol.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/packaging/test_installed_cli_blackbox.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/helper/test_marketplace.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/helper/test_pkgmgr.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/handlers/test_control_handler.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/handlers/test_import_contracts.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/handlers/test_legacy_file_chunk.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/test_action_consistency.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/test_connections.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/test_controllers.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/test_heartbeat_admission.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/io/test_stdio_server.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_artifact_store.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_container.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_dependency_environment.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_installation_manager.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_legacy_shadow.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_manager.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_mgr_runner.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_restart_coordinator.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_worker_launcher.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/plugin/test_workload_isolation.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/test_app.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/test_bounded_executor.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/test_event_loop_monitor.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/runtime/test_pull_api_handlers.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/test_log.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/test_message.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/test_plugin_logbuffer.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/test_storage.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/utils/test_deadline.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/utils/test_discovery.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/utils/test_importutil.py +0 -0
- {langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/tests/utils/test_platform.py +0 -0
|
@@ -53,8 +53,9 @@ Plugin-facing APIs live under `src/langbot_plugin/api/`.
|
|
|
53
53
|
- `definition/plugin.py` defines `BasePlugin`.
|
|
54
54
|
- `definition/components/` defines component base classes.
|
|
55
55
|
- `definition/components/manifest.py` defines component manifest models. Plugin
|
|
56
|
-
manifests may set `execution.sharedRuntime: shared-runtime-v1
|
|
57
|
-
the dedicated
|
|
56
|
+
manifests may set `execution.sharedRuntime: shared-runtime-v1` together with
|
|
57
|
+
`execution.componentModel: stateless-v1`; omission keeps the legacy dedicated
|
|
58
|
+
object model.
|
|
58
59
|
- `certification.py` defines optional ZIP-comment certification envelopes. It
|
|
59
60
|
canonicalizes envelope JSON, normalizes the ZIP digest by removing the comment,
|
|
60
61
|
and verifies the signed manifest identity and runtime profile without changing
|
|
@@ -176,9 +177,10 @@ worker immediately; stale or cross-Workspace transitions fail closed.
|
|
|
176
177
|
Dedicated enabled installations remain owned by installation-scoped
|
|
177
178
|
Supervisors. A certified shared worker is keyed by the raw artifact digest and
|
|
178
179
|
currently has pool size one: the first slot attach starts it and the last slot
|
|
179
|
-
detach stops it. Installations sharing that process
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
detach stops it. Installations sharing that process use one `BasePlugin` and one instance of each
|
|
181
|
+
component. Lightweight slots retain immutable config snapshots, Host authority,
|
|
182
|
+
revision and task ownership. Invocation-local context selects the slot; config
|
|
183
|
+
updates replace that snapshot without recreating components. Revision and
|
|
182
184
|
generation fencing remove the exact stale slot, cancel its in-flight actions,
|
|
183
185
|
and prevent background calls after detach.
|
|
184
186
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: langbot-plugin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
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
|
|
@@ -12,22 +12,24 @@ execution:
|
|
|
12
12
|
path: main.py
|
|
13
13
|
attr: Plugin
|
|
14
14
|
sharedRuntime: shared-runtime-v1
|
|
15
|
+
componentModel: stateless-v1
|
|
15
16
|
```
|
|
16
17
|
|
|
17
|
-
If `execution.sharedRuntime` is absent, the manifest remains a dedicated-runtime manifest.
|
|
18
|
+
If `execution.sharedRuntime` is absent, the manifest remains a dedicated-runtime manifest. `shared-runtime-v1` requires `componentModel: stateless-v1`; this declares the [stateless singleton component contract](stateless-components.md). Legacy per-installation object behavior remains compatible on dedicated workers but is not certifiable.
|
|
18
19
|
|
|
19
20
|
## Envelope format
|
|
20
21
|
|
|
21
|
-
The envelope is compact, sorted UTF-8 JSON in the ZIP comment.
|
|
22
|
+
The envelope is compact, sorted UTF-8 JSON in the ZIP comment. New stateless certificates use `certified-plugin-envelope-v2` with exactly these fields. Legacy v1 envelopes remain readable and verifiable, but have no signed `component_model` and cannot authorize shared singleton placement.
|
|
22
23
|
|
|
23
24
|
```json
|
|
24
25
|
{
|
|
25
|
-
"schema": "certified-plugin-envelope-
|
|
26
|
+
"schema": "certified-plugin-envelope-v2",
|
|
26
27
|
"key_id": "issuer-key-id",
|
|
27
28
|
"plugin_id": {"author": "publisher", "name": "plugin"},
|
|
28
29
|
"version": "1.2.3",
|
|
29
30
|
"digest": "lowercase-sha256-hex",
|
|
30
31
|
"shared_runtime": "shared-runtime-v1",
|
|
32
|
+
"component_model": "stateless-v1",
|
|
31
33
|
"signature": "base64-signature"
|
|
32
34
|
}
|
|
33
35
|
```
|
|
@@ -51,7 +53,7 @@ if result.status != "valid":
|
|
|
51
53
|
raise ValueError(result.status)
|
|
52
54
|
```
|
|
53
55
|
|
|
54
|
-
Verification binds the envelope's `plugin_id.author`, `plugin_id.name`, `version`, normalized digest, and `
|
|
56
|
+
Verification binds the envelope's `plugin_id.author`, `plugin_id.name`, `version`, normalized digest, `shared_runtime`, and `component_model` to `manifest.yaml`.
|
|
55
57
|
|
|
56
58
|
## Verification statuses
|
|
57
59
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Stateless component model (`stateless-v1`)
|
|
2
|
+
|
|
3
|
+
Certified cross-tenant plugins use one `BasePlugin` object and one object for every declared component manifest per artifact-digest worker. Multiple declared components of the same kind therefore have distinct shared objects. Installation attachments are lightweight immutable contexts; they do not create another plugin/component object graph.
|
|
4
|
+
|
|
5
|
+
## Manifest declaration
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
execution:
|
|
9
|
+
python:
|
|
10
|
+
path: main.py
|
|
11
|
+
attr: Plugin
|
|
12
|
+
sharedRuntime: shared-runtime-v1
|
|
13
|
+
componentModel: stateless-v1
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`sharedRuntime` without `componentModel: stateless-v1` is not eligible for certification. Legacy source and unsigned packages remain compatible with the dedicated path. OSS may downgrade an untrusted or legacy certificate to dedicated according to its admission policy; Cloud may reject it before installation.
|
|
17
|
+
|
|
18
|
+
## Programming contract
|
|
19
|
+
|
|
20
|
+
- Treat `BasePlugin` and every component object as process-wide singletons.
|
|
21
|
+
- Keep `initialize()` process-scoped. It runs once per worker, not once per installation.
|
|
22
|
+
- On `BasePlugin`, read installation configuration with `self.get_config()`. In a component, use `self.get_plugin_config()` or `self.plugin.get_config()`.
|
|
23
|
+
- Do not copy configuration, credentials, Workspace IDs, request data, or installation identity into instance fields or module globals.
|
|
24
|
+
- Do not mutate the returned configuration. Runtime installs an immutable snapshot for each invocation; `get_config()` returns a compatibility copy.
|
|
25
|
+
- Use SDK Host APIs for tenant storage, credentials, files, logging, models, tools, and RAG. Authority comes from the task-local `InstallationBinding`.
|
|
26
|
+
- If identity is needed, call `get_installation_binding()` during an invocation. Do not retain it after the call returns.
|
|
27
|
+
- Components must be re-entrant: invocations from different Workspaces may overlap on the same object.
|
|
28
|
+
- Tenant-bearing background work is forbidden in `stateless-v1` until the SDK exposes an explicit ownership and revocation API. Do not create tenant-bearing threads or detached tasks in `initialize()` or an invocation.
|
|
29
|
+
- Process-level caches may contain only public/artifact-level data. Tenant caches must include the full installation binding and be explicitly released on revocation.
|
|
30
|
+
|
|
31
|
+
This contract deliberately matches a future serverless execution model: component methods depend on input plus invocation context, while tenant state remains in Host services. The current release still uses long-lived workers; it does not provide a serverless deployment mode.
|
|
32
|
+
|
|
33
|
+
## Example
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
class LookupTool(Tool):
|
|
37
|
+
async def initialize(self) -> None:
|
|
38
|
+
# Process-wide initialization only.
|
|
39
|
+
self.http = StatelessHTTPTransport()
|
|
40
|
+
|
|
41
|
+
async def call(self, params, **kwargs):
|
|
42
|
+
config = self.get_plugin_config()
|
|
43
|
+
# Fetch secrets through Host APIs in the current invocation.
|
|
44
|
+
return await self.http.lookup(config["endpoint"], params)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Do not write:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
async def initialize(self):
|
|
51
|
+
self.endpoint = self.plugin.config["endpoint"]
|
|
52
|
+
self.api_key = self.plugin.config["api_key"]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Shared initialization has no tenant config, so this captures empty/stale data or fails. Any attempt to retain invocation config on the shared object is a certification blocker.
|
|
56
|
+
|
|
57
|
+
## Compatibility
|
|
58
|
+
|
|
59
|
+
Legacy source and unsigned packages keep the dedicated worker and existing object/config semantics. In OSS, certificate failures may downgrade to dedicated according to admission policy; Cloud may reject an ineligible package before storage. The stateless rules are an opt-in certification contract. Adding only the manifest fields is insufficient: source review and concurrency tests must prove the implementation follows the contract.
|
|
@@ -144,8 +144,10 @@ async def parent() -> None:
|
|
|
144
144
|
process.stdin,
|
|
145
145
|
process=process,
|
|
146
146
|
reserve_first_message_decode=True,
|
|
147
|
+
reserve_first_message_send=True,
|
|
147
148
|
),
|
|
148
149
|
context,
|
|
150
|
+
certified_shared_stdio=True,
|
|
149
151
|
)
|
|
150
152
|
# Isolate codec admission from manager ownership details.
|
|
151
153
|
handler.actions[PluginToRuntimeAction.REGISTER_PLUGIN.value] = (
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import abc
|
|
4
|
+
import typing
|
|
5
|
+
|
|
6
|
+
from langbot_plugin.api.definition.plugin import BasePlugin
|
|
7
|
+
from langbot_plugin.api.proxies.invocation import current_binding, current_config
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BaseComponent(abc.ABC):
|
|
11
|
+
"""The abstract base class for all components."""
|
|
12
|
+
|
|
13
|
+
plugin: BasePlugin
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
def get_plugin_config(self) -> dict[str, typing.Any]:
|
|
19
|
+
"""Return the task-local installation config for stateless components."""
|
|
20
|
+
|
|
21
|
+
handler = getattr(getattr(self, "plugin", None), "plugin_runtime_handler", None)
|
|
22
|
+
scoped = current_config(handler)
|
|
23
|
+
if scoped is not None:
|
|
24
|
+
return dict(scoped)
|
|
25
|
+
plugin = getattr(self, "plugin", None)
|
|
26
|
+
return plugin.get_config() if plugin is not None else {}
|
|
27
|
+
|
|
28
|
+
def get_installation_binding(self):
|
|
29
|
+
"""Return the active installation without storing tenant state on self."""
|
|
30
|
+
|
|
31
|
+
handler = getattr(getattr(self, "plugin", None), "plugin_runtime_handler", None)
|
|
32
|
+
return current_binding(handler)
|
|
33
|
+
|
|
34
|
+
async def initialize(self) -> None:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class NoneComponent(BaseComponent):
|
|
39
|
+
"""The component that does nothing, just acts as a placeholder."""
|
|
40
|
+
|
|
41
|
+
def __init__(self):
|
|
42
|
+
super().__init__()
|
|
43
|
+
|
|
44
|
+
async def initialize(self) -> None:
|
|
45
|
+
pass
|
|
@@ -128,6 +128,12 @@ class Execution(pydantic.BaseModel):
|
|
|
128
128
|
)
|
|
129
129
|
"""Certified shared runtime profile; absent manifests use a dedicated runtime."""
|
|
130
130
|
|
|
131
|
+
component_model: typing.Literal["stateless-v1"] | None = pydantic.Field(
|
|
132
|
+
default=None,
|
|
133
|
+
alias="componentModel",
|
|
134
|
+
)
|
|
135
|
+
"""Singleton, task-local component contract required for certification."""
|
|
136
|
+
|
|
131
137
|
@pydantic.model_validator(mode="before")
|
|
132
138
|
@classmethod
|
|
133
139
|
def _require_supported_shared_runtime_when_present(cls, values: typing.Any):
|
|
@@ -13,7 +13,11 @@ from langbot_plugin.api.entities.builtin.runner.result import RunnerResult
|
|
|
13
13
|
from langbot_plugin.api.entities.builtin.platform.events import EBAEvent
|
|
14
14
|
from langbot_plugin.api.proxies.runner.api import RunnerAPIProxy
|
|
15
15
|
from langbot_plugin.api.proxies.runner.tracing import _TracedRunAPI
|
|
16
|
-
from langbot_plugin.api.proxies.invocation import
|
|
16
|
+
from langbot_plugin.api.proxies.invocation import (
|
|
17
|
+
bind_invocation,
|
|
18
|
+
current_binding,
|
|
19
|
+
current_config,
|
|
20
|
+
)
|
|
17
21
|
|
|
18
22
|
|
|
19
23
|
class Runner(BaseComponent):
|
|
@@ -40,6 +44,9 @@ class Runner(BaseComponent):
|
|
|
40
44
|
self._plugin_identity = plugin_identity
|
|
41
45
|
|
|
42
46
|
def get_plugin_config(self) -> dict[str, Any]:
|
|
47
|
+
scoped = current_config(self._plugin_runtime_handler)
|
|
48
|
+
if scoped is not None:
|
|
49
|
+
return dict(scoped)
|
|
43
50
|
return dict(self._plugin_config)
|
|
44
51
|
|
|
45
52
|
@property
|
|
@@ -118,7 +125,15 @@ class Runner(BaseComponent):
|
|
|
118
125
|
await results.put(RunnerResult.run_completed(ctx.run_id))
|
|
119
126
|
|
|
120
127
|
async def execute_bound():
|
|
121
|
-
|
|
128
|
+
scoped_config = current_config(self._plugin_runtime_handler)
|
|
129
|
+
with bind_invocation(
|
|
130
|
+
self._plugin_runtime_handler,
|
|
131
|
+
ctx.api,
|
|
132
|
+
config=(
|
|
133
|
+
self._plugin_config if scoped_config is None else scoped_config
|
|
134
|
+
),
|
|
135
|
+
binding=current_binding(self._plugin_runtime_handler),
|
|
136
|
+
):
|
|
122
137
|
await execute()
|
|
123
138
|
|
|
124
139
|
task = asyncio.create_task(execute_bound())
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import abc
|
|
4
|
+
import typing
|
|
5
|
+
|
|
6
|
+
from langbot_plugin.api.proxies import langbot_api
|
|
7
|
+
from langbot_plugin.api.proxies.invocation import current_binding, current_config
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BasePlugin(abc.ABC, langbot_api.LangBotAPIProxy):
|
|
11
|
+
"""The base class for all plugins."""
|
|
12
|
+
|
|
13
|
+
_legacy_config: dict[str, typing.Any]
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def config(self) -> dict[str, typing.Any]:
|
|
17
|
+
"""Expose task-local config while preserving dedicated plugin behavior."""
|
|
18
|
+
|
|
19
|
+
scoped = current_config(getattr(self, "plugin_runtime_handler", None))
|
|
20
|
+
if scoped is not None:
|
|
21
|
+
return dict(scoped)
|
|
22
|
+
return getattr(self, "_legacy_config", {})
|
|
23
|
+
|
|
24
|
+
@config.setter
|
|
25
|
+
def config(self, value: dict[str, typing.Any]) -> None:
|
|
26
|
+
self._legacy_config = dict(value)
|
|
27
|
+
|
|
28
|
+
def get_config(self) -> dict[str, typing.Any]:
|
|
29
|
+
"""Return the active invocation config, or the legacy dedicated config."""
|
|
30
|
+
|
|
31
|
+
return self.config
|
|
32
|
+
|
|
33
|
+
def get_installation_binding(self):
|
|
34
|
+
"""Return the active certified installation binding, if any."""
|
|
35
|
+
|
|
36
|
+
return current_binding(getattr(self, "plugin_runtime_handler", None))
|
|
37
|
+
|
|
38
|
+
def __init__(self):
|
|
39
|
+
self._legacy_config = {}
|
|
40
|
+
|
|
41
|
+
async def initialize(self) -> None:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
def __del__(self) -> None:
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class NonePlugin(BasePlugin):
|
|
49
|
+
"""The plugin that does nothing, just acts as a placeholder."""
|
|
50
|
+
|
|
51
|
+
def __init__(self):
|
|
52
|
+
super().__init__()
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Task-local API binding shared by plugin and component methods."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from contextlib import contextmanager
|
|
6
|
+
from contextvars import ContextVar
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from functools import wraps
|
|
9
|
+
import inspect
|
|
10
|
+
from types import MappingProxyType
|
|
11
|
+
from typing import Any, Mapping
|
|
12
|
+
|
|
13
|
+
from langbot_plugin.entities.io.context import InstallationBinding
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def freeze_config(value: Any) -> Any:
|
|
17
|
+
"""Return an immutable invocation snapshot without sharing tenant objects."""
|
|
18
|
+
|
|
19
|
+
if isinstance(value, Mapping):
|
|
20
|
+
return MappingProxyType(
|
|
21
|
+
{str(key): freeze_config(item) for key, item in value.items()}
|
|
22
|
+
)
|
|
23
|
+
if isinstance(value, (list, tuple)):
|
|
24
|
+
return tuple(freeze_config(item) for item in value)
|
|
25
|
+
if isinstance(value, (set, frozenset)):
|
|
26
|
+
return frozenset(freeze_config(item) for item in value)
|
|
27
|
+
return value
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def thaw_config(value: Any) -> Any:
|
|
31
|
+
"""Return a recursively JSON-safe copy of an immutable config snapshot."""
|
|
32
|
+
|
|
33
|
+
if isinstance(value, Mapping):
|
|
34
|
+
return {str(key): thaw_config(item) for key, item in value.items()}
|
|
35
|
+
if isinstance(value, tuple):
|
|
36
|
+
return [thaw_config(item) for item in value]
|
|
37
|
+
if isinstance(value, frozenset):
|
|
38
|
+
return [thaw_config(item) for item in value]
|
|
39
|
+
return value
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class Invocation:
|
|
44
|
+
handler: Any
|
|
45
|
+
api: Any
|
|
46
|
+
config: Mapping[str, Any] | None = None
|
|
47
|
+
binding: InstallationBinding | None = None
|
|
48
|
+
active: bool = True
|
|
49
|
+
|
|
50
|
+
def require_active(self) -> None:
|
|
51
|
+
if not self.active:
|
|
52
|
+
raise RuntimeError("Plugin invocation has ended")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
_current: ContextVar[Invocation | None] = ContextVar("plugin_invocation", default=None)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@contextmanager
|
|
59
|
+
def bind_invocation(
|
|
60
|
+
handler,
|
|
61
|
+
api=None,
|
|
62
|
+
*,
|
|
63
|
+
config: Mapping[str, Any] | None = None,
|
|
64
|
+
binding: InstallationBinding | None = None,
|
|
65
|
+
):
|
|
66
|
+
invocation = Invocation(
|
|
67
|
+
handler,
|
|
68
|
+
api,
|
|
69
|
+
config=freeze_config(config or {}) if config is not None else None,
|
|
70
|
+
binding=binding,
|
|
71
|
+
)
|
|
72
|
+
token = _current.set(invocation)
|
|
73
|
+
try:
|
|
74
|
+
yield
|
|
75
|
+
finally:
|
|
76
|
+
invocation.active = False
|
|
77
|
+
_current.reset(token)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def current_api(handler):
|
|
81
|
+
invocation = _current.get()
|
|
82
|
+
if invocation is None or invocation.handler is not handler:
|
|
83
|
+
return None
|
|
84
|
+
if not invocation.active:
|
|
85
|
+
raise RuntimeError("Runner invocation has ended")
|
|
86
|
+
return invocation.api
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def current_invocation(handler=None) -> Invocation | None:
|
|
90
|
+
"""Return the active task-local invocation, rejecting escaped background work."""
|
|
91
|
+
|
|
92
|
+
invocation = _current.get()
|
|
93
|
+
if invocation is None:
|
|
94
|
+
return None
|
|
95
|
+
if handler is not None and invocation.handler is not handler:
|
|
96
|
+
return None
|
|
97
|
+
if not invocation.active:
|
|
98
|
+
raise RuntimeError("Plugin invocation has ended")
|
|
99
|
+
return invocation
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def invocation_capability(handler=None) -> Invocation | None:
|
|
103
|
+
"""Return the current revocable authority object for outbound boundaries."""
|
|
104
|
+
|
|
105
|
+
invocation = _current.get()
|
|
106
|
+
if invocation is None or (
|
|
107
|
+
handler is not None and invocation.handler is not handler
|
|
108
|
+
):
|
|
109
|
+
return None
|
|
110
|
+
invocation.require_active()
|
|
111
|
+
return invocation
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def current_config(handler=None) -> Mapping[str, Any] | None:
|
|
115
|
+
invocation = current_invocation(handler)
|
|
116
|
+
return None if invocation is None else invocation.config
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def current_binding(handler=None) -> InstallationBinding | None:
|
|
120
|
+
invocation = current_invocation(handler)
|
|
121
|
+
return None if invocation is None else invocation.binding
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def run_scoped(method):
|
|
125
|
+
"""Use the same public method with the current Runner authorization, if any."""
|
|
126
|
+
signature = inspect.signature(method)
|
|
127
|
+
|
|
128
|
+
def target(instance, args, kwargs):
|
|
129
|
+
api = current_api(instance.plugin_runtime_handler)
|
|
130
|
+
if api is None:
|
|
131
|
+
return method, (instance, *args), kwargs
|
|
132
|
+
bound = signature.bind(instance, *args, **kwargs)
|
|
133
|
+
arguments = dict(bound.arguments)
|
|
134
|
+
arguments.pop("self")
|
|
135
|
+
if method.__name__ == "call_tool":
|
|
136
|
+
arguments.pop("session", None)
|
|
137
|
+
arguments.pop("query_id", None)
|
|
138
|
+
return getattr(api, method.__name__), (), arguments
|
|
139
|
+
|
|
140
|
+
if inspect.isasyncgenfunction(method):
|
|
141
|
+
|
|
142
|
+
@wraps(method)
|
|
143
|
+
async def stream(self, *args, **kwargs):
|
|
144
|
+
fn, positional, named = target(self, args, kwargs)
|
|
145
|
+
async for item in fn(*positional, **named):
|
|
146
|
+
yield item
|
|
147
|
+
|
|
148
|
+
return stream
|
|
149
|
+
|
|
150
|
+
@wraps(method)
|
|
151
|
+
async def call(self, *args, **kwargs):
|
|
152
|
+
fn, positional, named = target(self, args, kwargs)
|
|
153
|
+
return await fn(*positional, **named)
|
|
154
|
+
|
|
155
|
+
return call
|
{langbot_plugin-0.6.20 → langbot_plugin-0.7.0}/src/langbot_plugin/api/proxies/langbot_api.py
RENAMED
|
@@ -79,6 +79,7 @@ class LangBotAPIProxy:
|
|
|
79
79
|
)
|
|
80
80
|
)["version"]
|
|
81
81
|
|
|
82
|
+
@run_scoped
|
|
82
83
|
async def get_bots(self) -> list[str]:
|
|
83
84
|
"""Get all bots"""
|
|
84
85
|
return (
|
|
@@ -87,6 +88,7 @@ class LangBotAPIProxy:
|
|
|
87
88
|
)
|
|
88
89
|
)["bots"]
|
|
89
90
|
|
|
91
|
+
@run_scoped
|
|
90
92
|
async def get_bot_info(self, bot_uuid: str) -> dict[str, Any]:
|
|
91
93
|
"""Get a bot info"""
|
|
92
94
|
return (
|
|
@@ -343,6 +345,7 @@ class LangBotAPIProxy:
|
|
|
343
345
|
PluginToRuntimeAction.DELETE_WORKSPACE_STORAGE, {"key": key}
|
|
344
346
|
)
|
|
345
347
|
|
|
348
|
+
@run_scoped
|
|
346
349
|
async def get_config_file(self, file_key: str) -> bytes:
|
|
347
350
|
"""Get a config file by file key
|
|
348
351
|
|
|
@@ -360,6 +363,7 @@ class LangBotAPIProxy:
|
|
|
360
363
|
|
|
361
364
|
return base64.b64decode(resp)
|
|
362
365
|
|
|
366
|
+
@run_scoped
|
|
363
367
|
async def list_plugins_manifest(self) -> list[str]:
|
|
364
368
|
"""List all plugins"""
|
|
365
369
|
return (
|
|
@@ -368,6 +372,7 @@ class LangBotAPIProxy:
|
|
|
368
372
|
)
|
|
369
373
|
)["plugins"]
|
|
370
374
|
|
|
375
|
+
@run_scoped
|
|
371
376
|
async def list_commands(self) -> list[str]:
|
|
372
377
|
"""List all commands"""
|
|
373
378
|
return (
|
|
@@ -510,6 +515,7 @@ class LangBotAPIProxy:
|
|
|
510
515
|
)
|
|
511
516
|
)["results"]
|
|
512
517
|
|
|
518
|
+
@run_scoped
|
|
513
519
|
async def vector_upsert(
|
|
514
520
|
self,
|
|
515
521
|
collection_id: str,
|
|
@@ -542,6 +548,7 @@ class LangBotAPIProxy:
|
|
|
542
548
|
timeout=60,
|
|
543
549
|
)
|
|
544
550
|
|
|
551
|
+
@run_scoped
|
|
545
552
|
async def vector_search(
|
|
546
553
|
self,
|
|
547
554
|
collection_id: str,
|
|
@@ -586,6 +593,7 @@ class LangBotAPIProxy:
|
|
|
586
593
|
)
|
|
587
594
|
)["results"]
|
|
588
595
|
|
|
596
|
+
@run_scoped
|
|
589
597
|
async def vector_delete(
|
|
590
598
|
self,
|
|
591
599
|
collection_id: str,
|
|
@@ -614,6 +622,7 @@ class LangBotAPIProxy:
|
|
|
614
622
|
)
|
|
615
623
|
)["count"]
|
|
616
624
|
|
|
625
|
+
@run_scoped
|
|
617
626
|
async def vector_list(
|
|
618
627
|
self,
|
|
619
628
|
collection_id: str,
|
|
@@ -644,6 +653,7 @@ class LangBotAPIProxy:
|
|
|
644
653
|
timeout=30,
|
|
645
654
|
)
|
|
646
655
|
|
|
656
|
+
@run_scoped
|
|
647
657
|
async def get_knowledge_file_stream(self, storage_path: str) -> bytes:
|
|
648
658
|
"""Get file content from Host's storage.
|
|
649
659
|
|
|
@@ -723,6 +733,7 @@ class LangBotAPIProxy:
|
|
|
723
733
|
|
|
724
734
|
# ================= Parser Capability APIs =================
|
|
725
735
|
|
|
736
|
+
@run_scoped
|
|
726
737
|
async def list_parsers(self, mime_type: str | None = None) -> list[dict[str, Any]]:
|
|
727
738
|
"""List available Parser plugins.
|
|
728
739
|
|
|
@@ -739,6 +750,7 @@ class LangBotAPIProxy:
|
|
|
739
750
|
)
|
|
740
751
|
)["parsers"]
|
|
741
752
|
|
|
753
|
+
@run_scoped
|
|
742
754
|
async def invoke_parser(
|
|
743
755
|
self,
|
|
744
756
|
plugin_author: str,
|
|
@@ -6,6 +6,7 @@ import json
|
|
|
6
6
|
import logging
|
|
7
7
|
import os
|
|
8
8
|
import posixpath
|
|
9
|
+
import re
|
|
9
10
|
import shlex
|
|
10
11
|
|
|
11
12
|
from .backend import BaseSandboxBackend, _MAX_RAW_OUTPUT_BYTES
|
|
@@ -95,7 +96,7 @@ def _adapt_path_for_e2b(path: str) -> str:
|
|
|
95
96
|
|
|
96
97
|
def _rewrite_command_paths_for_e2b(command: str) -> str:
|
|
97
98
|
"""Rewrite LangBot's logical /workspace paths for E2B's real writable path."""
|
|
98
|
-
return
|
|
99
|
+
return re.sub(r"(?<![\w.-])/workspace(?=$|/|[^\w.-])", E2B_WORKSPACE_DIR, command)
|
|
99
100
|
|
|
100
101
|
|
|
101
102
|
class E2BSandboxBackend(BaseSandboxBackend):
|
|
@@ -13,7 +13,7 @@ import signal
|
|
|
13
13
|
import tempfile
|
|
14
14
|
import uuid
|
|
15
15
|
|
|
16
|
-
from .backend import BaseSandboxBackend, _CommandResult
|
|
16
|
+
from .backend import BaseSandboxBackend, _CommandResult
|
|
17
17
|
from .errors import BoxError, BoxValidationError
|
|
18
18
|
from .models import (
|
|
19
19
|
BoxExecutionResult,
|
|
@@ -357,39 +357,6 @@ class HostProcessBackend(BaseSandboxBackend):
|
|
|
357
357
|
pass
|
|
358
358
|
await process.wait()
|
|
359
359
|
|
|
360
|
-
@staticmethod
|
|
361
|
-
async def _read_stream(
|
|
362
|
-
stream: asyncio.StreamReader | None,
|
|
363
|
-
limit: int = _MAX_RAW_OUTPUT_BYTES,
|
|
364
|
-
) -> tuple[bytes, int]:
|
|
365
|
-
if stream is None:
|
|
366
|
-
return b"", 0
|
|
367
|
-
chunks = bytearray()
|
|
368
|
-
total_size = 0
|
|
369
|
-
while True:
|
|
370
|
-
chunk = await stream.read(65536)
|
|
371
|
-
if not chunk:
|
|
372
|
-
break
|
|
373
|
-
total_size += len(chunk)
|
|
374
|
-
remaining = limit - len(chunks)
|
|
375
|
-
if remaining > 0:
|
|
376
|
-
chunks.extend(chunk[:remaining])
|
|
377
|
-
return bytes(chunks), total_size
|
|
378
|
-
|
|
379
|
-
@staticmethod
|
|
380
|
-
def _clip_captured_bytes(
|
|
381
|
-
data: bytes,
|
|
382
|
-
total_size: int,
|
|
383
|
-
limit: int = _MAX_RAW_OUTPUT_BYTES,
|
|
384
|
-
) -> str:
|
|
385
|
-
text = data.decode("utf-8", errors="replace").strip()
|
|
386
|
-
if total_size > limit:
|
|
387
|
-
text += (
|
|
388
|
-
f"\n... [raw output clipped at {limit} bytes, "
|
|
389
|
-
f"{total_size - limit} bytes discarded]"
|
|
390
|
-
)
|
|
391
|
-
return text
|
|
392
|
-
|
|
393
360
|
@staticmethod
|
|
394
361
|
def _preview(command: str) -> str:
|
|
395
362
|
command = command.strip()
|
|
@@ -15,7 +15,7 @@ from typing import Any
|
|
|
15
15
|
|
|
16
16
|
from langbot_plugin.runtime import bounded_executor
|
|
17
17
|
|
|
18
|
-
from .backend import BaseSandboxBackend, _CommandResult
|
|
18
|
+
from .backend import BaseSandboxBackend, _CommandResult
|
|
19
19
|
from .models import (
|
|
20
20
|
BoxExecutionResult,
|
|
21
21
|
BoxExecutionStatus,
|
|
@@ -945,33 +945,3 @@ class NsjailBackend(BaseSandboxBackend):
|
|
|
945
945
|
self.logger.info(f"Killed orphaned nsjail process {pid}")
|
|
946
946
|
except (OSError, ValueError):
|
|
947
947
|
continue
|
|
948
|
-
|
|
949
|
-
@staticmethod
|
|
950
|
-
def _clip_captured_bytes(
|
|
951
|
-
data: bytes, total_size: int, limit: int = _MAX_RAW_OUTPUT_BYTES
|
|
952
|
-
) -> str:
|
|
953
|
-
text = data.decode("utf-8", errors="replace").strip()
|
|
954
|
-
if total_size > limit:
|
|
955
|
-
text += f"\n... [raw output clipped at {limit} bytes, {total_size - limit} bytes discarded]"
|
|
956
|
-
return text
|
|
957
|
-
|
|
958
|
-
@staticmethod
|
|
959
|
-
async def _read_stream(
|
|
960
|
-
stream: asyncio.StreamReader | None,
|
|
961
|
-
limit: int = _MAX_RAW_OUTPUT_BYTES,
|
|
962
|
-
) -> tuple[bytes, int]:
|
|
963
|
-
if stream is None:
|
|
964
|
-
return b"", 0
|
|
965
|
-
|
|
966
|
-
chunks = bytearray()
|
|
967
|
-
total_size = 0
|
|
968
|
-
while True:
|
|
969
|
-
chunk = await stream.read(65536)
|
|
970
|
-
if not chunk:
|
|
971
|
-
break
|
|
972
|
-
total_size += len(chunk)
|
|
973
|
-
remaining = limit - len(chunks)
|
|
974
|
-
if remaining > 0:
|
|
975
|
-
chunks.extend(chunk[:remaining])
|
|
976
|
-
|
|
977
|
-
return bytes(chunks), total_size
|