dulus 0.2.37__tar.gz → 0.2.38__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. {dulus-0.2.37/dulus.egg-info → dulus-0.2.38}/PKG-INFO +1 -1
  2. {dulus-0.2.37 → dulus-0.2.38/dulus.egg-info}/PKG-INFO +1 -1
  3. {dulus-0.2.37 → dulus-0.2.38}/dulus.py +14 -5
  4. {dulus-0.2.37 → dulus-0.2.38}/pyproject.toml +1 -1
  5. {dulus-0.2.37 → dulus-0.2.38}/LICENSE +0 -0
  6. {dulus-0.2.37 → dulus-0.2.38}/MANIFEST.in +0 -0
  7. {dulus-0.2.37 → dulus-0.2.38}/README.md +0 -0
  8. {dulus-0.2.37 → dulus-0.2.38}/agent.py +0 -0
  9. {dulus-0.2.37 → dulus-0.2.38}/backend/__init__.py +0 -0
  10. {dulus-0.2.37 → dulus-0.2.38}/backend/compressor.py +0 -0
  11. {dulus-0.2.37 → dulus-0.2.38}/backend/context.py +0 -0
  12. {dulus-0.2.37 → dulus-0.2.38}/backend/githook.py +0 -0
  13. {dulus-0.2.37 → dulus-0.2.38}/backend/marketplace.py +0 -0
  14. {dulus-0.2.37 → dulus-0.2.38}/backend/mempalace_bridge.py +0 -0
  15. {dulus-0.2.37 → dulus-0.2.38}/backend/personas.py +0 -0
  16. {dulus-0.2.37 → dulus-0.2.38}/backend/plugins.py +0 -0
  17. {dulus-0.2.37 → dulus-0.2.38}/backend/server.py +0 -0
  18. {dulus-0.2.37 → dulus-0.2.38}/backend/tasks.py +0 -0
  19. {dulus-0.2.37 → dulus-0.2.38}/batch_api.py +0 -0
  20. {dulus-0.2.37 → dulus-0.2.38}/checkpoint/__init__.py +0 -0
  21. {dulus-0.2.37 → dulus-0.2.38}/checkpoint/hooks.py +0 -0
  22. {dulus-0.2.37 → dulus-0.2.38}/checkpoint/store.py +0 -0
  23. {dulus-0.2.37 → dulus-0.2.38}/checkpoint/types.py +0 -0
  24. {dulus-0.2.37 → dulus-0.2.38}/claude_code_watcher.py +0 -0
  25. {dulus-0.2.37 → dulus-0.2.38}/clipboard_utils.py +0 -0
  26. {dulus-0.2.37 → dulus-0.2.38}/cloudsave.py +0 -0
  27. {dulus-0.2.37 → dulus-0.2.38}/common.py +0 -0
  28. {dulus-0.2.37 → dulus-0.2.38}/compaction.py +0 -0
  29. {dulus-0.2.37 → dulus-0.2.38}/config.py +0 -0
  30. {dulus-0.2.37 → dulus-0.2.38}/context.py +0 -0
  31. {dulus-0.2.37 → dulus-0.2.38}/data/__init__.py +0 -0
  32. {dulus-0.2.37 → dulus-0.2.38}/data/active_persona.json +0 -0
  33. {dulus-0.2.37 → dulus-0.2.38}/data/context.json +0 -0
  34. {dulus-0.2.37 → dulus-0.2.38}/data/marketplace.json +0 -0
  35. {dulus-0.2.37 → dulus-0.2.38}/data/personas.json +0 -0
  36. {dulus-0.2.37 → dulus-0.2.38}/data/plugins/__init__.py +0 -0
  37. {dulus-0.2.37 → dulus-0.2.38}/data/plugins/composio/__init__.py +0 -0
  38. {dulus-0.2.37 → dulus-0.2.38}/data/plugins/composio/composio_plugin/__init__.py +0 -0
  39. {dulus-0.2.37 → dulus-0.2.38}/data/plugins/composio/composio_plugin/session_manager.py +0 -0
  40. {dulus-0.2.37 → dulus-0.2.38}/data/plugins/composio/composio_plugin/tool_generator.py +0 -0
  41. {dulus-0.2.37 → dulus-0.2.38}/data/plugins/composio/plugin.json +0 -0
  42. {dulus-0.2.37 → dulus-0.2.38}/data/plugins/composio/plugin_tool.py +0 -0
  43. {dulus-0.2.37 → dulus-0.2.38}/data/tasks.json +0 -0
  44. {dulus-0.2.37 → dulus-0.2.38}/docs/README.md +0 -0
  45. {dulus-0.2.37 → dulus-0.2.38}/docs/__init__.py +0 -0
  46. {dulus-0.2.37 → dulus-0.2.38}/docs/api.html +0 -0
  47. {dulus-0.2.37 → dulus-0.2.38}/docs/architecture.md +0 -0
  48. {dulus-0.2.37 → dulus-0.2.38}/docs/azure-speech-template.json +0 -0
  49. {dulus-0.2.37 → dulus-0.2.38}/docs/dashboard/index.html +0 -0
  50. {dulus-0.2.37 → dulus-0.2.38}/docs/divider.svg +0 -0
  51. {dulus-0.2.37 → dulus-0.2.38}/docs/generate.py +0 -0
  52. {dulus-0.2.37 → dulus-0.2.38}/docs/hero.svg +0 -0
  53. {dulus-0.2.37 → dulus-0.2.38}/docs/index.html +0 -0
  54. {dulus-0.2.37 → dulus-0.2.38}/docs/news.md +0 -0
  55. {dulus-0.2.37 → dulus-0.2.38}/docs/nvidia-models.svg +0 -0
  56. {dulus-0.2.37 → dulus-0.2.38}/docs/particle-playground.html +0 -0
  57. {dulus-0.2.37 → dulus-0.2.38}/docs/personas/index.html +0 -0
  58. {dulus-0.2.37 → dulus-0.2.38}/docs/poetry-banner.png +0 -0
  59. {dulus-0.2.37 → dulus-0.2.38}/docs/preview.html +0 -0
  60. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-agents.svg +0 -0
  61. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-brainstorm.svg +0 -0
  62. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-bridges.svg +0 -0
  63. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-features.svg +0 -0
  64. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-freetier.svg +0 -0
  65. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-memory.svg +0 -0
  66. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-models.svg +0 -0
  67. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-perms.svg +0 -0
  68. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-plugins.svg +0 -0
  69. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-quickstart.svg +0 -0
  70. {dulus-0.2.37 → dulus-0.2.38}/docs/sec-ssj.svg +0 -0
  71. {dulus-0.2.37 → dulus-0.2.38}/docs/spinners.svg +0 -0
  72. {dulus-0.2.37 → dulus-0.2.38}/docs/split-pane.svg +0 -0
  73. {dulus-0.2.37 → dulus-0.2.38}/docs/terminal-boot.svg +0 -0
  74. {dulus-0.2.37 → dulus-0.2.38}/docs/uploads/particle-playground.html +0 -0
  75. {dulus-0.2.37 → dulus-0.2.38}/dulus.egg-info/SOURCES.txt +0 -0
  76. {dulus-0.2.37 → dulus-0.2.38}/dulus.egg-info/dependency_links.txt +0 -0
  77. {dulus-0.2.37 → dulus-0.2.38}/dulus.egg-info/entry_points.txt +0 -0
  78. {dulus-0.2.37 → dulus-0.2.38}/dulus.egg-info/requires.txt +0 -0
  79. {dulus-0.2.37 → dulus-0.2.38}/dulus.egg-info/top_level.txt +0 -0
  80. {dulus-0.2.37 → dulus-0.2.38}/dulus_gui.py +0 -0
  81. {dulus-0.2.37 → dulus-0.2.38}/dulus_mcp/__init__.py +0 -0
  82. {dulus-0.2.37 → dulus-0.2.38}/dulus_mcp/client.py +0 -0
  83. {dulus-0.2.37 → dulus-0.2.38}/dulus_mcp/config.py +0 -0
  84. {dulus-0.2.37 → dulus-0.2.38}/dulus_mcp/tools.py +0 -0
  85. {dulus-0.2.37 → dulus-0.2.38}/dulus_mcp/types.py +0 -0
  86. {dulus-0.2.37 → dulus-0.2.38}/gui/__init__.py +0 -0
  87. {dulus-0.2.37 → dulus-0.2.38}/gui/agent_bridge.py +0 -0
  88. {dulus-0.2.37 → dulus-0.2.38}/gui/chat_widget.py +0 -0
  89. {dulus-0.2.37 → dulus-0.2.38}/gui/main_window.py +0 -0
  90. {dulus-0.2.37 → dulus-0.2.38}/gui/personas.py +0 -0
  91. {dulus-0.2.37 → dulus-0.2.38}/gui/session_utils.py +0 -0
  92. {dulus-0.2.37 → dulus-0.2.38}/gui/settings_dialog.py +0 -0
  93. {dulus-0.2.37 → dulus-0.2.38}/gui/sidebar.py +0 -0
  94. {dulus-0.2.37 → dulus-0.2.38}/gui/tasks_view.py +0 -0
  95. {dulus-0.2.37 → dulus-0.2.38}/gui/themes.py +0 -0
  96. {dulus-0.2.37 → dulus-0.2.38}/gui/tool_panel.py +0 -0
  97. {dulus-0.2.37 → dulus-0.2.38}/input.py +0 -0
  98. {dulus-0.2.37 → dulus-0.2.38}/license_manager.py +0 -0
  99. {dulus-0.2.37 → dulus-0.2.38}/memory/__init__.py +0 -0
  100. {dulus-0.2.37 → dulus-0.2.38}/memory/audit.py +0 -0
  101. {dulus-0.2.37 → dulus-0.2.38}/memory/consolidator.py +0 -0
  102. {dulus-0.2.37 → dulus-0.2.38}/memory/context.py +0 -0
  103. {dulus-0.2.37 → dulus-0.2.38}/memory/offload.py +0 -0
  104. {dulus-0.2.37 → dulus-0.2.38}/memory/palace.py +0 -0
  105. {dulus-0.2.37 → dulus-0.2.38}/memory/scan.py +0 -0
  106. {dulus-0.2.37 → dulus-0.2.38}/memory/sessions.py +0 -0
  107. {dulus-0.2.37 → dulus-0.2.38}/memory/store.py +0 -0
  108. {dulus-0.2.37 → dulus-0.2.38}/memory/tools.py +0 -0
  109. {dulus-0.2.37 → dulus-0.2.38}/memory/types.py +0 -0
  110. {dulus-0.2.37 → dulus-0.2.38}/memory/vector_search.py +0 -0
  111. {dulus-0.2.37 → dulus-0.2.38}/multi_agent/__init__.py +0 -0
  112. {dulus-0.2.37 → dulus-0.2.38}/multi_agent/subagent.py +0 -0
  113. {dulus-0.2.37 → dulus-0.2.38}/multi_agent/tools.py +0 -0
  114. {dulus-0.2.37 → dulus-0.2.38}/offload_helper.py +0 -0
  115. {dulus-0.2.37 → dulus-0.2.38}/plugin/__init__.py +0 -0
  116. {dulus-0.2.37 → dulus-0.2.38}/plugin/autoadapter.py +0 -0
  117. {dulus-0.2.37 → dulus-0.2.38}/plugin/loader.py +0 -0
  118. {dulus-0.2.37 → dulus-0.2.38}/plugin/recommend.py +0 -0
  119. {dulus-0.2.37 → dulus-0.2.38}/plugin/store.py +0 -0
  120. {dulus-0.2.37 → dulus-0.2.38}/plugin/types.py +0 -0
  121. {dulus-0.2.37 → dulus-0.2.38}/providers.py +0 -0
  122. {dulus-0.2.37 → dulus-0.2.38}/setup.cfg +0 -0
  123. {dulus-0.2.37 → dulus-0.2.38}/skill/__init__.py +0 -0
  124. {dulus-0.2.37 → dulus-0.2.38}/skill/builtin.py +0 -0
  125. {dulus-0.2.37 → dulus-0.2.38}/skill/clawhub.py +0 -0
  126. {dulus-0.2.37 → dulus-0.2.38}/skill/executor.py +0 -0
  127. {dulus-0.2.37 → dulus-0.2.38}/skill/loader.py +0 -0
  128. {dulus-0.2.37 → dulus-0.2.38}/skill/tools.py +0 -0
  129. {dulus-0.2.37 → dulus-0.2.38}/skills.py +0 -0
  130. {dulus-0.2.37 → dulus-0.2.38}/spinner.py +0 -0
  131. {dulus-0.2.37 → dulus-0.2.38}/string_utils.py +0 -0
  132. {dulus-0.2.37 → dulus-0.2.38}/subagent.py +0 -0
  133. {dulus-0.2.37 → dulus-0.2.38}/task/__init__.py +0 -0
  134. {dulus-0.2.37 → dulus-0.2.38}/task/store.py +0 -0
  135. {dulus-0.2.37 → dulus-0.2.38}/task/tools.py +0 -0
  136. {dulus-0.2.37 → dulus-0.2.38}/task/types.py +0 -0
  137. {dulus-0.2.37 → dulus-0.2.38}/tests/test_checkpoint.py +0 -0
  138. {dulus-0.2.37 → dulus-0.2.38}/tests/test_compaction.py +0 -0
  139. {dulus-0.2.37 → dulus-0.2.38}/tests/test_diff_view.py +0 -0
  140. {dulus-0.2.37 → dulus-0.2.38}/tests/test_injection_fix.py +0 -0
  141. {dulus-0.2.37 → dulus-0.2.38}/tests/test_license.py +0 -0
  142. {dulus-0.2.37 → dulus-0.2.38}/tests/test_mcp.py +0 -0
  143. {dulus-0.2.37 → dulus-0.2.38}/tests/test_memory.py +0 -0
  144. {dulus-0.2.37 → dulus-0.2.38}/tests/test_plugin.py +0 -0
  145. {dulus-0.2.37 → dulus-0.2.38}/tests/test_skills.py +0 -0
  146. {dulus-0.2.37 → dulus-0.2.38}/tests/test_subagent.py +0 -0
  147. {dulus-0.2.37 → dulus-0.2.38}/tests/test_task.py +0 -0
  148. {dulus-0.2.37 → dulus-0.2.38}/tests/test_telegram_buffer.py +0 -0
  149. {dulus-0.2.37 → dulus-0.2.38}/tests/test_tool_registry.py +0 -0
  150. {dulus-0.2.37 → dulus-0.2.38}/tests/test_voice.py +0 -0
  151. {dulus-0.2.37 → dulus-0.2.38}/tmux_offloader.py +0 -0
  152. {dulus-0.2.37 → dulus-0.2.38}/tmux_tools.py +0 -0
  153. {dulus-0.2.37 → dulus-0.2.38}/tool_registry.py +0 -0
  154. {dulus-0.2.37 → dulus-0.2.38}/tools.py +0 -0
  155. {dulus-0.2.37 → dulus-0.2.38}/ui/__init__.py +0 -0
  156. {dulus-0.2.37 → dulus-0.2.38}/ui/input.py +0 -0
  157. {dulus-0.2.37 → dulus-0.2.38}/ui/render.py +0 -0
  158. {dulus-0.2.37 → dulus-0.2.38}/voice/__init__.py +0 -0
  159. {dulus-0.2.37 → dulus-0.2.38}/voice/keyterms.py +0 -0
  160. {dulus-0.2.37 → dulus-0.2.38}/voice/recorder.py +0 -0
  161. {dulus-0.2.37 → dulus-0.2.38}/voice/stt.py +0 -0
  162. {dulus-0.2.37 → dulus-0.2.38}/voice/tts.py +0 -0
  163. {dulus-0.2.37 → dulus-0.2.38}/webchat.py +0 -0
  164. {dulus-0.2.37 → dulus-0.2.38}/webchat_server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dulus
3
- Version: 0.2.37
3
+ Version: 0.2.38
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dulus
3
- Version: 0.2.37
3
+ Version: 0.2.38
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
@@ -1459,11 +1459,20 @@ def cmd_context(_args: str, state, config) -> bool:
1459
1459
 
1460
1460
  def cmd_cost(_args: str, state, config) -> bool:
1461
1461
  from config import calc_cost
1462
- cost = calc_cost(config["model"],
1463
- state.total_input_tokens,
1464
- state.total_output_tokens)
1465
- info(f"Input tokens: {state.total_input_tokens:,}")
1466
- info(f"Output tokens: {state.total_output_tokens:,}")
1462
+ from compaction import estimate_tokens
1463
+
1464
+ # The accumulated counters (total_input_tokens etc.) sum the provider's
1465
+ # reported "tokens in this request" which includes the ENTIRE context
1466
+ # window every turn. That creates a quadratic explosion and is useless
1467
+ # for cost estimation. Instead, estimate from the actual message list.
1468
+ est_input = estimate_tokens(state.messages, model=config.get("model", ""), config=config)
1469
+ # Output is trickier to estimate from history alone; use the accumulated
1470
+ # counter as a lower-bound fallback but cap it to something sane.
1471
+ est_output = min(state.total_output_tokens, est_input)
1472
+
1473
+ cost = calc_cost(config["model"], est_input, est_output)
1474
+ info(f"Input tokens: ~{est_input:,} (estimated from {len(state.messages)} messages)")
1475
+ info(f"Output tokens: ~{est_output:,}")
1467
1476
  c_read = getattr(state, "total_cache_read_tokens", 0)
1468
1477
  c_write = getattr(state, "total_cache_creation_tokens", 0)
1469
1478
  if c_read > 0 or c_write > 0:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dulus"
7
- version = "0.2.37"
7
+ version = "0.2.38"
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