raindrop-crewai 0.0.1__tar.gz

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.
@@ -0,0 +1 @@
1
+ .venv/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Raindrop AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,239 @@
1
+ Metadata-Version: 2.4
2
+ Name: raindrop-crewai
3
+ Version: 0.0.1
4
+ Summary: Raindrop integration for CrewAI multi-agent framework
5
+ Project-URL: Homepage, https://raindrop.ai
6
+ Project-URL: Repository, https://github.com/invisible-tools/dawn/tree/main/packages/crewai-python
7
+ Project-URL: Documentation, https://docs.raindrop.ai
8
+ Author-email: Raindrop AI <sdk@raindrop.ai>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Typing :: Typed
12
+ Requires-Python: >=3.10
13
+ Requires-Dist: raindrop-ai>=0.0.42
14
+ Provides-Extra: crewai
15
+ Requires-Dist: crewai>=1.1.0; extra == 'crewai'
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
18
+ Requires-Dist: pytest>=8.0; extra == 'dev'
19
+ Requires-Dist: wrapt<2; extra == 'dev'
20
+ Description-Content-Type: text/markdown
21
+
22
+ # raindrop-crewai
23
+
24
+ Raindrop integration for [CrewAI](https://www.crewai.com/) (Python). Automatically captures crew kickoff invocations, multi-agent collaboration, task execution, and token usage by monkey-patching `Crew.kickoff*`.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install raindrop-crewai crewai
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ```python
35
+ from raindrop_crewai import RaindropCrewAI
36
+ from crewai import Agent, Crew, Task
37
+
38
+ raindrop = RaindropCrewAI(
39
+ api_key="your-write-key",
40
+ user_id="user-123",
41
+ )
42
+ raindrop.setup() # auto-patch all Crew.kickoff* methods
43
+
44
+ agent = Agent(
45
+ role="Senior Researcher",
46
+ goal="Find one interesting fact about {topic}",
47
+ backstory="You are an experienced researcher.",
48
+ )
49
+ task = Task(
50
+ description="Identify one interesting fact about {topic}.",
51
+ expected_output="A single sentence fact.",
52
+ agent=agent,
53
+ )
54
+ crew = Crew(agents=[agent], tasks=[task])
55
+
56
+ result = crew.kickoff(inputs={"topic": "AI safety"})
57
+ print(result.raw)
58
+
59
+ raindrop.shutdown()
60
+ ```
61
+
62
+ ### Factory function (alternative)
63
+
64
+ ```python
65
+ from raindrop_crewai import create_raindrop_crewai
66
+
67
+ raindrop = create_raindrop_crewai(api_key="your-write-key", user_id="user-123")
68
+ wrapped = raindrop.wrap(crew) # per-instance wrap (no global monkey-patch)
69
+ result = wrapped.kickoff(inputs={"topic": "AI safety"})
70
+ raindrop.shutdown()
71
+ ```
72
+
73
+ ## What Gets Captured
74
+
75
+ - **Crew kickoff invocations** — input variables, crew name, process type (sequential/hierarchical)
76
+ - **Agent metadata** — agent roles and count
77
+ - **Task metadata** — task descriptions, count, and per-task summaries
78
+ - **Token usage** — `ai.usage.prompt_tokens`, `ai.usage.completion_tokens`, `ai.usage.cached_tokens`, `ai.usage.total_tokens`
79
+ - **Model name** — extracted from the first agent's `llm.model` (when set)
80
+ - **Errors** — `error.type` / `error.message` properties; the original exception is always re-raised
81
+ - **Async support** — `kickoff()`, `kickoff_async()`, `kickoff_for_each()`, `kickoff_for_each_async()` are all instrumented
82
+ - **Nested OTel trace spans** — crew workflow → agent → task → LLM, via the `opentelemetry-instrumentation-crewai` instrumentor (see [Tracing](#tracing); per-tool spans are not produced — see [Known Limitations](#known-limitations))
83
+
84
+ ## Configuration patterns
85
+
86
+ ### Auto-patch all crews (recommended)
87
+
88
+ Monkey-patches the `Crew` class so every `kickoff*` call is traced:
89
+
90
+ ```python
91
+ from raindrop_crewai import setup_crewai
92
+
93
+ raindrop = setup_crewai(api_key="your-write-key", user_id="user-123")
94
+ # Every Crew.kickoff(...) is now traced automatically.
95
+ ```
96
+
97
+ ### Wrap a specific crew
98
+
99
+ Per-instance wrap with no global side effects:
100
+
101
+ ```python
102
+ raindrop = RaindropCrewAI(api_key="your-write-key", user_id="user-123")
103
+ wrapped = raindrop.wrap(crew)
104
+ result = wrapped.kickoff(inputs={"topic": "..."})
105
+ ```
106
+
107
+ ## Debug Mode
108
+
109
+ Enable verbose logging with `debug=True`:
110
+
111
+ ```python
112
+ raindrop = RaindropCrewAI(api_key="your-write-key", debug=True)
113
+ ```
114
+
115
+ This sets the `raindrop_crewai` logger to `DEBUG`, surfacing telemetry-side failures that are otherwise swallowed (so the user's pipeline never crashes due to instrumentation).
116
+
117
+ ## Identify Users
118
+
119
+ Associate events with a user identity after initialization:
120
+
121
+ ```python
122
+ raindrop.identify("user-123", {"name": "Alice", "plan": "pro"})
123
+ ```
124
+
125
+ ## Track Signals
126
+
127
+ Attach feedback, edits, or other custom signals to a previously-shipped event by its `event_id`. The Python SDK does not currently expose a `lastEventId` accessor like the TypeScript client does, so to attach a signal you need either (a) the `event_id` returned to your application out-of-band (e.g. logged by `debug=True`), or (b) the public ID surfaced on the dashboard's event detail page.
128
+
129
+ ```python
130
+ raindrop.track_signal(
131
+ event_id="<event-id-from-dashboard-or-debug-log>",
132
+ name="thumbs_up",
133
+ signal_type="feedback",
134
+ sentiment="POSITIVE",
135
+ comment="Great answer!",
136
+ )
137
+ ```
138
+
139
+ ## Tracing
140
+
141
+ When `tracing_enabled=True` (the default), the integration activates the `opentelemetry-instrumentation-crewai` instrumentor via `traceloop-sdk`, producing nested OTel spans for every crew execution:
142
+
143
+ - **Crew workflow** — root span covering the entire `kickoff()` call (`crewai.workflow`)
144
+ - **Agent execution** — child span per agent (`{role}.agent`)
145
+ - **Task execution** — child span per task (`{name}.task`)
146
+ - **LLM calls** — leaf spans for each underlying LLM call, with model name and token usage
147
+
148
+ Trace spans land in the dashboard's Traces tab after async ingestion (typically 30–120s).
149
+
150
+ To ship flat events only without OTel spans:
151
+
152
+ ```python
153
+ raindrop = RaindropCrewAI(api_key="your-write-key", tracing_enabled=False)
154
+ ```
155
+
156
+ ## Async Usage
157
+
158
+ ```python
159
+ import asyncio
160
+
161
+ async def main():
162
+ result = await crew.kickoff_async(inputs={"topic": "AI safety"})
163
+ print(result.raw)
164
+
165
+ results = await crew.kickoff_for_each_async(
166
+ inputs=[{"topic": "AI"}, {"topic": "ML"}]
167
+ )
168
+
169
+ asyncio.run(main())
170
+ ```
171
+
172
+ ## Flushing and Shutdown
173
+
174
+ ```python
175
+ raindrop.flush() # flush pending data
176
+ raindrop.shutdown() # flush + release resources (call before process exit)
177
+ ```
178
+
179
+ ## API Reference
180
+
181
+ ### `RaindropCrewAI`
182
+
183
+ | Parameter | Type | Default | Description |
184
+ |---|---|---|---|
185
+ | `api_key` | `Optional[str]` | `None` | Raindrop API key. If `None`, telemetry shipping is disabled (a `UserWarning` is issued). |
186
+ | `user_id` | `Optional[str]` | `None` | Default user identifier for all events. |
187
+ | `convo_id` | `Optional[str]` | `None` | Conversation/thread ID to group related events. |
188
+ | `tracing_enabled` | `bool` | `True` | Enable distributed tracing via the OTel CrewAI instrumentor. |
189
+ | `bypass_otel_for_tools` | `bool` | `True` | Forwarded to `raindrop.init()`. Controls whether tool spans on the underlying SDK skip the OTLP path. The CrewAI integration itself does not call `interaction.track_tool()`, so this flag has no observable effect on CrewAI events — exposed for SDK API parity. |
190
+ | `debug` | `bool` | `False` | Enable debug logging. |
191
+
192
+ ### Methods
193
+
194
+ | Method | Description |
195
+ |---|---|
196
+ | `setup()` | Monkey-patch `Crew.kickoff*` so every kickoff is traced (one-time, idempotent). |
197
+ | `wrap(crew)` | Per-instance wrap of a single `Crew` (no global side effects). Returns the wrapped crew. |
198
+ | `flush()` | Flush all pending events to the Raindrop API. |
199
+ | `shutdown()` | Flush remaining events and release resources. |
200
+ | `identify(user_id, traits)` | Identify a user with optional traits (`Dict[str, str \| int \| bool \| float]`). |
201
+ | `track_signal(event_id, name, ...)` | Track a signal event. See `track_signal` signature in `wrapper.py` for the full keyword-only parameters. |
202
+
203
+ ### Module-level helpers
204
+
205
+ - `create_raindrop_crewai(...)` — construct a `RaindropCrewAI` and return a no-op instance on failure (never crashes).
206
+ - `setup_crewai(...)` — convenience: construct a `RaindropCrewAI` and call `setup()` in one step.
207
+
208
+ ## Known Limitations
209
+
210
+ - **No per-tool spans / empty `event.toolCalls`** — the underlying `opentelemetry-instrumentation-crewai` instrumentor only wraps `Crew.kickoff` (workflow), `Agent.execute_task` (`.agent`), `Task.execute_sync` (`.task`), and `LLM.call` (LLM generation). It does NOT produce a span per tool invocation, so `event.toolCalls` on the dashboard will be empty for CrewAI runs. Tool usage surfaces only in the agent's final output text and indirectly in the agent/task span durations.
211
+ - **Streaming** — CrewAI's `CrewStreamingOutput` is returned to the caller as-is; the flat Raindrop event is shipped after the stream completes.
212
+ - **`finish_reason` is per-LLM, not per-crew** — `CrewOutput` does not expose `finish_reason`. Per-LLM finish reasons appear on the LLM trace spans inside the workflow trace, not on the flat event.
213
+ - **Python SDK feature surface** — the Python SDK is module-level and does not expose `EventShipper` / `TraceShipper` classes. The `identify()` and `track_signal()` methods are pass-through wrappers around the `raindrop.analytics.*` module functions.
214
+ - **wrapt < 2 required for tracing** — the OTel CrewAI instrumentor uses `wrapt.wrap_function_wrapper(..., module=...)` which was removed in wrapt 2.0. The package's dev dependencies pin `wrapt<2`; production environments using wrapt 2.x will see no trace spans (the flat event still ships).
215
+
216
+ ## Testing
217
+
218
+ ```bash
219
+ cd packages/crewai-python
220
+ pip install -e ".[crewai,dev]"
221
+
222
+ # All tests. Unit tests run unconditionally; e2e tests skip gracefully
223
+ # unless RAINDROP_WRITE_KEY + OPENAI_API_KEY + RAINDROP_DASHBOARD_TOKEN
224
+ # are all set (this is what CI does).
225
+ python -m pytest tests/ -v
226
+
227
+ # End-to-end against the live Raindrop backend (manual run, requires
228
+ # all three env vars). Get RAINDROP_DASHBOARD_TOKEN from app.raindrop.ai
229
+ # DevTools → Network → any backend.raindrop.ai request → Authorization
230
+ # header (token expires every ~30 min).
231
+ RAINDROP_WRITE_KEY=your-write-key \
232
+ RAINDROP_DASHBOARD_TOKEN=eyJ... \
233
+ OPENAI_API_KEY=sk-... \
234
+ python -m pytest tests/test_e2e.py -v
235
+ ```
236
+
237
+ ## Documentation
238
+
239
+ Full documentation: [Raindrop CrewAI Integration](https://docs.raindrop.ai/integrations/crewai).
@@ -0,0 +1,218 @@
1
+ # raindrop-crewai
2
+
3
+ Raindrop integration for [CrewAI](https://www.crewai.com/) (Python). Automatically captures crew kickoff invocations, multi-agent collaboration, task execution, and token usage by monkey-patching `Crew.kickoff*`.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install raindrop-crewai crewai
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ from raindrop_crewai import RaindropCrewAI
15
+ from crewai import Agent, Crew, Task
16
+
17
+ raindrop = RaindropCrewAI(
18
+ api_key="your-write-key",
19
+ user_id="user-123",
20
+ )
21
+ raindrop.setup() # auto-patch all Crew.kickoff* methods
22
+
23
+ agent = Agent(
24
+ role="Senior Researcher",
25
+ goal="Find one interesting fact about {topic}",
26
+ backstory="You are an experienced researcher.",
27
+ )
28
+ task = Task(
29
+ description="Identify one interesting fact about {topic}.",
30
+ expected_output="A single sentence fact.",
31
+ agent=agent,
32
+ )
33
+ crew = Crew(agents=[agent], tasks=[task])
34
+
35
+ result = crew.kickoff(inputs={"topic": "AI safety"})
36
+ print(result.raw)
37
+
38
+ raindrop.shutdown()
39
+ ```
40
+
41
+ ### Factory function (alternative)
42
+
43
+ ```python
44
+ from raindrop_crewai import create_raindrop_crewai
45
+
46
+ raindrop = create_raindrop_crewai(api_key="your-write-key", user_id="user-123")
47
+ wrapped = raindrop.wrap(crew) # per-instance wrap (no global monkey-patch)
48
+ result = wrapped.kickoff(inputs={"topic": "AI safety"})
49
+ raindrop.shutdown()
50
+ ```
51
+
52
+ ## What Gets Captured
53
+
54
+ - **Crew kickoff invocations** — input variables, crew name, process type (sequential/hierarchical)
55
+ - **Agent metadata** — agent roles and count
56
+ - **Task metadata** — task descriptions, count, and per-task summaries
57
+ - **Token usage** — `ai.usage.prompt_tokens`, `ai.usage.completion_tokens`, `ai.usage.cached_tokens`, `ai.usage.total_tokens`
58
+ - **Model name** — extracted from the first agent's `llm.model` (when set)
59
+ - **Errors** — `error.type` / `error.message` properties; the original exception is always re-raised
60
+ - **Async support** — `kickoff()`, `kickoff_async()`, `kickoff_for_each()`, `kickoff_for_each_async()` are all instrumented
61
+ - **Nested OTel trace spans** — crew workflow → agent → task → LLM, via the `opentelemetry-instrumentation-crewai` instrumentor (see [Tracing](#tracing); per-tool spans are not produced — see [Known Limitations](#known-limitations))
62
+
63
+ ## Configuration patterns
64
+
65
+ ### Auto-patch all crews (recommended)
66
+
67
+ Monkey-patches the `Crew` class so every `kickoff*` call is traced:
68
+
69
+ ```python
70
+ from raindrop_crewai import setup_crewai
71
+
72
+ raindrop = setup_crewai(api_key="your-write-key", user_id="user-123")
73
+ # Every Crew.kickoff(...) is now traced automatically.
74
+ ```
75
+
76
+ ### Wrap a specific crew
77
+
78
+ Per-instance wrap with no global side effects:
79
+
80
+ ```python
81
+ raindrop = RaindropCrewAI(api_key="your-write-key", user_id="user-123")
82
+ wrapped = raindrop.wrap(crew)
83
+ result = wrapped.kickoff(inputs={"topic": "..."})
84
+ ```
85
+
86
+ ## Debug Mode
87
+
88
+ Enable verbose logging with `debug=True`:
89
+
90
+ ```python
91
+ raindrop = RaindropCrewAI(api_key="your-write-key", debug=True)
92
+ ```
93
+
94
+ This sets the `raindrop_crewai` logger to `DEBUG`, surfacing telemetry-side failures that are otherwise swallowed (so the user's pipeline never crashes due to instrumentation).
95
+
96
+ ## Identify Users
97
+
98
+ Associate events with a user identity after initialization:
99
+
100
+ ```python
101
+ raindrop.identify("user-123", {"name": "Alice", "plan": "pro"})
102
+ ```
103
+
104
+ ## Track Signals
105
+
106
+ Attach feedback, edits, or other custom signals to a previously-shipped event by its `event_id`. The Python SDK does not currently expose a `lastEventId` accessor like the TypeScript client does, so to attach a signal you need either (a) the `event_id` returned to your application out-of-band (e.g. logged by `debug=True`), or (b) the public ID surfaced on the dashboard's event detail page.
107
+
108
+ ```python
109
+ raindrop.track_signal(
110
+ event_id="<event-id-from-dashboard-or-debug-log>",
111
+ name="thumbs_up",
112
+ signal_type="feedback",
113
+ sentiment="POSITIVE",
114
+ comment="Great answer!",
115
+ )
116
+ ```
117
+
118
+ ## Tracing
119
+
120
+ When `tracing_enabled=True` (the default), the integration activates the `opentelemetry-instrumentation-crewai` instrumentor via `traceloop-sdk`, producing nested OTel spans for every crew execution:
121
+
122
+ - **Crew workflow** — root span covering the entire `kickoff()` call (`crewai.workflow`)
123
+ - **Agent execution** — child span per agent (`{role}.agent`)
124
+ - **Task execution** — child span per task (`{name}.task`)
125
+ - **LLM calls** — leaf spans for each underlying LLM call, with model name and token usage
126
+
127
+ Trace spans land in the dashboard's Traces tab after async ingestion (typically 30–120s).
128
+
129
+ To ship flat events only without OTel spans:
130
+
131
+ ```python
132
+ raindrop = RaindropCrewAI(api_key="your-write-key", tracing_enabled=False)
133
+ ```
134
+
135
+ ## Async Usage
136
+
137
+ ```python
138
+ import asyncio
139
+
140
+ async def main():
141
+ result = await crew.kickoff_async(inputs={"topic": "AI safety"})
142
+ print(result.raw)
143
+
144
+ results = await crew.kickoff_for_each_async(
145
+ inputs=[{"topic": "AI"}, {"topic": "ML"}]
146
+ )
147
+
148
+ asyncio.run(main())
149
+ ```
150
+
151
+ ## Flushing and Shutdown
152
+
153
+ ```python
154
+ raindrop.flush() # flush pending data
155
+ raindrop.shutdown() # flush + release resources (call before process exit)
156
+ ```
157
+
158
+ ## API Reference
159
+
160
+ ### `RaindropCrewAI`
161
+
162
+ | Parameter | Type | Default | Description |
163
+ |---|---|---|---|
164
+ | `api_key` | `Optional[str]` | `None` | Raindrop API key. If `None`, telemetry shipping is disabled (a `UserWarning` is issued). |
165
+ | `user_id` | `Optional[str]` | `None` | Default user identifier for all events. |
166
+ | `convo_id` | `Optional[str]` | `None` | Conversation/thread ID to group related events. |
167
+ | `tracing_enabled` | `bool` | `True` | Enable distributed tracing via the OTel CrewAI instrumentor. |
168
+ | `bypass_otel_for_tools` | `bool` | `True` | Forwarded to `raindrop.init()`. Controls whether tool spans on the underlying SDK skip the OTLP path. The CrewAI integration itself does not call `interaction.track_tool()`, so this flag has no observable effect on CrewAI events — exposed for SDK API parity. |
169
+ | `debug` | `bool` | `False` | Enable debug logging. |
170
+
171
+ ### Methods
172
+
173
+ | Method | Description |
174
+ |---|---|
175
+ | `setup()` | Monkey-patch `Crew.kickoff*` so every kickoff is traced (one-time, idempotent). |
176
+ | `wrap(crew)` | Per-instance wrap of a single `Crew` (no global side effects). Returns the wrapped crew. |
177
+ | `flush()` | Flush all pending events to the Raindrop API. |
178
+ | `shutdown()` | Flush remaining events and release resources. |
179
+ | `identify(user_id, traits)` | Identify a user with optional traits (`Dict[str, str \| int \| bool \| float]`). |
180
+ | `track_signal(event_id, name, ...)` | Track a signal event. See `track_signal` signature in `wrapper.py` for the full keyword-only parameters. |
181
+
182
+ ### Module-level helpers
183
+
184
+ - `create_raindrop_crewai(...)` — construct a `RaindropCrewAI` and return a no-op instance on failure (never crashes).
185
+ - `setup_crewai(...)` — convenience: construct a `RaindropCrewAI` and call `setup()` in one step.
186
+
187
+ ## Known Limitations
188
+
189
+ - **No per-tool spans / empty `event.toolCalls`** — the underlying `opentelemetry-instrumentation-crewai` instrumentor only wraps `Crew.kickoff` (workflow), `Agent.execute_task` (`.agent`), `Task.execute_sync` (`.task`), and `LLM.call` (LLM generation). It does NOT produce a span per tool invocation, so `event.toolCalls` on the dashboard will be empty for CrewAI runs. Tool usage surfaces only in the agent's final output text and indirectly in the agent/task span durations.
190
+ - **Streaming** — CrewAI's `CrewStreamingOutput` is returned to the caller as-is; the flat Raindrop event is shipped after the stream completes.
191
+ - **`finish_reason` is per-LLM, not per-crew** — `CrewOutput` does not expose `finish_reason`. Per-LLM finish reasons appear on the LLM trace spans inside the workflow trace, not on the flat event.
192
+ - **Python SDK feature surface** — the Python SDK is module-level and does not expose `EventShipper` / `TraceShipper` classes. The `identify()` and `track_signal()` methods are pass-through wrappers around the `raindrop.analytics.*` module functions.
193
+ - **wrapt < 2 required for tracing** — the OTel CrewAI instrumentor uses `wrapt.wrap_function_wrapper(..., module=...)` which was removed in wrapt 2.0. The package's dev dependencies pin `wrapt<2`; production environments using wrapt 2.x will see no trace spans (the flat event still ships).
194
+
195
+ ## Testing
196
+
197
+ ```bash
198
+ cd packages/crewai-python
199
+ pip install -e ".[crewai,dev]"
200
+
201
+ # All tests. Unit tests run unconditionally; e2e tests skip gracefully
202
+ # unless RAINDROP_WRITE_KEY + OPENAI_API_KEY + RAINDROP_DASHBOARD_TOKEN
203
+ # are all set (this is what CI does).
204
+ python -m pytest tests/ -v
205
+
206
+ # End-to-end against the live Raindrop backend (manual run, requires
207
+ # all three env vars). Get RAINDROP_DASHBOARD_TOKEN from app.raindrop.ai
208
+ # DevTools → Network → any backend.raindrop.ai request → Authorization
209
+ # header (token expires every ~30 min).
210
+ RAINDROP_WRITE_KEY=your-write-key \
211
+ RAINDROP_DASHBOARD_TOKEN=eyJ... \
212
+ OPENAI_API_KEY=sk-... \
213
+ python -m pytest tests/test_e2e.py -v
214
+ ```
215
+
216
+ ## Documentation
217
+
218
+ Full documentation: [Raindrop CrewAI Integration](https://docs.raindrop.ai/integrations/crewai).
@@ -0,0 +1,50 @@
1
+ [project]
2
+ name = "raindrop-crewai"
3
+ version = "0.0.1"
4
+ description = "Raindrop integration for CrewAI multi-agent framework"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ requires-python = ">=3.10"
8
+ authors = [
9
+ {name = "Raindrop AI", email = "sdk@raindrop.ai"},
10
+ ]
11
+ classifiers = [
12
+ "Typing :: Typed",
13
+ ]
14
+ dependencies = [
15
+ "raindrop-ai>=0.0.42",
16
+ ]
17
+
18
+ [project.urls]
19
+ Homepage = "https://raindrop.ai"
20
+ Repository = "https://github.com/invisible-tools/dawn/tree/main/packages/crewai-python"
21
+ Documentation = "https://docs.raindrop.ai"
22
+
23
+ [project.optional-dependencies]
24
+ crewai = ["crewai>=1.1.0"]
25
+ # wrapt<2 is required because the OTel CrewAI instrumentor uses
26
+ # wrapt.wrap_function_wrapper(..., module=...) which was removed in wrapt 2.0.
27
+ # Without this pin, instrumentor activation silently fails ("No valid
28
+ # instruments set") and zero trace spans land in the dashboard. This bug
29
+ # was discovered in PR #2835 (Deep Agents) for the LangChain instrumentor;
30
+ # the same incompatibility affects every traceloop-style instrumentor.
31
+ dev = [
32
+ "pytest>=8.0",
33
+ "pytest-asyncio>=0.23.0",
34
+ "wrapt<2",
35
+ ]
36
+
37
+ [tool.pytest.ini_options]
38
+ testpaths = ["tests"]
39
+ python_files = ["test_*.py"]
40
+ python_classes = ["Test*"]
41
+ python_functions = ["test_*"]
42
+ addopts = ["-v", "--tb=short"]
43
+ asyncio_mode = "auto"
44
+
45
+ [build-system]
46
+ requires = ["hatchling"]
47
+ build-backend = "hatchling.build"
48
+
49
+ [tool.hatch.build.targets.wheel]
50
+ packages = ["raindrop_crewai"]
@@ -0,0 +1,4 @@
1
+ from .wrapper import RaindropCrewAI, create_raindrop_crewai, setup_crewai
2
+
3
+ __version__ = "0.0.1"
4
+ __all__ = ["RaindropCrewAI", "create_raindrop_crewai", "setup_crewai", "__version__"]
File without changes