flock-core 0.4.3__py3-none-any.whl → 0.4.503__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.
Potentially problematic release.
This version of flock-core might be problematic. Click here for more details.
- flock/cli/create_flock.py +0 -7
- flock/cli/execute_flock.py +19 -9
- flock/core/__init__.py +11 -0
- flock/core/flock.py +145 -80
- flock/core/flock_agent.py +117 -4
- flock/core/flock_evaluator.py +1 -1
- flock/core/flock_factory.py +290 -2
- flock/core/flock_module.py +101 -0
- flock/core/flock_registry.py +40 -3
- flock/core/flock_server_manager.py +136 -0
- flock/core/logging/__init__.py +4 -0
- flock/core/logging/logging.py +98 -11
- flock/core/logging/telemetry.py +1 -1
- flock/core/mcp/__init__.py +1 -0
- flock/core/mcp/flock_mcp_server.py +614 -0
- flock/core/mcp/flock_mcp_tool_base.py +201 -0
- flock/core/mcp/mcp_client.py +658 -0
- flock/core/mcp/mcp_client_manager.py +201 -0
- flock/core/mcp/mcp_config.py +237 -0
- flock/core/mcp/types/__init__.py +1 -0
- flock/core/mcp/types/callbacks.py +86 -0
- flock/core/mcp/types/factories.py +111 -0
- flock/core/mcp/types/handlers.py +240 -0
- flock/core/mcp/types/types.py +157 -0
- flock/core/mcp/util/__init__.py +0 -0
- flock/core/mcp/util/helpers.py +23 -0
- flock/core/mixin/dspy_integration.py +45 -12
- flock/core/serialization/flock_serializer.py +52 -1
- flock/core/util/hydrator.py +0 -1
- flock/core/util/spliter.py +4 -0
- flock/evaluators/declarative/declarative_evaluator.py +4 -3
- flock/mcp/servers/sse/__init__.py +1 -0
- flock/mcp/servers/sse/flock_sse_server.py +139 -0
- flock/mcp/servers/stdio/__init__.py +1 -0
- flock/mcp/servers/stdio/flock_stdio_server.py +138 -0
- flock/mcp/servers/websockets/__init__.py +1 -0
- flock/mcp/servers/websockets/flock_websocket_server.py +119 -0
- flock/modules/performance/metrics_module.py +159 -1
- flock/webapp/app/main.py +1 -1
- flock/webapp/app/services/flock_service.py +0 -1
- {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/METADATA +42 -4
- {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/RECORD +45 -25
- {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/WHEEL +0 -0
- {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/entry_points.txt +0 -0
- {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/licenses/LICENSE +0 -0
flock/core/logging/logging.py
CHANGED
|
@@ -10,7 +10,9 @@ Key points:
|
|
|
10
10
|
- Outside workflows, we use Loguru with rich formatting.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
+
import logging
|
|
13
14
|
import sys
|
|
15
|
+
from typing import Literal
|
|
14
16
|
|
|
15
17
|
from opentelemetry import trace
|
|
16
18
|
|
|
@@ -20,6 +22,19 @@ from temporalio import workflow
|
|
|
20
22
|
with workflow.unsafe.imports_passed_through():
|
|
21
23
|
from loguru import logger as loguru_logger
|
|
22
24
|
|
|
25
|
+
# ENABLED_FLOCK_LOGGER_LEVELS constant removed
|
|
26
|
+
|
|
27
|
+
# Mapping from level names to numeric values
|
|
28
|
+
LOG_LEVELS: dict[str, int] = {
|
|
29
|
+
"CRITICAL": logging.CRITICAL,
|
|
30
|
+
"ERROR": logging.ERROR,
|
|
31
|
+
"WARNING": logging.WARNING,
|
|
32
|
+
"INFO": logging.INFO,
|
|
33
|
+
"DEBUG": logging.DEBUG,
|
|
34
|
+
"SUCCESS": 35, # Custom success level
|
|
35
|
+
"NO_LOGS": 100, # Special level to disable logging
|
|
36
|
+
}
|
|
37
|
+
|
|
23
38
|
|
|
24
39
|
def in_workflow_context() -> bool:
|
|
25
40
|
"""Returns True if this code is running inside a Temporal workflow context.
|
|
@@ -85,6 +100,7 @@ COLOR_MAP = {
|
|
|
85
100
|
|
|
86
101
|
LOGGERS = [
|
|
87
102
|
"flock", # Core Flock orchestration
|
|
103
|
+
"flock.api", # Flock API specific logs
|
|
88
104
|
"agent", # General agent operations
|
|
89
105
|
"context", # Context management
|
|
90
106
|
"registry", # Unified registry operations (new)
|
|
@@ -238,6 +254,50 @@ loguru_logger.add(
|
|
|
238
254
|
# loguru_logger.add("logs/flock.log", rotation="100 MB", retention="30 days", level="DEBUG")
|
|
239
255
|
|
|
240
256
|
|
|
257
|
+
def get_default_severity(level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "NO_LOGS", "SUCCESS"] | int) -> int:
|
|
258
|
+
"""Get the default severity for a given level."""
|
|
259
|
+
if isinstance(level, str):
|
|
260
|
+
level_str = level.upper()
|
|
261
|
+
return LOG_LEVELS.get(level_str, LOG_LEVELS["ERROR"])
|
|
262
|
+
return level
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def configure_logging(flock_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "NO_LOGS", "SUCCESS"] | int,
|
|
266
|
+
external_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "NO_LOGS", "SUCCESS"] | int,
|
|
267
|
+
specific_levels: dict[str, Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "NO_LOGS", "SUCCESS"] | int] | None = None) -> None:
|
|
268
|
+
"""Configure both external and internal Flock logging systems.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
flock_level (str | int): The default logging level (e.g., "INFO", "ERROR", "DEBUG") or numeric level for Flock logging.
|
|
272
|
+
external_level (str | int): The default logging level (e.g., "INFO", "ERROR", "DEBUG") or numeric level for external logging.
|
|
273
|
+
specific_levels (dict[str, str | int] | None, optional): A dictionary mapping
|
|
274
|
+
logger names to their specific logging levels. Defaults to None.
|
|
275
|
+
"""
|
|
276
|
+
# Get default severity
|
|
277
|
+
|
|
278
|
+
external_severity = get_default_severity(external_level)
|
|
279
|
+
logging.basicConfig(level=external_severity)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
flock_severity = get_default_severity(flock_level)
|
|
283
|
+
|
|
284
|
+
specific_severities = {}
|
|
285
|
+
if specific_levels:
|
|
286
|
+
for name, logger_level in specific_levels.items():
|
|
287
|
+
severity = get_default_severity(logger_level)
|
|
288
|
+
specific_severities[name] = severity
|
|
289
|
+
|
|
290
|
+
# Apply to all cached loggers
|
|
291
|
+
for logger_name, log_instance in _LOGGER_CACHE.items():
|
|
292
|
+
target_severity = flock_severity
|
|
293
|
+
if logger_name in specific_severities:
|
|
294
|
+
target_severity = specific_severities[logger_name]
|
|
295
|
+
|
|
296
|
+
log_instance.min_level_severity = target_severity
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
241
301
|
# Define a dummy logger that does nothing
|
|
242
302
|
class DummyLogger:
|
|
243
303
|
"""A dummy logger that does nothing when called."""
|
|
@@ -276,19 +336,17 @@ class FlockLogger:
|
|
|
276
336
|
- Otherwise, it uses Loguru.
|
|
277
337
|
"""
|
|
278
338
|
|
|
279
|
-
def __init__(self, name: str,
|
|
339
|
+
def __init__(self, name: str, initial_min_level_severity: int):
|
|
280
340
|
"""Initialize the FlockLogger.
|
|
281
341
|
|
|
282
342
|
Args:
|
|
283
343
|
name (str): The name of the logger.
|
|
284
|
-
|
|
344
|
+
initial_min_level_severity (int): The minimum severity level for messages to be logged.
|
|
285
345
|
"""
|
|
286
346
|
self.name = name
|
|
287
|
-
self.
|
|
347
|
+
self.min_level_severity = initial_min_level_severity
|
|
288
348
|
|
|
289
349
|
def _get_logger(self):
|
|
290
|
-
if not self.enable_logging:
|
|
291
|
-
return dummy_logger
|
|
292
350
|
if in_workflow_context():
|
|
293
351
|
# Use Temporal's workflow.logger inside a workflow context.
|
|
294
352
|
return workflow.logger
|
|
@@ -316,6 +374,10 @@ class FlockLogger:
|
|
|
316
374
|
max_length: int = MAX_LENGTH,
|
|
317
375
|
**kwargs,
|
|
318
376
|
) -> None:
|
|
377
|
+
current_method_severity = LOG_LEVELS["DEBUG"]
|
|
378
|
+
if self.min_level_severity == LOG_LEVELS["NO_LOGS"] or \
|
|
379
|
+
current_method_severity < self.min_level_severity:
|
|
380
|
+
return
|
|
319
381
|
"""Debug a message.
|
|
320
382
|
|
|
321
383
|
Args:
|
|
@@ -334,6 +396,10 @@ class FlockLogger:
|
|
|
334
396
|
max_length: int = MAX_LENGTH,
|
|
335
397
|
**kwargs,
|
|
336
398
|
) -> None:
|
|
399
|
+
current_method_severity = LOG_LEVELS["INFO"]
|
|
400
|
+
if self.min_level_severity == LOG_LEVELS["NO_LOGS"] or \
|
|
401
|
+
current_method_severity < self.min_level_severity:
|
|
402
|
+
return
|
|
337
403
|
"""Info a message.
|
|
338
404
|
|
|
339
405
|
Args:
|
|
@@ -352,6 +418,10 @@ class FlockLogger:
|
|
|
352
418
|
max_length: int = MAX_LENGTH,
|
|
353
419
|
**kwargs,
|
|
354
420
|
) -> None:
|
|
421
|
+
current_method_severity = LOG_LEVELS["WARNING"]
|
|
422
|
+
if self.min_level_severity == LOG_LEVELS["NO_LOGS"] or \
|
|
423
|
+
current_method_severity < self.min_level_severity:
|
|
424
|
+
return
|
|
355
425
|
"""Warning a message.
|
|
356
426
|
|
|
357
427
|
Args:
|
|
@@ -370,6 +440,10 @@ class FlockLogger:
|
|
|
370
440
|
max_length: int = MAX_LENGTH,
|
|
371
441
|
**kwargs,
|
|
372
442
|
) -> None:
|
|
443
|
+
current_method_severity = LOG_LEVELS["ERROR"]
|
|
444
|
+
if self.min_level_severity == LOG_LEVELS["NO_LOGS"] or \
|
|
445
|
+
current_method_severity < self.min_level_severity:
|
|
446
|
+
return
|
|
373
447
|
"""Error a message.
|
|
374
448
|
|
|
375
449
|
Args:
|
|
@@ -388,6 +462,10 @@ class FlockLogger:
|
|
|
388
462
|
max_length: int = MAX_LENGTH,
|
|
389
463
|
**kwargs,
|
|
390
464
|
) -> None:
|
|
465
|
+
current_method_severity = LOG_LEVELS["ERROR"] # Exception implies ERROR level
|
|
466
|
+
if self.min_level_severity == LOG_LEVELS["NO_LOGS"] or \
|
|
467
|
+
current_method_severity < self.min_level_severity:
|
|
468
|
+
return
|
|
391
469
|
"""Exception a message.
|
|
392
470
|
|
|
393
471
|
Args:
|
|
@@ -406,6 +484,10 @@ class FlockLogger:
|
|
|
406
484
|
max_length: int = MAX_LENGTH,
|
|
407
485
|
**kwargs,
|
|
408
486
|
) -> None:
|
|
487
|
+
current_method_severity = LOG_LEVELS["SUCCESS"]
|
|
488
|
+
if self.min_level_severity == LOG_LEVELS["NO_LOGS"] or \
|
|
489
|
+
current_method_severity < self.min_level_severity:
|
|
490
|
+
return
|
|
409
491
|
"""Success a message.
|
|
410
492
|
|
|
411
493
|
Args:
|
|
@@ -420,16 +502,21 @@ class FlockLogger:
|
|
|
420
502
|
_LOGGER_CACHE: dict[str, FlockLogger] = {}
|
|
421
503
|
|
|
422
504
|
|
|
423
|
-
def get_logger(name: str = "flock"
|
|
505
|
+
def get_logger(name: str = "flock") -> FlockLogger:
|
|
424
506
|
"""Return a cached FlockLogger instance for the given name.
|
|
425
507
|
|
|
426
|
-
If the logger doesn't exist,
|
|
427
|
-
|
|
508
|
+
If the logger doesn't exist, it is created with 'enable_logging' set to False
|
|
509
|
+
by default (i.e., errors-only mode). Its state can then be changed by calling
|
|
510
|
+
the `configure_logging()` function.
|
|
511
|
+
If a logger with the given name already exists in the cache, its 'min_level_severity'
|
|
512
|
+
state is NOT modified by this function; it's simply returned.
|
|
428
513
|
"""
|
|
429
514
|
if name not in _LOGGER_CACHE:
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
_LOGGER_CACHE[name]
|
|
515
|
+
# New loggers default to errors-only (min_level_severity = ERROR_SEVERITY)
|
|
516
|
+
# until explicitly configured by configure_logging()
|
|
517
|
+
_LOGGER_CACHE[name] = FlockLogger(name, LOG_LEVELS["NO_LOGS"])
|
|
518
|
+
# The min_level_severity state of existing or newly created loggers
|
|
519
|
+
# should be managed by the configure_logging() function.
|
|
433
520
|
return _LOGGER_CACHE[name]
|
|
434
521
|
|
|
435
522
|
|
flock/core/logging/telemetry.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Flock MCP package."""
|