v2.9.2 (#645)
Co-authored-by: Clément Drouin <clement.drouin@mistral.ai> Co-authored-by: Clément Sirieix <clement.sirieix@mistral.ai> Co-authored-by: Lucas Marandat <31749711+lucasmrdt@users.noreply.github.com> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
1fd7eea289
commit
3b8f65b306
16 changed files with 300 additions and 52 deletions
|
|
@ -3,4 +3,4 @@ from __future__ import annotations
|
|||
from pathlib import Path
|
||||
|
||||
VIBE_ROOT = Path(__file__).parent
|
||||
__version__ = "2.9.1"
|
||||
__version__ = "2.9.2"
|
||||
|
|
|
|||
|
|
@ -1357,8 +1357,8 @@ class VibeApp(App): # noqa: PLR0904
|
|||
teleport_msg.set_status("Syncing with remote...")
|
||||
case TeleportStartingWorkflowEvent():
|
||||
teleport_msg.set_status("Teleporting...")
|
||||
case TeleportWaitingForGitHubEvent():
|
||||
teleport_msg.set_status("Connecting to GitHub...")
|
||||
case TeleportWaitingForGitHubEvent(message=msg):
|
||||
teleport_msg.set_status(msg or "Connecting to GitHub...")
|
||||
case TeleportAuthRequiredEvent(oauth_url=url, message=msg):
|
||||
webbrowser.open(url)
|
||||
teleport_msg.set_status(msg or "Authorizing GitHub...")
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ from vibe.core.config.patch import (
|
|||
SetField,
|
||||
)
|
||||
from vibe.core.config.schema import (
|
||||
ConfigDefinitionError,
|
||||
ConfigFragment,
|
||||
ConfigSchema,
|
||||
DuplicateMergeMetadataError,
|
||||
MergeFieldMetadata,
|
||||
WithConcatMerge,
|
||||
|
|
@ -68,8 +71,11 @@ __all__ = [
|
|||
"DEFAULT_TTS_PROVIDERS",
|
||||
"THINKING_LEVELS",
|
||||
"AppendToList",
|
||||
"ConfigDefinitionError",
|
||||
"ConfigFragment",
|
||||
"ConfigLayer",
|
||||
"ConfigLayerError",
|
||||
"ConfigSchema",
|
||||
"ConnectorConfig",
|
||||
"DeleteField",
|
||||
"DuplicateMergeMetadataError",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
|||
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic.fields import FieldInfo
|
||||
|
||||
from vibe.core.utils.merge import MergeStrategy
|
||||
|
|
@ -11,6 +12,61 @@ class DuplicateMergeMetadataError(TypeError):
|
|||
"""Raised when a field declares more than one MergeFieldMetadata marker."""
|
||||
|
||||
|
||||
class ConfigDefinitionError(TypeError):
|
||||
"""Raised when a config schema or fragment is declared with invalid fields."""
|
||||
|
||||
|
||||
class ConfigSchema(BaseModel):
|
||||
"""Base for composite config schemas composed of fragments and merge-aware fields."""
|
||||
|
||||
@classmethod
|
||||
def __pydantic_on_complete__(cls) -> None:
|
||||
super().__pydantic_on_complete__()
|
||||
|
||||
if cls.__name__ == "ConfigSchema" and cls.__module__ == __name__:
|
||||
return
|
||||
|
||||
for field_name, field_info in cls.model_fields.items():
|
||||
has_merge_metadata = MergeFieldMetadata.from_field(field_info) is not None
|
||||
is_fragment = isinstance(field_info.annotation, type) and issubclass(
|
||||
field_info.annotation, ConfigFragment
|
||||
)
|
||||
|
||||
if is_fragment and has_merge_metadata:
|
||||
raise ConfigDefinitionError(
|
||||
f"{cls.__name__}.{field_name} is a ConfigFragment field and "
|
||||
"must not declare merge metadata"
|
||||
)
|
||||
|
||||
if is_fragment or has_merge_metadata:
|
||||
continue
|
||||
|
||||
raise ConfigDefinitionError(
|
||||
f"{cls.__name__}.{field_name} must declare merge metadata or use a "
|
||||
"ConfigFragment subclass"
|
||||
)
|
||||
|
||||
|
||||
class ConfigFragment(BaseModel):
|
||||
"""Base for domain config groups with merge-aware top-level fields."""
|
||||
|
||||
@classmethod
|
||||
def __pydantic_on_complete__(cls) -> None:
|
||||
super().__pydantic_on_complete__()
|
||||
|
||||
if cls.__name__ == "ConfigFragment" and cls.__module__ == __name__:
|
||||
return
|
||||
|
||||
for field_name, field_info in cls.model_fields.items():
|
||||
if MergeFieldMetadata.from_field(field_info) is not None:
|
||||
continue
|
||||
|
||||
raise ConfigDefinitionError(
|
||||
f"{cls.__name__}.{field_name} must declare merge metadata via "
|
||||
"MergeFieldMetadata"
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class MergeFieldMetadata:
|
||||
"""Base Pydantic Annotated marker that declares how a config field merges across layers.
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ class TextOutputFormatter(OutputFormatter):
|
|||
self._print("Syncing with remote...")
|
||||
case TeleportStartingWorkflowEvent():
|
||||
self._print("Teleporting...")
|
||||
case TeleportWaitingForGitHubEvent():
|
||||
self._print("Connecting to GitHub...")
|
||||
case TeleportWaitingForGitHubEvent(message=msg):
|
||||
self._print(msg or "Connecting to GitHub...")
|
||||
case TeleportAuthRequiredEvent(oauth_url=url, message=msg):
|
||||
self._print(msg or f"Open to authorize GitHub: {url}")
|
||||
case TeleportAuthCompleteEvent():
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import AsyncGenerator
|
||||
from enum import StrEnum, auto
|
||||
import time
|
||||
import types
|
||||
|
|
@ -184,12 +185,13 @@ class NuageClient:
|
|||
|
||||
async def wait_for_github_connection(
|
||||
self, execution_id: str, timeout: float = 600.0, interval: float = 2.0
|
||||
) -> GitHubPublicData:
|
||||
) -> AsyncGenerator[GitHubPublicData, None]:
|
||||
deadline = time.monotonic() + timeout
|
||||
while time.monotonic() < deadline:
|
||||
github_data = await self.get_github_integration(execution_id)
|
||||
yield github_data
|
||||
if github_data.connected:
|
||||
return github_data
|
||||
return
|
||||
if github_data.is_error:
|
||||
raise ServiceTeleportError(
|
||||
github_data.error
|
||||
|
|
|
|||
|
|
@ -184,15 +184,22 @@ class TeleportService:
|
|||
)
|
||||
|
||||
yield TeleportWaitingForGitHubEvent()
|
||||
github_data = await self._nuage_client.get_github_integration(execution_id)
|
||||
|
||||
if not github_data.connected:
|
||||
if github_data.oauth_url:
|
||||
auth_event_sent = False
|
||||
async for github_data in self._nuage_client.wait_for_github_connection(
|
||||
execution_id
|
||||
):
|
||||
if github_data.connected:
|
||||
break
|
||||
if not auth_event_sent and github_data.oauth_url:
|
||||
yield TeleportAuthRequiredEvent(
|
||||
oauth_url=github_data.oauth_url, message=github_data.error
|
||||
)
|
||||
await self._nuage_client.wait_for_github_connection(execution_id)
|
||||
yield TeleportAuthCompleteEvent()
|
||||
auth_event_sent = True
|
||||
if github_data.error:
|
||||
yield TeleportWaitingForGitHubEvent(message=github_data.error)
|
||||
|
||||
yield TeleportAuthCompleteEvent()
|
||||
|
||||
yield TeleportFetchingUrlEvent()
|
||||
chat_url = await self._nuage_client.get_chat_assistant_url(execution_id)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class TeleportPushingEvent(BaseEvent):
|
|||
|
||||
|
||||
class TeleportWaitingForGitHubEvent(BaseEvent):
|
||||
pass
|
||||
message: str | None = None
|
||||
|
||||
|
||||
class TeleportFetchingUrlEvent(BaseEvent):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue