dulus 3.6.2__tar.gz → 3.7.0__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 (332) hide show
  1. {dulus-3.6.2/dulus.egg-info → dulus-3.7.0}/PKG-INFO +42 -3
  2. {dulus-3.6.2 → dulus-3.7.0}/README.md +40 -2
  3. {dulus-3.6.2 → dulus-3.7.0}/compaction.py +15 -2
  4. {dulus-3.6.2 → dulus-3.7.0}/config.py +11 -1
  5. {dulus-3.6.2 → dulus-3.7.0}/docs/FAQ.md +18 -0
  6. {dulus-3.6.2 → dulus-3.7.0}/docs/GETTING_STARTED.md +33 -17
  7. {dulus-3.6.2 → dulus-3.7.0/dulus.egg-info}/PKG-INFO +42 -3
  8. {dulus-3.6.2 → dulus-3.7.0}/dulus.egg-info/SOURCES.txt +2 -0
  9. {dulus-3.6.2 → dulus-3.7.0}/dulus.egg-info/requires.txt +1 -0
  10. {dulus-3.6.2 → dulus-3.7.0}/dulus.py +41 -4
  11. dulus-3.7.0/dulus_tools/fs_compass.py +472 -0
  12. {dulus-3.6.2 → dulus-3.7.0}/pyproject.toml +4 -1
  13. dulus-3.7.0/tests/test_fs_compass.py +78 -0
  14. {dulus-3.6.2 → dulus-3.7.0}/tools.py +4 -0
  15. {dulus-3.6.2 → dulus-3.7.0}/LICENSE +0 -0
  16. {dulus-3.6.2 → dulus-3.7.0}/MANIFEST.in +0 -0
  17. {dulus-3.6.2 → dulus-3.7.0}/agent.py +0 -0
  18. {dulus-3.6.2 → dulus-3.7.0}/analytics.py +0 -0
  19. {dulus-3.6.2 → dulus-3.7.0}/backend/__init__.py +0 -0
  20. {dulus-3.6.2 → dulus-3.7.0}/backend/agents_bridge.py +0 -0
  21. {dulus-3.6.2 → dulus-3.7.0}/backend/compressor.py +0 -0
  22. {dulus-3.6.2 → dulus-3.7.0}/backend/context.py +0 -0
  23. {dulus-3.6.2 → dulus-3.7.0}/backend/githook.py +0 -0
  24. {dulus-3.6.2 → dulus-3.7.0}/backend/marketplace.py +0 -0
  25. {dulus-3.6.2 → dulus-3.7.0}/backend/mempalace_bridge.py +0 -0
  26. {dulus-3.6.2 → dulus-3.7.0}/backend/personas.py +0 -0
  27. {dulus-3.6.2 → dulus-3.7.0}/backend/plugins.py +0 -0
  28. {dulus-3.6.2 → dulus-3.7.0}/backend/server.py +0 -0
  29. {dulus-3.6.2 → dulus-3.7.0}/backend/tasks.py +0 -0
  30. {dulus-3.6.2 → dulus-3.7.0}/batch_api.py +0 -0
  31. {dulus-3.6.2 → dulus-3.7.0}/checkpoint/__init__.py +0 -0
  32. {dulus-3.6.2 → dulus-3.7.0}/checkpoint/hooks.py +0 -0
  33. {dulus-3.6.2 → dulus-3.7.0}/checkpoint/store.py +0 -0
  34. {dulus-3.6.2 → dulus-3.7.0}/checkpoint/types.py +0 -0
  35. {dulus-3.6.2 → dulus-3.7.0}/claude_code_watcher.py +0 -0
  36. {dulus-3.6.2 → dulus-3.7.0}/clipboard_utils.py +0 -0
  37. {dulus-3.6.2 → dulus-3.7.0}/cloudsave.py +0 -0
  38. {dulus-3.6.2 → dulus-3.7.0}/common.py +0 -0
  39. {dulus-3.6.2 → dulus-3.7.0}/context.py +0 -0
  40. {dulus-3.6.2 → dulus-3.7.0}/data/__init__.py +0 -0
  41. {dulus-3.6.2 → dulus-3.7.0}/data/active_persona.json +0 -0
  42. {dulus-3.6.2 → dulus-3.7.0}/data/marketplace.json +0 -0
  43. {dulus-3.6.2 → dulus-3.7.0}/data/personas.json +0 -0
  44. {dulus-3.6.2 → dulus-3.7.0}/data/plugins/__init__.py +0 -0
  45. {dulus-3.6.2 → dulus-3.7.0}/data/plugins/composio/__init__.py +0 -0
  46. {dulus-3.6.2 → dulus-3.7.0}/data/plugins/composio/composio_plugin/__init__.py +0 -0
  47. {dulus-3.6.2 → dulus-3.7.0}/data/plugins/composio/composio_plugin/session_manager.py +0 -0
  48. {dulus-3.6.2 → dulus-3.7.0}/data/plugins/composio/composio_plugin/tool_generator.py +0 -0
  49. {dulus-3.6.2 → dulus-3.7.0}/data/plugins/composio/plugin.json +0 -0
  50. {dulus-3.6.2 → dulus-3.7.0}/data/plugins/composio/plugin_tool.py +0 -0
  51. {dulus-3.6.2 → dulus-3.7.0}/data/tasks.json +0 -0
  52. {dulus-3.6.2 → dulus-3.7.0}/docs/API.md +0 -0
  53. {dulus-3.6.2 → dulus-3.7.0}/docs/BRAND_GUIDE.md +0 -0
  54. {dulus-3.6.2 → dulus-3.7.0}/docs/CHANGELOG.md +0 -0
  55. {dulus-3.6.2 → dulus-3.7.0}/docs/CONTRIBUTING.md +0 -0
  56. {dulus-3.6.2 → dulus-3.7.0}/docs/DEPLOYMENT.md +0 -0
  57. {dulus-3.6.2 → dulus-3.7.0}/docs/Dulus_AI_Whitepaper_(v2.0).pdf +0 -0
  58. {dulus-3.6.2 → dulus-3.7.0}/docs/INVESTOR_BRIEF.md +0 -0
  59. {dulus-3.6.2 → dulus-3.7.0}/docs/README.md +0 -0
  60. {dulus-3.6.2 → dulus-3.7.0}/docs/README_AR.md +0 -0
  61. {dulus-3.6.2 → dulus-3.7.0}/docs/README_EN.md +0 -0
  62. {dulus-3.6.2 → dulus-3.7.0}/docs/README_ES.md +0 -0
  63. {dulus-3.6.2 → dulus-3.7.0}/docs/README_FR.md +0 -0
  64. {dulus-3.6.2 → dulus-3.7.0}/docs/README_JA.md +0 -0
  65. {dulus-3.6.2 → dulus-3.7.0}/docs/README_KO.md +0 -0
  66. {dulus-3.6.2 → dulus-3.7.0}/docs/README_PT.md +0 -0
  67. {dulus-3.6.2 → dulus-3.7.0}/docs/README_RU.md +0 -0
  68. {dulus-3.6.2 → dulus-3.7.0}/docs/README_ZH.md +0 -0
  69. {dulus-3.6.2 → dulus-3.7.0}/docs/SECURITY.md +0 -0
  70. {dulus-3.6.2 → dulus-3.7.0}/docs/__init__.py +0 -0
  71. {dulus-3.6.2 → dulus-3.7.0}/docs/api.html +0 -0
  72. {dulus-3.6.2 → dulus-3.7.0}/docs/architecture.md +0 -0
  73. {dulus-3.6.2 → dulus-3.7.0}/docs/azure-speech-template.json +0 -0
  74. {dulus-3.6.2 → dulus-3.7.0}/docs/dashboard/index.html +0 -0
  75. {dulus-3.6.2 → dulus-3.7.0}/docs/divider.svg +0 -0
  76. {dulus-3.6.2 → dulus-3.7.0}/docs/dulus-bird.png +0 -0
  77. {dulus-3.6.2 → dulus-3.7.0}/docs/generate.py +0 -0
  78. {dulus-3.6.2 → dulus-3.7.0}/docs/hero.svg +0 -0
  79. {dulus-3.6.2 → dulus-3.7.0}/docs/index.html +0 -0
  80. {dulus-3.6.2 → dulus-3.7.0}/docs/news.md +0 -0
  81. {dulus-3.6.2 → dulus-3.7.0}/docs/nvidia-models.svg +0 -0
  82. {dulus-3.6.2 → dulus-3.7.0}/docs/particle-playground.html +0 -0
  83. {dulus-3.6.2 → dulus-3.7.0}/docs/personas/index.html +0 -0
  84. {dulus-3.6.2 → dulus-3.7.0}/docs/poetry-banner.png +0 -0
  85. {dulus-3.6.2 → dulus-3.7.0}/docs/preview.html +0 -0
  86. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-agents.svg +0 -0
  87. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-brainstorm.svg +0 -0
  88. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-bridges.svg +0 -0
  89. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-features.svg +0 -0
  90. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-freetier.svg +0 -0
  91. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-memory.svg +0 -0
  92. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-models.svg +0 -0
  93. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-perms.svg +0 -0
  94. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-plugins.svg +0 -0
  95. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-quickstart.svg +0 -0
  96. {dulus-3.6.2 → dulus-3.7.0}/docs/sec-ssj.svg +0 -0
  97. {dulus-3.6.2 → dulus-3.7.0}/docs/spinners.svg +0 -0
  98. {dulus-3.6.2 → dulus-3.7.0}/docs/split-pane.svg +0 -0
  99. {dulus-3.6.2 → dulus-3.7.0}/docs/terminal-boot.svg +0 -0
  100. {dulus-3.6.2 → dulus-3.7.0}/dulus.egg-info/dependency_links.txt +0 -0
  101. {dulus-3.6.2 → dulus-3.7.0}/dulus.egg-info/entry_points.txt +0 -0
  102. {dulus-3.6.2 → dulus-3.7.0}/dulus.egg-info/top_level.txt +0 -0
  103. {dulus-3.6.2 → dulus-3.7.0}/dulus_gui.py +0 -0
  104. {dulus-3.6.2 → dulus-3.7.0}/dulus_gui_web.py +0 -0
  105. {dulus-3.6.2 → dulus-3.7.0}/dulus_mcp/__init__.py +0 -0
  106. {dulus-3.6.2 → dulus-3.7.0}/dulus_mcp/client.py +0 -0
  107. {dulus-3.6.2 → dulus-3.7.0}/dulus_mcp/config.py +0 -0
  108. {dulus-3.6.2 → dulus-3.7.0}/dulus_mcp/tools.py +0 -0
  109. {dulus-3.6.2 → dulus-3.7.0}/dulus_mcp/types.py +0 -0
  110. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/__init__.py +0 -0
  111. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/add_dir_manager.py +0 -0
  112. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/afk_mode.py +0 -0
  113. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/approval_runtime.py +0 -0
  114. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/background_tasks.py +0 -0
  115. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/clipboard_utils.py +0 -0
  116. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/diff_visualizer.py +0 -0
  117. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/export_import.py +0 -0
  118. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/hook_engine.py +0 -0
  119. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/notification_manager.py +0 -0
  120. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/session_fork.py +0 -0
  121. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/shell_mode.py +0 -0
  122. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/todo_visualizer.py +0 -0
  123. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/wire_events.py +0 -0
  124. {dulus-3.6.2 → dulus-3.7.0}/dulus_tools/yolo_mode.py +0 -0
  125. {dulus-3.6.2 → dulus-3.7.0}/governance.py +0 -0
  126. {dulus-3.6.2 → dulus-3.7.0}/gui/__init__.py +0 -0
  127. {dulus-3.6.2 → dulus-3.7.0}/gui/agent_bridge.py +0 -0
  128. {dulus-3.6.2 → dulus-3.7.0}/gui/chat_widget.py +0 -0
  129. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/App.tsx +0 -0
  130. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/THIRD_PARTY_NOTICES.md +0 -0
  131. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/dist/index.html +0 -0
  132. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/dist/standalone.html +0 -0
  133. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/index.html +0 -0
  134. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/index.tsx +0 -0
  135. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/metadata.json +0 -0
  136. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/package-lock.json +0 -0
  137. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/package.json +0 -0
  138. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/types.ts +0 -0
  139. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/utils.ts +0 -0
  140. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/vertex-ai-proxy-interceptor.js +0 -0
  141. {dulus-3.6.2 → dulus-3.7.0}/gui/dulus_orchestrator/vite.config.ts +0 -0
  142. {dulus-3.6.2 → dulus-3.7.0}/gui/main_window.py +0 -0
  143. {dulus-3.6.2 → dulus-3.7.0}/gui/personas.py +0 -0
  144. {dulus-3.6.2 → dulus-3.7.0}/gui/sandbox_server.py +0 -0
  145. {dulus-3.6.2 → dulus-3.7.0}/gui/session_utils.py +0 -0
  146. {dulus-3.6.2 → dulus-3.7.0}/gui/settings_dialog.py +0 -0
  147. {dulus-3.6.2 → dulus-3.7.0}/gui/sidebar.py +0 -0
  148. {dulus-3.6.2 → dulus-3.7.0}/gui/tasks_view.py +0 -0
  149. {dulus-3.6.2 → dulus-3.7.0}/gui/themes.py +0 -0
  150. {dulus-3.6.2 → dulus-3.7.0}/gui/tool_panel.py +0 -0
  151. {dulus-3.6.2 → dulus-3.7.0}/input.py +0 -0
  152. {dulus-3.6.2 → dulus-3.7.0}/license_manager.py +0 -0
  153. {dulus-3.6.2 → dulus-3.7.0}/memory/__init__.py +0 -0
  154. {dulus-3.6.2 → dulus-3.7.0}/memory/audit.py +0 -0
  155. {dulus-3.6.2 → dulus-3.7.0}/memory/consolidator.py +0 -0
  156. {dulus-3.6.2 → dulus-3.7.0}/memory/context.py +0 -0
  157. {dulus-3.6.2 → dulus-3.7.0}/memory/offload.py +0 -0
  158. {dulus-3.6.2 → dulus-3.7.0}/memory/palace.py +0 -0
  159. {dulus-3.6.2 → dulus-3.7.0}/memory/scan.py +0 -0
  160. {dulus-3.6.2 → dulus-3.7.0}/memory/sessions.py +0 -0
  161. {dulus-3.6.2 → dulus-3.7.0}/memory/store.py +0 -0
  162. {dulus-3.6.2 → dulus-3.7.0}/memory/tools.py +0 -0
  163. {dulus-3.6.2 → dulus-3.7.0}/memory/types.py +0 -0
  164. {dulus-3.6.2 → dulus-3.7.0}/memory/vector_search.py +0 -0
  165. {dulus-3.6.2 → dulus-3.7.0}/multi_agent/__init__.py +0 -0
  166. {dulus-3.6.2 → dulus-3.7.0}/multi_agent/subagent.py +0 -0
  167. {dulus-3.6.2 → dulus-3.7.0}/multi_agent/tools.py +0 -0
  168. {dulus-3.6.2 → dulus-3.7.0}/offload_helper.py +0 -0
  169. {dulus-3.6.2 → dulus-3.7.0}/personality_config.py +0 -0
  170. {dulus-3.6.2 → dulus-3.7.0}/plugin/__init__.py +0 -0
  171. {dulus-3.6.2 → dulus-3.7.0}/plugin/autoadapter.py +0 -0
  172. {dulus-3.6.2 → dulus-3.7.0}/plugin/loader.py +0 -0
  173. {dulus-3.6.2 → dulus-3.7.0}/plugin/recommend.py +0 -0
  174. {dulus-3.6.2 → dulus-3.7.0}/plugin/store.py +0 -0
  175. {dulus-3.6.2 → dulus-3.7.0}/plugin/types.py +0 -0
  176. {dulus-3.6.2 → dulus-3.7.0}/providers.py +0 -0
  177. {dulus-3.6.2 → dulus-3.7.0}/sandbox/README.md +0 -0
  178. {dulus-3.6.2 → dulus-3.7.0}/sandbox/__init__.py +0 -0
  179. {dulus-3.6.2 → dulus-3.7.0}/sandbox/components.json +0 -0
  180. {dulus-3.6.2 → dulus-3.7.0}/sandbox/dist/assets/index-DE51D6wI.css +0 -0
  181. {dulus-3.6.2 → dulus-3.7.0}/sandbox/dist/assets/index-DMCCNE9Y.js +0 -0
  182. {dulus-3.6.2 → dulus-3.7.0}/sandbox/dist/index.html +0 -0
  183. {dulus-3.6.2 → dulus-3.7.0}/sandbox/dist/wallpaper-default.jpg +0 -0
  184. {dulus-3.6.2 → dulus-3.7.0}/sandbox/dist/wallpapers/default.jpeg +0 -0
  185. {dulus-3.6.2 → dulus-3.7.0}/sandbox/dist/wallpapers/light.jpeg +0 -0
  186. {dulus-3.6.2 → dulus-3.7.0}/sandbox/dist/wallpapers/nature.jpeg +0 -0
  187. {dulus-3.6.2 → dulus-3.7.0}/sandbox/dist/wallpapers/tech.jpeg +0 -0
  188. {dulus-3.6.2 → dulus-3.7.0}/sandbox/eslint.config.js +0 -0
  189. {dulus-3.6.2 → dulus-3.7.0}/sandbox/index.html +0 -0
  190. {dulus-3.6.2 → dulus-3.7.0}/sandbox/info.md +0 -0
  191. {dulus-3.6.2 → dulus-3.7.0}/sandbox/package-lock.json +0 -0
  192. {dulus-3.6.2 → dulus-3.7.0}/sandbox/package.json +0 -0
  193. {dulus-3.6.2 → dulus-3.7.0}/sandbox/postcss.config.js +0 -0
  194. {dulus-3.6.2 → dulus-3.7.0}/sandbox/tailwind.config.js +0 -0
  195. {dulus-3.6.2 → dulus-3.7.0}/sandbox/tsconfig.app.json +0 -0
  196. {dulus-3.6.2 → dulus-3.7.0}/sandbox/tsconfig.json +0 -0
  197. {dulus-3.6.2 → dulus-3.7.0}/sandbox/tsconfig.node.json +0 -0
  198. {dulus-3.6.2 → dulus-3.7.0}/sandbox/vite.config.ts +0 -0
  199. {dulus-3.6.2 → dulus-3.7.0}/sandbox_bootstrap.py +0 -0
  200. {dulus-3.6.2 → dulus-3.7.0}/setup.cfg +0 -0
  201. {dulus-3.6.2 → dulus-3.7.0}/skill/__init__.py +0 -0
  202. {dulus-3.6.2 → dulus-3.7.0}/skill/builtin.py +0 -0
  203. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/LICENSE-obsidian-skills +0 -0
  204. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/README.md +0 -0
  205. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/defuddle/SKILL.md +0 -0
  206. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/json-canvas/SKILL.md +0 -0
  207. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/json-canvas/references/EXAMPLES.md +0 -0
  208. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/obsidian-bases/SKILL.md +0 -0
  209. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/obsidian-bases/references/FUNCTIONS_REFERENCE.md +0 -0
  210. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/obsidian-cli/SKILL.md +0 -0
  211. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/obsidian-markdown/SKILL.md +0 -0
  212. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/obsidian-markdown/references/CALLOUTS.md +0 -0
  213. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/obsidian-markdown/references/EMBEDS.md +0 -0
  214. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/obsidian-markdown/references/PROPERTIES.md +0 -0
  215. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/README.md +0 -0
  216. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/SKILL.md +0 -0
  217. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/addresses.json +0 -0
  218. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/advancedbackgroundchecks.json +0 -0
  219. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/beenverified.json +0 -0
  220. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/clustal.json +0 -0
  221. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/clustrmaps.json +0 -0
  222. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/cyberbackgroundchecks.json +0 -0
  223. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/familytreenow.json +0 -0
  224. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/fastpeoplesearch.json +0 -0
  225. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/intelius.json +0 -0
  226. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/mylife.json +0 -0
  227. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/nuwber.json +0 -0
  228. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/peekyou.json +0 -0
  229. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/peoplefinders.json +0 -0
  230. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/radaris.json +0 -0
  231. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/rehold.json +0 -0
  232. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/searchpeoplefree.json +0 -0
  233. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/socialcatfish.json +0 -0
  234. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/spokeo.json +0 -0
  235. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/thatsthem.json +0 -0
  236. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/truepeoplesearch.json +0 -0
  237. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/usphonebook.json +0 -0
  238. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/brokers/whitepages.json +0 -0
  239. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/legal/ccpa.md +0 -0
  240. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/legal/drop.md +0 -0
  241. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/legal/gdpr.md +0 -0
  242. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/methods.md +0 -0
  243. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/site-playbooks.md +0 -0
  244. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/references/state-machine.md +0 -0
  245. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/autopilot.py +0 -0
  246. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/badbool.py +0 -0
  247. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/brokers.py +0 -0
  248. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/cdp.py +0 -0
  249. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/config.py +0 -0
  250. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/crypto.py +0 -0
  251. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/dossier.py +0 -0
  252. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/email_modes.py +0 -0
  253. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/emailer.py +0 -0
  254. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/ledger.py +0 -0
  255. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/legal.py +0 -0
  256. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/paths.py +0 -0
  257. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/pdd.py +0 -0
  258. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/registry.py +0 -0
  259. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/report.py +0 -0
  260. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/scan.py +0 -0
  261. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/storage.py +0 -0
  262. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/tiers.py +0 -0
  263. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/scripts/vectors.py +0 -0
  264. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/templates/consent/authorization.md +0 -0
  265. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/templates/emails/ccpa-authorized-agent.txt +0 -0
  266. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/templates/emails/ccpa-deletion.txt +0 -0
  267. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/templates/emails/ccpa-indirect-deletion.txt +0 -0
  268. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/templates/emails/gdpr-erasure.txt +0 -0
  269. {dulus-3.6.2 → dulus-3.7.0}/skill/bundled/unbroker/templates/emails/generic-optout.txt +0 -0
  270. {dulus-3.6.2 → dulus-3.7.0}/skill/clawhub.py +0 -0
  271. {dulus-3.6.2 → dulus-3.7.0}/skill/executor.py +0 -0
  272. {dulus-3.6.2 → dulus-3.7.0}/skill/loader.py +0 -0
  273. {dulus-3.6.2 → dulus-3.7.0}/skill/tools.py +0 -0
  274. {dulus-3.6.2 → dulus-3.7.0}/skills.py +0 -0
  275. {dulus-3.6.2 → dulus-3.7.0}/soul.py +0 -0
  276. {dulus-3.6.2 → dulus-3.7.0}/spinner.py +0 -0
  277. {dulus-3.6.2 → dulus-3.7.0}/string_utils.py +0 -0
  278. {dulus-3.6.2 → dulus-3.7.0}/subagent.py +0 -0
  279. {dulus-3.6.2 → dulus-3.7.0}/task/__init__.py +0 -0
  280. {dulus-3.6.2 → dulus-3.7.0}/task/store.py +0 -0
  281. {dulus-3.6.2 → dulus-3.7.0}/task/tools.py +0 -0
  282. {dulus-3.6.2 → dulus-3.7.0}/task/types.py +0 -0
  283. {dulus-3.6.2 → dulus-3.7.0}/tests/test_afk_yolo.py +0 -0
  284. {dulus-3.6.2 → dulus-3.7.0}/tests/test_approval_runtime.py +0 -0
  285. {dulus-3.6.2 → dulus-3.7.0}/tests/test_background_task_tools.py +0 -0
  286. {dulus-3.6.2 → dulus-3.7.0}/tests/test_background_tasks.py +0 -0
  287. {dulus-3.6.2 → dulus-3.7.0}/tests/test_checkpoint.py +0 -0
  288. {dulus-3.6.2 → dulus-3.7.0}/tests/test_clipboard_utils.py +0 -0
  289. {dulus-3.6.2 → dulus-3.7.0}/tests/test_compaction.py +0 -0
  290. {dulus-3.6.2 → dulus-3.7.0}/tests/test_diff_view.py +0 -0
  291. {dulus-3.6.2 → dulus-3.7.0}/tests/test_diff_visualization.py +0 -0
  292. {dulus-3.6.2 → dulus-3.7.0}/tests/test_display_blocks.py +0 -0
  293. {dulus-3.6.2 → dulus-3.7.0}/tests/test_export_import.py +0 -0
  294. {dulus-3.6.2 → dulus-3.7.0}/tests/test_hook_engine.py +0 -0
  295. {dulus-3.6.2 → dulus-3.7.0}/tests/test_injection_fix.py +0 -0
  296. {dulus-3.6.2 → dulus-3.7.0}/tests/test_license.py +0 -0
  297. {dulus-3.6.2 → dulus-3.7.0}/tests/test_mcp.py +0 -0
  298. {dulus-3.6.2 → dulus-3.7.0}/tests/test_memory.py +0 -0
  299. {dulus-3.6.2 → dulus-3.7.0}/tests/test_notification_manager.py +0 -0
  300. {dulus-3.6.2 → dulus-3.7.0}/tests/test_plugin.py +0 -0
  301. {dulus-3.6.2 → dulus-3.7.0}/tests/test_session_fork.py +0 -0
  302. {dulus-3.6.2 → dulus-3.7.0}/tests/test_shell_mode.py +0 -0
  303. {dulus-3.6.2 → dulus-3.7.0}/tests/test_skills.py +0 -0
  304. {dulus-3.6.2 → dulus-3.7.0}/tests/test_steer_input.py +0 -0
  305. {dulus-3.6.2 → dulus-3.7.0}/tests/test_subagent.py +0 -0
  306. {dulus-3.6.2 → dulus-3.7.0}/tests/test_task.py +0 -0
  307. {dulus-3.6.2 → dulus-3.7.0}/tests/test_telegram_buffer.py +0 -0
  308. {dulus-3.6.2 → dulus-3.7.0}/tests/test_think_tool.py +0 -0
  309. {dulus-3.6.2 → dulus-3.7.0}/tests/test_todo_tool.py +0 -0
  310. {dulus-3.6.2 → dulus-3.7.0}/tests/test_todo_visualization.py +0 -0
  311. {dulus-3.6.2 → dulus-3.7.0}/tests/test_tool_registry.py +0 -0
  312. {dulus-3.6.2 → dulus-3.7.0}/tests/test_voice.py +0 -0
  313. {dulus-3.6.2 → dulus-3.7.0}/tests/test_wire_events.py +0 -0
  314. {dulus-3.6.2 → dulus-3.7.0}/tmux_offloader.py +0 -0
  315. {dulus-3.6.2 → dulus-3.7.0}/tmux_tools.py +0 -0
  316. {dulus-3.6.2 → dulus-3.7.0}/tool_registry.py +0 -0
  317. {dulus-3.6.2 → dulus-3.7.0}/ui/__init__.py +0 -0
  318. {dulus-3.6.2 → dulus-3.7.0}/ui/input.py +0 -0
  319. {dulus-3.6.2 → dulus-3.7.0}/ui/render.py +0 -0
  320. {dulus-3.6.2 → dulus-3.7.0}/voice/__init__.py +0 -0
  321. {dulus-3.6.2 → dulus-3.7.0}/voice/audio_utils.py +0 -0
  322. {dulus-3.6.2 → dulus-3.7.0}/voice/keyterms.py +0 -0
  323. {dulus-3.6.2 → dulus-3.7.0}/voice/recorder.py +0 -0
  324. {dulus-3.6.2 → dulus-3.7.0}/voice/stt.py +0 -0
  325. {dulus-3.6.2 → dulus-3.7.0}/voice/tts.py +0 -0
  326. {dulus-3.6.2 → dulus-3.7.0}/voice/wake_word.py +0 -0
  327. {dulus-3.6.2 → dulus-3.7.0}/webbridge/__init__.py +0 -0
  328. {dulus-3.6.2 → dulus-3.7.0}/webbridge/core.py +0 -0
  329. {dulus-3.6.2 → dulus-3.7.0}/webbridge/tools.py +0 -0
  330. {dulus-3.6.2 → dulus-3.7.0}/webchat.py +0 -0
  331. {dulus-3.6.2 → dulus-3.7.0}/webchat_server.py +0 -0
  332. {dulus-3.6.2 → dulus-3.7.0}/welcome.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dulus
3
- Version: 3.6.2
3
+ Version: 3.7.0
4
4
  Summary: Use IA as an agent without an API key. $0. Harvest your browser session for Gemini (guest, no login), Claude.ai, Claude Code, Kimi.com, Qwen, DeepSeek — drive them like an API, no per-token billing. Plus LiteLLM (100+ paid providers), local models via Ollama, /lang in 34 languages, Mesa Redonda, voice, OCR, MemPalace, embedded sandbox OS.
5
5
  Author: KevRojo
6
6
  License: GPL-3.0
@@ -37,6 +37,7 @@ Requires-Dist: typing-extensions>=4.10.0
37
37
  Requires-Dist: composio>=1.0.0rc2
38
38
  Requires-Dist: beautifulsoup4>=4.12.0
39
39
  Requires-Dist: sentry-sdk>=2.0.0
40
+ Requires-Dist: truststore>=0.9
40
41
  Requires-Dist: pytesseract>=0.3.10
41
42
  Provides-Extra: memory
42
43
  Requires-Dist: mempalace>=3.3.4; extra == "memory"
@@ -65,7 +66,7 @@ Dynamic: license-file
65
66
 
66
67
  # ▲ DULUS
67
68
  >
68
- > `pip install dulus` → press Enter → working IA in 30 seconds. Try it.
69
+ > `curl -fsSL …/install.sh | bash` → press Enter → working IA in 30 seconds. Try it.
69
70
 
70
71
  SET /sticky_input ON since the first run for the best experience!
71
72
 
@@ -176,13 +177,27 @@ Dulus adapt any python repository <3
176
177
 
177
178
  Download [`Dulus-Free-3.3.3-x64.msi`](https://github.com/KevRojo/Dulus/releases/download/v3.3.3/Dulus-Free-3.3.3-x64.msi) → double-click and fly. Embedded Python, every library, and the desktop GUI bundled. No pip, no terminal, no admin. ~85 MB.
178
179
 
179
- **Everyone else — one command:**
180
+ **Linux / macOS / WSL — one command (handles Python for you):**
181
+
182
+ ```bash
183
+ curl -fsSL https://raw.githubusercontent.com/KevRojo/Dulus/main/install.sh | bash
184
+ ```
185
+
186
+ The installer finds or **bootstraps Python 3.11+** (apt / deadsnakes / brew / uv), installs Dulus, and puts `dulus` on your PATH. Works on stock Ubuntu 20.04/22.04 where plain `pip install dulus` dies with `No matching distribution found` (pip hides packages that need a newer Python — Dulus needs ≥3.11).
187
+
188
+ **Already on Python 3.11+?** Then this is enough:
180
189
 
181
190
  ```bash
182
191
  pip install dulus
183
192
  dulus
184
193
  ```
185
194
 
195
+ **Windows (PowerShell, if you prefer the terminal over the MSI):**
196
+
197
+ ```powershell
198
+ iwr -useb https://raw.githubusercontent.com/KevRojo/Dulus/main/install.ps1 | iex
199
+ ```
200
+
186
201
  First run opens a welcome wizard that can get you **working IA without an API key** — it captures a Gemini guest session from your browser (no login, no card). Or set any key you already have. Zero to flight in 30 seconds.
187
202
 
188
203
  > 💡 Set `/sticky_input ON` on first run for the best experience.
@@ -270,3 +285,27 @@ audit it yourself.
270
285
  /config telemetry=off # inside Dulus
271
286
  DULUS_TELEMETRY=0 # environment variable
272
287
  ```
288
+
289
+ <p align="center"><img src="https://raw.githubusercontent.com/KevRojo/Dulus/main/docs/divider.svg" alt="" width="100%"></p>
290
+
291
+ ## 💛 Sponsors & Startup Programs
292
+
293
+ Dulus is proudly supported by these startup programs — powering our infrastructure, observability, and analytics:
294
+
295
+ <p align="center">
296
+ <a href="https://www.datadoghq.com/partner/datadog-for-startups/"><img src="https://cdn.simpleicons.org/datadog" height="42" alt="Datadog" title="Datadog for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
297
+ <a href="https://www.cloudflare.com/forstartups/"><img src="https://cdn.simpleicons.org/cloudflare" height="42" alt="Cloudflare" title="Cloudflare for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
298
+ <a href="https://sentry.io/for/startups/"><img src="https://cdn.simpleicons.org/sentry" height="42" alt="Sentry" title="Sentry for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
299
+ <a href="https://www.anthropic.com/startups"><img src="https://cdn.simpleicons.org/anthropic" height="42" alt="Anthropic" title="Claude for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
300
+ <a href="https://aws.amazon.com/activate/"><img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/amazonwebservices/amazonwebservices-plain-wordmark.svg" height="42" alt="AWS" title="AWS Activate"></a>
301
+ </p>
302
+ <p align="center">
303
+ <a href="https://www.mongodb.com/startups"><img src="https://cdn.simpleicons.org/mongodb" height="38" alt="MongoDB" title="MongoDB for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
304
+ <a href="https://mixpanel.com/startups/"><img src="https://cdn.simpleicons.org/mixpanel" height="38" alt="Mixpanel" title="Mixpanel for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
305
+ <a href="https://amplitude.com/startups"><img src="https://www.google.com/s2/favicons?domain=amplitude.com&sz=128" height="38" alt="Amplitude" title="Amplitude Startup Scholarship"></a>&nbsp;&nbsp;&nbsp;&nbsp;
306
+ <a href="https://www.digitalocean.com/hatch"><img src="https://cdn.simpleicons.org/digitalocean" height="38" alt="DigitalOcean" title="DigitalOcean Hatch"></a>&nbsp;&nbsp;&nbsp;&nbsp;
307
+ <a href="https://www.notion.com/startups"><img src="https://cdn.simpleicons.org/notion" height="38" alt="Notion" title="Notion for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
308
+ <a href="https://www.zendesk.com/campaign/startups/"><img src="https://cdn.simpleicons.org/zendesk" height="38" alt="Zendesk" title="Zendesk for Startups"></a>
309
+ </p>
310
+
311
+ <p align="center"><i>Want to support Dulus? → <a href="https://github.com/sponsors/KevRojo">GitHub Sponsors</a> 🦅</i></p>
@@ -1,6 +1,6 @@
1
1
  # ▲ DULUS
2
2
  >
3
- > `pip install dulus` → press Enter → working IA in 30 seconds. Try it.
3
+ > `curl -fsSL …/install.sh | bash` → press Enter → working IA in 30 seconds. Try it.
4
4
 
5
5
  SET /sticky_input ON since the first run for the best experience!
6
6
 
@@ -111,13 +111,27 @@ Dulus adapt any python repository <3
111
111
 
112
112
  Download [`Dulus-Free-3.3.3-x64.msi`](https://github.com/KevRojo/Dulus/releases/download/v3.3.3/Dulus-Free-3.3.3-x64.msi) → double-click and fly. Embedded Python, every library, and the desktop GUI bundled. No pip, no terminal, no admin. ~85 MB.
113
113
 
114
- **Everyone else — one command:**
114
+ **Linux / macOS / WSL — one command (handles Python for you):**
115
+
116
+ ```bash
117
+ curl -fsSL https://raw.githubusercontent.com/KevRojo/Dulus/main/install.sh | bash
118
+ ```
119
+
120
+ The installer finds or **bootstraps Python 3.11+** (apt / deadsnakes / brew / uv), installs Dulus, and puts `dulus` on your PATH. Works on stock Ubuntu 20.04/22.04 where plain `pip install dulus` dies with `No matching distribution found` (pip hides packages that need a newer Python — Dulus needs ≥3.11).
121
+
122
+ **Already on Python 3.11+?** Then this is enough:
115
123
 
116
124
  ```bash
117
125
  pip install dulus
118
126
  dulus
119
127
  ```
120
128
 
129
+ **Windows (PowerShell, if you prefer the terminal over the MSI):**
130
+
131
+ ```powershell
132
+ iwr -useb https://raw.githubusercontent.com/KevRojo/Dulus/main/install.ps1 | iex
133
+ ```
134
+
121
135
  First run opens a welcome wizard that can get you **working IA without an API key** — it captures a Gemini guest session from your browser (no login, no card). Or set any key you already have. Zero to flight in 30 seconds.
122
136
 
123
137
  > 💡 Set `/sticky_input ON` on first run for the best experience.
@@ -205,3 +219,27 @@ audit it yourself.
205
219
  /config telemetry=off # inside Dulus
206
220
  DULUS_TELEMETRY=0 # environment variable
207
221
  ```
222
+
223
+ <p align="center"><img src="https://raw.githubusercontent.com/KevRojo/Dulus/main/docs/divider.svg" alt="" width="100%"></p>
224
+
225
+ ## 💛 Sponsors & Startup Programs
226
+
227
+ Dulus is proudly supported by these startup programs — powering our infrastructure, observability, and analytics:
228
+
229
+ <p align="center">
230
+ <a href="https://www.datadoghq.com/partner/datadog-for-startups/"><img src="https://cdn.simpleicons.org/datadog" height="42" alt="Datadog" title="Datadog for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
231
+ <a href="https://www.cloudflare.com/forstartups/"><img src="https://cdn.simpleicons.org/cloudflare" height="42" alt="Cloudflare" title="Cloudflare for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
232
+ <a href="https://sentry.io/for/startups/"><img src="https://cdn.simpleicons.org/sentry" height="42" alt="Sentry" title="Sentry for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
233
+ <a href="https://www.anthropic.com/startups"><img src="https://cdn.simpleicons.org/anthropic" height="42" alt="Anthropic" title="Claude for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
234
+ <a href="https://aws.amazon.com/activate/"><img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/amazonwebservices/amazonwebservices-plain-wordmark.svg" height="42" alt="AWS" title="AWS Activate"></a>
235
+ </p>
236
+ <p align="center">
237
+ <a href="https://www.mongodb.com/startups"><img src="https://cdn.simpleicons.org/mongodb" height="38" alt="MongoDB" title="MongoDB for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
238
+ <a href="https://mixpanel.com/startups/"><img src="https://cdn.simpleicons.org/mixpanel" height="38" alt="Mixpanel" title="Mixpanel for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
239
+ <a href="https://amplitude.com/startups"><img src="https://www.google.com/s2/favicons?domain=amplitude.com&sz=128" height="38" alt="Amplitude" title="Amplitude Startup Scholarship"></a>&nbsp;&nbsp;&nbsp;&nbsp;
240
+ <a href="https://www.digitalocean.com/hatch"><img src="https://cdn.simpleicons.org/digitalocean" height="38" alt="DigitalOcean" title="DigitalOcean Hatch"></a>&nbsp;&nbsp;&nbsp;&nbsp;
241
+ <a href="https://www.notion.com/startups"><img src="https://cdn.simpleicons.org/notion" height="38" alt="Notion" title="Notion for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
242
+ <a href="https://www.zendesk.com/campaign/startups/"><img src="https://cdn.simpleicons.org/zendesk" height="38" alt="Zendesk" title="Zendesk for Startups"></a>
243
+ </p>
244
+
245
+ <p align="center"><i>Want to support Dulus? → <a href="https://github.com/sponsors/KevRojo">GitHub Sponsors</a> 🦅</i></p>
@@ -27,7 +27,8 @@ CHECKPOINT_DIR.mkdir(parents=True, exist_ok=True)
27
27
 
28
28
  # ── Token estimation ──────────────────────────────────────────────────────
29
29
 
30
- def estimate_tokens(messages: list, model: str = "", config: dict | None = None) -> int:
30
+ def estimate_tokens(messages: list, model: str = "", config: dict | None = None,
31
+ fast: bool = False) -> int:
31
32
  """Estimate token count.
32
33
 
33
34
  For Kimi/Moonshot models, uses the native Kimi API token estimation endpoint
@@ -37,11 +38,13 @@ def estimate_tokens(messages: list, model: str = "", config: dict | None = None)
37
38
  messages: list of message dicts with "content" field (str or list of dicts)
38
39
  model: model string (optional, e.g., "kimi-k2.5")
39
40
  config: agent config dict (optional, for accessing API keys)
41
+ fast: if True, NEVER hit the network — char-based estimation only.
42
+ Use this from hot paths (per-turn pre-checks, UI, tight loops).
40
43
  Returns:
41
44
  approximate token count, int
42
45
  """
43
46
  # Try Kimi native API estimation if this is a Kimi/Moonshot model
44
- if model and (providers.detect_provider(model) in ("kimi", "moonshot")):
47
+ if not fast and model and (providers.detect_provider(model) in ("kimi", "moonshot")):
45
48
  api_key = ""
46
49
  if config:
47
50
  api_key = providers.get_api_key("kimi", config) or providers.get_api_key("moonshot", config)
@@ -473,6 +476,16 @@ def maybe_compact(state, config: dict) -> bool:
473
476
  limit = get_context_limit(model)
474
477
  threshold = limit * 0.7
475
478
 
479
+ # Fast pre-check (startup-latency fix, 2026-07-06): the precise path can
480
+ # hit the Kimi token-estimation ENDPOINT — a blocking network round-trip
481
+ # that sits directly on the submit→dispatch critical path of EVERY turn,
482
+ # including the very first one where the conversation is obviously tiny.
483
+ # The char-based estimate deliberately overcounts (~10% buffer), so if
484
+ # even IT says we're under half the threshold, no network call can
485
+ # change the verdict. Skip straight to dispatch.
486
+ if estimate_tokens(state.messages, model=model, config=config, fast=True) <= threshold * 0.5:
487
+ return False
488
+
476
489
  if estimate_tokens(state.messages, model=model, config=config) <= threshold:
477
490
  return False
478
491
 
@@ -21,7 +21,17 @@ DEFAULTS = {
21
21
  "verbose": False,
22
22
  "thinking": False,
23
23
  "git_status": False,
24
- "thinking_budget": 50000,
24
+ # 0 = auto: scale budget with /thinking level (low=2048, med=6000,
25
+ # high=16000, on=8192). A non-zero value here overrides ALL levels —
26
+ # the old default of 50000 silently let every thinking turn burn up
27
+ # to 50K output tokens regardless of level.
28
+ "thinking_budget": 0,
29
+ # Anthropic prompt-cache TTL. "1h" = cache survives think-pauses between
30
+ # turns (the default 5-min ephemeral cache dies if you pause >5 min,
31
+ # forcing a full prefix re-write at 1.25x price every time). 1h costs 2x
32
+ # once on write, then ~0.1x on every hit — massively cheaper for
33
+ # interactive sessions.
34
+ "cache_ttl": "1h",
25
35
  "custom_base_url": "", # for "custom" provider
26
36
  "max_tool_output": 2500,
27
37
  "max_agent_depth": 3,
@@ -139,6 +139,15 @@ The token is the fuel layer for the Dulus business layer. The open-source REPL s
139
139
 
140
140
  ## Troubleshooting
141
141
 
142
+ ### "No matching distribution found for dulus"
143
+
144
+ Your system Python is older than 3.11. pip hides incompatible packages and prints that useless error instead of saying "need Python 3.11+".
145
+
146
+ ```bash
147
+ # Zero-friction fix — installer bootstraps Python for you
148
+ curl -fsSL https://raw.githubusercontent.com/KevRojo/Dulus/main/install.sh | bash
149
+ ```
150
+
142
151
  ### "No module named 'tkinter'"
143
152
 
144
153
  ```bash
@@ -225,6 +234,15 @@ rm -rf ~/.dulus
225
234
  # Luego corre `dulus` de nuevo para el wizard de bienvenida
226
235
  ```
227
236
 
237
+ ### "No matching distribution found for dulus" en Ubuntu
238
+
239
+ Tu Python del sistema es mas viejo que 3.11. pip esconde el paquete y tira ese error basura.
240
+
241
+ ```bash
242
+ # Arreglo zero friction — el installer te sube Python solo
243
+ curl -fsSL https://raw.githubusercontent.com/KevRojo/Dulus/main/install.sh | bash
244
+ ```
245
+
228
246
  ---
229
247
 
230
248
  > *Nombrado por el pajaro, no por el cohete. Seguimos volando.*
@@ -16,22 +16,7 @@
16
16
 
17
17
  ## Installation
18
18
 
19
- ### Option A: pip (Fastest)
20
-
21
- ```bash
22
- pip install dulus
23
- ```
24
-
25
- With optional extras:
26
-
27
- ```bash
28
- pip install "dulus[memory]" # + MemPalace semantic memory
29
- pip install "dulus[voice]" # + Voice I/O (Whisper STT + TTS)
30
- pip install "dulus[webbridge]" # + Playwright browser automation
31
- pip install "dulus[full]" # Everything
32
- ```
33
-
34
- ### Option B: One-liner Installer (Recommended)
19
+ ### Option A: One-liner Installer (Recommended — zero friction)
35
20
 
36
21
  **Linux / macOS / WSL / Termux:**
37
22
 
@@ -39,7 +24,9 @@ pip install "dulus[full]" # Everything
39
24
  curl -fsSL https://raw.githubusercontent.com/KevRojo/Dulus/main/install.sh | bash
40
25
  ```
41
26
 
42
- The installer detects your OS, package manager, and Python version, then offers profiles:
27
+ The installer finds **or bootstraps** Python ≥3.11 (apt / deadsnakes / brew / uv), installs Dulus, and puts `dulus` on your PATH. This is the path that works on stock Ubuntu 20.04/22.04 where plain `pip install dulus` dies with `No matching distribution found` (pip hides packages that need a newer Python).
28
+
29
+ Profiles:
43
30
 
44
31
  - **`full`** — Everything: voice (Whisper + PortAudio), browser tools (Playwright), MemPalace, tmux, WSL audio bridge (~1.5 GB)
45
32
  - **`standard`** — REPL + webchat + tmux daemon + Telegram bridge (~300 MB)
@@ -52,6 +39,8 @@ The installer detects your OS, package manager, and Python version, then offers
52
39
  irm https://raw.githubusercontent.com/KevRojo/Dulus/main/install.ps1 | iex
53
40
  ```
54
41
 
42
+ (Or skip Python entirely with the MSI — see README.)
43
+
55
44
  Power-user flags:
56
45
 
57
46
  ```bash
@@ -65,6 +54,23 @@ curl -fsSL .../install.sh | bash -s -- --profile=full --pipx
65
54
  curl -fsSL .../install.sh | bash -s -- --pre
66
55
  ```
67
56
 
57
+ ### Option B: pip (only if you already have Python 3.11+)
58
+
59
+ ```bash
60
+ pip install dulus
61
+ ```
62
+
63
+ With optional extras:
64
+
65
+ ```bash
66
+ pip install "dulus[memory]" # + MemPalace semantic memory
67
+ pip install "dulus[voice]" # + Voice I/O (Whisper STT + TTS)
68
+ pip install "dulus[webbridge]" # + Playwright browser automation
69
+ pip install "dulus[full]" # Everything
70
+ ```
71
+
72
+ > If pip says `No matching distribution found for dulus`, your Python is &lt; 3.11. Use Option A — the installer upgrades Python for you.
73
+
68
74
  ### Option C: Docker (Zero Local Python)
69
75
 
70
76
  ```bash
@@ -330,6 +336,16 @@ These are encrypted with XOR + base64 before saving to disk.
330
336
 
331
337
  ## Troubleshooting
332
338
 
339
+ ### "No matching distribution found for dulus"
340
+
341
+ Your Python is older than 3.11 (common on stock Ubuntu 20.04/22.04). pip hides packages that require a newer interpreter and prints that useless error instead of telling you the truth.
342
+
343
+ **Fix (zero friction):** use the one-liner — it bootstraps Python 3.11+ for you:
344
+
345
+ ```bash
346
+ curl -fsSL https://raw.githubusercontent.com/KevRojo/Dulus/main/install.sh | bash
347
+ ```
348
+
333
349
  ### "No module named 'tkinter'"
334
350
 
335
351
  ```bash
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dulus
3
- Version: 3.6.2
3
+ Version: 3.7.0
4
4
  Summary: Use IA as an agent without an API key. $0. Harvest your browser session for Gemini (guest, no login), Claude.ai, Claude Code, Kimi.com, Qwen, DeepSeek — drive them like an API, no per-token billing. Plus LiteLLM (100+ paid providers), local models via Ollama, /lang in 34 languages, Mesa Redonda, voice, OCR, MemPalace, embedded sandbox OS.
5
5
  Author: KevRojo
6
6
  License: GPL-3.0
@@ -37,6 +37,7 @@ Requires-Dist: typing-extensions>=4.10.0
37
37
  Requires-Dist: composio>=1.0.0rc2
38
38
  Requires-Dist: beautifulsoup4>=4.12.0
39
39
  Requires-Dist: sentry-sdk>=2.0.0
40
+ Requires-Dist: truststore>=0.9
40
41
  Requires-Dist: pytesseract>=0.3.10
41
42
  Provides-Extra: memory
42
43
  Requires-Dist: mempalace>=3.3.4; extra == "memory"
@@ -65,7 +66,7 @@ Dynamic: license-file
65
66
 
66
67
  # ▲ DULUS
67
68
  >
68
- > `pip install dulus` → press Enter → working IA in 30 seconds. Try it.
69
+ > `curl -fsSL …/install.sh | bash` → press Enter → working IA in 30 seconds. Try it.
69
70
 
70
71
  SET /sticky_input ON since the first run for the best experience!
71
72
 
@@ -176,13 +177,27 @@ Dulus adapt any python repository <3
176
177
 
177
178
  Download [`Dulus-Free-3.3.3-x64.msi`](https://github.com/KevRojo/Dulus/releases/download/v3.3.3/Dulus-Free-3.3.3-x64.msi) → double-click and fly. Embedded Python, every library, and the desktop GUI bundled. No pip, no terminal, no admin. ~85 MB.
178
179
 
179
- **Everyone else — one command:**
180
+ **Linux / macOS / WSL — one command (handles Python for you):**
181
+
182
+ ```bash
183
+ curl -fsSL https://raw.githubusercontent.com/KevRojo/Dulus/main/install.sh | bash
184
+ ```
185
+
186
+ The installer finds or **bootstraps Python 3.11+** (apt / deadsnakes / brew / uv), installs Dulus, and puts `dulus` on your PATH. Works on stock Ubuntu 20.04/22.04 where plain `pip install dulus` dies with `No matching distribution found` (pip hides packages that need a newer Python — Dulus needs ≥3.11).
187
+
188
+ **Already on Python 3.11+?** Then this is enough:
180
189
 
181
190
  ```bash
182
191
  pip install dulus
183
192
  dulus
184
193
  ```
185
194
 
195
+ **Windows (PowerShell, if you prefer the terminal over the MSI):**
196
+
197
+ ```powershell
198
+ iwr -useb https://raw.githubusercontent.com/KevRojo/Dulus/main/install.ps1 | iex
199
+ ```
200
+
186
201
  First run opens a welcome wizard that can get you **working IA without an API key** — it captures a Gemini guest session from your browser (no login, no card). Or set any key you already have. Zero to flight in 30 seconds.
187
202
 
188
203
  > 💡 Set `/sticky_input ON` on first run for the best experience.
@@ -270,3 +285,27 @@ audit it yourself.
270
285
  /config telemetry=off # inside Dulus
271
286
  DULUS_TELEMETRY=0 # environment variable
272
287
  ```
288
+
289
+ <p align="center"><img src="https://raw.githubusercontent.com/KevRojo/Dulus/main/docs/divider.svg" alt="" width="100%"></p>
290
+
291
+ ## 💛 Sponsors & Startup Programs
292
+
293
+ Dulus is proudly supported by these startup programs — powering our infrastructure, observability, and analytics:
294
+
295
+ <p align="center">
296
+ <a href="https://www.datadoghq.com/partner/datadog-for-startups/"><img src="https://cdn.simpleicons.org/datadog" height="42" alt="Datadog" title="Datadog for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
297
+ <a href="https://www.cloudflare.com/forstartups/"><img src="https://cdn.simpleicons.org/cloudflare" height="42" alt="Cloudflare" title="Cloudflare for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
298
+ <a href="https://sentry.io/for/startups/"><img src="https://cdn.simpleicons.org/sentry" height="42" alt="Sentry" title="Sentry for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
299
+ <a href="https://www.anthropic.com/startups"><img src="https://cdn.simpleicons.org/anthropic" height="42" alt="Anthropic" title="Claude for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
300
+ <a href="https://aws.amazon.com/activate/"><img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/amazonwebservices/amazonwebservices-plain-wordmark.svg" height="42" alt="AWS" title="AWS Activate"></a>
301
+ </p>
302
+ <p align="center">
303
+ <a href="https://www.mongodb.com/startups"><img src="https://cdn.simpleicons.org/mongodb" height="38" alt="MongoDB" title="MongoDB for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
304
+ <a href="https://mixpanel.com/startups/"><img src="https://cdn.simpleicons.org/mixpanel" height="38" alt="Mixpanel" title="Mixpanel for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
305
+ <a href="https://amplitude.com/startups"><img src="https://www.google.com/s2/favicons?domain=amplitude.com&sz=128" height="38" alt="Amplitude" title="Amplitude Startup Scholarship"></a>&nbsp;&nbsp;&nbsp;&nbsp;
306
+ <a href="https://www.digitalocean.com/hatch"><img src="https://cdn.simpleicons.org/digitalocean" height="38" alt="DigitalOcean" title="DigitalOcean Hatch"></a>&nbsp;&nbsp;&nbsp;&nbsp;
307
+ <a href="https://www.notion.com/startups"><img src="https://cdn.simpleicons.org/notion" height="38" alt="Notion" title="Notion for Startups"></a>&nbsp;&nbsp;&nbsp;&nbsp;
308
+ <a href="https://www.zendesk.com/campaign/startups/"><img src="https://cdn.simpleicons.org/zendesk" height="38" alt="Zendesk" title="Zendesk for Startups"></a>
309
+ </p>
310
+
311
+ <p align="center"><i>Want to support Dulus? → <a href="https://github.com/sponsors/KevRojo">GitHub Sponsors</a> 🦅</i></p>
@@ -130,6 +130,7 @@ dulus_tools/background_tasks.py
130
130
  dulus_tools/clipboard_utils.py
131
131
  dulus_tools/diff_visualizer.py
132
132
  dulus_tools/export_import.py
133
+ dulus_tools/fs_compass.py
133
134
  dulus_tools/hook_engine.py
134
135
  dulus_tools/notification_manager.py
135
136
  dulus_tools/session_fork.py
@@ -293,6 +294,7 @@ tests/test_diff_view.py
293
294
  tests/test_diff_visualization.py
294
295
  tests/test_display_blocks.py
295
296
  tests/test_export_import.py
297
+ tests/test_fs_compass.py
296
298
  tests/test_hook_engine.py
297
299
  tests/test_injection_fix.py
298
300
  tests/test_license.py
@@ -12,6 +12,7 @@ typing-extensions>=4.10.0
12
12
  composio>=1.0.0rc2
13
13
  beautifulsoup4>=4.12.0
14
14
  sentry-sdk>=2.0.0
15
+ truststore>=0.9
15
16
  pytesseract>=0.3.10
16
17
 
17
18
  [full]
@@ -273,6 +273,20 @@ except ImportError:
273
273
  _RICH = False
274
274
  console = None
275
275
 
276
+ # ── Corporate TLS interception fix (Cloudflare Zero Trust/WARP, Zscaler, …) ──
277
+ # Behind a TLS-inspecting proxy every HTTPS connection is re-signed by the
278
+ # company's CA. The OS trusts it, but Python's certifi bundle does NOT →
279
+ # requests/urllib3/sentry-sdk all die with CERTIFICATE_VERIFY_FAILED while the
280
+ # browser works fine. truststore makes Python use the OS trust store instead.
281
+ # Zero effect on machines without an interceptor. Opt out: DULUS_NO_TRUSTSTORE=1.
282
+ try:
283
+ import os as _ts_os
284
+ if not _ts_os.getenv("DULUS_NO_TRUSTSTORE"):
285
+ import truststore as _truststore
286
+ _truststore.inject_into_ssl()
287
+ except Exception:
288
+ pass # truststore not installed or injection failed — proceed with certifi
289
+
276
290
  # ── Sentry error tracking (optional — graceful degradation if not installed) ─
277
291
  # Off-switch for demos/privacy: set DULUS_NO_SENTRY=1 (or SENTRY_DSN="") to skip.
278
292
  try:
@@ -10234,14 +10248,17 @@ def repl(config: dict, initial_prompt: str = None):
10234
10248
  _DULUS_LOGO.append(" " + clr("New: /lang — speak any language or role. Type /news", "cyan", "dim"))
10235
10249
  _DULUS_LOGO.append(" ")
10236
10250
 
10237
- # Spinning galaxy animation
10251
+ # Spinning galaxy animation — trimmed from 8 frames (0.96s of pure
10252
+ # sleep) to 3 (0.24s). Startup-latency fix 2026-07-06: the boot
10253
+ # animation was the single largest self-inflicted stall on the
10254
+ # cold-start path. Keep the flair, cut the wait.
10238
10255
  _GALAXY_FRAMES = ["◜", "◝", "◞", "◟"]
10239
10256
  try:
10240
- for i in range(8):
10257
+ for i in range(3):
10241
10258
  frame = _GALAXY_FRAMES[i % 4]
10242
10259
  sys.stdout.write(f"\r {clr(frame, 'cyan', 'bold')} Initializing Dulus...")
10243
10260
  sys.stdout.flush()
10244
- time.sleep(0.12)
10261
+ time.sleep(0.08)
10245
10262
  sys.stdout.write(f"\r{' ' * 40}\r")
10246
10263
  sys.stdout.flush()
10247
10264
  except Exception:
@@ -10404,7 +10421,27 @@ def repl(config: dict, initial_prompt: str = None):
10404
10421
  )
10405
10422
  config["_ipc_thread"] = ti
10406
10423
  ti.start()
10407
-
10424
+
10425
+ # ── Pre-warm MemPalace while the user is still typing ─────────────────
10426
+ # (startup-latency fix, 2026-07-06) The per-turn memory injection in
10427
+ # run_query() imports mempalace.searcher (~1.1s — chromadb + embedding
10428
+ # stack) and pays a cold first search (~0.7s) INSIDE the first turn,
10429
+ # adding ~1.7s between submit and request dispatch. Warm both in a
10430
+ # daemon thread at boot: by the time the user finishes typing their
10431
+ # first real prompt, sys.modules and the search index are hot and the
10432
+ # same code path costs ~60ms.
10433
+ if config.get("mem_palace", True):
10434
+ def _prewarm_mempalace():
10435
+ try:
10436
+ from mempalace.searcher import search_memories as _pw_search
10437
+ from mempalace.config import MempalaceConfig as _PWCfg
10438
+ _pw_search("warmup", _PWCfg().palace_path, n_results=1)
10439
+ except Exception:
10440
+ pass # best-effort; run_query has its own fallback
10441
+ threading.Thread(
10442
+ target=_prewarm_mempalace, daemon=True, name="dulus-prewarm-mempalace"
10443
+ ).start()
10444
+
10408
10445
  def run_query(user_input: str, is_background: bool = False):
10409
10446
  nonlocal verbose
10410
10447