unique_orchestrator 2026.24.0.dev0__tar.gz → 2026.24.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.
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/PKG-INFO +7 -7
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/pyproject.toml +7 -7
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/config.py +56 -2
- unique_orchestrator-2026.24.0.dev2/unique_orchestrator/tests/test_agent_config_rjsf_ui_schema.py +53 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_config_services_validators.py +39 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/unique_ai_builder.py +73 -2
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/README.md +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/__init__.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/_builders/__init__.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/_builders/inject_tool_reminders.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/_builders/loop_iteration_runner.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/_builders/open_file_setup.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/_builders/skill_setup.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/prompts/generic_reference_prompt.jinja2 +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/prompts/system_prompt.jinja2 +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/prompts/user_message_prompt.jinja2 +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/settings.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_build_loop_iteration_runner.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_qwen_max_loop_iterations.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_register_code_interpreter_postprocessors.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_unique_ai_async_modify.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_unique_ai_execution_timing.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_unique_ai_get_filtered_user_metadata.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_unique_ai_log_tool_calls.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_unique_ai_loop_debug_params.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_unique_ai_persist_tool_calls.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_unique_ai_plan_or_execute_include.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_unique_ai_reference_order.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_unique_ai_render_system_prompt_user_instructions.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/tests/test_utils_resolve_other_options.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.0.dev2}/unique_orchestrator/unique_ai.py +0 -0
- {unique_orchestrator-2026.24.0.dev0 → unique_orchestrator-2026.24.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.24.0.
|
|
3
|
+
Version: 2026.24.0.dev2
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Andreas Hauri
|
|
6
6
|
Author-email: Andreas Hauri <andreas.hauri@unique.ai>
|
|
@@ -9,13 +9,13 @@ 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.24.0.
|
|
13
|
-
Requires-Dist: unique-stock-ticker>=2026.24.0.
|
|
14
|
-
Requires-Dist: unique-follow-up-questions>=2026.24.0.
|
|
15
|
-
Requires-Dist: unique-internal-search>=2026.24.0.
|
|
12
|
+
Requires-Dist: unique-toolkit>=2026.24.0.dev11,<2026.24.0rc0
|
|
13
|
+
Requires-Dist: unique-stock-ticker>=2026.24.0.dev1,<2026.24.0rc0
|
|
14
|
+
Requires-Dist: unique-follow-up-questions>=2026.24.0.dev2,<2026.24.0rc0
|
|
15
|
+
Requires-Dist: unique-internal-search>=2026.24.0.dev1,<2026.24.0rc0
|
|
16
16
|
Requires-Dist: unique-deep-research>=2026.24.0.dev0,<2026.24.0rc0
|
|
17
|
-
Requires-Dist: unique-web-search>=2026.24.0.
|
|
18
|
-
Requires-Dist: unique-swot>=2026.24.0.
|
|
17
|
+
Requires-Dist: unique-web-search>=2026.24.0.dev3,<2026.24.0rc0
|
|
18
|
+
Requires-Dist: unique-swot>=2026.24.0.dev2,<2026.24.0rc0
|
|
19
19
|
Requires-Dist: unique-skill-tool>=2026.24.0.dev0,<2026.24.0rc0
|
|
20
20
|
Requires-Dist: openai>=1.109.1,<3
|
|
21
21
|
Requires-Python: >=3.12, <4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "unique_orchestrator"
|
|
3
|
-
version = "2026.24.0.
|
|
3
|
+
version = "2026.24.0.dev2"
|
|
4
4
|
description = ""
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = { text = "Proprietary" }
|
|
@@ -13,13 +13,13 @@ 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.24.0.
|
|
17
|
-
"unique-stock-ticker>=2026.24.0.
|
|
18
|
-
"unique-follow-up-questions>=2026.24.0.
|
|
19
|
-
"unique-internal-search>=2026.24.0.
|
|
16
|
+
"unique-toolkit>=2026.24.0.dev11,<2026.24.0rc0",
|
|
17
|
+
"unique-stock-ticker>=2026.24.0.dev1,<2026.24.0rc0",
|
|
18
|
+
"unique-follow-up-questions>=2026.24.0.dev2,<2026.24.0rc0",
|
|
19
|
+
"unique-internal-search>=2026.24.0.dev1,<2026.24.0rc0",
|
|
20
20
|
"unique-deep-research>=2026.24.0.dev0,<2026.24.0rc0",
|
|
21
|
-
"unique-web-search>=2026.24.0.
|
|
22
|
-
"unique-swot>=2026.24.0.
|
|
21
|
+
"unique-web-search>=2026.24.0.dev3,<2026.24.0rc0",
|
|
22
|
+
"unique-swot>=2026.24.0.dev2,<2026.24.0rc0",
|
|
23
23
|
"unique-skill-tool>=2026.24.0.dev0,<2026.24.0rc0",
|
|
24
24
|
"openai>=1.109.1,<3",
|
|
25
25
|
]
|
|
@@ -14,6 +14,7 @@ from unique_internal_search.uploaded_search.config import (
|
|
|
14
14
|
)
|
|
15
15
|
from unique_stock_ticker.config import StockTickerConfig
|
|
16
16
|
from unique_swot import SwotAnalysisTool, SwotAnalysisToolConfig
|
|
17
|
+
from unique_toolkit._common.pydantic.rjsf_tags import RJSFMetaTag
|
|
17
18
|
from unique_toolkit._common.validators import (
|
|
18
19
|
LMI,
|
|
19
20
|
ClipInt,
|
|
@@ -76,6 +77,20 @@ class SpaceType(StrEnum):
|
|
|
76
77
|
T = TypeVar("T", bound=SpaceType)
|
|
77
78
|
|
|
78
79
|
|
|
80
|
+
class SwitchableLanguageModelConfig(BaseToolConfig):
|
|
81
|
+
"""A language model that chat users may select for a single message."""
|
|
82
|
+
|
|
83
|
+
display_name: str = Field(
|
|
84
|
+
description="Human-readable label shown to chat users in the model picker.",
|
|
85
|
+
)
|
|
86
|
+
language_model: LMI = Field(
|
|
87
|
+
description=(
|
|
88
|
+
"Language-model configuration accepted from the platform payload as "
|
|
89
|
+
"`languageModel`."
|
|
90
|
+
),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
79
94
|
class SpaceConfigBase(BaseToolConfig, Generic[T]):
|
|
80
95
|
"""Base class for space configuration."""
|
|
81
96
|
|
|
@@ -88,6 +103,18 @@ class SpaceConfigBase(BaseToolConfig, Generic[T]):
|
|
|
88
103
|
|
|
89
104
|
language_model: LMI = get_LMI_default_field(DEFAULT_GPT_4o)
|
|
90
105
|
|
|
106
|
+
allow_model_switching: bool = Field(
|
|
107
|
+
default=False,
|
|
108
|
+
description=(
|
|
109
|
+
"Whether chat users may override the language model for a single message"
|
|
110
|
+
),
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
switchable_language_models: list[SwitchableLanguageModelConfig] = Field(
|
|
114
|
+
default_factory=list,
|
|
115
|
+
description=("Language models selectable by chat users for a single message."),
|
|
116
|
+
)
|
|
117
|
+
|
|
91
118
|
custom_instructions: str = Field(
|
|
92
119
|
default="",
|
|
93
120
|
description="A custom instruction provided by the system admin.",
|
|
@@ -210,14 +237,20 @@ class EvaluationConfig(BaseToolConfig):
|
|
|
210
237
|
|
|
211
238
|
|
|
212
239
|
class UniqueAIPromptConfig(BaseToolConfig):
|
|
213
|
-
system_prompt_template:
|
|
240
|
+
system_prompt_template: Annotated[
|
|
241
|
+
str,
|
|
242
|
+
RJSFMetaTag.StringWidget.textarea(rows=25),
|
|
243
|
+
] = Field(
|
|
214
244
|
default_factory=lambda: (
|
|
215
245
|
Path(__file__).parent / "prompts" / "system_prompt.jinja2"
|
|
216
246
|
).read_text(),
|
|
217
247
|
description="The system prompt template as a Jinja2 template string.",
|
|
218
248
|
)
|
|
219
249
|
|
|
220
|
-
user_message_prompt_template:
|
|
250
|
+
user_message_prompt_template: Annotated[
|
|
251
|
+
str,
|
|
252
|
+
RJSFMetaTag.StringWidget.textarea(rows=4),
|
|
253
|
+
] = Field(
|
|
221
254
|
default_factory=lambda: (
|
|
222
255
|
Path(__file__).parent / "prompts" / "user_message_prompt.jinja2"
|
|
223
256
|
).read_text(),
|
|
@@ -421,6 +454,27 @@ class UniqueAIConfig(BaseToolConfig):
|
|
|
421
454
|
self.agent.experimental.sub_agents_config.referencing_config = None
|
|
422
455
|
return self
|
|
423
456
|
|
|
457
|
+
@model_validator(mode="after")
|
|
458
|
+
def remove_tools_with_unsupported_model_capabilities(self) -> "UniqueAIConfig":
|
|
459
|
+
if ModelCapabilities.RESPONSES_API in self.space.language_model.capabilities:
|
|
460
|
+
return self
|
|
461
|
+
|
|
462
|
+
self.space.tools = [
|
|
463
|
+
tool
|
|
464
|
+
for tool in self.space.tools
|
|
465
|
+
if tool.name != OpenAIBuiltInToolName.CODE_INTERPRETER
|
|
466
|
+
]
|
|
467
|
+
return self
|
|
468
|
+
|
|
469
|
+
@model_validator(mode="after")
|
|
470
|
+
def disable_responses_api_when_model_does_not_support_it(self) -> "UniqueAIConfig":
|
|
471
|
+
if ModelCapabilities.RESPONSES_API in self.space.language_model.capabilities:
|
|
472
|
+
return self
|
|
473
|
+
|
|
474
|
+
self.agent.experimental.responses_api_config.use_responses_api = False
|
|
475
|
+
self.agent.experimental.use_responses_api = False
|
|
476
|
+
return self
|
|
477
|
+
|
|
424
478
|
@model_validator(mode="after")
|
|
425
479
|
def enable_responses_api_for_code_interpreter_tool(self) -> "UniqueAIConfig":
|
|
426
480
|
"""Auto-enable the Responses API when Code Interpreter is added directly as a tool.
|
unique_orchestrator-2026.24.0.dev2/unique_orchestrator/tests/test_agent_config_rjsf_ui_schema.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from humps import camelize
|
|
2
|
+
from unique_toolkit._common.pydantic.rjsf_tags import ui_schema_for_model
|
|
3
|
+
|
|
4
|
+
from unique_orchestrator.config import UniqueAIAgentConfig
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _nested_get(data: dict, path: str) -> object:
|
|
8
|
+
current: object = data
|
|
9
|
+
for part in path.split("."):
|
|
10
|
+
assert isinstance(current, dict)
|
|
11
|
+
current = current[part]
|
|
12
|
+
return current
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_unique_ai_agent_config__prompt_fields__textarea_widgets() -> None:
|
|
16
|
+
ui_schema = ui_schema_for_model(UniqueAIAgentConfig, key_transform=camelize)
|
|
17
|
+
assert _nested_get(ui_schema, "promptConfig.systemPromptTemplate") == {
|
|
18
|
+
"ui:widget": "textarea",
|
|
19
|
+
"ui:disabled": False,
|
|
20
|
+
"ui:readonly": False,
|
|
21
|
+
"ui:options": {"rows": 25},
|
|
22
|
+
"ui:emptyValue": "",
|
|
23
|
+
}
|
|
24
|
+
assert _nested_get(ui_schema, "promptConfig.userMessagePromptTemplate") == {
|
|
25
|
+
"ui:widget": "textarea",
|
|
26
|
+
"ui:disabled": False,
|
|
27
|
+
"ui:readonly": False,
|
|
28
|
+
"ui:options": {"rows": 4},
|
|
29
|
+
"ui:emptyValue": "",
|
|
30
|
+
}
|
|
31
|
+
assert _nested_get(ui_schema, "services.followUpQuestionsConfig.userPrompt") == {
|
|
32
|
+
"ui:widget": "textarea",
|
|
33
|
+
"ui:disabled": False,
|
|
34
|
+
"ui:readonly": False,
|
|
35
|
+
"ui:options": {"rows": 10},
|
|
36
|
+
"ui:emptyValue": "",
|
|
37
|
+
}
|
|
38
|
+
assert _nested_get(ui_schema, "services.followUpQuestionsConfig.systemPrompt") == {
|
|
39
|
+
"ui:widget": "textarea",
|
|
40
|
+
"ui:disabled": False,
|
|
41
|
+
"ui:readonly": False,
|
|
42
|
+
"ui:options": {"rows": 15},
|
|
43
|
+
"ui:emptyValue": "",
|
|
44
|
+
}
|
|
45
|
+
assert _nested_get(
|
|
46
|
+
ui_schema, "services.followUpQuestionsConfig.suggestionsFormat"
|
|
47
|
+
) == {
|
|
48
|
+
"ui:widget": "textarea",
|
|
49
|
+
"ui:disabled": False,
|
|
50
|
+
"ui:readonly": False,
|
|
51
|
+
"ui:options": {"rows": 8},
|
|
52
|
+
"ui:emptyValue": "",
|
|
53
|
+
}
|
|
@@ -29,6 +29,45 @@ from unique_orchestrator.config import (
|
|
|
29
29
|
)
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
class TestUniqueAISpaceConfigModelSwitching:
|
|
33
|
+
def test_accepts_camel_case_model_switching_fields(self):
|
|
34
|
+
config = UniqueAISpaceConfig.model_validate(
|
|
35
|
+
{
|
|
36
|
+
"allowModelSwitching": True,
|
|
37
|
+
"switchableLanguageModels": [
|
|
38
|
+
{
|
|
39
|
+
"displayName": "GPT-4o",
|
|
40
|
+
"languageModel": LanguageModelName.AZURE_GPT_4o_2024_1120,
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
assert config.allow_model_switching is True
|
|
47
|
+
assert len(config.switchable_language_models) == 1
|
|
48
|
+
assert config.switchable_language_models[0].display_name == "GPT-4o"
|
|
49
|
+
assert (
|
|
50
|
+
config.switchable_language_models[0].language_model.name
|
|
51
|
+
== LanguageModelName.AZURE_GPT_4o_2024_1120
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
@pytest.mark.ai
|
|
55
|
+
def test_defaults_absent_switchable_language_models_from_node_backend(self):
|
|
56
|
+
"""Purpose: Verify omitted node-backend model-switching payloads parse.
|
|
57
|
+
Why this matters: Existing spaces can omit the new JSON field before it is configured.
|
|
58
|
+
Setup summary: Validate a payload without switchableLanguageModels and assert it defaults to [].
|
|
59
|
+
"""
|
|
60
|
+
config = UniqueAIConfig.model_validate(
|
|
61
|
+
{
|
|
62
|
+
"space": {
|
|
63
|
+
"allowModelSwitching": False,
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
assert config.space.switchable_language_models == []
|
|
69
|
+
|
|
70
|
+
|
|
32
71
|
class TestUniqueAIServicesStockTickerConfigValidator:
|
|
33
72
|
"""Test suite for UniqueAIServices.check_if_stock_ticker_config_is_none validator"""
|
|
34
73
|
|
|
@@ -68,7 +68,7 @@ from unique_toolkit.app.schemas import ChatEvent, McpServer
|
|
|
68
68
|
from unique_toolkit.chat.service import ChatService
|
|
69
69
|
from unique_toolkit.content import Content
|
|
70
70
|
from unique_toolkit.content.service import ContentService
|
|
71
|
-
from unique_toolkit.language_model.infos import ModelCapabilities
|
|
71
|
+
from unique_toolkit.language_model.infos import LanguageModelInfo, ModelCapabilities
|
|
72
72
|
from unique_toolkit.protocols.support import ResponsesSupportCompleteWithReferences
|
|
73
73
|
|
|
74
74
|
from unique_orchestrator._builders import (
|
|
@@ -83,7 +83,11 @@ from unique_orchestrator._builders.skill_setup import (
|
|
|
83
83
|
configure_skill_tool,
|
|
84
84
|
normalize_available_skills_for_tool,
|
|
85
85
|
)
|
|
86
|
-
from unique_orchestrator.config import
|
|
86
|
+
from unique_orchestrator.config import (
|
|
87
|
+
SwitchableLanguageModelConfig,
|
|
88
|
+
UniqueAIConfig,
|
|
89
|
+
UploadedSearchToolConfig,
|
|
90
|
+
)
|
|
87
91
|
from unique_orchestrator.unique_ai import UniqueAI
|
|
88
92
|
from unique_orchestrator.utils import filter_uploaded_documents_by_selection
|
|
89
93
|
|
|
@@ -126,6 +130,11 @@ async def build_unique_ai(
|
|
|
126
130
|
config: UniqueAIConfig,
|
|
127
131
|
debug_info_manager: DebugInfoManager,
|
|
128
132
|
) -> UniqueAI:
|
|
133
|
+
config = _apply_model_choice_override(event=event, logger=logger, config=config)
|
|
134
|
+
_record_language_model_debug_info(
|
|
135
|
+
debug_info_manager=debug_info_manager,
|
|
136
|
+
config=config,
|
|
137
|
+
)
|
|
129
138
|
common_components = await _build_common(event, logger, config)
|
|
130
139
|
|
|
131
140
|
if (
|
|
@@ -170,6 +179,68 @@ class _CommonComponents(NamedTuple):
|
|
|
170
179
|
mcp_servers: list[McpServer]
|
|
171
180
|
|
|
172
181
|
|
|
182
|
+
def _apply_model_choice_override(
|
|
183
|
+
*,
|
|
184
|
+
event: ChatEvent,
|
|
185
|
+
logger: Logger,
|
|
186
|
+
config: UniqueAIConfig,
|
|
187
|
+
) -> UniqueAIConfig:
|
|
188
|
+
if (
|
|
189
|
+
not config.space.allow_model_switching
|
|
190
|
+
or not event.payload.has_model_choice_override
|
|
191
|
+
):
|
|
192
|
+
return config
|
|
193
|
+
|
|
194
|
+
selected_model = event.payload.model_choice
|
|
195
|
+
if (
|
|
196
|
+
config.space.switchable_language_models
|
|
197
|
+
and not _is_switchable_language_model_choice(
|
|
198
|
+
selected_model=selected_model,
|
|
199
|
+
switchable_language_models=config.space.switchable_language_models,
|
|
200
|
+
)
|
|
201
|
+
):
|
|
202
|
+
raise ValueError(
|
|
203
|
+
f"User model choice {selected_model.display_name!r} is not "
|
|
204
|
+
"allowed for this space."
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
config_data = config.model_dump()
|
|
208
|
+
config_data["space"]["language_model"] = selected_model
|
|
209
|
+
validated_config = UniqueAIConfig.model_validate(config_data)
|
|
210
|
+
|
|
211
|
+
logger.info(
|
|
212
|
+
"Using user model choice %s.",
|
|
213
|
+
selected_model.display_name,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
return validated_config
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def _record_language_model_debug_info(
|
|
220
|
+
*,
|
|
221
|
+
debug_info_manager: DebugInfoManager,
|
|
222
|
+
config: UniqueAIConfig,
|
|
223
|
+
) -> None:
|
|
224
|
+
debug_info_manager.add(
|
|
225
|
+
"language_model",
|
|
226
|
+
config.space.language_model.model_dump(
|
|
227
|
+
mode="json",
|
|
228
|
+
include={"name", "provider", "family"},
|
|
229
|
+
),
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def _is_switchable_language_model_choice(
|
|
234
|
+
*,
|
|
235
|
+
selected_model: LanguageModelInfo,
|
|
236
|
+
switchable_language_models: list[SwitchableLanguageModelConfig],
|
|
237
|
+
) -> bool:
|
|
238
|
+
return any(
|
|
239
|
+
selected_model == switchable_model.language_model
|
|
240
|
+
for switchable_model in switchable_language_models
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
|
|
173
244
|
async def _build_common(
|
|
174
245
|
event: ChatEvent,
|
|
175
246
|
logger: Logger,
|
|
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
|