Skip to content

[agentserver] Fix storage typing and claims test broken by microsoft-agents-hosting-core 1.4.0 - #48660

Open
Shanmukha Pasumarthy (shanmukha1200) wants to merge 1 commit into
mainfrom
spasumarthy/agentserver-storage-typing-fix
Open

[agentserver] Fix storage typing and claims test broken by microsoft-agents-hosting-core 1.4.0#48660
Shanmukha Pasumarthy (shanmukha1200) wants to merge 1 commit into
mainfrom
spasumarthy/agentserver-storage-typing-fix

Conversation

@shanmukha1200

Copy link
Copy Markdown
Member

Problem

The python - agentserver pipeline (build 6724107) started failing on main without any repo change. The last green run (ec6daf825) and the first red run (bc99dcd26) have a completely empty diff across both affected packages:

git diff --stat ec6daf825 bc99dcd26 -- sdk/agentserver/azure-ai-agentserver-core/ \
                                       sdk/agentserver/azure-ai-agentserver-activity/
(empty)

The trigger is external. microsoft-agents-hosting-core is pinned open-ended as >=1.1.0, so CI resolves the newest release. 1.4.0 was published 2026-08-18 21:07 UTC — the last green build finished 13:13 UTC that day, and everything after it is red.

1.4.0 introduced two changes that broke us:

1. The package added a py.typed marker.

1.3.0: no py.typed
1.4.0: microsoft_agents/hosting/core/py.typed

Previously mypy ran against it with --ignore-missing-imports, so StoreItem and friends silently degraded to Any and nothing was checked. With the marker present mypy resolves the real signatures and surfaces two latent, pre-existing type errors in FoundryStorage:

_foundry_storage.py:330: error: Incompatible return value type (got "tuple[str, StoreItem]",
    expected "tuple[str | None, StoreItemT | None]")  [return-value]
_foundry_storage.py:343: error: Argument 2 to "set_item" of "FoundryStateStore" has
    incompatible type "MutableMapping[str, Any]"; expected "dict[str, JSONValue]"  [arg-type]

Note the JSON = MutableMapping[str, Any] alias is identical across 1.1.0 → 1.4.0. This was never a signature change, purely a visibility change.

2. ClaimsIdentity.is_authenticated became a deprecated computed property.

@property
def is_authenticated(self) -> bool:   # 1.4.0
    return bool(self.claims)          # constructor arg is now a deprecated no-op

It was a stored attribute in 1.1.0 / 1.2.0 / 1.3.0. test_claims_authenticated_with_empty_bot_app_id_has_empty_claims passes bot_app_id="", which produces an empty claim dict, so the assertion now evaluates False on all 6 platforms.

Fix

set_item / create_item — widened, no cast. These are our own APIs and they only serialize value, never mutate it, so the concrete dict requirement was needlessly narrow and rejected valid callers:

value: Mapping[str, JSONValue]     # was: JSONObject (= dict[str, JSONValue])

Mapping is covariant in its value type, so MutableMapping[str, Any] now satisfies it. Widening a parameter type is backward compatible — every existing caller still type-checks. The same widening is applied to LocalStateStoreBackend, and the two serialize_item_* helpers now materialize a dict at the wire boundary (a genuine defensive copy before json.dumps, not a type-system workaround). The adapter call site is then plain:

await store.set_item(_bounded_store_name(key), value.store_item_to_json())

_write_item — narrowing removed. Now matches the AsyncStorageBase signature (value: StoreItem). The TypeVar appeared only once so it bought nothing, and narrowing a parameter in an override violates LSP.

_read_item — the one remaining cast, with an explanatory comment. Unavoidable locally: StoreItem.from_json_to_store_item is annotated -> StoreItem in the third-party M365 SDK and does not narrow through type[StoreItemT]. We also can't widen our own return type, since return types are covariant in overrides. The cast is sound — target_cls is type[StoreItemT], so the runtime object genuinely is a StoreItemT. The upstream fix would be annotating it -> Self.

Test — asserts on authentication_type and the claim values instead of the now-deprecated is_authenticated.

Verification

Run locally with microsoft-agents-hosting-core==1.4.0 (and siblings) installed, which is what CI resolves:

Check Result
mypy — azure-ai-agentserver-activity 11 files, 0 errors (was 2)
mypy — azure-ai-agentserver-core storage 14 files, 0 errors
pytest — activity 105 passed, 1 skipped (was 1 failed)
pytest — core 903 passed, 57 skipped
pylint 10.00/10

The two remaining core failures (test_otlp_protocol.py::test_otlp_protocol_exports_all_signals[grpc] and test_tracing.py::TestSetupDistroExport::test_managed_otlp_handles_mixed_signal_protocols) are pre-existing and unrelated — verified failing on a clean tree at this same base. Likewise the two pre-existing black violations in _state.py / _local_state.py; none of the reformatted lines are touched by this PR.

Follow-up (not in this PR)

The root cause is an uncapped transitive dependency. Worth considering an upper bound on the microsoft-agents-* pins so a minor upstream release can't turn main red with no repo change. An upstream issue for from_json_to_store_item returning Self would let us delete the remaining cast.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
9 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
9 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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.

Pull request overview

Fixes compatibility with microsoft-agents-hosting-core 1.4.0 by correcting storage typing and updating claims tests.

Changes:

  • Widens state-store payload types from dict to Mapping.
  • Aligns the M365 storage adapter with upstream typed interfaces.
  • Updates the deprecated authentication assertion and package metadata.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
CHANGELOG.md Documents the widened storage API.
storage/_state.py Widens public item payload parameters.
storage/_state_serializer.py Converts mappings at serialization boundaries.
storage/_local_state.py Supports mappings in local storage.
core/_version.py Bumps core to 2.1.0b3.
api.md Updates the documented API surface.
tests/test_bridge_turn.py Replaces the deprecated authentication assertion.
activity/_foundry_storage.py Corrects upstream interface typing.

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

….4.0

The `python - agentserver` CI pipeline started failing on main without any
repo change. `microsoft-agents-hosting-core` 1.4.0 (published 2026-08-18) is
picked up by the open-ended `>=1.1.0` pin and introduced two breaks:

1. The package added a `py.typed` marker. Previously mypy ran against it with
   `--ignore-missing-imports` and silently degraded `StoreItem` and friends to
   `Any`, so nothing was checked. With the marker present mypy now resolves the
   real signatures and surfaces two latent type errors in `FoundryStorage`.

2. `ClaimsIdentity.is_authenticated` became a deprecated computed property
   returning `bool(self.claims)`; the constructor argument is now a no-op.

Fixes:

- `FoundryStateStore.set_item()` / `create_item()` now accept
  `Mapping[str, JSONValue]` instead of a concrete `dict`. The payload is only
  serialized, never mutated, so the narrower type rejected valid callers such
  as M365 `StoreItem.store_item_to_json()` (a `MutableMapping`). Widening a
  parameter is backward compatible for existing callers. The same widening is
  applied to `LocalStateStoreBackend` and the two `serialize_item_*` helpers,
  which materialize a `dict` at the wire boundary.
- `FoundryStorage._write_item` no longer narrows its parameter to `StoreItemT`,
  matching the `AsyncStorageBase` signature (the TypeVar bought nothing and the
  narrowing violated LSP).
- `FoundryStorage._read_item` casts the deserialized item, since
  `StoreItem.from_json_to_store_item` is annotated `-> StoreItem` upstream and
  does not narrow through `type[StoreItemT]`.
- `test_claims_authenticated_with_empty_bot_app_id_has_empty_claims` asserts on
  `authentication_type` and the claim values rather than the now-deprecated
  `is_authenticated`.
- Bumped `azure-ai-agentserver-core` to 2.1.0b3 so `_version.py` matches the new
  unreleased changelog entry, per repo convention (the changelog verifier
  otherwise treats the already-released 2.1.0b2 entry as the build under
  validation and rejects its date).

Verified with `microsoft-agents-hosting-core==1.4.0` installed: mypy clean on
both packages, activity 105 passed, core 903 passed. The two remaining core
failures (`test_otlp_protocol`, `test_tracing`) are pre-existing and unrelated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@shanmukha1200
Shanmukha Pasumarthy (shanmukha1200) force-pushed the spasumarthy/agentserver-storage-typing-fix branch from b2667d9 to 374cd58 Compare August 21, 2026 03:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Hosted Agents sdk/agentserver/*

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants