opencode-see-image 0.7.0 → 0.8.0

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 +47 -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 }> = []
@@ -231,8 +272,6 @@ async function seeImageViaSDK(
231
272
  candidates.push({ providerID: "opencode-go", modelID: "minimax-m3" })
232
273
  candidates.push({ providerID: "opencode", modelID: "big-pickle" })
233
274
 
234
- const errors: string[] = []
235
-
236
275
  for (const { providerID, modelID } of candidates) {
237
276
  let sessionID: string | undefined
238
277
  try {
@@ -298,8 +337,12 @@ async function seeImageViaSDK(
298
337
  }
299
338
  }
300
339
 
340
+ const errMsg = errors.join("; ")
341
+ const hint = errMsg.includes("usage limit")
342
+ ? ` Enable usage from your balance at https://opencode.ai/workspace/wrk_01KVARG0A0Y87XV5JYBNJ0WRXB/go`
343
+ : ""
301
344
  throw new Error(
302
- `see_image: SDK vision call failed for all candidates. ${errors.join("; ")}`,
345
+ `see_image: SDK vision call failed for all candidates. ${errMsg}.${hint}`,
303
346
  )
304
347
  }
305
348
 
@@ -439,6 +482,7 @@ const SeeImagePlugin: Plugin = async (ctx) => {
439
482
  resolved.mediaType,
440
483
  prompt,
441
484
  context.abort,
485
+ context.sessionID,
442
486
  )
443
487
  }
444
488
 
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.0",
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",