Skip to content

fix: safely recover malformed tool arguments - #330

Draft
WASIDJ wants to merge 1 commit into
inngest:mainfrom
WASIDJ:agent/fix-deepseek-tool-json
Draft

WASIDJ wants to merge 1 commit into
inngest:mainfrom
WASIDJ:agent/fix-deepseek-tool-json

Conversation

@WASIDJ

@WASIDJ WASIDJ commented Aug 10, 2026

Copy link
Copy Markdown

Safely recovers malformed tool-call JSON string content and validates parsed arguments before any tool handler executes.

DeepSeek can return HTTP 200 tool calls whose function.arguments contain raw control characters, invalid JSON escapes from generated source code, or ambiguous structural errors even when strict tool calling uses the beta endpoint. The old parser either rejected safely recoverable string content or used a regular expression that misidentified nested JavaScript template literals.

The parser now follows a deliberately narrow path:

direct JSON.parse
  ├── valid → return unchanged
  └── invalid → preserve raw controls / invalid escapes
                  ↓
             structural backtick parsing
                  ├── valid → Zod parseAsync → handler
                  └── ambiguous → sanitized error, no handler

Raw U+0000–U+001F characters are encoded so the decoded string value is unchanged. Invalid JSON escapes such as \' or \d have only their backslash escaped, preserving the exact original characters. Unescaped quotes, missing separators, and malformed structure are not guessed at. Errors include only tool name, finish reason, argument length, category, and position.

This also closes a safety gap where Zod schemas were converted for provider requests but were not applied at runtime before local, Inngest, or MCP tool handlers.

Live beta-endpoint stress testing produced two malformed responses among six HTTP 200 tool_calls responses. The invalid-escape response is recovered byte-semantically by this patch; the ambiguous unescaped-quote response remains an error as intended.

Validation: 73/73 tests including both MCP transports, TypeScript, ESLint, package build, a full 36,341-character captured invalid-escape fixture, and a fresh 45,352-character real DeepSeek call after reinstall and restart.

Partially addresses #329.

Changelog

  • Safely recover generated source code from malformed tool-call JSON while rejecting ambiguous repairs
  • Validate tool arguments before executing handlers

DeepSeek can emit raw JSON control characters or invalid escapes inside generated source code even with strict tool calling. Preserve those string values without guessing at ambiguous JSON structure, report sanitized parser diagnostics, and validate tool inputs before handlers run.
@changeset-bot

changeset-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d57e8d8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@inngest/agent-kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

This branch has not been deployed

No deployments
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