Skip to content

馃泝 fix: Project Only Accepted Agents API Tool Calls - #16384

Merged
danny-avila merged 2 commits into
devfrom
lia/adopt-accepted-tool-projection
Sep 26, 2026
Merged

danny-avila merged 2 commits into
devfrom
lia/adopt-accepted-tool-projection

Conversation

@lia-by-librechat

Copy link
Copy Markdown
Contributor

Pull Request

Summary

The Agents API currently reconstructs OpenAI tool_calls from run-step declarations and fragments. Those events describe tools the graph may already have executed, so internal and provider-owned calls can leak into the terminal client response as instructions to execute again. This also keeps the endpoint coupled to provider fragment indexes instead of the graph's accepted result.

This PR switches the streaming and non-streaming Agents API handler assembly to the accepted-result projector published in @librechat/agents@3.9.6. Content, reasoning, usage, and internal host-tool execution handlers remain unchanged. Graph- and provider-owned calls stay internal; only calls carrying an explicit trusted client disposition can enter OpenAI tool_calls.

Related to #13987
Related to #16206
Depends on LibreChat-AI/agents#560

How it works

model and tool activity
  -> @librechat/agents graph acceptance + per-call disposition
  -> SDK accepted-result projector
  -> validated OpenAI tool_calls, or no client tool request

The previous local run-step projector remains exported for compatibility and focused contract tests, but createOpenAIHandlers no longer registers it. The endpoint now registers the SDK projector's graph-owned acceptance and claim handlers alongside LibreChat's existing content and usage handlers.

Type of change

  • Bug fix
  • Tests / tooling / CI

Testing

Tested environments/configuration:

  • Node 24 with @librechat/agents@3.9.6 from the current lockfile
  • Streaming and non-streaming OpenAI-compatible Agents API responses
  • Internal SDK tool execution followed by a final text answer
  • SDK-owned and provider-owned accepted calls
  • Explicit client-delegated accepted calls
  • Provider failure and late-event suppression

Automated tests:

  • cd packages/api && ../../node_modules/.bin/jest --runInBand --silent --coverage=false src/agents/openai/handlers.spec.ts src/agents/openai/service.spec.ts src/agents/openai/toolCalls.graph.spec.ts src/agents/openai/toolCalls.spec.ts src/agents/openai/toolCalls.contract.spec.ts
  • cd packages/api && ../../node_modules/.bin/tsc --noEmit
  • Touched-file ESLint with --max-warnings=0, import sorting, and Prettier
  • npm run build:api

Screenshots / recordings

No user-facing UI change.

Risk / compatibility

The Agents API no longer emits graph-internal tool calls inferred from run steps. Caller-supplied OpenAI tools remain outside this PR because the service does not yet bind request tool schemas or authorize client execution. The legacy projector stays exported; only the endpoint handler assembly changes.

Checklist

  • I reviewed my own changes
  • Relevant tests have been added or updated
  • Existing relevant tests pass
  • The change does not introduce new warnings or errors
  • User-facing or complex behavior is documented where necessary
  • Required dependency changes have been merged/published
  • Required documentation PR: N/A

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Exact pushed head: aafab0f2afe3e8d537d30514b1e16d36fb3469df

This head switches the Agents API handler assembly from run-step reconstruction to the accepted-result projector published in @librechat/agents@3.9.6. SDK- and provider-owned calls remain internal in both streaming and non-streaming responses; only an explicit trusted client disposition can produce OpenAI tool_calls. Content, reasoning, usage, host tool execution, failure aborts, and final response framing remain host-owned.

Verification on this head: 111 focused tests passed across the five Agents API handler/service/tool-call suites; packages/api tsc --noEmit, zero-warning touched-file ESLint, import sorting, Prettier, npm run build:api, and diff checks passed. A real SDK graph regression executes an internal tool, produces final text, and verifies no tool call reaches the client. CI is green except the production API smoke job, which is still running; skipped E2E/MCP matrix jobs were not selected for this backend-only diff. No live-provider request was run.

@danny-avila
danny-avila merged commit 24f950a into dev Sep 26, 2026
28 checks passed
@danny-avila
danny-avila deleted the lia/adopt-accepted-tool-projection branch September 26, 2026 15:10
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.

2 participants