Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,5 @@ result-*
# Tests run the agent in the playground, we don't need to keep the session files
tests/playground/*
.qodo
.zencoder
.zenflow
94 changes: 78 additions & 16 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,69 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.4.0] - 2025-12-25
## [0.2.0] - 2025-12-30

### Added

- Support for XML-based tool calling via `--tool-format xml` flag.
- XML-specific prompts for all built-in tools (`bash`, `grep`, `read_file`, `write_file`, `search_replace`, `todo`).
- `XMLToolFormatHandler` for robust parsing of XML tool calls and generation of XML tool results.
- `supported_formats` field in `ModelConfig` and backend implementations to manage compatibility.
- Dynamic tool prompt resolution in `BaseTool` allowing automatic fallback to standard prompts if XML version is missing.
- First public release of ReVibe with all core functionality

### Changed

- TUI Visual & Functional Enhancements:
- Added `redact_xml_tool_calls(text)` utility in `revibe/core/utils.py` to remove raw `<tool_call>...<tool_call>` blocks from assistant output stream
- Refactored `StreamingMessageBase` in `revibe/cli/textual_ui/widgets/messages.py` to track `_displayed_content` for smart UI updates
- Enhanced premium tool summaries in chat history:
* Grep now shows as `Grep (pattern)` instead of `grep: 'pattern'`
* Bash now shows as `Bash (command)` instead of raw command string
* Read File now shows as `Read (filename)` with cleaner summary
* Write File now shows as `Write (filename)`
* Search & Replace now shows as `Patch (filename)`
- Applied redaction logic to `ReasoningMessage` in `revibe/cli/textual_ui/widgets/messages.py` to hide raw XML in reasoning blocks

### Fixed

- Case-sensitivity issue when specifying tool format via CLI.
- Type errors in backends when implementing `BackendLike` protocol (added missing `supported_formats`).
- Typo in `XMLToolFormatHandler` name property.

## [0.1.5.1] - 2025-12-30

### Added

- Support for XML-based tool calling via `--tool-format xml` flag.
- XML-specific prompts for all built-in tools (`bash`, `grep`, `read_file`, `write_file`, `search_replace`, `todo`).
- `XMLToolFormatHandler` for robust parsing of XML tool calls and generation of XML tool results.
- `supported_formats` field in `ModelConfig` and backend implementations to manage compatibility.
- Dynamic tool prompt resolution in `BaseTool` allowing automatic fallback to standard prompts if XML version is missing.

### Fixed

- Case-sensitivity issue when specifying tool format via CLI.
- Type errors in backends when implementing `BackendLike` protocol (added missing `supported_formats`).
- Typo in `XMLToolFormatHandler` name property.

## [0.1.5.0] - 2025-12-30

### Added

- Support for XML-based tool calling via `--tool-format xml` flag.
- XML-specific prompts for all built-in tools (`bash`, `grep`, `read_file`, `write_file`, `search_replace`, `todo`).
- `XMLToolFormatHandler` for robust parsing of XML tool calls and generation of XML tool results.
- `supported_formats` field in `ModelConfig` and backend implementations to manage compatibility.
- Dynamic tool prompt resolution in `BaseTool` allowing automatic fallback to standard prompts if XML version is missing.

### Fixed

- Case-sensitivity issue when specifying tool format via CLI.
- Type errors in backends when implementing `BackendLike` protocol (added missing `supported_formats`).
- Typo in `XMLToolFormatHandler` name property.
Comment on lines +38 to +68
Copy link

Copilot AI Dec 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CHANGELOG shows duplicate entries for versions 0.1.5.1 and 0.1.5.0 with nearly identical content, which creates confusion about the version history. The changelog should have unique entries per version with distinct changes documented.

Copilot uses AI. Check for mistakes.

## [0.1.4.0] - 2025-12-25

### Added

Expand Down Expand Up @@ -35,7 +97,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Remove conflicting default `api_base` for Qwen provider to allow proper endpoint auto-detection
- Enhance Qwen backend robustness with improved SSE parsing and graceful JSON error handling

## [1.3.0] - 2025-12-23
## [0.1.3.0] - 2025-12-23

### Added

Expand All @@ -57,22 +119,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix crash when switching mode
- Fix some cases where clipboard copy didn't work

## [1.2.2] - 2025-12-22
## [0.1.2.2] - 2025-12-22

### Fixed

- Remove dead code
- Fix artefacts automatically attached to the release
- Refactor agent post streaming

## [1.2.1] - 2025-12-18
## [0.1.2.1] - 2025-12-18

### Fixed

- Improve error message when running in home dir
- Do not show trusted folder workflow in home dir

## [1.2.0] - 2025-12-18
## [0.1.2.0] - 2025-12-18

### Added

Expand All @@ -94,7 +156,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Prevent segmentation fault on exit by shutting down thread pools
- Fix extra spacing with assistant message

## [1.1.3] - 2025-12-12
## [0.1.1.3] - 2025-12-12

### Added

Expand All @@ -115,20 +177,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix security issue: prevent command injection in GitHub Action prompt handling
- Fix issues with vLLM

## [1.1.2] - 2025-12-11
## [0.1.1.2] - 2025-12-11

### Changed

- add `terminal-auth` auth method to ACP agent only if the client supports it
- fix `user-agent` header when using Mistral backend, using SDK hook

## [1.1.1] - 2025-12-10
## [0.1.1.1] - 2025-12-10

### Changed

- added `include_commit_signature` in `config.toml` to disable signing commits

## [1.1.0] - 2025-12-10
## [0.1.1.0] - 2025-12-10

### Fixed

Expand All @@ -138,7 +200,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- improved context length from 100k to 200k

## [1.0.6] - 2025-12-10
## [0.1.0.6] - 2025-12-10

### Fixed

Expand All @@ -154,13 +216,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- update default system prompt reference
- document MCP tool permission configuration

## [1.0.5] - 2025-12-10
## [0.1.0.5] - 2025-12-10

### Fixed

- Fix streaming with OpenAI adapter

## [1.0.4] - 2025-12-09
## [0.1.0.4] - 2025-12-09

### Changed

Expand All @@ -174,25 +236,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Remove .envrc file

## [1.0.3] - 2025-12-09
## [0.1.0.3] - 2025-12-09

### Added

- Add LICENCE symlink in distribution/zed for compatibility with zed extension release process

## [1.0.2] - 2025-12-09
## [0.1.0.2] - 2025-12-09

### Fixed

- Fix setup flow for vibe-acp builds

## [1.0.1] - 2025-12-09
## [0.1.0.1] - 2025-12-09

### Fixed

- Fix update notification

## [1.0.0] - 2025-12-09
## [0.1.0.0] - 2025-12-09

### Added

Expand Down
30 changes: 30 additions & 0 deletions chnageimade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# TUI Visual & Functional Enhancements
Copy link

Copilot AI Dec 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filename contains a typo: "chnageimade.md" should be "changeimade.md" or preferably "changes_i_made.md" for better readability.

Copilot uses AI. Check for mistakes.

I have implemented several key changes to the TUI to improve the visual experience and support the new XML-based tool calling mode.

## 1. XML Tool Call Redaction
- **File**: `revibe/core/utils.py`
- **Change**: Added `redact_xml_tool_calls(text)` utility.
- **Purpose**: This function detects and removes raw `<tool_call>...</tool_call>` blocks from the assistant's output stream. It supports partially written tags, ensuring that raw XML never "flickers" on screen during streaming.

## 2. Streaming UI Refresh
- **File**: `revibe/cli/textual_ui/widgets/messages.py`
- **Change**: Refactored `StreamingMessageBase` to track `_displayed_content`.
- **Purpose**: Allows the UI to smart-update only when visible content changes. If a tool call block starts in the stream, the UI detects the decrease in "visible" characters (due to redaction) and resets the stream to prevent showing fragments of XML.

## 3. Premium Tool Summaries
I updated the display logic for all built-in tools to provide a cleaner, more premium aesthetic in the chat history:

- **Grep**: Now shows as `Grep (pattern)` instead of `grep: 'pattern'`.
- **Bash**: Now shows as `Bash (command)` instead of a raw command string.
- **Read File**: Now shows as `Read (filename)` with a cleaner summary.
- **Write File**: Now shows as `Write (filename)`.
- **Search & Replace**: Now shows as `Patch (filename)`.

## 4. Reasoning Integration
- **File**: `revibe/cli/textual_ui/widgets/messages.py`
- **Change**: Applied the same redaction logic to `ReasoningMessage`.
- **Purpose**: Ensures that even if the model starts thinking about tool calls in its reasoning block, the raw tags remain hidden from the user.

---
*Created on 2025-12-30 following TUI Aesthetic overhaul.*
Binary file added image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "revibe"
version = "1.4.0"
version = "0.2.0"
Copy link

Copilot AI Dec 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version downgrade from 1.4.0 to 0.2.0 is semantically incorrect. According to semantic versioning, this represents a major version decrease which typically indicates removing features or introducing breaking changes for a pre-1.0 release. If this is meant to be the first public release, consider using version 1.0.0 instead, or if continuing from 1.4.0, use 1.5.0 or 2.0.0 depending on the nature of changes.

Suggested change
version = "0.2.0"
version = "1.5.0"

Copilot uses AI. Check for mistakes.
description = "ReVibe - Multi-provider CLI coding agent"
readme = "README.md"
requires-python = ">=3.12"
Expand Down
4 changes: 4 additions & 0 deletions revibe/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ def run_cli(args: argparse.Namespace) -> None:
if args.enabled_tools:
config.enabled_tools = args.enabled_tools

if args.tool_format:
from revibe.core.config import ToolFormat
config.tool_format = ToolFormat(args.tool_format.lower())

loaded_messages = load_session(args, config)

stdin_prompt = get_prompt_from_stdin()
Expand Down
10 changes: 10 additions & 0 deletions revibe/cli/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ def parse_arguments() -> argparse.Namespace:
help="Run interactive setup: choose provider, theme, and configure API key",
)

parser.add_argument(
"--tool-format",
type=str,
choices=["native", "xml"],
default=None,
metavar="FORMAT",
help="Tool calling format: 'native' for API function calling (default), "
"'xml' for XML-based tool calling in prompts.",
)

continuation_group = parser.add_mutually_exclusive_group()
continuation_group.add_argument(
"-c",
Expand Down
1 change: 1 addition & 0 deletions revibe/cli/textual_ui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class BottomApp(StrEnum):
Model = auto()


# ruff: noqa: PLR0904
class VibeApp(App):
ENABLE_COMMAND_PALETTE = False
CSS_PATH = "app.tcss"
Expand Down
1 change: 0 additions & 1 deletion revibe/cli/textual_ui/terminal_theme.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

try:
import select
import termios

_UNIX_AVAILABLE = True
except ImportError:
Expand Down
40 changes: 35 additions & 5 deletions revibe/cli/textual_ui/widgets/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from textual.widgets._markdown import MarkdownStream

from revibe.cli.textual_ui.widgets.spinner import SpinnerMixin, SpinnerType
from revibe.core.utils import redact_xml_tool_calls


class NonSelectableStatic(Static):
Expand Down Expand Up @@ -63,6 +64,7 @@ class StreamingMessageBase(Static):
def __init__(self, content: str) -> None:
super().__init__()
self._content = content
self._displayed_content = ""
self._markdown: Markdown | None = None
self._stream: MarkdownStream | None = None

Expand All @@ -84,13 +86,35 @@ async def append_content(self, content: str) -> None:

self._content += content
if self._should_write_content():
await self._update_display()

async def _update_display(self) -> None:
new_displayed = self._process_content_for_display(self._content)

if len(new_displayed) > len(self._displayed_content):
# Append new content to stream
diff = new_displayed[len(self._displayed_content) :]
stream = self._ensure_stream()
await stream.write(content)
await stream.write(diff)
self._displayed_content = new_displayed
elif len(new_displayed) < len(self._displayed_content):
# Content shrunk (e.g. tag started), reset and re-render
if self._stream:
await self._stream.stop()
self._stream = None
if self._markdown:
await self._markdown.update("")
self._displayed_content = ""
# Recursively update with the now empty displayed content
await self._update_display()

def _process_content_for_display(self, content: str) -> str:
"""Process content before it is shown in the UI. Overridden by subclasses."""
return content

async def write_initial_content(self) -> None:
if self._content and self._should_write_content():
stream = self._ensure_stream()
await stream.write(self._content)
await self._update_display()

async def stop_stream(self) -> None:
if self._stream is None:
Expand All @@ -116,6 +140,9 @@ def compose(self) -> ComposeResult:
self._markdown = markdown
yield markdown

def _process_content_for_display(self, content: str) -> str:
return redact_xml_tool_calls(content)


class ReasoningMessage(SpinnerMixin, StreamingMessageBase):
SPINNER_TYPE = SpinnerType.LINE
Expand Down Expand Up @@ -176,8 +203,11 @@ async def set_collapsed(self, collapsed: bool) -> None:
await self._stream.stop()
self._stream = None
await self._markdown.update("")
stream = self._ensure_stream()
await stream.write(self._content)
self._displayed_content = ""
await self._update_display()

def _process_content_for_display(self, content: str) -> str:
return redact_xml_tool_calls(content)


class UserCommandMessage(Static):
Expand Down
2 changes: 0 additions & 2 deletions revibe/cli/textual_ui/widgets/welcome.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ class WelcomeBanner(Static):
COLOR_CACHE_THRESHOLD = 0.001
BORDER_PROGRESS_THRESHOLD = 0.01


def __init__(self, config: VibeConfig) -> None:
super().__init__(" ")
self.config = config
Expand Down Expand Up @@ -94,7 +93,6 @@ def _initialize_static_line_suffixes(self) -> None:
MODEL_COLOR = "#00D1FF"
STATS_COLOR = "#00FF94"
PATH_COLOR = "#B388FF"
DIM = "#6272A4"

self._static_line1_suffix = f"[{ACCENT}]✦[/] [b]ReVibe[/] [dim]v{__version__}[/]"
self._static_line2_suffix = (
Expand Down
Loading
Loading