provide-foundation 0.0.0.dev1__py3-none-any.whl → 0.0.0.dev2__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.
Files changed (93) hide show
  1. provide/foundation/__init__.py +29 -3
  2. provide/foundation/archive/operations.py +4 -6
  3. provide/foundation/cli/__init__.py +2 -2
  4. provide/foundation/cli/commands/deps.py +13 -7
  5. provide/foundation/cli/commands/logs/__init__.py +1 -1
  6. provide/foundation/cli/commands/logs/query.py +1 -1
  7. provide/foundation/cli/commands/logs/send.py +1 -1
  8. provide/foundation/cli/commands/logs/tail.py +1 -1
  9. provide/foundation/cli/decorators.py +11 -10
  10. provide/foundation/cli/main.py +1 -1
  11. provide/foundation/cli/testing.py +2 -35
  12. provide/foundation/cli/utils.py +21 -17
  13. provide/foundation/config/__init__.py +35 -2
  14. provide/foundation/config/converters.py +479 -0
  15. provide/foundation/config/defaults.py +67 -0
  16. provide/foundation/config/env.py +4 -19
  17. provide/foundation/config/loader.py +9 -3
  18. provide/foundation/console/input.py +5 -5
  19. provide/foundation/console/output.py +35 -13
  20. provide/foundation/context/__init__.py +8 -4
  21. provide/foundation/context/core.py +85 -109
  22. provide/foundation/crypto/certificates/operations.py +1 -1
  23. provide/foundation/errors/__init__.py +2 -3
  24. provide/foundation/errors/decorators.py +0 -231
  25. provide/foundation/errors/types.py +0 -97
  26. provide/foundation/file/directory.py +13 -22
  27. provide/foundation/file/lock.py +3 -1
  28. provide/foundation/hub/components.py +72 -384
  29. provide/foundation/hub/config.py +151 -0
  30. provide/foundation/hub/discovery.py +62 -0
  31. provide/foundation/hub/handlers.py +81 -0
  32. provide/foundation/hub/lifecycle.py +194 -0
  33. provide/foundation/hub/manager.py +4 -4
  34. provide/foundation/hub/processors.py +44 -0
  35. provide/foundation/integrations/__init__.py +11 -0
  36. provide/foundation/{observability → integrations}/openobserve/__init__.py +10 -7
  37. provide/foundation/{observability → integrations}/openobserve/auth.py +1 -1
  38. provide/foundation/{observability → integrations}/openobserve/client.py +12 -12
  39. provide/foundation/{observability → integrations}/openobserve/commands.py +3 -3
  40. provide/foundation/integrations/openobserve/config.py +37 -0
  41. provide/foundation/{observability → integrations}/openobserve/formatters.py +1 -1
  42. provide/foundation/{observability → integrations}/openobserve/otlp.py +1 -1
  43. provide/foundation/{observability → integrations}/openobserve/search.py +2 -2
  44. provide/foundation/{observability → integrations}/openobserve/streaming.py +4 -4
  45. provide/foundation/logger/config/logging.py +68 -298
  46. provide/foundation/logger/config/telemetry.py +41 -121
  47. provide/foundation/logger/setup/coordinator.py +1 -1
  48. provide/foundation/observability/__init__.py +2 -2
  49. provide/foundation/process/__init__.py +9 -0
  50. provide/foundation/process/exit.py +47 -0
  51. provide/foundation/process/lifecycle.py +33 -33
  52. provide/foundation/resilience/__init__.py +35 -0
  53. provide/foundation/resilience/circuit.py +164 -0
  54. provide/foundation/resilience/decorators.py +220 -0
  55. provide/foundation/resilience/fallback.py +193 -0
  56. provide/foundation/resilience/retry.py +325 -0
  57. provide/foundation/streams/config.py +79 -0
  58. provide/foundation/streams/console.py +7 -8
  59. provide/foundation/streams/core.py +6 -3
  60. provide/foundation/streams/file.py +12 -2
  61. provide/foundation/testing/__init__.py +7 -2
  62. provide/foundation/testing/cli.py +30 -17
  63. provide/foundation/testing/common/__init__.py +0 -2
  64. provide/foundation/testing/common/fixtures.py +0 -27
  65. provide/foundation/testing/file/content_fixtures.py +316 -0
  66. provide/foundation/testing/file/directory_fixtures.py +107 -0
  67. provide/foundation/testing/file/fixtures.py +45 -516
  68. provide/foundation/testing/file/special_fixtures.py +153 -0
  69. provide/foundation/testing/logger.py +76 -0
  70. provide/foundation/testing/process/async_fixtures.py +405 -0
  71. provide/foundation/testing/process/fixtures.py +50 -571
  72. provide/foundation/testing/process/subprocess_fixtures.py +209 -0
  73. provide/foundation/testing/threading/basic_fixtures.py +101 -0
  74. provide/foundation/testing/threading/data_fixtures.py +99 -0
  75. provide/foundation/testing/threading/execution_fixtures.py +263 -0
  76. provide/foundation/testing/threading/fixtures.py +34 -500
  77. provide/foundation/testing/threading/sync_fixtures.py +97 -0
  78. provide/foundation/testing/time/fixtures.py +4 -4
  79. provide/foundation/tools/cache.py +8 -6
  80. provide/foundation/tools/downloader.py +23 -12
  81. provide/foundation/tracer/spans.py +2 -2
  82. provide/foundation/transport/config.py +26 -95
  83. provide/foundation/transport/middleware.py +30 -36
  84. provide/foundation/utils/deps.py +14 -12
  85. provide/foundation/utils/parsing.py +49 -4
  86. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/METADATA +1 -1
  87. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/RECORD +93 -68
  88. /provide/foundation/{observability → integrations}/openobserve/exceptions.py +0 -0
  89. /provide/foundation/{observability → integrations}/openobserve/models.py +0 -0
  90. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/WHEEL +0 -0
  91. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/entry_points.txt +0 -0
  92. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/licenses/LICENSE +0 -0
  93. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev2.dist-info}/top_level.txt +0 -0
@@ -6,6 +6,7 @@ for JSON mode, colors, and proper stream separation.
6
6
  """
7
7
 
8
8
  import json
9
+ import os
9
10
  import sys
10
11
  from typing import Any
11
12
 
@@ -17,34 +18,48 @@ except ImportError:
17
18
  click = None
18
19
  _HAS_CLICK = False
19
20
 
20
- from provide.foundation.context import Context
21
+ from provide.foundation.context import CLIContext
22
+ from provide.foundation.errors.decorators import with_error_handling
21
23
  from provide.foundation.logger import get_logger
22
24
 
23
25
  log = get_logger(__name__)
24
26
 
25
27
 
26
- def _get_context() -> Context | None:
28
+ def _get_context() -> CLIContext | None:
27
29
  """Get current context from Click or environment."""
28
30
  if not _HAS_CLICK:
29
31
  return None
30
32
  ctx = click.get_current_context(silent=True)
31
- if ctx and hasattr(ctx, "obj") and isinstance(ctx.obj, Context):
33
+ if ctx and hasattr(ctx, "obj") and isinstance(ctx.obj, CLIContext):
32
34
  return ctx.obj
33
35
  return None
34
36
 
35
37
 
36
- def _should_use_json(ctx: Context | None = None) -> bool:
38
+ def _should_use_json(ctx: CLIContext | None = None) -> bool:
37
39
  """Determine if JSON output should be used."""
38
40
  if ctx is None:
39
41
  ctx = _get_context()
40
42
  return ctx.json_output if ctx else False
41
43
 
42
44
 
43
- def _should_use_color(ctx: Context | None = None, stream=None) -> bool:
45
+ def _should_use_color(ctx: CLIContext | None = None, stream=None) -> bool:
44
46
  """Determine if color output should be used."""
45
47
  if ctx is None:
46
48
  ctx = _get_context()
47
49
 
50
+ # Check FORCE_COLOR first (enables color even for non-TTY)
51
+ force_color = os.environ.get('FORCE_COLOR', '').lower()
52
+ if force_color in ('1', 'true', 'yes'):
53
+ return True
54
+
55
+ # Check NO_COLOR (disables color even for TTY)
56
+ if os.environ.get('NO_COLOR'):
57
+ return False
58
+
59
+ # Check context no_color setting
60
+ if ctx and ctx.no_color:
61
+ return False
62
+
48
63
  # Check if stream is a TTY
49
64
  if stream:
50
65
  return getattr(stream, "isatty", lambda: False)()
@@ -52,19 +67,21 @@ def _should_use_color(ctx: Context | None = None, stream=None) -> bool:
52
67
  return sys.stdout.isatty() or sys.stderr.isatty()
53
68
 
54
69
 
70
+ @with_error_handling(fallback=None, suppress=(TypeError, ValueError, AttributeError))
55
71
  def _output_json(data: Any, stream=sys.stdout) -> None:
56
72
  """Output data as JSON."""
57
- try:
58
- json_str = json.dumps(data, indent=2, default=str)
73
+ json_str = json.dumps(data, indent=2, default=str)
74
+ if _HAS_CLICK:
59
75
  click.echo(json_str, file=stream)
60
- except (TypeError, ValueError) as e:
61
- # Fallback to string representation
62
- click.echo(
63
- json.dumps({"error": f"JSON encoding failed: {e}", "data": str(data)}),
64
- file=stream,
65
- )
76
+ else:
77
+ print(json_str, file=stream)
66
78
 
67
79
 
80
+ @with_error_handling(
81
+ fallback=None,
82
+ suppress=(OSError, IOError, UnicodeEncodeError),
83
+ context_provider=lambda: {"function": "pout"}
84
+ )
68
85
  def pout(message: Any, **kwargs: Any) -> None:
69
86
  """
70
87
  Output message to stdout.
@@ -122,6 +139,11 @@ def pout(message: Any, **kwargs: Any) -> None:
122
139
  print(output, file=sys.stdout, end="")
123
140
 
124
141
 
142
+ @with_error_handling(
143
+ fallback=None,
144
+ suppress=(OSError, IOError, UnicodeEncodeError),
145
+ context_provider=lambda: {"function": "perr"}
146
+ )
125
147
  def perr(message: Any, **kwargs: Any) -> None:
126
148
  """
127
149
  Output message to stderr.
@@ -1,12 +1,16 @@
1
1
  """
2
2
  Core context management for provide-foundation.
3
3
 
4
- Provides unified application context that bridges configuration, runtime state,
5
- and presentation concerns across the foundation library.
4
+ Provides CLI runtime context for managing command execution state,
5
+ output formatting, and CLI-specific settings.
6
6
  """
7
7
 
8
- from provide.foundation.context.core import Context
8
+ from provide.foundation.context.core import CLIContext
9
+
10
+ # Backward compatibility
11
+ Context = CLIContext
9
12
 
10
13
  __all__ = [
11
- "Context",
14
+ "CLIContext",
15
+ "Context", # Backward compatibility
12
16
  ]
@@ -8,9 +8,11 @@ from typing import Any
8
8
 
9
9
  from attrs import define, field, fields, validators
10
10
 
11
+ from provide.foundation.config.env import RuntimeConfig
12
+ from provide.foundation.config.base import field as config_field, ConfigSource
13
+ from provide.foundation.config.converters import parse_bool_strict
11
14
  from provide.foundation.logger import get_logger
12
15
  from provide.foundation.logger.config import TelemetryConfig
13
- from provide.foundation.utils.parsing import parse_bool
14
16
 
15
17
  try:
16
18
  import tomli as tomllib
@@ -29,36 +31,68 @@ except ImportError:
29
31
  VALID_LOG_LEVELS = {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}
30
32
 
31
33
 
32
- @define(slots=True, frozen=False)
33
- class Context:
34
+ @define(slots=True, repr=False)
35
+ class CLIContext(RuntimeConfig):
34
36
  """
35
- Unified context for configuration and CLI state.
37
+ Runtime context for CLI execution and state management.
36
38
 
37
- Combines configuration management with runtime state for CLI tools
38
- and services. Supports loading from files, environment variables,
39
- and programmatic updates.
39
+ Manages CLI-specific settings, output formatting, and runtime state
40
+ during command execution. Supports loading from files, environment variables,
41
+ and programmatic updates during CLI command execution.
40
42
  """
41
43
 
42
- log_level: str = field(
43
- default="INFO", validator=validators.in_(VALID_LOG_LEVELS), converter=str.upper
44
+ log_level: str = config_field(
45
+ default="INFO",
46
+ env_var="PROVIDE_LOG_LEVEL",
47
+ converter=str.upper,
48
+ validator=validators.in_(VALID_LOG_LEVELS),
49
+ description="Logging level for CLI output"
44
50
  )
45
- profile: str = field(default="default")
46
- debug: bool = field(default=False, converter=lambda x: parse_bool(x, strict=True))
47
- json_output: bool = field(
48
- default=False, converter=lambda x: parse_bool(x, strict=True)
51
+ profile: str = config_field(
52
+ default="default",
53
+ env_var="PROVIDE_PROFILE",
54
+ description="Configuration profile to use"
49
55
  )
50
- config_file: Path | None = field(
51
- default=None, converter=lambda x: Path(x) if x else None
56
+ debug: bool = config_field(
57
+ default=False,
58
+ env_var="PROVIDE_DEBUG",
59
+ converter=parse_bool_strict,
60
+ description="Enable debug mode"
52
61
  )
53
- log_file: Path | None = field(
54
- default=None, converter=lambda x: Path(x) if x else None
62
+ json_output: bool = config_field(
63
+ default=False,
64
+ env_var="PROVIDE_JSON_OUTPUT",
65
+ converter=parse_bool_strict,
66
+ description="Output in JSON format"
55
67
  )
56
- log_format: str = field(default="key_value")
57
- no_color: bool = field(
58
- default=False, converter=lambda x: parse_bool(x, strict=True)
68
+ config_file: Path | None = config_field(
69
+ default=None,
70
+ env_var="PROVIDE_CONFIG_FILE",
71
+ converter=lambda x: Path(x) if x else None,
72
+ description="Path to configuration file"
59
73
  )
60
- no_emoji: bool = field(
61
- default=False, converter=lambda x: parse_bool(x, strict=True)
74
+ log_file: Path | None = config_field(
75
+ default=None,
76
+ env_var="PROVIDE_LOG_FILE",
77
+ converter=lambda x: Path(x) if x else None,
78
+ description="Path to log file"
79
+ )
80
+ log_format: str = config_field(
81
+ default="key_value",
82
+ env_var="PROVIDE_LOG_FORMAT",
83
+ description="Log output format (key_value or json)"
84
+ )
85
+ no_color: bool = config_field(
86
+ default=False,
87
+ env_var="NO_COLOR",
88
+ converter=parse_bool_strict,
89
+ description="Disable colored output"
90
+ )
91
+ no_emoji: bool = config_field(
92
+ default=False,
93
+ env_var="PROVIDE_NO_EMOJI",
94
+ converter=parse_bool_strict,
95
+ description="Disable emoji in output"
62
96
  )
63
97
 
64
98
  # Private fields - using Factory for mutable defaults
@@ -69,62 +103,9 @@ class Context:
69
103
  """Post-initialization hook."""
70
104
  pass # Validation is handled by attrs validators
71
105
 
72
- def _validate(self) -> None:
73
- """Validate context values. For attrs compatibility."""
74
- # Validation is handled by attrs validators automatically
75
- pass
76
-
77
- @classmethod
78
- def from_env(cls, prefix: str = "PROVIDE") -> "Context":
79
- """
80
- Create context from environment variables using TelemetryConfig system.
81
-
82
- Args:
83
- prefix: Environment variable prefix (default: PROVIDE)
84
-
85
- Returns:
86
- New Context instance with values from environment
87
- """
88
- # Use the main TelemetryConfig system for parsing
89
- telemetry_config = TelemetryConfig.from_env(strict=False)
90
-
91
- kwargs = {}
92
-
93
- # Map telemetry config values to CLI context
94
- kwargs["log_level"] = telemetry_config.logging.default_level
95
- if telemetry_config.logging.console_formatter:
96
- kwargs["log_format"] = telemetry_config.logging.console_formatter
97
- if telemetry_config.logging.log_file:
98
- kwargs["log_file"] = telemetry_config.logging.log_file
99
-
100
- # CLI-specific environment variables that don't exist in TelemetryConfig
101
- if profile := os.environ.get(f"{prefix}_PROFILE"):
102
- kwargs["profile"] = profile
103
-
104
- if debug := os.environ.get(f"{prefix}_DEBUG"):
105
- kwargs["debug"] = debug.lower() in ("true", "1", "yes", "on")
106
-
107
- if json_output := os.environ.get(f"{prefix}_JSON_OUTPUT"):
108
- kwargs["json_output"] = json_output.lower() in ("true", "1", "yes", "on")
109
-
110
- if config_file := os.environ.get(f"{prefix}_CONFIG_FILE"):
111
- kwargs["config_file"] = Path(config_file)
112
-
113
- # Map emoji settings to no_emoji (inverted)
114
- kwargs["no_emoji"] = not (
115
- telemetry_config.logging.logger_name_emoji_prefix_enabled
116
- and telemetry_config.logging.das_emoji_prefix_enabled
117
- )
118
-
119
- # Check for explicit NO_COLOR override
120
- if no_color := os.environ.get(f"{prefix}_NO_COLOR"):
121
- kwargs["no_color"] = no_color.lower() in ("true", "1", "yes", "on")
122
-
123
- return cls(**kwargs)
124
-
125
106
  def update_from_env(self, prefix: str = "PROVIDE") -> None:
126
107
  """
127
- Update context from environment variables using TelemetryConfig system.
108
+ Update context from environment variables.
128
109
 
129
110
  Args:
130
111
  prefix: Environment variable prefix (default: PROVIDE)
@@ -132,28 +113,19 @@ class Context:
132
113
  if self._frozen:
133
114
  raise RuntimeError("Context is frozen and cannot be modified")
134
115
 
135
- env_ctx = self.from_env(prefix)
136
-
137
- # Update values from TelemetryConfig (these are always updated since they're the primary source)
138
- self.log_level = env_ctx.log_level
139
- self.log_format = env_ctx.log_format
140
- if env_ctx.log_file:
141
- self.log_file = env_ctx.log_file
142
- self.no_emoji = env_ctx.no_emoji
143
-
144
- # Update CLI-specific values only if explicitly set in environment
145
- if os.environ.get(f"{prefix}_PROFILE"):
146
- self.profile = env_ctx.profile
147
- if os.environ.get(f"{prefix}_DEBUG"):
148
- self.debug = env_ctx.debug
149
- if os.environ.get(f"{prefix}_JSON_OUTPUT"):
150
- self.json_output = env_ctx.json_output
151
- if os.environ.get(f"{prefix}_CONFIG_FILE"):
152
- self.config_file = env_ctx.config_file
153
- if os.environ.get(f"{prefix}_NO_COLOR"):
154
- self.no_color = env_ctx.no_color
155
-
156
- self._validate()
116
+ # Create default instance and environment instance
117
+ default_ctx = self.__class__() # All defaults
118
+ env_ctx = self.from_env(prefix=prefix) # Environment + defaults
119
+
120
+ # Only update fields where environment differs from default
121
+ for attr in fields(self.__class__):
122
+ if not attr.name.startswith("_"): # Skip private fields
123
+ default_value = getattr(default_ctx, attr.name)
124
+ env_value = getattr(env_ctx, attr.name)
125
+
126
+ # If environment value differs from default, it came from env
127
+ if env_value != default_value:
128
+ setattr(self, attr.name, env_value)
157
129
 
158
130
  def to_dict(self) -> dict[str, Any]:
159
131
  """Convert context to dictionary."""
@@ -170,15 +142,16 @@ class Context:
170
142
  }
171
143
 
172
144
  @classmethod
173
- def from_dict(cls, data: dict[str, Any]) -> "Context":
145
+ def from_dict(cls, data: dict[str, Any], source: ConfigSource = ConfigSource.RUNTIME) -> "CLIContext":
174
146
  """
175
147
  Create context from dictionary.
176
148
 
177
149
  Args:
178
150
  data: Dictionary with context values
151
+ source: Source of the configuration data
179
152
 
180
153
  Returns:
181
- New Context instance
154
+ New CLIContext instance
182
155
  """
183
156
  kwargs = {}
184
157
 
@@ -212,9 +185,7 @@ class Context:
212
185
  Args:
213
186
  path: Path to configuration file
214
187
  """
215
- if self._frozen:
216
- raise RuntimeError("Context is frozen and cannot be modified")
217
-
188
+ # CLIContext is not frozen, so we can modify it
218
189
  path = Path(path)
219
190
  if not path.exists():
220
191
  raise FileNotFoundError(f"Config file not found: {path}")
@@ -294,16 +265,16 @@ class Context:
294
265
 
295
266
  path.write_text(content)
296
267
 
297
- def merge(self, other: "Context", override_defaults: bool = False) -> "Context":
268
+ def merge(self, other: "CLIContext", override_defaults: bool = False) -> "CLIContext":
298
269
  """
299
270
  Merge with another context, with other taking precedence.
300
271
 
301
272
  Args:
302
- other: Context to merge with
273
+ other: CLIContext to merge with
303
274
  override_defaults: If False, only override if other's value differs from its class default
304
275
 
305
276
  Returns:
306
- New merged Context instance
277
+ New merged CLIContext instance
307
278
  """
308
279
  merged_data = self.to_dict()
309
280
  other_data = other.to_dict()
@@ -318,7 +289,7 @@ class Context:
318
289
  from attrs import Factory
319
290
 
320
291
  defaults = {}
321
- for f in fields(Context):
292
+ for f in fields(CLIContext):
322
293
  if not f.name.startswith("_"): # Skip private fields
323
294
  if isinstance(f.default, Factory):
324
295
  defaults[f.name] = f.default.factory()
@@ -333,7 +304,7 @@ class Context:
333
304
  continue
334
305
  merged_data[key] = value
335
306
 
336
- return Context.from_dict(merged_data)
307
+ return CLIContext.from_dict(merged_data)
337
308
 
338
309
  def freeze(self) -> None:
339
310
  """Freeze context to prevent further modifications."""
@@ -341,7 +312,7 @@ class Context:
341
312
  # This is kept for API compatibility but does nothing
342
313
  self._frozen = True
343
314
 
344
- def copy(self) -> "Context":
315
+ def copy(self) -> "CLIContext":
345
316
  """Create a deep copy of the context."""
346
317
  return copy.deepcopy(self)
347
318
 
@@ -354,3 +325,8 @@ class Context:
354
325
  profile=self.profile,
355
326
  )
356
327
  return self._logger
328
+
329
+ def _validate(self) -> None:
330
+ """Validate context values. For attrs compatibility."""
331
+ # Validation is handled by attrs validators automatically
332
+ pass
@@ -30,7 +30,7 @@ from provide.foundation.crypto.constants import (
30
30
  DEFAULT_CERTIFICATE_VALIDITY_DAYS,
31
31
  DEFAULT_RSA_KEY_SIZE,
32
32
  )
33
- from .base import CertificateBase, CertificateError, KeyPair, PublicKey
33
+ from provide.foundation.crypto.certificates.base import CertificateBase, CertificateError, KeyPair, PublicKey
34
34
 
35
35
 
36
36
  def create_x509_certificate(
@@ -6,6 +6,8 @@ and utilities for robust error handling throughout the application.
6
6
  """
7
7
 
8
8
  from provide.foundation.errors.auth import AuthenticationError, AuthorizationError
9
+ # Re-export from resilience module for compatibility
10
+ from provide.foundation.resilience.decorators import retry as retry_on_error
9
11
  from provide.foundation.errors.base import FoundationError
10
12
  from provide.foundation.errors.config import (
11
13
  ConfigurationError,
@@ -20,7 +22,6 @@ from provide.foundation.errors.context import (
20
22
  )
21
23
  from provide.foundation.errors.decorators import (
22
24
  fallback_on_error,
23
- retry_on_error,
24
25
  suppress_and_log,
25
26
  with_error_handling,
26
27
  )
@@ -50,7 +51,6 @@ from provide.foundation.errors.safe_decorators import log_only_error_context
50
51
  from provide.foundation.errors.types import (
51
52
  ErrorCode,
52
53
  ErrorMetadata,
53
- RetryPolicy,
54
54
  )
55
55
 
56
56
  __all__ = [
@@ -77,7 +77,6 @@ __all__ = [
77
77
  "ProcessError",
78
78
  "ProcessTimeoutError",
79
79
  "ResourceError",
80
- "RetryPolicy",
81
80
  "RuntimeError",
82
81
  "StateError",
83
82
  "TimeoutError",