Skip to content

[CI only] validate PR #10202 review fixes (temporary) - #3

Closed
simin-yuan wants to merge 19 commits into
mainfrom
fix/filesystem-store-enametoolong-r2
Closed

simin-yuan wants to merge 19 commits into
mainfrom
fix/filesystem-store-enametoolong-r2

Conversation

@simin-yuan

Copy link
Copy Markdown
Owner

Temporary PR to run the upstream pull_request workflows on the same commit (b2fd616) in this fork, while the runs on microsoft/agent-framework await maintainer approval. No code changes beyond PR microsoft#10202; this PR will be closed once the runs finish.

westey-m and others added 19 commits November 9, 2026 10:29
…li version (microsoft#10156)

* Require minimum compatible copilot cli version

* Address PR comments
…osoft#10185)

* docs: keep consumer skills focused on development choices

* docs: allow removal-first cleanup of stale skill details
* .NET: clarify Harness client API selection

* docs: correct Harness research project endpoint setup

* docs: align Harness Step02 and Step03 project endpoint setup

* docs: replace Harness API guidance with a short client-choice note

Per review, the Harness README now only says that a harness runs on the
IChatClient you choose, points to the model providers page for feature
differences, and notes that the samples use Responses on Foundry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Avoid a conflict with GitHub Copilot CLI commands.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a207b899-3a71-4334-a1df-1c20c8af684f
…imit (microsoft#9907)

MemoryFileStore.search_transcripts appended a match and only then checked
whether it had reached the limit, so limit=0 (and any negative limit)
returned exactly one result instead of none. The limit is passed through
unchanged by the search_memory_transcripts tool, so a model supplying 0
silently got a single row.

Short-circuit before scanning when limit <= 0. Adds a regression test
covering limit=0 and a negative limit.

Co-authored-by: lisry-1 <249596828+lisry-1@users.noreply.github.com>
…SS client (microsoft#9911)

* Python: fix(mem0): do not forward unset user_id/agent_id as None to OSS client

after_run unconditionally passed both user_id and agent_id as direct
kwargs to the OSS AsyncMemory client, even though _validate_filters
permits configuring only one of them. When a user configured only
user_id (agent_id=None), add() received agent_id=None and crashed the
run after the model had already produced a reply.

Match the Platform path (_build_filters), which only includes non-empty
identity fields.

* test(mem0): cover agent-only OSS identity configuration

Parameterize the omit-unset-identity test to exercise both user-only and
agent-only configurations, asserting the configured identity is forwarded
and the other key is absent.

---------

Co-authored-by: lisry-1 <249596828+lisry-1@users.noreply.github.com>
…url (microsoft#9968)

* Python: Report the injected Mistral SDK client's endpoint in service_url

Mistral chat and embedding clients kept MISTRAL_SERVER_URL (or an explicit
server_url) in self.server_url when an SDK client was injected. Requests
still went to the injected client's endpoint, so service_url() and the
telemetry metadata reported the wrong server.

An injected mistralai.client.Mistral now always defines server_url.

Fixes microsoft#9965

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Clarify server_url docstring for injected Mistral SDK client

server_url is only ignored when a Mistral SDK client is injected. The
deprecated httpx.AsyncClient path via `client` still uses it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Read only the model setting when a Mistral SDK client is injected

An injected SDK client owns its credentials and endpoint, so the chat and
embedding clients no longer resolve MISTRAL_API_KEY or MISTRAL_SERVER_URL
for it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Use the regular Mistral settings types for an injected SDK client

Drop MistralChatModelSettings and MistralEmbeddingModelSettings. The
injected path loads MistralSettings / MistralEmbeddingSettings with
relaxed required fields and ignores the api_key and server_url values,
as requested in review.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…d Claude (microsoft#10003)

Co-authored-by: 123XieC <123XieC@users.noreply.github.com>
…ext (microsoft#10039)

* fix(redis): escape RediSearch query syntax in memory search text

RedisContextProvider passed the user's message straight into TextQuery /
AggregateHybridQuery as the search text. RediSearch reads several
punctuation marks as query syntax there — '|' unions terms, '?' is a fuzzy
marker, backticks quote exact phrases — so ordinary messages like
'ps aux | grep python' or 'Why ?' reached the engine as malformed grammar
(e.g. '@content:(ps | aux | | | grep | python)') and raised a syntax error
that failed the whole agent run; the model was never called.

Escape the search text with a TokenEscaper configured for the RediSearch
syntax characters before building either query. Spaces stay unescaped, so
the terms keep tokenizing and BM25 scoring works as before. Tag filter
values were already escaped through _vector_store's escaper; only the
free-text path was exposed.

Fixes microsoft#10002

* fix(redis): drop redis search syntax chars instead of double escaping

redisvl's TextQuery escapes every term itself: _tokenize_and_escape_query
runs the default TokenEscaper per token, and that escaper also escapes the
backslash a hand-escaped term already carries. The pre-escaped '|' from the
TokenEscaper built here therefore landed as a literal backslash-pipe that
was re-escaped again — the produced query still carried the bare '|', so
'ps aux | grep python' stayed broken, and tokens like 'v1.2' picked up a
backslash that changed BM25 matching.

Instead of escaping, strip the syntax characters redisvl's escaper does not
cover ('|', '?', backtick) and rejoin the remaining tokens as plain terms;
TextQuery then tokenizes and escapes each of them again as designed.

Suggested-by: Aman Agnihotri <163747435+its-amann@users.noreply.github.com>

---------

Co-authored-by: wxhking <186391338+wxhking@users.noreply.github.com>
…SE streaming responses (microsoft#10112)

* Python: fix(devui): omit connection-specific keep-alive header from SSE streaming responses

Remove the Connection: keep-alive header from both DevUI SSE streaming
responses in _server.py. RFC 9113 section 8.2.2 forbids connection-specific
header fields in HTTP/2 and HTTP/3, and HTTP/1.1 connections remain
persistent by default. Gateway and proxy handlers serving DevUI over HTTP/2
will no longer reject or strip malformed connection headers.

Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>

* Python: test(devui): add regression tests verifying absence of Connection header in streaming responses

Add regression tests in test_server.py ensuring both the local executor and OpenAI proxy streaming responses omit the connection-specific Connection header while preserving Cache-Control and X-Response-ID.

Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>

* Python: test(core): restore state type registry after registered child tag test

test_registered_child_tag_does_not_hijack_message_payload registered custom TextState with type_id=text into the global _STATE_TYPE_REGISTRY without cleaning it up. When run in the same test process before session deserialization tests that encounter text Content mappings, the lingering registration caused deserialization failures. Clean up the registered state type in a finally block.

Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>

---------

Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
…soft#10168)

Co-authored-by: lxcxjxhx <lxcxjxhx@users.noreply.github.com>
…t#10169)

Co-authored-by: lxcxjxhx <lxcxjxhx@users.noreply.github.com>
microsoft#10170)

Co-authored-by: lxcxjxhx <lxcxjxhx@users.noreply.github.com>
…ng file

On Windows without long-path support, FileSystemAgentFileStore.write() reported a path
that merely exceeded the OS limit as FileNotFoundError, which reads as a missing file
and sends callers looking for a bug in their own path handling.

The limit is now used only to explain an error the OS already raised: when write() fails
and a prefix of the path that is still inside the limit exists, the failure is re-raised
as OSError(errno.ENAMETOOLONG), chained to the original error. Paths are never rejected
up front, so a host with long-path support keeps its current behaviour and every
in-limit path is untouched. Directories use the 248-character directory limit, files the
260-character one.

The within-bound half of test_filesystem_store_matches_in_memory_complexity_bound now
expects ENAMETOOLONG on a Windows host with long paths disabled. New tests cover both
call sites with a pinned platform flag, check that unrelated FileNotFoundErrors still
propagate unchanged, and check that a path past the limit is still written and read when
the host supports long paths.

Fixes microsoft#10141
Count Windows path limits in UTF-16 code units instead of Python code
points, restrict the ENAMETOOLONG rewrite to FileNotFoundError so
collisions and permission failures keep their own types, and size the
regression test's file name from the temporary directory so the path
always crosses MAX_PATH.
@simin-yuan simin-yuan closed this Nov 10, 2026
@simin-yuan simin-yuan reopened this Nov 10, 2026
@simin-yuan simin-yuan closed this Nov 10, 2026
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.