gemcode 0.3.36__tar.gz → 0.3.38__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.
- {gemcode-0.3.36/src/gemcode.egg-info → gemcode-0.3.38}/PKG-INFO +1 -1
- {gemcode-0.3.36 → gemcode-0.3.38}/pyproject.toml +1 -1
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/cli.py +1 -1
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/invoke.py +2 -2
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/live_audio_engine.py +1 -1
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tui/input_handler.py +18 -9
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tui/scrollback.py +20 -2
- {gemcode-0.3.36 → gemcode-0.3.38/src/gemcode.egg-info}/PKG-INFO +1 -1
- {gemcode-0.3.36 → gemcode-0.3.38}/LICENSE +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/MANIFEST.in +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/README.md +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/setup.cfg +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/__init__.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/__main__.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/agent.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/audit.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/autocompact.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/callbacks.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/capability_routing.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/compaction.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/computer_use/__init__.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/computer_use/browser_computer.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/config.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/context_budget.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/context_warning.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/credentials.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/hitl_session.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/hooks.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/interactions.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/kairos_daemon.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/limits.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/logging_config.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/mcp_loader.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/memory/__init__.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/memory/embedding_memory_service.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/memory/file_memory_service.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/modality_tools.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/model_errors.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/model_routing.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/openapi_loader.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/paths.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/permissions.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/plugins/__init__.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/pricing.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/prompt_suggestions.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/query/__init__.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/query/config.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/query/deps.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/query/engine.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/query/stop_hooks.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/query/token_budget.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/query/transitions.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/refine.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/repl_commands.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/repl_slash.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/review_agent.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/session_runtime.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/session_store.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/slash_commands.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/thinking.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tool_prompt_manifest.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tool_registry.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/__init__.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/bash.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/browser.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/edit.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/filesystem.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/notes.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/search.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/shell.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/shell_gate.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/subtask.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/think.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/todo.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools/web.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tools_inspector.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/trust.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tui/spinner.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tui/welcome_banner.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/tui/welcome_rich.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/version.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/vertex.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/web/__init__.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/web/claude_sse_adapter.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/web/terminal_repl.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode/workspace_hints.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode.egg-info/SOURCES.txt +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode.egg-info/dependency_links.txt +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode.egg-info/entry_points.txt +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode.egg-info/requires.txt +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/src/gemcode.egg-info/top_level.txt +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_agent_instruction.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_autocompact.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_capability_routing.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_claude_web_adapter_sse.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_cli_init.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_computer_use_permissions.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_context_budget.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_context_warning.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_credentials.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_interactive_permission_ask.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_kairos_scheduler.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_modality_tools.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_model_error_retry.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_model_errors.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_model_routing.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_paths.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_permissions.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_prompt_suggestions.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_repl_commands.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_repl_slash.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_slash_commands.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_thinking_config.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_token_budget.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_tool_context_circulation.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_tools.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_tools_inspector.py +0 -0
- {gemcode-0.3.36 → gemcode-0.3.38}/tests/test_workspace_hints.py +0 -0
|
@@ -27,7 +27,7 @@ def _events_to_text(events) -> str:
|
|
|
27
27
|
if not event.content or not event.content.parts:
|
|
28
28
|
continue
|
|
29
29
|
for part in event.content.parts:
|
|
30
|
-
if part.text and event
|
|
30
|
+
if part.text and getattr(event, "author", None) != "user":
|
|
31
31
|
parts.append(part.text)
|
|
32
32
|
return "".join(parts)
|
|
33
33
|
|
|
@@ -27,8 +27,8 @@ def _events_to_text(events: list[Any]) -> str:
|
|
|
27
27
|
content = getattr(event, "content", None)
|
|
28
28
|
if not content or not getattr(content, "parts", None):
|
|
29
29
|
continue
|
|
30
|
-
|
|
31
|
-
if
|
|
30
|
+
# Omit only user-authored events; model events may have author=None.
|
|
31
|
+
if getattr(event, "author", None) == "user":
|
|
32
32
|
continue
|
|
33
33
|
for part in getattr(content, "parts", []) or []:
|
|
34
34
|
t = getattr(part, "text", None)
|
|
@@ -89,7 +89,7 @@ async def run_live_audio(
|
|
|
89
89
|
for part in event.content.parts:
|
|
90
90
|
part_text = getattr(part, "text", None)
|
|
91
91
|
# We only print model-authored text to avoid echoing user input.
|
|
92
|
-
if part_text and getattr(event, "author", None)
|
|
92
|
+
if part_text and getattr(event, "author", None) != "user":
|
|
93
93
|
sys.stdout.write(part_text)
|
|
94
94
|
sys.stdout.flush()
|
|
95
95
|
printed_any = True
|
|
@@ -15,6 +15,7 @@ stdout is not a TTY (e.g. piped input, CI).
|
|
|
15
15
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
|
+
import os
|
|
18
19
|
import sys
|
|
19
20
|
from typing import Callable
|
|
20
21
|
|
|
@@ -143,8 +144,8 @@ class GemCodeInputHandler:
|
|
|
143
144
|
"completion-menu.meta.completion": "bg:#0d2035 fg:#5a7a9a",
|
|
144
145
|
"completion-menu.meta.completion.current": "bg:#0065a0 fg:#cce8ff",
|
|
145
146
|
"completion-menu.border": "#0087d7",
|
|
146
|
-
# Bottom
|
|
147
|
-
"bottom-toolbar": "bg:#
|
|
147
|
+
# Bottom status line — muted (not multi-colour); detail in HTML
|
|
148
|
+
"bottom-toolbar": "bg:#0a0e12 fg:#5a6570",
|
|
148
149
|
}
|
|
149
150
|
)
|
|
150
151
|
|
|
@@ -170,9 +171,9 @@ class GemCodeInputHandler:
|
|
|
170
171
|
flags.append("BROWSER")
|
|
171
172
|
if flags:
|
|
172
173
|
extras = " · " + " ".join(f"[{f}]" for f in flags)
|
|
174
|
+
# Single muted tone (no bright cyan) — reads as a quiet status strip
|
|
173
175
|
return HTML(
|
|
174
|
-
f'<style bg="#
|
|
175
|
-
f'<style bg="#0d1f2d" fg="#3d6080"> · session {sid_short}'
|
|
176
|
+
f'<style bg="#0a0e12" fg="#5f6b78"> ◆ {model} · session {sid_short}'
|
|
176
177
|
f'{extras} · / for commands</style>'
|
|
177
178
|
)
|
|
178
179
|
|
|
@@ -183,6 +184,14 @@ class GemCodeInputHandler:
|
|
|
183
184
|
"""Ctrl+C clears current line (like a real shell)."""
|
|
184
185
|
event.app.current_buffer.reset()
|
|
185
186
|
|
|
187
|
+
# Rows reserved for the / command popup. Too high (e.g. 20) leaves a huge
|
|
188
|
+
# empty band above the prompt; 10–12 is enough for most slash lists.
|
|
189
|
+
try:
|
|
190
|
+
_menu_rows = int(os.environ.get("GEMCODE_TUI_RESERVE_MENU_LINES", "12"))
|
|
191
|
+
except ValueError:
|
|
192
|
+
_menu_rows = 12
|
|
193
|
+
_menu_rows = max(6, min(24, _menu_rows))
|
|
194
|
+
|
|
186
195
|
self._session = PromptSession(
|
|
187
196
|
history=InMemoryHistory(),
|
|
188
197
|
completer=_SlashCommandCompleter(),
|
|
@@ -190,11 +199,11 @@ class GemCodeInputHandler:
|
|
|
190
199
|
style=style,
|
|
191
200
|
bottom_toolbar=bottom_toolbar,
|
|
192
201
|
key_bindings=kb,
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
202
|
+
mouse_support=False,
|
|
203
|
+
complete_in_thread=True,
|
|
204
|
+
reserve_space_for_menu=_menu_rows,
|
|
205
|
+
# Single-column popup with description column (like VS Code)
|
|
206
|
+
complete_style="COLUMN",
|
|
198
207
|
)
|
|
199
208
|
|
|
200
209
|
def is_interactive(self) -> bool:
|
|
@@ -577,7 +577,9 @@ async def run_gemcode_scrollback_tui(
|
|
|
577
577
|
try:
|
|
578
578
|
if not ev.content or not ev.content.parts:
|
|
579
579
|
continue
|
|
580
|
-
|
|
580
|
+
# Only skip user turns. ADK often omits `author` on model events — do NOT
|
|
581
|
+
# skip those or the assistant text never renders (blank reply, ↓0 tokens).
|
|
582
|
+
if getattr(ev, "author", None) == "user":
|
|
581
583
|
continue
|
|
582
584
|
for part in ev.content.parts:
|
|
583
585
|
delta = getattr(part, "text", None)
|
|
@@ -616,6 +618,11 @@ async def run_gemcode_scrollback_tui(
|
|
|
616
618
|
if not confirmation_fcs:
|
|
617
619
|
thought_text = "".join(buffered_thought).strip()
|
|
618
620
|
final_text = "".join(buffered_final).strip()
|
|
621
|
+
# Gemini with thinking enabled may emit visible text only in "thought" parts;
|
|
622
|
+
# usage can show thoughts_token_count > 0 and candidates_token_count == 0.
|
|
623
|
+
if not final_text and thought_text:
|
|
624
|
+
final_text = thought_text
|
|
625
|
+
thought_text = ""
|
|
619
626
|
|
|
620
627
|
# ── Thinking display (collapsed by default, verbose with /thinking verbose)
|
|
621
628
|
if thought_text and not (
|
|
@@ -763,7 +770,18 @@ async def run_gemcode_scrollback_tui(
|
|
|
763
770
|
token_part = " · " + " · ".join(parts_t)
|
|
764
771
|
except Exception:
|
|
765
772
|
pass
|
|
766
|
-
|
|
773
|
+
# Bottom input bar already shows model + session; avoid duplicating them here
|
|
774
|
+
# (reduces visual noise and “gappy” repeats). Optional full line via env.
|
|
775
|
+
_dup = os.environ.get("GEMCODE_TUI_FOOTER_DUP_STATUS", "").lower() in (
|
|
776
|
+
"1", "true", "yes", "on",
|
|
777
|
+
)
|
|
778
|
+
if token_part:
|
|
779
|
+
if _dup:
|
|
780
|
+
print(f"{ansi.dim} · {model} · session {sid}{token_part}{ansi.reset}")
|
|
781
|
+
else:
|
|
782
|
+
print(f"{ansi.dim}{token_part}{ansi.reset}")
|
|
783
|
+
elif _dup:
|
|
784
|
+
print(f"{ansi.dim} · {model} · session {sid}{ansi.reset}")
|
|
767
785
|
if os.environ.get("GEMCODE_TUI_TURN_RULE", "1").lower() in (
|
|
768
786
|
"1",
|
|
769
787
|
"true",
|
|
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
|
|
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
|
|
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
|
|
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
|