From 5a1bd9cd173c865366ebe91c19ba0ae6e5e0248a Mon Sep 17 00:00:00 2001 From: Allen Wang Date: Thu, 27 Aug 2026 11:50:09 +0800 Subject: [PATCH 1/2] fix: update ScenarioProvider to inherit from _SampleChatProvider --- .../chat_provider/scenario_provider.py | 98 ++++++++++++++----- 1 file changed, 75 insertions(+), 23 deletions(-) diff --git a/src/mitocode/backend/chat_provider/scenario_provider.py b/src/mitocode/backend/chat_provider/scenario_provider.py index 30b7ab0..e1fd5c0 100644 --- a/src/mitocode/backend/chat_provider/scenario_provider.py +++ b/src/mitocode/backend/chat_provider/scenario_provider.py @@ -1,5 +1,3 @@ -"""旧实现,与现有ABC不符,已弃用,请勿参考!""" - """Scripted mock provider replaying a fixed multi-turn tool-call demo. Used for offline demos and TUI development: each ``chat`` call plays back @@ -9,7 +7,10 @@ import asyncio import json from types import SimpleNamespace -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, AsyncGenerator + +from mitocode.backend.chat_provider.sample_chat_provider import _SampleChatProvider + def _make_chunk( @@ -139,52 +140,84 @@ def _chunk_tool_call( return chunks -class ScenarioProvider: +class ScenarioProvider(_SampleChatProvider): """Mock provider that plays back a multi-turn tool-call scenario. Each call to :meth:`chat` advances an internal turn counter and returns - the next pre-recorded stream: markdown text, bash, write_file, read_file + the next pre-recorded stream: markdown text, bash / write_file / read_file tool calls with bubble sort code. """ - def __init__(self, delay: float = 0.03): + def __init__( + self, + default_model: str = "scenario-model", + default_model_list: Optional[List[str]] = None, + default_messages: Optional[List[Dict]] = None, + default_tools: Optional[List[Dict]] = None, + stream: bool = True, + settings: Optional[Dict[str, Any]] = None, + delay: float = 0.03, + ): """Initialize the provider with an inter-chunk streaming delay. Args: delay: Seconds to sleep between yielded chunks (default 0.03). """ + if default_model_list is None: + default_model_list = ["scenario-model"] + super().__init__( + default_model=default_model, + default_model_list=default_model_list, + default_messages=default_messages, + default_tools=default_tools, + stream=stream, + settings=settings, + ) self.turn = 0 self._delay = delay - @staticmethod - def get_model_list(): - """Return the model identifiers accepted by this provider.""" - return ["scenario-model"] + @classmethod + async def factory(cls, *args, **kwargs) -> "ScenarioProvider": + """Create and initialize a provider instance asynchronously.""" + ins = cls(*args, **kwargs) + await ins.init() + return ins @classmethod - def get_settings_schema(cls): + def get_settings_schema(cls) -> Dict[str, Any]: """Return the JSON Schema describing accepted settings.""" return { "type": "object", - "properties": {}, + "properties": { + "delay": {"type": "number", "minimum": 0, "default": 0.03}, + }, "additionalProperties": True, } - @staticmethod - def check_settings_schema(settings): - """Validate that *settings* is a dict; any keys are allowed.""" - return isinstance(settings, dict) + @classmethod + def check_settings_schema(cls, settings: Any) -> bool: + """Validate that *settings* is a dict with optional delay.""" + if not isinstance(settings, dict): + return False + delay = settings.get("delay", 0.03) + return isinstance(delay, (int, float)) and delay >= 0 + + async def get_model_list(self) -> List[str]: + """Return the model identifiers accepted by this provider.""" + return ["scenario-model"] - def init(self): + async def init(self) -> None: """No-op initialization hook kept for provider interface parity.""" - pass + delay = self.settings.get("delay", 0.03) if self.settings else 0.03 + self._delay = delay async def chat( self, - tools: Optional[list] = None, - messages: Optional[List[Dict[str, Any]]] = None, - **kwargs, - ): + model: str = "", + tools: Optional[List[Dict]] = None, + messages: Optional[List[Dict]] = None, + stream: bool = True, + ) -> AsyncGenerator | Dict: """Return an async stream playing back the next scripted turn. Each invocation advances the internal turn counter: turns 0-2 emit @@ -231,4 +264,23 @@ async def _stream(): yield c await asyncio.sleep(self._delay) - return _stream() + if stream: + return _stream() + + full_content = "" + for c in chunks: + if c.choices[0].delta.content: + full_content += c.choices[0].delta.content + return { + "choices": [ + { + "message": { + "role": "assistant", + "content": full_content, + }, + "finish_reason": "stop", + "index": 0, + } + ], + "model": model or self.default_model, + } From b80eaad992e4861b2d2f470b1505882fadc4a1d9 Mon Sep 17 00:00:00 2001 From: Allen Wang Date: Thu, 27 Aug 2026 11:50:42 +0800 Subject: [PATCH 2/2] feat: integrate ChatProviderOpenAI for enhanced chat capabilities --- src/mitocode/__main__.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/mitocode/__main__.py b/src/mitocode/__main__.py index 94bad04..0a0fa30 100644 --- a/src/mitocode/__main__.py +++ b/src/mitocode/__main__.py @@ -2,9 +2,13 @@ import argparse import asyncio +from pyexpat.errors import messages + +from httpx import stream from mitocode.backend.agent.agent_orchestrator import AgentOrchestrator from mitocode.backend.chat_provider.scenario_provider import ScenarioProvider +from mitocode.backend.chat_provider.chat_provider_openai import ChatProviderOpenAI from mitocode.backend.tool.tool_manager import ToolManager from mitocode.tui.ui_main import VibeFrontend @@ -65,7 +69,28 @@ def main(): tool_manager = ToolManager() _register_tools(tool_manager) - provider = ScenarioProvider(delay=args.speed) + provider = asyncio.run(ChatProviderOpenAI.factory( + default_model= "nvidia/nemotron-3.5-lightning:free", + default_model_list= None, + default_messages= None, + default_tools= None, + stream= True, + settings={ + "api_key": "sk-别看了这次我不会再把key提交到仓库了!", + "base_url": "https://openrouter.ai/api/v1", + "timeout": 60, + }) + ) + + # print(asyncio.run(provider.chat( + # model ="nvidia/nemotron-3.5-lightning:free", + # tools =None, + # messages = [ + # {"role": "system", "content": "You are a helpful assistant."}, + # {"role": "user", "content": "Hello!"} + # ], + # stream = False + # ))) orchestrator = AgentOrchestrator( tool_manager=tool_manager, default_provider=provider