langbot-plugin 0.4.4__tar.gz → 0.4.6__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 (255) hide show
  1. langbot_plugin-0.4.6/.github/workflows/test.yml +93 -0
  2. langbot_plugin-0.4.6/PKG-INFO +115 -0
  3. langbot_plugin-0.4.6/README.md +86 -0
  4. langbot_plugin-0.4.6/README_CN.md +83 -0
  5. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/pyproject.toml +1 -1
  6. langbot_plugin-0.4.6/scripts/check_action_consistency.py +277 -0
  7. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/provider/message.py +67 -1
  8. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/proxies/langbot_api.py +88 -14
  9. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/__init__.py +1 -1
  10. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/backend.py +106 -85
  11. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/e2b_backend.py +120 -81
  12. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/models.py +72 -68
  13. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/nsjail_backend.py +148 -128
  14. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/runtime.py +48 -2
  15. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/security.py +22 -18
  16. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/skill_store.py +283 -180
  17. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/__init__.py +6 -8
  18. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/i18n.py +2 -2
  19. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/run/handler.py +11 -3
  20. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/run/hotreload.py +8 -4
  21. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/entities/io/errors.py +3 -1
  22. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/helper/pkgmgr.py +4 -1
  23. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/controllers/ws/client.py +3 -1
  24. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/handlers/control.py +10 -4
  25. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/handlers/plugin.py +12 -10
  26. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/plugin/logbuffer.py +1 -5
  27. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/plugin/mgr.py +9 -7
  28. langbot_plugin-0.4.6/src/langbot_plugin/version.py +1 -0
  29. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/definition/components/test_components.py +12 -5
  30. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/entities/builtin/test_rag_models.py +8 -5
  31. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/entities/test_context.py +3 -1
  32. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/proxies/test_langbot_api.py +28 -0
  33. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/proxies/test_query_based_api.py +6 -2
  34. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/box/test_backend.py +226 -208
  35. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/box/test_backend_selection.py +60 -52
  36. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/box/test_client.py +189 -191
  37. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/box/test_e2b_backend.py +164 -135
  38. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/box/test_nsjail_backend.py +207 -188
  39. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/box/test_runtime.py +187 -183
  40. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/box/test_server.py +7 -22
  41. langbot_plugin-0.4.6/tests/box/test_skill_store.py +952 -0
  42. langbot_plugin-0.4.6/tests/cli/run/test_controller.py +519 -0
  43. langbot_plugin-0.4.6/tests/cli/run/test_hotreload.py +180 -0
  44. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/run/test_runtime_handler.py +309 -4
  45. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/test_buildplugin.py +1 -3
  46. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/test_initplugin.py +8 -2
  47. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/test_login.py +1 -3
  48. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/test_logout_publish.py +18 -4
  49. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/test_renderer.py +24 -13
  50. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/test_runplugin.py +6 -6
  51. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/entities/io/test_protocol.py +3 -1
  52. langbot_plugin-0.4.6/tests/packaging/test_installed_cli_blackbox.py +350 -0
  53. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/runtime/helper/test_marketplace.py +3 -1
  54. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/runtime/helper/test_pkgmgr.py +11 -3
  55. langbot_plugin-0.4.6/tests/runtime/io/handlers/test_control_handler.py +904 -0
  56. langbot_plugin-0.4.6/tests/runtime/io/handlers/test_plugin_handler.py +756 -0
  57. langbot_plugin-0.4.6/tests/runtime/io/test_action_consistency.py +79 -0
  58. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/runtime/io/test_handler.py +4 -4
  59. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/runtime/plugin/test_manager.py +323 -6
  60. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/runtime/test_app.py +1 -3
  61. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/test_plugin_logbuffer.py +3 -9
  62. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/utils/test_discovery.py +7 -6
  63. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/utils/test_importutil.py +3 -1
  64. langbot_plugin-0.4.4/.github/workflows/test.yml +0 -46
  65. langbot_plugin-0.4.4/PKG-INFO +0 -38
  66. langbot_plugin-0.4.4/README.md +0 -9
  67. langbot_plugin-0.4.4/src/langbot_plugin/version.py +0 -1
  68. langbot_plugin-0.4.4/tests/box/test_skill_store.py +0 -914
  69. langbot_plugin-0.4.4/tests/cli/run/test_controller.py +0 -172
  70. langbot_plugin-0.4.4/tests/runtime/io/handlers/test_control_handler.py +0 -452
  71. langbot_plugin-0.4.4/tests/runtime/io/handlers/test_plugin_handler.py +0 -317
  72. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/.github/workflows/cla.yml +0 -0
  73. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/.github/workflows/publish-pypi.yaml +0 -0
  74. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/.gitignore +0 -0
  75. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/.python-version +0 -0
  76. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/AGENTS.md +0 -0
  77. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/CLAUDE.md +0 -0
  78. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/CONTRIBUTING.md +0 -0
  79. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/LICENSE +0 -0
  80. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/data/.env.example +0 -0
  81. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/docs/Message.md +0 -0
  82. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/docs/PluginPages.md +0 -0
  83. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/docs/communication/apis/lb2rt.md +0 -0
  84. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/docs/communication/runtime_plugin.md +0 -0
  85. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/docs/dependency-management.md +0 -0
  86. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/docs/langbot-plugin-social.png +0 -0
  87. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/__init__.py +0 -0
  88. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/__init__.py +0 -0
  89. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/__init__.py +0 -0
  90. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/abstract/__init__.py +0 -0
  91. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/abstract/platform/__init__.py +0 -0
  92. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/abstract/platform/adapter.py +0 -0
  93. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/abstract/platform/event_logger.py +0 -0
  94. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/__init__.py +0 -0
  95. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/base.py +0 -0
  96. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/command/__init__.py +0 -0
  97. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/command/command.py +0 -0
  98. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/common/__init__.py +0 -0
  99. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/common/event_listener.py +0 -0
  100. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/knowledge_engine/__init__.py +0 -0
  101. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/knowledge_engine/engine.py +0 -0
  102. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/manifest.py +0 -0
  103. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/page/__init__.py +0 -0
  104. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/parser/__init__.py +0 -0
  105. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/parser/parser.py +0 -0
  106. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/tool/__init__.py +0 -0
  107. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/components/tool/tool.py +0 -0
  108. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/definition/plugin.py +0 -0
  109. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/__init__.py +0 -0
  110. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/__init__.py +0 -0
  111. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/command/__init__.py +0 -0
  112. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/command/context.py +0 -0
  113. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/command/errors.py +0 -0
  114. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/pipeline/__init__.py +0 -0
  115. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/pipeline/query.py +0 -0
  116. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/platform/__init__.py +0 -0
  117. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/platform/entities.py +0 -0
  118. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/platform/events.py +0 -0
  119. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/platform/logger.py +0 -0
  120. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/platform/message.py +0 -0
  121. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/provider/__init__.py +0 -0
  122. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/provider/prompt.py +0 -0
  123. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/provider/session.py +0 -0
  124. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/rag/__init__.py +0 -0
  125. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/rag/context.py +0 -0
  126. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/rag/enums.py +0 -0
  127. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/rag/errors.py +0 -0
  128. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/rag/models.py +0 -0
  129. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/resource/__init__.py +0 -0
  130. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/builtin/resource/tool.py +0 -0
  131. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/context.py +0 -0
  132. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/entities/events.py +0 -0
  133. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/proxies/__init__.py +0 -0
  134. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/proxies/base.py +0 -0
  135. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/proxies/event_context.py +0 -0
  136. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/proxies/execute_context.py +0 -0
  137. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/api/proxies/query_based_api.py +0 -0
  138. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/__init__.py +0 -0
  139. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/langbot-page-sdk.js +0 -0
  140. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/.env.example.example +0 -0
  141. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/.github/workflows/release.yml.example +0 -0
  142. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/.gitignore.example +0 -0
  143. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/.vscode/launch.json.example +0 -0
  144. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/README.md.example +0 -0
  145. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/__init__.py +0 -0
  146. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/assets/icon.svg.example +0 -0
  147. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/__init__.py +0 -0
  148. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/commands/__init__.py +0 -0
  149. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.py.example +0 -0
  150. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.yaml.example +0 -0
  151. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/event_listener/__init__.py +0 -0
  152. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/event_listener/default.py.example +0 -0
  153. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/event_listener/default.yaml.example +0 -0
  154. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/knowledge_engine/__init__.py +0 -0
  155. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.py.example +0 -0
  156. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.yaml.example +0 -0
  157. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/pages/{page_name}.html.example +0 -0
  158. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/pages/{page_name}.yaml.example +0 -0
  159. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/parser/__init__.py +0 -0
  160. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.py.example +0 -0
  161. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.yaml.example +0 -0
  162. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/tools/__init__.py +0 -0
  163. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.py.example +0 -0
  164. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.yaml.example +0 -0
  165. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/main.py.example +0 -0
  166. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/manifest.yaml.example +0 -0
  167. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/readme/README_zh_Hans.md.example +0 -0
  168. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/assets/templates/requirements.txt.example +0 -0
  169. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/actions.py +0 -0
  170. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/client.py +0 -0
  171. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/errors.py +0 -0
  172. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/box/server.py +0 -0
  173. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/__main__.py +0 -0
  174. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/commands/__init__.py +0 -0
  175. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/commands/buildplugin.py +0 -0
  176. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/commands/gencomponent.py +0 -0
  177. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/commands/initplugin.py +0 -0
  178. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/commands/login.py +0 -0
  179. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/commands/logout.py +0 -0
  180. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/commands/publish.py +0 -0
  181. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/commands/runplugin.py +0 -0
  182. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/gen/__init__.py +0 -0
  183. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/gen/renderer.py +0 -0
  184. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/locales/__init__.py +0 -0
  185. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/locales/en_US.py +0 -0
  186. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/locales/es_ES.py +0 -0
  187. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/locales/ja_JP.py +0 -0
  188. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/locales/th_TH.py +0 -0
  189. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/locales/vi_VN.py +0 -0
  190. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/locales/zh_Hans.py +0 -0
  191. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/locales/zh_Hant.py +0 -0
  192. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/run/__init__.py +0 -0
  193. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/run/controller.py +0 -0
  194. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/utils/__init__.py +0 -0
  195. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/utils/cloudsv.py +0 -0
  196. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/utils/form.py +0 -0
  197. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/cli/utils/page_components.py +0 -0
  198. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/entities/__init__.py +0 -0
  199. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/entities/io/__init__.py +0 -0
  200. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/entities/io/actions/__init__.py +0 -0
  201. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/entities/io/actions/enums.py +0 -0
  202. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/entities/io/req.py +0 -0
  203. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/entities/io/resp.py +0 -0
  204. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/entities/marketplace.py +0 -0
  205. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/LICENSE +0 -0
  206. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/README.md +0 -0
  207. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/__init__.py +0 -0
  208. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/app.py +0 -0
  209. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/context.py +0 -0
  210. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/helper/__init__.py +0 -0
  211. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/helper/marketplace.py +0 -0
  212. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/__init__.py +0 -0
  213. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/connection.py +0 -0
  214. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/connections/__init__.py +0 -0
  215. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/connections/stdio.py +0 -0
  216. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/connections/ws.py +0 -0
  217. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/controller.py +0 -0
  218. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/controllers/__init__.py +0 -0
  219. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/controllers/stdio/__init__.py +0 -0
  220. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/controllers/stdio/client.py +0 -0
  221. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/controllers/stdio/server.py +0 -0
  222. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/controllers/ws/__init__.py +0 -0
  223. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/controllers/ws/server.py +0 -0
  224. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/handler.py +0 -0
  225. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/io/handlers/__init__.py +0 -0
  226. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/plugin/__init__.py +0 -0
  227. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/plugin/container.py +0 -0
  228. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/runtime/settings.py +0 -0
  229. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/utils/__init__.py +0 -0
  230. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/utils/discover/__init__.py +0 -0
  231. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/utils/discover/engine.py +0 -0
  232. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/utils/importutil.py +0 -0
  233. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/utils/log.py +0 -0
  234. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/src/langbot_plugin/utils/platform.py +0 -0
  235. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/__init__.py +0 -0
  236. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/definition/test_manifest.py +0 -0
  237. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/entities/builtin/test_command_context.py +0 -0
  238. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/entities/builtin/test_platform_logger.py +0 -0
  239. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/entities/builtin/test_provider_message.py +0 -0
  240. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/entities/test_events.py +0 -0
  241. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/api/proxies/test_base.py +0 -0
  242. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/box/__init__.py +0 -0
  243. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/test_gencomponent.py +0 -0
  244. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/test_i18n_form.py +0 -0
  245. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/cli/test_page_components.py +0 -0
  246. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/entities/io/test_dependency_errors.py +0 -0
  247. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/helpers/__init__.py +0 -0
  248. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/helpers/protocol.py +0 -0
  249. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/runtime/io/handlers/test_import_contracts.py +0 -0
  250. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/runtime/io/test_connections.py +0 -0
  251. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/runtime/io/test_controllers.py +0 -0
  252. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/runtime/plugin/test_container.py +0 -0
  253. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/test_log.py +0 -0
  254. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/test_message.py +0 -0
  255. {langbot_plugin-0.4.4 → langbot_plugin-0.4.6}/tests/utils/test_platform.py +0 -0
@@ -0,0 +1,93 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - test-build
8
+ pull_request:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ unit-tests:
15
+ name: Unit Tests
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ python-version: ["3.10", "3.11", "3.12"]
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ with:
24
+ persist-credentials: false
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@v6
27
+ - name: Set up Python
28
+ run: uv python install ${{ matrix.python-version }}
29
+ - name: Run tests with coverage
30
+ run: |
31
+ uv run --python ${{ matrix.python-version }} pytest \
32
+ --ignore=tests/packaging \
33
+ --cov=langbot_plugin \
34
+ --cov-report=term-missing \
35
+ --cov-fail-under=84
36
+
37
+ test-lint:
38
+ name: Lint and Format
39
+ runs-on: ubuntu-latest
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+ with:
43
+ persist-credentials: false
44
+ - name: Install uv
45
+ uses: astral-sh/setup-uv@v6
46
+ - name: Ruff check
47
+ run: uv run ruff check src tests --output-format=concise
48
+ - name: Ruff format check
49
+ run: uv run ruff format --check src tests
50
+
51
+ package-smoke:
52
+ name: Package Smoke
53
+ runs-on: ubuntu-latest
54
+ steps:
55
+ - uses: actions/checkout@v4
56
+ with:
57
+ persist-credentials: false
58
+ - name: Install uv
59
+ uses: astral-sh/setup-uv@v6
60
+ - name: Set up Python
61
+ run: uv python install 3.12
62
+ - name: Installed wheel CLI smoke
63
+ run: uv run --python 3.12 pytest -q tests/packaging
64
+
65
+ scoped-type-check:
66
+ name: Scoped Type Check
67
+ runs-on: ubuntu-latest
68
+ steps:
69
+ - uses: actions/checkout@v4
70
+ with:
71
+ persist-credentials: false
72
+ - name: Install uv
73
+ uses: astral-sh/setup-uv@v6
74
+ - name: Mypy stable protocol modules
75
+ run: |
76
+ uv run mypy \
77
+ src/langbot_plugin/entities/io \
78
+ src/langbot_plugin/runtime/plugin/logbuffer.py \
79
+ src/langbot_plugin/utils/platform.py
80
+
81
+ action-consistency:
82
+ name: Action Protocol Consistency
83
+ runs-on: ubuntu-latest
84
+ steps:
85
+ - uses: actions/checkout@v4
86
+ with:
87
+ persist-credentials: false
88
+ - name: Set up Python
89
+ uses: actions/setup-python@v5
90
+ with:
91
+ python-version: "3.12"
92
+ - name: Check action enum / proxy / handler consistency
93
+ run: python scripts/check_action_consistency.py
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: langbot-plugin
3
+ Version: 0.4.6
4
+ Summary: This package contains the SDK, CLI for building plugins for LangBot, plus the runtime for hosting LangBot plugins
5
+ Project-URL: Homepage, https://langbot.app
6
+ Project-URL: Repository, https://github.com/langbot-app/langbot-plugin-sdk
7
+ Project-URL: Issues, https://github.com/langbot-app/langbot-plugin-sdk/issues
8
+ Author-email: Junyan Qin <rockchinq@gmail.com>
9
+ License-File: LICENSE
10
+ Requires-Python: >=3.10
11
+ Requires-Dist: aiofiles>=24.1.0
12
+ Requires-Dist: aiohttp>=3.9.0
13
+ Requires-Dist: dotenv>=0.9.9
14
+ Requires-Dist: e2b>=2.15
15
+ Requires-Dist: httpx>=0.28.1
16
+ Requires-Dist: jinja2>=3.1.6
17
+ Requires-Dist: packaging>=24.0
18
+ Requires-Dist: pip>=25.2
19
+ Requires-Dist: pydantic-settings>=2.10.1
20
+ Requires-Dist: pydantic>=2.11.5
21
+ Requires-Dist: pytest>=8.4.0
22
+ Requires-Dist: pyyaml>=6.0.2
23
+ Requires-Dist: textual>=3.2.0
24
+ Requires-Dist: types-aiofiles>=24.1.0.20250516
25
+ Requires-Dist: types-pyyaml>=6.0.12.20250516
26
+ Requires-Dist: watchdog>=6.0.0
27
+ Requires-Dist: websockets>=15.0.1
28
+ Description-Content-Type: text/markdown
29
+
30
+ <div align="center">
31
+
32
+ <h1>LangBot Plugin Infra</h1>
33
+
34
+ <p>Plugin SDK, CLI, Plugin Runtime and Box sandbox runtime for <a href="https://github.com/langbot-app/LangBot">LangBot</a>.</p>
35
+
36
+ [![PyPI](https://img.shields.io/pypi/v/langbot-plugin)](https://pypi.org/project/langbot-plugin/)
37
+ [![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
38
+ [![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE)
39
+
40
+ English / [简体中文](README_CN.md)
41
+
42
+ [Documentation](https://docs.langbot.app/zh/plugin/dev/tutor) ·
43
+ [Plugin Market](https://space.langbot.app) ·
44
+ [LangBot](https://github.com/langbot-app/LangBot)
45
+
46
+ </div>
47
+
48
+ ## Overview
49
+
50
+ This repository is the shared infrastructure powering LangBot's plugin and
51
+ sandbox subsystems. It is published to PyPI as the single
52
+ [`langbot-plugin`](https://pypi.org/project/langbot-plugin/) package and ships
53
+ three things:
54
+
55
+ - **Plugin SDK & CLI** (`lbp`) — Python APIs, base classes and the `lbp`
56
+ command for scaffolding, building, debugging and publishing plugins.
57
+ - **Plugin Runtime** (`lbp rt`) — the host process that discovers, installs and
58
+ runs plugins, bridging them to LangBot over stdio or WebSocket.
59
+ - **Box Runtime** (`lbp box`) — the code-sandbox service backing LangBot's Box
60
+ subsystem, executing untrusted code via Docker / nsjail / E2B backends.
61
+
62
+ LangBot depends on this package as the pinned `langbot-plugin==<x.y.z>` in its
63
+ `pyproject.toml`; the canonical version lives in this repo's `pyproject.toml`.
64
+
65
+ > The **Runtime** component (`src/langbot_plugin/runtime/`) is licensed
66
+ > separately under **AGPL**; everything else in this repository is **Apache 2.0**.
67
+ > See [`src/langbot_plugin/runtime/README.md`](src/langbot_plugin/runtime/README.md).
68
+
69
+ ## Install
70
+
71
+ ```bash
72
+ pip install langbot-plugin
73
+ # or, recommended
74
+ uv tool install langbot-plugin
75
+
76
+ lbp --help
77
+ ```
78
+
79
+ ## CLI at a glance
80
+
81
+ | Command | Purpose |
82
+ | --- | --- |
83
+ | `lbp init <name>` | Scaffold a new plugin project |
84
+ | `lbp comp <Type>` | Generate a component (Command / Tool / EventListener / KnowledgeEngine / Parser / Page) |
85
+ | `lbp run` | Run / remote-debug a plugin against a running LangBot |
86
+ | `lbp build` | Package the plugin into a distributable zip |
87
+ | `lbp publish` | Publish to the LangBot Plugin Market |
88
+ | `lbp login` / `lbp logout` | Authenticate with your LangBot account |
89
+ | `lbp rt` | Launch a standalone Plugin Runtime (control `5400`, debug `5401`) |
90
+ | `lbp box` | Launch a standalone Box sandbox runtime (default port `5410`) |
91
+ | `lbp ver` | Print the CLI / package version |
92
+
93
+ ## Component types
94
+
95
+ Plugins extend LangBot through six component types, scaffolded with
96
+ `lbp comp <Type>`:
97
+
98
+ - **Command** — user-triggered actions (e.g. `!weather tokyo`)
99
+ - **Tool** — LLM-callable functions for AI agents
100
+ - **EventListener** — handlers for message-pipeline events
101
+ - **KnowledgeEngine** — custom knowledge-base retrieval for RAG
102
+ - **Parser** — custom message / content parsing
103
+ - **Page** — custom web page embedded in the LangBot admin panel
104
+
105
+ ## Documentation
106
+
107
+ - Plugin development tutorial — https://docs.langbot.app/zh/plugin/dev/tutor
108
+ - Debugging the Runtime / CLI / SDK — https://docs.langbot.app/zh/develop/plugin-runtime
109
+ - Dev environment setup — https://docs.langbot.app/zh/develop/dev-config
110
+
111
+ ## License
112
+
113
+ Apache 2.0, except the Plugin Runtime (`src/langbot_plugin/runtime/`) which is
114
+ AGPL. See [LICENSE](LICENSE) and the
115
+ [Runtime README](src/langbot_plugin/runtime/README.md).
@@ -0,0 +1,86 @@
1
+ <div align="center">
2
+
3
+ <h1>LangBot Plugin Infra</h1>
4
+
5
+ <p>Plugin SDK, CLI, Plugin Runtime and Box sandbox runtime for <a href="https://github.com/langbot-app/LangBot">LangBot</a>.</p>
6
+
7
+ [![PyPI](https://img.shields.io/pypi/v/langbot-plugin)](https://pypi.org/project/langbot-plugin/)
8
+ [![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
9
+ [![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE)
10
+
11
+ English / [简体中文](README_CN.md)
12
+
13
+ [Documentation](https://docs.langbot.app/zh/plugin/dev/tutor) ·
14
+ [Plugin Market](https://space.langbot.app) ·
15
+ [LangBot](https://github.com/langbot-app/LangBot)
16
+
17
+ </div>
18
+
19
+ ## Overview
20
+
21
+ This repository is the shared infrastructure powering LangBot's plugin and
22
+ sandbox subsystems. It is published to PyPI as the single
23
+ [`langbot-plugin`](https://pypi.org/project/langbot-plugin/) package and ships
24
+ three things:
25
+
26
+ - **Plugin SDK & CLI** (`lbp`) — Python APIs, base classes and the `lbp`
27
+ command for scaffolding, building, debugging and publishing plugins.
28
+ - **Plugin Runtime** (`lbp rt`) — the host process that discovers, installs and
29
+ runs plugins, bridging them to LangBot over stdio or WebSocket.
30
+ - **Box Runtime** (`lbp box`) — the code-sandbox service backing LangBot's Box
31
+ subsystem, executing untrusted code via Docker / nsjail / E2B backends.
32
+
33
+ LangBot depends on this package as the pinned `langbot-plugin==<x.y.z>` in its
34
+ `pyproject.toml`; the canonical version lives in this repo's `pyproject.toml`.
35
+
36
+ > The **Runtime** component (`src/langbot_plugin/runtime/`) is licensed
37
+ > separately under **AGPL**; everything else in this repository is **Apache 2.0**.
38
+ > See [`src/langbot_plugin/runtime/README.md`](src/langbot_plugin/runtime/README.md).
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ pip install langbot-plugin
44
+ # or, recommended
45
+ uv tool install langbot-plugin
46
+
47
+ lbp --help
48
+ ```
49
+
50
+ ## CLI at a glance
51
+
52
+ | Command | Purpose |
53
+ | --- | --- |
54
+ | `lbp init <name>` | Scaffold a new plugin project |
55
+ | `lbp comp <Type>` | Generate a component (Command / Tool / EventListener / KnowledgeEngine / Parser / Page) |
56
+ | `lbp run` | Run / remote-debug a plugin against a running LangBot |
57
+ | `lbp build` | Package the plugin into a distributable zip |
58
+ | `lbp publish` | Publish to the LangBot Plugin Market |
59
+ | `lbp login` / `lbp logout` | Authenticate with your LangBot account |
60
+ | `lbp rt` | Launch a standalone Plugin Runtime (control `5400`, debug `5401`) |
61
+ | `lbp box` | Launch a standalone Box sandbox runtime (default port `5410`) |
62
+ | `lbp ver` | Print the CLI / package version |
63
+
64
+ ## Component types
65
+
66
+ Plugins extend LangBot through six component types, scaffolded with
67
+ `lbp comp <Type>`:
68
+
69
+ - **Command** — user-triggered actions (e.g. `!weather tokyo`)
70
+ - **Tool** — LLM-callable functions for AI agents
71
+ - **EventListener** — handlers for message-pipeline events
72
+ - **KnowledgeEngine** — custom knowledge-base retrieval for RAG
73
+ - **Parser** — custom message / content parsing
74
+ - **Page** — custom web page embedded in the LangBot admin panel
75
+
76
+ ## Documentation
77
+
78
+ - Plugin development tutorial — https://docs.langbot.app/zh/plugin/dev/tutor
79
+ - Debugging the Runtime / CLI / SDK — https://docs.langbot.app/zh/develop/plugin-runtime
80
+ - Dev environment setup — https://docs.langbot.app/zh/develop/dev-config
81
+
82
+ ## License
83
+
84
+ Apache 2.0, except the Plugin Runtime (`src/langbot_plugin/runtime/`) which is
85
+ AGPL. See [LICENSE](LICENSE) and the
86
+ [Runtime README](src/langbot_plugin/runtime/README.md).
@@ -0,0 +1,83 @@
1
+ <div align="center">
2
+
3
+ <h1>LangBot Plugin Infra</h1>
4
+
5
+ <p>为 <a href="https://github.com/langbot-app/LangBot">LangBot</a> 提供插件 SDK、CLI、插件运行时与 Box 代码沙箱运行时。</p>
6
+
7
+ [![PyPI](https://img.shields.io/pypi/v/langbot-plugin)](https://pypi.org/project/langbot-plugin/)
8
+ [![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
9
+ [![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE)
10
+
11
+ [English](README.md) / 简体中文
12
+
13
+ [文档](https://docs.langbot.app/zh/plugin/dev/tutor) ·
14
+ [插件市场](https://space.langbot.app) ·
15
+ [LangBot](https://github.com/langbot-app/LangBot)
16
+
17
+ </div>
18
+
19
+ ## 简介
20
+
21
+ 此仓库是支撑 LangBot **插件系统**与**代码沙箱**的共享基础设施,以单一的
22
+ [`langbot-plugin`](https://pypi.org/project/langbot-plugin/) 包发布到 PyPI,包含三部分:
23
+
24
+ - **插件 SDK 与 CLI**(`lbp`)—— 插件开发的 Python API、基类,以及用于脚手架、
25
+ 构建、调试和发布插件的 `lbp` 命令。
26
+ - **插件运行时**(`lbp rt`)—— 负责发现、安装并运行插件的宿主进程,通过 stdio
27
+ 或 WebSocket 与 LangBot 通信。
28
+ - **Box 运行时**(`lbp box`)—— 支撑 LangBot Box 子系统的代码沙箱服务,通过
29
+ Docker / nsjail / E2B 后端执行不受信任的代码。
30
+
31
+ LangBot 通过 `pyproject.toml` 中固定的 `langbot-plugin==<x.y.z>` 依赖此包;
32
+ 版本号以本仓库的 `pyproject.toml` 为准。
33
+
34
+ > **运行时**组件(`src/langbot_plugin/runtime/`)单独采用 **AGPL** 许可证,
35
+ > 本仓库其余部分采用 **Apache 2.0**,详见
36
+ > [`src/langbot_plugin/runtime/README.md`](src/langbot_plugin/runtime/README.md)。
37
+
38
+ ## 安装
39
+
40
+ ```bash
41
+ pip install langbot-plugin
42
+ # 或(推荐)
43
+ uv tool install langbot-plugin
44
+
45
+ lbp --help
46
+ ```
47
+
48
+ ## CLI 速览
49
+
50
+ | 命令 | 作用 |
51
+ | --- | --- |
52
+ | `lbp init <name>` | 初始化一个插件项目 |
53
+ | `lbp comp <Type>` | 生成组件(Command / Tool / EventListener / KnowledgeEngine / Parser / Page) |
54
+ | `lbp run` | 针对运行中的 LangBot 运行 / 远程调试插件 |
55
+ | `lbp build` | 将插件打包为可分发的 zip |
56
+ | `lbp publish` | 发布到 LangBot 插件市场 |
57
+ | `lbp login` / `lbp logout` | 登录 / 登出 LangBot 账号 |
58
+ | `lbp rt` | 启动独立的插件运行时(控制端口 `5400`,调试端口 `5401`) |
59
+ | `lbp box` | 启动独立的 Box 代码沙箱运行时(默认端口 `5410`) |
60
+ | `lbp ver` | 打印 CLI / 包版本 |
61
+
62
+ ## 组件类型
63
+
64
+ 插件通过六种组件类型扩展 LangBot,使用 `lbp comp <Type>` 生成:
65
+
66
+ - **Command** —— 用户触发的指令(如 `!weather tokyo`)
67
+ - **Tool** —— 供 AI Agent 调用的 LLM 工具函数
68
+ - **EventListener** —— 消息流水线事件的处理器
69
+ - **KnowledgeEngine** —— 用于 RAG 的自定义知识库检索
70
+ - **Parser** —— 自定义消息 / 内容解析
71
+ - **Page** —— 嵌入 LangBot 管理面板的自定义网页
72
+
73
+ ## 文档
74
+
75
+ - 插件开发教程 —— https://docs.langbot.app/zh/plugin/dev/tutor
76
+ - 调试运行时 / CLI / SDK —— https://docs.langbot.app/zh/develop/plugin-runtime
77
+ - 开发环境配置 —— https://docs.langbot.app/zh/develop/dev-config
78
+
79
+ ## 许可证
80
+
81
+ 本仓库采用 Apache 2.0,但插件运行时(`src/langbot_plugin/runtime/`)单独采用
82
+ AGPL。详见 [LICENSE](LICENSE) 与
83
+ [运行时 README](src/langbot_plugin/runtime/README.md)。
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "langbot-plugin"
3
- version = "0.4.4"
3
+ version = "0.4.6"
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,277 @@
1
+ #!/usr/bin/env python3
2
+ """Static consistency check for the action-based runtime protocol.
3
+
4
+ The runtime protocol (``runtime/io/``) dispatches calls by action name: a sender
5
+ calls ``call_action(SomeAction.MEMBER, ...)`` and a receiver must have registered
6
+ a handler with ``@handler.action(SomeAction.MEMBER)``. If the handler is missing,
7
+ the call fails *at runtime* with ``ValueError: Action <name> not found`` — a class
8
+ of bug that unit tests miss because they mock the proxy layer, and that only shows
9
+ up end-to-end (this is exactly how ``vector_list`` shipped broken: the enum member,
10
+ the plugin-side proxy, and a proxy-level test all existed, but no runtime forwarder
11
+ was registered).
12
+
13
+ This checker parses the SDK with ``ast`` (no imports, no side effects) and enforces:
14
+
15
+ 1. ERROR: every action *invoked* in-repo (``call_action`` / ``call_action_generator``
16
+ with a literal ``EnumClass.MEMBER`` argument) has a matching ``.action(...)``
17
+ registration in-repo — UNLESS the action's receiver is an external process
18
+ (the LangBot host), whose handlers live in a different repository. This is the
19
+ invariant ``vector_list`` violated.
20
+ 2. ERROR: every ``EnumClass.MEMBER`` referenced by an invocation or registration
21
+ actually exists on that enum class (guards against typos / renames).
22
+ 3. WARN: enum members that are neither invoked nor registered anywhere in-repo —
23
+ candidate dead wiring ("enum without action"). Warning only, because a member
24
+ may legitimately be invoked or handled by the LangBot host (a separate repo).
25
+
26
+ Action enum classes follow the ``<Sender>To<Receiver>Action`` naming convention.
27
+ The *receiver* is what must hold the handler, so Rule 1 only applies when the
28
+ receiver lives in this repository (Runtime or Plugin); actions received by the
29
+ LangBot host are handled there and cannot be checked from here.
30
+
31
+ Known, accepted exceptions are listed in ``KNOWN_EXCEPTIONS`` with a reason so the
32
+ gate can go green on a branch while pre-existing debt is tracked explicitly rather
33
+ than hidden.
34
+
35
+ Exit code is non-zero if any unexpected ERROR is found. Run from the repo root:
36
+
37
+ python scripts/check_action_consistency.py
38
+ """
39
+
40
+ from __future__ import annotations
41
+
42
+ import ast
43
+ import sys
44
+ from pathlib import Path
45
+
46
+ REPO_ROOT = Path(__file__).resolve().parent.parent
47
+ SRC_ROOT = REPO_ROOT / "src" / "langbot_plugin"
48
+ ENUMS_FILE = SRC_ROOT / "entities" / "io" / "actions" / "enums.py"
49
+
50
+ INVOKE_METHODS = {"call_action", "call_action_generator"}
51
+ REGISTER_METHODS = {"action"}
52
+
53
+ # Receivers whose action handlers live in THIS repository. Actions whose receiver
54
+ # is anything else (e.g. the LangBot host) are handled in another repo, so Rule 1
55
+ # (invoked => registered) cannot and must not be enforced here.
56
+ IN_REPO_RECEIVERS = {"Runtime", "Plugin"}
57
+
58
+ # Accepted, documented exceptions to keep the gate green while tracking known debt.
59
+ # Map (EnumClassName, MEMBER) -> reason. Remove an entry once the underlying issue
60
+ # is fixed; the checker reports any entry that has become unnecessary.
61
+ KNOWN_EXCEPTIONS: dict[tuple[str, str], str] = {
62
+ # invoke_llm_stream_events() references this member, but on the 0.4.x line the
63
+ # enum member and its runtime forwarder are absent (both exist and are wired on
64
+ # feat/agent-runner-plugin). Tracked for forward-port; the LangBot host already
65
+ # registers PluginToRuntimeAction.INVOKE_LLM_STREAM.
66
+ ("PluginToRuntimeAction", "INVOKE_LLM_STREAM"): (
67
+ "streaming LLM forwarder not yet ported to this branch; see feat/agent-runner-plugin"
68
+ ),
69
+ }
70
+
71
+
72
+ class Ref:
73
+ """A literal ``EnumClass.MEMBER`` reference at a source location."""
74
+
75
+ __slots__ = ("enum", "member", "file", "line")
76
+
77
+ def __init__(self, enum: str, member: str, file: Path, line: int):
78
+ self.enum = enum
79
+ self.member = member
80
+ self.file = file
81
+ self.line = line
82
+
83
+ @property
84
+ def key(self) -> tuple[str, str]:
85
+ return (self.enum, self.member)
86
+
87
+ def where(self) -> str:
88
+ rel = self.file.relative_to(REPO_ROOT)
89
+ return f"{rel}:{self.line}"
90
+
91
+
92
+ def action_receiver(enum_name: str) -> str | None:
93
+ """Return the receiver segment of a ``<Sender>To<Receiver>Action`` enum name.
94
+
95
+ Returns ``None`` for names without a ``To`` segment (e.g. ``CommonAction``),
96
+ which are treated as in-repo.
97
+ """
98
+ if not enum_name.endswith("Action"):
99
+ return None
100
+ core = enum_name[: -len("Action")]
101
+ if "To" not in core:
102
+ return None
103
+ return core.rsplit("To", 1)[1]
104
+
105
+
106
+ def receiver_in_repo(enum_name: str) -> bool:
107
+ receiver = action_receiver(enum_name)
108
+ return receiver is None or receiver in IN_REPO_RECEIVERS
109
+
110
+
111
+ def load_enum_members() -> dict[str, set[str]]:
112
+ """Return {EnumClassName: {MEMBER, ...}} for every action enum class."""
113
+ tree = ast.parse(ENUMS_FILE.read_text(encoding="utf-8"), filename=str(ENUMS_FILE))
114
+ enums: dict[str, set[str]] = {}
115
+ for node in tree.body:
116
+ if not isinstance(node, ast.ClassDef):
117
+ continue
118
+ members: set[str] = set()
119
+ for stmt in node.body:
120
+ targets: list[ast.expr] = []
121
+ if isinstance(stmt, ast.Assign):
122
+ targets = stmt.targets
123
+ elif isinstance(stmt, ast.AnnAssign) and stmt.target is not None:
124
+ targets = [stmt.target]
125
+ for target in targets:
126
+ if isinstance(target, ast.Name) and target.id.isupper():
127
+ members.add(target.id)
128
+ if members:
129
+ enums[node.name] = members
130
+ return enums
131
+
132
+
133
+ def _enum_member_arg(arg: ast.expr, enum_names: set[str]) -> tuple[str, str] | None:
134
+ """If ``arg`` is ``EnumClass.MEMBER`` for a known enum, return (enum, member)."""
135
+ if (
136
+ isinstance(arg, ast.Attribute)
137
+ and isinstance(arg.value, ast.Name)
138
+ and arg.value.id in enum_names
139
+ ):
140
+ return (arg.value.id, arg.attr)
141
+ return None
142
+
143
+
144
+ def scan(enum_names: set[str]) -> tuple[list[Ref], list[Ref]]:
145
+ """Walk the source tree, returning (invocations, registrations)."""
146
+ invocations: list[Ref] = []
147
+ registrations: list[Ref] = []
148
+
149
+ for path in sorted(SRC_ROOT.rglob("*.py")):
150
+ try:
151
+ tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
152
+ except SyntaxError as exc: # pragma: no cover - defensive
153
+ print(f"WARN: could not parse {path}: {exc}", file=sys.stderr)
154
+ continue
155
+
156
+ for node in ast.walk(tree):
157
+ if not isinstance(node, ast.Call) or not isinstance(
158
+ node.func, ast.Attribute
159
+ ):
160
+ continue
161
+ method = node.func.attr
162
+ if not node.args:
163
+ continue
164
+ ref = _enum_member_arg(node.args[0], enum_names)
165
+ if ref is None:
166
+ continue
167
+ enum, member = ref
168
+ location = Ref(enum, member, path, node.lineno)
169
+ if method in INVOKE_METHODS:
170
+ invocations.append(location)
171
+ elif method in REGISTER_METHODS:
172
+ registrations.append(location)
173
+
174
+ return invocations, registrations
175
+
176
+
177
+ def main() -> int:
178
+ if not ENUMS_FILE.exists():
179
+ print(f"ERROR: enum file not found: {ENUMS_FILE}", file=sys.stderr)
180
+ return 2
181
+
182
+ enums = load_enum_members()
183
+ enum_names = set(enums)
184
+ invocations, registrations = scan(enum_names)
185
+
186
+ registered_keys = {ref.key for ref in registrations}
187
+ invoked_keys = {ref.key for ref in invocations}
188
+
189
+ errors: list[str] = []
190
+ acknowledged: list[str] = []
191
+ used_exceptions: set[tuple[str, str]] = set()
192
+
193
+ # Rule 2: referenced members must exist on their enum (typo / rename guard).
194
+ for ref in invocations + registrations:
195
+ if ref.member in enums.get(ref.enum, set()):
196
+ continue
197
+ if ref.key in KNOWN_EXCEPTIONS:
198
+ used_exceptions.add(ref.key)
199
+ acknowledged.append(
200
+ f"{ref.enum}.{ref.member} at {ref.where()} — {KNOWN_EXCEPTIONS[ref.key]}"
201
+ )
202
+ continue
203
+ errors.append(
204
+ f"unknown action member {ref.enum}.{ref.member} referenced at "
205
+ f"{ref.where()} (not defined in {ENUMS_FILE.name})"
206
+ )
207
+
208
+ # Rule 1: every invoked action whose receiver is in-repo must be registered.
209
+ for ref in invocations:
210
+ if not receiver_in_repo(ref.enum):
211
+ continue # receiver is the external LangBot host; handler lives there
212
+ if ref.key in registered_keys:
213
+ continue
214
+ if ref.key in KNOWN_EXCEPTIONS:
215
+ used_exceptions.add(ref.key)
216
+ acknowledged.append(
217
+ f"{ref.enum}.{ref.member} invoked at {ref.where()} but not registered "
218
+ f"— {KNOWN_EXCEPTIONS[ref.key]}"
219
+ )
220
+ continue
221
+ errors.append(
222
+ f"{ref.enum}.{ref.member} is invoked at {ref.where()} but no "
223
+ f"`.action({ref.enum}.{ref.member})` handler is registered anywhere in "
224
+ f'src/ — calls will fail at runtime with "Action {ref.member.lower()} not found"'
225
+ )
226
+
227
+ # Stale-allowlist guard: every KNOWN_EXCEPTIONS entry should still be needed.
228
+ for key in KNOWN_EXCEPTIONS:
229
+ if key not in used_exceptions:
230
+ errors.append(
231
+ f"stale KNOWN_EXCEPTIONS entry {key[0]}.{key[1]} — the underlying "
232
+ f"inconsistency is gone; remove it from {Path(__file__).name}"
233
+ )
234
+
235
+ # Rule 3 (warning): enum members with no invocation and no registration in-repo.
236
+ warnings: list[str] = []
237
+ for enum, members in sorted(enums.items()):
238
+ for member in sorted(members):
239
+ key = (enum, member)
240
+ if key not in invoked_keys and key not in registered_keys:
241
+ warnings.append(
242
+ f"{enum}.{member} is never invoked nor registered in src/ "
243
+ f"(handled by the LangBot host, or dead wiring?)"
244
+ )
245
+
246
+ print(
247
+ f"action-consistency: {len(enums)} enums, "
248
+ f"{len(invoked_keys)} invoked, {len(registered_keys)} registered"
249
+ )
250
+
251
+ if acknowledged:
252
+ print(f"\n{len(acknowledged)} known exception(s) (tracked debt):")
253
+ for line in acknowledged:
254
+ print(f" KNOWN: {line}")
255
+
256
+ if warnings:
257
+ print(f"\n{len(warnings)} warning(s):")
258
+ for line in warnings:
259
+ print(f" WARN: {line}")
260
+
261
+ if errors:
262
+ print(f"\n{len(errors)} error(s):", file=sys.stderr)
263
+ for line in errors:
264
+ print(f" ERROR: {line}", file=sys.stderr)
265
+ print(
266
+ "\nAction protocol consistency check FAILED. "
267
+ "Register the missing handler(s) or fix the reference.",
268
+ file=sys.stderr,
269
+ )
270
+ return 1
271
+
272
+ print("\nAction protocol consistency check passed.")
273
+ return 0
274
+
275
+
276
+ if __name__ == "__main__":
277
+ raise SystemExit(main())