opencode-see-image 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.ts +48 -3
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -221,7 +221,48 @@ async function seeImageViaSDK(
221
221
  mediaType: string,
222
222
  prompt: string,
223
223
  abort?: AbortSignal,
224
+ currentSessionID?: string,
224
225
  ): Promise<{ text: string; model: string; provider: string }> {
226
+ const errors: string[] = []
227
+
228
+ // Try current session first (uses its existing model — free big-pickle, no new session needed)
229
+ if (currentSessionID) {
230
+ try {
231
+ const controller = new AbortController()
232
+ const timer = setTimeout(() => controller.abort(), TIMEOUT)
233
+ const result = await client.session.prompt({
234
+ path: { id: currentSessionID },
235
+ body: {
236
+ parts: [
237
+ { type: "file", mime: mediaType, url: dataUrl },
238
+ { type: "text", text: prompt },
239
+ ],
240
+ tools: {},
241
+ system:
242
+ "You are a vision assistant. Describe the image accurately and concisely. Answer with text only.",
243
+ },
244
+ signal: controller.signal,
245
+ })
246
+ clearTimeout(timer)
247
+
248
+ const parts = result.data?.parts ?? []
249
+ const text = (parts as any[])
250
+ .filter((p: any) => p.type === "text")
251
+ .map((p: any) => p.text)
252
+ .filter((t: any) => typeof t === "string" && t.length > 0)
253
+ .join("\n")
254
+ .trim()
255
+
256
+ if (text) {
257
+ return { text, model: "", provider: "current" }
258
+ }
259
+ errors.push(`current-session: no text in response`)
260
+ } catch (e: any) {
261
+ errors.push(`current-session: ${e?.message ?? e}`)
262
+ }
263
+ }
264
+
265
+ // Fallback: create new sessions with specific provider/model candidates
225
266
  const envProvider = process.env.SEE_IMAGE_PROVIDER
226
267
  const envModel = process.env.SEE_IMAGE_MODEL
227
268
  const candidates: Array<{ providerID: string; modelID: string }> = []
@@ -229,10 +270,9 @@ async function seeImageViaSDK(
229
270
  candidates.push({ providerID: envProvider, modelID: envModel })
230
271
  }
231
272
  candidates.push({ providerID: "opencode-go", modelID: "minimax-m3" })
273
+ candidates.push({ providerID: "opencode", modelID: "mimo-v2.5-free" })
232
274
  candidates.push({ providerID: "opencode", modelID: "big-pickle" })
233
275
 
234
- const errors: string[] = []
235
-
236
276
  for (const { providerID, modelID } of candidates) {
237
277
  let sessionID: string | undefined
238
278
  try {
@@ -298,8 +338,12 @@ async function seeImageViaSDK(
298
338
  }
299
339
  }
300
340
 
341
+ const errMsg = errors.join("; ")
342
+ const hint = errMsg.includes("usage limit")
343
+ ? ` Enable usage from your balance at https://opencode.ai/workspace/wrk_01KVARG0A0Y87XV5JYBNJ0WRXB/go`
344
+ : ""
301
345
  throw new Error(
302
- `see_image: SDK vision call failed for all candidates. ${errors.join("; ")}`,
346
+ `see_image: SDK vision call failed for all candidates. ${errMsg}.${hint}`,
303
347
  )
304
348
  }
305
349
 
@@ -439,6 +483,7 @@ const SeeImagePlugin: Plugin = async (ctx) => {
439
483
  resolved.mediaType,
440
484
  prompt,
441
485
  context.abort,
486
+ context.sessionID,
442
487
  )
443
488
  }
444
489
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-see-image",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "description": "Give non-vision opencode models the ability to see images/screenshots by routing them to a vision-capable model (MiniMax M3 via opencode-go by default).",
5
5
  "type": "module",
6
6
  "main": "index.ts",