dulus 0.2.7__tar.gz → 0.2.8__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-0.2.7/dulus.egg-info → dulus-0.2.8}/PKG-INFO +4 -4
- {dulus-0.2.7 → dulus-0.2.8}/README.md +3 -3
- {dulus-0.2.7 → dulus-0.2.8/dulus.egg-info}/PKG-INFO +4 -4
- {dulus-0.2.7 → dulus-0.2.8}/dulus.py +12 -5
- {dulus-0.2.7 → dulus-0.2.8}/memory/context.py +0 -2
- {dulus-0.2.7 → dulus-0.2.8}/memory/offload.py +4 -2
- {dulus-0.2.7 → dulus-0.2.8}/pyproject.toml +1 -1
- {dulus-0.2.7 → dulus-0.2.8}/LICENSE +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/MANIFEST.in +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/agent.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/compressor.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/context.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/githook.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/marketplace.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/mempalace_bridge.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/personas.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/plugins.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/server.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/backend/tasks.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/batch_api.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/checkpoint/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/checkpoint/hooks.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/checkpoint/store.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/checkpoint/types.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/claude_code_watcher.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/clipboard_utils.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/cloudsave.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/common.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/compaction.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/config.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/context.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/data/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/data/active_persona.json +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/data/context.json +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/data/marketplace.json +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/data/personas.json +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/data/tasks.json +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/README.md +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/api.html +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/architecture.md +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/azure-speech-template.json +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/dashboard/index.html +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/divider.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/generate.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/hero.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/index.html +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/news.md +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/nvidia-models.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/particle-playground.html +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/personas/index.html +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/preview.html +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-agents.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-brainstorm.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-bridges.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-features.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-freetier.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-memory.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-models.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-perms.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-plugins.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-quickstart.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/sec-ssj.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/spinners.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/split-pane.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/terminal-boot.svg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/docs/uploads/particle-playground.html +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus.egg-info/SOURCES.txt +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus.egg-info/dependency_links.txt +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus.egg-info/entry_points.txt +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus.egg-info/requires.txt +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus.egg-info/top_level.txt +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus_gui.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus_mcp/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus_mcp/client.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus_mcp/config.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus_mcp/tools.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/dulus_mcp/types.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/agent_bridge.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/chat_widget.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/main_window.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/personas.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/session_utils.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/settings_dialog.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/sidebar.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/tasks_view.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/themes.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/gui/tool_panel.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/input.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/license_manager.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/audit.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/consolidator.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/palace.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/scan.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/sessions.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/store.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/tools.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/types.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/memory/vector_search.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/multi_agent/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/multi_agent/subagent.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/multi_agent/tools.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/offload_helper.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/plugin/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/plugin/autoadapter.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/plugin/loader.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/plugin/recommend.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/plugin/store.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/plugin/types.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/providers.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/setup.cfg +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/skill/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/skill/builtin.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/skill/clawhub.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/skill/executor.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/skill/loader.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/skill/tools.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/skills.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/spinner.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/string_utils.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/subagent.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/task/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/task/store.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/task/tools.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/task/types.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_checkpoint.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_compaction.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_diff_view.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_injection_fix.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_license.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_mcp.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_memory.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_plugin.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_skills.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_subagent.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_task.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_telegram_buffer.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_tool_registry.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tests/test_voice.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tmux_offloader.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tmux_tools.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tool_registry.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/tools.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/ui/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/ui/input.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/ui/render.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/voice/__init__.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/voice/keyterms.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/voice/recorder.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/voice/stt.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/voice/tts.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/webchat.py +0 -0
- {dulus-0.2.7 → dulus-0.2.8}/webchat_server.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dulus
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Spanish-first multi-provider AI CLI — 14 NVIDIA models free, Mesa Redonda, voice, TTS, RTK token reducer, MemPalace
|
|
5
5
|
Author: KevRojo
|
|
6
6
|
License: GPL-3.0
|
|
@@ -84,7 +84,7 @@ SET /sticky_input ON since the first run for the best experience!
|
|
|
84
84
|
|
|
85
85
|
Dulus is a **lightweight Python reimplementation of Claude Code** that isn't locked to Claude. It ships the whole loop — REPL, tool dispatch, streaming, context compaction, checkpoints, sub-agents, voice, Telegram bridge, MCP, plugins — in roughly **12K lines you can actually read**. Fork it. Bend it. Run it offline against Qwen on your M2.
|
|
86
86
|
|
|
87
|
-
> **
|
|
87
|
+
> **v0.2.8 — May 8, 2026** — MemPalace injection: removed confidence-bias ranker, added relevance threshold + elastic char budget, fixed comma-trip on trivial filter. Job offload no longer leaks parent config (API keys, tokens) to `~/.dulus/jobs/*.json`.
|
|
88
88
|
> Type `/news` to see what changed.
|
|
89
89
|
|
|
90
90
|
---
|
|
@@ -113,14 +113,14 @@ ROUND TABLE (DULUS UNIQUE FEATURE)
|
|
|
113
113
|
|
|
114
114
|
<img alt="image" src="https://github.com/user-attachments/assets/9e8f17ed-6ca2-4ae0-b8c3-146ae5fef491" />
|
|
115
115
|
|
|
116
|
-
Dulus is the first one meeting
|
|
116
|
+
Dulus is the first one meeting multiple models at the same time working for the same objective and sharing their ideas.
|
|
117
117
|
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
### One-liner
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
pip install dulus
|
|
123
|
+
pip install dulus && dulus
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
That's it. Dulus prompts you for a key on first run.
|
|
@@ -45,7 +45,7 @@ SET /sticky_input ON since the first run for the best experience!
|
|
|
45
45
|
|
|
46
46
|
Dulus is a **lightweight Python reimplementation of Claude Code** that isn't locked to Claude. It ships the whole loop — REPL, tool dispatch, streaming, context compaction, checkpoints, sub-agents, voice, Telegram bridge, MCP, plugins — in roughly **12K lines you can actually read**. Fork it. Bend it. Run it offline against Qwen on your M2.
|
|
47
47
|
|
|
48
|
-
> **
|
|
48
|
+
> **v0.2.8 — May 8, 2026** — MemPalace injection: removed confidence-bias ranker, added relevance threshold + elastic char budget, fixed comma-trip on trivial filter. Job offload no longer leaks parent config (API keys, tokens) to `~/.dulus/jobs/*.json`.
|
|
49
49
|
> Type `/news` to see what changed.
|
|
50
50
|
|
|
51
51
|
---
|
|
@@ -74,14 +74,14 @@ ROUND TABLE (DULUS UNIQUE FEATURE)
|
|
|
74
74
|
|
|
75
75
|
<img alt="image" src="https://github.com/user-attachments/assets/9e8f17ed-6ca2-4ae0-b8c3-146ae5fef491" />
|
|
76
76
|
|
|
77
|
-
Dulus is the first one meeting
|
|
77
|
+
Dulus is the first one meeting multiple models at the same time working for the same objective and sharing their ideas.
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
### One-liner
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
|
-
pip install dulus
|
|
84
|
+
pip install dulus && dulus
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
That's it. Dulus prompts you for a key on first run.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dulus
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Spanish-first multi-provider AI CLI — 14 NVIDIA models free, Mesa Redonda, voice, TTS, RTK token reducer, MemPalace
|
|
5
5
|
Author: KevRojo
|
|
6
6
|
License: GPL-3.0
|
|
@@ -84,7 +84,7 @@ SET /sticky_input ON since the first run for the best experience!
|
|
|
84
84
|
|
|
85
85
|
Dulus is a **lightweight Python reimplementation of Claude Code** that isn't locked to Claude. It ships the whole loop — REPL, tool dispatch, streaming, context compaction, checkpoints, sub-agents, voice, Telegram bridge, MCP, plugins — in roughly **12K lines you can actually read**. Fork it. Bend it. Run it offline against Qwen on your M2.
|
|
86
86
|
|
|
87
|
-
> **
|
|
87
|
+
> **v0.2.8 — May 8, 2026** — MemPalace injection: removed confidence-bias ranker, added relevance threshold + elastic char budget, fixed comma-trip on trivial filter. Job offload no longer leaks parent config (API keys, tokens) to `~/.dulus/jobs/*.json`.
|
|
88
88
|
> Type `/news` to see what changed.
|
|
89
89
|
|
|
90
90
|
---
|
|
@@ -113,14 +113,14 @@ ROUND TABLE (DULUS UNIQUE FEATURE)
|
|
|
113
113
|
|
|
114
114
|
<img alt="image" src="https://github.com/user-attachments/assets/9e8f17ed-6ca2-4ae0-b8c3-146ae5fef491" />
|
|
115
115
|
|
|
116
|
-
Dulus is the first one meeting
|
|
116
|
+
Dulus is the first one meeting multiple models at the same time working for the same objective and sharing their ideas.
|
|
117
117
|
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
### One-liner
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
pip install dulus
|
|
123
|
+
pip install dulus && dulus
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
That's it. Dulus prompts you for a key on first run.
|
|
@@ -7041,7 +7041,7 @@ def repl(config: dict, initial_prompt: str = None):
|
|
|
7041
7041
|
else:
|
|
7042
7042
|
_trivial = {"hola", "klk", "gracias", "ok", "si", "no", "dale",
|
|
7043
7043
|
"exit", "quit", "help", "thanks", "bien"}
|
|
7044
|
-
_first = user_input.strip().lower().split()[0]
|
|
7044
|
+
_first = user_input.strip().lower().split()[0].strip(".,!?;:")
|
|
7045
7045
|
if _first in _trivial:
|
|
7046
7046
|
_mp_log(f"skip: trivial first word '{_first}'", "dim")
|
|
7047
7047
|
else:
|
|
@@ -7051,15 +7051,22 @@ def repl(config: dict, initial_prompt: str = None):
|
|
|
7051
7051
|
_q = user_input.strip()[:200]
|
|
7052
7052
|
_mp_log(f"querying: {_q!r}")
|
|
7053
7053
|
_raw_hits = find_relevant_memories(_q, max_results=3)
|
|
7054
|
-
|
|
7055
|
-
|
|
7054
|
+
_MIN_SCORE = 0.15
|
|
7055
|
+
if _mp_dbg:
|
|
7056
|
+
for _h in _raw_hits:
|
|
7057
|
+
_mp_log(f" hit: score={float(_h.get('keyword_score', 0.0)):.3f} {_h.get('name','?')}", "dim")
|
|
7058
|
+
_kept = [h for h in _raw_hits if float(h.get("keyword_score", 0.0)) >= _MIN_SCORE]
|
|
7059
|
+
if not _kept:
|
|
7060
|
+
_mp_log(f"skip: no hits above threshold {_MIN_SCORE} (raw={len(_raw_hits)})", "dim")
|
|
7056
7061
|
else:
|
|
7062
|
+
_BODY_BUDGET = 1800
|
|
7063
|
+
_per_hit = max(300, _BODY_BUDGET // len(_kept))
|
|
7057
7064
|
_parts = []
|
|
7058
|
-
for _i, _h in enumerate(
|
|
7065
|
+
for _i, _h in enumerate(_kept, 1):
|
|
7059
7066
|
_name = _h.get("name", f"hit_{_i}")
|
|
7060
7067
|
_desc = _h.get("description", "")
|
|
7061
7068
|
_body = _h.get("content", "").strip()
|
|
7062
|
-
_snip = _body[:
|
|
7069
|
+
_snip = _body[:_per_hit] + ("..." if len(_body) > _per_hit else "")
|
|
7063
7070
|
if _desc:
|
|
7064
7071
|
_parts.append(f"### {_name}\n_{_desc}_\n{_snip}")
|
|
7065
7072
|
else:
|
|
@@ -156,8 +156,6 @@ def find_relevant_memories(
|
|
|
156
156
|
if ks == 0.0 and vs == 0.0:
|
|
157
157
|
continue
|
|
158
158
|
score = 0.55 * vs + 0.45 * ks
|
|
159
|
-
# Tiny confidence nudge so high-confidence memories break ties
|
|
160
|
-
score += 0.01 * float(getattr(entry, "confidence", 1.0))
|
|
161
159
|
entry._search_score = score # type: ignore[attr-defined]
|
|
162
160
|
fused.append((score, entry))
|
|
163
161
|
|
|
@@ -27,7 +27,10 @@ def _tmux_offload(params: dict, config: dict) -> str:
|
|
|
27
27
|
JOBS_DIR.mkdir(parents=True, exist_ok=True)
|
|
28
28
|
job_path = JOBS_DIR / f"{job_id}.json"
|
|
29
29
|
|
|
30
|
-
# Save initial job state
|
|
30
|
+
# Save initial job state.
|
|
31
|
+
# IMPORTANT: never persist the parent config here — the child process
|
|
32
|
+
# calls load_config() itself, and dumping the in-memory config leaks
|
|
33
|
+
# API keys, session tokens, telegram bots, etc. to ~/.dulus/jobs/*.json.
|
|
31
34
|
job_data = {
|
|
32
35
|
"id": job_id,
|
|
33
36
|
"tool_name": tool_name,
|
|
@@ -35,7 +38,6 @@ def _tmux_offload(params: dict, config: dict) -> str:
|
|
|
35
38
|
"status": "running",
|
|
36
39
|
"created_at": datetime.now().isoformat(),
|
|
37
40
|
"owner_pid": os.getpid(),
|
|
38
|
-
"config": {k: v for k, v in config.items() if not k.startswith("_")}
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
with open(job_path, "w", encoding="utf-8") as f:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dulus"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.8"
|
|
8
8
|
description = "Spanish-first multi-provider AI CLI — 14 NVIDIA models free, Mesa Redonda, voice, TTS, RTK token reducer, MemPalace"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|