dulus 3.11.2__tar.gz → 3.11.3__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.11.2/dulus.egg-info → dulus-3.11.3}/PKG-INFO +1 -1
- {dulus-3.11.2 → dulus-3.11.3/dulus.egg-info}/PKG-INFO +1 -1
- {dulus-3.11.2 → dulus-3.11.3}/dulus.egg-info/SOURCES.txt +1 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus.py +37 -6
- {dulus-3.11.2 → dulus-3.11.3}/providers.py +0 -25
- {dulus-3.11.2 → dulus-3.11.3}/pyproject.toml +247 -247
- dulus-3.11.3/tests/test_dulus_account.py +183 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_provider_errors.py +0 -52
- {dulus-3.11.2 → dulus-3.11.3}/LICENSE +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/MANIFEST.in +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/README.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/agent.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/algolia_search.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/analytics.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/agents_bridge.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/compressor.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/context.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/githook.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/marketplace.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/mempalace_bridge.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/paths.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/personas.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/plugins.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/server.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/backend/tasks.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/banners/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/banners/banner_rotator.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/banners/banners_dulus_ai.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/batch_api.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/checkpoint/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/checkpoint/hooks.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/checkpoint/store.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/checkpoint/types.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/__main__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/ansi.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/assets/ascii/dulus_logo.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/assets/ascii/eagle.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/assets/ascii/terminal_art.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/banners.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/demo.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/effects.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/effort_slider.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/progress.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/py.typed +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/spinners.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cli_animations/status.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/clipboard_utils.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/cloudsave.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/common.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/compaction.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/config.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/context.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/active_persona.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/marketplace.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/personas.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/plugins/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/plugins/composio/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/plugins/composio/composio_plugin/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/plugins/composio/composio_plugin/session_manager.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/plugins/composio/composio_plugin/tool_generator.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/plugins/composio/plugin.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/plugins/composio/plugin_tool.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/data/tasks.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/display_blocks.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/API.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/BRAND_GUIDE.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/CHANGELOG.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/CONTRIBUTING.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/DEPLOYMENT.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/Dulus_AI_Whitepaper_(v2.0).pdf +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/Dulus_YC_Company_Overview_Aug_2026.pdf +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/FAQ.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/GETTING_STARTED.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README_AR.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README_EN.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README_ES.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README_FR.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README_JA.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README_KO.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README_PT.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README_RU.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/README_ZH.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/SECURITY.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/api.html +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/architecture.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/azure-speech-template.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/dashboard/index.html +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/divider.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/dulus-bird.png +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/generate.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/index.html +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/news.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/nvidia-models.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/particle-playground.html +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/personas/index.html +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/poetry-banner.png +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/preview.html +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/python-console.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/auto-adapter.png +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/dulus-os.png +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/hero.png +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/lookback_two_windows.png +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/pyc_heap.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/pyc_receipts.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/pyc_trap.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/roundtable.png +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/task-board.png +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/readme/webchat.png +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-agents.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-brainstorm.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-bridges.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-features.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-freetier.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-memory.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-models.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-perms.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-plugins.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-quickstart.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/sec-ssj.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/spinners.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/split-pane.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/terminal-boot.svg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/docs/termux-edge.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus.egg-info/dependency_links.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus.egg-info/entry_points.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus.egg-info/requires.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus.egg-info/top_level.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_bar_client.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_gui.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_mcp/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_mcp/client.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_mcp/commands.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_mcp/config.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_mcp/hub.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_mcp/tools.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_mcp/types.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_quick_menu.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/add_dir_manager.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/afk_mode.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/approval_runtime.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/background_tasks.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/clipboard_utils.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/diff_visualizer.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/export_import.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/hook_engine.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/notification_manager.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/session_fork.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/shell_mode.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/todo_visualizer.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/tree_ls.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/wire_events.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/dulus_tools/yolo_mode.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/file_filter.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/fs_compass.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/governance.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/agent_bridge.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/chat_widget.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/main_window.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/personas.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/sandbox_server.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/session_utils.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/settings_dialog.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/sidebar.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/tasks_view.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/themes.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/gui/tool_panel.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/input.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/license_manager.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/lookback.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/audit.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/consolidator.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/context.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/mempalace_bridge.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/offload.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/palace.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/scan.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/adaptation_guides.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/askuserquestion_after_numbered_list.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/background_jobs_no_extra_timers.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/cleverness_over_resources.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/corporate_tls_breaks_curl_cffi.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/hardened_rules.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/investigator_workflow_heuristic.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/native_code_over_sketchy_plugins.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/no_personal_info_in_code.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/searches_include_modified_date.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/tmux_send_keys_power_patterns.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/token_optimization_technique.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/tool_chaining_capability.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/insights/webbridge_evaluate_first_pattern.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/seeds/short_memory.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/sessions.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/store.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/tools.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/types.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/memory/vector_search.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/model_params.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/multi_agent/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/multi_agent/subagent.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/multi_agent/tools.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/paste_placeholders.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/personality_config.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/plugin/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/plugin/autoadapter.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/plugin/loader.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/plugin/recommend.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/plugin/store.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/plugin/types.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/profiles.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/pyconsole.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/README.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/components.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/dist/assets/index-DE51D6wI.css +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/dist/assets/index-DMCCNE9Y.js +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/dist/index.html +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/dist/wallpaper-default.jpg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/dist/wallpapers/default.jpeg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/dist/wallpapers/light.jpeg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/dist/wallpapers/nature.jpeg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/dist/wallpapers/tech.jpeg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/eslint.config.js +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/index.html +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/info.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/package-lock.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/package.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/postcss.config.js +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/tailwind.config.js +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/tsconfig.app.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/tsconfig.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/tsconfig.node.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox/vite.config.ts +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/sandbox_bootstrap.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/setup.cfg +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/builtin.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/LICENSE-obsidian-skills +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/README.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/defuddle/SKILL.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/json-canvas/SKILL.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/json-canvas/references/EXAMPLES.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/obsidian-bases/SKILL.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/obsidian-bases/references/FUNCTIONS_REFERENCE.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/obsidian-cli/SKILL.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/obsidian-markdown/SKILL.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/obsidian-markdown/references/CALLOUTS.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/obsidian-markdown/references/EMBEDS.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/obsidian-markdown/references/PROPERTIES.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/README.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/SKILL.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/addresses.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/advancedbackgroundchecks.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/beenverified.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/clustal.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/clustrmaps.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/cyberbackgroundchecks.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/familytreenow.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/fastpeoplesearch.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/intelius.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/mylife.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/nuwber.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/peekyou.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/peoplefinders.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/radaris.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/rehold.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/searchpeoplefree.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/socialcatfish.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/spokeo.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/thatsthem.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/truepeoplesearch.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/usphonebook.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/brokers/whitepages.json +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/legal/ccpa.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/legal/drop.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/legal/gdpr.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/methods.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/site-playbooks.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/references/state-machine.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/autopilot.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/badbool.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/brokers.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/cdp.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/config.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/crypto.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/dossier.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/email_modes.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/emailer.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/ledger.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/legal.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/paths.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/pdd.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/registry.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/report.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/scan.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/storage.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/tiers.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/scripts/vectors.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/templates/consent/authorization.md +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/templates/emails/ccpa-authorized-agent.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/templates/emails/ccpa-deletion.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/templates/emails/ccpa-indirect-deletion.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/templates/emails/gdpr-erasure.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/bundled/unbroker/templates/emails/generic-optout.txt +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/clawhub.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/executor.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/loader.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skill/tools.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/skills.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/soul.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/spinner.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/steer_input.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/subagent.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/task/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/task/store.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/task/tools.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/task/types.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_afk_yolo.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_approval_runtime.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_background_task_tools.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_background_tasks.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_chatgpt_oauth.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_checkpoint.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_cli_animations_integration.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_clipboard_utils.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_compaction.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_composio_tool_generator.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_diff_view.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_diff_visualization.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_display_blocks.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_export_import.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_grok_usage.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_hook_engine.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_injection_fix.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_license.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_lookback_cache.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_mcp.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_mcp_algolia.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_memory.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_memory_home_resolution.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_notification_manager.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_plugin.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_profile_isolation.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_session_fork.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_shell_mode.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_skills.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_skillssh_algolia.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_steer_input.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_subagent.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_task.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_telegram_buffer.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_think_tool.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_todo_tool.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_todo_visualization.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_tool_registry.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_tree_ls.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_voice.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_webbridge_tabs.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tests/test_wire_events.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tmux_tools.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tool_registry.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tools.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tools_background.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tools_think.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/tools_todo.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/ui/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/ui/input.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/ui/render.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/updater.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/voice/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/voice/audio_utils.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/voice/keyterms.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/voice/recorder.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/voice/stt.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/voice/tts.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/voice/wake_word.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/webbridge/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/webbridge/core.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/webbridge/tools.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/webchat.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/webchat_server.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/webchat_ui/__init__.py +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/webchat_ui/app.js +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/webchat_ui/index.html +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/webchat_ui/style.css +0 -0
- {dulus-3.11.2 → dulus-3.11.3}/welcome.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: dulus
|
|
3
|
-
Version: 3.11.
|
|
3
|
+
Version: 3.11.3
|
|
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>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: dulus
|
|
3
|
-
Version: 3.11.
|
|
3
|
+
Version: 3.11.3
|
|
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>
|
|
@@ -341,6 +341,7 @@ tests/test_composio_tool_generator.py
|
|
|
341
341
|
tests/test_diff_view.py
|
|
342
342
|
tests/test_diff_visualization.py
|
|
343
343
|
tests/test_display_blocks.py
|
|
344
|
+
tests/test_dulus_account.py
|
|
344
345
|
tests/test_export_import.py
|
|
345
346
|
tests/test_grok_usage.py
|
|
346
347
|
tests/test_hook_engine.py
|
|
@@ -380,7 +380,7 @@ try:
|
|
|
380
380
|
from importlib.metadata import version as _pkg_version
|
|
381
381
|
VERSION = _pkg_version("dulus")
|
|
382
382
|
except Exception:
|
|
383
|
-
VERSION = "3.11.
|
|
383
|
+
VERSION = "3.11.3" # dev fallback — keep in sync with pyproject.toml
|
|
384
384
|
|
|
385
385
|
# ── ANSI helpers (used even with rich for non-markdown output) ─────────────
|
|
386
386
|
from common import C, clr, info, ok, warn, err, stream_thinking, sanitize_text
|
|
@@ -3246,11 +3246,7 @@ def cmd_harvest(_args: str, _state, config) -> bool:
|
|
|
3246
3246
|
info("Login page detected. Please log in manually, then press ENTER here...")
|
|
3247
3247
|
input()
|
|
3248
3248
|
|
|
3249
|
-
|
|
3250
|
-
# (it keeps streaming/websocket connections open), so that wait
|
|
3251
|
-
# always burned the full 30s and timed out. Wait for the DOM
|
|
3252
|
-
# instead and give it a real ceiling.
|
|
3253
|
-
page.goto("https://claude.ai/new", wait_until="domcontentloaded", timeout=60000)
|
|
3249
|
+
page.goto("https://claude.ai/new", wait_until="networkidle")
|
|
3254
3250
|
time.sleep(2)
|
|
3255
3251
|
|
|
3256
3252
|
user_agent = page.evaluate("navigator.userAgent") if browser.pages else ""
|
|
@@ -9171,6 +9167,41 @@ def cmd_login(args: str, _state, config) -> bool:
|
|
|
9171
9167
|
"""
|
|
9172
9168
|
sub = (args or "").strip().lower()
|
|
9173
9169
|
|
|
9170
|
+
# ── Dulus account (OAuth 2.0 + PKCE against Dulus's own API) ──
|
|
9171
|
+
# Unlike the provider logins below, this one authenticates you to Dulus
|
|
9172
|
+
# itself, so the CLI can reach the Dulus API without an API key pasted in
|
|
9173
|
+
# by hand. `/login dulus key` mints a dulus_sk_* key for CI and servers.
|
|
9174
|
+
if sub.split(" ")[0] in ("dulus", "account"):
|
|
9175
|
+
import dulus_account
|
|
9176
|
+
|
|
9177
|
+
rest = (args or "").strip().split()
|
|
9178
|
+
force = "force" in rest
|
|
9179
|
+
if len(rest) > 1 and rest[1] in ("key", "apikey", "api-key"):
|
|
9180
|
+
name = rest[2] if len(rest) > 2 else "cli"
|
|
9181
|
+
dulus_account.create_api_key(name, notify=lambda m: print(clr(m, "cyan")))
|
|
9182
|
+
return True
|
|
9183
|
+
|
|
9184
|
+
if not force:
|
|
9185
|
+
store = dulus_account.load_store()
|
|
9186
|
+
if store.get("access_token") and not dulus_account._token_expired(store):
|
|
9187
|
+
print(clr("✅ Dulus account already signed in.", "green"))
|
|
9188
|
+
print(clr("Use `/login dulus force` to sign in again, or `/login dulus key` to mint an API key.", "green"))
|
|
9189
|
+
return True
|
|
9190
|
+
|
|
9191
|
+
if force:
|
|
9192
|
+
dulus_account.clear_store()
|
|
9193
|
+
print(clr("Starting Dulus sign-in (OAuth 2.0 + PKCE)…", "cyan"))
|
|
9194
|
+
try:
|
|
9195
|
+
token = dulus_account.login(notify=lambda m: print(clr(m, "cyan")))
|
|
9196
|
+
except Exception as e:
|
|
9197
|
+
token = None
|
|
9198
|
+
print(clr(f"Sign-in error: {e}", "red"))
|
|
9199
|
+
if token:
|
|
9200
|
+
print(clr("✅ Signed in to your Dulus account.", "green"))
|
|
9201
|
+
return True
|
|
9202
|
+
print(clr("Could not sign in. Re-run `/login dulus`.", "yellow"))
|
|
9203
|
+
return True
|
|
9204
|
+
|
|
9174
9205
|
# ── Claude / Anthropic subscription OAuth (no API key, no cookie webbridge) ──
|
|
9175
9206
|
# Mirrors the Grok flow: opens claude.ai in the browser, you approve and paste
|
|
9176
9207
|
# back the code, Dulus exchanges it for an OAuth token. claude-* models then run
|
|
@@ -91,15 +91,6 @@ class _ProviderRetry:
|
|
|
91
91
|
# Rate limit / server overload
|
|
92
92
|
if "429" in msg or "rate limit" in msg or "too many requests" in msg:
|
|
93
93
|
return True
|
|
94
|
-
# Capacity pushback. Anthropic answers 529 "overloaded_error" and other
|
|
95
|
-
# providers say "overloaded"/"capacity"/"server is busy" with assorted
|
|
96
|
-
# status codes; the next request usually succeeds, so this is exactly
|
|
97
|
-
# the case worth absorbing silently instead of surfacing to the user.
|
|
98
|
-
if ("529" in msg or "overloaded" in msg or "over capacity" in msg
|
|
99
|
-
or "at capacity" in msg or "server is busy" in msg
|
|
100
|
-
or "model is currently loading" in msg
|
|
101
|
-
or type(exc).__name__ in ("OverloadedError", "InternalServerError")):
|
|
102
|
-
return True
|
|
103
94
|
# Server errors
|
|
104
95
|
if "500" in msg or "502" in msg or "503" in msg or "504" in msg:
|
|
105
96
|
return True
|
|
@@ -5532,13 +5523,6 @@ def stream_anthropic(
|
|
|
5532
5523
|
yield AssistantTurn(text, tool_calls, 0, 0, thinking=thinking,
|
|
5533
5524
|
thinking_signature=thinking_signature, error=False)
|
|
5534
5525
|
return
|
|
5535
|
-
# Nothing emitted yet and the failure is transient (529 overloaded, a
|
|
5536
|
-
# blip, a rate limit): let it propagate so _ProviderRetry can quietly
|
|
5537
|
-
# try again. Turning it into text here would strand the retry wrapper,
|
|
5538
|
-
# which only ever sees a well-behaved generator. Once output has been
|
|
5539
|
-
# emitted a retry would duplicate it, so those still report.
|
|
5540
|
-
if not text and not tool_calls and _ProviderRetry.is_retryable(_e):
|
|
5541
|
-
raise
|
|
5542
5526
|
msg = friendly_api_error(_e)
|
|
5543
5527
|
yield TextChunk(msg)
|
|
5544
5528
|
yield AssistantTurn(msg, [], 0, 0, error=True)
|
|
@@ -6167,11 +6151,6 @@ def stream_openai_compat(
|
|
|
6167
6151
|
{**config, "_modelstudio_remaining": _ms_remaining[1:]},
|
|
6168
6152
|
)
|
|
6169
6153
|
return
|
|
6170
|
-
# Transient capacity pushback before the stream opened: propagate so
|
|
6171
|
-
# _ProviderRetry absorbs it silently. This is the create() call, so
|
|
6172
|
-
# nothing has been emitted yet and a retry cannot duplicate output.
|
|
6173
|
-
if _ProviderRetry.is_retryable(e):
|
|
6174
|
-
raise
|
|
6175
6154
|
msg = friendly_api_error(e)
|
|
6176
6155
|
yield TextChunk(msg)
|
|
6177
6156
|
yield AssistantTurn(msg, [], 0, 0, error=True)
|
|
@@ -6187,10 +6166,6 @@ def stream_openai_compat(
|
|
|
6187
6166
|
{**config, "_modelstudio_remaining": _ms_remaining[1:]},
|
|
6188
6167
|
)
|
|
6189
6168
|
return
|
|
6190
|
-
# Same as above: still inside the create() call, so a transient failure
|
|
6191
|
-
# can be retried without duplicating anything.
|
|
6192
|
-
if _ProviderRetry.is_retryable(e):
|
|
6193
|
-
raise
|
|
6194
6169
|
msg = friendly_api_error(e)
|
|
6195
6170
|
yield TextChunk(msg)
|
|
6196
6171
|
yield AssistantTurn(msg, [], 0, 0, error=True)
|
|
@@ -1,247 +1,247 @@
|
|
|
1
|
-
# setuptools is pinned <77 on purpose: 77+ implements PEP 639 (SPDX license
|
|
2
|
-
# string + license-files) which emits Metadata-Version 2.4. pip < 24.1 — which
|
|
3
|
-
# ships on Ubuntu 24.04 LTS (pip 24.0) and many other current distros — cannot
|
|
4
|
-
# read Metadata 2.4 and silently skips the package, so `pip install dulus` fails
|
|
5
|
-
# with "Could not find a version that satisfies the requirement dulus (from
|
|
6
|
-
# versions: none)" on a fresh machine. Staying <77 keeps Metadata at 2.1/2.2.
|
|
7
|
-
[build-system]
|
|
8
|
-
requires = ["setuptools>=61,<77", "wheel"]
|
|
9
|
-
build-backend = "setuptools.build_meta"
|
|
10
|
-
|
|
11
|
-
[project]
|
|
12
|
-
name = "dulus"
|
|
13
|
-
version = "3.11.
|
|
14
|
-
description = "Provider-independent agent runtime for the terminal — cloud and local models, real tools, MCP, plugins, memory, sub-agents, and Dulus OS."
|
|
15
|
-
readme = "README.md"
|
|
16
|
-
requires-python = ">=3.10"
|
|
17
|
-
# Legacy table form (not the PEP 639 SPDX string) so setuptools emits the older
|
|
18
|
-
# `License:` metadata field and keeps Metadata-Version at 2.1/2.2 — see the
|
|
19
|
-
# build-system note above. LICENSE ships via MANIFEST.in.
|
|
20
|
-
license = {text = "GPL-3.0-only"}
|
|
21
|
-
authors = [{name = "KevRojo", email = "dev@dulus.ai"}]
|
|
22
|
-
maintainers = [{name = "KevRojo", email = "dev@dulus.ai"}]
|
|
23
|
-
keywords = [
|
|
24
|
-
# Providers and runtimes people actually search for.
|
|
25
|
-
"ai", "cli", "llm", "claude", "gemini", "nvidia", "openai",
|
|
26
|
-
"kimi", "deepseek", "qwen", "ollama", "local-llm", "openai-compatible",
|
|
27
|
-
# What this thing IS. Without these the package never surfaces for the
|
|
28
|
-
# queries its own users type.
|
|
29
|
-
"agent", "ai-agent", "coding-agent", "autonomous-agent", "agentic",
|
|
30
|
-
"mcp", "terminal", "tui", "repl", "developer-tools", "sub-agents",
|
|
31
|
-
"tts", "voice",
|
|
32
|
-
]
|
|
33
|
-
classifiers = [
|
|
34
|
-
# 19K+ installs, a full test suite and a 3.11.x line in production. This
|
|
35
|
-
# sat at "4 - Beta" long after that stopped being true, and the Beta badge
|
|
36
|
-
# is the first thing anyone reads on the PyPI page.
|
|
37
|
-
"Development Status :: 5 - Production/Stable",
|
|
38
|
-
# Dulus is not console-only: it ships a desktop GUI (pywebview), a Qt
|
|
39
|
-
# status bar, a Flask webchat and Dulus OS. Listing just Console hid every
|
|
40
|
-
# one of those surfaces.
|
|
41
|
-
"Environment :: Console",
|
|
42
|
-
"Environment :: Web Environment",
|
|
43
|
-
"Environment :: X11 Applications :: Qt",
|
|
44
|
-
"Environment :: Win32 (MS Windows)",
|
|
45
|
-
"Environment :: MacOS X",
|
|
46
|
-
# "Agentic AI for everyone" — the README's own pitch — is not a
|
|
47
|
-
# developers-only audience.
|
|
48
|
-
"Intended Audience :: Developers",
|
|
49
|
-
"Intended Audience :: End Users/Desktop",
|
|
50
|
-
"Intended Audience :: System Administrators",
|
|
51
|
-
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
|
52
|
-
"Natural Language :: English",
|
|
53
|
-
"Natural Language :: Spanish",
|
|
54
|
-
"Operating System :: OS Independent",
|
|
55
|
-
"Programming Language :: Python :: 3",
|
|
56
|
-
"Programming Language :: Python :: 3 :: Only",
|
|
57
|
-
"Programming Language :: Python :: 3.10",
|
|
58
|
-
"Programming Language :: Python :: 3.11",
|
|
59
|
-
"Programming Language :: Python :: 3.12",
|
|
60
|
-
"Programming Language :: Python :: 3.13",
|
|
61
|
-
"Programming Language :: Python :: 3.14",
|
|
62
|
-
# Topics decide which PyPI category listings this appears in. AI + Terminals
|
|
63
|
-
# alone missed the shell, code-generation, chat and speech angles that
|
|
64
|
-
# describe just as much of what Dulus does.
|
|
65
|
-
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
66
|
-
"Topic :: Terminals",
|
|
67
|
-
"Topic :: Software Development :: Code Generators",
|
|
68
|
-
"Topic :: System :: Shells",
|
|
69
|
-
"Topic :: Communications :: Chat",
|
|
70
|
-
"Topic :: Multimedia :: Sound/Audio :: Speech",
|
|
71
|
-
"Topic :: Utilities",
|
|
72
|
-
]
|
|
73
|
-
dependencies = [
|
|
74
|
-
"anthropic>=0.40.0",
|
|
75
|
-
"openai>=1.30.0",
|
|
76
|
-
"httpx>=0.27.0",
|
|
77
|
-
"requests>=2.31.0",
|
|
78
|
-
'tomli>=2.0; python_version < "3.11"', # stdlib tomllib is 3.11+; backport for 3.10
|
|
79
|
-
"rich>=13.0.0",
|
|
80
|
-
"prompt_toolkit>=3.0.0",
|
|
81
|
-
"Flask>=3.1.3",
|
|
82
|
-
"bubblewrap-cli>=1.0.0",
|
|
83
|
-
"customtkinter>=5.2.0",
|
|
84
|
-
"Pillow>=10.0.0",
|
|
85
|
-
"typing-extensions>=4.10.0",
|
|
86
|
-
"pyttsx3",
|
|
87
|
-
# Composio Tool Router — bundled plugin needs this to talk to 1000+ apps
|
|
88
|
-
# without going through MCP. Only ~1MB on the wheel; worth it as a default.
|
|
89
|
-
"composio>=1.0.0rc2",
|
|
90
|
-
# HTML parsing — used by web scraping flows, harvest commands,
|
|
91
|
-
# and several plugins. Tiny dep; ship it by default.
|
|
92
|
-
"beautifulsoup4>=4.12.0",
|
|
93
|
-
"sentry-sdk>=2.0.0",
|
|
94
|
-
# OS trust store — fixes CERTIFICATE_VERIFY_FAILED behind corporate TLS
|
|
95
|
-
# interceptors (Cloudflare Zero Trust/WARP, Zscaler, Netskope). Tiny dep.
|
|
96
|
-
"truststore>=0.9",
|
|
97
|
-
# OCR — local text extraction from images/screenshots. pytesseract is
|
|
98
|
-
# lightweight; Tesseract binary must be installed separately (see README).
|
|
99
|
-
# Pillow already listed above — no duplicate needed.
|
|
100
|
-
"pytesseract>=0.3.10",
|
|
101
|
-
# Dulus Bar — the floating "Dynamic Island" (live model/ctx + Allow/Deny).
|
|
102
|
-
# A normal library dep: pip pulls it (and its PyQt6) at install time; the
|
|
103
|
-
# dulus wheel stays tiny — nothing is bundled. On by default so Dulus opens
|
|
104
|
-
# with the island out of the box; a silent no-op on headless/no-display
|
|
105
|
-
# boxes (Docker, servers, CI) since it never imports Qt without a screen.
|
|
106
|
-
# Off switch for anyone who dislikes it: DULUS_BAR=0 or /config dulus_bar=0.
|
|
107
|
-
"dulus-bar>=0.3.7",
|
|
108
|
-
]
|
|
109
|
-
|
|
110
|
-
# mempalace pulls chromadb (26 transitive deps incl. numpy + onnxruntime),
|
|
111
|
-
# which on termux/aarch64 has no wheels and on regular installs sends pip's
|
|
112
|
-
# resolver into a backtracking loop trying to reconcile typing-extensions /
|
|
113
|
-
# pydantic / httpx ranges. Keeping it optional lets `pip install dulus` succeed
|
|
114
|
-
# in seconds everywhere; power users opt in with `pip install dulus[memory]`
|
|
115
|
-
# (or `dulus[full]`) when they want MemPalace per-turn injection.
|
|
116
|
-
[project.optional-dependencies]
|
|
117
|
-
dev = [
|
|
118
|
-
"build>=1.2",
|
|
119
|
-
"pyright>=1.1.400",
|
|
120
|
-
"pytest>=8.0",
|
|
121
|
-
"pytest-asyncio>=0.23",
|
|
122
|
-
"twine>=5.0",
|
|
123
|
-
]
|
|
124
|
-
memory = ["mempalace>=3.3.4"]
|
|
125
|
-
voice = ["sounddevice", "pyttsx3", "elevenlabs>=1.0.0"]
|
|
126
|
-
webbridge = ["playwright>=1.40.0"]
|
|
127
|
-
# LiteLLM unified gateway — one provider entry, 100+ backends (OpenRouter,
|
|
128
|
-
# Groq, Together, Bedrock, Vertex, Cohere, Perplexity, xAI, Mistral, …).
|
|
129
|
-
# Optional because it pulls a sizeable transitive dep tree (tokenizers,
|
|
130
|
-
# tiktoken, click, importlib-metadata, etc.) most users won't need until
|
|
131
|
-
# they pick litellm in the welcome wizard.
|
|
132
|
-
litellm = ["litellm>=1.50.0"]
|
|
133
|
-
# OCR — local text extraction from images, no vision model call. Cheaper
|
|
134
|
-
# than /img for receipts, code screenshots, error stacks, dense tables.
|
|
135
|
-
# pytesseract needs the Tesseract binary installed separately:
|
|
136
|
-
# Windows: winget install -e --id UB-Mannheim.TesseractOCR
|
|
137
|
-
# Linux: sudo apt-get install -y tesseract-ocr
|
|
138
|
-
# macOS: brew install tesseract
|
|
139
|
-
# easyocr is the pure-Python fallback but pulls ~1GB of PyTorch deps,
|
|
140
|
-
# so we leave it out of the default extra; opt in with `dulus[ocr-deep]`.
|
|
141
|
-
ocr = ["pytesseract>=0.3.10", "Pillow>=10.0.0"]
|
|
142
|
-
ocr-deep = ["pytesseract>=0.3.10", "Pillow>=10.0.0", "easyocr>=1.7.0"]
|
|
143
|
-
full = ["mempalace>=3.3.4", "sounddevice", "elevenlabs>=1.0.0", "playwright>=1.40.0", "litellm>=1.50.0", "pytesseract>=0.3.10"]
|
|
144
|
-
|
|
145
|
-
[project.scripts]
|
|
146
|
-
dulus = "dulus:main"
|
|
147
|
-
|
|
148
|
-
[project.urls]
|
|
149
|
-
Homepage = "https://github.com/KevRojo/Dulus"
|
|
150
|
-
Repository = "https://github.com/KevRojo/Dulus"
|
|
151
|
-
Documentation = "https://kevrojo.github.io/Dulus/"
|
|
152
|
-
Changelog = "https://github.com/KevRojo/Dulus/blob/main/docs/news.md"
|
|
153
|
-
Issues = "https://github.com/KevRojo/Dulus/issues"
|
|
154
|
-
|
|
155
|
-
# ── Build config ────────────────────────────────────────────────────────────
|
|
156
|
-
# Fast-path: ship every top-level .py as a module + every subpackage with
|
|
157
|
-
# its __init__.py. Cleaner restructure can come later.
|
|
158
|
-
[tool.setuptools]
|
|
159
|
-
py-modules = [
|
|
160
|
-
"agent",
|
|
161
|
-
"algolia_search",
|
|
162
|
-
"batch_api",
|
|
163
|
-
"clipboard_utils",
|
|
164
|
-
"cloudsave",
|
|
165
|
-
"analytics",
|
|
166
|
-
"common",
|
|
167
|
-
"compaction",
|
|
168
|
-
"config",
|
|
169
|
-
"context",
|
|
170
|
-
"display_blocks",
|
|
171
|
-
"dulus",
|
|
172
|
-
"dulus_bar_client",
|
|
173
|
-
"dulus_gui",
|
|
174
|
-
"dulus_quick_menu",
|
|
175
|
-
"file_filter",
|
|
176
|
-
"fs_compass",
|
|
177
|
-
"governance",
|
|
178
|
-
"input",
|
|
179
|
-
"license_manager",
|
|
180
|
-
"lookback",
|
|
181
|
-
"model_params",
|
|
182
|
-
"paste_placeholders",
|
|
183
|
-
"personality_config",
|
|
184
|
-
"profiles",
|
|
185
|
-
"providers",
|
|
186
|
-
"pyconsole",
|
|
187
|
-
"sandbox_bootstrap",
|
|
188
|
-
"skills",
|
|
189
|
-
"soul",
|
|
190
|
-
"spinner",
|
|
191
|
-
"steer_input",
|
|
192
|
-
"subagent",
|
|
193
|
-
"tmux_tools",
|
|
194
|
-
"tool_registry",
|
|
195
|
-
"tools",
|
|
196
|
-
"tools_background",
|
|
197
|
-
"tools_think",
|
|
198
|
-
"tools_todo",
|
|
199
|
-
"updater",
|
|
200
|
-
"webchat",
|
|
201
|
-
"webchat_server",
|
|
202
|
-
"welcome",
|
|
203
|
-
]
|
|
204
|
-
|
|
205
|
-
[tool.setuptools.packages.find]
|
|
206
|
-
where = ["."]
|
|
207
|
-
include = [
|
|
208
|
-
"backend*",
|
|
209
|
-
"banners*",
|
|
210
|
-
"checkpoint*",
|
|
211
|
-
"cli_animations*",
|
|
212
|
-
"data*",
|
|
213
|
-
"docs*",
|
|
214
|
-
"gui*",
|
|
215
|
-
"dulus_mcp*",
|
|
216
|
-
"dulus_tools*",
|
|
217
|
-
"memory*",
|
|
218
|
-
"multi_agent*",
|
|
219
|
-
"plugin*",
|
|
220
|
-
"skill*",
|
|
221
|
-
"task*",
|
|
222
|
-
"ui*",
|
|
223
|
-
"voice*",
|
|
224
|
-
"webbridge*",
|
|
225
|
-
"webchat_ui*",
|
|
226
|
-
# sandbox/dist/ ships in the wheel so webchat serves /sandbox/ directly
|
|
227
|
-
# (back to the 0.2.81 layout — no tarball, no extract-on-first-run).
|
|
228
|
-
# GitHub Linguist won't double-count: .gitattributes marks sandbox/**
|
|
229
|
-
# as linguist-vendored=true.
|
|
230
|
-
"sandbox*",
|
|
231
|
-
]
|
|
232
|
-
exclude = [
|
|
233
|
-
"tests*",
|
|
234
|
-
"__pycache__*",
|
|
235
|
-
# Don't ship sandbox sources / node_modules / vite cache — only dist/.
|
|
236
|
-
"sandbox.src*",
|
|
237
|
-
"sandbox.node_modules*",
|
|
238
|
-
"sandbox.public*",
|
|
239
|
-
]
|
|
240
|
-
|
|
241
|
-
[tool.setuptools.package-data]
|
|
242
|
-
"*" = ["*.html", "*.css", "*.js", "*.jsx", "*.ts", "*.tsx", "*.svg", "*.json", "*.md", "*.png", "*.jpg", "*.jpeg", "*.txt", "*.py"]
|
|
243
|
-
"sandbox" = ["dist/**/*", "dist/**/.*"]
|
|
244
|
-
# Bundled Agent Skills shipped with Dulus (kepano's obsidian-skills suite,
|
|
245
|
-
# etc.). Each lives at `skill/bundled/<name>/SKILL.md` with optional
|
|
246
|
-
# `references/*.md` files the skill body links to.
|
|
247
|
-
"skill" = ["bundled/**/*"]
|
|
1
|
+
# setuptools is pinned <77 on purpose: 77+ implements PEP 639 (SPDX license
|
|
2
|
+
# string + license-files) which emits Metadata-Version 2.4. pip < 24.1 — which
|
|
3
|
+
# ships on Ubuntu 24.04 LTS (pip 24.0) and many other current distros — cannot
|
|
4
|
+
# read Metadata 2.4 and silently skips the package, so `pip install dulus` fails
|
|
5
|
+
# with "Could not find a version that satisfies the requirement dulus (from
|
|
6
|
+
# versions: none)" on a fresh machine. Staying <77 keeps Metadata at 2.1/2.2.
|
|
7
|
+
[build-system]
|
|
8
|
+
requires = ["setuptools>=61,<77", "wheel"]
|
|
9
|
+
build-backend = "setuptools.build_meta"
|
|
10
|
+
|
|
11
|
+
[project]
|
|
12
|
+
name = "dulus"
|
|
13
|
+
version = "3.11.3"
|
|
14
|
+
description = "Provider-independent agent runtime for the terminal — cloud and local models, real tools, MCP, plugins, memory, sub-agents, and Dulus OS."
|
|
15
|
+
readme = "README.md"
|
|
16
|
+
requires-python = ">=3.10"
|
|
17
|
+
# Legacy table form (not the PEP 639 SPDX string) so setuptools emits the older
|
|
18
|
+
# `License:` metadata field and keeps Metadata-Version at 2.1/2.2 — see the
|
|
19
|
+
# build-system note above. LICENSE ships via MANIFEST.in.
|
|
20
|
+
license = {text = "GPL-3.0-only"}
|
|
21
|
+
authors = [{name = "KevRojo", email = "dev@dulus.ai"}]
|
|
22
|
+
maintainers = [{name = "KevRojo", email = "dev@dulus.ai"}]
|
|
23
|
+
keywords = [
|
|
24
|
+
# Providers and runtimes people actually search for.
|
|
25
|
+
"ai", "cli", "llm", "claude", "gemini", "nvidia", "openai",
|
|
26
|
+
"kimi", "deepseek", "qwen", "ollama", "local-llm", "openai-compatible",
|
|
27
|
+
# What this thing IS. Without these the package never surfaces for the
|
|
28
|
+
# queries its own users type.
|
|
29
|
+
"agent", "ai-agent", "coding-agent", "autonomous-agent", "agentic",
|
|
30
|
+
"mcp", "terminal", "tui", "repl", "developer-tools", "sub-agents",
|
|
31
|
+
"tts", "voice",
|
|
32
|
+
]
|
|
33
|
+
classifiers = [
|
|
34
|
+
# 19K+ installs, a full test suite and a 3.11.x line in production. This
|
|
35
|
+
# sat at "4 - Beta" long after that stopped being true, and the Beta badge
|
|
36
|
+
# is the first thing anyone reads on the PyPI page.
|
|
37
|
+
"Development Status :: 5 - Production/Stable",
|
|
38
|
+
# Dulus is not console-only: it ships a desktop GUI (pywebview), a Qt
|
|
39
|
+
# status bar, a Flask webchat and Dulus OS. Listing just Console hid every
|
|
40
|
+
# one of those surfaces.
|
|
41
|
+
"Environment :: Console",
|
|
42
|
+
"Environment :: Web Environment",
|
|
43
|
+
"Environment :: X11 Applications :: Qt",
|
|
44
|
+
"Environment :: Win32 (MS Windows)",
|
|
45
|
+
"Environment :: MacOS X",
|
|
46
|
+
# "Agentic AI for everyone" — the README's own pitch — is not a
|
|
47
|
+
# developers-only audience.
|
|
48
|
+
"Intended Audience :: Developers",
|
|
49
|
+
"Intended Audience :: End Users/Desktop",
|
|
50
|
+
"Intended Audience :: System Administrators",
|
|
51
|
+
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
|
52
|
+
"Natural Language :: English",
|
|
53
|
+
"Natural Language :: Spanish",
|
|
54
|
+
"Operating System :: OS Independent",
|
|
55
|
+
"Programming Language :: Python :: 3",
|
|
56
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
57
|
+
"Programming Language :: Python :: 3.10",
|
|
58
|
+
"Programming Language :: Python :: 3.11",
|
|
59
|
+
"Programming Language :: Python :: 3.12",
|
|
60
|
+
"Programming Language :: Python :: 3.13",
|
|
61
|
+
"Programming Language :: Python :: 3.14",
|
|
62
|
+
# Topics decide which PyPI category listings this appears in. AI + Terminals
|
|
63
|
+
# alone missed the shell, code-generation, chat and speech angles that
|
|
64
|
+
# describe just as much of what Dulus does.
|
|
65
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
66
|
+
"Topic :: Terminals",
|
|
67
|
+
"Topic :: Software Development :: Code Generators",
|
|
68
|
+
"Topic :: System :: Shells",
|
|
69
|
+
"Topic :: Communications :: Chat",
|
|
70
|
+
"Topic :: Multimedia :: Sound/Audio :: Speech",
|
|
71
|
+
"Topic :: Utilities",
|
|
72
|
+
]
|
|
73
|
+
dependencies = [
|
|
74
|
+
"anthropic>=0.40.0",
|
|
75
|
+
"openai>=1.30.0",
|
|
76
|
+
"httpx>=0.27.0",
|
|
77
|
+
"requests>=2.31.0",
|
|
78
|
+
'tomli>=2.0; python_version < "3.11"', # stdlib tomllib is 3.11+; backport for 3.10
|
|
79
|
+
"rich>=13.0.0",
|
|
80
|
+
"prompt_toolkit>=3.0.0",
|
|
81
|
+
"Flask>=3.1.3",
|
|
82
|
+
"bubblewrap-cli>=1.0.0",
|
|
83
|
+
"customtkinter>=5.2.0",
|
|
84
|
+
"Pillow>=10.0.0",
|
|
85
|
+
"typing-extensions>=4.10.0",
|
|
86
|
+
"pyttsx3",
|
|
87
|
+
# Composio Tool Router — bundled plugin needs this to talk to 1000+ apps
|
|
88
|
+
# without going through MCP. Only ~1MB on the wheel; worth it as a default.
|
|
89
|
+
"composio>=1.0.0rc2",
|
|
90
|
+
# HTML parsing — used by web scraping flows, harvest commands,
|
|
91
|
+
# and several plugins. Tiny dep; ship it by default.
|
|
92
|
+
"beautifulsoup4>=4.12.0",
|
|
93
|
+
"sentry-sdk>=2.0.0",
|
|
94
|
+
# OS trust store — fixes CERTIFICATE_VERIFY_FAILED behind corporate TLS
|
|
95
|
+
# interceptors (Cloudflare Zero Trust/WARP, Zscaler, Netskope). Tiny dep.
|
|
96
|
+
"truststore>=0.9",
|
|
97
|
+
# OCR — local text extraction from images/screenshots. pytesseract is
|
|
98
|
+
# lightweight; Tesseract binary must be installed separately (see README).
|
|
99
|
+
# Pillow already listed above — no duplicate needed.
|
|
100
|
+
"pytesseract>=0.3.10",
|
|
101
|
+
# Dulus Bar — the floating "Dynamic Island" (live model/ctx + Allow/Deny).
|
|
102
|
+
# A normal library dep: pip pulls it (and its PyQt6) at install time; the
|
|
103
|
+
# dulus wheel stays tiny — nothing is bundled. On by default so Dulus opens
|
|
104
|
+
# with the island out of the box; a silent no-op on headless/no-display
|
|
105
|
+
# boxes (Docker, servers, CI) since it never imports Qt without a screen.
|
|
106
|
+
# Off switch for anyone who dislikes it: DULUS_BAR=0 or /config dulus_bar=0.
|
|
107
|
+
"dulus-bar>=0.3.7",
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
# mempalace pulls chromadb (26 transitive deps incl. numpy + onnxruntime),
|
|
111
|
+
# which on termux/aarch64 has no wheels and on regular installs sends pip's
|
|
112
|
+
# resolver into a backtracking loop trying to reconcile typing-extensions /
|
|
113
|
+
# pydantic / httpx ranges. Keeping it optional lets `pip install dulus` succeed
|
|
114
|
+
# in seconds everywhere; power users opt in with `pip install dulus[memory]`
|
|
115
|
+
# (or `dulus[full]`) when they want MemPalace per-turn injection.
|
|
116
|
+
[project.optional-dependencies]
|
|
117
|
+
dev = [
|
|
118
|
+
"build>=1.2",
|
|
119
|
+
"pyright>=1.1.400",
|
|
120
|
+
"pytest>=8.0",
|
|
121
|
+
"pytest-asyncio>=0.23",
|
|
122
|
+
"twine>=5.0",
|
|
123
|
+
]
|
|
124
|
+
memory = ["mempalace>=3.3.4"]
|
|
125
|
+
voice = ["sounddevice", "pyttsx3", "elevenlabs>=1.0.0"]
|
|
126
|
+
webbridge = ["playwright>=1.40.0"]
|
|
127
|
+
# LiteLLM unified gateway — one provider entry, 100+ backends (OpenRouter,
|
|
128
|
+
# Groq, Together, Bedrock, Vertex, Cohere, Perplexity, xAI, Mistral, …).
|
|
129
|
+
# Optional because it pulls a sizeable transitive dep tree (tokenizers,
|
|
130
|
+
# tiktoken, click, importlib-metadata, etc.) most users won't need until
|
|
131
|
+
# they pick litellm in the welcome wizard.
|
|
132
|
+
litellm = ["litellm>=1.50.0"]
|
|
133
|
+
# OCR — local text extraction from images, no vision model call. Cheaper
|
|
134
|
+
# than /img for receipts, code screenshots, error stacks, dense tables.
|
|
135
|
+
# pytesseract needs the Tesseract binary installed separately:
|
|
136
|
+
# Windows: winget install -e --id UB-Mannheim.TesseractOCR
|
|
137
|
+
# Linux: sudo apt-get install -y tesseract-ocr
|
|
138
|
+
# macOS: brew install tesseract
|
|
139
|
+
# easyocr is the pure-Python fallback but pulls ~1GB of PyTorch deps,
|
|
140
|
+
# so we leave it out of the default extra; opt in with `dulus[ocr-deep]`.
|
|
141
|
+
ocr = ["pytesseract>=0.3.10", "Pillow>=10.0.0"]
|
|
142
|
+
ocr-deep = ["pytesseract>=0.3.10", "Pillow>=10.0.0", "easyocr>=1.7.0"]
|
|
143
|
+
full = ["mempalace>=3.3.4", "sounddevice", "elevenlabs>=1.0.0", "playwright>=1.40.0", "litellm>=1.50.0", "pytesseract>=0.3.10"]
|
|
144
|
+
|
|
145
|
+
[project.scripts]
|
|
146
|
+
dulus = "dulus:main"
|
|
147
|
+
|
|
148
|
+
[project.urls]
|
|
149
|
+
Homepage = "https://github.com/KevRojo/Dulus"
|
|
150
|
+
Repository = "https://github.com/KevRojo/Dulus"
|
|
151
|
+
Documentation = "https://kevrojo.github.io/Dulus/"
|
|
152
|
+
Changelog = "https://github.com/KevRojo/Dulus/blob/main/docs/news.md"
|
|
153
|
+
Issues = "https://github.com/KevRojo/Dulus/issues"
|
|
154
|
+
|
|
155
|
+
# ── Build config ────────────────────────────────────────────────────────────
|
|
156
|
+
# Fast-path: ship every top-level .py as a module + every subpackage with
|
|
157
|
+
# its __init__.py. Cleaner restructure can come later.
|
|
158
|
+
[tool.setuptools]
|
|
159
|
+
py-modules = [
|
|
160
|
+
"agent",
|
|
161
|
+
"algolia_search",
|
|
162
|
+
"batch_api",
|
|
163
|
+
"clipboard_utils",
|
|
164
|
+
"cloudsave",
|
|
165
|
+
"analytics",
|
|
166
|
+
"common",
|
|
167
|
+
"compaction",
|
|
168
|
+
"config",
|
|
169
|
+
"context",
|
|
170
|
+
"display_blocks",
|
|
171
|
+
"dulus",
|
|
172
|
+
"dulus_bar_client",
|
|
173
|
+
"dulus_gui",
|
|
174
|
+
"dulus_quick_menu",
|
|
175
|
+
"file_filter",
|
|
176
|
+
"fs_compass",
|
|
177
|
+
"governance",
|
|
178
|
+
"input",
|
|
179
|
+
"license_manager",
|
|
180
|
+
"lookback",
|
|
181
|
+
"model_params",
|
|
182
|
+
"paste_placeholders",
|
|
183
|
+
"personality_config",
|
|
184
|
+
"profiles",
|
|
185
|
+
"providers",
|
|
186
|
+
"pyconsole",
|
|
187
|
+
"sandbox_bootstrap",
|
|
188
|
+
"skills",
|
|
189
|
+
"soul",
|
|
190
|
+
"spinner",
|
|
191
|
+
"steer_input",
|
|
192
|
+
"subagent",
|
|
193
|
+
"tmux_tools",
|
|
194
|
+
"tool_registry",
|
|
195
|
+
"tools",
|
|
196
|
+
"tools_background",
|
|
197
|
+
"tools_think",
|
|
198
|
+
"tools_todo",
|
|
199
|
+
"updater",
|
|
200
|
+
"webchat",
|
|
201
|
+
"webchat_server",
|
|
202
|
+
"welcome",
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
[tool.setuptools.packages.find]
|
|
206
|
+
where = ["."]
|
|
207
|
+
include = [
|
|
208
|
+
"backend*",
|
|
209
|
+
"banners*",
|
|
210
|
+
"checkpoint*",
|
|
211
|
+
"cli_animations*",
|
|
212
|
+
"data*",
|
|
213
|
+
"docs*",
|
|
214
|
+
"gui*",
|
|
215
|
+
"dulus_mcp*",
|
|
216
|
+
"dulus_tools*",
|
|
217
|
+
"memory*",
|
|
218
|
+
"multi_agent*",
|
|
219
|
+
"plugin*",
|
|
220
|
+
"skill*",
|
|
221
|
+
"task*",
|
|
222
|
+
"ui*",
|
|
223
|
+
"voice*",
|
|
224
|
+
"webbridge*",
|
|
225
|
+
"webchat_ui*",
|
|
226
|
+
# sandbox/dist/ ships in the wheel so webchat serves /sandbox/ directly
|
|
227
|
+
# (back to the 0.2.81 layout — no tarball, no extract-on-first-run).
|
|
228
|
+
# GitHub Linguist won't double-count: .gitattributes marks sandbox/**
|
|
229
|
+
# as linguist-vendored=true.
|
|
230
|
+
"sandbox*",
|
|
231
|
+
]
|
|
232
|
+
exclude = [
|
|
233
|
+
"tests*",
|
|
234
|
+
"__pycache__*",
|
|
235
|
+
# Don't ship sandbox sources / node_modules / vite cache — only dist/.
|
|
236
|
+
"sandbox.src*",
|
|
237
|
+
"sandbox.node_modules*",
|
|
238
|
+
"sandbox.public*",
|
|
239
|
+
]
|
|
240
|
+
|
|
241
|
+
[tool.setuptools.package-data]
|
|
242
|
+
"*" = ["*.html", "*.css", "*.js", "*.jsx", "*.ts", "*.tsx", "*.svg", "*.json", "*.md", "*.png", "*.jpg", "*.jpeg", "*.txt", "*.py"]
|
|
243
|
+
"sandbox" = ["dist/**/*", "dist/**/.*"]
|
|
244
|
+
# Bundled Agent Skills shipped with Dulus (kepano's obsidian-skills suite,
|
|
245
|
+
# etc.). Each lives at `skill/bundled/<name>/SKILL.md` with optional
|
|
246
|
+
# `references/*.md` files the skill body links to.
|
|
247
|
+
"skill" = ["bundled/**/*"]
|