velune-cli 0.9.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 (279) 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 +208 -0
  5. velune/cli/autocomplete.py +80 -0
  6. velune/cli/banner.py +60 -0
  7. velune/cli/commands/__init__.py +32 -0
  8. velune/cli/commands/ask.py +175 -0
  9. velune/cli/commands/base.py +16 -0
  10. velune/cli/commands/chat.py +228 -0
  11. velune/cli/commands/config.py +224 -0
  12. velune/cli/commands/daemon.py +88 -0
  13. velune/cli/commands/doctor.py +721 -0
  14. velune/cli/commands/init.py +170 -0
  15. velune/cli/commands/mcp.py +82 -0
  16. velune/cli/commands/memory.py +293 -0
  17. velune/cli/commands/models.py +683 -0
  18. velune/cli/commands/preflight.py +95 -0
  19. velune/cli/commands/run.py +270 -0
  20. velune/cli/commands/setup.py +184 -0
  21. velune/cli/commands/workspace.py +249 -0
  22. velune/cli/context.py +36 -0
  23. velune/cli/councilmodel_ui.py +199 -0
  24. velune/cli/display/council_view.py +254 -0
  25. velune/cli/display/memory_view.py +126 -0
  26. velune/cli/display/panels.py +35 -0
  27. velune/cli/display/progress.py +25 -0
  28. velune/cli/display/themes.py +25 -0
  29. velune/cli/main.py +15 -0
  30. velune/cli/model_selector.py +51 -0
  31. velune/cli/modes.py +86 -0
  32. velune/cli/pull_ui.py +123 -0
  33. velune/cli/registry.py +80 -0
  34. velune/cli/rendering/__init__.py +5 -0
  35. velune/cli/rendering/error_panel.py +79 -0
  36. velune/cli/rendering/markdown.py +63 -0
  37. velune/cli/repl.py +1855 -0
  38. velune/cli/session_manager.py +71 -0
  39. velune/cli/slash_commands.py +37 -0
  40. velune/cli/theme.py +8 -0
  41. velune/cognition/__init__.py +23 -0
  42. velune/cognition/agents/__init__.py +7 -0
  43. velune/cognition/agents/coder.py +209 -0
  44. velune/cognition/agents/planner.py +156 -0
  45. velune/cognition/agents/reviewer.py +195 -0
  46. velune/cognition/arbitrator.py +220 -0
  47. velune/cognition/architecture.py +415 -0
  48. velune/cognition/budget.py +65 -0
  49. velune/cognition/council/__init__.py +47 -0
  50. velune/cognition/council/base.py +217 -0
  51. velune/cognition/council/challenger.py +74 -0
  52. velune/cognition/council/coder.py +79 -0
  53. velune/cognition/council/critic_agent.py +43 -0
  54. velune/cognition/council/critic_configs.py +111 -0
  55. velune/cognition/council/critics.py +41 -0
  56. velune/cognition/council/debate.py +46 -0
  57. velune/cognition/council/factory.py +140 -0
  58. velune/cognition/council/messages.py +56 -0
  59. velune/cognition/council/planner.py +124 -0
  60. velune/cognition/council/reviewer.py +74 -0
  61. velune/cognition/council/synthesizer.py +67 -0
  62. velune/cognition/council/tiers.py +188 -0
  63. velune/cognition/council_orchestrator.py +282 -0
  64. velune/cognition/firewall.py +354 -0
  65. velune/cognition/module.py +46 -0
  66. velune/cognition/orchestrator.py +1205 -0
  67. velune/cognition/personality.py +238 -0
  68. velune/cognition/state.py +104 -0
  69. velune/cognition/style_resolver.py +64 -0
  70. velune/cognition/verification.py +205 -0
  71. velune/context/__init__.py +28 -0
  72. velune/context/assembler.py +240 -0
  73. velune/context/budget.py +97 -0
  74. velune/context/extractive.py +95 -0
  75. velune/context/prompt_adaptation.py +480 -0
  76. velune/context/sections.py +99 -0
  77. velune/context/token_counter.py +134 -0
  78. velune/context/utilization.py +33 -0
  79. velune/context/window.py +63 -0
  80. velune/core/__init__.py +89 -0
  81. velune/core/background.py +5 -0
  82. velune/core/config/__init__.py +37 -0
  83. velune/core/errors/__init__.py +90 -0
  84. velune/core/errors/catalog.py +188 -0
  85. velune/core/errors/execution.py +31 -0
  86. velune/core/errors/memory.py +25 -0
  87. velune/core/errors/orchestration.py +31 -0
  88. velune/core/errors/provider.py +37 -0
  89. velune/core/event_loop.py +35 -0
  90. velune/core/logging.py +83 -0
  91. velune/core/paths.py +165 -0
  92. velune/core/runtime.py +113 -0
  93. velune/core/startup_profiler.py +56 -0
  94. velune/core/task_registry.py +117 -0
  95. velune/core/trace.py +83 -0
  96. velune/core/types/__init__.py +48 -0
  97. velune/core/types/agent.py +53 -0
  98. velune/core/types/context.py +42 -0
  99. velune/core/types/inference.py +38 -0
  100. velune/core/types/memory.py +42 -0
  101. velune/core/types/model.py +70 -0
  102. velune/core/types/provider.py +62 -0
  103. velune/core/types/repository.py +38 -0
  104. velune/core/types/task.py +61 -0
  105. velune/core/types/workspace.py +28 -0
  106. velune/daemon/client.py +13 -0
  107. velune/daemon/server.py +127 -0
  108. velune/daemon/transport.py +179 -0
  109. velune/events.py +204 -0
  110. velune/execution/__init__.py +22 -0
  111. velune/execution/benchmarker.py +315 -0
  112. velune/execution/cancellation.py +53 -0
  113. velune/execution/checkpointer.py +130 -0
  114. velune/execution/command_spec.py +165 -0
  115. velune/execution/diff_preview.py +197 -0
  116. velune/execution/executor.py +181 -0
  117. velune/execution/module.py +18 -0
  118. velune/execution/multi_diff.py +67 -0
  119. velune/execution/path_guard.py +74 -0
  120. velune/execution/planner.py +91 -0
  121. velune/execution/rollback.py +89 -0
  122. velune/execution/sandbox.py +268 -0
  123. velune/execution/validator.py +115 -0
  124. velune/hardware/__init__.py +1 -0
  125. velune/hardware/detector.py +192 -0
  126. velune/kernel/__init__.py +55 -0
  127. velune/kernel/bootstrap.py +125 -0
  128. velune/kernel/config.py +426 -0
  129. velune/kernel/entrypoint.py +78 -0
  130. velune/kernel/health.py +54 -0
  131. velune/kernel/lifecycle.py +143 -0
  132. velune/kernel/module.py +17 -0
  133. velune/kernel/modules.py +23 -0
  134. velune/kernel/registry.py +96 -0
  135. velune/kernel/schemas.py +28 -0
  136. velune/main.py +9 -0
  137. velune/mcp/__init__.py +9 -0
  138. velune/mcp/client.py +115 -0
  139. velune/mcp/config.py +19 -0
  140. velune/mcp/server.py +624 -0
  141. velune/memory/__init__.py +32 -0
  142. velune/memory/compaction.py +506 -0
  143. velune/memory/embedding_pipeline.py +241 -0
  144. velune/memory/lifecycle.py +680 -0
  145. velune/memory/module.py +218 -0
  146. velune/memory/prioritizer.py +67 -0
  147. velune/memory/storage/episodic_schema.sql +53 -0
  148. velune/memory/storage/lancedb_store.py +282 -0
  149. velune/memory/storage/sqlite_manager.py +369 -0
  150. velune/memory/storage/sqlite_pool.py +149 -0
  151. velune/memory/tiers/episodic.py +588 -0
  152. velune/memory/tiers/graph.py +378 -0
  153. velune/memory/tiers/lineage.py +416 -0
  154. velune/memory/tiers/semantic.py +475 -0
  155. velune/memory/tiers/working.py +168 -0
  156. velune/memory/vitality.py +132 -0
  157. velune/models/__init__.py +15 -0
  158. velune/models/family.py +76 -0
  159. velune/models/module.py +20 -0
  160. velune/models/probes.py +192 -0
  161. velune/models/profile_cache.py +84 -0
  162. velune/models/profiler.py +108 -0
  163. velune/models/registry.py +251 -0
  164. velune/models/scorer.py +233 -0
  165. velune/models/specializations.py +205 -0
  166. velune/orchestration/__init__.py +19 -0
  167. velune/orchestration/engine.py +239 -0
  168. velune/orchestration/module.py +15 -0
  169. velune/orchestration/role_assignments.py +82 -0
  170. velune/orchestration/schemas.py +98 -0
  171. velune/plugins/__init__.py +20 -0
  172. velune/plugins/hooks.py +50 -0
  173. velune/plugins/loader.py +161 -0
  174. velune/plugins/registry.py +56 -0
  175. velune/plugins/schemas.py +21 -0
  176. velune/providers/__init__.py +23 -0
  177. velune/providers/adapters/anthropic.py +257 -0
  178. velune/providers/adapters/fireworks.py +115 -0
  179. velune/providers/adapters/google.py +234 -0
  180. velune/providers/adapters/groq.py +151 -0
  181. velune/providers/adapters/huggingface.py +210 -0
  182. velune/providers/adapters/llamacpp.py +208 -0
  183. velune/providers/adapters/lmstudio.py +175 -0
  184. velune/providers/adapters/ollama.py +233 -0
  185. velune/providers/adapters/openai.py +213 -0
  186. velune/providers/adapters/openrouter.py +81 -0
  187. velune/providers/adapters/together.py +134 -0
  188. velune/providers/adapters/xai.py +60 -0
  189. velune/providers/base.py +86 -0
  190. velune/providers/benchmarker.py +138 -0
  191. velune/providers/discovery/__init__.py +33 -0
  192. velune/providers/discovery/anthropic.py +79 -0
  193. velune/providers/discovery/benchmarks.py +44 -0
  194. velune/providers/discovery/classifier.py +69 -0
  195. velune/providers/discovery/fireworks.py +95 -0
  196. velune/providers/discovery/gguf.py +88 -0
  197. velune/providers/discovery/google.py +95 -0
  198. velune/providers/discovery/gpu.py +117 -0
  199. velune/providers/discovery/groq.py +21 -0
  200. velune/providers/discovery/huggingface.py +67 -0
  201. velune/providers/discovery/lmstudio.py +80 -0
  202. velune/providers/discovery/ollama.py +162 -0
  203. velune/providers/discovery/openai.py +96 -0
  204. velune/providers/discovery/openrouter.py +113 -0
  205. velune/providers/discovery/scanner.py +115 -0
  206. velune/providers/discovery/together.py +114 -0
  207. velune/providers/discovery/xai.py +57 -0
  208. velune/providers/health.py +67 -0
  209. velune/providers/health_monitor.py +169 -0
  210. velune/providers/keystore.py +142 -0
  211. velune/providers/local_paths.py +49 -0
  212. velune/providers/local_resolver.py +229 -0
  213. velune/providers/module.py +51 -0
  214. velune/providers/ollama_manager.py +193 -0
  215. velune/providers/registry.py +220 -0
  216. velune/providers/router.py +255 -0
  217. velune/providers/task_classifier.py +288 -0
  218. velune/py.typed +0 -0
  219. velune/repository/__init__.py +33 -0
  220. velune/repository/analyzer.py +127 -0
  221. velune/repository/ast_parser.py +822 -0
  222. velune/repository/blast_radius.py +298 -0
  223. velune/repository/boundary_classifier.py +295 -0
  224. velune/repository/cognition.py +316 -0
  225. velune/repository/grapher.py +179 -0
  226. velune/repository/import_graph.py +263 -0
  227. velune/repository/incremental_indexer.py +275 -0
  228. velune/repository/index_state.py +96 -0
  229. velune/repository/indexer.py +243 -0
  230. velune/repository/module.py +17 -0
  231. velune/repository/parser.py +474 -0
  232. velune/repository/project_type.py +300 -0
  233. velune/repository/rename_journal.py +287 -0
  234. velune/repository/scanner.py +193 -0
  235. velune/repository/schemas.py +102 -0
  236. velune/repository/symbol_registry.py +365 -0
  237. velune/repository/tracker.py +252 -0
  238. velune/retrieval/__init__.py +27 -0
  239. velune/retrieval/cache.py +110 -0
  240. velune/retrieval/fast_path.py +391 -0
  241. velune/retrieval/graph.py +124 -0
  242. velune/retrieval/hybrid.py +271 -0
  243. velune/retrieval/keyword.py +131 -0
  244. velune/retrieval/module.py +26 -0
  245. velune/retrieval/pipeline.py +303 -0
  246. velune/retrieval/reranker.py +102 -0
  247. velune/retrieval/schemas.py +59 -0
  248. velune/retrieval/slow_path.py +364 -0
  249. velune/retrieval/vector.py +203 -0
  250. velune/telemetry/__init__.py +59 -0
  251. velune/telemetry/cognition.py +267 -0
  252. velune/telemetry/cost_estimator.py +92 -0
  253. velune/telemetry/debug.py +304 -0
  254. velune/telemetry/doctor.py +244 -0
  255. velune/telemetry/logging.py +286 -0
  256. velune/telemetry/spans.py +277 -0
  257. velune/telemetry/token_tracker.py +140 -0
  258. velune/telemetry/usage_tracker.py +340 -0
  259. velune/tools/__init__.py +41 -0
  260. velune/tools/base/registry.py +87 -0
  261. velune/tools/base/tool.py +63 -0
  262. velune/tools/code/navigate.py +116 -0
  263. velune/tools/code/search.py +123 -0
  264. velune/tools/filesystem/read.py +75 -0
  265. velune/tools/filesystem/search.py +136 -0
  266. velune/tools/filesystem/write.py +163 -0
  267. velune/tools/git/history.py +177 -0
  268. velune/tools/git/operations.py +122 -0
  269. velune/tools/git/state.py +121 -0
  270. velune/tools/module.py +81 -0
  271. velune/tools/terminal/execute.py +72 -0
  272. velune/tools/terminal/history.py +47 -0
  273. velune/tools/web/fetch.py +55 -0
  274. velune/tools/web/validator.py +122 -0
  275. velune_cli-0.9.0.dist-info/METADATA +518 -0
  276. velune_cli-0.9.0.dist-info/RECORD +279 -0
  277. velune_cli-0.9.0.dist-info/WHEEL +4 -0
  278. velune_cli-0.9.0.dist-info/entry_points.txt +2 -0
  279. velune_cli-0.9.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,254 @@
1
+ """Rich terminal visualization of the Reasoning Council debate, scoring, and votes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from rich.box import ROUNDED
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+ from rich.table import Table
11
+ from rich.text import Text
12
+
13
+ from velune.cognition.council.planner import TaskPlan
14
+ from velune.models.specializations import CouncilRole
15
+
16
+
17
+ class CouncilDisplayView:
18
+ """Beautiful Rich-based UI components to visualize Reasoning Council deliberations."""
19
+
20
+ def __init__(self, console: Console) -> None:
21
+ self.console = console
22
+
23
+ def render_header(self, task: str) -> None:
24
+ """Display an eye-catching header for the council run."""
25
+ self.console.print()
26
+ self.console.print(
27
+ Panel(
28
+ Text.assemble(
29
+ (
30
+ "[bold magenta]VELUNE COGNITIVE OS[/bold magenta] — [cyan]Reasoning Council Active[/cyan]\n"
31
+ ),
32
+ ("[dim]Objective:[/dim] ", "[italic white]" + task + "[/italic white]"),
33
+ ),
34
+ border_style="magenta",
35
+ box=ROUNDED,
36
+ title="[bold white]🧠 Cognitive Deliberation[/bold white]",
37
+ title_align="left",
38
+ )
39
+ )
40
+
41
+ def render_role_assignments(self, assignments: dict[CouncilRole, Any]) -> None:
42
+ """Render a table displaying mapped specialized models for the council."""
43
+ table = Table(
44
+ title="[bold cyan]Mapped Council Specializations[/bold cyan]",
45
+ box=ROUNDED,
46
+ border_style="dim",
47
+ expand=True,
48
+ )
49
+ table.add_column("Council Seat", style="bold yellow")
50
+ table.add_column("Provider / Endpoint", style="green")
51
+ table.add_column("Target Model", style="cyan")
52
+ table.add_column("Key Skills / Tags", style="magenta")
53
+
54
+ for role, desc in assignments.items():
55
+ caps = []
56
+ if hasattr(desc, "capabilities") and desc.capabilities:
57
+ for cap_name in ["coding", "reasoning", "planning", "summarization", "tool_use"]:
58
+ level = getattr(desc.capabilities, cap_name, None)
59
+ if level and level > 0:
60
+ caps.append(f"{cap_name} ({level.name})")
61
+ tags = (
62
+ ", ".join(caps)
63
+ if caps
64
+ else ", ".join(desc.tags)
65
+ if getattr(desc, "tags", None)
66
+ else "reasoning"
67
+ )
68
+ table.add_row(role.value.upper(), desc.provider_id.capitalize(), desc.model_id, tags)
69
+ self.console.print(table)
70
+ self.console.print()
71
+
72
+ def render_step_header(self, step_name: str, agent_emoji: str = "🤖") -> None:
73
+ """Draw an elegant boundary indicating a change in agent active deliberation."""
74
+ self.console.print(
75
+ f"\n[bold magenta]●[/bold magenta] [bold white]{agent_emoji} {step_name}[/bold white] is deliberating..."
76
+ )
77
+
78
+ def render_planner_dag(self, plan: TaskPlan) -> None:
79
+ """Render the Planner's task plan DAG as a neat hierarchical or sequential table."""
80
+ table = Table(
81
+ title="[bold yellow]Execution Plan Compiled by Council Planner[/bold yellow]",
82
+ box=ROUNDED,
83
+ border_style="yellow",
84
+ expand=True,
85
+ )
86
+ table.add_column("ID", style="bold cyan", width=8)
87
+ table.add_column("Description", style="white")
88
+ table.add_column("Dependencies", style="magenta")
89
+ table.add_column("Validation Strategy", style="green")
90
+
91
+ for step in plan.steps:
92
+ deps = ", ".join(step.dependencies) if step.dependencies else "[dim]None[/dim]"
93
+ val = step.metadata.get("test_command") or "Syntax check + File existence"
94
+ table.add_row(step.id, step.description, deps, str(val))
95
+ self.console.print(table)
96
+ self.console.print()
97
+
98
+ def render_code_proposal(self, code_proposal: str) -> None:
99
+ """Format the coder's proposed implementation code inside a syntax-focused block."""
100
+ self.console.print(
101
+ Panel(
102
+ Text(code_proposal, style="green"),
103
+ title="[bold green]💻 Coder Proposed Patch[/bold green]",
104
+ border_style="green",
105
+ box=ROUNDED,
106
+ expand=True,
107
+ )
108
+ )
109
+
110
+ def render_reviewer_report(self, report: Any) -> None:
111
+ """Render the Reviewer's static audit, showing passed status and critical issues."""
112
+ if isinstance(report, dict):
113
+ passed = report.get("passed", True)
114
+ confidence = report.get("confidence_rating", 0.8)
115
+ issues = report.get("critical_issues", [])
116
+ else:
117
+ passed = report.passed
118
+ confidence = report.confidence_rating
119
+ issues = report.critical_issues
120
+
121
+ status_text = (
122
+ "[bold green]PASS[/bold green]" if passed else "[bold red]FAIL / BLOCKED[/bold red]"
123
+ )
124
+ border_style = "green" if passed else "red"
125
+
126
+ content = []
127
+ content.append(f"[bold]Verification Status:[/bold] {status_text}")
128
+ content.append(f"[bold]Confidence Rating:[/bold] {confidence:.2f}")
129
+
130
+ if issues:
131
+ content.append("\n[bold red]⚠️ Critical Issues Detected:[/bold red]")
132
+ for issue in issues:
133
+ content.append(f" [red]•[/red] {issue}")
134
+ else:
135
+ content.append(
136
+ "\n[green]✓ Static static checks passed. No syntactical or safety concerns raised.[/green]"
137
+ )
138
+
139
+ self.console.print(
140
+ Panel(
141
+ "\n".join(content),
142
+ title="[bold]🔍 Reviewer Audit[/bold]",
143
+ border_style=border_style,
144
+ box=ROUNDED,
145
+ expand=True,
146
+ )
147
+ )
148
+
149
+ def render_challenger_report(self, report: Any) -> None:
150
+ """Render the Challenger's adversarial audit and failure vector probes."""
151
+ if isinstance(report, dict):
152
+ severity = report.get("severity_rating", 0.0)
153
+ vectors = report.get("failure_vectors", [])
154
+ else:
155
+ severity = report.severity_rating
156
+ vectors = report.failure_vectors
157
+
158
+ border_style = "yellow" if severity > 0.4 else "dim"
159
+
160
+ content = []
161
+ content.append(
162
+ f"[bold]Adversarial Severity Rating:[/bold] [bold red]{severity:.2f}[/bold red] / 1.00"
163
+ )
164
+
165
+ if vectors:
166
+ content.append("\n[bold yellow]⚡ Failure Vectors Simulated:[/bold yellow]")
167
+ for vec in vectors:
168
+ content.append(f" [yellow]•[/yellow] {vec}")
169
+ else:
170
+ content.append(
171
+ "\n[dim]No significant failure vectors or edge-case gaps simulated.[/dim]"
172
+ )
173
+
174
+ self.console.print(
175
+ Panel(
176
+ "\n".join(content),
177
+ title="[bold]⚡ Challenger Adversarial Check[/bold]",
178
+ border_style=border_style,
179
+ box=ROUNDED,
180
+ expand=True,
181
+ )
182
+ )
183
+
184
+ def render_arbitration_result(self, res: Any) -> None:
185
+ """Display calibrated confidence score, contradiction matches, and human-review flags."""
186
+ if isinstance(res, dict):
187
+ confidence = res.get("overall_confidence", 0.8)
188
+ review_required = res.get("requires_human_review", False)
189
+ flags = res.get("flags", [])
190
+ winning_claims = res.get("winning_claims", [])
191
+ synthesis_inst = res.get("synthesis_instructions", "")
192
+ else:
193
+ confidence = res.overall_confidence
194
+ review_required = res.requires_human_review
195
+ flags = res.flags
196
+ winning_claims = res.winning_claims
197
+ synthesis_inst = res.synthesis_instructions
198
+
199
+ # Color calibrated confidence based on score
200
+ if confidence > 0.75:
201
+ conf_str = f"[bold green]{confidence * 100:.1f}% (High Confidence)[/bold green]"
202
+ border_style = "green"
203
+ elif confidence > 0.55:
204
+ conf_str = f"[bold yellow]{confidence * 100:.1f}% (Medium Confidence)[/bold yellow]"
205
+ border_style = "yellow"
206
+ else:
207
+ conf_str = (
208
+ f"[bold red]{confidence * 100:.1f}% (Low Confidence / High Volatility)[/bold red]"
209
+ )
210
+ border_style = "red"
211
+
212
+ status_text = (
213
+ "[bold red]YES (Blocked / Escalate)[/bold red]"
214
+ if review_required
215
+ else "[bold green]NO (Autonomous Pass)[/bold green]"
216
+ )
217
+
218
+ content = []
219
+ content.append(f"[bold]Calibrated Council Confidence Score:[/bold] {conf_str}")
220
+ content.append(f"[bold]Escalate to Human-in-the-Loop Review:[/bold] {status_text}")
221
+
222
+ if flags:
223
+ content.append(f"[bold red]System Flags Raised:[/bold red] {', '.join(flags)}")
224
+
225
+ if winning_claims:
226
+ content.append("\n[bold cyan]Winning Claims & Arbitration Compromise:[/bold cyan]")
227
+ for claim in winning_claims:
228
+ content.append(f" [cyan]✓[/cyan] {claim}")
229
+
230
+ if synthesis_inst:
231
+ content.append("\n[bold dim]Arbitrator Instructions for Synthesizer:[/bold dim]")
232
+ content.append(f"[dim]{synthesis_inst}[/dim]")
233
+
234
+ self.console.print(
235
+ Panel(
236
+ "\n".join(content),
237
+ title="[bold white]⚖️ Council Arbitration Engine[/bold white]",
238
+ border_style=border_style,
239
+ box=ROUNDED,
240
+ expand=True,
241
+ )
242
+ )
243
+
244
+ def render_synthesized_response(self, text: str) -> None:
245
+ """Display final walker walkthrough summary and accomplishments."""
246
+ self.console.print(
247
+ Panel(
248
+ Text(text, style="white"),
249
+ title="[bold magenta]🚀 Deliberated Walkthrough & Accomplishments[/bold magenta]",
250
+ border_style="magenta",
251
+ box=ROUNDED,
252
+ expand=True,
253
+ )
254
+ )
@@ -0,0 +1,126 @@
1
+ """Rich terminal rendering of hierarchical memory tiers, priority decays, and graph entities."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from rich.box import ROUNDED
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+ from rich.table import Table
11
+ from rich.text import Text
12
+ from rich.tree import Tree
13
+
14
+
15
+ class MemoryDisplayView:
16
+ """Beautiful Rich-based UI components to visualize Velune's 5-tier Hierarchical Memory system."""
17
+
18
+ def __init__(self, console: Console) -> None:
19
+ self.console = console
20
+
21
+ def render_memory_architecture(self, stats: dict[str, Any]) -> None:
22
+ """Render a magnificent visual map of the memory tiers and active index statistics."""
23
+ self.console.print(
24
+ Panel(
25
+ Text.assemble(
26
+ ("[bold magenta]VELUNE CORE HIERARCHICAL MEMORY MAP[/bold magenta]\n"),
27
+ (
28
+ "[dim]Active Workspace:[/dim] [italic cyan]"
29
+ + str(stats.get("workspace", "current"))
30
+ + "[/italic cyan]\n\n"
31
+ ),
32
+ (
33
+ "[bold yellow]Tier 1: Working Memory[/bold yellow] ──► In-memory state, fast lookups (TTL: "
34
+ + str(stats.get("working_memory_ttl", 3600))
35
+ + "s)\n"
36
+ ),
37
+ (
38
+ "[bold green]Tier 2: Episodic SQLite[/bold green] ──► Task runs, step histories (Retention: "
39
+ + str(stats.get("episodic_retention_days", 30))
40
+ + " days)\n"
41
+ ),
42
+ (
43
+ "[bold blue]Tier 3: Semantic Qdrant[/bold blue] ──► Vector code snippet indices (Similarity Threshold: "
44
+ + str(stats.get("semantic_threshold", 0.85))
45
+ + ")\n"
46
+ ),
47
+ (
48
+ "[bold cyan]Tier 4: Graphiti Graph[/bold cyan] ──► Entity relationships & AST Dependency Graph (Graphiti Enabled: "
49
+ + str(stats.get("graph_enabled", True))
50
+ + ")\n"
51
+ ),
52
+ (
53
+ "[bold red]Tier 5: Archive Storage[/bold red] ──► Long-term zstd-compressed cold files"
54
+ ),
55
+ ),
56
+ title="[bold white]🧠 Memory Architecture Map[/bold white]",
57
+ border_style="magenta",
58
+ box=ROUNDED,
59
+ title_align="left",
60
+ )
61
+ )
62
+
63
+ def render_memory_records_table(self, records: list[dict[str, Any]], memory_type: str) -> None:
64
+ """Render a structured table showing registered records across specific memory tiers."""
65
+ table = Table(
66
+ title=f"[bold green]Registered Memory Records ({memory_type.capitalize()})[/bold green]",
67
+ box=ROUNDED,
68
+ border_style="green",
69
+ expand=True,
70
+ )
71
+ table.add_column("Record ID / Key", style="bold cyan", width=25)
72
+ table.add_column("Memory Tier", style="magenta")
73
+ table.add_column("Importance Score", style="yellow")
74
+ table.add_column("Content Preview", style="white")
75
+ table.add_column("Age (s) / Status", style="blue")
76
+
77
+ for rec in records:
78
+ importance = rec.get("importance", 1.0)
79
+ importance_bar = "★" * int(importance * 5)
80
+ table.add_row(
81
+ rec.get("id", "N/A"),
82
+ rec.get("tier", memory_type),
83
+ f"{importance:.2f} ({importance_bar})",
84
+ rec.get("content_preview", ""),
85
+ rec.get("status", "Active"),
86
+ )
87
+ self.console.print(table)
88
+ self.console.print()
89
+
90
+ def render_knowledge_graph(
91
+ self, entities: list[dict[str, Any]], relations: list[dict[str, Any]]
92
+ ) -> None:
93
+ """Render a beautiful hierarchical tree of knowledge graph entities and their relational links."""
94
+ root = Tree("[bold cyan]🌐 Graphiti Knowledge Graph Root[/bold cyan]")
95
+
96
+ # Index entities by type for rendering
97
+ by_type: dict[str, list[dict[str, Any]]] = {}
98
+ for ent in entities:
99
+ etype = ent.get("type", "entity").upper()
100
+ if etype not in by_type:
101
+ by_type[etype] = []
102
+ by_type[etype].append(ent)
103
+
104
+ for etype, items in by_type.items():
105
+ type_node = root.add(f"[bold yellow]🏷️ {etype}[/bold yellow]")
106
+ for item in items:
107
+ name = item.get("name", item.get("id", "Unknown"))
108
+ importance = item.get("importance", 1.0)
109
+ item_node = type_node.add(f"[cyan]{name}[/cyan] [dim](imp: {importance:.2f})[/dim]")
110
+
111
+ # Find relations where this item is the source
112
+ for rel in relations:
113
+ if rel.get("source") == item.get("id"):
114
+ item_node.add(
115
+ f"──[magenta]{rel.get('relation', 'connected')}[/magenta]──► [white]{rel.get('target')}[/white]"
116
+ )
117
+
118
+ self.console.print(
119
+ Panel(
120
+ root,
121
+ title="[bold white]Knowledge Graph Visualization[/bold white]",
122
+ border_style="cyan",
123
+ box=ROUNDED,
124
+ )
125
+ )
126
+ self.console.print()
@@ -0,0 +1,35 @@
1
+ """Rich-based terminal panels."""
2
+
3
+ from rich.console import Console
4
+ from rich.panel import Panel
5
+ from rich.table import Table
6
+
7
+
8
+ class DisplayPanels:
9
+ """Utility class for creating rich display panels."""
10
+
11
+ def __init__(self, console: Console):
12
+ self.console = console
13
+
14
+ def info_panel(self, title: str, content: str) -> None:
15
+ """Display an info panel."""
16
+ self.console.print(Panel(content, title=title, border_style="blue"))
17
+
18
+ def success_panel(self, title: str, content: str) -> None:
19
+ """Display a success panel."""
20
+ self.console.print(Panel(content, title=title, border_style="green"))
21
+
22
+ def warning_panel(self, title: str, content: str) -> None:
23
+ """Display a warning panel."""
24
+ self.console.print(Panel(content, title=title, border_style="yellow"))
25
+
26
+ def error_panel(self, title: str, content: str) -> None:
27
+ """Display an error panel."""
28
+ self.console.print(Panel(content, title=title, border_style="red"))
29
+
30
+ def create_table(self, title: str, columns: list[str]) -> Table:
31
+ """Create a rich table."""
32
+ table = Table(title=title)
33
+ for column in columns:
34
+ table.add_column(column)
35
+ return table
@@ -0,0 +1,25 @@
1
+ """Rich-based progress display."""
2
+
3
+ from rich.console import Console
4
+ from rich.progress import BarColumn, Progress, SpinnerColumn, TaskProgressColumn, TextColumn
5
+
6
+
7
+ class ProgressDisplay:
8
+ """Utility class for displaying progress."""
9
+
10
+ def __init__(self, console: Console):
11
+ self.console = console
12
+
13
+ def create_progress(self) -> Progress:
14
+ """Create a rich progress bar."""
15
+ return Progress(
16
+ SpinnerColumn(),
17
+ TextColumn("[progress.description]{task.description}"),
18
+ BarColumn(),
19
+ TaskProgressColumn(),
20
+ console=self.console,
21
+ )
22
+
23
+ def spinner(self, description: str):
24
+ """Create a spinner context manager."""
25
+ return self.console.status(description)
@@ -0,0 +1,25 @@
1
+ """Rich terminal themes."""
2
+
3
+ from rich.theme import Theme
4
+
5
+
6
+ class VeluneTheme:
7
+ """Velune CLI theme — modern, restrained color palette."""
8
+
9
+ @staticmethod
10
+ def get_theme() -> Theme:
11
+ """Get the Velune theme with sophisticated color choices."""
12
+ return Theme(
13
+ {
14
+ "info": "blue", # Primary blue for info
15
+ "warning": "yellow", # Warm yellow for warnings
16
+ "error": "red", # Clear red for errors
17
+ "success": "green", # Green for success
18
+ "title": "bold blue", # Primary blue titles
19
+ "subtitle": "dim blue", # Subtle secondary blue
20
+ "key": "dim white", # Subtle key labels
21
+ "value": "white", # Clear values
22
+ "muted": "dim", # Background/muted text
23
+ "accent": "#d4af37", # Warm gold accent
24
+ }
25
+ )
velune/cli/main.py ADDED
@@ -0,0 +1,15 @@
1
+ """Backward-compatible CLI entry point."""
2
+
3
+ import sys
4
+
5
+ if sys.platform == "win32":
6
+ try:
7
+ sys.stdout.reconfigure(encoding="utf-8")
8
+ sys.stderr.reconfigure(encoding="utf-8")
9
+ except Exception:
10
+ pass
11
+
12
+ from velune.cli.app import app
13
+
14
+ if __name__ == "__main__":
15
+ app()
@@ -0,0 +1,51 @@
1
+ from velune.cli.modes import ModeConfig
2
+ from velune.core.types.model import ModelDescriptor
3
+
4
+
5
+ class ModeAwareModelSelector:
6
+ def __init__(self, model_registry, provider_registry) -> None:
7
+ self.model_registry = model_registry
8
+ self.provider_registry = provider_registry
9
+
10
+ def select_for_mode(
11
+ self,
12
+ config: ModeConfig,
13
+ current_model: ModelDescriptor | None,
14
+ ) -> ModelDescriptor | None:
15
+ all_models = [
16
+ m
17
+ for m in self.model_registry.list_all()
18
+ if self.provider_registry.get(m.provider_id) is not None
19
+ ]
20
+ if not all_models:
21
+ return current_model
22
+
23
+ if config.use_fastest_model:
24
+ # Smallest context window = fastest / lightest
25
+ # Prefer local 3B/7B over cloud in optimus
26
+ local = [m for m in all_models if m.is_local]
27
+ pool = local if local else all_models
28
+ return min(pool, key=lambda m: m.context_length)
29
+
30
+ if config.use_largest_model:
31
+ # Largest context + highest capability score
32
+ def capability_score(m: ModelDescriptor) -> int:
33
+ caps = m.capabilities
34
+ if not caps:
35
+ return 0
36
+ return sum(
37
+ [
38
+ getattr(caps, f, 0).value if hasattr(getattr(caps, f, None), "value") else 0
39
+ for f in [
40
+ "coding",
41
+ "reasoning",
42
+ "planning",
43
+ "summarization",
44
+ "instruction_following",
45
+ ]
46
+ ]
47
+ )
48
+
49
+ return max(all_models, key=capability_score)
50
+
51
+ return current_model
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