Skip to content

Commit f1f355f

Browse files
authored
Merge branch 'main' into copilot/fix-docstring-formatting
2 parents b414522 + 8622478 commit f1f355f

137 files changed

Lines changed: 11144 additions & 2215 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ jobs:
8585
defaults:
8686
run:
8787
working-directory: ./
88+
env:
89+
PYTHONPATH: ${{ github.workspace }}/versioning/helper
8890

8991
strategy:
9092
matrix:
@@ -107,15 +109,13 @@ jobs:
107109
run: uv lock && uv sync --locked --all-extras --dev
108110

109111
- name: Verify centralized version constraints
110-
run: python scripts/verify_constraints.py
112+
run: uv run --frozen tox -e verify-constraints
111113

112114
- name: Check linting
113-
run: |
114-
uv run --frozen ruff check . --preview
115+
run: uv run --frozen tox -e lint
115116

116117
- name: Check formatting
117-
run: |
118-
uv run --frozen ruff format --check .
118+
run: uv run --frozen tox -e format
119119

120120
- name: Build package
121121
run: |
@@ -124,14 +124,12 @@ jobs:
124124
AGENT365_PYTHON_SDK_PACKAGE_VERSION: ${{ needs.version-number.outputs.PACKAGE_VERSION }}
125125

126126
- name: Run unit tests
127-
run: |
128-
uv run --frozen pytest tests/ -v --tb=short -m "not integration"
127+
run: uv run --frozen tox -e py3${{ matrix.python-version == '3.11' && '11' || '12' }}
129128

130129
- name: Run integration tests
131130
# Only run integration tests if secrets are available
132131
if: ${{ vars.RUN_INTEGRATION_TESTS == 'true' }}
133-
run: |
134-
uv run --frozen pytest -m integration -v --tb=short
132+
run: uv run --frozen tox -e integration
135133
env:
136134
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
137135
AZURE_OPENAI_ENDPOINT: ${{ vars.AZURE_OPENAI_ENDPOINT }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ dist/
7272
build/
7373
.eggs/
7474
.pytest_cache/
75+
.tox/
7576
_version.py
7677

7778
# Test coverage and reports

CLAUDE.md

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,31 @@ pytest tests/ --cov=libraries --cov-report=html -v
6161
- `unit`: Fast, mocked tests (default)
6262
- `integration`: Slow tests requiring real services/API keys
6363

64+
### Running with tox
65+
66+
```bash
67+
# Run all default environments (lint, format, unit tests on 3.11 + 3.12)
68+
uv run tox
69+
70+
# Run a specific environment
71+
uv run tox -e lint
72+
uv run tox -e format
73+
uv run tox -e py311
74+
uv run tox -e py312
75+
76+
# Run integration tests (requires env vars)
77+
uv run tox -e integration
78+
79+
# Verify centralized dependency constraints
80+
uv run tox -e verify-constraints
81+
82+
# Pass extra args to pytest
83+
uv run tox -e py311 -- -k "environment"
84+
85+
# List all available environments
86+
uv run tox list
87+
```
88+
6489
### Linting and Formatting
6590

6691
```bash
@@ -194,6 +219,18 @@ Place it before imports with one blank line after.
194219
- **Never** use the keyword "Kairo" in code - it's a legacy reference that must be removed/replaced
195220
- If found during code review, flag for removal
196221

222+
### Observability Export Configuration — Coordinated Review Required
223+
224+
The following three constants must stay in sync. If a PR changes **any one** of them, the reviewer (human or Copilot) **must** ask the author to confirm the other two are still correct:
225+
226+
| Constant | Location |
227+
|---|---|
228+
| `PROD_OBSERVABILITY_SCOPE` | `libraries/microsoft-agents-a365-runtime/microsoft_agents_a365/runtime/environment_utils.py` |
229+
| `DEFAULT_ENDPOINT_URL` | `libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/exporters/agent365_exporter.py` |
230+
| Export URL path pattern | `build_export_url()` in `libraries/microsoft-agents-a365-observability-core/microsoft_agents_a365/observability/core/exporters/utils.py` |
231+
232+
Snapshot tests in `tests/observability/core/test_export_config_consistency.py` will fail if any value drifts, but the developer must also verify the values are correct for the target environment — the tests only catch accidental drift, not intentional-but-incomplete updates.
233+
197234
### Python Conventions
198235

199236
- Type hints required on all function parameters and return types
@@ -241,7 +278,8 @@ Place it before imports with one blank line after.
241278
The `.github/workflows/ci.yml` pipeline:
242279
- Runs on pushes to `main` and `release/*` branches
243280
- Tests both Python 3.11 and 3.12
244-
- Executes: lint check → format check → build → unit tests → integration tests (if secrets available)
281+
- Uses **tox** (via `uv run --frozen tox -e <env>`) to run lint, format, test, and constraint verification steps
282+
- Executes: verify-constraints → lint → format → build → unit tests → integration tests (if secrets available)
245283
- Only publishes packages on `release/*` branches when SDK changes detected
246284
- Uses git-based versioning (tags on release branches = official versions, others = dev versions)
247285

docs/design.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,23 @@ The foundation for distributed tracing in agent applications. Built on OpenTelem
8181

8282
| Class | Purpose |
8383
|-------|---------|
84-
| `InvokeAgentDetails` | Agent endpoint, session ID, and invocation metadata |
84+
| `InvokeAgentScopeDetails` | Agent endpoint and invocation metadata |
8585
| `AgentDetails` | Agent identification and metadata |
86-
| `TenantDetails` | Tenant identification for multi-tenant scenarios |
86+
| `UserDetails` | Human caller identification (user ID, email, name, IP) |
87+
| `CallerDetails` | Wrapper for user details and/or caller agent details |
88+
| `SpanDetails` | Parent context, timing, and span kind for custom spans |
8789
| `InferenceCallDetails` | Model name, tokens, provider information |
8890
| `ToolCallDetails` | Tool name, arguments, endpoint |
89-
| `Request` | Execution context and correlation ID |
91+
| `Request` | Content, correlation ID, and conversation ID |
9092

9193
**Usage Example:**
9294

9395
```python
9496
from microsoft_agents_a365.observability.core import (
9597
configure,
9698
InvokeAgentScope,
97-
InvokeAgentDetails,
98-
TenantDetails,
99+
InvokeAgentScopeDetails,
100+
AgentDetails,
99101
Request,
100102
BaggageBuilder,
101103
)
@@ -112,9 +114,9 @@ configure(
112114
with BaggageBuilder().tenant_id(tenant_id).agent_id(agent_id).build():
113115
# Trace agent invocation
114116
with InvokeAgentScope.start(
115-
invoke_agent_details=InvokeAgentDetails(...),
116-
tenant_details=TenantDetails(...),
117-
request=Request(...)
117+
request=Request(content="Hello"),
118+
invoke_scope_details=InvokeAgentScopeDetails(...),
119+
agent_details=AgentDetails(...),
118120
) as scope:
119121
# Agent logic here
120122
scope.record_response("result")

libraries/microsoft-agents-a365-notifications/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[build-system]
2-
requires = ["setuptools>=68", "wheel", "tzdata"]
3-
build-backend = "setuptools.build_meta"
2+
requires = ["setuptools>=68", "wheel", "tzdata", "tomlkit", "packaging"]
3+
build-backend = "build_backend"
44

55
[project]
66
name = "microsoft-agents-a365-notifications"
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Changelog — microsoft-agents-a365-observability-core
2+
3+
All notable changes to this package will be documented in this file.
4+
5+
## [0.3.0]
6+
7+
### Breaking Changes
8+
9+
- **New permission required: `Agent365.Observability.OtelWrite`** — The observability exporter now requires this scope as both a delegated and application permission on your agent blueprint. See [Upgrade Instructions](#upgrade-instructions-observability-permission-for-existing-agents) below.
10+
11+
---
12+
13+
### Upgrade Instructions: Observability Permission for Existing Agents
14+
15+
Existing agent blueprints need `Agent365.Observability.OtelWrite` granted as both a **delegated permission** and an **application permission**. Choose either option below.
16+
17+
#### Option A — Agent 365 CLI (requires both config files)
18+
19+
Requires `a365.config.json` and `a365.generated.config.json` in your config directory, a Global Administrator account, and [Agent 365 CLI v1.1.139-preview](https://www.nuget.org/packages/Microsoft.Agents.A365.DevTools.Cli/1.1.139-preview) or later.
20+
21+
```
22+
a365 setup admin --config-dir "<path-to-config-dir>"
23+
```
24+
25+
This grants all missing permissions including the new Observability scopes.
26+
27+
#### Option B — Entra Portal (no config files required)
28+
29+
Requires Global Administrator access to the blueprint app registration.
30+
31+
1. Go to **Entra portal** > **App registrations** > select your Blueprint app
32+
2. Go to **API permissions** > **Add a permission** > **APIs my organization uses** > search for `9b975845-388f-4429-889e-eab1ef63949c`
33+
3. Select **Delegated permissions** > check `Agent365.Observability.OtelWrite` > **Add permissions**
34+
4. Repeat step 2–3, this time select **Application permissions** > check `Agent365.Observability.OtelWrite` > **Add permissions**
35+
5. Click **Grant admin consent** and confirm
36+
37+
Both `Agent365.Observability.OtelWrite` (Delegated) and `Agent365.Observability.OtelWrite` (Application) should show **Granted** status.
38+
39+
> **Note:** If your agent is autonomous, you only need the **Application permission**. The delegated permission is required for agents that authenticate via a user session.
40+
41+
---
42+
43+
## [0.2.1.dev46]
44+
45+
### Breaking Changes
46+
47+
- **`InvokeAgentDetails` renamed to `InvokeAgentScopeDetails`** — Now contains only scope-level config (`endpoint`). Agent identity (`AgentDetails`) is a separate parameter. `session_id` moved to `Request`.
48+
- **`InvokeAgentScope.start()`**: New signature `start(request, invoke_scope_details, agent_details, caller_details?, span_details?)`. `request` is required.
49+
- **`InferenceScope.start()`**: New signature `start(request, details, agent_details, user_details?, span_details?)`. `request` is required.
50+
- **`ExecuteToolScope.start()`**: New signature `start(request, details, agent_details, user_details?, span_details?)`. Same pattern as `InferenceScope`.
51+
- **`OutputScope.start()`**: New signature `start(request, response, agent_details, user_details?, span_details?)`. Same pattern.
52+
- **`CallerDetails` renamed to `UserDetails`** — Fields renamed: `caller_id``user_id`, `caller_upn``user_email`, `caller_name``user_name`, `caller_client_ip``user_client_ip`.
53+
- **`CallerDetails` is now a composite wrapper** — Groups `user_details: UserDetails` and `caller_agent_details: AgentDetails` for A2A scenarios.
54+
- **`TenantDetails` removed**`tenant_id` is now on `AgentDetails.tenant_id`. Removed from all scope `start()` methods.
55+
- **`ExecutionType` enum removed** — Removed from `Request`. `GEN_AI_EXECUTION_TYPE_KEY` constant also removed.
56+
- **`AgentDetails` fields renamed**`agent_auid``agentic_user_id`, `agent_upn``agentic_user_email`. `conversation_id` moved to `Request`.
57+
- **`Request` model updated** — Removed `execution_type`. Added `conversation_id`. `content` is now optional.
58+
- **`BaggageBuilder` methods renamed**`agent_upn()``agentic_user_email()`, `agent_auid()``agentic_user_id()`, `caller_id()``user_id()`, `caller_name()``user_name()`, `caller_upn()``user_email()`, `caller_client_ip()``user_client_ip()`.
59+
60+
### Added
61+
62+
- **`SpanDetails`** — Groups `span_kind`, `parent_context`, `start_time`, `end_time` for scope construction.
63+
- **`UserDetails`** — Human caller identity with `user_id`, `user_email`, `user_name`, `user_client_ip`.
64+
- **`CallerDetails`** (new wrapper) — Groups `user_details` and `caller_agent_details` for A2A scenarios.
65+
- **`InvokeAgentScopeDetails`** — Scope-level config with `endpoint` only.
66+
- **`Request.conversation_id`** — Conversation ID field on the unified `Request` model.
67+
- **`ERROR_TYPE_CANCELLED`** constant — `"TaskCanceledException"`, used by `record_cancellation()`.
68+
- **`OutputScope`** now exported from `microsoft_agents_a365.observability.core`.

0 commit comments

Comments
 (0)