@anionex/dsh-vision-toolkit 0.1.37 → 0.1.38

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/src/runtime.ts CHANGED
@@ -16,6 +16,7 @@ import { SaxesParser } from 'saxes'
16
16
  import { describeArtifact, type ArtifactDescriptor } from './artifacts.ts'
17
17
  import { isBuiltInFreeVisionProvider, type ResolvedVisionToolkitConfig } from './config.ts'
18
18
  import { BUILT_IN_FREE_VISION_KEY } from './defaults.ts'
19
+ import { evidenceRuntimeFingerprint } from './evidence-cache.ts'
19
20
  import { VisionToolkitError } from './errors.ts'
20
21
  import {
21
22
  assertDistinctOutput,
@@ -480,6 +481,12 @@ export interface ToolCallOptions {
480
481
  sessionScope?: object
481
482
  }
482
483
 
484
+ /** One immutable vision-service snapshot used to generate cache-keyed evidence. */
485
+ export interface CapturedEvidenceRuntime {
486
+ readonly evidenceFingerprint: string
487
+ glance(request: GlanceRequest, options: ToolCallOptions): Promise<GlanceResult>
488
+ }
489
+
483
490
  interface GlanceCacheEntry {
484
491
  key: string
485
492
  result: GlanceResult
@@ -698,6 +705,25 @@ export class VisionToolkitRuntime {
698
705
  return this.adapter.versionInfo
699
706
  }
700
707
 
708
+ /** Stable identity for persisted image descriptions produced by this runtime. */
709
+ get evidenceFingerprint(): string {
710
+ return evidenceRuntimeFingerprint(this.config, undefined, process.env.VISION_SSL_VERIFY?.trim())
711
+ }
712
+
713
+ /** Capture the credential and provider identity used by one evidence conversion. */
714
+ async captureEvidenceRuntime(): Promise<CapturedEvidenceRuntime> {
715
+ const env = await this.resolveVisionEnv()
716
+ const evidenceFingerprint = evidenceRuntimeFingerprint(
717
+ this.config,
718
+ createHash('sha256').update(env.VISION_API_KEY).digest('hex'),
719
+ env.VISION_SSL_VERIFY,
720
+ )
721
+ return Object.freeze({
722
+ evidenceFingerprint,
723
+ glance: (request: GlanceRequest, options: ToolCallOptions) => this.glanceWithEnv(request, options, env),
724
+ })
725
+ }
726
+
701
727
  private timeout(options: ToolCallOptions): number {
702
728
  const value = options.timeoutMs ?? this.config.timeoutMs
703
729
  if (!Number.isInteger(value) || value < 1000 || value > MAX_TIMEOUT_MS) {
@@ -1213,6 +1239,14 @@ export class VisionToolkitRuntime {
1213
1239
 
1214
1240
  /** glance: describe, targeted QA, OCR, or multi-image comparison. */
1215
1241
  async glance(request: GlanceRequest, options: ToolCallOptions): Promise<GlanceResult> {
1242
+ return this.glanceWithEnv(request, options)
1243
+ }
1244
+
1245
+ private async glanceWithEnv(
1246
+ request: GlanceRequest,
1247
+ options: ToolCallOptions,
1248
+ capturedEnv?: UpstreamEnvironment,
1249
+ ): Promise<GlanceResult> {
1216
1250
  return this.runOperation('vision_glance', options, async (operation) => {
1217
1251
  if (request.images.length === 0) throw new VisionToolkitError('input', 'glance requires at least one image')
1218
1252
  if (request.query !== undefined && request.ocr === true) {
@@ -1235,7 +1269,7 @@ export class VisionToolkitRuntime {
1235
1269
  this.accountImage(image, operation)
1236
1270
  images.push(image)
1237
1271
  }
1238
- const env = await this.resolveVisionEnv()
1272
+ const env = capturedEnv ?? await this.resolveVisionEnv()
1239
1273
  const cacheKey = options.sessionScope === undefined
1240
1274
  ? undefined
1241
1275
  : await this.glanceCacheKey(request, images, env, operation.signal)