yncli 1.1.0__tar.gz → 1.1.2__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.1.0 → yncli-1.1.2}/PKG-INFO +1 -1
- {yncli-1.1.0 → yncli-1.1.2}/pyproject.toml +1 -1
- {yncli-1.1.0 → yncli-1.1.2}/setup.py +1 -1
- {yncli-1.1.0 → yncli-1.1.2}/yncli/agent.py +5 -1
- {yncli-1.1.0 → yncli-1.1.2}/yncli/tui.py +29 -0
- yncli-1.1.2/yncli/version.py +1 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli.egg-info/PKG-INFO +1 -1
- yncli-1.1.0/yncli/version.py +0 -1
- {yncli-1.1.0 → yncli-1.1.2}/README.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/setup.cfg +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/__init__.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/architect.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/code_review.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/debug_oracle.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/debugger.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/polyglot.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/refactor_master.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/security_auditor.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/system_architect.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/test_runner.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/built_in_skills/ultrabrain.md +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/clean_text.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/client.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/config.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/language_detector.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/main.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/mention_resolver.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/skills_manager.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/system_prompt.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/tools/__init__.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/tools/file_tools.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/tools/polyglot_tools.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/tools/search_tools.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/tools/system_tools.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/update_checker.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/workspace_memory.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli/workspace_scanner.py +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli.egg-info/SOURCES.txt +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli.egg-info/dependency_links.txt +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli.egg-info/entry_points.txt +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli.egg-info/requires.txt +0 -0
- {yncli-1.1.0 → yncli-1.1.2}/yncli.egg-info/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ long_description = (this_directory / "README.md").read_text(encoding="utf-8") if
|
|
|
6
6
|
|
|
7
7
|
setup(
|
|
8
8
|
name="yncli",
|
|
9
|
-
version="1.1.
|
|
9
|
+
version="1.1.2",
|
|
10
10
|
description="Autonomous Polyglot AI Coding Agent & TUI",
|
|
11
11
|
long_description=long_description,
|
|
12
12
|
long_description_content_type="text/markdown",
|
|
@@ -119,7 +119,11 @@ class Agent:
|
|
|
119
119
|
on_content=on_content
|
|
120
120
|
)
|
|
121
121
|
except Exception as e:
|
|
122
|
-
|
|
122
|
+
raw_err = str(e)
|
|
123
|
+
if "429" in raw_err or "quota" in raw_err.lower() or "14018" in raw_err or "额度" in raw_err:
|
|
124
|
+
err_msg = f"Kuota token API untuk model '{self.model}' telah habis (Error 429: Quota Exceeded).\nSilakan beralih ke model lain dengan mengetik: /model (contoh: /model ag/claude-sonnet-4-6 atau ag/gemini-3.7-flash-high)"
|
|
125
|
+
else:
|
|
126
|
+
err_msg = f"Koneksi ke AI terganggu: {raw_err}"
|
|
123
127
|
if on_content:
|
|
124
128
|
on_content(f"\n[ERROR] {err_msg}\n")
|
|
125
129
|
return {"thinking": "".join(total_thinking), "content": err_msg}
|
|
@@ -26,6 +26,7 @@ class TerminalUI:
|
|
|
26
26
|
self.console = Console(force_terminal=True, soft_wrap=True)
|
|
27
27
|
self.session = None
|
|
28
28
|
self._active_spinner: Optional[Status] = None
|
|
29
|
+
self._pasted_blocks: Dict[str, str] = {}
|
|
29
30
|
|
|
30
31
|
def _stop_spinner(self) -> None:
|
|
31
32
|
if self._active_spinner:
|
|
@@ -83,12 +84,33 @@ class TerminalUI:
|
|
|
83
84
|
display_meta="file"
|
|
84
85
|
)
|
|
85
86
|
|
|
87
|
+
from prompt_toolkit.key_binding import KeyBindings
|
|
88
|
+
from prompt_toolkit.keys import Keys
|
|
89
|
+
|
|
86
90
|
completer = MentionCompleter(self.agent.workspace_memory)
|
|
91
|
+
kb = KeyBindings()
|
|
92
|
+
|
|
93
|
+
# Hidden paste store for current prompt session
|
|
94
|
+
self._pasted_blocks = {}
|
|
95
|
+
|
|
96
|
+
@kb.add(Keys.BracketedPaste)
|
|
97
|
+
def _(event):
|
|
98
|
+
data = event.data
|
|
99
|
+
line_count = len(data.splitlines())
|
|
100
|
+
# If pasted text is multiline or long (>= 2 lines or > 120 chars)
|
|
101
|
+
if line_count >= 2 or len(data) > 150:
|
|
102
|
+
paste_id = f"PASTE_BLOCK_{len(self._pasted_blocks) + 1}"
|
|
103
|
+
self._pasted_blocks[paste_id] = data
|
|
104
|
+
token = f"[ pasted {line_count} lines ]"
|
|
105
|
+
event.current_buffer.insert_text(f" {token} ")
|
|
106
|
+
else:
|
|
107
|
+
event.current_buffer.insert_text(data)
|
|
87
108
|
|
|
88
109
|
self.session = PromptSession(
|
|
89
110
|
history=FileHistory(str(history_file)),
|
|
90
111
|
auto_suggest=AutoSuggestFromHistory(),
|
|
91
112
|
completer=completer,
|
|
113
|
+
key_bindings=kb,
|
|
92
114
|
style=prompt_style
|
|
93
115
|
)
|
|
94
116
|
except Exception:
|
|
@@ -424,6 +446,13 @@ class TerminalUI:
|
|
|
424
446
|
self.handle_slash_command(user_input)
|
|
425
447
|
continue
|
|
426
448
|
|
|
449
|
+
if getattr(self, "_pasted_blocks", None):
|
|
450
|
+
for pid, full_content in self._pasted_blocks.items():
|
|
451
|
+
# Replace any [ pasted ... ] markers with the real full content for AI
|
|
452
|
+
import re
|
|
453
|
+
user_input = re.sub(r'\[\s*pasted\s+\d+\s+lines?\s*\]', f"\n```\n{full_content}\n```\n", user_input, count=1)
|
|
454
|
+
self._pasted_blocks.clear()
|
|
455
|
+
|
|
427
456
|
self.execute_turn(user_input)
|
|
428
457
|
|
|
429
458
|
except (KeyboardInterrupt, EOFError):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.1.2"
|
yncli-1.1.0/yncli/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.1.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|