u
This commit is contained in:
@@ -236,7 +236,7 @@ function extractImageInputs(args = {}) {
|
||||
|
||||
/**
|
||||
* Fetches a database image by its content hash using store or authenticated local endpoint.
|
||||
* @param {string} hash 64-char SHA-256 hex
|
||||
* @param {string} hash 8-char SHA-256 Base62
|
||||
* @param {number} googleAuthId
|
||||
* @returns {Promise<Buffer>}
|
||||
*/
|
||||
@@ -323,7 +323,7 @@ export function createAnalyzeImageTool({ googleAuthId, model }) {
|
||||
// ── Load the bytes ────────────────────────────────────────────
|
||||
const items = [];
|
||||
for (const item of inputs) {
|
||||
// Only a path that actually carries a 64-char content hash is a database image.
|
||||
// Only a path that actually carries an 8-char content hash is a database image.
|
||||
// A bare "images/…" prefix is just the VFS folder, so it must NOT be treated as
|
||||
// a DB lookup or `images/candidates/x.avif` would be misread as a hash path.
|
||||
const hash = extractFullHash(item.path);
|
||||
@@ -355,7 +355,7 @@ export function createAnalyzeImageTool({ googleAuthId, model }) {
|
||||
throw new ToolError(
|
||||
`Image not found or empty: "${item.path}". ` +
|
||||
(hash
|
||||
? 'Database images must be addressed as "image/<fullHash>" with a 64-char hash.'
|
||||
? 'Database images must be addressed as "image/<fullHash>" with an 8-char hash.'
|
||||
: 'Store it first (search_images writes to "images/…") or check the path with find_files.')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ function resolveImagesApiUrl() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a database image by its 64-char content hash using store or authenticated local endpoint.
|
||||
* Fetches a database image by its 8-char content hash using store or authenticated local endpoint.
|
||||
* @param {string} hash
|
||||
* @param {number} googleAuthId
|
||||
* @returns {Promise<Buffer>}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { getStore } from '../db/store.js';
|
||||
import env from '../config/env.js';
|
||||
import { getDefaultSkills } from './skill.js';
|
||||
|
||||
const FULL_HASH_REGEX = /^[a-fA-F0-9]{64}$/;
|
||||
const FULL_HASH_REGEX = /^[a-zA-Z0-9]{8}$/;
|
||||
const VIRTUAL_IMAGE_FOLDERS = new Set(['image', 'images']);
|
||||
|
||||
export function getMimeType(filePath) {
|
||||
@@ -55,18 +55,26 @@ export function getMimeType(filePath) {
|
||||
export function extractFullHash(p) {
|
||||
if (typeof p !== 'string' || !p.trim()) return null;
|
||||
const clean = p.trim().replace(/^vfs:\/+/i, '').replace(/^([a-zA-Z]:|\/)+/, '');
|
||||
const parts = clean.split('/');
|
||||
const parts = clean.split('/').filter(Boolean);
|
||||
if (parts.length === 0) return null;
|
||||
|
||||
const first = parts[0].toLowerCase();
|
||||
const last = parts[parts.length - 1];
|
||||
const ext = path.extname(last).toLowerCase();
|
||||
const withoutExt = last.replace(/\.[a-zA-Z0-9]+$/, '');
|
||||
if (FULL_HASH_REGEX.test(withoutExt)) {
|
||||
return withoutExt.toLowerCase();
|
||||
}
|
||||
for (const part of parts) {
|
||||
const seg = part.replace(/\.[a-zA-Z0-9]+$/, '');
|
||||
if (FULL_HASH_REGEX.test(seg)) {
|
||||
return seg.toLowerCase();
|
||||
|
||||
// Under virtual image folder (e.g. image/aB1cD2eF, images/aB1cD2eF.avif)
|
||||
if (VIRTUAL_IMAGE_FOLDERS.has(first)) {
|
||||
if (parts.length === 2 && FULL_HASH_REGEX.test(withoutExt)) {
|
||||
return withoutExt;
|
||||
}
|
||||
}
|
||||
|
||||
// Direct hash (e.g. "aB1cD2eF" or "aB1cD2eF.avif")
|
||||
if (parts.length === 1 && FULL_HASH_REGEX.test(withoutExt) && (!ext || ext === '.avif')) {
|
||||
return withoutExt;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user