genxai-framework 0.1.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.
Files changed (156) hide show
  1. cli/__init__.py +3 -0
  2. cli/commands/__init__.py +6 -0
  3. cli/commands/approval.py +85 -0
  4. cli/commands/audit.py +127 -0
  5. cli/commands/metrics.py +25 -0
  6. cli/commands/tool.py +389 -0
  7. cli/main.py +32 -0
  8. genxai/__init__.py +81 -0
  9. genxai/api/__init__.py +5 -0
  10. genxai/api/app.py +21 -0
  11. genxai/config/__init__.py +5 -0
  12. genxai/config/settings.py +37 -0
  13. genxai/connectors/__init__.py +19 -0
  14. genxai/connectors/base.py +122 -0
  15. genxai/connectors/kafka.py +92 -0
  16. genxai/connectors/postgres_cdc.py +95 -0
  17. genxai/connectors/registry.py +44 -0
  18. genxai/connectors/sqs.py +94 -0
  19. genxai/connectors/webhook.py +73 -0
  20. genxai/core/__init__.py +37 -0
  21. genxai/core/agent/__init__.py +32 -0
  22. genxai/core/agent/base.py +206 -0
  23. genxai/core/agent/config_io.py +59 -0
  24. genxai/core/agent/registry.py +98 -0
  25. genxai/core/agent/runtime.py +970 -0
  26. genxai/core/communication/__init__.py +6 -0
  27. genxai/core/communication/collaboration.py +44 -0
  28. genxai/core/communication/message_bus.py +192 -0
  29. genxai/core/communication/protocols.py +35 -0
  30. genxai/core/execution/__init__.py +22 -0
  31. genxai/core/execution/metadata.py +181 -0
  32. genxai/core/execution/queue.py +201 -0
  33. genxai/core/graph/__init__.py +30 -0
  34. genxai/core/graph/checkpoints.py +77 -0
  35. genxai/core/graph/edges.py +131 -0
  36. genxai/core/graph/engine.py +813 -0
  37. genxai/core/graph/executor.py +516 -0
  38. genxai/core/graph/nodes.py +161 -0
  39. genxai/core/graph/trigger_runner.py +40 -0
  40. genxai/core/memory/__init__.py +19 -0
  41. genxai/core/memory/base.py +72 -0
  42. genxai/core/memory/embedding.py +327 -0
  43. genxai/core/memory/episodic.py +448 -0
  44. genxai/core/memory/long_term.py +467 -0
  45. genxai/core/memory/manager.py +543 -0
  46. genxai/core/memory/persistence.py +297 -0
  47. genxai/core/memory/procedural.py +461 -0
  48. genxai/core/memory/semantic.py +526 -0
  49. genxai/core/memory/shared.py +62 -0
  50. genxai/core/memory/short_term.py +303 -0
  51. genxai/core/memory/vector_store.py +508 -0
  52. genxai/core/memory/working.py +211 -0
  53. genxai/core/state/__init__.py +6 -0
  54. genxai/core/state/manager.py +293 -0
  55. genxai/core/state/schema.py +115 -0
  56. genxai/llm/__init__.py +14 -0
  57. genxai/llm/base.py +150 -0
  58. genxai/llm/factory.py +329 -0
  59. genxai/llm/providers/__init__.py +1 -0
  60. genxai/llm/providers/anthropic.py +249 -0
  61. genxai/llm/providers/cohere.py +274 -0
  62. genxai/llm/providers/google.py +334 -0
  63. genxai/llm/providers/ollama.py +147 -0
  64. genxai/llm/providers/openai.py +257 -0
  65. genxai/llm/routing.py +83 -0
  66. genxai/observability/__init__.py +6 -0
  67. genxai/observability/logging.py +327 -0
  68. genxai/observability/metrics.py +494 -0
  69. genxai/observability/tracing.py +372 -0
  70. genxai/performance/__init__.py +39 -0
  71. genxai/performance/cache.py +256 -0
  72. genxai/performance/pooling.py +289 -0
  73. genxai/security/audit.py +304 -0
  74. genxai/security/auth.py +315 -0
  75. genxai/security/cost_control.py +528 -0
  76. genxai/security/default_policies.py +44 -0
  77. genxai/security/jwt.py +142 -0
  78. genxai/security/oauth.py +226 -0
  79. genxai/security/pii.py +366 -0
  80. genxai/security/policy_engine.py +82 -0
  81. genxai/security/rate_limit.py +341 -0
  82. genxai/security/rbac.py +247 -0
  83. genxai/security/validation.py +218 -0
  84. genxai/tools/__init__.py +21 -0
  85. genxai/tools/base.py +383 -0
  86. genxai/tools/builtin/__init__.py +131 -0
  87. genxai/tools/builtin/communication/__init__.py +15 -0
  88. genxai/tools/builtin/communication/email_sender.py +159 -0
  89. genxai/tools/builtin/communication/notification_manager.py +167 -0
  90. genxai/tools/builtin/communication/slack_notifier.py +118 -0
  91. genxai/tools/builtin/communication/sms_sender.py +118 -0
  92. genxai/tools/builtin/communication/webhook_caller.py +136 -0
  93. genxai/tools/builtin/computation/__init__.py +15 -0
  94. genxai/tools/builtin/computation/calculator.py +101 -0
  95. genxai/tools/builtin/computation/code_executor.py +183 -0
  96. genxai/tools/builtin/computation/data_validator.py +259 -0
  97. genxai/tools/builtin/computation/hash_generator.py +129 -0
  98. genxai/tools/builtin/computation/regex_matcher.py +201 -0
  99. genxai/tools/builtin/data/__init__.py +15 -0
  100. genxai/tools/builtin/data/csv_processor.py +213 -0
  101. genxai/tools/builtin/data/data_transformer.py +299 -0
  102. genxai/tools/builtin/data/json_processor.py +233 -0
  103. genxai/tools/builtin/data/text_analyzer.py +288 -0
  104. genxai/tools/builtin/data/xml_processor.py +175 -0
  105. genxai/tools/builtin/database/__init__.py +15 -0
  106. genxai/tools/builtin/database/database_inspector.py +157 -0
  107. genxai/tools/builtin/database/mongodb_query.py +196 -0
  108. genxai/tools/builtin/database/redis_cache.py +167 -0
  109. genxai/tools/builtin/database/sql_query.py +145 -0
  110. genxai/tools/builtin/database/vector_search.py +163 -0
  111. genxai/tools/builtin/file/__init__.py +17 -0
  112. genxai/tools/builtin/file/directory_scanner.py +214 -0
  113. genxai/tools/builtin/file/file_compressor.py +237 -0
  114. genxai/tools/builtin/file/file_reader.py +102 -0
  115. genxai/tools/builtin/file/file_writer.py +122 -0
  116. genxai/tools/builtin/file/image_processor.py +186 -0
  117. genxai/tools/builtin/file/pdf_parser.py +144 -0
  118. genxai/tools/builtin/test/__init__.py +15 -0
  119. genxai/tools/builtin/test/async_simulator.py +62 -0
  120. genxai/tools/builtin/test/data_transformer.py +99 -0
  121. genxai/tools/builtin/test/error_generator.py +82 -0
  122. genxai/tools/builtin/test/simple_math.py +94 -0
  123. genxai/tools/builtin/test/string_processor.py +72 -0
  124. genxai/tools/builtin/web/__init__.py +15 -0
  125. genxai/tools/builtin/web/api_caller.py +161 -0
  126. genxai/tools/builtin/web/html_parser.py +330 -0
  127. genxai/tools/builtin/web/http_client.py +187 -0
  128. genxai/tools/builtin/web/url_validator.py +162 -0
  129. genxai/tools/builtin/web/web_scraper.py +170 -0
  130. genxai/tools/custom/my_test_tool_2.py +9 -0
  131. genxai/tools/dynamic.py +105 -0
  132. genxai/tools/mcp_server.py +167 -0
  133. genxai/tools/persistence/__init__.py +6 -0
  134. genxai/tools/persistence/models.py +55 -0
  135. genxai/tools/persistence/service.py +322 -0
  136. genxai/tools/registry.py +227 -0
  137. genxai/tools/security/__init__.py +11 -0
  138. genxai/tools/security/limits.py +214 -0
  139. genxai/tools/security/policy.py +20 -0
  140. genxai/tools/security/sandbox.py +248 -0
  141. genxai/tools/templates.py +435 -0
  142. genxai/triggers/__init__.py +19 -0
  143. genxai/triggers/base.py +104 -0
  144. genxai/triggers/file_watcher.py +75 -0
  145. genxai/triggers/queue.py +68 -0
  146. genxai/triggers/registry.py +82 -0
  147. genxai/triggers/schedule.py +66 -0
  148. genxai/triggers/webhook.py +68 -0
  149. genxai/utils/__init__.py +1 -0
  150. genxai/utils/tokens.py +295 -0
  151. genxai_framework-0.1.0.dist-info/METADATA +495 -0
  152. genxai_framework-0.1.0.dist-info/RECORD +156 -0
  153. genxai_framework-0.1.0.dist-info/WHEEL +5 -0
  154. genxai_framework-0.1.0.dist-info/entry_points.txt +2 -0
  155. genxai_framework-0.1.0.dist-info/licenses/LICENSE +21 -0
  156. genxai_framework-0.1.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,30 @@
1
+ """Graph-based orchestration engine for GenXAI."""
2
+
3
+ from genxai.core.graph.nodes import Node, NodeType
4
+ from genxai.core.graph.edges import Edge
5
+ from genxai.core.graph.engine import Graph
6
+ from genxai.core.graph.executor import (
7
+ EnhancedGraph,
8
+ WorkflowExecutor,
9
+ execute_workflow_sync,
10
+ )
11
+ from genxai.core.graph.checkpoints import (
12
+ WorkflowCheckpoint,
13
+ WorkflowCheckpointManager,
14
+ )
15
+ from genxai.core.graph.trigger_runner import TriggerWorkflowRunner
16
+ from genxai.core.execution import WorkerQueueEngine
17
+
18
+ __all__ = [
19
+ "Node",
20
+ "NodeType",
21
+ "Edge",
22
+ "Graph",
23
+ "EnhancedGraph",
24
+ "WorkflowExecutor",
25
+ "execute_workflow_sync",
26
+ "WorkflowCheckpoint",
27
+ "WorkflowCheckpointManager",
28
+ "TriggerWorkflowRunner",
29
+ "WorkerQueueEngine",
30
+ ]
@@ -0,0 +1,77 @@
1
+ """Workflow checkpoint persistence utilities."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from datetime import datetime
7
+ from pathlib import Path
8
+ from typing import Any, Dict, Optional
9
+ import json
10
+
11
+ from genxai.core.graph.nodes import NodeStatus
12
+
13
+
14
+ @dataclass
15
+ class WorkflowCheckpoint:
16
+ """Snapshot of a workflow run."""
17
+
18
+ name: str
19
+ workflow: str
20
+ created_at: str
21
+ state: Dict[str, Any]
22
+ node_statuses: Dict[str, str]
23
+
24
+ def to_dict(self) -> Dict[str, Any]:
25
+ return {
26
+ "name": self.name,
27
+ "workflow": self.workflow,
28
+ "created_at": self.created_at,
29
+ "state": self.state,
30
+ "node_statuses": self.node_statuses,
31
+ }
32
+
33
+ @classmethod
34
+ def from_dict(cls, data: Dict[str, Any]) -> "WorkflowCheckpoint":
35
+ return cls(
36
+ name=data["name"],
37
+ workflow=data["workflow"],
38
+ created_at=data["created_at"],
39
+ state=data.get("state", {}),
40
+ node_statuses=data.get("node_statuses", {}),
41
+ )
42
+
43
+
44
+ class WorkflowCheckpointManager:
45
+ """Persist workflow checkpoints to disk."""
46
+
47
+ def __init__(self, base_dir: Path) -> None:
48
+ self.base_dir = base_dir
49
+
50
+ def save(self, checkpoint: WorkflowCheckpoint) -> Path:
51
+ self.base_dir.mkdir(parents=True, exist_ok=True)
52
+ path = self.base_dir / f"checkpoint_{checkpoint.name}.json"
53
+ path.write_text(json.dumps(checkpoint.to_dict(), indent=2, default=str))
54
+ return path
55
+
56
+ def load(self, name: str) -> WorkflowCheckpoint:
57
+ path = self.base_dir / f"checkpoint_{name}.json"
58
+ if not path.exists():
59
+ raise FileNotFoundError(f"Checkpoint not found: {path}")
60
+ data = json.loads(path.read_text())
61
+ return WorkflowCheckpoint.from_dict(data)
62
+
63
+
64
+ def create_checkpoint(
65
+ name: str,
66
+ workflow: str,
67
+ state: Dict[str, Any],
68
+ node_statuses: Dict[str, NodeStatus],
69
+ ) -> WorkflowCheckpoint:
70
+ """Create a checkpoint object from current workflow state."""
71
+ return WorkflowCheckpoint(
72
+ name=name,
73
+ workflow=workflow,
74
+ created_at=datetime.now().isoformat(),
75
+ state=state,
76
+ node_statuses={node_id: status.value for node_id, status in node_statuses.items()},
77
+ )
@@ -0,0 +1,131 @@
1
+ """Edge types and implementations for graph connections."""
2
+
3
+ from enum import Enum
4
+ from typing import Any, Callable, Dict, Optional
5
+ from pydantic import BaseModel, Field, ConfigDict
6
+
7
+
8
+ class Edge(BaseModel):
9
+ """Edge connecting two nodes in the graph."""
10
+
11
+ model_config = ConfigDict(arbitrary_types_allowed=True)
12
+
13
+ source: str
14
+ target: str
15
+ condition: Optional[Callable[[Dict[str, Any]], bool]] = None
16
+ metadata: Dict[str, Any] = Field(default_factory=dict)
17
+ priority: int = 0 # For ordering multiple edges from same source
18
+
19
+
20
+ def __repr__(self) -> str:
21
+ """String representation of the edge."""
22
+ condition_str = "conditional" if self.condition else "unconditional"
23
+ return f"Edge({self.source} -> {self.target}, {condition_str})"
24
+
25
+ def __hash__(self) -> int:
26
+ """Hash function for edge."""
27
+ return hash((self.source, self.target))
28
+
29
+ def evaluate_condition(self, state: Dict[str, Any]) -> bool:
30
+ """Evaluate the edge condition with given state."""
31
+ if self.condition is None:
32
+ return True
33
+ try:
34
+ return self.condition(state)
35
+ except Exception:
36
+ return False
37
+
38
+
39
+ class EdgeType(str, Enum):
40
+ """High-level edge type used by the public WorkflowEngine API.
41
+
42
+ The core engine implements sequencing/parallelism via metadata flags.
43
+ This enum is a compatibility layer for integration tests + user-facing APIs.
44
+ """
45
+
46
+ SEQUENTIAL = "sequential"
47
+ PARALLEL = "parallel"
48
+ CONDITIONAL = "conditional"
49
+
50
+
51
+ class WorkflowEdge(Edge):
52
+ """Compatibility edge that accepts from_node/to_node/edge_type."""
53
+
54
+ def __init__(
55
+ self,
56
+ from_node: str,
57
+ to_node: str,
58
+ edge_type: EdgeType = EdgeType.SEQUENTIAL,
59
+ condition: Optional[Callable[[Dict[str, Any]], bool]] = None,
60
+ **kwargs: Any,
61
+ ) -> None:
62
+ metadata = dict(kwargs.pop("metadata", {}) or {})
63
+
64
+ if edge_type == EdgeType.PARALLEL:
65
+ metadata["parallel"] = True
66
+
67
+ super().__init__(
68
+ source=from_node,
69
+ target=to_node,
70
+ condition=condition,
71
+ metadata=metadata,
72
+ **kwargs,
73
+ )
74
+
75
+
76
+
77
+ class ConditionalEdge(Edge):
78
+ """Edge with a condition that must be satisfied."""
79
+
80
+ def __init__(
81
+ self,
82
+ source: str,
83
+ target: str,
84
+ condition: Callable[[Dict[str, Any]], bool],
85
+ **kwargs: Any,
86
+ ) -> None:
87
+ """Initialize conditional edge."""
88
+ super().__init__(source=source, target=target, condition=condition, **kwargs)
89
+
90
+
91
+ class ParallelEdge(Edge):
92
+ """Edge that allows parallel execution."""
93
+
94
+ def __init__(self, source: str, target: str, **kwargs: Any) -> None:
95
+ """Initialize parallel edge."""
96
+ super().__init__(
97
+ source=source,
98
+ target=target,
99
+ metadata={"parallel": True, **kwargs.get("metadata", {})},
100
+ **{k: v for k, v in kwargs.items() if k != "metadata"},
101
+ )
102
+
103
+
104
+ # Backwards compatible alias for integration tests
105
+ # They import: from genxai.core.graph.edges import Edge, EdgeType
106
+ # and instantiate Edge(from_node=..., to_node=..., edge_type=...)
107
+ _EdgePydantic = Edge
108
+
109
+
110
+ def Edge(*args: Any, **kwargs: Any): # type: ignore
111
+ """Factory for edges.
112
+
113
+ - If called with `source`/`target` it behaves like the pydantic Edge model.
114
+ - If called with `from_node`/`to_node` (and optional `edge_type`) it returns
115
+ a WorkflowEdge.
116
+ """
117
+
118
+ if "from_node" in kwargs or "to_node" in kwargs:
119
+ from_node = kwargs.pop("from_node")
120
+ to_node = kwargs.pop("to_node")
121
+ edge_type = kwargs.pop("edge_type", EdgeType.SEQUENTIAL)
122
+ condition = kwargs.pop("condition", None)
123
+ return WorkflowEdge(
124
+ from_node=from_node,
125
+ to_node=to_node,
126
+ edge_type=edge_type,
127
+ condition=condition,
128
+ **kwargs,
129
+ )
130
+
131
+ return _EdgePydantic(*args, **kwargs)