Fix:robot image issues and add test cases#1815
Conversation
WalkthroughRobot chat now uses a pluggable message-content resolver, normalizes mixed message content for rendering, combines uploaded files into one outgoing message, derives conversation titles from extracted text, and adds coverage for the updated conversation and utility behavior. ChangesRobot chat content handling
Sequence Diagram(s)sequenceDiagram
participant MainVue as Main.vue
participant RobotChat as RobotChat.vue
participant Resolver as resolveChatMessageContent
participant MarkdownRenderer as MarkdownRenderer.vue
MainVue->>RobotChat: message-content-resolver prop
RobotChat->>Resolver: resolveMessageContent(message, context)
Resolver-->>RobotChat: normalized content
RobotChat->>MarkdownRenderer: renderable text or array content
MarkdownRenderer-->>RobotChat: sanitized HTML
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/plugins/robot/src/components/renderers/MarkdownRenderer.vue`:
- Around line 74-81: The content normalization in MarkdownRenderer.vue does not
handle primitive string array entries, so the new string[] path renders empty
for values like ['foo', 'bar']. Update the content-building logic in the
renderer’s props.message.content handling to recognize string items inside the
Array.isArray branch, alongside the existing item?.text and item?.content
extraction, so primitive strings are preserved before filtering and joining.
In `@packages/plugins/robot/src/Main.vue`:
- Around line 257-260: Non-agent messages are returning raw message.content,
which leaves restored multimodal attachments in the unsupported image_url shape
and causes them to be dropped by RobotChat. Update the non-assistant branch in
Main.vue so it normalizes any content items into the renderer-friendly image
form before returning, using the existing message.renderContent path as the
preferred source and mapping uploaded image_url entries into the img/image shape
expected by the renderer. Keep the fix localized to the message handling logic
around isAgentMessage, message.role, and the return fallback.
In `@packages/plugins/robot/test/utils/chat.utils.test.ts`:
- Around line 214-239: The regression test for mergeStringFields is using falsy
primitives, so it never exercises the truthy non-string preservation path.
Update the test in chat.utils.test.ts to use truthy non-string values in
mergeStringFields and verify they are not overwritten, while keeping a separate
assertion for mergeable object merging so both branches are covered. Use the
mergeStringFields helper and the existing test case structure to locate and
adjust the expectations.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 49ead49f-72b6-4a60-82fa-fc2a4ea69905
📒 Files selected for processing (6)
packages/plugins/robot/src/Main.vuepackages/plugins/robot/src/components/chat/RobotChat.vuepackages/plugins/robot/src/components/renderers/MarkdownRenderer.vuepackages/plugins/robot/src/composables/core/useConversation.tspackages/plugins/robot/test/composables/core/useConversation.test.tspackages/plugins/robot/test/utils/chat.utils.test.ts
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/plugins/robot/src/composables/core/useConversation.ts (1)
333-335: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winGuard empty title source before substring.
When there is no user message,
messageContentisundefined;extractMessageTextreturns'',JSON.stringify(undefined)returnsundefined, andcontentStr.substring(...)throws.Proposed fix
const messageContent = getActiveEngine()?.messages.value.find((item) => item.role === 'user')?.content - const contentStr = extractMessageText(messageContent) || JSON.stringify(messageContent) - updateTitle(currentId, contentStr.substring(0, 20)) + const contentStr = extractMessageText(messageContent) || JSON.stringify(messageContent) || '' + if (contentStr) { + updateTitle(currentId, contentStr.substring(0, 20)) + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/plugins/robot/src/composables/core/useConversation.ts` around lines 333 - 335, Guard the title source in useConversation before calling substring on contentStr. In the code that derives messageContent and contentStr, ensure you fall back to a non-empty string when getActiveEngine()?.messages.value has no user message, since extractMessageText and JSON.stringify(undefined) can both yield an unusable value. Update updateTitle to receive a safe string and only then apply substring, using the nearby messageContent/contentStr logic as the fix point.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/plugins/robot/src/Main.vue`:
- Around line 278-283: The `isGenerating` check in `Main.vue` treats only
`STATUS.FINISHED` as terminal, so agent loading stays visible for `error` and
`aborted` states. Update the logic around `isLastMessage`/`isGenerating` to
treat `STATUS.ERROR` and `STATUS.ABORTED` as terminal as well, and keep the
`AgentLoading` content filtered out whenever `context.status` is any
non-generating final state.
In `@packages/plugins/robot/src/utils/chat.utils.ts`:
- Around line 57-59: The extraction logic in chat.utils.ts only handles
RobotMessageContentType.Text, so Markdown text bubbles are dropped and become
empty. Update the helper that reads RobotRenderContentItem to treat
RobotMessageContentType.Markdown the same as Text, preserving its text/content
fallback when returning the rendered value.
---
Outside diff comments:
In `@packages/plugins/robot/src/composables/core/useConversation.ts`:
- Around line 333-335: Guard the title source in useConversation before calling
substring on contentStr. In the code that derives messageContent and contentStr,
ensure you fall back to a non-empty string when
getActiveEngine()?.messages.value has no user message, since extractMessageText
and JSON.stringify(undefined) can both yield an unusable value. Update
updateTitle to receive a safe string and only then apply substring, using the
nearby messageContent/contentStr logic as the fix point.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 99b22422-9701-40d8-aece-e82ebe6b773d
📒 Files selected for processing (7)
packages/plugins/robot/src/Main.vuepackages/plugins/robot/src/components/chat/RobotChat.vuepackages/plugins/robot/src/components/renderers/MarkdownRenderer.vuepackages/plugins/robot/src/composables/core/useConversation.tspackages/plugins/robot/src/types/chat.types.tspackages/plugins/robot/src/utils/chat.utils.tspackages/plugins/robot/test/utils/chat.utils.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/plugins/robot/src/components/chat/RobotChat.vue

English | 简体中文
PR
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
Background and solution
What is the current behavior?
Issue Number: N/A
What is the new behavior?
主要修复robot插件在消息渲染与图片上传场景下的交互问题,并补充对应测试用例,提升会话处理与多模态消息链路的稳定性。
主要改动
RobotChat消息解析逻辑,统一处理 Agent 消息、Markdown 文本及图片内容渲染。useConversation和chat.utils相关单元测试:1、useConversation 会话适配层
验证了会话状态暴露、消息管理、会话创建/切换、metadata 持久化、默认标题生成等核心行为,尤其补充了多模态消息场景下的标题提取逻辑,确保历史对话标题优先取首条用户文本而不是直接展示 JSON。
2、chat.utils 工具函数
补充了消息格式化、错误序列化、字符串字段合并、SSE 流解析、loading 清理、system prompt 注入等纯函数测试,覆盖普通文本、工具调用、多模态 text + image_url、异常输入容错等边界场景。
验证
pnpm --filter @opentiny/tiny-engine-plugin-robot testDoes this PR introduce a breaking change?
Other information
Summary by CodeRabbit