ioc-scope-mce-core 2.0.0rc1__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.
- ioc_scope_mce_core-2.0.0rc1/PKG-INFO +47 -0
- ioc_scope_mce_core-2.0.0rc1/pyproject.toml +79 -0
- ioc_scope_mce_core-2.0.0rc1/setup.cfg +4 -0
- ioc_scope_mce_core-2.0.0rc1/src/ioc_scope_mce_core.egg-info/PKG-INFO +47 -0
- ioc_scope_mce_core-2.0.0rc1/src/ioc_scope_mce_core.egg-info/SOURCES.txt +76 -0
- ioc_scope_mce_core-2.0.0rc1/src/ioc_scope_mce_core.egg-info/dependency_links.txt +1 -0
- ioc_scope_mce_core-2.0.0rc1/src/ioc_scope_mce_core.egg-info/requires.txt +48 -0
- ioc_scope_mce_core-2.0.0rc1/src/ioc_scope_mce_core.egg-info/top_level.txt +1 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/__init__.py +27 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/catalog.py +208 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/config.py +33 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/helpers.py +184 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/metadata.py +192 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/metric.py +163 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/provider.py +36 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/registry/__init__.py +98 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/registry/discovery.py +739 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/registry/provider.py +40 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/registry/service.py +89 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/__init__.py +21 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/_registry.py +223 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/agent_to_agent_interactions.py +53 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/agent_to_tool_interactions.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/answer_correctness.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/answer_relevancy.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/bias.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/call_count.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/coherence.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/completion_rate.py +53 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/component_conflict_rate.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/consistency.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/context_preservation.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/conversation_completeness.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/cost.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/cycles_count.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/duration.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/general_structure_and_style.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/goal_success_rate.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/graph_determinism_score.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/groundedness.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/hallucination.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/information_retention.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/intent_recognition_accuracy.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/llm_average_confidence.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/llm_error_rate.py +76 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/llm_maximum_confidence.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/llm_minimum_confidence.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/response_completeness.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/role_adherence.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/sentiment.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/task_completion.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/task_delegation_accuracy.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/token_count.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/tonality.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/tool_error.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/tool_error_rate.py +14 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/tool_utilization_accuracy.py +95 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/topic_adherence.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/toxicity.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/workflow_cohesion_index.py +18 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/specs/workflow_efficiency.py +90 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/core/types.py +99 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/__init__.py +29 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/caching.py +611 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/context_builder.py +298 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/data/model_prices.json +1 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/engine.py +886 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/llm.py +338 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/pricing.py +146 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/scheduler.py +61 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/strategies.py +129 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/usage.py +84 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/engine/worker.py +12 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/providers/__init__.py +9 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/providers/base_wrapper.py +133 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/providers/catalog.py +28 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/providers/template/__init__.py +4 -0
- ioc_scope_mce_core-2.0.0rc1/src/mce/providers/virtual/aggregators.py +159 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ioc-scope-mce-core
|
|
3
|
+
Version: 2.0.0rc1
|
|
4
|
+
Summary: Metrics Computation Engine core
|
|
5
|
+
Author-email: Outshift Open <oss-github@cisco.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Requires-Python: <3.15,>=3.13
|
|
8
|
+
Requires-Dist: pydantic>=2.0.0
|
|
9
|
+
Requires-Dist: click>=8.0.0
|
|
10
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
11
|
+
Requires-Dist: requests>=2.28.0
|
|
12
|
+
Requires-Dist: networkx>=3.0.0
|
|
13
|
+
Requires-Dist: packaging>=23.0
|
|
14
|
+
Requires-Dist: pandas>=1.5.0
|
|
15
|
+
Requires-Dist: pydantic-settings>=2.10.1
|
|
16
|
+
Requires-Dist: typer>=0.9.0
|
|
17
|
+
Requires-Dist: rdflib>=7.0.0
|
|
18
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
19
|
+
Requires-Dist: ioc-scope-ontology>=1.1.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pytest; extra == "dev"
|
|
22
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
23
|
+
Requires-Dist: black; extra == "dev"
|
|
24
|
+
Requires-Dist: flake8; extra == "dev"
|
|
25
|
+
Requires-Dist: mypy; extra == "dev"
|
|
26
|
+
Requires-Dist: httpx; extra == "dev"
|
|
27
|
+
Provides-Extra: neo4j
|
|
28
|
+
Requires-Dist: neo4j>=6.1.0; extra == "neo4j"
|
|
29
|
+
Provides-Extra: deepeval
|
|
30
|
+
Requires-Dist: ioc-scope-mce-provider-deepeval>=0.1.0; extra == "deepeval"
|
|
31
|
+
Provides-Extra: llm
|
|
32
|
+
Requires-Dist: ioc-scope-mce-provider-native>=0.1.0; extra == "llm"
|
|
33
|
+
Provides-Extra: opik
|
|
34
|
+
Requires-Dist: ioc-scope-mce-provider-opik>=0.1.0; extra == "opik"
|
|
35
|
+
Provides-Extra: ragas
|
|
36
|
+
Requires-Dist: ioc-scope-mce-provider-ragas>=0.1.0; extra == "ragas"
|
|
37
|
+
Provides-Extra: server
|
|
38
|
+
Requires-Dist: fastapi>=0.111.0; extra == "server"
|
|
39
|
+
Requires-Dist: uvicorn>=0.30.0; extra == "server"
|
|
40
|
+
Provides-Extra: all
|
|
41
|
+
Requires-Dist: ioc-scope-mce-provider-native>=0.1.0; extra == "all"
|
|
42
|
+
Requires-Dist: ioc-scope-mce-provider-sdk>=0.1.0; extra == "all"
|
|
43
|
+
Requires-Dist: ioc-scope-mce-provider-deepeval>=0.1.0; extra == "all"
|
|
44
|
+
Requires-Dist: ioc-scope-mce-provider-opik>=0.1.0; extra == "all"
|
|
45
|
+
Requires-Dist: ioc-scope-mce-provider-ragas>=0.1.0; extra == "all"
|
|
46
|
+
Requires-Dist: fastapi>=0.111.0; extra == "all"
|
|
47
|
+
Requires-Dist: uvicorn>=0.30.0; extra == "all"
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ioc-scope-mce-core"
|
|
7
|
+
version = "2.0.0rc1"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "Outshift Open", email = "oss-github@cisco.com" }
|
|
10
|
+
]
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
description = "Metrics Computation Engine core"
|
|
13
|
+
requires-python = ">=3.13,<3.15"
|
|
14
|
+
dependencies = [
|
|
15
|
+
"pydantic>=2.0.0",
|
|
16
|
+
"click>=8.0.0",
|
|
17
|
+
"python-dotenv>=1.0.0",
|
|
18
|
+
"requests>=2.28.0",
|
|
19
|
+
"networkx>=3.0.0",
|
|
20
|
+
"packaging>=23.0",
|
|
21
|
+
"pandas>=1.5.0",
|
|
22
|
+
"pydantic-settings>=2.10.1",
|
|
23
|
+
"typer>=0.9.0",
|
|
24
|
+
"rdflib>=7.0.0",
|
|
25
|
+
"pyyaml>=6.0.0",
|
|
26
|
+
"ioc-scope-ontology>=1.1.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
dev = [
|
|
31
|
+
"pytest",
|
|
32
|
+
"pytest-asyncio",
|
|
33
|
+
"black",
|
|
34
|
+
"flake8",
|
|
35
|
+
"mypy",
|
|
36
|
+
"httpx",
|
|
37
|
+
]
|
|
38
|
+
neo4j = [
|
|
39
|
+
"neo4j>=6.1.0",
|
|
40
|
+
]
|
|
41
|
+
deepeval = [
|
|
42
|
+
"ioc-scope-mce-provider-deepeval>=0.1.0",
|
|
43
|
+
]
|
|
44
|
+
llm = [
|
|
45
|
+
"ioc-scope-mce-provider-native>=0.1.0",
|
|
46
|
+
]
|
|
47
|
+
opik = [
|
|
48
|
+
"ioc-scope-mce-provider-opik>=0.1.0",
|
|
49
|
+
]
|
|
50
|
+
ragas = [
|
|
51
|
+
"ioc-scope-mce-provider-ragas>=0.1.0",
|
|
52
|
+
]
|
|
53
|
+
server = [
|
|
54
|
+
"fastapi>=0.111.0",
|
|
55
|
+
"uvicorn>=0.30.0",
|
|
56
|
+
]
|
|
57
|
+
all = [
|
|
58
|
+
"ioc-scope-mce-provider-native>=0.1.0",
|
|
59
|
+
"ioc-scope-mce-provider-sdk>=0.1.0",
|
|
60
|
+
"ioc-scope-mce-provider-deepeval>=0.1.0",
|
|
61
|
+
"ioc-scope-mce-provider-opik>=0.1.0",
|
|
62
|
+
"ioc-scope-mce-provider-ragas>=0.1.0",
|
|
63
|
+
"fastapi>=0.111.0",
|
|
64
|
+
"uvicorn>=0.30.0",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
[tool.setuptools.packages.find]
|
|
68
|
+
where = ["src"]
|
|
69
|
+
|
|
70
|
+
[tool.setuptools.package-data]
|
|
71
|
+
"mce.engine" = ["data/*.json"]
|
|
72
|
+
|
|
73
|
+
[tool.uv.sources]
|
|
74
|
+
ioc-scope-mce-provider-native = { workspace = true }
|
|
75
|
+
ioc-scope-mce-provider-sdk = { workspace = true }
|
|
76
|
+
ioc-scope-mce-provider-deepeval = { workspace = true }
|
|
77
|
+
ioc-scope-mce-provider-opik = { workspace = true }
|
|
78
|
+
ioc-scope-mce-provider-ragas = { workspace = true }
|
|
79
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ioc-scope-mce-core
|
|
3
|
+
Version: 2.0.0rc1
|
|
4
|
+
Summary: Metrics Computation Engine core
|
|
5
|
+
Author-email: Outshift Open <oss-github@cisco.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Requires-Python: <3.15,>=3.13
|
|
8
|
+
Requires-Dist: pydantic>=2.0.0
|
|
9
|
+
Requires-Dist: click>=8.0.0
|
|
10
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
11
|
+
Requires-Dist: requests>=2.28.0
|
|
12
|
+
Requires-Dist: networkx>=3.0.0
|
|
13
|
+
Requires-Dist: packaging>=23.0
|
|
14
|
+
Requires-Dist: pandas>=1.5.0
|
|
15
|
+
Requires-Dist: pydantic-settings>=2.10.1
|
|
16
|
+
Requires-Dist: typer>=0.9.0
|
|
17
|
+
Requires-Dist: rdflib>=7.0.0
|
|
18
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
19
|
+
Requires-Dist: ioc-scope-ontology>=1.1.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pytest; extra == "dev"
|
|
22
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
23
|
+
Requires-Dist: black; extra == "dev"
|
|
24
|
+
Requires-Dist: flake8; extra == "dev"
|
|
25
|
+
Requires-Dist: mypy; extra == "dev"
|
|
26
|
+
Requires-Dist: httpx; extra == "dev"
|
|
27
|
+
Provides-Extra: neo4j
|
|
28
|
+
Requires-Dist: neo4j>=6.1.0; extra == "neo4j"
|
|
29
|
+
Provides-Extra: deepeval
|
|
30
|
+
Requires-Dist: ioc-scope-mce-provider-deepeval>=0.1.0; extra == "deepeval"
|
|
31
|
+
Provides-Extra: llm
|
|
32
|
+
Requires-Dist: ioc-scope-mce-provider-native>=0.1.0; extra == "llm"
|
|
33
|
+
Provides-Extra: opik
|
|
34
|
+
Requires-Dist: ioc-scope-mce-provider-opik>=0.1.0; extra == "opik"
|
|
35
|
+
Provides-Extra: ragas
|
|
36
|
+
Requires-Dist: ioc-scope-mce-provider-ragas>=0.1.0; extra == "ragas"
|
|
37
|
+
Provides-Extra: server
|
|
38
|
+
Requires-Dist: fastapi>=0.111.0; extra == "server"
|
|
39
|
+
Requires-Dist: uvicorn>=0.30.0; extra == "server"
|
|
40
|
+
Provides-Extra: all
|
|
41
|
+
Requires-Dist: ioc-scope-mce-provider-native>=0.1.0; extra == "all"
|
|
42
|
+
Requires-Dist: ioc-scope-mce-provider-sdk>=0.1.0; extra == "all"
|
|
43
|
+
Requires-Dist: ioc-scope-mce-provider-deepeval>=0.1.0; extra == "all"
|
|
44
|
+
Requires-Dist: ioc-scope-mce-provider-opik>=0.1.0; extra == "all"
|
|
45
|
+
Requires-Dist: ioc-scope-mce-provider-ragas>=0.1.0; extra == "all"
|
|
46
|
+
Requires-Dist: fastapi>=0.111.0; extra == "all"
|
|
47
|
+
Requires-Dist: uvicorn>=0.30.0; extra == "all"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
pyproject.toml
|
|
2
|
+
src/ioc_scope_mce_core.egg-info/PKG-INFO
|
|
3
|
+
src/ioc_scope_mce_core.egg-info/SOURCES.txt
|
|
4
|
+
src/ioc_scope_mce_core.egg-info/dependency_links.txt
|
|
5
|
+
src/ioc_scope_mce_core.egg-info/requires.txt
|
|
6
|
+
src/ioc_scope_mce_core.egg-info/top_level.txt
|
|
7
|
+
src/mce/__init__.py
|
|
8
|
+
src/mce/core/catalog.py
|
|
9
|
+
src/mce/core/config.py
|
|
10
|
+
src/mce/core/helpers.py
|
|
11
|
+
src/mce/core/metadata.py
|
|
12
|
+
src/mce/core/metric.py
|
|
13
|
+
src/mce/core/provider.py
|
|
14
|
+
src/mce/core/types.py
|
|
15
|
+
src/mce/core/registry/__init__.py
|
|
16
|
+
src/mce/core/registry/discovery.py
|
|
17
|
+
src/mce/core/registry/provider.py
|
|
18
|
+
src/mce/core/registry/service.py
|
|
19
|
+
src/mce/core/specs/__init__.py
|
|
20
|
+
src/mce/core/specs/_registry.py
|
|
21
|
+
src/mce/core/specs/agent_to_agent_interactions.py
|
|
22
|
+
src/mce/core/specs/agent_to_tool_interactions.py
|
|
23
|
+
src/mce/core/specs/answer_correctness.py
|
|
24
|
+
src/mce/core/specs/answer_relevancy.py
|
|
25
|
+
src/mce/core/specs/bias.py
|
|
26
|
+
src/mce/core/specs/call_count.py
|
|
27
|
+
src/mce/core/specs/coherence.py
|
|
28
|
+
src/mce/core/specs/completion_rate.py
|
|
29
|
+
src/mce/core/specs/component_conflict_rate.py
|
|
30
|
+
src/mce/core/specs/consistency.py
|
|
31
|
+
src/mce/core/specs/context_preservation.py
|
|
32
|
+
src/mce/core/specs/conversation_completeness.py
|
|
33
|
+
src/mce/core/specs/cost.py
|
|
34
|
+
src/mce/core/specs/cycles_count.py
|
|
35
|
+
src/mce/core/specs/duration.py
|
|
36
|
+
src/mce/core/specs/general_structure_and_style.py
|
|
37
|
+
src/mce/core/specs/goal_success_rate.py
|
|
38
|
+
src/mce/core/specs/graph_determinism_score.py
|
|
39
|
+
src/mce/core/specs/groundedness.py
|
|
40
|
+
src/mce/core/specs/hallucination.py
|
|
41
|
+
src/mce/core/specs/information_retention.py
|
|
42
|
+
src/mce/core/specs/intent_recognition_accuracy.py
|
|
43
|
+
src/mce/core/specs/llm_average_confidence.py
|
|
44
|
+
src/mce/core/specs/llm_error_rate.py
|
|
45
|
+
src/mce/core/specs/llm_maximum_confidence.py
|
|
46
|
+
src/mce/core/specs/llm_minimum_confidence.py
|
|
47
|
+
src/mce/core/specs/response_completeness.py
|
|
48
|
+
src/mce/core/specs/role_adherence.py
|
|
49
|
+
src/mce/core/specs/sentiment.py
|
|
50
|
+
src/mce/core/specs/task_completion.py
|
|
51
|
+
src/mce/core/specs/task_delegation_accuracy.py
|
|
52
|
+
src/mce/core/specs/token_count.py
|
|
53
|
+
src/mce/core/specs/tonality.py
|
|
54
|
+
src/mce/core/specs/tool_error.py
|
|
55
|
+
src/mce/core/specs/tool_error_rate.py
|
|
56
|
+
src/mce/core/specs/tool_utilization_accuracy.py
|
|
57
|
+
src/mce/core/specs/topic_adherence.py
|
|
58
|
+
src/mce/core/specs/toxicity.py
|
|
59
|
+
src/mce/core/specs/workflow_cohesion_index.py
|
|
60
|
+
src/mce/core/specs/workflow_efficiency.py
|
|
61
|
+
src/mce/engine/__init__.py
|
|
62
|
+
src/mce/engine/caching.py
|
|
63
|
+
src/mce/engine/context_builder.py
|
|
64
|
+
src/mce/engine/engine.py
|
|
65
|
+
src/mce/engine/llm.py
|
|
66
|
+
src/mce/engine/pricing.py
|
|
67
|
+
src/mce/engine/scheduler.py
|
|
68
|
+
src/mce/engine/strategies.py
|
|
69
|
+
src/mce/engine/usage.py
|
|
70
|
+
src/mce/engine/worker.py
|
|
71
|
+
src/mce/engine/data/model_prices.json
|
|
72
|
+
src/mce/providers/__init__.py
|
|
73
|
+
src/mce/providers/base_wrapper.py
|
|
74
|
+
src/mce/providers/catalog.py
|
|
75
|
+
src/mce/providers/template/__init__.py
|
|
76
|
+
src/mce/providers/virtual/aggregators.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
pydantic>=2.0.0
|
|
2
|
+
click>=8.0.0
|
|
3
|
+
python-dotenv>=1.0.0
|
|
4
|
+
requests>=2.28.0
|
|
5
|
+
networkx>=3.0.0
|
|
6
|
+
packaging>=23.0
|
|
7
|
+
pandas>=1.5.0
|
|
8
|
+
pydantic-settings>=2.10.1
|
|
9
|
+
typer>=0.9.0
|
|
10
|
+
rdflib>=7.0.0
|
|
11
|
+
pyyaml>=6.0.0
|
|
12
|
+
ioc-scope-ontology>=1.1.0
|
|
13
|
+
|
|
14
|
+
[all]
|
|
15
|
+
ioc-scope-mce-provider-native>=0.1.0
|
|
16
|
+
ioc-scope-mce-provider-sdk>=0.1.0
|
|
17
|
+
ioc-scope-mce-provider-deepeval>=0.1.0
|
|
18
|
+
ioc-scope-mce-provider-opik>=0.1.0
|
|
19
|
+
ioc-scope-mce-provider-ragas>=0.1.0
|
|
20
|
+
fastapi>=0.111.0
|
|
21
|
+
uvicorn>=0.30.0
|
|
22
|
+
|
|
23
|
+
[deepeval]
|
|
24
|
+
ioc-scope-mce-provider-deepeval>=0.1.0
|
|
25
|
+
|
|
26
|
+
[dev]
|
|
27
|
+
pytest
|
|
28
|
+
pytest-asyncio
|
|
29
|
+
black
|
|
30
|
+
flake8
|
|
31
|
+
mypy
|
|
32
|
+
httpx
|
|
33
|
+
|
|
34
|
+
[llm]
|
|
35
|
+
ioc-scope-mce-provider-native>=0.1.0
|
|
36
|
+
|
|
37
|
+
[neo4j]
|
|
38
|
+
neo4j>=6.1.0
|
|
39
|
+
|
|
40
|
+
[opik]
|
|
41
|
+
ioc-scope-mce-provider-opik>=0.1.0
|
|
42
|
+
|
|
43
|
+
[ragas]
|
|
44
|
+
ioc-scope-mce-provider-ragas>=0.1.0
|
|
45
|
+
|
|
46
|
+
[server]
|
|
47
|
+
fastapi>=0.111.0
|
|
48
|
+
uvicorn>=0.30.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mce
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Copyright (c) 2026 Cisco Systems, Inc. and its affiliates
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from pkgutil import extend_path
|
|
5
|
+
|
|
6
|
+
import warnings
|
|
7
|
+
|
|
8
|
+
# Allow multiple workspace packages to contribute to top-level `mce`.
|
|
9
|
+
__path__ = extend_path(__path__, __name__)
|
|
10
|
+
|
|
11
|
+
# Suppress Pydantic v1 compatibility warning from opik in Python 3.14+
|
|
12
|
+
# Must be at the top level before any other imports
|
|
13
|
+
warnings.filterwarnings(
|
|
14
|
+
"ignore",
|
|
15
|
+
message="Core Pydantic V1 functionality isn't compatible with Python 3.14 or greater",
|
|
16
|
+
category=UserWarning,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# Expose key public components
|
|
20
|
+
try:
|
|
21
|
+
from .core.types import MetricResult as MetricResult
|
|
22
|
+
from .core.metric import Metric as Metric
|
|
23
|
+
from .engine.engine import MetricEngine as MetricEngine
|
|
24
|
+
|
|
25
|
+
__all__ = ["MetricResult", "Metric", "MetricEngine"]
|
|
26
|
+
except ImportError:
|
|
27
|
+
__all__: list[str] = []
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# Copyright (c) 2026 Cisco Systems, Inc. and its affiliates
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import importlib
|
|
7
|
+
import inspect
|
|
8
|
+
import pkgutil
|
|
9
|
+
import threading
|
|
10
|
+
import statistics
|
|
11
|
+
from mce.core.metric import Metric
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
# Lazy imports for heavy dependencies
|
|
16
|
+
try:
|
|
17
|
+
from scope_ontology import OntologyService
|
|
18
|
+
except ImportError:
|
|
19
|
+
OntologyService = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class MetricCatalogService:
|
|
23
|
+
"""
|
|
24
|
+
Core Service: unified registry for Metric instances.
|
|
25
|
+
Supports lazy creation of templated aggregate (virtual) metrics.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
_instance = None
|
|
29
|
+
_lock = threading.Lock() # Guards singleton creation
|
|
30
|
+
|
|
31
|
+
def __init__(self):
|
|
32
|
+
self._contracts: dict[str, Metric | type[Metric]] = {}
|
|
33
|
+
self._unified_metrics: dict[str, list[Metric]] = {}
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def get_instance(cls):
|
|
37
|
+
"""Thread-safe singleton accessor."""
|
|
38
|
+
if cls._instance is None:
|
|
39
|
+
with cls._lock:
|
|
40
|
+
if cls._instance is None: # double-checked locking
|
|
41
|
+
cls._instance = MetricCatalogService()
|
|
42
|
+
return cls._instance
|
|
43
|
+
|
|
44
|
+
def register_metric(self, metric: Metric | type[Metric]) -> None:
|
|
45
|
+
"""Register a unified Metric plugin or abstract Base."""
|
|
46
|
+
if isinstance(metric, type):
|
|
47
|
+
# Abstract Class registration
|
|
48
|
+
if not hasattr(metric, "metadata"):
|
|
49
|
+
return # Skip if no metadata
|
|
50
|
+
mid = metric.metadata.name
|
|
51
|
+
self._contracts[mid] = metric
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
# Instance registration
|
|
55
|
+
mid = metric.metric_id
|
|
56
|
+
if mid not in self._contracts:
|
|
57
|
+
self._contracts[mid] = metric
|
|
58
|
+
|
|
59
|
+
if mid not in self._unified_metrics:
|
|
60
|
+
self._unified_metrics[mid] = []
|
|
61
|
+
self._unified_metrics[mid].append(metric)
|
|
62
|
+
|
|
63
|
+
def get_contract(self, metric_id: str) -> Metric | type[Metric] | None:
|
|
64
|
+
"""Look up a registered contract (or unified metric) by ID."""
|
|
65
|
+
return self._contracts.get(metric_id)
|
|
66
|
+
|
|
67
|
+
def get_metric(self, metric_id: str) -> Metric | None:
|
|
68
|
+
"""
|
|
69
|
+
Get a unified metric instance.
|
|
70
|
+
|
|
71
|
+
**Lazy Loading for Templated Aggregates** (Option C):
|
|
72
|
+
If metric_id matches pattern "operation_BaseMetric" (e.g., "avg_AnswerRelevancy"),
|
|
73
|
+
automatically create and cache an AggregateMetric instance.
|
|
74
|
+
|
|
75
|
+
Supported operations:
|
|
76
|
+
- avg_* → AverageMetric(base_metric)
|
|
77
|
+
- max_* → AggregateMetric(base_metric, "max", max)
|
|
78
|
+
- min_* → AggregateMetric(base_metric, "min", min)
|
|
79
|
+
- sum_* → AggregateMetric(base_metric, "sum", sum)
|
|
80
|
+
"""
|
|
81
|
+
# Check if already registered
|
|
82
|
+
metrics = self._unified_metrics.get(metric_id, [])
|
|
83
|
+
if metrics:
|
|
84
|
+
return metrics[0]
|
|
85
|
+
|
|
86
|
+
# Lazy loading: detect templated aggregate pattern
|
|
87
|
+
operation_mapping = {
|
|
88
|
+
"avg": ("avg", "AverageMetric"),
|
|
89
|
+
"max": ("max", "max"),
|
|
90
|
+
"min": ("min", "min"),
|
|
91
|
+
"sum": ("sum", "sum"),
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
for prefix, (op_name, op_type) in operation_mapping.items():
|
|
95
|
+
if metric_id.startswith(f"{prefix}_"):
|
|
96
|
+
base_metric_id = metric_id[len(prefix) + 1 :] # Remove "avg_" prefix
|
|
97
|
+
|
|
98
|
+
# Validate base metric exists
|
|
99
|
+
if base_metric_id not in self._contracts:
|
|
100
|
+
return None # Base metric not found, cannot create aggregate
|
|
101
|
+
|
|
102
|
+
# Import and instantiate appropriate aggregate metric
|
|
103
|
+
if op_type == "AverageMetric":
|
|
104
|
+
from mce.providers.virtual.aggregators import AverageMetric
|
|
105
|
+
|
|
106
|
+
aggregate_metric = AverageMetric(target_metric_id=base_metric_id)
|
|
107
|
+
else:
|
|
108
|
+
# max / min / sum operations
|
|
109
|
+
from mce.providers.virtual.aggregators import AggregateMetric
|
|
110
|
+
|
|
111
|
+
# Fix #20: statistics imported at module level
|
|
112
|
+
op_fn_map = {
|
|
113
|
+
"max": max,
|
|
114
|
+
"min": min,
|
|
115
|
+
"sum": sum,
|
|
116
|
+
"avg": statistics.mean,
|
|
117
|
+
}
|
|
118
|
+
aggregate_metric = AggregateMetric(
|
|
119
|
+
target_metric_id=base_metric_id,
|
|
120
|
+
operation_name=op_name,
|
|
121
|
+
operation_fn=op_fn_map[op_name],
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Resolve target_types for the new metric
|
|
125
|
+
self._resolve_target_types(aggregate_metric)
|
|
126
|
+
|
|
127
|
+
# Register the lazily created metric
|
|
128
|
+
self.register_metric(aggregate_metric)
|
|
129
|
+
return aggregate_metric
|
|
130
|
+
|
|
131
|
+
return None
|
|
132
|
+
|
|
133
|
+
def _resolve_target_types(self, metric: "Metric") -> None:
|
|
134
|
+
"""Resolve target_types for a lazily created aggregate metric.
|
|
135
|
+
|
|
136
|
+
Fix #16: delegates to the single source of truth in discovery.py
|
|
137
|
+
(ensure_target_types) instead of duplicating the mapping logic here.
|
|
138
|
+
The lazy import avoids the circular dependency
|
|
139
|
+
(catalog → discovery → catalog).
|
|
140
|
+
"""
|
|
141
|
+
from mce.core.registry.discovery import (
|
|
142
|
+
ensure_target_types,
|
|
143
|
+
) # lazy — avoids circular import
|
|
144
|
+
|
|
145
|
+
ensure_target_types(metric)
|
|
146
|
+
|
|
147
|
+
# If ensure_target_types could not resolve (no scope/attachment_point),
|
|
148
|
+
# fall back to ontology_class-based mapping for aggregate metrics which
|
|
149
|
+
# inherit the base metric's class name rather than a MAS prefix.
|
|
150
|
+
md = metric.metadata
|
|
151
|
+
if not getattr(md, "target_types", None):
|
|
152
|
+
ap = md.attachment_point
|
|
153
|
+
if ap and OntologyService is not None:
|
|
154
|
+
try:
|
|
155
|
+
onto = OntologyService.get_instance()
|
|
156
|
+
md.target_types = onto.get_subclasses_of(ap)
|
|
157
|
+
return
|
|
158
|
+
except Exception as e:
|
|
159
|
+
logger.warning(
|
|
160
|
+
"OntologyService.get_subclasses_of(%r) failed: %s — "
|
|
161
|
+
"falling back to ontology_class mapping for '%s'.",
|
|
162
|
+
ap,
|
|
163
|
+
e,
|
|
164
|
+
md.name,
|
|
165
|
+
)
|
|
166
|
+
# Last resort: map known ontology_class strings.
|
|
167
|
+
_class_map = {
|
|
168
|
+
"Session": {"mas:Session"},
|
|
169
|
+
"LLMCall": {"mas:LLMCall"},
|
|
170
|
+
"mas:LLMCall": {"mas:LLMCall"},
|
|
171
|
+
"ToolCall": {"mas:ToolCall"},
|
|
172
|
+
"mas:ToolCall": {"mas:ToolCall"},
|
|
173
|
+
}
|
|
174
|
+
md.target_types = _class_map.get(md.ontology_class, set())
|
|
175
|
+
|
|
176
|
+
def get_all_contracts(self) -> list[Metric | type[Metric]]:
|
|
177
|
+
return list(self._contracts.values())
|
|
178
|
+
|
|
179
|
+
def discover_metrics(self, package_path: str = "mce.metrics"):
|
|
180
|
+
"""Auto-discover concrete Metric subclasses in the specified package."""
|
|
181
|
+
try:
|
|
182
|
+
module = importlib.import_module(package_path)
|
|
183
|
+
path = getattr(module, "__path__", [])
|
|
184
|
+
# NOTE: use module_name (not `name`) so the inner member loop cannot
|
|
185
|
+
# shadow the outer iteration variable — that was a silent bug.
|
|
186
|
+
# Fix #5: use walk_packages (recursive) instead of iter_modules (single-level)
|
|
187
|
+
# so metrics in sub-packages are not silently dropped.
|
|
188
|
+
for _, module_name, _ in pkgutil.walk_packages(
|
|
189
|
+
path, prefix=f"{package_path}."
|
|
190
|
+
):
|
|
191
|
+
sub_module = importlib.import_module(module_name)
|
|
192
|
+
for member_name, obj in inspect.getmembers(sub_module):
|
|
193
|
+
if (
|
|
194
|
+
inspect.isclass(obj)
|
|
195
|
+
and issubclass(obj, Metric)
|
|
196
|
+
and obj is not Metric
|
|
197
|
+
):
|
|
198
|
+
if inspect.isabstract(obj):
|
|
199
|
+
continue # Skip abstract bases
|
|
200
|
+
try:
|
|
201
|
+
instance = obj()
|
|
202
|
+
self.register_metric(instance)
|
|
203
|
+
except Exception as e:
|
|
204
|
+
logger.warning(
|
|
205
|
+
"Failed to instantiate metric %s: %s", member_name, e
|
|
206
|
+
)
|
|
207
|
+
except ImportError as e:
|
|
208
|
+
logger.warning("Could not import package %s: %s", package_path, e)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Copyright (c) 2026 Cisco Systems, Inc. and its affiliates
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MceSettings(BaseSettings):
|
|
9
|
+
"""
|
|
10
|
+
Configuration for the MCE library.
|
|
11
|
+
Settings can be overridden by environment variables with the prefix MCE_.
|
|
12
|
+
|
|
13
|
+
Provider availability is determined automatically: if a package is importable
|
|
14
|
+
(e.g. deepeval, ragas, opik) its metrics are discovered and registered.
|
|
15
|
+
Install the metapackage to get everything, or install individual provider
|
|
16
|
+
packages to pick only what you need.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
strict_fail_fast: bool = Field(
|
|
20
|
+
default=False, description="Raise exceptions on provider initialization failure"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
model_config = SettingsConfigDict(
|
|
24
|
+
env_prefix="MCE_",
|
|
25
|
+
env_file=".env",
|
|
26
|
+
env_file_encoding="utf-8",
|
|
27
|
+
case_sensitive=False,
|
|
28
|
+
extra="ignore",
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Global settings instance
|
|
33
|
+
settings = MceSettings()
|