velune-cli 1.0.0__py3-none-any.whl

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 (229) hide show
  1. velune/__init__.py +5 -0
  2. velune/__main__.py +6 -0
  3. velune/cli/__init__.py +5 -0
  4. velune/cli/app.py +212 -0
  5. velune/cli/autocomplete.py +76 -0
  6. velune/cli/banner.py +98 -0
  7. velune/cli/commands/__init__.py +32 -0
  8. velune/cli/commands/ask.py +149 -0
  9. velune/cli/commands/base.py +16 -0
  10. velune/cli/commands/chat.py +188 -0
  11. velune/cli/commands/config.py +182 -0
  12. velune/cli/commands/daemon.py +85 -0
  13. velune/cli/commands/doctor.py +373 -0
  14. velune/cli/commands/init.py +160 -0
  15. velune/cli/commands/mcp.py +80 -0
  16. velune/cli/commands/memory.py +269 -0
  17. velune/cli/commands/models.py +462 -0
  18. velune/cli/commands/preflight.py +95 -0
  19. velune/cli/commands/run.py +171 -0
  20. velune/cli/commands/setup.py +182 -0
  21. velune/cli/commands/workspace.py +217 -0
  22. velune/cli/context.py +37 -0
  23. velune/cli/councilmodel_ui.py +171 -0
  24. velune/cli/display/council_view.py +240 -0
  25. velune/cli/display/memory_view.py +93 -0
  26. velune/cli/display/panels.py +35 -0
  27. velune/cli/display/progress.py +25 -0
  28. velune/cli/display/themes.py +21 -0
  29. velune/cli/main.py +15 -0
  30. velune/cli/model_selector.py +44 -0
  31. velune/cli/modes.py +86 -0
  32. velune/cli/pull_ui.py +118 -0
  33. velune/cli/registry.py +81 -0
  34. velune/cli/repl.py +1178 -0
  35. velune/cli/session_manager.py +69 -0
  36. velune/cli/slash_commands.py +37 -0
  37. velune/cognition/__init__.py +19 -0
  38. velune/cognition/arbitrator.py +216 -0
  39. velune/cognition/architecture.py +398 -0
  40. velune/cognition/council/__init__.py +47 -0
  41. velune/cognition/council/base.py +216 -0
  42. velune/cognition/council/challenger.py +70 -0
  43. velune/cognition/council/coder.py +79 -0
  44. velune/cognition/council/critic_agent.py +39 -0
  45. velune/cognition/council/critic_configs.py +111 -0
  46. velune/cognition/council/critics.py +41 -0
  47. velune/cognition/council/debate.py +44 -0
  48. velune/cognition/council/factory.py +140 -0
  49. velune/cognition/council/messages.py +53 -0
  50. velune/cognition/council/planner.py +119 -0
  51. velune/cognition/council/reviewer.py +72 -0
  52. velune/cognition/council/synthesizer.py +67 -0
  53. velune/cognition/council/tiers.py +181 -0
  54. velune/cognition/firewall.py +256 -0
  55. velune/cognition/module.py +38 -0
  56. velune/cognition/orchestrator.py +886 -0
  57. velune/cognition/personality.py +236 -0
  58. velune/cognition/style_resolver.py +62 -0
  59. velune/cognition/verification.py +201 -0
  60. velune/context/__init__.py +11 -0
  61. velune/context/extractive.py +94 -0
  62. velune/context/window.py +62 -0
  63. velune/core/__init__.py +89 -0
  64. velune/core/background.py +5 -0
  65. velune/core/config/__init__.py +37 -0
  66. velune/core/errors/__init__.py +53 -0
  67. velune/core/errors/execution.py +26 -0
  68. velune/core/errors/memory.py +21 -0
  69. velune/core/errors/orchestration.py +26 -0
  70. velune/core/errors/provider.py +31 -0
  71. velune/core/event_loop.py +30 -0
  72. velune/core/logging.py +83 -0
  73. velune/core/runtime.py +106 -0
  74. velune/core/task_registry.py +120 -0
  75. velune/core/trace.py +80 -0
  76. velune/core/types/__init__.py +48 -0
  77. velune/core/types/agent.py +49 -0
  78. velune/core/types/context.py +39 -0
  79. velune/core/types/inference.py +35 -0
  80. velune/core/types/memory.py +39 -0
  81. velune/core/types/model.py +64 -0
  82. velune/core/types/provider.py +35 -0
  83. velune/core/types/repository.py +35 -0
  84. velune/core/types/task.py +56 -0
  85. velune/core/types/workspace.py +28 -0
  86. velune/daemon/client.py +13 -0
  87. velune/daemon/server.py +115 -0
  88. velune/daemon/transport.py +169 -0
  89. velune/events.py +194 -0
  90. velune/execution/__init__.py +22 -0
  91. velune/execution/benchmarker.py +311 -0
  92. velune/execution/cancellation.py +53 -0
  93. velune/execution/checkpointer.py +128 -0
  94. velune/execution/command_spec.py +140 -0
  95. velune/execution/diff_preview.py +172 -0
  96. velune/execution/executor.py +173 -0
  97. velune/execution/module.py +16 -0
  98. velune/execution/multi_diff.py +70 -0
  99. velune/execution/path_guard.py +19 -0
  100. velune/execution/planner.py +91 -0
  101. velune/execution/rollback.py +80 -0
  102. velune/execution/sandbox.py +257 -0
  103. velune/execution/validator.py +113 -0
  104. velune/hardware/__init__.py +1 -0
  105. velune/hardware/detector.py +162 -0
  106. velune/kernel/__init__.py +58 -0
  107. velune/kernel/bootstrap.py +107 -0
  108. velune/kernel/config.py +252 -0
  109. velune/kernel/health.py +54 -0
  110. velune/kernel/lifecycle.py +102 -0
  111. velune/kernel/module.py +15 -0
  112. velune/kernel/modules.py +23 -0
  113. velune/kernel/registry.py +93 -0
  114. velune/kernel/schemas.py +28 -0
  115. velune/main.py +9 -0
  116. velune/mcp/__init__.py +9 -0
  117. velune/mcp/client.py +113 -0
  118. velune/mcp/config.py +19 -0
  119. velune/mcp/server.py +90 -0
  120. velune/memory/__init__.py +28 -0
  121. velune/memory/lifecycle.py +154 -0
  122. velune/memory/module.py +94 -0
  123. velune/memory/prioritizer.py +65 -0
  124. velune/memory/storage/sqlite_manager.py +368 -0
  125. velune/memory/tiers/episodic.py +156 -0
  126. velune/memory/tiers/graph.py +282 -0
  127. velune/memory/tiers/lineage.py +367 -0
  128. velune/memory/tiers/semantic.py +198 -0
  129. velune/memory/tiers/working.py +165 -0
  130. velune/models/__init__.py +16 -0
  131. velune/models/module.py +18 -0
  132. velune/models/probes.py +182 -0
  133. velune/models/profile_cache.py +82 -0
  134. velune/models/profiler.py +105 -0
  135. velune/models/registry.py +201 -0
  136. velune/models/scorer.py +225 -0
  137. velune/models/specializations.py +196 -0
  138. velune/orchestration/__init__.py +15 -0
  139. velune/orchestration/module.py +14 -0
  140. velune/orchestration/role_assignments.py +78 -0
  141. velune/orchestration/schemas.py +99 -0
  142. velune/plugins/__init__.py +13 -0
  143. velune/plugins/hooks.py +49 -0
  144. velune/plugins/loader.py +95 -0
  145. velune/plugins/registry.py +54 -0
  146. velune/plugins/schemas.py +19 -0
  147. velune/providers/__init__.py +18 -0
  148. velune/providers/adapters/anthropic.py +231 -0
  149. velune/providers/adapters/fireworks.py +115 -0
  150. velune/providers/adapters/google.py +234 -0
  151. velune/providers/adapters/groq.py +151 -0
  152. velune/providers/adapters/huggingface.py +203 -0
  153. velune/providers/adapters/llamacpp.py +202 -0
  154. velune/providers/adapters/lmstudio.py +173 -0
  155. velune/providers/adapters/ollama.py +186 -0
  156. velune/providers/adapters/openai.py +207 -0
  157. velune/providers/adapters/openrouter.py +81 -0
  158. velune/providers/adapters/together.py +134 -0
  159. velune/providers/adapters/xai.py +60 -0
  160. velune/providers/base.py +86 -0
  161. velune/providers/benchmarker.py +135 -0
  162. velune/providers/discovery/__init__.py +33 -0
  163. velune/providers/discovery/anthropic.py +77 -0
  164. velune/providers/discovery/benchmarks.py +44 -0
  165. velune/providers/discovery/classifier.py +69 -0
  166. velune/providers/discovery/fireworks.py +95 -0
  167. velune/providers/discovery/gguf.py +87 -0
  168. velune/providers/discovery/google.py +95 -0
  169. velune/providers/discovery/gpu.py +109 -0
  170. velune/providers/discovery/groq.py +20 -0
  171. velune/providers/discovery/huggingface.py +67 -0
  172. velune/providers/discovery/lmstudio.py +80 -0
  173. velune/providers/discovery/ollama.py +165 -0
  174. velune/providers/discovery/openai.py +96 -0
  175. velune/providers/discovery/openrouter.py +113 -0
  176. velune/providers/discovery/scanner.py +114 -0
  177. velune/providers/discovery/together.py +114 -0
  178. velune/providers/discovery/xai.py +57 -0
  179. velune/providers/keystore.py +83 -0
  180. velune/providers/local_paths.py +49 -0
  181. velune/providers/local_resolver.py +208 -0
  182. velune/providers/module.py +15 -0
  183. velune/providers/ollama_manager.py +193 -0
  184. velune/providers/registry.py +173 -0
  185. velune/providers/router.py +82 -0
  186. velune/py.typed +0 -0
  187. velune/repository/__init__.py +21 -0
  188. velune/repository/analyzer.py +123 -0
  189. velune/repository/cognition.py +172 -0
  190. velune/repository/grapher.py +182 -0
  191. velune/repository/indexer.py +229 -0
  192. velune/repository/module.py +15 -0
  193. velune/repository/parser.py +378 -0
  194. velune/repository/project_type.py +293 -0
  195. velune/repository/scanner.py +177 -0
  196. velune/repository/schemas.py +102 -0
  197. velune/repository/tracker.py +233 -0
  198. velune/retrieval/__init__.py +27 -0
  199. velune/retrieval/graph.py +117 -0
  200. velune/retrieval/hybrid.py +250 -0
  201. velune/retrieval/keyword.py +113 -0
  202. velune/retrieval/module.py +19 -0
  203. velune/retrieval/reranker.py +68 -0
  204. velune/retrieval/schemas.py +59 -0
  205. velune/retrieval/vector.py +163 -0
  206. velune/telemetry/__init__.py +7 -0
  207. velune/telemetry/cognition.py +260 -0
  208. velune/telemetry/token_tracker.py +133 -0
  209. velune/tools/__init__.py +41 -0
  210. velune/tools/base/registry.py +84 -0
  211. velune/tools/base/tool.py +63 -0
  212. velune/tools/code/navigate.py +107 -0
  213. velune/tools/code/search.py +112 -0
  214. velune/tools/filesystem/read.py +75 -0
  215. velune/tools/filesystem/search.py +123 -0
  216. velune/tools/filesystem/write.py +160 -0
  217. velune/tools/git/history.py +185 -0
  218. velune/tools/git/operations.py +132 -0
  219. velune/tools/git/state.py +134 -0
  220. velune/tools/module.py +65 -0
  221. velune/tools/terminal/execute.py +72 -0
  222. velune/tools/terminal/history.py +47 -0
  223. velune/tools/web/fetch.py +55 -0
  224. velune/tools/web/validator.py +96 -0
  225. velune_cli-1.0.0.dist-info/METADATA +497 -0
  226. velune_cli-1.0.0.dist-info/RECORD +229 -0
  227. velune_cli-1.0.0.dist-info/WHEEL +4 -0
  228. velune_cli-1.0.0.dist-info/entry_points.txt +2 -0
  229. velune_cli-1.0.0.dist-info/licenses/LICENSE +201 -0
velune/cli/modes.py ADDED
@@ -0,0 +1,86 @@
1
+ from dataclasses import dataclass
2
+ from enum import Enum
3
+
4
+
5
+ class SessionMode(Enum):
6
+ NORMAL = "normal"
7
+ OPTIMUS = "optimus"
8
+ GODLY = "godly"
9
+
10
+
11
+ @dataclass
12
+ class ModeConfig:
13
+ mode: SessionMode
14
+ council_tier: str # "instant" | "minimal" | "standard" | "full" | "auto"
15
+ context_compression: bool # compress context before each call
16
+ max_context_tokens: int # hard cap on context sent per call
17
+ temperature: float
18
+ retrieval_depth: int # how many memory + repo chunks to pull
19
+ use_fastest_model: bool # optimus: pick smallest capable model
20
+ use_largest_model: bool # godly: pick largest available model
21
+ disable_critics: bool # optimus: skip critic agents
22
+ description: str
23
+ prompt_color: str # Rich color for prompt badge
24
+
25
+
26
+ MODE_CONFIGS: dict[SessionMode, ModeConfig] = {
27
+ SessionMode.NORMAL: ModeConfig(
28
+ mode=SessionMode.NORMAL,
29
+ council_tier="auto",
30
+ context_compression=False,
31
+ max_context_tokens=16384,
32
+ temperature=0.3,
33
+ retrieval_depth=8,
34
+ use_fastest_model=False,
35
+ use_largest_model=False,
36
+ disable_critics=False,
37
+ description="Balanced — auto-selects council tier per task",
38
+ prompt_color="cyan",
39
+ ),
40
+ SessionMode.OPTIMUS: ModeConfig(
41
+ mode=SessionMode.OPTIMUS,
42
+ council_tier="instant",
43
+ context_compression=True,
44
+ max_context_tokens=4096,
45
+ temperature=0.1,
46
+ retrieval_depth=3,
47
+ use_fastest_model=True,
48
+ use_largest_model=False,
49
+ disable_critics=True,
50
+ description="Speed mode — smallest model, compressed context, instant tier",
51
+ prompt_color="yellow",
52
+ ),
53
+ SessionMode.GODLY: ModeConfig(
54
+ mode=SessionMode.GODLY,
55
+ council_tier="full",
56
+ context_compression=False,
57
+ max_context_tokens=128000,
58
+ temperature=0.5,
59
+ retrieval_depth=20,
60
+ use_fastest_model=False,
61
+ use_largest_model=True,
62
+ disable_critics=False,
63
+ description="Maximum — largest model, full context, complete council",
64
+ prompt_color="magenta",
65
+ ),
66
+ }
67
+
68
+
69
+ class ModeManager:
70
+ def __init__(self) -> None:
71
+ self._active = SessionMode.NORMAL
72
+
73
+ @property
74
+ def current(self) -> SessionMode:
75
+ return self._active
76
+
77
+ @property
78
+ def config(self) -> ModeConfig:
79
+ return MODE_CONFIGS[self._active]
80
+
81
+ def set_mode(self, mode: SessionMode) -> ModeConfig:
82
+ self._active = mode
83
+ return self.config
84
+
85
+ def is_normal(self) -> bool:
86
+ return self._active == SessionMode.NORMAL
velune/cli/pull_ui.py ADDED
@@ -0,0 +1,118 @@
1
+ """Interactive model browser TUI for /pull — select a model to download."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from prompt_toolkit.application import Application
8
+ from prompt_toolkit.formatted_text import FormattedText
9
+ from prompt_toolkit.key_binding import KeyBindings
10
+ from prompt_toolkit.layout import Layout
11
+ from prompt_toolkit.layout.containers import Window
12
+ from prompt_toolkit.layout.controls import FormattedTextControl
13
+
14
+ from velune.providers.ollama_manager import RECOMMENDED_MODELS
15
+
16
+ if TYPE_CHECKING:
17
+ from rich.console import Console
18
+
19
+ _SKILL_STYLES: dict[str, str] = {
20
+ "coding": "fg:ansigreen",
21
+ "reasoning": "fg:ansimagenta",
22
+ "embedding": "fg:ansicyan",
23
+ "general": "fg:ansibrightblack",
24
+ }
25
+
26
+
27
+ async def run_pull_ui(
28
+ local_models: list[str],
29
+ hardware_ram_gb: float,
30
+ console: Console,
31
+ ) -> str | None:
32
+ """Show the interactive model browser and return the chosen model_id, or None."""
33
+
34
+ selected_idx = [0]
35
+ result: list[str | None] = [None]
36
+
37
+ def _fits(model: dict) -> bool:
38
+ try:
39
+ needed = float(model["ram_needed"].replace(" GB", "").strip())
40
+ return hardware_ram_gb >= needed
41
+ except Exception:
42
+ return True
43
+
44
+ def render_list() -> FormattedText:
45
+ lines: list[tuple[str, str]] = []
46
+ lines.append(("bold", " Available models to pull\n"))
47
+ lines.append(("fg:ansibrightblack", " ↑↓ navigate · Enter pull · Esc cancel\n\n"))
48
+ lines.append(("fg:ansibrightblack", f" Your RAM: {hardware_ram_gb:.0f} GB\n\n"))
49
+
50
+ for i, model in enumerate(RECOMMENDED_MODELS):
51
+ is_active = i == selected_idx[0]
52
+ prefix = "❯ " if is_active else " "
53
+ row_style = "bold fg:cyan" if is_active else ""
54
+ model_id = model["model_id"]
55
+ is_local = any(
56
+ m == model_id or m.split(":")[0] == model_id.split(":")[0]
57
+ and m == model_id
58
+ for m in local_models
59
+ )
60
+ fits = _fits(model)
61
+ skill = model.get("skill", "general")
62
+ skill_style = _SKILL_STYLES.get(skill, "fg:ansibrightblack")
63
+
64
+ if is_local:
65
+ status = " ✓ installed"
66
+ status_style = "fg:ansigreen"
67
+ elif not fits:
68
+ status = " needs more RAM"
69
+ status_style = "fg:ansibrightblack"
70
+ else:
71
+ status = ""
72
+ status_style = ""
73
+
74
+ lines.append((
75
+ row_style,
76
+ f" {prefix}{model_id:<34} {model['size_gb']:4.1f} GB ",
77
+ ))
78
+ lines.append((skill_style, f"[{skill}]"))
79
+ if status:
80
+ lines.append((status_style, status))
81
+ lines.append(("", "\n"))
82
+
83
+ if is_active:
84
+ lines.append(("fg:ansibrightblack", f" {model['description']}\n"))
85
+ lines.append(("fg:ansibrightblack", f" RAM needed: {model['ram_needed']}\n"))
86
+
87
+ return FormattedText(lines)
88
+
89
+ kb = KeyBindings()
90
+
91
+ @kb.add("up")
92
+ def _up(event) -> None:
93
+ selected_idx[0] = (selected_idx[0] - 1) % len(RECOMMENDED_MODELS)
94
+
95
+ @kb.add("down")
96
+ def _down(event) -> None:
97
+ selected_idx[0] = (selected_idx[0] + 1) % len(RECOMMENDED_MODELS)
98
+
99
+ @kb.add("enter")
100
+ def _select(event) -> None:
101
+ result[0] = RECOMMENDED_MODELS[selected_idx[0]]["model_id"]
102
+ event.app.exit()
103
+
104
+ @kb.add("escape")
105
+ @kb.add("c-c")
106
+ def _cancel(event) -> None:
107
+ event.app.exit()
108
+
109
+ app = Application(
110
+ layout=Layout(Window(
111
+ content=FormattedTextControl(render_list, focusable=True),
112
+ )),
113
+ key_bindings=kb,
114
+ full_screen=False,
115
+ mouse_support=False,
116
+ )
117
+ await app.run_async()
118
+ return result[0]
velune/cli/registry.py ADDED
@@ -0,0 +1,81 @@
1
+ """CLI command discovery and registration."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import importlib
6
+ from collections.abc import Sequence
7
+ from importlib.metadata import EntryPoint, entry_points
8
+ from types import ModuleType
9
+
10
+ import typer
11
+
12
+ from velune.cli.commands import (
13
+ ask_command,
14
+ chat_command,
15
+ config_cmd,
16
+ daemon_cmd,
17
+ doctor_cmd,
18
+ init_command,
19
+ mcp_cmd,
20
+ mcp_serve,
21
+ memory_cmd,
22
+ models_cmd,
23
+ run_command,
24
+ setup_command,
25
+ workspace_cmd,
26
+ )
27
+ from velune.kernel.registry import ServiceContainer
28
+
29
+ BUILTIN_COMMAND_MODULES: Sequence[str] = (
30
+ "velune.cli.commands.ask",
31
+ "velune.cli.commands.chat",
32
+ "velune.cli.commands.run",
33
+ "velune.cli.commands.models",
34
+ "velune.cli.commands.workspace",
35
+ "velune.cli.commands.memory",
36
+ "velune.cli.commands.config",
37
+ "velune.cli.commands.daemon",
38
+ "velune.cli.commands.doctor",
39
+ "velune.cli.commands.mcp",
40
+ )
41
+
42
+
43
+ def discover_builtin_modules() -> list[ModuleType]:
44
+ """Import and return built-in command modules."""
45
+
46
+ modules: list[ModuleType] = []
47
+ for module_name in BUILTIN_COMMAND_MODULES:
48
+ modules.append(importlib.import_module(module_name))
49
+ return modules
50
+
51
+
52
+ def discover_plugin_entry_points(group: str = "velune.commands") -> list[EntryPoint]:
53
+ """Return third-party command extension entry points."""
54
+
55
+ return list(entry_points(group=group))
56
+
57
+
58
+ def register_commands(app: typer.Typer, container: ServiceContainer) -> None:
59
+ """Attach all built-in and plugin command groups to the app."""
60
+
61
+ app.command(name="ask")(ask_command)
62
+ app.command(name="chat")(chat_command)
63
+ app.command(name="init")(init_command)
64
+ app.command(name="run")(run_command)
65
+ app.command(name="setup")(setup_command)
66
+ app.command(name="mcp-serve")(mcp_serve)
67
+ app.add_typer(models_cmd, name="models")
68
+ app.add_typer(workspace_cmd, name="workspace")
69
+ app.add_typer(memory_cmd, name="memory")
70
+ app.add_typer(config_cmd, name="config")
71
+ app.add_typer(daemon_cmd, name="daemon")
72
+ app.add_typer(doctor_cmd, name="doctor")
73
+ app.add_typer(mcp_cmd, name="mcp")
74
+
75
+
76
+ for entry_point in discover_plugin_entry_points():
77
+ loaded = entry_point.load()
78
+ if hasattr(loaded, "register"):
79
+ loaded.register(app=app, container=container)
80
+ elif callable(loaded):
81
+ loaded(app=app, container=container)