Skip to content

fix(openaicompletions): recover leaked DSML tool calls safely - #4851

Merged
lyingbug merged 2 commits into
Tencent:mainfrom
lyingbug:fix/dsml-tool-call-recovery
Oct 28, 2026
Merged

lyingbug merged 2 commits into
Tencent:mainfrom
lyingbug:fix/dsml-tool-call-recovery

Conversation

@lyingbug

Copy link
Copy Markdown
Collaborator

Description

Some OpenAI-compatible endpoints return a DSML function_calls block in content with finish_reason=stop. The agent then displays protocol markup and stops instead of invoking tools. Recover complete trailing DSML blocks in both streaming and non-streaming completions, using the tools enabled by the current request.

  • Preserve plain-text preambles and handle markers split across stream chunks, including full-width and ASCII bars.
  • Leave Markdown examples, undeclared or disabled tools, incomplete envelopes, malformed parameters, and abnormal completion endings unchanged. Respect named tool choices and disabled parallel calls.
  • Prefer native tool_calls when both representations are present, avoiding duplicate execution.
  • Preserve JSON integers and decimals without converting them through float64.

Recovery is conservative: ambiguous or partially parsed content remains text. No configuration or public API changes.

Type of Change

  • 🐛 Bug fix
  • 🧪 Test

Related Issue

Related to #2798, which addresses leaked DSML with rejection and retry.

Testing

  • 37 response scenarios, each exercised through both Chat and ChatStream using local HTTP/SSE fixtures.
  • Confirmed the quoted-example, malformed-parameter, duplicate-call, and integer-precision regressions fail against the original implementation in both response modes, then pass with this fix.
  • go test ./internal/models/... ./internal/agent/...
  • go vet and go test over all 148 CI application packages, excluding /docreader/ as in app.yml.
  • Server build: go build -o <temporary-directory>/server ./cmd/server.
  • golangci-lint run --new-from-rev=github_public/main ./... — 0 issues.
  • git diff --check github_public/main...HEAD

Checklist

  • Diff whitespace check passes
  • Changed Go files are formatted
  • Targeted and application tests pass
  • Diff-scoped lint passes
  • Broader checks and their scope are recorded above
  • Self-reviewed the code
  • Added regression coverage
  • Documentation considered; no configuration or public API documentation changes needed
  • No breaking changes

Screenshots / Recordings

Not applicable; backend-only change.

- Added a new `dsmlFilter` to manage and extract DSML tool calls from streamed content, ensuring that native tool-call syntax does not disrupt user-facing responses.
- Introduced `extractDSMLToolCalls` function to parse DSML calls and return structured data while preserving malformed markup visibility.
- Enhanced the `parseResponse` and `processStream` methods to integrate DSML handling, updating finish reasons accordingly.
- Created unit tests for DSML extraction and filtering to validate functionality and ensure robustness against various input scenarios.

(cherry picked from commit 4294bcc3aefbe4cbf1c8ec81d148e2bc5d0efdd5)
@lyingbug
lyingbug marked this pull request as ready for review October 28, 2026 15:19
@lyingbug
lyingbug merged commit bb73a15 into Tencent:main Oct 28, 2026
4 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.

1 participant