generate_image_with_alt
Defined in dapp/app/lib/mcp/tools/image-generate-workflow.ts, this tool centralizes OpenAI image creation and the client-side delivery contract.
Pipeline Highlights
- Input schema — accepts a
promptplus an optionalname. Sizes/quality are fixed byaiServerConfig.image.defaultsto keep runtime predictable. - Generation —
callOpenAIImageis the sole generator path today; it enforces the OpenAI provider and falls back to fetching the signed URL whenb64_jsonis absent. - Alt Text —
generateAltTextuses the configured vision provider (openaiorlmstudio) so every image ships with accessible copy even though the pixels never touch disk. - Streaming — the handler pushes JSON first (
{ kind: 'store-image', name, width, height, dataBase64 }) and then the<img src="store://...">text segment so hydrators can populate caches before the transcript renders.
Image Delivery
Images generated by tools are never stored server-side. The workflow (image-generate-workflow.ts) streams a base64 payload through SSE, marks it with kind: 'store-image', and inserts a placeholder <img src="store://image/..."> tag in the text portion. The client’s hydration hook writes the data into memory so parseContentWithMedia.ts can render it inline.
// dapp/app/lib/mcp/tools/image-generate-workflow.ts
const imageGenerateWorkflow: Tool<Params> = {
name: 'generate_image_with_alt',
description: 'Generate an image and emit a store:// payload + alt text.',
async handler({ prompt, name }) {
const { pngBase64, w, h } = await callOpenAIImage(prompt);
const alt = await generateAltText(`data:image/png;base64,${pngBase64}`);
const fileName = uniqueName(name);
const json = jsonResult({
kind: 'store-image',
name: fileName,
mime: 'image/png',
width: w,
height: h,
alt,
dataBase64: pngBase64,
});
const text = textResult(
`<img src="store://image/${fileName}" alt="${alt.replace(/"/g, '"')}" width="${w}" height="${h}" />`,
);
return { content: [...json.content, ...text.content] };
},
};Presenter Behavior
dapp/components/chatBot/ToolActivity/catalog/presenters/generate_image_with_alt.presenter.ts keeps the UI minimal:
| Status | Label | Details |
|---|---|---|
| pending | Generating image… | No body text; indicates the tool is still queueing. |
| success | Image ready | Shows name (width×height) when available so the user knows what asset arrived. |
| error | Image failed | Surfaces the raw error text (e.g., provider outage) for quick troubleshooting. |
Ties to the Frontend
useHydrateToolImages.ts listens for the { kind: 'store-image' } JSON emitted by this tool. That hook writes the base64 bytes into the useLocalImageStore, so the <img src="store://image/..."> tag rendered in the chat stream resolves instantly without another network hop.