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