{"id":478130,"date":"2026-04-30T14:35:19","date_gmt":"2026-04-30T14:35:19","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=478130"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=478130","title":{"rendered":"\u041c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u0435 \u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u044b\u0445 \u043c\u0430\u0448\u0438\u043d: \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0418\u0418-\u0430\u0433\u0435\u043d\u0442\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044f"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e61\/fdf\/882\/e61fdf8826b06bb81dc57bb8244edec9.png\" width=\"2048\" height=\"2048\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/e61\/fdf\/882\/e61fdf8826b06bb81dc57bb8244edec9.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e61\/fdf\/882\/e61fdf8826b06bb81dc57bb8244edec9.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041c\u044b \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438, \u0447\u0442\u043e \u0418\u0418-\u0430\u0433\u0435\u043d\u0442\u044b \u2014 \u044d\u0442\u043e \u043f\u0440\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c. \u0411\u044b\u0441\u0442\u0440\u0435\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434, \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c, \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041d\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0431\u0435\u0437 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f \u2014 \u044d\u0442\u043e \u043d\u0435 \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442, \u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441. \u041d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u043f\u0440\u043e\u0440\u044b\u0432 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043a\u043e\u0433\u0434\u0430 \u0430\u0433\u0435\u043d\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 <strong>\u0434\u0443\u043c\u0430\u0442\u044c, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c<\/strong>. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u0435\u0431\u044f \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0448\u0430\u0433\u0430. \u0421\u043e\u043c\u043d\u0435\u0432\u0430\u0442\u044c\u0441\u044f. \u0421\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u0418 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u044e\u0442 \u0432 \u0442\u0435\u043e\u0440\u0438\u0438. \u041d\u043e \u0441\u0442\u043e\u0438\u0442 \u0434\u0430\u0442\u044c \u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043c\u0438\u0440\u0443, \u043a\u0430\u043a \u043f\u0440\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438: \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0430\u0446\u0438\u0438, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0451\u043d\u043d\u044b\u0435 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f; \u043a\u0430\u0441\u043a\u0430\u0434\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u0433\u0434\u0435 \u043e\u0434\u043d\u0430 \u043d\u0435\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u0442\u044f\u043d\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439; \u0441\u043b\u0435\u043f\u043e\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0446\u0435\u043b\u0438 \u0441 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432; \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u0430\u043c\u043e\u043a\u0440\u0438\u0442\u0438\u043a\u0438. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u043d\u0435 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0443\u043c\u043d\u0435\u0435. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 <strong>\u0432 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435<\/strong>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0435 \u0432 \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u0432\u0435\u043d\u043e \u0446\u0438\u043a\u043b\u0430 \u00ab\u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u2192 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u2192 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u2192 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u00bb.<\/p>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u2014 \u043f\u0440\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0431\u0435\u0437\u0434\u0443\u043c\u043d\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 <strong>\u043c\u044b\u0441\u043b\u044f\u0449\u0435\u0433\u043e \u043a\u043e\u043b\u043b\u0435\u0433\u0443<\/strong>. \u0418 \u043e\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043a\u043e\u0434\u043e\u043c, \u0430 \u043a \u043b\u044e\u0431\u043e\u043c\u0443 \u0434\u043e\u043c\u0435\u043d\u0443, \u0433\u0434\u0435 \u0446\u0435\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u044b\u0441\u043e\u043a\u0430: \u044e\u0440\u0438\u0441\u043f\u0440\u0443\u0434\u0435\u043d\u0446\u0438\u044f, \u043c\u0435\u0434\u0438\u0446\u0438\u043d\u0430, \u0444\u0438\u043d\u0430\u043d\u0441\u044b, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439, \u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<h2>\ud83d\udc0d \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0418\u0418-\u0430\u0433\u0435\u043d\u0442\u0430 \u043d\u0430 Python<\/h2>\n<h3>\ud83d\udcc1 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h3>\n<pre><code>reflective_agent\/\u251c\u2500\u2500 core\/\u2502   \u251c\u2500\u2500 __init__.py\u2502   \u251c\u2500\u2500 agent.py           # \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b \u0430\u0433\u0435\u043d\u0442\u0430\u2502   \u251c\u2500\u2500 context.py         # \u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u2502   \u251c\u2500\u2500 state.py           # \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c\u2502   \u2514\u2500\u2500 types.py           # \u0422\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445\u251c\u2500\u2500 tools\/\u2502   \u251c\u2500\u2500 __init__.py\u2502   \u251c\u2500\u2500 base.py            # \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432\u2502   \u251c\u2500\u2500 filesystem.py      # \u0424\u0430\u0439\u043b\u043e\u0432\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u2502   \u251c\u2500\u2500 terminal.py        # \u0422\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b\u2502   \u2514\u2500\u2500 mcp_adapter.py     # MCP \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u251c\u2500\u2500 safety\/\u2502   \u251c\u2500\u2500 __init__.py\u2502   \u251c\u2500\u2500 jail.py            # Scope Jail\u2502   \u251c\u2500\u2500 detectors.py       # \u0414\u0435\u0442\u0435\u043a\u0446\u0438\u044f \u0446\u0438\u043a\u043b\u043e\u0432\u2502   \u2514\u2500\u2500 snapshots.py       # \u0421\u043d\u0430\u043f\u0448\u043e\u0442\u044b \u0438 \u043e\u0442\u043a\u0430\u0442\u251c\u2500\u2500 ui\/\u2502   \u251c\u2500\u2500 __init__.py\u2502   \u2514\u2500\u2500 console.py         # \u041a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u2514\u2500\u2500 main.py                # \u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\ud83d\udce6 \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<pre><code class=\"python\"># core\/types.pyfrom dataclasses import dataclass, fieldfrom typing import Any, Optional, List, Dict, Literalfrom datetime import datetimefrom enum import Enumclass AgentMode(Enum):    CHAT = \"chat\"    AGENT = \"agent\"    TERMINAL = \"terminal\"class ToolRisk(Enum):    SAFE_READ = \"safe_read\"      # \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438    MODIFY = \"modify\"            # \u0427\u0435\u0440\u043d\u043e\u0432\u0438\u043a    DESTRUCTIVE = \"destructive\"  # \u0422\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f@dataclassclass Message:    role: Literal[\"user\", \"assistant\", \"system\", \"tool\"]    content: Optional[str]    timestamp: float = field(default_factory=datetime.now().timestamp)    tool_calls: Optional[List[Dict]] = None    tool_call_id: Optional[str] = None    name: Optional[str] = None    requires_action: Optional[str] = None@dataclassclass ToolCall:    id: str    name: str    arguments: Dict[str, Any]    risk: ToolRisk@dataclassclass Draft:    file_path: str    original_content: str    new_content: str    status: Literal[\"pending\", \"accepted\", \"rejected\"] = \"pending\"@dataclassclass Snapshot:    id: str    timestamp: float    files: Dict[str, str]    messages: List[Message]    drafts: List[Draft]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\ud83e\udde0 \u042f\u0434\u0440\u043e \u0430\u0433\u0435\u043d\u0442\u0430<\/h3>\n<pre><code class=\"python\"># core\/agent.pyimport asyncioimport jsonimport hashlibfrom typing import List, Optional, Dict, Any, Callablefrom datetime import datetimefrom openai import AsyncOpenAIfrom .types import (    AgentMode, Message, ToolCall, Draft, Snapshot, ToolRisk)from .context import DynamicContextfrom .state import AgentStatefrom safety.jail import ScopeJailfrom safety.detectors import LoopDetector, IterationLimiterfrom safety.snapshots import SnapshotManagerfrom tools.base import ToolRegistryclass ReflectiveAgent:    \"\"\"\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0418\u0418-\u0430\u0433\u0435\u043d\u0442 \u0441 \u0441\u0435\u043c\u0438\u0441\u0442\u0443\u043f\u0435\u043d\u0447\u0430\u0442\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c\"\"\"        def __init__(        self,        model: str = \"gpt-4\",        api_key: str = None,        max_iterations: int = 15,        require_confirmation: bool = True    ):        self.client = AsyncOpenAI(api_key=api_key)        self.model = model        self.state = AgentState()        self.context = DynamicContext()        self.tools = ToolRegistry()        self.jail = ScopeJail()        self.loop_detector = LoopDetector(max_repeats=3)        self.iteration_limiter = IterationLimiter(max_iterations)        self.snapshot_manager = SnapshotManager()        self.require_confirmation = require_confirmation                # \u0424\u043b\u0430\u0433\u0438        self.is_reflecting = False        self._abort_controller = False            async def run(self, user_input: str) -&gt; None:        \"\"\"\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0430\u0433\u0435\u043d\u0442\u0430\"\"\"                # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043d\u0430\u043f\u0448\u043e\u0442 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c        await self.snapshot_manager.create_snapshot(self.state)                # \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f        user_message = Message(            role=\"user\",            content=user_input,            timestamp=datetime.now().timestamp()        )        self.state.add_message(user_message)                # \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b        await self._run_cycle(depth=1)        async def _run_cycle(self, depth: int) -&gt; None:        \"\"\"\u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f\"\"\"                # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f        if self._abort_controller:            return                # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043b\u0438\u043c\u0438\u0442\u0430 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439        if not self.iteration_limiter.can_continue(depth):            await self._handle_iteration_limit()            return                try:            # 1. \u0412\u041e\u0421\u041f\u0420\u0418\u042f\u0422\u0418\u0415 - \u0421\u0431\u043e\u0440 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430            context = await self.context.build_context(self.state)                        # 2. \u041f\u041b\u0410\u041d\u0418\u0420\u041e\u0412\u0410\u041d\u0418\u0415 - \u0412\u044b\u0437\u043e\u0432 LLM            response = await self._call_llm(context)                        # \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u0430            assistant_msg = Message(                role=\"assistant\",                content=response.get(\"content\"),                tool_calls=response.get(\"tool_calls\")            )            self.state.add_message(assistant_msg)                        # 3. \u041e\u0411\u0420\u0410\u0411\u041e\u0422\u041a\u0410 TOOL CALLS            if response.get(\"tool_calls\"):                await self._process_tool_calls(response[\"tool_calls\"])                                # \u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0448\u0430\u0433\u0430                await self._run_cycle(depth + 1)            else:                # \u041d\u0435\u0442 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 -&gt; \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435                await self._complete_task()                        except Exception as e:            await self._handle_error(e, depth)        async def _call_llm(self, context: str) -&gt; Dict[str, Any]:        \"\"\"\u0412\u044b\u0437\u043e\u0432 LLM \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c \u043f\u0440\u043e\u043c\u043f\u0442\u043e\u043c \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438\"\"\"                messages = [            {\"role\": \"system\", \"content\": self._build_system_prompt()},            *[self._serialize_message(m) for m in self.state.messages]        ]                # \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043a\u0430\u043a \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435        messages.insert(1, {\"role\": \"system\", \"content\": context})                tools = self.tools.get_openai_schema()                response = await self.client.chat.completions.create(            model=self.model,            messages=messages,            tools=tools if tools else None,            tool_choice=\"auto\" if tools else None,            temperature=0.3        )                message = response.choices[0].message                result = {\"content\": message.content or \"\"}                if message.tool_calls:            result[\"tool_calls\"] = [                {                    \"id\": tc.id,                    \"name\": tc.function.name,                    \"arguments\": json.loads(tc.function.arguments)                }                for tc in message.tool_calls            ]                return result        async def _process_tool_calls(self, tool_calls: List[Dict]) -&gt; None:        \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432\"\"\"                for tool_call in tool_calls:            if self._abort_controller:                break                        # 4. \u0428\u041b\u042e\u0417 - \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438            risk = self.tools.get_risk(tool_call[\"name\"])                        if risk == ToolRisk.DESTRUCTIVE and self.require_confirmation:                # \u041f\u0430\u0443\u0437\u0430, \u0436\u0434\u0435\u043c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f                await self._request_confirmation(tool_call)                return  # \u0412\u044b\u0445\u043e\u0434 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430, \u0436\u0434\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0435                        # 5. \u0414\u0415\u0422\u0415\u041a\u0426\u0418\u042f \u0417\u0410\u0426\u0418\u041a\u041b\u0418\u0412\u0410\u041d\u0418\u0419            signature = self._get_tool_signature(tool_call)            if self.loop_detector.check(signature):                await self._handle_loop_detected(tool_call)                return                        # 6. Scope Jail - \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u0440\u0430\u043d\u0438\u0446            if not await self.jail.check_permissions(tool_call):                await self._handle_access_denied(tool_call)                continue                        # 7. \u0412\u042b\u041f\u041e\u041b\u041d\u0415\u041d\u0418\u0415 \u0418\u041d\u0421\u0422\u0420\u0423\u041c\u0415\u041d\u0422\u0410            result = await self.tools.execute(                tool_call[\"name\"],                tool_call[\"arguments\"],                is_draft=(risk == ToolRisk.MODIFY)            )                        # \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442            tool_msg = Message(                role=\"tool\",                content=result,                tool_call_id=tool_call[\"id\"],                name=tool_call[\"name\"]            )            self.state.add_message(tool_msg)        async def _complete_task(self) -&gt; None:        \"\"\"\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u0444\u0430\u0437\u043e\u0439 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438\"\"\"                if not self.is_reflecting:            # \u0424\u0410\u0417\u0410 \u0420\u0415\u0424\u041b\u0415\u041a\u0421\u0418\u0418            self.is_reflecting = True                        # \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0441\u0430\u043c\u043e\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443            reflection_msg = Message(                role=\"system\",                content=\"\ud83d\udd04 **SELF-REFLECTION PHASE**\\n\\n\"                        \"\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443:\\n\"                        \"1. \u0412\u0441\u0435 \u043b\u0438 \u0448\u0430\u0433\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044b?\\n\"                        \"2. \u041d\u0435\u0442 \u043b\u0438 \u043e\u0448\u0438\u0431\u043e\u043a \u0438\u043b\u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043e\u0432?\\n\"                        \"3. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b - \u0438\u0441\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u0438\u0445\\n\"                        \"4. \u0415\u0441\u043b\u0438 \u0432\u0441\u0451 \u0432\u0435\u0440\u043d\u043e - \u0432\u044b\u0437\u043e\u0432\u0438\u0442\u0435 task_completed(verified=true)\",                requires_action=\"reflect\"            )            self.state.add_message(reflection_msg)                        # \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0446\u0438\u043a\u043b \u0434\u043b\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438            await self._run_cycle(depth=self.state.current_depth + 1)        else:            # \u0424\u0418\u041d\u0410\u041b\u042c\u041d\u041e\u0415 \u0417\u0410\u0412\u0415\u0420\u0428\u0415\u041d\u0418\u0415            if self.state.drafts:                # \u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043e\u043a\u043d\u043e \u0440\u0435\u0432\u044c\u044e                await self._show_review_modal()                        print(\"\\n\u2705 \u0417\u0430\u0434\u0430\u0447\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430!\")            print(f\"\ud83d\udcca \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430: {self.state.get_stats()}\")            self.is_reflecting = False        def _build_system_prompt(self) -&gt; str:        \"\"\"\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u043f\u0442\u0430\"\"\"        return \"\"\"\u0422\u042b - \u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0418\u0418-\u0430\u0433\u0435\u043d\u0442. \u0422\u0432\u043e\u044f \u0437\u0430\u0434\u0430\u0447\u0430 - \u043f\u043e\u043c\u043e\u0433\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b.\u041f\u0420\u0410\u0412\u0418\u041b\u0410:1. \u041f\u0435\u0440\u0435\u0434 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c \u043e\u0431\u044a\u044f\u0441\u043d\u0438, \u0447\u0442\u043e \u0442\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0448\u044c\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c2. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 create_plan \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u04473. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0439 \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435\u043c4. \u041d\u0435 \u0433\u0430\u0434\u0430\u0439 - \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438\u0414\u041e\u0421\u0422\u0423\u041f\u041d\u042b\u0415 \u041f\u0420\u0418\u041d\u0426\u0418\u041f\u042b:- \u0427\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u0438: \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u0434\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f- \u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f: \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0439 \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443- \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c: \u043d\u0435 \u0432\u044b\u0445\u043e\u0434\u0438 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u0445 \u0433\u0440\u0430\u043d\u0438\u0446\"\"\"        async def _request_confirmation(self, tool_call: Dict) -&gt; None:        \"\"\"\u0417\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\"\"\"                self.state.pending_confirmation = tool_call                print(f\"\\n\u26a0\ufe0f  \u0422\u0420\u0415\u0411\u0423\u0415\u0422\u0421\u042f \u041f\u041e\u0414\u0422\u0412\u0415\u0420\u0416\u0414\u0415\u041d\u0418\u0415\")        print(f\"\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442: {tool_call['name']}\")        print(f\"\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b: {json.dumps(tool_call['arguments'], indent=2, ensure_ascii=False)}\")                # \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0437\u0434\u0435\u0441\u044c \u0431\u044b\u043b \u0431\u044b UI        # \u0414\u043b\u044f \u043a\u043e\u043d\u0441\u043e\u043b\u0438 - \u0436\u0434\u0435\u043c \u0432\u0432\u043e\u0434\u0430        response = input(\"\\n\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c? (y\/n): \").lower()                if response == 'y':            await self.confirm_action()        else:            await self.reject_action()        async def confirm_action(self) -&gt; None:        \"\"\"\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\"\"\"                if not self.state.pending_confirmation:            return                tool_call = self.state.pending_confirmation        self.state.pending_confirmation = None                # \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435        result = await self.tools.execute(            tool_call[\"name\"],            tool_call[\"arguments\"],            is_draft=False  # \u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435        )                tool_msg = Message(            role=\"tool\",            content=result,            tool_call_id=tool_call[\"id\"],            name=tool_call[\"name\"]        )        self.state.add_message(tool_msg)                # \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0446\u0438\u043a\u043b        await self._run_cycle(self.state.current_depth + 1)        async def reject_action(self) -&gt; None:        \"\"\"\u041e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\"\"\"                if not self.state.pending_confirmation:            return                tool_call = self.state.pending_confirmation        self.state.pending_confirmation = None                tool_msg = Message(            role=\"tool\",            content=\"\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c\",            tool_call_id=tool_call[\"id\"],            name=tool_call[\"name\"]        )        self.state.add_message(tool_msg)                await self._run_cycle(self.state.current_depth + 1)        def stop(self) -&gt; None:        \"\"\"\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0430\u0433\u0435\u043d\u0442\u0430\"\"\"        self._abort_controller = True        async def _handle_error(self, error: Exception, depth: int) -&gt; None:        \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0441 \u0430\u0432\u0442\u043e-\u043f\u043e\u0432\u0442\u043e\u0440\u043e\u043c\"\"\"                if self.state.retry_count &lt; 2:            self.state.retry_count += 1            delay = 5  # \u0441\u0435\u043a\u0443\u043d\u0434                        print(f\"\u26a0\ufe0f \u041e\u0448\u0438\u0431\u043a\u0430: {error}. \u041f\u043e\u0432\u0442\u043e\u0440 \u0447\u0435\u0440\u0435\u0437 {delay}\u0441...\")            await asyncio.sleep(delay)                        # \u041f\u043e\u0432\u0442\u043e\u0440 \u0441 \u0442\u043e\u0439 \u0436\u0435 \u0433\u043b\u0443\u0431\u0438\u043d\u043e\u0439            await self._run_cycle(depth)        else:            print(f\"\u274c \u041a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430: {error}\")            self.state.add_message(Message(                role=\"system\",                content=f\"\u041e\u0448\u0438\u0431\u043a\u0430: {error}\"            ))        def _get_tool_signature(self, tool_call: Dict) -&gt; str:        \"\"\"\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u0434\u0435\u0442\u0435\u043a\u0446\u0438\u0438 \u0446\u0438\u043a\u043b\u043e\u0432\"\"\"        content = f\"{tool_call['name']}:{json.dumps(tool_call['arguments'], sort_keys=True)}\"        return hashlib.md5(content.encode()).hexdigest()        async def _show_review_modal(self) -&gt; None:        \"\"\"\u041f\u043e\u043a\u0430\u0437 \u043e\u043a\u043d\u0430 \u0440\u0435\u0432\u044c\u044e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439\"\"\"                print(\"\\n\ud83d\udcdd \u0418\u0417\u041c\u0415\u041d\u0415\u041d\u0418\u042f \u0412 \u0427\u0415\u0420\u041d\u041e\u0412\u0418\u041a\u0410\u0425:\")        for i, draft in enumerate(self.state.drafts):            print(f\"\\n{i+1}. {draft.file_path}\")            print(f\"   \u0421\u0442\u0430\u0442\u0443\u0441: {draft.status}\")            print(f\"   \u0420\u0430\u0437\u043c\u0435\u0440: {len(draft.new_content)} \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\")                response = input(\"\\n\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f? (y\/n): \").lower()                if response == 'y':            await self._commit_drafts()        else:            await self._rollback()        async def _commit_drafts(self) -&gt; None:        \"\"\"\u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u043e\u0432\"\"\"        for draft in self.state.drafts:            if draft.status == \"pending\":                await self.tools.apply_draft(draft)                draft.status = \"accepted\"                print(\"\u2705 \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u044b\")        async def _rollback(self) -&gt; None:        \"\"\"\u041e\u0442\u043a\u0430\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439\"\"\"        await self.snapshot_manager.restore_snapshot(self.state)        print(\"\u21a9\ufe0f \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u044b\")        async def _handle_iteration_limit(self) -&gt; None:        \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u044f \u043b\u0438\u043c\u0438\u0442\u0430 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439\"\"\"        print(f\"\\n\u26a0\ufe0f \u0414\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 \u043b\u0438\u043c\u0438\u0442 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 ({self.iteration_limiter.max_iterations})\")                response = input(\"\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c? (y\/n): \").lower()                if response == 'y':            self.iteration_limiter.reset()            await self._run_cycle(depth=1)        else:            self.stop()        async def _handle_loop_detected(self, tool_call: Dict) -&gt; None:        \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430\"\"\"        print(f\"\\n\ud83d\udd04 \u041e\u0411\u041d\u0410\u0420\u0423\u0416\u0415\u041d \u0426\u0418\u041a\u041b: {tool_call['name']}\")        print(\"\u0410\u0433\u0435\u043d\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442 \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\")        self.stop()        async def _handle_access_denied(self, tool_call: Dict) -&gt; None:        \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430\"\"\"        print(f\"\\n\ud83d\udeab \u0414\u041e\u0421\u0422\u0423\u041f \u0417\u0410\u041f\u0420\u0415\u0429\u0415\u041d: {tool_call['name']}\")        print(f\"\u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u0432\u044b\u0445\u043e\u0434\u0430 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u043e\u0439 \u0437\u043e\u043d\u044b\")                self.state.add_message(Message(            role=\"system\",            content=f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430: {tool_call['name']} - \u0432\u044b\u0445\u043e\u0434 \u0437\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b\"        ))        def _serialize_message(self, msg: Message) -&gt; Dict:        \"\"\"\u0421\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u043b\u044f OpenAI API\"\"\"        result = {\"role\": msg.role}                if msg.content:            result[\"content\"] = msg.content        if msg.tool_calls:            result[\"tool_calls\"] = msg.tool_calls        if msg.tool_call_id:            result[\"tool_call_id\"] = msg.tool_call_id        if msg.name:            result[\"name\"] = msg.name                return result<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\ud83d\udee0\ufe0f \u0411\u0430\u0437\u043e\u0432\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b<\/h3>\n<pre><code class=\"python\"># tools\/base.pyfrom abc import ABC, abstractmethodfrom typing import Dict, Any, List, Optionalfrom core.types import ToolRiskclass BaseTool(ABC):    \"\"\"\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432\"\"\"        def __init__(self, name: str, description: str, risk: ToolRisk):        self.name = name        self.description = description        self.risk = risk        self.parameters = self.get_parameters()        @abstractmethod    def get_parameters(self) -&gt; Dict[str, Any]:        \"\"\"\u0421\u0445\u0435\u043c\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0434\u043b\u044f OpenAI API\"\"\"        pass        @abstractmethod    async def execute(self, **kwargs) -&gt; str:        \"\"\"\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\"\"\"        passclass FileSystemTool(BaseTool):    \"\"\"\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b\"\"\"        def __init__(self, workspace_root: str):        self.workspace_root = workspace_root        super().__init__(            name=\"read_file\",            description=\"Read file content\",            risk=ToolRisk.SAFE_READ        )        def get_parameters(self) -&gt; Dict[str, Any]:        return {            \"type\": \"object\",            \"properties\": {                \"path\": {\"type\": \"string\", \"description\": \"File path\"}            },            \"required\": [\"path\"]        }        async def execute(self, path: str, **kwargs) -&gt; str:        # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043f\u0443\u0442\u0438        full_path = self._safe_path(path)                try:            with open(full_path, 'r', encoding='utf-8') as f:                return f.read()        except Exception as e:            return f\"Error reading file: {e}\"        def _safe_path(self, path: str) -&gt; str:        \"\"\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438\"\"\"        import os        full = os.path.join(self.workspace_root, path.lstrip('\/'))        if not full.startswith(self.workspace_root):            raise PermissionError(\"Access denied: path outside workspace\")        return fullclass PatchFileTool(BaseTool):    \"\"\"\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u0430\u0442\u0447\u0438\u043d\u0433\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 (\u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a)\"\"\"        def __init__(self, draft_manager):        self.draft_manager = draft_manager        super().__init__(            name=\"patch_file\",            description=\"Patch file content (creates draft)\",            risk=ToolRisk.MODIFY        )        def get_parameters(self) -&gt; Dict[str, Any]:        return {            \"type\": \"object\",            \"properties\": {                \"path\": {\"type\": \"string\"},                \"search_str\": {\"type\": \"string\"},                \"replace_str\": {\"type\": \"string\"}            },            \"required\": [\"path\", \"search_str\", \"replace_str\"]        }        async def execute(self, path: str, search_str: str, replace_str: str, **kwargs) -&gt; str:        # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f        draft = await self.draft_manager.create_draft(            path=path,            search_str=search_str,            replace_str=replace_str        )                return f\"Draft created: {path}\\nPreview: {draft.new_content[:200]}...\"class ToolRegistry:    \"\"\"\u0420\u0435\u0435\u0441\u0442\u0440 \u0432\u0441\u0435\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432\"\"\"        def __init__(self):        self._tools: Dict[str, BaseTool] = {}        def register(self, tool: BaseTool) -&gt; None:        self._tools[tool.name] = tool        async def execute(self, name: str, arguments: Dict[str, Any], is_draft: bool = False) -&gt; str:        if name not in self._tools:            return f\"Error: Tool '{name}' not found\"                tool = self._tools[name]                # \u0414\u043b\u044f \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a        if tool.risk == ToolRisk.MODIFY and is_draft:            return await tool.execute(**arguments, _is_draft=True)                return await tool.execute(**arguments)        def get_openai_schema(self) -&gt; List[Dict]:        \"\"\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0445\u0435\u043c\u044b \u0434\u043b\u044f OpenAI API\"\"\"        return [            {                \"type\": \"function\",                \"function\": {                    \"name\": tool.name,                    \"description\": tool.description,                    \"parameters\": tool.parameters                }            }            for tool in self._tools.values()        ]        def get_risk(self, tool_name: str) -&gt; ToolRisk:        \"\"\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u044f \u0440\u0438\u0441\u043a\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\"\"\"        if tool_name not in self._tools:            return ToolRisk.SAFE_READ        return self._tools[tool_name].risk<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\ud83d\udd12 \u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438<\/h3>\n<pre><code class=\"python\"># safety\/jail.pyfrom typing import Dict, Any, Listimport reclass ScopeJail:    \"\"\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u0440\u0430\u043d\u0438\u0446 \u0434\u043e\u0441\u0442\u0443\u043f\u0430\"\"\"        def __init__(self, allowed_paths: List[str] = None, blocked_patterns: List[str] = None):        self.allowed_paths = allowed_paths or [\".\"]        self.blocked_patterns = blocked_patterns or [            r\"\\.\\.\/\",           # \u041e\u0431\u0445\u043e\u0434 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439            r\"\/etc\/passwd\",     # \u0421\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b            r\"rm\\s+-rf\",        # \u041e\u043f\u0430\u0441\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b            r\"sudo\\s+\",         # \u041f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0439            r\"\\|\\s*sh\\s\",       # \u0418\u043d\u044a\u0435\u043a\u0446\u0438\u0438        ]        async def check_permissions(self, tool_call: Dict[str, Any]) -&gt; bool:        \"\"\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\"\"\"                tool_name = tool_call.get(\"name\")        args = tool_call.get(\"arguments\", {})                # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0443\u0442\u0435\u0439        for path_key in [\"path\", \"oldPath\", \"newPath\", \"source\", \"destination\"]:            if path_key in args:                if not self._check_path(args[path_key]):                    return False                # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434        if tool_name == \"exec_command\":            command = args.get(\"command\", \"\")            if not self._check_command(command):                return False                return True        def _check_path(self, path: str) -&gt; bool:        \"\"\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043f\u0443\u0442\u0438\"\"\"                # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u043e\u0431\u0445\u043e\u0434\u0430        for pattern in self.blocked_patterns:            if re.search(pattern, path):                return False                return True        def _check_command(self, command: str) -&gt; bool:        \"\"\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b\"\"\"                dangerous = [\"rm -rf\", \"dd if=\", \"mkfs\", \":(){ :|:&amp; };:\"]        for cmd in dangerous:            if cmd in command.lower():                return False                return Trueclass LoopDetector:    \"\"\"\u0414\u0435\u0442\u0435\u043a\u0442\u043e\u0440 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u0439\"\"\"        def __init__(self, max_repeats: int = 3, window_size: int = 10):        self.max_repeats = max_repeats        self.window_size = window_size        self._signatures: List[str] = []        def check(self, signature: str) -&gt; bool:        \"\"\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u0435\"\"\"                self._signatures.append(signature)                # \u041e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 N        if len(self._signatures) &gt; self.window_size:            self._signatures.pop(0)                # \u041f\u043e\u0434\u0441\u0447\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u0439        repeats = sum(1 for s in self._signatures if s == signature)                return repeats &gt;= self.max_repeats        def reset(self) -&gt; None:        \"\"\"\u0421\u0431\u0440\u043e\u0441 \u0434\u0435\u0442\u0435\u043a\u0442\u043e\u0440\u0430\"\"\"        self._signatures.clear()class IterationLimiter:    \"\"\"\u041b\u0438\u043c\u0438\u0442\u0435\u0440 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439\"\"\"        def __init__(self, max_iterations: int = 15):        self.max_iterations = max_iterations        def can_continue(self, current_depth: int) -&gt; bool:        return current_depth &lt;= self.max_iterations        def reset(self) -&gt; None:        passclass SnapshotManager:    \"\"\"\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430\u043c\u0438 \u0438 \u043e\u0442\u043a\u0430\u0442\u0430\u043c\u0438\"\"\"        def __init__(self):        self._snapshots: List[Snapshot] = []        async def create_snapshot(self, state: 'AgentState') -&gt; Snapshot:        \"\"\"\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\"\"\"                snapshot = Snapshot(            id=self._generate_id(),            timestamp=datetime.now().timestamp(),            files=state.files.copy(),            messages=state.messages.copy(),            drafts=state.drafts.copy()        )                self._snapshots.append(snapshot)        return snapshot        async def restore_snapshot(self, state: 'AgentState', snapshot_id: str = None) -&gt; bool:        \"\"\"\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0438\u0437 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430\"\"\"                if not self._snapshots:            return False                if snapshot_id:            snapshot = next((s for s in self._snapshots if s.id == snapshot_id), None)        else:            snapshot = self._snapshots[-1]  # \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439                if not snapshot:            return False                # \u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f        state.files = snapshot.files.copy()        state.messages = snapshot.messages.copy()        state.drafts = snapshot.drafts.copy()                return True        def _generate_id(self) -&gt; str:        \"\"\"\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f ID \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0430\"\"\"        import uuid        return str(uuid.uuid4())[:8]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\ud83c\udfae \u041a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u0439 UI<\/h3>\n<pre><code class=\"python\"># ui\/console.pyimport asynciofrom core.agent import ReflectiveAgentclass ConsoleUI:    \"\"\"\u041a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0430\u0433\u0435\u043d\u0442\u043e\u043c\"\"\"        def __init__(self):        self.agent = None        async def run(self):        \"\"\"\u0417\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\"\"\"                print(\"=\" * 60)        print(\"\ud83e\udd16 \u0420\u0415\u0424\u041b\u0415\u041a\u0421\u0418\u0420\u0423\u042e\u0429\u0418\u0419 \u0418\u0418-\u0410\u0413\u0415\u041d\u0422\")        print(\"=\" * 60)        print(\"\\n\u041a\u043e\u043c\u0430\u043d\u0434\u044b:\")        print(\"  \/stop - \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430\")        print(\"  \/status - \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441\")        print(\"  \/snapshot - \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043d\u0430\u043f\u0448\u043e\u0442\")        print(\"  \/rollback - \u043e\u0442\u043a\u0430\u0442 \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0443\")        print(\"  \/help - \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u043c\u043e\u0449\u044c\")        print(\"\\n\" + \"=\" * 60)                # \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0433\u0435\u043d\u0442\u0430        api_key = input(\"\\n\ud83d\udd11 OpenAI API Key: \").strip()                self.agent = ReflectiveAgent(            model=\"gpt-4\",            api_key=api_key,            max_iterations=15,            require_confirmation=True        )                print(\"\\n\u2705 \u0410\u0433\u0435\u043d\u0442 \u0433\u043e\u0442\u043e\u0432 \u043a \u0440\u0430\u0431\u043e\u0442\u0435!\")        print(\"\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0432\u0430\u0448 \u0437\u0430\u043f\u0440\u043e\u0441:\\n\")                while True:            try:                user_input = input(\"\ud83d\udc64 \u0412\u044b: \").strip()                                if not user_input:                    continue                                if user_input.startswith(\"\/\"):                    await self._handle_command(user_input)                    continue                                print(\"\\n\ud83e\udd16 \u0410\u0433\u0435\u043d\u0442 \u0434\u0443\u043c\u0430\u0435\u0442...\\n\")                                # \u0417\u0430\u043f\u0443\u0441\u043a \u0430\u0433\u0435\u043d\u0442\u0430                await self.agent.run(user_input)                                print(\"\\n\" + \"-\" * 40 + \"\\n\")                            except KeyboardInterrupt:                print(\"\\n\\n\ud83d\udc4b \u0414\u043e \u0441\u0432\u0438\u0434\u0430\u043d\u0438\u044f!\")                break            except Exception as e:                print(f\"\\n\u274c \u041e\u0448\u0438\u0431\u043a\u0430: {e}\\n\")        async def _handle_command(self, command: str):        \"\"\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\"\"\"                if command == \"\/stop\":            self.agent.stop()            print(\"\u23f9\ufe0f \u0410\u0433\u0435\u043d\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\")                elif command == \"\/status\":            print(f\"\\n\ud83d\udcca \u0421\u0442\u0430\u0442\u0443\u0441:\")            print(f\"  \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439: {len(self.agent.state.messages)}\")            print(f\"  \u0427\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u043e\u0432: {len(self.agent.state.drafts)}\")            print(f\"  \u0418\u0442\u0435\u0440\u0430\u0446\u0438\u0439: {self.agent.state.current_depth}\")                elif command == \"\/snapshot\":            snapshot = await self.agent.snapshot_manager.create_snapshot(self.agent.state)            print(f\"\ud83d\udcf8 \u0421\u043d\u0430\u043f\u0448\u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u043d: {snapshot.id}\")                elif command == \"\/rollback\":            await self.agent.snapshot_manager.restore_snapshot(self.agent.state)            print(\"\u21a9\ufe0f \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043e\u0442\u043a\u0430\u0442 \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0443\")                elif command == \"\/help\":            print(\"\\n\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:\")            print(\"  \/stop - \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430\")            print(\"  \/status - \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441\")            print(\"  \/snapshot - \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043d\u0430\u043f\u0448\u043e\u0442\")            print(\"  \/rollback - \u043e\u0442\u043a\u0430\u0442 \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u0443\")            print(\"  \/help - \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u043c\u043e\u0449\u044c\")                else:            print(f\"\u274c \u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430: {command}\")async def main():    ui = ConsoleUI()    await ui.run()if __name__ == \"__main__\":    asyncio.run(main())<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\ud83d\ude80 \u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430<\/h3>\n<pre><code class=\"python\"># main.pyimport asynciofrom ui.console import ConsoleUIfrom core.agent import ReflectiveAgentfrom tools.filesystem import FileSystemTool, PatchFileToolfrom tools.terminal import TerminalToolfrom tools.mcp_adapter import MCPAdapterasync def main():    \"\"\"\u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\"\"\"        # \u0417\u0430\u043f\u0443\u0441\u043a \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430    ui = ConsoleUI()    await ui.run()async def demo():    \"\"\"\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u0433\u0435\u043d\u0442\u0430 \u0431\u0435\u0437 UI\"\"\"        agent = ReflectiveAgent(        model=\"gpt-4\",        api_key=\"your-api-key\",  # \u0417\u0430\u043c\u0435\u043d\u0438\u0442\u0435 \u043d\u0430 \u0432\u0430\u0448 \u043a\u043b\u044e\u0447        max_iterations=10    )        # \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432    from tools.filesystem import FileSystemTool, PatchFileTool    from tools.terminal import TerminalTool        agent.tools.register(FileSystemTool(workspace_root=\".\/workspace\"))    agent.tools.register(PatchFileTool(agent.state.draft_manager))    agent.tools.register(TerminalTool())        # \u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f    queries = [        \"\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0439 \u0444\u0430\u0439\u043b README.md\",        \"\u0421\u043e\u0437\u0434\u0430\u0439 \u043d\u043e\u0432\u044b\u0439 Python \u0444\u0430\u0439\u043b \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 hello_world\",        \"\u041a\u0430\u043a\u043e\u0439 \u0441\u0435\u0439\u0447\u0430\u0441 Python version?\",    ]        for query in queries:        print(f\"\\n{'='*60}\")        print(f\"\ud83d\udc64 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c: {query}\")        print(f\"{'='*60}\\n\")                await agent.run(query)                print(\"\\n\" + \"=\"*60 + \"\\n\")if __name__ == \"__main__\":    # \u0414\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438    # asyncio.run(demo())        # \u0414\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u0436\u0438\u043c\u0430    asyncio.run(main())<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\ud83d\udce6 \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439<\/h3>\n<pre><code class=\"bash\"># requirements.txtopenai&gt;=1.0.0asynciopydantic&gt;=2.0.0python-dotenv&gt;=1.0.0<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"bash\">pip install -r requirements.txt<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\ud83c\udfaf \u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/h3>\n<ol>\n<li>\n<p><strong>\u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b<\/strong> &#8212; \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f \u0432\u043c\u0435\u0441\u0442\u043e while<\/p>\n<\/li>\n<li>\n<p><strong>\u0427\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u0438<\/strong> &#8212; \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 DraftManager<\/p>\n<\/li>\n<li>\n<p><strong>\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f<\/strong> &#8212; \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0430\u043c\u043e\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435\u043c<\/p>\n<\/li>\n<li>\n<p><strong>\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c<\/strong> &#8212; \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 (Jail, \u0434\u0435\u0442\u0435\u043a\u0442\u043e\u0440 \u0446\u0438\u043a\u043b\u043e\u0432)<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u043d\u0430\u043f\u0448\u043e\u0442\u044b<\/strong> &#8212; \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043a\u0430\u0442\u0430 \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p><strong>Human-in-the-loop<\/strong> &#8212; \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043e\u043f\u0430\u0441\u043d\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439<\/p>\n<\/li>\n<\/ol>\n<hr\/>\n<h3>\ud83e\udde9 \u041f\u043e\u0447\u0435\u043c\u0443 \u00ab\u0431\u044b\u0441\u0442\u0440\u044b\u0439\u00bb \u0430\u0433\u0435\u043d\u0442 \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/h3>\n<p>\u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0430\u0433\u0435\u043d\u0442\u043e\u0432 \u0436\u0438\u0432\u0443\u0442 \u043f\u043e \u0441\u0445\u0435\u043c\u0435 <code>think \u2192 do<\/code>. \u042d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u043e, \u043d\u043e \u0445\u0440\u0443\u043f\u043a\u043e. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0434\u043d\u043e\u0439 \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0430\u0446\u0438\u0438, \u043d\u0435\u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u043f\u0442\u0430 \u0438\u043b\u0438 \u043d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0441\u0440\u0435\u0434\u044b \u2014 \u0438 \u0430\u0433\u0435\u043d\u0442 \u043c\u043e\u043b\u0447\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0435 \u0442\u043e\u043c\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u043f\u0438\u0441\u044c\u043c\u043e, \u043b\u043e\u043c\u0430\u0435\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043e\u0442\u0447\u0451\u0442 \u0438\u043b\u0438 \u0443\u0445\u043e\u0434\u0438\u0442 \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0441\u0436\u0438\u0433\u0430\u044f \u0431\u044e\u0434\u0436\u0435\u0442.<\/p>\n<p>\u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u044d\u0442\u0443 \u0441\u0445\u0435\u043c\u0443 \u043d\u0430 \u0441\u0435\u043c\u0438\u0441\u0442\u0443\u043f\u0435\u043d\u0447\u0430\u0442\u044b\u0439 \u0446\u0438\u043a\u043b:<\/p>\n<pre><code>\u0412\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u2192 \u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u2192 \u0427\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u2192 \u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u2192 \u0428\u043b\u044e\u0437 \u2192 \u041a\u043e\u043c\u043c\u0438\u0442 \u2192 \u041e\u0442\u043a\u0430\u0442<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043d\u0435 \u0437\u0430\u043c\u0435\u0434\u043b\u044f\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0435\u0451 <strong>\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0439, \u0430\u0443\u0434\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430<\/strong>.<\/p>\n<hr\/>\n<h3>\ud83c\udfd7\ufe0f \u0421\u0435\u043c\u044c \u0441\u0442\u043e\u043b\u043f\u043e\u0432 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b<\/h3>\n<h4>1. \u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430<\/h4>\n<p>\u0410\u0433\u0435\u043d\u0442 \u043d\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u0441\u043b\u0435\u043f\u0443\u044e. \u041f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u043e\u043d \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0440\u0435\u0434\u044b: \u043a\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b, \u043a\u0430\u043a\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b, \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442, \u0447\u0442\u043e \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0435\u0441\u0441\u0438\u0438. \u042d\u0442\u043e \u043a\u0430\u043a \u043f\u0438\u043b\u043e\u0442, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u0431\u043e\u0440\u044b \u043f\u0435\u0440\u0435\u0434 \u043c\u0430\u043d\u0451\u0432\u0440\u043e\u043c.<\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0438\u0445\u0438\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u043c\u043f\u0442 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 <strong>\u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442<\/strong>:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0427\u0442\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u044f<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0414\u0435\u0440\u0435\u0432\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u044b, \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b, API-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b \u2014 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0430 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u0430\u0440\u0442\u0430 \u043c\u0435\u0441\u0442\u043d\u043e\u0441\u0442\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u043e, \u0441 \u0447\u0435\u043c \u0430\u0433\u0435\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u044f\u043c\u043e \u0441\u0435\u0439\u0447\u0430\u0441<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u0442\u043a\u0440\u044b\u0442\u044b\u0435 \u0432\u043a\u043b\u0430\u0434\u043a\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0413\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0431\u043b\u0430\u0441\u0442\u0438 (Scope)<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0451\u0442\u043a\u0438\u0439 \u043f\u0435\u0440\u0438\u043c\u0435\u0442\u0440, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043b\u044c\u0437\u044f \u0432\u044b\u0445\u043e\u0434\u0438\u0442\u044c<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u0440\u0430\u0441\u043d\u0430\u044f \u043b\u0435\u043d\u0442\u0430 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435 \u043f\u0440\u043e\u0438\u0441\u0448\u0435\u0441\u0442\u0432\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0441 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430\u043c\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u044f\u0441 \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043e\u043b\u043d\u0430\u044f \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u0435\u0441\u0441\u0438\u0438<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0430\u044f \u043f\u0430\u043c\u044f\u0442\u044c<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u042d\u0442\u043e \u0434\u0430\u0451\u0442 \u0430\u0433\u0435\u043d\u0442\u0443 \u043d\u0435 \u00ab\u0432\u0441\u0435\u0437\u043d\u0430\u043d\u0438\u0435\u00bb, \u0430 <strong>\u0441\u0438\u0442\u0443\u0430\u0446\u0438\u043e\u043d\u043d\u0443\u044e \u043e\u0441\u0432\u0435\u0434\u043e\u043c\u043b\u0451\u043d\u043d\u043e\u0441\u0442\u044c<\/strong> \u2014 \u0440\u043e\u0432\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442. \u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u043d\u043e\u0432\u043e \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u043c\u0438 \u0434\u043e\u043f\u0443\u0449\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<hr\/>\n<h4>2. \u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0441 \u043f\u0440\u0430\u0432\u043e\u043c \u043d\u0430 \u043f\u0430\u0443\u0437\u0443<\/h4>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u0436\u0451\u0441\u0442\u043a\u043e\u0433\u043e <code>while(true)<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <strong>\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f<\/strong>. \u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e? \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0418\u0418-\u0430\u0433\u0435\u043d\u0442 \u2014 \u043d\u0435 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440, \u0430 \u0434\u0438\u0430\u043b\u043e\u0433.<\/p>\n<p>\u0410\u0433\u0435\u043d\u0442 \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f, \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0443\u0442\u043e\u0447\u043d\u0435\u043d\u0438\u0435, \u0434\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430, \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0432\u0435\u0431\u0445\u0443\u043a\u0430 \u0438\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0434\u043e\u043b\u0433\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u0441 \u0442\u043e\u0433\u043e \u0436\u0435 \u043c\u0435\u0441\u0442\u0430. \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0434\u0438\u0430\u043b\u043e\u0433\u0430, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u0431\u044e\u0434\u0436\u0435\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f. \u041f\u0430\u0443\u0437\u0430 \u043d\u0435 \u043b\u043e\u043c\u0430\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u2014 \u043e\u043d\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0432 \u0435\u0433\u043e \u0414\u041d\u041a. \u0427\u0435\u043b\u043e\u0432\u0435\u043a \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0442\u0443\u0440\u0435, \u0430 \u043d\u0435 \u0432\u044b\u043f\u0430\u0434\u0430\u0435\u0442 \u0438\u0437 \u043d\u0435\u0433\u043e.<\/p>\n<hr\/>\n<h4>3. \u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0430 \u0438 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u0438<\/h4>\n<p>\u041e\u0434\u043d\u043e \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043c\u043e\u0449\u043d\u044b\u0445 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u2014 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f <strong>\u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u043e\u0432<\/strong>. \u0412\u0441\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c \u0441\u0440\u0430\u0437\u0443. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e:<\/p>\n<ol>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0435\u0441\u0441\u0438\u0438 \u0432\u0438\u0434\u044f\u0442 \u0443\u0436\u0435 \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 (\u0447\u0442\u043e\u0431\u044b \u0430\u0433\u0435\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c).<\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u0442\u0440\u043e\u043d\u0443\u0442\u044b\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0438\u0434\u0438\u0442 \u043e\u043a\u043d\u043e \u0440\u0435\u0432\u044c\u044e: \u0434\u0438\u0444\u0444 \u0432\u0441\u0435\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u044c, \u043e\u0442\u043a\u043b\u043e\u043d\u0438\u0442\u044c \u0438\u043b\u0438 \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p>\u0422\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044f\u0432\u043d\u043e\u0433\u043e \u00ab\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c\u00bb \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u0438 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ol>\n<p>\u042d\u0442\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f <code>git staging<\/code>, \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0451\u043d\u043d\u044b\u0439 \u043d\u0430 \u043b\u044e\u0431\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u0411\u0443\u0434\u044c \u0442\u043e \u043f\u0440\u0430\u0432\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430, \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 CRM, \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0437\u0430\u043f\u0443\u0441\u043a ETL-\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u2014 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u00ab\u0447\u0442\u043e \u0431\u044b\u043b\u043e\u00bb \u0438 \u00ab\u0447\u0442\u043e \u0441\u0442\u0430\u043d\u0435\u0442\u00bb, \u043d\u043e \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u0442 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d-\u0441\u0440\u0435\u0434\u0443. \u0427\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0430\u0433\u0435\u043d\u0442\u0430 \u0438\u0437 \u00ab\u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f\u00bb \u0432 \u00ab\u0441\u043e\u0432\u0435\u0442\u043d\u0438\u043a\u0430\u00bb, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0437\u0430 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u043c.<\/p>\n<hr\/>\n<h4>4. \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0430\u0437\u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438<\/h4>\n<p>\u042d\u0442\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0439 \u0431\u043b\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442 \u00ab\u0434\u0443\u043c\u0430\u044e\u0449\u0435\u0433\u043e\u00bb \u0430\u0433\u0435\u043d\u0442\u0430 \u043e\u0442 \u00ab\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e\u00bb. \u041a\u043e\u0433\u0434\u0430 \u0430\u0433\u0435\u043d\u0442 \u0441\u0447\u0438\u0442\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u043e\u0439, \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u044d\u0442\u043e \u043d\u0430 \u0432\u0435\u0440\u0443.<\/p>\n<p>\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f <strong>\u0444\u0430\u0437\u0430 \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438<\/strong> \u2014 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0430\u0443\u0434\u0438\u0442:<\/p>\n<ul>\n<li>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0446\u0435\u043b\u0438?<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u0442 \u043b\u0438 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447\u0438\u0439 \u0438\u043b\u0438 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0448\u0430\u0433\u043e\u0432?<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0431\u043b\u044e\u0434\u0435\u043d\u044b \u043b\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u0444\u043e\u0440\u043c\u0430\u0442\u044b, \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f?<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0443\u0445\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0438\u043b\u0438 \u0442\u0435\u0441\u0442?<\/p>\n<\/li>\n<\/ul>\n<p>\u0410\u0433\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442 \u0441\u0432\u043e\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043f\u0435\u0440\u0435\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442. \u0415\u0441\u043b\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u2014 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445 \u0447\u0435\u0440\u0435\u0437 \u0442\u0435 \u0436\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b. \u0422\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u044f\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f (<code>verified: true<\/code>) \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u043e\u0439.<\/p>\n<p>\u042d\u0442\u043e \u0430\u043d\u0430\u043b\u043e\u0433 \u0447\u0435\u043a-\u043b\u0438\u0441\u0442\u0430 \u043f\u0438\u043b\u043e\u0442\u0430 \u043f\u0435\u0440\u0435\u0434 \u0432\u0437\u043b\u0451\u0442\u043e\u043c: \u043b\u0443\u0447\u0448\u0435 \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0439 \u0448\u0430\u0433 \u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443, \u0447\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435. \u0412 \u044e\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0434\u043e\u043c\u0435\u043d\u0435 \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u043b\u043e \u0431\u044b \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u0441\u0442\u0430\u0442\u044c\u0438 \u0437\u0430\u043a\u043e\u043d\u0430. \u0412 \u043c\u0435\u0434\u0438\u0446\u0438\u043d\u0441\u043a\u043e\u043c \u2014 \u043f\u0435\u0440\u0435\u043a\u0440\u0451\u0441\u0442\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0441 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f\u043c\u0438. \u0412 \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u043e\u043c \u2014 \u0441\u0432\u0435\u0440\u043a\u0443 \u0440\u0430\u0441\u0447\u0451\u0442\u043e\u0432 \u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u044b\u043c\u0438 \u0441\u0443\u043c\u043c\u0430\u043c\u0438. \u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0430\u0433\u0435\u043d\u0442\u0430 \u0438\u0437 \u00ab\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0442\u0435\u043a\u0441\u0442\u0430\u00bb \u0432 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f.<\/p>\n<hr\/>\n<h4>5. \u0427\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438\u0439 \u0448\u043b\u044e\u0437 \u0434\u043b\u044f \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439<\/h4>\n<p>\u0412\u0441\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u0442\u0440\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0440\u0438\u0441\u043a\u0430:<\/p>\n<ul>\n<li>\n<p>\ud83d\udfe2 <strong>\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0435 \u0447\u0442\u0435\u043d\u0438\u044f<\/strong> \u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\ud83d\udfe1 <strong>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f<\/strong> \u2014 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u0438, \u043d\u0435 \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u044f \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b<\/p>\n<\/li>\n<li>\n<p>\ud83d\udd34 <strong>\u0414\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438<\/strong> \u2014 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u044f\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<\/ul>\n<p>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0435 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438, \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u043e\u043b\u0435\u0439, \u043c\u0430\u0441\u0441\u043e\u0432\u044b\u0435 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438, \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u2014 \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0440\u0430\u0442\u0438\u043c\u043e \u0438\u043b\u0438 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u0441\u0440\u0435\u0434\u0443, \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0430\u0443\u0437\u044b. \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443 \u0441 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c, \u0440\u0438\u0441\u043a\u0430\u043c\u0438, \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430\u043c\u0438 \u0438 \u043f\u0440\u0435\u0432\u044c\u044e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u0410\u0433\u0435\u043d\u0442 \u0437\u0430\u043c\u0438\u0440\u0430\u0435\u0442, \u0436\u0434\u0451\u0442 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u00ab\u0437\u0435\u043b\u0451\u043d\u043e\u0433\u043e \u0441\u0432\u0435\u0442\u0430\u00bb.<\/p>\n<p>\u042d\u0442\u043e \u043d\u0435 \u0447\u0430\u0442 \u0441 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438, \u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d <strong>Human-in-the-Loop<\/strong>: \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0439, \u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430 \u043d\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0431\u0435\u0437\u0440\u0430\u0441\u0441\u0443\u0434\u0441\u0442\u0432\u043e.<\/p>\n<hr\/>\n<h4>6. \u041c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 \u043f\u0440\u0435\u0434\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435\u043b\u0438<\/h4>\n<p>\u0417\u0430\u0449\u0438\u0442\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435. \u041e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0447\u0430\u0441\u0442\u044c\u044e \u0446\u0438\u043a\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u041a\u0430\u0436\u0434\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0430\u0433\u0435\u043d\u0442\u0430 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u043f\u0440\u0435\u0434\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435\u043b\u0438, \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0432 \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u043b\u043e\u0439:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041c\u0435\u0445\u0430\u043d\u0438\u0437\u043c<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u044f<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>Scope Jail<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0432\u044b\u0445\u043e\u0434 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0440\u043e\u043b\u0435\u0439, \u043f\u043e\u043b\u0438\u0442\u0438\u043a<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0417\u0430\u0431\u043e\u0440 \u0432\u043e\u043a\u0440\u0443\u0433 \u0441\u0442\u0440\u043e\u0439\u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0414\u0435\u0442\u0435\u043a\u0442\u043e\u0440 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u0439<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">3 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0434\u0440\u044f\u0434 \u0441 \u043e\u0434\u043d\u043e\u0439 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439 \u2192 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u043e\u0439<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0442\u0435\u043b\u044c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041b\u0438\u043c\u0438\u0442\u044b \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0416\u0451\u0441\u0442\u043a\u0438\u0435 \u043f\u043e\u0442\u043e\u043b\u043a\u0438 \u043d\u0430 \u0448\u0430\u0433\u0438 \u0438 \u0442\u043e\u043a\u0435\u043d\u044b \u0441 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u00ab\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c?\u00bb<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u0430\u0439\u043c\u0435\u0440 \u0438 \u0441\u0447\u0451\u0442\u0447\u0438\u043a \u0431\u044e\u0434\u0436\u0435\u0442\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0421\u043d\u0430\u043f\u0448\u043e\u0442\u044b \u0438 \u043e\u0442\u043a\u0430\u0442<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u043e\u0447\u043a\u0430 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0435\u0439. \u041e\u0448\u0438\u0431\u043a\u0430? \u041e\u0442\u043a\u0430\u0442 \u0432 \u043e\u0434\u0438\u043d \u043a\u043b\u0438\u043a<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043d\u043e\u043f\u043a\u0430 \u00ab\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0441\u0451\u00bb<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>Abort-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u0430\u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u043b\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0410\u0432\u0430\u0440\u0438\u0439\u043d\u044b\u0439 \u0442\u043e\u0440\u043c\u043e\u0437<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u042d\u0442\u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0435 \u00ab\u043f\u043e\u0432\u0435\u0440\u0445\u00bb \u0430\u0433\u0435\u043d\u0442\u0430, \u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0432 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438\u0445 \u043e\u0431\u043e\u0439\u0442\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0430 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0442\u0435\u043a\u0441\u0442\u0430. \u0410\u0433\u0435\u043d\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u00ab\u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c\u0441\u044f\u00bb \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043e\u0431\u043e\u0439\u0442\u0438 \u0437\u0430\u0449\u0438\u0442\u0443.<\/p>\n<hr\/>\n<h4>7. \u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432<\/h4>\n<p>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043d\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u0430 \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0434\u043e\u043c\u0435\u043d\u0443. \u0427\u0435\u0440\u0435\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 (\u0430\u043d\u0430\u043b\u043e\u0433 <strong>Model Context Protocol<\/strong>) \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u043b\u044e\u0431\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b: \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, CRM, \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u044b, \u043f\u043e\u0447\u0442\u0430, IoT-\u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u0432\u043d\u0435\u0448\u043d\u0438\u0435 API.<\/p>\n<p>\u042d\u0442\u043e \u043a\u0430\u043a USB-C \u0434\u043b\u044f \u0418\u0418-\u0430\u0433\u0435\u043d\u0442\u043e\u0432:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0414\u043e\u043c\u0435\u043d<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0427\u0442\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 MCP<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0430\u0439\u043b\u043e\u0432\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, Git, \u043b\u0438\u043d\u0442\u0435\u0440\u044b<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041f\u0440\u0430\u0432\u043e<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u0430\u0437\u044b \u0437\u0430\u043a\u043e\u043d\u043e\u0432, \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u043e\u0432, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\u043e\u0432<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0435\u0434\u0438\u0446\u0438\u043d\u0430<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041c\u0435\u0434\u0438\u0446\u0438\u043d\u0441\u043a\u0438\u0435 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u0438, \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u043e\u0432<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0424\u0438\u043d\u0430\u043d\u0441\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0442\u0451\u0436\u043d\u044b\u0435 \u0448\u043b\u044e\u0437\u044b, CRM, \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u044e\u0434\u0436\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0440\u0430\u0441\u0441\u044b\u043b\u043e\u043a, \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430, CMS<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0411\u0430\u0437\u044b \u0437\u043d\u0430\u043d\u0438\u0439, \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u0430\u0434\u0430\u043d\u0438\u0439<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0410\u0433\u0435\u043d\u0442 \u0432\u0438\u0434\u0438\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u00ab\u0440\u0443\u043a\u00bb, \u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0430\u0433\u0435\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438, \u0437\u0430\u0432\u0442\u0440\u0430 \u2014 \u0441 \u0447\u0430\u0442-\u0431\u043e\u0442\u0430\u043c\u0438, \u043f\u043e\u0441\u043b\u0435\u0437\u0430\u0432\u0442\u0440\u0430 \u2014 \u0441 \u043b\u043e\u0433\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438. \u042f\u0434\u0440\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f.<\/p>\n<hr\/>\n<h3>\ud83c\udf0d \u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0444\u0435\u0440\u0430\u0445?<\/h3>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0414\u043e\u043c\u0435\u043d<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u043c\u0435\u0440 \u0446\u0438\u043a\u043b\u0430 \u0430\u0433\u0435\u043d\u0442\u0430<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0410\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u2192 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432 \u0441\u0443\u0445\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u2192 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u043e\u0431\u044a\u0451\u043c \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u2192 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0435\u0432\u044c\u044e \u2192 \u043f\u043e\u0441\u043b\u0435 \u043e\u0434\u043e\u0431\u0440\u0435\u043d\u0438\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0447\u0451\u0442 \u0438 \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433 \u0438 \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u2192 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0442\u043e\u043d, \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0440\u0435\u0433\u043b\u0430\u043c\u0435\u043d\u0442\u0443 \u2192 \u0436\u0434\u0451\u0442 \u043e\u0434\u043e\u0431\u0440\u0435\u043d\u0438\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u2192 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u2192 \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0418\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0441\u0438\u043d\u0442\u0435\u0437<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u2192 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0438 \u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u2192 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u043e\u0431\u0437\u043e\u0440\u0430 \u2192 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0441\u0430\u043c\u043e\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0430\u0437\u0440\u044b\u0432\u044b \u2192 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441 \u0446\u0438\u0442\u0430\u0442\u0430\u043c\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u043c\u0438<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0427\u0438\u0442\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u0438\u0437 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u2192 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u0437\u0430\u0434\u0430\u0447\u0438 \u2192 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u0439 \u2192 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u043f\u043b\u0430\u043d\u0430 \u2192 \u043f\u043e\u0441\u043b\u0435 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0442\u0438\u043a\u0435\u0442\u044b \u0438 \u0441\u0442\u0430\u0432\u0438\u0442 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0442\u0438\u043a\u0435\u0442 \u2192 \u0438\u0449\u0435\u0442 \u043f\u043e\u0445\u043e\u0436\u0438\u0435 \u043a\u0435\u0439\u0441\u044b \u0432 \u0431\u0430\u0437\u0435 \u2192 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0432\u0435\u0442-\u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u2192 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 SLA \u0438 \u0442\u043e\u043d\u0443 \u0431\u0440\u0435\u043d\u0434\u0430 \u2192 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0443 \u2192 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0441\u043b\u0435 \u043a\u043b\u0438\u043a\u0430<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>\u042e\u0440\u0438\u0441\u043f\u0440\u0443\u0434\u0435\u043d\u0446\u0438\u044f<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u2192 \u0432\u044b\u044f\u0432\u043b\u044f\u0435\u0442 \u0440\u0438\u0441\u043a\u0438 \u043f\u043e \u0441\u0435\u043a\u0446\u0438\u044f\u043c \u2192 \u0441\u0432\u0435\u0440\u044f\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u044b \u0441 \u0441\u0443\u0434\u0435\u0431\u043d\u043e\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0439 \u2192 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u2192 \u044e\u0440\u0438\u0441\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0438 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412\u043e \u0432\u0441\u0435\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u043f\u0430\u0442\u0442\u0435\u0440\u043d: <strong>\u0430\u0433\u0435\u043d\u0442 \u0434\u0443\u043c\u0430\u0435\u0442, \u043f\u0440\u0438\u043c\u0435\u0440\u044f\u0435\u0442, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442<\/strong>.<\/p>\n<hr\/>\n<h3>\ud83d\udd04 \u0410\u043d\u0430\u0442\u043e\u043c\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430: \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u2014 \u0430\u043d\u0430\u043b\u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0441 \u0440\u0438\u0441\u043a\u0430\u043c\u0438:<\/p>\n<pre><code>\u041f\u041e\u041b\u042c\u0417\u041e\u0412\u0410\u0422\u0415\u041b\u042c: \"\u041f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0439 \u0434\u043e\u0433\u043e\u0432\u043e\u0440 \u0430\u0440\u0435\u043d\u0434\u044b \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u0440\u0438\u0441\u043a\u043e\u0432\"          \u2193\ud83d\udd35 \u0412\u041e\u0421\u041f\u0420\u0418\u042f\u0422\u0418\u0415: \u0410\u0433\u0435\u043d\u0442 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0444\u0430\u0439\u043b, \u0432\u0438\u0434\u0438\u0442 \u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435          \u2193\ud83d\udfe1 \u041f\u041b\u0410\u041d\u0418\u0420\u041e\u0412\u0410\u041d\u0418\u0415: \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0447\u0442\u043e \u044d\u0442\u043e \u0434\u043e\u0433\u043e\u0432\u043e\u0440 \u0430\u0440\u0435\u043d\u0434\u044b. \u041f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0430\u043d\u0430\u043b\u0438\u0437 \u043f\u043e \u0441\u0435\u043a\u0446\u0438\u044f\u043c:   \u043f\u0440\u0435\u0434\u043c\u0435\u0442, \u0441\u0440\u043e\u043a\u0438, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u0440\u0430\u0441\u0442\u043e\u0440\u0436\u0435\u043d\u0438\u0435. \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u0437\u0430\u043a\u043e\u043d\u0430.          \u2193   \u250c\u2500\u2192\ud83d\udd34 \u0414\u0415\u0419\u0421\u0422\u0412\u0418\u0415: \u0427\u0438\u0442\u0430\u0435\u0442 \u0441\u0435\u043a\u0446\u0438\u044e \u00ab\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u00bb, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043e\u0446\u0435\u043d\u043a\u0443 \u043d\u0435\u0443\u0441\u0442\u043e\u0439\u043a\u0438   \u2502       \u2193   \u2502   \ud83d\udfe3 \u0420\u0415\u0424\u041b\u0415\u041a\u0421\u0418\u042f: \u041d\u0430\u0445\u043e\u0434\u0438\u0442 \u043f\u0443\u043d\u043a\u0442 \u0441 \u0437\u0430\u0432\u044b\u0448\u0435\u043d\u043d\u043e\u0439 \u043d\u0435\u0443\u0441\u0442\u043e\u0439\u043a\u043e\u0439.   \u2502       \u0421\u0432\u0435\u0440\u044f\u0435\u0442 \u0441 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0443\u0434\u0435\u0431\u043d\u043e\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0439. \u0424\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0440\u0438\u0441\u043a \u0432 \u0447\u0435\u0440\u043d\u043e\u0432\u0438\u043a.   \u2502       \u2193   \u2514\u2500\u2500\u2500\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0446\u0438\u043a\u043b \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u043a\u0446\u0438\u0439          \u2193\ud83d\udfe3 \u0424\u0418\u041d\u0410\u041b\u042c\u041d\u0410\u042f \u0420\u0415\u0424\u041b\u0415\u041a\u0421\u0418\u042f: \u041f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0432\u0441\u0435 \u0432\u044b\u0432\u043e\u0434\u044b, \u0438\u0449\u0435\u0442 \u0443\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u0440\u0438\u0441\u043a\u0438,   \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u043d\u0435 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447\u0430\u0442 \u043b\u0438 \u0432\u044b\u0432\u043e\u0434\u044b \u043f\u043e \u0440\u0430\u0437\u043d\u044b\u043c \u0441\u0435\u043a\u0446\u0438\u044f\u043c \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443          \u2193\ud83d\udd34 \u0428\u041b\u042e\u0417: \u041e\u043a\u043d\u043e \u0440\u0435\u0432\u044c\u044e \u2014 \u00ab\u041d\u0430\u0439\u0434\u0435\u043d\u043e 12 \u0440\u0438\u0441\u043a\u043e\u0432, 3 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438. \u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u043a\u0438?\u00bb   \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0438\u0434\u0438\u0442 \u0434\u0438\u0444\u0444 \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u043f\u0443\u043d\u043a\u0442\u0443, \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u043e\u0442\u043a\u043b\u043e\u043d\u0438\u0442\u044c          \u2193\u041f\u041e\u041b\u042c\u0417\u041e\u0412\u0410\u0422\u0415\u041b\u042c: \u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442          \u2193\u2705 \u041a\u041e\u041c\u041c\u0418\u0422: \u0427\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u0438 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u044b \u043a \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0443. \u0421\u043d\u0430\u043f\u0448\u043e\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d.<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0442 \u0441\u043f\u0435\u0448\u043a\u0438. \u041a\u0430\u0436\u0434\u044b\u0439 \u0448\u0430\u0433 \u043e\u0441\u043e\u0437\u043d\u0430\u043d, \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d, \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0451\u043d. \u0410\u0433\u0435\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435 \u043a\u0430\u043a \u00ab\u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u00bb, \u0430 \u043a\u0430\u043a <strong>\u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a<\/strong>.<\/p>\n<hr\/>\n<h3>\ud83d\udca1 \u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438\u0433\u0440\u044b?<\/h3>\n<p><strong>\u0414\u043e\u0432\u0435\u0440\u0438\u0435 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043d\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435, \u0430 \u043d\u0435 \u043d\u0430 \u043e\u0431\u0435\u0449\u0430\u043d\u0438\u044f\u0445.<\/strong> \u0427\u0435\u0440\u043d\u043e\u0432\u0438\u043a\u0438, \u0441\u043d\u0430\u043f\u0448\u043e\u0442\u044b \u0438 \u0448\u043b\u044e\u0437\u044b \u0434\u0435\u043b\u0430\u044e\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u044b\u043c\u0438. \u0421\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0441\u0431\u043e\u044f \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u0441\u044f \u043a \u043d\u0443\u043b\u044e. \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u043b\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u043e\u0438\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430 \u043d\u0430 \u0440\u0430\u0431\u043e\u0447\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u043e \u044f\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043d\u0438 \u043e\u0434\u043d\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043d\u0435 \u043f\u043e\u043a\u0438\u043d\u0435\u0442 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0443.<\/p>\n<p><strong>\u0418\u0418 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043a\u043e\u043b\u043b\u0435\u0433\u043e\u0439, \u0430 \u043d\u0435 \u0447\u0451\u0440\u043d\u044b\u043c \u044f\u0449\u0438\u043a\u043e\u043c.<\/strong> \u041a\u0430\u0436\u0434\u044b\u0439 \u0448\u0430\u0433 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u0435\u043d, \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u043c \u0438 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u043c. \u0427\u0435\u043b\u043e\u0432\u0435\u043a \u0432\u0438\u0434\u0438\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u043d\u043e \u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u0412\u044b \u043d\u0435 \u0433\u0430\u0434\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b \u0418\u0418 \u2014 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0448\u0430\u0433 \u0438 \u0434\u0435\u0440\u0436\u0438\u0442\u0435 \u0440\u0443\u043a\u0443 \u043d\u0430 \u043f\u0443\u043b\u044c\u0441\u0435.<\/p>\n<p><strong>\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u0430, \u0430 \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430.<\/strong> \u041f\u0440\u0435\u0434\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0430 \u043d\u0435 \u043f\u0440\u043e\u043c\u043f\u0442\u0430. \u041c\u043e\u0434\u0435\u043b\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u00ab\u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c\u0441\u044f\u00bb \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043e\u0431\u043e\u0439\u0442\u0438 \u0437\u0430\u0449\u0438\u0442\u0443, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438, \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p><strong>\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0441\u0442\u044c \u0431\u0435\u0437 \u0441\u0442\u0440\u0430\u0445\u0430.<\/strong> \u041e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0446\u0438\u043a\u043b \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u0434\u0435, \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0435\u043a\u0441\u0442\u0430\u0445, \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430\u0445 \u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f\u0445. \u041c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u2014 \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430. \u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0430\u0433\u0435\u043d\u0442\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0447\u0435\u043c \u0443\u0433\u043e\u0434\u043d\u043e, \u043d\u0435 \u0442\u0435\u0440\u044f\u044f \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p><strong>\u042d\u043a\u043e\u043d\u043e\u043c\u0438\u043a\u0430 \u043f\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0435\u043c.<\/strong> \u041b\u0438\u043c\u0438\u0442\u044b \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439, \u0434\u0435\u0442\u0435\u043a\u0442\u043e\u0440 \u0446\u0438\u043a\u043b\u043e\u0432 \u0438 \u043f\u0430\u0443\u0437\u044b \u043d\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u044e\u0442 runaway-\u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438 \u0438 \u043d\u0435\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u0411\u044e\u0434\u0436\u0435\u0442 \u0440\u0430\u0441\u0445\u043e\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e, \u0430 \u043d\u0435 \u0441\u0436\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u00ab\u043c\u044b\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0436\u0432\u0430\u0447\u043a\u0435\u00bb.<\/p>\n<hr\/>\n<h3>\ud83d\udd2e \u0427\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435: \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u0430\u0433\u0435\u043d\u0442\u043e\u0432<\/h3>\n<p>\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0437\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438 \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u0438:<\/p>\n<ol>\n<li>\n<p><strong>\u041a\u043e\u043b\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f<\/strong>: \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0430\u0433\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430 \u2014 \u043a\u0430\u043a \u043a\u043e\u0434-\u0440\u0435\u0432\u044c\u044e, \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u0435\u0434\u0438\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f<\/strong>: \u0430\u0433\u0435\u043d\u0442 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0439\u0442\u0438 \u043d\u0435 \u0442\u0430\u043a, \u0434\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0430 \u043d\u0435 \u043f\u043e\u0441\u043b\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430\u0445<\/strong>: \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u043d\u0435\u0443\u0434\u0430\u0447 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u00ab\u043f\u0430\u043c\u044f\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430\u00bb \u0438 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0437\u0430\u0434\u0430\u0447\u0430\u0445.<\/p>\n<\/li>\n<li>\n<p><strong>\u042d\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f<\/strong>: \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0446\u0435\u043b\u044f\u043c, \u043d\u043e \u0438 \u044d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043d\u043e\u0440\u043c\u0430\u043c \u0438 \u0440\u0435\u0433\u0443\u043b\u044f\u0442\u043e\u0440\u043d\u044b\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c.<\/p>\n<\/li>\n<\/ol>\n<hr\/>\n<h3>\ud83d\udd1a \u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435: \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u0435 \u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0435 \u2014 \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441<\/h3>\n<p>\u041c\u044b \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438 \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0418\u0418 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e. \u041d\u043e \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u043f\u0440\u043e\u0440\u044b\u0432 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0443\u0447\u0438\u043c \u043c\u0430\u0448\u0438\u043d\u044b \u043d\u0435 \u0442\u043e\u0440\u043e\u043f\u0438\u0442\u044c\u0441\u044f. \u041a\u043e\u0433\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0438\u043c\u0443\u043b\u043e\u043c \u0438 \u0440\u0435\u0430\u043a\u0446\u0438\u0435\u0439 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0430\u0443\u0437\u0430 \u2014 \u043d\u0430 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0435, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443, \u0441\u043e\u043c\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0413\u043e\u043d\u043a\u0430 \u0437\u0430 \u00ab\u043f\u043e\u043b\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0441\u0442\u044c\u044e\u00bb \u0447\u0430\u0441\u0442\u043e \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0438\u0438: <strong>\u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u0430\u0436\u043d\u0435\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438<\/strong>. \u0410\u0433\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e, \u043d\u043e \u043b\u043e\u043c\u0430\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b, \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u0435\u043d. \u0410\u0433\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0443\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u043d\u043e \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0435\u0431\u044f \u0438 \u0443\u0432\u0430\u0436\u0430\u0435\u0442 \u0433\u0440\u0430\u043d\u0438\u0446\u044b, \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430.<\/p>\n<p>\u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430 \u2014 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e \u0442\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0418\u0418 \u00ab\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0435\u0435\u00bb \u043a\u0430\u043a \u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433\u043e\u0432\u044b\u0439 \u0441\u043b\u043e\u0433\u0430\u043d. \u042d\u0442\u043e \u043f\u0440\u043e <strong>\u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u0430\u0433\u0435\u043d\u0442\u043e\u0432<\/strong>: \u0442\u0435\u0445, \u043a\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430, \u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043d\u0438\u043c. \u041a\u0442\u043e \u043d\u0435 \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0441\u0432\u043e\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0430 \u0434\u0435\u043b\u0430\u0435\u0442 \u0438\u0445 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u043c\u0438. \u041a\u0442\u043e \u043d\u0435 \u0431\u043e\u0438\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u0431\u044f \u0438 \u043f\u0440\u0438\u0437\u043d\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443. \u041a\u0442\u043e \u0431\u0435\u0440\u0451\u0442 \u043d\u0430 \u0441\u0435\u0431\u044f \u0440\u0443\u0442\u0438\u043d\u0443, \u0441\u0438\u043d\u0442\u0435\u0437 \u0438 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435, \u043d\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u043c \u043f\u0440\u0430\u0432\u043e \u0432\u0435\u0442\u043e, \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0438 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043b\u043e\u0432\u043e.<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u0438\u0435 \u0430\u0433\u0435\u043d\u0442\u044b \u0432\u044b\u0439\u0434\u0443\u0442 \u0438\u0437 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0438\u0440. \u0412 \u0431\u043e\u043b\u044c\u043d\u0438\u0446\u044b, \u0441\u0443\u0434\u044b, \u0431\u0430\u043d\u043a\u0438, \u0444\u0430\u0431\u0440\u0438\u043a\u0438. \u041d\u0435 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u0410 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0432\u0435\u0440\u044f\u0442\u044c.<\/p>\n<p><em>\u0421\u0430\u043c\u044b\u0439 \u0443\u043c\u043d\u044b\u0439 \u0430\u0433\u0435\u043d\u0442 \u2014 \u043d\u0435 \u0442\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0441\u0451 \u0441\u0430\u043c. \u0410 \u0442\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u0435\u0431\u044f \u0438 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c: \u00ab\u042f \u0432\u0441\u0451 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043d\u044f\u043b?\u00bb<\/em><\/p>\n<hr\/>\n<p><em>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 (\u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438, fuzzy-\u043f\u043e\u0438\u0441\u043a, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f MCP, \u043b\u043e\u0433\u0438\u043a\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430) \u0438\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0434\u043e\u043c\u0435\u043d\u0430 \u2014 \u0434\u0430\u0439\u0442\u0435 \u0437\u043d\u0430\u0442\u044c, \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u043e\u0434 \u043c\u0438\u043a\u0440\u043e\u0441\u043a\u043e\u043f\u043e\u043c.<\/em><\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1030196\/\">https:\/\/habr.com\/ru\/articles\/1030196\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041c\u044b \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438, \u0447\u0442\u043e \u0418\u0418-\u0430\u0433\u0435\u043d\u0442\u044b \u2014 \u044d\u0442\u043e \u043f\u0440\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c. \u0411\u044b\u0441\u0442\u0440\u0435\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434, \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c, \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041d\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0431\u0435\u0437 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f \u2014 \u044d\u0442\u043e \u043d\u0435 \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442, \u0430 \u0440\u0435\u0444\u043b\u0435\u043a\u0441. \u041d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u043f\u0440\u043e\u0440\u044b\u0432 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442, \u043a\u043e\u0433\u0434\u0430 \u0430\u0433\u0435\u043d\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0434\u0443\u043c\u0430\u0442\u044c, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u0435\u0431\u044f \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0448\u0430\u0433\u0430. \u0421\u043e\u043c\u043d\u0435\u0432\u0430\u0442\u044c\u0441\u044f. \u0421\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u0418 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c.\u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u044f\u0437\u044b\u043a\u043e\u0432\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u044e\u0442 \u0432 \u0442\u0435\u043e\u0440\u0438\u0438. \u041d\u043e \u0441\u0442\u043e\u0438\u0442 \u0434\u0430\u0442\u044c \u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043c\u0438\u0440\u0443, \u043a\u0430\u043a \u043f\u0440\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438: \u0433\u0430\u043b\u043b\u044e\u0446\u0438\u043d\u0430\u0446\u0438\u0438, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0451\u043d\u043d\u044b\u0435 \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f; \u043a\u0430\u0441\u043a\u0430\u0434\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u0433\u0434\u0435 \u043e\u0434\u043d\u0430 \u043d\u0435\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u0442\u044f\u043d\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439; \u0441\u043b\u0435\u043f\u043e\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u0446\u0435\u043b\u0438 \u0441 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u0431\u043e\u0447\u043d\u044b\u0445 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432; \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u0430\u043c\u043e\u043a\u0440\u0438\u0442\u0438\u043a\u0438. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u043d\u0435 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0443\u043c\u043d\u0435\u0435. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u0432 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0435 \u0432 \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u0432\u0435\u043d\u043e \u0446\u0438\u043a\u043b\u0430 \u00ab\u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u2192 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u2192 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u2192 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u00bb.\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u2014 \u043f\u0440\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0431\u0435\u0437\u0434\u0443\u043c\u043d\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u043c\u044b\u0441\u043b\u044f\u0449\u0435\u0433\u043e \u043a\u043e\u043b\u043b\u0435\u0433\u0443. \u0418 \u043e\u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043a\u043e\u0434\u043e\u043c, \u0430 \u043a \u043b\u044e\u0431\u043e\u043c\u0443 \u0434\u043e\u043c\u0435\u043d\u0443, \u0433\u0434\u0435 \u0446\u0435\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u044b\u0441\u043e\u043a\u0430: \u044e\u0440\u0438\u0441\u043f\u0440\u0443\u0434\u0435\u043d\u0446\u0438\u044f, \u043c\u0435\u0434\u0438\u0446\u0438\u043d\u0430, \u0444\u0438\u043d\u0430\u043d\u0441\u044b, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439, \u043c\u0430\u0440\u043a\u0435\u0442\u0438\u043d\u0433, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435.\ud83d\udc0d \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0418\u0418-\u0430\u0433\u0435\u043d\u0442\u0430 \u043d\u0430 Python\ud83d\udcc1 \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430reflective_agent\/\u251c\u2500\u2500 core\/\u2502   \u251c\u2500\u2500 __init__.py\u2502   \u251c\u2500\u2500 agent.py           # \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b \u0430\u0433\u0435\u043d\u0442\u0430\u2502   \u251c\u2500\u2500 context.py         # \u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u2502   \u251c\u2500\u2500 state.py           # \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c\u2502   \u2514\u2500\u2500 types.py           # \u0422\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445\u251c\u2500\u2500 tools\/\u2502   \u251c\u2500\u2500 __init__.py\u2502   \u251c\u2500\u2500 base.py            # \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432\u2502   \u251c\u2500\u2500 filesystem.py      # \u0424\u0430\u0439\u043b\u043e\u0432\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u2502   \u251c\u2500\u2500 terminal.py        # \u0422\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b\u2502   \u2514\u2500\u2500 mcp_adapter.py     # MCP \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u251c\u2500\u2500 safety\/\u2502   \u251c\u2500\u2500 __init__.py\u2502   \u251c\u2500\u2500 jail.py            # Scope Jail\u2502   \u251c\u2500\u2500 detectors.py       # \u0414\u0435\u0442\u0435\u043a\u0446\u0438\u044f \u0446\u0438\u043a\u043b\u043e\u0432\u2502   \u2514\u2500\u2500 snapshots.py       # \u0421\u043d\u0430\u043f\u0448\u043e\u0442\u044b \u0438 \u043e\u0442\u043a\u0430\u0442\u251c\u2500\u2500 ui\/\u2502   \u251c\u2500\u2500 __init__.py\u2502   \u2514\u2500\u2500 console.py         # \u041a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u2514\u2500\u2500 main.py                # \u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430\ud83d\udce6 \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445# core\/types.pyfrom dataclasses import dataclass, fieldfrom typing import Any, Optional, List, Dict, Literalfrom datetime import datetimefrom enum import Enumclass AgentMode(Enum):    CHAT = &#171;chat&#187;    AGENT = &#171;agent&#187;    TERMINAL = &#171;terminal&#187;class ToolRisk(Enum):    SAFE_READ = &#171;safe_read&#187;      # \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438    MODIFY = &#171;modify&#187;            # \u0427\u0435\u0440\u043d\u043e\u0432\u0438\u043a    DESTRUCTIVE = &#171;destructive&#187;  # \u0422\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f@dataclassclass Message:    role: Literal[&#171;user&#187;, &#171;assistant&#187;, &#171;system&#187;, &#171;tool&#187;]    content: Optional[str]    timestamp: float = field(default_factory=datetime.now().timestamp)    tool_calls: Optional[List[Dict]] = None    tool_call_id: Optional[str] = None    name: Optional[str] = None    requires_action: Optional[str] = None@dataclassclass ToolCall:    id: str    name: str    arguments: Dict[str, Any]    risk: ToolRisk@dataclassclass Draft:    file_path: str    original_content: str    new_content: str    status: Literal[&#171;pending&#187;, &#171;accepted&#187;, &#171;rejected&#187;] = &#171;pending&#187;@dataclassclass Snapshot:    id: str    timestamp: float    files: Dict[str, str]    messages: List[Message]    drafts: List[Draft]\ud83e\udde0 \u042f\u0434\u0440\u043e \u0430\u0433\u0435\u043d\u0442\u0430# core\/agent.pyimport asyncioimport jsonimport hashlibfrom typing import List, Optional, Dict, Any, Callablefrom datetime import datetimefrom openai import AsyncOpenAIfrom .types import (    AgentMode, Message, ToolCall, Draft, Snapshot, ToolRisk)from .context import DynamicContextfrom .state import AgentStatefrom safety.jail import ScopeJailfrom safety.detectors import LoopDetector, IterationLimiterfrom safety.snapshots import SnapshotManagerfrom tools.base import ToolRegistryclass ReflectiveAgent:    &#171;&#187;&#187;\u0420\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0418\u0418-\u0430\u0433\u0435\u043d\u0442 \u0441 \u0441\u0435\u043c\u0438\u0441\u0442\u0443\u043f\u0435\u043d\u0447\u0430\u0442\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c&#187;&#187;&#187;        def __init__(        self,        model: str = &#171;gpt-4&#187;,        api_key: str = None,        max_iterations: int = 15,        require_confirmation: bool = True    ):        self.client = AsyncOpenAI(api_key=api_key)        self.model = model        self.state = AgentState()        self.context = DynamicContext()        self.tools = ToolRegistry()        self.jail = ScopeJail()        self.loop_detector = LoopDetector(max_repeats=3)        self.iteration_limiter = IterationLimiter(max_iterations)        self.snapshot_manager = SnapshotManager()        self.require_confirmation = require_confirmation                # \u0424\u043b\u0430\u0433\u0438        self.is_reflecting = False        self._abort_controller = False            async def run(self, user_input: str) -&gt; None:        &#171;&#187;&#187;\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0430\u0433\u0435\u043d\u0442\u0430&#187;&#187;&#187;                # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043d\u0430\u043f\u0448\u043e\u0442 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c        await self.snapshot_manager.create_snapshot(self.state)                # \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f        user_message = Message(            role=&#187;user&#187;,            content=user_input,            timestamp=datetime.now().timestamp()        )        self.state.add_message(user_message)                # \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b        await self._run_cycle(depth=1)        async def _run_cycle(self, depth: int) -&gt; None:        &#171;&#187;&#187;\u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f&#187;&#187;&#187;                # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f        if self._abort_controller:            return                # \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043b\u0438\u043c\u0438\u0442\u0430 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439        if not self.iteration_limiter.can_continue(depth):            await self._handle_iteration_limit()            return                try:            # 1. \u0412\u041e\u0421\u041f\u0420\u0418\u042f\u0422\u0418\u0415 &#8212; \u0421\u0431\u043e\u0440 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430            context = await self.context.build_context(self.state)                        # 2. \u041f\u041b\u0410\u041d\u0418\u0420\u041e\u0412\u0410\u041d\u0418\u0415 &#8212; \u0412\u044b\u0437\u043e\u0432 LLM            response = await self._call_llm(context)                        # \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u0430            assistant_msg = Message(                role=&#187;assistant&#187;,                content=response.get(&#171;content&#187;),                tool_calls=response.get(&#171;tool_calls&#187;)            )            self.state.add_message(assistant_msg)                        # 3. \u041e\u0411\u0420\u0410\u0411\u041e\u0422\u041a\u0410 TOOL CALLS            if response.get(&#171;tool_calls&#187;):                await self._process_tool_calls(response[&#171;tool_calls&#187;])                                # \u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0448\u0430\u0433\u0430                await self._run_cycle(depth + 1)            else:                # \u041d\u0435\u0442 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 -&gt; \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435                await self._complete_task()                        except Exception as e:            await self._handle_error(e, depth)        async def _call_llm(self, context: str) -&gt; Dict[str, Any]:        &#171;&#187;&#187;\u0412\u044b\u0437\u043e\u0432 LLM \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c \u043f\u0440\u043e\u043c\u043f\u0442\u043e\u043c \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438&#187;&#187;&#187;                messages = [            {&#171;role&#187;: &#171;system&#187;, &#171;content&#187;: self._build_system_prompt()},            *[self._serialize_message(m) for m in self.state.messages]        ]                # \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043a\u0430\u043a \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435        messages.insert(1, {&#171;role&#187;: &#171;system&#187;, &#171;content&#187;: context})                tools = self.tools.get_openai_schema()                response = await self.client.chat.completions.create(            model=self.model,            messages=messages,            tools=tools if tools else None,            tool_choice=&#187;auto&#187; if tools else None,            temperature=0.3        )                message = response.choices[0].message                result = {&#171;content&#187;: message.content or &#171;&#187;}                if message.tool_calls:            result[&#171;tool_calls&#187;] = [                {                    &#171;id&#187;: tc.id,                    &#171;name&#187;: tc.function.name,                    &#171;arguments&#187;: json.loads(tc.function.arguments)                }                for tc in message.tool_calls            ]                return result        async def _process_tool_calls(self, tool_calls: List[Dict]) -&gt; None:        &#171;&#187;&#187;\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432&#187;&#187;&#187;                for tool_call in tool_calls:            if self._abort_controller:                break                        # 4. \u0428\u041b\u042e\u0417 &#8212; \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438            risk = self.tools.get_risk(tool_call[&#171;name&#187;])                        if risk == ToolRisk.DESTRUCTIVE and self.require_confirmation:                # \u041f\u0430\u0443\u0437\u0430, \u0436\u0434\u0435\u043c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f                await self._request_confirmation(tool_call)                return  # \u0412\u044b\u0445\u043e\u0434 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430, \u0436\u0434\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0435                        # 5. \u0414\u0415\u0422\u0415\u041a\u0426\u0418\u042f \u0417\u0410\u0426\u0418\u041a\u041b\u0418\u0412\u0410\u041d\u0418\u0419            signature = self._get_tool_signature(tool_call)            if self.loop_detector.check(signature):                await self._handle_loop_detected(tool_call)                return                        # 6. Scope Jail &#8212; \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u0440\u0430\u043d\u0438\u0446            if not await self.jail.check_permissions(tool_call):                await self._handle_access_denied(tool_call)                continue                        # 7. \u0412\u042b\u041f\u041e\u041b\u041d\u0415\u041d\u0418\u0415 \u0418\u041d\u0421\u0422\u0420\u0423\u041c\u0415\u041d\u0422\u0410            result = await self.tools.execute(                tool_call[&#171;name&#187;],                tool_call[&#171;arguments&#187;],                is_draft=(risk == ToolRisk.MODIFY)            )                        # \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442            tool_msg = Message(                role=&#187;tool&#187;,                content=result,                tool_call_id=tool_call[&#171;id&#187;],                name=tool_call[&#171;name&#187;]            )            self.state.add_message(tool_msg)        async def _complete_task(self) -&gt; None:        &#171;&#187;&#187;\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u0444\u0430\u0437\u043e\u0439 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438&#187;&#187;&#187;                if not self.is_reflecting:            # \u0424\u0410\u0417\u0410 \u0420\u0415\u0424\u041b\u0415\u041a\u0421\u0418\u0418            self.is_reflecting = True                        # \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0441\u0430\u043c\u043e\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443            reflection_msg = Message(                role=&#187;system&#187;,                content=&#187;\ud83d\udd04 **SELF-REFLECTION PHASE**\\n\\n&#187;                        &#171;\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443:\\n&#187;                        &#171;1. \u0412\u0441\u0435 \u043b\u0438 \u0448\u0430\u0433\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044b?\\n&#187;                        &#171;2. \u041d\u0435\u0442 \u043b\u0438 \u043e\u0448\u0438\u0431\u043e\u043a \u0438\u043b\u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043e\u0432?\\n&#187;                        &#171;3. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b &#8212; \u0438\u0441\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u0438\u0445\\n&#187;                        &#171;4. \u0415\u0441\u043b\u0438 \u0432\u0441\u0451 \u0432\u0435\u0440\u043d\u043e &#8212; \u0432\u044b\u0437\u043e\u0432\u0438\u0442\u0435 task_completed(verified=true)&#187;,                requires_action=&#187;reflect&#187;            )            self.state.add_message(reflection_msg)                        # \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0446\u0438\u043a\u043b \u0434\u043b\u044f \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438            await self._run_cycle(depth=self.state.current_depth + 1)        else:            # \u0424\u0418\u041d\u0410\u041b\u042c\u041d\u041e\u0415 &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-478130","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/478130","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=478130"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/478130\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=478130"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=478130"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=478130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}