dulus 3.9.4__tar.gz → 3.10.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.
- {dulus-3.9.4 → dulus-3.10.0}/MANIFEST.in +1 -0
- {dulus-3.9.4/dulus.egg-info → dulus-3.10.0}/PKG-INFO +1 -1
- {dulus-3.9.4 → dulus-3.10.0}/agent.py +4 -0
- {dulus-3.9.4 → dulus-3.10.0}/analytics.py +3 -71
- {dulus-3.9.4 → dulus-3.10.0}/docs/CHANGELOG.md +46 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/dashboard/index.html +0 -10
- {dulus-3.9.4 → dulus-3.10.0}/docs/index.html +0 -10
- {dulus-3.9.4 → dulus-3.10.0}/docs/news.md +6 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/personas/index.html +0 -10
- {dulus-3.9.4 → dulus-3.10.0/dulus.egg-info}/PKG-INFO +1 -1
- {dulus-3.9.4 → dulus-3.10.0}/dulus.egg-info/SOURCES.txt +5 -1
- {dulus-3.9.4 → dulus-3.10.0}/dulus.egg-info/top_level.txt +1 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_mcp/commands.py +182 -182
- {dulus-3.9.4 → dulus-3.10.0}/dulus_mcp/hub.py +845 -845
- {dulus-3.9.4 → dulus-3.10.0}/pyproject.toml +2 -1
- {dulus-3.9.4 → dulus-3.10.0}/updater.py +178 -178
- {dulus-3.9.4 → dulus-3.10.0}/voice/tts.py +30 -1
- {dulus-3.9.4 → dulus-3.10.0}/webchat_server.py +98 -68
- dulus-3.10.0/webchat_ui/__init__.py +1 -0
- dulus-3.10.0/webchat_ui/app.js +1585 -0
- dulus-3.10.0/webchat_ui/index.html +349 -0
- dulus-3.10.0/webchat_ui/style.css +1802 -0
- {dulus-3.9.4 → dulus-3.10.0}/LICENSE +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/README.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/agents_bridge.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/compressor.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/context.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/githook.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/marketplace.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/mempalace_bridge.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/personas.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/plugins.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/server.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/backend/tasks.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/batch_api.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/checkpoint/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/checkpoint/hooks.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/checkpoint/store.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/checkpoint/types.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/claude_code_watcher.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/clipboard_utils.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/cloudsave.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/common.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/compaction.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/config.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/context.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/active_persona.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/marketplace.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/personas.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/plugins/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/plugins/composio/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/plugins/composio/composio_plugin/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/plugins/composio/composio_plugin/session_manager.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/plugins/composio/composio_plugin/tool_generator.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/plugins/composio/plugin.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/plugins/composio/plugin_tool.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/data/tasks.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/API.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/BRAND_GUIDE.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/CONTRIBUTING.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/DEPLOYMENT.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/Dulus_AI_Whitepaper_(v2.0).pdf +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/FAQ.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/GETTING_STARTED.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/INVESTOR_BRIEF.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README_AR.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README_EN.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README_ES.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README_FR.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README_JA.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README_KO.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README_PT.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README_RU.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/README_ZH.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/SECURITY.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/api.html +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/architecture.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/azure-speech-template.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/divider.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/dulus-bird.png +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/generate.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/hero.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/nvidia-models.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/particle-playground.html +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/poetry-banner.png +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/preview.html +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-agents.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-brainstorm.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-bridges.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-features.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-freetier.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-memory.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-models.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-perms.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-plugins.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-quickstart.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/sec-ssj.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/spinners.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/split-pane.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/docs/terminal-boot.svg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus.egg-info/dependency_links.txt +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus.egg-info/entry_points.txt +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus.egg-info/requires.txt +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_gui.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_gui_web.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_mcp/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_mcp/client.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_mcp/config.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_mcp/tools.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_mcp/types.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/add_dir_manager.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/afk_mode.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/approval_runtime.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/background_tasks.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/clipboard_utils.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/diff_visualizer.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/export_import.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/hook_engine.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/notification_manager.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/session_fork.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/shell_mode.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/todo_visualizer.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/tree_ls.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/wire_events.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/dulus_tools/yolo_mode.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/governance.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/agent_bridge.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/chat_widget.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/App.tsx +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/THIRD_PARTY_NOTICES.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/dist/index.html +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/dist/standalone.html +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/index.html +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/index.tsx +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/metadata.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/package-lock.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/package.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/types.ts +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/utils.ts +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/vertex-ai-proxy-interceptor.js +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/dulus_orchestrator/vite.config.ts +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/main_window.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/personas.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/sandbox_server.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/session_utils.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/settings_dialog.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/sidebar.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/tasks_view.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/themes.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/gui/tool_panel.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/input.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/license_manager.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/audit.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/consolidator.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/context.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/offload.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/palace.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/scan.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/sessions.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/store.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/tools.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/types.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/memory/vector_search.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/multi_agent/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/multi_agent/subagent.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/multi_agent/tools.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/offload_helper.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/personality_config.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/plugin/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/plugin/autoadapter.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/plugin/loader.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/plugin/recommend.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/plugin/store.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/plugin/types.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/providers.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/README.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/components.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/dist/assets/index-DE51D6wI.css +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/dist/assets/index-DMCCNE9Y.js +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/dist/index.html +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/dist/wallpaper-default.jpg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/dist/wallpapers/default.jpeg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/dist/wallpapers/light.jpeg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/dist/wallpapers/nature.jpeg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/dist/wallpapers/tech.jpeg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/eslint.config.js +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/index.html +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/info.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/package-lock.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/package.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/postcss.config.js +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/tailwind.config.js +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/tsconfig.app.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/tsconfig.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/tsconfig.node.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox/vite.config.ts +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/sandbox_bootstrap.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/setup.cfg +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/builtin.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/LICENSE-obsidian-skills +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/README.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/defuddle/SKILL.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/json-canvas/SKILL.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/json-canvas/references/EXAMPLES.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/obsidian-bases/SKILL.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/obsidian-bases/references/FUNCTIONS_REFERENCE.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/obsidian-cli/SKILL.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/obsidian-markdown/SKILL.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/obsidian-markdown/references/CALLOUTS.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/obsidian-markdown/references/EMBEDS.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/obsidian-markdown/references/PROPERTIES.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/README.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/SKILL.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/addresses.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/advancedbackgroundchecks.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/beenverified.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/clustal.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/clustrmaps.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/cyberbackgroundchecks.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/familytreenow.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/fastpeoplesearch.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/intelius.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/mylife.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/nuwber.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/peekyou.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/peoplefinders.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/radaris.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/rehold.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/searchpeoplefree.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/socialcatfish.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/spokeo.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/thatsthem.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/truepeoplesearch.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/usphonebook.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/brokers/whitepages.json +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/legal/ccpa.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/legal/drop.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/legal/gdpr.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/methods.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/site-playbooks.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/references/state-machine.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/autopilot.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/badbool.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/brokers.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/cdp.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/config.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/crypto.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/dossier.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/email_modes.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/emailer.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/ledger.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/legal.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/paths.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/pdd.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/registry.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/report.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/scan.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/storage.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/tiers.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/scripts/vectors.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/templates/consent/authorization.md +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/templates/emails/ccpa-authorized-agent.txt +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/templates/emails/ccpa-deletion.txt +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/templates/emails/ccpa-indirect-deletion.txt +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/templates/emails/gdpr-erasure.txt +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/bundled/unbroker/templates/emails/generic-optout.txt +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/clawhub.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/executor.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/loader.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skill/tools.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/skills.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/soul.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/spinner.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/string_utils.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/subagent.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/task/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/task/store.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/task/tools.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/task/types.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_afk_yolo.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_approval_runtime.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_background_task_tools.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_background_tasks.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_checkpoint.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_clipboard_utils.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_compaction.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_diff_view.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_diff_visualization.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_display_blocks.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_export_import.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_hook_engine.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_injection_fix.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_license.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_mcp.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_memory.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_notification_manager.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_plugin.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_session_fork.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_shell_mode.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_skills.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_steer_input.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_subagent.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_task.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_telegram_buffer.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_think_tool.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_todo_tool.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_todo_visualization.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_tool_registry.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_tree_ls.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_voice.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tests/test_wire_events.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tmux_offloader.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tmux_tools.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tool_registry.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/tools.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/ui/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/ui/input.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/ui/render.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/voice/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/voice/audio_utils.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/voice/keyterms.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/voice/recorder.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/voice/stt.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/voice/wake_word.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/webbridge/__init__.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/webbridge/core.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/webbridge/tools.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/webchat.py +0 -0
- {dulus-3.9.4 → dulus-3.10.0}/welcome.py +0 -0
|
@@ -6,5 +6,6 @@ recursive-include gui/dulus_orchestrator/dist *
|
|
|
6
6
|
exclude gui/dulus_orchestrator/dist/runtime-state.js
|
|
7
7
|
exclude gui/dulus_orchestrator/dist/desktop-pet.html
|
|
8
8
|
recursive-include webbridge *
|
|
9
|
+
recursive-include webchat_ui *.html *.css *.js
|
|
9
10
|
global-exclude __pycache__/*
|
|
10
11
|
global-exclude *.pyc
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dulus
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.10.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
|
|
@@ -162,6 +162,8 @@ def run(
|
|
|
162
162
|
tool_schemas=get_tool_schemas(),
|
|
163
163
|
config=config,
|
|
164
164
|
)):
|
|
165
|
+
if cancel_check and cancel_check():
|
|
166
|
+
return
|
|
165
167
|
if isinstance(event, (TextChunk, ThinkingChunk)):
|
|
166
168
|
yield event
|
|
167
169
|
elif isinstance(event, AssistantTurn):
|
|
@@ -217,6 +219,8 @@ def run(
|
|
|
217
219
|
|
|
218
220
|
# ── Execute tools ────────────────────────────────────────────────
|
|
219
221
|
for tc in assistant_turn.tool_calls:
|
|
222
|
+
if cancel_check and cancel_check():
|
|
223
|
+
return
|
|
220
224
|
yield ToolStart(tc["name"], tc["input"])
|
|
221
225
|
|
|
222
226
|
# ── Governance gate (capabilities + pre_tool hook) ───────────────
|
|
@@ -29,7 +29,6 @@ silently ignored; telemetry must never slow down or break Dulus.
|
|
|
29
29
|
from __future__ import annotations
|
|
30
30
|
|
|
31
31
|
import base64
|
|
32
|
-
import datetime as _dt
|
|
33
32
|
import json
|
|
34
33
|
import os
|
|
35
34
|
import platform
|
|
@@ -46,23 +45,6 @@ MP_TOKEN = os.environ.get("DULUS_MP_TOKEN", "966ce8f5ccb32f06788f51be9f8bf8f5")
|
|
|
46
45
|
|
|
47
46
|
_MP_ENDPOINT = "https://api.mixpanel.com/track"
|
|
48
47
|
|
|
49
|
-
# ── PostHog (product analytics, runs alongside Mixpanel) ────────────────────
|
|
50
|
-
# Project API keys (phc_...) are public/write-only by design — meant to ship in
|
|
51
|
-
# client code, cannot read data. Override with DULUS_POSTHOG_KEY.
|
|
52
|
-
POSTHOG_KEY = os.environ.get(
|
|
53
|
-
"DULUS_POSTHOG_KEY", "phc_yqAJ42vbj8YFkdpxZicsS4asdbWFTPy6orR8uRNewfYD"
|
|
54
|
-
)
|
|
55
|
-
_POSTHOG_ENDPOINT = os.environ.get(
|
|
56
|
-
"DULUS_POSTHOG_HOST", "https://us.i.posthog.com"
|
|
57
|
-
).rstrip("/") + "/capture/"
|
|
58
|
-
|
|
59
|
-
# ── Amplitude (behavioral analytics, runs alongside the others) ─────────────
|
|
60
|
-
# API keys are write-only client keys (safe to ship). Override w/ DULUS_AMPLITUDE_KEY.
|
|
61
|
-
AMPLITUDE_KEY = os.environ.get(
|
|
62
|
-
"DULUS_AMPLITUDE_KEY", "2511c9e1fc597b8bc6b81f193cc615a2"
|
|
63
|
-
)
|
|
64
|
-
_AMPLITUDE_ENDPOINT = "https://api2.amplitude.com/2/httpapi"
|
|
65
|
-
|
|
66
48
|
# Populated by init_telemetry(); None = not initialised / disabled.
|
|
67
49
|
_distinct_id: str | None = None
|
|
68
50
|
_enabled: bool = False
|
|
@@ -139,11 +121,10 @@ def track(event: str, properties: dict | None = None) -> None:
|
|
|
139
121
|
}
|
|
140
122
|
|
|
141
123
|
def _send() -> None:
|
|
142
|
-
from urllib.request import Request, urlopen
|
|
143
|
-
from urllib.parse import urlencode
|
|
144
|
-
|
|
145
|
-
# Mixpanel
|
|
146
124
|
try:
|
|
125
|
+
from urllib.request import Request, urlopen
|
|
126
|
+
from urllib.parse import urlencode
|
|
127
|
+
|
|
147
128
|
data = urlencode(
|
|
148
129
|
{"data": base64.b64encode(json.dumps([payload]).encode()).decode()}
|
|
149
130
|
).encode()
|
|
@@ -152,55 +133,6 @@ def track(event: str, properties: dict | None = None) -> None:
|
|
|
152
133
|
except Exception:
|
|
153
134
|
pass # telemetry must never break Dulus
|
|
154
135
|
|
|
155
|
-
# PostHog (same event, product-analytics brain)
|
|
156
|
-
if POSTHOG_KEY:
|
|
157
|
-
try:
|
|
158
|
-
ph_props = {
|
|
159
|
-
"dulus_version": _dulus_version,
|
|
160
|
-
"os": platform.system(),
|
|
161
|
-
"python": f"{sys.version_info.major}.{sys.version_info.minor}",
|
|
162
|
-
"$process_person_profile": False, # anonymous, no PII person
|
|
163
|
-
**(properties or {}),
|
|
164
|
-
}
|
|
165
|
-
ph_payload = {
|
|
166
|
-
"api_key": POSTHOG_KEY,
|
|
167
|
-
"event": event,
|
|
168
|
-
"distinct_id": _distinct_id,
|
|
169
|
-
"properties": ph_props,
|
|
170
|
-
"timestamp": _dt.datetime.utcnow().isoformat() + "Z",
|
|
171
|
-
}
|
|
172
|
-
ph_data = json.dumps(ph_payload).encode()
|
|
173
|
-
ph_req = Request(
|
|
174
|
-
_POSTHOG_ENDPOINT, data=ph_data, method="POST",
|
|
175
|
-
headers={"Content-Type": "application/json"},
|
|
176
|
-
)
|
|
177
|
-
urlopen(ph_req, timeout=4).read()
|
|
178
|
-
except Exception:
|
|
179
|
-
pass # telemetry must never break Dulus
|
|
180
|
-
|
|
181
|
-
# Amplitude (same event, behavioral-analytics brain)
|
|
182
|
-
if AMPLITUDE_KEY:
|
|
183
|
-
try:
|
|
184
|
-
amp_event = {
|
|
185
|
-
"user_id": (_distinct_id or "anon").ljust(5, "_"), # min 5 chars
|
|
186
|
-
"event_type": event,
|
|
187
|
-
"platform": platform.system(),
|
|
188
|
-
"app_version": _dulus_version,
|
|
189
|
-
"event_properties": (properties or {}),
|
|
190
|
-
}
|
|
191
|
-
amp_payload = {
|
|
192
|
-
"api_key": AMPLITUDE_KEY,
|
|
193
|
-
"events": [amp_event],
|
|
194
|
-
}
|
|
195
|
-
amp_data = json.dumps(amp_payload).encode()
|
|
196
|
-
amp_req = Request(
|
|
197
|
-
_AMPLITUDE_ENDPOINT, data=amp_data, method="POST",
|
|
198
|
-
headers={"Content-Type": "application/json"},
|
|
199
|
-
)
|
|
200
|
-
urlopen(amp_req, timeout=4).read()
|
|
201
|
-
except Exception:
|
|
202
|
-
pass # telemetry must never break Dulus
|
|
203
|
-
|
|
204
136
|
threading.Thread(target=_send, daemon=True, name="telemetry").start()
|
|
205
137
|
|
|
206
138
|
|
|
@@ -15,6 +15,52 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
15
15
|
- Security policy
|
|
16
16
|
- Brand guidelines
|
|
17
17
|
|
|
18
|
+
## [3.9.5] - 2026-07-11
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- TTS `c` cancel key not working while the REPL prompt was active:
|
|
22
|
+
`msvcrt.kbhit()` only sees keystrokes when the raw console owns stdin, so
|
|
23
|
+
prompt_toolkit swallowed the `c` before the watcher saw it. Added a second
|
|
24
|
+
detection path via `GetAsyncKeyState` (physical key state, edge-detected)
|
|
25
|
+
that fires regardless of who owns stdin, plus a 30ms sleep so the watcher
|
|
26
|
+
no longer busy-spins a CPU core during playback.
|
|
27
|
+
|
|
28
|
+
## [3.9.4] - 2026-07-11
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- Catastrophic config reset: `save_config()` wrote the caller's dict verbatim,
|
|
32
|
+
so a thin dict (e.g. only `lang` + `user_name` at early startup) silently
|
|
33
|
+
wiped every other key — API keys, voice config, everything. Now it merges
|
|
34
|
+
DEFAULTS + on-disk config first (with `.bak` fallback if the on-disk copy
|
|
35
|
+
is corrupt), then applies runtime changes on top.
|
|
36
|
+
|
|
37
|
+
## [3.9.3] - 2026-07-11
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
- `/lang` was silently overpowered by `soul.md` / gold memories that assert a
|
|
41
|
+
voice ("I speak Dominican Spanish"). The chosen language is now re-asserted
|
|
42
|
+
at the end of the system prompt (highest-authority position) and `/lang`
|
|
43
|
+
injects an immediate directive into the live conversation so the switch
|
|
44
|
+
takes effect the same turn. Defaults untouched — no `/lang` set means the
|
|
45
|
+
soul keeps control.
|
|
46
|
+
|
|
47
|
+
## [3.9.2] - 2026-07-11
|
|
48
|
+
|
|
49
|
+
### Added
|
|
50
|
+
- `/update` self-update command: quiet cached (6h TTL) non-blocking PyPI check
|
|
51
|
+
on startup, in-place upgrade, `now|check|status|on|off` subcommands.
|
|
52
|
+
|
|
53
|
+
## [3.9.0] - 2026-07-11
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
- MCP Marketplace: `/mcp list|search|install` over a live catalog of 2000+
|
|
57
|
+
servers from registry.modelcontextprotocol.io + awesome-mcp, deduped,
|
|
58
|
+
6h-TTL cached, offline-safe. One-shot install: resolve command, write
|
|
59
|
+
config, connect, verify tools, hot-reload into the live session.
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
- Windows launcher for node-based MCP servers (`npx` ships as `npx.cmd`).
|
|
63
|
+
|
|
18
64
|
## [3.6.2] - 2026-07-04
|
|
19
65
|
|
|
20
66
|
### Fixed
|
|
@@ -2,16 +2,6 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
|
|
4
4
|
<head>
|
|
5
|
-
<!-- Amplitude behavioral analytics -->
|
|
6
|
-
<script src="https://cdn.amplitude.com/script/2511c9e1fc597b8bc6b81f193cc615a2.js"></script>
|
|
7
|
-
<script>window.amplitude&&window.amplitude.init&&window.amplitude.init('2511c9e1fc597b8bc6b81f193cc615a2',{"fetchRemoteConfig":true,"autocapture":true});</script>
|
|
8
|
-
|
|
9
|
-
<!-- PostHog product analytics -->
|
|
10
|
-
<script>
|
|
11
|
-
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture identify reset get_distinct_id capture_pageview capture_pageleave".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
|
12
|
-
posthog.init('phc_yqAJ42vbj8YFkdpxZicsS4asdbWFTPy6orR8uRNewfYD',{api_host:'https://us.i.posthog.com',person_profiles:'identified_only',capture_pageview:true,capture_pageleave:true});
|
|
13
|
-
</script>
|
|
14
|
-
|
|
15
5
|
<meta charset="UTF-8">
|
|
16
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
17
7
|
<title>Dulus — Task Dashboard</title>
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
<!-- Amplitude behavioral analytics -->
|
|
5
|
-
<script src="https://cdn.amplitude.com/script/2511c9e1fc597b8bc6b81f193cc615a2.js"></script>
|
|
6
|
-
<script>window.amplitude&&window.amplitude.init&&window.amplitude.init('2511c9e1fc597b8bc6b81f193cc615a2',{"fetchRemoteConfig":true,"autocapture":true});</script>
|
|
7
|
-
|
|
8
|
-
<!-- PostHog product analytics -->
|
|
9
|
-
<script>
|
|
10
|
-
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture identify reset get_distinct_id capture_pageview capture_pageleave".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
|
11
|
-
posthog.init('phc_yqAJ42vbj8YFkdpxZicsS4asdbWFTPy6orR8uRNewfYD',{api_host:'https://us.i.posthog.com',person_profiles:'identified_only',capture_pageview:true,capture_pageleave:true});
|
|
12
|
-
</script>
|
|
13
|
-
|
|
14
4
|
<meta charset="UTF-8">
|
|
15
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
16
6
|
<title>Dulus — Hunt. Patch. Ship.</title>
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## 🔥🔥🔥 News (Pacific Time)
|
|
4
4
|
|
|
5
|
+
- July 11, 2026 (**v3.9.5**): **⏹ The `c` key now ALWAYS stops the voice.** Pressing `c` to cancel TTS playback only worked *sometimes* — and the reason was sneaky: the cancel watcher listened via `msvcrt.kbhit()`, which only sees keystrokes when the raw console owns stdin. With the fancy REPL prompt (prompt_toolkit) active, the prompt swallowed your `c` before the watcher ever saw it, and you were stuck listening to the whole monologue. Now there's a second detection path reading the **physical key state straight from the OS** (`GetAsyncKeyState`, edge-detected so a held key doesn't retrigger) — it fires no matter who owns stdin. Bonus: the watcher loop now sleeps 30ms per tick instead of busy-spinning a full CPU core while audio plays. Press `c`, voice dies, instantly, every time. 🦅🇩🇴
|
|
6
|
+
|
|
7
|
+
- July 11, 2026 (**v3.9.4**): **🛡️ Killed the config-wipe bug for real this time.** v3.6.1 made config writes atomic — but there was a second, nastier path to the same disaster: `save_config()` wrote the caller's dict **verbatim**. If anything called it with a thin dict (early startup, a command that rebuilt a minimal config), every other key you owned — API keys, voice config, provider settings, all of it — silently vanished, shrinking `config.json` to 2 keys. No crash needed; a perfectly successful write was the weapon. Now `save_config()` merges DEFAULTS + whatever is already on disk FIRST (with `.bak` fallback if the on-disk copy is corrupt), then applies the runtime changes on top. A thin save physically cannot drop your keys anymore. If your config ever mysteriously "reset itself": this was it, and it's dead now. 🦅🇩🇴
|
|
8
|
+
|
|
9
|
+
- July 11, 2026 (**v3.9.3**): **🗣️ `/lang` now beats your soul.** If you customized your Dulus with a `soul.md` or gold memories that assert a voice ("I speak Dominican Spanish"), those conversation-injected identities quietly overpowered the one language line at the top of the system prompt — so `/lang en` looked like it did nothing and Dulus kept replying in the soul's tongue. Two-layer fix: the chosen language is now re-asserted at the **end** of the system prompt (highest-authority position) explicitly overriding soul/essence/gold-memory language claims, AND `/lang` injects an immediate directive into the live conversation so the switch lands **the same turn** — not next session. Default setups are untouched: no `/lang` set means your soul keeps full control of the voice. 🦅🇩🇴
|
|
10
|
+
|
|
5
11
|
- July 11, 2026: **🔄 Self-update — every Dulus stays on the latest, automatically.** The whole point of the organism is that a fix found by one Dulus reaches every other Dulus fast. So now Dulus keeps *itself* current: on startup it does a quiet, cached (6h TTL), non-blocking check against PyPI, and if there's a newer release it upgrades in place — no `pip install -U` dance, no stale nodes drifting behind. New `/update` command with everything you'd expect: `/update` (check + upgrade if newer), `/update now` (force), `/update check` (look but don't touch), `/update status` (see installed vs latest), and `/update on|off` to toggle the automatic startup check (on by default). Handles PEP 668 externally-managed Pythons automatically, and the check *never* blocks or crashes your boot — if PyPI is down or you're offline, Dulus just carries on. The fleet moves as one. 🦅🇩🇴
|
|
6
12
|
|
|
7
13
|
- July 11, 2026: **🔌 MCP Marketplace — 2000+ servers, zero friction, install by name.** MCP (Model Context Protocol) was always one of Dulus's most powerful features and almost nobody used it — the friction killed it. You had to *find* a server somewhere, dig up its exact launch command, hand-edit a `.mcp.json`, and pray it connected. Dead on arrival. So we built a real marketplace on top of it. `/mcp list` and `/mcp search <anything>` now browse a live catalog of **2000+ servers** pulled from the official [registry.modelcontextprotocol.io](https://registry.modelcontextprotocol.io) (the metaregistry backed by Anthropic, GitHub, Microsoft & PulseMCP) plus the community awesome-mcp list — deduped, cached with a 6h TTL, and **offline-safe** (falls back to a curated set if you're on a plane). Then `/mcp install <name>` does the whole thing in one shot: resolves the launch command, writes the config, **connects, verifies the tools, and hot-reloads them live into your current session** — no restart, no JSON, no manual anything. `/mcp installed` shows what's live with a green/red status dot, `/mcp runtimes` tells you which runtimes (node/python/docker) you've got. Also shipped a Windows launcher fix so node-based servers (`npx`, which ships as `npx.cmd` on Windows) actually start instead of silently failing — probably the real reason MCP "never worked" for a lot of Windows users. From *"I've never touched MCP"* to *"connected in 5 seconds."* 🦅🇩🇴
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
<!-- Amplitude behavioral analytics -->
|
|
5
|
-
<script src="https://cdn.amplitude.com/script/2511c9e1fc597b8bc6b81f193cc615a2.js"></script>
|
|
6
|
-
<script>window.amplitude&&window.amplitude.init&&window.amplitude.init('2511c9e1fc597b8bc6b81f193cc615a2',{"fetchRemoteConfig":true,"autocapture":true});</script>
|
|
7
|
-
|
|
8
|
-
<!-- PostHog product analytics -->
|
|
9
|
-
<script>
|
|
10
|
-
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture identify reset get_distinct_id capture_pageview capture_pageleave".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
|
|
11
|
-
posthog.init('phc_yqAJ42vbj8YFkdpxZicsS4asdbWFTPy6orR8uRNewfYD',{api_host:'https://us.i.posthog.com',person_profiles:'identified_only',capture_pageview:true,capture_pageleave:true});
|
|
12
|
-
</script>
|
|
13
|
-
|
|
14
4
|
<meta charset="UTF-8">
|
|
15
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
16
6
|
<title>Mesa Redonda — Dulus Personas</title>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dulus
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.10.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
|