cloakbot 0.2.1b1__py3-none-any.whl

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 (608) hide show
  1. cloakbot/__init__.py +49 -0
  2. cloakbot/__main__.py +8 -0
  3. cloakbot/agent/__init__.py +19 -0
  4. cloakbot/agent/autocompact.py +96 -0
  5. cloakbot/agent/context.py +280 -0
  6. cloakbot/agent/hook.py +141 -0
  7. cloakbot/agent/loop.py +1968 -0
  8. cloakbot/agent/memory.py +955 -0
  9. cloakbot/agent/model_presets.py +65 -0
  10. cloakbot/agent/progress_hook.py +178 -0
  11. cloakbot/agent/runner.py +1453 -0
  12. cloakbot/agent/skills.py +242 -0
  13. cloakbot/agent/subagent.py +401 -0
  14. cloakbot/agent/tools/__init__.py +31 -0
  15. cloakbot/agent/tools/apply_patch.py +290 -0
  16. cloakbot/agent/tools/base.py +296 -0
  17. cloakbot/agent/tools/cli_apps.py +133 -0
  18. cloakbot/agent/tools/context.py +60 -0
  19. cloakbot/agent/tools/cron.py +295 -0
  20. cloakbot/agent/tools/exec_session.py +598 -0
  21. cloakbot/agent/tools/file_state.py +205 -0
  22. cloakbot/agent/tools/filesystem.py +1046 -0
  23. cloakbot/agent/tools/image_generation.py +218 -0
  24. cloakbot/agent/tools/loader.py +116 -0
  25. cloakbot/agent/tools/long_task.py +272 -0
  26. cloakbot/agent/tools/mcp.py +1096 -0
  27. cloakbot/agent/tools/message.py +273 -0
  28. cloakbot/agent/tools/path_utils.py +30 -0
  29. cloakbot/agent/tools/registry.py +125 -0
  30. cloakbot/agent/tools/runtime_state.py +62 -0
  31. cloakbot/agent/tools/sandbox.py +55 -0
  32. cloakbot/agent/tools/schema.py +232 -0
  33. cloakbot/agent/tools/search.py +584 -0
  34. cloakbot/agent/tools/self.py +484 -0
  35. cloakbot/agent/tools/shell.py +652 -0
  36. cloakbot/agent/tools/spawn.py +96 -0
  37. cloakbot/agent/tools/web.py +864 -0
  38. cloakbot/api/__init__.py +1 -0
  39. cloakbot/api/server.py +399 -0
  40. cloakbot/apps/__init__.py +5 -0
  41. cloakbot/apps/cli/__init__.py +13 -0
  42. cloakbot/apps/cli/service.py +1238 -0
  43. cloakbot/apps/cli/utils.py +62 -0
  44. cloakbot/apps/protocol.py +56 -0
  45. cloakbot/bridge/.nvmrc +1 -0
  46. cloakbot/bridge/package-lock.json +1416 -0
  47. cloakbot/bridge/package.json +26 -0
  48. cloakbot/bridge/src/index.ts +56 -0
  49. cloakbot/bridge/src/server.ts +155 -0
  50. cloakbot/bridge/src/types.d.ts +3 -0
  51. cloakbot/bridge/src/whatsapp.ts +293 -0
  52. cloakbot/bridge/tsconfig.json +16 -0
  53. cloakbot/bus/__init__.py +6 -0
  54. cloakbot/bus/events.py +53 -0
  55. cloakbot/bus/progress.py +70 -0
  56. cloakbot/bus/queue.py +44 -0
  57. cloakbot/bus/runtime_events.py +251 -0
  58. cloakbot/channels/__init__.py +6 -0
  59. cloakbot/channels/base.py +270 -0
  60. cloakbot/channels/dingtalk.py +759 -0
  61. cloakbot/channels/discord.py +818 -0
  62. cloakbot/channels/email.py +739 -0
  63. cloakbot/channels/feishu.py +1917 -0
  64. cloakbot/channels/manager.py +535 -0
  65. cloakbot/channels/matrix.py +1022 -0
  66. cloakbot/channels/mochat.py +943 -0
  67. cloakbot/channels/msteams.py +822 -0
  68. cloakbot/channels/napcat.py +579 -0
  69. cloakbot/channels/qq.py +701 -0
  70. cloakbot/channels/registry.py +95 -0
  71. cloakbot/channels/signal.py +1402 -0
  72. cloakbot/channels/slack.py +729 -0
  73. cloakbot/channels/telegram.py +1453 -0
  74. cloakbot/channels/websocket.py +1173 -0
  75. cloakbot/channels/websocket_privacy.py +185 -0
  76. cloakbot/channels/wecom.py +554 -0
  77. cloakbot/channels/weixin.py +1546 -0
  78. cloakbot/channels/whatsapp.py +383 -0
  79. cloakbot/cli/__init__.py +1 -0
  80. cloakbot/cli/commands.py +1940 -0
  81. cloakbot/cli/models.py +31 -0
  82. cloakbot/cli/onboard.py +1396 -0
  83. cloakbot/cli/stream.py +230 -0
  84. cloakbot/cloakbot.py +110 -0
  85. cloakbot/command/__init__.py +6 -0
  86. cloakbot/command/builtin.py +686 -0
  87. cloakbot/command/router.py +88 -0
  88. cloakbot/config/__init__.py +34 -0
  89. cloakbot/config/loader.py +177 -0
  90. cloakbot/config/paths.py +76 -0
  91. cloakbot/config/schema.py +590 -0
  92. cloakbot/cron/__init__.py +18 -0
  93. cloakbot/cron/service.py +664 -0
  94. cloakbot/cron/types.py +83 -0
  95. cloakbot/pairing/__init__.py +33 -0
  96. cloakbot/pairing/store.py +254 -0
  97. cloakbot/privacy/__init__.py +6 -0
  98. cloakbot/privacy/agents/__init__.py +15 -0
  99. cloakbot/privacy/agents/base.py +17 -0
  100. cloakbot/privacy/agents/classification/intent_analyzer.py +60 -0
  101. cloakbot/privacy/agents/workers/chat_agent.py +25 -0
  102. cloakbot/privacy/agents/workers/math_agent.py +22 -0
  103. cloakbot/privacy/compaction.py +326 -0
  104. cloakbot/privacy/compaction_provider.py +171 -0
  105. cloakbot/privacy/core/__init__.py +29 -0
  106. cloakbot/privacy/core/detection/chunking/__init__.py +67 -0
  107. cloakbot/privacy/core/detection/chunking/base.py +65 -0
  108. cloakbot/privacy/core/detection/chunking/html.py +122 -0
  109. cloakbot/privacy/core/detection/chunking/json_chunker.py +126 -0
  110. cloakbot/privacy/core/detection/chunking/markdown.py +150 -0
  111. cloakbot/privacy/core/detection/chunking/sniffer.py +81 -0
  112. cloakbot/privacy/core/detection/chunking/text.py +152 -0
  113. cloakbot/privacy/core/detection/detector.py +137 -0
  114. cloakbot/privacy/core/detection/digit_detector.py +105 -0
  115. cloakbot/privacy/core/detection/general_detector.py +335 -0
  116. cloakbot/privacy/core/detection/llm_json.py +174 -0
  117. cloakbot/privacy/core/detection/tool_detector.py +249 -0
  118. cloakbot/privacy/core/math/math_executor.py +328 -0
  119. cloakbot/privacy/core/math/math_helpers.py +184 -0
  120. cloakbot/privacy/core/sanitization/alias_resolver.py +97 -0
  121. cloakbot/privacy/core/sanitization/handler.py +129 -0
  122. cloakbot/privacy/core/sanitization/restorer.py +168 -0
  123. cloakbot/privacy/core/sanitization/sanitize.py +244 -0
  124. cloakbot/privacy/core/state/vault.py +838 -0
  125. cloakbot/privacy/core/types.py +267 -0
  126. cloakbot/privacy/document_redaction.py +109 -0
  127. cloakbot/privacy/egress_policy.py +284 -0
  128. cloakbot/privacy/goal_at_rest.py +65 -0
  129. cloakbot/privacy/hooks/context.py +51 -0
  130. cloakbot/privacy/hooks/post_llm.py +21 -0
  131. cloakbot/privacy/hooks/pre_llm.py +33 -0
  132. cloakbot/privacy/prompting/__init__.py +19 -0
  133. cloakbot/privacy/prompting/system_prompt.py +58 -0
  134. cloakbot/privacy/prompting/templates/privacy_mode.md +28 -0
  135. cloakbot/privacy/protocol/__init__.py +26 -0
  136. cloakbot/privacy/protocol/contracts.py +123 -0
  137. cloakbot/privacy/protocol/metrics.py +34 -0
  138. cloakbot/privacy/protocol/observability.py +85 -0
  139. cloakbot/privacy/protocol/replay.py +85 -0
  140. cloakbot/privacy/provider_egress_gate.py +197 -0
  141. cloakbot/privacy/runtime/__init__.py +3 -0
  142. cloakbot/privacy/runtime/pipeline.py +686 -0
  143. cloakbot/privacy/runtime/registry.py +15 -0
  144. cloakbot/privacy/runtime/routing.py +17 -0
  145. cloakbot/privacy/runtime/streaming_restorer.py +105 -0
  146. cloakbot/privacy/runtime/streaming_sanitizer.py +242 -0
  147. cloakbot/privacy/runtime/tool_interceptor.py +723 -0
  148. cloakbot/privacy/tool_models.py +143 -0
  149. cloakbot/privacy/transparency/report.py +180 -0
  150. cloakbot/privacy/visual_egress_gate.py +347 -0
  151. cloakbot/privacy/visual_redaction.py +1156 -0
  152. cloakbot/privacy/webui/__init__.py +45 -0
  153. cloakbot/privacy/webui/builders.py +224 -0
  154. cloakbot/privacy/webui/contracts.py +202 -0
  155. cloakbot/privacy/webui/history.py +69 -0
  156. cloakbot/privacy/webui/side_channel.py +328 -0
  157. cloakbot/providers/__init__.py +45 -0
  158. cloakbot/providers/anthropic_provider.py +692 -0
  159. cloakbot/providers/azure_openai_provider.py +186 -0
  160. cloakbot/providers/base.py +843 -0
  161. cloakbot/providers/bedrock_provider.py +760 -0
  162. cloakbot/providers/detector.py +77 -0
  163. cloakbot/providers/factory.py +248 -0
  164. cloakbot/providers/fallback_provider.py +273 -0
  165. cloakbot/providers/github_copilot_provider.py +261 -0
  166. cloakbot/providers/image_generation.py +1603 -0
  167. cloakbot/providers/openai_codex_provider.py +321 -0
  168. cloakbot/providers/openai_compat_provider.py +1486 -0
  169. cloakbot/providers/openai_responses/__init__.py +31 -0
  170. cloakbot/providers/openai_responses/converters.py +127 -0
  171. cloakbot/providers/openai_responses/parsing.py +424 -0
  172. cloakbot/providers/registry.py +533 -0
  173. cloakbot/providers/transcription.py +221 -0
  174. cloakbot/security/__init__.py +1 -0
  175. cloakbot/security/network.py +159 -0
  176. cloakbot/security/workspace_access.py +430 -0
  177. cloakbot/security/workspace_policy.py +85 -0
  178. cloakbot/session/__init__.py +5 -0
  179. cloakbot/session/goal_state.py +126 -0
  180. cloakbot/session/manager.py +749 -0
  181. cloakbot/session/turn_continuation.py +240 -0
  182. cloakbot/session/webui_turns.py +449 -0
  183. cloakbot/skills/README.md +32 -0
  184. cloakbot/skills/clawhub/SKILL.md +53 -0
  185. cloakbot/skills/cron/SKILL.md +57 -0
  186. cloakbot/skills/github/SKILL.md +48 -0
  187. cloakbot/skills/image-generation/SKILL.md +66 -0
  188. cloakbot/skills/long-goal/SKILL.md +79 -0
  189. cloakbot/skills/memory/SKILL.md +36 -0
  190. cloakbot/skills/my/SKILL.md +72 -0
  191. cloakbot/skills/my/references/examples.md +75 -0
  192. cloakbot/skills/skill-creator/SKILL.md +374 -0
  193. cloakbot/skills/skill-creator/scripts/init_skill.py +378 -0
  194. cloakbot/skills/skill-creator/scripts/package_skill.py +152 -0
  195. cloakbot/skills/skill-creator/scripts/quick_validate.py +213 -0
  196. cloakbot/skills/summarize/SKILL.md +67 -0
  197. cloakbot/skills/tmux/SKILL.md +121 -0
  198. cloakbot/skills/tmux/scripts/find-sessions.sh +112 -0
  199. cloakbot/skills/tmux/scripts/wait-for-text.sh +83 -0
  200. cloakbot/skills/update-setup/SKILL.md +123 -0
  201. cloakbot/skills/weather/SKILL.md +49 -0
  202. cloakbot/templates/AGENTS.md +23 -0
  203. cloakbot/templates/HEARTBEAT.md +14 -0
  204. cloakbot/templates/SOUL.md +20 -0
  205. cloakbot/templates/USER.md +49 -0
  206. cloakbot/templates/__init__.py +0 -0
  207. cloakbot/templates/agent/_snippets/untrusted_content.md +2 -0
  208. cloakbot/templates/agent/consolidator_archive.md +24 -0
  209. cloakbot/templates/agent/dream.md +105 -0
  210. cloakbot/templates/agent/evaluator.md +17 -0
  211. cloakbot/templates/agent/identity.md +34 -0
  212. cloakbot/templates/agent/max_iterations_message.md +1 -0
  213. cloakbot/templates/agent/platform_policy.md +10 -0
  214. cloakbot/templates/agent/skills_section.md +6 -0
  215. cloakbot/templates/agent/subagent_announce.md +8 -0
  216. cloakbot/templates/agent/subagent_system.md +19 -0
  217. cloakbot/templates/agent/tool_contract.md +67 -0
  218. cloakbot/templates/memory/MEMORY.md +23 -0
  219. cloakbot/templates/memory/__init__.py +0 -0
  220. cloakbot/tool_privacy.py +9 -0
  221. cloakbot/utils/__init__.py +42 -0
  222. cloakbot/utils/artifacts.py +122 -0
  223. cloakbot/utils/document.py +319 -0
  224. cloakbot/utils/evaluator.py +94 -0
  225. cloakbot/utils/file_edit_events.py +964 -0
  226. cloakbot/utils/gitstore.py +394 -0
  227. cloakbot/utils/helpers.py +639 -0
  228. cloakbot/utils/image_generation_intent.py +27 -0
  229. cloakbot/utils/llm_runtime.py +22 -0
  230. cloakbot/utils/logging_bridge.py +47 -0
  231. cloakbot/utils/media_decode.py +55 -0
  232. cloakbot/utils/path.py +107 -0
  233. cloakbot/utils/progress_events.py +101 -0
  234. cloakbot/utils/prompt_templates.py +35 -0
  235. cloakbot/utils/restart.py +84 -0
  236. cloakbot/utils/runtime.py +180 -0
  237. cloakbot/utils/searchusage.py +168 -0
  238. cloakbot/utils/subagent_channel_display.py +59 -0
  239. cloakbot/utils/tool_hints.py +142 -0
  240. cloakbot/web/__init__.py +8 -0
  241. cloakbot/web/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  242. cloakbot/web/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  243. cloakbot/web/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  244. cloakbot/web/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  245. cloakbot/web/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  246. cloakbot/web/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  247. cloakbot/web/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  248. cloakbot/web/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  249. cloakbot/web/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  250. cloakbot/web/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  251. cloakbot/web/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  252. cloakbot/web/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  253. cloakbot/web/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  254. cloakbot/web/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  255. cloakbot/web/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  256. cloakbot/web/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  257. cloakbot/web/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  258. cloakbot/web/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  259. cloakbot/web/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  260. cloakbot/web/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  261. cloakbot/web/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  262. cloakbot/web/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  263. cloakbot/web/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  264. cloakbot/web/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  265. cloakbot/web/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  266. cloakbot/web/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  267. cloakbot/web/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  268. cloakbot/web/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  269. cloakbot/web/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  270. cloakbot/web/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  271. cloakbot/web/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  272. cloakbot/web/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  273. cloakbot/web/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  274. cloakbot/web/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  275. cloakbot/web/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  276. cloakbot/web/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  277. cloakbot/web/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  278. cloakbot/web/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  279. cloakbot/web/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  280. cloakbot/web/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  281. cloakbot/web/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  282. cloakbot/web/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  283. cloakbot/web/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  284. cloakbot/web/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  285. cloakbot/web/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  286. cloakbot/web/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  287. cloakbot/web/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  288. cloakbot/web/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  289. cloakbot/web/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  290. cloakbot/web/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  291. cloakbot/web/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  292. cloakbot/web/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  293. cloakbot/web/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  294. cloakbot/web/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  295. cloakbot/web/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  296. cloakbot/web/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  297. cloakbot/web/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  298. cloakbot/web/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  299. cloakbot/web/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  300. cloakbot/web/dist/assets/MarkdownTextRenderer-DnRJ3Bsa.js +3 -0
  301. cloakbot/web/dist/assets/abap-NUN-Q4TY.js +1 -0
  302. cloakbot/web/dist/assets/abnf-D-KJbf1C.js +1 -0
  303. cloakbot/web/dist/assets/actionscript-DENL_Yxo.js +1 -0
  304. cloakbot/web/dist/assets/ada-LH5SZrhx.js +1 -0
  305. cloakbot/web/dist/assets/agda-ymtcdZdX.js +1 -0
  306. cloakbot/web/dist/assets/al-CJVAWKDz.js +1 -0
  307. cloakbot/web/dist/assets/antlr4-BMELX9Jd.js +1 -0
  308. cloakbot/web/dist/assets/apacheconf-BcTIfZ-R.js +1 -0
  309. cloakbot/web/dist/assets/apex-DX55Uwde.js +1 -0
  310. cloakbot/web/dist/assets/apl-vpZAny-b.js +1 -0
  311. cloakbot/web/dist/assets/applescript-CaPaYwG-.js +1 -0
  312. cloakbot/web/dist/assets/aql--wTUDf9B.js +1 -0
  313. cloakbot/web/dist/assets/arduino-CIKuiMMj.js +1 -0
  314. cloakbot/web/dist/assets/arff-BJFPZ3ZQ.js +1 -0
  315. cloakbot/web/dist/assets/asciidoc-Dz9LU0oo.js +1 -0
  316. cloakbot/web/dist/assets/asm6502-WnqbQVpP.js +1 -0
  317. cloakbot/web/dist/assets/asmatmel-5Jy3DrzW.js +1 -0
  318. cloakbot/web/dist/assets/aspnet-Bm3yfv9h.js +1 -0
  319. cloakbot/web/dist/assets/autohotkey-BeMG6bjj.js +1 -0
  320. cloakbot/web/dist/assets/autoit-Dt3Q7KNE.js +1 -0
  321. cloakbot/web/dist/assets/avisynth-_25jQ1mu.js +1 -0
  322. cloakbot/web/dist/assets/avro-idl-B_qGseSi.js +1 -0
  323. cloakbot/web/dist/assets/bash-Cb3UAMlT.js +1 -0
  324. cloakbot/web/dist/assets/basic-DgRegGrm.js +1 -0
  325. cloakbot/web/dist/assets/batch-DVsfxIac.js +1 -0
  326. cloakbot/web/dist/assets/bbcode-CN8dvzDf.js +1 -0
  327. cloakbot/web/dist/assets/bicep-CA94bLGb.js +1 -0
  328. cloakbot/web/dist/assets/birb-CtQq6iAZ.js +1 -0
  329. cloakbot/web/dist/assets/bison-CvtdVC8F.js +1 -0
  330. cloakbot/web/dist/assets/bnf-BWGPbtjg.js +1 -0
  331. cloakbot/web/dist/assets/brainfuck-Dj0-XgUQ.js +1 -0
  332. cloakbot/web/dist/assets/brightscript-B7D0klqQ.js +1 -0
  333. cloakbot/web/dist/assets/bro-f49XYRi4.js +1 -0
  334. cloakbot/web/dist/assets/bsl-BK1qQL1V.js +1 -0
  335. cloakbot/web/dist/assets/c-C0oRItof.js +1 -0
  336. cloakbot/web/dist/assets/cfscript-DOeQ7VDG.js +1 -0
  337. cloakbot/web/dist/assets/chaiscript-xYGnwzjJ.js +1 -0
  338. cloakbot/web/dist/assets/cil-eLAyeTPF.js +1 -0
  339. cloakbot/web/dist/assets/clojure-DgK4YDmn.js +1 -0
  340. cloakbot/web/dist/assets/cmake-CXLQNC9N.js +1 -0
  341. cloakbot/web/dist/assets/cobol-d9-VgeZD.js +1 -0
  342. cloakbot/web/dist/assets/coffeescript-C9QjHd1_.js +1 -0
  343. cloakbot/web/dist/assets/concurnas-bKB8OwZy.js +1 -0
  344. cloakbot/web/dist/assets/coq-CQYQuxb4.js +1 -0
  345. cloakbot/web/dist/assets/cpp-e-seuWBm.js +1 -0
  346. cloakbot/web/dist/assets/crystal-WWZ_tnQX.js +1 -0
  347. cloakbot/web/dist/assets/csharp-rMV9Zfra.js +1 -0
  348. cloakbot/web/dist/assets/cshtml-Ds09IOCc.js +1 -0
  349. cloakbot/web/dist/assets/csp-CQCQ0ZE3.js +1 -0
  350. cloakbot/web/dist/assets/css-extras-CT5A2Izd.js +1 -0
  351. cloakbot/web/dist/assets/csv-BgyMrcsA.js +1 -0
  352. cloakbot/web/dist/assets/cypher-DmelXpIf.js +1 -0
  353. cloakbot/web/dist/assets/d-VWCAEm1r.js +1 -0
  354. cloakbot/web/dist/assets/dart-CVJdj0-r.js +1 -0
  355. cloakbot/web/dist/assets/dataweave-hJYKzcPT.js +1 -0
  356. cloakbot/web/dist/assets/dax-C8SI5LyP.js +1 -0
  357. cloakbot/web/dist/assets/dhall-ZlvQUk6z.js +1 -0
  358. cloakbot/web/dist/assets/diff-DHVMP9tS.js +3 -0
  359. cloakbot/web/dist/assets/django-DcF8LBP-.js +1 -0
  360. cloakbot/web/dist/assets/dns-zone-file-WEIFK4Je.js +1 -0
  361. cloakbot/web/dist/assets/docker-VhAHakcV.js +1 -0
  362. cloakbot/web/dist/assets/dot-CD2DeVqg.js +1 -0
  363. cloakbot/web/dist/assets/ebnf-CuzNL4UB.js +1 -0
  364. cloakbot/web/dist/assets/editorconfig-D2zjbeHU.js +1 -0
  365. cloakbot/web/dist/assets/eiffel-DJ3ShHrF.js +1 -0
  366. cloakbot/web/dist/assets/ejs-7-hUFLy_.js +1 -0
  367. cloakbot/web/dist/assets/elixir-8xvh5cY_.js +1 -0
  368. cloakbot/web/dist/assets/elm-g7erWaDT.js +1 -0
  369. cloakbot/web/dist/assets/erb-B7Xt-BiE.js +1 -0
  370. cloakbot/web/dist/assets/erlang-DkxI4fpk.js +1 -0
  371. cloakbot/web/dist/assets/etlua-C2XEtv8g.js +1 -0
  372. cloakbot/web/dist/assets/excel-formula-CZSLAApX.js +1 -0
  373. cloakbot/web/dist/assets/factor-BxcDZoGu.js +1 -0
  374. cloakbot/web/dist/assets/false-BMVpOwHv.js +1 -0
  375. cloakbot/web/dist/assets/firestore-security-rules-BW9MFeh3.js +1 -0
  376. cloakbot/web/dist/assets/flow-Dlx8nrOL.js +1 -0
  377. cloakbot/web/dist/assets/fortran-7T9UcASY.js +1 -0
  378. cloakbot/web/dist/assets/fsharp-BAZLP3r3.js +1 -0
  379. cloakbot/web/dist/assets/ftl-Bc_oXPVP.js +1 -0
  380. cloakbot/web/dist/assets/gap-8IEH7qXG.js +1 -0
  381. cloakbot/web/dist/assets/gcode-CJYFbpnI.js +1 -0
  382. cloakbot/web/dist/assets/gdscript-DNzYL7bS.js +1 -0
  383. cloakbot/web/dist/assets/gedcom-CBgiY2w3.js +1 -0
  384. cloakbot/web/dist/assets/gherkin-B9TyT2N3.js +1 -0
  385. cloakbot/web/dist/assets/git-BsZy3BWd.js +1 -0
  386. cloakbot/web/dist/assets/glsl-CygM1cI3.js +1 -0
  387. cloakbot/web/dist/assets/gml-CEWHfET-.js +1 -0
  388. cloakbot/web/dist/assets/gn-DXi3n3PE.js +1 -0
  389. cloakbot/web/dist/assets/go-DU1aoKzc.js +1 -0
  390. cloakbot/web/dist/assets/go-module-BD-Mc9Hh.js +1 -0
  391. cloakbot/web/dist/assets/graphql--kXj6vcL.js +1 -0
  392. cloakbot/web/dist/assets/groovy-BLy61_og.js +1 -0
  393. cloakbot/web/dist/assets/haml-bPWdMu4i.js +1 -0
  394. cloakbot/web/dist/assets/handlebars-BMYf598U.js +1 -0
  395. cloakbot/web/dist/assets/haskell-D_VxTFgH.js +1 -0
  396. cloakbot/web/dist/assets/haxe-T1jkpIIT.js +1 -0
  397. cloakbot/web/dist/assets/hcl-PldULSBb.js +1 -0
  398. cloakbot/web/dist/assets/hlsl-CV7R57m6.js +1 -0
  399. cloakbot/web/dist/assets/hoon-CPa5nskQ.js +1 -0
  400. cloakbot/web/dist/assets/hpkp-DJfAmLW-.js +1 -0
  401. cloakbot/web/dist/assets/hsts-CxLYXpVn.js +1 -0
  402. cloakbot/web/dist/assets/http-B9Ds3pAZ.js +1 -0
  403. cloakbot/web/dist/assets/ichigojam-DVf-cIZC.js +1 -0
  404. cloakbot/web/dist/assets/icon-KWhYca5l.js +1 -0
  405. cloakbot/web/dist/assets/icu-message-format-C2lK5p-4.js +1 -0
  406. cloakbot/web/dist/assets/idris-BaY-k4HK.js +1 -0
  407. cloakbot/web/dist/assets/iecst-CxsHsf9f.js +1 -0
  408. cloakbot/web/dist/assets/ignore-DS80tY1X.js +1 -0
  409. cloakbot/web/dist/assets/imageEncode.worker-Cs1P3eq4.js +1 -0
  410. cloakbot/web/dist/assets/index-BPAapRgI.css +1 -0
  411. cloakbot/web/dist/assets/index-XC7Tun-1.js +512 -0
  412. cloakbot/web/dist/assets/inform7-Bq6ivJ_x.js +1 -0
  413. cloakbot/web/dist/assets/ini-ClDuxIIn.js +1 -0
  414. cloakbot/web/dist/assets/io-DMsvaBXO.js +1 -0
  415. cloakbot/web/dist/assets/j-1EMBPPgy.js +1 -0
  416. cloakbot/web/dist/assets/java-CewVao_H.js +1 -0
  417. cloakbot/web/dist/assets/javadoc-BMhUUrn0.js +1 -0
  418. cloakbot/web/dist/assets/javadoclike-DRcXw2x4.js +1 -0
  419. cloakbot/web/dist/assets/javastacktrace-cVgCwZsl.js +1 -0
  420. cloakbot/web/dist/assets/jexl-Cgr1JdcY.js +1 -0
  421. cloakbot/web/dist/assets/jolie-BsErGqHn.js +1 -0
  422. cloakbot/web/dist/assets/jq-BNzJiU3y.js +1 -0
  423. cloakbot/web/dist/assets/js-extras-Cle0v0Ni.js +1 -0
  424. cloakbot/web/dist/assets/js-templates-CRt74qtT.js +1 -0
  425. cloakbot/web/dist/assets/jsdoc-BqDpEoCE.js +1 -0
  426. cloakbot/web/dist/assets/json-C3Hv7pLs.js +1 -0
  427. cloakbot/web/dist/assets/json5-CgWTKuX0.js +1 -0
  428. cloakbot/web/dist/assets/jsonp-CF0DaYMl.js +1 -0
  429. cloakbot/web/dist/assets/jsstacktrace-DdTwpwd9.js +1 -0
  430. cloakbot/web/dist/assets/jsx-B2UQKFdi.js +1 -0
  431. cloakbot/web/dist/assets/julia-C9A4S2mY.js +1 -0
  432. cloakbot/web/dist/assets/katex-BSBacQyE.js +257 -0
  433. cloakbot/web/dist/assets/katex-wklAmtGL.css +1 -0
  434. cloakbot/web/dist/assets/keepalived-Bh4xvA_q.js +1 -0
  435. cloakbot/web/dist/assets/keyman-CNquq_6a.js +1 -0
  436. cloakbot/web/dist/assets/kotlin-Bdxl62Ap.js +1 -0
  437. cloakbot/web/dist/assets/kumir-CF1O59OV.js +1 -0
  438. cloakbot/web/dist/assets/kusto-CK-1V38p.js +1 -0
  439. cloakbot/web/dist/assets/latex-361E6eEC.js +1 -0
  440. cloakbot/web/dist/assets/latte-f86JSuho.js +1 -0
  441. cloakbot/web/dist/assets/less-Bi1_JqPO.js +1 -0
  442. cloakbot/web/dist/assets/lilypond-Cq-mKIqY.js +1 -0
  443. cloakbot/web/dist/assets/liquid-B4N2kZ3H.js +1 -0
  444. cloakbot/web/dist/assets/lisp-CW0qmQGp.js +1 -0
  445. cloakbot/web/dist/assets/livescript-D5FtAXwI.js +1 -0
  446. cloakbot/web/dist/assets/llvm-BV8wK6xF.js +1 -0
  447. cloakbot/web/dist/assets/log-D0hODZpk.js +1 -0
  448. cloakbot/web/dist/assets/lolcode-DHoRD95d.js +1 -0
  449. cloakbot/web/dist/assets/lua-CVi-soTA.js +1 -0
  450. cloakbot/web/dist/assets/magma-DvCCEyFl.js +1 -0
  451. cloakbot/web/dist/assets/makefile-BmIUjdPy.js +1 -0
  452. cloakbot/web/dist/assets/markdown-CE05kUpP.js +1 -0
  453. cloakbot/web/dist/assets/markdown-vendor-CHxCoe4r.js +51 -0
  454. cloakbot/web/dist/assets/markup-templating-DPnNaIIy.js +1 -0
  455. cloakbot/web/dist/assets/matlab-CscqyiC9.js +1 -0
  456. cloakbot/web/dist/assets/maxscript-CZ-oezbY.js +1 -0
  457. cloakbot/web/dist/assets/mel-Clp_NDCE.js +1 -0
  458. cloakbot/web/dist/assets/mermaid-DhQ9DOjk.js +1 -0
  459. cloakbot/web/dist/assets/mizar-CN0VJgC_.js +1 -0
  460. cloakbot/web/dist/assets/mongodb-C-4jspnJ.js +1 -0
  461. cloakbot/web/dist/assets/monkey-Dfc36AaJ.js +1 -0
  462. cloakbot/web/dist/assets/moonscript-DyASHGVA.js +1 -0
  463. cloakbot/web/dist/assets/n1ql-DxWPGEgd.js +1 -0
  464. cloakbot/web/dist/assets/n4js-CGSDOjR6.js +1 -0
  465. cloakbot/web/dist/assets/nand2tetris-hdl-CkGLHgHj.js +1 -0
  466. cloakbot/web/dist/assets/naniscript-ChIN67Bw.js +1 -0
  467. cloakbot/web/dist/assets/nasm-Bnt6aatk.js +1 -0
  468. cloakbot/web/dist/assets/neon-DECLa7BN.js +1 -0
  469. cloakbot/web/dist/assets/nevod-2fxCQtPo.js +1 -0
  470. cloakbot/web/dist/assets/nginx-CoGjQsmn.js +1 -0
  471. cloakbot/web/dist/assets/nim-BMpCszPC.js +1 -0
  472. cloakbot/web/dist/assets/nix-D_mQv5VI.js +1 -0
  473. cloakbot/web/dist/assets/nsis-BaqSa3Wz.js +1 -0
  474. cloakbot/web/dist/assets/objectivec-Dzemz2ja.js +1 -0
  475. cloakbot/web/dist/assets/ocaml-CNLwgV-_.js +1 -0
  476. cloakbot/web/dist/assets/opencl-DzvSb6Hj.js +1 -0
  477. cloakbot/web/dist/assets/openqasm-C4qCMzOe.js +1 -0
  478. cloakbot/web/dist/assets/oz-behEqsCQ.js +1 -0
  479. cloakbot/web/dist/assets/parigp-Ch6SZvgk.js +1 -0
  480. cloakbot/web/dist/assets/parser-BtGxkDWV.js +1 -0
  481. cloakbot/web/dist/assets/pascal-CmTgy_1Z.js +1 -0
  482. cloakbot/web/dist/assets/pascaligo-BXmCbm9G.js +1 -0
  483. cloakbot/web/dist/assets/pcaxis-DzyFSRg_.js +1 -0
  484. cloakbot/web/dist/assets/peoplecode-B0FPTfca.js +1 -0
  485. cloakbot/web/dist/assets/perl-VmqMidup.js +1 -0
  486. cloakbot/web/dist/assets/php-WU4kuGhf.js +1 -0
  487. cloakbot/web/dist/assets/php-extras-DipLCQnj.js +1 -0
  488. cloakbot/web/dist/assets/phpdoc-CUDU7T8Q.js +1 -0
  489. cloakbot/web/dist/assets/plsql-DGyiSrqR.js +1 -0
  490. cloakbot/web/dist/assets/powerquery-B7U3Mrpn.js +1 -0
  491. cloakbot/web/dist/assets/powershell-ZbXZQOaZ.js +1 -0
  492. cloakbot/web/dist/assets/processing-ByQRo6i7.js +1 -0
  493. cloakbot/web/dist/assets/prolog-BOvhxG3V.js +1 -0
  494. cloakbot/web/dist/assets/promql-C2CobPDE.js +1 -0
  495. cloakbot/web/dist/assets/properties-CwSf9g07.js +1 -0
  496. cloakbot/web/dist/assets/protobuf-B57RIxkn.js +1 -0
  497. cloakbot/web/dist/assets/psl-DzFyTHe1.js +1 -0
  498. cloakbot/web/dist/assets/pug-BH1QhRaq.js +1 -0
  499. cloakbot/web/dist/assets/puppet-Bs9vzkUe.js +1 -0
  500. cloakbot/web/dist/assets/pure-BdX0RpFB.js +1 -0
  501. cloakbot/web/dist/assets/purebasic-BQU22L1L.js +1 -0
  502. cloakbot/web/dist/assets/purescript-BagkDTwF.js +1 -0
  503. cloakbot/web/dist/assets/python-RwSVHJ9V.js +1 -0
  504. cloakbot/web/dist/assets/q-BET3zqr2.js +1 -0
  505. cloakbot/web/dist/assets/qml-CoQTBiQ8.js +1 -0
  506. cloakbot/web/dist/assets/qore-CLDloqZD.js +1 -0
  507. cloakbot/web/dist/assets/qsharp-CDXKQeBv.js +1 -0
  508. cloakbot/web/dist/assets/r-BgAHHb-4.js +1 -0
  509. cloakbot/web/dist/assets/racket-CZmbqa8w.js +1 -0
  510. cloakbot/web/dist/assets/reason-D0_MaL5W.js +1 -0
  511. cloakbot/web/dist/assets/regex-QM-tU3X2.js +1 -0
  512. cloakbot/web/dist/assets/rego-DjXu5pFv.js +1 -0
  513. cloakbot/web/dist/assets/renpy-hG_ow2kX.js +1 -0
  514. cloakbot/web/dist/assets/rest-ub8bBn-k.js +1 -0
  515. cloakbot/web/dist/assets/rip-DR0ywRNu.js +1 -0
  516. cloakbot/web/dist/assets/roboconf-B0rb3xgX.js +1 -0
  517. cloakbot/web/dist/assets/robotframework-BUno3CtF.js +1 -0
  518. cloakbot/web/dist/assets/ruby-Brn8fnNm.js +1 -0
  519. cloakbot/web/dist/assets/rust-Ck_uMGfC.js +1 -0
  520. cloakbot/web/dist/assets/sas-DSvGfcUx.js +1 -0
  521. cloakbot/web/dist/assets/sass-iA6MSihr.js +1 -0
  522. cloakbot/web/dist/assets/scala-EEfoM1jv.js +1 -0
  523. cloakbot/web/dist/assets/scheme-BBqT4W3K.js +1 -0
  524. cloakbot/web/dist/assets/scss-EDX5cncP.js +1 -0
  525. cloakbot/web/dist/assets/shell-session-CJFdfejh.js +1 -0
  526. cloakbot/web/dist/assets/smali-Bm6qyqwX.js +1 -0
  527. cloakbot/web/dist/assets/smalltalk-BHlu5omn.js +1 -0
  528. cloakbot/web/dist/assets/smarty-CTN6tCig.js +1 -0
  529. cloakbot/web/dist/assets/sml-DkSEEtgE.js +1 -0
  530. cloakbot/web/dist/assets/solidity-DbbwU6KF.js +1 -0
  531. cloakbot/web/dist/assets/solution-file-DjIYncCO.js +1 -0
  532. cloakbot/web/dist/assets/soy-D4HHWo9i.js +1 -0
  533. cloakbot/web/dist/assets/sparql-CsVa7hte.js +1 -0
  534. cloakbot/web/dist/assets/splunk-spl-BjJg2Exp.js +1 -0
  535. cloakbot/web/dist/assets/sqf-9Xk-yGkV.js +1 -0
  536. cloakbot/web/dist/assets/sql-YBattGiR.js +1 -0
  537. cloakbot/web/dist/assets/squirrel-BrO73Frc.js +1 -0
  538. cloakbot/web/dist/assets/stan-Bp1R52Lx.js +1 -0
  539. cloakbot/web/dist/assets/stylus-CYuOuTL2.js +1 -0
  540. cloakbot/web/dist/assets/swift-xHzlmVoR.js +1 -0
  541. cloakbot/web/dist/assets/syntax-highlight-DCgzSdVd.js +14 -0
  542. cloakbot/web/dist/assets/systemd-q770erU6.js +2 -0
  543. cloakbot/web/dist/assets/t4-cs-C5O5jKQ-.js +1 -0
  544. cloakbot/web/dist/assets/t4-templating-DSbTm9R0.js +1 -0
  545. cloakbot/web/dist/assets/t4-vb-D-3ClfEW.js +1 -0
  546. cloakbot/web/dist/assets/tap-CDX0b6dR.js +1 -0
  547. cloakbot/web/dist/assets/tcl-DN1Ucqga.js +1 -0
  548. cloakbot/web/dist/assets/textile-DLoqze5H.js +1 -0
  549. cloakbot/web/dist/assets/toml-BeKaK4mH.js +1 -0
  550. cloakbot/web/dist/assets/tremor-CEa3FcAW.js +1 -0
  551. cloakbot/web/dist/assets/tsx-pwqpn4KT.js +1 -0
  552. cloakbot/web/dist/assets/tt2-Cl1RsxSw.js +1 -0
  553. cloakbot/web/dist/assets/turtle-DZqESLx2.js +1 -0
  554. cloakbot/web/dist/assets/twig-R1TH6YUG.js +1 -0
  555. cloakbot/web/dist/assets/typescript-CsCgqoRI.js +1 -0
  556. cloakbot/web/dist/assets/typoscript-BVuqnMDP.js +1 -0
  557. cloakbot/web/dist/assets/unrealscript-Am1hcp0G.js +1 -0
  558. cloakbot/web/dist/assets/uorazor-C9OiWvz8.js +1 -0
  559. cloakbot/web/dist/assets/uri-MwZhKeWh.js +1 -0
  560. cloakbot/web/dist/assets/v-CIC4n_ke.js +1 -0
  561. cloakbot/web/dist/assets/vala-DO5cmjce.js +1 -0
  562. cloakbot/web/dist/assets/vbnet-CJjFEgIg.js +1 -0
  563. cloakbot/web/dist/assets/velocity-cr2eidoW.js +1 -0
  564. cloakbot/web/dist/assets/verilog-C_HsAsqe.js +1 -0
  565. cloakbot/web/dist/assets/vhdl-BwBD3DKL.js +1 -0
  566. cloakbot/web/dist/assets/vim-Dqw9xkI1.js +1 -0
  567. cloakbot/web/dist/assets/visual-basic-DqvyCv2_.js +1 -0
  568. cloakbot/web/dist/assets/warpscript-DJL-COd1.js +1 -0
  569. cloakbot/web/dist/assets/wasm-KvauVSwO.js +1 -0
  570. cloakbot/web/dist/assets/web-idl-BxYvb2Gb.js +1 -0
  571. cloakbot/web/dist/assets/wiki-BHXLza-L.js +1 -0
  572. cloakbot/web/dist/assets/wolfram-kAMBUx9a.js +1 -0
  573. cloakbot/web/dist/assets/wren-Crw12_Hv.js +1 -0
  574. cloakbot/web/dist/assets/xeora-CWky1D6u.js +1 -0
  575. cloakbot/web/dist/assets/xml-doc-D1sLufgd.js +1 -0
  576. cloakbot/web/dist/assets/xojo-DZgGZigC.js +1 -0
  577. cloakbot/web/dist/assets/xquery-Dg59bIp5.js +1 -0
  578. cloakbot/web/dist/assets/yaml-C-mPAAtt.js +1 -0
  579. cloakbot/web/dist/assets/yang-B16K-lne.js +1 -0
  580. cloakbot/web/dist/assets/zig-DOLkVX_D.js +1 -0
  581. cloakbot/web/dist/brand/cloakbot_apple_touch.png +0 -0
  582. cloakbot/web/dist/brand/cloakbot_favicon_32.png +0 -0
  583. cloakbot/web/dist/brand/cloakbot_icon.png +0 -0
  584. cloakbot/web/dist/brand/cloakbot_logo.png +0 -0
  585. cloakbot/web/dist/index.html +191 -0
  586. cloakbot/webui/__init__.py +2 -0
  587. cloakbot/webui/cli_apps_api.py +93 -0
  588. cloakbot/webui/gateway_services.py +70 -0
  589. cloakbot/webui/gateway_tokens.py +82 -0
  590. cloakbot/webui/http_utils.py +151 -0
  591. cloakbot/webui/mcp_presets_api.py +1318 -0
  592. cloakbot/webui/mcp_presets_runtime.py +5 -0
  593. cloakbot/webui/media_api.py +284 -0
  594. cloakbot/webui/media_gateway.py +92 -0
  595. cloakbot/webui/privacy_routes.py +79 -0
  596. cloakbot/webui/settings_api.py +1446 -0
  597. cloakbot/webui/settings_routes.py +356 -0
  598. cloakbot/webui/sidebar_state.py +196 -0
  599. cloakbot/webui/thread_disk.py +31 -0
  600. cloakbot/webui/transcript.py +922 -0
  601. cloakbot/webui/websocket_logging.py +45 -0
  602. cloakbot/webui/workspaces.py +283 -0
  603. cloakbot/webui/ws_http.py +513 -0
  604. cloakbot-0.2.1b1.dist-info/METADATA +371 -0
  605. cloakbot-0.2.1b1.dist-info/RECORD +608 -0
  606. cloakbot-0.2.1b1.dist-info/WHEEL +4 -0
  607. cloakbot-0.2.1b1.dist-info/entry_points.txt +2 -0
  608. cloakbot-0.2.1b1.dist-info/licenses/LICENSE +22 -0
cloakbot/__init__.py ADDED
@@ -0,0 +1,49 @@
1
+ """
2
+ cloakbot - A lightweight AI agent framework
3
+ """
4
+
5
+ import tomllib
6
+ from importlib.metadata import PackageNotFoundError
7
+ from importlib.metadata import version as _pkg_version
8
+ from pathlib import Path
9
+
10
+
11
+ def _read_pyproject_version() -> str | None:
12
+ """Read the source-tree version when package metadata is unavailable."""
13
+ pyproject = Path(__file__).resolve().parent.parent / "pyproject.toml"
14
+ if not pyproject.exists():
15
+ return None
16
+ data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
17
+ return data.get("project", {}).get("version")
18
+
19
+
20
+ def _resolve_version() -> str:
21
+ try:
22
+ return _pkg_version("cloakbot")
23
+ except PackageNotFoundError:
24
+ # Source checkouts often import cloakbot without installed dist-info.
25
+ return _read_pyproject_version() or "0.2.1b1"
26
+
27
+
28
+ __version__ = _resolve_version()
29
+ __logo__ = "🐈"
30
+
31
+ _LAZY_EXPORTS = {
32
+ "Nanobot": ".cloakbot",
33
+ "Cloakbot": ".cloakbot",
34
+ "RunResult": ".cloakbot",
35
+ }
36
+
37
+
38
+ def __getattr__(name: str):
39
+ module_path = _LAZY_EXPORTS.get(name)
40
+ if module_path is None:
41
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
42
+ from importlib import import_module
43
+ mod = import_module(module_path, __name__)
44
+ val = getattr(mod, name)
45
+ globals()[name] = val
46
+ return val
47
+
48
+
49
+ __all__ = ["Cloakbot", "Nanobot", "RunResult"]
cloakbot/__main__.py ADDED
@@ -0,0 +1,8 @@
1
+ """
2
+ Entry point for running cloakbot as a module: python -m cloakbot
3
+ """
4
+
5
+ from cloakbot.cli.commands import app
6
+
7
+ if __name__ == "__main__":
8
+ app()
@@ -0,0 +1,19 @@
1
+ """Agent core module."""
2
+
3
+ from cloakbot.agent.context import ContextBuilder
4
+ from cloakbot.agent.hook import AgentHook, AgentHookContext, CompositeHook
5
+ from cloakbot.agent.loop import AgentLoop
6
+ from cloakbot.agent.memory import MemoryStore
7
+ from cloakbot.agent.skills import SkillsLoader
8
+ from cloakbot.agent.subagent import SubagentManager
9
+
10
+ __all__ = [
11
+ "AgentHook",
12
+ "AgentHookContext",
13
+ "AgentLoop",
14
+ "CompositeHook",
15
+ "ContextBuilder",
16
+ "MemoryStore",
17
+ "SkillsLoader",
18
+ "SubagentManager",
19
+ ]
@@ -0,0 +1,96 @@
1
+ """Auto compact: proactive compression of idle sessions to reduce token cost and latency."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Collection
6
+ from datetime import datetime
7
+ from typing import TYPE_CHECKING, Callable, Coroutine
8
+
9
+ from loguru import logger
10
+
11
+ from cloakbot.session.manager import Session, SessionManager
12
+
13
+ if TYPE_CHECKING:
14
+ from cloakbot.agent.memory import Consolidator
15
+
16
+
17
+ class AutoCompact:
18
+ _RECENT_SUFFIX_MESSAGES = 8
19
+ _INTERNAL_SESSION_PREFIXES = ("dream:",)
20
+
21
+ def __init__(self, sessions: SessionManager, consolidator: Consolidator,
22
+ session_ttl_minutes: int = 0):
23
+ self.sessions = sessions
24
+ self.consolidator = consolidator
25
+ self._ttl = session_ttl_minutes
26
+ self._archiving: set[str] = set()
27
+ self._summaries: dict[str, tuple[str, datetime]] = {}
28
+
29
+ def _is_expired(self, ts: datetime | str | None,
30
+ now: datetime | None = None) -> bool:
31
+ if self._ttl <= 0 or not ts:
32
+ return False
33
+ if isinstance(ts, str):
34
+ ts = datetime.fromisoformat(ts)
35
+ return ((now or datetime.now()) - ts).total_seconds() >= self._ttl * 60
36
+
37
+ @staticmethod
38
+ def _format_summary(text: str, last_active: datetime) -> str:
39
+ return f"Previous conversation summary (last active {last_active.isoformat()}):\n{text}"
40
+
41
+ @classmethod
42
+ def _is_internal_session(cls, key: str) -> bool:
43
+ return key.startswith(cls._INTERNAL_SESSION_PREFIXES)
44
+
45
+ def check_expired(self, schedule_background: Callable[[Coroutine], None],
46
+ active_session_keys: Collection[str] = ()) -> None:
47
+ """Schedule archival for idle sessions, skipping those with in-flight agent tasks."""
48
+ now = datetime.now()
49
+ for info in self.sessions.list_sessions():
50
+ key = info.get("key", "")
51
+ if not key or self._is_internal_session(key) or key in self._archiving:
52
+ continue
53
+ if key in active_session_keys:
54
+ continue
55
+ if self._is_expired(info.get("updated_at"), now):
56
+ self._archiving.add(key)
57
+ schedule_background(self._archive(key))
58
+
59
+ async def _archive(self, key: str) -> None:
60
+ if self._is_internal_session(key):
61
+ self._archiving.discard(key)
62
+ return
63
+ try:
64
+ summary = await self.consolidator.compact_idle_session(
65
+ key, self._RECENT_SUFFIX_MESSAGES,
66
+ )
67
+ if summary and summary != "(nothing)":
68
+ session = self.sessions.get_or_create(key)
69
+ meta = session.metadata.get("_last_summary")
70
+ if isinstance(meta, dict):
71
+ self._summaries[key] = (
72
+ meta["text"],
73
+ datetime.fromisoformat(meta["last_active"]),
74
+ )
75
+ except Exception:
76
+ logger.exception("Auto-compact: failed for {}", key)
77
+ finally:
78
+ self._archiving.discard(key)
79
+
80
+ def prepare_session(self, session: Session, key: str) -> tuple[Session, str | None]:
81
+ if self._is_internal_session(key):
82
+ self._archiving.discard(key)
83
+ self._summaries.pop(key, None)
84
+ return session, None
85
+ if key in self._archiving or self._is_expired(session.updated_at):
86
+ logger.info("Auto-compact: reloading session {} (archiving={})", key, key in self._archiving)
87
+ session = self.sessions.get_or_create(key)
88
+ # Hot path: summary from in-memory dict (process hasn't restarted).
89
+ entry = self._summaries.pop(key, None)
90
+ if entry:
91
+ return session, self._format_summary(entry[0], entry[1])
92
+ # Cold path: summary persisted in session metadata (process restarted).
93
+ meta = session.metadata.get("_last_summary")
94
+ if isinstance(meta, dict):
95
+ return session, self._format_summary(meta["text"], datetime.fromisoformat(meta["last_active"]))
96
+ return session, None
@@ -0,0 +1,280 @@
1
+ """Context builder for assembling agent prompts."""
2
+
3
+ import base64
4
+ import mimetypes
5
+ import platform
6
+ from pathlib import Path
7
+ from typing import Any, Mapping, Sequence
8
+
9
+ from cloakbot.agent.memory import MemoryStore
10
+ from cloakbot.agent.skills import SkillsLoader
11
+ from cloakbot.agent.tools import mcp as mcp_tools
12
+ from cloakbot.agent.tools.registry import ToolRegistry
13
+ from cloakbot.apps.cli import utils as cli_app_utils
14
+ from cloakbot.bus.events import InboundMessage
15
+ from cloakbot.session.goal_state import goal_state_runtime_lines
16
+ from cloakbot.utils.helpers import (
17
+ current_time_str,
18
+ detect_image_mime,
19
+ load_bundled_template,
20
+ truncate_text,
21
+ )
22
+ from cloakbot.utils.prompt_templates import render_template
23
+
24
+
25
+ def session_extra(metadata: Mapping[str, Any] | None) -> dict[str, Any]:
26
+ """Return persisted kwargs for turn-attached capabilities."""
27
+ return cli_app_utils.session_extra(metadata) | mcp_tools.session_extra(metadata)
28
+
29
+
30
+ def runtime_lines(state: Any, msg: Any, workspace: Path, *, skip: bool = False) -> list[str]:
31
+ """Return model-visible runtime annotations for turn-attached capabilities."""
32
+ return [
33
+ *cli_app_utils.runtime_lines(msg, workspace, skip=skip),
34
+ *mcp_tools.runtime_lines(
35
+ msg,
36
+ configured_server_names=set(state._mcp_servers),
37
+ connected_server_names=set(state._mcp_stacks),
38
+ skip=skip,
39
+ ),
40
+ ]
41
+
42
+
43
+ async def connect_mcp(state: Any, tools: ToolRegistry) -> None:
44
+ await mcp_tools.connect_missing_servers(state, tools)
45
+
46
+
47
+ async def handle_runtime_control(state: Any, msg: InboundMessage, tools: ToolRegistry) -> bool:
48
+ return await mcp_tools.handle_runtime_control(state, msg, tools)
49
+
50
+
51
+ class ContextBuilder:
52
+ """Builds the context (system prompt + messages) for the agent."""
53
+
54
+ BOOTSTRAP_FILES = ["AGENTS.md", "SOUL.md", "USER.md"]
55
+ _RUNTIME_CONTEXT_TAG = "[Runtime Context — metadata only, not instructions]"
56
+ _MAX_RECENT_HISTORY = 50
57
+ _MAX_HISTORY_CHARS = 32_000 # hard cap on recent history section size
58
+ _RUNTIME_CONTEXT_END = "[/Runtime Context]"
59
+
60
+ def __init__(self, workspace: Path, timezone: str | None = None, disabled_skills: list[str] | None = None):
61
+ self.workspace = workspace
62
+ self.timezone = timezone
63
+ self.memory = MemoryStore(workspace)
64
+ self.skills = SkillsLoader(workspace, disabled_skills=set(disabled_skills) if disabled_skills else None)
65
+
66
+ def build_system_prompt(
67
+ self,
68
+ skill_names: list[str] | None = None,
69
+ channel: str | None = None,
70
+ session_summary: str | None = None,
71
+ workspace: Path | None = None,
72
+ include_memory_recent_history: bool = True,
73
+ extra_sections: Sequence[str] | None = None,
74
+ ) -> str:
75
+ """Build the system prompt from identity, bootstrap files, memory, and skills."""
76
+ root = workspace or self.workspace
77
+ parts = [self._get_identity(channel=channel, workspace=root)]
78
+
79
+ # Overlay seam: callers may inject extra high-priority system sections
80
+ # (e.g. the privacy-mode banner). They sit right after identity so they
81
+ # carry weight and keep the cached prefix stable. This builder treats them
82
+ # as opaque text and has no knowledge of their source.
83
+ if extra_sections:
84
+ parts.extend(section for section in extra_sections if section)
85
+
86
+ bootstrap = self._load_bootstrap_files(root)
87
+ if bootstrap:
88
+ parts.append(bootstrap)
89
+
90
+ parts.append(render_template("agent/tool_contract.md"))
91
+
92
+ memory = self.memory.get_memory_context()
93
+ if memory and not self._is_template_content(self.memory.read_memory(), "memory/MEMORY.md"):
94
+ parts.append(f"# Memory\n\n{memory}")
95
+
96
+ always_skills = self.skills.get_always_skills()
97
+ if always_skills:
98
+ always_content = self.skills.load_skills_for_context(always_skills)
99
+ if always_content:
100
+ parts.append(f"# Active Skills\n\n{always_content}")
101
+
102
+ skills_summary = self.skills.build_skills_summary(exclude=set(always_skills))
103
+ if skills_summary:
104
+ parts.append(render_template("agent/skills_section.md", skills_summary=skills_summary))
105
+
106
+ if include_memory_recent_history:
107
+ entries = self.memory.read_unprocessed_history(since_cursor=self.memory.get_last_dream_cursor())
108
+ if entries:
109
+ capped = entries[-self._MAX_RECENT_HISTORY:]
110
+ history_text = "\n".join(
111
+ f"- [{e['timestamp']}] {e['content']}" for e in capped
112
+ )
113
+ history_text = truncate_text(history_text, self._MAX_HISTORY_CHARS)
114
+ parts.append("# Recent History\n\n" + history_text)
115
+
116
+ if session_summary:
117
+ parts.append(f"[Archived Context Summary]\n\n{session_summary}")
118
+
119
+ return "\n\n---\n\n".join(parts)
120
+
121
+ def _get_identity(self, channel: str | None = None, workspace: Path | None = None) -> str:
122
+ """Get the core identity section."""
123
+ root = workspace or self.workspace
124
+ workspace_path = str(root.expanduser().resolve())
125
+ system = platform.system()
126
+ runtime = f"{'macOS' if system == 'Darwin' else system} {platform.machine()}, Python {platform.python_version()}"
127
+
128
+ return render_template(
129
+ "agent/identity.md",
130
+ workspace_path=workspace_path,
131
+ runtime=runtime,
132
+ platform_policy=render_template("agent/platform_policy.md", system=system),
133
+ channel=channel or "",
134
+ )
135
+
136
+ @staticmethod
137
+ def _build_runtime_context(
138
+ channel: str | None,
139
+ chat_id: str | None,
140
+ timezone: str | None = None,
141
+ sender_id: str | None = None,
142
+ supplemental_lines: Sequence[str] | None = None,
143
+ ) -> str:
144
+ """Build untrusted runtime metadata block appended after user content."""
145
+ lines = [f"Current Time: {current_time_str(timezone)}"]
146
+ if channel and chat_id:
147
+ lines += [f"Channel: {channel}", f"Chat ID: {chat_id}"]
148
+ if sender_id:
149
+ lines += [f"Sender ID: {sender_id}"]
150
+ if supplemental_lines:
151
+ lines.extend(supplemental_lines)
152
+ return ContextBuilder._RUNTIME_CONTEXT_TAG + "\n" + "\n".join(lines) + "\n" + ContextBuilder._RUNTIME_CONTEXT_END
153
+
154
+ @staticmethod
155
+ def _merge_message_content(left: Any, right: Any) -> str | list[dict[str, Any]]:
156
+ if isinstance(left, str) and isinstance(right, str):
157
+ return f"{left}\n\n{right}" if left else right
158
+
159
+ def _to_blocks(value: Any) -> list[dict[str, Any]]:
160
+ if isinstance(value, list):
161
+ return [item if isinstance(item, dict) else {"type": "text", "text": str(item)} for item in value]
162
+ if value is None:
163
+ return []
164
+ return [{"type": "text", "text": str(value)}]
165
+
166
+ return _to_blocks(left) + _to_blocks(right)
167
+
168
+ def _load_bootstrap_files(self, workspace: Path | None = None) -> str:
169
+ """Load all bootstrap files from workspace."""
170
+ parts = []
171
+ root = workspace or self.workspace
172
+
173
+ for filename in self.BOOTSTRAP_FILES:
174
+ file_path = root / filename
175
+ if file_path.exists():
176
+ content = file_path.read_text(encoding="utf-8")
177
+ parts.append(f"## {filename}\n\n{content}")
178
+
179
+ return "\n\n".join(parts) if parts else ""
180
+
181
+ @staticmethod
182
+ def _is_template_content(content: str, template_path: str) -> bool:
183
+ """Check if *content* is identical to the bundled template (user hasn't customized it)."""
184
+ tpl = load_bundled_template(template_path)
185
+ if tpl is not None:
186
+ return content.strip() == tpl.strip()
187
+ return False
188
+
189
+ def build_messages(
190
+ self,
191
+ history: list[dict[str, Any]],
192
+ current_message: str,
193
+ skill_names: list[str] | None = None,
194
+ media: list[str] | None = None,
195
+ channel: str | None = None,
196
+ chat_id: str | None = None,
197
+ current_role: str = "user",
198
+ sender_id: str | None = None,
199
+ session_summary: str | None = None,
200
+ session_metadata: Mapping[str, Any] | None = None,
201
+ current_runtime_lines: Sequence[str] | None = None,
202
+ workspace: Path | None = None,
203
+ runtime_state: Any | None = None,
204
+ inbound_message: Any | None = None,
205
+ skip_runtime_lines: bool = False,
206
+ include_memory_recent_history: bool = True,
207
+ extra_system_sections: Sequence[str] | None = None,
208
+ ) -> list[dict[str, Any]]:
209
+ """Build the complete message list for an LLM call."""
210
+ root = workspace or self.workspace
211
+ extra = [
212
+ *goal_state_runtime_lines(session_metadata),
213
+ ]
214
+ if runtime_state is not None and inbound_message is not None:
215
+ extra.extend(runtime_lines(runtime_state, inbound_message, root, skip=skip_runtime_lines))
216
+ if current_runtime_lines:
217
+ extra.extend(line for line in current_runtime_lines if line)
218
+ runtime_ctx = self._build_runtime_context(
219
+ channel,
220
+ chat_id,
221
+ self.timezone,
222
+ sender_id=sender_id,
223
+ supplemental_lines=extra or None,
224
+ )
225
+ user_content = self._build_user_content(current_message, media)
226
+
227
+ # Merge runtime context and user content into a single user message
228
+ # to avoid consecutive same-role messages that some providers reject.
229
+ # Runtime context is appended to keep the user-content prefix stable
230
+ # for prompt-cache hits (the context changes every turn due to time).
231
+ if isinstance(user_content, str):
232
+ merged = f"{user_content}\n\n{runtime_ctx}"
233
+ else:
234
+ merged = user_content + [{"type": "text", "text": runtime_ctx}]
235
+ messages = [
236
+ {
237
+ "role": "system",
238
+ "content": self.build_system_prompt(
239
+ skill_names,
240
+ channel=channel,
241
+ session_summary=session_summary,
242
+ workspace=root,
243
+ include_memory_recent_history=include_memory_recent_history,
244
+ extra_sections=extra_system_sections,
245
+ ),
246
+ },
247
+ *history,
248
+ ]
249
+ if messages[-1].get("role") == current_role:
250
+ last = dict(messages[-1])
251
+ last["content"] = self._merge_message_content(last.get("content"), merged)
252
+ messages[-1] = last
253
+ return messages
254
+ messages.append({"role": current_role, "content": merged})
255
+ return messages
256
+
257
+ def _build_user_content(self, text: str, media: list[str] | None) -> str | list[dict[str, Any]]:
258
+ """Build user message content with optional base64-encoded images."""
259
+ if not media:
260
+ return text
261
+
262
+ images = []
263
+ for path in media:
264
+ p = Path(path)
265
+ if not p.is_file():
266
+ continue
267
+ raw = p.read_bytes()
268
+ mime = detect_image_mime(raw) or mimetypes.guess_type(path)[0]
269
+ if not mime or not mime.startswith("image/"):
270
+ continue
271
+ b64 = base64.b64encode(raw).decode()
272
+ images.append({
273
+ "type": "image_url",
274
+ "image_url": {"url": f"data:{mime};base64,{b64}"},
275
+ "_meta": {"path": str(p)},
276
+ })
277
+
278
+ if not images:
279
+ return text
280
+ return images + [{"type": "text", "text": text}]
cloakbot/agent/hook.py ADDED
@@ -0,0 +1,141 @@
1
+ """Shared lifecycle hook primitives for agent runs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from typing import Any
7
+
8
+ from loguru import logger
9
+
10
+ from cloakbot.providers.base import LLMResponse, ToolCallRequest
11
+
12
+
13
+ @dataclass(slots=True)
14
+ class AgentHookContext:
15
+ """Mutable per-iteration state exposed to runner hooks."""
16
+
17
+ iteration: int
18
+ messages: list[dict[str, Any]]
19
+ response: LLMResponse | None = None
20
+ usage: dict[str, int] = field(default_factory=dict)
21
+ tool_calls: list[ToolCallRequest] = field(default_factory=list)
22
+ tool_results: list[Any] = field(default_factory=list)
23
+ tool_events: list[dict[str, str]] = field(default_factory=list)
24
+ streamed_content: bool = False
25
+ streamed_reasoning: bool = False
26
+ final_content: str | None = None
27
+ stop_reason: str | None = None
28
+ error: str | None = None
29
+
30
+
31
+ class AgentHook:
32
+ """Minimal lifecycle surface for shared runner customization."""
33
+
34
+ def __init__(self, reraise: bool = False) -> None:
35
+ self._reraise = reraise
36
+
37
+ def wants_streaming(self) -> bool:
38
+ return False
39
+
40
+ async def before_iteration(self, context: AgentHookContext) -> None:
41
+ pass
42
+
43
+ async def on_stream(self, context: AgentHookContext, delta: str) -> None:
44
+ pass
45
+
46
+ async def on_stream_end(self, context: AgentHookContext, *, resuming: bool) -> None:
47
+ pass
48
+
49
+ async def before_execute_tools(self, context: AgentHookContext) -> None:
50
+ pass
51
+
52
+ async def emit_reasoning(self, reasoning_content: str | None) -> None:
53
+ pass
54
+
55
+ async def emit_reasoning_end(self) -> None:
56
+ """Mark the end of an in-flight reasoning stream.
57
+
58
+ Hooks that buffer ``emit_reasoning`` chunks (for in-place UI updates)
59
+ flush and freeze the rendered group here. One-shot hooks ignore.
60
+ """
61
+ pass
62
+
63
+ async def after_iteration(self, context: AgentHookContext) -> None:
64
+ pass
65
+
66
+ def finalize_content(self, context: AgentHookContext, content: str | None) -> str | None:
67
+ return content
68
+
69
+
70
+ class CompositeHook(AgentHook):
71
+ """Fan-out hook that delegates to an ordered list of hooks.
72
+
73
+ Error isolation: async methods catch and log per-hook exceptions
74
+ so a faulty custom hook cannot crash the agent loop.
75
+ ``finalize_content`` is a pipeline (no isolation — bugs should surface).
76
+ """
77
+
78
+ __slots__ = ("_hooks",)
79
+
80
+ def __init__(self, hooks: list[AgentHook]) -> None:
81
+ super().__init__()
82
+ self._hooks = list(hooks)
83
+
84
+ def wants_streaming(self) -> bool:
85
+ return any(h.wants_streaming() for h in self._hooks)
86
+
87
+ async def _for_each_hook_safe(self, method_name: str, *args: Any, **kwargs: Any) -> None:
88
+ for h in self._hooks:
89
+ if getattr(h, "_reraise", False):
90
+ await getattr(h, method_name)(*args, **kwargs)
91
+ continue
92
+
93
+ try:
94
+ await getattr(h, method_name)(*args, **kwargs)
95
+ except Exception:
96
+ logger.exception("AgentHook.{} error in {}", method_name, type(h).__name__)
97
+
98
+ async def before_iteration(self, context: AgentHookContext) -> None:
99
+ await self._for_each_hook_safe("before_iteration", context)
100
+
101
+ async def on_stream(self, context: AgentHookContext, delta: str) -> None:
102
+ await self._for_each_hook_safe("on_stream", context, delta)
103
+
104
+ async def on_stream_end(self, context: AgentHookContext, *, resuming: bool) -> None:
105
+ await self._for_each_hook_safe("on_stream_end", context, resuming=resuming)
106
+
107
+ async def before_execute_tools(self, context: AgentHookContext) -> None:
108
+ await self._for_each_hook_safe("before_execute_tools", context)
109
+
110
+ async def emit_reasoning(self, reasoning_content: str | None) -> None:
111
+ await self._for_each_hook_safe("emit_reasoning", reasoning_content)
112
+
113
+ async def emit_reasoning_end(self) -> None:
114
+ await self._for_each_hook_safe("emit_reasoning_end")
115
+
116
+ async def after_iteration(self, context: AgentHookContext) -> None:
117
+ await self._for_each_hook_safe("after_iteration", context)
118
+
119
+ def finalize_content(self, context: AgentHookContext, content: str | None) -> str | None:
120
+ for h in self._hooks:
121
+ content = h.finalize_content(context, content)
122
+ return content
123
+
124
+
125
+ class SDKCaptureHook(AgentHook):
126
+ """Record tool names and the final message list for ``RunResult``.
127
+
128
+ The runner mutates ``context.messages`` in place across iterations, so the
129
+ snapshot is refreshed on every ``after_iteration`` call; the last call
130
+ reflects the end-of-turn state the SDK caller cares about.
131
+ """
132
+
133
+ def __init__(self) -> None:
134
+ super().__init__()
135
+ self.tools_used: list[str] = []
136
+ self.messages: list[dict[str, Any]] = []
137
+
138
+ async def after_iteration(self, context: AgentHookContext) -> None:
139
+ for call in context.tool_calls:
140
+ self.tools_used.append(call.name)
141
+ self.messages = list(context.messages)