gemini.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import { tool } from "@opencode-ai/plugin/tool"
  2. async function parseImageInput(input: string) {
  3. // Accepts file path ("./img.png") or data URL ("data:image/png;base64,...")
  4. if (input.startsWith("data:")) {
  5. const base64 = input.split(",")[1]
  6. const mime = input.substring(5, input.indexOf(";"))
  7. return { mime, base64 }
  8. }
  9. // Treat as file path
  10. const file = Bun.file(input)
  11. const arr = await file.arrayBuffer()
  12. const base64 = Buffer.from(arr).toString("base64")
  13. // Best-effort mime
  14. const mime = file.type || "image/png"
  15. return { mime, base64 }
  16. }
  17. export default tool({
  18. description: "Edit an image using Gemini. Pass file path or data URL.",
  19. args: {
  20. image: tool.schema.string().describe("File path or data URL"),
  21. prompt: tool.schema.string().describe("Edit instruction"),
  22. output: tool.schema.string().optional().describe("Output filename (default edited.png)"),
  23. },
  24. async execute(args, context) {
  25. const apiKey = process.env.GEMINI_API_KEY
  26. if (!apiKey) return "Set GEMINI_API_KEY in your environment"
  27. const { mime, base64 } = await parseImageInput(args.image)
  28. const res = await fetch(
  29. "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image-preview:generateContent",
  30. {
  31. method: "POST",
  32. headers: {
  33. "Content-Type": "application/json",
  34. "x-goog-api-key": apiKey,
  35. },
  36. body: JSON.stringify({
  37. inputs: [{ mimeType: mime, data: base64 }],
  38. contents: [{ parts: [{ text: args.prompt }]}],
  39. }),
  40. }
  41. )
  42. if (!res.ok) return `API error: ${await res.text()}`
  43. const json = await res.json()
  44. const b64 = json?.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data
  45. if (!b64) return "No image data returned"
  46. const out = args.output || "edited.png"
  47. await Bun.write(out, Buffer.from(b64, "base64"))
  48. return `Saved ${out}`
  49. },
  50. })