fix: install git for durable state recovery
This commit is contained in:
@@ -5,6 +5,10 @@ ENV PYTHONPATH=/app/modelhub_submmit_api
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends ca-certificates git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
|
||||
@@ -362,18 +362,19 @@ counts fail closed for older candidates, and no startup or periodic cleanup can
|
||||
cancel a task by date. It also keeps unclassified/ambiguous historical failures
|
||||
neutral in GPU/framework success feedback while preserving deterministic OOM
|
||||
and architecture cleanup.
|
||||
Version `2026.08.15.1` replaces the 70/30 quota with hierarchical success-first
|
||||
Version `2026.08.15.2` replaces the 70/30 quota with hierarchical success-first
|
||||
routing, dynamically gates models through the official GPU/task/framework/config
|
||||
APIs, enriches ModelScope metadata and model lineage, learns only proven safe
|
||||
config vectors, and adds crash-safe write-ahead state synchronization to the
|
||||
`agent-state` branch. It also exposes `/ready` and extends deterministic cleanup
|
||||
to officially removed waiting GPU/framework routes.
|
||||
to officially removed waiting GPU/framework routes. The runtime image installs
|
||||
Git and CA certificates required by state recovery and synchronization.
|
||||
|
||||
## Deploy
|
||||
|
||||
Create a tag and submit the repository URL plus tag in "我的适配智能体".
|
||||
|
||||
```bash
|
||||
git tag -a agent-v25 -m "ModelHub agent 2026.08.15.1"
|
||||
git push origin main agent-v25
|
||||
git tag -a agent-v26 -m "ModelHub agent 2026.08.15.2"
|
||||
git push origin main agent-v26
|
||||
```
|
||||
|
||||
@@ -222,16 +222,23 @@ class StateGitSync:
|
||||
return env
|
||||
|
||||
def _git(self, *args: str, cwd: Path | None = None, check: bool = True) -> subprocess.CompletedProcess[str]:
|
||||
result = subprocess.run(
|
||||
["git", *args],
|
||||
cwd=str(cwd or self.project_root),
|
||||
env=self._git_environment(),
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
timeout=45,
|
||||
check=False,
|
||||
)
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", *args],
|
||||
cwd=str(cwd or self.project_root),
|
||||
env=self._git_environment(),
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
timeout=45,
|
||||
check=False,
|
||||
)
|
||||
except FileNotFoundError as exc:
|
||||
raise StateSyncError(
|
||||
"git executable is unavailable; rebuild the service image from the repository Dockerfile"
|
||||
) from exc
|
||||
except subprocess.TimeoutExpired as exc:
|
||||
raise StateSyncError("git operation timed out after 45 seconds") from exc
|
||||
if check and result.returncode != 0:
|
||||
reason = _safe_text(result.stderr.strip() or result.stdout.strip() or f"git exited {result.returncode}")
|
||||
raise StateSyncError(reason)
|
||||
|
||||
@@ -1 +1 @@
|
||||
AGENT_VERSION = "2026.08.15.1"
|
||||
AGENT_VERSION = "2026.08.15.2"
|
||||
|
||||
@@ -20,6 +20,7 @@ from hf_discovery import HuggingFaceDiscovery, parse_model_card_front_matter #
|
||||
from official_capabilities import OfficialCapabilityRegistry # noqa: E402
|
||||
from routing_engine import SuccessFirstRoutingEngine # noqa: E402
|
||||
from state_sync import StateGitSync # noqa: E402
|
||||
from state_sync import StateSyncError # noqa: E402
|
||||
|
||||
|
||||
class OfficialClient:
|
||||
@@ -207,6 +208,19 @@ class SuperAgentTests(unittest.TestCase):
|
||||
)
|
||||
)
|
||||
|
||||
def test_missing_git_has_actionable_state_sync_error(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temporary_dir:
|
||||
manager = StateGitSync(
|
||||
project_root=Path(temporary_dir),
|
||||
credentials={"username": "u", "email": "e@example.com", "password": "p"},
|
||||
remote="unused",
|
||||
log_fn=lambda _: None,
|
||||
)
|
||||
with patch("state_sync.subprocess.run", side_effect=FileNotFoundError("git")):
|
||||
with self.assertRaisesRegex(StateSyncError, "rebuild the service image"):
|
||||
manager._git("version")
|
||||
manager.close()
|
||||
|
||||
def test_config_patch_requires_repeated_cross_model_success(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as temporary_dir:
|
||||
root = Path(temporary_dir)
|
||||
|
||||
Reference in New Issue
Block a user