autoglm-gui 0.4.12__tar.gz → 0.4.14__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/api/__init__.py +2 -1
- autoglm_gui-0.4.14/AutoGLM_GUI/api/version.py +192 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/schemas.py +11 -0
- autoglm_gui-0.4.12/AutoGLM_GUI/static/assets/about-kgOkkOWe.js → autoglm_gui-0.4.14/AutoGLM_GUI/static/assets/about-29B5FDM8.js +1 -1
- autoglm_gui-0.4.14/AutoGLM_GUI/static/assets/chat-DTN2oKtA.js +149 -0
- autoglm_gui-0.4.14/AutoGLM_GUI/static/assets/index-Dy550Qqg.css +1 -0
- autoglm_gui-0.4.12/AutoGLM_GUI/static/assets/index-BPYHsweG.js → autoglm_gui-0.4.14/AutoGLM_GUI/static/assets/index-mVNV0VwM.js +1 -1
- autoglm_gui-0.4.14/AutoGLM_GUI/static/assets/index-wu8Wjf12.js +10 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/static/index.html +2 -2
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/PKG-INFO +55 -2
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/README.md +54 -1
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/pyproject.toml +1 -1
- autoglm_gui-0.4.12/AutoGLM_GUI/static/assets/chat-CZV3RByK.js +0 -149
- autoglm_gui-0.4.12/AutoGLM_GUI/static/assets/index-Beu9cbSy.css +0 -1
- autoglm_gui-0.4.12/AutoGLM_GUI/static/assets/index-DfI_Z1Cx.js +0 -10
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/.gitignore +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/__init__.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/__main__.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/adb_plus/__init__.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/adb_plus/device.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/adb_plus/ip.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/adb_plus/keyboard_installer.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/adb_plus/screenshot.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/adb_plus/serial.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/adb_plus/touch.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/api/agents.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/api/control.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/api/devices.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/api/media.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/config.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/config_manager.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/exceptions.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/logger.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/platform_utils.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/scrcpy_protocol.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/scrcpy_stream.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/server.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/socketio_server.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/state.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/static/assets/worker-D6BRitjy.js +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/AutoGLM_GUI/version.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/LICENSE +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/__init__.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/actions/__init__.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/actions/handler.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/adb/__init__.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/adb/connection.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/adb/device.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/adb/input.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/adb/screenshot.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/agent.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/config/__init__.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/config/apps.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/config/i18n.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/config/prompts.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/config/prompts_en.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/config/prompts_zh.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/model/__init__.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/phone_agent/model/client.py +0 -0
- {autoglm_gui-0.4.12 → autoglm_gui-0.4.14}/scrcpy-server-v3.3.3 +0 -0
|
@@ -11,7 +11,7 @@ from fastapi.staticfiles import StaticFiles
|
|
|
11
11
|
|
|
12
12
|
from AutoGLM_GUI.version import APP_VERSION
|
|
13
13
|
|
|
14
|
-
from . import agents, control, devices, media
|
|
14
|
+
from . import agents, control, devices, media, version
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def _get_static_dir() -> Path | None:
|
|
@@ -54,6 +54,7 @@ def create_app() -> FastAPI:
|
|
|
54
54
|
app.include_router(devices.router)
|
|
55
55
|
app.include_router(control.router)
|
|
56
56
|
app.include_router(media.router)
|
|
57
|
+
app.include_router(version.router)
|
|
57
58
|
|
|
58
59
|
static_dir = _get_static_dir()
|
|
59
60
|
if static_dir is not None and static_dir.exists():
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Version check API for detecting updates from GitHub Releases."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import re
|
|
5
|
+
import time
|
|
6
|
+
import urllib.request
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from fastapi import APIRouter
|
|
10
|
+
|
|
11
|
+
from AutoGLM_GUI.logger import logger
|
|
12
|
+
from AutoGLM_GUI.schemas import VersionCheckResponse
|
|
13
|
+
from AutoGLM_GUI.version import APP_VERSION
|
|
14
|
+
|
|
15
|
+
router = APIRouter()
|
|
16
|
+
|
|
17
|
+
# In-memory cache for version check results
|
|
18
|
+
_version_cache: dict[str, Any] = {
|
|
19
|
+
"data": None,
|
|
20
|
+
"timestamp": 0,
|
|
21
|
+
"ttl": 3600, # 1 hour cache TTL
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# GitHub repository information
|
|
25
|
+
GITHUB_REPO = "suyiiyii/AutoGLM-GUI"
|
|
26
|
+
GITHUB_API_URL = f"https://api.github.com/repos/{GITHUB_REPO}/releases/latest"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def parse_version(version_str: str) -> tuple[int, ...] | None:
|
|
30
|
+
"""
|
|
31
|
+
Parse semantic version string into tuple of integers.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
version_str: Version string like "0.4.12" or "v0.5.0"
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Tuple of version numbers like (0, 4, 12) or None if invalid
|
|
38
|
+
"""
|
|
39
|
+
# Handle dev/unknown versions
|
|
40
|
+
if version_str in ("dev", "unknown", "..."):
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
# Strip 'v' prefix if present
|
|
44
|
+
version_str = version_str.lstrip("v")
|
|
45
|
+
|
|
46
|
+
# Remove pre-release tags (e.g., "-beta", "-rc1")
|
|
47
|
+
version_str = re.split(r"[-+]", version_str)[0]
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
return tuple(int(x) for x in version_str.split("."))
|
|
51
|
+
except (ValueError, AttributeError):
|
|
52
|
+
logger.warning(f"Failed to parse version: {version_str}")
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def compare_versions(current: str, latest: str) -> bool:
|
|
57
|
+
"""
|
|
58
|
+
Compare two semantic versions.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
current: Current version string
|
|
62
|
+
latest: Latest version string
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
True if update is available (latest > current), False otherwise
|
|
66
|
+
"""
|
|
67
|
+
current_tuple = parse_version(current)
|
|
68
|
+
latest_tuple = parse_version(latest)
|
|
69
|
+
|
|
70
|
+
# If either version is invalid, assume no update
|
|
71
|
+
if current_tuple is None or latest_tuple is None:
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
return latest_tuple > current_tuple
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def fetch_latest_release() -> dict[str, Any] | None:
|
|
78
|
+
"""
|
|
79
|
+
Fetch latest release information from GitHub API.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Release data dict with 'tag_name', 'html_url', 'published_at' or None on error
|
|
83
|
+
"""
|
|
84
|
+
try:
|
|
85
|
+
# Create request with User-Agent header (required by GitHub API)
|
|
86
|
+
req = urllib.request.Request(
|
|
87
|
+
GITHUB_API_URL,
|
|
88
|
+
headers={"User-Agent": f"AutoGLM-GUI/{APP_VERSION}"},
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Fetch data with 10-second timeout
|
|
92
|
+
with urllib.request.urlopen(req, timeout=10) as response:
|
|
93
|
+
data = json.loads(response.read().decode("utf-8"))
|
|
94
|
+
logger.debug(
|
|
95
|
+
f"Successfully fetched latest release: {data.get('tag_name', 'unknown')}"
|
|
96
|
+
)
|
|
97
|
+
return data
|
|
98
|
+
|
|
99
|
+
except urllib.error.HTTPError as e:
|
|
100
|
+
if e.code == 403:
|
|
101
|
+
logger.warning(
|
|
102
|
+
"GitHub API rate limit exceeded (HTTP 403), using cached data if available"
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
logger.warning(f"GitHub API HTTP error {e.code}: {e.reason}")
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
except urllib.error.URLError as e:
|
|
109
|
+
logger.warning(f"Network error fetching latest release: {e.reason}")
|
|
110
|
+
return None
|
|
111
|
+
|
|
112
|
+
except json.JSONDecodeError as e:
|
|
113
|
+
logger.error(f"Failed to parse GitHub API response: {e}")
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
except Exception as e:
|
|
117
|
+
logger.error(f"Unexpected error fetching latest release: {e}")
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@router.get("/api/version/latest", response_model=VersionCheckResponse)
|
|
122
|
+
def check_version() -> VersionCheckResponse:
|
|
123
|
+
"""
|
|
124
|
+
Check for available updates from GitHub Releases.
|
|
125
|
+
|
|
126
|
+
Returns version comparison results with caching to minimize API calls.
|
|
127
|
+
Cache TTL is 1 hour to stay within GitHub API rate limits (60 req/hour).
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
VersionCheckResponse with update information
|
|
131
|
+
"""
|
|
132
|
+
current_time = time.time()
|
|
133
|
+
|
|
134
|
+
# Check if cache is still valid
|
|
135
|
+
if (
|
|
136
|
+
_version_cache["data"] is not None
|
|
137
|
+
and current_time - _version_cache["timestamp"] < _version_cache["ttl"]
|
|
138
|
+
):
|
|
139
|
+
logger.debug(
|
|
140
|
+
f"Using cached version check result (age: {int(current_time - _version_cache['timestamp'])}s)"
|
|
141
|
+
)
|
|
142
|
+
return _version_cache["data"]
|
|
143
|
+
|
|
144
|
+
# Fetch latest release from GitHub
|
|
145
|
+
release_data = fetch_latest_release()
|
|
146
|
+
|
|
147
|
+
if release_data is None:
|
|
148
|
+
# If fetch failed, check if we have cached data to fall back to
|
|
149
|
+
if _version_cache["data"] is not None:
|
|
150
|
+
logger.warning("Using stale cached data due to fetch failure")
|
|
151
|
+
return _version_cache["data"]
|
|
152
|
+
|
|
153
|
+
# No cache available, return safe defaults
|
|
154
|
+
response = VersionCheckResponse(
|
|
155
|
+
current_version=APP_VERSION,
|
|
156
|
+
latest_version=None,
|
|
157
|
+
has_update=False,
|
|
158
|
+
release_url=None,
|
|
159
|
+
published_at=None,
|
|
160
|
+
error="Failed to fetch latest version from GitHub",
|
|
161
|
+
)
|
|
162
|
+
logger.info("Version check failed, returning safe defaults")
|
|
163
|
+
return response
|
|
164
|
+
|
|
165
|
+
# Extract version information from release data
|
|
166
|
+
tag_name = release_data.get("tag_name", "")
|
|
167
|
+
latest_version = tag_name.lstrip("v") # Strip 'v' prefix
|
|
168
|
+
release_url = release_data.get("html_url")
|
|
169
|
+
published_at = release_data.get("published_at")
|
|
170
|
+
|
|
171
|
+
# Compare versions
|
|
172
|
+
has_update = compare_versions(APP_VERSION, latest_version)
|
|
173
|
+
|
|
174
|
+
# Build response
|
|
175
|
+
response = VersionCheckResponse(
|
|
176
|
+
current_version=APP_VERSION,
|
|
177
|
+
latest_version=latest_version,
|
|
178
|
+
has_update=has_update,
|
|
179
|
+
release_url=release_url,
|
|
180
|
+
published_at=published_at,
|
|
181
|
+
error=None,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Update cache
|
|
185
|
+
_version_cache["data"] = response
|
|
186
|
+
_version_cache["timestamp"] = current_time
|
|
187
|
+
|
|
188
|
+
logger.info(
|
|
189
|
+
f"Version check completed: current={APP_VERSION}, latest={latest_version}, has_update={has_update}"
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
return response
|
|
@@ -175,3 +175,14 @@ class WiFiDisconnectResponse(BaseModel):
|
|
|
175
175
|
success: bool
|
|
176
176
|
message: str
|
|
177
177
|
error: str | None = None
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
class VersionCheckResponse(BaseModel):
|
|
181
|
+
"""Version update check response."""
|
|
182
|
+
|
|
183
|
+
current_version: str
|
|
184
|
+
latest_version: str | None = None
|
|
185
|
+
has_update: bool = False
|
|
186
|
+
release_url: str | None = None
|
|
187
|
+
published_at: str | None = None
|
|
188
|
+
error: str | None = None
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as o}from"./index-
|
|
1
|
+
import{j as o}from"./index-wu8Wjf12.js";function t(){return o.jsx("div",{className:"p-2",children:o.jsx("h3",{children:"About"})})}export{t as component};
|