Skip to content

fix(agent): validate context/memory tool schemas before wrapping (#47707) - #52140

Merged
kshitijk4poor merged 1 commit into
mainfrom
salvage/47707-tool-schema-validation
Jun 24, 2026
Merged

fix(agent): validate context/memory tool schemas before wrapping (#47707)#52140
kshitijk4poor merged 1 commit into
mainfrom
salvage/47707-tool-schema-validation

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

One malformed tool schema from a context engine or memory provider no longer disables the entire toolset with an HTTP 400 from strict providers like DeepSeek.

Root cause

agent_init.py wrapped each schema from get_tool_schemas() as {"type": "function", "function": _schema} without validating that _schema has a top-level name. A provider returning an already-wrapped entry ({"type":"function","function":{...}}) would be double-wrapped into a nameless tool. Strict providers reject the entire request with tools[N].function: missing field name (HTTP 400), breaking every turn.

Changes

  • agent/memory_manager.py: shared normalize_tool_schema() helper that unwraps already-wrapped entries and returns None for nameless schemas. Wired into all 4 call sites: agent_init context-engine loop + 3 memory_manager surfaces (inject_memory_provider_tools, add_provider routing, get_all_tool_schemas)
  • agent/agent_init.py: uses normalize_tool_schema() in the context-engine tool injection loop
  • tests/agent/test_memory_provider.py: 9 new tests (unwrap, skip-nameless, non-dict, non-string-name, good+bad alongside, real injection path)

Validation

  • 9 new tests pass
  • Clean cherry-pick, no conflicts

Salvaged from #47712 by @Bartok9.

Closes #47707

Closes #47707

Context engines and memory providers expose tool schemas via
get_tool_schemas(). agent_init.py wrapped each as
{"type":"function","function":_schema} without validating that
_schema carries a top-level name. A provider returning an entry already
in OpenAI tool form ({"type":"function","function":{...}}) was then
double-wrapped into a tool whose function has no name. Strict providers
(e.g. DeepSeek) reject the entire request with HTTP 400
'tools[N].function: missing field name', so one malformed schema
silently disables the whole toolset and breaks every turn. The schema
was also never added to valid_tool_names, so even lenient providers
could not call it.

Add a shared normalize_tool_schema() helper that unwraps an
already-wrapped entry and returns None for anything lacking a resolvable
string name. Wire it into the agent_init context-engine loop and all
three memory_manager surfaces (inject_memory_provider_tools,
add_provider routing index, get_all_tool_schemas), so a single bad
plugin schema is skipped with a warning instead of poisoning the
request.

Verification: 209 targeted agent/memory tests pass (incl. 9 new).
New tests assert the unwrap + skip-nameless behavior and fail without
the fix.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: salvage/47707-tool-schema-validation vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11197 on HEAD, 11197 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5916 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@kshitijk4poor
kshitijk4poor enabled auto-merge June 24, 2026 20:57
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists labels Jun 24, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: this is a salvage of #47712 (@Bartok9) for issue #47707, which has a saturated competing-fix cluster: #47712 (same files/scope), #47721 (context-engine-only), #47732 (unwrap variant), #48065 (agent_init.py-only subset). #49437 was already closed as a dup of #47712. Flagging for a maintainer to pick the canonical PR; the normalize_tool_schema fix is not yet on main.

@Bartok9

Bartok9 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Thanks for the triage map @alt-glitch — happy to consolidate. Quick case for this one as canonical:

Salvaged from #47712. If a maintainer prefers I rebase onto a different base or fold in anything from #47732's variant, glad to do it.

@kshitijk4poor
kshitijk4poor merged commit cedbb4c into main Jun 24, 2026
48 of 50 checks passed
@kshitijk4poor
kshitijk4poor deleted the salvage/47707-tool-schema-validation branch June 24, 2026 21:06
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…-tool-schema-validation

fix(agent): validate context/memory tool schemas before wrapping (NousResearch#47707)
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…-tool-schema-validation

fix(agent): validate context/memory tool schemas before wrapping (NousResearch#47707)
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…-tool-schema-validation

fix(agent): validate context/memory tool schemas before wrapping (NousResearch#47707)
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…-tool-schema-validation

fix(agent): validate context/memory tool schemas before wrapping (NousResearch#47707)
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…-tool-schema-validation

fix(agent): validate context/memory tool schemas before wrapping (NousResearch#47707)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Context-engine/memory-provider tool schemas are wrapped without validating a top-level name — one malformed schema 400s the entire request

3 participants