palmengine 0.7.4__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 (196) hide show
  1. palm/__init__.py +23 -0
  2. palm/app/__init__.py +22 -0
  3. palm/app/app.py +356 -0
  4. palm/app/bootstrap.py +124 -0
  5. palm/app/cli_settings.py +63 -0
  6. palm/app/registry.py +72 -0
  7. palm/app/resolvers.py +43 -0
  8. palm/app/session.py +67 -0
  9. palm/app/settings.py +61 -0
  10. palm/backends/__init__.py +5 -0
  11. palm/backends/behavior_tree/__init__.py +7 -0
  12. palm/backends/behavior_tree/runner.py +68 -0
  13. palm/common/__init__.py +91 -0
  14. palm/common/exceptions.py +50 -0
  15. palm/common/executions/__init__.py +12 -0
  16. palm/common/executions/executor.py +413 -0
  17. palm/common/executions/flow_submission.py +114 -0
  18. palm/common/executions/process_submission.py +55 -0
  19. palm/common/hooks/__init__.py +6 -0
  20. palm/common/hooks/instance_persistence.py +68 -0
  21. palm/common/hooks/state_snapshot.py +72 -0
  22. palm/common/managers/__init__.py +15 -0
  23. palm/common/managers/base.py +25 -0
  24. palm/common/managers/instance_manager.py +341 -0
  25. palm/common/patterns/__init__.py +6 -0
  26. palm/common/patterns/build_context.py +23 -0
  27. palm/common/patterns/builder.py +51 -0
  28. palm/common/persistence/__init__.py +23 -0
  29. palm/common/persistence/definition_repository.py +299 -0
  30. palm/common/persistence/instance_repository.py +193 -0
  31. palm/common/persistence/instance_resume.py +16 -0
  32. palm/common/persistence/instance_sync.py +110 -0
  33. palm/common/plans/__init__.py +7 -0
  34. palm/common/plans/execution_plan.py +59 -0
  35. palm/common/plans/process_plan.py +32 -0
  36. palm/common/plans/registry.py +68 -0
  37. palm/common/storage/__init__.py +5 -0
  38. palm/common/storage/factory.py +141 -0
  39. palm/core/__init__.py +112 -0
  40. palm/core/auth/__init__.py +9 -0
  41. palm/core/auth/engine.py +57 -0
  42. palm/core/base.py +54 -0
  43. palm/core/behavior_tree/__init__.py +58 -0
  44. palm/core/behavior_tree/base.py +92 -0
  45. palm/core/behavior_tree/base_pattern.py +39 -0
  46. palm/core/behavior_tree/composite.py +24 -0
  47. palm/core/behavior_tree/decorator.py +37 -0
  48. palm/core/behavior_tree/engine.py +118 -0
  49. palm/core/behavior_tree/exceptions.py +21 -0
  50. palm/core/behavior_tree/leaf.py +20 -0
  51. palm/core/behavior_tree/nodes/__init__.py +27 -0
  52. palm/core/behavior_tree/nodes/composite/__init__.py +10 -0
  53. palm/core/behavior_tree/nodes/composite/parallel_node.py +74 -0
  54. palm/core/behavior_tree/nodes/composite/selector_node.py +35 -0
  55. palm/core/behavior_tree/nodes/composite/sequence_node.py +35 -0
  56. palm/core/behavior_tree/nodes/decorator/__init__.py +7 -0
  57. palm/core/behavior_tree/nodes/decorator/inverter_node.py +21 -0
  58. palm/core/behavior_tree/nodes/decorator/repeat_node.py +38 -0
  59. palm/core/behavior_tree/nodes/decorator/retry_node.py +33 -0
  60. palm/core/behavior_tree/nodes/leaf/__init__.py +11 -0
  61. palm/core/behavior_tree/nodes/leaf/action_node.py +31 -0
  62. palm/core/behavior_tree/nodes/leaf/condition_node.py +26 -0
  63. palm/core/behavior_tree/nodes/leaf/interactive_leaf.py +45 -0
  64. palm/core/behavior_tree/root.py +19 -0
  65. palm/core/context/__init__.py +10 -0
  66. palm/core/context/base_state.py +43 -0
  67. palm/core/context/engine.py +110 -0
  68. palm/core/event/__init__.py +9 -0
  69. palm/core/event/engine.py +52 -0
  70. palm/core/exceptions.py +56 -0
  71. palm/core/orchestration/__init__.py +35 -0
  72. palm/core/orchestration/drive.py +38 -0
  73. palm/core/orchestration/engine.py +316 -0
  74. palm/core/orchestration/events.py +17 -0
  75. palm/core/orchestration/exceptions.py +47 -0
  76. palm/core/orchestration/execution/__init__.py +5 -0
  77. palm/core/orchestration/execution/base_runner.py +18 -0
  78. palm/core/orchestration/execution_context.py +16 -0
  79. palm/core/orchestration/hooks.py +65 -0
  80. palm/core/orchestration/input_capable.py +26 -0
  81. palm/core/orchestration/job.py +142 -0
  82. palm/core/orchestration/job_state.py +40 -0
  83. palm/core/orchestration/mode/__init__.py +8 -0
  84. palm/core/orchestration/mode/base_mode.py +52 -0
  85. palm/core/orchestration/mode/unconfigured_mode.py +41 -0
  86. palm/core/orchestration/run_result.py +24 -0
  87. palm/core/registry.py +73 -0
  88. palm/core/resource/__init__.py +10 -0
  89. palm/core/resource/base_provider.py +29 -0
  90. palm/core/resource/engine.py +39 -0
  91. palm/core/storage/__init__.py +10 -0
  92. palm/core/storage/base_backend.py +53 -0
  93. palm/core/storage/engine.py +93 -0
  94. palm/definitions/__init__.py +10 -0
  95. palm/definitions/flow.py +67 -0
  96. palm/definitions/process.py +70 -0
  97. palm/instances/__init__.py +9 -0
  98. palm/instances/process_instance.py +113 -0
  99. palm/instances/state_snapshot.py +80 -0
  100. palm/instances/status_history.py +42 -0
  101. palm/patterns/__init__.py +15 -0
  102. palm/patterns/_apps.py +18 -0
  103. palm/patterns/_registry.py +134 -0
  104. palm/patterns/dag/__init__.py +10 -0
  105. palm/patterns/dag/builder.py +26 -0
  106. palm/patterns/dag/pattern.py +21 -0
  107. palm/patterns/dag/registry.py +9 -0
  108. palm/patterns/etl/__init__.py +10 -0
  109. palm/patterns/etl/builder.py +26 -0
  110. palm/patterns/etl/pattern.py +26 -0
  111. palm/patterns/etl/registry.py +9 -0
  112. palm/patterns/wizard/__init__.py +63 -0
  113. palm/patterns/wizard/action_leaf.py +94 -0
  114. palm/patterns/wizard/backtrack.py +71 -0
  115. palm/patterns/wizard/base.py +10 -0
  116. palm/patterns/wizard/builder.py +170 -0
  117. palm/patterns/wizard/commit_leaf.py +113 -0
  118. palm/patterns/wizard/config.py +156 -0
  119. palm/patterns/wizard/events.py +19 -0
  120. palm/patterns/wizard/handler.py +94 -0
  121. palm/patterns/wizard/keys.py +23 -0
  122. palm/patterns/wizard/options.py +66 -0
  123. palm/patterns/wizard/pattern.py +143 -0
  124. palm/patterns/wizard/persistence.py +54 -0
  125. palm/patterns/wizard/registry.py +24 -0
  126. palm/patterns/wizard/resume.py +34 -0
  127. palm/patterns/wizard/step_kinds.py +13 -0
  128. palm/patterns/wizard/step_leaf.py +98 -0
  129. palm/patterns/wizard/submission.py +21 -0
  130. palm/patterns/wizard/summary_leaf.py +78 -0
  131. palm/patterns/wizard/tree.py +78 -0
  132. palm/patterns/wizard/validation.py +137 -0
  133. palm/providers/__init__.py +13 -0
  134. palm/providers/_apps.py +14 -0
  135. palm/providers/graphql/__init__.py +6 -0
  136. palm/providers/graphql/provider.py +20 -0
  137. palm/providers/graphql/registry.py +6 -0
  138. palm/providers/postgres/__init__.py +6 -0
  139. palm/providers/postgres/provider.py +20 -0
  140. palm/providers/postgres/registry.py +6 -0
  141. palm/providers/rest/__init__.py +6 -0
  142. palm/providers/rest/provider.py +20 -0
  143. palm/providers/rest/registry.py +6 -0
  144. palm/runtimes/__init__.py +24 -0
  145. palm/runtimes/base.py +290 -0
  146. palm/runtimes/cli.py +118 -0
  147. palm/runtimes/cli_pkg/__init__.py +6 -0
  148. palm/runtimes/cli_pkg/actions.py +68 -0
  149. palm/runtimes/cli_pkg/args.py +211 -0
  150. palm/runtimes/cli_pkg/bootstrap.py +53 -0
  151. palm/runtimes/cli_pkg/commands/__init__.py +5 -0
  152. palm/runtimes/cli_pkg/commands/registry.py +413 -0
  153. palm/runtimes/cli_pkg/completion.py +184 -0
  154. palm/runtimes/cli_pkg/context.py +80 -0
  155. palm/runtimes/cli_pkg/display.py +178 -0
  156. palm/runtimes/cli_pkg/doctor.py +112 -0
  157. palm/runtimes/cli_pkg/instance_ops.py +126 -0
  158. palm/runtimes/cli_pkg/instances.py +52 -0
  159. palm/runtimes/cli_pkg/output.py +33 -0
  160. palm/runtimes/cli_pkg/repl.py +88 -0
  161. palm/runtimes/cli_pkg/settings.py +5 -0
  162. palm/runtimes/cli_pkg/startup.py +67 -0
  163. palm/runtimes/cli_pkg/version_info.py +59 -0
  164. palm/runtimes/daemon.py +46 -0
  165. palm/runtimes/embedded.py +27 -0
  166. palm/runtimes/hooks.py +115 -0
  167. palm/runtimes/host.py +41 -0
  168. palm/runtimes/schedulers/__init__.py +6 -0
  169. palm/runtimes/schedulers/inline.py +61 -0
  170. palm/runtimes/schedulers/queued.py +133 -0
  171. palm/runtimes/server/__init__.py +6 -0
  172. palm/runtimes/server/auth.py +37 -0
  173. palm/runtimes/server/http.py +281 -0
  174. palm/runtimes/server/runtime.py +195 -0
  175. palm/runtimes/wiring.py +59 -0
  176. palm/states/__init__.py +10 -0
  177. palm/states/blackboard_state.py +40 -0
  178. palm/storages/__init__.py +21 -0
  179. palm/storages/_apps.py +20 -0
  180. palm/storages/filesystem/__init__.py +6 -0
  181. palm/storages/filesystem/backend.py +175 -0
  182. palm/storages/filesystem/registry.py +6 -0
  183. palm/storages/memory/__init__.py +6 -0
  184. palm/storages/memory/backend.py +42 -0
  185. palm/storages/memory/registry.py +6 -0
  186. palm/storages/mongodb/__init__.py +6 -0
  187. palm/storages/mongodb/backend.py +81 -0
  188. palm/storages/mongodb/registry.py +6 -0
  189. palm/storages/postgres/__init__.py +6 -0
  190. palm/storages/postgres/backend.py +36 -0
  191. palm/storages/postgres/registry.py +6 -0
  192. palm/utils/__init__.py +5 -0
  193. palmengine-0.7.4.dist-info/METADATA +370 -0
  194. palmengine-0.7.4.dist-info/RECORD +196 -0
  195. palmengine-0.7.4.dist-info/WHEEL +4 -0
  196. palmengine-0.7.4.dist-info/entry_points.txt +2 -0
palm/app/resolvers.py ADDED
@@ -0,0 +1,43 @@
1
+ """
2
+ Definition reference resolution — shared by library and CLI callers.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import TYPE_CHECKING
8
+
9
+ from palm.common.exceptions import DefinitionNotFoundError
10
+ from palm.definitions.flow import FlowDefinition
11
+ from palm.definitions.process import ProcessDefinition
12
+
13
+ if TYPE_CHECKING:
14
+ from palm.app.app import PalmApp
15
+ from palm.common.persistence.definition_repository import DefinitionRepository
16
+
17
+
18
+ def resolve_flow(repository: DefinitionRepository, ref: str) -> FlowDefinition:
19
+ """Resolve a flow by display name, falling back to definition id."""
20
+ try:
21
+ return repository.get_flow(ref)
22
+ except DefinitionNotFoundError:
23
+ return repository.get_flow(ref, by_id=True)
24
+
25
+
26
+ def resolve_process(repository: DefinitionRepository, ref: str) -> ProcessDefinition:
27
+ """Resolve a process by display name, falling back to definition id."""
28
+ try:
29
+ return repository.get_process(ref)
30
+ except DefinitionNotFoundError:
31
+ return repository.get_process(ref, by_id=True)
32
+
33
+
34
+ def resolve_flow_for_app(app: PalmApp, ref: str, *, runtime_name: str | None = None) -> FlowDefinition:
35
+ """Resolve a flow via a :class:`~palm.app.app.PalmApp` runtime repository."""
36
+ return resolve_flow(app.repository(runtime_name=runtime_name), ref)
37
+
38
+
39
+ def resolve_process_for_app(
40
+ app: PalmApp, ref: str, *, runtime_name: str | None = None
41
+ ) -> ProcessDefinition:
42
+ """Resolve a process via a :class:`~palm.app.app.PalmApp` runtime repository."""
43
+ return resolve_process(app.repository(runtime_name=runtime_name), ref)
palm/app/session.py ADDED
@@ -0,0 +1,67 @@
1
+ """
2
+ CLI session bootstrap — thin PalmApp client for terminal entrypoints.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from pathlib import Path
8
+ from typing import Any
9
+
10
+ from palm.app.app import PalmApp
11
+ from palm.app.bootstrap import runtime_start_options
12
+ from palm.app.cli_settings import resolve_cli_settings
13
+ from palm.app.settings import PalmSettings
14
+ from palm.core.storage import StorageEngine
15
+
16
+
17
+ def create_console() -> Any:
18
+ """Build a Rich console for CLI output."""
19
+ try:
20
+ from rich.console import Console
21
+
22
+ return Console(highlight=False)
23
+ except ImportError as exc:
24
+ raise SystemExit(
25
+ "Rich is required for the Palm CLI. Install with: pip install palmengine[cli]"
26
+ ) from exc
27
+
28
+
29
+ def create_cli_app(
30
+ *,
31
+ storage_backend: str | None = None,
32
+ data_dir: Path | None = None,
33
+ storage: StorageEngine | None = None,
34
+ settings: PalmSettings | None = None,
35
+ ) -> PalmApp:
36
+ """
37
+ Construct a fully bootstrapped :class:`~palm.app.app.PalmApp` for the CLI.
38
+
39
+ Settings resolve from ``PALM_*`` environment variables, with optional CLI flag
40
+ overrides. ``bootstrap_cli`` wires the embedded runtime, ``InstanceManager``,
41
+ persistence hooks, and definition catalog — no manual runtime assembly.
42
+
43
+ Shared ``storage`` enables resume across separate CLI invocations (daemon +
44
+ terminal) when both use the same engine instance or durable backend + data dir.
45
+ """
46
+ if settings is not None:
47
+ cfg = settings
48
+ if storage_backend is not None:
49
+ cfg = resolve_cli_settings(storage_backend=storage_backend, settings=cfg)
50
+ if data_dir is not None:
51
+ cfg = resolve_cli_settings(data_dir=data_dir, settings=cfg)
52
+ else:
53
+ shared_backend = (
54
+ storage.backend_name
55
+ if storage is not None and storage.is_initialized and storage.backend_name
56
+ else None
57
+ )
58
+ cfg = resolve_cli_settings(
59
+ storage_backend=storage_backend,
60
+ data_dir=data_dir,
61
+ align_shared_storage=shared_backend if storage_backend is None else None,
62
+ )
63
+
64
+ app = PalmApp(cfg, storage=storage)
65
+ app.bootstrap()
66
+ app.bootstrap_cli(**runtime_start_options(cfg))
67
+ return app
palm/app/settings.py ADDED
@@ -0,0 +1,61 @@
1
+ """
2
+ PalmSettings — central configuration for Palm applications.
3
+
4
+ Loaded from environment variables (``PALM_*``) and optional ``.env`` files via
5
+ ``pydantic-settings``.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from pathlib import Path
11
+ from typing import Literal
12
+
13
+ from pydantic import Field
14
+ from pydantic_settings import BaseSettings, SettingsConfigDict
15
+
16
+ SchedulerPolicy = Literal["inline", "queued"]
17
+
18
+
19
+ class PalmSettings(BaseSettings):
20
+ """
21
+ Application-wide Palm configuration.
22
+
23
+ Environment prefix: ``PALM_`` (e.g. ``PALM_STORAGE_BACKEND=postgres``).
24
+ """
25
+
26
+ model_config = SettingsConfigDict(
27
+ env_prefix="PALM_",
28
+ env_file=".env",
29
+ env_file_encoding="utf-8",
30
+ extra="ignore",
31
+ )
32
+
33
+ storage_backend: str = "memory"
34
+ data_dir: Path | None = None
35
+ observability: bool = False
36
+ auth_enforce: bool = False
37
+ auth_roles: list[str] = Field(default_factory=lambda: ["user"])
38
+ load_example_definitions: bool = True
39
+ default_scheduler: SchedulerPolicy = "inline"
40
+ max_concurrent_jobs: int | None = None
41
+ enable_state_snapshot: bool = False
42
+ snapshot_on_status: list[str] = Field(
43
+ default_factory=lambda: ["WAITING_FOR_INPUT", "SUCCEEDED", "FAILED"]
44
+ )
45
+ max_snapshots_per_instance: int = 10
46
+ max_loaded_instances: int = 128
47
+ max_concurrent_active: int = 32
48
+ reconcile_instances_on_startup: bool = True
49
+
50
+ def definition_roots(self) -> list[Path]:
51
+ """Directories scanned for ``register_definitions`` modules."""
52
+ roots: list[Path] = []
53
+ if self.data_dir is not None:
54
+ roots.append(self.data_dir / "definitions")
55
+ roots.extend(
56
+ [
57
+ Path.cwd() / "examples" / "definitions",
58
+ ]
59
+ )
60
+ return roots
61
+
@@ -0,0 +1,5 @@
1
+ """Concrete job runners for Palm orchestration (modular apps)."""
2
+
3
+ from palm.backends.behavior_tree import BehaviorTreeRunner
4
+
5
+ __all__ = ["BehaviorTreeRunner"]
@@ -0,0 +1,7 @@
1
+ """
2
+ Behavior-tree job runner app — default ``JobRunner`` for pattern executables.
3
+ """
4
+
5
+ from palm.backends.behavior_tree.runner import BehaviorTreeRunner
6
+
7
+ __all__ = ["BehaviorTreeRunner"]
@@ -0,0 +1,68 @@
1
+ """
2
+ BehaviorTreeRunner — runs ``BasePattern`` executables against job state.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from palm.core.behavior_tree import BasePattern, PatternStatus
8
+ from palm.core.orchestration.execution.base_runner import JobRunner
9
+ from palm.core.orchestration.execution_context import ExecutionContext
10
+ from palm.core.orchestration.job import JobStatus
11
+ from palm.core.orchestration.run_result import RunResult
12
+
13
+
14
+ class BehaviorTreeRunner(JobRunner):
15
+ """Advances a ``BasePattern`` stored in ``job.executable`` using ``job.state``."""
16
+
17
+ def run(self, ctx: ExecutionContext, *, budget: int | None = None) -> RunResult:
18
+ job = ctx.job
19
+ if job.is_terminal:
20
+ return RunResult(status=job.status, result=job.result)
21
+
22
+ pattern = job.executable
23
+ if not isinstance(pattern, BasePattern):
24
+ return RunResult(
25
+ status=JobStatus.FAILED,
26
+ error=TypeError("BehaviorTreeRunner requires a BasePattern executable"),
27
+ propagate=True,
28
+ )
29
+
30
+ ticks = budget if budget is not None else 10_000
31
+ if ticks < 1:
32
+ raise ValueError("budget must be >= 1")
33
+
34
+ logical_status = job.status
35
+ if logical_status == JobStatus.PENDING:
36
+ logical_status = JobStatus.RUNNING
37
+
38
+ for _ in range(ticks):
39
+ try:
40
+ status = pattern.tick(job.state)
41
+ except Exception as exc:
42
+ return RunResult(status=JobStatus.FAILED, error=exc, propagate=True)
43
+
44
+ if status == PatternStatus.WAITING_FOR_INPUT:
45
+ return RunResult(status=JobStatus.WAITING_FOR_INPUT)
46
+
47
+ if status == PatternStatus.SUCCESS:
48
+ return RunResult(
49
+ status=JobStatus.SUCCEEDED,
50
+ result=job.state.get("__result__"),
51
+ )
52
+
53
+ if status == PatternStatus.FAILURE:
54
+ err = job.state.get("__error__")
55
+ return RunResult(
56
+ status=JobStatus.FAILED,
57
+ error=err if isinstance(err, BaseException) else RuntimeError("pattern failed"),
58
+ )
59
+
60
+ logical_status = JobStatus.RUNNING
61
+
62
+ if logical_status == JobStatus.RUNNING:
63
+ return RunResult(status=JobStatus.RUNNING)
64
+
65
+ return RunResult(
66
+ status=JobStatus.FAILED,
67
+ error=RuntimeError("pattern did not reach a terminal status"),
68
+ )
@@ -0,0 +1,91 @@
1
+ """
2
+ Shared coordination logic for Palm (non-plugin, non-core).
3
+
4
+ ``palm.common`` holds definition-driven submission, plan staging, persistence
5
+ helpers, orchestration hooks, and pattern materialization — the glue between
6
+ ``palm.core`` engines, ``palm.definitions``, and extensible ``palm.patterns``.
7
+
8
+ Extensible plugins live elsewhere:
9
+
10
+ - ``palm.patterns`` — register via ``pattern_registry``
11
+ - ``palm.providers`` — register via ``provider_registry``
12
+ - ``palm.storages`` — register via ``storage_registry``
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import TYPE_CHECKING
18
+
19
+ if TYPE_CHECKING:
20
+ from palm.common.executions.executor import DefinitionExecutor
21
+ from palm.common.executions.flow_submission import FlowSubmission
22
+ from palm.common.hooks.instance_persistence import InstancePersistenceHook
23
+ from palm.common.patterns.build_context import PatternBuildContext
24
+ from palm.common.persistence.definition_repository import DefinitionRepository
25
+ from palm.common.persistence.instance_repository import InstanceRepository
26
+ from palm.common.plans.execution_plan import ExecutionPlan
27
+ from palm.common.plans.process_plan import ProcessPlan
28
+ from palm.common.plans.registry import PlanRegistry, StoredPlan
29
+ from palm.instances import ProcessInstance, StatusHistoryEntry
30
+
31
+ __all__ = [
32
+ "DefinitionBuildError",
33
+ "DefinitionExecutor",
34
+ "DefinitionNotFoundError",
35
+ "DefinitionRepository",
36
+ "ExecutionError",
37
+ "ExecutionPlan",
38
+ "FlowSubmission",
39
+ "InstanceNotFoundError",
40
+ "InstancePersistenceHook",
41
+ "InstanceRepository",
42
+ "InstanceResumeError",
43
+ "PatternBuildContext",
44
+ "PlanNotFoundError",
45
+ "PlanRegistry",
46
+ "PlanValidationError",
47
+ "ProcessInstance",
48
+ "ProcessPlan",
49
+ "StatusHistoryEntry",
50
+ "StoredPlan",
51
+ "build_pattern",
52
+ "prepare_flow_submission",
53
+ "prepare_process_plans",
54
+ ]
55
+
56
+ _LAZY_EXPORTS: dict[str, tuple[str, str]] = {
57
+ "DefinitionBuildError": ("palm.common.exceptions", "DefinitionBuildError"),
58
+ "DefinitionNotFoundError": ("palm.common.exceptions", "DefinitionNotFoundError"),
59
+ "ExecutionError": ("palm.common.exceptions", "ExecutionError"),
60
+ "InstanceNotFoundError": ("palm.common.exceptions", "InstanceNotFoundError"),
61
+ "InstanceResumeError": ("palm.common.exceptions", "InstanceResumeError"),
62
+ "PlanNotFoundError": ("palm.common.exceptions", "PlanNotFoundError"),
63
+ "PlanValidationError": ("palm.common.exceptions", "PlanValidationError"),
64
+ "DefinitionExecutor": ("palm.common.executions.executor", "DefinitionExecutor"),
65
+ "FlowSubmission": ("palm.common.executions.flow_submission", "FlowSubmission"),
66
+ "prepare_flow_submission": ("palm.common.executions.flow_submission", "prepare_flow_submission"),
67
+ "prepare_process_plans": ("palm.common.executions.process_submission", "prepare_process_plans"),
68
+ "InstancePersistenceHook": ("palm.common.hooks.instance_persistence", "InstancePersistenceHook"),
69
+ "PatternBuildContext": ("palm.common.patterns.build_context", "PatternBuildContext"),
70
+ "build_pattern": ("palm.common.patterns.builder", "build_pattern"),
71
+ "DefinitionRepository": ("palm.common.persistence.definition_repository", "DefinitionRepository"),
72
+ "InstanceRepository": ("palm.common.persistence.instance_repository", "InstanceRepository"),
73
+ "ExecutionPlan": ("palm.common.plans.execution_plan", "ExecutionPlan"),
74
+ "ProcessPlan": ("palm.common.plans.process_plan", "ProcessPlan"),
75
+ "PlanRegistry": ("palm.common.plans.registry", "PlanRegistry"),
76
+ "StoredPlan": ("palm.common.plans.registry", "StoredPlan"),
77
+ "ProcessInstance": ("palm.instances", "ProcessInstance"),
78
+ "StatusHistoryEntry": ("palm.instances", "StatusHistoryEntry"),
79
+ }
80
+
81
+
82
+ def __getattr__(name: str):
83
+ if name not in _LAZY_EXPORTS:
84
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
85
+ module_path, attr = _LAZY_EXPORTS[name]
86
+ import importlib
87
+
88
+ module = importlib.import_module(module_path)
89
+ value = getattr(module, attr)
90
+ globals()[name] = value
91
+ return value
@@ -0,0 +1,50 @@
1
+ """
2
+ Execution-layer exceptions (outside core).
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+
8
+ class ExecutionError(Exception):
9
+ """Base error for definition-driven execution."""
10
+
11
+
12
+ class DefinitionBuildError(ExecutionError):
13
+ """Raised when a flow or process definition cannot be built."""
14
+
15
+
16
+ class DefinitionNotFoundError(ExecutionError):
17
+ """Raised when a definition name or id cannot be resolved."""
18
+
19
+ def __init__(self, kind: str, ref: str) -> None:
20
+ super().__init__(f"{kind} definition not found: {ref!r}")
21
+ self.kind = kind
22
+ self.ref = ref
23
+
24
+
25
+ class InstanceNotFoundError(ExecutionError):
26
+ """Raised when a process instance id cannot be loaded."""
27
+
28
+ def __init__(self, instance_id: str) -> None:
29
+ super().__init__(f"Process instance not found: {instance_id!r}")
30
+ self.instance_id = instance_id
31
+
32
+
33
+ class InstanceResumeError(ExecutionError):
34
+ """Raised when an instance cannot be resumed (terminal, missing flow, etc.)."""
35
+
36
+
37
+ class InstanceActiveLimitError(ExecutionError):
38
+ """Raised when the active instance limit is exceeded."""
39
+
40
+
41
+ class PlanValidationError(ExecutionError):
42
+ """Raised when an :class:`~palm.common.plans.execution_plan.ExecutionPlan` fails pre-submit checks."""
43
+
44
+
45
+ class PlanNotFoundError(ExecutionError):
46
+ """Raised when a stored plan id cannot be resolved."""
47
+
48
+ def __init__(self, plan_id: str) -> None:
49
+ super().__init__(f"Execution plan not found: {plan_id!r}")
50
+ self.plan_id = plan_id
@@ -0,0 +1,12 @@
1
+ """Definition-driven submission — prepare and submit orchestration jobs."""
2
+
3
+ from palm.common.executions.executor import DefinitionExecutor
4
+ from palm.common.executions.flow_submission import FlowSubmission, prepare_flow_submission
5
+ from palm.common.executions.process_submission import prepare_process_plans
6
+
7
+ __all__ = [
8
+ "DefinitionExecutor",
9
+ "FlowSubmission",
10
+ "prepare_flow_submission",
11
+ "prepare_process_plans",
12
+ ]