soliplex 0.72__tar.gz → 0.72.2__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 (92) hide show
  1. {soliplex-0.72/src/soliplex.egg-info → soliplex-0.72.2}/PKG-INFO +3 -2
  2. {soliplex-0.72 → soliplex-0.72.2}/pyproject.toml +3 -2
  3. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/rooms.py +20 -1
  4. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/skills.py +9 -0
  5. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/models.py +1 -1
  6. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/tui/rest_api.py +1 -1
  7. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/room_file_uploads.py +9 -1
  8. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/thread_file_uploads.py +27 -14
  9. {soliplex-0.72 → soliplex-0.72.2/src/soliplex.egg-info}/PKG-INFO +3 -2
  10. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex.egg-info/requires.txt +2 -1
  11. {soliplex-0.72 → soliplex-0.72.2}/LICENSE +0 -0
  12. {soliplex-0.72 → soliplex-0.72.2}/MANIFEST.in +0 -0
  13. {soliplex-0.72 → soliplex-0.72.2}/README.md +0 -0
  14. {soliplex-0.72 → soliplex-0.72.2}/example/skills/bare-bones/SKILL.md +0 -0
  15. {soliplex-0.72 → soliplex-0.72.2}/setup.cfg +0 -0
  16. {soliplex-0.72 → soliplex-0.72.2}/skills/soliplex-docs/SKILL.md +0 -0
  17. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/agents.py +0 -0
  18. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/agui/__init__.py +0 -0
  19. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/agui/parser.py +0 -0
  20. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/agui/persistence.py +0 -0
  21. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/agui/schema.py +0 -0
  22. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/agui/util.py +0 -0
  23. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/authn.py +0 -0
  24. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/authz/__init__.py +0 -0
  25. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/authz/persistence.py +0 -0
  26. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/authz/schema.py +0 -0
  27. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/cli/admin_users.py +0 -0
  28. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/cli/ask.py +0 -0
  29. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/cli/audit.py +0 -0
  30. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/cli/cli_util.py +0 -0
  31. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/cli/main.py +0 -0
  32. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/cli/ollama.py +0 -0
  33. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/cli/room_authz.py +0 -0
  34. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/cli/serve.py +0 -0
  35. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/cli/types.py +0 -0
  36. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/completions.py +0 -0
  37. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/__init__.py +0 -0
  38. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/_utils.py +0 -0
  39. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/agents.py +0 -0
  40. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/agui.py +0 -0
  41. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/authsystem.py +0 -0
  42. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/completions.py +0 -0
  43. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/exceptions.py +0 -0
  44. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/installation.py +0 -0
  45. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/logfire.py +0 -0
  46. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/meta.py +0 -0
  47. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/middleware.py +0 -0
  48. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/quizzes.py +0 -0
  49. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/rag.py +0 -0
  50. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/routing.py +0 -0
  51. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/secrets.py +0 -0
  52. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/config/tools.py +0 -0
  53. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/examples.py +0 -0
  54. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/installation.py +0 -0
  55. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/log_ingest.py +0 -0
  56. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/loggers.py +0 -0
  57. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/main.py +0 -0
  58. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/mcp_auth.py +0 -0
  59. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/mcp_client.py +0 -0
  60. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/mcp_server.py +0 -0
  61. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/ollama.py +0 -0
  62. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/quizzes.py +0 -0
  63. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/rag_audit.py +0 -0
  64. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/sandbox_audit.py +0 -0
  65. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/secrets.py +0 -0
  66. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/skills/bwrap_sandbox/SKILL.md +0 -0
  67. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/skills/bwrap_sandbox/__init__.py +0 -0
  68. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/titles.py +0 -0
  69. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/tools/__init__.py +0 -0
  70. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/tools/agui_run_feedback.py +0 -0
  71. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/tools/file_uploads.py +0 -0
  72. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/tools/rag.py +0 -0
  73. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/tui/cli.py +0 -0
  74. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/tui/main.py +0 -0
  75. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/tui/serve.py +0 -0
  76. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/util.py +0 -0
  77. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/__init__.py +0 -0
  78. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/agui.py +0 -0
  79. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/authn.py +0 -0
  80. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/authz.py +0 -0
  81. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/completions.py +0 -0
  82. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/installation.py +0 -0
  83. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/log_ingest.py +0 -0
  84. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/quizzes.py +0 -0
  85. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/rooms.py +0 -0
  86. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/sandbox_workdirs.py +0 -0
  87. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/stats.py +0 -0
  88. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex/views/streaming.py +0 -0
  89. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex.egg-info/SOURCES.txt +0 -0
  90. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex.egg-info/dependency_links.txt +0 -0
  91. {soliplex-0.72 → soliplex-0.72.2}/src/soliplex.egg-info/entry_points.txt +0 -0
  92. {soliplex-0.72 → soliplex-0.72.2}/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.72
3
+ Version: 0.72.2
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
@@ -19,12 +19,13 @@ Requires-Dist: fastapi
19
19
  Requires-Dist: fastmcp<3.4,>=3.3.0
20
20
  Requires-Dist: fakeredis!=2.35.0
21
21
  Requires-Dist: greenlet
22
- Requires-Dist: haiku.rag-slim<0.66,>=0.65
22
+ Requires-Dist: haiku.rag-slim<0.67,>=0.66
23
23
  Requires-Dist: haiku-skills<0.19,>=0.18.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: pillow<12.4,>=12.3.0
28
29
  Requires-Dist: python-jsonpath
29
30
  Requires-Dist: python-multipart>=0.0.31
30
31
  Requires-Dist: jwcrypto
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "soliplex"
7
- version = "0.72"
7
+ version = "0.72.2"
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"
@@ -25,12 +25,13 @@ dependencies = [
25
25
  "fastmcp >= 3.3.0, < 3.4",
26
26
  "fakeredis != 2.35.0", # brownbag
27
27
  "greenlet",
28
- "haiku.rag-slim >= 0.65, < 0.66",
28
+ "haiku.rag-slim >= 0.66, < 0.67",
29
29
  "haiku-skills >= 0.18.0, < 0.19",
30
30
  "idna >= 3.15",
31
31
  "itsdangerous",
32
32
  "joserfc >= 1.6.7, < 1.7", # CVE-2026-48990
33
33
  "jsonpatch",
34
+ "pillow >= 12.3.0, < 12.4", # PYSEC-2026-225{3,4,5,6,7}
34
35
  "python-jsonpath", # RFC 9535 query support
35
36
  "python-multipart >= 0.0.31", # Multiple CVEs
36
37
  "jwcrypto",
@@ -3,6 +3,7 @@ from __future__ import annotations # forward refs in typing decls
3
3
  import dataclasses
4
4
  import pathlib
5
5
  import typing
6
+ import warnings
6
7
 
7
8
  from . import _utils
8
9
  from . import agents as config_agents
@@ -20,6 +21,12 @@ _default_dict_field = _utils._default_dict_field
20
21
  # ============================================================================
21
22
 
22
23
 
24
+ ENABLE_ATTACHMENTS_DEPRECATION = (
25
+ "'RoomConfig.enable_attachments' is deprecated, and will be removed "
26
+ "after 'soliplex v0.73'"
27
+ )
28
+
29
+
23
30
  @dataclasses.dataclass(kw_only=True)
24
31
  class RoomConfig:
25
32
  """Configuration for a chat room"""
@@ -38,7 +45,7 @@ class RoomConfig:
38
45
  _order: str = None # defaults to 'id'
39
46
  welcome_message: str = None
40
47
  suggestions: list[str] = _default_list_field()
41
- enable_attachments: bool = False
48
+ enable_attachments: bool | None = None # deprecated / ignored (#1133)
42
49
 
43
50
  #
44
51
  # Tool options
@@ -79,6 +86,13 @@ class RoomConfig:
79
86
  if logo_image is not None:
80
87
  self._logo_image = logo_image
81
88
 
89
+ if self.enable_attachments is not None:
90
+ warnings.warn(
91
+ ENABLE_ATTACHMENTS_DEPRECATION,
92
+ DeprecationWarning,
93
+ stacklevel=3,
94
+ )
95
+
82
96
  @classmethod
83
97
  def from_yaml(
84
98
  cls,
@@ -170,6 +184,11 @@ class RoomConfig:
170
184
  """Map each RAG-bearing skill's name to its LanceDB path."""
171
185
  return self.skills.rag_db_paths if self.skills is not None else {}
172
186
 
187
+ @property
188
+ def has_sandbox(self) -> bool:
189
+ """Does the room have the sandbox skill?"""
190
+ return self.skills.has_sandbox if self.skills is not None else False
191
+
173
192
  @property
174
193
  def agui_feature_names(self) -> tuple[str]:
175
194
  agent_features = set(self.agent_config.agui_feature_names)
@@ -593,6 +593,15 @@ class RoomSkillsConfig(_SkillConfigModelBase):
593
593
  if isinstance(skill_config, _HR_SkillConfigBase)
594
594
  }
595
595
 
596
+ @property
597
+ def has_sandbox(self) -> bool:
598
+ """Does the room have the sandbox skill?"""
599
+ return any(
600
+ skill_config
601
+ for skill_config in self.skill_configs.values()
602
+ if isinstance(skill_config, BwrapSandboxSkillConfig)
603
+ )
604
+
596
605
  @property
597
606
  def skill_preambles(self) -> list[str]:
598
607
  preambles = []
@@ -268,7 +268,7 @@ class Room(pydantic.BaseModel):
268
268
  description: str
269
269
  welcome_message: str
270
270
  suggestions: list[str]
271
- enable_attachments: bool
271
+ enable_attachments: bool | None = None # Deprecated: #1133
272
272
  tools: ConfiguredTools
273
273
  mcp_client_toolsets: ConfiguredMCPClientToolsets
274
274
  skills: ConfiguredSkills
@@ -184,7 +184,7 @@ class TUI_REST_API:
184
184
  thread_id: str,
185
185
  file_path: pathlib.Path,
186
186
  ) -> None:
187
- upload_url = f"{self.api_v1_base}/uploads/{room_id}/{thread_id}"
187
+ upload_url = f"{self.api_v1_base}/uploads/{room_id}/thread/{thread_id}"
188
188
 
189
189
  with file_path.open("rb") as file_stream:
190
190
  files = {
@@ -190,12 +190,20 @@ async def post_uploads_room(
190
190
  the_logger=the_logger,
191
191
  )
192
192
 
193
+ if not _room_config.has_sandbox:
194
+ raise fastapi.HTTPException(
195
+ status_code=405,
196
+ detail="Sandbox not configured",
197
+ headers={"Allow": "GET"},
198
+ )
199
+
193
200
  uploads_path = the_installation.rooms_upload_path
194
201
 
195
202
  if uploads_path is None:
196
203
  raise fastapi.HTTPException(
197
- status_code=404,
204
+ status_code=405,
198
205
  detail="Room uploads not configured",
206
+ headers={"Allow": "GET"},
199
207
  )
200
208
 
201
209
  room_dir = pathlib.Path(uploads_path) / room_id
@@ -27,7 +27,7 @@ depend_the_logger = views.depend_the_logger
27
27
  "GET /v1/uploads/{room_id}/thread/{thread_id}",
28
28
  )
29
29
  @router.get("/v1/uploads/{room_id}/thread/{thread_id}")
30
- async def get_uploads_room_thread(
30
+ async def get_uploads_room_id_thread_thread_id(
31
31
  request: fastapi.Request,
32
32
  room_id: str,
33
33
  thread_id: pydantic.UUID4,
@@ -66,7 +66,7 @@ async def get_uploads_room_thread(
66
66
  filename = file_or_sub.name
67
67
  filename_urls[filename] = request.url_for(
68
68
  # View function name, not the route path.
69
- "get_uploads_room_thread_filename",
69
+ "get_uploads_room_id_thread_thread_id_filename",
70
70
  room_id=room_id,
71
71
  thread_id=thread_id,
72
72
  filename=filename,
@@ -92,7 +92,7 @@ async def get_uploads_room_thread(
92
92
  "/v1/uploads/{room_id}/thread/{thread_id}/file/{filename}",
93
93
  response_class=responses.FileResponse,
94
94
  )
95
- async def get_uploads_room_thread_filename(
95
+ async def get_uploads_room_id_thread_thread_id_filename(
96
96
  room_id: str,
97
97
  thread_id: pydantic.UUID4,
98
98
  filename: str,
@@ -142,10 +142,15 @@ async def get_uploads_room_thread_filename(
142
142
 
143
143
 
144
144
  @soliplex_views_util.logfire_span(
145
- "POST /v1/uploads/{room_id}/{thread_id}/",
145
+ "POST /v1/uploads/{room_id}/thread/{thread_id}/",
146
146
  )
147
- @router.post("/v1/uploads/{room_id}/{thread_id}", status_code=204)
148
- async def post_uploads_room_thread(
147
+ @router.post("/v1/uploads/{room_id}/thread/{thread_id}", status_code=204)
148
+ @router.post(
149
+ "/v1/uploads/{room_id}/{thread_id}",
150
+ status_code=204,
151
+ deprecated=True, # see #1137
152
+ )
153
+ async def post_uploads_room_id_thread_thread_id(
149
154
  room_id: str,
150
155
  thread_id: pydantic.UUID4,
151
156
  upload_file: fastapi.UploadFile,
@@ -173,6 +178,22 @@ async def post_uploads_room_thread(
173
178
  the_logger=the_logger,
174
179
  )
175
180
 
181
+ if not _room_config.has_sandbox:
182
+ raise fastapi.HTTPException(
183
+ status_code=405,
184
+ detail="Sandbox not configured",
185
+ headers={"Allow": "GET"},
186
+ )
187
+
188
+ uploads_path = the_installation.threads_upload_path
189
+
190
+ if uploads_path is None:
191
+ raise fastapi.HTTPException(
192
+ status_code=405,
193
+ detail="Thread uploads not configured",
194
+ headers={"Allow": "GET"},
195
+ )
196
+
176
197
  try:
177
198
  await the_threads.get_thread(
178
199
  user_name=user_name,
@@ -185,14 +206,6 @@ async def post_uploads_room_thread(
185
206
  detail=exc.args,
186
207
  ) from None
187
208
 
188
- uploads_path = the_installation.threads_upload_path
189
-
190
- if uploads_path is None:
191
- raise fastapi.HTTPException(
192
- status_code=404,
193
- detail="Thread uploads not configured",
194
- )
195
-
196
209
  thread_dir = pathlib.Path(uploads_path) / thread_id
197
210
  thread_dir.mkdir(parents=True, exist_ok=True)
198
211
  stripped_filename = pathlib.Path(upload_file.filename).name
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soliplex
3
- Version: 0.72
3
+ Version: 0.72.2
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
@@ -19,12 +19,13 @@ Requires-Dist: fastapi
19
19
  Requires-Dist: fastmcp<3.4,>=3.3.0
20
20
  Requires-Dist: fakeredis!=2.35.0
21
21
  Requires-Dist: greenlet
22
- Requires-Dist: haiku.rag-slim<0.66,>=0.65
22
+ Requires-Dist: haiku.rag-slim<0.67,>=0.66
23
23
  Requires-Dist: haiku-skills<0.19,>=0.18.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: pillow<12.4,>=12.3.0
28
29
  Requires-Dist: python-jsonpath
29
30
  Requires-Dist: python-multipart>=0.0.31
30
31
  Requires-Dist: jwcrypto
@@ -9,12 +9,13 @@ fastapi
9
9
  fastmcp<3.4,>=3.3.0
10
10
  fakeredis!=2.35.0
11
11
  greenlet
12
- haiku.rag-slim<0.66,>=0.65
12
+ haiku.rag-slim<0.67,>=0.66
13
13
  haiku-skills<0.19,>=0.18.0
14
14
  idna>=3.15
15
15
  itsdangerous
16
16
  joserfc<1.7,>=1.6.7
17
17
  jsonpatch
18
+ pillow<12.4,>=12.3.0
18
19
  python-jsonpath
19
20
  python-multipart>=0.0.31
20
21
  jwcrypto
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes