@blockrun/clawrouter 0.12.25 → 0.12.26

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.
package/dist/cli.js CHANGED
@@ -3,6 +3,9 @@
3
3
  // src/proxy.ts
4
4
  import { createServer } from "http";
5
5
  import { finished } from "stream";
6
+ import { homedir as homedir4 } from "os";
7
+ import { join as join5 } from "path";
8
+ import { mkdir as mkdir3, writeFile as writeFile2, readFile, stat as fsStat } from "fs/promises";
6
9
  import { createPublicClient as createPublicClient2, http as http2 } from "viem";
7
10
  import { base as base2 } from "viem/chains";
8
11
  import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
@@ -5032,6 +5035,7 @@ ${lines.join("\n")}`;
5032
5035
  // src/proxy.ts
5033
5036
  var BLOCKRUN_API = "https://blockrun.ai/api";
5034
5037
  var BLOCKRUN_SOLANA_API = "https://sol.blockrun.ai/api";
5038
+ var IMAGE_DIR = join5(homedir4(), ".openclaw", "blockrun", "images");
5035
5039
  var AUTO_MODEL = "blockrun/auto";
5036
5040
  var ROUTING_PROFILES = /* @__PURE__ */ new Set([
5037
5041
  "blockrun/free",
@@ -5813,6 +5817,81 @@ async function startProxy(options) {
5813
5817
  res.end(JSON.stringify({ object: "list", data: models }));
5814
5818
  return;
5815
5819
  }
5820
+ if (req.url?.startsWith("/images/") && req.method === "GET") {
5821
+ const filename = req.url.slice("/images/".length).split("?")[0].replace(/[^a-zA-Z0-9._-]/g, "");
5822
+ if (!filename) {
5823
+ res.writeHead(400);
5824
+ res.end("Bad request");
5825
+ return;
5826
+ }
5827
+ const filePath = join5(IMAGE_DIR, filename);
5828
+ try {
5829
+ const s = await fsStat(filePath);
5830
+ if (!s.isFile()) throw new Error("not a file");
5831
+ const ext = filename.split(".").pop()?.toLowerCase() ?? "png";
5832
+ const mime = { png: "image/png", jpg: "image/jpeg", jpeg: "image/jpeg", webp: "image/webp", gif: "image/gif" };
5833
+ const data = await readFile(filePath);
5834
+ res.writeHead(200, { "Content-Type": mime[ext] ?? "application/octet-stream", "Content-Length": data.length });
5835
+ res.end(data);
5836
+ } catch {
5837
+ res.writeHead(404, { "Content-Type": "application/json" });
5838
+ res.end(JSON.stringify({ error: "Image not found" }));
5839
+ }
5840
+ return;
5841
+ }
5842
+ if (req.url === "/v1/images/generations" && req.method === "POST") {
5843
+ const chunks = [];
5844
+ for await (const chunk of req) {
5845
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
5846
+ }
5847
+ const reqBody = Buffer.concat(chunks);
5848
+ try {
5849
+ const upstream = await payFetch(`${apiBase}/v1/images/generations`, {
5850
+ method: "POST",
5851
+ headers: { "content-type": "application/json", "user-agent": USER_AGENT },
5852
+ body: reqBody
5853
+ });
5854
+ const text = await upstream.text();
5855
+ if (!upstream.ok) {
5856
+ res.writeHead(upstream.status, { "Content-Type": "application/json" });
5857
+ res.end(text);
5858
+ return;
5859
+ }
5860
+ let result;
5861
+ try {
5862
+ result = JSON.parse(text);
5863
+ } catch {
5864
+ res.writeHead(200, { "Content-Type": "application/json" });
5865
+ res.end(text);
5866
+ return;
5867
+ }
5868
+ if (result.data?.length) {
5869
+ await mkdir3(IMAGE_DIR, { recursive: true });
5870
+ const port2 = server.address()?.port ?? 8402;
5871
+ for (const img of result.data) {
5872
+ const m = img.url?.match(/^data:(image\/\w+);base64,(.+)$/);
5873
+ if (m) {
5874
+ const [, mimeType, b64] = m;
5875
+ const ext = mimeType === "image/jpeg" ? "jpg" : mimeType.split("/")[1] ?? "png";
5876
+ const filename = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}.${ext}`;
5877
+ await writeFile2(join5(IMAGE_DIR, filename), Buffer.from(b64, "base64"));
5878
+ img.url = `http://localhost:${port2}/images/${filename}`;
5879
+ console.log(`[ClawRouter] Image saved \u2192 ${img.url}`);
5880
+ }
5881
+ }
5882
+ }
5883
+ res.writeHead(200, { "Content-Type": "application/json" });
5884
+ res.end(JSON.stringify(result));
5885
+ } catch (err) {
5886
+ const msg = err instanceof Error ? err.message : String(err);
5887
+ console.error(`[ClawRouter] Image generation error: ${msg}`);
5888
+ if (!res.headersSent) {
5889
+ res.writeHead(502, { "Content-Type": "application/json" });
5890
+ res.end(JSON.stringify({ error: "Image generation failed", details: msg }));
5891
+ }
5892
+ }
5893
+ return;
5894
+ }
5816
5895
  if (req.url?.match(/^\/v1\/(?:x|partner)\//)) {
5817
5896
  try {
5818
5897
  await proxyPartnerRequest(req, res, apiBase, payFetch);