Skip to content

Add typed execute-tool schema payloads - #267

Merged
Hector Hernandez (hectorhdzg) merged 21 commits into
microsoft:mainfrom
nikhilNava:copilot/execute-tool-schema
Sep 24, 2026
Merged

Hector Hernandez (hectorhdzg) merged 21 commits into
microsoft:mainfrom
nikhilNava:copilot/execute-tool-schema

Conversation

@nikhilNava

@nikhilNava Nikhil Navakiran (nikhilNava) commented Sep 11, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • add typed execute-tool arguments and result models for the versioned 1.0 JSON contract
  • add action, outcome, and policy enums plus nested resource, security, sensitivity, and pagination models
  • preserve existing dict/string inputs and use non-throwing diagnostic serialization for invalid payloads

Python parity for the non-ETW behavior in microsoft/opentelemetry-distro-dotnet#149.

Validation

  • full tests: 1149 passed, 36 skipped
  • A365 tests: 534 passed, 15 skipped
  • Black, Pylint, and Mypy: passed

Compatibility Note

The JSON wire contract now wraps provider-specific extension values under metadata. The corresponding .NET, JavaScript, schema, and downstream parser updates must roll out as a coordinated contract change.

nikhilc-microsoft and others added 10 commits September 11, 2026 16:17
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The tox mypy commands already pass --ignore-missing-imports, so the msal section was unnecessary and unrelated to the execute-tool schema feature.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Serialization of typed execute-tool payloads is now non-throwing and matches
the .NET contract (PR microsoft/opentelemetry-distro-dotnet#149). Any per-value
failure, reference cycle, unsupported type, non-finite float (allow_nan=False),
undefined enum token, or extension-data collision replaces the payload with the
diagnostic object {"serialization_error":"Failed to serialize execute tool
payload."} instead of leaking an exception or orphaning the span. Disabled
telemetry paths are safe for the same reason.

None is now omitted only for model properties; None inside caller-supplied
mappings and lists is preserved as JSON null. Bytes serialize as base64,
datetime/date/time as ISO-8601, UUID and enums as their string values, and
Decimal as a JSON number.

Adds public ToolCallAction, ToolCallOutcomeStatus, and ToolPolicyDecision str
enums matching .NET. Typed enum fields accept enum members and the exact
lowercase tokens for backward compatibility, rejecting undefined, mis-cased,
numeric, boolean, and foreign-enum values.

Extension-data collisions are checked only against properties that are actually
serialized, so extension data may supply a key whose model property is None
while still being rejected when it would overwrite a present property.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…modes

Covers the ToolCallAction, ToolCallOutcomeStatus, and ToolPolicyDecision tokens,
the accepted exact lowercase strings, null retention inside caller mappings and
lists, extension-data collision rules, and the non-throwing diagnostic payload.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ections

Raw dictionary arguments and results now share the diagnostic fallback with the
typed models, matching .NET PR microsoft/opentelemetry-distro-dotnet#149 where
the dictionary overloads also route through MessageUtils.SerializeToolPayload.
Previously a cyclic or otherwise unserializable dictionary raised out of
ExecuteToolScope.start(), leaving the span started but never ended. The existing
safe_json_dumps output is unchanged for payloads that already serialized.

Typed payload serialization now emits sets, frozensets, and other sized
collections as JSON arrays instead of discarding the whole payload, matching how
.NET writes any IEnumerable value.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Performance comparison

Threshold: regressions >15.0% on gating scenarios fail the build. Higher ops/s is better; positive Δ means the PR is slower.

Scenario Gating Baseline (ops/s) Candidate (ops/s) Δ % Status
azure_monitor_log yes 16,575.0 16,454.0 +0.74% ✅
azure_monitor_span yes 150,557.1 159,974.4 -5.89% ✅
otel_log no 19,059.2 18,873.6 +0.98% ✅
otel_span no 40,824.7 41,143.8 -0.78% ✅

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Three moderate serialization issues remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds typed Agent365 execute-tool schema models, enums, nested metadata, serialization, telemetry integration, tests, and documentation while preserving raw payload support.

Changes:

  • Adds versioned argument/result models and public exports.
  • Integrates typed payload serialization into tool scopes.
  • Adds tests, documentation, and changelog updates.
  • Three moderate serialization issues remain in tool_call_schema.py: enum validation bypass via extension_data (1 vote), Decimal precision loss (3 votes), and UTC timestamp formatting mismatch (1 vote).
File summaries
File Summary
tests/a365/test_tool_call_schema.py Tests schema serialization behavior.
tests/a365/test_execute_tool_scope.py Tests scope integration and failure handling.
src/microsoft/opentelemetry/a365/README.md Lists the new model module.
src/microsoft/opentelemetry/a365/core/tool_call_details.py Adds typed argument support.
src/microsoft/opentelemetry/a365/core/models/tool_call_schema.py Defines typed models and serializer; contains the three moderate issues noted above.
src/microsoft/opentelemetry/a365/core/execute_tool_scope.py Serializes typed and raw tool payloads.
src/microsoft/opentelemetry/a365/core/__init__.py Exposes the new public API.
README.md Adds usage overview.
CHANGELOG.md Records the unreleased feature.
A365_DOCUMENTATION.md Documents the schema contract.
Review details

Suppressed comments (2)

src/microsoft/opentelemetry/a365/core/models/tool_call_schema.py:297

  • Enum validation can be bypassed through extension_data whenever the typed property is None: for example, ExecuteToolCallArguments(extension_data={"action": "write"}) emits action: "write", even though the documented enum contract says undefined tokens are rejected. When an extension key matches a declared enum field, validate it with _coerce_enum (while still allowing valid tokens) instead of serializing it as an arbitrary value.
        for key, item_value in extension_data.items():
            json_key = _json_object_key(key)
            if json_key in serialized:
                raise ValueError(f"Extension data cannot overwrite execute tool payload property '{json_key}'.")
            serialized[json_key] = _to_json_value(item_value, stack)

src/microsoft/opentelemetry/a365/core/models/tool_call_schema.py:202

  • datetime.isoformat() renders a UTC-aware value with +00:00, whereas the parity implementation's System.Text.Json serialization emits UTC DateTime values with the Z designator. A timestamp in data or extension data therefore produces a different execute-tool payload (the added test currently locks in +00:00); normalize UTC-aware datetimes to the contract's Z form and add a regression case.
def _to_isoformat(value: datetime.datetime | datetime.date | datetime.time) -> str:
    """Return the ISO-8601 text for a date/time value."""
    return value.isoformat()
  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/microsoft/opentelemetry/a365/core/models/tool_call_schema.py Outdated
Comment thread src/microsoft/opentelemetry/a365/core/models/tool_call_schema.py Outdated
nikhilc-microsoft and others added 7 commits September 23, 2026 15:33
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
nikhilc-microsoft and others added 3 commits September 24, 2026 10:52
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@hectorhdzg
Hector Hernandez (hectorhdzg) merged commit 10cf953 into microsoft:main Sep 24, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants