JSPM

@vectorforge-ai/sdk

0.1.3
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q37793F
  • License MIT

Official Node.js/TypeScript SDK for VectorForge Cloud APIs

Package Exports

  • @vectorforge-ai/sdk
  • @vectorforge-ai/sdk/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@vectorforge-ai/sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

VectorForge Node SDK

Official TypeScript/Node.js client for VectorForge Cloud APIs.

VectorForge is a trust and confidence layer for AI and automations, providing:

  • DIVTs (Digital Integrity Verification Tokens) - Cryptographic "birth certificates" for data
  • AI Answer Confidence Scoring - Privacy-preserving and comprehensive scoring
  • Worldstate Logging - Immutable event capture for AI operations
  • Hybrid Post-Quantum Cryptography - ECDSA P-521 + ML-DSA-65 signatures

Installation

npm install @vectorforge-ai/sdk

From Source (Development)

git clone https://github.com/vectorforge/api
cd api/sdk/node
npm install
npm run build

For image support:

npm install sharp

Quick Start

Configuration

import { createVectorForgeClient } from '@vectorforge-ai/sdk';

// Option 1: Use environment variables (recommended)
// export VF_API_BASE_URL="https://api.vectorforge.ai"
// export VF_API_KEY="vf_prod_YourApiKeyHere"
const client = createVectorForgeClient();

// Option 2: Pass config directly
const client = createVectorForgeClient({
  baseUrl: "https://api.vectorforge.ai",
  apiKey: "vf_prod_YourApiKeyHere",
});

The SDK provides high-level methods that handle canonicalization and hashing automatically. These are the recommended way to use VectorForge.

Register Text Content

import { createVectorForgeClient } from '@vectorforge-ai/sdk';

const client = createVectorForgeClient();

const result = await client.registerContent(
  'prompt:123',
  'What is the capital of France?',
  'prompt_receipt_v1',
  { user_id: 'user-456', session: 'sess-789' }
);

console.log(`DIVT ID: ${result.divt_id}`);
console.log(`ECDSA signature: ${result.ecdsa_sig_b64.substring(0, 32)}...`);
console.log(`ML-DSA signature: ${result.ml_dsa_sig_b64.substring(0, 32)}...`);
console.log(`Ledger status: ${result.ledger_status}`);

What it does:

  1. Normalizes text (Unicode NFC, line endings, trim whitespace)
  2. Computes SHA3-512 hash
  3. Creates DIVT with hybrid post-quantum signatures
  4. Returns divt_id for future verification

Register JSON Data

const result = await client.registerJson(
  'rag_snapshot:v42',
  {
    snapshot_type: 'rag-corpus',
    doc_hashes: ['hash1', 'hash2'],
    index_hash: 'index_hash_value',
    timestamp: '2025-11-21T10:00:00Z',
  },
  'rag_snapshot_v1',
  { project: 'hr-assistant', env: 'prod' }
);

console.log(`RAG snapshot registered: ${result.divt_id}`);

What it does:

  1. Canonical JSON serialization (sorted keys, minimal whitespace)
  2. Computes SHA3-512 hash
  3. Creates DIVT

Register Embedding Vector

const result = await client.registerEmbedding(
  'chunk:doc-123:p5',
  [0.123456, -0.987654, 0.456789, ...],  // Your embedding vector
  'rag_chunk_v1',
  { document_id: 'doc-123', paragraph: 5 },
  6  // Decimal precision
);

console.log(`Embedding registered: ${result.divt_id}`);

What it does:

  1. Validates embedding (rejects NaN/Infinity)
  2. Formats with fixed precision for deterministic hashing
  3. Computes SHA3-512 hash
  4. Creates DIVT

Register Image

Requires: npm install sharp

import { readFile } from 'fs/promises';

const imageBuffer = await readFile('receipt.png');

const result = await client.registerImage(
  'image:receipt-456',
  imageBuffer,
  'image_receipt_v1',
  { source: 'mobile_app', user_id: 'user-789' },
  1024  // Max dimension
);

console.log(`Image registered: ${result.divt_id}`);

What it does:

  1. Decodes image (supports PNG, JPEG, WebP)
  2. Normalizes to sRGB color space
  3. Resizes if needed (preserves aspect ratio)
  4. Re-encodes as deterministic PNG
  5. Computes SHA3-512 hash
  6. Creates DIVT

Complete Example: Prompt Receipt with Verification

import { createVectorForgeClient } from '@vectorforge-ai/sdk';

const client = createVectorForgeClient();

// Register AI prompt + response
const promptData = {
  prompt: 'What is the capital of France?',
  response: 'Paris',
  model: 'gpt-4',
  timestamp: '2025-11-21T10:00:00Z',
};

const registerResult = await client.registerJson(
  'prompt_receipt:flow-abc-123',
  promptData,
  'prompt_receipt_v1',
  { workflow: 'customer_support' }
);

const divtId = registerResult.divt_id;
console.log(`✓ Prompt receipt registered: ${divtId}`);

// Later: Verify the prompt receipt
const verifyResult = await client.verifyJson(divtId, promptData);

if (verifyResult.verified) {
  console.log('✓ DIVT is valid');
  console.log(`  - Hash valid: ${verifyResult.hash_valid}`);
  console.log(`  - ECDSA signature valid: ${verifyResult.ecdsa_signature_valid}`);
  console.log(`  - ML-DSA signature valid: ${verifyResult.ml_dsa_signature_valid}`);
  console.log(`  - Object ID: ${verifyResult.object_id}`);
  console.log(`  - Created: ${verifyResult.created_at}`);
  console.log(`  - Ledger status: ${verifyResult.ledger_status}`);
} else {
  console.log('✗ DIVT verification failed');
  console.log(`  - Hash valid: ${verifyResult.hash_valid}`);
  console.log(`  - Revoked: ${verifyResult.revoked}`);
}

Low-Level API (Advanced)

For advanced use cases where you want to compute hashes yourself, use the low-level register() method:

import { canon } from '@vectorforge-ai/sdk';

// Compute hash manually
const text = 'Hello, World!';
const hashB64 = canon.hashContentV1(text);

// Register with pre-computed hash
const result = await client.register({
  object_id: 'doc-123',
  hash_mode: 'content',
  hash_version: 'content_v1',
  hash_b64: hashB64,
  data_type: 'prompt_receipt_v1',
});

Canonicalization Utilities

import { canon } from '@vectorforge-ai/sdk';

// Text canonicalization
const hashB64 = canon.hashContentV1('Hello, World!');

// JSON canonicalization
const hashB64 = canon.hashJsonV1({ key: 'value', nested: { a: 1 } });

// Embedding canonicalization
const hashB64 = canon.hashEmbeddingV1([0.1, 0.2, 0.3], 6);

// Image canonicalization (requires sharp)
const imageBuffer = await readFile('image.png');
const hashB64 = await canon.hashImageV1(imageBuffer, 1024);

// Or get canonical bytes without hashing
const canonicalBuffer = canon.canonicalizeContentV1('Hello');
const hashB64 = canon.sha3512Digest(canonicalBuffer);

Verification

Verify a Single DIVT

// Using hash_b64 (advanced)
const result = await client.verify({
  divt_id: '019abc12-3456-7890-abcd-ef0123456789',
  hash_b64: 'your-precomputed-hash-base64',
});

if (result.verified) {
  console.log('✓ DIVT is valid');
  console.log(`  - Hash valid: ${result.hash_valid}`);
  console.log(`  - ECDSA valid: ${result.ecdsa_signature_valid}`);
  console.log(`  - ML-DSA valid: ${result.ml_dsa_signature_valid}`);
  console.log(`  - Revoked: ${result.revoked}`);
} else {
  console.log('✗ DIVT verification failed');
}

Verify with High-Level Helpers

// Verify text content
const result = await client.verifyContent(divtId, 'Hello, World!');

// Verify JSON data
const result = await client.verifyJson(divtId, { key: 'value' });

Bundle API

Get comprehensive verification bundles for DIVTs including worldstate context and scoring results.

Get Bundle by DIVT ID

const bundle = await client.getBundle({
  divt_id: '019abc12-3456-7890-abcd-ef0123456789',
});

console.log('DIVT Verification:');
console.log(`  - Verified: ${bundle.divt.verified}`);
console.log(`  - Hash valid: ${bundle.divt.hash_valid}`);
console.log(`  - Ledger status: ${bundle.divt.ledger_status}`);

console.log(`Worldstate events: ${bundle.worldstate.length}`);
console.log(`Scoring events: ${bundle.scoring.length}`);
console.log(`Generated at: ${bundle.generated_at}`);

Get Bundle by Object ID

const bundle = await client.getBundle({
  object_id: 'prompt_receipt:flow-abc-123',
  include_history: true,
});

Scoring API

Privacy Score (No Raw Content Sent)

const result = await client.scorePrivacy({
  query_id: 'query-123',
  answer_id: 'answer-456',
  evidence: [
    {
      object_id: 'chunk:doc-1:p1',
      divt_id: '019abc...',
      tenant_id: 'my-tenant',
      similarity: 0.95,
      chunk_confidence: 0.9,
    },
  ],
});

console.log(`Overall confidence: ${result.overall_confidence}`);
console.log(`Semantic confidence: ${result.semantic_confidence}`);
console.log(`Integrity score: ${result.integrity_score}`);
console.log(`Verified count: ${result.verified_count}/${result.vector_count}`);

Full Score (With Groq Judge)

const result = await client.scoreFull({
  query: 'What is the capital of France?',
  answer: 'The capital of France is Paris.',
  evidence: [
    {
      object_id: 'chunk:doc-1:p1',
      divt_id: '019abc...',
      tenant_id: 'my-tenant',
      text: 'Paris is the capital city of France.',
      similarity: 0.95,
    },
  ],
  options: {
    log_worldstate: 'minimal',
  },
});

console.log(`Overall confidence: ${result.overall_confidence}`);
console.log(`Support score: ${result.support_score}`);
console.log(`Faithfulness score: ${result.faithfulness_score}`);

Worldstate Read

Get Single Worldstate Record

// Get worldstate record metadata
const item = await client.getWorldstateItem({
  wsl_id: '019abc12-3456-7890-abcd-ef0123456789',
});

console.log(`Kind: ${item.kind}`);
console.log(`Timestamp: ${item.timestamp}`);
console.log(`Ledger status: ${item.ledger_status}`);
console.log(`Summary: ${item.data_summary}`);

// Get worldstate record with full data from S3
const itemWithData = await client.getWorldstateItem({
  wsl_id: '019abc12-3456-7890-abcd-ef0123456789',
  include_data: true,
});

console.log('Full data:', itemWithData.data);

List Worldstate Records

// List all records
const result = await client.listWorldstate();
console.log(`Found ${result.count} records`);

// List with filters
const promptReceipts = await client.listWorldstate({
  kind: 'prompt_receipt',
  created_from: '2025-11-01T00:00:00Z',
  created_to: '2025-11-30T23:59:59Z',
  limit: 50,
});

// Paginate through all results
let cursor = promptReceipts.cursor;
while (cursor) {
  const page = await client.listWorldstate({ cursor });
  for (const item of page.items) {
    console.log(`${item.wsl_id}: ${item.data_summary}`);
  }
  cursor = page.cursor;
}

Available Filters:

  • kind: Filter by event type (prompt_receipt, scoring_event, rag_snapshot, etc.)
  • created_from: Start of time range (ISO 8601)
  • created_to: End of time range (ISO 8601)
  • limit: Page size (max 100, default 50)
  • cursor: Pagination cursor from previous response

Stream Events (SSE)

const oneHourAgo = new Date(Date.now() - 3600000).toISOString();

await client.streamEvents(
  {
    since: oneHourAgo,
    types: ['divt_registered', 'scoring_event'],
    limit: 50,
  },
  (event) => {
    console.log(`[${event.type}] ${event.id} at ${event.timestamp}`);
  }
);

Error Handling

import { VectorForgeAPIError } from '@vectorforge-ai/sdk';

try {
  const result = await client.registerContent(
    'doc-123',
    'Hello, World!',
    'prompt_receipt_v1'
  );
} catch (error) {
  if (error instanceof VectorForgeAPIError) {
    console.error(`API Error: ${error.message}`);
    console.error(`Status: ${error.statusCode}`);
    console.error(`Code: ${error.error}`);
    if (error.details) {
      console.error(`Details: ${error.details}`);
    }
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Common Error Codes:

  • invalid_api_key (401) - API key invalid or expired
  • quota_exceeded (429) - Monthly request limit reached
  • rate_limit_exceeded (429) - Too many requests
  • plan_limitation (403) - Feature not available on your plan
  • network_error (0) - Network connectivity issue

Type Support

Full TypeScript support with type definitions:

import type {
  RegisterInput,
  RegisterResult,
  VerifyInput,
  VerifyResult,
  BundleInput,
  BundleResult,
  PrivacyScoreInput,
  FullScoreInput,
  ScoreResult,
  StreamEventsInput,
  StreamEvent,
} from '@vectorforge-ai/sdk';

Integration Tests

To run integration tests against the live API:

export VF_API_BASE_URL="https://api.vectorforge.ai"
export VF_API_KEY="your-api-key"
npm test

Requirements

  • Node.js: >= 18.0.0 (uses native fetch)
  • Dependencies:
    • js-sha3 (SHA3-512 hashing)
  • Optional:
    • sharp >= 0.33.0 (for image registration)


Support


License

MIT © VectorForge