Skip to content

Commit d461eac

Browse files
Merge branch 'main' into dependabot/uv/werkzeug-3.1.5
2 parents 3613c96 + 14c2b49 commit d461eac

File tree

7 files changed

+136
-5
lines changed

7 files changed

+136
-5
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Dependency Review - blocks PRs that introduce known-vulnerable dependencies
2+
name: Dependency Review
3+
4+
on:
5+
pull_request:
6+
branches: [main]
7+
8+
permissions:
9+
contents: read
10+
pull-requests: write
11+
12+
jobs:
13+
dependency-review:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
19+
- name: Dependency Review
20+
uses: actions/dependency-review-action@v4
21+
with:
22+
fail-on-severity: high
23+
comment-summary-in-pr: always
24+
deny-licenses: GPL-3.0-only, AGPL-3.0-only

.pre-commit-config.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Pre-commit hooks for Agent365-python
2+
# Install: pip install pre-commit && pre-commit install
3+
# Run manually: pre-commit run --all-files
4+
5+
repos:
6+
# Gitleaks - detect secrets in code
7+
- repo: https://github.com/gitleaks/gitleaks
8+
rev: v8.18.4
9+
hooks:
10+
- id: gitleaks
11+
12+
# Whitespace fixes
13+
- repo: https://github.com/pre-commit/pre-commit-hooks
14+
rev: v4.6.0
15+
hooks:
16+
- id: trailing-whitespace
17+
args: [--markdown-linebreak-ext=md]
18+
- id: end-of-file-fixer
19+
- id: mixed-line-ending
20+
args: [--fix=lf]
21+
- id: check-merge-conflict
22+
- id: check-yaml
23+
args: [--allow-multiple-documents]
24+
- id: check-json
25+
- id: check-toml
26+
- id: check-ast
27+
28+
# Python specific - using Ruff (matches CI settings)
29+
- repo: https://github.com/astral-sh/ruff-pre-commit
30+
rev: v0.4.4
31+
hooks:
32+
- id: ruff
33+
args: [--fix, --line-length=100]
34+
- id: ruff-format
35+
args: [--line-length=100]

libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/execute_tool_scope.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def start(
3030
agent_details: AgentDetails,
3131
tenant_details: TenantDetails,
3232
request: Request | None = None,
33+
parent_id: str | None = None,
3334
) -> "ExecuteToolScope":
3435
"""Creates and starts a new scope for tool execution tracing.
3536
@@ -38,18 +39,21 @@ def start(
3839
agent_details: The details of the agent making the call
3940
tenant_details: The details of the tenant
4041
request: Optional request details for additional context
42+
parent_id: Optional parent Activity ID used to link this span to an upstream
43+
operation
4144
4245
Returns:
4346
A new ExecuteToolScope instance
4447
"""
45-
return ExecuteToolScope(details, agent_details, tenant_details, request)
48+
return ExecuteToolScope(details, agent_details, tenant_details, request, parent_id)
4649

4750
def __init__(
4851
self,
4952
details: ToolCallDetails,
5053
agent_details: AgentDetails,
5154
tenant_details: TenantDetails,
5255
request: Request | None = None,
56+
parent_id: str | None = None,
5357
):
5458
"""Initialize the tool execution scope.
5559
@@ -58,13 +62,16 @@ def __init__(
5862
agent_details: The details of the agent making the call
5963
tenant_details: The details of the tenant
6064
request: Optional request details for additional context
65+
parent_id: Optional parent Activity ID used to link this span to an upstream
66+
operation
6167
"""
6268
super().__init__(
6369
kind="Internal",
6470
operation_name=EXECUTE_TOOL_OPERATION_NAME,
6571
activity_name=f"{EXECUTE_TOOL_OPERATION_NAME} {details.tool_name}",
6672
agent_details=agent_details,
6773
tenant_details=tenant_details,
74+
parent_id=parent_id,
6875
)
6976

7077
# Extract details using deconstruction-like approach

libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/inference_scope.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def start(
3434
agent_details: AgentDetails,
3535
tenant_details: TenantDetails,
3636
request: Request | None = None,
37+
parent_id: str | None = None,
3738
) -> "InferenceScope":
3839
"""Creates and starts a new scope for inference tracing.
3940
@@ -42,18 +43,21 @@ def start(
4243
agent_details: The details of the agent making the call
4344
tenant_details: The details of the tenant
4445
request: Optional request details for additional context
46+
parent_id: Optional parent Activity ID used to link this span to an upstream
47+
operation
4548
4649
Returns:
4750
A new InferenceScope instance
4851
"""
49-
return InferenceScope(details, agent_details, tenant_details, request)
52+
return InferenceScope(details, agent_details, tenant_details, request, parent_id)
5053

5154
def __init__(
5255
self,
5356
details: InferenceCallDetails,
5457
agent_details: AgentDetails,
5558
tenant_details: TenantDetails,
5659
request: Request | None = None,
60+
parent_id: str | None = None,
5761
):
5862
"""Initialize the inference scope.
5963
@@ -62,6 +66,8 @@ def __init__(
6266
agent_details: The details of the agent making the call
6367
tenant_details: The details of the tenant
6468
request: Optional request details for additional context
69+
parent_id: Optional parent Activity ID used to link this span to an upstream
70+
operation
6571
"""
6672

6773
super().__init__(
@@ -70,6 +76,7 @@ def __init__(
7076
activity_name=f"{details.operationName.value} {details.model}",
7177
agent_details=agent_details,
7278
tenant_details=tenant_details,
79+
parent_id=parent_id,
7380
)
7481

7582
if request:

tests/observability/core/test_execute_tool_scope.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,32 @@ def test_request_metadata_set_on_span(self):
131131
request.source_metadata.description,
132132
)
133133

134+
def test_execute_tool_scope_with_parent_id(self):
135+
"""Test ExecuteToolScope uses parent_id to link span to parent context."""
136+
parent_trace_id = "1234567890abcdef1234567890abcdef"
137+
parent_span_id = "abcdefabcdef1234"
138+
parent_id = f"00-{parent_trace_id}-{parent_span_id}-01"
139+
140+
with ExecuteToolScope.start(
141+
self.tool_details, self.agent_details, self.tenant_details, parent_id=parent_id
142+
):
143+
pass
144+
145+
finished_spans = self.span_exporter.get_finished_spans()
146+
self.assertTrue(finished_spans, "Expected at least one span to be created")
147+
148+
span = finished_spans[-1]
149+
150+
# Verify span inherits parent's trace_id
151+
span_trace_id = f"{span.context.trace_id:032x}"
152+
self.assertEqual(span_trace_id, parent_trace_id)
153+
154+
# Verify span's parent_span_id matches
155+
self.assertIsNotNone(span.parent, "Expected span to have a parent")
156+
self.assertTrue(hasattr(span.parent, "span_id"), "Expected parent to have span_id")
157+
span_parent_id = f"{span.parent.span_id:016x}"
158+
self.assertEqual(span_parent_id, parent_span_id)
159+
134160

135161
if __name__ == "__main__":
136162
# Run pytest only on the current file

tests/observability/core/test_inference_scope.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,38 @@ def test_record_thought_process(self):
340340
# Should not raise an exception
341341
self.assertTrue(hasattr(scope, "record_thought_process"))
342342

343+
def test_inference_scope_with_parent_id(self):
344+
"""Test InferenceScope uses parent_id to link span to parent context."""
345+
details = InferenceCallDetails(
346+
operationName=InferenceOperationType.CHAT,
347+
model="gpt-4",
348+
providerName="openai",
349+
)
350+
351+
parent_trace_id = "1234567890abcdef1234567890abcdef"
352+
parent_span_id = "abcdefabcdef1234"
353+
parent_id = f"00-{parent_trace_id}-{parent_span_id}-01"
354+
355+
with InferenceScope.start(
356+
details, self.agent_details, self.tenant_details, parent_id=parent_id
357+
):
358+
pass
359+
360+
finished_spans = self.span_exporter.get_finished_spans()
361+
self.assertTrue(finished_spans, "Expected at least one span to be created")
362+
363+
span = finished_spans[-1]
364+
365+
# Verify span inherits parent's trace_id
366+
span_trace_id = f"{span.context.trace_id:032x}"
367+
self.assertEqual(span_trace_id, parent_trace_id)
368+
369+
# Verify span's parent_span_id matches
370+
self.assertIsNotNone(span.parent, "Expected span to have a parent")
371+
self.assertTrue(hasattr(span.parent, "span_id"), "Expected parent to have span_id")
372+
span_parent_id = f"{span.parent.span_id:016x}"
373+
self.assertEqual(span_parent_id, parent_span_id)
374+
343375

344376
if __name__ == "__main__":
345377
# Run pytest only on the current file

uv.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)