pi-banana 2.5.0 → 2.5.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.
@@ -20,7 +20,7 @@
20
20
 
21
21
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
22
22
  import { resolveProvider, openaiGenerateImage, openaiEditImage, openaiVision, sizeFor } from "./providers.ts";
23
- import { runBananaSetup } from "./wizard.ts";
23
+ import { runBananaSetup, configureBananaProvider } from "./wizard.ts";
24
24
  import { StringEnum } from "@earendil-works/pi-ai";
25
25
  import {
26
26
  Box,
@@ -250,6 +250,29 @@ export default function (pi: ExtensionAPI) {
250
250
  },
251
251
  });
252
252
 
253
+ pi.registerTool({
254
+ name: "banana_configure",
255
+ label: "Banana Configure",
256
+ description:
257
+ "Configure banana to generate images through an OpenAI-compatible provider (mantice) instead of Google. " +
258
+ "Probes the endpoint, auto-selects image models per quality tier, and saves the configuration. " +
259
+ "Call this when the user asks to set up or switch the image provider.",
260
+ promptSnippet: "Configure the banana image provider (mantice) non-interactively.",
261
+ parameters: Type.Object({
262
+ baseUrl: Type.String({ description: "OpenAI-compatible base URL, e.g. https://llm.fornace.net/v1" }),
263
+ apiKey: Type.Optional(Type.String({
264
+ description: "API key. Omit to reuse the mantice/google key already stored in pi credentials.",
265
+ })),
266
+ visionModel: Type.Optional(Type.String({
267
+ description: "Model for image analysis. Omit to auto-detect (e.g. fornace-vision).",
268
+ })),
269
+ }),
270
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
271
+ const report = await configureBananaProvider(ctx, params);
272
+ return { content: [{ type: "text", text: report }], details: {} };
273
+ },
274
+ });
275
+
253
276
  pi.registerTool({
254
277
  name: "banana_image",
255
278
  label: "Banana Image",
@@ -20,6 +20,53 @@ function pickDefault(candidates: string[], hint: RegExp): string | undefined {
20
20
  return candidates.find((m) => hint.test(m)) ?? candidates[0];
21
21
  }
22
22
 
23
+ export interface ConfigureOptions {
24
+ baseUrl: string;
25
+ apiKey?: string;
26
+ visionModel?: string;
27
+ }
28
+
29
+ /** Non-interactive provider configuration: resolves the key, probes the
30
+ * endpoint, auto-assigns quality tiers, and persists to settings.json.
31
+ * Returns a human-readable report. Used by banana_configure and the wizard. */
32
+ export async function configureBananaProvider(ctx: any, opts: ConfigureOptions): Promise<string> {
33
+ const baseUrl = opts.baseUrl.replace(/\/+$/, "");
34
+ let apiKey = opts.apiKey;
35
+ if (!apiKey && ctx?.modelRegistry) {
36
+ for (const p of ["mantice", "google"]) {
37
+ try {
38
+ apiKey = await ctx.modelRegistry.getApiKeyForProvider(p);
39
+ if (apiKey) break;
40
+ } catch { /* next */ }
41
+ }
42
+ }
43
+ if (!apiKey) apiKey = process.env.MANTICE_API_KEY;
44
+ if (!apiKey) throw new Error("No API key found: pass apiKey, log in via /login, or set MANTICE_API_KEY.");
45
+
46
+ const probe = await probeCapabilities(baseUrl, apiKey);
47
+ if (!probe.supportsImageGen || probe.imageModels.length === 0) {
48
+ throw new Error("Endpoint has no image generation models. Nothing was saved.");
49
+ }
50
+ const pick = (hint: RegExp, fallback?: string) =>
51
+ probe.imageModels.find((m) => hint.test(m)) ?? fallback ?? probe.imageModels[0];
52
+ const models = {
53
+ lite: pick(/lite|fast|turbo|mini/i),
54
+ fast: pick(/^(?!.*(lite|high|max|pro|ultra)).*$/i),
55
+ high: pick(/max|high|pro|ultra/i),
56
+ };
57
+ const visionModel = opts.visionModel ?? probe.visionModels[0];
58
+ persistBananaConfig({ baseUrl, apiKey, models, ...(visionModel ? { visionModel } : {}) });
59
+ return [
60
+ `Configured banana on ${baseUrl}:`,
61
+ ` lite = ${models.lite}`,
62
+ ` fast = ${models.fast}`,
63
+ ` high = ${models.high}`,
64
+ visionModel ? ` vision = ${visionModel}` : " vision = (google default kept)",
65
+ `Image edit endpoint: ${probe.supportsImageEdit ? "available" : "not available"}.`,
66
+ "banana_image and banana_vision now use this provider.",
67
+ ].join("\n");
68
+ }
69
+
23
70
  export async function runBananaSetup(ctx: any): Promise<void> {
24
71
  const ui = ctx.ui;
25
72
  ui.notify("Banana setup: configure an OpenAI-compatible image provider (mantice works).", "info");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-banana",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "Generate, edit, and analyze images in pi using Google Nano Banana (image gen) and Gemini Vision (analysis). Inline terminal preview, reference-image editing, auto-save.",
5
5
  "author": "Francesco Frapporti <effedue@gmail.com>",
6
6
  "license": "MIT",