v1.2.0
Co-Authored-By: Quentin Torroba <quentin.torroba@mistral.ai> Co-Authored-By: Michel Thomazo <michel.thomazo@mistral.ai> Co-Authored-By: Kracekumar <kracethekingmaker@gmail.com>
This commit is contained in:
parent
661588de0c
commit
d8dbeeb31e
91 changed files with 4521 additions and 873 deletions
|
|
@ -46,17 +46,23 @@ from acp.schema import (
|
|||
)
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
from vibe import VIBE_ROOT
|
||||
from vibe import VIBE_ROOT, __version__
|
||||
from vibe.acp.tools.base import BaseAcpTool
|
||||
from vibe.acp.tools.session_update import (
|
||||
tool_call_session_update,
|
||||
tool_result_session_update,
|
||||
)
|
||||
from vibe.acp.utils import TOOL_OPTIONS, ToolOption, VibeSessionMode
|
||||
from vibe.core import __version__
|
||||
from vibe.acp.utils import (
|
||||
TOOL_OPTIONS,
|
||||
ToolOption,
|
||||
acp_to_agent_mode,
|
||||
get_all_acp_session_modes,
|
||||
is_valid_acp_mode,
|
||||
)
|
||||
from vibe.core.agent import Agent as VibeAgent
|
||||
from vibe.core.autocompletion.path_prompt_adapter import render_path_prompt
|
||||
from vibe.core.config import MissingAPIKeyError, VibeConfig, load_api_keys_from_env
|
||||
from vibe.core.modes import AgentMode
|
||||
from vibe.core.tools.base import BaseToolConfig, ToolPermission
|
||||
from vibe.core.types import (
|
||||
ApprovalResponse,
|
||||
|
|
@ -72,7 +78,6 @@ class AcpSession(BaseModel):
|
|||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
id: str
|
||||
agent: VibeAgent
|
||||
mode_id: VibeSessionMode = VibeSessionMode.APPROVAL_REQUIRED
|
||||
task: asyncio.Task[None] | None = None
|
||||
|
||||
|
||||
|
|
@ -154,9 +159,11 @@ class VibeAcpAgent(AcpAgent):
|
|||
async def newSession(self, params: NewSessionRequest) -> NewSessionResponse:
|
||||
capability_disabled_tools = self._get_disabled_tools_from_capabilities()
|
||||
load_api_keys_from_env()
|
||||
|
||||
cwd = Path(params.cwd)
|
||||
try:
|
||||
config = VibeConfig.load(
|
||||
workdir=Path(params.cwd),
|
||||
workdir=cwd,
|
||||
tool_paths=[str(VIBE_ROOT / "acp" / "tools" / "builtins")],
|
||||
disabled_tools=capability_disabled_tools,
|
||||
)
|
||||
|
|
@ -165,7 +172,7 @@ class VibeAcpAgent(AcpAgent):
|
|||
"message": "You must be authenticated before creating a new session"
|
||||
}) from e
|
||||
|
||||
agent = VibeAgent(config=config, auto_approve=False, enable_streaming=True)
|
||||
agent = VibeAgent(config=config, mode=AgentMode.DEFAULT, enable_streaming=True)
|
||||
# NOTE: For now, we pin session.id to agent.session_id right after init time.
|
||||
# We should just use agent.session_id everywhere, but it can still change during
|
||||
# session lifetime (e.g. agent.compact is called).
|
||||
|
|
@ -188,8 +195,8 @@ class VibeAcpAgent(AcpAgent):
|
|||
],
|
||||
),
|
||||
modes=SessionModeState(
|
||||
currentModeId=session.mode_id,
|
||||
availableModes=VibeSessionMode.get_all_acp_session_modes(),
|
||||
currentModeId=session.agent.mode.value,
|
||||
availableModes=get_all_acp_session_modes(),
|
||||
),
|
||||
)
|
||||
return response
|
||||
|
|
@ -280,11 +287,21 @@ class VibeAcpAgent(AcpAgent):
|
|||
) -> SetSessionModeResponse | None:
|
||||
session = self._get_session(params.sessionId)
|
||||
|
||||
if not VibeSessionMode.is_valid(params.modeId):
|
||||
if not is_valid_acp_mode(params.modeId):
|
||||
return None
|
||||
|
||||
session.mode_id = VibeSessionMode(params.modeId)
|
||||
session.agent.auto_approve = params.modeId == VibeSessionMode.AUTO_APPROVE
|
||||
new_mode = acp_to_agent_mode(params.modeId)
|
||||
if new_mode is None:
|
||||
return None
|
||||
|
||||
await session.agent.switch_mode(new_mode)
|
||||
|
||||
if new_mode.auto_approve:
|
||||
session.agent.approval_callback = None
|
||||
else:
|
||||
session.agent.set_approval_callback(
|
||||
self._create_approval_callback(session.id)
|
||||
)
|
||||
|
||||
return SetSessionModeResponse()
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import argparse
|
|||
from dataclasses import dataclass
|
||||
import sys
|
||||
|
||||
from vibe.acp.acp_agent import run_acp_server
|
||||
from vibe.setup.onboarding import run_onboarding
|
||||
from vibe import __version__
|
||||
from vibe.core.paths.config_paths import unlock_config_paths
|
||||
|
||||
# Configure line buffering for subprocess communication
|
||||
sys.stdout.reconfigure(line_buffering=True) # pyright: ignore[reportAttributeAccessIssue]
|
||||
|
|
@ -20,12 +20,20 @@ class Arguments:
|
|||
|
||||
def parse_arguments() -> Arguments:
|
||||
parser = argparse.ArgumentParser(description="Run Mistral Vibe in ACP mode")
|
||||
parser.add_argument(
|
||||
"-v", "--version", action="version", version=f"%(prog)s {__version__}"
|
||||
)
|
||||
parser.add_argument("--setup", action="store_true", help="Setup API key and exit")
|
||||
args = parser.parse_args()
|
||||
return Arguments(setup=args.setup)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
unlock_config_paths()
|
||||
|
||||
from vibe.acp.acp_agent import run_acp_server
|
||||
from vibe.setup.onboarding import run_onboarding
|
||||
|
||||
args = parse_arguments()
|
||||
if args.setup:
|
||||
run_onboarding()
|
||||
|
|
|
|||
|
|
@ -1,47 +1,11 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
from enum import StrEnum
|
||||
from typing import Literal, cast
|
||||
|
||||
from acp.schema import PermissionOption, SessionMode
|
||||
|
||||
|
||||
class VibeSessionMode(enum.StrEnum):
|
||||
APPROVAL_REQUIRED = enum.auto()
|
||||
AUTO_APPROVE = enum.auto()
|
||||
|
||||
def to_acp_session_mode(self) -> SessionMode:
|
||||
match self:
|
||||
case self.APPROVAL_REQUIRED:
|
||||
return SessionMode(
|
||||
id=VibeSessionMode.APPROVAL_REQUIRED,
|
||||
name="Approval Required",
|
||||
description="Requires user approval for tool executions",
|
||||
)
|
||||
case self.AUTO_APPROVE:
|
||||
return SessionMode(
|
||||
id=VibeSessionMode.AUTO_APPROVE,
|
||||
name="Auto Approve",
|
||||
description="Automatically approves all tool executions",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_acp_session_mode(cls, session_mode: SessionMode) -> VibeSessionMode | None:
|
||||
if not cls.is_valid(session_mode.id):
|
||||
return None
|
||||
return cls(session_mode.id)
|
||||
|
||||
@classmethod
|
||||
def is_valid(cls, mode_id: str) -> bool:
|
||||
try:
|
||||
return cls(mode_id).to_acp_session_mode() is not None
|
||||
except (ValueError, KeyError):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def get_all_acp_session_modes(cls) -> list[SessionMode]:
|
||||
return [mode.to_acp_session_mode() for mode in cls]
|
||||
from vibe.core.modes import MODE_CONFIGS, AgentMode
|
||||
|
||||
|
||||
class ToolOption(StrEnum):
|
||||
|
|
@ -68,3 +32,22 @@ TOOL_OPTIONS = [
|
|||
kind=cast(Literal["reject_once"], ToolOption.REJECT_ONCE),
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def agent_mode_to_acp(mode: AgentMode) -> SessionMode:
|
||||
config = MODE_CONFIGS[mode]
|
||||
return SessionMode(
|
||||
id=mode.value, name=config.display_name, description=config.description
|
||||
)
|
||||
|
||||
|
||||
def acp_to_agent_mode(mode_id: str) -> AgentMode | None:
|
||||
return AgentMode.from_string(mode_id)
|
||||
|
||||
|
||||
def is_valid_acp_mode(mode_id: str) -> bool:
|
||||
return AgentMode.from_string(mode_id) is not None
|
||||
|
||||
|
||||
def get_all_acp_session_modes() -> list[SessionMode]:
|
||||
return [agent_mode_to_acp(mode) for mode in AgentMode]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue