supervaizer 0.10.19__tar.gz → 0.10.21__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.19 → supervaizer-0.10.21}/PKG-INFO +2 -1
  2. {supervaizer-0.10.19 → supervaizer-0.10.21}/pyproject.toml +6 -1
  3. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/__version__.py +1 -1
  4. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/routes.py +28 -32
  5. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/index.html +1 -6
  6. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/commands/local.py +10 -12
  7. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/drivers/aws_app_runner.py +8 -12
  8. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/drivers/cloud_run.py +13 -17
  9. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/drivers/do_app_platform.py +5 -7
  10. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/examples/controller_template.py +20 -22
  11. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/protocol/a2a/model.py +30 -39
  12. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/server.py +25 -25
  13. {supervaizer-0.10.19 → supervaizer-0.10.21}/.gitignore +0 -0
  14. {supervaizer-0.10.19 → supervaizer-0.10.21}/LICENSE.md +0 -0
  15. {supervaizer-0.10.19 → supervaizer-0.10.21}/README.md +0 -0
  16. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/__init__.py +0 -0
  17. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/account.py +0 -0
  18. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/account_service.py +0 -0
  19. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/static/favicon.ico +0 -0
  20. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/static/js/job-start-form.js +0 -0
  21. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/agent_detail.html +0 -0
  22. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/agents.html +0 -0
  23. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/agents_grid.html +0 -0
  24. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/base.html +0 -0
  25. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/case_detail.html +0 -0
  26. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/cases_list.html +0 -0
  27. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/cases_table.html +0 -0
  28. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/console.html +0 -0
  29. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/dashboard.html +0 -0
  30. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/job_detail.html +0 -0
  31. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/job_start_test.html +0 -0
  32. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/jobs_list.html +0 -0
  33. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/jobs_table.html +0 -0
  34. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/navigation.html +0 -0
  35. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/recent_activity.html +0 -0
  36. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/server.html +0 -0
  37. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/server_status_cards.html +0 -0
  38. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/admin/templates/supervaize_instructions.html +0 -0
  39. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/agent.py +0 -0
  40. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/case.py +0 -0
  41. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/cli.py +0 -0
  42. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/common.py +0 -0
  43. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/__init__.py +0 -0
  44. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/cli.py +0 -0
  45. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/commands/__init__.py +0 -0
  46. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/commands/clean.py +0 -0
  47. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/commands/down.py +0 -0
  48. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/commands/plan.py +0 -0
  49. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/commands/status.py +0 -0
  50. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/commands/up.py +0 -0
  51. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/docker.py +0 -0
  52. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/driver_factory.py +0 -0
  53. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/drivers/__init__.py +0 -0
  54. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/drivers/base.py +0 -0
  55. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/health.py +0 -0
  56. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/state.py +0 -0
  57. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/templates/Dockerfile.template +0 -0
  58. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/templates/debug_env.py +0 -0
  59. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/templates/docker-compose.yml.template +0 -0
  60. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/templates/dockerignore.template +0 -0
  61. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/templates/entrypoint.sh +0 -0
  62. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/templates/index.html +0 -0
  63. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/deploy/utils.py +0 -0
  64. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/event.py +0 -0
  65. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/instructions.py +0 -0
  66. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/job.py +0 -0
  67. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/job_service.py +0 -0
  68. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/lifecycle.py +0 -0
  69. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/parameter.py +0 -0
  70. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/protocol/__init__.py +0 -0
  71. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/protocol/a2a/__init__.py +0 -0
  72. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/protocol/a2a/routes.py +0 -0
  73. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/py.typed +0 -0
  74. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/routes.py +0 -0
  75. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/server_utils.py +0 -0
  76. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/storage.py +0 -0
  77. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/telemetry.py +0 -0
  78. {supervaizer-0.10.19 → supervaizer-0.10.21}/src/supervaizer/utils/__init__.py +0 -0
  79. {supervaizer-0.10.19 → supervaizer-0.10.21}/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.19
3
+ Version: 0.10.21
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
@@ -56,6 +56,7 @@ Requires-Dist: respx>=0.22.0; extra == 'dev'
56
56
  Requires-Dist: ruff>=0.15.0; extra == 'dev'
57
57
  Requires-Dist: types-deprecated>=1.3.1; extra == 'dev'
58
58
  Requires-Dist: types-python-slugify>=8.0.2.20240310; extra == 'dev'
59
+ Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
59
60
  Description-Content-Type: text/markdown
60
61
 
61
62
  # SUPERVAIZER
@@ -69,6 +69,7 @@ dev = [
69
69
  "respx>=0.22.0",
70
70
  "ruff>=0.15.0",
71
71
  "types-deprecated>=1.3.1",
72
+ "types-PyYAML>=6.0.0",
72
73
  "types-python-slugify>=8.0.2.20240310",
73
74
 
74
75
  ]
@@ -108,6 +109,10 @@ path = "src/supervaizer/__version__.py"
108
109
  combine-as-imports = true
109
110
  force-wrap-aliases = true
110
111
 
112
+ [tool.ruff.format]
113
+ # Match Cursor style: keep opening brace on same line as call, e.g. append({ ... })
114
+ preview = true
115
+
111
116
  [tool.commitizen]
112
117
  name = "cz_gitmoji"
113
118
 
@@ -121,7 +126,7 @@ mypy_path = "src"
121
126
  disallow_any_expr = false
122
127
 
123
128
  [tool.bumpversion]
124
- current_version = "0.10.19"
129
+ current_version = "0.10.21"
125
130
  commit = true
126
131
  tag = true
127
132
  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.19"
8
+ VERSION = "0.10.21"
9
9
  API_VERSION = "v1"
10
10
  TELEMETRY_VERSION = "v1"
@@ -931,28 +931,24 @@ def create_admin_routes() -> APIRouter:
931
931
  # Combine and sort by created_at
932
932
  activities = []
933
933
  for job in recent_jobs:
934
- activities.append(
935
- {
936
- "type": "job",
937
- "id": job.get("id"),
938
- "name": job.get("name"),
939
- "status": job.get("status"),
940
- "created_at": job.get("created_at"),
941
- "agent_name": job.get("agent_name"),
942
- }
943
- )
934
+ activities.append({
935
+ "type": "job",
936
+ "id": job.get("id"),
937
+ "name": job.get("name"),
938
+ "status": job.get("status"),
939
+ "created_at": job.get("created_at"),
940
+ "agent_name": job.get("agent_name"),
941
+ })
944
942
 
945
943
  for case in recent_cases:
946
- activities.append(
947
- {
948
- "type": "case",
949
- "id": case.get("id"),
950
- "name": case.get("name"),
951
- "status": case.get("status"),
952
- "created_at": case.get("created_at"),
953
- "job_id": case.get("job_id"),
954
- }
955
- )
944
+ activities.append({
945
+ "type": "case",
946
+ "id": case.get("id"),
947
+ "name": case.get("name"),
948
+ "status": case.get("status"),
949
+ "created_at": case.get("created_at"),
950
+ "job_id": case.get("job_id"),
951
+ })
956
952
 
957
953
  # Sort by created_at descending
958
954
  activities.sort(key=lambda x: str(x.get("created_at", "")), reverse=True)
@@ -1209,23 +1205,23 @@ def get_dashboard_stats(storage: StorageManager) -> AdminStats:
1209
1205
 
1210
1206
  # Calculate job stats
1211
1207
  job_total = len(all_jobs)
1212
- job_running = len(
1213
- [j for j in all_jobs if j.get("status") in ["in_progress", "awaiting"]]
1214
- )
1208
+ job_running = len([
1209
+ j for j in all_jobs if j.get("status") in ["in_progress", "awaiting"]
1210
+ ])
1215
1211
  job_completed = len([j for j in all_jobs if j.get("status") == "completed"])
1216
- job_failed = len(
1217
- [j for j in all_jobs if j.get("status") in ["failed", "cancelled"]]
1218
- )
1212
+ job_failed = len([
1213
+ j for j in all_jobs if j.get("status") in ["failed", "cancelled"]
1214
+ ])
1219
1215
 
1220
1216
  # Calculate case stats
1221
1217
  case_total = len(all_cases)
1222
- case_running = len(
1223
- [c for c in all_cases if c.get("status") in ["in_progress", "awaiting"]]
1224
- )
1218
+ case_running = len([
1219
+ c for c in all_cases if c.get("status") in ["in_progress", "awaiting"]
1220
+ ])
1225
1221
  case_completed = len([c for c in all_cases if c.get("status") == "completed"])
1226
- case_failed = len(
1227
- [c for c in all_cases if c.get("status") in ["failed", "cancelled"]]
1228
- )
1222
+ case_failed = len([
1223
+ c for c in all_cases if c.get("status") in ["failed", "cancelled"]
1224
+ ])
1229
1225
 
1230
1226
  # TinyDB collections count (tables)
1231
1227
  collections_count = len(storage._db.tables())
@@ -41,12 +41,7 @@
41
41
  OpenAPI
42
42
  </a>
43
43
  </li>
44
- <li><strong>BASE:</strong> {{ base }}
45
- <br>
46
- <strong>PUBLIC_URL:</strong> {{ public_url }}
47
- <br>
48
- <strong>FULL_URL:</strong> {{ full_url }}
49
- <br>
44
+ <li><strong>BASE URL:</strong> {{ base }}
50
45
  </li>
51
46
 
52
47
  {% if show_admin %}
@@ -231,18 +231,16 @@ def _start_docker_compose(
231
231
 
232
232
  # Set environment variables for Docker Compose
233
233
  env = os.environ.copy()
234
- env.update(
235
- {
236
- "SERVICE_NAME": service_name,
237
- "SERVICE_PORT": str(port),
238
- "SUPERVAIZER_API_KEY": secrets["api_key"],
239
- "SV_RSA_PRIVATE_KEY": secrets["rsa_private_key"],
240
- "SUPERVAIZER_ENVIRONMENT": "dev",
241
- "SUPERVAIZER_HOST": "0.0.0.0",
242
- "SUPERVAIZER_PORT": str(port),
243
- "SV_LOG_LEVEL": "INFO",
244
- }
245
- )
234
+ env.update({
235
+ "SERVICE_NAME": service_name,
236
+ "SERVICE_PORT": str(port),
237
+ "SUPERVAIZER_API_KEY": secrets["api_key"],
238
+ "SV_RSA_PRIVATE_KEY": secrets["rsa_private_key"],
239
+ "SUPERVAIZER_ENVIRONMENT": "dev",
240
+ "SUPERVAIZER_HOST": "0.0.0.0",
241
+ "SUPERVAIZER_PORT": str(port),
242
+ "SV_LOG_LEVEL": "INFO",
243
+ })
246
244
 
247
245
  cmd = ["docker-compose", "-f", str(compose_file), "up", "-d"]
248
246
 
@@ -455,12 +455,10 @@ class AWSAppRunnerDriver(BaseDriver):
455
455
  # Build secret references
456
456
  secret_refs = []
457
457
  for secret_name in secrets.keys():
458
- secret_refs.append(
459
- {
460
- "Name": secret_name,
461
- "ValueFrom": f"arn:aws:secretsmanager:{self.region}:{account_id}:secret:{secret_name}",
462
- }
463
- )
458
+ secret_refs.append({
459
+ "Name": secret_name,
460
+ "ValueFrom": f"arn:aws:secretsmanager:{self.region}:{account_id}:secret:{secret_name}",
461
+ })
464
462
 
465
463
  # Service configuration
466
464
  service_config = {
@@ -560,12 +558,10 @@ class AWSAppRunnerDriver(BaseDriver):
560
558
  ]
561
559
 
562
560
  # Add the public URL
563
- env_vars.append(
564
- {
565
- "Name": "SUPERVAIZER_PUBLIC_URL",
566
- "Value": public_url,
567
- }
568
- )
561
+ env_vars.append({
562
+ "Name": "SUPERVAIZER_PUBLIC_URL",
563
+ "Value": public_url,
564
+ })
569
565
 
570
566
  # Update service
571
567
  self.apprunner_client.update_service(
@@ -451,17 +451,15 @@ class CloudRunDriver(BaseDriver):
451
451
  # Build secret references
452
452
  secret_refs = []
453
453
  for secret_name in secrets.keys():
454
- secret_refs.append(
455
- {
456
- "name": secret_name,
457
- "value_source": {
458
- "secret_key_ref": {
459
- "secret": f"projects/{self.project_id}/secrets/{secret_name}",
460
- "version": "latest",
461
- }
462
- },
463
- }
464
- )
454
+ secret_refs.append({
455
+ "name": secret_name,
456
+ "value_source": {
457
+ "secret_key_ref": {
458
+ "secret": f"projects/{self.project_id}/secrets/{secret_name}",
459
+ "version": "latest",
460
+ }
461
+ },
462
+ })
465
463
 
466
464
  # Service configuration
467
465
  service_config = {
@@ -532,12 +530,10 @@ class CloudRunDriver(BaseDriver):
532
530
  env_vars.append(env_var)
533
531
 
534
532
  # Add the public URL
535
- env_vars.append(
536
- {
537
- "name": "SUPERVAIZER_PUBLIC_URL",
538
- "value": public_url,
539
- }
540
- )
533
+ env_vars.append({
534
+ "name": "SUPERVAIZER_PUBLIC_URL",
535
+ "value": public_url,
536
+ })
541
537
 
542
538
  # Update service
543
539
  service.template.containers[0].env = env_vars
@@ -346,13 +346,11 @@ class DOAppPlatformDriver(BaseDriver):
346
346
  # Build secret references
347
347
  secret_refs = []
348
348
  for secret_name in secrets.keys():
349
- secret_refs.append(
350
- {
351
- "key": secret_name,
352
- "scope": "RUN_TIME",
353
- "type": "SECRET",
354
- }
355
- )
349
+ secret_refs.append({
350
+ "key": secret_name,
351
+ "scope": "RUN_TIME",
352
+ "type": "SECRET",
353
+ })
356
354
 
357
355
  # App spec
358
356
  app_spec = {
@@ -34,28 +34,26 @@ DEV_PUBLIC_URL = "https://myagent-dev.loca.lt"
34
34
  PROD_PUBLIC_URL = "https://myagent.cloud-hosting.net:8001"
35
35
 
36
36
  # Define the parameters and secrets expected by the agent
37
- agent_parameters: ParametersSetup | None = ParametersSetup.from_list(
38
- [
39
- Parameter(
40
- name="OPEN_API_KEY",
41
- description="OpenAPI Key",
42
- is_environment=True,
43
- is_secret=True,
44
- ),
45
- Parameter(
46
- name="SERPER_API",
47
- description="Server API key updated",
48
- is_environment=True,
49
- is_secret=True,
50
- ),
51
- Parameter(
52
- name="COMPETITOR_SUMMARY_URL",
53
- description="Competitor Summary URL",
54
- is_environment=True,
55
- is_secret=False,
56
- ),
57
- ]
58
- )
37
+ agent_parameters: ParametersSetup | None = ParametersSetup.from_list([
38
+ Parameter(
39
+ name="OPEN_API_KEY",
40
+ description="OpenAPI Key",
41
+ is_environment=True,
42
+ is_secret=True,
43
+ ),
44
+ Parameter(
45
+ name="SERPER_API",
46
+ description="Server API key updated",
47
+ is_environment=True,
48
+ is_secret=True,
49
+ ),
50
+ Parameter(
51
+ name="COMPETITOR_SUMMARY_URL",
52
+ description="Competitor Summary URL",
53
+ is_environment=True,
54
+ is_secret=False,
55
+ ),
56
+ ])
59
57
 
60
58
  # Define the method used to start a job
61
59
  job_start_method: AgentMethod = AgentMethod(
@@ -56,51 +56,42 @@ def create_agent_card(agent: Agent, base_url: str) -> Dict[str, Any]:
56
56
  tools = []
57
57
 
58
58
  # Add basic job tools
59
- tools.append(
60
- {
61
- "name": "job_start",
62
- "description": (
63
- agent.methods.job_start.description if agent.methods else None
64
- )
65
- or f"Start a job with {agent.name}",
66
- "input_schema": {
67
- "type": "object",
68
- "properties": {
69
- "job_fields": {"type": "object"},
70
- "job_context": {"type": "object"},
71
- },
72
- },
73
- }
74
- )
75
-
76
- tools.append(
77
- {
78
- "name": "job_status",
79
- "description": "Check the status of a job",
80
- "input_schema": {
81
- "type": "object",
82
- "properties": {"job_id": {"type": "string"}},
59
+ tools.append({
60
+ "name": "job_start",
61
+ "description": (agent.methods.job_start.description if agent.methods else None)
62
+ or f"Start a job with {agent.name}",
63
+ "input_schema": {
64
+ "type": "object",
65
+ "properties": {
66
+ "job_fields": {"type": "object"},
67
+ "job_context": {"type": "object"},
83
68
  },
84
- }
85
- )
69
+ },
70
+ })
71
+
72
+ tools.append({
73
+ "name": "job_status",
74
+ "description": "Check the status of a job",
75
+ "input_schema": {
76
+ "type": "object",
77
+ "properties": {"job_id": {"type": "string"}},
78
+ },
79
+ })
86
80
 
87
81
  # Add custom tools if available
88
82
  if agent.methods and agent.methods.custom:
89
83
  for name, method in agent.methods.custom.items():
90
- tools.append(
91
- {
92
- "name": name,
93
- "description": method.description
94
- or f"Execute {name} custom method",
95
- "input_schema": {
96
- "type": "object",
97
- "properties": {
98
- "method_name": {"type": "string", "const": name},
99
- "params": {"type": "object"},
100
- },
84
+ tools.append({
85
+ "name": name,
86
+ "description": method.description or f"Execute {name} custom method",
87
+ "input_schema": {
88
+ "type": "object",
89
+ "properties": {
90
+ "method_name": {"type": "string", "const": name},
91
+ "params": {"type": "object"},
101
92
  },
102
- }
103
- )
93
+ },
94
+ })
104
95
 
105
96
  # Build authentication object
106
97
  authentication = {
@@ -11,7 +11,7 @@ import time
11
11
  import uuid
12
12
  from datetime import datetime
13
13
  from pathlib import Path
14
- from typing import Any, ClassVar, Dict, List, Optional, TypeVar
14
+ from typing import Any, ClassVar, Dict, List, Optional, TypeVar, cast
15
15
  from urllib.parse import urlunparse
16
16
 
17
17
  from cryptography.hazmat.backends import default_backend
@@ -23,7 +23,7 @@ from fastapi.exceptions import RequestValidationError
23
23
  from fastapi.responses import HTMLResponse, JSONResponse
24
24
  from fastapi.security import APIKeyHeader
25
25
  from fastapi.templating import Jinja2Templates
26
- from pydantic import BaseModel, field_validator, Field
26
+ from pydantic import BaseModel, Field, field_validator
27
27
  from rich import inspect
28
28
 
29
29
  from supervaizer.__version__ import API_VERSION, VERSION
@@ -58,7 +58,7 @@ T = TypeVar("T")
58
58
  def _get_or_create_server_id() -> str:
59
59
  """Use SUPERVAIZER_SERVER_ID from env if set; else create uuid and set env."""
60
60
  existing = os.getenv("SUPERVAIZER_SERVER_ID")
61
- if existing:
61
+ if existing and len(existing) > 5:
62
62
  return existing
63
63
  new_id = str(uuid.uuid4())
64
64
  os.environ["SUPERVAIZER_SERVER_ID"] = new_id
@@ -68,13 +68,14 @@ def _get_or_create_server_id() -> str:
68
68
  def _get_or_create_private_key() -> RSAPrivateKey:
69
69
  """Use SUPERVAIZER_PRIVATE_KEY from env if set; else create key and set env."""
70
70
  pem = os.getenv("SUPERVAIZER_PRIVATE_KEY")
71
- if pem:
71
+ if pem and len(pem) > 5:
72
72
  try:
73
- return serialization.load_pem_private_key(
73
+ key = serialization.load_pem_private_key(
74
74
  pem.encode("utf-8"),
75
75
  password=None,
76
76
  backend=default_backend(),
77
77
  )
78
+ return cast(RSAPrivateKey, key)
78
79
  except Exception as e:
79
80
  log.warning(
80
81
  f"[Server] Invalid SUPERVAIZER_PRIVATE_KEY, generating new key: {e}"
@@ -117,16 +118,14 @@ def save_server_info_to_storage(server_instance: "Server") -> None:
117
118
  agents = []
118
119
  if hasattr(server_instance, "agents") and server_instance.agents:
119
120
  for agent in server_instance.agents:
120
- agents.append(
121
- {
122
- "name": agent.name,
123
- "description": agent.description,
124
- "version": agent.version,
125
- "api_path": agent.path,
126
- "slug": agent.slug,
127
- "instructions_path": agent.instructions_path,
128
- }
129
- )
121
+ agents.append({
122
+ "name": agent.name,
123
+ "description": agent.description,
124
+ "version": agent.version,
125
+ "api_path": agent.path,
126
+ "slug": agent.slug,
127
+ "instructions_path": agent.instructions_path,
128
+ })
130
129
 
131
130
  # Create server info
132
131
  server_info = ServerInfo(
@@ -167,16 +166,14 @@ def get_server_info_from_live(server_instance: "Server") -> ServerInfo:
167
166
  agents = []
168
167
  if hasattr(server_instance, "agents") and server_instance.agents:
169
168
  for agent in server_instance.agents:
170
- agents.append(
171
- {
172
- "name": agent.name,
173
- "description": agent.description,
174
- "version": agent.version,
175
- "api_path": agent.path,
176
- "slug": agent.slug,
177
- "instructions_path": agent.instructions_path,
178
- }
179
- )
169
+ agents.append({
170
+ "name": agent.name,
171
+ "description": agent.description,
172
+ "version": agent.version,
173
+ "api_path": agent.path,
174
+ "slug": agent.slug,
175
+ "instructions_path": agent.instructions_path,
176
+ })
180
177
  start_time = getattr(server_instance, "_start_time", time.time())
181
178
  return ServerInfo(
182
179
  host=getattr(server_instance, "host", "N/A"),
@@ -456,6 +453,9 @@ class Server(ServerAbstract):
456
453
 
457
454
  @self.app.get("/", response_class=HTMLResponse)
458
455
  async def home_page(request: Request) -> HTMLResponse:
456
+ root_index = Path.cwd() / "index.html"
457
+ if root_index.is_file():
458
+ return HTMLResponse(content=root_index.read_text(encoding="utf-8"))
459
459
  base = self.public_url or f"{self.scheme}://{self.host}:{self.port}"
460
460
  return _home_templates.TemplateResponse(
461
461
  "index.html",
File without changes
File without changes
File without changes