unique_orchestrator 2026.32.0.dev2__tar.gz → 2026.32.0.dev4__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.
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/PKG-INFO +5 -5
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/pyproject.toml +5 -5
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/prompts/system_prompt.jinja2 +4 -1
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/unique_ai_builder.py +41 -9
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/README.md +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/__init__.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/_builders/__init__.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/_builders/history_manager.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/_builders/inject_tool_reminders.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/_builders/loop_iteration_runner.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/_builders/open_file_setup.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/_builders/skill_setup.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/config.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/prompts/generic_reference_prompt.jinja2 +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/prompts/user_message_prompt.jinja2 +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/settings.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_agent_config_rjsf_ui_schema.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_build_loop_iteration_runner.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_config_services_validators.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_qwen_max_loop_iterations.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_register_code_interpreter_postprocessors.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_async_modify.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_execution_timing.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_get_filtered_user_metadata.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_log_tool_calls.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_loop_debug_params.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_persist_tool_calls.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_plan_or_execute_include.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_reference_order.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_render_system_prompt_user_instructions.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_unique_ai_token_usage.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/tests/test_utils_resolve_other_options.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/unique_ai.py +0 -0
- {unique_orchestrator-2026.32.0.dev2 → unique_orchestrator-2026.32.0.dev4}/unique_orchestrator/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-orchestrator
|
|
3
|
-
Version: 2026.32.0.
|
|
3
|
+
Version: 2026.32.0.dev4
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Andreas Hauri
|
|
6
6
|
Author-email: Andreas Hauri <andreas.hauri@unique.ai>
|
|
@@ -9,15 +9,15 @@ 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.32.0.
|
|
12
|
+
Requires-Dist: unique-toolkit>=2026.32.0.dev8,<2026.32.0rc0
|
|
13
13
|
Requires-Dist: unique-stock-ticker>=2026.32.0.dev1,<2026.32.0rc0
|
|
14
|
-
Requires-Dist: unique-follow-up-questions>=2026.32.0.
|
|
15
|
-
Requires-Dist: unique-internal-search>=2026.32.0.
|
|
14
|
+
Requires-Dist: unique-follow-up-questions>=2026.32.0.dev1,<2026.32.0rc0
|
|
15
|
+
Requires-Dist: unique-internal-search>=2026.32.0.dev2,<2026.32.0rc0
|
|
16
16
|
Requires-Dist: unique-deep-research>=2026.32.0.dev1,<2026.32.0rc0
|
|
17
17
|
Requires-Dist: unique-web-search>=2026.32.0.dev2,<2026.32.0rc0
|
|
18
18
|
Requires-Dist: unique-swot>=2026.32.0.dev0,<2026.32.0rc0
|
|
19
19
|
Requires-Dist: unique-skill-tool>=2026.32.0.dev0,<2026.32.0rc0
|
|
20
|
-
Requires-Dist: unique-user-memory>=2026.32.0.
|
|
20
|
+
Requires-Dist: unique-user-memory>=2026.32.0.dev4,<2026.32.0rc0
|
|
21
21
|
Requires-Dist: openai>=1.109.1,<3
|
|
22
22
|
Requires-Python: >=3.12, <4
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "unique_orchestrator"
|
|
3
|
-
version = "2026.32.0.
|
|
3
|
+
version = "2026.32.0.dev4"
|
|
4
4
|
description = ""
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "Proprietary" }
|
|
@@ -13,15 +13,15 @@ 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.32.0.
|
|
16
|
+
"unique-toolkit>=2026.32.0.dev8,<2026.32.0rc0",
|
|
17
17
|
"unique-stock-ticker>=2026.32.0.dev1,<2026.32.0rc0",
|
|
18
|
-
"unique-follow-up-questions>=2026.32.0.
|
|
19
|
-
"unique-internal-search>=2026.32.0.
|
|
18
|
+
"unique-follow-up-questions>=2026.32.0.dev1,<2026.32.0rc0",
|
|
19
|
+
"unique-internal-search>=2026.32.0.dev2,<2026.32.0rc0",
|
|
20
20
|
"unique-deep-research>=2026.32.0.dev1,<2026.32.0rc0",
|
|
21
21
|
"unique-web-search>=2026.32.0.dev2,<2026.32.0rc0",
|
|
22
22
|
"unique-swot>=2026.32.0.dev0,<2026.32.0rc0",
|
|
23
23
|
"unique-skill-tool>=2026.32.0.dev0,<2026.32.0rc0",
|
|
24
|
-
"unique-user-memory>=2026.32.0.
|
|
24
|
+
"unique-user-memory>=2026.32.0.dev4,<2026.32.0rc0",
|
|
25
25
|
"openai>=1.109.1,<3",
|
|
26
26
|
]
|
|
27
27
|
|
|
@@ -30,7 +30,10 @@ Here is some metadata about the user, which may help you write better queries, a
|
|
|
30
30
|
# What I know about you
|
|
31
31
|
The following profile was distilled from past conversations with this user. Treat it as durable user context: adapt your tone, examples, and depth to it. If the user asks what you know or remember about them, you may share this memory back to them, including verbatim if they request it. Do not treat it as authoritative for facts about the world.
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
The memory is maintained for you: an automatic postprocessing step re-reads every turn after your final answer and updates the profile on its own. You can read the memory while answering, but you cannot add to, edit, or delete it during your response, and nothing the user says changes whether the update runs. Therefore:
|
|
34
|
+
- Never ask the user whether something should be remembered, saved, or added to their profile.
|
|
35
|
+
- Never offer to update the memory, and never state that you have updated it, are updating it, or will update it.
|
|
36
|
+
- When the user shares a new fact about themselves, or asks you to remember or forget something, acknowledge it in one short clause and continue with their actual request.
|
|
34
37
|
|
|
35
38
|
{{ user_memory }}
|
|
36
39
|
{%- endif %}
|
|
@@ -69,7 +69,8 @@ from unique_toolkit.experimental.integrations.openai.streaming.event_routing imp
|
|
|
69
69
|
)
|
|
70
70
|
from unique_toolkit.language_model.infos import LanguageModelInfo, ModelCapabilities
|
|
71
71
|
from unique_toolkit.protocols.support import ResponsesSupportCompleteWithReferences
|
|
72
|
-
from unique_user_memory.user_memory import load_user_memory
|
|
72
|
+
from unique_user_memory.user_memory import load_user_memory, profile_body
|
|
73
|
+
from unique_user_memory.user_memory_message_log import UserMemoryMessageLogger
|
|
73
74
|
from unique_user_memory.user_memory_postprocessor import UserMemoryPostprocessor
|
|
74
75
|
|
|
75
76
|
from unique_orchestrator._builders import (
|
|
@@ -298,6 +299,7 @@ async def _build_common(
|
|
|
298
299
|
config: UniqueAIConfig,
|
|
299
300
|
) -> _CommonComponents:
|
|
300
301
|
chat_service = ChatService(event)
|
|
302
|
+
message_step_logger = MessageStepLogger(chat_service)
|
|
301
303
|
|
|
302
304
|
llm_service = LanguageModelService.from_event(event)
|
|
303
305
|
|
|
@@ -393,14 +395,40 @@ async def _build_common(
|
|
|
393
395
|
if user_memory_config.use_orchestrator_language_model
|
|
394
396
|
else user_memory_config.language_model
|
|
395
397
|
)
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
config=user_memory_config,
|
|
399
|
-
language_model=memory_language_model,
|
|
398
|
+
memory_message_step_logger = UserMemoryMessageLogger(
|
|
399
|
+
message_step_logger,
|
|
400
400
|
logger=logger,
|
|
401
401
|
)
|
|
402
|
-
|
|
403
|
-
|
|
402
|
+
await memory_message_step_logger.log_loading_start()
|
|
403
|
+
user_memory_state = None
|
|
404
|
+
load_succeeded = False
|
|
405
|
+
try:
|
|
406
|
+
user_memory_state = await load_user_memory(
|
|
407
|
+
event=event,
|
|
408
|
+
config=user_memory_config,
|
|
409
|
+
language_model=memory_language_model,
|
|
410
|
+
logger=logger,
|
|
411
|
+
)
|
|
412
|
+
load_succeeded = True
|
|
413
|
+
except Exception as exc:
|
|
414
|
+
# Soft-fail like a None return: keep the turn running without
|
|
415
|
+
# memory, but always close the RUNNING loading Step first.
|
|
416
|
+
logger.warning(
|
|
417
|
+
"[user-memory] load raised - running without memory: [%s] %s",
|
|
418
|
+
type(exc).__name__,
|
|
419
|
+
exc,
|
|
420
|
+
)
|
|
421
|
+
finally:
|
|
422
|
+
if not load_succeeded:
|
|
423
|
+
await memory_message_step_logger.log_loading_failed()
|
|
424
|
+
|
|
425
|
+
if load_succeeded and user_memory_state is not None:
|
|
426
|
+
await memory_message_step_logger.log_loading_complete(
|
|
427
|
+
with_settings_entry=True
|
|
428
|
+
)
|
|
429
|
+
# The postprocessor keeps the full file (it needs the frontmatter to
|
|
430
|
+
# carry turn_count forward); the prompt only gets the Markdown body.
|
|
431
|
+
user_memory_text = profile_body(user_memory_state.text)
|
|
404
432
|
postprocessor_manager.add_postprocessor(
|
|
405
433
|
UserMemoryPostprocessor(
|
|
406
434
|
config=user_memory_config,
|
|
@@ -408,9 +436,13 @@ async def _build_common(
|
|
|
408
436
|
event=event,
|
|
409
437
|
state=user_memory_state,
|
|
410
438
|
logger=logger,
|
|
411
|
-
|
|
439
|
+
message_step_logger=memory_message_step_logger,
|
|
412
440
|
)
|
|
413
441
|
)
|
|
442
|
+
elif load_succeeded:
|
|
443
|
+
await memory_message_step_logger.log_loading_complete(
|
|
444
|
+
with_settings_entry=False
|
|
445
|
+
)
|
|
414
446
|
|
|
415
447
|
return _CommonComponents(
|
|
416
448
|
chat_service=chat_service,
|
|
@@ -429,7 +461,7 @@ async def _build_common(
|
|
|
429
461
|
user_memory_text=user_memory_text,
|
|
430
462
|
postprocessor_manager=postprocessor_manager,
|
|
431
463
|
response_watcher=response_watcher,
|
|
432
|
-
message_step_logger=
|
|
464
|
+
message_step_logger=message_step_logger,
|
|
433
465
|
)
|
|
434
466
|
|
|
435
467
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|