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
@@ -0,0 +1,269 @@
1
+ """Memory commands — velune memory inspect/stats/clear/compact.
2
+
3
+ Phase 1 Honesty Refactor
4
+ ------------------------
5
+ All three commands previously returned hardcoded fake data or performed
6
+ no actual work. They now:
7
+
8
+ * ``inspect`` — reads real records from the episodic SQLite tier.
9
+ Falls back gracefully to an empty result set on cold start (no DB yet).
10
+
11
+ * ``clear`` — actually calls ``delete_session()`` (episodic) or
12
+ ``clear()`` (working) to remove data. No longer a no-op.
13
+
14
+ * ``compact`` — emits an honest "not yet implemented" notice instead of
15
+ printing fabricated distillation counters. The command still succeeds
16
+ so callers can script against it safely.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import typer
22
+ from rich.console import Console
23
+
24
+ from velune.cli.context import CLIContext
25
+ from velune.cli.display.memory_view import MemoryDisplayView
26
+
27
+ console = Console()
28
+ memory_cmd = typer.Typer(help="Memory management commands")
29
+
30
+
31
+ @memory_cmd.command("stats")
32
+ def memory_stats(ctx: typer.Context) -> None:
33
+ """Show visual memory map and registered policy statistics."""
34
+ cli_context = ctx.obj
35
+ if not isinstance(cli_context, CLIContext):
36
+ raise typer.BadParameter("CLI context was not properly initialized")
37
+
38
+ config = cli_context.config
39
+
40
+ # Compile memory statistics block
41
+ stats = {
42
+ "workspace": str(cli_context.workspace),
43
+ "working_memory_ttl": config.memory.working_memory_ttl,
44
+ "episodic_retention_days": config.memory.episodic_retention_days,
45
+ "semantic_threshold": config.memory.semantic_threshold,
46
+ "graph_enabled": config.memory.graph_enabled,
47
+ }
48
+
49
+ if cli_context.json_mode:
50
+ import json
51
+ print(json.dumps(stats))
52
+ return
53
+
54
+ display = MemoryDisplayView(console)
55
+ display.render_memory_architecture(stats)
56
+
57
+
58
+ @memory_cmd.command("inspect")
59
+ def memory_inspect(
60
+ ctx: typer.Context,
61
+ tier: str = typer.Option("all", "--tier", "-t", help="Memory tier to inspect (working, episodic, all)"),
62
+ limit: int = typer.Option(10, "--limit", "-l", help="Number of records to show"),
63
+ session_id: str = typer.Option("", "--session", "-s", help="Filter by session ID (empty = all)"),
64
+ ) -> None:
65
+ """Inspect stored records across different memory tiers.
66
+
67
+ Reads *real* data from the episodic SQLite database. If no data has
68
+ been written yet (cold start), an empty table is shown rather than
69
+ fabricated placeholder records.
70
+ """
71
+ cli_context = ctx.obj
72
+ if not isinstance(cli_context, CLIContext):
73
+ raise typer.BadParameter("CLI context was not properly initialized")
74
+
75
+ from velune.core.event_loop import submit
76
+ submit(_memory_inspect_async(cli_context, tier, limit, session_id))
77
+
78
+
79
+ async def _memory_inspect_async(
80
+ cli_context: CLIContext,
81
+ tier: str,
82
+ limit: int,
83
+ session_id: str,
84
+ ) -> None:
85
+ container = cli_context.container
86
+ lifecycle = container.get("runtime.lifecycle")
87
+
88
+ await lifecycle.startup()
89
+
90
+ records: list[dict] = []
91
+
92
+ # --- Working memory (always in-process) ---
93
+ if tier.lower() in ("working", "all"):
94
+ try:
95
+ working = container.get("runtime.working_memory")
96
+ if working:
97
+ for turn in working.get_recent_turns(limit=limit):
98
+ if session_id and getattr(turn, "session_id", "") != session_id:
99
+ continue
100
+ records.append({
101
+ "id": f"wrk-{turn.timestamp:.0f}",
102
+ "tier": "working",
103
+ "importance": 0.0, # working tier has no importance scores yet
104
+ "content_preview": (turn.content[:120] + "…") if len(turn.content) > 120 else turn.content,
105
+ "status": turn.role,
106
+ })
107
+ except Exception as exc:
108
+ if not cli_context.json_mode:
109
+ console.print(f"[yellow]⚠ Could not read working memory: {exc}[/yellow]")
110
+
111
+ # --- Episodic memory (SQLite) ---
112
+ if tier.lower() in ("episodic", "all"):
113
+ try:
114
+ episodic = container.get("runtime.episodic_memory")
115
+ if episodic:
116
+ # If no session_id filter provided, scan recent turns from a
117
+ # heuristic default session so the table isn't always empty.
118
+ sid = session_id or "default"
119
+ turns = episodic.get_turns(sid)
120
+ for turn in turns[-limit:]:
121
+ records.append({
122
+ "id": f"eps-{turn.id or turn.timestamp:.0f}",
123
+ "tier": "episodic",
124
+ "importance": 0.0,
125
+ "content_preview": (turn.content[:120] + "…") if len(turn.content) > 120 else turn.content,
126
+ "status": turn.role,
127
+ })
128
+ except Exception as exc:
129
+ if not cli_context.json_mode:
130
+ console.print(f"[yellow]⚠ Could not read episodic memory: {exc}[/yellow]")
131
+
132
+ if cli_context.json_mode:
133
+ import json
134
+ print(json.dumps({"records": records[:limit]}))
135
+ else:
136
+ display = MemoryDisplayView(console)
137
+ if records:
138
+ display.render_memory_records_table(records[:limit], tier)
139
+ else:
140
+ console.print(
141
+ "[dim]No memory records found"
142
+ + (f" for session '{session_id}'" if session_id else "")
143
+ + ". Run a task first to populate episodic memory.[/dim]"
144
+ )
145
+
146
+ await lifecycle.shutdown()
147
+
148
+
149
+ @memory_cmd.command("clear")
150
+ def memory_clear(
151
+ ctx: typer.Context,
152
+ tier: str = typer.Argument(..., help="Memory tier to clear (working, episodic, all)"),
153
+ session_id: str = typer.Option("default", "--session", "-s", help="Session ID to clear"),
154
+ confirm: bool = typer.Option(False, "--confirm", "-y", help="Skip safety prompt"),
155
+ ) -> None:
156
+ """Clear memory records of a specific tier.
157
+
158
+ Actually removes data — no longer a no-op.
159
+ """
160
+ cli_context = ctx.obj
161
+ if not isinstance(cli_context, CLIContext):
162
+ raise typer.BadParameter("CLI context was not properly initialized")
163
+
164
+ if not cli_context.json_mode and not confirm:
165
+ typer.confirm(
166
+ f"Are you sure you want to purge '{tier}' memory tier"
167
+ + (f" for session '{session_id}'" if session_id else "")
168
+ + "?",
169
+ abort=True,
170
+ )
171
+
172
+ from velune.core.event_loop import submit
173
+ submit(_memory_clear_async(cli_context, tier, session_id))
174
+
175
+
176
+ async def _memory_clear_async(cli_context: CLIContext, tier: str, session_id: str) -> None:
177
+ container = cli_context.container
178
+ lifecycle = container.get("runtime.lifecycle")
179
+ await lifecycle.startup()
180
+
181
+ cleared: list[str] = []
182
+ errors: list[str] = []
183
+
184
+ if tier.lower() in ("working", "all"):
185
+ try:
186
+ working = container.get("runtime.working_memory")
187
+ if working:
188
+ working.clear()
189
+ cleared.append("working")
190
+ except Exception as exc:
191
+ errors.append(f"working: {exc}")
192
+
193
+ if tier.lower() in ("episodic", "all"):
194
+ try:
195
+ episodic = container.get("runtime.episodic_memory")
196
+ if episodic and session_id:
197
+ episodic.delete_session(session_id)
198
+ cleared.append(f"episodic[session={session_id}]")
199
+ except Exception as exc:
200
+ errors.append(f"episodic: {exc}")
201
+
202
+ await lifecycle.shutdown()
203
+
204
+ if cli_context.json_mode:
205
+ import json
206
+ print(json.dumps({"success": not errors, "cleared": cleared, "errors": errors}))
207
+ else:
208
+ for c in cleared:
209
+ console.print(f"[green]✓ Cleared {c} memory.[/green]")
210
+ for e in errors:
211
+ console.print(f"[red]✗ Error clearing {e}[/red]")
212
+ if not cleared and not errors:
213
+ console.print("[dim]Nothing to clear.[/dim]")
214
+
215
+
216
+ @memory_cmd.command("compact")
217
+ def memory_compact(ctx: typer.Context) -> None:
218
+ """Trigger the memory consolidator to compress episodic history into vectors & graph facts.
219
+
220
+ Note: Semantic distillation (vector + graph consolidation) is not yet
221
+ implemented in Phase 1. This command will report honestly instead of
222
+ printing fabricated success counters.
223
+ """
224
+ cli_context = ctx.obj
225
+ if not isinstance(cli_context, CLIContext):
226
+ raise typer.BadParameter("CLI context was not properly initialized")
227
+
228
+ from velune.core.event_loop import submit
229
+ submit(_memory_compact_async(cli_context))
230
+
231
+
232
+ async def _memory_compact_async(cli_context: CLIContext) -> None:
233
+ container = cli_context.container
234
+ lifecycle = container.get("runtime.lifecycle")
235
+
236
+ await lifecycle.startup()
237
+
238
+ # Compact only what Phase 1 actually implements:
239
+ # flush working memory turns → episodic SQLite.
240
+ # Semantic distillation and graph consolidation are planned for a later phase.
241
+ if not cli_context.json_mode:
242
+ console.print("[bold cyan]⠋[/bold cyan] Flushing working memory to episodic store...")
243
+
244
+ try:
245
+ # shutdown() now handles the flush
246
+ await lifecycle.shutdown()
247
+ if not cli_context.json_mode:
248
+ console.print("[green]✓[/green] Working memory flushed to episodic SQLite.")
249
+ console.print(
250
+ "[dim]Note: semantic distillation (vector + graph consolidation) "
251
+ "is planned for a future phase and is not yet active.[/dim]"
252
+ )
253
+ except Exception as exc:
254
+ await lifecycle.shutdown()
255
+ if not cli_context.json_mode:
256
+ console.print(f"[red]✗ Compaction error: {exc}[/red]")
257
+ if cli_context.json_mode:
258
+ import json
259
+ print(json.dumps({"success": False, "error": str(exc)}))
260
+ return
261
+
262
+ if cli_context.json_mode:
263
+ import json
264
+ print(json.dumps({
265
+ "success": True,
266
+ "message": "Working memory flushed to episodic SQLite. Semantic compaction not yet implemented.",
267
+ }))
268
+ else:
269
+ console.print("[bold green]Memory flush complete.[/bold green]")