langbot-plugin 0.4.3__tar.gz → 0.4.4__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 (242) hide show
  1. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/PKG-INFO +1 -1
  2. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/pyproject.toml +1 -1
  3. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/proxies/langbot_api.py +37 -0
  4. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/entities/io/actions/enums.py +2 -0
  5. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/controllers/stdio/client.py +3 -0
  6. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/handlers/control.py +11 -0
  7. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/handlers/plugin.py +24 -0
  8. langbot_plugin-0.4.4/src/langbot_plugin/runtime/plugin/logbuffer.py +125 -0
  9. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/plugin/mgr.py +21 -0
  10. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/proxies/test_langbot_api.py +18 -0
  11. langbot_plugin-0.4.4/tests/test_plugin_logbuffer.py +78 -0
  12. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/.github/workflows/cla.yml +0 -0
  13. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/.github/workflows/publish-pypi.yaml +0 -0
  14. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/.github/workflows/test.yml +0 -0
  15. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/.gitignore +0 -0
  16. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/.python-version +0 -0
  17. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/AGENTS.md +0 -0
  18. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/CLAUDE.md +0 -0
  19. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/CONTRIBUTING.md +0 -0
  20. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/LICENSE +0 -0
  21. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/README.md +0 -0
  22. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/data/.env.example +0 -0
  23. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/docs/Message.md +0 -0
  24. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/docs/PluginPages.md +0 -0
  25. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/docs/communication/apis/lb2rt.md +0 -0
  26. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/docs/communication/runtime_plugin.md +0 -0
  27. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/docs/dependency-management.md +0 -0
  28. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/docs/langbot-plugin-social.png +0 -0
  29. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/__init__.py +0 -0
  30. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/__init__.py +0 -0
  31. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/__init__.py +0 -0
  32. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/abstract/__init__.py +0 -0
  33. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/abstract/platform/__init__.py +0 -0
  34. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/abstract/platform/adapter.py +0 -0
  35. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/abstract/platform/event_logger.py +0 -0
  36. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/__init__.py +0 -0
  37. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/base.py +0 -0
  38. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/command/__init__.py +0 -0
  39. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/command/command.py +0 -0
  40. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/common/__init__.py +0 -0
  41. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/common/event_listener.py +0 -0
  42. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/knowledge_engine/__init__.py +0 -0
  43. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/knowledge_engine/engine.py +0 -0
  44. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/manifest.py +0 -0
  45. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/page/__init__.py +0 -0
  46. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/parser/__init__.py +0 -0
  47. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/parser/parser.py +0 -0
  48. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/tool/__init__.py +0 -0
  49. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/components/tool/tool.py +0 -0
  50. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/definition/plugin.py +0 -0
  51. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/__init__.py +0 -0
  52. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/__init__.py +0 -0
  53. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/command/__init__.py +0 -0
  54. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/command/context.py +0 -0
  55. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/command/errors.py +0 -0
  56. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/pipeline/__init__.py +0 -0
  57. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/pipeline/query.py +0 -0
  58. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/platform/__init__.py +0 -0
  59. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/platform/entities.py +0 -0
  60. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/platform/events.py +0 -0
  61. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/platform/logger.py +0 -0
  62. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/platform/message.py +0 -0
  63. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/provider/__init__.py +0 -0
  64. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/provider/message.py +0 -0
  65. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/provider/prompt.py +0 -0
  66. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/provider/session.py +0 -0
  67. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/rag/__init__.py +0 -0
  68. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/rag/context.py +0 -0
  69. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/rag/enums.py +0 -0
  70. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/rag/errors.py +0 -0
  71. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/rag/models.py +0 -0
  72. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/resource/__init__.py +0 -0
  73. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/builtin/resource/tool.py +0 -0
  74. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/context.py +0 -0
  75. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/entities/events.py +0 -0
  76. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/proxies/__init__.py +0 -0
  77. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/proxies/base.py +0 -0
  78. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/proxies/event_context.py +0 -0
  79. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/proxies/execute_context.py +0 -0
  80. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/api/proxies/query_based_api.py +0 -0
  81. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/__init__.py +0 -0
  82. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/langbot-page-sdk.js +0 -0
  83. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/.env.example.example +0 -0
  84. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/.github/workflows/release.yml.example +0 -0
  85. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/.gitignore.example +0 -0
  86. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/.vscode/launch.json.example +0 -0
  87. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/README.md.example +0 -0
  88. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/__init__.py +0 -0
  89. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/assets/icon.svg.example +0 -0
  90. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/__init__.py +0 -0
  91. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/commands/__init__.py +0 -0
  92. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.py.example +0 -0
  93. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/commands/{cmd_name}.yaml.example +0 -0
  94. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/event_listener/__init__.py +0 -0
  95. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/event_listener/default.py.example +0 -0
  96. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/event_listener/default.yaml.example +0 -0
  97. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/knowledge_engine/__init__.py +0 -0
  98. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.py.example +0 -0
  99. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/knowledge_engine/{knowledge_engine_name}.yaml.example +0 -0
  100. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/pages/{page_name}.html.example +0 -0
  101. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/pages/{page_name}.yaml.example +0 -0
  102. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/parser/__init__.py +0 -0
  103. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.py.example +0 -0
  104. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/parser/{parser_name}.yaml.example +0 -0
  105. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/tools/__init__.py +0 -0
  106. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.py.example +0 -0
  107. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/components/tools/{tool_name}.yaml.example +0 -0
  108. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/main.py.example +0 -0
  109. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/manifest.yaml.example +0 -0
  110. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/readme/README_zh_Hans.md.example +0 -0
  111. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/assets/templates/requirements.txt.example +0 -0
  112. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/__init__.py +0 -0
  113. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/actions.py +0 -0
  114. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/backend.py +0 -0
  115. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/client.py +0 -0
  116. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/e2b_backend.py +0 -0
  117. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/errors.py +0 -0
  118. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/models.py +0 -0
  119. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/nsjail_backend.py +0 -0
  120. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/runtime.py +0 -0
  121. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/security.py +0 -0
  122. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/server.py +0 -0
  123. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/box/skill_store.py +0 -0
  124. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/__init__.py +0 -0
  125. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/__main__.py +0 -0
  126. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/commands/__init__.py +0 -0
  127. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/commands/buildplugin.py +0 -0
  128. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/commands/gencomponent.py +0 -0
  129. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/commands/initplugin.py +0 -0
  130. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/commands/login.py +0 -0
  131. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/commands/logout.py +0 -0
  132. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/commands/publish.py +0 -0
  133. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/commands/runplugin.py +0 -0
  134. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/gen/__init__.py +0 -0
  135. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/gen/renderer.py +0 -0
  136. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/i18n.py +0 -0
  137. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/locales/__init__.py +0 -0
  138. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/locales/en_US.py +0 -0
  139. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/locales/es_ES.py +0 -0
  140. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/locales/ja_JP.py +0 -0
  141. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/locales/th_TH.py +0 -0
  142. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/locales/vi_VN.py +0 -0
  143. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/locales/zh_Hans.py +0 -0
  144. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/locales/zh_Hant.py +0 -0
  145. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/run/__init__.py +0 -0
  146. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/run/controller.py +0 -0
  147. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/run/handler.py +0 -0
  148. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/run/hotreload.py +0 -0
  149. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/utils/__init__.py +0 -0
  150. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/utils/cloudsv.py +0 -0
  151. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/utils/form.py +0 -0
  152. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/cli/utils/page_components.py +0 -0
  153. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/entities/__init__.py +0 -0
  154. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/entities/io/__init__.py +0 -0
  155. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/entities/io/actions/__init__.py +0 -0
  156. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/entities/io/errors.py +0 -0
  157. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/entities/io/req.py +0 -0
  158. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/entities/io/resp.py +0 -0
  159. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/entities/marketplace.py +0 -0
  160. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/LICENSE +0 -0
  161. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/README.md +0 -0
  162. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/__init__.py +0 -0
  163. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/app.py +0 -0
  164. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/context.py +0 -0
  165. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/helper/__init__.py +0 -0
  166. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/helper/marketplace.py +0 -0
  167. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/helper/pkgmgr.py +0 -0
  168. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/__init__.py +0 -0
  169. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/connection.py +0 -0
  170. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/connections/__init__.py +0 -0
  171. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/connections/stdio.py +0 -0
  172. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/connections/ws.py +0 -0
  173. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/controller.py +0 -0
  174. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/controllers/__init__.py +0 -0
  175. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/controllers/stdio/__init__.py +0 -0
  176. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/controllers/stdio/server.py +0 -0
  177. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/controllers/ws/__init__.py +0 -0
  178. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/controllers/ws/client.py +0 -0
  179. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/controllers/ws/server.py +0 -0
  180. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/handler.py +0 -0
  181. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/io/handlers/__init__.py +0 -0
  182. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/plugin/__init__.py +0 -0
  183. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/plugin/container.py +0 -0
  184. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/runtime/settings.py +0 -0
  185. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/utils/__init__.py +0 -0
  186. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/utils/discover/__init__.py +0 -0
  187. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/utils/discover/engine.py +0 -0
  188. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/utils/importutil.py +0 -0
  189. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/utils/log.py +0 -0
  190. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/utils/platform.py +0 -0
  191. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/src/langbot_plugin/version.py +0 -0
  192. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/__init__.py +0 -0
  193. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/definition/components/test_components.py +0 -0
  194. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/definition/test_manifest.py +0 -0
  195. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/entities/builtin/test_command_context.py +0 -0
  196. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/entities/builtin/test_platform_logger.py +0 -0
  197. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/entities/builtin/test_provider_message.py +0 -0
  198. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/entities/builtin/test_rag_models.py +0 -0
  199. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/entities/test_context.py +0 -0
  200. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/entities/test_events.py +0 -0
  201. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/proxies/test_base.py +0 -0
  202. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/api/proxies/test_query_based_api.py +0 -0
  203. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/box/__init__.py +0 -0
  204. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/box/test_backend.py +0 -0
  205. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/box/test_backend_selection.py +0 -0
  206. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/box/test_client.py +0 -0
  207. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/box/test_e2b_backend.py +0 -0
  208. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/box/test_nsjail_backend.py +0 -0
  209. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/box/test_runtime.py +0 -0
  210. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/box/test_server.py +0 -0
  211. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/box/test_skill_store.py +0 -0
  212. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/run/test_controller.py +0 -0
  213. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/run/test_runtime_handler.py +0 -0
  214. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/test_buildplugin.py +0 -0
  215. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/test_gencomponent.py +0 -0
  216. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/test_i18n_form.py +0 -0
  217. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/test_initplugin.py +0 -0
  218. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/test_login.py +0 -0
  219. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/test_logout_publish.py +0 -0
  220. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/test_page_components.py +0 -0
  221. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/test_renderer.py +0 -0
  222. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/cli/test_runplugin.py +0 -0
  223. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/entities/io/test_dependency_errors.py +0 -0
  224. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/entities/io/test_protocol.py +0 -0
  225. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/helpers/__init__.py +0 -0
  226. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/helpers/protocol.py +0 -0
  227. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/helper/test_marketplace.py +0 -0
  228. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/helper/test_pkgmgr.py +0 -0
  229. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/io/handlers/test_control_handler.py +0 -0
  230. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/io/handlers/test_import_contracts.py +0 -0
  231. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/io/handlers/test_plugin_handler.py +0 -0
  232. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/io/test_connections.py +0 -0
  233. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/io/test_controllers.py +0 -0
  234. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/io/test_handler.py +0 -0
  235. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/plugin/test_container.py +0 -0
  236. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/plugin/test_manager.py +0 -0
  237. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/runtime/test_app.py +0 -0
  238. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/test_log.py +0 -0
  239. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/test_message.py +0 -0
  240. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/utils/test_discovery.py +0 -0
  241. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/utils/test_importutil.py +0 -0
  242. {langbot_plugin-0.4.3 → langbot_plugin-0.4.4}/tests/utils/test_platform.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langbot-plugin
3
- Version: 0.4.3
3
+ Version: 0.4.4
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.4.3"
3
+ version = "0.4.4"
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 = [
@@ -284,6 +284,43 @@ class LangBotAPIProxy:
284
284
  )
285
285
  )["vectors"]
286
286
 
287
+ async def invoke_rerank(
288
+ self,
289
+ rerank_model_uuid: str,
290
+ query: str,
291
+ documents: list[str],
292
+ top_k: int | None = None,
293
+ extra_args: dict[str, Any] | None = None,
294
+ timeout: float = 60.0,
295
+ ) -> list[dict[str, Any]]:
296
+ """Rerank documents using Host's rerank model.
297
+
298
+ Args:
299
+ rerank_model_uuid: The UUID of the rerank model to use.
300
+ query: Query text used to score document relevance.
301
+ documents: Candidate document texts to rerank.
302
+ top_k: Optional number of scored results to return.
303
+ extra_args: Optional provider-specific arguments.
304
+ timeout: Request timeout in seconds.
305
+
306
+ Returns:
307
+ List of score dicts, usually containing ``index`` and
308
+ ``relevance_score``.
309
+ """
310
+ return (
311
+ await self.plugin_runtime_handler.call_action(
312
+ PluginToRuntimeAction.INVOKE_RERANK,
313
+ {
314
+ "rerank_model_uuid": rerank_model_uuid,
315
+ "query": query,
316
+ "documents": documents,
317
+ "top_k": top_k,
318
+ "extra_args": extra_args or {},
319
+ },
320
+ timeout=timeout,
321
+ )
322
+ )["results"]
323
+
287
324
  async def vector_upsert(
288
325
  self,
289
326
  collection_id: str,
@@ -61,6 +61,7 @@ class PluginToRuntimeAction(ActionType):
61
61
  CALL_TOOL = "call_tool"
62
62
 
63
63
  INVOKE_EMBEDDING = "invoke_embedding"
64
+ INVOKE_RERANK = "invoke_rerank"
64
65
  VECTOR_UPSERT = "vector_upsert"
65
66
  VECTOR_SEARCH = "vector_search"
66
67
  VECTOR_DELETE = "vector_delete"
@@ -111,6 +112,7 @@ class LangBotToRuntimeAction(ActionType):
111
112
  GET_PLUGIN_INFO = "get_plugin_info"
112
113
  GET_PLUGIN_ICON = "get_plugin_icon"
113
114
  GET_PLUGIN_README = "get_plugin_readme"
115
+ GET_PLUGIN_LOGS = "get_plugin_logs"
114
116
  GET_PLUGIN_ASSETS_FILE = "get_plugin_assets_file"
115
117
  INSTALL_PLUGIN = "install_plugin"
116
118
  RESTART_PLUGIN = "restart_plugin"
@@ -34,6 +34,9 @@ class StdioClientController(Controller):
34
34
  *self.args,
35
35
  stdin=asyncio.subprocess.PIPE,
36
36
  stdout=asyncio.subprocess.PIPE,
37
+ # Capture stderr (where the plugin's Python `logging` output goes)
38
+ # so the runtime can buffer per-plugin logs for the detail page.
39
+ stderr=asyncio.subprocess.PIPE,
37
40
  env=self.env,
38
41
  cwd=self.working_dir,
39
42
  )
@@ -106,6 +106,17 @@ class ControlConnectionHandler(handler.Handler):
106
106
  else:
107
107
  return handler.ActionResponse.success({"readme_file_key": None})
108
108
 
109
+ @self.action(LangBotToRuntimeAction.GET_PLUGIN_LOGS)
110
+ async def get_plugin_logs(data: dict[str, Any]) -> handler.ActionResponse:
111
+ author = data["plugin_author"]
112
+ plugin_name = data["plugin_name"]
113
+ limit = int(data.get("limit", 200))
114
+ level = data.get("level") or None
115
+ logs = await self.context.plugin_mgr.get_plugin_logs(
116
+ author, plugin_name, limit=limit, level=level
117
+ )
118
+ return handler.ActionResponse.success({"logs": logs})
119
+
109
120
  @self.action(LangBotToRuntimeAction.GET_PLUGIN_ASSETS_FILE)
110
121
  async def get_plugin_assets_file(
111
122
  data: dict[str, Any],
@@ -13,6 +13,7 @@ from langbot_plugin.entities.io.actions.enums import (
13
13
  from langbot_plugin.runtime import context as context_module
14
14
  import asyncio
15
15
  from langbot_plugin.runtime.settings import settings as runtime_settings
16
+ from langbot_plugin.runtime.plugin.logbuffer import PluginLogBuffer
16
17
 
17
18
  logger = logging.getLogger(__name__)
18
19
 
@@ -31,6 +32,9 @@ class PluginConnectionHandler(handler.Handler):
31
32
  stdio_process: asyncio.subprocess.Process | None = None
32
33
  """The stdio process of the plugin."""
33
34
 
35
+ log_buffer: PluginLogBuffer
36
+ """Ring buffer holding recent log lines (from the plugin's stderr)."""
37
+
34
38
  subprocess_on_windows_task: asyncio.Task | None = None
35
39
  """The task for the subprocess on Windows."""
36
40
 
@@ -59,6 +63,15 @@ class PluginConnectionHandler(handler.Handler):
59
63
  self.debug_plugin = debug_plugin
60
64
  self.stdio_process = stdio_process
61
65
 
66
+ # Capture the plugin subprocess's stderr (Python `logging` output) into
67
+ # a per-plugin ring buffer so LangBot can show logs on the detail page.
68
+ self.log_buffer = PluginLogBuffer()
69
+ if (
70
+ self.stdio_process is not None
71
+ and self.stdio_process.stderr is not None
72
+ ):
73
+ self.log_buffer.start_reader(self.stdio_process.stderr)
74
+
62
75
  @self.action(PluginToRuntimeAction.REGISTER_PLUGIN)
63
76
  async def register_plugin(data: dict[str, Any]) -> handler.ActionResponse:
64
77
 
@@ -232,6 +245,17 @@ class PluginConnectionHandler(handler.Handler):
232
245
  )
233
246
  return handler.ActionResponse.success(result)
234
247
 
248
+ @self.action(PluginToRuntimeAction.INVOKE_RERANK)
249
+ async def invoke_rerank(data: dict[str, Any]) -> handler.ActionResponse:
250
+ result = await self.context.control_handler.call_action(
251
+ PluginToRuntimeAction.INVOKE_RERANK,
252
+ {
253
+ **data,
254
+ },
255
+ timeout=60,
256
+ )
257
+ return handler.ActionResponse.success(result)
258
+
235
259
  # ================= RAG Capability Handlers (Plugin -> Runtime -> Host) =================
236
260
 
237
261
  async def _proxy_rag_action(
@@ -0,0 +1,125 @@
1
+ # Plugin log buffer: captures a plugin subprocess's stderr (where Python
2
+ # `logging` output is emitted) into a bounded in-memory ring buffer so that
3
+ # LangBot can display per-plugin logs on the plugin detail page.
4
+
5
+ from __future__ import annotations
6
+
7
+ import asyncio
8
+ import collections
9
+ import logging
10
+ import re
11
+ import time
12
+ import typing
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ # Matches the standard SDK log line produced by
17
+ # `langbot_plugin.utils.log.configure_process_logging`, e.g.:
18
+ # [06-13 10:30:00.123] main.py (45) - [INFO] : This is an info message
19
+ # We only need the level here; the rest is kept verbatim as the message text.
20
+ _LEVEL_RE = re.compile(r"^\[[^\]]+\]\s.*?-\s\[(?P<level>[A-Z]+)\]\s:\s")
21
+
22
+ # Known logging level names, used to validate the parsed token.
23
+ _KNOWN_LEVELS = {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}
24
+
25
+ # Default ring-buffer capacity (number of log lines retained per plugin).
26
+ DEFAULT_MAX_LINES = 1000
27
+
28
+
29
+ class PluginLogBuffer:
30
+ """A bounded ring buffer holding recent log lines for a single plugin.
31
+
32
+ Each entry is a dict: {"ts": float, "level": str, "text": str}.
33
+ `level` is best-effort parsed from the line; continuation lines (e.g.
34
+ multi-line tracebacks) inherit the previous entry's level.
35
+ """
36
+
37
+ def __init__(self, max_lines: int = DEFAULT_MAX_LINES) -> None:
38
+ self._buffer: collections.deque[dict[str, typing.Any]] = collections.deque(
39
+ maxlen=max_lines
40
+ )
41
+ self._last_level: str = "INFO"
42
+ self._reader_task: asyncio.Task | None = None
43
+
44
+ def add_line(self, raw_line: str) -> None:
45
+ """Parse and append a single raw stderr line to the buffer."""
46
+ text = raw_line.rstrip("\n").rstrip("\r")
47
+ if text.strip() == "":
48
+ return
49
+
50
+ match = _LEVEL_RE.match(text)
51
+ if match:
52
+ level = match.group("level")
53
+ if level not in _KNOWN_LEVELS:
54
+ level = self._last_level
55
+ else:
56
+ self._last_level = level
57
+ else:
58
+ # Continuation line (traceback / multi-line message): inherit level.
59
+ level = self._last_level
60
+
61
+ self._buffer.append(
62
+ {
63
+ "ts": time.time(),
64
+ "level": level,
65
+ "text": text,
66
+ }
67
+ )
68
+
69
+ def get_logs(
70
+ self,
71
+ limit: int = 200,
72
+ level: str | None = None,
73
+ ) -> list[dict[str, typing.Any]]:
74
+ """Return the most recent log entries.
75
+
76
+ Args:
77
+ limit: Max number of entries to return (most recent first-in-order).
78
+ level: Optional minimum level filter (e.g. "WARNING" returns
79
+ WARNING/ERROR/CRITICAL only). None returns all levels.
80
+ """
81
+ entries = list(self._buffer)
82
+
83
+ if level:
84
+ min_no = logging.getLevelName(level)
85
+ if isinstance(min_no, int):
86
+ entries = [
87
+ e
88
+ for e in entries
89
+ if _level_no(e["level"]) >= min_no
90
+ ]
91
+
92
+ if limit and limit > 0:
93
+ entries = entries[-limit:]
94
+
95
+ return entries
96
+
97
+ def clear(self) -> None:
98
+ self._buffer.clear()
99
+
100
+ async def attach_stream(self, stream: asyncio.StreamReader) -> None:
101
+ """Continuously read lines from a stream into the buffer until EOF."""
102
+ try:
103
+ while True:
104
+ line_bytes = await stream.readline()
105
+ if not line_bytes:
106
+ break
107
+ self.add_line(line_bytes.decode("utf-8", errors="replace"))
108
+ except Exception as e: # noqa: BLE001 - reader must never crash the runtime
109
+ logger.debug(f"Plugin log stream reader stopped: {e}")
110
+
111
+ def start_reader(self, stream: asyncio.StreamReader) -> None:
112
+ """Spawn a background task reading the given stream into the buffer."""
113
+ if self._reader_task is not None and not self._reader_task.done():
114
+ return
115
+ self._reader_task = asyncio.create_task(self.attach_stream(stream))
116
+
117
+ def stop_reader(self) -> None:
118
+ if self._reader_task is not None and not self._reader_task.done():
119
+ self._reader_task.cancel()
120
+ self._reader_task = None
121
+
122
+
123
+ def _level_no(level_name: str) -> int:
124
+ no = logging.getLevelName(level_name)
125
+ return no if isinstance(no, int) else logging.INFO
@@ -729,6 +729,27 @@ class PluginManager:
729
729
 
730
730
  return b""
731
731
 
732
+ async def get_plugin_logs(
733
+ self,
734
+ plugin_author: str,
735
+ plugin_name: str,
736
+ limit: int = 200,
737
+ level: str | None = None,
738
+ ) -> list[dict[str, typing.Any]]:
739
+ """Return recent log entries captured from the plugin's stderr.
740
+
741
+ Each entry: {"ts": float, "level": str, "text": str}.
742
+ Returns an empty list if the plugin is not running.
743
+ """
744
+ plugin = self.find_plugin(plugin_author, plugin_name)
745
+ if plugin is not None and plugin._runtime_plugin_handler is not None:
746
+ log_buffer = getattr(
747
+ plugin._runtime_plugin_handler, "log_buffer", None
748
+ )
749
+ if log_buffer is not None:
750
+ return log_buffer.get_logs(limit=limit, level=level)
751
+ return []
752
+
732
753
  async def get_plugin_assets_file(
733
754
  self, plugin_author: str, plugin_name: str, file_key: str
734
755
  ) -> tuple[bytes, str]:
@@ -146,6 +146,9 @@ async def test_tool_and_rag_helpers_preserve_payload_contracts():
146
146
  PluginToRuntimeAction.GET_TOOL_DETAIL: {"tool": {"name": "tool"}},
147
147
  PluginToRuntimeAction.CALL_TOOL: {"tool_response": {"ok": True}},
148
148
  PluginToRuntimeAction.INVOKE_EMBEDDING: {"vectors": [[0.1]]},
149
+ PluginToRuntimeAction.INVOKE_RERANK: {
150
+ "results": [{"index": 0, "relevance_score": 0.9}]
151
+ },
149
152
  PluginToRuntimeAction.VECTOR_SEARCH: {"results": [{"id": "1"}]},
150
153
  PluginToRuntimeAction.VECTOR_DELETE: {"count": 2},
151
154
  PluginToRuntimeAction.VECTOR_LIST: {"items": [], "total": 0},
@@ -161,6 +164,9 @@ async def test_tool_and_rag_helpers_preserve_payload_contracts():
161
164
  assert await proxy.get_tool_detail("tool") == {"name": "tool"}
162
165
  assert await proxy.call_tool("tool", {"q": 1}, {"s": 1}, 7) == {"ok": True}
163
166
  assert await proxy.invoke_embedding("embed", ["hi"]) == [[0.1]]
167
+ assert await proxy.invoke_rerank(
168
+ "rerank", "query", ["doc"], top_k=1, extra_args={"return_documents": False}
169
+ ) == [{"index": 0, "relevance_score": 0.9}]
164
170
  await proxy.vector_upsert("c", [[0.1]], ["id"], documents=["doc"])
165
171
  assert await proxy.vector_search("c", [0.1], filters={"a": 1}) == [{"id": "1"}]
166
172
  assert await proxy.vector_delete("c", file_ids=["f"]) == 2
@@ -174,6 +180,18 @@ async def test_tool_and_rag_helpers_preserve_payload_contracts():
174
180
  assert call_tool_call[1]["tool_parameters"] == {"q": 1}
175
181
  assert call_tool_call[2] == 180
176
182
 
183
+ rerank_call = [
184
+ call for call in handler.calls if call[0] is PluginToRuntimeAction.INVOKE_RERANK
185
+ ][0]
186
+ assert rerank_call[1] == {
187
+ "rerank_model_uuid": "rerank",
188
+ "query": "query",
189
+ "documents": ["doc"],
190
+ "top_k": 1,
191
+ "extra_args": {"return_documents": False},
192
+ }
193
+ assert rerank_call[2] == 60.0
194
+
177
195
 
178
196
  @pytest.mark.asyncio
179
197
  async def test_get_knowledge_file_stream_reads_and_deletes_local_chunk_file():
@@ -0,0 +1,78 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+
5
+ from langbot_plugin.runtime.plugin.logbuffer import PluginLogBuffer
6
+
7
+
8
+ def test_parses_standard_log_line_level():
9
+ buf = PluginLogBuffer()
10
+ buf.add_line(
11
+ "[06-13 10:30:00.123] main.py (45) - [INFO] : hello world"
12
+ )
13
+ logs = buf.get_logs()
14
+ assert len(logs) == 1
15
+ assert logs[0]["level"] == "INFO"
16
+ assert logs[0]["text"].endswith("hello world")
17
+
18
+
19
+ def test_continuation_line_inherits_level():
20
+ buf = PluginLogBuffer()
21
+ buf.add_line(
22
+ "[06-13 10:30:00.123] main.py (45) - [ERROR] : boom"
23
+ )
24
+ buf.add_line("Traceback (most recent call last):")
25
+ buf.add_line(' File "x.py", line 1, in <module>')
26
+ logs = buf.get_logs()
27
+ assert len(logs) == 3
28
+ assert all(e["level"] == "ERROR" for e in logs)
29
+
30
+
31
+ def test_level_filter():
32
+ buf = PluginLogBuffer()
33
+ buf.add_line("[06-13 10:30:00.1] a.py (1) - [INFO] : i")
34
+ buf.add_line("[06-13 10:30:00.2] a.py (2) - [WARNING] : w")
35
+ buf.add_line("[06-13 10:30:00.3] a.py (3) - [ERROR] : e")
36
+ warn_and_up = buf.get_logs(level="WARNING")
37
+ assert [e["level"] for e in warn_and_up] == ["WARNING", "ERROR"]
38
+
39
+
40
+ def test_ring_buffer_cap():
41
+ buf = PluginLogBuffer(max_lines=5)
42
+ for i in range(20):
43
+ buf.add_line(f"[06-13 10:30:00.1] a.py (1) - [INFO] : line {i}")
44
+ logs = buf.get_logs(limit=100)
45
+ assert len(logs) == 5
46
+ assert logs[-1]["text"].endswith("line 19")
47
+
48
+
49
+ def test_limit():
50
+ buf = PluginLogBuffer()
51
+ for i in range(50):
52
+ buf.add_line(f"[06-13 10:30:00.1] a.py (1) - [INFO] : line {i}")
53
+ logs = buf.get_logs(limit=10)
54
+ assert len(logs) == 10
55
+ assert logs[-1]["text"].endswith("line 49")
56
+
57
+
58
+ def test_empty_lines_skipped():
59
+ buf = PluginLogBuffer()
60
+ buf.add_line("")
61
+ buf.add_line(" \n")
62
+ assert buf.get_logs() == []
63
+
64
+
65
+ def test_attach_stream_reads_to_eof():
66
+ async def run():
67
+ reader = asyncio.StreamReader()
68
+ reader.feed_data(
69
+ b"[06-13 10:30:00.1] a.py (1) - [INFO] : streamed\n"
70
+ )
71
+ reader.feed_eof()
72
+ buf = PluginLogBuffer()
73
+ await buf.attach_stream(reader)
74
+ return buf.get_logs()
75
+
76
+ logs = asyncio.run(run())
77
+ assert len(logs) == 1
78
+ assert logs[0]["text"].endswith("streamed")
File without changes
File without changes
File without changes
File without changes