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.
- aizen_ai_cli-2.5.0/PKG-INFO +109 -0
- aizen_ai_cli-2.5.0/README.md +69 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/agent.py +7 -2
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/commands.py +29 -3
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/config.py +1 -1
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/context.py +8 -8
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/main.py +7 -16
- aizen_ai_cli-2.5.0/aizen/rag.py +709 -0
- aizen_ai_cli-2.5.0/aizen/tools/commands.py +279 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/dispatcher.py +42 -5
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/helpers.py +0 -5
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/utils.py +1 -1
- aizen_ai_cli-2.5.0/aizen_ai_cli.egg-info/PKG-INFO +109 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/SOURCES.txt +2 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/pyproject.toml +1 -1
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/setup.py +1 -1
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_agent.py +23 -23
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_commands.py +1 -8
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_dispatcher.py +1 -7
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_file_ops.py +1 -6
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_helpers.py +0 -8
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_plugins.py +4 -6
- aizen_ai_cli-2.5.0/tests/test_rag_search.py +1472 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_retry.py +7 -8
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_search.py +0 -7
- aizen_ai_cli-2.4.1/PKG-INFO +0 -276
- aizen_ai_cli-2.4.1/README.md +0 -236
- aizen_ai_cli-2.4.1/aizen/tools/commands.py +0 -222
- aizen_ai_cli-2.4.1/aizen_ai_cli.egg-info/PKG-INFO +0 -276
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/MANIFEST.in +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/__init__.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/exceptions.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/logging_config.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/mcp.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/plugins.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/retry.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/session.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/__init__.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/file_ops.py +3 -3
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen/tools/search.py +1 -1
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/dependency_links.txt +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/entry_points.txt +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/requires.txt +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/aizen_ai_cli.egg-info/top_level.txt +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/requirements.txt +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/setup.cfg +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_config.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_context.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_main.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_mcp.py +0 -0
- {aizen_ai_cli-2.4.1 → aizen_ai_cli-2.5.0}/tests/test_session.py +0 -0
- {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
|
+
[](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
|
+
[](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
|
-
|
|
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
|
|
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.
|
|
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
|
|
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,
|
|
56
|
-
from .
|
|
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
|