unique_toolkit 2026.34.0.dev6__py3-none-any.whl → 2026.34.0.dev8__py3-none-any.whl
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_toolkit/agentic/feature_flags/__init__.py +2 -1
- unique_toolkit/agentic/feature_flags/feature_flags.py +36 -1
- unique_toolkit/agentic/history_manager/loop_token_reducer.py +16 -3
- unique_toolkit/agentic/history_manager/utils.py +6 -4
- unique_toolkit/agentic/tools/a2a/tool/service.py +5 -6
- unique_toolkit/agentic/tools/mcp/tool_wrapper.py +11 -16
- unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py +11 -7
- unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py +28 -23
- unique_toolkit/experimental/resources/feature_flags/__init__.py +10 -3
- unique_toolkit/experimental/resources/feature_flags/client.py +14 -14
- unique_toolkit/monitoring/__init__.py +4 -0
- unique_toolkit/monitoring/tracing.py +69 -1
- unique_toolkit/services/chat_service.py +5 -3
- {unique_toolkit-2026.34.0.dev6.dist-info → unique_toolkit-2026.34.0.dev8.dist-info}/METADATA +3 -1
- {unique_toolkit-2026.34.0.dev6.dist-info → unique_toolkit-2026.34.0.dev8.dist-info}/RECORD +16 -16
- {unique_toolkit-2026.34.0.dev6.dist-info → unique_toolkit-2026.34.0.dev8.dist-info}/WHEEL +0 -0
|
@@ -1,11 +1,41 @@
|
|
|
1
|
+
from enum import StrEnum
|
|
1
2
|
from typing import Any
|
|
2
3
|
|
|
3
4
|
from pydantic import Field, field_validator
|
|
4
5
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
6
|
+
from typing_extensions import deprecated
|
|
5
7
|
|
|
6
8
|
from unique_toolkit._common.config_checker import register_config
|
|
7
9
|
|
|
8
10
|
|
|
11
|
+
class FeatureFlagNames(StrEnum):
|
|
12
|
+
"""Flag name constants used by unique_toolkit's own agentic features.
|
|
13
|
+
|
|
14
|
+
Values match both the env-var fallback names (``FeatureFlags`` below) and
|
|
15
|
+
the configuration-backend registry keys used by
|
|
16
|
+
``unique_toolkit.experimental.resources.feature_flags.FeatureFlagClient``.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
enable_selected_uploaded_files_un_18215 = (
|
|
20
|
+
"FEATURE_FLAG_ENABLE_SELECTED_UPLOADED_FILES_UN_18215"
|
|
21
|
+
)
|
|
22
|
+
enable_mcp_metadata_fallback_un_19145 = (
|
|
23
|
+
"FEATURE_FLAG_ENABLE_MCP_METADATA_FALLBACK_UN_19145"
|
|
24
|
+
)
|
|
25
|
+
enable_html_rendering_un_15131 = "FEATURE_FLAG_ENABLE_HTML_RENDERING_UN_15131"
|
|
26
|
+
enable_code_execution_fence_un_17972 = (
|
|
27
|
+
"FEATURE_FLAG_ENABLE_CODE_EXECUTION_FENCE_UN_17972"
|
|
28
|
+
)
|
|
29
|
+
enable_html_with_fence_un_17927 = "FEATURE_FLAG_ENABLE_HTML_WITH_FENCE_UN_17927"
|
|
30
|
+
enable_web_search_argument_screening_un_18741 = (
|
|
31
|
+
"FEATURE_FLAG_ENABLE_WEB_SEARCH_ARGUMENT_SCREENING_UN_18741"
|
|
32
|
+
)
|
|
33
|
+
enable_new_answers_ui_un_14411 = "FEATURE_FLAG_ENABLE_NEW_ANSWERS_UI_UN_14411"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@deprecated(
|
|
37
|
+
"Use unique_toolkit.experimental.resources.feature_flags.is_flag_enabled instead"
|
|
38
|
+
)
|
|
9
39
|
class FeatureFlag:
|
|
10
40
|
"""A feature flag that can be enabled globally or for specific company IDs.
|
|
11
41
|
|
|
@@ -45,6 +75,9 @@ class FeatureFlag:
|
|
|
45
75
|
return f"FeatureFlag({self.value})"
|
|
46
76
|
|
|
47
77
|
|
|
78
|
+
@deprecated(
|
|
79
|
+
"Use unique_toolkit.experimental.resources.feature_flags.is_flag_enabled instead"
|
|
80
|
+
)
|
|
48
81
|
@register_config()
|
|
49
82
|
class FeatureFlags(BaseSettings):
|
|
50
83
|
"""Feature flags loaded from environment variables.
|
|
@@ -145,5 +178,7 @@ class FeatureFlags(BaseSettings):
|
|
|
145
178
|
return FeatureFlag(False)
|
|
146
179
|
|
|
147
180
|
|
|
148
|
-
#
|
|
181
|
+
# Deprecated, unused elsewhere in this toolkit — kept only for external
|
|
182
|
+
# backward compatibility. Use unique_toolkit.experimental.resources.feature_flags
|
|
183
|
+
# .is_flag_enabled instead.
|
|
149
184
|
feature_flags = FeatureFlags()
|
|
@@ -109,7 +109,19 @@ class LoopTokenReducer:
|
|
|
109
109
|
self._max_db_source_number: int = -1
|
|
110
110
|
self._db_source_map: dict[int, ContentChunk] = {}
|
|
111
111
|
self._enable_tool_call_persistence = enable_tool_call_persistence
|
|
112
|
-
self.
|
|
112
|
+
self._event = event
|
|
113
|
+
# Lazily resolved on first async use since the flag check is async;
|
|
114
|
+
# `_resolved` distinguishes "not yet checked" from a resolved `None` (flag off).
|
|
115
|
+
self._selected_content_ids: set[str] | None = None
|
|
116
|
+
self._selected_content_ids_resolved = False
|
|
117
|
+
|
|
118
|
+
async def _get_selected_content_ids(self) -> set[str] | None:
|
|
119
|
+
if not self._selected_content_ids_resolved:
|
|
120
|
+
self._selected_content_ids = await get_selected_uploaded_content_ids(
|
|
121
|
+
self._event
|
|
122
|
+
)
|
|
123
|
+
self._selected_content_ids_resolved = True
|
|
124
|
+
return self._selected_content_ids
|
|
113
125
|
|
|
114
126
|
@property
|
|
115
127
|
def max_db_source_number(self) -> int:
|
|
@@ -354,6 +366,7 @@ class LoopTokenReducer:
|
|
|
354
366
|
Returns:
|
|
355
367
|
list[LanguageModelMessage]: The history
|
|
356
368
|
"""
|
|
369
|
+
selected_content_ids = await self._get_selected_content_ids()
|
|
357
370
|
if self._enable_tool_call_persistence:
|
|
358
371
|
(
|
|
359
372
|
full_history,
|
|
@@ -365,7 +378,7 @@ class LoopTokenReducer:
|
|
|
365
378
|
chat_service=self._chat_service,
|
|
366
379
|
content_service=self._content_service,
|
|
367
380
|
file_content_serializer=self._file_content_serializer,
|
|
368
|
-
selected_content_ids=
|
|
381
|
+
selected_content_ids=selected_content_ids,
|
|
369
382
|
)
|
|
370
383
|
self._max_db_source_number = max_src
|
|
371
384
|
self._db_source_map = src_map
|
|
@@ -376,7 +389,7 @@ class LoopTokenReducer:
|
|
|
376
389
|
chat_service=self._chat_service,
|
|
377
390
|
content_service=self._content_service,
|
|
378
391
|
file_content_serializer=self._file_content_serializer,
|
|
379
|
-
selected_content_ids=
|
|
392
|
+
selected_content_ids=selected_content_ids,
|
|
380
393
|
)
|
|
381
394
|
|
|
382
395
|
if remove_from_text is not None:
|
|
@@ -3,10 +3,11 @@ import logging
|
|
|
3
3
|
from copy import deepcopy
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
6
|
-
from unique_toolkit.agentic.feature_flags import
|
|
6
|
+
from unique_toolkit.agentic.feature_flags import FeatureFlagNames
|
|
7
7
|
from unique_toolkit.agentic.tools.schemas import Source
|
|
8
8
|
from unique_toolkit.app.schemas import ChatEvent
|
|
9
9
|
from unique_toolkit.content.schemas import ContentChunk
|
|
10
|
+
from unique_toolkit.experimental.resources.feature_flags import is_flag_enabled
|
|
10
11
|
from unique_toolkit.language_model.schemas import (
|
|
11
12
|
LanguageModelAssistantMessage,
|
|
12
13
|
LanguageModelMessage,
|
|
@@ -16,15 +17,16 @@ from unique_toolkit.language_model.schemas import (
|
|
|
16
17
|
logger = logging.getLogger(__name__)
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
def get_selected_uploaded_content_ids(event: ChatEvent) -> set[str] | None:
|
|
20
|
+
async def get_selected_uploaded_content_ids(event: ChatEvent) -> set[str] | None:
|
|
20
21
|
"""Derive the set of content IDs the user explicitly selected.
|
|
21
22
|
|
|
22
23
|
Returns ``None`` when the feature flag is disabled (meaning *all*
|
|
23
24
|
uploaded images should be included), or a ``set[str]`` of IDs when
|
|
24
25
|
only a subset should be attached.
|
|
25
26
|
"""
|
|
26
|
-
if not
|
|
27
|
-
|
|
27
|
+
if not await is_flag_enabled(
|
|
28
|
+
FeatureFlagNames.enable_selected_uploaded_files_un_18215,
|
|
29
|
+
company_id=event.company_id,
|
|
28
30
|
):
|
|
29
31
|
return None
|
|
30
32
|
|
|
@@ -22,7 +22,7 @@ from unique_toolkit._common.referencing import (
|
|
|
22
22
|
)
|
|
23
23
|
from unique_toolkit._common.utils.jinja.render import render_template
|
|
24
24
|
from unique_toolkit.agentic.evaluation.schemas import EvaluationMetricName
|
|
25
|
-
from unique_toolkit.agentic.feature_flags import
|
|
25
|
+
from unique_toolkit.agentic.feature_flags import FeatureFlagNames
|
|
26
26
|
from unique_toolkit.agentic.tools.a2a.response_watcher import SubAgentResponseWatcher
|
|
27
27
|
from unique_toolkit.agentic.tools.a2a.tool._memory import (
|
|
28
28
|
get_sub_agent_short_term_memory_manager,
|
|
@@ -53,6 +53,7 @@ from unique_toolkit.chat.schemas import (
|
|
|
53
53
|
)
|
|
54
54
|
from unique_toolkit.chat.service import ChatService
|
|
55
55
|
from unique_toolkit.content import ContentChunk, ContentReference
|
|
56
|
+
from unique_toolkit.experimental.resources.feature_flags import is_flag_enabled
|
|
56
57
|
from unique_toolkit.language_model import (
|
|
57
58
|
LanguageModelFunction,
|
|
58
59
|
LanguageModelService,
|
|
@@ -431,11 +432,9 @@ class SubAgentTool(Tool[SubAgentToolConfig]):
|
|
|
431
432
|
message: str,
|
|
432
433
|
state: ProgressState,
|
|
433
434
|
) -> None:
|
|
434
|
-
if (
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
self._company_id
|
|
438
|
-
)
|
|
435
|
+
if self._tool_progress_reporter is not None and not await is_flag_enabled(
|
|
436
|
+
FeatureFlagNames.enable_new_answers_ui_un_14411,
|
|
437
|
+
company_id=self._company_id or "",
|
|
439
438
|
):
|
|
440
439
|
await self._tool_progress_reporter.notify_from_tool_call(
|
|
441
440
|
tool_call=tool_call,
|
|
@@ -9,7 +9,7 @@ from typing import Any, Dict
|
|
|
9
9
|
import unique_sdk
|
|
10
10
|
|
|
11
11
|
from unique_toolkit.agentic.evaluation.schemas import EvaluationMetricName
|
|
12
|
-
from unique_toolkit.agentic.feature_flags import
|
|
12
|
+
from unique_toolkit.agentic.feature_flags import FeatureFlagNames
|
|
13
13
|
from unique_toolkit.agentic.tools.mcp.models import MCPToolConfig
|
|
14
14
|
from unique_toolkit.agentic.tools.schemas import ToolCallResponse
|
|
15
15
|
from unique_toolkit.agentic.tools.tool import Tool
|
|
@@ -21,6 +21,7 @@ from unique_toolkit.app.schemas import ChatEvent, McpServer, McpTool
|
|
|
21
21
|
from unique_toolkit.chat.schemas import MessageLog, MessageLogStatus
|
|
22
22
|
from unique_toolkit.chat.service import ChatService
|
|
23
23
|
from unique_toolkit.content.functions import upload_content_from_bytes
|
|
24
|
+
from unique_toolkit.experimental.resources.feature_flags import is_flag_enabled
|
|
24
25
|
from unique_toolkit.language_model import LanguageModelService
|
|
25
26
|
from unique_toolkit.language_model.schemas import (
|
|
26
27
|
LanguageModelFunction,
|
|
@@ -133,11 +134,9 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
133
134
|
)
|
|
134
135
|
|
|
135
136
|
# Notify progress if reporter is available
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
self._event.company_id
|
|
140
|
-
)
|
|
137
|
+
if self._tool_progress_reporter and not await is_flag_enabled(
|
|
138
|
+
FeatureFlagNames.enable_new_answers_ui_un_14411,
|
|
139
|
+
company_id=self._event.company_id,
|
|
141
140
|
):
|
|
142
141
|
await self._tool_progress_reporter.notify_from_tool_call(
|
|
143
142
|
tool_call=tool_call,
|
|
@@ -172,11 +171,9 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
172
171
|
)
|
|
173
172
|
|
|
174
173
|
# Notify completion
|
|
175
|
-
if (
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
self._event.company_id
|
|
179
|
-
)
|
|
174
|
+
if self._tool_progress_reporter and not await is_flag_enabled(
|
|
175
|
+
FeatureFlagNames.enable_new_answers_ui_un_14411,
|
|
176
|
+
company_id=self._event.company_id,
|
|
180
177
|
):
|
|
181
178
|
await self._tool_progress_reporter.notify_from_tool_call(
|
|
182
179
|
tool_call=tool_call,
|
|
@@ -198,11 +195,9 @@ class MCPToolWrapper(Tool[MCPToolConfig]):
|
|
|
198
195
|
self.logger.error(f"Error executing MCP tool {self.name}: {e}")
|
|
199
196
|
|
|
200
197
|
# Notify failure
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
self._event.company_id
|
|
205
|
-
)
|
|
198
|
+
if self._tool_progress_reporter and not await is_flag_enabled(
|
|
199
|
+
FeatureFlagNames.enable_new_answers_ui_un_14411,
|
|
200
|
+
company_id=self._event.company_id,
|
|
206
201
|
):
|
|
207
202
|
await self._tool_progress_reporter.notify_from_tool_call(
|
|
208
203
|
tool_call=tool_call,
|
|
@@ -6,11 +6,15 @@ from typing import override
|
|
|
6
6
|
from pydantic import BaseModel, Field
|
|
7
7
|
from pydantic.json_schema import SkipJsonSchema
|
|
8
8
|
|
|
9
|
-
from unique_toolkit.agentic.feature_flags
|
|
9
|
+
from unique_toolkit.agentic.feature_flags import FeatureFlagNames
|
|
10
10
|
from unique_toolkit.agentic.postprocessor.postprocessor_manager import (
|
|
11
11
|
ResponsesApiPostprocessor,
|
|
12
12
|
)
|
|
13
13
|
from unique_toolkit.agentic.tools.config import get_configuration_dict
|
|
14
|
+
from unique_toolkit.experimental.resources.feature_flags import (
|
|
15
|
+
COMPANY_ID_PLACEHOLDER,
|
|
16
|
+
is_flag_enabled,
|
|
17
|
+
)
|
|
14
18
|
from unique_toolkit.language_model.schemas import ResponsesLanguageModelStreamResponse
|
|
15
19
|
|
|
16
20
|
_TEMPLATE = """
|
|
@@ -56,15 +60,15 @@ class ShowExecutedCodePostprocessor(ResponsesApiPostprocessor):
|
|
|
56
60
|
super().__init__(self.__class__.__name__)
|
|
57
61
|
self._config = config
|
|
58
62
|
self._company_id = company_id
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
and not feature_flags.enable_code_execution_fence_un_17972.is_enabled(
|
|
62
|
-
company_id
|
|
63
|
-
)
|
|
64
|
-
)
|
|
63
|
+
# Resolved in run() (before apply_postprocessing_to_response) since flag evaluation is async.
|
|
64
|
+
self._is_enabled = False
|
|
65
65
|
|
|
66
66
|
@override
|
|
67
67
|
async def run(self, loop_response: ResponsesLanguageModelStreamResponse) -> None:
|
|
68
|
+
self._is_enabled = self._config.enable and not await is_flag_enabled(
|
|
69
|
+
FeatureFlagNames.enable_code_execution_fence_un_17972,
|
|
70
|
+
company_id=self._company_id or COMPANY_ID_PLACEHOLDER,
|
|
71
|
+
)
|
|
68
72
|
if self._is_enabled:
|
|
69
73
|
await asyncio.sleep(self._config.sleep_time_before_display)
|
|
70
74
|
|
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py
CHANGED
|
@@ -21,7 +21,7 @@ from tenacity import (
|
|
|
21
21
|
|
|
22
22
|
from unique_toolkit import ChatService
|
|
23
23
|
from unique_toolkit._common.execution import failsafe_async
|
|
24
|
-
from unique_toolkit.agentic.feature_flags
|
|
24
|
+
from unique_toolkit.agentic.feature_flags import FeatureFlagNames
|
|
25
25
|
from unique_toolkit.agentic.postprocessor.postprocessor_manager import (
|
|
26
26
|
ResponsesApiPostprocessor,
|
|
27
27
|
)
|
|
@@ -39,6 +39,10 @@ from unique_toolkit.agentic.tools.openai_builtin.code_interpreter.schemas import
|
|
|
39
39
|
)
|
|
40
40
|
from unique_toolkit.content.schemas import ContentReference
|
|
41
41
|
from unique_toolkit.content.service import ContentService
|
|
42
|
+
from unique_toolkit.experimental.resources.feature_flags import (
|
|
43
|
+
COMPANY_ID_PLACEHOLDER,
|
|
44
|
+
is_flag_enabled,
|
|
45
|
+
)
|
|
42
46
|
from unique_toolkit.language_model.schemas import ResponsesLanguageModelStreamResponse
|
|
43
47
|
from unique_toolkit.services.knowledge_base import KnowledgeBaseService
|
|
44
48
|
from unique_toolkit.short_term_memory.service import ShortTermMemoryService
|
|
@@ -389,6 +393,10 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
389
393
|
# Cleared at the start of each run(); holds this-turn download sizes.
|
|
390
394
|
self._file_size_map: dict[str, int] = {}
|
|
391
395
|
|
|
396
|
+
# Resolved in run() (before apply_postprocessing_to_response) since flag evaluation is async.
|
|
397
|
+
self._fence_ff_on = False
|
|
398
|
+
self._html_fence_ff_on = False
|
|
399
|
+
|
|
392
400
|
def _build_retry(self) -> AsyncRetrying:
|
|
393
401
|
"""Build a tenacity retry policy from the current config.
|
|
394
402
|
|
|
@@ -409,6 +417,17 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
409
417
|
run_t0 = time.monotonic()
|
|
410
418
|
self._log.info("run() started — fetching and uploading code interpreter files")
|
|
411
419
|
|
|
420
|
+
self._fence_ff_on = await is_flag_enabled(
|
|
421
|
+
FeatureFlagNames.enable_code_execution_fence_un_17972,
|
|
422
|
+
company_id=self._company_id or COMPANY_ID_PLACEHOLDER,
|
|
423
|
+
)
|
|
424
|
+
# htmlWithSource requires BOTH the fence FF and the HTML-fence FF on; default
|
|
425
|
+
# (FF off) keeps HtmlRendering, so existing deployments are unaffected.
|
|
426
|
+
self._html_fence_ff_on = await is_flag_enabled(
|
|
427
|
+
FeatureFlagNames.enable_html_with_fence_un_17927,
|
|
428
|
+
company_id=self._company_id or COMPANY_ID_PLACEHOLDER,
|
|
429
|
+
)
|
|
430
|
+
|
|
412
431
|
container_files = loop_response.container_files
|
|
413
432
|
self._log.info(
|
|
414
433
|
"run() found %d container file annotation(s): %s",
|
|
@@ -554,9 +573,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
554
573
|
self._log.info(
|
|
555
574
|
"apply_postprocessing started — %d file(s) in content_map, fence_ff=%s",
|
|
556
575
|
len(self._content_map),
|
|
557
|
-
|
|
558
|
-
self._company_id
|
|
559
|
-
),
|
|
576
|
+
self._fence_ff_on,
|
|
560
577
|
)
|
|
561
578
|
|
|
562
579
|
if loop_response.message.references is None:
|
|
@@ -566,18 +583,6 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
566
583
|
|
|
567
584
|
ref_number = _get_next_ref_number(loop_response.message.references)
|
|
568
585
|
changed = False
|
|
569
|
-
fence_ff_on = feature_flags.enable_code_execution_fence_un_17972.is_enabled(
|
|
570
|
-
self._company_id
|
|
571
|
-
)
|
|
572
|
-
# HTML uses htmlWithSource only when BOTH the code-execution fence FF AND the
|
|
573
|
-
# dedicated HTML-fence FF are on. Default (FF off) keeps HtmlRendering so
|
|
574
|
-
# existing deployments are unaffected.
|
|
575
|
-
html_fence_ff_on = (
|
|
576
|
-
fence_ff_on
|
|
577
|
-
and feature_flags.enable_html_with_fence_un_17927.is_enabled(
|
|
578
|
-
self._company_id
|
|
579
|
-
)
|
|
580
|
-
)
|
|
581
586
|
|
|
582
587
|
replaced_files: list[str] = []
|
|
583
588
|
missed_files: list[str] = []
|
|
@@ -611,7 +616,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
611
616
|
|
|
612
617
|
# HTML rendered as HtmlRendering block unless the dedicated html-fence FF
|
|
613
618
|
# is on (enable_html_with_fence_un_17927). Default keeps HtmlRendering.
|
|
614
|
-
elif is_html and not
|
|
619
|
+
elif is_html and not self._html_fence_ff_on:
|
|
615
620
|
loop_response.message.text, replaced = _replace_container_html_citation(
|
|
616
621
|
text=loop_response.message.text or "",
|
|
617
622
|
filename=filename,
|
|
@@ -619,7 +624,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
619
624
|
)
|
|
620
625
|
changed |= replaced
|
|
621
626
|
|
|
622
|
-
# Non-HTML files, or HTML when
|
|
627
|
+
# Non-HTML files, or HTML when self._html_fence_ff_on → inline content link for
|
|
623
628
|
# subsequent fence injection (htmlWithSource / imgWithSource / fileWithSource)
|
|
624
629
|
else:
|
|
625
630
|
loop_response.message.text, replaced = _replace_container_file_citation(
|
|
@@ -627,7 +632,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
627
632
|
filename=filename,
|
|
628
633
|
content_id=content_id,
|
|
629
634
|
ref_number=ref_number,
|
|
630
|
-
use_content_link=
|
|
635
|
+
use_content_link=self._fence_ff_on,
|
|
631
636
|
)
|
|
632
637
|
changed |= replaced
|
|
633
638
|
|
|
@@ -644,7 +649,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
644
649
|
|
|
645
650
|
# HtmlRendering and htmlWithSource both embed contentId directly — no ContentReference needed
|
|
646
651
|
is_html_rendered = is_html
|
|
647
|
-
if replaced and not (is_image or is_html_rendered or
|
|
652
|
+
if replaced and not (is_image or is_html_rendered or self._fence_ff_on):
|
|
648
653
|
loop_response.message.references.append(
|
|
649
654
|
ContentReference(
|
|
650
655
|
sequence_number=ref_number,
|
|
@@ -663,9 +668,9 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
663
668
|
error_files,
|
|
664
669
|
)
|
|
665
670
|
|
|
666
|
-
if
|
|
671
|
+
if self._fence_ff_on:
|
|
667
672
|
code_blocks = _build_code_blocks(
|
|
668
|
-
loop_response, self._content_map, include_html=
|
|
673
|
+
loop_response, self._content_map, include_html=self._html_fence_ff_on
|
|
669
674
|
)
|
|
670
675
|
self._log.info(
|
|
671
676
|
"Fence injection — %d code block(s), files: %s",
|
|
@@ -673,7 +678,7 @@ class DisplayCodeInterpreterFilesPostProcessor(
|
|
|
673
678
|
[f.filename for b in code_blocks for f in b.files],
|
|
674
679
|
)
|
|
675
680
|
_warn_unmatched_code_blocks(
|
|
676
|
-
self._content_map, code_blocks, include_html=
|
|
681
|
+
self._content_map, code_blocks, include_html=self._html_fence_ff_on
|
|
677
682
|
)
|
|
678
683
|
text_before = loop_response.message.text
|
|
679
684
|
loop_response.message.text = _inject_code_execution_fences(
|
|
@@ -12,10 +12,15 @@ Required env vars::
|
|
|
12
12
|
|
|
13
13
|
Quick start — explicit IDs::
|
|
14
14
|
|
|
15
|
-
from unique_toolkit.experimental.resources.feature_flags import FeatureFlagClient
|
|
15
|
+
from unique_toolkit.experimental.resources.feature_flags import FeatureFlagClient, is_flag_enabled
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
# Requires CONFIGURATION_BACKEND_URL / FEATURE_FLAG_SERVICE_ID to be set;
|
|
18
|
+
# falls back to the env-var value (or stale cache) on transport errors.
|
|
19
|
+
enabled = await is_flag_enabled("FEATURE_FLAG_ENABLE_X", company_id=company_id)
|
|
20
|
+
|
|
21
|
+
# Or manage the singleton directly:
|
|
22
|
+
client = FeatureFlagClient.from_settings() # raises if URL/service_id absent
|
|
23
|
+
client = get_feature_flag_client() # same — thin passthrough to from_settings()
|
|
19
24
|
|
|
20
25
|
Per-request binding (when you have UniqueSettings / AuthContext)::
|
|
21
26
|
|
|
@@ -32,6 +37,7 @@ See README.md for the full evaluation-order diagram and adoption steps.
|
|
|
32
37
|
"""
|
|
33
38
|
|
|
34
39
|
from .client import (
|
|
40
|
+
COMPANY_ID_PLACEHOLDER,
|
|
35
41
|
BoundFeatureFlagClient,
|
|
36
42
|
FeatureFlagClient,
|
|
37
43
|
get_feature_flag_client,
|
|
@@ -41,6 +47,7 @@ from .schemas import FlagEvaluation
|
|
|
41
47
|
from .settings import FeatureFlagSettings
|
|
42
48
|
|
|
43
49
|
__all__ = [
|
|
50
|
+
"COMPANY_ID_PLACEHOLDER",
|
|
44
51
|
"BoundFeatureFlagClient",
|
|
45
52
|
"FeatureFlagClient",
|
|
46
53
|
"FlagEvaluation",
|
|
@@ -177,21 +177,15 @@ class FeatureFlagClient:
|
|
|
177
177
|
|
|
178
178
|
@staticmethod
|
|
179
179
|
def _env_fallback(flag: str, company_id: str | None = None) -> bool:
|
|
180
|
-
"""Read *flag* from env vars
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
comma-separated company-ID allowlists (``"company1,company2"``),
|
|
184
|
-
consistent with ``unique_toolkit.agentic.feature_flags.FeatureFlags``.
|
|
185
|
-
"""
|
|
186
|
-
raw = os.getenv(flag, "false").strip()
|
|
187
|
-
raw_lower = raw.lower()
|
|
180
|
+
"""Read *flag* from env vars: plain booleans or comma-separated company-ID allowlists."""
|
|
181
|
+
raw = os.getenv(flag, "false")
|
|
182
|
+
raw_lower = raw.strip().lower()
|
|
188
183
|
if raw_lower in ("true", "1", "yes"):
|
|
189
184
|
return True
|
|
190
185
|
if raw_lower in ("false", "0", "no", ""):
|
|
191
186
|
return False
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return company_id in allowed if company_id else False
|
|
187
|
+
allowlist = [c.strip() for c in raw.split(",") if c.strip()]
|
|
188
|
+
return company_id in allowlist if company_id else False
|
|
195
189
|
|
|
196
190
|
|
|
197
191
|
class BoundFeatureFlagClient:
|
|
@@ -215,12 +209,18 @@ class BoundFeatureFlagClient:
|
|
|
215
209
|
return (await self.evaluate(flag)).value
|
|
216
210
|
|
|
217
211
|
|
|
212
|
+
# For is_flag_enabled() callers with no real company_id. Not a real company:
|
|
213
|
+
# bool-configured flags still resolve correctly; allowlist-configured ones safely read as off.
|
|
214
|
+
COMPANY_ID_PLACEHOLDER = "company_id_placeholder"
|
|
215
|
+
|
|
216
|
+
|
|
218
217
|
def get_feature_flag_client() -> FeatureFlagClient:
|
|
219
218
|
"""Return the process-level :class:`FeatureFlagClient` singleton.
|
|
220
219
|
|
|
221
|
-
Built lazily via :meth:`FeatureFlagClient.from_settings
|
|
222
|
-
``CONFIGURATION_BACKEND_URL`` and ``FEATURE_FLAG_SERVICE_ID`` from env
|
|
223
|
-
|
|
220
|
+
Built lazily via :meth:`FeatureFlagClient.from_settings`, which reads
|
|
221
|
+
``CONFIGURATION_BACKEND_URL`` and ``FEATURE_FLAG_SERVICE_ID`` from env and
|
|
222
|
+
raises :class:`ValueError` if either is missing. Evaluations fall back to
|
|
223
|
+
env-var defaults (or a stale cached value) only on *transport* errors.
|
|
224
224
|
"""
|
|
225
225
|
return FeatureFlagClient.from_settings()
|
|
226
226
|
|
|
@@ -4,6 +4,8 @@ from unique_toolkit.monitoring.tracing import (
|
|
|
4
4
|
TracingSettings,
|
|
5
5
|
configure_tracing,
|
|
6
6
|
inject_trace_headers,
|
|
7
|
+
instrument_fastapi_app,
|
|
8
|
+
instrument_requests,
|
|
7
9
|
)
|
|
8
10
|
|
|
9
11
|
__all__ = [
|
|
@@ -12,6 +14,8 @@ __all__ = [
|
|
|
12
14
|
"TracingSettings",
|
|
13
15
|
"configure_tracing",
|
|
14
16
|
"inject_trace_headers",
|
|
17
|
+
"instrument_fastapi_app",
|
|
18
|
+
"instrument_requests",
|
|
15
19
|
]
|
|
16
20
|
|
|
17
21
|
_MONITORING_AVAILABLE = False
|
|
@@ -9,7 +9,10 @@ from typing import TYPE_CHECKING, ClassVar, Self, TypeAlias, cast
|
|
|
9
9
|
from pydantic import AliasChoices, Field
|
|
10
10
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
11
11
|
|
|
12
|
+
from unique_toolkit.app.find_env_file import find_env_file
|
|
13
|
+
|
|
12
14
|
if TYPE_CHECKING:
|
|
15
|
+
from fastapi import FastAPI # pyright: ignore[reportMissingImports]
|
|
13
16
|
from opentelemetry.trace.propagation.tracecontext import (
|
|
14
17
|
TraceContextTextMapPropagator,
|
|
15
18
|
)
|
|
@@ -25,6 +28,10 @@ _OTEL_EXTRA_MESSAGE = (
|
|
|
25
28
|
"OpenTelemetry tracing requires the unique_toolkit[otel] extra. "
|
|
26
29
|
"Install it with: uv add 'unique-toolkit[otel]'"
|
|
27
30
|
)
|
|
31
|
+
_FASTAPI_EXTRA_MESSAGE = (
|
|
32
|
+
"FastAPI instrumentation requires the unique_toolkit[fastapi] extra. "
|
|
33
|
+
"Install it with: uv add 'unique-toolkit[fastapi]'"
|
|
34
|
+
)
|
|
28
35
|
|
|
29
36
|
|
|
30
37
|
class TraceExporter(StrEnum):
|
|
@@ -42,6 +49,8 @@ class TracingSettings(BaseSettings):
|
|
|
42
49
|
env_prefix="OTEL_",
|
|
43
50
|
env_ignore_empty=True,
|
|
44
51
|
extra="ignore",
|
|
52
|
+
env_file=find_env_file(".env", required=False),
|
|
53
|
+
env_file_encoding="utf-8",
|
|
45
54
|
)
|
|
46
55
|
|
|
47
56
|
traces_exporter: TraceExporter | None = None
|
|
@@ -90,6 +99,11 @@ def _missing_otel_extra() -> ImportError:
|
|
|
90
99
|
return ImportError(_OTEL_EXTRA_MESSAGE)
|
|
91
100
|
|
|
92
101
|
|
|
102
|
+
def _missing_fastapi_extra() -> ImportError:
|
|
103
|
+
"""Create a consistent error for an unavailable optional FastAPI dependency."""
|
|
104
|
+
return ImportError(_FASTAPI_EXTRA_MESSAGE)
|
|
105
|
+
|
|
106
|
+
|
|
93
107
|
def _trace_context_propagator() -> TraceContextTextMapPropagator:
|
|
94
108
|
"""Return a W3C trace-context propagator without forwarding baggage."""
|
|
95
109
|
try:
|
|
@@ -165,9 +179,12 @@ def configure_tracing(
|
|
|
165
179
|
|
|
166
180
|
try:
|
|
167
181
|
from opentelemetry import trace
|
|
182
|
+
from opentelemetry.baggage.propagation import W3CBaggagePropagator
|
|
168
183
|
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
|
|
169
184
|
OTLPSpanExporter,
|
|
170
185
|
)
|
|
186
|
+
from opentelemetry.propagate import set_global_textmap
|
|
187
|
+
from opentelemetry.propagators.composite import CompositePropagator
|
|
171
188
|
from opentelemetry.sdk.resources import Resource
|
|
172
189
|
from opentelemetry.sdk.trace import TracerProvider
|
|
173
190
|
from opentelemetry.sdk.trace.export import (
|
|
@@ -176,6 +193,9 @@ def configure_tracing(
|
|
|
176
193
|
SimpleSpanProcessor,
|
|
177
194
|
)
|
|
178
195
|
from opentelemetry.trace import ProxyTracerProvider
|
|
196
|
+
from opentelemetry.trace.propagation.tracecontext import (
|
|
197
|
+
TraceContextTextMapPropagator,
|
|
198
|
+
)
|
|
179
199
|
except ImportError as error:
|
|
180
200
|
raise _missing_otel_extra() from error
|
|
181
201
|
|
|
@@ -196,6 +216,54 @@ def configure_tracing(
|
|
|
196
216
|
if exporter is TraceExporter.CONSOLE:
|
|
197
217
|
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
|
|
198
218
|
else:
|
|
199
|
-
|
|
219
|
+
# Sizing pinned to match the Node services' instrumentation.ts.
|
|
220
|
+
provider.add_span_processor(
|
|
221
|
+
BatchSpanProcessor(
|
|
222
|
+
OTLPSpanExporter(),
|
|
223
|
+
max_queue_size=2048,
|
|
224
|
+
max_export_batch_size=512,
|
|
225
|
+
schedule_delay_millis=5000,
|
|
226
|
+
)
|
|
227
|
+
)
|
|
200
228
|
trace.set_tracer_provider(provider)
|
|
229
|
+
# Trace-context + baggage, the shared subset of the Node services' propagator.
|
|
230
|
+
set_global_textmap(
|
|
231
|
+
CompositePropagator([TraceContextTextMapPropagator(), W3CBaggagePropagator()])
|
|
232
|
+
)
|
|
201
233
|
return True
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def instrument_fastapi_app(app: FastAPI, *, excluded_urls: str | None = None) -> None:
|
|
237
|
+
"""Trace inbound requests for an already-created FastAPI app instance.
|
|
238
|
+
|
|
239
|
+
Uses ``FastAPIInstrumentor.instrument_app`` rather than the global
|
|
240
|
+
``FastAPIInstrumentor().instrument()``: the global form swaps out the
|
|
241
|
+
``fastapi.FastAPI`` class, so it only takes effect for app objects created
|
|
242
|
+
afterward. Instrumenting the instance has no such ordering requirement.
|
|
243
|
+
"""
|
|
244
|
+
try:
|
|
245
|
+
import fastapi # noqa: F401 # pyright: ignore[reportMissingImports, reportUnusedImport]
|
|
246
|
+
except ImportError as error:
|
|
247
|
+
# opentelemetry-instrumentation-fastapi imports fastapi internally, so without
|
|
248
|
+
# this explicit check its own ImportError would be misreported below as a
|
|
249
|
+
# missing otel extra when fastapi itself is what's actually missing.
|
|
250
|
+
raise _missing_fastapi_extra() from error
|
|
251
|
+
|
|
252
|
+
try:
|
|
253
|
+
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
|
|
254
|
+
except ImportError as error:
|
|
255
|
+
raise _missing_otel_extra() from error
|
|
256
|
+
FastAPIInstrumentor.instrument_app(app, excluded_urls=excluded_urls)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def instrument_requests() -> None:
|
|
260
|
+
"""Trace outbound calls made with the ``requests`` library.
|
|
261
|
+
|
|
262
|
+
Patches ``requests`` at module level, so callers that already imported it
|
|
263
|
+
are still covered.
|
|
264
|
+
"""
|
|
265
|
+
try:
|
|
266
|
+
from opentelemetry.instrumentation.requests import RequestsInstrumentor
|
|
267
|
+
except ImportError as error:
|
|
268
|
+
raise _missing_otel_extra() from error
|
|
269
|
+
RequestsInstrumentor().instrument()
|
|
@@ -22,7 +22,7 @@ from unique_toolkit._common.metadata_filter_scope import (
|
|
|
22
22
|
merge_scope_clause_into_metadata_filter,
|
|
23
23
|
)
|
|
24
24
|
from unique_toolkit._common.utils.files import is_file_content, is_image_content
|
|
25
|
-
from unique_toolkit.agentic.feature_flags import
|
|
25
|
+
from unique_toolkit.agentic.feature_flags import FeatureFlagNames
|
|
26
26
|
from unique_toolkit.agentic.message_log_order import next_message_log_order
|
|
27
27
|
from unique_toolkit.app.unique_settings import UniqueContext, UniqueSettings
|
|
28
28
|
from unique_toolkit.chat.cancellation import CancellationWatcher
|
|
@@ -100,6 +100,7 @@ from unique_toolkit.content.schemas import (
|
|
|
100
100
|
ContentSearchType,
|
|
101
101
|
)
|
|
102
102
|
from unique_toolkit.elicitation.service import ElicitationService
|
|
103
|
+
from unique_toolkit.experimental.resources.feature_flags import is_flag_enabled
|
|
103
104
|
from unique_toolkit.language_model.constants import (
|
|
104
105
|
DEFAULT_COMPLETE_TEMPERATURE,
|
|
105
106
|
DEFAULT_COMPLETE_TIMEOUT,
|
|
@@ -1805,8 +1806,9 @@ class ChatService(ChatServiceDeprecated):
|
|
|
1805
1806
|
|
|
1806
1807
|
if not rate_limit_retry_config.log_message_on_retry:
|
|
1807
1808
|
return
|
|
1808
|
-
if not
|
|
1809
|
-
|
|
1809
|
+
if not await is_flag_enabled(
|
|
1810
|
+
FeatureFlagNames.enable_new_answers_ui_un_14411,
|
|
1811
|
+
company_id=self._company_id,
|
|
1810
1812
|
):
|
|
1811
1813
|
return
|
|
1812
1814
|
|
{unique_toolkit-2026.34.0.dev6.dist-info → unique_toolkit-2026.34.0.dev8.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-toolkit
|
|
3
|
-
Version: 2026.34.0.
|
|
3
|
+
Version: 2026.34.0.dev8
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Cedric Klinkert, Martin Fadler, Sadique Sheik, Fabian Schläpfer, Pascal Hauri, Ejiroghene Oki-Peter, Rami Azouz, Ricardo Visini, Sanzio Monti
|
|
6
6
|
Author-email: Cedric Klinkert <cedric.klinkert@unique.ch>, Martin Fadler <martin.fadler@unique.ch>, Sadique Sheik <sadique@unique.ch>, Fabian Schläpfer <fabian@unique.ch>, Pascal Hauri <pascal@unique.ch>, Ejiroghene Oki-Peter <oki-peter.ejiroghene@unique.ai>, Rami Azouz <rami.ext@unique.ch>, Ricardo Visini <ricardo.visini@unique.ch>, Sanzio Monti <sanzio.monti@unique.ai>
|
|
@@ -44,6 +44,8 @@ Requires-Dist: langchain-core>=1.0.0,<2 ; extra == 'langchain'
|
|
|
44
44
|
Requires-Dist: prometheus-client>=0.24.1,<1 ; extra == 'monitoring'
|
|
45
45
|
Requires-Dist: opentelemetry-sdk>=1.27,<2 ; extra == 'otel'
|
|
46
46
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.27,<2 ; extra == 'otel'
|
|
47
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.65b0,<1 ; extra == 'otel'
|
|
48
|
+
Requires-Dist: opentelemetry-instrumentation-requests>=0.65b0,<1 ; extra == 'otel'
|
|
47
49
|
Requires-Python: >=3.12
|
|
48
50
|
Provides-Extra: fastapi
|
|
49
51
|
Provides-Extra: langchain
|
|
@@ -111,13 +111,13 @@ unique_toolkit/agentic/evaluation/tests/test_hallucination_utils.py,sha256=ogds7
|
|
|
111
111
|
unique_toolkit/agentic/evaluation/tests/test_output_parser.py,sha256=KfltytmvqnPWLhmZpBXqcRmnlYorw_USwM5rkLVv8so,5179
|
|
112
112
|
unique_toolkit/agentic/evaluation/tests/test_prompt_loaders.py,sha256=zBREdlKf5tdDyB8XSaNgpQv3-tuZJoYteeJrp6WMWDM,11897
|
|
113
113
|
unique_toolkit/agentic/evaluation/utils.py,sha256=HmyPaDV8wdW-_gOjjW-wDaMKgdrsP5-SHP7OqTmGI_A,264
|
|
114
|
-
unique_toolkit/agentic/feature_flags/__init__.py,sha256=
|
|
115
|
-
unique_toolkit/agentic/feature_flags/feature_flags.py,sha256=
|
|
114
|
+
unique_toolkit/agentic/feature_flags/__init__.py,sha256=fBR9FaLrc9e8sdYDe1LwP9aNJt5aLLtAq3nIphVWkIk,191
|
|
115
|
+
unique_toolkit/agentic/feature_flags/feature_flags.py,sha256=IqJMvWEJ49gRuIKkLfg4ZBcEPjaXO1KBuJ-SnRfLakg,6756
|
|
116
116
|
unique_toolkit/agentic/history_manager/history_construction_with_contents.py,sha256=70lm8pYmQpb0HRpqzPTb4ikh8vVbvhfGR5S-D4Ftbbc,25306
|
|
117
117
|
unique_toolkit/agentic/history_manager/history_manager.py,sha256=RIVeQxlCq25JwUY6WWQzz5zoOCouAK7shbxUztpgZPs,15903
|
|
118
|
-
unique_toolkit/agentic/history_manager/loop_token_reducer.py,sha256=
|
|
118
|
+
unique_toolkit/agentic/history_manager/loop_token_reducer.py,sha256=lgo5zAq6gYLo7FFTNWe5sc6o80vnadKsr-cgEDP6hM8,30754
|
|
119
119
|
unique_toolkit/agentic/history_manager/settings.py,sha256=Lrx3a8yXeU0MXrWlV6RZSHsgYWF9Zrs8LyR96OpqQ_k,1216
|
|
120
|
-
unique_toolkit/agentic/history_manager/utils.py,sha256=
|
|
120
|
+
unique_toolkit/agentic/history_manager/utils.py,sha256=DiBip8xtah3I9-G-_Ul3OjlYKunrXR-5RJtzREHWV_0,6579
|
|
121
121
|
unique_toolkit/agentic/loop_runner/__init__.py,sha256=91539BPsDVJ8qG0fyGPZ47vSLBupNnbjxkQf7RzqdBs,1412
|
|
122
122
|
unique_toolkit/agentic/loop_runner/_iteration_handler_utils.py,sha256=y3tjTAtpkyL_Y7279_3v0fGaq9FUYN3UquwdIB3ZhgI,3831
|
|
123
123
|
unique_toolkit/agentic/loop_runner/_responses_iteration_handler_utils.py,sha256=DuQRsToV0KLs7YcFjJVnEmrryhlX5q4isztx2jUxZcI,2064
|
|
@@ -173,7 +173,7 @@ unique_toolkit/agentic/tools/a2a/tool/__init__.py,sha256=9x8nGZsMcpF8ch0RKoelGPl
|
|
|
173
173
|
unique_toolkit/agentic/tools/a2a/tool/_memory.py,sha256=w8bxjokrqHQZgApd55b5rHXF-DpgJwaKTg4CvLBLamc,1034
|
|
174
174
|
unique_toolkit/agentic/tools/a2a/tool/_schema.py,sha256=wMwyunViTnxaURvenkATEvyfXn5LvLaP0HxbYqdZGls,158
|
|
175
175
|
unique_toolkit/agentic/tools/a2a/tool/config.py,sha256=v4rZQU42RjUTC5Md-Cye1rUIWDlHpuhc3MzcyvpGQNw,9748
|
|
176
|
-
unique_toolkit/agentic/tools/a2a/tool/service.py,sha256=
|
|
176
|
+
unique_toolkit/agentic/tools/a2a/tool/service.py,sha256=_N6dxN3qsps77de4t3VhOxH5GLD5cGM83j4I8Pp2-3A,24257
|
|
177
177
|
unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py,sha256=0w3721KiJot54PIy105DNiOGviLiiKNHi6kECDGvO1k,27199
|
|
178
178
|
unique_toolkit/agentic/tools/agent_chunks_hanlder.py,sha256=eO0g46wZOQlmWqYYVGiszRVe8K2LX-9qW30ZCdGg5eE,1943
|
|
179
179
|
unique_toolkit/agentic/tools/config.py,sha256=AOtBn2tL1rIoPPzl1csAHLD5aetYqPL-jAqkIoSBxyE,7468
|
|
@@ -201,7 +201,7 @@ unique_toolkit/agentic/tools/factory.py,sha256=YK9uh2EqotQFb9stsXs-A8lsNaxklTCd_
|
|
|
201
201
|
unique_toolkit/agentic/tools/mcp/__init__.py,sha256=RLF_p-LDRC7GhiB3fdCi4u3bh6V9PY_w26fg61BLyco,122
|
|
202
202
|
unique_toolkit/agentic/tools/mcp/manager.py,sha256=EfWbfNhB8Lnx2EqBgUXhK7klFLaBv2eezvYq8J0TXyo,3808
|
|
203
203
|
unique_toolkit/agentic/tools/mcp/models.py,sha256=DaBVzwJ4dqtgzm8Mv0-NOGBU04zyVe-RgWntBhkpmnE,742
|
|
204
|
-
unique_toolkit/agentic/tools/mcp/tool_wrapper.py,sha256=
|
|
204
|
+
unique_toolkit/agentic/tools/mcp/tool_wrapper.py,sha256=fE5nVALJ-wVZkkbbJ_ySRLBhAAR6sCAAu1lUxQQVWC4,15596
|
|
205
205
|
unique_toolkit/agentic/tools/names.py,sha256=MDF0ONLrxeC-iz--EtyrHAox_RN6zasxo5MSbXQYGyw,412
|
|
206
206
|
unique_toolkit/agentic/tools/openai_builtin/__init__.py,sha256=Q6d9mhsLRVF3erT2yMxLld62D3FTZ8nbovI4vLv4Nso,701
|
|
207
207
|
unique_toolkit/agentic/tools/openai_builtin/base.py,sha256=QWF-GL_fkJqzGPpxvtg69-TB_IjsrxokeJVQESzH-18,1415
|
|
@@ -217,8 +217,8 @@ unique_toolkit/agentic/tools/openai_builtin/code_interpreter/builder/builder.py,
|
|
|
217
217
|
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py,sha256=C4Vrj_xLgLB8AEUz-cp0JpXAIwYwz-VaSRh-xAG7PW8,2381
|
|
218
218
|
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/__init__.py,sha256=SzEiUqxIw8D4_51SvTt-8oTOYTGirYkmH4J6SgojzME,634
|
|
219
219
|
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/artifacts.py,sha256=wAgDrcXZbCdDbNWNpbMigBUXySzbKQXSfg3KsZfAWfs,3115
|
|
220
|
-
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py,sha256=
|
|
221
|
-
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py,sha256=
|
|
220
|
+
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/code_display.py,sha256=WC__H2lhprchVVKsQzPeckhq-EcYg1ePYtrHIAoVzpQ,3165
|
|
221
|
+
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/postprocessors/generated_files.py,sha256=CJ9qVZ720ekyYUyUezsXpQEteNcmYJxw_Jb-JRdhSqI,63127
|
|
222
222
|
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/schemas.py,sha256=W7egCmYrPrzic0aXsu9wY5fvQ8y_cl4Tzq_cjVs0mZs,542
|
|
223
223
|
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/tool/__init__.py,sha256=r6yXmGTLJzXNq5laHOlre9veu--VbCQVlDRVm2QUGzI,326
|
|
224
224
|
unique_toolkit/agentic/tools/openai_builtin/code_interpreter/tool/config.py,sha256=sbLV-fYt_veBAdonqAHY9sm-eHxpjIZgc1KVbm03pZY,19042
|
|
@@ -358,10 +358,10 @@ unique_toolkit/experimental/resources/facades/__init__.py,sha256=imKXMz2nsQcg5zm
|
|
|
358
358
|
unique_toolkit/experimental/resources/facades/identity/__init__.py,sha256=7r-1_gr81Idc6AJ1IRO6GCHx7psmC81BtD15BWxrlYs,1640
|
|
359
359
|
unique_toolkit/experimental/resources/facades/identity/service.py,sha256=A5I7QkNy-Su9FmOkrl8z1iwWhqzoo6KgxEgcdvnWN2M,4287
|
|
360
360
|
unique_toolkit/experimental/resources/feature_flags/README.md,sha256=ChPgYn4-SzY1UyF3OQgBxHzMk6JH_hVKfzHsTcKhcXo,6122
|
|
361
|
-
unique_toolkit/experimental/resources/feature_flags/__init__.py,sha256=
|
|
361
|
+
unique_toolkit/experimental/resources/feature_flags/__init__.py,sha256=C8k2YyJBTEJyKP0ZLH3zvcGwVIHShiz2XHleKbgFIl0,1978
|
|
362
362
|
unique_toolkit/experimental/resources/feature_flags/_graphql_client.py,sha256=a0KxF0EJk7baYChVKFy8bllIJShHKELyQReFd_B9bXs,1743
|
|
363
363
|
unique_toolkit/experimental/resources/feature_flags/_ttl_cache.py,sha256=lPEdWX1JkP2985M1AqQ0uYyWGlagXB0LvOtQPltbgJo,2520
|
|
364
|
-
unique_toolkit/experimental/resources/feature_flags/client.py,sha256=
|
|
364
|
+
unique_toolkit/experimental/resources/feature_flags/client.py,sha256=NAGCjsQpolJNaSJk0dZbpCouUIYbKbFzOOpEqodvmE8,8739
|
|
365
365
|
unique_toolkit/experimental/resources/feature_flags/schemas.py,sha256=chLsBNkIL4BOvGrwrGeixy7BmNSi2BagXD6Jr2fZcqs,602
|
|
366
366
|
unique_toolkit/experimental/resources/feature_flags/settings.py,sha256=3L_c-0zxj4cpuHd3NL3mZ2kN35V6npgh6_hSwu6Gk00,1071
|
|
367
367
|
unique_toolkit/experimental/resources/group/__init__.py,sha256=qPi2DWgWLZw1ku0zi-UsPdornfl8pczW6QSYT5P8CzQ,2098
|
|
@@ -402,14 +402,14 @@ unique_toolkit/language_model/service.py,sha256=hDoJBBgG_wWs8WuC_c8tnmK8cNu8o5Eh
|
|
|
402
402
|
unique_toolkit/language_model/settings.py,sha256=7szohExI-qmTfUf2Zp5AB5TzrsZy1UekAGyXx_UaPMc,1524
|
|
403
403
|
unique_toolkit/language_model/stream_transform.py,sha256=iNNGpLY_7G6Bpp9Y4KtbIkQm3WB4yZt75BXcqx0DVkI,2775
|
|
404
404
|
unique_toolkit/language_model/utils.py,sha256=bPQ4l6_YO71w-zaIPanUUmtbXC1_hCvLK0tAFc3VCRc,1902
|
|
405
|
-
unique_toolkit/monitoring/__init__.py,sha256=
|
|
405
|
+
unique_toolkit/monitoring/__init__.py,sha256=XHRzPx4LKcbKruRrf_gNv50amhvhy8Go2IkOoHMuLsw,1486
|
|
406
406
|
unique_toolkit/monitoring/gunicorn.py,sha256=urTFFS5zYHKoxb1TEQHcLqb2byi-aYgFRHGwgYRzYYI,844
|
|
407
407
|
unique_toolkit/monitoring/middleware.py,sha256=MNsUuKgt74mSnUwttXTB_AxX546Pz2zKoAP9OewVrwQ,4531
|
|
408
408
|
unique_toolkit/monitoring/registry.py,sha256=De2Bx5QBBRJQY2MM3xtntiJ2JU2FoKkVT7rNMG7ewgA,5874
|
|
409
|
-
unique_toolkit/monitoring/tracing.py,sha256=
|
|
409
|
+
unique_toolkit/monitoring/tracing.py,sha256=0lmLuQjyyC3iFpNTw8rOyCpEZ6PTvp16nVbzcO9d2sQ,10043
|
|
410
410
|
unique_toolkit/protocols/support.py,sha256=x5edzbBmKAUuvm3oLFh52gkgQsqR5LU7M0t8RHK0DZk,5161
|
|
411
411
|
unique_toolkit/services/__init__.py,sha256=b9Wl7Wvz1JmZDbDexIZzBoXZ0wscXuczGAH8LoL-Qak,572
|
|
412
|
-
unique_toolkit/services/chat_service.py,sha256=
|
|
412
|
+
unique_toolkit/services/chat_service.py,sha256=6lVMSwvi2ztPebK6meo9BVLOL_Wdje5wPSUBp5dMZIg,99268
|
|
413
413
|
unique_toolkit/services/factory.py,sha256=7gNeanyHkgX23Iz7RMCQTCkE9gI5asCI11nXxM0jjx4,9832
|
|
414
414
|
unique_toolkit/services/knowledge_base.py,sha256=6dM4abcXR9y2VYoR6SK79gwjrzb83Wm8jMPPIt5z95o,43461
|
|
415
415
|
unique_toolkit/short_term_memory/__init__.py,sha256=2mI3AUrffgH7Yt-xS57EGqnHf7jnn6xquoKEhJqk3Wg,185
|
|
@@ -420,6 +420,6 @@ unique_toolkit/short_term_memory/service.py,sha256=2JMBEBn6GoyK-a0xvdcWpPft-3C74
|
|
|
420
420
|
unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
421
421
|
unique_toolkit/smart_rules/compile.py,sha256=vRe0aMJWuVIK-VsqomgxQImzke7MDmwgSxxJfYCa7zw,1386
|
|
422
422
|
unique_toolkit/test_utilities/events.py,sha256=FLrhMh0A_mQutAUjoD0FdMcVQ4Gq31r35OVGzRjvLro,6760
|
|
423
|
-
unique_toolkit-2026.34.0.
|
|
424
|
-
unique_toolkit-2026.34.0.
|
|
425
|
-
unique_toolkit-2026.34.0.
|
|
423
|
+
unique_toolkit-2026.34.0.dev8.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
424
|
+
unique_toolkit-2026.34.0.dev8.dist-info/METADATA,sha256=xKbzXHZ9elQ5mo-UZHvCPfjCK1Hfr3ds0Xum8Z1v8Ns,7821
|
|
425
|
+
unique_toolkit-2026.34.0.dev8.dist-info/RECORD,,
|
|
File without changes
|