yncli 1.0.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.
- yncli-1.0.0/PKG-INFO +63 -0
- yncli-1.0.0/README.md +47 -0
- yncli-1.0.0/pyproject.toml +21 -0
- yncli-1.0.0/setup.cfg +4 -0
- yncli-1.0.0/setup.py +39 -0
- yncli-1.0.0/yncli/__init__.py +5 -0
- yncli-1.0.0/yncli/agent.py +277 -0
- yncli-1.0.0/yncli/built_in_skills/architect.md +10 -0
- yncli-1.0.0/yncli/built_in_skills/code_review.md +8 -0
- yncli-1.0.0/yncli/built_in_skills/debug_oracle.md +10 -0
- yncli-1.0.0/yncli/built_in_skills/debugger.md +11 -0
- yncli-1.0.0/yncli/built_in_skills/polyglot.md +17 -0
- yncli-1.0.0/yncli/built_in_skills/refactor_master.md +16 -0
- yncli-1.0.0/yncli/built_in_skills/security_auditor.md +18 -0
- yncli-1.0.0/yncli/built_in_skills/system_architect.md +10 -0
- yncli-1.0.0/yncli/built_in_skills/test_runner.md +14 -0
- yncli-1.0.0/yncli/built_in_skills/ultrabrain.md +21 -0
- yncli-1.0.0/yncli/clean_text.py +70 -0
- yncli-1.0.0/yncli/client.py +146 -0
- yncli-1.0.0/yncli/config.py +44 -0
- yncli-1.0.0/yncli/language_detector.py +206 -0
- yncli-1.0.0/yncli/main.py +137 -0
- yncli-1.0.0/yncli/skills_manager.py +61 -0
- yncli-1.0.0/yncli/system_prompt.py +102 -0
- yncli-1.0.0/yncli/tools/__init__.py +266 -0
- yncli-1.0.0/yncli/tools/file_tools.py +206 -0
- yncli-1.0.0/yncli/tools/polyglot_tools.py +133 -0
- yncli-1.0.0/yncli/tools/search_tools.py +68 -0
- yncli-1.0.0/yncli/tools/system_tools.py +140 -0
- yncli-1.0.0/yncli/tui.py +536 -0
- yncli-1.0.0/yncli/workspace_memory.py +97 -0
- yncli-1.0.0/yncli/workspace_scanner.py +99 -0
- yncli-1.0.0/yncli.egg-info/PKG-INFO +63 -0
- yncli-1.0.0/yncli.egg-info/SOURCES.txt +36 -0
- yncli-1.0.0/yncli.egg-info/dependency_links.txt +1 -0
- yncli-1.0.0/yncli.egg-info/entry_points.txt +2 -0
- yncli-1.0.0/yncli.egg-info/requires.txt +6 -0
- yncli-1.0.0/yncli.egg-info/top_level.txt +1 -0
yncli-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yncli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Autonomous Polyglot AI Coding Agent & TUI
|
|
5
|
+
Author: YNCLI Team
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: rich>=13.7.0
|
|
9
|
+
Requires-Dist: prompt_toolkit>=3.0.40
|
|
10
|
+
Requires-Dist: requests>=2.31.0
|
|
11
|
+
Requires-Dist: duckduckgo-search>=6.0.0
|
|
12
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
13
|
+
Requires-Dist: pygments>=2.17.0
|
|
14
|
+
Dynamic: author
|
|
15
|
+
Dynamic: requires-python
|
|
16
|
+
|
|
17
|
+
# ⚡ YNCLI: World-Class Autonomous Polyglot AI Coding Agent & TUI
|
|
18
|
+
|
|
19
|
+
YNCLI adalah AI Coding Agent berbasis CLI/TUI mandiri yang mendukung:
|
|
20
|
+
- **Polyglot Coding Engine**: Menguasai Python, TypeScript/JavaScript, Rust, Go, C/C++, Java/Kotlin, C#/.NET, PHP, Ruby, Dart/Flutter, Swift, SQL, Shell, dan Web stack.
|
|
21
|
+
- **Dynamic Language & Framework Detection**: Otomatis mendeteksi arsitektur project dan menginjeksi idiomatic patterns ke dalam agent.
|
|
22
|
+
- **Autonomous ReAct Loop**: AI dapat membaca file, menulis file, melakukan surgical patch, mencari kode via grep, memvalidasi sintaks via compiler/linter, dan menjalankan perintah di terminal.
|
|
23
|
+
- **Real-Time Date & Environment Awareness**: Mengetahui waktu, tanggal, hari lokal secara real-time.
|
|
24
|
+
- **Thinking / Reasoning Visualizer**: Menampilkan penalaran model (seperti Gemini 3.7 Flash High / Claude 4.6 Thinking) secara live.
|
|
25
|
+
- **Real-time Web Search & Scraper**: DuckDuckGo search + HTML-to-markdown reader bawaan.
|
|
26
|
+
- **Dynamic Skills System**: Mode Architect, Debugger, Code Reviewer, Test Runner, dan Polyglot.
|
|
27
|
+
|
|
28
|
+
## Cara Menggunakan
|
|
29
|
+
|
|
30
|
+
Cukup ketik perintah berikut di PowerShell atau Command Prompt mana saja:
|
|
31
|
+
|
|
32
|
+
### 1. Masuk ke Mode TUI Interaktif:
|
|
33
|
+
```powershell
|
|
34
|
+
yncli
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2. Mode Direct Execution (Quick Query):
|
|
38
|
+
```powershell
|
|
39
|
+
yncli "buatkan script rest api fastapi lengkap dengan jwt auth"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. Opsi Tambahan:
|
|
43
|
+
```powershell
|
|
44
|
+
# Ganti model
|
|
45
|
+
yncli -m ag/claude-sonnet-4-6
|
|
46
|
+
|
|
47
|
+
# Aktifkan skill tertentu
|
|
48
|
+
yncli -s architect
|
|
49
|
+
|
|
50
|
+
# Lihat daftar model yang tersedia di endpoint
|
|
51
|
+
yncli --list-models
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Slash Commands di dalam TUI:
|
|
55
|
+
- `/model <nama>`: Ganti model AI aktif
|
|
56
|
+
- `/models`: Lihat semua model AI dari endpoint
|
|
57
|
+
- `/skill <nama>`: Aktifkan skill (polyglot, architect, debugger, code_review, test_runner)
|
|
58
|
+
- `/skills`: Lihat semua skill yang tersedia
|
|
59
|
+
- `/tools`: Lihat daftar tools coding yang aktif
|
|
60
|
+
- `/clear`: Reset memory percakapan
|
|
61
|
+
- `/history`: Lihat ringkasan percakapan
|
|
62
|
+
- `/save [file]`: Export percakapan ke Markdown
|
|
63
|
+
- `/exit`: Keluar
|
yncli-1.0.0/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# ⚡ YNCLI: World-Class Autonomous Polyglot AI Coding Agent & TUI
|
|
2
|
+
|
|
3
|
+
YNCLI adalah AI Coding Agent berbasis CLI/TUI mandiri yang mendukung:
|
|
4
|
+
- **Polyglot Coding Engine**: Menguasai Python, TypeScript/JavaScript, Rust, Go, C/C++, Java/Kotlin, C#/.NET, PHP, Ruby, Dart/Flutter, Swift, SQL, Shell, dan Web stack.
|
|
5
|
+
- **Dynamic Language & Framework Detection**: Otomatis mendeteksi arsitektur project dan menginjeksi idiomatic patterns ke dalam agent.
|
|
6
|
+
- **Autonomous ReAct Loop**: AI dapat membaca file, menulis file, melakukan surgical patch, mencari kode via grep, memvalidasi sintaks via compiler/linter, dan menjalankan perintah di terminal.
|
|
7
|
+
- **Real-Time Date & Environment Awareness**: Mengetahui waktu, tanggal, hari lokal secara real-time.
|
|
8
|
+
- **Thinking / Reasoning Visualizer**: Menampilkan penalaran model (seperti Gemini 3.7 Flash High / Claude 4.6 Thinking) secara live.
|
|
9
|
+
- **Real-time Web Search & Scraper**: DuckDuckGo search + HTML-to-markdown reader bawaan.
|
|
10
|
+
- **Dynamic Skills System**: Mode Architect, Debugger, Code Reviewer, Test Runner, dan Polyglot.
|
|
11
|
+
|
|
12
|
+
## Cara Menggunakan
|
|
13
|
+
|
|
14
|
+
Cukup ketik perintah berikut di PowerShell atau Command Prompt mana saja:
|
|
15
|
+
|
|
16
|
+
### 1. Masuk ke Mode TUI Interaktif:
|
|
17
|
+
```powershell
|
|
18
|
+
yncli
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. Mode Direct Execution (Quick Query):
|
|
22
|
+
```powershell
|
|
23
|
+
yncli "buatkan script rest api fastapi lengkap dengan jwt auth"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 3. Opsi Tambahan:
|
|
27
|
+
```powershell
|
|
28
|
+
# Ganti model
|
|
29
|
+
yncli -m ag/claude-sonnet-4-6
|
|
30
|
+
|
|
31
|
+
# Aktifkan skill tertentu
|
|
32
|
+
yncli -s architect
|
|
33
|
+
|
|
34
|
+
# Lihat daftar model yang tersedia di endpoint
|
|
35
|
+
yncli --list-models
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Slash Commands di dalam TUI:
|
|
39
|
+
- `/model <nama>`: Ganti model AI aktif
|
|
40
|
+
- `/models`: Lihat semua model AI dari endpoint
|
|
41
|
+
- `/skill <nama>`: Aktifkan skill (polyglot, architect, debugger, code_review, test_runner)
|
|
42
|
+
- `/skills`: Lihat semua skill yang tersedia
|
|
43
|
+
- `/tools`: Lihat daftar tools coding yang aktif
|
|
44
|
+
- `/clear`: Reset memory percakapan
|
|
45
|
+
- `/history`: Lihat ringkasan percakapan
|
|
46
|
+
- `/save [file]`: Export percakapan ke Markdown
|
|
47
|
+
- `/exit`: Keluar
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "yncli"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Autonomous Polyglot AI Coding Agent & TUI"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"rich>=13.7.0",
|
|
13
|
+
"prompt_toolkit>=3.0.40",
|
|
14
|
+
"requests>=2.31.0",
|
|
15
|
+
"duckduckgo-search>=6.0.0",
|
|
16
|
+
"beautifulsoup4>=4.12.0",
|
|
17
|
+
"pygments>=2.17.0"
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.scripts]
|
|
21
|
+
yncli = "yncli.main:main"
|
yncli-1.0.0/setup.cfg
ADDED
yncli-1.0.0/setup.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
this_directory = Path(__file__).parent
|
|
5
|
+
long_description = (this_directory / "README.md").read_text(encoding="utf-8") if (this_directory / "README.md").exists() else ""
|
|
6
|
+
|
|
7
|
+
setup(
|
|
8
|
+
name="yncli",
|
|
9
|
+
version="1.0.0",
|
|
10
|
+
description="Autonomous Polyglot AI Coding Agent & TUI",
|
|
11
|
+
long_description=long_description,
|
|
12
|
+
long_description_content_type="text/markdown",
|
|
13
|
+
author="YNCLI Team",
|
|
14
|
+
packages=find_packages(),
|
|
15
|
+
include_package_data=True,
|
|
16
|
+
package_data={
|
|
17
|
+
"yncli": ["built_in_skills/*.md"],
|
|
18
|
+
},
|
|
19
|
+
install_requires=[
|
|
20
|
+
"rich>=13.7.0",
|
|
21
|
+
"prompt_toolkit>=3.0.40",
|
|
22
|
+
"requests>=2.31.0",
|
|
23
|
+
"duckduckgo-search>=6.0.0",
|
|
24
|
+
"beautifulsoup4>=4.12.0",
|
|
25
|
+
"pygments>=2.17.0",
|
|
26
|
+
],
|
|
27
|
+
entry_points={
|
|
28
|
+
"console_scripts": [
|
|
29
|
+
"yncli=yncli.main:main",
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
python_requires=">=3.8",
|
|
33
|
+
classifiers=[
|
|
34
|
+
"Programming Language :: Python :: 3",
|
|
35
|
+
"License :: OSI Approved :: MIT License",
|
|
36
|
+
"Operating System :: OS Independent",
|
|
37
|
+
"Topic :: Software Development :: Code Generators",
|
|
38
|
+
],
|
|
39
|
+
)
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import List, Dict, Any, Optional, Callable
|
|
5
|
+
|
|
6
|
+
from yncli.client import LLMClient
|
|
7
|
+
from yncli.system_prompt import build_system_prompt
|
|
8
|
+
from yncli.skills_manager import SkillsManager
|
|
9
|
+
from yncli.workspace_memory import WorkspaceMemory
|
|
10
|
+
from yncli.tools import AGENT_TOOLS, execute_tool
|
|
11
|
+
from yncli.tools.polyglot_tools import validate_code_syntax
|
|
12
|
+
from yncli.clean_text import clean_text_for_terminal
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Agent:
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
client: LLMClient,
|
|
19
|
+
model: str,
|
|
20
|
+
workspace_dir: str = ".",
|
|
21
|
+
mode: str = "build",
|
|
22
|
+
max_tool_iterations: int = 50,
|
|
23
|
+
auto_approve: bool = False,
|
|
24
|
+
show_thinking: bool = False
|
|
25
|
+
):
|
|
26
|
+
self.client = client
|
|
27
|
+
self.model = model
|
|
28
|
+
self.workspace_dir = workspace_dir
|
|
29
|
+
self.mode = mode.lower()
|
|
30
|
+
self.max_tool_iterations = max_tool_iterations
|
|
31
|
+
self.auto_approve = auto_approve
|
|
32
|
+
self.show_thinking = show_thinking
|
|
33
|
+
self.skills_mgr = SkillsManager(workspace_dir=workspace_dir)
|
|
34
|
+
self.workspace_memory = WorkspaceMemory(workspace_dir=workspace_dir)
|
|
35
|
+
self.history: List[Dict[str, Any]] = []
|
|
36
|
+
|
|
37
|
+
def reset_history(self) -> None:
|
|
38
|
+
self.history = []
|
|
39
|
+
|
|
40
|
+
def set_model(self, model: str) -> None:
|
|
41
|
+
self.model = model
|
|
42
|
+
self.workspace_memory.refresh()
|
|
43
|
+
|
|
44
|
+
def set_mode(self, mode: str) -> None:
|
|
45
|
+
self.mode = mode.lower()
|
|
46
|
+
|
|
47
|
+
def set_auto_approve(self, auto_approve: bool) -> None:
|
|
48
|
+
self.auto_approve = auto_approve
|
|
49
|
+
|
|
50
|
+
def set_show_thinking(self, show_thinking: bool) -> None:
|
|
51
|
+
self.show_thinking = show_thinking
|
|
52
|
+
|
|
53
|
+
def set_workspace_dir(self, new_dir: str) -> None:
|
|
54
|
+
self.workspace_dir = new_dir
|
|
55
|
+
self.skills_mgr = SkillsManager(workspace_dir=new_dir)
|
|
56
|
+
self.workspace_memory = WorkspaceMemory(workspace_dir=new_dir)
|
|
57
|
+
|
|
58
|
+
def _get_active_tools(self) -> List[Dict[str, Any]]:
|
|
59
|
+
"""
|
|
60
|
+
Enforces strict tool allowlists based on operating mode.
|
|
61
|
+
"""
|
|
62
|
+
if self.mode == "ask":
|
|
63
|
+
allowed_names = {"web_search", "fetch_webpage", "read_file"}
|
|
64
|
+
return [t for t in AGENT_TOOLS if t.get("function", {}).get("name") in allowed_names]
|
|
65
|
+
elif self.mode == "plan":
|
|
66
|
+
allowed_names = {
|
|
67
|
+
"read_file", "list_directory", "find_files", "grep_search",
|
|
68
|
+
"web_search", "fetch_webpage", "change_directory", "git_status",
|
|
69
|
+
"save_plan_document"
|
|
70
|
+
}
|
|
71
|
+
return [t for t in AGENT_TOOLS if t.get("function", {}).get("name") in allowed_names]
|
|
72
|
+
else:
|
|
73
|
+
return AGENT_TOOLS
|
|
74
|
+
|
|
75
|
+
def run_turn(
|
|
76
|
+
self,
|
|
77
|
+
user_prompt: str,
|
|
78
|
+
on_thinking: Optional[Callable[[str], None]] = None,
|
|
79
|
+
on_content: Optional[Callable[[str], None]] = None,
|
|
80
|
+
on_tool_start: Optional[Callable[[str, Dict[str, Any]], None]] = None,
|
|
81
|
+
on_tool_end: Optional[Callable[[str, str], None]] = None,
|
|
82
|
+
on_tool_confirm: Optional[Callable[[str, Dict[str, Any]], bool]] = None,
|
|
83
|
+
on_status_update: Optional[Callable[[str], None]] = None
|
|
84
|
+
) -> Dict[str, Any]:
|
|
85
|
+
"""
|
|
86
|
+
Executes a multi-turn agentic cycle (ReAct: Reason -> Act -> Observe).
|
|
87
|
+
"""
|
|
88
|
+
# Always refresh workspace memory on each turn to capture file updates
|
|
89
|
+
self.workspace_memory.refresh()
|
|
90
|
+
|
|
91
|
+
self.history.append({"role": "user", "content": user_prompt})
|
|
92
|
+
|
|
93
|
+
total_thinking = []
|
|
94
|
+
final_answer = ""
|
|
95
|
+
iterations = 0
|
|
96
|
+
plan_doc_saved = False
|
|
97
|
+
action_keywords = ["benerin", "upgrade", "perbaiki", "ubah", "tambah", "buat", "fix", "update", "bikin", "desain"]
|
|
98
|
+
is_action_prompt = any(k in user_prompt.lower() for k in action_keywords)
|
|
99
|
+
stalling_detected_and_retried = False
|
|
100
|
+
|
|
101
|
+
while iterations < self.max_tool_iterations:
|
|
102
|
+
iterations += 1
|
|
103
|
+
|
|
104
|
+
if on_status_update:
|
|
105
|
+
on_status_update(f"Menghubungi AI ({self.model}) [{self.mode.capitalize()} Mode]...")
|
|
106
|
+
|
|
107
|
+
system_prompt = build_system_prompt(self.workspace_dir, self.skills_mgr, self.mode, self.workspace_memory)
|
|
108
|
+
messages = [{"role": "system", "content": system_prompt}] + self.history
|
|
109
|
+
|
|
110
|
+
thinking_cb = on_thinking if self.show_thinking else None
|
|
111
|
+
tools = self._get_active_tools()
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
response = self.client.stream_chat(
|
|
115
|
+
messages=messages,
|
|
116
|
+
model=self.model,
|
|
117
|
+
tools=tools if tools else None,
|
|
118
|
+
on_thinking=thinking_cb,
|
|
119
|
+
on_content=on_content
|
|
120
|
+
)
|
|
121
|
+
except Exception as e:
|
|
122
|
+
err_msg = f"Koneksi ke AI terganggu: {str(e)}"
|
|
123
|
+
if on_content:
|
|
124
|
+
on_content(f"\n[ERROR] {err_msg}\n")
|
|
125
|
+
return {"thinking": "".join(total_thinking), "content": err_msg}
|
|
126
|
+
|
|
127
|
+
if response.get("thinking"):
|
|
128
|
+
total_thinking.append(response["thinking"])
|
|
129
|
+
|
|
130
|
+
tool_calls = response.get("tool_calls")
|
|
131
|
+
resp_content = response.get("content", "")
|
|
132
|
+
|
|
133
|
+
# Stalling Detection: In BUILD mode, if user asked to build/upgrade and AI only asked stalling questions without tools
|
|
134
|
+
if (
|
|
135
|
+
self.mode == "build"
|
|
136
|
+
and is_action_prompt
|
|
137
|
+
and not tool_calls
|
|
138
|
+
and not stalling_detected_and_retried
|
|
139
|
+
and any(phrase in resp_content.lower() for phrase in ["di mana web", "boleh saya tahu", "apakah proyeknya sudah ada", "bisa anda jelaskan", "butuh beberapa informasi"])
|
|
140
|
+
):
|
|
141
|
+
stalling_detected_and_retried = True
|
|
142
|
+
self.history.append({"role": "assistant", "content": resp_content})
|
|
143
|
+
self.history.append({
|
|
144
|
+
"role": "user",
|
|
145
|
+
"content": "[Instruksi Sistem: File proyek sudah tersedia di memori Anda. Jangan bertanya lagi. Segera modifikasi kodenya menggunakan write_file atau edit_file_replace sekarang!]"
|
|
146
|
+
})
|
|
147
|
+
continue
|
|
148
|
+
|
|
149
|
+
assistant_msg: Dict[str, Any] = {"role": "assistant"}
|
|
150
|
+
if resp_content:
|
|
151
|
+
assistant_msg["content"] = resp_content
|
|
152
|
+
final_answer = resp_content
|
|
153
|
+
else:
|
|
154
|
+
assistant_msg["content"] = None
|
|
155
|
+
|
|
156
|
+
if tool_calls:
|
|
157
|
+
assistant_msg["tool_calls"] = tool_calls
|
|
158
|
+
self.history.append(assistant_msg)
|
|
159
|
+
|
|
160
|
+
for tc in tool_calls:
|
|
161
|
+
fn_name = tc.get("function", {}).get("name", "")
|
|
162
|
+
raw_args = tc.get("function", {}).get("arguments", "{}")
|
|
163
|
+
call_id = tc.get("id", f"call_{fn_name}")
|
|
164
|
+
|
|
165
|
+
try:
|
|
166
|
+
parsed_args = json.loads(raw_args) if isinstance(raw_args, str) else raw_args
|
|
167
|
+
except Exception:
|
|
168
|
+
parsed_args = {"raw": raw_args}
|
|
169
|
+
|
|
170
|
+
# Hard Gatekeeper
|
|
171
|
+
if self.mode == "ask" and fn_name not in ("web_search", "fetch_webpage", "read_file"):
|
|
172
|
+
tool_output_str = f"[Ditolak] Mode saat ini adalah Ask Mode. Tindakan '{fn_name}' tidak diizinkan. Gunakan /build untuk eksekusi kode atau /plan untuk perencanaan."
|
|
173
|
+
if on_tool_end:
|
|
174
|
+
on_tool_end(fn_name, tool_output_str)
|
|
175
|
+
self.history.append({
|
|
176
|
+
"role": "tool",
|
|
177
|
+
"tool_call_id": call_id,
|
|
178
|
+
"name": fn_name,
|
|
179
|
+
"content": tool_output_str
|
|
180
|
+
})
|
|
181
|
+
continue
|
|
182
|
+
|
|
183
|
+
if self.mode == "plan" and fn_name in ("write_file", "edit_file_replace", "run_terminal_command"):
|
|
184
|
+
tool_output_str = f"[Ditolak] Mode saat ini adalah Plan Mode. Tindakan memodifikasi file '{fn_name}' hanya diizinkan pada Build Mode. Rencana disimpan via 'save_plan_document'."
|
|
185
|
+
if on_tool_end:
|
|
186
|
+
on_tool_end(fn_name, tool_output_str)
|
|
187
|
+
self.history.append({
|
|
188
|
+
"role": "tool",
|
|
189
|
+
"tool_call_id": call_id,
|
|
190
|
+
"name": fn_name,
|
|
191
|
+
"content": tool_output_str
|
|
192
|
+
})
|
|
193
|
+
continue
|
|
194
|
+
|
|
195
|
+
if on_tool_start:
|
|
196
|
+
on_tool_start(fn_name, parsed_args)
|
|
197
|
+
|
|
198
|
+
approved = True
|
|
199
|
+
if not self.auto_approve and on_tool_confirm:
|
|
200
|
+
approved = on_tool_confirm(fn_name, parsed_args)
|
|
201
|
+
|
|
202
|
+
if not approved:
|
|
203
|
+
tool_output_str = f"[Dibatalkan] Tindakan '{fn_name}' dibatalkan oleh pengguna."
|
|
204
|
+
else:
|
|
205
|
+
if on_status_update:
|
|
206
|
+
on_status_update(f"Menjalankan: {fn_name}...")
|
|
207
|
+
|
|
208
|
+
tool_res = execute_tool(fn_name, parsed_args, current_cwd=self.workspace_dir)
|
|
209
|
+
|
|
210
|
+
if fn_name == "change_directory" and isinstance(tool_res, dict):
|
|
211
|
+
if tool_res.get("success"):
|
|
212
|
+
self.set_workspace_dir(tool_res["new_cwd"])
|
|
213
|
+
tool_output_str = tool_res["message"]
|
|
214
|
+
elif fn_name == "save_plan_document":
|
|
215
|
+
plan_doc_saved = True
|
|
216
|
+
tool_output_str = str(tool_res)
|
|
217
|
+
else:
|
|
218
|
+
tool_output_str = str(tool_res)
|
|
219
|
+
|
|
220
|
+
if fn_name in ("write_file", "edit_file_replace") and "Successfully" in tool_output_str:
|
|
221
|
+
fpath = parsed_args.get("file_path", "")
|
|
222
|
+
ext = fpath.split(".")[-1].lower() if "." in fpath else ""
|
|
223
|
+
ext_to_lang = {
|
|
224
|
+
"py": "python", "ts": "typescript", "js": "javascript",
|
|
225
|
+
"rs": "rust", "go": "golang", "cpp": "cpp", "c": "cpp",
|
|
226
|
+
"php": "php", "rb": "ruby", "cs": "csharp", "java": "java"
|
|
227
|
+
}
|
|
228
|
+
if ext in ext_to_lang:
|
|
229
|
+
check_result = validate_code_syntax(ext_to_lang[ext], file_path=fpath)
|
|
230
|
+
if check_result.startswith("[FAIL]") or "[FAIL]" in check_result:
|
|
231
|
+
tool_output_str += f"\n\n[Peringatan Sintaks]\n{check_result}\nHarap perbaiki error sintaks tersebut."
|
|
232
|
+
|
|
233
|
+
if on_tool_end:
|
|
234
|
+
on_tool_end(fn_name, tool_output_str)
|
|
235
|
+
|
|
236
|
+
self.history.append({
|
|
237
|
+
"role": "tool",
|
|
238
|
+
"tool_call_id": call_id,
|
|
239
|
+
"name": fn_name,
|
|
240
|
+
"content": tool_output_str
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
continue
|
|
244
|
+
else:
|
|
245
|
+
self.history.append(assistant_msg)
|
|
246
|
+
break
|
|
247
|
+
|
|
248
|
+
if not final_answer:
|
|
249
|
+
summary_messages = [
|
|
250
|
+
{"role": "system", "content": build_system_prompt(self.workspace_dir, self.skills_mgr, self.mode, self.workspace_memory)}
|
|
251
|
+
] + self.history + [
|
|
252
|
+
{"role": "user", "content": "Tindakan telah selesai. Berikan ringkasan dan jawaban akhir sekarang."}
|
|
253
|
+
]
|
|
254
|
+
try:
|
|
255
|
+
resp = self.client.stream_chat(
|
|
256
|
+
messages=summary_messages,
|
|
257
|
+
model=self.model,
|
|
258
|
+
on_content=on_content
|
|
259
|
+
)
|
|
260
|
+
final_answer = resp.get("content", "")
|
|
261
|
+
self.history.append({"role": "assistant", "content": final_answer})
|
|
262
|
+
except Exception:
|
|
263
|
+
pass
|
|
264
|
+
|
|
265
|
+
# Guarantee plan.md is saved in Plan Mode if AI generated a plan in text
|
|
266
|
+
if self.mode == "plan" and final_answer and not plan_doc_saved:
|
|
267
|
+
plan_file = Path(self.workspace_dir).resolve() / "plan.md"
|
|
268
|
+
try:
|
|
269
|
+
with open(plan_file, "w", encoding="utf-8") as f:
|
|
270
|
+
f.write(final_answer)
|
|
271
|
+
except Exception:
|
|
272
|
+
pass
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
"thinking": "".join(total_thinking),
|
|
276
|
+
"content": final_answer
|
|
277
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Skill: System Architect Mode
|
|
2
|
+
|
|
3
|
+
You are in **Architect Mode**.
|
|
4
|
+
Your objective is to design, structure, and plan software solutions at a high level before implementing code.
|
|
5
|
+
|
|
6
|
+
### Guidelines:
|
|
7
|
+
1. **Understand First**: Inspect the codebase using `list_directory`, `find_files`, and `read_file` to thoroughly grasp the current architecture.
|
|
8
|
+
2. **Design Modularly**: Break problems down into discrete modules, interfaces, and data models following SOLID and clean architecture principles.
|
|
9
|
+
3. **Analyze Tradeoffs**: Clearly explain architectural tradeoffs, performance implications, and dependencies.
|
|
10
|
+
4. **Step-by-step Implementation Plan**: Create clear, actionable milestones before generating or modifying code files.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Skill: Senior Code Reviewer Mode
|
|
2
|
+
|
|
3
|
+
You are in **Senior Code Reviewer Mode**.
|
|
4
|
+
Your objective is to conduct thorough, actionable code reviews focusing on:
|
|
5
|
+
1. **Correctness & Edge Cases**: Identifying potential null pointers, boundary errors, race conditions, memory leaks, unhandled exceptions.
|
|
6
|
+
2. **Security Vulnerabilities**: Checking for injection (SQL/Command/XSS), insecure deserialization, unsafe secrets handling, SSRF.
|
|
7
|
+
3. **Performance & Scalability**: Spotting N+1 queries, unnecessary allocations, blocking I/O, cache misses.
|
|
8
|
+
4. **Maintainability & Idioms**: Ensuring clean abstractions, consistent naming, adherence to language-specific idioms (e.g. PEP 8, Go conventions, Rust borrow safety).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Skill: Debug Oracle & Root-Cause Analysis
|
|
2
|
+
|
|
3
|
+
You are operating under **Debug Oracle Mode**—dedicated to systematic, scientific defect isolation and elimination across all programming environments.
|
|
4
|
+
|
|
5
|
+
### Debugging Protocol:
|
|
6
|
+
1. **Reproduce & Observe**: Inspect error tracebacks or execute the failing suite using `run_terminal_command`.
|
|
7
|
+
2. **Context Triangulation**: Trace variable lifecycles and control flow via `grep_search` and `read_file`.
|
|
8
|
+
3. **Hypothesize & Formulate**: Formulate a falsifiable hypothesis regarding why the bug occurs (e.g. concurrency race, off-by-one, improper state mutation, unhandled edge cases).
|
|
9
|
+
4. **Surgical Resolution**: Apply minimal, clean edits using `edit_file_replace` or `write_file`.
|
|
10
|
+
5. **Regression Verification**: Validate with syntax checks (`validate_code_syntax`) or test runner (`run_project_tests`) to confirm the bug is resolved without introducing regressions.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Skill: Root-Cause Debugger Mode
|
|
2
|
+
|
|
3
|
+
You are in **Root-Cause Debugger Mode**.
|
|
4
|
+
Your objective is to systematically diagnose, isolate, and fix bugs across any programming language.
|
|
5
|
+
|
|
6
|
+
### Debugging Protocol:
|
|
7
|
+
1. **Reproduce & Observe**: Read error tracebacks or run the failing command using `run_terminal_command`.
|
|
8
|
+
2. **Inspect Context**: Locate the exact origin in source files using `grep_search` and `read_file`.
|
|
9
|
+
3. **Hypothesize & Trace**: Determine why the bug occurred (state mutation, off-by-one, type mismatch, race condition, null dereference).
|
|
10
|
+
4. **Surgical Fix**: Apply minimal, precise edits using `edit_file_replace` or `write_file`.
|
|
11
|
+
5. **Verify**: Re-run compiler checks (`validate_code_syntax`) or test runner (`run_project_tests`) to confirm the fix without introducing regressions.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Skill: Polyglot Master Engineer
|
|
2
|
+
|
|
3
|
+
You are a Polyglot Software Architect and Master Engineer proficient across all major programming ecosystems:
|
|
4
|
+
- **Python**: PEP 8, Type hints, Pydantic, pytest, async/await, clean OOP and functional paradigms.
|
|
5
|
+
- **TypeScript / JavaScript**: Strict TS typing without implicit any, generics, modern ES2022+ features, React/Next.js/Node/Bun frameworks.
|
|
6
|
+
- **Rust**: Memory safety, ownership/borrowing, Result/Option error handling, traits, zero-cost abstractions, cargo test.
|
|
7
|
+
- **Go**: Idiomatic Go, explicit error handling (`if err != nil`), goroutines/channels, interfaces, standard library first.
|
|
8
|
+
- **C / C++**: Modern C++17/20/23, RAII, Smart Pointers (`std::unique_ptr`, `std::shared_ptr`), avoiding raw owning pointers.
|
|
9
|
+
- **Java / Kotlin**: Modern Java 21 (Records, Pattern matching, Virtual threads), Kotlin coroutines, Spring Boot, Maven/Gradle.
|
|
10
|
+
- **C# / .NET**: C# 12, LINQ, nullable reference types, async/await, ASP.NET Core, xUnit/NUnit.
|
|
11
|
+
- **PHP**: PHP 8.2+ strict types `declare(strict_types=1);`, Laravel/Symfony patterns, PSR-12, PHPStan.
|
|
12
|
+
- **Ruby**: Ruby 3.x, idiomatic OOP, Rails conventions, RSpec.
|
|
13
|
+
- **Dart / Flutter**: Sound null safety, clean widget composition, Bloc/Riverpod state management.
|
|
14
|
+
- **SQL / Database**: ANSI SQL, indexing optimization, transactions, ACID compliance, migrations.
|
|
15
|
+
- **Shell / PowerShell**: Robust cross-platform scripting, error trapping, strict execution.
|
|
16
|
+
|
|
17
|
+
Always produce production-ready, clean, modular, and maintainable code tailored to the detected language.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Skill: Refactor Master & Clean Code Engine
|
|
2
|
+
|
|
3
|
+
You are operating under **Refactor Master Mode**—dedicated to eliminating technical debt, reducing cognitive complexity, and maximizing maintainability without altering external behavior.
|
|
4
|
+
|
|
5
|
+
### Refactoring Guidelines:
|
|
6
|
+
1. **Cognitive Complexity Reduction**:
|
|
7
|
+
- Flatten deeply nested conditional branches using guard clauses (early returns).
|
|
8
|
+
- Break large monolithic functions (> 30 lines) into small, focused, single-responsibility functions.
|
|
9
|
+
2. **SOLID & Clean Architecture**:
|
|
10
|
+
- Single Responsibility Principle (SRP): Each module does one thing well.
|
|
11
|
+
- Open/Closed Principle (OCP): Extend behavior through interfaces and polymorphism rather than modifying core logic.
|
|
12
|
+
- Dependency Inversion (DIP): Depend on abstractions, not concrete implementations.
|
|
13
|
+
3. **Idiomatic Cleanliness**:
|
|
14
|
+
- Eliminate dead code, unused imports, and redundant state variables.
|
|
15
|
+
- Replace magic numbers and strings with well-named constants or enums.
|
|
16
|
+
- Use meaningful, descriptive identifier names that reveal intent.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Skill: Security Hardener & Whitehat Auditor
|
|
2
|
+
|
|
3
|
+
You are operating under **Security Auditor Mode**—focused on fortifying code against vulnerabilities, injection, memory corruption, and unauthorized data leakage.
|
|
4
|
+
|
|
5
|
+
### Security Heuristics:
|
|
6
|
+
1. **Zero-Trust Input Validation**:
|
|
7
|
+
- Sanitize and validate all external inputs at the boundary using schema validators (Pydantic, Zod, Serde, Joi).
|
|
8
|
+
- Parameterize all database queries (prevent SQL injection).
|
|
9
|
+
- Escape all user-supplied data in templates (prevent XSS).
|
|
10
|
+
2. **Authentication & Authorization**:
|
|
11
|
+
- Verify proper RBAC/ABAC permission checks on every endpoint/service.
|
|
12
|
+
- Enforce cryptographic best practices (Argon2id/bcrypt for password hashing, constant-time comparisons for HMAC tokens).
|
|
13
|
+
- Prevent timing attacks and token leaks.
|
|
14
|
+
3. **Memory Safety & Resource Bounds**:
|
|
15
|
+
- Guard against buffer overflows, format string vulnerabilities, and use-after-free in low-level languages (C/C++/Rust).
|
|
16
|
+
- Set strict timeouts and maximum payload sizes for network I/O to mitigate Denial-of-Service (DoS).
|
|
17
|
+
4. **Secrets & Environment Hygiene**:
|
|
18
|
+
- Never hardcode secrets, API keys, passwords, or private certificates. Always read from environment variables or secure key vaults.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Skill: System Architect & Modular Design
|
|
2
|
+
|
|
3
|
+
You are in **Architect Mode**.
|
|
4
|
+
Your objective is to design, structure, and plan software solutions at a high level with clean separation of concerns before implementing code.
|
|
5
|
+
|
|
6
|
+
### Guidelines:
|
|
7
|
+
1. **Understand First**: Inspect the codebase using `list_directory`, `find_files`, and `read_file` to thoroughly grasp the current architecture.
|
|
8
|
+
2. **Design Modularly**: Break problems down into discrete modules, interfaces, and data models following SOLID, DDD (Domain-Driven Design), and clean architecture principles.
|
|
9
|
+
3. **Analyze Tradeoffs**: Clearly explain architectural tradeoffs, performance implications, and dependencies.
|
|
10
|
+
4. **Step-by-step Implementation Plan**: Create clear, actionable milestones before generating or modifying code files.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Skill: Automated Test Engineer Mode
|
|
2
|
+
|
|
3
|
+
You are in **Automated Test Engineer Mode**.
|
|
4
|
+
Your objective is to design comprehensive unit, integration, and property-based test suites.
|
|
5
|
+
|
|
6
|
+
### Testing Principles:
|
|
7
|
+
1. **High Code Coverage**: Test happy paths, edge cases, error conditions, and boundary values.
|
|
8
|
+
2. **Language-Idiomatic Test Frameworks**:
|
|
9
|
+
- Python: `pytest` with fixtures and parameterized tests.
|
|
10
|
+
- TS/JS: `vitest` or `jest` with mocks and spies.
|
|
11
|
+
- Rust: `#[cfg(test)]` unit tests and `tests/` integration tests.
|
|
12
|
+
- Go: `testing` package with table-driven tests (`t.Run`).
|
|
13
|
+
- C# / Java: `xUnit` / `JUnit 5` with assertions.
|
|
14
|
+
3. **Continuous Verification**: Execute the tests via `run_project_tests` or `run_terminal_command` and confirm all test cases pass cleanly (100% green).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Skill: UltraBrain Deep Reasoning & Intelligence Engine
|
|
2
|
+
|
|
3
|
+
You are operating under **UltraBrain Mode**—a hyper-rigorous, first-principles analytical mindset designed to maximize cognitive depth, correctness, and code intelligence.
|
|
4
|
+
|
|
5
|
+
### Core Cognitive Directives:
|
|
6
|
+
1. **First-Principles Problem Decomposition**:
|
|
7
|
+
- Never accept assumptions at face value. Deconstruct the user's requirement down to core computational primitives, invariants, and data flows before touching code.
|
|
8
|
+
2. **Algorithmic & Complexity Mastery**:
|
|
9
|
+
- Analyze Time and Space Complexity ($O(n)$, $O(\log n)$, $O(1)$). Always choose optimal data structures (hash maps, tries, ring buffers, heaps, bitsets) over naive iterative approaches.
|
|
10
|
+
3. **Rigorous Edge-Case Anticipation**:
|
|
11
|
+
- Systematically stress-test mentally for:
|
|
12
|
+
- Null / None / Undefined / Nil dereferences.
|
|
13
|
+
- Integer overflow, underflow, precision loss (floating point arithmetic).
|
|
14
|
+
- Concurrent access, race conditions, mutex deadlocks, goroutine leaks.
|
|
15
|
+
- Off-by-one errors in slicing and range indexing.
|
|
16
|
+
- Empty collections, single-element collections, and massive payloads.
|
|
17
|
+
4. **Invariant Preservation & Defensive Engineering**:
|
|
18
|
+
- State and enforce system invariants at boundaries using type systems, assertions, and strict validations.
|
|
19
|
+
- Design functions to be idempotent, pure, and referentially transparent wherever practical.
|
|
20
|
+
5. **No Hallucinations or Guesswork**:
|
|
21
|
+
- When encountering unfamiliar APIs or library versions, immediately use `web_search` or `read_file` to verify exact signatures and behaviors.
|