supervaizer 0.10.13__tar.gz → 0.10.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.
Files changed (79) hide show
  1. {supervaizer-0.10.13 → supervaizer-0.10.14}/PKG-INFO +1 -1
  2. {supervaizer-0.10.13 → supervaizer-0.10.14}/pyproject.toml +1 -1
  3. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/__version__.py +1 -1
  4. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/account.py +7 -1
  5. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/routes.py +33 -33
  6. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/index.html +1 -0
  7. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/server.py +32 -35
  8. {supervaizer-0.10.13 → supervaizer-0.10.14}/.gitignore +0 -0
  9. {supervaizer-0.10.13 → supervaizer-0.10.14}/LICENSE.md +0 -0
  10. {supervaizer-0.10.13 → supervaizer-0.10.14}/README.md +0 -0
  11. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/__init__.py +0 -0
  12. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/account_service.py +0 -0
  13. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/static/favicon.ico +0 -0
  14. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/static/js/job-start-form.js +0 -0
  15. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/agent_detail.html +0 -0
  16. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/agents.html +0 -0
  17. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/agents_grid.html +0 -0
  18. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/base.html +0 -0
  19. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/case_detail.html +0 -0
  20. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/cases_list.html +0 -0
  21. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/cases_table.html +0 -0
  22. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/console.html +0 -0
  23. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/dashboard.html +0 -0
  24. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/job_detail.html +0 -0
  25. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/job_start_test.html +0 -0
  26. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/jobs_list.html +0 -0
  27. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/jobs_table.html +0 -0
  28. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/navigation.html +0 -0
  29. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/recent_activity.html +0 -0
  30. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/server.html +0 -0
  31. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/server_status_cards.html +0 -0
  32. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/admin/templates/supervaize_instructions.html +0 -0
  33. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/agent.py +0 -0
  34. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/case.py +0 -0
  35. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/cli.py +0 -0
  36. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/common.py +0 -0
  37. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/__init__.py +0 -0
  38. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/cli.py +0 -0
  39. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/commands/__init__.py +0 -0
  40. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/commands/clean.py +0 -0
  41. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/commands/down.py +0 -0
  42. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/commands/local.py +0 -0
  43. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/commands/plan.py +0 -0
  44. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/commands/status.py +0 -0
  45. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/commands/up.py +0 -0
  46. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/docker.py +0 -0
  47. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/driver_factory.py +0 -0
  48. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/drivers/__init__.py +0 -0
  49. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/drivers/aws_app_runner.py +0 -0
  50. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/drivers/base.py +0 -0
  51. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/drivers/cloud_run.py +0 -0
  52. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/drivers/do_app_platform.py +0 -0
  53. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/health.py +0 -0
  54. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/state.py +0 -0
  55. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/templates/Dockerfile.template +0 -0
  56. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/templates/debug_env.py +0 -0
  57. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/templates/docker-compose.yml.template +0 -0
  58. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/templates/dockerignore.template +0 -0
  59. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/templates/entrypoint.sh +0 -0
  60. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/templates/index.html +0 -0
  61. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/deploy/utils.py +0 -0
  62. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/event.py +0 -0
  63. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/examples/controller_template.py +0 -0
  64. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/instructions.py +0 -0
  65. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/job.py +0 -0
  66. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/job_service.py +0 -0
  67. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/lifecycle.py +0 -0
  68. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/parameter.py +0 -0
  69. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/protocol/__init__.py +0 -0
  70. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/protocol/a2a/__init__.py +0 -0
  71. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/protocol/a2a/model.py +0 -0
  72. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/protocol/a2a/routes.py +0 -0
  73. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/py.typed +0 -0
  74. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/routes.py +0 -0
  75. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/server_utils.py +0 -0
  76. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/storage.py +0 -0
  77. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/telemetry.py +0 -0
  78. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/utils/__init__.py +0 -0
  79. {supervaizer-0.10.13 → supervaizer-0.10.14}/src/supervaizer/utils/version_check.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supervaizer
3
- Version: 0.10.13
3
+ Version: 0.10.14
4
4
  Summary: Controller system for Supervaize
5
5
  Project-URL: Homepage, https://supervaize.com
6
6
  Project-URL: Repository, https://github.com/supervaize/supervaizer
@@ -121,7 +121,7 @@ mypy_path = "src"
121
121
  disallow_any_expr = false
122
122
 
123
123
  [tool.bumpversion]
124
- current_version = "0.10.13"
124
+ current_version = "0.10.14"
125
125
  commit = true
126
126
  tag = true
127
127
  tag_name = "v{new_version}"
@@ -5,6 +5,6 @@
5
5
  # https://mozilla.org/MPL/2.0/.
6
6
 
7
7
 
8
- VERSION = "0.10.13"
8
+ VERSION = "0.10.14"
9
9
  API_VERSION = "v1"
10
10
  TELEMETRY_VERSION = "v1"
@@ -199,7 +199,13 @@ class Account(AccountAbstract):
199
199
  from supervaizer.event import ServerRegisterEvent
200
200
 
201
201
  event = ServerRegisterEvent(server=server, account=self)
202
- return self.send_event(sender=server, event=event)
202
+ result = self.send_event(sender=server, event=event)
203
+ if isinstance(result, ApiSuccess):
204
+ log.success(result.message)
205
+ # TODO: Update server with the server ID from the response. store this ID in env variable.
206
+ else:
207
+ log.error(result.message)
208
+ return result
203
209
 
204
210
  def _create_api_result(
205
211
  self,
@@ -445,7 +445,11 @@ def create_admin_routes() -> APIRouter:
445
445
  if isinstance(result, ApiSuccess):
446
446
  return JSONResponse(
447
447
  status_code=200,
448
- content={"success": True, "message": result.message, "detail": result.detail},
448
+ content={
449
+ "success": True,
450
+ "message": result.message,
451
+ "detail": result.detail,
452
+ },
449
453
  )
450
454
  # ApiError
451
455
  return JSONResponse(
@@ -921,28 +925,24 @@ def create_admin_routes() -> APIRouter:
921
925
  # Combine and sort by created_at
922
926
  activities = []
923
927
  for job in recent_jobs:
924
- activities.append(
925
- {
926
- "type": "job",
927
- "id": job.get("id"),
928
- "name": job.get("name"),
929
- "status": job.get("status"),
930
- "created_at": job.get("created_at"),
931
- "agent_name": job.get("agent_name"),
932
- }
933
- )
928
+ activities.append({
929
+ "type": "job",
930
+ "id": job.get("id"),
931
+ "name": job.get("name"),
932
+ "status": job.get("status"),
933
+ "created_at": job.get("created_at"),
934
+ "agent_name": job.get("agent_name"),
935
+ })
934
936
 
935
937
  for case in recent_cases:
936
- activities.append(
937
- {
938
- "type": "case",
939
- "id": case.get("id"),
940
- "name": case.get("name"),
941
- "status": case.get("status"),
942
- "created_at": case.get("created_at"),
943
- "job_id": case.get("job_id"),
944
- }
945
- )
938
+ activities.append({
939
+ "type": "case",
940
+ "id": case.get("id"),
941
+ "name": case.get("name"),
942
+ "status": case.get("status"),
943
+ "created_at": case.get("created_at"),
944
+ "job_id": case.get("job_id"),
945
+ })
946
946
 
947
947
  # Sort by created_at descending
948
948
  activities.sort(key=lambda x: str(x.get("created_at", "")), reverse=True)
@@ -1199,23 +1199,23 @@ def get_dashboard_stats(storage: StorageManager) -> AdminStats:
1199
1199
 
1200
1200
  # Calculate job stats
1201
1201
  job_total = len(all_jobs)
1202
- job_running = len(
1203
- [j for j in all_jobs if j.get("status") in ["in_progress", "awaiting"]]
1204
- )
1202
+ job_running = len([
1203
+ j for j in all_jobs if j.get("status") in ["in_progress", "awaiting"]
1204
+ ])
1205
1205
  job_completed = len([j for j in all_jobs if j.get("status") == "completed"])
1206
- job_failed = len(
1207
- [j for j in all_jobs if j.get("status") in ["failed", "cancelled"]]
1208
- )
1206
+ job_failed = len([
1207
+ j for j in all_jobs if j.get("status") in ["failed", "cancelled"]
1208
+ ])
1209
1209
 
1210
1210
  # Calculate case stats
1211
1211
  case_total = len(all_cases)
1212
- case_running = len(
1213
- [c for c in all_cases if c.get("status") in ["in_progress", "awaiting"]]
1214
- )
1212
+ case_running = len([
1213
+ c for c in all_cases if c.get("status") in ["in_progress", "awaiting"]
1214
+ ])
1215
1215
  case_completed = len([c for c in all_cases if c.get("status") == "completed"])
1216
- case_failed = len(
1217
- [c for c in all_cases if c.get("status") in ["failed", "cancelled"]]
1218
- )
1216
+ case_failed = len([
1217
+ c for c in all_cases if c.get("status") in ["failed", "cancelled"]
1218
+ ])
1219
1219
 
1220
1220
  # TinyDB collections count (tables)
1221
1221
  collections_count = len(storage._db.tables())
@@ -16,6 +16,7 @@
16
16
  <p class="mt-2 text-sm text-gray-500">
17
17
  Controller version {{ version }} · API version {{ api_version }}
18
18
  </p>
19
+ <p class="mt-1 text-xs text-gray-400 font-mono">Server ID: {{ server_id }}</p>
19
20
 
20
21
  <div class="mt-8">
21
22
  <h2 class="text-lg font-medium text-gray-900 mb-4">Links</h2>
@@ -20,7 +20,7 @@ from cryptography.hazmat.primitives.asymmetric import rsa
20
20
  from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateKey, RSAPublicKey
21
21
  from fastapi import FastAPI, HTTPException, Request, Security, status
22
22
  from fastapi.exceptions import RequestValidationError
23
- from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
23
+ from fastapi.responses import HTMLResponse, JSONResponse
24
24
  from fastapi.security import APIKeyHeader
25
25
  from fastapi.templating import Jinja2Templates
26
26
  from pydantic import BaseModel, field_validator, Field
@@ -46,11 +46,7 @@ from supervaizer.routes import (
46
46
  create_utils_routes,
47
47
  get_server,
48
48
  )
49
- from supervaizer.storage import (
50
- PERSISTENCE_ENABLED,
51
- StorageManager,
52
- load_running_entities_on_startup,
53
- )
49
+ from supervaizer.storage import StorageManager, load_running_entities_on_startup
54
50
 
55
51
  insp = inspect
56
52
 
@@ -59,6 +55,16 @@ T = TypeVar("T")
59
55
  # Additional imports for server persistence
60
56
 
61
57
 
58
+ def _get_or_create_server_id() -> str:
59
+ """Use SUPERVAIZER_SERVER_ID from env if set; else create uuid and set env."""
60
+ existing = os.getenv("SUPERVAIZER_SERVER_ID")
61
+ if existing:
62
+ return existing
63
+ new_id = str(uuid.uuid4())
64
+ os.environ["SUPERVAIZER_SERVER_ID"] = new_id
65
+ return new_id
66
+
67
+
62
68
  class ServerInfo(BaseModel):
63
69
  """Complete server information for storage."""
64
70
 
@@ -74,9 +80,7 @@ class ServerInfo(BaseModel):
74
80
 
75
81
 
76
82
  def save_server_info_to_storage(server_instance: "Server") -> None:
77
- """Save server information to storage (only when persistence is enabled)."""
78
- if not PERSISTENCE_ENABLED:
79
- return
83
+ """Save server information to storage."""
80
84
  try:
81
85
  storage = StorageManager()
82
86
 
@@ -154,6 +158,10 @@ class ServerAbstract(SvBaseModel):
154
158
  """
155
159
 
156
160
  supervaizer_VERSION: ClassVar[str] = VERSION
161
+ server_id: str = Field(
162
+ default_factory=_get_or_create_server_id,
163
+ description="Unique server id (SUPERVAIZER_SERVER_ID env or persisted uuid)",
164
+ )
157
165
  scheme: str = Field(description="URL scheme (http or https)")
158
166
  host: str = Field(
159
167
  description="Host to bind the server to (e.g., 0.0.0.0 for all interfaces)"
@@ -242,10 +250,10 @@ class Server(ServerAbstract):
242
250
  supervisor_account: Optional[Account] = None,
243
251
  a2a_endpoints: bool = True,
244
252
  admin_interface: bool = True,
245
- scheme: str = os.getenv("SUPERVAIZER_SCHEME", "https"),
253
+ scheme: str = "http",
246
254
  environment: str = os.getenv("SUPERVAIZER_ENVIRONMENT", "dev"),
247
255
  host: str = os.getenv("SUPERVAIZER_HOST", "0.0.0.0"),
248
- port: int = int(os.getenv("SUPERVAIZER_PORT", 443)),
256
+ port: int = int(os.getenv("SUPERVAIZER_PORT", 8000)),
249
257
  debug: bool = False,
250
258
  reload: bool = False,
251
259
  mac_addr: str = "",
@@ -360,6 +368,8 @@ class Server(ServerAbstract):
360
368
  **kwargs,
361
369
  )
362
370
 
371
+ log.info(f"[Server launch] Server ID: {self.server_id}")
372
+
363
373
  # Create routes
364
374
  if self.supervisor_account:
365
375
  log.info(
@@ -383,13 +393,6 @@ class Server(ServerAbstract):
383
393
  # Save server info to storage for admin interface
384
394
  save_server_info_to_storage(self)
385
395
 
386
- # Favicon (served at root so /docs, /redoc, etc. pick it up)
387
- _favicon_path = Path(__file__).parent / "admin" / "static" / "favicon.ico"
388
-
389
- @self.app.get("/favicon.ico", include_in_schema=False)
390
- async def favicon() -> FileResponse:
391
- return FileResponse(_favicon_path, media_type="image/x-icon")
392
-
393
396
  # Home page (template in admin/templates)
394
397
  _home_templates = Jinja2Templates(
395
398
  directory=str(Path(__file__).parent / "admin" / "templates")
@@ -397,20 +400,16 @@ class Server(ServerAbstract):
397
400
 
398
401
  @self.app.get("/", response_class=HTMLResponse)
399
402
  async def home_page(request: Request) -> HTMLResponse:
400
- root_index = Path.cwd() / "index.html"
401
- if root_index.is_file():
402
- return HTMLResponse(content=root_index.read_text(encoding="utf-8"))
403
403
  base = self.public_url or f"{self.scheme}://{self.host}:{self.port}"
404
404
  return _home_templates.TemplateResponse(
405
405
  "index.html",
406
406
  {
407
407
  "request": request,
408
408
  "base": base,
409
- "public_url": self.public_url,
410
- "full_url": f"{self.scheme}://{self.host}:{self.port}",
411
409
  "version": VERSION,
412
410
  "api_version": API_VERSION,
413
411
  "show_admin": bool(self.api_key and admin_interface),
412
+ "server_id": self.server_id,
414
413
  },
415
414
  )
416
415
 
@@ -481,6 +480,7 @@ class Server(ServerAbstract):
481
480
  """Get registration info for the server."""
482
481
  assert self.public_key is not None, "Public key not initialized"
483
482
  return {
483
+ "server_id": self.server_id,
484
484
  "url": self.public_url,
485
485
  "uri": self.uri,
486
486
  "api_version": API_VERSION,
@@ -500,9 +500,7 @@ class Server(ServerAbstract):
500
500
  "agents": [agent.registration_info for agent in self.agents],
501
501
  }
502
502
 
503
- def launch(
504
- self, log_level: Optional[str] = "INFO", start_uvicorn: bool = False
505
- ) -> None:
503
+ def launch(self, log_level: Optional[str] = "INFO") -> None:
506
504
  if log_level:
507
505
  log.remove()
508
506
  log.add(
@@ -561,16 +559,15 @@ class Server(ServerAbstract):
561
559
  if updated_agent:
562
560
  log.info(f"[Server launch] Updated agent {updated_agent.name}")
563
561
 
564
- if start_uvicorn:
565
- import uvicorn
562
+ import uvicorn
566
563
 
567
- uvicorn.run(
568
- self.app,
569
- host=self.host,
570
- port=self.port,
571
- reload=self.reload,
572
- log_level=log_level,
573
- )
564
+ uvicorn.run(
565
+ self.app,
566
+ host=self.host,
567
+ port=self.port,
568
+ reload=self.reload,
569
+ log_level=log_level,
570
+ )
574
571
 
575
572
  def instructions(self) -> None:
576
573
  server_url = f"http://{self.host}:{self.port}"
File without changes
File without changes
File without changes