claude-glm 1.3.1 → 1.3.2
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.
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
// Vision preprocessing: converts image blocks to text descriptions for non-vision models
|
|
2
|
+
import { createHash } from "crypto";
|
|
2
3
|
import type { AnthropicRequest } from "./types.js";
|
|
3
4
|
|
|
4
5
|
const DEFAULT_VISION_MODEL = "google/gemini-2.5-flash";
|
|
5
6
|
const DESCRIBE_PROMPT =
|
|
6
7
|
"Describe this image in granular detail — layout, text, colors, objects, spatial relationships, any code or data visible.";
|
|
7
8
|
|
|
9
|
+
// In-memory cache: hash of image data → description text
|
|
10
|
+
const descriptionCache = new Map<string, string>();
|
|
11
|
+
|
|
12
|
+
function imageKey(block: ImageBlock): string {
|
|
13
|
+
if (block.source.type === "url" && block.source.url) {
|
|
14
|
+
return "url:" + block.source.url;
|
|
15
|
+
}
|
|
16
|
+
// Hash first 2048 chars of base64 + length for a fast, collision-resistant key
|
|
17
|
+
const data = block.source.data;
|
|
18
|
+
return createHash("sha256").update(data.slice(0, 2048) + ":" + data.length).digest("hex");
|
|
19
|
+
}
|
|
20
|
+
|
|
8
21
|
interface ImageBlock {
|
|
9
22
|
type: "image";
|
|
10
23
|
source: { type: string; media_type: string; data: string; url?: string };
|
|
@@ -89,18 +102,29 @@ export async function preprocessImages(
|
|
|
89
102
|
|
|
90
103
|
if (tasks.length === 0) return;
|
|
91
104
|
|
|
92
|
-
|
|
105
|
+
// Split into cached hits and new images that need describing
|
|
106
|
+
const uncached = tasks.filter((t) => !descriptionCache.has(imageKey(t.block)));
|
|
107
|
+
const cached = tasks.length - uncached.length;
|
|
93
108
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
if (uncached.length > 0) {
|
|
110
|
+
console.log(`[ccx] Describing ${uncached.length} new image(s) via ${model} (${cached} cached)...`);
|
|
111
|
+
const descriptions = await Promise.all(
|
|
112
|
+
uncached.map((t) => describeImage(t.block, model, apiKey))
|
|
113
|
+
);
|
|
114
|
+
for (let i = 0; i < uncached.length; i++) {
|
|
115
|
+
descriptionCache.set(imageKey(uncached[i].block), descriptions[i]);
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
console.log(`[ccx] All ${tasks.length} image(s) served from cache`);
|
|
119
|
+
}
|
|
97
120
|
|
|
98
121
|
// Replace image blocks with text descriptions (reverse order to preserve indices)
|
|
99
122
|
for (let i = tasks.length - 1; i >= 0; i--) {
|
|
100
123
|
const { msg, idx } = tasks[i];
|
|
124
|
+
const desc = descriptionCache.get(imageKey(tasks[i].block))!;
|
|
101
125
|
msg.content[idx] = {
|
|
102
126
|
type: "text",
|
|
103
|
-
text: `[Image Description: ${
|
|
127
|
+
text: `[Image Description: ${desc}]`,
|
|
104
128
|
};
|
|
105
129
|
}
|
|
106
130
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-glm",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Cross-platform installer for Claude Code with Z.AI GLM models, multi-provider proxy, and dangerously-skip-permissions shortcuts. Run with: npx claude-glm",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|