aizen-ai-cli 2.4.1__tar.gz → 2.5.0__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 (52) hide show
  1. aizen_ai_cli-2.5.0/PKG-INFO +109 -0
  2. aizen_ai_cli-2.5.0/README.md +69 -0
  3. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/agent.py +7 -2
  4. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/commands.py +29 -3
  5. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/config.py +1 -1
  6. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/context.py +8 -8
  7. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/main.py +7 -16
  8. aizen_ai_cli-2.5.0/aizen/rag.py +709 -0
  9. aizen_ai_cli-2.5.0/aizen/tools/commands.py +279 -0
  10. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/dispatcher.py +42 -5
  11. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/helpers.py +0 -5
  12. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/utils.py +1 -1
  13. aizen_ai_cli-2.5.0/aizen_ai_cli.egg-info/PKG-INFO +109 -0
  14. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/SOURCES.txt +2 -0
  15. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/pyproject.toml +1 -1
  16. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/setup.py +1 -1
  17. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_agent.py +23 -23
  18. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_commands.py +1 -8
  19. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_dispatcher.py +1 -7
  20. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_file_ops.py +1 -6
  21. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_helpers.py +0 -8
  22. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_plugins.py +4 -6
  23. aizen_ai_cli-2.5.0/tests/test_rag_search.py +1472 -0
  24. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_retry.py +7 -8
  25. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_search.py +0 -7
  26. aizen_ai_cli-2.4.1/PKG-INFO +0 -276
  27. aizen_ai_cli-2.4.1/README.md +0 -236
  28. aizen_ai_cli-2.4.1/aizen/tools/commands.py +0 -222
  29. aizen_ai_cli-2.4.1/aizen_ai_cli.egg-info/PKG-INFO +0 -276
  30. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/MANIFEST.in +0 -0
  31. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/__init__.py +0 -0
  32. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/exceptions.py +0 -0
  33. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/logging_config.py +0 -0
  34. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/mcp.py +0 -0
  35. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/plugins.py +0 -0
  36. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/retry.py +0 -0
  37. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/session.py +0 -0
  38. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/__init__.py +0 -0
  39. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/file_ops.py +3 -3
  40. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/search.py +1 -1
  41. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/dependency_links.txt +0 -0
  42. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/entry_points.txt +0 -0
  43. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/requires.txt +0 -0
  44. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/top_level.txt +0 -0
  45. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/requirements.txt +0 -0
  46. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/setup.cfg +0 -0
  47. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_config.py +0 -0
  48. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_context.py +0 -0
  49. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_main.py +0 -0
  50. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_mcp.py +0 -0
  51. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_session.py +0 -0
  52. {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_utils.py +0 -0
@@ -0,0 +1,109 @@
1
+ Metadata-Version: 2.4
2
+ Name: aizen-ai-cli
3
+ Version: 2.5.0
4
+ Summary: Aizen AI Agent — A professional-grade AI coding assistant for your terminal.
5
+ Author: Irtaza Malik
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/irtaza302/aizen-agent
8
+ Project-URL: Repository, https://github.com/irtaza302/aizen-agent
9
+ Project-URL: Issues, https://github.com/irtaza302/aizen-agent/issues
10
+ Keywords: ai,cli,coding-assistant,terminal,openrouter,llm
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Software Development
22
+ Classifier: Topic :: Utilities
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ Requires-Dist: openai>=1.0
26
+ Requires-Dist: python-dotenv>=1.0
27
+ Requires-Dist: rich>=13.0
28
+ Requires-Dist: prompt_toolkit>=3.0
29
+ Requires-Dist: questionary>=2.0.0
30
+ Requires-Dist: mcp>=1.0.0
31
+ Provides-Extra: tiktoken
32
+ Requires-Dist: tiktoken>=0.5; extra == "tiktoken"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=7.0; extra == "dev"
35
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
36
+ Requires-Dist: pytest-mock>=3.0; extra == "dev"
37
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
38
+ Requires-Dist: ruff>=0.1; extra == "dev"
39
+ Requires-Dist: mypy>=1.0; extra == "dev"
40
+
41
+ # Aizen AI Agent 🚀
42
+
43
+ [![CI](https://github.com/irtaza302/aizen-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/irtaza302/aizen-agent/actions/workflows/ci.yml)
44
+
45
+ Aizen is a powerful, asynchronous AI assistant that integrates seamlessly into your terminal workflow. It reads your code, edits files safely, runs commands, and provides real‑time, richly formatted assistance—all while keeping costs transparent and sessions persistent.
46
+
47
+ ## 🌟 Key Benefits
48
+
49
+ - **Effortless Integration** — Operates directly in your terminal, preserving shell state across commands.
50
+ - **Intelligent Editing** — Perform precise, color‑coded file edits with `edit_file`.
51
+ - **Background Execution** — Run long‑running tasks asynchronously and retrieve results later.
52
+ - **Cost‑Aware Usage** — Real‑time cost estimation for all major LLMs.
53
+ - **Persistent Sessions** — Save and restore conversations with checkpoints.
54
+ - **Rich Visual Feedback** — Stream responses with live previews and animated thought indicators.
55
+ - **Semantic Codebase Search** — Fast local RAG (Retrieval-Augmented Generation) using the `/search` command.
56
+ - **Extensible Architecture** — Custom plugins and project‑specific rules tailor Aizen to your workflow.
57
+ - **Comprehensive Logging** — Rotating logs with optional verbose output for debugging.
58
+
59
+ ## 🚀 Core Features
60
+
61
+ ### Asynchronous Architecture
62
+ - Fully asynchronous operations using `asyncio` and `AsyncOpenAI` for concurrent processing, parallel tool runs, and streaming.
63
+
64
+ ### Stateful Terminal Session
65
+ - Environment variables and directory changes persist across interactions.
66
+
67
+ ### Rich Markdown Rendering
68
+ - Full Markdown support with headers, code blocks, lists, and styling via Rich.
69
+
70
+ ### Surgical File Editing
71
+ - Precise search‑and‑replace with color‑coded diff previews (`edit_file`).
72
+
73
+ ### Vision Support
74
+ - Native image handling and encoding for Vision APIs (e.g., GPT‑4o, Claude 3.5 Sonnet).
75
+
76
+ ### Local Codebase RAG
77
+ - Intelligent semantic search across your entire codebase using local embeddings and SQLite vector caching, accessible via the `/search` command and available to the agent.
78
+
79
+ ### Real‑Time Command Streaming
80
+ - Background command execution with async streaming of stdout/stderr; use `run_command --background`.
81
+
82
+ ## 🎛️ Workflow Tools
83
+
84
+ - **Background Tasks** — Run non‑blocking commands; monitor with `check_background_task`; cancel with `kill_background_task`.
85
+ - **Session Persistence** — Powered by SQLite (`~/.aizen_sessions/aizen.db`), auto‑migrating older JSON sessions.
86
+ - **Project‑Specific Rules** — Auto‑load `.aizen_rules` or `.cursorrules` for repo‑specific behavior.
87
+ - **Smart Autocomplete** — TAB‑completion with `.gitignore` awareness and directory traversal.
88
+
89
+ ## 💰 Cost Tracking
90
+
91
+ - Real‑time token counting for inputs and outputs.
92
+ - Current cost estimate shown in the CLI status bar.
93
+ - Supports Anthropic (Claude 3.5/3.7 Sonnet, Opus, Haiku), Google (Gemini 2.5 Pro/Flash), and OpenAI (GPT‑4o, o1, o3‑mini).
94
+
95
+ ## 📌 Session Management & Search
96
+
97
+ - `/search [query]` — Perform semantic search across your codebase.
98
+ - `/reindex [dir]` — Manually trigger indexing for local semantic search.
99
+ - `/checkpoint [name]` — Save conversation snapshots.
100
+ - `/restore [name]` — Restore a previous checkpoint.
101
+
102
+ ## 📁 Structured Logging
103
+
104
+ - Logs stored at `~/.aizen_logs/aizen.log` (rotated, 5 MB caps, 3 files).
105
+ - Verbose flag mirrors output to console.
106
+
107
+ ## 📦 Publishing & Development
108
+
109
+ - Use `publish.sh` to build and publish to PyPI, NPM, and PyInstaller binaries.
@@ -0,0 +1,69 @@
1
+ # Aizen AI Agent 🚀
2
+
3
+ [![CI](https://github.com/irtaza302/aizen-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/irtaza302/aizen-agent/actions/workflows/ci.yml)
4
+
5
+ Aizen is a powerful, asynchronous AI assistant that integrates seamlessly into your terminal workflow. It reads your code, edits files safely, runs commands, and provides real‑time, richly formatted assistance—all while keeping costs transparent and sessions persistent.
6
+
7
+ ## 🌟 Key Benefits
8
+
9
+ - **Effortless Integration** — Operates directly in your terminal, preserving shell state across commands.
10
+ - **Intelligent Editing** — Perform precise, color‑coded file edits with `edit_file`.
11
+ - **Background Execution** — Run long‑running tasks asynchronously and retrieve results later.
12
+ - **Cost‑Aware Usage** — Real‑time cost estimation for all major LLMs.
13
+ - **Persistent Sessions** — Save and restore conversations with checkpoints.
14
+ - **Rich Visual Feedback** — Stream responses with live previews and animated thought indicators.
15
+ - **Semantic Codebase Search** — Fast local RAG (Retrieval-Augmented Generation) using the `/search` command.
16
+ - **Extensible Architecture** — Custom plugins and project‑specific rules tailor Aizen to your workflow.
17
+ - **Comprehensive Logging** — Rotating logs with optional verbose output for debugging.
18
+
19
+ ## 🚀 Core Features
20
+
21
+ ### Asynchronous Architecture
22
+ - Fully asynchronous operations using `asyncio` and `AsyncOpenAI` for concurrent processing, parallel tool runs, and streaming.
23
+
24
+ ### Stateful Terminal Session
25
+ - Environment variables and directory changes persist across interactions.
26
+
27
+ ### Rich Markdown Rendering
28
+ - Full Markdown support with headers, code blocks, lists, and styling via Rich.
29
+
30
+ ### Surgical File Editing
31
+ - Precise search‑and‑replace with color‑coded diff previews (`edit_file`).
32
+
33
+ ### Vision Support
34
+ - Native image handling and encoding for Vision APIs (e.g., GPT‑4o, Claude 3.5 Sonnet).
35
+
36
+ ### Local Codebase RAG
37
+ - Intelligent semantic search across your entire codebase using local embeddings and SQLite vector caching, accessible via the `/search` command and available to the agent.
38
+
39
+ ### Real‑Time Command Streaming
40
+ - Background command execution with async streaming of stdout/stderr; use `run_command --background`.
41
+
42
+ ## 🎛️ Workflow Tools
43
+
44
+ - **Background Tasks** — Run non‑blocking commands; monitor with `check_background_task`; cancel with `kill_background_task`.
45
+ - **Session Persistence** — Powered by SQLite (`~/.aizen_sessions/aizen.db`), auto‑migrating older JSON sessions.
46
+ - **Project‑Specific Rules** — Auto‑load `.aizen_rules` or `.cursorrules` for repo‑specific behavior.
47
+ - **Smart Autocomplete** — TAB‑completion with `.gitignore` awareness and directory traversal.
48
+
49
+ ## 💰 Cost Tracking
50
+
51
+ - Real‑time token counting for inputs and outputs.
52
+ - Current cost estimate shown in the CLI status bar.
53
+ - Supports Anthropic (Claude 3.5/3.7 Sonnet, Opus, Haiku), Google (Gemini 2.5 Pro/Flash), and OpenAI (GPT‑4o, o1, o3‑mini).
54
+
55
+ ## 📌 Session Management & Search
56
+
57
+ - `/search [query]` — Perform semantic search across your codebase.
58
+ - `/reindex [dir]` — Manually trigger indexing for local semantic search.
59
+ - `/checkpoint [name]` — Save conversation snapshots.
60
+ - `/restore [name]` — Restore a previous checkpoint.
61
+
62
+ ## 📁 Structured Logging
63
+
64
+ - Logs stored at `~/.aizen_logs/aizen.log` (rotated, 5 MB caps, 3 files).
65
+ - Verbose flag mirrors output to console.
66
+
67
+ ## 📦 Publishing & Development
68
+
69
+ - Use `publish.sh` to build and publish to PyPI, NPM, and PyInstaller binaries.
@@ -10,6 +10,7 @@ Extracted from main.py to enable:
10
10
  import asyncio
11
11
  import json
12
12
  import random
13
+ import re
13
14
  from typing import Any
14
15
 
15
16
  from rich.live import Live
@@ -159,7 +160,11 @@ class AgentRunner:
159
160
  full_content += delta.content
160
161
  if full_content.strip():
161
162
  try:
162
- display_content = f"**◆ AIZEN:** {full_content}"
163
+ # Strip reasoning/thought tags for cleaner UI display
164
+ cleaned_content = re.sub(r'<think>.*?(?:</think>|$)', '', full_content, flags=re.DOTALL)
165
+ cleaned_content = re.sub(r'<\|channel>thought.*?(?:<channel\|>|$)', '', cleaned_content, flags=re.DOTALL)
166
+
167
+ display_content = f"**◆ AIZEN:** {cleaned_content.strip()}"
163
168
  rendered = Markdown(display_content)
164
169
  live.update(rendered)
165
170
  except Exception:
@@ -192,7 +197,7 @@ class AgentRunner:
192
197
  tool_text.append(" ...", style=f"{Theme.MUTED}")
193
198
  live.update(tool_text)
194
199
 
195
- except Exception as e:
200
+ except Exception:
196
201
  # Re-raise — let the caller (main_loop) handle specific exception types
197
202
  raise
198
203
 
@@ -6,9 +6,7 @@ import subprocess
6
6
  from datetime import datetime
7
7
 
8
8
  import questionary
9
-
10
9
  from prompt_toolkit.completion import Completer, Completion
11
- from prompt_toolkit import PromptSession
12
10
  from rich.table import Table
13
11
 
14
12
  from .config import (
@@ -47,6 +45,8 @@ SLASH_COMMANDS = [
47
45
  ("/commit", "Auto-generate and commit changes"),
48
46
  ("/diff", "Show all uncommitted changes"),
49
47
  ("/auto", "Enter autonomous agentic mode for a complex task"),
48
+ ("/search", "Search the codebase using semantic (RAG) search"),
49
+ ("/reindex", "Reindex the codebase for semantic search"),
50
50
  ]
51
51
 
52
52
  # In-memory checkpoint storage for conversation branching
@@ -69,7 +69,7 @@ class AizenCompleter(Completer):
69
69
  if stripped.startswith("/"):
70
70
  if " " not in stripped:
71
71
  query = stripped.lower()
72
- cmds_with_args = {"/model", "/save", "/load", "/export", "/checkpoint", "/restore"}
72
+ cmds_with_args = {"/model", "/save", "/load", "/export", "/checkpoint", "/restore", "/search", "/reindex"}
73
73
  for cmd, description in SLASH_COMMANDS:
74
74
  if cmd.startswith(query):
75
75
  completion_text = cmd + " " if cmd in cmds_with_args else cmd
@@ -287,6 +287,11 @@ async def handle_slash_command(
287
287
  help_table.add_row(" 🔀 /commit", "Auto-generate and commit changes")
288
288
  help_table.add_row(" 📊 /diff", "Show all uncommitted changes")
289
289
 
290
+ # ── Search & RAG ──
291
+ help_table.add_row(f"[bold {Theme.MUTED}]── Search & RAG ──[/bold {Theme.MUTED}]", "")
292
+ help_table.add_row(" 🔍 /search [query]", "Search the codebase using semantic (RAG) search")
293
+ help_table.add_row(" 🔄 /reindex [dir]", "Reindex the codebase for semantic search")
294
+
290
295
  # ── Agent ──
291
296
  help_table.add_row(f"[bold {Theme.MUTED}]── Agent ──[/bold {Theme.MUTED}]", "")
292
297
  help_table.add_row(" 🤖 /auto [task]", "Enter autonomous mode for a complex task (max iterations apply)")
@@ -658,6 +663,10 @@ async def handle_slash_command(
658
663
  console.print("[yellow]Commit aborted.[/yellow]\n")
659
664
  return False
660
665
 
666
+ if final_msg is None:
667
+ console.print(f" [{Theme.WARNING}]Commit aborted.[/{Theme.WARNING}]\n")
668
+ return False
669
+
661
670
  final_msg = final_msg.strip()
662
671
  if not final_msg:
663
672
  console.print(f" [{Theme.ERROR}]Error: Commit message cannot be empty. Aborted.[/{Theme.ERROR}]\n")
@@ -728,6 +737,23 @@ async def handle_slash_command(
728
737
  except Exception as e:
729
738
  console.print(f" [{Theme.ERROR}]Error showing diff: {e}[/{Theme.ERROR}]\n")
730
739
 
740
+ elif cmd == "/search":
741
+ from .rag import get_global_vector_store, get_global_embedding_generator, SlashCommandRunner
742
+ runner = SlashCommandRunner(get_global_vector_store(), get_global_embedding_generator())
743
+ runner.run(command_str, console)
744
+ console.print()
745
+
746
+ elif cmd == "/reindex":
747
+ import asyncio
748
+ from .rag import reindex_directory
749
+ target_dir = arg if arg else "."
750
+ console.print(f" [{Theme.MUTED}]Re-indexing codebase directory '{target_dir}' in background...[/{Theme.MUTED}]")
751
+ try:
752
+ await asyncio.to_thread(reindex_directory, target_dir)
753
+ console.print(f" [{Theme.SUCCESS}]✓ Reindexing complete.[/{Theme.SUCCESS}]\n")
754
+ except Exception as e:
755
+ console.print(f" [{Theme.ERROR}]Error during reindexing: {e}[/{Theme.ERROR}]\n")
756
+
731
757
  else:
732
758
  console.print(
733
759
  f" [{Theme.ERROR}]Unknown command: {cmd}[/{Theme.ERROR}] — type [bold {Theme.ACCENT}]/help[/bold {Theme.ACCENT}] for commands.\n"
@@ -20,7 +20,7 @@ logger = logging.getLogger("aizen")
20
20
 
21
21
  # Read version from installed package metadata (stays in sync with pyproject.toml).
22
22
  # Falls back to a hardcoded value only when running from source without installing.
23
- _FALLBACK_VERSION = "2.4.1"
23
+ _FALLBACK_VERSION = "2.5.0"
24
24
  try:
25
25
  VERSION = _pkg_version("aizen-ai-cli")
26
26
  except PackageNotFoundError:
@@ -184,7 +184,7 @@ class ContextPruner:
184
184
  """
185
185
  import re
186
186
  dropped_count = 0
187
-
187
+
188
188
  # Keep the system prompt and the last couple of turns intact
189
189
  if len(messages) <= 3:
190
190
  return 0
@@ -200,7 +200,7 @@ class ContextPruner:
200
200
  if old_content != new_content:
201
201
  msg["content"] = new_content
202
202
  dropped_count += 1
203
-
203
+
204
204
  return dropped_count
205
205
 
206
206
  @staticmethod
@@ -215,20 +215,20 @@ class ContextPruner:
215
215
  system_msg = messages[0]
216
216
  recent = messages[-recent_count:]
217
217
  middle = messages[1:-recent_count]
218
-
218
+
219
219
  user_topics = [
220
- m["content"][:100].replace('\n', ' ')
221
- for m in middle
220
+ m["content"][:100].replace('\n', ' ')
221
+ for m in middle
222
222
  if m.get("role") == "user" and m.get("content")
223
223
  ]
224
-
224
+
225
225
  summary = "Previous conversation summary: The user and assistant discussed " + "; ".join(user_topics[:5]) + ". The assistant helped with these requests."
226
-
226
+
227
227
  messages[:] = [
228
228
  system_msg,
229
229
  {"role": "user", "content": f"Previous conversation summary:\n{summary}"},
230
230
  {"role": "assistant", "content": "Understood. I have the context. How can I continue helping?"},
231
231
  ] + recent
232
-
232
+
233
233
  return summary
234
234
 
@@ -6,28 +6,20 @@ Aizen AI Agent — A professional-grade AI coding assistant for your terminal.
6
6
  import argparse
7
7
  import asyncio
8
8
  import base64
9
- import json
10
9
  import mimetypes
11
10
  import os
12
- import random
13
11
  import re
14
12
  import subprocess
15
13
  import sys
16
- from typing import Any
17
14
 
18
- from openai import APIConnectionError as OpenAIConnectionError
19
- from openai import APITimeoutError, AsyncOpenAI, AuthenticationError, BadRequestError
20
- from openai import RateLimitError as OpenAIRateLimitError
15
+ from openai import AsyncOpenAI
21
16
  from prompt_toolkit import PromptSession
22
17
  from prompt_toolkit.filters import completion_is_selected, has_completions
23
18
  from prompt_toolkit.formatted_text import FormattedText
24
19
  from prompt_toolkit.key_binding import KeyBindings
25
20
  from prompt_toolkit.styles import Style
26
- from rich.live import Live
27
- from rich.markdown import Markdown
28
- from rich.spinner import Spinner
29
- from rich.text import Text
30
21
 
22
+ from .agent import AgentRunner
31
23
  from .commands import AizenCompleter, handle_slash_command
32
24
  from .config import (
33
25
  AIZEN_ASCII,
@@ -52,9 +44,8 @@ from .mcp import MCPManager
52
44
  from .plugins import plugin_manager
53
45
  from .retry import retry_with_backoff
54
46
  from .session import save_session
55
- from .tools import backup_manager, execute_tool, tools
56
- from .agent import AgentRunner
57
- from .utils import Struct, TokenTracker, fetch_url_content, generate_directory_tree, truncate_output
47
+ from .tools import backup_manager, tools
48
+ from .utils import TokenTracker, fetch_url_content, generate_directory_tree
58
49
 
59
50
 
60
51
  def inject_file_context(user_input: str) -> str:
@@ -420,7 +411,7 @@ async def main_loop():
420
411
  # ── Auto-compact if context is critically full ──
421
412
  if context_manager.needs_auto_compact() and len(messages) > 4:
422
413
  console.print("[dim yellow]⚡ Context limit reached. Attempting smart pruning...[/dim yellow]")
423
-
414
+
424
415
  dropped_count = ContextPruner.prune_attached_contexts(messages)
425
416
  estimated_total = context_manager.estimate_messages_tokens(messages, token_tracker.estimate_tokens)
426
417
  context_manager.update(estimated_total)
@@ -447,10 +438,10 @@ async def main_loop():
447
438
  auto_iteration_count=auto_iteration_count,
448
439
  max_auto_iterations=max_auto_iterations,
449
440
  )
450
-
441
+
451
442
  try:
452
443
  await runner.run_turn(messages)
453
-
444
+
454
445
  # Update state back from runner (if it changed during auto mode)
455
446
  is_auto_mode = runner.is_auto_mode
456
447
  auto_iteration_count = runner.auto_iteration_count