langbot-plugin 0.4.6__tar.gz → 0.4.7__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.4.7/AGENTS.md +121 -0
- langbot_plugin-0.4.7/ARCHITECTURE.md +225 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/PKG-INFO +1 -1
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/docs/communication/apis/lb2rt.md +22 -1
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/pyproject.toml +1 -1
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/command/errors.py +0 -1
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/backend.py +28 -5
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/runtime.py +307 -99
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/server.py +1 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/run/handler.py +37 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/entities/io/actions/enums.py +2 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/handlers/control.py +11 -4
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/handlers/plugin.py +10 -1
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/plugin/logbuffer.py +19 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/plugin/mgr.py +158 -2
- langbot_plugin-0.4.7/src/langbot_plugin/version.py +1 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/box/test_backend.py +62 -7
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/box/test_backend_selection.py +7 -4
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/box/test_runtime.py +327 -6
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/run/test_runtime_handler.py +29 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/io/handlers/test_control_handler.py +40 -1
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/io/handlers/test_plugin_handler.py +16 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/plugin/test_manager.py +166 -2
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/test_plugin_logbuffer.py +28 -0
- langbot_plugin-0.4.6/AGENTS.md +0 -1117
- langbot_plugin-0.4.6/src/langbot_plugin/version.py +0 -1
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/.github/workflows/cla.yml +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/.github/workflows/publish-pypi.yaml +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/.github/workflows/test.yml +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/.gitignore +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/.python-version +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/CLAUDE.md +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/CONTRIBUTING.md +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/LICENSE +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/README.md +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/README_CN.md +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/data/.env.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/docs/Message.md +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/docs/PluginPages.md +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/docs/communication/runtime_plugin.md +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/docs/dependency-management.md +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/docs/langbot-plugin-social.png +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/scripts/check_action_consistency.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/abstract/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/abstract/platform/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/abstract/platform/adapter.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/abstract/platform/event_logger.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/base.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/command/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/command/command.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/common/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/common/event_listener.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/knowledge_engine/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/knowledge_engine/engine.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/manifest.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/page/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/parser/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/parser/parser.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/tool/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/components/tool/tool.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/definition/plugin.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/command/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/command/context.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/pipeline/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/pipeline/query.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/platform/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/platform/entities.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/platform/events.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/platform/logger.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/platform/message.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/provider/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/provider/message.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/provider/prompt.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/provider/session.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/rag/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/rag/context.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/rag/enums.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/rag/errors.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/rag/models.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/resource/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/builtin/resource/tool.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/context.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/entities/events.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/proxies/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/proxies/base.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/proxies/event_context.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/proxies/execute_context.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/proxies/langbot_api.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/api/proxies/query_based_api.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/langbot-page-sdk.js +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/.env.example.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/.github/workflows/release.yml.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/.gitignore.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/.vscode/launch.json.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/README.md.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/assets/icon.svg.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/commands/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.py.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.yaml.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/event_listener/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/event_listener/default.py.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/event_listener/default.yaml.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/knowledge_engine/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.py.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.yaml.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/pages/{page_name}.html.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/pages/{page_name}.yaml.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/parser/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.py.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.yaml.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/tools/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.py.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.yaml.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/main.py.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/manifest.yaml.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/readme/README_zh_Hans.md.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/assets/templates/requirements.txt.example +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/actions.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/client.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/e2b_backend.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/errors.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/models.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/nsjail_backend.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/security.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/box/skill_store.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/__main__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/commands/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/commands/buildplugin.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/commands/gencomponent.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/commands/initplugin.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/commands/login.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/commands/logout.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/commands/publish.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/commands/runplugin.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/gen/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/gen/renderer.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/i18n.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/locales/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/locales/en_US.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/locales/es_ES.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/locales/ja_JP.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/locales/th_TH.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/locales/vi_VN.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/locales/zh_Hans.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/locales/zh_Hant.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/run/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/run/controller.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/run/hotreload.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/utils/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/utils/cloudsv.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/utils/form.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/cli/utils/page_components.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/entities/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/entities/io/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/entities/io/actions/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/entities/io/errors.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/entities/io/req.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/entities/io/resp.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/entities/marketplace.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/LICENSE +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/README.md +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/app.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/context.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/helper/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/helper/marketplace.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/helper/pkgmgr.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/connection.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/connections/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/connections/stdio.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/connections/ws.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/controller.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/controllers/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/controllers/stdio/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/controllers/stdio/client.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/controllers/stdio/server.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/controllers/ws/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/controllers/ws/client.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/controllers/ws/server.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/handler.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/io/handlers/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/plugin/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/plugin/container.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/runtime/settings.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/utils/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/utils/discover/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/utils/discover/engine.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/utils/importutil.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/utils/log.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/src/langbot_plugin/utils/platform.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/definition/components/test_components.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/definition/test_manifest.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/entities/builtin/test_command_context.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/entities/builtin/test_platform_logger.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/entities/builtin/test_provider_message.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/entities/builtin/test_rag_models.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/entities/test_context.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/entities/test_events.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/proxies/test_base.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/proxies/test_langbot_api.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/api/proxies/test_query_based_api.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/box/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/box/test_client.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/box/test_e2b_backend.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/box/test_nsjail_backend.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/box/test_server.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/box/test_skill_store.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/run/test_controller.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/run/test_hotreload.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/test_buildplugin.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/test_gencomponent.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/test_i18n_form.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/test_initplugin.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/test_login.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/test_logout_publish.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/test_page_components.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/test_renderer.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/cli/test_runplugin.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/entities/io/test_dependency_errors.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/entities/io/test_protocol.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/helpers/__init__.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/helpers/protocol.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/packaging/test_installed_cli_blackbox.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/helper/test_marketplace.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/helper/test_pkgmgr.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/io/handlers/test_import_contracts.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/io/test_action_consistency.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/io/test_connections.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/io/test_controllers.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/io/test_handler.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/plugin/test_container.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/runtime/test_app.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/test_log.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/test_message.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/utils/test_discovery.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/utils/test_importutil.py +0 -0
- {langbot_plugin-0.4.6 → langbot_plugin-0.4.7}/tests/utils/test_platform.py +0 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file guides code agents working in the `langbot-plugin-sdk` repository. `CLAUDE.md` is a symlink to this file.
|
|
4
|
+
|
|
5
|
+
Read `ARCHITECTURE.md` before non-trivial SDK, CLI, Plugin Runtime, Box Runtime, protocol, or cross-repo LangBot changes. This file is the working checklist; `ARCHITECTURE.md` is the system map.
|
|
6
|
+
|
|
7
|
+
## Quick Facts
|
|
8
|
+
|
|
9
|
+
- Package name: `langbot-plugin`.
|
|
10
|
+
- Python: `>=3.10`.
|
|
11
|
+
- CLI entrypoint: `lbp = langbot_plugin.cli:main`.
|
|
12
|
+
- Main consumers: LangBot main repo and third-party plugins.
|
|
13
|
+
- Runtime license: `src/langbot_plugin/runtime/` is AGPL; the rest is Apache 2.0.
|
|
14
|
+
- LangBot pins this package in its `pyproject.toml`; local cross-repo testing needs a local install into LangBot's venv.
|
|
15
|
+
|
|
16
|
+
## Essential Commands
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv sync --dev
|
|
20
|
+
uv run lbp --help
|
|
21
|
+
uv run lbp ver
|
|
22
|
+
uv run lbp init MyPlugin
|
|
23
|
+
uv run lbp comp Command
|
|
24
|
+
uv run lbp run
|
|
25
|
+
uv run lbp build
|
|
26
|
+
uv run lbp publish
|
|
27
|
+
uv run lbp rt
|
|
28
|
+
uv run lbp box
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Focused validation:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv run pytest tests/api -q
|
|
35
|
+
uv run pytest tests/cli -q
|
|
36
|
+
uv run pytest tests/runtime -q
|
|
37
|
+
uv run pytest tests/box -q
|
|
38
|
+
uv run pytest tests/packaging/test_installed_cli_blackbox.py -q
|
|
39
|
+
uv run python scripts/check_action_consistency.py
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Where to Look
|
|
43
|
+
|
|
44
|
+
- Architecture map: `ARCHITECTURE.md`.
|
|
45
|
+
- CLI entrypoint and flags: `src/langbot_plugin/cli/__init__.py`.
|
|
46
|
+
- Plugin SDK APIs: `src/langbot_plugin/api/`.
|
|
47
|
+
- Plugin Runtime: `src/langbot_plugin/runtime/`.
|
|
48
|
+
- Box Runtime: `src/langbot_plugin/box/`.
|
|
49
|
+
- Action protocol: `src/langbot_plugin/entities/io/` and `src/langbot_plugin/runtime/io/handler.py`.
|
|
50
|
+
- Plugin tutorial: https://docs.langbot.app/zh/plugin/dev/tutor.
|
|
51
|
+
- Runtime/CLI/SDK debugging: https://docs.langbot.app/zh/develop/plugin-runtime.
|
|
52
|
+
- LangBot main repo: `../LangBot/`.
|
|
53
|
+
|
|
54
|
+
## Cross-Repo LangBot Testing
|
|
55
|
+
|
|
56
|
+
Use sibling repos:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
langbot-projects/
|
|
60
|
+
├── LangBot/
|
|
61
|
+
└── langbot-plugin-sdk/
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
When changing shared entities, component contracts, action payloads, Plugin Runtime, or Box Runtime:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# from langbot-plugin-sdk, with LangBot's .venv active
|
|
68
|
+
uv pip install .
|
|
69
|
+
|
|
70
|
+
# from LangBot; keep local SDK installed
|
|
71
|
+
uv run --no-sync main.py
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Standalone runtime flows:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Plugin Runtime, default control :5400 and debug :5401
|
|
78
|
+
uv run --no-sync lbp rt
|
|
79
|
+
|
|
80
|
+
# Box Runtime, default :5410
|
|
81
|
+
uv run --no-sync lbp box
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Then configure LangBot as needed:
|
|
85
|
+
|
|
86
|
+
- Plugin runtime: `plugin.runtime_ws_url: ws://localhost:5400/control/ws`, launch LangBot with `--standalone-runtime`.
|
|
87
|
+
- Box runtime: `box.runtime.endpoint: ws://127.0.0.1:5410`, choose `box.backend`, launch LangBot with `--standalone-box`.
|
|
88
|
+
|
|
89
|
+
## Change Rules
|
|
90
|
+
|
|
91
|
+
- Treat action enums and Pydantic models as cross-process API contracts; update callers, handlers, and tests together.
|
|
92
|
+
- Do not duplicate action strings outside the enum definitions.
|
|
93
|
+
- Keep generated plugin templates, component base classes, CLI renderer behavior, and docs consistent when component contracts change.
|
|
94
|
+
- Preserve `uv run --no-sync` guidance for local SDK testing; otherwise LangBot may reinstall the pinned PyPI package.
|
|
95
|
+
- Keep comments/docstrings in English and user-facing labels/descriptions i18n-ready.
|
|
96
|
+
- Commit message format: `<type>(<scope>): <subject>`.
|
|
97
|
+
|
|
98
|
+
## Runtime Pitfalls
|
|
99
|
+
|
|
100
|
+
- Direct local LangBot runs often spawn Plugin Runtime over stdio; stdio disconnects cannot auto-reconnect.
|
|
101
|
+
- Orphan Runtime processes holding `5400`/`5401` commonly break `lbp run` debugging.
|
|
102
|
+
- Docker deployments use `langbot_plugin_runtime:5400/control/ws` and `langbot_box:5410` as service hosts.
|
|
103
|
+
- A false Box “no backend” often means Docker socket permission is missing, not that Docker is unavailable.
|
|
104
|
+
- nsjail inside containers needs host cgroup namespace for cgroup v2 limits; do not fake memory limits with `RLIMIT_AS` because it breaks tools that reserve large virtual memory.
|
|
105
|
+
- There is no supported `python -m langbot_plugin.box` entrypoint; use `lbp box`.
|
|
106
|
+
- `CLAUDE.md` is a symlink to this file; edit `AGENTS.md`, not the symlink.
|
|
107
|
+
|
|
108
|
+
## Principles
|
|
109
|
+
|
|
110
|
+
- Keep it simple, stupid.
|
|
111
|
+
- Entities should not be multiplied unnecessarily.
|
|
112
|
+
- 八荣八耻
|
|
113
|
+
|
|
114
|
+
以瞎猜接口为耻,以认真查询为荣。
|
|
115
|
+
以模糊执行为耻,以寻求确认为荣。
|
|
116
|
+
以臆想业务为耻,以人类确认为荣。
|
|
117
|
+
以创造接口为耻,以复用现有为荣。
|
|
118
|
+
以跳过验证为耻,以主动测试为荣。
|
|
119
|
+
以破坏架构为耻,以遵循规范为荣。
|
|
120
|
+
以假装理解为耻,以诚实无知为荣。
|
|
121
|
+
以盲目修改为耻,以谨慎重构为荣。
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This document maps the `langbot-plugin-sdk` repository. It explains the durable structure and cross-process contracts. For working rules, commands, and pitfalls, see `AGENTS.md`.
|
|
4
|
+
|
|
5
|
+
## What This Repository Is
|
|
6
|
+
|
|
7
|
+
`langbot-plugin-sdk` is the infrastructure package behind LangBot's plugin and sandbox systems. It is published to PyPI as `langbot-plugin` and pinned by the LangBot main repo.
|
|
8
|
+
|
|
9
|
+
The package has four roles:
|
|
10
|
+
|
|
11
|
+
- **Plugin SDK**: public APIs and entities imported by plugin authors.
|
|
12
|
+
- **CLI**: `lbp`, used to scaffold, run, debug, build, publish, and launch runtimes.
|
|
13
|
+
- **Plugin Runtime**: `lbp rt`, the host process that manages plugin packages and plugin processes.
|
|
14
|
+
- **Box Runtime**: `lbp box`, the sandbox runtime used by LangBot's Box subsystem.
|
|
15
|
+
|
|
16
|
+
The runtime code under `src/langbot_plugin/runtime/` is AGPL; the rest of the repo is Apache 2.0.
|
|
17
|
+
|
|
18
|
+
## Repository Boundary
|
|
19
|
+
|
|
20
|
+
This repo is coupled to LangBot but owns different things.
|
|
21
|
+
|
|
22
|
+
- The LangBot main repo owns product behavior, HTTP API, web UI, platform adapters, pipeline execution, model/tool orchestration, persistence, skills integration, and the LangBot-side runtime connectors.
|
|
23
|
+
- This SDK repo owns plugin author APIs, shared message/event/context entities, the action RPC protocol, `lbp`, Plugin Runtime implementation, and Box Runtime implementation.
|
|
24
|
+
- Plugins import this package directly; LangBot also imports it for shared entities and runtime protocols.
|
|
25
|
+
|
|
26
|
+
If a change alters shared entities, component contracts, action names/payloads, runtime behavior, or Box models, update/test both repos in lockstep.
|
|
27
|
+
|
|
28
|
+
## Top-Level Layout
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
langbot-plugin-sdk/
|
|
32
|
+
├── src/langbot_plugin/
|
|
33
|
+
│ ├── api/ # Public plugin-author SDK
|
|
34
|
+
│ │ ├── definition/ # BasePlugin, components, manifests
|
|
35
|
+
│ │ ├── entities/ # Contexts, events, builtin platform/provider models
|
|
36
|
+
│ │ └── proxies/ # APIs exposed to plugin code
|
|
37
|
+
│ ├── cli/ # `lbp` entrypoint and subcommands
|
|
38
|
+
│ ├── runtime/ # Plugin Runtime (`lbp rt`)
|
|
39
|
+
│ ├── box/ # Box Runtime (`lbp box`)
|
|
40
|
+
│ ├── entities/io/ # Action RPC request/response/error/action models
|
|
41
|
+
│ ├── assets/ # Scaffolding templates and page SDK asset
|
|
42
|
+
│ └── utils/
|
|
43
|
+
├── docs/ # Supplemental protocol/component docs
|
|
44
|
+
├── tests/ # Unit and black-box tests
|
|
45
|
+
├── pyproject.toml
|
|
46
|
+
└── README.md
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Public Plugin SDK
|
|
50
|
+
|
|
51
|
+
Plugin-facing APIs live under `src/langbot_plugin/api/`.
|
|
52
|
+
|
|
53
|
+
- `definition/plugin.py` defines `BasePlugin`.
|
|
54
|
+
- `definition/components/` defines component base classes.
|
|
55
|
+
- `definition/components/manifest.py` defines component manifest models.
|
|
56
|
+
- `entities/` defines event/context/message/provider data models passed across LangBot, runtime, and plugin code.
|
|
57
|
+
- `proxies/` defines methods plugins can call back into LangBot, such as messaging, storage, model invocation, tools, RAG, parser, and query-scoped APIs.
|
|
58
|
+
|
|
59
|
+
Plugins extend LangBot through six component types:
|
|
60
|
+
|
|
61
|
+
- `Command`
|
|
62
|
+
- `Tool`
|
|
63
|
+
- `EventListener`
|
|
64
|
+
- `KnowledgeEngine`
|
|
65
|
+
- `Parser`
|
|
66
|
+
- `Page`
|
|
67
|
+
|
|
68
|
+
The CLI scaffolds components via `lbp comp <Type>`. Component templates live under `src/langbot_plugin/assets/templates/`; generation logic lives under `src/langbot_plugin/cli/gen/`.
|
|
69
|
+
|
|
70
|
+
## CLI Architecture
|
|
71
|
+
|
|
72
|
+
`lbp` is declared in `pyproject.toml` and enters at `src/langbot_plugin/cli:main`, implemented by `src/langbot_plugin/cli/__init__.py`.
|
|
73
|
+
|
|
74
|
+
Subcommands:
|
|
75
|
+
|
|
76
|
+
- `init`: scaffold a plugin project.
|
|
77
|
+
- `comp`: generate a plugin component.
|
|
78
|
+
- `run`: run/remote-debug a plugin against a Runtime debug server.
|
|
79
|
+
- `build`: package a plugin zip.
|
|
80
|
+
- `publish`: publish a plugin to the marketplace.
|
|
81
|
+
- `login` / `logout`: marketplace authentication.
|
|
82
|
+
- `rt`: launch the Plugin Runtime.
|
|
83
|
+
- `box`: launch the Box Runtime.
|
|
84
|
+
- `ver`: print package version.
|
|
85
|
+
|
|
86
|
+
Subcommand implementations live under `cli/commands/`, `cli/run/`, and `cli/gen/`. CLI i18n lives under `cli/locales/`.
|
|
87
|
+
|
|
88
|
+
## Action RPC Protocol
|
|
89
|
+
|
|
90
|
+
The runtime protocol is a bidirectional action RPC protocol over stdio or WebSocket. It is implemented by `runtime/io/handler.py` and data models under `entities/io/`.
|
|
91
|
+
|
|
92
|
+
Request shape:
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{ "seq_id": 1, "action": "action_name", "data": {} }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Response shape:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{ "seq_id": 1, "code": 0, "message": "success", "data": {}, "chunk_status": "continue" }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Core mechanics:
|
|
105
|
+
|
|
106
|
+
- `seq_id` correlates responses to requests.
|
|
107
|
+
- Messages with `action` are requests; messages with `code` are responses.
|
|
108
|
+
- Each peer may initiate requests on the same connection.
|
|
109
|
+
- `Handler.call_action()` waits for one response.
|
|
110
|
+
- `Handler.call_action_generator()` consumes streamed responses.
|
|
111
|
+
- Streaming emits `chunk_status: "continue"` chunks and ends with `"end"`.
|
|
112
|
+
- File transfer uses `CommonAction.FILE_CHUNK` with 16KB base64 chunks stored under `data/temp/lbp/`.
|
|
113
|
+
|
|
114
|
+
Action enums are the protocol contract:
|
|
115
|
+
|
|
116
|
+
- `CommonAction`
|
|
117
|
+
- `PluginToRuntimeAction`
|
|
118
|
+
- `RuntimeToPluginAction`
|
|
119
|
+
- `LangBotToRuntimeAction`
|
|
120
|
+
- `RuntimeToLangBotAction`
|
|
121
|
+
- `LangBotToBoxAction`
|
|
122
|
+
|
|
123
|
+
Do not duplicate action strings outside these enums.
|
|
124
|
+
|
|
125
|
+
## Plugin Runtime
|
|
126
|
+
|
|
127
|
+
`lbp rt` enters `runtime/app.py::main()` and builds `RuntimeApplication`.
|
|
128
|
+
|
|
129
|
+
Runtime graph:
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
LangBot PluginRuntimeConnector
|
|
133
|
+
↔ control connection
|
|
134
|
+
↔ RuntimeApplication
|
|
135
|
+
→ PluginManager
|
|
136
|
+
→ PluginContainer(s)
|
|
137
|
+
↔ PluginConnectionHandler(s)
|
|
138
|
+
↔ plugin process(es)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Important modules:
|
|
142
|
+
|
|
143
|
+
- `runtime/app.py`: selects stdio vs WebSocket control transport, starts control/debug servers, launches plugin manager tasks.
|
|
144
|
+
- `runtime/context.py`: shared runtime context object.
|
|
145
|
+
- `runtime/settings.py`: runtime settings, including marketplace/cloud URL.
|
|
146
|
+
- `runtime/plugin/mgr.py`: plugin discovery, installation, dependency checks, launch, shutdown, event/tool/command/RAG/page dispatch.
|
|
147
|
+
- `runtime/plugin/container.py`: loaded plugin package, manifest, component containers, status.
|
|
148
|
+
- `runtime/io/handlers/control.py`: actions LangBot calls on the Runtime.
|
|
149
|
+
- `runtime/io/handlers/plugin.py`: actions the Runtime calls on plugin processes.
|
|
150
|
+
- `runtime/io/controllers/`: stdio/WebSocket server and client controllers.
|
|
151
|
+
- `runtime/io/connections/`: transport-specific connection implementations.
|
|
152
|
+
|
|
153
|
+
The Runtime has two external channels:
|
|
154
|
+
|
|
155
|
+
- **control channel**: LangBot ↔ Runtime, stdio or `:5400/control/ws` by default.
|
|
156
|
+
- **debug channel**: plugin dev process ↔ Runtime, WebSocket `:5401/plugin/debug/ws` by default.
|
|
157
|
+
|
|
158
|
+
Installed plugins are stored under `data/plugins/{author}__{name}`. Runtime plugin processes normally run as separate Python processes and connect back via stdio or debug WebSocket.
|
|
159
|
+
|
|
160
|
+
## Box Runtime
|
|
161
|
+
|
|
162
|
+
`lbp box` enters `box/server.py::main()` and serves `BoxRuntime` through action RPC.
|
|
163
|
+
|
|
164
|
+
Box graph:
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
LangBot BoxService
|
|
168
|
+
↔ BoxRuntimeConnector
|
|
169
|
+
↔ BoxServerHandler
|
|
170
|
+
→ BoxRuntime
|
|
171
|
+
→ Backend session(s)
|
|
172
|
+
→ Docker/Podman, nsjail, or E2B sandbox
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Important modules:
|
|
176
|
+
|
|
177
|
+
- `box/server.py`: CLI entrypoint, aiohttp WebSocket routes, `BoxServerHandler` action registration.
|
|
178
|
+
- `box/runtime.py`: session lifecycle, per-session locks, TTL cleanup, command execution, managed processes.
|
|
179
|
+
- `box/models.py`: `BoxSpec`, execution results, managed-process specs.
|
|
180
|
+
- `box/client.py`: action-RPC client used by LangBot-side connector/service.
|
|
181
|
+
- `box/actions.py`: `LangBotToBoxAction` enum.
|
|
182
|
+
- `box/backend.py`: backend abstraction and local backend selection.
|
|
183
|
+
- `box/nsjail_backend.py`: nsjail backend.
|
|
184
|
+
- `box/e2b_backend.py`: E2B backend.
|
|
185
|
+
- `box/skill_store.py`: Box-owned skill package CRUD and install/preview helpers.
|
|
186
|
+
- `box/security.py`: path/security helper logic.
|
|
187
|
+
|
|
188
|
+
Default Box WebSocket endpoints on port `5410`:
|
|
189
|
+
|
|
190
|
+
- `/rpc/ws`: action RPC control channel.
|
|
191
|
+
- `/v1/sessions/{session_id}/managed-process/ws`: legacy default process stdio relay.
|
|
192
|
+
- `/v1/sessions/{session_id}/managed-process/{process_id}/ws`: named process stdio relay.
|
|
193
|
+
|
|
194
|
+
There is no supported `python -m langbot_plugin.box` entrypoint; use `lbp box`.
|
|
195
|
+
|
|
196
|
+
## Backend Selection
|
|
197
|
+
|
|
198
|
+
Box can execute through multiple sandbox backends:
|
|
199
|
+
|
|
200
|
+
- Docker/Podman through the local CLI backend path.
|
|
201
|
+
- nsjail for local Linux sandboxing.
|
|
202
|
+
- E2B for remote cloud sandboxes.
|
|
203
|
+
|
|
204
|
+
LangBot sends Box config during initialization. Backend selection is controlled by LangBot's `box.backend` config (`local`, `docker`, `nsjail`, `e2b`) and the Box runtime's backend availability probes.
|
|
205
|
+
|
|
206
|
+
A false “no backend” often means Docker exists but the user cannot access the Docker socket. nsjail inside containers requires host cgroup namespace for cgroup v2 limits if hard memory/pid/cpu enforcement is expected.
|
|
207
|
+
|
|
208
|
+
## Cross-Repo Development Flow
|
|
209
|
+
|
|
210
|
+
When changing shared contracts:
|
|
211
|
+
|
|
212
|
+
1. Change this SDK repo first or in the same branch set.
|
|
213
|
+
2. Install the local SDK into LangBot's virtualenv: `uv pip install .` from this repo while LangBot's `.venv` is active.
|
|
214
|
+
3. Run LangBot with `uv run --no-sync ...` so `uv` does not replace the local SDK with the pinned PyPI package.
|
|
215
|
+
4. Exercise the exact path changed: plugin stdio, plugin WebSocket, `lbp run`, `lbp rt`, `lbp box`, Box WebSocket, or Box stdio.
|
|
216
|
+
|
|
217
|
+
The SDK `AGENTS.md` keeps the short command checklist; this file keeps the structural map.
|
|
218
|
+
|
|
219
|
+
## Design Biases
|
|
220
|
+
|
|
221
|
+
- Keep plugin-author SDK APIs stable and explicit.
|
|
222
|
+
- Treat action enums and Pydantic models as cross-process API contracts.
|
|
223
|
+
- Keep runtime process management separate from LangBot product logic.
|
|
224
|
+
- Keep Box sandbox semantics in `box/`; LangBot should call Box through the service/client protocol.
|
|
225
|
+
- Prefer tests around protocol shape and black-box CLI behavior when changing runtime boundaries.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langbot-plugin
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.7
|
|
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
|
|
@@ -39,13 +39,34 @@
|
|
|
39
39
|
### Request
|
|
40
40
|
|
|
41
41
|
```json
|
|
42
|
+
{
|
|
43
|
+
"event_context": {},
|
|
44
|
+
"include_plugins": ["author/name"]
|
|
45
|
+
}
|
|
42
46
|
```
|
|
43
47
|
|
|
44
48
|
### Response
|
|
45
49
|
|
|
46
50
|
```json
|
|
51
|
+
{
|
|
52
|
+
"emitted_plugins": [],
|
|
53
|
+
"response_sources": [
|
|
54
|
+
{
|
|
55
|
+
"kind": "reply_message_chain",
|
|
56
|
+
"plugin": {
|
|
57
|
+
"author": "plugin_author",
|
|
58
|
+
"name": "plugin_name"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"event_context": {}
|
|
63
|
+
}
|
|
47
64
|
```
|
|
48
65
|
|
|
66
|
+
`emitted_plugins` contains plugins whose event handlers ran. `response_sources`
|
|
67
|
+
contains plugins that changed a deferred response field on the event context, such
|
|
68
|
+
as `reply_message_chain`.
|
|
69
|
+
|
|
49
70
|
## `list_tools`
|
|
50
71
|
|
|
51
72
|
### Request
|
|
@@ -68,4 +89,4 @@
|
|
|
68
89
|
### Response
|
|
69
90
|
|
|
70
91
|
```json
|
|
71
|
-
```
|
|
92
|
+
```
|
|
@@ -5,6 +5,7 @@ import asyncio
|
|
|
5
5
|
import dataclasses
|
|
6
6
|
import datetime as dt
|
|
7
7
|
import logging
|
|
8
|
+
import os
|
|
8
9
|
import re
|
|
9
10
|
import shlex
|
|
10
11
|
import shutil
|
|
@@ -26,6 +27,7 @@ from .security import validate_sandbox_security
|
|
|
26
27
|
# produce large output within the time limit. After this many bytes the
|
|
27
28
|
# remaining output is discarded before decoding.
|
|
28
29
|
_MAX_RAW_OUTPUT_BYTES = 1_048_576 # 1 MB per stream
|
|
30
|
+
_FALSE_VALUES = {"0", "false"}
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
@dataclasses.dataclass(slots=True)
|
|
@@ -80,6 +82,7 @@ class CLISandboxBackend(BaseSandboxBackend):
|
|
|
80
82
|
super().__init__(logger)
|
|
81
83
|
self.command = command
|
|
82
84
|
self.name = backend_name
|
|
85
|
+
self.cpu_limit_enabled = True
|
|
83
86
|
|
|
84
87
|
async def is_available(self) -> bool:
|
|
85
88
|
if shutil.which(self.command) is None:
|
|
@@ -121,16 +124,14 @@ class CLISandboxBackend(BaseSandboxBackend):
|
|
|
121
124
|
if spec.network == BoxNetworkMode.OFF:
|
|
122
125
|
args.extend(["--network", "none"])
|
|
123
126
|
|
|
124
|
-
|
|
125
|
-
args.extend(["--cpus", str(spec.cpus)])
|
|
126
|
-
args.extend(["--memory", f"{spec.memory_mb}m"])
|
|
127
|
-
args.extend(["--pids-limit", str(spec.pids_limit)])
|
|
127
|
+
args.extend(self._build_resource_limit_args(spec))
|
|
128
128
|
|
|
129
129
|
if spec.read_only_rootfs:
|
|
130
130
|
args.append("--read-only")
|
|
131
131
|
args.extend(["--tmpfs", "/tmp:size=64m"])
|
|
132
132
|
|
|
133
133
|
if spec.host_path is not None and spec.host_path_mode != BoxHostMountMode.NONE:
|
|
134
|
+
os.makedirs(spec.host_path, exist_ok=True)
|
|
134
135
|
mount_spec = (
|
|
135
136
|
f"{spec.host_path}:{spec.mount_path}:{spec.host_path_mode.value}"
|
|
136
137
|
)
|
|
@@ -149,7 +150,8 @@ class CLISandboxBackend(BaseSandboxBackend):
|
|
|
149
150
|
f"session_id={spec.session_id} container_name={container_name} "
|
|
150
151
|
f"image={spec.image} network={spec.network.value} "
|
|
151
152
|
f"host_path={spec.host_path} host_path_mode={spec.host_path_mode.value} mount_path={spec.mount_path} "
|
|
152
|
-
f"cpus={spec.cpus}
|
|
153
|
+
f"cpus={spec.cpus} cpu_limit_enabled={self.cpu_limit_enabled} "
|
|
154
|
+
f"memory_mb={spec.memory_mb} pids_limit={spec.pids_limit} "
|
|
153
155
|
f"read_only_rootfs={spec.read_only_rootfs} workspace_quota_mb={spec.workspace_quota_mb}"
|
|
154
156
|
)
|
|
155
157
|
|
|
@@ -333,6 +335,14 @@ class CLISandboxBackend(BaseSandboxBackend):
|
|
|
333
335
|
suffix = uuid.uuid4().hex[:8]
|
|
334
336
|
return f"langbot-box-{normalized[:32]}-{suffix}"
|
|
335
337
|
|
|
338
|
+
def _build_resource_limit_args(self, spec: BoxSpec) -> list[str]:
|
|
339
|
+
args: list[str] = []
|
|
340
|
+
if self.cpu_limit_enabled:
|
|
341
|
+
args.extend(["--cpus", str(spec.cpus)])
|
|
342
|
+
args.extend(["--memory", f"{spec.memory_mb}m"])
|
|
343
|
+
args.extend(["--pids-limit", str(spec.pids_limit)])
|
|
344
|
+
return args
|
|
345
|
+
|
|
336
346
|
def _build_exec_command(self, workdir: str, cmd: str) -> str:
|
|
337
347
|
quoted_workdir = shlex.quote(workdir)
|
|
338
348
|
return f"mkdir -p {quoted_workdir} && cd {quoted_workdir} && {cmd}"
|
|
@@ -430,3 +440,16 @@ class CLISandboxBackend(BaseSandboxBackend):
|
|
|
430
440
|
class DockerBackend(CLISandboxBackend):
|
|
431
441
|
def __init__(self, logger: logging.Logger):
|
|
432
442
|
super().__init__(logger=logger, command="docker", backend_name="docker")
|
|
443
|
+
|
|
444
|
+
def configure(self, config: dict) -> None:
|
|
445
|
+
raw_value = config.get("cpu_limit_enabled", True)
|
|
446
|
+
if isinstance(raw_value, bool):
|
|
447
|
+
enabled = raw_value
|
|
448
|
+
else:
|
|
449
|
+
enabled = str(raw_value).strip().lower() not in _FALSE_VALUES
|
|
450
|
+
self.cpu_limit_enabled = enabled
|
|
451
|
+
if not enabled:
|
|
452
|
+
self.logger.warning(
|
|
453
|
+
"Docker sandbox CPU limit is disabled by config "
|
|
454
|
+
"(box.docker.cpu_limit_enabled=false); containers will be started without --cpus."
|
|
455
|
+
)
|