supervaizer 0.10.11__py3-none-any.whl → 0.10.13__py3-none-any.whl
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.
- supervaizer/__init__.py +7 -3
- supervaizer/__version__.py +1 -1
- supervaizer/admin/routes.py +51 -2
- supervaizer/admin/templates/server.html +50 -4
- supervaizer/agent.py +2 -1
- {supervaizer-0.10.11.dist-info → supervaizer-0.10.13.dist-info}/METADATA +1 -1
- {supervaizer-0.10.11.dist-info → supervaizer-0.10.13.dist-info}/RECORD +10 -10
- {supervaizer-0.10.11.dist-info → supervaizer-0.10.13.dist-info}/WHEEL +0 -0
- {supervaizer-0.10.11.dist-info → supervaizer-0.10.13.dist-info}/entry_points.txt +0 -0
- {supervaizer-0.10.11.dist-info → supervaizer-0.10.13.dist-info}/licenses/LICENSE.md +0 -0
supervaizer/__init__.py
CHANGED
|
@@ -13,6 +13,8 @@ from supervaizer.agent import (
|
|
|
13
13
|
AgentMethod,
|
|
14
14
|
AgentMethodParams,
|
|
15
15
|
AgentMethods,
|
|
16
|
+
AgentMethodField,
|
|
17
|
+
FieldTypeEnum,
|
|
16
18
|
)
|
|
17
19
|
from supervaizer.case import (
|
|
18
20
|
Case,
|
|
@@ -50,6 +52,7 @@ __all__ = [
|
|
|
50
52
|
"Agent",
|
|
51
53
|
"AgentCustomMethodParams",
|
|
52
54
|
"AgentMethod",
|
|
55
|
+
"AgentMethodField",
|
|
53
56
|
"AgentMethodParams",
|
|
54
57
|
"AgentMethods",
|
|
55
58
|
"AgentRegisterEvent",
|
|
@@ -57,11 +60,11 @@ __all__ = [
|
|
|
57
60
|
"ApiResult",
|
|
58
61
|
"ApiSuccess",
|
|
59
62
|
"Case",
|
|
60
|
-
"CaseNodeUpdate",
|
|
61
|
-
"CaseNodeType",
|
|
62
|
-
"Cases",
|
|
63
63
|
"CaseNode",
|
|
64
64
|
"CaseNodes",
|
|
65
|
+
"CaseNodeType",
|
|
66
|
+
"CaseNodeUpdate",
|
|
67
|
+
"Cases",
|
|
65
68
|
"CaseStartEvent",
|
|
66
69
|
"CaseUpdateEvent",
|
|
67
70
|
"create_error_response",
|
|
@@ -75,6 +78,7 @@ __all__ = [
|
|
|
75
78
|
"ErrorType",
|
|
76
79
|
"Event",
|
|
77
80
|
"EventType",
|
|
81
|
+
"FieldTypeEnum",
|
|
78
82
|
"Job",
|
|
79
83
|
"JobContext",
|
|
80
84
|
"JobFinishedEvent",
|
supervaizer/__version__.py
CHANGED
supervaizer/admin/routes.py
CHANGED
|
@@ -20,8 +20,8 @@ from pathlib import Path
|
|
|
20
20
|
from typing import Any, AsyncGenerator, Dict, List, Optional
|
|
21
21
|
|
|
22
22
|
import psutil
|
|
23
|
-
from fastapi import APIRouter, HTTPException, Query, Request, Security
|
|
24
|
-
from fastapi.responses import HTMLResponse, Response
|
|
23
|
+
from fastapi import APIRouter, Depends, HTTPException, Query, Request, Security
|
|
24
|
+
from fastapi.responses import HTMLResponse, JSONResponse, Response
|
|
25
25
|
from fastapi.security import APIKeyHeader
|
|
26
26
|
from fastapi.templating import Jinja2Templates
|
|
27
27
|
from pydantic import BaseModel
|
|
@@ -413,6 +413,55 @@ def create_admin_routes() -> APIRouter:
|
|
|
413
413
|
log.error(f"Get server status API error: {e}")
|
|
414
414
|
raise HTTPException(status_code=500, detail=str(e))
|
|
415
415
|
|
|
416
|
+
@router.post("/api/server/register")
|
|
417
|
+
async def register_server_with_supervisor(
|
|
418
|
+
request: Request,
|
|
419
|
+
_: bool = Depends(verify_admin_access),
|
|
420
|
+
) -> JSONResponse:
|
|
421
|
+
"""Trigger SERVER_REGISTER to the supervaizer supervisor."""
|
|
422
|
+
try:
|
|
423
|
+
from supervaizer.common import ApiSuccess
|
|
424
|
+
from supervaizer.routes import get_server
|
|
425
|
+
|
|
426
|
+
get_current = request.app.dependency_overrides.get(get_server)
|
|
427
|
+
if get_current is None:
|
|
428
|
+
raise HTTPException(
|
|
429
|
+
status_code=503,
|
|
430
|
+
detail="Server instance not available (admin not running with live server)",
|
|
431
|
+
)
|
|
432
|
+
try:
|
|
433
|
+
server = await get_current()
|
|
434
|
+
except (NotImplementedError, TypeError):
|
|
435
|
+
raise HTTPException(
|
|
436
|
+
status_code=503,
|
|
437
|
+
detail="Server instance not available (admin not running with live server)",
|
|
438
|
+
)
|
|
439
|
+
if not getattr(server, "supervisor_account", None):
|
|
440
|
+
raise HTTPException(
|
|
441
|
+
status_code=503,
|
|
442
|
+
detail="No supervisor account configured",
|
|
443
|
+
)
|
|
444
|
+
result = server.supervisor_account.register_server(server=server)
|
|
445
|
+
if isinstance(result, ApiSuccess):
|
|
446
|
+
return JSONResponse(
|
|
447
|
+
status_code=200,
|
|
448
|
+
content={"success": True, "message": result.message, "detail": result.detail},
|
|
449
|
+
)
|
|
450
|
+
# ApiError
|
|
451
|
+
return JSONResponse(
|
|
452
|
+
status_code=502,
|
|
453
|
+
content={
|
|
454
|
+
"success": False,
|
|
455
|
+
"message": result.message,
|
|
456
|
+
"detail": getattr(result, "detail", None),
|
|
457
|
+
},
|
|
458
|
+
)
|
|
459
|
+
except HTTPException:
|
|
460
|
+
raise
|
|
461
|
+
except Exception as e:
|
|
462
|
+
log.error(f"Server register API error: {e}")
|
|
463
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
464
|
+
|
|
416
465
|
@router.get("/api/agents")
|
|
417
466
|
async def get_agents_api(
|
|
418
467
|
request: Request,
|
|
@@ -12,7 +12,15 @@
|
|
|
12
12
|
</h2>
|
|
13
13
|
<p class="mt-1 text-sm text-gray-500">Monitor server health and configuration</p>
|
|
14
14
|
</div>
|
|
15
|
-
<div class="mt-4 flex md:mt-0">
|
|
15
|
+
<div class="mt-4 flex md:mt-0 gap-2">
|
|
16
|
+
<button
|
|
17
|
+
id="register-supervisor-btn"
|
|
18
|
+
type="button"
|
|
19
|
+
class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
|
20
|
+
>
|
|
21
|
+
<span id="register-indicator" class="htmx-indicator -ml-1 mr-2 h-4 w-4 border-2 border-white border-t-transparent rounded-full animate-spin"></span>
|
|
22
|
+
Register with supervisor
|
|
23
|
+
</button>
|
|
16
24
|
<button
|
|
17
25
|
hx-get="/admin/api/server/status"
|
|
18
26
|
hx-target="#server-status-container"
|
|
@@ -26,6 +34,7 @@
|
|
|
26
34
|
Refresh
|
|
27
35
|
</button>
|
|
28
36
|
</div>
|
|
37
|
+
<div id="register-result" class="mt-2 text-sm hidden" role="alert"></div>
|
|
29
38
|
</div>
|
|
30
39
|
|
|
31
40
|
<!-- Server Status Cards -->
|
|
@@ -91,15 +100,52 @@
|
|
|
91
100
|
</div>
|
|
92
101
|
|
|
93
102
|
<script>
|
|
94
|
-
// Auto-refresh server status every 30 seconds
|
|
95
103
|
document.addEventListener('DOMContentLoaded', function() {
|
|
96
|
-
//
|
|
104
|
+
// Auto-refresh server status every 30 seconds
|
|
97
105
|
setInterval(function() {
|
|
98
106
|
const refreshButton = document.querySelector('[hx-get="/admin/api/server/status"]');
|
|
99
107
|
if (refreshButton) {
|
|
100
108
|
htmx.trigger(refreshButton, 'click');
|
|
101
109
|
}
|
|
102
|
-
}, 30000);
|
|
110
|
+
}, 30000);
|
|
111
|
+
|
|
112
|
+
// Register with supervisor button
|
|
113
|
+
const registerBtn = document.getElementById('register-supervisor-btn');
|
|
114
|
+
const registerIndicator = document.getElementById('register-indicator');
|
|
115
|
+
const registerResult = document.getElementById('register-result');
|
|
116
|
+
if (registerBtn) {
|
|
117
|
+
registerBtn.addEventListener('click', async function() {
|
|
118
|
+
const params = new URLSearchParams(window.location.search);
|
|
119
|
+
const key = params.get('key');
|
|
120
|
+
const url = key ? '/admin/api/server/register?key=' + encodeURIComponent(key) : '/admin/api/server/register';
|
|
121
|
+
registerResult.classList.add('hidden');
|
|
122
|
+
registerIndicator.classList.remove('htmx-indicator');
|
|
123
|
+
registerBtn.disabled = true;
|
|
124
|
+
try {
|
|
125
|
+
const res = await fetch(url, { method: 'POST' });
|
|
126
|
+
const data = await res.json().catch(function() { return {}; });
|
|
127
|
+
registerResult.classList.remove('hidden');
|
|
128
|
+
if (res.ok && data.success) {
|
|
129
|
+
registerResult.className = 'mt-2 text-sm text-green-700';
|
|
130
|
+
registerResult.textContent = data.message || 'Registered successfully.';
|
|
131
|
+
} else {
|
|
132
|
+
registerResult.className = 'mt-2 text-sm text-red-700';
|
|
133
|
+
if (res.status === 403) {
|
|
134
|
+
registerResult.textContent = 'Authentication required. Open this page with ?key=...';
|
|
135
|
+
} else {
|
|
136
|
+
registerResult.textContent = (data.detail && typeof data.detail === 'object' && data.detail.message) ? data.detail.message : (data.message || 'Registration failed.');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
} catch (e) {
|
|
140
|
+
registerResult.classList.remove('hidden');
|
|
141
|
+
registerResult.className = 'mt-2 text-sm text-red-700';
|
|
142
|
+
registerResult.textContent = 'Request failed: ' + (e.message || String(e));
|
|
143
|
+
} finally {
|
|
144
|
+
registerIndicator.classList.add('htmx-indicator');
|
|
145
|
+
registerBtn.disabled = false;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
103
149
|
});
|
|
104
150
|
</script>
|
|
105
151
|
{% endblock %}
|
supervaizer/agent.py
CHANGED
|
@@ -78,7 +78,7 @@ class AgentMethodField(BaseModel):
|
|
|
78
78
|
type: Any = Field(
|
|
79
79
|
description="Python type of the field for pydantic validation - note , ChoiceField and MultipleChoiceField are a list[str]"
|
|
80
80
|
)
|
|
81
|
-
field_type: FieldTypeEnum = Field(
|
|
81
|
+
field_type: FieldTypeEnum | str = Field(
|
|
82
82
|
default=FieldTypeEnum.CHAR, description="Field type for persistence"
|
|
83
83
|
)
|
|
84
84
|
description: str | None = Field(
|
|
@@ -185,6 +185,7 @@ class AgentMethodAbstract(BaseModel):
|
|
|
185
185
|
default=None,
|
|
186
186
|
description="A list of field specifications for generating forms/UI, following the django.forms.fields definition",
|
|
187
187
|
)
|
|
188
|
+
|
|
188
189
|
description: str | None = Field(
|
|
189
190
|
default=None, description="Optional description of what the method does"
|
|
190
191
|
)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
supervaizer/__init__.py,sha256=
|
|
2
|
-
supervaizer/__version__.py,sha256=
|
|
1
|
+
supervaizer/__init__.py,sha256=UNFcgJT-2708tLRFXohWr3320LVAzh3_WZZhrU9j1Iw,2427
|
|
2
|
+
supervaizer/__version__.py,sha256=wRbe-Q7prh4XO5nZ2QCM3r5X1kyop9Z1iXGnIAsvsXY,349
|
|
3
3
|
supervaizer/account.py,sha256=TZQdDo1OdjquFsLFxPvUUqzOcdMOIAQHHaREghD5SJ4,11421
|
|
4
4
|
supervaizer/account_service.py,sha256=ZgZ0fhsbSVA076c-35ZZoYJBrQZsAwfFS7namVeoD3s,3459
|
|
5
|
-
supervaizer/agent.py,sha256=
|
|
5
|
+
supervaizer/agent.py,sha256=EtmqBH9fsO4k8YcHnjj55_4uOmb5URZwLlIIJReWg7A,36516
|
|
6
6
|
supervaizer/case.py,sha256=dOgRujyf4MFcZ-937zxJbqLIPduKg6ZspHuhnWiq13Q,14385
|
|
7
7
|
supervaizer/cli.py,sha256=3KH4gZXTiJ9GtY375kGm5HaKCGV2V8WEbcWdF_sWWEc,13936
|
|
8
8
|
supervaizer/common.py,sha256=6ygNS1YxliP-e6OEVX7vDuC8YAaT2rYhjqQ_8txnWlg,10066
|
|
@@ -17,7 +17,7 @@ supervaizer/server.py,sha256=79MtQcB4fpV9VgFh-dBsbwbHf097waeLmBnArhClVb8,22473
|
|
|
17
17
|
supervaizer/server_utils.py,sha256=FMglpADQBJynkR2v-pfwANu6obsaPvR9j0BQc5Otpac,1590
|
|
18
18
|
supervaizer/storage.py,sha256=WLX8ggwt1AGF07DrfD1K6PyP2-N45c_Ep4CL0iPLVbI,15332
|
|
19
19
|
supervaizer/telemetry.py,sha256=XSYw8ZwoY8W6C7mhwHU67t7trJzWd7CBkkSNdsDT_HA,2596
|
|
20
|
-
supervaizer/admin/routes.py,sha256=
|
|
20
|
+
supervaizer/admin/routes.py,sha256=g69rpjYcMIyMrqnRMyf3YZbYLMa6GBMWWPF1-vh2M6s,47662
|
|
21
21
|
supervaizer/admin/static/favicon.ico,sha256=wFyXw96AplZoEcW45dJBeC1pHTcPSH07HGWbtrc49mI,5558
|
|
22
22
|
supervaizer/admin/static/js/job-start-form.js,sha256=s--AGVYzgc9mE20POYeM0BNm0Wy41aBZVv99tc0cSPU,11938
|
|
23
23
|
supervaizer/admin/templates/agent_detail.html,sha256=DFOGfjuQNC39FOLYUW_jD0A01WpBY1umatGCslyJ0_c,7581
|
|
@@ -36,7 +36,7 @@ supervaizer/admin/templates/jobs_list.html,sha256=VJ2VYe62dHXvjQQgUAVyKcn58rO591
|
|
|
36
36
|
supervaizer/admin/templates/jobs_table.html,sha256=BCOI_7QlxJ5XOra7WKou48a2lNwQYASCMFTtgzHNotw,5974
|
|
37
37
|
supervaizer/admin/templates/navigation.html,sha256=Ci_CMLqBuIKRt3JCFtn9Vjz1AAkqC75WMT6IQUiByFI,11724
|
|
38
38
|
supervaizer/admin/templates/recent_activity.html,sha256=hL06GXF1a-C_tkj3pRLrDTTDqG0KplcWMZFengFMuEc,4843
|
|
39
|
-
supervaizer/admin/templates/server.html,sha256=
|
|
39
|
+
supervaizer/admin/templates/server.html,sha256=CScvNTNdc0Wi2entmzZHSnqrBjqIOZUsbQrWD58pBYM,8527
|
|
40
40
|
supervaizer/admin/templates/server_status_cards.html,sha256=yJ36hkfgQpscYkiaodFDQPnmJWeb2W7gey09Z3T6JsY,7882
|
|
41
41
|
supervaizer/admin/templates/supervaize_instructions.html,sha256=LTLla1xgIeLpFf7bond_lxH5qdQQ2ak52Fd7hqChi1I,10225
|
|
42
42
|
supervaizer/deploy/__init__.py,sha256=DvngGQu8tS_Yz5FU4kKCvPpod11IGCtZWkUNeB5aVHI,557
|
|
@@ -72,8 +72,8 @@ supervaizer/protocol/a2a/routes.py,sha256=rkQTNBD1NTYimKCb8iOk4bVf9ldDP1LqHfOsyh
|
|
|
72
72
|
supervaizer/utils/__init__.py,sha256=fd0NFwN_cen3QPms2SOnuz4jcetay3f_31dit2As7EA,458
|
|
73
73
|
supervaizer/utils/version_check.py,sha256=-tsOURpHVh0LNTbpQsyJDJENKszC-NzXDSO_EToEQPE,1893
|
|
74
74
|
supervaizer/py.typed,sha256=bHhvLx7c6MqrzXVPbdK3qAOcSxzp4wDtTx4QifMC2EY,74
|
|
75
|
-
supervaizer-0.10.
|
|
76
|
-
supervaizer-0.10.
|
|
77
|
-
supervaizer-0.10.
|
|
78
|
-
supervaizer-0.10.
|
|
79
|
-
supervaizer-0.10.
|
|
75
|
+
supervaizer-0.10.13.dist-info/METADATA,sha256=DQHnw0z-YcxPDQwAQNF3qMxS9_EKQ1gVqWf_8Vq7KEg,12648
|
|
76
|
+
supervaizer-0.10.13.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
77
|
+
supervaizer-0.10.13.dist-info/entry_points.txt,sha256=vL_IBR_AeEI2u2-6YL4PY9k2Mar4-gprG8-UxERWjmg,52
|
|
78
|
+
supervaizer-0.10.13.dist-info/licenses/LICENSE.md,sha256=dmdnt1vfpxNPr8Lt0BnxKE5uzUwK3CWTthTUStgOXjY,15327
|
|
79
|
+
supervaizer-0.10.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|