Flutter's generateStructured() overrides the caller's system prompt; other SDKs don't
Follow-up from #840 by @ayaangazali -- thanks again for that PR!
What
Now that includeSchemaInPrompt actually gets set, RunAnywhereStructuredOutput.generateWithStructuredOutput (bindings/flutter/packages/runanywhere/lib/public/extensions/runanywhere_structured_output.dart:92-94) runs commons' preparePrompt and unconditionally replaces effectiveOptions.systemPrompt with the generic JSON-generator prompt it returns, dropping any caller-supplied LLMOptions.systemPrompt. Flutter's canonical RunAnywhere.llm.generateStructured goes through this wrapper, so it now silently loses the caller's system prompt. Swift and Kotlin canonical llm.generateStructured (and React Native's) never call preparePrompt and keep the caller's system prompt intact -- only the Swift and Web wrapper facades override it the same way Flutter now does.
Why it matters
A Flutter app that sets a custom system prompt (persona, tone, domain instructions) and then calls RunAnywhere.llm.generateStructured will have that prompt silently discarded in favor of commons' generic structured-output prompt, while the same call in Swift/Kotlin/RN keeps it. That's an unexpected, undocumented cross-SDK behavior difference.
Suggested approach
Either join the caller's system prompt with the prepared one in every SDK wrapper that calls preparePrompt (Flutter, Swift wrapper, Web), or move schema rendering into commons (see the companion issue) so canonical and wrapper paths behave identically everywhere.
Done when
- Flutter's
generateStructured/generateWithStructuredOutputpreserves a caller-supplied system prompt whenincludeSchemaInPromptis set, or the cross-SDK behavior difference is explicitly documented as intentional. - The same check is done for the Swift and Web wrapper facades that call
preparePrompt.
Not blocking #840. @ayaangazali, you know this code well now -- you're welcome to take this one if you're interested.
Opened with help from Claude Code and Codex.
Reviewed with help from Claude Code and Codex.
Source: RunanywhereAI/runanywhere-sdks