Skip to content

feat: image generation verifier#15

Open
think-in-universe wants to merge 4 commits intomainfrom
feat/image-generation-verifier
Open

feat: image generation verifier#15
think-in-universe wants to merge 4 commits intomainfrom
feat/image-generation-verifier

Conversation

@think-in-universe
Copy link
Contributor

@think-in-universe think-in-universe commented Jan 22, 2026

Features

  • verifier for image generation API
  • verifier for image generation with end-to-end encryption enabled

How to Verify

Set up environment variables

export BASE_URL=<cloud-api-url> (e.g. https://cloud-api.near.ai)
export API_KEY=<your-api-key>

Verify with TypeScript scripts

# install dependencies
pnpm i
# verify non-encrypted image generation
pnpm run image
# verify encrypted image generation
pnpm run encrypted-image

Verify with Python scripts

# install dependencies
pip install -r requirements.txt
# verify non-encrypted image generation
python3 py/image_verifier.py
# verify encrypted image generation
python3 py/encrypted_image_verifier.py

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds image generation verification capabilities to the NEAR AI Cloud verifier tool, implementing both standard signature verification and end-to-end encrypted image generation. The changes introduce new TypeScript and Python implementations that follow the existing patterns established by the chat verifier.

Changes:

  • Added image generation verifier for both TypeScript and Python with signature and attestation verification
  • Added encrypted image generation verifier supporting both ECDSA and Ed25519 encryption algorithms
  • Refactored encryption utilities into shared modules (encryption_utils.ts and encryption_utils.py) to reduce code duplication
  • Updated encrypted_chat_verifier to use the shared encryption utilities
  • Added npm scripts for running image and encrypted-image verifiers
  • Extended README with comprehensive documentation for image generation verification

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
ts/image_verifier.ts New TypeScript implementation for verifying signed image generation responses
ts/encrypted_image_verifier.ts New TypeScript implementation for testing end-to-end encryption in image generation
ts/encryption_utils.ts New shared encryption utilities extracted from encrypted_chat_verifier
ts/encrypted_chat_verifier.ts Refactored to use shared encryption utilities from encryption_utils module
py/image_verifier.py New Python implementation for verifying signed image generation responses
py/encrypted_image_verifier.py New Python implementation for testing end-to-end encryption in image generation
py/encryption_utils.py New shared encryption utilities extracted from encrypted_chat_verifier
py/encrypted_chat_verifier.py Refactored to use shared encryption utilities from encryption_utils module
package.json Added 'image' and 'encrypted-image' npm scripts
README.md Added documentation for image generation verifier and encrypted image generation verifier

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +106 to +115
except requests.exceptions.HTTPError as e:
print(f"✗ Request failed: {e}")
if e.response is not None:
print(f" Status code: {e.response.status_code}")
try:
error_detail = e.response.json()
print(f" Error detail: {json.dumps(error_detail, indent=2)}")
except Exception as e:
print(f"✗ Failed to parse error detail: {e}")
print(f" Response text: {e.response.text[:200]}")
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable shadowing: the exception variable 'e' on line 113 shadows the outer 'e' from line 106. On line 115, when accessing e.response.text, this refers to the inner exception from the JSON parsing, not the HTTPError. Consider renaming the inner exception variable to avoid confusion, e.g., except Exception as parse_error:

Suggested change
except requests.exceptions.HTTPError as e:
print(f"✗ Request failed: {e}")
if e.response is not None:
print(f" Status code: {e.response.status_code}")
try:
error_detail = e.response.json()
print(f" Error detail: {json.dumps(error_detail, indent=2)}")
except Exception as e:
print(f"✗ Failed to parse error detail: {e}")
print(f" Response text: {e.response.text[:200]}")
except requests.exceptions.HTTPError as http_error:
print(f"✗ Request failed: {http_error}")
if http_error.response is not None:
print(f" Status code: {http_error.response.status_code}")
try:
error_detail = http_error.response.json()
print(f" Error detail: {json.dumps(error_detail, indent=2)}")
except Exception as parse_error:
print(f"✗ Failed to parse error detail: {parse_error}")
print(f" Response text: {http_error.response.text[:200]}")

Copilot uses AI. Check for mistakes.
async def main():
"""Run example verification of image generation."""
parser = argparse.ArgumentParser(description="Verify NEAR AI Cloud Signed Image Generation Responses")
parser.add_argument("--model", default="Qwen/Qwen-Image")
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default model in Python implementation is "Qwen/Qwen-Image", but the TypeScript implementation uses "black-forest-labs/FLUX.2-klein-4B". All documentation in README.md refers to the FLUX model. Consider aligning the Python default with the TypeScript implementation for consistency.

Suggested change
parser.add_argument("--model", default="Qwen/Qwen-Image")
parser.add_argument("--model", default="black-forest-labs/FLUX.2-klein-4B")

Copilot uses AI. Check for mistakes.
parser = argparse.ArgumentParser(
description="Test End-to-End Encryption for NEAR AI Cloud Image Generation"
)
parser.add_argument("--model", default="Qwen/Qwen-Image")
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default model is "Qwen/Qwen-Image", but it should be "black-forest-labs/FLUX.2-klein-4B" to match the TypeScript implementation at ts/encrypted_image_verifier.ts:222 and all documentation in README.md.

Suggested change
parser.add_argument("--model", default="Qwen/Qwen-Image")
parser.add_argument("--model", default="black-forest-labs/FLUX.2-klein-4B")

Copilot uses AI. Check for mistakes.
* (Used by non-streaming examples and attestation key fetch.)
*/
export async function makeRequest(url: string, options: any = {}): Promise<any> {
return await new Promise((resolve, reject) => {
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The await keyword is unnecessary here since new Promise already returns a Promise. Remove the await to simplify the code: return new Promise((resolve, reject) => {

Suggested change
return await new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {

Copilot uses AI. Check for mistakes.
const req = client.request(requestOptions, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk.toString();
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The explicit .toString() call is inconsistent with the existing pattern in the codebase. Both chat_verifier.ts:66 and image_verifier.ts:73 use data += chunk; without calling .toString(). Consider removing .toString() for consistency: data += chunk;

Suggested change
data += chunk.toString();
data += chunk;

Copilot uses AI. Check for mistakes.
}

const payload: ImageGenerationResponse = response;
const imageId = payload.id || 'unknown';
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If payload.id is missing, the code sets imageId to 'unknown' and continues, but this will cause verifyImage to fail when it tries to fetch the signature. Consider checking for a valid id and returning early, similar to the pattern in image_verifier.ts lines 246-250.

Suggested change
const imageId = payload.id || 'unknown';
if (!payload.id) {
console.log('✗ Response is missing image ID; cannot verify image.');
return;
}
const imageId = payload.id;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants