unique-orchestrator 2026.40.0.dev0__tar.gz → 2026.40.0.dev2__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 (34) hide show
  1. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/PKG-INFO +2 -2
  2. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/pyproject.toml +2 -2
  3. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_register_code_interpreter_postprocessors.py +62 -7
  4. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/unique_ai_builder.py +6 -1
  5. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/README.md +0 -0
  6. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/__init__.py +0 -0
  7. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/_builders/__init__.py +0 -0
  8. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/_builders/history_manager.py +0 -0
  9. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/_builders/inject_tool_reminders.py +0 -0
  10. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/_builders/loop_iteration_runner.py +0 -0
  11. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/_builders/open_file_setup.py +0 -0
  12. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/_builders/skill_setup.py +0 -0
  13. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/config.py +0 -0
  14. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/prompts/generic_reference_prompt.jinja2 +0 -0
  15. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/prompts/system_prompt.jinja2 +0 -0
  16. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/prompts/user_message_prompt.jinja2 +0 -0
  17. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/settings.py +0 -0
  18. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_agent_config_rjsf_ui_schema.py +0 -0
  19. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_build_loop_iteration_runner.py +0 -0
  20. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_config_services_validators.py +0 -0
  21. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_qwen_max_loop_iterations.py +0 -0
  22. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_async_modify.py +0 -0
  23. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_execution_timing.py +0 -0
  24. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_get_filtered_user_metadata.py +0 -0
  25. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_log_tool_calls.py +0 -0
  26. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_loop_debug_params.py +0 -0
  27. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_persist_tool_calls.py +0 -0
  28. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_plan_or_execute_include.py +0 -0
  29. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_reference_order.py +0 -0
  30. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_render_system_prompt_user_instructions.py +0 -0
  31. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_unique_ai_token_usage.py +0 -0
  32. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/tests/test_utils_resolve_other_options.py +0 -0
  33. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/unique_ai.py +0 -0
  34. {unique_orchestrator-2026.40.0.dev0 → unique_orchestrator-2026.40.0.dev2}/unique_orchestrator/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-orchestrator
3
- Version: 2026.40.0.dev0
3
+ Version: 2026.40.0.dev2
4
4
  Summary:
5
5
  Author: Andreas Hauri
6
6
  Author-email: Andreas Hauri <andreas.hauri@unique.ai>
@@ -9,7 +9,7 @@ Requires-Dist: pydantic>=2.8.2,<3
9
9
  Requires-Dist: pydantic-settings>=2.10.1,<3
10
10
  Requires-Dist: typing-extensions>=4.9.0,<5
11
11
  Requires-Dist: jinja2>=3.1.0,<4
12
- Requires-Dist: unique-toolkit>=2026.40.0.dev0,<2026.40.0rc0
12
+ Requires-Dist: unique-toolkit>=2026.40.0.dev5,<2026.40.0rc0
13
13
  Requires-Dist: unique-stock-ticker>=2026.40.0.dev0,<2026.40.0rc0
14
14
  Requires-Dist: unique-follow-up-questions>=2026.40.0.dev0,<2026.40.0rc0
15
15
  Requires-Dist: unique-internal-search>=2026.40.0.dev0,<2026.40.0rc0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique_orchestrator"
3
- version = "2026.40.0.dev0"
3
+ version = "2026.40.0.dev2"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  license = { text = "Proprietary" }
@@ -13,7 +13,7 @@ dependencies = [
13
13
  "pydantic-settings>=2.10.1,<3",
14
14
  "typing-extensions>=4.9.0,<5",
15
15
  "jinja2>=3.1.0,<4",
16
- "unique-toolkit>=2026.40.0.dev0,<2026.40.0rc0",
16
+ "unique-toolkit>=2026.40.0.dev5,<2026.40.0rc0",
17
17
  "unique-stock-ticker>=2026.40.0.dev0,<2026.40.0rc0",
18
18
  "unique-follow-up-questions>=2026.40.0.dev0,<2026.40.0rc0",
19
19
  "unique-internal-search>=2026.40.0.dev0,<2026.40.0rc0",
@@ -218,25 +218,78 @@ class TestConfigPassthrough:
218
218
  assert postprocessor._config is custom_code_display_config
219
219
 
220
220
  @pytest.mark.ai
221
- def test_show_executed_code_postprocessor_receives_company_id(self):
222
- """ShowExecutedCodePostprocessor must receive company_id for fence FF checks (UN-17972)."""
221
+ def test_show_executed_code_postprocessor_receives_fence_config(self):
222
+ """The enable_code_execution_fence config value must be threaded through.
223
+
224
+ The field lives on the code-display config. When fences are disabled
225
+ there, the legacy executed-code display must become active (given the
226
+ enable=True default), and the files postprocessor must keep fences off.
227
+ """
228
+ from unique_toolkit.agentic.tools.openai_builtin.code_interpreter.postprocessors.code_display import (
229
+ ShowExecutedCodePostprocessorConfig,
230
+ )
231
+
232
+ ci_config = CodeInterpreterExtendedConfig(
233
+ executed_code_display_config=ShowExecutedCodePostprocessorConfig(
234
+ enable_code_execution_fence=False
235
+ )
236
+ )
223
237
  mgr = _make_postprocessor_manager()
224
238
 
225
239
  _register_code_interpreter_postprocessors(
226
- tools=[_make_code_interpreter_tool()],
240
+ tools=[_make_code_interpreter_tool(config=ci_config)],
227
241
  postprocessor_manager=mgr,
228
242
  client=MagicMock(),
229
243
  content_service=MagicMock(),
230
244
  user_id="u1",
231
- company_id="company-fence",
245
+ company_id="c1",
232
246
  chat_id="ch1",
233
247
  chat_service=MagicMock(),
234
248
  )
235
249
 
236
- postprocessor: ShowExecutedCodePostprocessor = (
250
+ show_code_pp: ShowExecutedCodePostprocessor = (
237
251
  mgr.add_postprocessor.call_args_list[0][0][0]
238
252
  )
239
- assert postprocessor._company_id == "company-fence"
253
+ display_files_pp: DisplayCodeInterpreterFilesPostProcessor = (
254
+ mgr.add_postprocessor.call_args_list[1][0][0]
255
+ )
256
+ # Fence off → legacy code display is active; files postprocessor keeps fences off.
257
+ assert show_code_pp._is_enabled is True
258
+ assert display_files_pp._fence_enabled is False
259
+
260
+ @pytest.mark.ai
261
+ def test_display_files_postprocessor_receives_html_fence_config(self):
262
+ """The enable_html_with_fence config value must be threaded through.
263
+
264
+ The field lives on the code-display config, but only the files
265
+ postprocessor reads it (UN-17927).
266
+ """
267
+ from unique_toolkit.agentic.tools.openai_builtin.code_interpreter.postprocessors.code_display import (
268
+ ShowExecutedCodePostprocessorConfig,
269
+ )
270
+
271
+ ci_config = CodeInterpreterExtendedConfig(
272
+ executed_code_display_config=ShowExecutedCodePostprocessorConfig(
273
+ enable_html_with_fence=False
274
+ )
275
+ )
276
+ mgr = _make_postprocessor_manager()
277
+
278
+ _register_code_interpreter_postprocessors(
279
+ tools=[_make_code_interpreter_tool(config=ci_config)],
280
+ postprocessor_manager=mgr,
281
+ client=MagicMock(),
282
+ content_service=MagicMock(),
283
+ user_id="u1",
284
+ company_id="c1",
285
+ chat_id="ch1",
286
+ chat_service=MagicMock(),
287
+ )
288
+
289
+ display_files_pp: DisplayCodeInterpreterFilesPostProcessor = (
290
+ mgr.add_postprocessor.call_args_list[1][0][0]
291
+ )
292
+ assert display_files_pp._html_fence_enabled is False
240
293
 
241
294
  @pytest.mark.ai
242
295
  def test_display_files_postprocessor_receives_client_and_company_id(self):
@@ -261,9 +314,11 @@ class TestConfigPassthrough:
261
314
  mgr.add_postprocessor.call_args_list[1][0][0]
262
315
  )
263
316
  assert pp._client is client
264
- assert pp._company_id == "company-99"
265
317
  # All three IDs were passed, so short-term memory manager is initialised
266
318
  assert pp._short_term_memory_manager is not None
319
+ # The postprocessor does not keep the company_id; it only scopes the memory.
320
+ memory_service = pp._short_term_memory_manager._short_term_memory_service
321
+ assert memory_service.company_id == "company-99"
267
322
 
268
323
 
269
324
  # ---------------------------------------------------------------------------
@@ -507,7 +507,6 @@ def _register_code_interpreter_postprocessors(
507
507
  postprocessor_manager.add_postprocessor(
508
508
  ShowExecutedCodePostprocessor(
509
509
  config=code_interpreter_config.executed_code_display_config,
510
- company_id=company_id,
511
510
  )
512
511
  )
513
512
  postprocessor_manager.add_postprocessor(
@@ -519,6 +518,12 @@ def _register_code_interpreter_postprocessors(
519
518
  company_id=company_id,
520
519
  chat_id=chat_id,
521
520
  chat_service=chat_service,
521
+ code_execution_fence_enabled=(
522
+ code_interpreter_config.executed_code_display_config.enable_code_execution_fence
523
+ ),
524
+ html_with_fence_enabled=(
525
+ code_interpreter_config.executed_code_display_config.enable_html_with_fence
526
+ ),
522
527
  )
523
528
  )
524
529