Skip to content

Commit bc227df

Browse files
committed
2 parents 66cb3ff + 54ac161 commit bc227df

9 files changed

Lines changed: 181 additions & 91 deletions

File tree

.github/workflows/codeql.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050

5151
# Initializes the CodeQL tools for scanning.
5252
- name: Initialize CodeQL
53-
uses: github/codeql-action/init@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
53+
uses: github/codeql-action/init@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3
5454
with:
5555
languages: ${{ matrix.language }}
5656
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -60,7 +60,7 @@ jobs:
6060
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
6161
# If this step fails, then you should remove it and run the build manually (see below)
6262
- name: Autobuild
63-
uses: github/codeql-action/autobuild@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
63+
uses: github/codeql-action/autobuild@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3
6464

6565
# ℹ️ Command-line programs to run using the OS shell.
6666
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -73,6 +73,6 @@ jobs:
7373
# ./location_of_script_within_repo/buildscript.sh
7474

7575
- name: Perform CodeQL Analysis
76-
uses: github/codeql-action/analyze@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
76+
uses: github/codeql-action/analyze@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3
7777
with:
7878
category: "/language:${{matrix.language}}"
Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
1-
# Dependency Review Action
2-
#
3-
# This Action will scan dependency manifest files that change as part of a Pull Request,
4-
# surfacing known-vulnerable versions of the packages declared or updated in the PR.
5-
# Once installed, if the workflow run is marked as required,
6-
# PRs introducing known-vulnerable packages will be blocked from merging.
7-
#
8-
# Source repository: https://github.com/actions/dependency-review-action
9-
name: 'Dependency Review'
10-
on: [pull_request]
1+
# Dependency Review - blocks PRs that introduce known-vulnerable dependencies
2+
name: Dependency Review
3+
4+
on:
5+
pull_request:
6+
branches: [main]
117

128
permissions:
139
contents: read
10+
pull-requests: write
1411

1512
jobs:
1613
dependency-review:
1714
runs-on: ubuntu-latest
1815
steps:
19-
- name: Harden the runner (Audit all outbound calls)
20-
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
21-
with:
22-
egress-policy: audit
16+
- name: Checkout repository
17+
uses: actions/checkout@v6
2318

24-
- name: 'Checkout Repository'
25-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
26-
- name: 'Dependency Review'
27-
uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2
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

.github/workflows/scorecards.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,6 @@ jobs:
7676

7777
# Upload the results to GitHub's code scanning dashboard.
7878
- name: "Upload to code-scanning"
79-
uses: github/codeql-action/upload-sarif@45cbd0c69e560cd9e7cd7f8c32362050c9b7ded2 # v4.32.2
79+
uses: github/codeql-action/upload-sarif@9e907b5e64f6b83e7804b09294d44122997950d6 # v4.32.3
8080
with:
8181
sarif_file: results.sarif

.pre-commit-config.yaml

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +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+
15
repos:
2-
- repo: https://github.com/gitleaks/gitleaks
3-
rev: v8.16.3
4-
hooks:
5-
- id: gitleaks
6-
- repo: https://github.com/pre-commit/pre-commit-hooks
7-
rev: v4.4.0
8-
hooks:
9-
- id: end-of-file-fixer
10-
- id: trailing-whitespace
11-
- repo: https://github.com/pylint-dev/pylint
12-
rev: v2.17.2
13-
hooks:
14-
- id: pylint
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

0 commit comments

Comments
 (0)