diff --git a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py index 8176c59f..f077bcfe 100644 --- a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +++ b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py @@ -36,6 +36,9 @@ from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer from veadk.types import AgentRunConfig from veadk.utils.logger import get_logger +from volcengine.base.Request import Request +from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator +from opentelemetry import context logger = get_logger(__name__) @@ -117,6 +120,8 @@ async def agent_card() -> dict: agent_card = await agent_card_builder.build() return agent_card.model_dump() +async def get_cozeloop_space_id() -> dict: + return {"space_id": os.getenv("OBSERVABILITY_OPENTELEMETRY_COZELOOP_SERVICE_NAME", default="")} load_tracer() @@ -132,7 +137,7 @@ async def agent_card() -> dict: a2a_app.post("/run_agent", operation_id="run_agent", tags=["mcp"])(run_agent_func) a2a_app.get("/agent_card", operation_id="agent_card", tags=["mcp"])(agent_card) - +a2a_app.get("/get_cozeloop_space_id", operation_id="get_cozeloop_space_id", tags=["mcp"])(get_cozeloop_space_id) # === Build mcp server === @@ -159,6 +164,25 @@ async def combined_lifespan(app: FastAPI): redoc_url=None ) +@app.middleware("http") +async def otel_context_middleware(request: Request, call_next): + carrier = { + "traceparent": request.headers.get("Traceparent"), + "tracestate": request.headers.get("Tracestate"), + } + logger.debug(f"carrier: {carrier}") + if carrier["traceparent"] is None: + return await call_next(request) + else: + ctx = TraceContextTextMapPropagator().extract(carrier=carrier) + logger.debug(f"ctx: {ctx}") + token = context.attach(ctx) + try: + response = await call_next(request) + finally: + context.detach(token) + return response + # Mount A2A routes to main app for route in a2a_app.routes: app.routes.append(route) diff --git a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt index d4b2885a..abf02522 100644 --- a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +++ b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt @@ -1 +1,3 @@ -veadk-python \ No newline at end of file +veadk-python +fastapi +uvicorn[standard] \ No newline at end of file diff --git a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh index 3bfb5915..58bdcb96 100755 --- a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +++ b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh @@ -33,13 +33,6 @@ while [[ $# -gt 0 ]]; do esac done -# in case of deployment deps not installed in user's requirements.txt -if pip list | grep -q "^fastapi \|^uvicorn "; then - echo "fastapi and uvicorn already installed" -else - python3 -m pip install uvicorn[standard] fastapi -fi - # Check if MODEL_AGENT_API_KEY is set if [ -z "$MODEL_AGENT_API_KEY" ]; then echo "MODEL_AGENT_API_KEY is not set. Please set it in your environment variables." diff --git a/veadk/integrations/ve_faas/ve_faas.py b/veadk/integrations/ve_faas/ve_faas.py index c94fe7fa..eb54a97b 100644 --- a/veadk/integrations/ve_faas/ve_faas.py +++ b/veadk/integrations/ve_faas/ve_faas.py @@ -152,6 +152,8 @@ def _create_application( "GatewayName": gateway_name, "ServiceName": service_name, "UpstreamName": upstream_name, + "EnableKeyAuth": True, + "EnableMcpSession": True, }, "TemplateId": self.template_id, }, diff --git a/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py b/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py index cb5b73f1..a38e218c 100644 --- a/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +++ b/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py @@ -49,6 +49,10 @@ def common_cozeloop_report_source(**kwargs) -> str: return "veadk" +def common_cozeloop_call_type(**kwargs) -> str: + return kwargs.get("call_type") + + def llm_openinference_instrumentation_veadk(**kwargs) -> str: return VERSION @@ -68,4 +72,5 @@ def llm_openinference_instrumentation_veadk(**kwargs) -> str: "user.id": common_gen_ai_user_id, # CozeLoop / TLS required "session.id": common_gen_ai_session_id, # CozeLoop / TLS required "cozeloop.report.source": common_cozeloop_report_source, # CozeLoop required + "cozeloop.call_type": common_cozeloop_call_type, # CozeLoop required } diff --git a/veadk/tracing/telemetry/telemetry.py b/veadk/tracing/telemetry/telemetry.py index 4210061a..838532d0 100644 --- a/veadk/tracing/telemetry/telemetry.py +++ b/veadk/tracing/telemetry/telemetry.py @@ -227,6 +227,11 @@ def trace_call_llm( model_name=invocation_context.agent.model_name if isinstance(invocation_context.agent, Agent) else "", + call_type=span.context.trace_state.get("call_type") + if hasattr(span, "context") + and hasattr(span.context, "trace_state") + and hasattr(span.context.trace_state, "get") + else "", ) llm_attributes_mapping = ATTRIBUTES.get("llm", {})