fix(agent): stop fabricating empty message content - #2678
Open
1688mengdie wants to merge 1 commit into
Open
Conversation
The Text arm of `impl From<Message> for AIMessage` injected a synthetic placeholder for empty text to avoid sending empty content to the provider: empty user text became "(empty message)", empty system became "You are a helpful assistant.", and any other empty text became a single space. The model then treated these fabricated strings as a real user utterance or a system directive. The fabricated value also defeats the downstream converters' existing empty-content handling (openai/gemini filter out empty content, anthropic skips an empty system message), because a non-empty fabricated string bypasses the filter. The Mixed arm already produces None for empty text and is the correct in-file precedent to reuse. Return None for empty text in the Text arm instead, keeping the existing warn! diagnostic. Nothing synthetic reaches the provider, the empty-content semantics of the converters apply, and the normal non-empty path is unchanged. Test: added 4 behavioral cases (empty user/system/assistant to None, and non-empty text preserved) in message.rs; agentic::core::message::tests pass. AI: generated with review; verified with `cargo test -p bitfun-core --features agent-runtime --jobs 4` (message.rs tests green; one unrelated pre-existing coordinator test still fails on the clean baseline).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The Text arm of
impl From<Message> for AIMessageinjected a synthetic placeholderfor empty text to avoid sending empty content to the provider: empty user text became
"(empty message)", empty system text became"You are a helpful assistant.", andany other empty text became a single space. The model then treated these fabricated
strings as a real user utterance or a system directive.
Root cause
The "avoid empty content" defensive intent was implemented by injecting a non-empty
synthetic token, which defeats the downstream converters' existing empty-content
handling (openai/gemini filter out empty content, anthropic skips an empty system
message) because a non-empty fabricated string bypasses those filters. The Mixed arm
already returns
Nonefor empty text and is the correct in-file precedent to reuse;the Text arm did not.
Fix
Return
Nonefor empty text in the Text arm instead of fabricating a placeholder,keeping the existing
warn!diagnostic. Nothing synthetic reaches the provider, theconverters' empty-content semantics apply, and the normal non-empty path is unchanged.
No new helper or configuration is introduced.
Testing
message.rs: empty user/system/assistant text becomesNone; non-empty text is preserved.cargo test -p bitfun-core --features agent-runtime --jobs 4-message::testsgreen(9 passed); one unrelated pre-existing coordinator test still fails on the clean
baseline.
Closes #2675
Commit list:
cc7e90846fix(agent): stop fabricating empty message content- message.rs Text armplaceholder -> None; adds 4 behavioral tests.