veadk-python 0.2.16__py3-none-any.whl → 0.2.17__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.
- veadk/a2a/remote_ve_agent.py +56 -1
- veadk/agent.py +79 -26
- veadk/agents/loop_agent.py +22 -9
- veadk/agents/parallel_agent.py +21 -9
- veadk/agents/sequential_agent.py +18 -9
- veadk/auth/veauth/apmplus_veauth.py +32 -39
- veadk/auth/veauth/ark_veauth.py +3 -1
- veadk/auth/veauth/utils.py +12 -0
- veadk/auth/veauth/viking_mem0_veauth.py +91 -0
- veadk/cli/cli.py +5 -1
- veadk/cli/cli_create.py +62 -1
- veadk/cli/cli_deploy.py +36 -1
- veadk/cli/cli_eval.py +55 -0
- veadk/cli/cli_init.py +44 -3
- veadk/cli/cli_kb.py +36 -1
- veadk/cli/cli_pipeline.py +66 -1
- veadk/cli/cli_prompt.py +16 -1
- veadk/cli/cli_uploadevalset.py +15 -1
- veadk/cli/cli_web.py +35 -4
- veadk/cloud/cloud_agent_engine.py +142 -25
- veadk/cloud/cloud_app.py +219 -12
- veadk/configs/database_configs.py +4 -0
- veadk/configs/model_configs.py +5 -1
- veadk/configs/tracing_configs.py +2 -2
- veadk/evaluation/adk_evaluator/adk_evaluator.py +77 -17
- veadk/evaluation/base_evaluator.py +219 -3
- veadk/evaluation/deepeval_evaluator/deepeval_evaluator.py +116 -1
- veadk/evaluation/eval_set_file_loader.py +20 -0
- veadk/evaluation/eval_set_recorder.py +54 -0
- veadk/evaluation/types.py +32 -0
- veadk/evaluation/utils/prometheus.py +61 -0
- veadk/knowledgebase/backends/base_backend.py +14 -1
- veadk/knowledgebase/backends/in_memory_backend.py +10 -1
- veadk/knowledgebase/backends/opensearch_backend.py +26 -0
- veadk/knowledgebase/backends/redis_backend.py +29 -2
- veadk/knowledgebase/backends/vikingdb_knowledge_backend.py +43 -5
- veadk/knowledgebase/knowledgebase.py +173 -12
- veadk/memory/long_term_memory.py +148 -4
- veadk/memory/long_term_memory_backends/mem0_backend.py +11 -0
- veadk/memory/short_term_memory.py +119 -5
- veadk/runner.py +412 -1
- veadk/tools/builtin_tools/llm_shield.py +381 -0
- veadk/tools/builtin_tools/mcp_router.py +9 -2
- veadk/tools/builtin_tools/run_code.py +25 -5
- veadk/tools/builtin_tools/web_search.py +38 -154
- veadk/tracing/base_tracer.py +28 -1
- veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +105 -1
- veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py +260 -0
- veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py +69 -0
- veadk/tracing/telemetry/attributes/extractors/types.py +78 -0
- veadk/tracing/telemetry/exporters/apmplus_exporter.py +157 -0
- veadk/tracing/telemetry/exporters/base_exporter.py +8 -0
- veadk/tracing/telemetry/exporters/cozeloop_exporter.py +60 -1
- veadk/tracing/telemetry/exporters/inmemory_exporter.py +118 -1
- veadk/tracing/telemetry/exporters/tls_exporter.py +66 -0
- veadk/tracing/telemetry/opentelemetry_tracer.py +111 -1
- veadk/tracing/telemetry/telemetry.py +118 -2
- veadk/version.py +1 -1
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/METADATA +1 -1
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/RECORD +64 -62
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/WHEEL +0 -0
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/entry_points.txt +0 -0
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/licenses/LICENSE +0 -0
- {veadk_python-0.2.16.dist-info → veadk_python-0.2.17.dist-info}/top_level.txt +0 -0
|
@@ -26,6 +26,29 @@ from opentelemetry.trace.span import Span
|
|
|
26
26
|
|
|
27
27
|
@dataclass
|
|
28
28
|
class ExtractorResponse:
|
|
29
|
+
"""Response container for telemetry attribute extractors.
|
|
30
|
+
|
|
31
|
+
ExtractorResponse encapsulates the output from attribute extraction functions
|
|
32
|
+
and provides metadata about how the extracted data should be applied to
|
|
33
|
+
OpenTelemetry spans. It supports different response types for flexible
|
|
34
|
+
span annotation patterns.
|
|
35
|
+
|
|
36
|
+
The response system enables extractors to return various data formats
|
|
37
|
+
including simple attributes, structured events, and event collections,
|
|
38
|
+
allowing for rich telemetry data capture and organization.
|
|
39
|
+
|
|
40
|
+
Attributes:
|
|
41
|
+
content: The extracted data to be applied to the span. Can be any type
|
|
42
|
+
depending on the response type and extractor implementation.
|
|
43
|
+
type: Specification of how the content should be applied to spans.
|
|
44
|
+
Controls the span annotation method used.
|
|
45
|
+
|
|
46
|
+
Response Types:
|
|
47
|
+
- "attribute": Sets span attributes using set_attribute()
|
|
48
|
+
- "event": Adds span events using add_event()
|
|
49
|
+
- "event_list": Adds multiple events from a structured list
|
|
50
|
+
"""
|
|
51
|
+
|
|
29
52
|
content: Any
|
|
30
53
|
|
|
31
54
|
type: Literal["attribute", "event", "event_list"] = "attribute"
|
|
@@ -40,6 +63,27 @@ class ExtractorResponse:
|
|
|
40
63
|
def update_span(
|
|
41
64
|
span: _Span | Span, attr_name: str, response: "ExtractorResponse"
|
|
42
65
|
) -> None:
|
|
66
|
+
"""Apply extractor response content to an OpenTelemetry span.
|
|
67
|
+
|
|
68
|
+
This method interprets the ExtractorResponse and applies its content
|
|
69
|
+
to the given span using the appropriate OpenTelemetry API method
|
|
70
|
+
based on the response type.
|
|
71
|
+
|
|
72
|
+
Processing Logic:
|
|
73
|
+
- attribute: Sets span attributes, supporting both single values and lists
|
|
74
|
+
- event: Adds span events, handling both single events and event lists
|
|
75
|
+
- event_list: Processes structured event lists with key-value pairs
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
span: OpenTelemetry span to annotate with extracted data
|
|
79
|
+
attr_name: Attribute name or event name for span annotation
|
|
80
|
+
response: ExtractorResponse containing the data and type information
|
|
81
|
+
|
|
82
|
+
Note:
|
|
83
|
+
- Gracefully handles unsupported response types by discarding them
|
|
84
|
+
- Type checking ensures safe attribute and event operations
|
|
85
|
+
- List processing supports nested dictionary structures
|
|
86
|
+
"""
|
|
43
87
|
if response.type == "attribute":
|
|
44
88
|
res = response.content
|
|
45
89
|
if isinstance(res, list):
|
|
@@ -73,6 +117,24 @@ class ExtractorResponse:
|
|
|
73
117
|
|
|
74
118
|
@dataclass
|
|
75
119
|
class LLMAttributesParams:
|
|
120
|
+
"""Parameter container for LLM attribute extractors.
|
|
121
|
+
|
|
122
|
+
LLMAttributesParams packages all the contextual information needed by
|
|
123
|
+
LLM attribute extraction functions. It provides access to the complete
|
|
124
|
+
LLM call context including request parameters, response data, and
|
|
125
|
+
execution environment details.
|
|
126
|
+
|
|
127
|
+
Attributes:
|
|
128
|
+
invocation_context: Complete context of the agent invocation including
|
|
129
|
+
agent instance, session information, user details, and execution state
|
|
130
|
+
event_id: Unique identifier for this specific LLM call event within
|
|
131
|
+
the broader agent execution trace
|
|
132
|
+
llm_request: Request object containing model name, parameters, prompt
|
|
133
|
+
content, and configuration settings sent to the language model
|
|
134
|
+
llm_response: Response object containing generated content, usage metadata,
|
|
135
|
+
token counts, timing information, and any error details
|
|
136
|
+
"""
|
|
137
|
+
|
|
76
138
|
invocation_context: InvocationContext
|
|
77
139
|
event_id: str
|
|
78
140
|
llm_request: LlmRequest
|
|
@@ -81,6 +143,22 @@ class LLMAttributesParams:
|
|
|
81
143
|
|
|
82
144
|
@dataclass
|
|
83
145
|
class ToolAttributesParams:
|
|
146
|
+
"""Parameter container for tool attribute extractors.
|
|
147
|
+
|
|
148
|
+
ToolAttributesParams packages all the contextual information needed by
|
|
149
|
+
tool attribute extraction functions. It provides access to tool execution
|
|
150
|
+
details including tool metadata, input arguments, and execution results
|
|
151
|
+
for comprehensive tool usage telemetry.
|
|
152
|
+
|
|
153
|
+
Attributes:
|
|
154
|
+
tool: Tool instance that was executed, containing metadata such as
|
|
155
|
+
name, description, function signature, and custom metadata
|
|
156
|
+
args: Dictionary of arguments that were passed to the tool function
|
|
157
|
+
during execution, including parameter names and values
|
|
158
|
+
function_response_event: Event object containing the tool's execution
|
|
159
|
+
results, return values, timing information, and any error details
|
|
160
|
+
"""
|
|
161
|
+
|
|
84
162
|
tool: BaseTool
|
|
85
163
|
args: dict[str, Any]
|
|
86
164
|
function_response_event: Event
|
|
@@ -112,6 +112,25 @@ _GEN_AI_CLIENT_TOKEN_USAGE_BUCKETS = [
|
|
|
112
112
|
|
|
113
113
|
@dataclass
|
|
114
114
|
class Meters:
|
|
115
|
+
"""Metric names and identifiers for OpenTelemetry instrumentation.
|
|
116
|
+
|
|
117
|
+
This class defines standardized metric names used for LLM and agent
|
|
118
|
+
observability. The metrics follow OpenTelemetry semantic conventions
|
|
119
|
+
for generative AI operations and include custom APMPlus metrics for
|
|
120
|
+
enhanced monitoring capabilities.
|
|
121
|
+
|
|
122
|
+
Standard Gen AI Metrics:
|
|
123
|
+
- LLM_CHAT_COUNT: Counter for LLM invocation frequency
|
|
124
|
+
- LLM_TOKEN_USAGE: Histogram for token consumption analysis
|
|
125
|
+
- LLM_OPERATION_DURATION: Histogram for operation latency tracking
|
|
126
|
+
- LLM_COMPLETIONS_EXCEPTIONS: Counter for error rate monitoring
|
|
127
|
+
- Streaming metrics: Performance analysis for streaming responses
|
|
128
|
+
|
|
129
|
+
APMPlus Custom Metrics:
|
|
130
|
+
- APMPLUS_SPAN_LATENCY: Span execution time for performance analysis
|
|
131
|
+
- APMPLUS_TOOL_TOKEN_USAGE: Tool-specific token consumption tracking
|
|
132
|
+
"""
|
|
133
|
+
|
|
115
134
|
LLM_CHAT_COUNT = "gen_ai.chat.count"
|
|
116
135
|
LLM_TOKEN_USAGE = "gen_ai.client.token.usage"
|
|
117
136
|
LLM_OPERATION_DURATION = "gen_ai.client.operation.duration"
|
|
@@ -134,9 +153,42 @@ class Meters:
|
|
|
134
153
|
|
|
135
154
|
|
|
136
155
|
class MeterUploader:
|
|
156
|
+
"""Metrics uploader for APMPlus observability platform integration.
|
|
157
|
+
|
|
158
|
+
MeterUploader manages the collection and transmission of telemetry metrics
|
|
159
|
+
to Volcengine's APMPlus platform. It creates and maintains OpenTelemetry
|
|
160
|
+
metric instruments for comprehensive agent performance monitoring.
|
|
161
|
+
|
|
162
|
+
Key Features:
|
|
163
|
+
- Automatic metric instrument creation with appropriate buckets
|
|
164
|
+
- LLM call metrics including token usage and latency
|
|
165
|
+
- Tool execution metrics for performance analysis
|
|
166
|
+
- Error tracking and exception monitoring
|
|
167
|
+
- Integration with OpenTelemetry metrics SDK
|
|
168
|
+
|
|
169
|
+
Metrics Collected:
|
|
170
|
+
- LLM invocation counts and frequencies
|
|
171
|
+
- Token consumption (input/output) with histogram distribution
|
|
172
|
+
- Operation latency with performance bucket analysis
|
|
173
|
+
- Error rates and exception details
|
|
174
|
+
- Span-level performance metrics for APMPlus dashboards
|
|
175
|
+
"""
|
|
176
|
+
|
|
137
177
|
def __init__(
|
|
138
178
|
self, name: str, endpoint: str, headers: dict, resource_attributes: dict
|
|
139
179
|
) -> None:
|
|
180
|
+
"""Initialize the meter uploader with APMPlus configuration.
|
|
181
|
+
|
|
182
|
+
Sets up the global metrics provider, creates metric instruments,
|
|
183
|
+
and configures OTLP export to APMPlus endpoints with proper
|
|
184
|
+
resource attribution and authentication.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
name: Meter name for identification and organization
|
|
188
|
+
endpoint: APMPlus OTLP endpoint URL for metric transmission
|
|
189
|
+
headers: Authentication headers including APMPlus app key
|
|
190
|
+
resource_attributes: Service metadata for metric attribution
|
|
191
|
+
"""
|
|
140
192
|
# global_metrics_provider -> global_tracer_provider
|
|
141
193
|
# exporter -> exporter
|
|
142
194
|
# metric_reader -> processor
|
|
@@ -224,6 +276,26 @@ class MeterUploader:
|
|
|
224
276
|
llm_request: LlmRequest,
|
|
225
277
|
llm_response: LlmResponse,
|
|
226
278
|
) -> None:
|
|
279
|
+
"""Record comprehensive metrics for LLM call operations.
|
|
280
|
+
|
|
281
|
+
Captures detailed telemetry data for language model invocations
|
|
282
|
+
including token consumption, latency, and error information.
|
|
283
|
+
This data enables cost optimization, performance analysis, and
|
|
284
|
+
reliability monitoring in APMPlus dashboards.
|
|
285
|
+
|
|
286
|
+
Metrics Recorded:
|
|
287
|
+
- Invocation count with model and operation attributes
|
|
288
|
+
- Input/output token usage with separate tracking
|
|
289
|
+
- Operation duration from span timing data
|
|
290
|
+
- Error counts and exception details
|
|
291
|
+
- Span latency for performance analysis
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
invocation_context: Context with agent, session, and user information
|
|
295
|
+
event_id: Unique identifier for this LLM call event
|
|
296
|
+
llm_request: Request object with model and parameter details
|
|
297
|
+
llm_response: Response object with content and usage metadata
|
|
298
|
+
"""
|
|
227
299
|
attributes = {
|
|
228
300
|
"gen_ai_system": "volcengine",
|
|
229
301
|
"gen_ai_response_model": llm_request.model,
|
|
@@ -307,6 +379,22 @@ class MeterUploader:
|
|
|
307
379
|
args: dict[str, Any],
|
|
308
380
|
function_response_event: Event,
|
|
309
381
|
):
|
|
382
|
+
"""Record metrics for tool execution operations.
|
|
383
|
+
|
|
384
|
+
Captures performance and usage metrics for tool invocations
|
|
385
|
+
including execution latency and estimated token consumption.
|
|
386
|
+
Enables monitoring of tool performance and resource usage patterns.
|
|
387
|
+
|
|
388
|
+
Metrics Recorded:
|
|
389
|
+
- Tool execution latency from span timing
|
|
390
|
+
- Input/output token estimation based on text length
|
|
391
|
+
- Tool-specific attributes for categorization
|
|
392
|
+
|
|
393
|
+
Args:
|
|
394
|
+
tool: Tool instance that was executed
|
|
395
|
+
args: Arguments passed to the tool function
|
|
396
|
+
function_response_event: Event containing execution results
|
|
397
|
+
"""
|
|
310
398
|
logger.debug(f"Record tool call work in progress. Tool: {tool.name}")
|
|
311
399
|
span = trace.get_current_span()
|
|
312
400
|
if not span:
|
|
@@ -349,6 +437,17 @@ class MeterUploader:
|
|
|
349
437
|
|
|
350
438
|
|
|
351
439
|
class APMPlusExporterConfig(BaseModel):
|
|
440
|
+
"""Configuration model for APMPlus exporter settings.
|
|
441
|
+
|
|
442
|
+
Manages connection parameters and authentication details for
|
|
443
|
+
integrating with Volcengine's APMPlus observability platform.
|
|
444
|
+
|
|
445
|
+
Attributes:
|
|
446
|
+
endpoint: OTLP endpoint URL for APMPlus data ingestion
|
|
447
|
+
app_key: Authentication key for APMPlus API access
|
|
448
|
+
service_name: Service identifier displayed in APMPlus interface
|
|
449
|
+
"""
|
|
450
|
+
|
|
352
451
|
endpoint: str = Field(
|
|
353
452
|
default_factory=lambda: settings.apmplus_config.otel_exporter_endpoint,
|
|
354
453
|
)
|
|
@@ -362,9 +461,56 @@ class APMPlusExporterConfig(BaseModel):
|
|
|
362
461
|
|
|
363
462
|
|
|
364
463
|
class APMPlusExporter(BaseExporter):
|
|
464
|
+
"""OpenTelemetry exporter for Volcengine APMPlus observability platform.
|
|
465
|
+
|
|
466
|
+
APMPlusExporter provides comprehensive integration with Volcengine's APMPlus
|
|
467
|
+
platform, enabling advanced observability for VeADK agents. It combines
|
|
468
|
+
distributed tracing with detailed metrics collection for complete visibility
|
|
469
|
+
into agent performance, costs, and reliability.
|
|
470
|
+
|
|
471
|
+
Key Capabilities:
|
|
472
|
+
- OTLP-based span export to APMPlus with authentication
|
|
473
|
+
- Comprehensive metrics collection for LLM and tool operations
|
|
474
|
+
- Automatic resource attribution with service identification
|
|
475
|
+
- Cost tracking through detailed token usage metrics
|
|
476
|
+
- Performance monitoring with latency histograms
|
|
477
|
+
- Error tracking and exception monitoring
|
|
478
|
+
|
|
479
|
+
Configuration:
|
|
480
|
+
The exporter uses VeADK settings for automatic configuration but
|
|
481
|
+
can be customized with explicit parameters. Authentication is
|
|
482
|
+
handled through APMPlus app keys in request headers.
|
|
483
|
+
|
|
484
|
+
Examples:
|
|
485
|
+
Basic usage with default settings:
|
|
486
|
+
```python
|
|
487
|
+
exporter = APMPlusExporter()
|
|
488
|
+
tracer = OpentelemetryTracer(exporters=[exporter])
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
Note:
|
|
492
|
+
- Requires valid APMPlus app key for authentication
|
|
493
|
+
- Endpoint should point to APMPlus OTLP ingestion service
|
|
494
|
+
- Service name appears in APMPlus dashboards for identification
|
|
495
|
+
- Metrics and spans are automatically correlated by trace context
|
|
496
|
+
- Supports both development and production environments
|
|
497
|
+
"""
|
|
498
|
+
|
|
365
499
|
config: APMPlusExporterConfig = Field(default_factory=APMPlusExporterConfig)
|
|
366
500
|
|
|
367
501
|
def model_post_init(self, context: Any) -> None:
|
|
502
|
+
"""Initialize APMPlus exporter components after model construction.
|
|
503
|
+
|
|
504
|
+
Sets up OTLP span exporter, batch processor, and meter uploader
|
|
505
|
+
with proper authentication and resource attribution for APMPlus
|
|
506
|
+
integration.
|
|
507
|
+
|
|
508
|
+
Components Initialized:
|
|
509
|
+
- OTLP span exporter with APMPlus endpoint and authentication
|
|
510
|
+
- Batch span processor for efficient data transmission
|
|
511
|
+
- Meter uploader for comprehensive metrics collection
|
|
512
|
+
- Resource attributes for service identification
|
|
513
|
+
"""
|
|
368
514
|
logger.info(f"APMPlusExporter sevice name: {self.config.service_name}")
|
|
369
515
|
|
|
370
516
|
headers = {
|
|
@@ -391,6 +537,17 @@ class APMPlusExporter(BaseExporter):
|
|
|
391
537
|
|
|
392
538
|
@override
|
|
393
539
|
def export(self) -> None:
|
|
540
|
+
"""Force immediate export of pending telemetry data to APMPlus.
|
|
541
|
+
|
|
542
|
+
Triggers force flush on the OTLP span exporter to ensure all
|
|
543
|
+
buffered span data is immediately transmitted to APMPlus for
|
|
544
|
+
real-time observability and debugging.
|
|
545
|
+
|
|
546
|
+
Operations:
|
|
547
|
+
- Forces flush of span exporter if initialized
|
|
548
|
+
- Logs export status and configuration details
|
|
549
|
+
- Handles cases where exporter is not properly initialized
|
|
550
|
+
"""
|
|
394
551
|
if self._exporter:
|
|
395
552
|
self._exporter.force_flush()
|
|
396
553
|
|
|
@@ -18,6 +18,14 @@ from pydantic import BaseModel, ConfigDict, Field
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class BaseExporter(BaseModel):
|
|
21
|
+
"""Abstract base class for OpenTelemetry span exporters in VeADK tracing system.
|
|
22
|
+
|
|
23
|
+
BaseExporter provides the foundation for implementing custom telemetry data
|
|
24
|
+
exporters that send span data to various observability platforms. It defines
|
|
25
|
+
the common interface and configuration structure that all concrete exporters
|
|
26
|
+
must follow.
|
|
27
|
+
"""
|
|
28
|
+
|
|
21
29
|
model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
|
|
22
30
|
|
|
23
31
|
resource_attributes: dict = Field(default_factory=dict)
|
|
@@ -27,6 +27,17 @@ logger = get_logger(__name__)
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class CozeloopExporterConfig(BaseModel):
|
|
30
|
+
"""Configuration model for CozeLoop exporter settings.
|
|
31
|
+
|
|
32
|
+
Manages connection parameters and authentication details for
|
|
33
|
+
integrating with CozeLoop observability and evaluation platform.
|
|
34
|
+
|
|
35
|
+
Attributes:
|
|
36
|
+
endpoint: OTLP HTTP endpoint URL for CozeLoop data ingestion
|
|
37
|
+
space_id: Workspace identifier for organizing data in CozeLoop
|
|
38
|
+
token: Authentication token for CozeLoop API access
|
|
39
|
+
"""
|
|
40
|
+
|
|
30
41
|
endpoint: str = Field(
|
|
31
42
|
default_factory=lambda: settings.cozeloop_config.otel_exporter_endpoint,
|
|
32
43
|
)
|
|
@@ -39,9 +50,47 @@ class CozeloopExporterConfig(BaseModel):
|
|
|
39
50
|
|
|
40
51
|
|
|
41
52
|
class CozeloopExporter(BaseExporter):
|
|
53
|
+
"""OpenTelemetry exporter for CozeLoop evaluation and observability platform.
|
|
54
|
+
|
|
55
|
+
CozeloopExporter provides integration with CozeLoop platform for agent
|
|
56
|
+
evaluation, monitoring, and analysis. It uses HTTP-based OTLP export
|
|
57
|
+
to send trace data to CozeLoop's evaluation infrastructure for detailed
|
|
58
|
+
performance analysis and evaluation workflows.
|
|
59
|
+
|
|
60
|
+
Integration:
|
|
61
|
+
CozeLoop specializes in AI agent evaluation and provides advanced
|
|
62
|
+
analytics for conversation quality, tool usage effectiveness, and
|
|
63
|
+
overall agent performance metrics. The exporter enables seamless
|
|
64
|
+
integration with CozeLoop's evaluation workflows.
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
Basic usage with default settings:
|
|
68
|
+
```python
|
|
69
|
+
exporter = CozeloopExporter()
|
|
70
|
+
tracer = OpentelemetryTracer(exporters=[exporter])
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Note:
|
|
74
|
+
- Requires valid CozeLoop workspace ID and authentication token
|
|
75
|
+
- Data is organized by workspace for multi-tenant isolation
|
|
76
|
+
- Suitable for both development and production evaluation workflows
|
|
77
|
+
"""
|
|
78
|
+
|
|
42
79
|
config: CozeloopExporterConfig = Field(default_factory=CozeloopExporterConfig)
|
|
43
80
|
|
|
44
81
|
def model_post_init(self, context: Any) -> None:
|
|
82
|
+
"""Initialize CozeLoop exporter components after model construction.
|
|
83
|
+
|
|
84
|
+
Sets up HTTP-based OTLP span exporter and batch processor with
|
|
85
|
+
proper authentication headers and workspace identification for
|
|
86
|
+
CozeLoop platform integration.
|
|
87
|
+
|
|
88
|
+
Components Initialized:
|
|
89
|
+
- HTTP OTLP span exporter with CozeLoop endpoint
|
|
90
|
+
- Batch span processor for efficient data transmission
|
|
91
|
+
- Authentication headers with workspace ID and bearer token
|
|
92
|
+
- Timeout configuration for reliable network operations
|
|
93
|
+
"""
|
|
45
94
|
logger.info(f"CozeloopExporter space ID: {self.config.space_id}")
|
|
46
95
|
|
|
47
96
|
headers = {
|
|
@@ -60,7 +109,17 @@ class CozeloopExporter(BaseExporter):
|
|
|
60
109
|
|
|
61
110
|
@override
|
|
62
111
|
def export(self) -> None:
|
|
63
|
-
"""Force export of telemetry data.
|
|
112
|
+
"""Force immediate export of pending telemetry data to CozeLoop.
|
|
113
|
+
|
|
114
|
+
Triggers force flush on the HTTP OTLP span exporter to ensure all
|
|
115
|
+
buffered span data is immediately transmitted to CozeLoop for
|
|
116
|
+
real-time evaluation and analysis.
|
|
117
|
+
|
|
118
|
+
Operations:
|
|
119
|
+
- Forces flush of span exporter if initialized
|
|
120
|
+
- Logs export status with endpoint and workspace details
|
|
121
|
+
- Handles cases where exporter is not properly initialized
|
|
122
|
+
"""
|
|
64
123
|
if self._exporter:
|
|
65
124
|
self._exporter.force_flush()
|
|
66
125
|
logger.info(
|
|
@@ -31,7 +31,27 @@ logger = get_logger(__name__)
|
|
|
31
31
|
|
|
32
32
|
# ======== Adapted from Google ADK ========
|
|
33
33
|
class _InMemoryExporter(export.SpanExporter):
|
|
34
|
+
"""Internal span exporter that stores spans in memory for local analysis and debugging.
|
|
35
|
+
|
|
36
|
+
This exporter collects and stores OpenTelemetry spans in memory rather than
|
|
37
|
+
sending them to external services. It's particularly useful for development,
|
|
38
|
+
testing, and local trace analysis scenarios where immediate access to span
|
|
39
|
+
data is needed.
|
|
40
|
+
|
|
41
|
+
Key Features:
|
|
42
|
+
- In-memory span storage with session-based organization
|
|
43
|
+
- Trace ID tracking for span correlation
|
|
44
|
+
- Session-to-trace mapping for efficient filtering
|
|
45
|
+
- Support for span retrieval by session ID
|
|
46
|
+
|
|
47
|
+
Attributes:
|
|
48
|
+
_spans: List of all collected ReadableSpan objects
|
|
49
|
+
trace_id: Current trace identifier from the most recent span
|
|
50
|
+
session_trace_dict: Mapping of session IDs to their associated trace IDs
|
|
51
|
+
"""
|
|
52
|
+
|
|
34
53
|
def __init__(self) -> None:
|
|
54
|
+
"""Initialize the in-memory exporter with empty storage containers."""
|
|
35
55
|
super().__init__()
|
|
36
56
|
self._spans = []
|
|
37
57
|
self.trace_id = ""
|
|
@@ -39,6 +59,18 @@ class _InMemoryExporter(export.SpanExporter):
|
|
|
39
59
|
|
|
40
60
|
@override
|
|
41
61
|
def export(self, spans: Sequence[ReadableSpan]) -> export.SpanExportResult:
|
|
62
|
+
"""Export spans to in-memory storage with session tracking.
|
|
63
|
+
|
|
64
|
+
Processes and stores spans while maintaining session-to-trace mapping
|
|
65
|
+
for efficient retrieval. Extracts session information from LLM call spans
|
|
66
|
+
to enable session-based filtering.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
spans: Sequence of ReadableSpan objects to store
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
SpanExportResult.SUCCESS: Always returns success for in-memory storage
|
|
73
|
+
"""
|
|
42
74
|
for span in spans:
|
|
43
75
|
if span.context:
|
|
44
76
|
self.trace_id = span.context.trace_id
|
|
@@ -60,23 +92,70 @@ class _InMemoryExporter(export.SpanExporter):
|
|
|
60
92
|
|
|
61
93
|
@override
|
|
62
94
|
def force_flush(self, timeout_millis: int = 30000) -> bool:
|
|
95
|
+
"""Force flush operation for in-memory exporter.
|
|
96
|
+
|
|
97
|
+
Since spans are immediately stored in memory, this operation
|
|
98
|
+
always succeeds without performing any actual flushing.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
bool: Always True indicating successful flush
|
|
102
|
+
"""
|
|
63
103
|
return True
|
|
64
104
|
|
|
65
105
|
def get_finished_spans(self, session_id: str):
|
|
106
|
+
"""Retrieve all spans associated with a specific session ID.
|
|
107
|
+
|
|
108
|
+
Filters stored spans to return only those belonging to the specified
|
|
109
|
+
session, enabling session-scoped trace analysis and debugging.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
session_id: Session identifier to filter spans by
|
|
113
|
+
|
|
114
|
+
Returns:
|
|
115
|
+
list[ReadableSpan]: List of spans associated with the session,
|
|
116
|
+
empty list if session not found or no spans available
|
|
117
|
+
"""
|
|
66
118
|
trace_ids = self.session_trace_dict.get(session_id, None)
|
|
67
119
|
if trace_ids is None or not trace_ids:
|
|
68
120
|
return []
|
|
69
121
|
return [x for x in self._spans if x.context.trace_id in trace_ids]
|
|
70
122
|
|
|
71
123
|
def clear(self):
|
|
124
|
+
"""Clear all stored spans and session mappings.
|
|
125
|
+
|
|
126
|
+
Removes all collected span data from memory, useful for cleanup
|
|
127
|
+
between test runs or to free memory in long-running processes.
|
|
128
|
+
"""
|
|
72
129
|
self._spans.clear()
|
|
73
130
|
|
|
74
131
|
|
|
75
132
|
class _InMemorySpanProcessor(export.SimpleSpanProcessor):
|
|
133
|
+
"""Custom span processor for in-memory export with enhanced span annotation.
|
|
134
|
+
|
|
135
|
+
Extends SimpleSpanProcessor to add VeADK-specific span attributes and
|
|
136
|
+
context management. Handles span lifecycle events to set appropriate
|
|
137
|
+
attributes and manage OpenTelemetry context for nested span hierarchies.
|
|
138
|
+
"""
|
|
139
|
+
|
|
76
140
|
def __init__(self, exporter: _InMemoryExporter) -> None:
|
|
141
|
+
"""Initialize the span processor with the given in-memory exporter.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
exporter: _InMemoryExporter instance for storing processed spans
|
|
145
|
+
"""
|
|
77
146
|
super().__init__(exporter)
|
|
78
147
|
|
|
79
148
|
def on_start(self, span, parent_context) -> None:
|
|
149
|
+
"""Handle span start events with type-specific attribute setting.
|
|
150
|
+
|
|
151
|
+
Automatically detects span types based on name patterns and applies
|
|
152
|
+
appropriate attributes. Sets up OpenTelemetry context for hierarchical
|
|
153
|
+
span management and instrumentation suppression.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
span: The span being started
|
|
157
|
+
parent_context: Parent OpenTelemetry context
|
|
158
|
+
"""
|
|
80
159
|
if span.name.startswith("invocation"):
|
|
81
160
|
span.set_attribute("gen_ai.operation.name", "chain")
|
|
82
161
|
span.set_attribute("gen_ai.span.kind", "workflow")
|
|
@@ -99,6 +178,15 @@ class _InMemorySpanProcessor(export.SimpleSpanProcessor):
|
|
|
99
178
|
setattr(span, "_agent_run_token", token) # for later detach
|
|
100
179
|
|
|
101
180
|
def on_end(self, span: ReadableSpan) -> None:
|
|
181
|
+
"""Handle span end events with proper context cleanup.
|
|
182
|
+
|
|
183
|
+
Exports the finished span to the in-memory storage while managing
|
|
184
|
+
OpenTelemetry context and cleaning up attached tokens to prevent
|
|
185
|
+
memory leaks.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
span: The span that has finished execution
|
|
189
|
+
"""
|
|
102
190
|
if span.context:
|
|
103
191
|
if not span.context.trace_flags.sampled:
|
|
104
192
|
return
|
|
@@ -120,9 +208,38 @@ class _InMemorySpanProcessor(export.SimpleSpanProcessor):
|
|
|
120
208
|
|
|
121
209
|
|
|
122
210
|
class InMemoryExporter(BaseExporter):
|
|
123
|
-
"""
|
|
211
|
+
"""In-memory span exporter for local debugging and observability analysis.
|
|
212
|
+
|
|
213
|
+
InMemoryExporter provides a complete in-memory tracing solution that stores
|
|
214
|
+
spans locally for immediate analysis, debugging, and testing. It's ideal for
|
|
215
|
+
development environments where external observability platforms are not
|
|
216
|
+
available or not desired.
|
|
217
|
+
|
|
218
|
+
Use Cases:
|
|
219
|
+
- Development and debugging of agent workflows
|
|
220
|
+
- Unit and integration testing with trace verification
|
|
221
|
+
- Local trace analysis and performance profiling
|
|
222
|
+
- Offline environments without external connectivity
|
|
223
|
+
- Trace data export for post-processing and analysis
|
|
224
|
+
|
|
225
|
+
Integration:
|
|
226
|
+
The exporter is automatically added to OpentelemetryTracer instances
|
|
227
|
+
and cannot be manually configured to avoid conflicts. It provides the
|
|
228
|
+
foundation for local trace file generation and analysis.
|
|
229
|
+
|
|
230
|
+
Note:
|
|
231
|
+
- Cannot be added to exporter lists (validation prevents this)
|
|
232
|
+
- Automatically managed by OpentelemetryTracer
|
|
233
|
+
- Memory usage grows with span count - consider periodic clearing
|
|
234
|
+
- Session tracking requires properly configured session IDs
|
|
235
|
+
"""
|
|
124
236
|
|
|
125
237
|
def __init__(self, name: str = "inmemory_exporter") -> None:
|
|
238
|
+
"""Initialize the in-memory exporter with internal components.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
name: Identifier for this exporter instance.
|
|
242
|
+
"""
|
|
126
243
|
super().__init__()
|
|
127
244
|
|
|
128
245
|
self.name = name
|
|
@@ -27,6 +27,19 @@ logger = get_logger(__name__)
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class TLSExporterConfig(BaseModel):
|
|
30
|
+
"""Configuration model for Volcengine TLS exporter settings.
|
|
31
|
+
|
|
32
|
+
Manages connection parameters and authentication details for
|
|
33
|
+
integrating with Volcengine's TLS logging and observability platform.
|
|
34
|
+
|
|
35
|
+
Attributes:
|
|
36
|
+
endpoint: OTLP HTTP endpoint URL for TLS data ingestion
|
|
37
|
+
region: Volcengine region where the TLS service is deployed
|
|
38
|
+
topic_id: TLS topic identifier for organizing log data
|
|
39
|
+
access_key: Volcengine access key for API authentication
|
|
40
|
+
secret_key: Volcengine secret key for API authentication
|
|
41
|
+
"""
|
|
42
|
+
|
|
30
43
|
endpoint: str = Field(
|
|
31
44
|
default_factory=lambda: settings.tls_config.otel_exporter_endpoint,
|
|
32
45
|
)
|
|
@@ -41,9 +54,51 @@ class TLSExporterConfig(BaseModel):
|
|
|
41
54
|
|
|
42
55
|
|
|
43
56
|
class TLSExporter(BaseExporter):
|
|
57
|
+
"""OpenTelemetry exporter for Volcengine TLS platform.
|
|
58
|
+
|
|
59
|
+
TLSExporter provides integration with Volcengine's TLS platform for
|
|
60
|
+
centralized logging and trace data management. It uses HTTP-based OTLP
|
|
61
|
+
export to send trace data to TLS topics for storage, analysis, and
|
|
62
|
+
long-term retention.
|
|
63
|
+
|
|
64
|
+
Use Cases:
|
|
65
|
+
- Centralized trace data storage and archival
|
|
66
|
+
- Long-term performance trend analysis
|
|
67
|
+
- Compliance and audit trail requirements
|
|
68
|
+
- Cross-service trace correlation and analysis
|
|
69
|
+
- Integration with existing TLS logging infrastructure
|
|
70
|
+
|
|
71
|
+
Examples:
|
|
72
|
+
Basic usage with default settings:
|
|
73
|
+
```python
|
|
74
|
+
exporter = TLSExporter()
|
|
75
|
+
tracer = OpentelemetryTracer(exporters=[exporter])
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Note:
|
|
79
|
+
- Requires valid Volcengine credentials and TLS topic ID
|
|
80
|
+
- Data is organized by topics for efficient management
|
|
81
|
+
- Supports regional deployments for data locality compliance
|
|
82
|
+
- Integrates with TLS alerting and analysis features
|
|
83
|
+
- Suitable for production environments requiring data retention
|
|
84
|
+
"""
|
|
85
|
+
|
|
44
86
|
config: TLSExporterConfig = Field(default_factory=TLSExporterConfig)
|
|
45
87
|
|
|
46
88
|
def model_post_init(self, context: Any) -> None:
|
|
89
|
+
"""Initialize TLS exporter components after model construction.
|
|
90
|
+
|
|
91
|
+
Sets up HTTP-based OTLP span exporter and batch processor with
|
|
92
|
+
Volcengine authentication headers and TLS topic configuration for
|
|
93
|
+
centralized trace data management.
|
|
94
|
+
|
|
95
|
+
Components Initialized:
|
|
96
|
+
- HTTP OTLP span exporter with TLS endpoint
|
|
97
|
+
- Batch span processor for efficient data transmission
|
|
98
|
+
- Authentication headers with Volcengine credentials
|
|
99
|
+
- Topic and region configuration for data routing
|
|
100
|
+
- Timeout configuration for reliable network operations
|
|
101
|
+
"""
|
|
47
102
|
logger.info(f"TLSExporter topic ID: {self.config.topic_id}")
|
|
48
103
|
|
|
49
104
|
headers = {
|
|
@@ -64,6 +119,17 @@ class TLSExporter(BaseExporter):
|
|
|
64
119
|
|
|
65
120
|
@override
|
|
66
121
|
def export(self) -> None:
|
|
122
|
+
"""Force immediate export of pending telemetry data to TLS.
|
|
123
|
+
|
|
124
|
+
Triggers force flush on the HTTP OTLP span exporter to ensure all
|
|
125
|
+
buffered span data is immediately transmitted to TLS for centralized
|
|
126
|
+
logging and analysis.
|
|
127
|
+
|
|
128
|
+
Operations:
|
|
129
|
+
- Forces flush of span exporter if initialized
|
|
130
|
+
- Logs export status with endpoint and topic details
|
|
131
|
+
- Handles cases where exporter is not properly initialized
|
|
132
|
+
"""
|
|
67
133
|
if self._exporter:
|
|
68
134
|
self._exporter.force_flush()
|
|
69
135
|
logger.info(
|