package agents import ( "bytes" "context" "encoding/base64" "encoding/json" "fmt" "os" "os/exec" "path/filepath" "strings" "time" "g.fc.run/ai/byre/internal/mcp" ) func (m *Manager) renderDiagramTool() mcp.Tool { return mcp.Tool{ Name: "render_diagram", Description: "See a diagram as byre's app draws it in the transcript: pass the body of a ```diagram block and get back a PNG of the result, drawn by the app's own renderer in light mode. " + "A source the app can't draw comes back as the reason instead.", InputSchema: json.RawMessage(`{ "type": "object", "properties": { "source": {"type": "string", "description": "The block's body, without the fence lines."} }, "required": ["source"] }`), Rich: func(ctx context.Context, raw json.RawMessage) mcp.Result { args := struct { Source string `json:"source"` }{} err := json.Unmarshal(raw, &args) if err != nil { return mcp.TextResult(fmt.Sprintf("malformed render_diagram call: %v", err), true) } png, err := renderDiagram(ctx, args.Source) if err != nil { return mcp.TextResult(err.Error(), true) } return mcp.Result{Content: []mcp.Content{{Type: "image", Data: base64.StdEncoding.EncodeToString(png), MimeType: "image/png"}}} }, } } func renderDiagram(ctx context.Context, source string) ([]byte, error) { exe, err := os.Executable() if err != nil { return nil, err } app := filepath.Join(filepath.Dir(exe), "..", "MacOS", "Byre") ctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() cmd := exec.CommandContext(ctx, app, "render-diagram") cmd.Stdin = strings.NewReader(source) stderr := bytes.Buffer{} cmd.Stderr = &stderr out, err := cmd.Output() if err != nil { return nil, fmt.Errorf("render diagram: %w: %s", err, strings.TrimSpace(stderr.String())) } return out, nil }