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.

Files changed (45) hide show
  1. flock/cli/create_flock.py +0 -7
  2. flock/cli/execute_flock.py +19 -9
  3. flock/core/__init__.py +11 -0
  4. flock/core/flock.py +145 -80
  5. flock/core/flock_agent.py +117 -4
  6. flock/core/flock_evaluator.py +1 -1
  7. flock/core/flock_factory.py +290 -2
  8. flock/core/flock_module.py +101 -0
  9. flock/core/flock_registry.py +40 -3
  10. flock/core/flock_server_manager.py +136 -0
  11. flock/core/logging/__init__.py +4 -0
  12. flock/core/logging/logging.py +98 -11
  13. flock/core/logging/telemetry.py +1 -1
  14. flock/core/mcp/__init__.py +1 -0
  15. flock/core/mcp/flock_mcp_server.py +614 -0
  16. flock/core/mcp/flock_mcp_tool_base.py +201 -0
  17. flock/core/mcp/mcp_client.py +658 -0
  18. flock/core/mcp/mcp_client_manager.py +201 -0
  19. flock/core/mcp/mcp_config.py +237 -0
  20. flock/core/mcp/types/__init__.py +1 -0
  21. flock/core/mcp/types/callbacks.py +86 -0
  22. flock/core/mcp/types/factories.py +111 -0
  23. flock/core/mcp/types/handlers.py +240 -0
  24. flock/core/mcp/types/types.py +157 -0
  25. flock/core/mcp/util/__init__.py +0 -0
  26. flock/core/mcp/util/helpers.py +23 -0
  27. flock/core/mixin/dspy_integration.py +45 -12
  28. flock/core/serialization/flock_serializer.py +52 -1
  29. flock/core/util/hydrator.py +0 -1
  30. flock/core/util/spliter.py +4 -0
  31. flock/evaluators/declarative/declarative_evaluator.py +4 -3
  32. flock/mcp/servers/sse/__init__.py +1 -0
  33. flock/mcp/servers/sse/flock_sse_server.py +139 -0
  34. flock/mcp/servers/stdio/__init__.py +1 -0
  35. flock/mcp/servers/stdio/flock_stdio_server.py +138 -0
  36. flock/mcp/servers/websockets/__init__.py +1 -0
  37. flock/mcp/servers/websockets/flock_websocket_server.py +119 -0
  38. flock/modules/performance/metrics_module.py +159 -1
  39. flock/webapp/app/main.py +1 -1
  40. flock/webapp/app/services/flock_service.py +0 -1
  41. {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/METADATA +42 -4
  42. {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/RECORD +45 -25
  43. {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/WHEEL +0 -0
  44. {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/entry_points.txt +0 -0
  45. {flock_core-0.4.3.dist-info → flock_core-0.4.503.dist-info}/licenses/LICENSE +0 -0
@@ -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, enable_logging: bool = False):
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
- enable_logging (bool, optional): Whether to enable logging. Defaults to False.
344
+ initial_min_level_severity (int): The minimum severity level for messages to be logged.
285
345
  """
286
346
  self.name = name
287
- self.enable_logging = enable_logging
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", enable_logging: bool = True) -> FlockLogger:
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, create it.
427
- If it does exist, update 'enable_logging' if a new value is passed.
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
- _LOGGER_CACHE[name] = FlockLogger(name, enable_logging)
431
- else:
432
- _LOGGER_CACHE[name].enable_logging = enable_logging
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
 
@@ -120,7 +120,7 @@ class TelemetryConfig:
120
120
  )
121
121
 
122
122
  otlp_exporter = OTLPSpanExporter(
123
- collector_endpoint=self.otlp_endpoint,
123
+ endpoint=self.otlp_endpoint,
124
124
  )
125
125
  else:
126
126
  raise ValueError(
@@ -0,0 +1 @@
1
+ """Flock MCP package."""