fix(vision): stop read_image from poisoning text-provider sessions

Image turns already get a vision-model description injected into the prompt,
but the agent kept calling read_image to "confirm" the pictures. Those tool
results carry base64 image parts that Goose persists, so every later turn
against the text-only chat provider failed with `unknown variant image_url`
before the agent could write the page. WeChat page requests therefore fell
through to the fail-closed delivery message.

Drop read_image for the turn whenever a vision model handles the images, say
so explicitly in the injected prompt, and teach the poison scan to recognise
tool image parts so already-polluted sessions rotate instead of failing again.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-22 10:40:12 +08:00
parent 4d12ea438b
commit ef4ce12bbf
9 changed files with 457 additions and 6 deletions
+13 -2
View File
@@ -85,7 +85,10 @@ import { resolveMindSpaceUserPublishDir } from './mindspace-runtime-config.mjs';
import {
buildPageDataCollectFailureText,
} from './mindspace-page-data-finish-guard.mjs';
import { conversationHasImageUrlContent } from './chat-image-turn-scope.mjs';
import {
conversationHasImageUrlContent,
conversationHasToolImageContent,
} from './chat-image-turn-scope.mjs';
export { buildWechatAgentPrompt };
@@ -2450,12 +2453,20 @@ export function createWechatMpService({
}
const payload = await readJsonResponse(response);
const conversation = Array.isArray(payload?.conversation) ? payload.conversation : [];
if (!conversationHasImageUrlContent(conversation)) {
const hasImageUrlContent = conversationHasImageUrlContent(conversation);
// REGRESSION GUARD: vision-turn-read-image-isolation — read_image leaves
// base64 image parts inside tool responses instead of image_url. Goose
// keeps them, so the next turn against a text-only chat provider fails
// before the agent can write any page.
const hasToolImageContent = conversationHasToolImageContent(conversation);
if (!hasImageUrlContent && !hasToolImageContent) {
return { sessionId, carriedSessionContent, rotated: false };
}
logger.warn?.('WeChat MP rotating image-polluted agent session before reply:', {
agentSessionId: sessionId,
conversationLength: conversation.length,
hasImageUrlContent,
hasToolImageContent,
});
const nextRoute = await ensureWechatAgentSession({
userId,