@anionex/dsh-vision-toolkit 0.1.31 → 0.1.32
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/README.md +6 -8
- package/README.zh.md +6 -8
- package/lib/image-input-variants.js +72 -22
- package/lib/image-input-variants.js.map +1 -1
- package/lib/plugin-update.js +8 -1
- package/lib/plugin-update.js.map +1 -1
- package/lib/runtime.js +12 -9
- package/lib/runtime.js.map +1 -1
- package/lib/types/image-input-variants.d.ts.map +1 -1
- package/lib/types/plugin-update.d.ts.map +1 -1
- package/lib/types/runtime.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/image-input-variants.ts +74 -21
- package/src/plugin-update.ts +8 -1
- package/src/runtime.ts +12 -9
package/src/plugin-update.ts
CHANGED
|
@@ -822,6 +822,13 @@ export class VisionToolkitPluginUpdateService {
|
|
|
822
822
|
profile: ProfileInstall,
|
|
823
823
|
pnpmPath: string,
|
|
824
824
|
): Promise<CommandResult> {
|
|
825
|
+
// Windows batch shims cannot be spawned directly; route them through cmd.exe.
|
|
826
|
+
const program = this.platform === 'win32' && /\.(?:cmd|bat)$/i.test(pnpmPath)
|
|
827
|
+
? process.env.COMSPEC ?? 'cmd.exe'
|
|
828
|
+
: pnpmPath
|
|
829
|
+
const argv = program === pnpmPath
|
|
830
|
+
? [pnpmPath, ...args]
|
|
831
|
+
: [program, '/d', '/s', '/c', pnpmPath, ...args]
|
|
825
832
|
const controller = new AbortController()
|
|
826
833
|
let timedOut = false
|
|
827
834
|
const timeout = setTimeout(() => {
|
|
@@ -830,7 +837,7 @@ export class VisionToolkitPluginUpdateService {
|
|
|
830
837
|
}, timeoutMs)
|
|
831
838
|
try {
|
|
832
839
|
const handle = this.ctx.subprocess.spawn({
|
|
833
|
-
argv
|
|
840
|
+
argv,
|
|
834
841
|
cwd: profile.profileDir,
|
|
835
842
|
stdio: {
|
|
836
843
|
stdin: 'ignore',
|
package/src/runtime.ts
CHANGED
|
@@ -56,7 +56,9 @@ const VISION_MODEL_TEST_IMAGE = fileURLToPath(new URL('../assets/vision-model-te
|
|
|
56
56
|
const VISION_MODEL_TEST_PROMPT = 'This is an explicit service readiness test. Reply with one short sentence confirming that you received the image.'
|
|
57
57
|
|
|
58
58
|
/** Bump when the Pillow compression ladder changes so stale cache entries are ignored. */
|
|
59
|
-
const COMPRESSED_IMAGE_CACHE_VERSION = '
|
|
59
|
+
const COMPRESSED_IMAGE_CACHE_VERSION = 'v2'
|
|
60
|
+
/** Cache keys carry 64-bit digests so Windows paths stay below MAX_PATH; the full file sha256 is computed on read and compared against this prefix. */
|
|
61
|
+
const COMPRESSED_IMAGE_CACHE_KEY_DIGEST_LENGTH = 16
|
|
60
62
|
const COMPRESSED_IMAGE_CACHE_MAX_ENTRIES = 200
|
|
61
63
|
const COMPRESSED_IMAGE_CACHE_MAX_BYTES = 512 * 1024 * 1024
|
|
62
64
|
const COMPRESSED_IMAGE_CACHE_STALE_PARTIAL_MS = 60 * 60 * 1000
|
|
@@ -883,7 +885,7 @@ export class VisionToolkitRuntime {
|
|
|
883
885
|
private async readCacheCandidate(
|
|
884
886
|
root: string,
|
|
885
887
|
name: string,
|
|
886
|
-
|
|
888
|
+
expectedOutDigestPrefix: string,
|
|
887
889
|
maxBytes: number,
|
|
888
890
|
maxPixels: number,
|
|
889
891
|
operation: OperationContext,
|
|
@@ -909,7 +911,8 @@ export class VisionToolkitRuntime {
|
|
|
909
911
|
} catch {
|
|
910
912
|
return undefined
|
|
911
913
|
}
|
|
912
|
-
|
|
914
|
+
const digest = createHash('sha256').update(bytes).digest('hex')
|
|
915
|
+
if (bytes.length !== info.size || !digest.startsWith(expectedOutDigestPrefix)) return undefined
|
|
913
916
|
let probed: { width: number; height: number; format: string } | undefined
|
|
914
917
|
try {
|
|
915
918
|
probed = await this.adapter.probeImageSize(real, { signal: operation.signal })
|
|
@@ -929,7 +932,7 @@ export class VisionToolkitRuntime {
|
|
|
929
932
|
|
|
930
933
|
private cacheEntryOutDigest(entry: string, prefix: string): string | undefined {
|
|
931
934
|
const tail = entry.slice(prefix.length + 1)
|
|
932
|
-
return /^[0-9a-f]{
|
|
935
|
+
return /^[0-9a-f]{16}-/u.test(tail) ? tail.slice(0, 16) : undefined
|
|
933
936
|
}
|
|
934
937
|
|
|
935
938
|
private async pruneCompressedCache(root: string): Promise<void> {
|
|
@@ -997,21 +1000,21 @@ export class VisionToolkitRuntime {
|
|
|
997
1000
|
if (bytes.length !== image.bytes) {
|
|
998
1001
|
throw new VisionToolkitError('input', `image changed while preparing the vision request: ${image.path}`)
|
|
999
1002
|
}
|
|
1000
|
-
const digest = createHash('sha256').update(bytes).digest('hex')
|
|
1003
|
+
const digest = createHash('sha256').update(bytes).digest('hex').slice(0, COMPRESSED_IMAGE_CACHE_KEY_DIGEST_LENGTH)
|
|
1001
1004
|
const root = await this.compressedImageRoot(policy)
|
|
1002
1005
|
await this.pruneCompressedCache(root)
|
|
1003
1006
|
const prefix = `${COMPRESSED_IMAGE_CACHE_VERSION}-${digest}-b${this.config.maxImageBytes}-p${this.config.maxImagePixels}`
|
|
1004
1007
|
for (const entry of await readdir(root)) {
|
|
1005
1008
|
if (!entry.startsWith(`${prefix}-`) || entry.startsWith('.')) continue
|
|
1006
|
-
const
|
|
1007
|
-
if (
|
|
1009
|
+
const outDigestPrefix = this.cacheEntryOutDigest(entry, prefix)
|
|
1010
|
+
if (outDigestPrefix === undefined) {
|
|
1008
1011
|
await rm(join(root, entry), { force: true }).catch(() => {})
|
|
1009
1012
|
continue
|
|
1010
1013
|
}
|
|
1011
1014
|
const cached = await this.readCacheCandidate(
|
|
1012
1015
|
root,
|
|
1013
1016
|
entry,
|
|
1014
|
-
|
|
1017
|
+
outDigestPrefix,
|
|
1015
1018
|
this.config.maxImageBytes,
|
|
1016
1019
|
this.config.maxImagePixels,
|
|
1017
1020
|
operation,
|
|
@@ -1037,7 +1040,7 @@ export class VisionToolkitRuntime {
|
|
|
1037
1040
|
}
|
|
1038
1041
|
const extension = compressed.format === 'jpeg' ? 'jpg' : compressed.format
|
|
1039
1042
|
const stagedBytes = await readFile(staged, { signal: operation.signal })
|
|
1040
|
-
const outDigest = createHash('sha256').update(stagedBytes).digest('hex')
|
|
1043
|
+
const outDigest = createHash('sha256').update(stagedBytes).digest('hex').slice(0, COMPRESSED_IMAGE_CACHE_KEY_DIGEST_LENGTH)
|
|
1041
1044
|
const finalName = `${prefix}-${outDigest}-${compressed.width}x${compressed.height}.${extension}`
|
|
1042
1045
|
const finalPath = join(root, finalName)
|
|
1043
1046
|
const existing = await this.readCacheCandidate(
|