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