langbot-plugin 0.7.12__tar.gz → 0.7.13__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.
Files changed (393) hide show
  1. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/ARCHITECTURE.md +35 -6
  2. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/PKG-INFO +1 -1
  3. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/pyproject.toml +1 -1
  4. langbot_plugin-0.7.13/src/langbot_plugin/artifact.py +245 -0
  5. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/actions.py +0 -11
  6. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/backend.py +63 -4
  7. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/client.py +0 -227
  8. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/e2b_backend.py +370 -20
  9. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/host_backend.py +16 -1
  10. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/models.py +53 -19
  11. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/nsjail_backend.py +7 -6
  12. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/runtime.py +117 -46
  13. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/server.py +4 -145
  14. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/tenancy.py +4 -8
  15. langbot_plugin-0.7.13/src/langbot_plugin/skill_store.py +1640 -0
  16. langbot_plugin-0.7.13/src/langbot_plugin/version.py +1 -0
  17. langbot_plugin-0.7.13/src/langbot_plugin/workspace.py +19 -0
  18. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_admission.py +62 -22
  19. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_backend.py +36 -1
  20. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_client.py +0 -180
  21. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_e2b_backend.py +334 -0
  22. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_nsjail_backend.py +1 -1
  23. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_runtime.py +113 -1
  24. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_server.py +14 -295
  25. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_skill_store.py +139 -136
  26. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_storage_analysis.py +3 -4
  27. langbot_plugin-0.7.13/tests/e2e/test_run_mount_isolation.py +117 -0
  28. langbot_plugin-0.7.13/tests/test_artifact_materialization.py +77 -0
  29. langbot_plugin-0.7.13/tests/test_skill_store.py +300 -0
  30. langbot_plugin-0.7.12/src/langbot_plugin/box/skill_store.py +0 -1015
  31. langbot_plugin-0.7.12/src/langbot_plugin/version.py +0 -1
  32. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/.github/workflows/cla.yml +0 -0
  33. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/.github/workflows/publish-pypi.yaml +0 -0
  34. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/.github/workflows/publish.yml +0 -0
  35. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/.github/workflows/test.yml +0 -0
  36. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/.gitignore +0 -0
  37. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/.python-version +0 -0
  38. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/AGENTS.md +0 -0
  39. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/CLAUDE.md +0 -0
  40. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/CONTRIBUTING.md +0 -0
  41. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/LICENSE +0 -0
  42. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/README.md +0 -0
  43. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/README_CN.md +0 -0
  44. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/data/.env.example +0 -0
  45. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/Message.md +0 -0
  46. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/PluginPages.md +0 -0
  47. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/agent-runner-interactions.md +0 -0
  48. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/agent-runner-pluginization/PROTOCOL_V1.md +0 -0
  49. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/agent-runner-pluginization/README.md +0 -0
  50. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/agent-runner-pluginization/SDK_RUNTIME_PLAN.md +0 -0
  51. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/certified-plugins.md +0 -0
  52. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/communication/apis/lb2rt.md +0 -0
  53. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/communication/runtime_plugin.md +0 -0
  54. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/dependency-management.md +0 -0
  55. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/langbot-plugin-social.png +0 -0
  56. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/runner.md +0 -0
  57. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/docs/stateless-components.md +0 -0
  58. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/local_e2e/acceptance.json +0 -0
  59. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/local_e2e/registration_fanin.py +0 -0
  60. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/local_e2e/run_acceptance.py +0 -0
  61. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/mypy.ini +0 -0
  62. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/scripts/check_action_consistency.py +0 -0
  63. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/scripts/runtime_resource_probe.py +0 -0
  64. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/__init__.py +0 -0
  65. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/__init__.py +0 -0
  66. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/__init__.py +0 -0
  67. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/asset_gateway.py +0 -0
  68. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/daemon.py +0 -0
  69. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/decorators.py +0 -0
  70. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/external_tools.py +0 -0
  71. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/mcp_access.py +0 -0
  72. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/mcp_bridge.py +0 -0
  73. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/mcp_config.py +0 -0
  74. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/mcp_protocol.py +0 -0
  75. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/agent_tools/mcp_stdio.py +0 -0
  76. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/__init__.py +0 -0
  77. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/abstract/__init__.py +0 -0
  78. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/abstract/platform/__init__.py +0 -0
  79. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/abstract/platform/adapter.py +0 -0
  80. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/abstract/platform/event_logger.py +0 -0
  81. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/__init__.py +0 -0
  82. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/base.py +0 -0
  83. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/command/__init__.py +0 -0
  84. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/command/command.py +0 -0
  85. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/common/__init__.py +0 -0
  86. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/common/event_listener.py +0 -0
  87. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/knowledge_engine/__init__.py +0 -0
  88. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/knowledge_engine/engine.py +0 -0
  89. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/manifest.py +0 -0
  90. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/page/__init__.py +0 -0
  91. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/parser/__init__.py +0 -0
  92. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/parser/parser.py +0 -0
  93. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/runner/__init__.py +0 -0
  94. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/runner/runner.py +0 -0
  95. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/tool/__init__.py +0 -0
  96. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/components/tool/tool.py +0 -0
  97. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/definition/plugin.py +0 -0
  98. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/__init__.py +0 -0
  99. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/__init__.py +0 -0
  100. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/command/__init__.py +0 -0
  101. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/command/context.py +0 -0
  102. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/command/errors.py +0 -0
  103. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/pipeline/__init__.py +0 -0
  104. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/pipeline/query.py +0 -0
  105. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/platform/__init__.py +0 -0
  106. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/platform/entities.py +0 -0
  107. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/platform/errors.py +0 -0
  108. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/platform/events.py +0 -0
  109. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/platform/logger.py +0 -0
  110. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/platform/message.py +0 -0
  111. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/provider/__init__.py +0 -0
  112. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/provider/message.py +0 -0
  113. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/provider/prompt.py +0 -0
  114. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/provider/reasoning.py +0 -0
  115. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/provider/session.py +0 -0
  116. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/rag/__init__.py +0 -0
  117. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/rag/context.py +0 -0
  118. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/rag/enums.py +0 -0
  119. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/rag/errors.py +0 -0
  120. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/rag/models.py +0 -0
  121. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/resource/__init__.py +0 -0
  122. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/resource/tool.py +0 -0
  123. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/__init__.py +0 -0
  124. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/box.py +0 -0
  125. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/capabilities.py +0 -0
  126. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/compat.py +0 -0
  127. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/context.py +0 -0
  128. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/context_access.py +0 -0
  129. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/delivery.py +0 -0
  130. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/errors.py +0 -0
  131. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/event.py +0 -0
  132. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/input.py +0 -0
  133. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/interaction.py +0 -0
  134. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/manifest.py +0 -0
  135. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/page_results.py +0 -0
  136. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/permissions.py +0 -0
  137. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/resources.py +0 -0
  138. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/result.py +0 -0
  139. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/run_ledger.py +0 -0
  140. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/runtime.py +0 -0
  141. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/runtime_registry.py +0 -0
  142. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/state.py +0 -0
  143. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/stats.py +0 -0
  144. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/steering.py +0 -0
  145. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/transcript.py +0 -0
  146. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/builtin/runner/trigger.py +0 -0
  147. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/context.py +0 -0
  148. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/events.py +0 -0
  149. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/entities/execution.py +0 -0
  150. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/__init__.py +0 -0
  151. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/base.py +0 -0
  152. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/event_context.py +0 -0
  153. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/execute_context.py +0 -0
  154. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/invocation.py +0 -0
  155. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/langbot_api.py +0 -0
  156. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/query_based_api.py +0 -0
  157. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/__init__.py +0 -0
  158. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/admin.py +0 -0
  159. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/api.py +0 -0
  160. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/box.py +0 -0
  161. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/common.py +0 -0
  162. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/context.py +0 -0
  163. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/ledger.py +0 -0
  164. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/platform.py +0 -0
  165. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/reply_stream.py +0 -0
  166. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/resources.py +0 -0
  167. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/state.py +0 -0
  168. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/api/proxies/runner/tracing.py +0 -0
  169. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/__init__.py +0 -0
  170. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/langbot-page-sdk.js +0 -0
  171. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/.env.example.example +0 -0
  172. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/.github/workflows/release.yml.example +0 -0
  173. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/.gitignore.example +0 -0
  174. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/.vscode/launch.json.example +0 -0
  175. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/README.md.example +0 -0
  176. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/__init__.py +0 -0
  177. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/assets/icon.svg.example +0 -0
  178. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/__init__.py +0 -0
  179. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/commands/__init__.py +0 -0
  180. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.py.example +0 -0
  181. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.yaml.example +0 -0
  182. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/event_listener/__init__.py +0 -0
  183. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/event_listener/default.py.example +0 -0
  184. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/event_listener/default.yaml.example +0 -0
  185. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/knowledge_engine/__init__.py +0 -0
  186. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.py.example +0 -0
  187. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.yaml.example +0 -0
  188. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/pages/{page_name}.html.example +0 -0
  189. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/pages/{page_name}.yaml.example +0 -0
  190. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/parser/__init__.py +0 -0
  191. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.py.example +0 -0
  192. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.yaml.example +0 -0
  193. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/runner/__init__.py +0 -0
  194. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/runner/{runner_name}.py.example +0 -0
  195. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/runner/{runner_name}.yaml.example +0 -0
  196. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/tools/__init__.py +0 -0
  197. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.py.example +0 -0
  198. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.yaml.example +0 -0
  199. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/main.py.example +0 -0
  200. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/manifest.yaml.example +0 -0
  201. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/readme/README_zh_Hans.md.example +0 -0
  202. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/assets/templates/requirements.txt.example +0 -0
  203. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/__init__.py +0 -0
  204. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/errors.py +0 -0
  205. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/box/security.py +0 -0
  206. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/certification.py +0 -0
  207. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/__init__.py +0 -0
  208. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/__main__.py +0 -0
  209. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/commands/__init__.py +0 -0
  210. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/commands/buildplugin.py +0 -0
  211. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/commands/gencomponent.py +0 -0
  212. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/commands/initplugin.py +0 -0
  213. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/commands/login.py +0 -0
  214. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/commands/logout.py +0 -0
  215. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/commands/publish.py +0 -0
  216. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/commands/runplugin.py +0 -0
  217. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/gen/__init__.py +0 -0
  218. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/gen/renderer.py +0 -0
  219. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/i18n.py +0 -0
  220. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/locales/__init__.py +0 -0
  221. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/locales/en_US.py +0 -0
  222. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/locales/es_ES.py +0 -0
  223. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/locales/ja_JP.py +0 -0
  224. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/locales/th_TH.py +0 -0
  225. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/locales/vi_VN.py +0 -0
  226. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/locales/zh_Hans.py +0 -0
  227. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/locales/zh_Hant.py +0 -0
  228. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/run/__init__.py +0 -0
  229. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/run/controller.py +0 -0
  230. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/run/handler.py +0 -0
  231. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/run/hotreload.py +0 -0
  232. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/utils/__init__.py +0 -0
  233. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/utils/cloudsv.py +0 -0
  234. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/utils/form.py +0 -0
  235. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/cli/utils/page_components.py +0 -0
  236. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/entities/__init__.py +0 -0
  237. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/entities/io/__init__.py +0 -0
  238. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/entities/io/actions/__init__.py +0 -0
  239. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/entities/io/actions/enums.py +0 -0
  240. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/entities/io/context.py +0 -0
  241. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/entities/io/errors.py +0 -0
  242. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/entities/io/req.py +0 -0
  243. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/entities/io/resp.py +0 -0
  244. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/entities/marketplace.py +0 -0
  245. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/LICENSE +0 -0
  246. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/README.md +0 -0
  247. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/__init__.py +0 -0
  248. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/app.py +0 -0
  249. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/bounded_executor.py +0 -0
  250. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/context.py +0 -0
  251. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/event_loop_monitor.py +0 -0
  252. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/helper/__init__.py +0 -0
  253. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/helper/marketplace.py +0 -0
  254. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/helper/pkgmgr.py +0 -0
  255. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/__init__.py +0 -0
  256. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/connection.py +0 -0
  257. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/connections/__init__.py +0 -0
  258. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/connections/stdio.py +0 -0
  259. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/connections/ws.py +0 -0
  260. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/controller.py +0 -0
  261. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/controllers/__init__.py +0 -0
  262. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/controllers/stdio/__init__.py +0 -0
  263. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/controllers/stdio/client.py +0 -0
  264. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/controllers/stdio/server.py +0 -0
  265. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/controllers/ws/__init__.py +0 -0
  266. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/controllers/ws/client.py +0 -0
  267. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/controllers/ws/server.py +0 -0
  268. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/handler.py +0 -0
  269. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/handlers/__init__.py +0 -0
  270. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/handlers/control.py +0 -0
  271. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/io/handlers/plugin.py +0 -0
  272. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/ops_metrics.py +0 -0
  273. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/__init__.py +0 -0
  274. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/artifact.py +0 -0
  275. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/container.py +0 -0
  276. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/dependency_environment.py +0 -0
  277. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/logbuffer.py +0 -0
  278. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/mgr.py +0 -0
  279. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/restart_coordinator.py +0 -0
  280. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/runner_service.py +0 -0
  281. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/worker_launcher.py +0 -0
  282. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/worker_observability.py +0 -0
  283. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/plugin/worker_watchdog.py +0 -0
  284. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/security.py +0 -0
  285. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/runtime/settings.py +0 -0
  286. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/storage.py +0 -0
  287. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/utils/__init__.py +0 -0
  288. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/utils/deadline.py +0 -0
  289. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/utils/discover/__init__.py +0 -0
  290. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/utils/discover/engine.py +0 -0
  291. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/utils/importutil.py +0 -0
  292. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/utils/log.py +0 -0
  293. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/src/langbot_plugin/utils/platform.py +0 -0
  294. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/__init__.py +0 -0
  295. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/definition/components/test_components.py +0 -0
  296. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/definition/components/test_imports.py +0 -0
  297. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/definition/test_manifest.py +0 -0
  298. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/builtin/runner/test_context_result.py +0 -0
  299. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/builtin/runner/test_history_event_entities.py +0 -0
  300. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/builtin/runner/test_interaction.py +0 -0
  301. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/builtin/runner/test_run_ledger_entities.py +0 -0
  302. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/builtin/test_command_context.py +0 -0
  303. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/builtin/test_platform_logger.py +0 -0
  304. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/builtin/test_provider_message.py +0 -0
  305. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/builtin/test_rag_models.py +0 -0
  306. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/test_context.py +0 -0
  307. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/entities/test_events.py +0 -0
  308. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/proxies/__init__.py +0 -0
  309. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/proxies/test_agent_run_api_proxy.py +0 -0
  310. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/proxies/test_base.py +0 -0
  311. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/proxies/test_box_api.py +0 -0
  312. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/proxies/test_history_event_api_proxy.py +0 -0
  313. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/proxies/test_langbot_api.py +0 -0
  314. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/proxies/test_llm_stream_ownership.py +0 -0
  315. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/proxies/test_query_based_api.py +0 -0
  316. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/proxies/test_reasoning_parameter.py +0 -0
  317. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/test_agent_tools_mcp_bridge.py +0 -0
  318. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/test_runner_handlers.py +0 -0
  319. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/test_runner_handlers_matrix.py +0 -0
  320. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/api/test_runner_public_apis.py +0 -0
  321. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/__init__.py +0 -0
  322. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_backend_selection.py +0 -0
  323. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/box/test_host_backend.py +0 -0
  324. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/run/test_controller.py +0 -0
  325. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/run/test_hotreload.py +0 -0
  326. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/run/test_runtime_handler.py +0 -0
  327. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_buildplugin.py +0 -0
  328. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_gencomponent.py +0 -0
  329. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_i18n_form.py +0 -0
  330. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_initplugin.py +0 -0
  331. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_login.py +0 -0
  332. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_logout_publish.py +0 -0
  333. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_page_components.py +0 -0
  334. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_renderer.py +0 -0
  335. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_runner_usages.py +0 -0
  336. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/cli/test_runplugin.py +0 -0
  337. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/e2e/standalone_runtime_eba_probe.py +0 -0
  338. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/entities/io/test_dependency_errors.py +0 -0
  339. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/entities/io/test_protocol.py +0 -0
  340. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/fixtures/eba_event_probe_plugin/.gitignore +0 -0
  341. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/fixtures/eba_event_probe_plugin/assets/icon.svg +0 -0
  342. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/fixtures/eba_event_probe_plugin/components/event_listener/default.py +0 -0
  343. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/fixtures/eba_event_probe_plugin/components/event_listener/default.yaml +0 -0
  344. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/fixtures/eba_event_probe_plugin/main.py +0 -0
  345. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/fixtures/eba_event_probe_plugin/manifest.yaml +0 -0
  346. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/helpers/__init__.py +0 -0
  347. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/helpers/protocol.py +0 -0
  348. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/packaging/test_installed_cli_blackbox.py +0 -0
  349. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/packaging/test_release_metadata.py +0 -0
  350. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/helper/test_marketplace.py +0 -0
  351. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/helper/test_pkgmgr.py +0 -0
  352. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/handlers/test_control_handler.py +0 -0
  353. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/handlers/test_import_contracts.py +0 -0
  354. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/handlers/test_legacy_file_chunk.py +0 -0
  355. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/handlers/test_plugin_handler.py +0 -0
  356. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/test_action_consistency.py +0 -0
  357. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/test_connections.py +0 -0
  358. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/test_controllers.py +0 -0
  359. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/test_handler.py +0 -0
  360. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/test_heartbeat_admission.py +0 -0
  361. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/test_stdio_server.py +0 -0
  362. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/io/test_stream_flow_control.py +0 -0
  363. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_artifact_store.py +0 -0
  364. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_container.py +0 -0
  365. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_dependency_environment.py +0 -0
  366. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_exact_dify_real_worker.py +0 -0
  367. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_exact_legacy_sdk_compat.py +0 -0
  368. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_installation_manager.py +0 -0
  369. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_legacy_shadow.py +0 -0
  370. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_manager.py +0 -0
  371. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_mgr_runner.py +0 -0
  372. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_mode_resource_limits.py +0 -0
  373. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_restart_coordinator.py +0 -0
  374. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_shared_worker_subprocess.py +0 -0
  375. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_worker_launcher.py +0 -0
  376. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_worker_plugin_identity.py +0 -0
  377. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/plugin/test_workload_isolation.py +0 -0
  378. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/test_app.py +0 -0
  379. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/test_bounded_executor.py +0 -0
  380. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/test_event_loop_monitor.py +0 -0
  381. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/test_ops_metrics.py +0 -0
  382. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/runtime/test_pull_api_handlers.py +0 -0
  383. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/test_certification.py +0 -0
  384. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/test_log.py +0 -0
  385. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/test_message.py +0 -0
  386. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/test_plugin_logbuffer.py +0 -0
  387. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/test_storage.py +0 -0
  388. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/test_worker_observability.py +0 -0
  389. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/test_worker_watchdog.py +0 -0
  390. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/utils/test_deadline.py +0 -0
  391. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/utils/test_discovery.py +0 -0
  392. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/utils/test_importutil.py +0 -0
  393. {langbot_plugin-0.7.12 → langbot_plugin-0.7.13}/tests/utils/test_platform.py +0 -0
@@ -20,7 +20,7 @@ The runtime code under `src/langbot_plugin/runtime/` is AGPL; the rest of the re
20
20
  This repo is coupled to LangBot but owns different things.
21
21
 
22
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.
23
+ - This SDK repo owns plugin author APIs, shared message/event/context entities, the action RPC protocol, the execution-independent filesystem Skill store, `lbp`, Plugin Runtime implementation, and Box Runtime implementation.
24
24
  - Plugins import this package directly; LangBot also imports it for shared entities and runtime protocols.
25
25
 
26
26
  If a change alters shared entities, component contracts, action names/payloads, runtime behavior, or Box models, update/test both repos in lockstep.
@@ -37,6 +37,8 @@ langbot-plugin-sdk/
37
37
  │ ├── cli/ # `lbp` entrypoint and subcommands
38
38
  │ ├── runtime/ # Plugin Runtime (`lbp rt`)
39
39
  │ ├── box/ # Box Runtime (`lbp box`)
40
+ │ ├── skill_store.py # Execution-independent Skill package storage
41
+ │ ├── workspace.py # Neutral Workspace namespace identity
40
42
  │ ├── entities/io/ # Action RPC request/response/error/action models
41
43
  │ ├── assets/ # Scaffolding templates and page SDK asset
42
44
  │ └── utils/
@@ -420,7 +422,7 @@ Important modules:
420
422
 
421
423
  - `box/server.py`: CLI entrypoint, aiohttp WebSocket routes, `BoxServerHandler` action registration.
422
424
  - `box/runtime.py`: session lifecycle, per-session locks, TTL cleanup, command execution, managed processes.
423
- - `box/models.py`: `BoxSpec`, execution results, managed-process specs.
425
+ - `box/models.py`: generic `BoxSpec`/read-only mount contracts, execution results, managed-process specs.
424
426
  - `box/client.py`: action-RPC client used by LangBot-side connector/service.
425
427
  - `box/actions.py`: `LangBotToBoxAction` enum.
426
428
  - `box/backend.py`: backend abstraction and local backend selection.
@@ -428,7 +430,7 @@ Important modules:
428
430
  trusted local development.
429
431
  - `box/nsjail_backend.py`: nsjail backend.
430
432
  - `box/e2b_backend.py`: E2B backend.
431
- - `box/skill_store.py`: Box-owned skill package CRUD and install/preview helpers.
433
+ - `skill_store.py`: generic Skill package CRUD, revision, and read-only resource helpers; it does not start or connect to Box.
432
434
  - `box/security.py`: path/security helper logic.
433
435
 
434
436
  Default Box WebSocket endpoints on port `5410`:
@@ -437,8 +439,34 @@ Default Box WebSocket endpoints on port `5410`:
437
439
  - `/v1/sessions/{session_id}/managed-process/ws`: legacy default process stdio relay.
438
440
  - `/v1/sessions/{session_id}/managed-process/{process_id}/ws`: named process stdio relay.
439
441
 
440
- Box keeps durable skill/storage paths in an `(instance, workspace)` namespace,
441
- while sandbox sessions and managed processes use an
442
+ The Skill store keeps an authoritative registry in an `(instance, workspace)`
443
+ namespace. Each successful publication validates a complete staging tree,
444
+ computes one `sha256-tree-v1` digest, atomically installs an immutable revision,
445
+ and only then advances the registry pointer. Updates require the current
446
+ `base_revision`; deletion removes the pointer while retaining revisions for
447
+ active or recoverable runs. Former mutable package directories are only a
448
+ one-time online-upgrade import source.
449
+
450
+ LangBot Core composes pinned revisions into generic read-only `BoxMountSpec`
451
+ values. Ordinary fixed mounts include `content_digest` and `manifest_path` in
452
+ the session signature; supported digest-addressed packages are excluded from it.
453
+ Digest-addressed packages use the reserved
454
+ `/opt/langbot-artifacts/<digest>` namespace. Docker/Podman pre-mount a read-only
455
+ cache and atomically populate verified revisions before execution. E2B seals and
456
+ verifies packages before publishing stable digest projections. These packages can
457
+ be added after a Box is acquired, without replacing the session. nsjail applies
458
+ all mounts independently per execution. Fixed ordinary host mounts still reject
459
+ incompatible reuse; a conflict never implicitly destroys the existing session.
460
+ The unsafe host development backend maps each execution's paths without claiming
461
+ filesystem isolation. Cached artifacts are shared within a Box, just like its
462
+ Workspace; version pinning is not isolation between commands sharing that Box. Box
463
+ has no Skill model, CRUD API, or `SKILL.md` knowledge in its normal path; it only
464
+ validates and mounts artifacts. Copy-based backends prepare a digest-specific
465
+ staging tree, verify the complete manifest, and publish it before projecting the
466
+ mount path, so partial transfers and removed-file residue cannot be executed.
467
+ Core and the Box Runtime SDK are upgraded in lockstep; Box deliberately rejects
468
+ retired Skill-aware payload fields instead of carrying a mixed-version bridge.
469
+ Sandbox sessions and managed processes use an
442
470
  `(instance, workspace, placement_generation)` namespace. Authenticated tenant
443
471
  RPCs advance a monotonic generation fence, cancel in-flight older RPCs, and
444
472
  retire older sessions. Managed-process relay handshakes carry Workspace and
@@ -484,5 +512,6 @@ The SDK `AGENTS.md` keeps the short command checklist; this file keeps the struc
484
512
  - Keep plugin-author SDK APIs stable and explicit.
485
513
  - Treat action enums and Pydantic models as cross-process API contracts.
486
514
  - Keep runtime process management separate from LangBot product logic.
487
- - Keep Box sandbox semantics in `box/`; LangBot should call Box through the service/client protocol.
515
+ - Keep Box limited to generic sandbox/session/mount semantics; Skill policy and
516
+ package orchestration belong to LangBot Core.
488
517
  - Prefer tests around protocol shape and black-box CLI behavior when changing runtime boundaries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: langbot-plugin
3
- Version: 0.7.12
3
+ Version: 0.7.13
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "langbot-plugin"
3
- version = "0.7.12"
3
+ version = "0.7.13"
4
4
  description = "This package contains the SDK, CLI for building plugins for LangBot, plus the runtime for hosting LangBot plugins"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -0,0 +1,245 @@
1
+ from __future__ import annotations
2
+
3
+ import hashlib
4
+ import json
5
+ import os
6
+ import posixpath
7
+ import stat
8
+ from collections.abc import Collection
9
+
10
+
11
+ TREE_MANIFEST_ALGORITHM = "sha256-tree-v1"
12
+ _MAX_MANIFEST_BYTES = 4 * 1024 * 1024
13
+
14
+
15
+ def validate_tree_manifest(
16
+ manifest: dict,
17
+ *,
18
+ max_files: int,
19
+ max_total_bytes: int,
20
+ subject: str = "Artifact",
21
+ ) -> tuple[str, dict]:
22
+ """Validate a persisted manifest and return its canonical digest."""
23
+
24
+ if not isinstance(manifest, dict) or set(manifest) != {
25
+ "algorithm",
26
+ "files",
27
+ "total_bytes",
28
+ }:
29
+ raise ValueError(f"{subject} manifest has an invalid shape")
30
+ if manifest["algorithm"] != TREE_MANIFEST_ALGORITHM:
31
+ raise ValueError(f"{subject} manifest uses an unsupported algorithm")
32
+ files = manifest["files"]
33
+ if not isinstance(files, list) or len(files) > max_files:
34
+ raise ValueError(f"{subject} manifest contains too many files")
35
+ seen: set[str] = set()
36
+ calculated_total = 0
37
+ for entry in files:
38
+ if not isinstance(entry, dict) or set(entry) != {
39
+ "path",
40
+ "size",
41
+ "sha256",
42
+ "executable",
43
+ }:
44
+ raise ValueError(f"{subject} manifest contains an invalid file entry")
45
+ path = entry["path"]
46
+ if (
47
+ not isinstance(path, str)
48
+ or not path
49
+ or "\0" in path
50
+ or "\\" in path
51
+ or posixpath.isabs(path)
52
+ or posixpath.normpath(path) != path
53
+ or path in {".", ".."}
54
+ or path.startswith("../")
55
+ or path in seen
56
+ ):
57
+ raise ValueError(f"{subject} manifest contains an unsafe path")
58
+ seen.add(path)
59
+ size = entry["size"]
60
+ if isinstance(size, bool) or not isinstance(size, int) or size < 0:
61
+ raise ValueError(f"{subject} manifest contains an invalid file size")
62
+ calculated_total += size
63
+ digest = entry["sha256"]
64
+ if (
65
+ not isinstance(digest, str)
66
+ or len(digest) != 64
67
+ or any(ch not in "0123456789abcdef" for ch in digest)
68
+ ):
69
+ raise ValueError(f"{subject} manifest contains an invalid file digest")
70
+ if not isinstance(entry["executable"], bool):
71
+ raise ValueError(f"{subject} manifest contains an invalid file mode")
72
+
73
+ declared_total = manifest["total_bytes"]
74
+ if (
75
+ isinstance(declared_total, bool)
76
+ or not isinstance(declared_total, int)
77
+ or declared_total != calculated_total
78
+ or declared_total > max_total_bytes
79
+ ):
80
+ raise ValueError(f"{subject} manifest contains an invalid total size")
81
+ canonical = json.dumps(
82
+ manifest,
83
+ ensure_ascii=False,
84
+ separators=(",", ":"),
85
+ sort_keys=True,
86
+ ).encode("utf-8")
87
+ return f"sha256:{hashlib.sha256(canonical).hexdigest()}", manifest
88
+
89
+
90
+ def load_tree_manifest(
91
+ path: str,
92
+ *,
93
+ max_files: int,
94
+ max_total_bytes: int,
95
+ subject: str = "Artifact",
96
+ ) -> tuple[str, dict]:
97
+ if os.path.getsize(path) > _MAX_MANIFEST_BYTES:
98
+ raise ValueError(f"{subject} manifest is too large")
99
+ with open(path, "rb") as file:
100
+ body = file.read(_MAX_MANIFEST_BYTES + 1)
101
+ if len(body) > _MAX_MANIFEST_BYTES:
102
+ raise ValueError(f"{subject} manifest is too large")
103
+ try:
104
+ manifest = json.loads(body)
105
+ except (UnicodeDecodeError, json.JSONDecodeError) as exc:
106
+ raise ValueError(f"{subject} manifest is invalid JSON") from exc
107
+ return validate_tree_manifest(
108
+ manifest,
109
+ max_files=max_files,
110
+ max_total_bytes=max_total_bytes,
111
+ subject=subject,
112
+ )
113
+
114
+
115
+ def build_tree_manifest(
116
+ root: str,
117
+ *,
118
+ max_files: int,
119
+ max_total_bytes: int,
120
+ skip_directories: Collection[str] = (),
121
+ subject: str = "Artifact",
122
+ ) -> tuple[str, dict]:
123
+ """Validate a regular-file tree and return its canonical content digest."""
124
+
125
+ resolved_root = os.path.realpath(str(root or "").strip())
126
+ if not resolved_root or not os.path.isdir(resolved_root):
127
+ raise ValueError(f"{subject} directory is unavailable")
128
+
129
+ files: list[dict] = []
130
+ total_bytes = 0
131
+ for current_root, dir_names, file_names in os.walk(
132
+ resolved_root,
133
+ followlinks=False,
134
+ ):
135
+ dir_names[:] = [name for name in dir_names if name not in skip_directories]
136
+ dir_names.sort()
137
+ file_names.sort()
138
+ for directory_name in dir_names:
139
+ if os.path.islink(os.path.join(current_root, directory_name)):
140
+ raise ValueError(f"{subject} cannot contain symbolic links")
141
+ for file_name in file_names:
142
+ path = os.path.join(current_root, file_name)
143
+ file_stat = os.stat(path, follow_symlinks=False)
144
+ if os.path.islink(path):
145
+ raise ValueError(f"{subject} cannot contain symbolic links")
146
+ if not stat.S_ISREG(file_stat.st_mode):
147
+ raise ValueError(f"{subject} can contain regular files only")
148
+ if len(files) >= max_files:
149
+ raise ValueError(f"{subject} contains too many files")
150
+ total_bytes += file_stat.st_size
151
+ if total_bytes > max_total_bytes:
152
+ raise ValueError(f"{subject} is too large")
153
+
154
+ file_digest = hashlib.sha256()
155
+ with open(path, "rb") as file:
156
+ while True:
157
+ chunk = file.read(256 * 1024)
158
+ if not chunk:
159
+ break
160
+ file_digest.update(chunk)
161
+ files.append(
162
+ {
163
+ "path": os.path.relpath(path, resolved_root).replace(os.sep, "/"),
164
+ "size": file_stat.st_size,
165
+ "sha256": file_digest.hexdigest(),
166
+ "executable": bool(stat.S_IMODE(file_stat.st_mode) & 0o111),
167
+ }
168
+ )
169
+
170
+ manifest = {
171
+ "algorithm": TREE_MANIFEST_ALGORITHM,
172
+ "files": files,
173
+ "total_bytes": total_bytes,
174
+ }
175
+ return validate_tree_manifest(
176
+ manifest,
177
+ max_files=max_files,
178
+ max_total_bytes=max_total_bytes,
179
+ subject=subject,
180
+ )
181
+
182
+
183
+ __all__ = [
184
+ "TREE_MANIFEST_ALGORITHM",
185
+ "build_tree_manifest",
186
+ "load_tree_manifest",
187
+ "validate_tree_manifest",
188
+ ]
189
+
190
+
191
+ def materialize_tree(
192
+ source: str, manifest_path: str, expected_digest: str, cache_root: str
193
+ ) -> str:
194
+ """Publish a complete verified tree outside the sandbox before making it visible."""
195
+ import shutil
196
+ import tempfile
197
+
198
+ max_bytes = 256 * 1024 * 1024
199
+ digest, manifest = load_tree_manifest(
200
+ manifest_path, max_files=2048, max_total_bytes=max_bytes
201
+ )
202
+ if digest != expected_digest:
203
+ raise ValueError("Artifact manifest does not match content_digest")
204
+ target = os.path.join(cache_root, digest[7:])
205
+ if os.path.isdir(target) and not os.path.islink(target):
206
+ return target
207
+ used = sum(
208
+ os.path.getsize(os.path.join(root, name))
209
+ for root, _, names in os.walk(cache_root)
210
+ for name in names
211
+ )
212
+ if len(os.listdir(cache_root)) >= 256 or used + manifest["total_bytes"] > max_bytes:
213
+ raise ValueError("Immutable artifact cache limit reached; acquire a new Box")
214
+ staging = tempfile.mkdtemp(
215
+ prefix="langbot-artifact-stage-", dir=os.path.dirname(cache_root)
216
+ )
217
+ try:
218
+ for entry in manifest["files"]:
219
+ source_path = os.path.join(source, *entry["path"].split("/"))
220
+ descriptor = os.open(
221
+ source_path,
222
+ os.O_RDONLY
223
+ | getattr(os, "O_NOFOLLOW", 0)
224
+ | getattr(os, "O_NONBLOCK", 0),
225
+ )
226
+ with os.fdopen(descriptor, "rb") as stream:
227
+ if not stat.S_ISREG(os.fstat(stream.fileno()).st_mode):
228
+ raise ValueError("Artifact source must be a regular file")
229
+ body = stream.read(entry["size"] + 1)
230
+ if (
231
+ len(body) != entry["size"]
232
+ or hashlib.sha256(body).hexdigest() != entry["sha256"]
233
+ ):
234
+ raise ValueError(f"Artifact source changed: {entry['path']}")
235
+ destination = os.path.join(staging, *entry["path"].split("/"))
236
+ os.makedirs(os.path.dirname(destination), exist_ok=True)
237
+ with open(destination, "xb") as stream:
238
+ stream.write(body)
239
+ os.chmod(destination, 0o555 if entry["executable"] else 0o444)
240
+ os.chmod(staging, 0o755)
241
+ os.rename(staging, target)
242
+ return target
243
+ finally:
244
+ if os.path.isdir(staging):
245
+ shutil.rmtree(staging)
@@ -24,15 +24,4 @@ class LangBotToBoxAction(ActionType):
24
24
  STOP_MANAGED_PROCESS = "box_stop_managed_process"
25
25
  GET_BACKEND_INFO = "box_get_backend_info"
26
26
  GET_STORAGE_ANALYSIS = "box_get_storage_analysis"
27
- LIST_SKILLS = "box_list_skills"
28
- GET_SKILL = "box_get_skill"
29
- CREATE_SKILL = "box_create_skill"
30
- UPDATE_SKILL = "box_update_skill"
31
- DELETE_SKILL = "box_delete_skill"
32
- SCAN_SKILL_DIRECTORY = "box_scan_skill_directory"
33
- LIST_SKILL_FILES = "box_list_skill_files"
34
- READ_SKILL_FILE = "box_read_skill_file"
35
- WRITE_SKILL_FILE = "box_write_skill_file"
36
- PREVIEW_SKILL_ZIP = "box_preview_skill_zip"
37
- INSTALL_SKILL_ZIP = "box_install_skill_zip"
38
27
  SHUTDOWN = "box_shutdown"
@@ -10,9 +10,14 @@ import re
10
10
  import shlex
11
11
  import shutil
12
12
  import uuid
13
+ import tempfile
14
+
15
+ from ..artifact import materialize_tree
16
+ from ..runtime import bounded_executor
13
17
 
14
18
  from .errors import BoxError
15
19
  from .models import (
20
+ ARTIFACT_MOUNT_ROOT,
16
21
  BoxExecutionResult,
17
22
  BoxExecutionStatus,
18
23
  BoxHostMountMode,
@@ -41,6 +46,8 @@ class _CommandResult:
41
46
  class BaseSandboxBackend(abc.ABC):
42
47
  name: str
43
48
  instance_id: str = ""
49
+ execution_scoped_mounts: bool = False
50
+ content_addressed_mounts: bool = False
44
51
 
45
52
  def __init__(self, logger: logging.Logger):
46
53
  self.logger = logger
@@ -87,7 +94,7 @@ class BaseSandboxBackend(abc.ABC):
87
94
  "mount_isolation": False if strict else None,
88
95
  "network_isolation": False if strict else None,
89
96
  "hard_workspace_quota": False if strict else None,
90
- "hard_skill_storage_quota": False if strict else None,
97
+ "hard_read_only_mount_quota": False if strict else None,
91
98
  "bounded_ephemeral_storage": False if strict else None,
92
99
  "inode_quota": False if strict else None,
93
100
  }
@@ -154,6 +161,7 @@ class BaseSandboxBackend(abc.ABC):
154
161
 
155
162
 
156
163
  class CLISandboxBackend(BaseSandboxBackend):
164
+ content_addressed_mounts = True
157
165
  command: str
158
166
 
159
167
  def __init__(self, logger: logging.Logger, command: str, backend_name: str):
@@ -161,6 +169,7 @@ class CLISandboxBackend(BaseSandboxBackend):
161
169
  self.command = command
162
170
  self.name = backend_name
163
171
  self.cpu_limit_enabled = True
172
+ self._artifact_roots: dict[str, str] = {}
164
173
 
165
174
  async def is_available(self) -> bool:
166
175
  if shutil.which(self.command) is None:
@@ -215,8 +224,12 @@ class CLISandboxBackend(BaseSandboxBackend):
215
224
  )
216
225
  args.extend(["-v", mount_spec])
217
226
 
227
+ artifact_root = tempfile.mkdtemp(prefix="langbot-box-artifacts-")
228
+ os.chmod(artifact_root, 0o755)
229
+ self._artifact_roots[container_name] = artifact_root
230
+ args.extend(["-v", f"{artifact_root}:{ARTIFACT_MOUNT_ROOT}:ro"])
218
231
  for mount in spec.extra_mounts:
219
- if mount.mode != BoxHostMountMode.NONE:
232
+ if mount.mode != BoxHostMountMode.NONE and not mount.is_content_addressed:
220
233
  args.extend(
221
234
  ["-v", f"{mount.host_path}:{mount.mount_path}:{mount.mode.value}"]
222
235
  )
@@ -233,7 +246,27 @@ class CLISandboxBackend(BaseSandboxBackend):
233
246
  f"read_only_rootfs={spec.read_only_rootfs} workspace_quota_mb={spec.workspace_quota_mb}"
234
247
  )
235
248
 
236
- await self._run_command(args, timeout_sec=30, check=True)
249
+ start_task = None
250
+ try:
251
+ await self._prepare_artifacts(container_name, spec)
252
+ start_task = asyncio.create_task(
253
+ self._run_command(args, timeout_sec=30, check=True)
254
+ )
255
+ await asyncio.shield(start_task)
256
+ except BaseException:
257
+ if start_task is not None:
258
+ try:
259
+ await start_task
260
+ except BaseException:
261
+ pass
262
+ await self._run_command(
263
+ [self.command, "rm", "-f", container_name],
264
+ timeout_sec=20,
265
+ check=False,
266
+ )
267
+ self._artifact_roots.pop(container_name, None)
268
+ shutil.rmtree(artifact_root)
269
+ raise
237
270
 
238
271
  return BoxSessionInfo(
239
272
  session_id=spec.session_id,
@@ -254,7 +287,29 @@ class CLISandboxBackend(BaseSandboxBackend):
254
287
  last_used_at=now,
255
288
  )
256
289
 
290
+ async def _prepare_artifacts(self, session_id: str, spec: BoxSpec) -> None:
291
+ for mount in spec.extra_mounts:
292
+ if mount.is_content_addressed:
293
+ root = self._artifact_roots.get(session_id)
294
+ if root is None:
295
+ raise BoxError(
296
+ "Immutable artifact cache is unavailable; acquire a new Box"
297
+ )
298
+ try:
299
+ await bounded_executor.run_blocking_atomic(
300
+ materialize_tree,
301
+ mount.host_path,
302
+ mount.manifest_path,
303
+ mount.content_digest,
304
+ root,
305
+ )
306
+ except (OSError, ValueError) as exc:
307
+ raise BoxError(
308
+ f"Immutable artifact preparation failed: {exc}"
309
+ ) from exc
310
+
257
311
  async def exec(self, session: BoxSessionInfo, spec: BoxSpec) -> BoxExecutionResult:
312
+ await self._prepare_artifacts(session.backend_session_id, spec)
258
313
  start = dt.datetime.now(dt.timezone.utc)
259
314
  args = [self.command, "exec"]
260
315
 
@@ -316,11 +371,15 @@ class CLISandboxBackend(BaseSandboxBackend):
316
371
  f"LangBot Box backend stop_session: backend={self.name} "
317
372
  f"session_id={session.session_id} container_name={session.backend_session_id}"
318
373
  )
319
- await self._run_command(
374
+ result = await self._run_command(
320
375
  [self.command, "rm", "-f", session.backend_session_id],
321
376
  timeout_sec=20,
322
377
  check=False,
323
378
  )
379
+ if result.return_code == 0:
380
+ root = self._artifact_roots.pop(session.backend_session_id, None)
381
+ if root is not None:
382
+ await bounded_executor.run_blocking_cleanup(shutil.rmtree, root)
324
383
 
325
384
  async def is_session_alive(self, session: BoxSessionInfo) -> bool:
326
385
  result = await self._run_command(