hivetrace 1.3.5__tar.gz → 1.3.7__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.
Files changed (53) hide show
  1. hivetrace-1.3.7/PKG-INFO +911 -0
  2. hivetrace-1.3.7/README.md +893 -0
  3. hivetrace-1.3.7/hivetrace.egg-info/PKG-INFO +911 -0
  4. {hivetrace-1.3.5 → hivetrace-1.3.7}/setup.py +1 -1
  5. hivetrace-1.3.5/PKG-INFO +0 -832
  6. hivetrace-1.3.5/README.md +0 -814
  7. hivetrace-1.3.5/hivetrace.egg-info/PKG-INFO +0 -832
  8. {hivetrace-1.3.5 → hivetrace-1.3.7}/LICENSE +0 -0
  9. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/__init__.py +0 -0
  10. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/__init__.py +0 -0
  11. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/base_adapter.py +0 -0
  12. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/crewai/__init__.py +0 -0
  13. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/crewai/adapter.py +0 -0
  14. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/crewai/decorators.py +0 -0
  15. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/crewai/monitored_agent.py +0 -0
  16. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/crewai/monitored_crew.py +0 -0
  17. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/crewai/tool_wrapper.py +0 -0
  18. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/langchain/__init__.py +0 -0
  19. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/langchain/adapter.py +0 -0
  20. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/langchain/api.py +0 -0
  21. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/langchain/behavior_tracker.py +0 -0
  22. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/langchain/callback.py +0 -0
  23. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/langchain/decorators.py +0 -0
  24. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/langchain/models.py +0 -0
  25. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/openai_agents/__init__.py +0 -0
  26. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/openai_agents/adapter.py +0 -0
  27. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/openai_agents/models.py +0 -0
  28. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/openai_agents/tracing.py +0 -0
  29. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/utils/__init__.py +0 -0
  30. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/adapters/utils/logging.py +0 -0
  31. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/client/__init__.py +0 -0
  32. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/client/async_client.py +0 -0
  33. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/client/base.py +0 -0
  34. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/client/sync_client.py +0 -0
  35. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/errors/__init__.py +0 -0
  36. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/errors/api.py +0 -0
  37. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/errors/base.py +0 -0
  38. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/errors/network.py +0 -0
  39. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/errors/validation.py +0 -0
  40. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/handlers/__init__.py +0 -0
  41. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/handlers/error_handler.py +0 -0
  42. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/handlers/response_builder.py +0 -0
  43. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/models/__init__.py +0 -0
  44. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/models/requests.py +0 -0
  45. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/models/responses.py +0 -0
  46. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/utils/__init__.py +0 -0
  47. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/utils/error_helpers.py +0 -0
  48. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace/utils/uuid_generator.py +0 -0
  49. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace.egg-info/SOURCES.txt +0 -0
  50. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace.egg-info/dependency_links.txt +0 -0
  51. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace.egg-info/requires.txt +0 -0
  52. {hivetrace-1.3.5 → hivetrace-1.3.7}/hivetrace.egg-info/top_level.txt +0 -0
  53. {hivetrace-1.3.5 → hivetrace-1.3.7}/setup.cfg +0 -0
@@ -0,0 +1,911 @@
1
+ Metadata-Version: 2.1
2
+ Name: hivetrace
3
+ Version: 1.3.7
4
+ Summary: Hivetrace SDK for monitoring LLM applications
5
+ Home-page: http://hivetrace.ai
6
+ Author: Raft
7
+ Author-email: sales@raftds.com
8
+ Keywords: SDK,monitoring,logging,LLM,AI,Hivetrace
9
+ Classifier: License :: OSI Approved :: Apache Software License
10
+ Requires-Python: >=3.8
11
+ Description-Content-Type: text/markdown
12
+ Provides-Extra: all
13
+ Provides-Extra: base
14
+ Provides-Extra: crewai
15
+ Provides-Extra: langchain
16
+ Provides-Extra: openai_agents
17
+ License-File: LICENSE
18
+
19
+ # Hivetrace SDK
20
+
21
+ ## Overview
22
+
23
+ The Hivetrace SDK lets you integrate with the Hivetrace service to monitor user prompts and LLM responses. It supports both synchronous and asynchronous workflows and can be configured via environment variables.
24
+
25
+ ---
26
+
27
+ ## Installation
28
+
29
+ Install from PyPI:
30
+
31
+ ```bash
32
+ pip install hivetrace[base]
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Quick Start
38
+
39
+ ```python
40
+ from hivetrace import SyncHivetraceSDK, AsyncHivetraceSDK
41
+ ```
42
+
43
+ You can use either the synchronous client (`SyncHivetraceSDK`) or the asynchronous client (`AsyncHivetraceSDK`). Choose the one that fits your runtime.
44
+
45
+ ---
46
+
47
+ ## Synchronous Client
48
+
49
+ ### Initialize (Sync)
50
+
51
+ ```python
52
+ # The sync client reads configuration from environment variables or accepts an explicit config
53
+ client = SyncHivetraceSDK()
54
+ ```
55
+
56
+ ### Send a user prompt (input)
57
+
58
+ ```python
59
+ response = client.input(
60
+ application_id="your-application-id", # Obtained after registering the application in the UI
61
+ message="User prompt here",
62
+ )
63
+ ```
64
+
65
+ ### Send an LLM response (output)
66
+
67
+ ```python
68
+ response = client.output(
69
+ application_id="your-application-id",
70
+ message="LLM response here",
71
+ )
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Asynchronous Client
77
+
78
+ ### Initialize (Async)
79
+
80
+ ```python
81
+ # The async client can be used as a context manager
82
+ client = AsyncHivetraceSDK()
83
+ ```
84
+
85
+ ### Send a user prompt (input)
86
+
87
+ ```python
88
+ response = await client.input(
89
+ application_id="your-application-id",
90
+ message="User prompt here",
91
+ )
92
+ ```
93
+
94
+ ### Send an LLM response (output)
95
+
96
+ ```python
97
+ response = await client.output(
98
+ application_id="your-application-id",
99
+ message="LLM response here",
100
+ )
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Example with Additional Parameters
106
+
107
+ ```python
108
+ response = client.input(
109
+ application_id="your-application-id",
110
+ message="User prompt here",
111
+ additional_parameters={
112
+ "session_id": "your-session-id",
113
+ "user_id": "your-user-id",
114
+ "agents": {
115
+ "agent-1-id": {"name": "Agent 1", "description": "Agent description"},
116
+ "agent-2-id": {"name": "Agent 2"},
117
+ "agent-3-id": {}
118
+ }
119
+ }
120
+ )
121
+ ```
122
+
123
+ > **Note:** `session_id`, `user_id`, and all agent IDs must be valid UUIDs.
124
+
125
+ ---
126
+
127
+ ## API
128
+
129
+ ### `input`
130
+
131
+ ```python
132
+ # Sync
133
+ def input(application_id: str, message: str, additional_parameters: dict | None = None) -> dict: ...
134
+
135
+ # Async
136
+ async def input(application_id: str, message: str, additional_parameters: dict | None = None) -> dict: ...
137
+ ```
138
+
139
+ Sends a **user prompt** to Hivetrace.
140
+
141
+ * `application_id` — Application identifier (must be a valid UUID, created in the UI)
142
+ * `message` — The user prompt
143
+ * `additional_parameters` — Optional dictionary with extra context (session, user, agents, etc.)
144
+
145
+ **Response example:**
146
+
147
+ ```json
148
+ {
149
+ "status": "processed",
150
+ "monitoring_result": {
151
+ "is_toxic": false,
152
+ "type_of_violation": "benign",
153
+ "token_count": 9,
154
+ "token_usage_warning": false,
155
+ "token_usage_unbounded": false
156
+ }
157
+ }
158
+ ```
159
+
160
+ ---
161
+
162
+ ### `output`
163
+
164
+ ```python
165
+ # Sync
166
+ def output(application_id: str, message: str, additional_parameters: dict | None = None) -> dict: ...
167
+
168
+ # Async
169
+ async def output(application_id: str, message: str, additional_parameters: dict | None = None) -> dict: ...
170
+ ```
171
+
172
+ Sends an **LLM response** to Hivetrace.
173
+
174
+ * `application_id` — Application identifier (must be a valid UUID, created in the UI)
175
+ * `message` — The LLM response
176
+ * `additional_parameters` — Optional dictionary with extra context (session, user, agents, etc.)
177
+
178
+ **Response example:**
179
+
180
+ ```json
181
+ {
182
+ "status": "processed",
183
+ "monitoring_result": {
184
+ "is_toxic": false,
185
+ "type_of_violation": "safe",
186
+ "token_count": 21,
187
+ "token_usage_warning": false,
188
+ "token_usage_unbounded": false
189
+ }
190
+ }
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Sending Requests in Sync Mode
196
+
197
+ ```python
198
+ def main():
199
+ # option 1: context manager
200
+ with SyncHivetraceSDK() as client:
201
+ response = client.input(
202
+ application_id="your-application-id",
203
+ message="User prompt here",
204
+ )
205
+
206
+ # option 2: manual close
207
+ client = SyncHivetraceSDK()
208
+ try:
209
+ response = client.input(
210
+ application_id="your-application-id",
211
+ message="User prompt here",
212
+ )
213
+ finally:
214
+ client.close()
215
+
216
+ main()
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Sending Requests in Async Mode
222
+
223
+ ```python
224
+ import asyncio
225
+
226
+ async def main():
227
+ # option 1: context manager
228
+ async with AsyncHivetraceSDK() as client:
229
+ response = await client.input(
230
+ application_id="your-application-id",
231
+ message="User prompt here",
232
+ )
233
+
234
+ # option 2: manual close
235
+ client = AsyncHivetraceSDK()
236
+ try:
237
+ response = await client.input(
238
+ application_id="your-application-id",
239
+ message="User prompt here",
240
+ )
241
+ finally:
242
+ await client.close()
243
+
244
+ asyncio.run(main())
245
+ ```
246
+
247
+ ### Closing the Async Client
248
+
249
+ ```python
250
+ await client.close()
251
+ ```
252
+
253
+ ---
254
+
255
+ ## Configuration
256
+
257
+ The SDK reads configuration from environment variables:
258
+
259
+ * `HIVETRACE_URL` — Base URL allowed to call.
260
+ * `HIVETRACE_ACCESS_TOKEN` — API token used for authentication.
261
+
262
+ These are loaded automatically when you create a client.
263
+
264
+
265
+ ### Configuration Sources
266
+
267
+ Hivetrace SDK can retrieve configuration from the following sources:
268
+
269
+ **.env File:**
270
+
271
+ ```bash
272
+ HIVETRACE_URL=https://your-hivetrace-instance.com
273
+ HIVETRACE_ACCESS_TOKEN=your-access-token # obtained in the UI (API Tokens page)
274
+ ```
275
+
276
+ The SDK will automatically load these settings.
277
+
278
+ You can also pass a config dict explicitly when creating a client instance.
279
+ ```bash
280
+ client = SyncHivetraceSDK(
281
+ config={
282
+ "HIVETRACE_URL": HIVETRACE_URL,
283
+ "HIVETRACE_ACCESS_TOKEN": HIVETRACE_ACCESS_TOKEN,
284
+ },
285
+ )
286
+ ```
287
+
288
+ ## Environment Variables
289
+
290
+ Set up your environment variables for easier configuration:
291
+
292
+ ```bash
293
+ # .env file
294
+ HIVETRACE_URL=https://your-hivetrace-instance.com
295
+ HIVETRACE_ACCESS_TOKEN=your-access-token
296
+ HIVETRACE_APP_ID=your-application-id
297
+ ```
298
+
299
+ # CrewAI Integration
300
+
301
+ **Demo repository**
302
+
303
+ [https://github.com/anntish/multiagents-crew-forge](https://github.com/anntish/multiagents-crew-forge)
304
+
305
+ ## Step 1: Install the dependency
306
+
307
+ **What to do:** Add the HiveTrace SDK to your project
308
+
309
+ **Where:** In `requirements.txt` or via pip
310
+
311
+ ```bash
312
+ # Via pip (for quick testing)
313
+ pip install hivetrace[crewai]>=1.3.5
314
+
315
+ # Or add to requirements.txt (recommended)
316
+ echo "hivetrace[crewai]>=1.3.3" >> requirements.txt
317
+ pip install -r requirements.txt
318
+ ```
319
+
320
+ **Why:** The HiveTrace SDK provides decorators and clients for sending agent activity data to the monitoring platform.
321
+
322
+ ---
323
+
324
+ ## Step 2: **ADD** unique IDs for each agent
325
+
326
+ **Example:** In `src/config.py`
327
+
328
+ ```python
329
+ PLANNER_ID = "333e4567-e89b-12d3-a456-426614174001"
330
+ WRITER_ID = "444e4567-e89b-12d3-a456-426614174002"
331
+ EDITOR_ID = "555e4567-e89b-12d3-a456-426614174003"
332
+ ```
333
+
334
+ **Why agents need IDs:** HiveTrace tracks each agent individually. A UUID ensures the agent can be uniquely identified in the monitoring system.
335
+
336
+ ---
337
+
338
+ ## Step 3: Create an agent mapping
339
+
340
+ **What to do:** Map agent roles to their HiveTrace IDs
341
+
342
+ **Example:** In `src/agents.py` (where your agents are defined)
343
+
344
+ ```python
345
+ from crewai import Agent
346
+ # ADD: import agent IDs
347
+ from src.config import EDITOR_ID, PLANNER_ID, WRITER_ID
348
+
349
+ # ADD: mapping for HiveTrace (REQUIRED!)
350
+ agent_id_mapping = {
351
+ "Content Planner": { # ← Exactly the same as Agent(role="Content Planner")
352
+ "id": PLANNER_ID,
353
+ "description": "Creates content plans"
354
+ },
355
+ "Content Writer": { # ← Exactly the same as Agent(role="Content Writer")
356
+ "id": WRITER_ID,
357
+ "description": "Writes high-quality articles"
358
+ },
359
+ "Editor": { # ← Exactly the same as Agent(role="Editor")
360
+ "id": EDITOR_ID,
361
+ "description": "Edits and improves articles"
362
+ },
363
+ }
364
+
365
+ # Your existing agents (NO CHANGES)
366
+ planner = Agent(
367
+ role="Content Planner", # ← Must match key in agent_id_mapping
368
+ goal="Create a structured content plan for the given topic",
369
+ backstory="You are an experienced analyst...",
370
+ verbose=True,
371
+ )
372
+
373
+ writer = Agent(
374
+ role="Content Writer", # ← Must match key in agent_id_mapping
375
+ goal="Write an informative and engaging article",
376
+ backstory="You are a talented writer...",
377
+ verbose=True,
378
+ )
379
+
380
+ editor = Agent(
381
+ role="Editor", # ← Must match key in agent_id_mapping
382
+ goal="Improve the article",
383
+ backstory="You are an experienced editor...",
384
+ verbose=True,
385
+ )
386
+ ```
387
+
388
+ **Important:** The keys in `agent_id_mapping` must **exactly** match the `role` of your agents. Otherwise, HiveTrace will not be able to associate activity with the correct agent.
389
+
390
+ ---
391
+
392
+ ## Step 4: Integrate with tools (if used)
393
+
394
+ **What to do:** Add HiveTrace support to tools
395
+
396
+ **Example:** In `src/tools.py`
397
+
398
+ ```python
399
+ from crewai.tools import BaseTool
400
+ from typing import Optional
401
+
402
+ class WordCountTool(BaseTool):
403
+ name: str = "WordCountTool"
404
+ description: str = "Count words, characters and sentences in text"
405
+ # ADD: HiveTrace field (REQUIRED!)
406
+ agent_id: Optional[str] = None
407
+
408
+ def _run(self, text: str) -> str:
409
+ word_count = len(text.split())
410
+ return f"Word count: {word_count}"
411
+ ```
412
+
413
+ **Example:** In `src/agents.py`
414
+
415
+ ```python
416
+ from src.tools import WordCountTool
417
+ from src.config import PLANNER_ID, WRITER_ID, EDITOR_ID
418
+
419
+ # ADD: create tools for each agent
420
+ planner_tools = [WordCountTool()]
421
+ writer_tools = [WordCountTool()]
422
+ editor_tools = [WordCountTool()]
423
+
424
+ # ADD: assign tools to agents
425
+ for tool in planner_tools:
426
+ tool.agent_id = PLANNER_ID
427
+
428
+ for tool in writer_tools:
429
+ tool.agent_id = WRITER_ID
430
+
431
+ for tool in editor_tools:
432
+ tool.agent_id = EDITOR_ID
433
+
434
+ # Use tools in agents
435
+ planner = Agent(
436
+ role="Content Planner",
437
+ tools=planner_tools, # ← Agent-specific tools
438
+ # ... other parameters
439
+ )
440
+ ```
441
+
442
+ **Why:** HiveTrace tracks tool usage. The `agent_id` field in the tool class and its assignment let HiveTrace know which agent used which tool.
443
+
444
+ ---
445
+
446
+ ## Step 5: Initialize HiveTrace in FastAPI (if used)
447
+
448
+ **What to do:** Add the HiveTrace client to the application lifecycle
449
+
450
+ **Example:** In `main.py`
451
+
452
+ ```python
453
+ from contextlib import asynccontextmanager
454
+ from fastapi import FastAPI
455
+ # ADD: import HiveTrace SDK
456
+ from hivetrace import SyncHivetraceSDK
457
+ from src.config import HIVETRACE_ACCESS_TOKEN, HIVETRACE_URL
458
+
459
+ @asynccontextmanager
460
+ async def lifespan(app: FastAPI):
461
+ # ADD: initialize HiveTrace client
462
+ hivetrace = SyncHivetraceSDK(
463
+ config={
464
+ "HIVETRACE_URL": HIVETRACE_URL,
465
+ "HIVETRACE_ACCESS_TOKEN": HIVETRACE_ACCESS_TOKEN,
466
+ }
467
+ )
468
+ # Store client in app state
469
+ app.state.hivetrace = hivetrace
470
+ try:
471
+ yield
472
+ finally:
473
+ # IMPORTANT: close connection on shutdown
474
+ hivetrace.close()
475
+
476
+ app = FastAPI(lifespan=lifespan)
477
+ ```
478
+
479
+ ---
480
+
481
+ ## Step 6: Integrate into business logic
482
+
483
+ **What to do:** Wrap Crew creation with the HiveTrace decorator
484
+
485
+ **Example:** In `src/services/topic_service.py`
486
+
487
+ ```python
488
+ import uuid
489
+ from typing import Optional
490
+ from crewai import Crew
491
+ # ADD: HiveTrace imports
492
+ from hivetrace import SyncHivetraceSDK
493
+ from hivetrace import crewai_trace as trace
494
+
495
+ from src.agents import agent_id_mapping, planner, writer, editor
496
+ from src.tasks import plan_task, write_task, edit_task
497
+ from src.config import HIVETRACE_APP_ID
498
+
499
+ def process_topic(
500
+ topic: str,
501
+ hivetrace: SyncHivetraceSDK, # ← ADD parameter
502
+ user_id: Optional[str] = None,
503
+ session_id: Optional[str] = None,
504
+ ):
505
+ # ADD: generate unique conversation ID
506
+ agent_conversation_id = str(uuid.uuid4())
507
+
508
+ # ADD: common trace parameters
509
+ common_params = {
510
+ "agent_conversation_id": agent_conversation_id,
511
+ "user_id": user_id,
512
+ "session_id": session_id,
513
+ }
514
+
515
+ # ADD: log user request
516
+ hivetrace.input(
517
+ application_id=HIVETRACE_APP_ID,
518
+ message=f"Requesting information from agents on topic: {topic}",
519
+ additional_parameters={
520
+ **common_params,
521
+ "agents": agent_id_mapping, # ← pass agent mapping
522
+ },
523
+ )
524
+
525
+ # ADD: @trace decorator for monitoring Crew
526
+ @trace(
527
+ hivetrace=hivetrace,
528
+ application_id=HIVETRACE_APP_ID,
529
+ agent_id_mapping=agent_id_mapping, # ← REQUIRED!
530
+ )
531
+ def create_crew():
532
+ return Crew(
533
+ agents=[planner, writer, editor],
534
+ tasks=[plan_task, write_task, edit_task],
535
+ verbose=True,
536
+ )
537
+
538
+ # Execute with monitoring
539
+ crew = create_crew()
540
+ result = crew.kickoff(
541
+ inputs={"topic": topic},
542
+ **common_params # ← pass common parameters
543
+ )
544
+
545
+ return {
546
+ "result": result.raw,
547
+ "execution_details": {**common_params, "status": "completed"},
548
+ }
549
+ ```
550
+
551
+ **How it works:**
552
+
553
+ 1. **`agent_conversation_id`** — unique ID for grouping all actions under a single request
554
+ 2. **`hivetrace.input()`** — sends the user’s request to HiveTrace for inspection
555
+ 3. **`@trace`**:
556
+
557
+ * Intercepts all agent actions inside the Crew
558
+ * Sends data about each step to HiveTrace
559
+ * Associates actions with specific agents via `agent_id_mapping`
560
+ 4. **`**common_params`** — passes metadata into `crew.kickoff()` so all events are linked
561
+
562
+ **Critical:** The `@trace` decorator must be applied to the function that creates and returns the `Crew`, **not** the function that calls `kickoff()`.
563
+
564
+ ---
565
+
566
+ ## Step 7: Update FastAPI endpoints (if used)
567
+
568
+ **What to do:** Pass the HiveTrace client to the business logic
569
+
570
+ **Example:** In `src/routers/topic_router.py`
571
+
572
+ ```python
573
+ from fastapi import APIRouter, Body, Request
574
+ # ADD: import HiveTrace type
575
+ from hivetrace import SyncHivetraceSDK
576
+
577
+ from src.services.topic_service import process_topic
578
+ from src.config import SESSION_ID, USER_ID
579
+
580
+ router = APIRouter(prefix="/api")
581
+
582
+ @router.post("/process-topic")
583
+ async def api_process_topic(request: Request, request_body: dict = Body(...)):
584
+ # ADD: get HiveTrace client from app state
585
+ hivetrace: SyncHivetraceSDK = request.app.state.hivetrace
586
+
587
+ return process_topic(
588
+ topic=request_body["topic"],
589
+ hivetrace=hivetrace, # ← pass client
590
+ user_id=USER_ID,
591
+ session_id=SESSION_ID,
592
+ )
593
+ ```
594
+
595
+ **Why:** The API endpoint must pass the HiveTrace client to the business logic so monitoring data can be sent.
596
+
597
+ ---
598
+
599
+ ## 🚨 Common mistakes
600
+
601
+ 1. **Role mismatch** — make sure keys in `agent_id_mapping` exactly match `role` in agents
602
+ 2. **Missing `agent_id_mapping`** — the `@trace` decorator must receive the mapping
603
+ 3. **Decorator on wrong function** — `@trace` must be applied to the Crew creation function, not `kickoff`
604
+ 4. **Client not closed** — remember to call `hivetrace.close()` in the lifespan
605
+ 5. **Invalid credentials** — check your HiveTrace environment variables
606
+
607
+
608
+ # LangChain Integration
609
+
610
+ **Demo repository**
611
+
612
+ [https://github.com/anntish/multiagents-langchain-forge](https://github.com/anntish/multiagents-langchain-forge)
613
+
614
+ This project implements monitoring of a multi-agent system in LangChain via the HiveTrace SDK.
615
+
616
+ ### Step 1. Install Dependencies
617
+
618
+ ```bash
619
+ pip install hivetrace[langchain]>=1.3.5
620
+ # optional: add to requirements.txt and install
621
+ echo "hivetrace[langchain]>=1.3.3" >> requirements.txt
622
+ pip install -r requirements.txt
623
+ ```
624
+
625
+ What the package provides: SDK clients (sync/async), a universal callback for LangChain agents, and ready-to-use calls for sending inputs/logs/outputs to HiveTrace.
626
+
627
+ ### Step 2. Configure Environment Variables
628
+
629
+ * `HIVETRACE_URL`: HiveTrace address
630
+ * `HIVETRACE_ACCESS_TOKEN`: HiveTrace access token
631
+ * `HIVETRACE_APP_ID`: your application ID in HiveTrace
632
+ * `OPENAI_API_KEY`: key for the LLM provider (example with OpenAI)
633
+ * Additionally: `OPENAI_MODEL`, `USER_ID`, `SESSION_ID`
634
+
635
+ ### Step 3. Assign Fixed UUIDs to Your Agents
636
+
637
+ Create a dictionary of fixed UUIDs for all "agent nodes" (e.g., orchestrator, specialized agents). This ensures unambiguous identification in tracing.
638
+
639
+ Example: file `src/core/constants.py`:
640
+
641
+ ```python
642
+ PREDEFINED_AGENT_IDS = {
643
+ "MainHub": "111e1111-e89b-12d3-a456-426614174099",
644
+ "text_agent": "222e2222-e89b-12d3-a456-426614174099",
645
+ "math_agent": "333e3333-e89b-12d3-a456-426614174099",
646
+ "pre_text_agent": "444e4444-e89b-12d3-a456-426614174099",
647
+ "pre_math_agent": "555e5555-e89b-12d3-a456-426614174099",
648
+ }
649
+ ```
650
+
651
+ Tip: dictionary keys must match the actual node names appearing in logs (`tool`/agent name in LangChain calls).
652
+
653
+ ### Step 4. Attach the Callback to Executors and Tools
654
+
655
+ Create and use `AgentLoggingCallback` — it should be passed:
656
+
657
+ * as a callback in `AgentExecutor` (orchestrator), and
658
+ * as `callback_handler` in your tools/agent wrappers (`BaseTool`).
659
+
660
+ Example: file `src/core/orchestrator.py` (fragment):
661
+
662
+ ```python
663
+ from hivetrace.adapters.langchain import AgentLoggingCallback
664
+ from langchain.agents import AgentExecutor, create_openai_tools_agent
665
+ from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
666
+
667
+ class OrchestratorAgent:
668
+ def __init__(self, llm, predefined_agent_ids=None):
669
+ self.llm = llm
670
+ self.logging_callback = AgentLoggingCallback(
671
+ default_root_name="MainHub",
672
+ predefined_agent_ids=predefined_agent_ids,
673
+ )
674
+ # Example: wrapper agents as tools
675
+ # MathAgentTool/TextAgentTool internally pass self.logging_callback further
676
+ agent = create_openai_tools_agent(self.llm, self.tools, ChatPromptTemplate.from_messages([
677
+ ("system", "You are the orchestrator agent of a multi-agent system."),
678
+ MessagesPlaceholder(variable_name="chat_history", optional=True),
679
+ ("human", "{input}"),
680
+ MessagesPlaceholder(variable_name="agent_scratchpad"),
681
+ ]))
682
+ self.executor = AgentExecutor(
683
+ agent=agent,
684
+ tools=self.tools,
685
+ verbose=True,
686
+ callbacks=[self.logging_callback],
687
+ )
688
+ ```
689
+
690
+ Important: all nested agents/tools that create their own `AgentExecutor` or inherit from `BaseTool` must also receive this `callback_handler` so their steps are included in tracing.
691
+
692
+ ### Step 5. One-Line Integration in a Business Method
693
+
694
+ Use the `run_with_tracing` helper from `hivetrace/adapters/langchain/api.py`. It:
695
+
696
+ * logs the input with agent mapping and metadata;
697
+ * calls your orchestrator;
698
+ * collects and sends accumulated logs/final answer.
699
+
700
+ Minimal example (script):
701
+
702
+ ```python
703
+ import os, uuid
704
+ from langchain_openai import ChatOpenAI
705
+ from src.core.orchestrator import OrchestratorAgent
706
+ from src.core.constants import PREDEFINED_AGENT_IDS
707
+ from hivetrace.adapters.langchain import run_with_tracing
708
+
709
+ llm = ChatOpenAI(model=os.getenv("OPENAI_MODEL", "gpt-4o-mini"), temperature=0.2, streaming=False)
710
+ orchestrator = OrchestratorAgent(llm, predefined_agent_ids=PREDEFINED_AGENT_IDS)
711
+
712
+ result = run_with_tracing(
713
+ orchestrator=orchestrator,
714
+ query="Format this text and count the number of words",
715
+ application_id=os.getenv("HIVETRACE_APP_ID"),
716
+ user_id=os.getenv("USER_ID"),
717
+ session_id=os.getenv("SESSION_ID"),
718
+ conversation_id=str(uuid.uuid4()),
719
+ )
720
+ print(result)
721
+ ```
722
+
723
+ FastAPI variant (handler fragment):
724
+
725
+ ```python
726
+ from fastapi import APIRouter, Request
727
+ from hivetrace.adapters.langchain import run_with_tracing
728
+ import uuid
729
+
730
+ router = APIRouter()
731
+
732
+ @router.post("/query")
733
+ async def process_query(payload: dict, request: Request):
734
+ orchestrator = request.app.state.orchestrator
735
+ conv_id = str(uuid.uuid4()) # always create a new agent_conversation_id for each request to group agent work for the same question
736
+ result = run_with_tracing(
737
+ orchestrator=orchestrator,
738
+ query=payload["query"],
739
+ application_id=request.app.state.HIVETRACE_APP_ID,
740
+ user_id=request.app.state.USER_ID,
741
+ session_id=request.app.state.SESSION_ID,
742
+ conversation_id=conv_id,
743
+ )
744
+ return {"status": "success", "result": result}
745
+ ```
746
+
747
+ ### Step 6. Reusing the HiveTrace Client (Optional)
748
+
749
+ Helpers automatically create a short-lived client if none is provided. If you want to reuse a client — create it once during the application's lifecycle and pass it to helpers.
750
+
751
+ FastAPI (lifespan):
752
+
753
+ ```python
754
+ from contextlib import asynccontextmanager
755
+ from fastapi import FastAPI
756
+ from hivetrace import SyncHivetraceSDK
757
+
758
+ @asynccontextmanager
759
+ async def lifespan(app: FastAPI):
760
+ hivetrace = SyncHivetraceSDK()
761
+ app.state.hivetrace = hivetrace
762
+ try:
763
+ yield
764
+ finally:
765
+ hivetrace.close()
766
+
767
+ app = FastAPI(lifespan=lifespan)
768
+ ```
769
+
770
+ Then:
771
+
772
+ ```python
773
+ result = run_with_tracing(
774
+ orchestrator=orchestrator,
775
+ query=payload.query,
776
+ hivetrace=request.app.state.hivetrace, # pass your own client
777
+ application_id=request.app.state.HIVETRACE_APP_ID,
778
+ )
779
+ ```
780
+
781
+ ### How Logs Look in HiveTrace
782
+
783
+ * **Agent nodes**: orchestrator nodes and specialized "agent wrappers" (`text_agent`, `math_agent`, etc.).
784
+ * **Actual tools**: low-level tools (e.g., `text_analyzer`, `text_formatter`) are logged on start/end events.
785
+ * **Service records**: automatically added `return_result` (returning result to parent) and `final_answer` (final answer of the root node) steps.
786
+
787
+ This gives a clear call graph with data flow direction and the final answer.
788
+
789
+ ### Common Mistakes and How to Avoid Them
790
+
791
+ * **Name mismatch**: key in `PREDEFINED_AGENT_IDS` must match the node/tool name in logs.
792
+ * **No agent mapping**: either pass `agents_mapping` to `run_with_tracing` or define `predefined_agent_ids` in `AgentLoggingCallback` — the SDK will build the mapping automatically.
793
+ * **Callback not attached**: add `AgentLoggingCallback` to all `AgentExecutor` and `BaseTool` wrappers via the `callback_handler` parameter.
794
+ * **Client not closed**: use lifespan/context manager for `SyncHivetraceSDK`.
795
+
796
+
797
+ # OpenAI Agents Integration
798
+
799
+ **Demo repository**
800
+
801
+ [https://github.com/anntish/openai-agents-forge](https://github.com/anntish/openai-agents-forge)
802
+
803
+ ### 1. Installation
804
+
805
+ ```bash
806
+ pip install hivetrace[openai_agents]==1.3.5
807
+ ```
808
+
809
+ ---
810
+
811
+ ### 2. Environment Setup
812
+
813
+ Set the environment variables (via `.env` or export):
814
+
815
+ ```bash
816
+ HIVETRACE_URL=http://localhost:8000 # Your HiveTrace URL
817
+ HIVETRACE_ACCESS_TOKEN=ht_... # Your HiveTrace access token
818
+ HIVETRACE_APPLICATION_ID=00000000-...-0000 # Your HiveTrace application ID
819
+
820
+ SESSION_ID=
821
+ USERID=
822
+
823
+ OPENAI_API_KEY=
824
+ OPENAI_BASE_URL=https://api.openai.com/v1
825
+ OPENAI_MODEL=gpt-4o-mini
826
+ ```
827
+
828
+ ---
829
+
830
+ ### 3. Attach the Trace Processor in Code
831
+
832
+ Add 3 lines before creating/using your agents:
833
+
834
+ ```python
835
+ from agents import set_trace_processors
836
+ from hivetrace.adapters.openai_agents.tracing import HivetraceOpenAIAgentProcessor
837
+
838
+ set_trace_processors([
839
+ HivetraceOpenAIAgentProcessor() # will take config from env
840
+ ])
841
+ ```
842
+
843
+ Alternative (explicit configuration if you don’t want to rely on env):
844
+
845
+ ```python
846
+ from agents import set_trace_processors
847
+ from hivetrace import SyncHivetraceSDK
848
+ from hivetrace.adapters.openai_agents.tracing import HivetraceOpenAIAgentProcessor
849
+
850
+ hivetrace = SyncHivetraceSDK(config={
851
+ "HIVETRACE_URL": "http://localhost:8000",
852
+ "HIVETRACE_ACCESS_TOKEN": "ht_...",
853
+ })
854
+
855
+ set_trace_processors([
856
+ HivetraceOpenAIAgentProcessor(
857
+ application_id="00000000-0000-0000-0000-000000000000",
858
+ hivetrace_instance=hivetrace,
859
+ )
860
+ ])
861
+ ```
862
+
863
+ Important:
864
+
865
+ * Register the processor only once at app startup.
866
+ * Attach it before the first agent run (`Runner.run(...)` / `Runner.run_sync(...)`).
867
+
868
+ ---
869
+
870
+ ### 4. Minimal "Before/After" Example
871
+
872
+ Before:
873
+
874
+ ```python
875
+ from agents import Agent, Runner
876
+
877
+ assistant = Agent(name="Assistant", instructions="Be helpful.")
878
+ print(Runner.run_sync(assistant, "Hi!"))
879
+ ```
880
+
881
+ After (with HiveTrace monitoring):
882
+
883
+ ```python
884
+ from agents import Agent, Runner, set_trace_processors
885
+ from hivetrace.adapters.openai_agents.tracing import HivetraceOpenAIAgentProcessor
886
+
887
+ set_trace_processors([HivetraceOpenAIAgentProcessor()])
888
+
889
+ assistant = Agent(name="Assistant", instructions="Be helpful.")
890
+ print(Runner.run_sync(assistant, "Hi!"))
891
+ ```
892
+
893
+ From this moment, all agent calls, handoffs, and tool invocations will be logged in HiveTrace.
894
+
895
+ ---
896
+
897
+ ### 5. Tool Tracing
898
+
899
+ If you use tools, decorate them with `@function_tool` so their calls are automatically traced:
900
+
901
+ ```python
902
+ from agents import function_tool
903
+
904
+ @function_tool(description_override="Adds two numbers")
905
+ def calculate_sum(a: int, b: int) -> int:
906
+ return a + b
907
+ ```
908
+
909
+ Add this tool to your agent’s `tools=[...]` — and its calls will appear in HiveTrace with inputs/outputs.
910
+
911
+ ---