dulus 3.14.1__tar.gz → 3.14.2__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 (388) hide show
  1. {dulus-3.14.1/dulus.egg-info → dulus-3.14.2}/PKG-INFO +7 -1
  2. {dulus-3.14.1 → dulus-3.14.2}/docs/news.md +1 -1
  3. {dulus-3.14.1 → dulus-3.14.2/dulus.egg-info}/PKG-INFO +7 -1
  4. {dulus-3.14.1 → dulus-3.14.2}/dulus.egg-info/requires.txt +6 -0
  5. {dulus-3.14.1 → dulus-3.14.2}/dulus.py +1 -1
  6. {dulus-3.14.1 → dulus-3.14.2}/providers.py +249 -0
  7. {dulus-3.14.1 → dulus-3.14.2}/pyproject.toml +21 -1
  8. {dulus-3.14.1 → dulus-3.14.2}/LICENSE +0 -0
  9. {dulus-3.14.1 → dulus-3.14.2}/MANIFEST.in +0 -0
  10. {dulus-3.14.1 → dulus-3.14.2}/README.md +0 -0
  11. {dulus-3.14.1 → dulus-3.14.2}/agent.py +0 -0
  12. {dulus-3.14.1 → dulus-3.14.2}/algolia_search.py +0 -0
  13. {dulus-3.14.1 → dulus-3.14.2}/analytics.py +0 -0
  14. {dulus-3.14.1 → dulus-3.14.2}/backend/__init__.py +0 -0
  15. {dulus-3.14.1 → dulus-3.14.2}/backend/agents_bridge.py +0 -0
  16. {dulus-3.14.1 → dulus-3.14.2}/backend/compressor.py +0 -0
  17. {dulus-3.14.1 → dulus-3.14.2}/backend/context.py +0 -0
  18. {dulus-3.14.1 → dulus-3.14.2}/backend/githook.py +0 -0
  19. {dulus-3.14.1 → dulus-3.14.2}/backend/marketplace.py +0 -0
  20. {dulus-3.14.1 → dulus-3.14.2}/backend/mempalace_bridge.py +0 -0
  21. {dulus-3.14.1 → dulus-3.14.2}/backend/paths.py +0 -0
  22. {dulus-3.14.1 → dulus-3.14.2}/backend/personas.py +0 -0
  23. {dulus-3.14.1 → dulus-3.14.2}/backend/plugins.py +0 -0
  24. {dulus-3.14.1 → dulus-3.14.2}/backend/server.py +0 -0
  25. {dulus-3.14.1 → dulus-3.14.2}/backend/tasks.py +0 -0
  26. {dulus-3.14.1 → dulus-3.14.2}/banners/__init__.py +0 -0
  27. {dulus-3.14.1 → dulus-3.14.2}/banners/banner_rotator.py +0 -0
  28. {dulus-3.14.1 → dulus-3.14.2}/banners/banners_dulus_ai.txt +0 -0
  29. {dulus-3.14.1 → dulus-3.14.2}/batch_api.py +0 -0
  30. {dulus-3.14.1 → dulus-3.14.2}/checkpoint/__init__.py +0 -0
  31. {dulus-3.14.1 → dulus-3.14.2}/checkpoint/hooks.py +0 -0
  32. {dulus-3.14.1 → dulus-3.14.2}/checkpoint/store.py +0 -0
  33. {dulus-3.14.1 → dulus-3.14.2}/checkpoint/types.py +0 -0
  34. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/__init__.py +0 -0
  35. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/__main__.py +0 -0
  36. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/ansi.py +0 -0
  37. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/assets/ascii/dulus_logo.txt +0 -0
  38. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/assets/ascii/eagle.txt +0 -0
  39. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/assets/ascii/terminal_art.txt +0 -0
  40. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/banners.py +0 -0
  41. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/demo.py +0 -0
  42. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/effects.py +0 -0
  43. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/effort_slider.py +0 -0
  44. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/progress.py +0 -0
  45. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/py.typed +0 -0
  46. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/spinners.py +0 -0
  47. {dulus-3.14.1 → dulus-3.14.2}/cli_animations/status.py +0 -0
  48. {dulus-3.14.1 → dulus-3.14.2}/clipboard_utils.py +0 -0
  49. {dulus-3.14.1 → dulus-3.14.2}/cloudsave.py +0 -0
  50. {dulus-3.14.1 → dulus-3.14.2}/common.py +0 -0
  51. {dulus-3.14.1 → dulus-3.14.2}/compaction.py +0 -0
  52. {dulus-3.14.1 → dulus-3.14.2}/config.py +0 -0
  53. {dulus-3.14.1 → dulus-3.14.2}/context.py +0 -0
  54. {dulus-3.14.1 → dulus-3.14.2}/data/__init__.py +0 -0
  55. {dulus-3.14.1 → dulus-3.14.2}/data/active_persona.json +0 -0
  56. {dulus-3.14.1 → dulus-3.14.2}/data/marketplace.json +0 -0
  57. {dulus-3.14.1 → dulus-3.14.2}/data/personas.json +0 -0
  58. {dulus-3.14.1 → dulus-3.14.2}/data/plugins/__init__.py +0 -0
  59. {dulus-3.14.1 → dulus-3.14.2}/data/plugins/composio/__init__.py +0 -0
  60. {dulus-3.14.1 → dulus-3.14.2}/data/plugins/composio/composio_plugin/__init__.py +0 -0
  61. {dulus-3.14.1 → dulus-3.14.2}/data/plugins/composio/composio_plugin/session_manager.py +0 -0
  62. {dulus-3.14.1 → dulus-3.14.2}/data/plugins/composio/composio_plugin/tool_generator.py +0 -0
  63. {dulus-3.14.1 → dulus-3.14.2}/data/plugins/composio/plugin.json +0 -0
  64. {dulus-3.14.1 → dulus-3.14.2}/data/plugins/composio/plugin_tool.py +0 -0
  65. {dulus-3.14.1 → dulus-3.14.2}/data/tasks.json +0 -0
  66. {dulus-3.14.1 → dulus-3.14.2}/display_blocks.py +0 -0
  67. {dulus-3.14.1 → dulus-3.14.2}/docs/API.md +0 -0
  68. {dulus-3.14.1 → dulus-3.14.2}/docs/BRAND_GUIDE.md +0 -0
  69. {dulus-3.14.1 → dulus-3.14.2}/docs/CHANGELOG.md +0 -0
  70. {dulus-3.14.1 → dulus-3.14.2}/docs/CONTRIBUTING.md +0 -0
  71. {dulus-3.14.1 → dulus-3.14.2}/docs/DEPLOYMENT.md +0 -0
  72. {dulus-3.14.1 → dulus-3.14.2}/docs/FAQ.md +0 -0
  73. {dulus-3.14.1 → dulus-3.14.2}/docs/GETTING_STARTED.md +0 -0
  74. {dulus-3.14.1 → dulus-3.14.2}/docs/README.md +0 -0
  75. {dulus-3.14.1 → dulus-3.14.2}/docs/README_AR.md +0 -0
  76. {dulus-3.14.1 → dulus-3.14.2}/docs/README_EN.md +0 -0
  77. {dulus-3.14.1 → dulus-3.14.2}/docs/README_ES.md +0 -0
  78. {dulus-3.14.1 → dulus-3.14.2}/docs/README_FR.md +0 -0
  79. {dulus-3.14.1 → dulus-3.14.2}/docs/README_JA.md +0 -0
  80. {dulus-3.14.1 → dulus-3.14.2}/docs/README_KO.md +0 -0
  81. {dulus-3.14.1 → dulus-3.14.2}/docs/README_PT.md +0 -0
  82. {dulus-3.14.1 → dulus-3.14.2}/docs/README_RU.md +0 -0
  83. {dulus-3.14.1 → dulus-3.14.2}/docs/README_ZH.md +0 -0
  84. {dulus-3.14.1 → dulus-3.14.2}/docs/SECURITY.md +0 -0
  85. {dulus-3.14.1 → dulus-3.14.2}/docs/__init__.py +0 -0
  86. {dulus-3.14.1 → dulus-3.14.2}/docs/api.html +0 -0
  87. {dulus-3.14.1 → dulus-3.14.2}/docs/architecture.md +0 -0
  88. {dulus-3.14.1 → dulus-3.14.2}/docs/azure-speech-template.json +0 -0
  89. {dulus-3.14.1 → dulus-3.14.2}/docs/dashboard/index.html +0 -0
  90. {dulus-3.14.1 → dulus-3.14.2}/docs/divider.svg +0 -0
  91. {dulus-3.14.1 → dulus-3.14.2}/docs/dulus-bird.png +0 -0
  92. {dulus-3.14.1 → dulus-3.14.2}/docs/generate.py +0 -0
  93. {dulus-3.14.1 → dulus-3.14.2}/docs/index.html +0 -0
  94. {dulus-3.14.1 → dulus-3.14.2}/docs/nvidia-models.svg +0 -0
  95. {dulus-3.14.1 → dulus-3.14.2}/docs/particle-playground.html +0 -0
  96. {dulus-3.14.1 → dulus-3.14.2}/docs/personas/index.html +0 -0
  97. {dulus-3.14.1 → dulus-3.14.2}/docs/poetry-banner.png +0 -0
  98. {dulus-3.14.1 → dulus-3.14.2}/docs/preview.html +0 -0
  99. {dulus-3.14.1 → dulus-3.14.2}/docs/python-console.md +0 -0
  100. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/auto-adapter.png +0 -0
  101. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/dulus-os.png +0 -0
  102. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/hero.png +0 -0
  103. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/lookback_two_windows.png +0 -0
  104. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/pyc_heap.svg +0 -0
  105. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/pyc_receipts.svg +0 -0
  106. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/pyc_trap.svg +0 -0
  107. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/roundtable.png +0 -0
  108. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/task-board.png +0 -0
  109. {dulus-3.14.1 → dulus-3.14.2}/docs/readme/webchat.png +0 -0
  110. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-agents.svg +0 -0
  111. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-brainstorm.svg +0 -0
  112. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-bridges.svg +0 -0
  113. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-features.svg +0 -0
  114. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-freetier.svg +0 -0
  115. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-memory.svg +0 -0
  116. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-models.svg +0 -0
  117. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-perms.svg +0 -0
  118. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-plugins.svg +0 -0
  119. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-quickstart.svg +0 -0
  120. {dulus-3.14.1 → dulus-3.14.2}/docs/sec-ssj.svg +0 -0
  121. {dulus-3.14.1 → dulus-3.14.2}/docs/spinners.svg +0 -0
  122. {dulus-3.14.1 → dulus-3.14.2}/docs/split-pane.svg +0 -0
  123. {dulus-3.14.1 → dulus-3.14.2}/docs/terminal-boot.svg +0 -0
  124. {dulus-3.14.1 → dulus-3.14.2}/docs/termux-edge.md +0 -0
  125. {dulus-3.14.1 → dulus-3.14.2}/dulus.egg-info/SOURCES.txt +0 -0
  126. {dulus-3.14.1 → dulus-3.14.2}/dulus.egg-info/dependency_links.txt +0 -0
  127. {dulus-3.14.1 → dulus-3.14.2}/dulus.egg-info/entry_points.txt +0 -0
  128. {dulus-3.14.1 → dulus-3.14.2}/dulus.egg-info/top_level.txt +0 -0
  129. {dulus-3.14.1 → dulus-3.14.2}/dulus_account.py +0 -0
  130. {dulus-3.14.1 → dulus-3.14.2}/dulus_bar_client.py +0 -0
  131. {dulus-3.14.1 → dulus-3.14.2}/dulus_gui.py +0 -0
  132. {dulus-3.14.1 → dulus-3.14.2}/dulus_mcp/__init__.py +0 -0
  133. {dulus-3.14.1 → dulus-3.14.2}/dulus_mcp/client.py +0 -0
  134. {dulus-3.14.1 → dulus-3.14.2}/dulus_mcp/commands.py +0 -0
  135. {dulus-3.14.1 → dulus-3.14.2}/dulus_mcp/config.py +0 -0
  136. {dulus-3.14.1 → dulus-3.14.2}/dulus_mcp/hub.py +0 -0
  137. {dulus-3.14.1 → dulus-3.14.2}/dulus_mcp/tools.py +0 -0
  138. {dulus-3.14.1 → dulus-3.14.2}/dulus_mcp/types.py +0 -0
  139. {dulus-3.14.1 → dulus-3.14.2}/dulus_quick_menu.py +0 -0
  140. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/__init__.py +0 -0
  141. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/add_dir_manager.py +0 -0
  142. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/afk_mode.py +0 -0
  143. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/approval_runtime.py +0 -0
  144. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/background_tasks.py +0 -0
  145. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/clipboard_utils.py +0 -0
  146. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/diff_visualizer.py +0 -0
  147. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/export_import.py +0 -0
  148. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/hook_engine.py +0 -0
  149. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/isolate.py +0 -0
  150. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/notification_manager.py +0 -0
  151. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/session_fork.py +0 -0
  152. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/shell_mode.py +0 -0
  153. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/todo_visualizer.py +0 -0
  154. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/tree_ls.py +0 -0
  155. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/wire_events.py +0 -0
  156. {dulus-3.14.1 → dulus-3.14.2}/dulus_tools/yolo_mode.py +0 -0
  157. {dulus-3.14.1 → dulus-3.14.2}/file_filter.py +0 -0
  158. {dulus-3.14.1 → dulus-3.14.2}/fs_compass.py +0 -0
  159. {dulus-3.14.1 → dulus-3.14.2}/governance.py +0 -0
  160. {dulus-3.14.1 → dulus-3.14.2}/gui/__init__.py +0 -0
  161. {dulus-3.14.1 → dulus-3.14.2}/gui/agent_bridge.py +0 -0
  162. {dulus-3.14.1 → dulus-3.14.2}/gui/chat_widget.py +0 -0
  163. {dulus-3.14.1 → dulus-3.14.2}/gui/main_window.py +0 -0
  164. {dulus-3.14.1 → dulus-3.14.2}/gui/personas.py +0 -0
  165. {dulus-3.14.1 → dulus-3.14.2}/gui/sandbox_server.py +0 -0
  166. {dulus-3.14.1 → dulus-3.14.2}/gui/session_utils.py +0 -0
  167. {dulus-3.14.1 → dulus-3.14.2}/gui/settings_dialog.py +0 -0
  168. {dulus-3.14.1 → dulus-3.14.2}/gui/sidebar.py +0 -0
  169. {dulus-3.14.1 → dulus-3.14.2}/gui/tasks_view.py +0 -0
  170. {dulus-3.14.1 → dulus-3.14.2}/gui/themes.py +0 -0
  171. {dulus-3.14.1 → dulus-3.14.2}/gui/tool_panel.py +0 -0
  172. {dulus-3.14.1 → dulus-3.14.2}/input.py +0 -0
  173. {dulus-3.14.1 → dulus-3.14.2}/license_manager.py +0 -0
  174. {dulus-3.14.1 → dulus-3.14.2}/lookback.py +0 -0
  175. {dulus-3.14.1 → dulus-3.14.2}/memory/__init__.py +0 -0
  176. {dulus-3.14.1 → dulus-3.14.2}/memory/audit.py +0 -0
  177. {dulus-3.14.1 → dulus-3.14.2}/memory/consolidator.py +0 -0
  178. {dulus-3.14.1 → dulus-3.14.2}/memory/context.py +0 -0
  179. {dulus-3.14.1 → dulus-3.14.2}/memory/mempalace_bridge.py +0 -0
  180. {dulus-3.14.1 → dulus-3.14.2}/memory/offload.py +0 -0
  181. {dulus-3.14.1 → dulus-3.14.2}/memory/palace.py +0 -0
  182. {dulus-3.14.1 → dulus-3.14.2}/memory/scan.py +0 -0
  183. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/adaptation_guides.md +0 -0
  184. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/askuserquestion_after_numbered_list.md +0 -0
  185. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/background_jobs_no_extra_timers.md +0 -0
  186. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/cleverness_over_resources.md +0 -0
  187. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/corporate_tls_breaks_curl_cffi.md +0 -0
  188. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/hardened_rules.md +0 -0
  189. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/investigator_workflow_heuristic.md +0 -0
  190. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/native_code_over_sketchy_plugins.md +0 -0
  191. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/no_personal_info_in_code.md +0 -0
  192. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/searches_include_modified_date.md +0 -0
  193. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/tmux_send_keys_power_patterns.md +0 -0
  194. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/token_optimization_technique.md +0 -0
  195. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/tool_chaining_capability.md +0 -0
  196. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/insights/webbridge_evaluate_first_pattern.md +0 -0
  197. {dulus-3.14.1 → dulus-3.14.2}/memory/seeds/short_memory.md +0 -0
  198. {dulus-3.14.1 → dulus-3.14.2}/memory/sessions.py +0 -0
  199. {dulus-3.14.1 → dulus-3.14.2}/memory/store.py +0 -0
  200. {dulus-3.14.1 → dulus-3.14.2}/memory/tools.py +0 -0
  201. {dulus-3.14.1 → dulus-3.14.2}/memory/types.py +0 -0
  202. {dulus-3.14.1 → dulus-3.14.2}/memory/vector_search.py +0 -0
  203. {dulus-3.14.1 → dulus-3.14.2}/model_params.py +0 -0
  204. {dulus-3.14.1 → dulus-3.14.2}/multi_agent/__init__.py +0 -0
  205. {dulus-3.14.1 → dulus-3.14.2}/multi_agent/subagent.py +0 -0
  206. {dulus-3.14.1 → dulus-3.14.2}/multi_agent/tools.py +0 -0
  207. {dulus-3.14.1 → dulus-3.14.2}/paste_placeholders.py +0 -0
  208. {dulus-3.14.1 → dulus-3.14.2}/personality_config.py +0 -0
  209. {dulus-3.14.1 → dulus-3.14.2}/plugin/__init__.py +0 -0
  210. {dulus-3.14.1 → dulus-3.14.2}/plugin/autoadapter.py +0 -0
  211. {dulus-3.14.1 → dulus-3.14.2}/plugin/loader.py +0 -0
  212. {dulus-3.14.1 → dulus-3.14.2}/plugin/recommend.py +0 -0
  213. {dulus-3.14.1 → dulus-3.14.2}/plugin/store.py +0 -0
  214. {dulus-3.14.1 → dulus-3.14.2}/plugin/types.py +0 -0
  215. {dulus-3.14.1 → dulus-3.14.2}/profiles.py +0 -0
  216. {dulus-3.14.1 → dulus-3.14.2}/pyconsole.py +0 -0
  217. {dulus-3.14.1 → dulus-3.14.2}/sandbox/README.md +0 -0
  218. {dulus-3.14.1 → dulus-3.14.2}/sandbox/__init__.py +0 -0
  219. {dulus-3.14.1 → dulus-3.14.2}/sandbox/dist/assets/index-DE51D6wI.css +0 -0
  220. {dulus-3.14.1 → dulus-3.14.2}/sandbox/dist/assets/index-DMCCNE9Y.js +0 -0
  221. {dulus-3.14.1 → dulus-3.14.2}/sandbox/dist/index.html +0 -0
  222. {dulus-3.14.1 → dulus-3.14.2}/sandbox/dist/wallpaper-default.jpg +0 -0
  223. {dulus-3.14.1 → dulus-3.14.2}/sandbox/dist/wallpapers/default.jpeg +0 -0
  224. {dulus-3.14.1 → dulus-3.14.2}/sandbox/dist/wallpapers/light.jpeg +0 -0
  225. {dulus-3.14.1 → dulus-3.14.2}/sandbox/dist/wallpapers/nature.jpeg +0 -0
  226. {dulus-3.14.1 → dulus-3.14.2}/sandbox/dist/wallpapers/tech.jpeg +0 -0
  227. {dulus-3.14.1 → dulus-3.14.2}/sandbox/info.md +0 -0
  228. {dulus-3.14.1 → dulus-3.14.2}/sandbox_bootstrap.py +0 -0
  229. {dulus-3.14.1 → dulus-3.14.2}/setup.cfg +0 -0
  230. {dulus-3.14.1 → dulus-3.14.2}/skill/__init__.py +0 -0
  231. {dulus-3.14.1 → dulus-3.14.2}/skill/builtin.py +0 -0
  232. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/LICENSE-obsidian-skills +0 -0
  233. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/README.md +0 -0
  234. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/defuddle/SKILL.md +0 -0
  235. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/json-canvas/SKILL.md +0 -0
  236. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/json-canvas/references/EXAMPLES.md +0 -0
  237. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/obsidian-bases/SKILL.md +0 -0
  238. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/obsidian-bases/references/FUNCTIONS_REFERENCE.md +0 -0
  239. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/obsidian-cli/SKILL.md +0 -0
  240. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/obsidian-markdown/SKILL.md +0 -0
  241. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/obsidian-markdown/references/CALLOUTS.md +0 -0
  242. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/obsidian-markdown/references/EMBEDS.md +0 -0
  243. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/obsidian-markdown/references/PROPERTIES.md +0 -0
  244. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/README.md +0 -0
  245. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/SKILL.md +0 -0
  246. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/addresses.json +0 -0
  247. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/advancedbackgroundchecks.json +0 -0
  248. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/beenverified.json +0 -0
  249. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/clustal.json +0 -0
  250. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/clustrmaps.json +0 -0
  251. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/cyberbackgroundchecks.json +0 -0
  252. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/familytreenow.json +0 -0
  253. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/fastpeoplesearch.json +0 -0
  254. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/intelius.json +0 -0
  255. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/mylife.json +0 -0
  256. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/nuwber.json +0 -0
  257. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/peekyou.json +0 -0
  258. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/peoplefinders.json +0 -0
  259. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/radaris.json +0 -0
  260. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/rehold.json +0 -0
  261. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/searchpeoplefree.json +0 -0
  262. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/socialcatfish.json +0 -0
  263. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/spokeo.json +0 -0
  264. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/thatsthem.json +0 -0
  265. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/truepeoplesearch.json +0 -0
  266. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/usphonebook.json +0 -0
  267. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/brokers/whitepages.json +0 -0
  268. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/legal/ccpa.md +0 -0
  269. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/legal/drop.md +0 -0
  270. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/legal/gdpr.md +0 -0
  271. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/methods.md +0 -0
  272. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/site-playbooks.md +0 -0
  273. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/references/state-machine.md +0 -0
  274. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/autopilot.py +0 -0
  275. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/badbool.py +0 -0
  276. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/brokers.py +0 -0
  277. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/cdp.py +0 -0
  278. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/config.py +0 -0
  279. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/crypto.py +0 -0
  280. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/dossier.py +0 -0
  281. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/email_modes.py +0 -0
  282. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/emailer.py +0 -0
  283. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/ledger.py +0 -0
  284. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/legal.py +0 -0
  285. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/paths.py +0 -0
  286. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/pdd.py +0 -0
  287. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/registry.py +0 -0
  288. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/report.py +0 -0
  289. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/scan.py +0 -0
  290. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/storage.py +0 -0
  291. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/tiers.py +0 -0
  292. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/scripts/vectors.py +0 -0
  293. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/templates/consent/authorization.md +0 -0
  294. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/templates/emails/ccpa-authorized-agent.txt +0 -0
  295. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/templates/emails/ccpa-deletion.txt +0 -0
  296. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/templates/emails/ccpa-indirect-deletion.txt +0 -0
  297. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/templates/emails/gdpr-erasure.txt +0 -0
  298. {dulus-3.14.1 → dulus-3.14.2}/skill/bundled/unbroker/templates/emails/generic-optout.txt +0 -0
  299. {dulus-3.14.1 → dulus-3.14.2}/skill/clawhub.py +0 -0
  300. {dulus-3.14.1 → dulus-3.14.2}/skill/executor.py +0 -0
  301. {dulus-3.14.1 → dulus-3.14.2}/skill/loader.py +0 -0
  302. {dulus-3.14.1 → dulus-3.14.2}/skill/tools.py +0 -0
  303. {dulus-3.14.1 → dulus-3.14.2}/skills.py +0 -0
  304. {dulus-3.14.1 → dulus-3.14.2}/soul.py +0 -0
  305. {dulus-3.14.1 → dulus-3.14.2}/spinner.py +0 -0
  306. {dulus-3.14.1 → dulus-3.14.2}/steer_input.py +0 -0
  307. {dulus-3.14.1 → dulus-3.14.2}/subagent.py +0 -0
  308. {dulus-3.14.1 → dulus-3.14.2}/task/__init__.py +0 -0
  309. {dulus-3.14.1 → dulus-3.14.2}/task/store.py +0 -0
  310. {dulus-3.14.1 → dulus-3.14.2}/task/tools.py +0 -0
  311. {dulus-3.14.1 → dulus-3.14.2}/task/types.py +0 -0
  312. {dulus-3.14.1 → dulus-3.14.2}/tests/test_afk_yolo.py +0 -0
  313. {dulus-3.14.1 → dulus-3.14.2}/tests/test_approval_runtime.py +0 -0
  314. {dulus-3.14.1 → dulus-3.14.2}/tests/test_background_task_tools.py +0 -0
  315. {dulus-3.14.1 → dulus-3.14.2}/tests/test_background_tasks.py +0 -0
  316. {dulus-3.14.1 → dulus-3.14.2}/tests/test_chatgpt_oauth.py +0 -0
  317. {dulus-3.14.1 → dulus-3.14.2}/tests/test_checkpoint.py +0 -0
  318. {dulus-3.14.1 → dulus-3.14.2}/tests/test_cli_animations_integration.py +0 -0
  319. {dulus-3.14.1 → dulus-3.14.2}/tests/test_clipboard_utils.py +0 -0
  320. {dulus-3.14.1 → dulus-3.14.2}/tests/test_compaction.py +0 -0
  321. {dulus-3.14.1 → dulus-3.14.2}/tests/test_composio_tool_generator.py +0 -0
  322. {dulus-3.14.1 → dulus-3.14.2}/tests/test_diff_view.py +0 -0
  323. {dulus-3.14.1 → dulus-3.14.2}/tests/test_diff_visualization.py +0 -0
  324. {dulus-3.14.1 → dulus-3.14.2}/tests/test_display_blocks.py +0 -0
  325. {dulus-3.14.1 → dulus-3.14.2}/tests/test_dulus_account.py +0 -0
  326. {dulus-3.14.1 → dulus-3.14.2}/tests/test_export_import.py +0 -0
  327. {dulus-3.14.1 → dulus-3.14.2}/tests/test_gold_memory_preload.py +0 -0
  328. {dulus-3.14.1 → dulus-3.14.2}/tests/test_grok_usage.py +0 -0
  329. {dulus-3.14.1 → dulus-3.14.2}/tests/test_hook_engine.py +0 -0
  330. {dulus-3.14.1 → dulus-3.14.2}/tests/test_injection_fix.py +0 -0
  331. {dulus-3.14.1 → dulus-3.14.2}/tests/test_json_protocol.py +0 -0
  332. {dulus-3.14.1 → dulus-3.14.2}/tests/test_license.py +0 -0
  333. {dulus-3.14.1 → dulus-3.14.2}/tests/test_lookback_cache.py +0 -0
  334. {dulus-3.14.1 → dulus-3.14.2}/tests/test_lookback_compact.py +0 -0
  335. {dulus-3.14.1 → dulus-3.14.2}/tests/test_mcp.py +0 -0
  336. {dulus-3.14.1 → dulus-3.14.2}/tests/test_mcp_algolia.py +0 -0
  337. {dulus-3.14.1 → dulus-3.14.2}/tests/test_memory.py +0 -0
  338. {dulus-3.14.1 → dulus-3.14.2}/tests/test_memory_home_resolution.py +0 -0
  339. {dulus-3.14.1 → dulus-3.14.2}/tests/test_notification_manager.py +0 -0
  340. {dulus-3.14.1 → dulus-3.14.2}/tests/test_plugin.py +0 -0
  341. {dulus-3.14.1 → dulus-3.14.2}/tests/test_profile_isolation.py +0 -0
  342. {dulus-3.14.1 → dulus-3.14.2}/tests/test_profile_plugin_scope.py +0 -0
  343. {dulus-3.14.1 → dulus-3.14.2}/tests/test_provider_errors.py +0 -0
  344. {dulus-3.14.1 → dulus-3.14.2}/tests/test_session_fork.py +0 -0
  345. {dulus-3.14.1 → dulus-3.14.2}/tests/test_shell_detection.py +0 -0
  346. {dulus-3.14.1 → dulus-3.14.2}/tests/test_shell_mode.py +0 -0
  347. {dulus-3.14.1 → dulus-3.14.2}/tests/test_skills.py +0 -0
  348. {dulus-3.14.1 → dulus-3.14.2}/tests/test_skillssh_algolia.py +0 -0
  349. {dulus-3.14.1 → dulus-3.14.2}/tests/test_steer_input.py +0 -0
  350. {dulus-3.14.1 → dulus-3.14.2}/tests/test_subagent.py +0 -0
  351. {dulus-3.14.1 → dulus-3.14.2}/tests/test_task.py +0 -0
  352. {dulus-3.14.1 → dulus-3.14.2}/tests/test_telegram_buffer.py +0 -0
  353. {dulus-3.14.1 → dulus-3.14.2}/tests/test_think_tool.py +0 -0
  354. {dulus-3.14.1 → dulus-3.14.2}/tests/test_todo_tool.py +0 -0
  355. {dulus-3.14.1 → dulus-3.14.2}/tests/test_todo_visualization.py +0 -0
  356. {dulus-3.14.1 → dulus-3.14.2}/tests/test_tool_registry.py +0 -0
  357. {dulus-3.14.1 → dulus-3.14.2}/tests/test_tree_ls.py +0 -0
  358. {dulus-3.14.1 → dulus-3.14.2}/tests/test_voice.py +0 -0
  359. {dulus-3.14.1 → dulus-3.14.2}/tests/test_webbridge_tabs.py +0 -0
  360. {dulus-3.14.1 → dulus-3.14.2}/tests/test_wire_events.py +0 -0
  361. {dulus-3.14.1 → dulus-3.14.2}/tmux_tools.py +0 -0
  362. {dulus-3.14.1 → dulus-3.14.2}/token_budget.py +0 -0
  363. {dulus-3.14.1 → dulus-3.14.2}/tool_registry.py +0 -0
  364. {dulus-3.14.1 → dulus-3.14.2}/tools.py +0 -0
  365. {dulus-3.14.1 → dulus-3.14.2}/tools_background.py +0 -0
  366. {dulus-3.14.1 → dulus-3.14.2}/tools_think.py +0 -0
  367. {dulus-3.14.1 → dulus-3.14.2}/tools_todo.py +0 -0
  368. {dulus-3.14.1 → dulus-3.14.2}/ui/__init__.py +0 -0
  369. {dulus-3.14.1 → dulus-3.14.2}/ui/input.py +0 -0
  370. {dulus-3.14.1 → dulus-3.14.2}/ui/render.py +0 -0
  371. {dulus-3.14.1 → dulus-3.14.2}/updater.py +0 -0
  372. {dulus-3.14.1 → dulus-3.14.2}/voice/__init__.py +0 -0
  373. {dulus-3.14.1 → dulus-3.14.2}/voice/audio_utils.py +0 -0
  374. {dulus-3.14.1 → dulus-3.14.2}/voice/keyterms.py +0 -0
  375. {dulus-3.14.1 → dulus-3.14.2}/voice/recorder.py +0 -0
  376. {dulus-3.14.1 → dulus-3.14.2}/voice/stt.py +0 -0
  377. {dulus-3.14.1 → dulus-3.14.2}/voice/tts.py +0 -0
  378. {dulus-3.14.1 → dulus-3.14.2}/voice/wake_word.py +0 -0
  379. {dulus-3.14.1 → dulus-3.14.2}/webbridge/__init__.py +0 -0
  380. {dulus-3.14.1 → dulus-3.14.2}/webbridge/core.py +0 -0
  381. {dulus-3.14.1 → dulus-3.14.2}/webbridge/tools.py +0 -0
  382. {dulus-3.14.1 → dulus-3.14.2}/webchat.py +0 -0
  383. {dulus-3.14.1 → dulus-3.14.2}/webchat_server.py +0 -0
  384. {dulus-3.14.1 → dulus-3.14.2}/webchat_ui/__init__.py +0 -0
  385. {dulus-3.14.1 → dulus-3.14.2}/webchat_ui/app.js +0 -0
  386. {dulus-3.14.1 → dulus-3.14.2}/webchat_ui/index.html +0 -0
  387. {dulus-3.14.1 → dulus-3.14.2}/webchat_ui/style.css +0 -0
  388. {dulus-3.14.1 → dulus-3.14.2}/welcome.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dulus
3
- Version: 3.14.1
3
+ Version: 3.14.2
4
4
  Summary: Provider-independent agent runtime for the terminal — cloud and local models, real tools, MCP, plugins, memory, sub-agents, and Dulus OS.
5
5
  Author-email: KevRojo <dev@dulus.ai>
6
6
  Maintainer-email: KevRojo <dev@dulus.ai>
@@ -65,6 +65,12 @@ Requires-Dist: mcp>=1.0.0
65
65
  Requires-Dist: uv>=0.4.0
66
66
  Requires-Dist: sse-starlette>=2.0.0
67
67
  Requires-Dist: starlette>=0.38.0
68
+ Requires-Dist: posthog>=3.0.0
69
+ Requires-Dist: mempalace>=3.3.4
70
+ Requires-Dist: sounddevice
71
+ Requires-Dist: elevenlabs>=1.0.0
72
+ Requires-Dist: playwright>=1.40.0
73
+ Requires-Dist: litellm>=1.50.0
68
74
  Provides-Extra: dev
69
75
  Requires-Dist: build>=1.2; extra == "dev"
70
76
  Requires-Dist: pyright>=1.1.400; extra == "dev"
@@ -4,7 +4,7 @@
4
4
 
5
5
  - September 2, 2026 (**v3.14.1**): **🌐 Web-harvest browser fix.** `/harvest-gemini` (and claude/kimi/qwen/deepseek) no longer launch without a browser after the first run. The installer used to key off the *pip package*, so once the wizard installed it, later harvests skipped the *browser* download entirely — leaving you with a package but no Chromium. Now a single idempotent guard ensures both the package and the browser are present every time. `pip install -U dulus`. 🦅
6
6
 
7
- - September 2, 2026 (**v6.0.5**): **🚀 Dulus 6.0.5 is live.** The newest build just landed — same free open runtime, sharper and faster. No API key, no credit card, your machine. Grab it: `pip install -U dulus`. 🦅🇩🇴
7
+ - September 3, 2026 (**v3.14.2**): **📦 One-shot install — everything's in the box now.** No more `dulus[full]` archaeology: `pip install dulus` now pulls the whole runtime by default — memory palace, voice, browser automation, LiteLLM routing and analytics all come along. Plus a new **Meta AI (Muse Spark)** provider (`meta/muse-spark-1.3`). Same free open runtime, your machine. `pip install -U dulus`. 🦅🇩🇴
8
8
 
9
9
  - September 1, 2026 (**v3.13.9**): **🔒 `/isolate` — workspace bubble, on demand.** Flip `/isolate on` and Write / Edit / NotebookEdit + Bash mutations stay locked to the frozen workspace root (plus anything you added with `/add-dir`). Read-only tools keep flying free. No `/temp` backdoor — pure bubble. Blocked? Dulus tells you straight: write `/isolate off` if you want help outside. `pip install -U dulus`. 🦅
10
10
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dulus
3
- Version: 3.14.1
3
+ Version: 3.14.2
4
4
  Summary: Provider-independent agent runtime for the terminal — cloud and local models, real tools, MCP, plugins, memory, sub-agents, and Dulus OS.
5
5
  Author-email: KevRojo <dev@dulus.ai>
6
6
  Maintainer-email: KevRojo <dev@dulus.ai>
@@ -65,6 +65,12 @@ Requires-Dist: mcp>=1.0.0
65
65
  Requires-Dist: uv>=0.4.0
66
66
  Requires-Dist: sse-starlette>=2.0.0
67
67
  Requires-Dist: starlette>=0.38.0
68
+ Requires-Dist: posthog>=3.0.0
69
+ Requires-Dist: mempalace>=3.3.4
70
+ Requires-Dist: sounddevice
71
+ Requires-Dist: elevenlabs>=1.0.0
72
+ Requires-Dist: playwright>=1.40.0
73
+ Requires-Dist: litellm>=1.50.0
68
74
  Provides-Extra: dev
69
75
  Requires-Dist: build>=1.2; extra == "dev"
70
76
  Requires-Dist: pyright>=1.1.400; extra == "dev"
@@ -21,6 +21,12 @@ mcp>=1.0.0
21
21
  uv>=0.4.0
22
22
  sse-starlette>=2.0.0
23
23
  starlette>=0.38.0
24
+ posthog>=3.0.0
25
+ mempalace>=3.3.4
26
+ sounddevice
27
+ elevenlabs>=1.0.0
28
+ playwright>=1.40.0
29
+ litellm>=1.50.0
24
30
 
25
31
  [:python_version < "3.11"]
26
32
  tomli>=2.0
@@ -396,7 +396,7 @@ try:
396
396
  from importlib.metadata import version as _pkg_version
397
397
  VERSION = _pkg_version("dulus")
398
398
  except Exception:
399
- VERSION = "3.14.1" # dev fallback — keep in sync with pyproject.toml
399
+ VERSION = "3.14.2" # dev fallback — keep in sync with pyproject.toml
400
400
 
401
401
  # ── Machine-readable protocol output (`--output json`) ─────────────────────
402
402
  # Dulus is increasingly run as a child process by another agent runtime (an
@@ -875,6 +875,19 @@ PROVIDERS: dict[str, dict] = {
875
875
  "fugu-mini", "fugu-ultra",
876
876
  ],
877
877
  },
878
+ # Meta AI (Muse Spark) — Responses-API-style SSE endpoint at api.meta.ai.
879
+ # Key via /config meta_api_key=... or export META_API_KEY.
880
+ # Pick models as 'meta/muse-spark-1.3' (or bare 'muse-spark-1.3').
881
+ "meta": {
882
+ "type": "meta",
883
+ "api_key_env": "META_API_KEY",
884
+ "base_url": "https://api.meta.ai/v1",
885
+ "context_limit": 128000,
886
+ "max_completion_tokens": 32000,
887
+ "models": [
888
+ "muse-spark-1.3", "muse-spark-1.3-contributor",
889
+ ],
890
+ },
878
891
  }
879
892
 
880
893
  # Cost per million tokens (approximate, fallback to 0 for unknown)
@@ -934,6 +947,9 @@ _PREFIXES = [
934
947
  ("gpt-5-codex", "chatgpt-oauth"),
935
948
  ("codex-mini", "chatgpt-oauth"),
936
949
  ("codex-auto", "chatgpt-oauth"),
950
+ # Meta AI (Muse Spark) — api.meta.ai Responses-style SSE, key via META_API_KEY.
951
+ ("meta/", "meta"),
952
+ ("muse-", "meta"),
937
953
  ("claude-", "anthropic"),
938
954
  ("gpt-", "openai"),
939
955
  ("o1", "openai"),
@@ -2842,6 +2858,236 @@ def stream_chatgpt_oauth(
2842
2858
  cache_read_tokens=cached_tok)
2843
2859
 
2844
2860
 
2861
+ # ── Meta AI (Muse Spark) — API key, Responses-API-style SSE ────────────────
2862
+ META_API_BASE_URL = "https://api.meta.ai/v1"
2863
+
2864
+
2865
+ def stream_meta(
2866
+ api_key: str,
2867
+ model: str,
2868
+ system: str,
2869
+ messages: list,
2870
+ tool_schemas: list,
2871
+ config: dict,
2872
+ ) -> Generator:
2873
+ """Meta AI Muse Spark via api.meta.ai/v1/responses (SSE, OpenAI Responses
2874
+ wire format). Key: /config meta_api_key=... or META_API_KEY.
2875
+ Yields TextChunk / ThinkingChunk / AssistantTurn."""
2876
+ import requests as _req
2877
+
2878
+ if not api_key:
2879
+ yield TextChunk(
2880
+ "[meta] No API key. Set one with `/config meta_api_key=...` "
2881
+ "or export META_API_KEY."
2882
+ )
2883
+ yield AssistantTurn(
2884
+ "[meta] No API key. Set META_API_KEY or /config meta_api_key=...",
2885
+ [], 0, 0, error=True,
2886
+ )
2887
+ return
2888
+
2889
+ instructions, input_items = _chatgpt_messages_to_responses_input(system, messages)
2890
+
2891
+ body: dict[str, Any] = {
2892
+ "model": model,
2893
+ "input": input_items,
2894
+ "stream": True,
2895
+ "temperature": 1,
2896
+ "max_output_tokens": 32000,
2897
+ "top_p": 1,
2898
+ }
2899
+ if instructions:
2900
+ body["instructions"] = instructions
2901
+
2902
+ tools = _chatgpt_tools_to_responses(tool_schemas)
2903
+ if tools:
2904
+ body["tools"] = tools
2905
+ if not (config or {}).get("disable_tool_choice"):
2906
+ body["tool_choice"] = "auto"
2907
+
2908
+ base = (PROVIDERS.get("meta", {}).get("base_url") or META_API_BASE_URL).rstrip("/")
2909
+ url = base + "/responses"
2910
+ headers = {
2911
+ "Authorization": f"Bearer {api_key}",
2912
+ "Content-Type": "application/json",
2913
+ "Accept": "text/event-stream",
2914
+ }
2915
+
2916
+ text = ""
2917
+ thinking = ""
2918
+ in_tok = 0
2919
+ out_tok = 0
2920
+ cached_tok = 0
2921
+ tool_buf: dict[str, dict] = {}
2922
+ tool_order: list[str] = []
2923
+ current_call_id: str | None = None
2924
+ stream_interrupted = False
2925
+ resp = None
2926
+
2927
+ def _ensure_tool(call_id: str | None, name: str | None = None) -> str:
2928
+ nonlocal current_call_id
2929
+ cid = call_id or current_call_id or f"call_{len(tool_order)}"
2930
+ if cid not in tool_buf:
2931
+ tool_buf[cid] = {"id": cid, "name": name or "", "args": ""}
2932
+ tool_order.append(cid)
2933
+ elif name and not tool_buf[cid].get("name"):
2934
+ tool_buf[cid]["name"] = name
2935
+ current_call_id = cid
2936
+ return cid
2937
+
2938
+ try:
2939
+ resp = _req.post(url, headers=headers, json=body, stream=True, timeout=300)
2940
+
2941
+ if resp.status_code in (401, 403):
2942
+ body_preview = (resp.text or "")[:300]
2943
+ yield TextChunk(
2944
+ f"[meta] Auth error {resp.status_code}. Check your key: "
2945
+ f"/config meta_api_key=... Detail: {body_preview}"
2946
+ )
2947
+ yield AssistantTurn(
2948
+ f"[meta] Auth error {resp.status_code}. Check meta_api_key.",
2949
+ [], 0, 0, error=True,
2950
+ )
2951
+ return
2952
+ if resp.status_code >= 400:
2953
+ body_preview = (resp.text or "")[:400]
2954
+ yield TextChunk(f"[meta] HTTP {resp.status_code}: {body_preview}")
2955
+ yield AssistantTurn(
2956
+ f"[meta] HTTP {resp.status_code}: {body_preview}",
2957
+ [], 0, 0, error=True,
2958
+ )
2959
+ return
2960
+
2961
+ event_type = ""
2962
+ # NOTE: iterate RAW BYTES (no decode_unicode). requests defaults to
2963
+ # ISO-8859-1 for text/event-stream when the server omits charset, which
2964
+ # mangled UTF-8 accents (á→á, ñ→ñ) in Spanish output. Decoding each
2965
+ # line explicitly as UTF-8 fixes the mojibake.
2966
+ for raw_line in resp.iter_lines():
2967
+ if raw_line is None:
2968
+ continue
2969
+ line = raw_line.decode("utf-8", "replace").strip() if isinstance(raw_line, (bytes, bytearray)) else raw_line.strip()
2970
+ if not line:
2971
+ continue
2972
+ if line.startswith(":"):
2973
+ continue
2974
+ if line.startswith("event:"):
2975
+ event_type = line[6:].strip()
2976
+ continue
2977
+ if not line.startswith("data:"):
2978
+ continue
2979
+ data = line[5:].strip()
2980
+ if data == "[DONE]":
2981
+ break
2982
+ try:
2983
+ event = json.loads(data)
2984
+ except Exception:
2985
+ continue
2986
+ if not isinstance(event, dict):
2987
+ continue
2988
+ et = event.get("type") or event_type or ""
2989
+
2990
+ if et in ("response.output_text.delta", "response.refusal.delta"):
2991
+ delta = event.get("delta") or ""
2992
+ if delta:
2993
+ text += delta
2994
+ yield TextChunk(delta)
2995
+ continue
2996
+
2997
+ if et in (
2998
+ "response.reasoning_summary_text.delta",
2999
+ "response.reasoning_text.delta",
3000
+ ):
3001
+ delta = event.get("delta") or ""
3002
+ if delta:
3003
+ thinking += delta
3004
+ yield ThinkingChunk(delta)
3005
+ continue
3006
+
3007
+ if et == "response.output_item.added":
3008
+ item = event.get("item") or {}
3009
+ if isinstance(item, dict) and item.get("type") == "function_call":
3010
+ _ensure_tool(item.get("call_id") or item.get("id"), item.get("name"))
3011
+ continue
3012
+
3013
+ if et == "response.function_call_arguments.delta":
3014
+ cid = event.get("call_id") or current_call_id
3015
+ key = _ensure_tool(cid)
3016
+ delta_args = event.get("delta") or ""
3017
+ if delta_args:
3018
+ tool_buf[key]["args"] += delta_args
3019
+ continue
3020
+
3021
+ if et == "response.function_call_arguments.done":
3022
+ cid = event.get("call_id") or current_call_id
3023
+ key = _ensure_tool(cid)
3024
+ final_args = event.get("arguments")
3025
+ if final_args is not None:
3026
+ tool_buf[key]["args"] = final_args
3027
+ continue
3028
+
3029
+ if et == "response.output_item.done":
3030
+ item = event.get("item") or {}
3031
+ if isinstance(item, dict) and item.get("type") == "function_call":
3032
+ key = _ensure_tool(item.get("call_id") or item.get("id"), item.get("name"))
3033
+ if item.get("name"):
3034
+ tool_buf[key]["name"] = item["name"]
3035
+ if item.get("arguments") is not None:
3036
+ tool_buf[key]["args"] = item["arguments"]
3037
+ if item.get("call_id"):
3038
+ tool_buf[key]["id"] = item["call_id"]
3039
+ continue
3040
+
3041
+ if et in ("response.completed", "response.incomplete"):
3042
+ resp_obj = event.get("response") or {}
3043
+ usage = resp_obj.get("usage") or event.get("usage") or {}
3044
+ if isinstance(usage, dict):
3045
+ in_tok = int(usage.get("input_tokens") or usage.get("prompt_tokens") or in_tok or 0)
3046
+ out_tok = int(usage.get("output_tokens") or usage.get("completion_tokens") or out_tok or 0)
3047
+ _det = usage.get("input_tokens_details") or usage.get("prompt_tokens_details") or {}
3048
+ if isinstance(_det, dict):
3049
+ cached_tok = int(_det.get("cached_tokens") or cached_tok or 0)
3050
+ continue
3051
+
3052
+ if et in ("response.failed", "error"):
3053
+ err = event.get("error") or event.get("response", {}).get("error") or event
3054
+ if isinstance(err, dict):
3055
+ msg = err.get("message") or err.get("code") or json.dumps(err)[:300]
3056
+ else:
3057
+ msg = str(err)[:300]
3058
+ note = f"\n\n_[meta error: {msg}]_"
3059
+ text += note
3060
+ yield TextChunk(note)
3061
+ continue
3062
+
3063
+ except _req.exceptions.ChunkedEncodingError:
3064
+ stream_interrupted = True
3065
+ except _req.exceptions.ConnectionError:
3066
+ stream_interrupted = True
3067
+ except Exception as e:
3068
+ msg = f"[meta] Error: {e}"
3069
+ yield TextChunk(msg)
3070
+ yield AssistantTurn(msg, [], 0, 0, error=True)
3071
+ return
3072
+ finally:
3073
+ if resp is not None:
3074
+ try:
3075
+ resp.close()
3076
+ except Exception:
3077
+ pass
3078
+
3079
+ if stream_interrupted and not tool_buf:
3080
+ note = "\n\n_[meta: el streaming se cortó a media respuesta — esto es parcial, reintenta]_"
3081
+ text += note
3082
+ yield TextChunk(note)
3083
+
3084
+ ordered_buf = {i: tool_buf[k] for i, k in enumerate(tool_order)} if tool_order else tool_buf
3085
+ final_tool_calls = _finalize_tool_calls(ordered_buf)
3086
+
3087
+ yield AssistantTurn(text, final_tool_calls, in_tok, out_tok, thinking=thinking,
3088
+ cache_read_tokens=cached_tok)
3089
+
3090
+
2845
3091
  def stream_xai_oauth(
2846
3092
  model: str,
2847
3093
  system: str,
@@ -7512,6 +7758,9 @@ def stream(
7512
7758
  # ChatGPT/Codex subscription OAuth (`/login chatgpt` or ~/.codex/auth.json)
7513
7759
  # → chatgpt.com/backend-api/codex/responses (Responses API, not chat/completions)
7514
7760
  yield from stream_chatgpt_oauth(model_name, system, messages, tool_schemas, config)
7761
+ elif prov["type"] == "meta":
7762
+ # Meta AI (Muse Spark) via api.meta.ai/v1/responses — API key (META_API_KEY).
7763
+ yield from stream_meta(api_key, model_name, system, messages, tool_schemas, config)
7515
7764
  elif prov["type"] == "gcloud":
7516
7765
  yield from stream_gcloud(model_name, system, messages, tool_schemas, config)
7517
7766
  elif prov["type"] == "litellm":
@@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta"
10
10
 
11
11
  [project]
12
12
  name = "dulus"
13
- version = "3.14.1"
13
+ version = "3.14.2"
14
14
  description = "Provider-independent agent runtime for the terminal — cloud and local models, real tools, MCP, plugins, memory, sub-agents, and Dulus OS."
15
15
  readme = "README.md"
16
16
  requires-python = ">=3.10"
@@ -112,6 +112,26 @@ dependencies = [
112
112
  "uv>=0.4.0",
113
113
  "sse-starlette>=2.0.0",
114
114
  "starlette>=0.38.0",
115
+ # Product analytics — usage/telemetry (respects opt-out). Nobody runs
116
+ # `pip install dulus[full]`, so shipping it here is the only way metrics
117
+ # actually reach us from real installs.
118
+ "posthog>=3.0.0",
119
+ # Memory Palace — per-turn semantic memory injection. Pulls chromadb; on
120
+ # exotic targets (termux/aarch64) wheels may be missing, but the vast
121
+ # majority of installs want this ON by default rather than hunting the
122
+ # `[memory]` extra nobody types.
123
+ "mempalace>=3.3.4",
124
+ # Voice I/O — mic capture + cloud TTS. On by default so `/voice` works out
125
+ # of the box; silent no-op on headless boxes with no audio device.
126
+ "sounddevice",
127
+ "elevenlabs>=1.0.0",
128
+ # Browser automation — /harvest-*, WebBridge, JS-rendered scraping. The pip
129
+ # package ships here; the Chromium binary is fetched on first harvest.
130
+ "playwright>=1.40.0",
131
+ # LiteLLM unified gateway — one provider entry, 100+ backends. Bundled by
132
+ # default so the welcome wizard's litellm option works without a second
133
+ # install step.
134
+ "litellm>=1.50.0",
115
135
  ]
116
136
 
117
137
  # mempalace pulls chromadb (26 transitive deps incl. numpy + onnxruntime),
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes