unique_toolkit 2026.32.0.dev2__py3-none-any.whl → 2026.32.0.dev4__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/debug_info_manager/debug_info_manager.py +42 -0
- unique_toolkit/agentic/postprocessor/postprocessor_manager.py +31 -0
- unique_toolkit/agentic/tools/a2a/tool/service.py +53 -2
- unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py +73 -0
- unique_toolkit/monitoring/registry.py +25 -2
- {unique_toolkit-2026.32.0.dev2.dist-info → unique_toolkit-2026.32.0.dev4.dist-info}/METADATA +4 -4
- {unique_toolkit-2026.32.0.dev2.dist-info → unique_toolkit-2026.32.0.dev4.dist-info}/RECORD +8 -8
- {unique_toolkit-2026.32.0.dev2.dist-info → unique_toolkit-2026.32.0.dev4.dist-info}/WHEEL +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
1
2
|
from typing import Any, Required, TypedDict
|
|
2
3
|
|
|
3
4
|
from unique_toolkit.agentic.tools.openai_builtin import OpenAICodeInterpreterTool
|
|
@@ -7,8 +8,10 @@ from unique_toolkit.agentic.tools.openai_builtin.code_interpreter.postprocessors
|
|
|
7
8
|
)
|
|
8
9
|
from unique_toolkit.agentic.tools.schemas import ToolCallResponse
|
|
9
10
|
from unique_toolkit.agentic.tools.tool_manager import ToolManager
|
|
11
|
+
from unique_toolkit.language_model.invocation_stats import LanguageModelInvocationStats
|
|
10
12
|
from unique_toolkit.language_model.schemas import (
|
|
11
13
|
LanguageModelStreamResponse,
|
|
14
|
+
LanguageModelTokenUsage,
|
|
12
15
|
ResponsesLanguageModelStreamResponse,
|
|
13
16
|
)
|
|
14
17
|
|
|
@@ -40,6 +43,16 @@ class AnalyticsToolName(TypedDict):
|
|
|
40
43
|
display_name: str
|
|
41
44
|
|
|
42
45
|
|
|
46
|
+
class AnalyticsTokenUsage(TypedDict):
|
|
47
|
+
model_name: str
|
|
48
|
+
completion_tokens: int | None
|
|
49
|
+
prompt_tokens: int | None
|
|
50
|
+
total_tokens: int | None
|
|
51
|
+
reasoning_tokens: int | None
|
|
52
|
+
cached_tokens: int | None
|
|
53
|
+
cache_write_tokens: int | None
|
|
54
|
+
|
|
55
|
+
|
|
43
56
|
class Analytics(TypedDict):
|
|
44
57
|
answer_length: int
|
|
45
58
|
artifacts_created_count: int | None
|
|
@@ -54,6 +67,7 @@ class Analytics(TypedDict):
|
|
|
54
67
|
references_count: int
|
|
55
68
|
skills_used: list[AnalyticsSkill]
|
|
56
69
|
subagent_names_used: list[AnalyticsToolName]
|
|
70
|
+
tokens: list[AnalyticsTokenUsage]
|
|
57
71
|
tool_call_count: int
|
|
58
72
|
tools_used: list[AnalyticsTool]
|
|
59
73
|
total_time_to_answer_ms: int | None
|
|
@@ -115,6 +129,7 @@ class DebugInfoManager:
|
|
|
115
129
|
total_time_to_answer_ms: int | None = None,
|
|
116
130
|
artifacts: ArtifactsDebugInfo | None = None,
|
|
117
131
|
context_memory_updated: bool | None = None,
|
|
132
|
+
invocations: list[LanguageModelInvocationStats] | None = None,
|
|
118
133
|
) -> None:
|
|
119
134
|
"""Add a stable 'analytics' snapshot for downstream ROI/usage reporting.
|
|
120
135
|
|
|
@@ -152,6 +167,7 @@ class DebugInfoManager:
|
|
|
152
167
|
loop_iteration_count=loop_iteration_count,
|
|
153
168
|
subagent_names_used=_unique_tool_names(analytics_tools, "is_sub_agent"),
|
|
154
169
|
mcp_tool_names_used=_unique_tool_names(analytics_tools, "is_mcp"),
|
|
170
|
+
tokens=_aggregate_tokens_by_model(invocations or []),
|
|
155
171
|
total_time_to_answer_ms=total_time_to_answer_ms,
|
|
156
172
|
artifacts_created_count=artifacts["count"] if artifacts else None,
|
|
157
173
|
artifacts_created_filetype=artifacts["filetypes"] if artifacts else None,
|
|
@@ -163,6 +179,32 @@ class DebugInfoManager:
|
|
|
163
179
|
self.add("analytics", analytics)
|
|
164
180
|
|
|
165
181
|
|
|
182
|
+
def _aggregate_tokens_by_model(
|
|
183
|
+
invocations: list[LanguageModelInvocationStats],
|
|
184
|
+
) -> list[AnalyticsTokenUsage]:
|
|
185
|
+
usages_by_model: dict[str, list[LanguageModelTokenUsage]] = defaultdict(list)
|
|
186
|
+
for invocation in invocations:
|
|
187
|
+
usages_by_model[str(invocation.model_name)].append(invocation.token_usage)
|
|
188
|
+
|
|
189
|
+
totals: list[AnalyticsTokenUsage] = []
|
|
190
|
+
for model_name in sorted(usages_by_model):
|
|
191
|
+
usage = LanguageModelTokenUsage.sum_usages(usages_by_model[model_name])
|
|
192
|
+
if usage is None:
|
|
193
|
+
continue
|
|
194
|
+
totals.append(
|
|
195
|
+
AnalyticsTokenUsage(
|
|
196
|
+
model_name=model_name,
|
|
197
|
+
completion_tokens=usage.completion_tokens,
|
|
198
|
+
prompt_tokens=usage.prompt_tokens,
|
|
199
|
+
total_tokens=usage.total_tokens,
|
|
200
|
+
reasoning_tokens=usage.reasoning_tokens,
|
|
201
|
+
cached_tokens=usage.cached_tokens,
|
|
202
|
+
cache_write_tokens=usage.cache_write_tokens,
|
|
203
|
+
)
|
|
204
|
+
)
|
|
205
|
+
return totals
|
|
206
|
+
|
|
207
|
+
|
|
166
208
|
def _unique_tool_names(
|
|
167
209
|
analytics_tools: list[AnalyticsTool], flag: str
|
|
168
210
|
) -> list[AnalyticsToolName]:
|
|
@@ -41,6 +41,17 @@ class Postprocessor(ABC):
|
|
|
41
41
|
"""Override in subclasses whose `run()` makes its own LLM call(s)."""
|
|
42
42
|
return []
|
|
43
43
|
|
|
44
|
+
def take_pending_invocation_stats(self) -> list[LanguageModelInvocationStats]:
|
|
45
|
+
"""Pop usage incurred before this turn's `run()` was reached.
|
|
46
|
+
|
|
47
|
+
Called unconditionally at the start of every turn so usage from work
|
|
48
|
+
done ahead of postprocessing (e.g. a load-time LLM call) is still
|
|
49
|
+
reported on turns that exit before `run()` executes. Override in
|
|
50
|
+
subclasses that do such work; must clear the pending stats so `run()`
|
|
51
|
+
does not report them a second time.
|
|
52
|
+
"""
|
|
53
|
+
return []
|
|
54
|
+
|
|
44
55
|
|
|
45
56
|
class ResponsesApiPostprocessor(ABC):
|
|
46
57
|
def __init__(self, name: str):
|
|
@@ -74,6 +85,13 @@ class ResponsesApiPostprocessor(ABC):
|
|
|
74
85
|
"""
|
|
75
86
|
return []
|
|
76
87
|
|
|
88
|
+
def take_pending_invocation_stats(self) -> list[LanguageModelInvocationStats]:
|
|
89
|
+
"""Pop usage incurred before this turn's `run()` was reached.
|
|
90
|
+
|
|
91
|
+
See `Postprocessor.take_pending_invocation_stats` for why this exists.
|
|
92
|
+
"""
|
|
93
|
+
return []
|
|
94
|
+
|
|
77
95
|
|
|
78
96
|
class PostprocessorManager:
|
|
79
97
|
"""
|
|
@@ -196,6 +214,19 @@ class PostprocessorManager:
|
|
|
196
214
|
"""Per-LLM-call stats from every postprocessor that made its own LLM call(s)."""
|
|
197
215
|
return list(self._invocation_stats)
|
|
198
216
|
|
|
217
|
+
def take_pending_invocation_stats(self) -> list[LanguageModelInvocationStats]:
|
|
218
|
+
"""Pop pre-`run()` usage (e.g. load-time calls) from every postprocessor.
|
|
219
|
+
|
|
220
|
+
Call this unconditionally at the start of a turn, before it's known
|
|
221
|
+
whether `run_postprocessors` will even be reached this turn, so that
|
|
222
|
+
usage is never silently dropped on turns that exit early.
|
|
223
|
+
"""
|
|
224
|
+
return [
|
|
225
|
+
invocation
|
|
226
|
+
for postprocessor in self._get_all_postprocessors()
|
|
227
|
+
for invocation in postprocessor.take_pending_invocation_stats()
|
|
228
|
+
]
|
|
229
|
+
|
|
199
230
|
async def execute_postprocessors(
|
|
200
231
|
self,
|
|
201
232
|
loop_response: LanguageModelStreamResponse,
|
|
@@ -4,12 +4,15 @@ import json
|
|
|
4
4
|
import logging
|
|
5
5
|
import re
|
|
6
6
|
from datetime import datetime
|
|
7
|
-
from typing import override
|
|
7
|
+
from typing import Any, override
|
|
8
8
|
|
|
9
9
|
import unique_sdk
|
|
10
10
|
from pydantic import Field, TypeAdapter, create_model
|
|
11
11
|
from unique_sdk.api_resources._space import Space
|
|
12
|
-
from unique_sdk.utils.chat_in_space import
|
|
12
|
+
from unique_sdk.utils.chat_in_space import (
|
|
13
|
+
get_message_invocations,
|
|
14
|
+
send_message_and_wait_for_completion,
|
|
15
|
+
)
|
|
13
16
|
|
|
14
17
|
from unique_toolkit._common.execution import SafeTaskExecutor
|
|
15
18
|
from unique_toolkit._common.referencing import (
|
|
@@ -55,6 +58,7 @@ from unique_toolkit.language_model import (
|
|
|
55
58
|
LanguageModelService,
|
|
56
59
|
LanguageModelToolDescription,
|
|
57
60
|
)
|
|
61
|
+
from unique_toolkit.language_model.invocation_stats import LanguageModelInvocationStats
|
|
58
62
|
|
|
59
63
|
logger = logging.getLogger(__name__)
|
|
60
64
|
|
|
@@ -296,6 +300,13 @@ class SubAgentTool(Tool[SubAgentToolConfig]):
|
|
|
296
300
|
if self.config.passthrough_config.enabled:
|
|
297
301
|
await self._display_sub_agent_response(response)
|
|
298
302
|
|
|
303
|
+
sub_agent_invocations = _prefix_sub_agent_invocation_sources(
|
|
304
|
+
invocations=_parse_sub_agent_invocation_stats(
|
|
305
|
+
get_message_invocations(response)
|
|
306
|
+
),
|
|
307
|
+
tool_name=self.name,
|
|
308
|
+
tool_call_id=tool_call.id,
|
|
309
|
+
)
|
|
299
310
|
return ToolCallResponse(
|
|
300
311
|
id=tool_call.id,
|
|
301
312
|
name=tool_call.name,
|
|
@@ -307,9 +318,12 @@ class SubAgentTool(Tool[SubAgentToolConfig]):
|
|
|
307
318
|
content_chunks=content_chunks,
|
|
308
319
|
debug_info={
|
|
309
320
|
"chat_id": response["chatId"],
|
|
321
|
+
"user_message_id": response.get("triggeringUserMessageId"),
|
|
322
|
+
"assistant_message_id": response.get("id"),
|
|
310
323
|
"assistant_id": self.config.assistant_id,
|
|
311
324
|
"display_name": self._display_name,
|
|
312
325
|
},
|
|
326
|
+
invocation_stats=sub_agent_invocations,
|
|
313
327
|
)
|
|
314
328
|
except TimeoutError as e:
|
|
315
329
|
raise e
|
|
@@ -495,6 +509,7 @@ class SubAgentTool(Tool[SubAgentToolConfig]):
|
|
|
495
509
|
parentAssistantId=self.config.assistant_id,
|
|
496
510
|
),
|
|
497
511
|
on_message_update=on_message_update,
|
|
512
|
+
wait_for_invocations=True,
|
|
498
513
|
)
|
|
499
514
|
except TimeoutError as e:
|
|
500
515
|
await self._notify_progress(
|
|
@@ -513,6 +528,42 @@ class SubAgentTool(Tool[SubAgentToolConfig]):
|
|
|
513
528
|
) from e
|
|
514
529
|
|
|
515
530
|
|
|
531
|
+
def _parse_sub_agent_invocation_stats(
|
|
532
|
+
raw_invocations: list[dict[str, Any]],
|
|
533
|
+
) -> list[LanguageModelInvocationStats]:
|
|
534
|
+
"""Deserialize sub-agent invocation stats, ignoring malformed entries.
|
|
535
|
+
|
|
536
|
+
A single unparseable entry (e.g. a stale model name) must not fail the
|
|
537
|
+
whole tool call and drop an otherwise-successful sub-agent reply -- see
|
|
538
|
+
`_load_invocation_stats_from_debug_info` in unique_orchestrator, which
|
|
539
|
+
applies the same per-entry tolerance for the same reason.
|
|
540
|
+
"""
|
|
541
|
+
invocations: list[LanguageModelInvocationStats] = []
|
|
542
|
+
for raw_invocation in raw_invocations:
|
|
543
|
+
try:
|
|
544
|
+
invocations.append(
|
|
545
|
+
LanguageModelInvocationStats.model_validate(raw_invocation)
|
|
546
|
+
)
|
|
547
|
+
except Exception:
|
|
548
|
+
logger.warning(
|
|
549
|
+
"Ignoring malformed sub-agent LLM invocation stats",
|
|
550
|
+
exc_info=True,
|
|
551
|
+
)
|
|
552
|
+
return invocations
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
def _prefix_sub_agent_invocation_sources(
|
|
556
|
+
invocations: list[LanguageModelInvocationStats],
|
|
557
|
+
tool_name: str,
|
|
558
|
+
tool_call_id: str,
|
|
559
|
+
) -> list[LanguageModelInvocationStats]:
|
|
560
|
+
prefix = f"subagent.{tool_name}.{tool_call_id}"
|
|
561
|
+
return [
|
|
562
|
+
invocation.model_copy(update={"source": f"{prefix}.{invocation.source}"})
|
|
563
|
+
for invocation in invocations
|
|
564
|
+
]
|
|
565
|
+
|
|
566
|
+
|
|
516
567
|
def _format_response(tool_name: str, text: str, system_reminders: list[str]) -> str:
|
|
517
568
|
if len(system_reminders) == 0:
|
|
518
569
|
return text
|
|
@@ -17,6 +17,7 @@ from unique_toolkit.agentic.tools.a2a.tool.config import (
|
|
|
17
17
|
from unique_toolkit.agentic.tools.a2a.tool.service import (
|
|
18
18
|
_format_response,
|
|
19
19
|
_get_sub_agent_system_reminders,
|
|
20
|
+
_parse_sub_agent_invocation_stats,
|
|
20
21
|
_prepare_sub_agent_response_refs,
|
|
21
22
|
_remove_extra_refs,
|
|
22
23
|
_response_has_refs,
|
|
@@ -59,6 +60,78 @@ def refs_list() -> list[dict[str, Any]]:
|
|
|
59
60
|
]
|
|
60
61
|
|
|
61
62
|
|
|
63
|
+
# Tests for _parse_sub_agent_invocation_stats
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@pytest.mark.ai
|
|
67
|
+
def test_parse_sub_agent_invocation_stats__skips_malformed_entry__keeps_valid_ones() -> (
|
|
68
|
+
None
|
|
69
|
+
):
|
|
70
|
+
"""
|
|
71
|
+
Purpose: Verify one malformed invocation entry doesn't discard the rest.
|
|
72
|
+
Why this matters: A single bad entry must not fail the whole sub-agent tool
|
|
73
|
+
call and drop an otherwise-successful reply.
|
|
74
|
+
Setup summary: Mix a valid entry with a malformed one (missing required
|
|
75
|
+
fields), verify only the valid entry survives.
|
|
76
|
+
"""
|
|
77
|
+
# Arrange
|
|
78
|
+
raw_invocations = [
|
|
79
|
+
{
|
|
80
|
+
"modelName": "gpt-4",
|
|
81
|
+
"tokenUsage": {"totalTokens": 10},
|
|
82
|
+
"source": "main_loop",
|
|
83
|
+
},
|
|
84
|
+
{"modelName": "gpt-4"}, # missing required tokenUsage/source
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
# Act
|
|
88
|
+
result = _parse_sub_agent_invocation_stats(raw_invocations)
|
|
89
|
+
|
|
90
|
+
# Assert
|
|
91
|
+
assert len(result) == 1
|
|
92
|
+
assert result[0].source == "main_loop"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@pytest.mark.ai
|
|
96
|
+
def test_parse_sub_agent_invocation_stats__returns_empty__when_all_malformed() -> None:
|
|
97
|
+
"""
|
|
98
|
+
Purpose: Verify an all-malformed list returns empty instead of raising.
|
|
99
|
+
Why this matters: The sub-agent tool call must still succeed and return the
|
|
100
|
+
answer even if every persisted stats entry is unparseable.
|
|
101
|
+
Setup summary: Only malformed entries, assert empty list with no exception.
|
|
102
|
+
"""
|
|
103
|
+
# Arrange
|
|
104
|
+
raw_invocations = [{"modelName": "gpt-4"}, {"source": "main_loop"}]
|
|
105
|
+
|
|
106
|
+
# Act
|
|
107
|
+
result = _parse_sub_agent_invocation_stats(raw_invocations)
|
|
108
|
+
|
|
109
|
+
# Assert
|
|
110
|
+
assert result == []
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@pytest.mark.ai
|
|
114
|
+
def test_parse_sub_agent_invocation_stats__parses_all__when_all_valid() -> None:
|
|
115
|
+
"""
|
|
116
|
+
Purpose: Verify parsing is unaffected by the malformed-entry tolerance
|
|
117
|
+
when every entry is well-formed.
|
|
118
|
+
Why this matters: The fix must not silently drop good data too.
|
|
119
|
+
Setup summary: Two valid entries, assert both are returned.
|
|
120
|
+
"""
|
|
121
|
+
# Arrange
|
|
122
|
+
raw_invocations = [
|
|
123
|
+
{"modelName": "gpt-4", "tokenUsage": {"totalTokens": 3}, "source": "a"},
|
|
124
|
+
{"modelName": "gpt-4", "tokenUsage": {"totalTokens": 5}, "source": "b"},
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
# Act
|
|
128
|
+
result = _parse_sub_agent_invocation_stats(raw_invocations)
|
|
129
|
+
|
|
130
|
+
# Assert
|
|
131
|
+
assert len(result) == 2
|
|
132
|
+
assert [inv.source for inv in result] == ["a", "b"]
|
|
133
|
+
|
|
134
|
+
|
|
62
135
|
# Tests for _format_response
|
|
63
136
|
|
|
64
137
|
|
|
@@ -5,6 +5,7 @@ import functools
|
|
|
5
5
|
import os
|
|
6
6
|
import time
|
|
7
7
|
import warnings
|
|
8
|
+
from collections.abc import Sequence
|
|
8
9
|
from contextlib import contextmanager
|
|
9
10
|
from typing import Any, Callable, Literal
|
|
10
11
|
|
|
@@ -66,9 +67,31 @@ class MetricNamespace:
|
|
|
66
67
|
def __init__(self, prefix: str) -> None:
|
|
67
68
|
self._prefix = prefix
|
|
68
69
|
|
|
69
|
-
def histogram(
|
|
70
|
+
def histogram(
|
|
71
|
+
self,
|
|
72
|
+
name: str,
|
|
73
|
+
description: str,
|
|
74
|
+
labels: list[str],
|
|
75
|
+
buckets: Sequence[float] | None = None,
|
|
76
|
+
) -> Histogram:
|
|
77
|
+
"""Create a Histogram, optionally with custom bucket boundaries.
|
|
78
|
+
|
|
79
|
+
When ``buckets`` is omitted, prometheus_client's default buckets are used
|
|
80
|
+
(top finite bucket 10s). Provide explicit buckets for workloads whose
|
|
81
|
+
latency regularly exceeds 10s so ``histogram_quantile`` can resolve the
|
|
82
|
+
tail; observations above the largest bucket fall into the implicit +Inf
|
|
83
|
+
bucket. prometheus_client appends +Inf automatically.
|
|
84
|
+
"""
|
|
85
|
+
if buckets is None:
|
|
86
|
+
return Histogram(
|
|
87
|
+
f"{self._prefix}_{name}", description, labels, registry=REGISTRY
|
|
88
|
+
)
|
|
70
89
|
return Histogram(
|
|
71
|
-
f"{self._prefix}_{name}",
|
|
90
|
+
f"{self._prefix}_{name}",
|
|
91
|
+
description,
|
|
92
|
+
labels,
|
|
93
|
+
registry=REGISTRY,
|
|
94
|
+
buckets=tuple(buckets),
|
|
72
95
|
)
|
|
73
96
|
|
|
74
97
|
def counter(self, name: str, description: str, labels: list[str]) -> Counter:
|
{unique_toolkit-2026.32.0.dev2.dist-info → unique_toolkit-2026.32.0.dev4.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-toolkit
|
|
3
|
-
Version: 2026.32.0.
|
|
3
|
+
Version: 2026.32.0.dev4
|
|
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>
|
|
@@ -16,7 +16,7 @@ Requires-Dist: sseclient>=0.0.27,<0.0.28
|
|
|
16
16
|
Requires-Dist: openai>=1.105.0,<3
|
|
17
17
|
Requires-Dist: platformdirs>=4.0.0,<5
|
|
18
18
|
Requires-Dist: pillow>=12.1.1
|
|
19
|
-
Requires-Dist: unique-sdk>=2026.32.0.
|
|
19
|
+
Requires-Dist: unique-sdk>=2026.32.0.dev5,<2026.32.0rc0
|
|
20
20
|
Requires-Dist: jambo>=0.1.2,<0.2
|
|
21
21
|
Requires-Dist: jinja2>=3.1.6,<4
|
|
22
22
|
Requires-Dist: docxtpl>=0.20.1,<0.21
|
|
@@ -33,8 +33,8 @@ Requires-Dist: tenacity>=9.1.4
|
|
|
33
33
|
Requires-Dist: pydantic-core>=2.41.5
|
|
34
34
|
Requires-Dist: cachetools>=5.0,<6
|
|
35
35
|
Requires-Dist: rapidfuzz>=3.0,<4
|
|
36
|
-
Requires-Dist: fastapi>=0.
|
|
37
|
-
Requires-Dist: starlette>=
|
|
36
|
+
Requires-Dist: fastapi>=0.133.0,<1.0.0 ; extra == 'fastapi'
|
|
37
|
+
Requires-Dist: starlette>=1.3.1,<2.0.0 ; extra == 'fastapi'
|
|
38
38
|
Requires-Dist: uvicorn>=0.37.0,<0.38 ; extra == 'fastapi'
|
|
39
39
|
Requires-Dist: openai>=1.105.0,<3 ; extra == 'langchain'
|
|
40
40
|
Requires-Dist: langchain>=1.0.0,<2 ; extra == 'langchain'
|
|
@@ -83,7 +83,7 @@ unique_toolkit/_common/utils/write_configuration.py,sha256=fzvr4C-XBL3OSM3Od9Tbq
|
|
|
83
83
|
unique_toolkit/_common/validate_required_values.py,sha256=cA8GPwkV1EPsG6ffIkmAn3Dx4LRRMC1EAURmT7PyuCg,551
|
|
84
84
|
unique_toolkit/_common/validators.py,sha256=ElnkMsyEY24TfzfTVHvireyT39EnZgW5N40T0P4b6gE,2638
|
|
85
85
|
unique_toolkit/agentic/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
86
|
-
unique_toolkit/agentic/debug_info_manager/debug_info_manager.py,sha256=
|
|
86
|
+
unique_toolkit/agentic/debug_info_manager/debug_info_manager.py,sha256=VZLDOTAJJ_jVOZ4Zw4C2F-uCv3vsjZTcvbljGBYKh-A,10501
|
|
87
87
|
unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py,sha256=bDjrHLqfwtd7ewdIdyTFHabG-15t3iXvs34ywoYXcik,11888
|
|
88
88
|
unique_toolkit/agentic/evaluation/config.py,sha256=u5-iuT-4mfA2_9UZjZ-TN3YutVf35aR4EsF9l61Odnk,1696
|
|
89
89
|
unique_toolkit/agentic/evaluation/context_relevancy/prompts/__init__.py,sha256=IKGvHW2viBylTUjEJNKvIXO4YrYwdJXBHSxA9rKtiRI,355
|
|
@@ -138,7 +138,7 @@ unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py,sha256=_hS65fq1eH
|
|
|
138
138
|
unique_toolkit/agentic/message_log_manager/__init__.py,sha256=3-KY_sGkPbNoSnrzwPY0FQIJNnsz4NHXvocXgGRUeuE,169
|
|
139
139
|
unique_toolkit/agentic/message_log_manager/service.py,sha256=yXeV_70ATUJrFi_KYRJ8PRmRbo27kQjY5cjazxDFkpI,9840
|
|
140
140
|
unique_toolkit/agentic/message_log_order.py,sha256=GaZOlAkFS2BpTc72af6Nit9inm6LskBYTze5Q7dd9cs,1041
|
|
141
|
-
unique_toolkit/agentic/postprocessor/postprocessor_manager.py,sha256=
|
|
141
|
+
unique_toolkit/agentic/postprocessor/postprocessor_manager.py,sha256=76n2aNqjsM6P6SJDuKtlGTFdIlaVHr2klsz9BhgNUAM,10761
|
|
142
142
|
unique_toolkit/agentic/reference_manager/reference_manager.py,sha256=axqjSNFoR6oGVKg_fK1D2IsA9sxvreyPutRxK17dBxI,4844
|
|
143
143
|
unique_toolkit/agentic/reference_manager/tests/test_external_context.py,sha256=FlCr8rcvrJDkVbKW6pDylSTmP0v0luH_3TGBvXm4KZw,1246
|
|
144
144
|
unique_toolkit/agentic/responses_api/__init__.py,sha256=9WTO-ef7fGE9Y1QtZJFm8Q_jkwK8Srtl-HWvpAD2Wxs,668
|
|
@@ -173,8 +173,8 @@ 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=
|
|
177
|
-
unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py,sha256=
|
|
176
|
+
unique_toolkit/agentic/tools/a2a/tool/service.py,sha256=j3kQZ1P-gYyXE2SmbbyNIVC1tIgTm8pJkCwrfUB9YU8,24173
|
|
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
|
|
180
180
|
unique_toolkit/agentic/tools/experimental/__init__.py,sha256=ArEcXHGPtMRNsDnsyo9v1fev0EZWdJ6D7NWdPEFLQKM,956
|
|
@@ -404,7 +404,7 @@ unique_toolkit/language_model/utils.py,sha256=bPQ4l6_YO71w-zaIPanUUmtbXC1_hCvLK0
|
|
|
404
404
|
unique_toolkit/monitoring/__init__.py,sha256=z1gkOCLxGcg936MFuLSeWFa0tREcBFSUbV09NxilBw4,1065
|
|
405
405
|
unique_toolkit/monitoring/gunicorn.py,sha256=urTFFS5zYHKoxb1TEQHcLqb2byi-aYgFRHGwgYRzYYI,844
|
|
406
406
|
unique_toolkit/monitoring/middleware.py,sha256=JNh5v_INAkexuLtXhCG9n5n2t6Pnf8ZdPTnimAVS0_s,2931
|
|
407
|
-
unique_toolkit/monitoring/registry.py,sha256=
|
|
407
|
+
unique_toolkit/monitoring/registry.py,sha256=De2Bx5QBBRJQY2MM3xtntiJ2JU2FoKkVT7rNMG7ewgA,5874
|
|
408
408
|
unique_toolkit/protocols/support.py,sha256=x5edzbBmKAUuvm3oLFh52gkgQsqR5LU7M0t8RHK0DZk,5161
|
|
409
409
|
unique_toolkit/services/__init__.py,sha256=b9Wl7Wvz1JmZDbDexIZzBoXZ0wscXuczGAH8LoL-Qak,572
|
|
410
410
|
unique_toolkit/services/chat_service.py,sha256=ofhNHCW7kz6xXN4pUTBdDEYovZ7PXhUglPDgez8Qov0,99142
|
|
@@ -418,6 +418,6 @@ unique_toolkit/short_term_memory/service.py,sha256=2JMBEBn6GoyK-a0xvdcWpPft-3C74
|
|
|
418
418
|
unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
419
419
|
unique_toolkit/smart_rules/compile.py,sha256=vRe0aMJWuVIK-VsqomgxQImzke7MDmwgSxxJfYCa7zw,1386
|
|
420
420
|
unique_toolkit/test_utilities/events.py,sha256=FLrhMh0A_mQutAUjoD0FdMcVQ4Gq31r35OVGzRjvLro,6760
|
|
421
|
-
unique_toolkit-2026.32.0.
|
|
422
|
-
unique_toolkit-2026.32.0.
|
|
423
|
-
unique_toolkit-2026.32.0.
|
|
421
|
+
unique_toolkit-2026.32.0.dev4.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
422
|
+
unique_toolkit-2026.32.0.dev4.dist-info/METADATA,sha256=INpTCsVe9pxypJm__jhb4ItWNy616eN71Bn04P9Y6WU,7465
|
|
423
|
+
unique_toolkit-2026.32.0.dev4.dist-info/RECORD,,
|
|
File without changes
|