loopy-agent 0.4.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.
- loopy/__init__.py +153 -0
- loopy/_types.pyi +520 -0
- loopy/agents.py +604 -0
- loopy/cache.py +236 -0
- loopy/cli.py +326 -0
- loopy/evals.py +447 -0
- loopy/gateway.py +409 -0
- loopy/guardrails.py +226 -0
- loopy/loop.py +171 -0
- loopy/mcp.py +216 -0
- loopy/middleware.py +460 -0
- loopy/observe.py +380 -0
- loopy/plugins/__init__.py +353 -0
- loopy/plugins/audio.py +244 -0
- loopy/plugins/marketplace.py +284 -0
- loopy/plugins/memory.py +309 -0
- loopy/plugins/rag.py +269 -0
- loopy/plugins/tools.py +297 -0
- loopy/py.typed +0 -0
- loopy_agent-0.4.0.dist-info/METADATA +816 -0
- loopy_agent-0.4.0.dist-info/RECORD +23 -0
- loopy_agent-0.4.0.dist-info/WHEEL +4 -0
- loopy_agent-0.4.0.dist-info/entry_points.txt +2 -0
loopy/__init__.py
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Loopy — 8 Essential AI Concepts in one toolkit.
|
|
3
|
+
|
|
4
|
+
Modules:
|
|
5
|
+
loop - Agentic loop engine (Plan → Act → Observe → Reflect)
|
|
6
|
+
gateway - Multi-provider LLM routing with auth & rate limiting
|
|
7
|
+
guardrails - PII detection, jailbreak filtering, output safety
|
|
8
|
+
evals - Judge-based model evaluation framework
|
|
9
|
+
cache - Semantic token caching for cost optimization
|
|
10
|
+
observe - Traces, logs, and metrics for LLM observability
|
|
11
|
+
mcp - Model Context Protocol client
|
|
12
|
+
agents - Multi-agent orchestration with subagents
|
|
13
|
+
|
|
14
|
+
v0.2.0 additions:
|
|
15
|
+
- Evaluator-optimizer pattern (EvalGate, JudgeConfig)
|
|
16
|
+
- Orchestrator-workers pattern (Router, TaskDecomposer)
|
|
17
|
+
- Async context managers and connection pooling
|
|
18
|
+
- New middleware: Retry, CircuitBreaker, Fallback
|
|
19
|
+
|
|
20
|
+
v0.3.0 additions:
|
|
21
|
+
- OpenTelemetry export for traces/metrics
|
|
22
|
+
- First-party plugins: RAG, Tools, Memory
|
|
23
|
+
- Plugin marketplace support
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from loopy.loop import AgentLoop, StepResult, LoopConfig, StepStatus
|
|
27
|
+
from loopy.gateway import Gateway, ModelProvider, ProviderConfig, GatewayResponse, ConnectionPool
|
|
28
|
+
from loopy.guardrails import GuardrailPipeline, InputFilter, OutputFilter, FilterAction
|
|
29
|
+
from loopy.evals import (
|
|
30
|
+
Evaluator, EvalCase, EvalResult, EvalSuite, Verdict,
|
|
31
|
+
EvalGate, EvalGateType, JudgeConfig, EvalGateResult,
|
|
32
|
+
)
|
|
33
|
+
from loopy.cache import LLMCache, CacheStats
|
|
34
|
+
from loopy.observe import Tracer, Span, SpanStatus, MetricsCollector
|
|
35
|
+
from loopy.mcp import MCPClient, Tool, LocalMCP
|
|
36
|
+
from loopy.agents import (
|
|
37
|
+
Orchestrator, SubAgent, AgentResult, AgentStatus,
|
|
38
|
+
Router, RoutingRule, TaskDecomposer, SubTask,
|
|
39
|
+
)
|
|
40
|
+
from loopy.middleware import (
|
|
41
|
+
Middleware,
|
|
42
|
+
MiddlewarePipeline,
|
|
43
|
+
MiddlewareContext,
|
|
44
|
+
FunctionMiddleware,
|
|
45
|
+
LoggingMiddleware,
|
|
46
|
+
TimingMiddleware,
|
|
47
|
+
RateLimitMiddleware,
|
|
48
|
+
CacheMiddleware,
|
|
49
|
+
ValidationMiddleware,
|
|
50
|
+
RetryMiddleware,
|
|
51
|
+
CircuitBreakerMiddleware,
|
|
52
|
+
FallbackMiddleware,
|
|
53
|
+
)
|
|
54
|
+
from loopy.plugins import Plugin, PluginRegistry, PluginLoader, PluginInfo
|
|
55
|
+
|
|
56
|
+
# First-party plugins (lazy import to avoid circular deps)
|
|
57
|
+
try:
|
|
58
|
+
from loopy.plugins.rag import RAGPlugin, Document, Retriever
|
|
59
|
+
from loopy.plugins.tools import ToolsPlugin, Tool, ToolResult
|
|
60
|
+
from loopy.plugins.memory import MemoryPlugin, Memory, MemoryStore
|
|
61
|
+
from loopy.plugins.audio import AudioPlugin, SpeechToText, TextToSpeech
|
|
62
|
+
from loopy.plugins.marketplace import MarketplacePlugin, PluginMarketplace
|
|
63
|
+
except ImportError:
|
|
64
|
+
pass # Optional dependencies
|
|
65
|
+
|
|
66
|
+
from loopy.observe import TraceExporter
|
|
67
|
+
|
|
68
|
+
__version__ = "0.4.0"
|
|
69
|
+
|
|
70
|
+
__all__ = [
|
|
71
|
+
# Agentic Loop
|
|
72
|
+
"AgentLoop",
|
|
73
|
+
"StepResult",
|
|
74
|
+
"LoopConfig",
|
|
75
|
+
"StepStatus",
|
|
76
|
+
# Gateway
|
|
77
|
+
"Gateway",
|
|
78
|
+
"ModelProvider",
|
|
79
|
+
"ProviderConfig",
|
|
80
|
+
"GatewayResponse",
|
|
81
|
+
"ConnectionPool",
|
|
82
|
+
# Guardrails
|
|
83
|
+
"GuardrailPipeline",
|
|
84
|
+
"InputFilter",
|
|
85
|
+
"OutputFilter",
|
|
86
|
+
"FilterAction",
|
|
87
|
+
# Evals (including v0.2.0 evaluator-optimizer)
|
|
88
|
+
"Evaluator",
|
|
89
|
+
"EvalCase",
|
|
90
|
+
"EvalResult",
|
|
91
|
+
"EvalSuite",
|
|
92
|
+
"Verdict",
|
|
93
|
+
"EvalGate",
|
|
94
|
+
"EvalGateType",
|
|
95
|
+
"JudgeConfig",
|
|
96
|
+
"EvalGateResult",
|
|
97
|
+
# Cache
|
|
98
|
+
"LLMCache",
|
|
99
|
+
"CacheStats",
|
|
100
|
+
# Observability
|
|
101
|
+
"Tracer",
|
|
102
|
+
"Span",
|
|
103
|
+
"SpanStatus",
|
|
104
|
+
"MetricsCollector",
|
|
105
|
+
# MCP
|
|
106
|
+
"MCPClient",
|
|
107
|
+
"Tool",
|
|
108
|
+
"LocalMCP",
|
|
109
|
+
# Multi-Agent (including v0.2.0 orchestrator-workers)
|
|
110
|
+
"Orchestrator",
|
|
111
|
+
"SubAgent",
|
|
112
|
+
"AgentResult",
|
|
113
|
+
"AgentStatus",
|
|
114
|
+
"Router",
|
|
115
|
+
"RoutingRule",
|
|
116
|
+
"TaskDecomposer",
|
|
117
|
+
"SubTask",
|
|
118
|
+
# Middleware (including v0.2.0 new middleware)
|
|
119
|
+
"Middleware",
|
|
120
|
+
"MiddlewarePipeline",
|
|
121
|
+
"MiddlewareContext",
|
|
122
|
+
"FunctionMiddleware",
|
|
123
|
+
"LoggingMiddleware",
|
|
124
|
+
"TimingMiddleware",
|
|
125
|
+
"RateLimitMiddleware",
|
|
126
|
+
"CacheMiddleware",
|
|
127
|
+
"ValidationMiddleware",
|
|
128
|
+
"RetryMiddleware",
|
|
129
|
+
"CircuitBreakerMiddleware",
|
|
130
|
+
"FallbackMiddleware",
|
|
131
|
+
# Plugins
|
|
132
|
+
"Plugin",
|
|
133
|
+
"PluginRegistry",
|
|
134
|
+
"PluginLoader",
|
|
135
|
+
"PluginInfo",
|
|
136
|
+
# First-party plugins
|
|
137
|
+
"RAGPlugin",
|
|
138
|
+
"Document",
|
|
139
|
+
"Retriever",
|
|
140
|
+
"ToolsPlugin",
|
|
141
|
+
"Tool",
|
|
142
|
+
"ToolResult",
|
|
143
|
+
"MemoryPlugin",
|
|
144
|
+
"Memory",
|
|
145
|
+
"MemoryStore",
|
|
146
|
+
"AudioPlugin",
|
|
147
|
+
"SpeechToText",
|
|
148
|
+
"TextToSpeech",
|
|
149
|
+
"MarketplacePlugin",
|
|
150
|
+
"PluginMarketplace",
|
|
151
|
+
# Observability exports
|
|
152
|
+
"TraceExporter",
|
|
153
|
+
]
|
loopy/_types.pyi
ADDED
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Type stubs for loopy package.
|
|
3
|
+
|
|
4
|
+
Provides complete type hints for IDE autocompletion and static analysis.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any, Callable, Awaitable, Protocol, TypeVar, Generic, overload
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from enum import Enum
|
|
12
|
+
|
|
13
|
+
T = TypeVar("T")
|
|
14
|
+
|
|
15
|
+
# ============================================================
|
|
16
|
+
# Loop Types
|
|
17
|
+
# ============================================================
|
|
18
|
+
|
|
19
|
+
class StepStatus(str, Enum):
|
|
20
|
+
PLANNING: str
|
|
21
|
+
ACTING: str
|
|
22
|
+
OBSERVING: str
|
|
23
|
+
REFLECTING: str
|
|
24
|
+
COMPLETE: str
|
|
25
|
+
FAILED: str
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class StepResult:
|
|
29
|
+
step: int
|
|
30
|
+
status: StepStatus
|
|
31
|
+
plan: str
|
|
32
|
+
action: str
|
|
33
|
+
observation: str
|
|
34
|
+
reflection: str
|
|
35
|
+
data: dict[str, Any]
|
|
36
|
+
error: str | None
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class LoopConfig:
|
|
40
|
+
max_steps: int
|
|
41
|
+
max_retries: int
|
|
42
|
+
stop_on_error: bool
|
|
43
|
+
planner: Callable[[list[StepResult]], Awaitable[str]] | None
|
|
44
|
+
actor: Callable[[str], Awaitable[str]] | None
|
|
45
|
+
observer: Callable[[str], Awaitable[str]] | None
|
|
46
|
+
reflector: Callable[[list[StepResult]], Awaitable[str]] | None
|
|
47
|
+
should_stop: Callable[[list[StepResult]], Awaitable[bool]] | None
|
|
48
|
+
|
|
49
|
+
class AgentLoop:
|
|
50
|
+
def __init__(self, config: LoopConfig | None = ...) -> None: ...
|
|
51
|
+
async def run(self, initial_context: str = ...) -> list[StepResult]: ...
|
|
52
|
+
|
|
53
|
+
# ============================================================
|
|
54
|
+
# Gateway Types
|
|
55
|
+
# ============================================================
|
|
56
|
+
|
|
57
|
+
class ModelProvider(str, Enum):
|
|
58
|
+
OPENAI: str
|
|
59
|
+
ANTHROPIC: str
|
|
60
|
+
OLLAMA: str
|
|
61
|
+
CUSTOM: str
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class ProviderConfig:
|
|
65
|
+
provider: ModelProvider
|
|
66
|
+
api_key: str | None
|
|
67
|
+
base_url: str
|
|
68
|
+
model: str
|
|
69
|
+
rpm: int
|
|
70
|
+
tpm: int
|
|
71
|
+
|
|
72
|
+
@dataclass
|
|
73
|
+
class GatewayResponse:
|
|
74
|
+
content: str
|
|
75
|
+
model: str
|
|
76
|
+
provider: ModelProvider
|
|
77
|
+
tokens_used: int
|
|
78
|
+
latency_ms: float
|
|
79
|
+
cached: bool
|
|
80
|
+
metadata: dict[str, Any]
|
|
81
|
+
|
|
82
|
+
class Gateway:
|
|
83
|
+
def __init__(self) -> None: ...
|
|
84
|
+
def add_provider(self, name: str, config: ProviderConfig) -> None: ...
|
|
85
|
+
async def chat(
|
|
86
|
+
self,
|
|
87
|
+
message: str,
|
|
88
|
+
provider: str | None = ...,
|
|
89
|
+
system: str | None = ...,
|
|
90
|
+
temperature: float = ...,
|
|
91
|
+
max_tokens: int = ...,
|
|
92
|
+
**kwargs: Any,
|
|
93
|
+
) -> GatewayResponse: ...
|
|
94
|
+
async def chat_batch(
|
|
95
|
+
self,
|
|
96
|
+
messages: list[str],
|
|
97
|
+
provider: str | None = ...,
|
|
98
|
+
system: str | None = ...,
|
|
99
|
+
temperature: float = ...,
|
|
100
|
+
max_tokens: int = ...,
|
|
101
|
+
max_concurrent: int = ...,
|
|
102
|
+
) -> list[GatewayResponse]: ...
|
|
103
|
+
async def chat_streaming(
|
|
104
|
+
self,
|
|
105
|
+
message: str,
|
|
106
|
+
provider: str | None = ...,
|
|
107
|
+
system: str | None = ...,
|
|
108
|
+
temperature: float = ...,
|
|
109
|
+
max_tokens: int = ...,
|
|
110
|
+
) -> Any: ... # AsyncGenerator[str, None]
|
|
111
|
+
def get_logs(self) -> list[dict[str, Any]]: ...
|
|
112
|
+
async def close(self) -> None: ...
|
|
113
|
+
|
|
114
|
+
# ============================================================
|
|
115
|
+
# Guardrails Types
|
|
116
|
+
# ============================================================
|
|
117
|
+
|
|
118
|
+
class FilterAction(str, Enum):
|
|
119
|
+
BLOCK: str
|
|
120
|
+
REDACT: str
|
|
121
|
+
WARN: str
|
|
122
|
+
PASS: str
|
|
123
|
+
|
|
124
|
+
@dataclass
|
|
125
|
+
class FilterResult:
|
|
126
|
+
action: FilterAction
|
|
127
|
+
original: str
|
|
128
|
+
filtered: str
|
|
129
|
+
reasons: list[str]
|
|
130
|
+
metadata: dict[str, Any]
|
|
131
|
+
|
|
132
|
+
@dataclass
|
|
133
|
+
class GuardrailConfig:
|
|
134
|
+
detect_ssn: bool
|
|
135
|
+
detect_email: bool
|
|
136
|
+
detect_phone: bool
|
|
137
|
+
detect_credit_card: bool
|
|
138
|
+
detect_ip_address: bool
|
|
139
|
+
detect_jailbreak: bool
|
|
140
|
+
jailbreak_sensitivity: float
|
|
141
|
+
blocked_patterns: list[str]
|
|
142
|
+
blocked_keywords: list[str]
|
|
143
|
+
custom_filters: list[Callable[[str], Awaitable[FilterResult]]]
|
|
144
|
+
|
|
145
|
+
class InputFilter:
|
|
146
|
+
def __init__(self, config: GuardrailConfig | None = ...) -> None: ...
|
|
147
|
+
def check(self, text: str) -> FilterResult: ...
|
|
148
|
+
|
|
149
|
+
class OutputFilter:
|
|
150
|
+
def __init__(self, config: GuardrailConfig | None = ...) -> None: ...
|
|
151
|
+
def check(self, text: str) -> FilterResult: ...
|
|
152
|
+
|
|
153
|
+
class GuardrailPipeline:
|
|
154
|
+
def __init__(self, config: GuardrailConfig | None = ...) -> None: ...
|
|
155
|
+
def filter_input(self, text: str) -> FilterResult: ...
|
|
156
|
+
def filter_output(self, text: str) -> FilterResult: ...
|
|
157
|
+
def get_history(self) -> list[dict[str, Any]]: ...
|
|
158
|
+
|
|
159
|
+
# ============================================================
|
|
160
|
+
# Evals Types
|
|
161
|
+
# ============================================================
|
|
162
|
+
|
|
163
|
+
class Verdict(str, Enum):
|
|
164
|
+
PASS: str
|
|
165
|
+
FAIL: str
|
|
166
|
+
PARTIAL: str
|
|
167
|
+
|
|
168
|
+
@dataclass
|
|
169
|
+
class EvalCase:
|
|
170
|
+
name: str
|
|
171
|
+
input_text: str
|
|
172
|
+
expected_output: str | None
|
|
173
|
+
criteria: list[str]
|
|
174
|
+
tags: list[str]
|
|
175
|
+
threshold: float
|
|
176
|
+
|
|
177
|
+
@dataclass
|
|
178
|
+
class EvalResult:
|
|
179
|
+
case: EvalCase
|
|
180
|
+
actual_output: str
|
|
181
|
+
verdict: Verdict
|
|
182
|
+
score: float
|
|
183
|
+
reasoning: str
|
|
184
|
+
criteria_scores: dict[str, float]
|
|
185
|
+
metadata: dict[str, Any]
|
|
186
|
+
|
|
187
|
+
@dataclass
|
|
188
|
+
class EvalSuite:
|
|
189
|
+
name: str
|
|
190
|
+
cases: list[EvalCase]
|
|
191
|
+
description: str
|
|
192
|
+
|
|
193
|
+
@dataclass
|
|
194
|
+
class EvalReport:
|
|
195
|
+
suite_name: str
|
|
196
|
+
results: list[EvalResult]
|
|
197
|
+
@property
|
|
198
|
+
def total(self) -> int: ...
|
|
199
|
+
@property
|
|
200
|
+
def passed(self) -> int: ...
|
|
201
|
+
@property
|
|
202
|
+
def failed(self) -> int: ...
|
|
203
|
+
@property
|
|
204
|
+
def partial(self) -> int: ...
|
|
205
|
+
@property
|
|
206
|
+
def pass_rate(self) -> float: ...
|
|
207
|
+
@property
|
|
208
|
+
def average_score(self) -> float: ...
|
|
209
|
+
def summary(self) -> dict[str, Any]: ...
|
|
210
|
+
|
|
211
|
+
class Evaluator:
|
|
212
|
+
def __init__(
|
|
213
|
+
self,
|
|
214
|
+
judge_fn: Callable[[str], Awaitable[str]] | None = ...,
|
|
215
|
+
model_fn: Callable[[str], Awaitable[str]] | None = ...,
|
|
216
|
+
) -> None: ...
|
|
217
|
+
async def run(
|
|
218
|
+
self,
|
|
219
|
+
suite: EvalSuite,
|
|
220
|
+
model_fn: Callable[[str], Awaitable[str]] | None = ...,
|
|
221
|
+
) -> EvalReport: ...
|
|
222
|
+
|
|
223
|
+
# ============================================================
|
|
224
|
+
# Cache Types
|
|
225
|
+
# ============================================================
|
|
226
|
+
|
|
227
|
+
@dataclass
|
|
228
|
+
class CacheEntry:
|
|
229
|
+
key: str
|
|
230
|
+
response: str
|
|
231
|
+
model: str
|
|
232
|
+
tokens_saved: int
|
|
233
|
+
created_at: float
|
|
234
|
+
last_accessed: float
|
|
235
|
+
access_count: int
|
|
236
|
+
metadata: dict[str, Any]
|
|
237
|
+
|
|
238
|
+
@dataclass
|
|
239
|
+
class CacheStats:
|
|
240
|
+
hits: int
|
|
241
|
+
misses: int
|
|
242
|
+
total_saved_tokens: int
|
|
243
|
+
@property
|
|
244
|
+
def hit_rate(self) -> float: ...
|
|
245
|
+
@property
|
|
246
|
+
def estimated_savings(self) -> float: ...
|
|
247
|
+
|
|
248
|
+
class LLMCache:
|
|
249
|
+
def __init__(
|
|
250
|
+
self,
|
|
251
|
+
ttl: int = ...,
|
|
252
|
+
max_size: int = ...,
|
|
253
|
+
persist_path: str | Path | None = ...,
|
|
254
|
+
) -> None: ...
|
|
255
|
+
def get(self, prompt: str, model: str, **kwargs: Any) -> str | None: ...
|
|
256
|
+
def set(
|
|
257
|
+
self,
|
|
258
|
+
prompt: str,
|
|
259
|
+
response: str,
|
|
260
|
+
model: str,
|
|
261
|
+
tokens: int = ...,
|
|
262
|
+
**kwargs: Any,
|
|
263
|
+
) -> None: ...
|
|
264
|
+
def invalidate(self, prompt: str, model: str, **kwargs: Any) -> bool: ...
|
|
265
|
+
def clear(self) -> None: ...
|
|
266
|
+
def stats(self) -> CacheStats: ...
|
|
267
|
+
|
|
268
|
+
# ============================================================
|
|
269
|
+
# Observability Types
|
|
270
|
+
# ============================================================
|
|
271
|
+
|
|
272
|
+
class SpanStatus(str, Enum):
|
|
273
|
+
OK: str
|
|
274
|
+
ERROR: str
|
|
275
|
+
UNSET: str
|
|
276
|
+
|
|
277
|
+
@dataclass
|
|
278
|
+
class Span:
|
|
279
|
+
name: str
|
|
280
|
+
trace_id: str
|
|
281
|
+
span_id: str
|
|
282
|
+
parent_id: str | None
|
|
283
|
+
start_time: float
|
|
284
|
+
end_time: float | None
|
|
285
|
+
status: SpanStatus
|
|
286
|
+
attributes: dict[str, Any]
|
|
287
|
+
events: list[dict[str, Any]]
|
|
288
|
+
@property
|
|
289
|
+
def duration_ms(self) -> float | None: ...
|
|
290
|
+
def set_attribute(self, key: str, value: Any) -> None: ...
|
|
291
|
+
def add_event(self, name: str, attributes: dict[str, Any] | None = ...) -> None: ...
|
|
292
|
+
def set_status(self, status: SpanStatus, message: str = ...) -> None: ...
|
|
293
|
+
def end(self) -> None: ...
|
|
294
|
+
def to_dict(self) -> dict[str, Any]: ...
|
|
295
|
+
|
|
296
|
+
class Tracer:
|
|
297
|
+
def __init__(self, service: str = ...) -> None: ...
|
|
298
|
+
def start_span(self, name: str, parent_id: str | None = ..., **attributes: Any) -> Span: ...
|
|
299
|
+
def start(self, name: str, **attributes: Any) -> SpanContext: ...
|
|
300
|
+
def get_spans(self) -> list[Span]: ...
|
|
301
|
+
def get_trace(self, trace_id: str) -> list[Span]: ...
|
|
302
|
+
def export_json(self) -> str: ...
|
|
303
|
+
def export_otlp(self) -> list[dict[str, Any]]: ...
|
|
304
|
+
def clear(self) -> None: ...
|
|
305
|
+
|
|
306
|
+
class SpanContext:
|
|
307
|
+
span: Span
|
|
308
|
+
def __enter__(self) -> Span: ...
|
|
309
|
+
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: ...
|
|
310
|
+
|
|
311
|
+
@dataclass
|
|
312
|
+
class MetricPoint:
|
|
313
|
+
name: str
|
|
314
|
+
value: float
|
|
315
|
+
timestamp: float
|
|
316
|
+
tags: dict[str, str]
|
|
317
|
+
|
|
318
|
+
class MetricsCollector:
|
|
319
|
+
def __init__(self) -> None: ...
|
|
320
|
+
def increment(self, name: str, value: float = ..., **tags: str) -> None: ...
|
|
321
|
+
def histogram(self, name: str, value: float, **tags: str) -> None: ...
|
|
322
|
+
def gauge(self, name: str, value: float, **tags: str) -> None: ...
|
|
323
|
+
def summary(self) -> dict[str, Any]: ...
|
|
324
|
+
def export(self) -> list[dict[str, Any]]: ...
|
|
325
|
+
def clear(self) -> None: ...
|
|
326
|
+
|
|
327
|
+
# ============================================================
|
|
328
|
+
# MCP Types
|
|
329
|
+
# ============================================================
|
|
330
|
+
|
|
331
|
+
@dataclass
|
|
332
|
+
class Tool:
|
|
333
|
+
name: str
|
|
334
|
+
description: str
|
|
335
|
+
input_schema: dict[str, Any]
|
|
336
|
+
annotations: dict[str, Any]
|
|
337
|
+
|
|
338
|
+
@dataclass
|
|
339
|
+
class ToolCall:
|
|
340
|
+
name: str
|
|
341
|
+
arguments: dict[str, Any]
|
|
342
|
+
|
|
343
|
+
@dataclass
|
|
344
|
+
class ToolResult:
|
|
345
|
+
content: str | list[dict[str, Any]]
|
|
346
|
+
is_error: bool
|
|
347
|
+
metadata: dict[str, Any]
|
|
348
|
+
|
|
349
|
+
class MCPClient:
|
|
350
|
+
def __init__(self, server_url: str, api_key: str | None = ...) -> None: ...
|
|
351
|
+
async def list_tools(self) -> list[Tool]: ...
|
|
352
|
+
async def call_tool(self, name: str, arguments: dict[str, Any] | None = ...) -> ToolResult: ...
|
|
353
|
+
async def health_check(self) -> bool: ...
|
|
354
|
+
async def close(self) -> None: ...
|
|
355
|
+
|
|
356
|
+
class LocalMCP:
|
|
357
|
+
def __init__(self) -> None: ...
|
|
358
|
+
def tool(
|
|
359
|
+
self,
|
|
360
|
+
name: str,
|
|
361
|
+
description: str = ...,
|
|
362
|
+
input_schema: dict[str, Any] | None = ...,
|
|
363
|
+
) -> Callable: ...
|
|
364
|
+
async def list_tools(self) -> list[Tool]: ...
|
|
365
|
+
async def call_tool(self, name: str, arguments: dict[str, Any] | None = ...) -> ToolResult: ...
|
|
366
|
+
|
|
367
|
+
# ============================================================
|
|
368
|
+
# Agents Types
|
|
369
|
+
# ============================================================
|
|
370
|
+
|
|
371
|
+
class AgentStatus(str, Enum):
|
|
372
|
+
PENDING: str
|
|
373
|
+
RUNNING: str
|
|
374
|
+
COMPLETED: str
|
|
375
|
+
FAILED: str
|
|
376
|
+
|
|
377
|
+
@dataclass
|
|
378
|
+
class AgentResult:
|
|
379
|
+
agent_name: str
|
|
380
|
+
status: AgentStatus
|
|
381
|
+
output: str
|
|
382
|
+
error: str | None
|
|
383
|
+
metadata: dict[str, Any]
|
|
384
|
+
duration_ms: float
|
|
385
|
+
|
|
386
|
+
@dataclass
|
|
387
|
+
class SubAgent:
|
|
388
|
+
name: str
|
|
389
|
+
description: str
|
|
390
|
+
tools: list[str]
|
|
391
|
+
system_prompt: str
|
|
392
|
+
handler: Callable[[str, dict[str, Any]], Awaitable[str]] | None
|
|
393
|
+
status: AgentStatus
|
|
394
|
+
result: AgentResult | None
|
|
395
|
+
|
|
396
|
+
class Orchestrator:
|
|
397
|
+
def __init__(self, max_concurrent: int = ...) -> None: ...
|
|
398
|
+
def add_agent(self, agent: SubAgent) -> None: ...
|
|
399
|
+
def get_agent(self, name: str) -> SubAgent | None: ...
|
|
400
|
+
def list_agents(self) -> list[SubAgent]: ...
|
|
401
|
+
async def run(
|
|
402
|
+
self,
|
|
403
|
+
task: str,
|
|
404
|
+
agent_name: str | None = ...,
|
|
405
|
+
context: dict[str, Any] | None = ...,
|
|
406
|
+
) -> AgentResult: ...
|
|
407
|
+
async def run_all(
|
|
408
|
+
self,
|
|
409
|
+
task: str,
|
|
410
|
+
context: dict[str, Any] | None = ...,
|
|
411
|
+
) -> list[AgentResult]: ...
|
|
412
|
+
def get_history(self) -> list[AgentResult]: ...
|
|
413
|
+
def get_summary(self) -> dict[str, Any]: ...
|
|
414
|
+
|
|
415
|
+
# ============================================================
|
|
416
|
+
# Middleware Types
|
|
417
|
+
# ============================================================
|
|
418
|
+
|
|
419
|
+
@dataclass
|
|
420
|
+
class MiddlewareContext:
|
|
421
|
+
operation: str
|
|
422
|
+
data: dict[str, Any]
|
|
423
|
+
metadata: dict[str, Any]
|
|
424
|
+
cancelled: bool
|
|
425
|
+
cancel_reason: str
|
|
426
|
+
def cancel(self, reason: str = ...) -> None: ...
|
|
427
|
+
|
|
428
|
+
class Middleware(ABC):
|
|
429
|
+
@property
|
|
430
|
+
def name(self) -> str: ...
|
|
431
|
+
async def before(self, ctx: MiddlewareContext) -> MiddlewareContext: ...
|
|
432
|
+
async def after(self, ctx: MiddlewareContext, result: Any) -> Any: ...
|
|
433
|
+
async def on_error(self, ctx: MiddlewareContext, error: Exception) -> Exception: ...
|
|
434
|
+
|
|
435
|
+
class FunctionMiddleware(Middleware):
|
|
436
|
+
def __init__(
|
|
437
|
+
self,
|
|
438
|
+
name: str = ...,
|
|
439
|
+
before_fn: Callable[[MiddlewareContext], Awaitable[MiddlewareContext]] | None = ...,
|
|
440
|
+
after_fn: Callable[[MiddlewareContext, Any], Awaitable[Any]] | None = ...,
|
|
441
|
+
error_fn: Callable[[MiddlewareContext, Exception], Awaitable[Exception]] | None = ...,
|
|
442
|
+
) -> None: ...
|
|
443
|
+
|
|
444
|
+
class MiddlewarePipeline:
|
|
445
|
+
def __init__(self) -> None: ...
|
|
446
|
+
def add(self, middleware: Middleware) -> None: ...
|
|
447
|
+
def remove(self, name: str) -> bool: ...
|
|
448
|
+
def clear(self) -> None: ...
|
|
449
|
+
async def execute(
|
|
450
|
+
self,
|
|
451
|
+
operation: str,
|
|
452
|
+
handler: Callable[..., Awaitable[Any]],
|
|
453
|
+
data: dict[str, Any] | None = ...,
|
|
454
|
+
**kwargs: Any,
|
|
455
|
+
) -> Any: ...
|
|
456
|
+
|
|
457
|
+
class LoggingMiddleware(Middleware): ...
|
|
458
|
+
class TimingMiddleware(Middleware): ...
|
|
459
|
+
|
|
460
|
+
class RateLimitMiddleware(Middleware):
|
|
461
|
+
def __init__(self, max_per_second: int = ...) -> None: ...
|
|
462
|
+
|
|
463
|
+
class CacheMiddleware(Middleware):
|
|
464
|
+
def __init__(self, ttl: int = ...) -> None: ...
|
|
465
|
+
|
|
466
|
+
class ValidationMiddleware(Middleware):
|
|
467
|
+
def __init__(
|
|
468
|
+
self,
|
|
469
|
+
required_fields: list[str] | None = ...,
|
|
470
|
+
validators: dict[str, Callable[[Any], bool]] | None = ...,
|
|
471
|
+
) -> None: ...
|
|
472
|
+
|
|
473
|
+
# ============================================================
|
|
474
|
+
# Plugin Types
|
|
475
|
+
# ============================================================
|
|
476
|
+
|
|
477
|
+
@dataclass
|
|
478
|
+
class PluginInfo:
|
|
479
|
+
name: str
|
|
480
|
+
version: str
|
|
481
|
+
description: str
|
|
482
|
+
author: str
|
|
483
|
+
url: str
|
|
484
|
+
capabilities: list[str]
|
|
485
|
+
requires: list[str]
|
|
486
|
+
|
|
487
|
+
class Plugin(ABC):
|
|
488
|
+
@property
|
|
489
|
+
@abstractmethod
|
|
490
|
+
def info(self) -> PluginInfo: ...
|
|
491
|
+
@abstractmethod
|
|
492
|
+
async def setup(self, registry: PluginRegistry) -> None: ...
|
|
493
|
+
async def teardown(self) -> None: ...
|
|
494
|
+
|
|
495
|
+
class PluginRegistry:
|
|
496
|
+
def __init__(self) -> None: ...
|
|
497
|
+
async def load(self, plugin: Plugin) -> None: ...
|
|
498
|
+
async def load_package(self, module_path: str) -> None: ...
|
|
499
|
+
async def load_directory(self, directory: str | Path) -> int: ...
|
|
500
|
+
def register_tool(self, name: str, handler: Callable) -> None: ...
|
|
501
|
+
def get_tool(self, name: str) -> Callable | None: ...
|
|
502
|
+
def list_tools(self) -> list[str]: ...
|
|
503
|
+
def register_middleware(self, name: str, middleware: Any) -> None: ...
|
|
504
|
+
def get_middleware(self, name: str) -> Any: ...
|
|
505
|
+
def register_provider(self, name: str, provider: Any) -> None: ...
|
|
506
|
+
def get_provider(self, name: str) -> Any: ...
|
|
507
|
+
def register_extension(self, hook_name: str, callback: Callable) -> None: ...
|
|
508
|
+
async def trigger_extension(self, hook_name: str, *args: Any, **kwargs: Any) -> list[Any]: ...
|
|
509
|
+
def get_plugin(self, name: str) -> Plugin | None: ...
|
|
510
|
+
def list_plugins(self) -> list[PluginInfo]: ...
|
|
511
|
+
async def unload(self, name: str) -> bool: ...
|
|
512
|
+
async def unload_all(self) -> None: ...
|
|
513
|
+
|
|
514
|
+
class PluginLoader:
|
|
515
|
+
def __init__(self, registry: PluginRegistry | None = ...) -> None: ...
|
|
516
|
+
async def discover(
|
|
517
|
+
self,
|
|
518
|
+
package: str | None = ...,
|
|
519
|
+
directory: str | Path | None = ...,
|
|
520
|
+
) -> int: ...
|