rapidagent 0.3.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 (50) hide show
  1. rapidagent/__init__.py +4 -0
  2. rapidagent/backends/__init__.py +16 -0
  3. rapidagent/backends/base.py +193 -0
  4. rapidagent/backends/direct.py +1018 -0
  5. rapidagent/backends/langgraph.py +185 -0
  6. rapidagent/blueprints/__init__.py +5 -0
  7. rapidagent/blueprints/rag.py +62 -0
  8. rapidagent/blueprints/research.py +91 -0
  9. rapidagent/blueprints/support.py +95 -0
  10. rapidagent/cli/__init__.py +0 -0
  11. rapidagent/cli/main.py +309 -0
  12. rapidagent/config/__init__.py +5 -0
  13. rapidagent/config/defaults.py +42 -0
  14. rapidagent/config/loader.py +46 -0
  15. rapidagent/config/schema.py +58 -0
  16. rapidagent/core/__init__.py +5 -0
  17. rapidagent/core/base.py +255 -0
  18. rapidagent/core/state.py +45 -0
  19. rapidagent/core/types.py +19 -0
  20. rapidagent/graphs/__init__.py +6 -0
  21. rapidagent/graphs/react.py +66 -0
  22. rapidagent/graphs/sequential.py +54 -0
  23. rapidagent/graphs/supervisor.py +116 -0
  24. rapidagent/graphs/swarm.py +98 -0
  25. rapidagent/guardrails/__init__.py +22 -0
  26. rapidagent/guardrails/base.py +199 -0
  27. rapidagent/guardrails/builtins.py +318 -0
  28. rapidagent/guardrails/config.py +97 -0
  29. rapidagent/memory/__init__.py +5 -0
  30. rapidagent/memory/base.py +34 -0
  31. rapidagent/memory/file_store.py +47 -0
  32. rapidagent/memory/in_memory.py +29 -0
  33. rapidagent/models/__init__.py +3 -0
  34. rapidagent/models/config.py +547 -0
  35. rapidagent/nodes/__init__.py +7 -0
  36. rapidagent/nodes/human.py +45 -0
  37. rapidagent/nodes/llm.py +44 -0
  38. rapidagent/nodes/memory.py +48 -0
  39. rapidagent/nodes/router.py +42 -0
  40. rapidagent/nodes/tool_executor.py +49 -0
  41. rapidagent/tools/__init__.py +5 -0
  42. rapidagent/tools/builtins.py +32 -0
  43. rapidagent/tools/decorator.py +80 -0
  44. rapidagent/tools/registry.py +51 -0
  45. rapidagent-0.3.0.dist-info/METADATA +394 -0
  46. rapidagent-0.3.0.dist-info/RECORD +50 -0
  47. rapidagent-0.3.0.dist-info/WHEEL +5 -0
  48. rapidagent-0.3.0.dist-info/entry_points.txt +2 -0
  49. rapidagent-0.3.0.dist-info/licenses/LICENSE +21 -0
  50. rapidagent-0.3.0.dist-info/top_level.txt +1 -0
rapidagent/__init__.py ADDED
@@ -0,0 +1,4 @@
1
+ from rapidagent.core.base import RapidAgent, BaseNode, BaseGraph
2
+ from rapidagent.tools.decorator import tool
3
+
4
+ __all__ = ["RapidAgent", "BaseNode", "BaseGraph", "tool"]
@@ -0,0 +1,16 @@
1
+ # Lazy imports — backends may have optional dependencies
2
+ from rapidagent.backends.base import Backend, BackendResult
3
+
4
+ __all__ = ["Backend", "BackendResult"]
5
+
6
+
7
+ def LangGraphBackend(*args, **kwargs):
8
+ """Lazy loader — langgraph is an optional dependency."""
9
+ from rapidagent.backends.langgraph import LangGraphBackend as _LB
10
+ return _LB(*args, **kwargs)
11
+
12
+
13
+ def DirectBackend(*args, **kwargs):
14
+ """Lazy loader — pure Python, no extra deps."""
15
+ from rapidagent.backends.direct import DirectBackend as _DB
16
+ return _DB(*args, **kwargs)
@@ -0,0 +1,193 @@
1
+ """Abstract backend interface for agent execution."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import abc
6
+ import sys
7
+ from dataclasses import dataclass, field
8
+ from typing import Any, Generator
9
+
10
+ from rapidagent.models.config import ModelConfig
11
+ from rapidagent.tools.registry import ToolRegistry
12
+
13
+
14
+ # ---------------------------------------------------------------------------
15
+ # Token / cost tracking
16
+ # ---------------------------------------------------------------------------
17
+
18
+ @dataclass
19
+ class TokenUsage:
20
+ """Token and cost tracking from an LLM response."""
21
+
22
+ prompt_tokens: int = 0
23
+ completion_tokens: int = 0
24
+ total_tokens: int = 0
25
+ cost_usd: float = 0.0
26
+
27
+ def add(self, other: TokenUsage) -> None:
28
+ self.prompt_tokens += other.prompt_tokens
29
+ self.completion_tokens += other.completion_tokens
30
+ self.total_tokens += other.total_tokens
31
+ self.cost_usd += other.cost_usd
32
+
33
+ @classmethod
34
+ def from_openai_response(cls, response: Any, model: str = "gpt-4o-mini") -> TokenUsage:
35
+ """Parse token usage from an OpenAI chat completion response."""
36
+ rates = {
37
+ "gpt-4o-mini": (0.00015, 0.00060),
38
+ "gpt-4o": (0.00250, 0.01000),
39
+ "gpt-5": (0.00500, 0.02000),
40
+ }
41
+ usage = getattr(response, "usage", None) or getattr(response, "usage_metadata", None)
42
+ if usage is None:
43
+ return cls()
44
+
45
+ pt = getattr(usage, "prompt_tokens", getattr(usage, "input_tokens", 0)) or 0
46
+ ct = getattr(usage, "completion_tokens", getattr(usage, "output_tokens", 0)) or 0
47
+ r = rates.get(model, (0.0, 0.0))
48
+ cost = (pt / 1_000_000) * r[0] + (ct / 1_000_000) * r[1]
49
+ return cls(prompt_tokens=pt, completion_tokens=ct, total_tokens=pt + ct, cost_usd=cost)
50
+
51
+
52
+ # ---------------------------------------------------------------------------
53
+ # Result
54
+ # ---------------------------------------------------------------------------
55
+
56
+ @dataclass
57
+ class BackendResult:
58
+ """Standard result returned by any backend's ``invoke`` / ``stream``."""
59
+
60
+ messages: list[Any] = field(default_factory=list)
61
+ content: str = ""
62
+ error: str | None = None
63
+ raw: dict[str, Any] = field(default_factory=dict)
64
+ usage: TokenUsage = field(default_factory=TokenUsage)
65
+
66
+ @classmethod
67
+ def from_content(cls, content: str) -> "BackendResult":
68
+ return cls(content=content, messages=[{"role": "assistant", "content": content}])
69
+
70
+
71
+ # ---------------------------------------------------------------------------
72
+ # Backend
73
+ # ---------------------------------------------------------------------------
74
+
75
+ class Backend(abc.ABC):
76
+ """Abstract base for agent execution backends."""
77
+
78
+ name: str = ""
79
+
80
+ def __init__(self, checkpoint_dir: str | None = None) -> None:
81
+ self._checkpoint_dir = checkpoint_dir
82
+ self._guardrail_pipeline: Any = None
83
+
84
+ def set_guardrails(self, pipeline: Any) -> None:
85
+ self._guardrail_pipeline = pipeline
86
+
87
+ # -- Single agent --
88
+
89
+ @abc.abstractmethod
90
+ def build_react(
91
+ self,
92
+ llm_config: ModelConfig,
93
+ tools: ToolRegistry,
94
+ system_prompt: str,
95
+ max_iterations: int = 10,
96
+ response_format: type | None = None,
97
+ ) -> Any:
98
+ """Build a compiled ReAct agent.
99
+
100
+ Args:
101
+ llm_config: Model configuration (provider, model, auth, etc.).
102
+ tools: Registered tools.
103
+ system_prompt: System prompt for the LLM.
104
+ max_iterations: Max ReAct loop iterations.
105
+ response_format: Optional Pydantic model for structured output.
106
+ Returns:
107
+ An opaque compiled object for ``invoke`` / ``stream``.
108
+ """
109
+ ...
110
+
111
+ @abc.abstractmethod
112
+ def invoke(
113
+ self,
114
+ compiled: Any,
115
+ message: str,
116
+ thread_id: str | None = None,
117
+ stream: bool = False,
118
+ ) -> BackendResult:
119
+ """Run the agent with a message.
120
+
121
+ Args:
122
+ compiled: Compiled agent from ``build_react``.
123
+ message: User input.
124
+ thread_id: Conversation thread ID (for checkpointing).
125
+ stream: If True, ``result.content`` is updated progressively.
126
+ """
127
+ ...
128
+
129
+ @abc.abstractmethod
130
+ def stream(
131
+ self,
132
+ compiled: Any,
133
+ message: str,
134
+ thread_id: str | None = None,
135
+ ) -> Any:
136
+ """Stream agent execution events."""
137
+ ...
138
+
139
+ # -- Multi-agent --
140
+
141
+ def build_supervisor(
142
+ self,
143
+ supervisor_config: ModelConfig,
144
+ workers: dict[str, Any],
145
+ supervisor_prompt: str | None = None,
146
+ ) -> Any:
147
+ """Build a supervisor/worker multi-agent system.
148
+
149
+ Falls back to ``DirectSupervisorGraph`` by default.
150
+ Override in backend-specific subclasses for deeper integration.
151
+ """
152
+ from rapidagent.backends.direct import DirectSupervisorGraph
153
+
154
+ return DirectSupervisorGraph(
155
+ supervisor_config=supervisor_config,
156
+ workers=workers,
157
+ supervisor_prompt=supervisor_prompt,
158
+ )
159
+
160
+
161
+ # ---------------------------------------------------------------------------
162
+ # Helpers
163
+ # ---------------------------------------------------------------------------
164
+
165
+ def get_default_backend() -> str:
166
+ if sys.version_info >= (3, 14):
167
+ return "direct"
168
+ return "langgraph"
169
+
170
+
171
+ def create_backend(name: str | None = None, checkpoint_dir: str | None = None) -> Backend:
172
+ import warnings
173
+
174
+ name = name or get_default_backend()
175
+
176
+ if name == "langgraph":
177
+ try:
178
+ from rapidagent.backends.langgraph import LangGraphBackend
179
+
180
+ return LangGraphBackend(checkpoint_dir=checkpoint_dir)
181
+ except ImportError:
182
+ warnings.warn(
183
+ "LangGraph not installed. Falling back to 'direct'. "
184
+ "Install: pip install rapidagent[langgraph]",
185
+ stacklevel=2,
186
+ )
187
+ from rapidagent.backends.direct import DirectBackend
188
+ return DirectBackend(checkpoint_dir=checkpoint_dir)
189
+ elif name == "direct":
190
+ from rapidagent.backends.direct import DirectBackend
191
+ return DirectBackend(checkpoint_dir=checkpoint_dir)
192
+ else:
193
+ raise ValueError(f"Unknown backend: '{name}'. Supported: 'langgraph', 'direct'.")