minder-cli 0.2.0__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.
- minder/__init__.py +12 -0
- minder/api/routers/prompts.py +177 -0
- minder/application/__init__.py +1 -0
- minder/application/admin/__init__.py +11 -0
- minder/application/admin/dto.py +453 -0
- minder/application/admin/jobs.py +327 -0
- minder/application/admin/use_cases.py +1895 -0
- minder/auth/__init__.py +12 -0
- minder/auth/context.py +26 -0
- minder/auth/middleware.py +70 -0
- minder/auth/principal.py +59 -0
- minder/auth/rate_limiter.py +89 -0
- minder/auth/rbac.py +60 -0
- minder/auth/service.py +541 -0
- minder/bootstrap/__init__.py +9 -0
- minder/bootstrap/providers.py +109 -0
- minder/bootstrap/transport.py +807 -0
- minder/cache/__init__.py +10 -0
- minder/cache/providers.py +140 -0
- minder/chunking/__init__.py +4 -0
- minder/chunking/code_splitter.py +184 -0
- minder/chunking/splitter.py +136 -0
- minder/cli.py +1542 -0
- minder/config.py +179 -0
- minder/continuity.py +363 -0
- minder/dev.py +160 -0
- minder/embedding/__init__.py +9 -0
- minder/embedding/base.py +7 -0
- minder/embedding/local.py +65 -0
- minder/embedding/openai.py +7 -0
- minder/graph/__init__.py +11 -0
- minder/graph/edges.py +13 -0
- minder/graph/executor.py +127 -0
- minder/graph/graph.py +263 -0
- minder/graph/nodes/__init__.py +27 -0
- minder/graph/nodes/evaluator.py +21 -0
- minder/graph/nodes/guard.py +64 -0
- minder/graph/nodes/llm.py +59 -0
- minder/graph/nodes/planning.py +30 -0
- minder/graph/nodes/reasoning.py +87 -0
- minder/graph/nodes/reranker.py +141 -0
- minder/graph/nodes/retriever.py +86 -0
- minder/graph/nodes/verification.py +230 -0
- minder/graph/nodes/workflow_planner.py +250 -0
- minder/graph/runtime.py +15 -0
- minder/graph/state.py +26 -0
- minder/llm/__init__.py +5 -0
- minder/llm/base.py +14 -0
- minder/llm/local.py +381 -0
- minder/llm/openai.py +89 -0
- minder/models/__init__.py +109 -0
- minder/models/base.py +10 -0
- minder/models/client.py +137 -0
- minder/models/document.py +34 -0
- minder/models/error.py +32 -0
- minder/models/graph.py +114 -0
- minder/models/history.py +32 -0
- minder/models/job.py +62 -0
- minder/models/prompt.py +41 -0
- minder/models/repository.py +62 -0
- minder/models/rule.py +68 -0
- minder/models/session.py +51 -0
- minder/models/skill.py +52 -0
- minder/models/user.py +41 -0
- minder/models/workflow.py +35 -0
- minder/observability/__init__.py +57 -0
- minder/observability/audit.py +243 -0
- minder/observability/logging.py +253 -0
- minder/observability/metrics.py +448 -0
- minder/observability/tracing.py +215 -0
- minder/presentation/__init__.py +1 -0
- minder/presentation/http/__init__.py +1 -0
- minder/presentation/http/admin/__init__.py +3 -0
- minder/presentation/http/admin/api.py +1309 -0
- minder/presentation/http/admin/context.py +94 -0
- minder/presentation/http/admin/dashboard.py +111 -0
- minder/presentation/http/admin/jobs.py +208 -0
- minder/presentation/http/admin/memories.py +185 -0
- minder/presentation/http/admin/prompts.py +219 -0
- minder/presentation/http/admin/routes.py +127 -0
- minder/presentation/http/admin/runtime.py +650 -0
- minder/presentation/http/admin/search.py +368 -0
- minder/presentation/http/admin/skills.py +230 -0
- minder/prompts/__init__.py +646 -0
- minder/prompts/formatter.py +142 -0
- minder/resources/__init__.py +318 -0
- minder/retrieval/__init__.py +5 -0
- minder/retrieval/hybrid.py +178 -0
- minder/retrieval/mmr.py +116 -0
- minder/retrieval/multi_hop.py +115 -0
- minder/runtime.py +15 -0
- minder/server.py +145 -0
- minder/store/__init__.py +64 -0
- minder/store/document.py +115 -0
- minder/store/error.py +82 -0
- minder/store/feedback.py +114 -0
- minder/store/graph.py +588 -0
- minder/store/history.py +57 -0
- minder/store/interfaces.py +512 -0
- minder/store/milvus/__init__.py +11 -0
- minder/store/milvus/client.py +26 -0
- minder/store/milvus/collections.py +15 -0
- minder/store/milvus/vector_store.py +232 -0
- minder/store/mongodb/__init__.py +11 -0
- minder/store/mongodb/client.py +49 -0
- minder/store/mongodb/indexes.py +90 -0
- minder/store/mongodb/operational_store.py +993 -0
- minder/store/relational.py +1087 -0
- minder/store/repo_state.py +58 -0
- minder/store/rule.py +93 -0
- minder/store/vector.py +79 -0
- minder/tools/__init__.py +47 -0
- minder/tools/auth.py +94 -0
- minder/tools/graph.py +839 -0
- minder/tools/ingest.py +353 -0
- minder/tools/memory.py +381 -0
- minder/tools/query.py +307 -0
- minder/tools/registry.py +269 -0
- minder/tools/repo_scanner.py +1266 -0
- minder/tools/search.py +15 -0
- minder/tools/session.py +316 -0
- minder/tools/skills.py +899 -0
- minder/tools/workflow.py +215 -0
- minder/transport/__init__.py +4 -0
- minder/transport/base.py +286 -0
- minder/transport/sse.py +252 -0
- minder/transport/stdio.py +29 -0
- minder_cli-0.2.0.dist-info/METADATA +318 -0
- minder_cli-0.2.0.dist-info/RECORD +132 -0
- minder_cli-0.2.0.dist-info/WHEEL +4 -0
- minder_cli-0.2.0.dist-info/entry_points.txt +2 -0
- minder_cli-0.2.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""OpenTelemetry tracing helpers for Minder.
|
|
2
|
+
|
|
3
|
+
The module uses a graceful-degradation pattern: it tries to import the
|
|
4
|
+
``opentelemetry`` packages at import time. If they are not installed the
|
|
5
|
+
module falls back to a lightweight no-op implementation so the rest of the
|
|
6
|
+
codebase can import and call ``get_tracer`` / ``trace_async`` / ``start_span``
|
|
7
|
+
unconditionally without a hard dependency on the OTel SDK.
|
|
8
|
+
|
|
9
|
+
Installing the SDK is opt-in:
|
|
10
|
+
uv add opentelemetry-api opentelemetry-sdk
|
|
11
|
+
|
|
12
|
+
The OTLP exporter is also optional:
|
|
13
|
+
uv add opentelemetry-exporter-otlp-proto-grpc
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import functools
|
|
18
|
+
import logging
|
|
19
|
+
from contextlib import asynccontextmanager, contextmanager
|
|
20
|
+
from typing import Any, AsyncIterator, Callable, Iterator, TypeVar
|
|
21
|
+
|
|
22
|
+
_log = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
F = TypeVar("F", bound=Callable[..., Any])
|
|
25
|
+
|
|
26
|
+
# ---------------------------------------------------------------------------
|
|
27
|
+
# Try to import the real OTel SDK
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
from opentelemetry import trace as _otel_trace # type: ignore[import-not-found,import-untyped]
|
|
32
|
+
from opentelemetry.sdk.resources import Resource # type: ignore[import-not-found,import-untyped]
|
|
33
|
+
from opentelemetry.sdk.trace import TracerProvider # type: ignore[import-not-found,import-untyped]
|
|
34
|
+
from opentelemetry.sdk.trace.export import ( # type: ignore[import-not-found,import-untyped]
|
|
35
|
+
BatchSpanProcessor,
|
|
36
|
+
ConsoleSpanExporter,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
_OTEL_AVAILABLE = True
|
|
40
|
+
except ImportError: # pragma: no cover – OTel is optional
|
|
41
|
+
_OTEL_AVAILABLE = False
|
|
42
|
+
|
|
43
|
+
# ---------------------------------------------------------------------------
|
|
44
|
+
# Global tracer provider reference
|
|
45
|
+
# ---------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
_provider: Any = None # TracerProvider | None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _is_configured() -> bool:
|
|
51
|
+
return _provider is not None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# ---------------------------------------------------------------------------
|
|
55
|
+
# Initialisation
|
|
56
|
+
# ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def configure_tracing(
|
|
60
|
+
service_name: str = "minder",
|
|
61
|
+
service_version: str = "0.1.0",
|
|
62
|
+
*,
|
|
63
|
+
otlp_endpoint: str | None = None,
|
|
64
|
+
console_export: bool = False,
|
|
65
|
+
) -> None:
|
|
66
|
+
"""Initialise the OTel tracer provider.
|
|
67
|
+
|
|
68
|
+
Call once at server startup (from ``bootstrap/providers.py``).
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
service_name: OTel ``service.name`` resource attribute.
|
|
72
|
+
service_version: OTel ``service.version`` resource attribute.
|
|
73
|
+
otlp_endpoint: gRPC OTLP collector endpoint, e.g.
|
|
74
|
+
``"http://otel-collector:4317"``. When *None* and
|
|
75
|
+
*console_export* is *False*, a no-op provider is used.
|
|
76
|
+
console_export: Emit spans to stdout (useful for local debugging).
|
|
77
|
+
"""
|
|
78
|
+
global _provider # noqa: PLW0603
|
|
79
|
+
|
|
80
|
+
if not _OTEL_AVAILABLE:
|
|
81
|
+
_log.info(
|
|
82
|
+
"opentelemetry-sdk not installed — tracing disabled. "
|
|
83
|
+
"Run `uv add opentelemetry-api opentelemetry-sdk` to enable."
|
|
84
|
+
)
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
resource = Resource.create(
|
|
88
|
+
{"service.name": service_name, "service.version": service_version}
|
|
89
|
+
)
|
|
90
|
+
provider = TracerProvider(resource=resource)
|
|
91
|
+
|
|
92
|
+
if console_export:
|
|
93
|
+
provider.add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
|
|
94
|
+
elif otlp_endpoint:
|
|
95
|
+
try:
|
|
96
|
+
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( # type: ignore[import-not-found,import-untyped]
|
|
97
|
+
OTLPSpanExporter,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
provider.add_span_processor(
|
|
101
|
+
BatchSpanProcessor(OTLPSpanExporter(endpoint=otlp_endpoint))
|
|
102
|
+
)
|
|
103
|
+
except ImportError:
|
|
104
|
+
_log.warning(
|
|
105
|
+
"opentelemetry-exporter-otlp-proto-grpc not installed; "
|
|
106
|
+
"OTLP tracing export disabled."
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
_otel_trace.set_tracer_provider(provider)
|
|
110
|
+
_provider = provider
|
|
111
|
+
_log.info(
|
|
112
|
+
"OTel tracing configured (service=%s, console=%s, otlp=%s).",
|
|
113
|
+
service_name,
|
|
114
|
+
console_export,
|
|
115
|
+
otlp_endpoint,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# ---------------------------------------------------------------------------
|
|
120
|
+
# No-op span context manager (fallback)
|
|
121
|
+
# ---------------------------------------------------------------------------
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class _NoOpSpan:
|
|
125
|
+
"""Minimal span interface used when OTel is not available."""
|
|
126
|
+
|
|
127
|
+
def set_attribute(self, key: str, value: Any) -> None: # noqa: ARG002
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
def record_exception(self, exc: BaseException) -> None: # noqa: ARG002
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
def set_status(self, *args: Any, **kwargs: Any) -> None:
|
|
134
|
+
pass
|
|
135
|
+
|
|
136
|
+
def __enter__(self) -> "_NoOpSpan":
|
|
137
|
+
return self
|
|
138
|
+
|
|
139
|
+
def __exit__(self, *_: Any) -> None:
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# ---------------------------------------------------------------------------
|
|
144
|
+
# Public helpers
|
|
145
|
+
# ---------------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def get_tracer(name: str) -> Any:
|
|
149
|
+
"""Return an OTel tracer (or a minimal no-op tracer).
|
|
150
|
+
|
|
151
|
+
The returned object supports ``tracer.start_as_current_span(name)`` and
|
|
152
|
+
``tracer.start_span(name)`` with the standard OTel API surface.
|
|
153
|
+
"""
|
|
154
|
+
if _OTEL_AVAILABLE and _is_configured():
|
|
155
|
+
return _otel_trace.get_tracer(name)
|
|
156
|
+
return _NoOpTracer()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class _NoOpTracer:
|
|
160
|
+
"""No-op tracer returned when OTel SDK is absent or not configured."""
|
|
161
|
+
|
|
162
|
+
@contextmanager
|
|
163
|
+
def start_as_current_span(self, name: str, **_kwargs: Any) -> Iterator[_NoOpSpan]: # noqa: ARG002
|
|
164
|
+
yield _NoOpSpan()
|
|
165
|
+
|
|
166
|
+
def start_span(self, name: str, **_kwargs: Any) -> _NoOpSpan: # noqa: ARG002
|
|
167
|
+
return _NoOpSpan()
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
@contextmanager
|
|
171
|
+
def start_span(name: str, tracer_name: str = "minder") -> Iterator[Any]:
|
|
172
|
+
"""Context manager that starts a named span (no-op if OTel unavailable)."""
|
|
173
|
+
tracer = get_tracer(tracer_name)
|
|
174
|
+
with tracer.start_as_current_span(name) as span:
|
|
175
|
+
yield span
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@asynccontextmanager
|
|
179
|
+
async def async_span(name: str, tracer_name: str = "minder") -> AsyncIterator[Any]:
|
|
180
|
+
"""Async context manager that starts a named span."""
|
|
181
|
+
tracer = get_tracer(tracer_name)
|
|
182
|
+
with tracer.start_as_current_span(name) as span:
|
|
183
|
+
yield span
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def trace_async(
|
|
187
|
+
span_name: str | None = None,
|
|
188
|
+
tracer_name: str = "minder",
|
|
189
|
+
) -> Callable[[F], F]:
|
|
190
|
+
"""Decorator that wraps an async function in an OTel span.
|
|
191
|
+
|
|
192
|
+
Example::
|
|
193
|
+
|
|
194
|
+
@trace_async("graph.retriever.run")
|
|
195
|
+
async def run(self, state):
|
|
196
|
+
...
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
def decorator(fn: F) -> F:
|
|
200
|
+
name = span_name or f"{fn.__module__}.{fn.__qualname__}"
|
|
201
|
+
|
|
202
|
+
@functools.wraps(fn)
|
|
203
|
+
async def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
204
|
+
async with async_span(name, tracer_name=tracer_name) as span:
|
|
205
|
+
try:
|
|
206
|
+
result = await fn(*args, **kwargs)
|
|
207
|
+
return result
|
|
208
|
+
except Exception as exc:
|
|
209
|
+
if hasattr(span, "record_exception"):
|
|
210
|
+
span.record_exception(exc)
|
|
211
|
+
raise
|
|
212
|
+
|
|
213
|
+
return wrapper # type: ignore[return-value]
|
|
214
|
+
|
|
215
|
+
return decorator
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__all__: list[str] = []
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__all__: list[str] = []
|