soliplex 0.86__tar.gz → 0.87__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 (126) hide show
  1. {soliplex-0.86/src/soliplex.egg-info → soliplex-0.87}/PKG-INFO +11 -11
  2. {soliplex-0.86 → soliplex-0.87}/pyproject.toml +11 -11
  3. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/rag.py +2 -1
  4. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/rooms.py +12 -3
  5. {soliplex-0.86 → soliplex-0.87}/src/soliplex/loggers.py +27 -1
  6. {soliplex-0.86 → soliplex-0.87}/src/soliplex/models.py +12 -0
  7. {soliplex-0.86 → soliplex-0.87}/src/soliplex/tools/agui_run_feedback.py +388 -52
  8. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/installation.py +57 -0
  9. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/room_file_uploads.py +99 -9
  10. {soliplex-0.86 → soliplex-0.87/src/soliplex.egg-info}/PKG-INFO +11 -11
  11. {soliplex-0.86 → soliplex-0.87}/src/soliplex.egg-info/requires.txt +10 -10
  12. {soliplex-0.86 → soliplex-0.87}/LICENSE +0 -0
  13. {soliplex-0.86 → soliplex-0.87}/MANIFEST.in +0 -0
  14. {soliplex-0.86 → soliplex-0.87}/README.md +0 -0
  15. {soliplex-0.86 → soliplex-0.87}/example/skills/bare-bones/SKILL.md +0 -0
  16. {soliplex-0.86 → soliplex-0.87}/example/skills/stanzas/SKILL.md +0 -0
  17. {soliplex-0.86 → soliplex-0.87}/setup.cfg +0 -0
  18. {soliplex-0.86 → soliplex-0.87}/skills/soliplex-docs/SKILL.md +0 -0
  19. {soliplex-0.86 → soliplex-0.87}/src/soliplex/agents.py +0 -0
  20. {soliplex-0.86 → soliplex-0.87}/src/soliplex/agui/__init__.py +0 -0
  21. {soliplex-0.86 → soliplex-0.87}/src/soliplex/agui/parser.py +0 -0
  22. {soliplex-0.86 → soliplex-0.87}/src/soliplex/agui/persistence.py +0 -0
  23. {soliplex-0.86 → soliplex-0.87}/src/soliplex/agui/schema.py +0 -0
  24. {soliplex-0.86 → soliplex-0.87}/src/soliplex/agui/sse_delivery.py +0 -0
  25. {soliplex-0.86 → soliplex-0.87}/src/soliplex/agui/util.py +0 -0
  26. {soliplex-0.86 → soliplex-0.87}/src/soliplex/alembic_migrations/__init__.py +0 -0
  27. {soliplex-0.86 → soliplex-0.87}/src/soliplex/alembic_migrations/env.py +0 -0
  28. {soliplex-0.86 → soliplex-0.87}/src/soliplex/alembic_migrations/versions/216d48e1e2e5_soliplex_v0_53.py +0 -0
  29. {soliplex-0.86 → soliplex-0.87}/src/soliplex/alembic_migrations/versions/4b63e5f3f39e_soliplex_v0_51_1.py +0 -0
  30. {soliplex-0.86 → soliplex-0.87}/src/soliplex/alembic_migrations/versions/63edaa5987f6_soliplex_v0_67.py +0 -0
  31. {soliplex-0.86 → soliplex-0.87}/src/soliplex/alembic_migrations/versions/a1c7d3e90b42_soliplex_v0_80.py +0 -0
  32. {soliplex-0.86 → soliplex-0.87}/src/soliplex/alembic_migrations/versions/b7e2f41c9d05_soliplex_v0_82.py +0 -0
  33. {soliplex-0.86 → soliplex-0.87}/src/soliplex/alembic_migrations/versions/d5009d4f9874_soliplex_v0_44.py +0 -0
  34. {soliplex-0.86 → soliplex-0.87}/src/soliplex/alembic_migrations/versions/f13fea6c1953_soliplex_v0_86.py +0 -0
  35. {soliplex-0.86 → soliplex-0.87}/src/soliplex/authn.py +0 -0
  36. {soliplex-0.86 → soliplex-0.87}/src/soliplex/authz/__init__.py +0 -0
  37. {soliplex-0.86 → soliplex-0.87}/src/soliplex/authz/persistence.py +0 -0
  38. {soliplex-0.86 → soliplex-0.87}/src/soliplex/authz/schema.py +0 -0
  39. {soliplex-0.86 → soliplex-0.87}/src/soliplex/capabilities/filesystem.py +0 -0
  40. {soliplex-0.86 → soliplex-0.87}/src/soliplex/capabilities/rag_audit.py +0 -0
  41. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/admin_users.py +0 -0
  42. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/ask.py +0 -0
  43. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/__init__.py +0 -0
  44. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/_common.py +0 -0
  45. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/admin_users.py +0 -0
  46. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/completions.py +0 -0
  47. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/databases.py +0 -0
  48. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/environment.py +0 -0
  49. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/installation.py +0 -0
  50. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/interpolation.py +0 -0
  51. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/logfire.py +0 -0
  52. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/logging.py +0 -0
  53. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/oidc.py +0 -0
  54. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/ollama.py +0 -0
  55. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/quizzes.py +0 -0
  56. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/room_authz.py +0 -0
  57. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/rooms.py +0 -0
  58. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/secrets.py +0 -0
  59. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/audit/skills.py +0 -0
  60. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/cli_util.py +0 -0
  61. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/database.py +0 -0
  62. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/main.py +0 -0
  63. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/ollama.py +0 -0
  64. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/room_authz.py +0 -0
  65. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/serve.py +0 -0
  66. {soliplex-0.86 → soliplex-0.87}/src/soliplex/cli/types.py +0 -0
  67. {soliplex-0.86 → soliplex-0.87}/src/soliplex/completions.py +0 -0
  68. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/__init__.py +0 -0
  69. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/_utils.py +0 -0
  70. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/agents.py +0 -0
  71. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/agui.py +0 -0
  72. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/authsystem.py +0 -0
  73. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/completions.py +0 -0
  74. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/exceptions.py +0 -0
  75. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/installation.py +0 -0
  76. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/interpolation.py +0 -0
  77. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/logfire.py +0 -0
  78. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/meta.py +0 -0
  79. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/middleware.py +0 -0
  80. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/quizzes.py +0 -0
  81. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/routing.py +0 -0
  82. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/secrets.py +0 -0
  83. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/skills.py +0 -0
  84. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/sse_delivery.py +0 -0
  85. {soliplex-0.86 → soliplex-0.87}/src/soliplex/config/tools.py +0 -0
  86. {soliplex-0.86 → soliplex-0.87}/src/soliplex/examples.py +0 -0
  87. {soliplex-0.86 → soliplex-0.87}/src/soliplex/installation.py +0 -0
  88. {soliplex-0.86 → soliplex-0.87}/src/soliplex/log_ingest.py +0 -0
  89. {soliplex-0.86 → soliplex-0.87}/src/soliplex/main.py +0 -0
  90. {soliplex-0.86 → soliplex-0.87}/src/soliplex/mcp_auth.py +0 -0
  91. {soliplex-0.86 → soliplex-0.87}/src/soliplex/mcp_client.py +0 -0
  92. {soliplex-0.86 → soliplex-0.87}/src/soliplex/mcp_server.py +0 -0
  93. {soliplex-0.86 → soliplex-0.87}/src/soliplex/ollama.py +0 -0
  94. {soliplex-0.86 → soliplex-0.87}/src/soliplex/quizzes.py +0 -0
  95. {soliplex-0.86 → soliplex-0.87}/src/soliplex/rag_audit.py +0 -0
  96. {soliplex-0.86 → soliplex-0.87}/src/soliplex/sandbox_audit.py +0 -0
  97. {soliplex-0.86 → soliplex-0.87}/src/soliplex/secrets.py +0 -0
  98. {soliplex-0.86 → soliplex-0.87}/src/soliplex/skills/bwrap_sandbox/SKILL.md +0 -0
  99. {soliplex-0.86 → soliplex-0.87}/src/soliplex/skills/bwrap_sandbox/__init__.py +0 -0
  100. {soliplex-0.86 → soliplex-0.87}/src/soliplex/titles.py +0 -0
  101. {soliplex-0.86 → soliplex-0.87}/src/soliplex/tools/__init__.py +0 -0
  102. {soliplex-0.86 → soliplex-0.87}/src/soliplex/tools/file_uploads.py +0 -0
  103. {soliplex-0.86 → soliplex-0.87}/src/soliplex/tools/rag.py +0 -0
  104. {soliplex-0.86 → soliplex-0.87}/src/soliplex/tui/cli.py +0 -0
  105. {soliplex-0.86 → soliplex-0.87}/src/soliplex/tui/main.py +0 -0
  106. {soliplex-0.86 → soliplex-0.87}/src/soliplex/tui/rest_api.py +0 -0
  107. {soliplex-0.86 → soliplex-0.87}/src/soliplex/tui/serve.py +0 -0
  108. {soliplex-0.86 → soliplex-0.87}/src/soliplex/util.py +0 -0
  109. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/__init__.py +0 -0
  110. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/agui.py +0 -0
  111. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/authn.py +0 -0
  112. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/authz.py +0 -0
  113. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/completions.py +0 -0
  114. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/log_ingest.py +0 -0
  115. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/quizzes.py +0 -0
  116. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/rooms.py +0 -0
  117. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/sandbox_workdirs.py +0 -0
  118. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/stats.py +0 -0
  119. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/streaming.py +0 -0
  120. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/templates/consent.html.mako +0 -0
  121. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/templates/cookie-too-large.html.mako +0 -0
  122. {soliplex-0.86 → soliplex-0.87}/src/soliplex/views/thread_file_uploads.py +0 -0
  123. {soliplex-0.86 → soliplex-0.87}/src/soliplex.egg-info/SOURCES.txt +0 -0
  124. {soliplex-0.86 → soliplex-0.87}/src/soliplex.egg-info/dependency_links.txt +0 -0
  125. {soliplex-0.86 → soliplex-0.87}/src/soliplex.egg-info/entry_points.txt +0 -0
  126. {soliplex-0.86 → soliplex-0.87}/src/soliplex.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soliplex
3
- Version: 0.86
3
+ Version: 0.87
4
4
  Summary: An AI-powered Retrieval-Augmented Generation (RAG) system with a modern web interface.
5
5
  Author-email: Enfold <info@enfoldsystems.net>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -9,39 +9,39 @@ Requires-Python: >=3.13
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
11
  Requires-Dist: ag-ui-protocol<0.1.19,>=0.1.18
12
- Requires-Dist: aiohttp<3.15,>=3.14.2
12
+ Requires-Dist: aiohttp<3.15,>=3.14.4
13
13
  Requires-Dist: aiosqlite
14
14
  Requires-Dist: alembic<1.19,>=1.18.4
15
15
  Requires-Dist: authlib
16
16
  Requires-Dist: bubble-sandbox<0.14,>=0.13.0
17
- Requires-Dist: packaging
17
+ Requires-Dist: certifi>=2026.10.19
18
18
  Requires-Dist: cryptography>=50.0.0
19
- Requires-Dist: fastapi
20
- Requires-Dist: fastmcp<5.0,>=4.0.2
21
19
  Requires-Dist: fakeredis!=2.35.0
20
+ Requires-Dist: fastapi
21
+ Requires-Dist: fastmcp<5.0,>=4.1.2
22
22
  Requires-Dist: greenlet
23
- Requires-Dist: haiku.rag-slim<0.99,>=0.98.0
23
+ Requires-Dist: haiku.rag-slim<0.102,>=0.101.0
24
24
  Requires-Dist: idna>=3.15
25
25
  Requires-Dist: itsdangerous
26
26
  Requires-Dist: joserfc<1.7,>=1.6.7
27
27
  Requires-Dist: jsonpatch
28
- Requires-Dist: mcp>=1.27.2
29
- Requires-Dist: pillow<12.4,>=12.3.0
30
- Requires-Dist: python-jsonpath
31
- Requires-Dist: python-multipart>=0.0.31
32
28
  Requires-Dist: jwcrypto
33
29
  Requires-Dist: logfire[fastapi]
30
+ Requires-Dist: mcp>=1.27.2
31
+ Requires-Dist: packaging
32
+ Requires-Dist: pillow<14,>=13.0
34
33
  Requires-Dist: pyasn1>=0.6.4
35
34
  Requires-Dist: pydantic-ai-slim[google]<3.0,>=2.53.0
36
35
  Requires-Dist: pydantic-settings<2.15,>=2.14.2
37
36
  Requires-Dist: pyjwt<2.16,>=2.15.0
38
37
  Requires-Dist: pymdown-extensions>=11.0.0
38
+ Requires-Dist: python-jsonpath
39
39
  Requires-Dist: python-keycloak
40
+ Requires-Dist: python-multipart>=0.0.31
40
41
  Requires-Dist: skills-ref
41
42
  Requires-Dist: sqlmodel
42
43
  Requires-Dist: starlette>=1.3.1
43
44
  Requires-Dist: uvicorn[standard]
44
- Requires-Dist: certifi>=2025.11.12
45
45
  Provides-Extra: postgres
46
46
  Requires-Dist: psycopg; extra == "postgres"
47
47
  Provides-Extra: postgres-binary
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "soliplex"
7
- version = "0.86"
7
+ version = "0.87"
8
8
  description = "An AI-powered Retrieval-Augmented Generation (RAG) system with a modern web interface."
9
9
  authors = [{ name = "Enfold", email = "info@enfoldsystems.net" }]
10
10
  readme = "README.md"
@@ -15,39 +15,39 @@ classifiers = [
15
15
  ]
16
16
  dependencies = [
17
17
  "ag-ui-protocol >= 0.1.18, < 0.1.19",
18
- "aiohttp >= 3.14.2, < 3.15", # multiple CVEs
18
+ "aiohttp >= 3.14.4, < 3.15", # multiple CVEs
19
19
  "aiosqlite",
20
20
  "alembic >= 1.18.4, < 1.19",
21
21
  "authlib",
22
22
  "bubble-sandbox >= 0.13.0, < 0.14",
23
- "packaging",
23
+ "certifi >= 2026.10.19", # PYSEC-2026-4320
24
24
  "cryptography >= 50.0.0", # PYSEC-2026-3552
25
- "fastapi",
26
- "fastmcp >= 4.0.2, < 5.0",
27
25
  "fakeredis != 2.35.0", # brownbag
26
+ "fastapi",
27
+ "fastmcp >= 4.1.2, < 5.0",
28
28
  "greenlet",
29
- "haiku.rag-slim >= 0.98.0, < 0.99",
29
+ "haiku.rag-slim >= 0.101.0, < 0.102",
30
30
  "idna >= 3.15",
31
31
  "itsdangerous",
32
32
  "joserfc >= 1.6.7, < 1.7", # CVE-2026-48990
33
33
  "jsonpatch",
34
- "mcp >= 1.27.2", # CVE-2026-52870
35
- "pillow >= 12.3.0, < 12.4", # PYSEC-2026-225{3,4,5,6,7}
36
- "python-jsonpath", # RFC 9535 query support
37
- "python-multipart >= 0.0.31", # Multiple CVEs
38
34
  "jwcrypto",
39
35
  "logfire[fastapi]",
36
+ "mcp >= 1.27.2", # CVE-2026-52870
37
+ "packaging",
38
+ "pillow >= 13.0, < 14", # Many-many
40
39
  "pyasn1 >= 0.6.4", # PYSEC-2026-3456
41
40
  "pydantic-ai-slim[google] >= 2.53.0, < 3.0", # PYSEC-2026-4285
42
41
  "pydantic-settings >= 2.14.2, < 2.15", # GHSA-4xgf-cpjx-pc3j
43
42
  "pyjwt >= 2.15.0, < 2.16", # CVE-2026-102275
44
43
  "pymdown-extensions >= 11.0.0", # CVE-2026-61632
44
+ "python-jsonpath", # RFC 9535 query support
45
45
  "python-keycloak",
46
+ "python-multipart >= 0.0.31", # Multiple CVEs
46
47
  "skills-ref",
47
48
  "sqlmodel",
48
49
  "starlette >= 1.3.1", # Multiple CVEs
49
50
  "uvicorn[standard]",
50
- "certifi >= 2025.11.12",
51
51
  ]
52
52
 
53
53
  # Database drivers are not dependencies: soliplex imports none of them,
@@ -84,7 +84,8 @@ class RagDbFileNotFound(ValueError):
84
84
  self._config_path = _config_path
85
85
  super().__init__(
86
86
  f"RAG DB file not found: {rag_db_filename} "
87
- f"(configured in {_config_path})"
87
+ f"(configured in {_config_path}). "
88
+ "Run 'haiku-rag init' to create."
88
89
  )
89
90
 
90
91
 
@@ -289,7 +289,11 @@ class RoomConfig:
289
289
 
290
290
  @property
291
291
  def has_thread_uploads(self) -> bool:
292
- """Can files be uploaded to threads in this room at all?"""
292
+ """Can files be uploaded to threads in this room?
293
+
294
+ Thread uploads do not require extra permissions, but they are
295
+ allowed only in rooms which configure the sandbox skill.
296
+ """
293
297
  upload_path = getattr(
294
298
  self._installation_config,
295
299
  "threads_upload_path",
@@ -299,13 +303,18 @@ class RoomConfig:
299
303
 
300
304
  @property
301
305
  def has_room_uploads(self) -> bool:
302
- """Can files be uploaded to this room at all?"""
306
+ """Can files be uploaded to this room?
307
+
308
+ Room uploads require only that the installation's uploads tree
309
+ is configured: upload is permitted by the room authorization
310
+ policy's 'ALLOW WRITE' ACL entries.
311
+ """
303
312
  upload_path = getattr(
304
313
  self._installation_config,
305
314
  "rooms_upload_path",
306
315
  None,
307
316
  )
308
- return self.has_sandbox and upload_path is not None
317
+ return upload_path is not None
309
318
 
310
319
  @property
311
320
  def agui_feature_names(self) -> tuple[str]:
@@ -40,6 +40,7 @@ UPLOADS_GET_ROOM_FILE = "uploads get room file"
40
40
  UPLOADS_GET_ROOM_THREAD = "uploads get room thread"
41
41
  UPLOADS_GET_ROOM_THREAD_FILE = "uploads get room thread file"
42
42
  UPLOADS_POST_ROOM = "uploads post room"
43
+ UPLOADS_DELETE_ROOM_FILE = "uploads delete room file"
43
44
  UPLOADS_POST_ROOM_THREAD = "uploads post room thread"
44
45
 
45
46
  WORKDIRS_GET_ROOM_THREAD = "workdirs get room thread"
@@ -106,6 +107,11 @@ INST_GET_INSTALLATION_PROVIDERS = "get installation providers"
106
107
  INST_GET_INSTALLATION_GIT_METADATA = "get installation git metadata"
107
108
  INST_GET_INSTALLATION_IDENTITY = "get installation identity"
108
109
  INST_NO_INSTALLATION_IDENTITY = "installation identity not configured"
110
+ INST_POST_RELOAD_ROOMS = "installation reload rooms"
111
+ INST_RELOAD_ROOMS_MULTI_WRITER = (
112
+ "room configs reload unsupported with multiple workers: restart"
113
+ " the server to reload"
114
+ )
109
115
 
110
116
  LOG_INGEST_INGEST_LOGS = "ingest logs"
111
117
  LOG_INGEST_PAYLOAD_TOO_BIG = "payload too big"
@@ -163,6 +169,7 @@ AUDIT_RESOURCE_INSTALLATION = "installation"
163
169
  AUDIT_RESOURCE_INSTALLATION_VERSIONS = "installation-versions"
164
170
  AUDIT_RESOURCE_INSTALLATION_PROVIDERS = "installation-providers"
165
171
  AUDIT_RESOURCE_INSTALLATION_GIT_METADATA = "installation-git-metadata"
172
+ AUDIT_RESOURCE_INSTALLATION_ROOMS = "installation-rooms"
166
173
  AUDIT_RESOURCE_ROOM_UPLOAD = "room-upload"
167
174
 
168
175
  # room-authz audit events
@@ -180,6 +187,7 @@ AUDIT_INSTALLATION_READ = "installation read"
180
187
  AUDIT_INSTALLATION_VERSIONS_READ = "installation versions read"
181
188
  AUDIT_INSTALLATION_PROVIDERS_READ = "installation providers read"
182
189
  AUDIT_INSTALLATION_GIT_METADATA_READ = "installation git metadata read"
190
+ AUDIT_INSTALLATION_ROOMS_RELOADED = "installation rooms reloaded"
183
191
 
184
192
  # server-lifecycle audit events
185
193
  AUDIT_SERVER_STARTING = "server starting"
@@ -213,9 +221,10 @@ AUDIT_SANDBOX_ACTION_READ_IMAGE = "read-image"
213
221
  AUDIT_SANDBOX_REASON_TIMEOUT = "timeout"
214
222
  AUDIT_SANDBOX_REASON_EXIT_CODE = "exit-code"
215
223
 
216
- # room-upload audit events: an admin (privileged) adds shared reference
224
+ # room-upload audit events: an admin / privileged user adds shared reference
217
225
  # material to a room, changing what the room's agent and members can access.
218
226
  AUDIT_ROOM_UPLOAD_ADDED = "room upload added"
227
+ AUDIT_ROOM_UPLOAD_DELETED = "room upload deleted"
219
228
 
220
229
  # room-access audit events. 'AUDIT_ROOM_ACCESS' is the single "a principal
221
230
  # accessed room X" event, emitted across every entry path: the authenticated
@@ -547,6 +556,14 @@ class InstallationConfigAuditLog(AuditLogWrapper):
547
556
  def installation_git_metadata_read(self):
548
557
  self._succeeded(AUDIT_INSTALLATION_GIT_METADATA_READ)
549
558
 
559
+ def rooms_reloaded(self, added, removed, changed):
560
+ self._succeeded(
561
+ AUDIT_INSTALLATION_ROOMS_RELOADED,
562
+ rooms_added=added,
563
+ rooms_removed=removed,
564
+ rooms_changed=changed,
565
+ )
566
+
550
567
 
551
568
  class RAGAccessAuditLog(AuditLogWrapper):
552
569
  """Record knowledge-base accesses made while answering a request
@@ -769,6 +786,15 @@ class RoomUploadAuditLog(AuditLogWrapper):
769
786
  upload_filename=filename,
770
787
  )
771
788
 
789
+ def room_upload_deleted(self, room_id: str, filename: str):
790
+ # NB: 'filename' is a reserved LogRecord attribute, so the stored
791
+ # file is recorded under 'upload_filename'.
792
+ self._succeeded(
793
+ AUDIT_ROOM_UPLOAD_DELETED,
794
+ room_id=room_id,
795
+ upload_filename=filename,
796
+ )
797
+
772
798
 
773
799
  class RoomAccessAuditLog(AuditLogWrapper):
774
800
  """Record access to a room (and, for the CLI, the agent-run outcome).
@@ -483,6 +483,18 @@ class InstallationInfo(pydantic.BaseModel):
483
483
  )
484
484
 
485
485
 
486
+ class RoomConfigsReloaded(pydantic.BaseModel):
487
+ """The room IDs the last room-configs reload changed
488
+
489
+ 'changed' means the reloaded config compares unequal to the one it
490
+ replaced; unchanged rooms appear in none of the three fields.
491
+ """
492
+
493
+ added: list[str] = []
494
+ removed: list[str] = []
495
+ changed: list[str] = []
496
+
497
+
486
498
  class Installation(pydantic.BaseModel):
487
499
  """Configuration for a set of rooms, completions, etc."""
488
500