Skip to content

Feat/spatialwalk#2043

Open
plutoless wants to merge 21 commits intomainfrom
feat/spatialwalk
Open

Feat/spatialwalk#2043
plutoless wants to merge 21 commits intomainfrom
feat/spatialwalk

Conversation

@plutoless
Copy link
Contributor

No description provided.

@plutoless plutoless requested a review from halajohn as a code owner February 8, 2026 13:03
@claude
Copy link

claude bot commented Feb 8, 2026

Code Review PR 2043 - Spatialwalk Avatar Example Agent

Thank you for this substantial contribution adding 21,505 lines across 148 files. I conducted a thorough review focusing on code quality, security, performance, and best practices.

Critical Issues - Must Fix Before Merge

1. Hardcoded API Credentials in Version Control - HIGH SEVERITY

Location: ai_agents/agents/examples/spatialwalk-avatar/frontend/.env

The .env file contains a hardcoded Spatialwalk App ID being committed to the repository.
Risk: This credential is publicly exposed in the repository history.

Required Fix:

  • Remove the .env file from git tracking
  • Ensure .env is in .gitignore
  • Create .env.example with placeholder values
  • Document required environment variables in README

2. Missing Input Validation in API Route - HIGH SEVERITY

Location: frontend/src/app/api/agents/start/route.tsx:54

The API route forwards user input directly to backend without validation.

Risks:

  • Injection attacks through malicious payloads
  • Server-side request forgery SSRF
  • Denial of service through malformed data

Recommended: Add validation for request_id, channel_name, user_uid, graph_name, and properties fields with type checking and regex patterns.

3. Improper Error Handling Exposes System Details

Location: frontend/src/app/api/agents/start/route.tsx:54

Issues:

  • Throwing strings instead of Error objects
  • Generic error messages could leak configuration details

Recommended: Use proper error responses with appropriate status codes.

High Priority Issues

4. Type Safety - Excessive Use of any

Multiple files in frontend/src/common/ use liberal any types defeating TypeScript type checking.
Recommended: Define proper interfaces with specific types.

5. Potential Memory Leak in Avatar Component

Location: frontend/src/components/Agent/AvatarSpatialwalk.tsx:231

Cleanup code has race conditions using void on cleanup promises and calling dispose before async cleanup completes.

6. Insecure Random ID Generation

Location: frontend/src/common/utils.ts:103

Issues:

  • Not cryptographically secure
  • Small range only 99,999 possible values
  • High collision probability

Risk: User ID collisions, potential session hijacking
Recommended: Use crypto.randomUUID or proper ID generation library

7. Missing CSRF Protection

No CSRF tokens or SameSite cookie protection visible in API routes.

Performance Concerns

8. Inefficient Audio Processing Loop

Location: frontend/src/common/hooks.ts:227

Audio visualizer updates 100 times per second regardless of changes.
Recommended: Use requestAnimationFrame for smoother updates.

9. Polling in Avatar Initialization

Busy-waiting loop checking container dimensions.
Recommended: Use ResizeObserver or IntersectionObserver instead.

Code Quality Issues

10. Missing Dependency Arrays in Callbacks

Location: frontend/src/app/page.tsx:96

Stale closure issue - callback wont have latest state.
Recommended: Use useCallback or add dependencies to array.

11. Inconsistent Error Handling

Functions throw strings, Errors, or return error objects inconsistently.
Recommended: Standardize on Error objects with proper error classes.

Test Coverage - HIGH PRIORITY

12. Minimal Test Coverage

The PR adds substantial functionality but includes minimal test coverage:

  • No frontend unit tests
  • No integration tests for API routes
  • No E2E tests for critical user flows
  • No security-focused tests for injection vulnerabilities

Recommendation: Add comprehensive test coverage before merging targeting at least 60 percent for critical paths.

Docker and Infrastructure

13. Docker Security Best Practices

Location: Dockerfile:83

Issues:

  • Running as root user
  • Piping curl to bash without verification
  • No health checks

Recommended: Add non-root user, verify scripts before execution, add healthcheck.

Positive Aspects

  1. Good separation of concerns - Frontend, backend, and agent logic well-organized
  2. Proper cleanup in most useEffect hooks - Shows awareness of resource management
  3. Environment variable usage - Most secrets use environment variables
  4. TypeScript usage - Type safety attempted
  5. Comprehensive README - Good documentation for setup
  6. Follows TEN Framework patterns - Adheres to repository extension architecture

Summary and Recommendations

Must Fix Before Merge:

  1. Remove .env file from repository and add to .gitignore
  2. Add input validation to all API routes
  3. Implement proper error handling no string throws
  4. Add comprehensive test coverage at least 60 percent

Should Fix:

  1. Replace any types with proper interfaces
  2. Fix memory leaks in cleanup handlers
  3. Use cryptographically secure random ID generation
  4. Implement CSRF protection

Consider:

  1. Add rate limiting on API endpoints
  2. Add request logging and monitoring
  3. Improve Docker security posture

Overall Assessment: This PR adds substantial and valuable functionality to the TEN Framework with a well-structured example. However, there are several critical security issues that must be addressed before merging. The code quality is generally good but needs hardening for production use, particularly around input validation, error handling, and test coverage.

Please address the critical issues and consider the high-priority recommendations. Happy to review again once these items are addressed!

@claude
Copy link

claude bot commented Feb 8, 2026

Code Review: PR #2043 - Spatialwalk Avatar Example

Thank you for this substantial contribution! I've reviewed the 21,421 line addition and found good architectural patterns but several critical security concerns that need addressing.


🔴 CRITICAL Security Issues

1. Unvalidated URL Opening (XSS/Phishing Risk)

Location: frontend/src/manager/rtc/rtc.ts:271-275

Opens arbitrary URLs without validation. Agent responses could redirect users to malicious sites.

Recommendation: Validate URLs with strict whitelist using URL() constructor.


2. Unprotected JSON.parse Operations

Location: frontend/src/manager/rtc/rtc.ts:241, 256

No try-catch or schema validation. Malformed JSON causes crashes.

Recommendation: Use zod for schema validation with proper error handling.


3. XSS Risk in Image URLs

Location: frontend/src/components/Chat/MessageList.tsx:63

Image src attributes populated directly from untrusted data. Accepts data: URIs, javascript: protocol, or SVG with embedded scripts.

Recommendation: Validate image URLs, restrict to http/https protocols only.


4. Missing API Input Validation

Location: frontend/src/app/api/agents/start/route.tsx:19-28

Request body forwarded to backend with no validation.

Recommendation: Add zod schema validation for all API inputs (request_id, channel_name, user_uid, etc).


5. Exposed Spatialwalk App ID

Location: frontend/.env:5

NEXT_PUBLIC_SPATIALWALK_APP_ID committed to version control, exposing to all users. Could enable quota exhaustion.

Recommendation: Move to server-side environment variable.


6. Weak Random ID Generation

Location: frontend/src/common/utils.ts:17-23

Uses Math.random() with only 5-digit entropy (100000-199999 range). Could enable session hijacking.

Recommendation: Use crypto.getRandomValues() for security-sensitive IDs.


⚠️ Code Quality Issues

7. Memory Leak Potential

Location: frontend/src/manager/rtc/rtc.ts:223-229

Timeouts created for incomplete messages but never cleaned up when destroy() is called.

8. Missing Type Safety

Location: frontend/src/common/request.ts

Excessive use of any types defeats TypeScript benefits.

9. Production Debug Logging

Location: Multiple files

Sensitive data exposed in production console logs including test logging.

10. No Rate Limiting

Location: frontend/src/components/Layout/Action.tsx:123

API ping every 3 seconds without exponential backoff on errors.


📋 Summary

Severity Count Category
Critical 4 Security (XSS, Injection, Validation)
High 2 Configuration & Cryptography
Medium 4 Memory Leaks, Type Safety, Logging

Immediate Action Items

  1. Add URL validation for window.open()
  2. Implement zod validation for all API endpoints
  3. Add try-catch + schema validation for JSON.parse
  4. Sanitize image URLs
  5. Move Spatialwalk App ID to backend
  6. Replace Math.random() with crypto.getRandomValues()
  7. Add timeout cleanup in RTC manager
  8. Remove debug logging

✨ Positive Aspects

  • Good separation of concerns (RTC/RTM managers)
  • Redux state management well-structured
  • Component architecture follows React best practices
  • Comprehensive UI components with shadcn/ui

The codebase demonstrates solid architecture but needs security hardening before merging. Please address the critical issues and I'm happy to review again!

@claude
Copy link

claude bot commented Feb 8, 2026

Pull Request Review: Feat/spatialwalk

Overview

This PR adds a new spatialwalk-avatar example agent (~21,400 additions, 147 files). It's a comprehensive Next.js + Python voice assistant integrating Agora RTC, STT, LLM, and TTS components.

🔴 Critical Issues

1. Security: Hardcoded Credentials in .env File

Location: ai_agents/agents/examples/spatialwalk-avatar/frontend/.env:5

The .env file contains a hardcoded Spatialwalk App ID:

NEXT_PUBLIC_SPATIALWALK_APP_ID=app_mjbs0ykx_cz1eev

Issues:

  • .env files should never be committed to version control
  • This exposes production credentials publicly
  • The app ID appears to be a real credential

Recommendation:

  • Remove .env from the repository immediately
  • Add .env to .gitignore (only .env.example should be tracked)
  • Rotate the exposed credential (app_mjbs0ykx_cz1eev)
  • Consider using a secrets management solution

2. Security: Weak Error Handling Exposes Internal Details

Location: frontend/src/app/api/agents/start/route.tsx:16-17

if (!AGENT_SERVER_URL) {
  throw "Environment variables are not available";
}

Issues:

  • Throwing raw strings instead of Error objects is poor practice
  • Error messages could expose internal configuration details to clients
  • Line 44-46 shows error responses may leak implementation details

Recommendation:

if (!AGENT_SERVER_URL) {
  return NextResponse.json(
    { code: "1", msg: "Service configuration error" },
    { status: 500 }
  );
}

3. Security: No Input Validation on API Routes

Location: frontend/src/app/api/agents/start/route.tsx:19-28

The route accepts user input without validation:

const {
  request_id,
  channel_name,
  user_uid,
  graph_name,
  language,
  voice_type,
  properties,
} = body;

Issues:

  • No validation of channel_name, user_uid, graph_name, etc.
  • Could lead to injection attacks or unexpected behavior
  • properties object is passed through without sanitization

Recommendation:

  • Add input validation using Zod or similar
  • Sanitize all user inputs
  • Validate properties object structure

4. Type Safety: Unsafe Type Assertions

Location: frontend/src/common/request.ts:36,55,67,97

Multiple instances of any types:

let resp: any = await axios.post(url, data);

Issues:

  • Defeats TypeScript's type safety
  • Makes refactoring error-prone
  • No compile-time guarantees about response structure

Recommendation:

interface AgoraDataResponse {
  code: string;
  data?: {
    appId: string;
    token: string;
  };
  msg?: string;
}

const resp = await axios.post<AgoraDataResponse>(url, data);

⚠️ Code Quality Issues

5. Error Handling: Silent Failures

Location: frontend/src/manager/rtc/rtc.ts:64-66,74-76,93-95

} catch (err) {
  console.error("Failed to create video track", err);
}

Issues:

  • Errors are logged but not surfaced to users
  • Application continues in broken state
  • No recovery mechanism

Recommendation:

  • Emit error events that UI can handle
  • Provide user-facing error messages
  • Consider retry logic for transient failures

6. Race Condition: Async Queue Flushing

Location: tenapp/ten_packages/extension/main_python/agent/agent.py:197-203

while not self._llm_queue.empty():
    try:
        self._llm_queue.get_nowait()
        self._llm_queue.task_done()
    except asyncio.QueueEmpty:
        break

Issues:

  • Race condition: queue could receive items between empty() check and get_nowait()
  • Multiple concurrent flushes could cause issues

Recommendation:

# Drain queue atomically
while True:
    try:
        self._llm_queue.get_nowait()
        self._llm_queue.task_done()
    except asyncio.QueueEmpty:
        break

7. Documentation Mismatch

Location: README.md:1,61,70,174

The README references "voice-assistant" but the directory is "spatialwalk-avatar":

cd agents/examples/voice-assistant  # Should be spatialwalk-avatar

Recommendation:

  • Update all path references to match actual directory name
  • Update title if this is meant to be "Spatialwalk Avatar" not "Voice Assistant"

8. Missing Tests

Finding: No test files found in the entire PR

Issues:

  • 21,420 lines of code with zero tests
  • No way to verify functionality
  • High risk for regressions

Recommendation:

  • Add unit tests for Python agent logic
  • Add integration tests for API routes
  • Add E2E tests for critical user flows
  • Target minimum 60% coverage for new code

📊 Performance Considerations

9. Bundle Size: Large Lock Files

Location:

  • frontend/bun.lock (1,261 lines)
  • frontend/package-lock.json (6,481 lines)

Issues:

  • Both Bun and npm lock files present suggests mixed package managers
  • Large dependency trees increase attack surface and bundle size

Recommendation:

  • Choose one package manager (Bun or npm)
  • Audit dependencies for unused packages
  • Consider bundle size analysis

10. Memory Leak Potential

Location: extension/main_python/agent/llm_exec.py:52

self.loop = asyncio.get_event_loop()
self.loop.create_task(self._process_input_queue())

Issues:

  • Task created in __init__ but no cleanup reference stored
  • Could prevent garbage collection

Recommendation:

self._process_task = self.loop.create_task(self._process_input_queue())

async def stop(self):
    if self._process_task and not self._process_task.done():
        self._process_task.cancel()

✅ Positive Aspects

  1. Good Architecture: Clean separation between Agent and Extension layers
  2. Event-Driven Design: Decorator-based event handlers in extension.py are elegant
  3. Async/Await: Proper use of asyncio throughout Python code
  4. Type Hints: Python code uses type hints effectively
  5. Docker Support: Multi-stage build optimizes image size
  6. UI Components: Using shadcn/ui provides consistent component library

🔧 Minor Issues

  1. Dockerfile Line 3: ARG USE_AGENT=agents/examples/spatial-walk-avatar - Inconsistent path separator vs actual directory spatialwalk-avatar
  2. Magic Numbers: TIMEOUT_MS = 5000 in rtc.ts:19 should be configurable
  3. Console.logs: Production code contains console.error statements that should use proper logging
  4. Empty Files: tenapp/ten_packages/extension/main_python/agent/__init__.py is empty

Summary

Overall Assessment: This PR adds significant functionality but has critical security issues that must be addressed before merging.

Merge Recommendation:Request Changes

Priority Actions Required:

  1. Remove .env file from repository and rotate credentials
  2. Add input validation to all API routes
  3. Fix error handling to avoid exposing internal details
  4. Add type safety to TypeScript code
  5. Add basic test coverage (at minimum for security-critical paths)
  6. Fix documentation path inconsistencies

Estimated Effort: 1-2 days to address critical issues


🤖 Generated by Claude Code - Review completed on 2026-02-08

@plutoless plutoless force-pushed the feat/spatialwalk branch 3 times, most recently from 65321ab to 643b80e Compare February 8, 2026 13:23
@claude
Copy link

claude bot commented Feb 8, 2026

Code Review: PR #2043 - Spatialwalk Avatar Example

Thank you for this substantial contribution! This PR adds 21,504 lines across 148 files. I've completed a comprehensive code review covering security, code quality, and best practices.

🚨 CRITICAL SECURITY ISSUE

1. .env File Committed to Repository

  • File: ai_agents/agents/examples/spatialwalk-avatar/frontend/.env
  • Problem: Contains NEXT_PUBLIC_SPATIALWALK_APP_ID=app_mjbs0ykx_cz1eev
  • Action Required: git rm --cached ai_agents/agents/examples/spatialwalk-avatar/frontend/.env
  • Impact: Medium - The app ID could be rate-limited or abused

Create .env.example instead with placeholder values.

🔴 HIGH PRIORITY ISSUES

2. API Route Throws Strings Instead of Error Objects

  • File: frontend/src/app/api/agents/start/route.tsx:16-17
  • Problem: throw "Environment variables are not available" - Never throw strings
  • Fix: Return proper NextResponse.json with error status instead

3. Incorrect Error Handling in API Route

  • File: frontend/src/app/api/agents/start/route.tsx:43-52
  • Problem: Checks error instanceof Response but axios throws AxiosError
  • Fix: Use axios.isAxiosError(error) instead

Full review with code examples continues in next comment...

@claude
Copy link

claude bot commented Feb 8, 2026

🟡 MEDIUM PRIORITY ISSUES

4. RTC Manager - Missing Error Context

  • File: frontend/src/manager/rtc/rtc.ts:45-49
  • Problem: Uses != instead of !==, error message lacks details
  • Fix: Use strict equality and include error details in message

5. RTC Manager - Silent Error Swallowing

  • File: frontend/src/manager/rtc/rtc.ts:62-66
  • Problem: Camera/mic errors are logged but silently swallowed
  • Fix: Emit error events or throw so UI can handle gracefully

6. RTC Manager - Unsafe Chunk Parsing

  • File: frontend/src/manager/rtc/rtc.ts:186-201
  • Problem: No validation that split returns 4 parts; content with pipe chars breaks parsing
  • Fix: Validate parts.length before destructuring, join remaining parts for content

7. RTM Manager - Unprotected JSON.parse

  • File: frontend/src/manager/rtm/index.ts:96-108
  • Problem: JSON.parse can throw but not wrapped in try-catch
  • Fix: Add try-catch and validate message structure before emitting

8. Request Utilities - Excessive Use of any

  • File: frontend/src/common/request.ts:27-38
  • Problem: All API functions use any type, defeating TypeScript purpose
  • Fix: Define proper interfaces for request/response types

@claude
Copy link

claude bot commented Feb 8, 2026

🟢 LOW PRIORITY ISSUES

9. Debug Logging in Production

  • File: frontend/src/manager/rtm/index.ts:55-56
  • Problem: logLevel set to debug with TODO comment
  • Fix: Use process.env.NODE_ENV to conditionally set log level

10. React useEffect Missing Dependencies

  • File: frontend/src/app/page.tsx:33-39
  • Problem: onRemoteUserChanged not in dependency array causes stale closures
  • Fix: Wrap callback in React.useCallback and include in dependencies

📊 SECURITY SUMMARY

Severity Issue Location
🔴 High .env file committed frontend/.env
🟡 Medium No input validation on API endpoints api/agents/start/route.tsx
🟡 Medium Error messages expose internal structure Multiple files
🟡 Medium No rate limiting on API routes All API routes
🟢 Low Debug logging in production rtm/index.ts:56
🟢 Low String thrown instead of Error route.tsx:17

@claude
Copy link

claude bot commented Feb 8, 2026

Code Review: PR #2043 - Spatialwalk Avatar Example

Thank you for this comprehensive addition! This PR adds a complete new example with 148 files and 21,505 additions. Here's my detailed review:

🔴 Critical Issues

1. Security: API Key Exposure

File: frontend/.env:5

  • Issue: Committed NEXT_PUBLIC_SPATIALWALK_APP_ID=app_mjbs0ykx_cz1eev to repository
  • Risk: Publicly exposes app credentials in git history
  • Fix: Move to .env.local (gitignored) and provide .env.example template instead

2. Memory Leak: AudioContext Not Cleaned Up

File: frontend/src/common/hooks.ts:31-77 (useMultibandTrackVolume)

  • Issue: AudioContext created on every track change but never closed
  • Fix: Add cleanup:
return () => {
  source.disconnect();
  clearInterval(interval);
  ctx.close(); // ADD THIS
};

3. Module-Level State Causing Bugs

File: frontend/src/components/Dynamic/RTCCard.tsx:33

  • Issue: let hasInit: boolean = false; persists across remounts
  • Impact: Breaks in HMR, causes initialization bugs
  • Fix: Move to component state or useRef

4. Silent Error Swallowing

Files: Multiple locations including:

  • frontend/src/components/Layout/Action.tsx:52,76
  • frontend/src/components/Agent/AvatarSpatialwalk.tsx:158
} catch {
  // Empty catch blocks - no logging!
}
  • Fix: At minimum, log errors for debugging

5. Race Conditions in Async Operations

File: frontend/src/components/Agent/AvatarSpatialwalk.tsx:143-172

  • Issue: Cancellation checked AFTER async operations complete
  • Impact: Potential state updates after unmount
  • Fix: Check cancellation flag before async operations

⚠️ High Priority Issues

6. Unvalidated User Input

File: frontend/src/components/Agent/AvatarSpatialwalk.tsx:43-47

  • URL parameters used directly without validation
  • Risk: Potential injection attacks
  • Fix: Validate and sanitize URL parameters

7. Missing useEffect Dependencies

File: frontend/src/components/authInitializer/index.tsx:54

useEffect(() => {
  // Uses initialize()
}, [dispatch]); // Missing 'initialize' in dependencies

8. Excessive any Types

File: frontend/src/common/request.ts (throughout)

  • Multiple let resp: any declarations
  • Fix: Define proper response types for type safety

9. Dynamic Imports in Wrong Place

File: frontend/src/app/page.tsx:35

React.useEffect(() => {
  const { rtcManager } = require("../manager/rtc/rtc"); // Anti-pattern
  • Fix: Import at module level

10. Global Interval Not Cleaned Up

File: frontend/src/components/Layout/Action.tsx:22,118-132

  • Module-level intervalId may leak
  • Fix: Use useRef and cleanup in useEffect

⚡ Performance Concerns

11. High-Frequency State Updates

File: frontend/src/common/hooks.ts:69

  • setInterval at 10ms = 100 updates/second
  • Consider: requestAnimationFrame or reduced frequency

12. Bundle Size Optimization

File: frontend/next.config.mjs:15

  • Verify tree-shaking works for large dependencies (AvatarKit, Agora RTC)

📝 Code Quality Issues

13. 100+ console.log Statements

  • Debug logs left throughout production code
  • Impact: Performance overhead, information disclosure
  • Fix: Use proper logging library with levels

14. Wrong Dockerfile Stage Name

File: frontend/Dockerfile:38

  • Stage named melvinortega8722 instead of runner/production
  • Fix: Use conventional naming

15. Large Component Files

  • frontend/src/components/Chat/ChatCfgModuleSelect.tsx (540 lines)
  • frontend/src/common/graph.ts (578 lines)
  • Consider: Split into smaller, focused components

16. Error Handling Strategy

File: frontend/src/common/request.ts

  • Inconsistent: some functions throw, others return error objects
  • Fix: Standardize error handling approach

17. Commented Dead Code

Files:

  • frontend/src/manager/rtc/rtc.ts:180-187
  • frontend/src/proxy.tsx:20-35
  • Fix: Remove or document why kept

✅ Positive Aspects

  • Good use of TypeScript overall
  • Proper component structure with shadcn/ui
  • Redux Toolkit for state management
  • Comprehensive feature set
  • Docker configuration present
  • Next.js 16 with standalone output

🎯 Recommendations

Immediate (Before Merge)

  1. ❌ Remove committed .env file, use .env.example
  2. ❌ Fix AudioContext memory leak
  3. ❌ Fix module-level state issues
  4. ❌ Add error logging to empty catch blocks

Short-term

  1. Add proper error boundaries
  2. Fix race conditions in async operations
  3. Add missing useEffect dependencies
  4. Validate user inputs

Medium-term

  • Reduce any usage with proper types
  • Add test coverage
  • Remove console.log statements
  • Optimize performance bottlenecks

Long-term

  • Refactor large components
  • Improve architecture (reduce coupling)
  • Add comprehensive documentation

Overall Assessment: This is a feature-rich example with good foundation, but requires production-hardening before deployment. The critical security and memory leak issues should be addressed before merging.

Happy to discuss any of these findings! 🚀

@claude
Copy link

claude bot commented Feb 8, 2026

✅ POSITIVE ASPECTS

The PR demonstrates good software engineering practices:

  1. Good separation of concerns (managers, components, utilities)
  2. Uses modern React patterns (hooks, functional components)
  3. TypeScript enabled with strict mode
  4. Proper Next.js 14+ app directory structure
  5. Event-driven architecture with EventEmitter pattern
  6. Uses established libraries (Agora, Redux)
  7. Proper .gitignore setup
  8. Uses Biome for linting

📋 RECOMMENDATIONS

Before Merge (Critical):

  1. ✅ Remove .env file from git history
  2. ✅ Fix error handling (throw Error objects, not strings)
  3. ✅ Add proper TypeScript types (remove any)
  4. ✅ Fix React useEffect dependency warnings
  5. ✅ Add input validation to API routes

Short Term:

  • Add error boundaries in React components
  • Implement rate limiting on API routes
  • Add request/response validation using Zod or similar
  • Add proper logging infrastructure (not just console.log)

Long Term:

  • Add comprehensive testing (unit, integration)
  • Add API documentation
  • Add performance monitoring
  • Implement CI/CD with security scanning

@claude
Copy link

claude bot commented Feb 8, 2026

🎯 CONCLUSION

This PR adds a substantial new feature (21,504 lines across 148 files) with solid overall architecture. The event-driven design and component organization are well thought out.

However, there are critical security issues and numerous code quality issues that need to be addressed:

Critical:

  • .env file committed with app credentials
  • Improper error handling that could cause runtime failures

Important:

  • Lack of input validation
  • Excessive use of any types
  • Missing error propagation
  • Unprotected parsing operations

Recommendation: REQUEST CHANGES

Please address at minimum:

  1. The critical security issue (remove .env from git)
  2. High priority issues modify playground default settings,fix voice type error #2-3 (error handling in API routes)
  3. Consider adding TypeScript types to replace any

The architectural foundation is strong - these fixes will significantly improve the code quality and security posture. Happy to review again once these are addressed!

@claude
Copy link

claude bot commented Feb 8, 2026

Pull Request Review: Spatial-Walk-Avatar Example

Thank you for this comprehensive contribution! This PR adds a sophisticated Next.js-based spatial audio avatar agent with 19,590 lines of new code. The implementation demonstrates strong architectural patterns, but there are several critical issues that need attention before merging.

Executive Summary

Strengths:

  • Clean modular architecture with proper separation of concerns
  • Event-driven design with robust error isolation
  • Strong TypeScript usage with proper interfaces
  • Well-structured Redux state management
  • Comprehensive UI component library

Critical Issues Found:

  • Security vulnerability in URL handling
  • Type safety concerns with excessive any usage
  • Memory leak potential in event listeners
  • Production debug code left in place

🔴 Critical Issues (Must Fix Before Merge)

1. Security Vulnerability - Unvalidated URL Opening

File: frontend/src/manager/rtc/rtc.ts:273

if (action === "browse_website") {
  console.log("Opening website", actionData.url);
  window.open(actionData.url, "_blank");  // ⚠️ No validation!
  return;
}

Risk: Arbitrary URL execution could enable XSS attacks via javascript: protocol or redirect to phishing sites.

Fix:

if (action === "browse_website") {
  try {
    const url = new URL(actionData.url);
    // Only allow safe protocols
    if (!['http:', 'https:'].includes(url.protocol)) {
      console.error("Invalid URL protocol:", url.protocol);
      return;
    }
    window.open(url.href, "_blank", "noopener,noreferrer");
  } catch (e) {
    console.error("Invalid URL:", actionData.url, e);
  }
  return;
}

2. Type Safety - Excessive any Usage

File: frontend/src/common/request.ts:36, 55, 75, etc.

Multiple API functions return any, defeating TypeScript's safety guarantees:

let resp: any = await axios.post(url, data);
resp = resp.data || {};
return resp;

Recommendation: Define response interfaces and validate with Zod:

import { z } from 'zod';

const PingResponseSchema = z.object({
  code: z.number(),
  message: z.string().optional(),
});

type PingResponse = z.infer<typeof PingResponseSchema>;

export const apiPing = async (channel_name: string): Promise<PingResponse> => {
  const resp = await axios.post(url, { channel_name });
  return PingResponseSchema.parse(resp.data);
};

3. Improper Error Handling

File: frontend/src/app/api/agents/start/route.tsx:16

throw "Environment variables are not available";  // ⚠️ Throwing string instead of Error

Fix:

throw new Error("Environment variables are not available");

4. Missing Input Validation in API Route

File: frontend/src/app/api/agents/start/route.tsx

The /api/agents/start route accepts arbitrary request body without validation. This could cause runtime errors or security issues.

Fix: Add Zod validation:

import { z } from 'zod';

const StartAgentSchema = z.object({
  request_id: z.string().uuid(),
  channel_name: z.string().min(1),
  user_uid: z.number().int().positive(),
  graph_name: z.string().min(1),
  properties: z.record(z.unknown()).optional(),
  timeout: z.number().int().positive().optional(),
});

export async function POST(request: Request) {
  try {
    const body = await request.json();
    const validatedData = StartAgentSchema.parse(body);
    // ... use validatedData
  } catch (e) {
    if (e instanceof z.ZodError) {
      return Response.json({ error: "Invalid request", details: e.errors }, { status: 400 });
    }
    // ...
  }
}

🟡 Medium Priority Issues

5. Memory Leak - Event Listener Binding

File: frontend/src/manager/rtm/index.ts:85-90

this._rtm.addEventListener("message", this.handleRTMMessage.bind(this));
this._rtm.addEventListener("status", this.handleRTMStatus.bind(this));

Problem: bind(this) creates new function references on each call. When removeEventListener is called later with a different function reference, the listener won't be removed, causing memory leaks.

Fix: Use arrow functions in class properties:

private handleRTMMessage = async (event: RTMMessageEvent) => {
  // implementation
};

private handleRTMStatus = (event: RTMStatusEvent) => {
  // implementation
};

// Then in listen():
this._rtm.addEventListener("message", this.handleRTMMessage);
this._rtm.addEventListener("status", this.handleRTMStatus);

6. Production Debug Logs

Files:

  • frontend/src/manager/rtc/rtc.ts:177 - "[test] textstream raw data"
  • frontend/src/manager/rtc/rtc.ts:242-244 - Debug logging

Please remove or convert to conditional development-only logging:

if (process.env.NODE_ENV === 'development') {
  console.log('[test] textstream raw data:', msg);
}

7. TODO Comments Left in Code

File: frontend/src/manager/rtm/index.ts:56

// TODO: use info log level

Please resolve this TODO before merging or create a follow-up issue.

8. Large Component Size

File: frontend/src/components/Chat/ChatCfgModuleSelect.tsx (541 lines)

This component handles both form rendering and complex graph manipulation logic. Consider extracting:

  • Form logic into a custom hook (useChatModuleForm)
  • Graph update logic into a separate utility (updateGraphConnections)

This improves testability and maintainability.


🟢 Low Priority / Code Quality Issues

9. Non-Strict Equality Check

File: frontend/src/manager/rtc/rtc.ts:48

if (code != 0) {  // Should be !==

Use strict equality (!==) throughout for consistency.

10. Magic Numbers

File: frontend/src/manager/rtc/rtc.ts

const TIMEOUT_MS = 5000;  // Hardcoded timeout

Consider making this configurable or documenting why 5000ms was chosen.

11. Incomplete RTM Presence Handling

File: frontend/src/manager/rtm/index.ts:112-114

Presence events are only logged but not processed. If presence tracking isn't needed, consider removing the event listener.


Test Coverage

Observation: No test files are included in this PR for the frontend application.

Recommendation: Add tests for critical functionality:

  • RTC message chunking/reconstruction logic (rtc.ts)
  • Graph editor operations (graph.ts)
  • API request error handling (request.ts)
  • Form validation (ChatCfgModuleSelect)

Suggested testing approach:

// Example: tests/manager/rtc/rtc.test.ts
describe('RTC Message Chunking', () => {
  it('should reconstruct chunked messages correctly', () => {
    // Test chunking logic
  });
  
  it('should timeout incomplete messages after TIMEOUT_MS', () => {
    // Test timeout cleanup
  });
});

Performance Considerations

The implementation looks efficient overall. A few observations:

  1. Message Chunking Logic (rtc.ts:162-209): Good use of Map for O(1) lookups. The timeout cleanup prevents memory leaks from incomplete messages.

  2. Redux State Updates: Proper use of immutable patterns. No unnecessary re-renders detected.

  3. Event Emitter: Error isolation in callbacks (events.ts:23-30) prevents cascade failures - excellent pattern!

  4. Potential Optimization: Consider debouncing graph updates in ChatCfgModuleSelect to avoid excessive state updates during rapid user interactions.


Security Assessment

Beyond the critical URL validation issue mentioned above:

  1. CORS Configuration: Verify AGENT_SERVER_URL allows requests only from trusted origins
  2. Token Management: Agora tokens appear properly scoped to channels
  3. Environment Variables: Good use of server-side environment variable access in API routes
  4. Sensitive Data: No API keys or secrets detected in frontend code (good practice)

Alignment with Repository Guidelines

Per AGENTS.md:

YAGNI Principle: Code appears focused on current requirements without over-engineering
KISS Principle: Architecture is straightforward and readable
No Git-Ignored Files Modified: All changes are source files
⚠️ Type Safety: Some deviations with any usage (noted above)


Recommendations for PR Acceptance

Before merging, please address:

  • Fix URL validation security issue (rtc.ts:273)
  • Replace throw "string" with throw new Error() (route.tsx:16)
  • Add input validation to /api/agents/start route
  • Fix event listener memory leak (rtm/index.ts:85-90)
  • Remove debug/test console logs from production code
  • Fix non-strict equality checks (!= should be !==)
  • Resolve TODO comment or create follow-up issue

Optional improvements (can be post-merge):

  • Add TypeScript interfaces for API responses instead of any
  • Extract ChatCfgModuleSelect into smaller components
  • Add unit tests for critical logic paths
  • Document magic numbers and timeout values
  • Implement RTM presence handling or remove listeners

Conclusion

This is a well-architected example demonstrating sophisticated real-time communication patterns and modern React best practices. The modular design and event-driven architecture are commendable. However, the security vulnerability and type safety issues must be resolved before merging to maintain code quality standards.

Once the critical issues are addressed, this will be an excellent addition to the TEN Framework examples. Great work on the overall implementation! 🎉


Reviewed with ❤️ by Claude Code

@claude
Copy link

claude bot commented Feb 8, 2026

Code Review: PR #2043 - Feat/spatialwalk

Thank you for this substantial contribution adding the spatialwalk-avatar example agent! This is a comprehensive implementation with 19,590 additions across 103 files. I've completed a thorough review and identified several critical security issues, bugs, and code quality improvements needed before merging.


🔴 Critical Issues (Must Fix)

1. XSS Vulnerability via window.open()

Location: frontend/src/manager/rtc/rtc.ts:273

if (action === "browse_website") {
  console.log("Opening website", actionData.url);
  window.open(actionData.url, "_blank"); // ⚠️ SECURITY RISK
  return;
}

Issue: Malicious agent responses could open arbitrary URLs, including javascript: URIs leading to XSS attacks.

Fix:

if (action === "browse_website") {
  const url = actionData.url;
  try {
    const parsed = new URL(url);
    if (!['http:', 'https:'].includes(parsed.protocol)) {
      console.error('Invalid protocol:', parsed.protocol);
      return;
    }
    window.open(url, "_blank", "noopener,noreferrer");
  } catch (e) {
    console.error('Invalid URL:', url);
  }
}

2. XSS Vulnerability via Image Source

Location: frontend/src/components/Chat/MessageList.tsx:63

{data.data_type === EMessageDataType.IMAGE ? (
  <img src={data.text} alt="chat" className="w-full" />  // ⚠️ XSS RISK

Issue: Image source from untrusted agent responses rendered without validation - potential XSS via javascript: URIs.

Fix:

const isValidImageUrl = (url: string): boolean => {
  try {
    const parsed = new URL(url);
    return ['http:', 'https:', 'data:'].includes(parsed.protocol);
  } catch {
    return false;
  }
};

// In render:
{data.data_type === EMessageDataType.IMAGE ? (
  <img 
    src={isValidImageUrl(data.text) ? data.text : '/placeholder.png'} 
    alt="chat" 
    className="w-full"
    referrerPolicy="no-referrer"
  />
) : (
  <p className={...}>{data.text}</p>
)}

3. Missing Input Validation in API Route

Location: frontend/src/app/api/agents/start/route.tsx:19-28

Issue: No validation on request body parameters before forwarding to backend - potential injection attacks.

Fix: Add input validation using zod or similar:

import { z } from 'zod';

const startAgentSchema = z.object({
  request_id: z.string().min(1),
  channel_name: z.string().min(1),
  user_uid: z.number().int().positive(),
  graph_name: z.string().min(1),
  language: z.string().optional(),
  voice_type: z.string().optional(),
  properties: z.record(z.any()).optional()
});

// In handler:
const body = await request.json();
const validated = startAgentSchema.parse(body); // Will throw if invalid

4. Prototype Pollution Vulnerability

Location: frontend/src/common/utils.ts:92-103

Issue: deepMerge function vulnerable to prototype pollution attacks.

Fix:

export const deepMerge = (target: Record<string, any>, source: Record<string, any>): Record<string, any> => {
  for (const key of Object.keys(source)) {
    if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
      continue; // Skip dangerous keys
    }
    if (source[key] instanceof Object && key in target) {
      Object.assign(source[key], deepMerge(target[key], source[key]));
    }
  }
  return { ...target, ...source };
};

🟠 High Priority Issues (Should Fix)

5. Race Condition in RTC Track Management

Location: frontend/src/manager/rtc/rtc.ts:103-115

this.client.unpublish(this.localTracks.videoTrack); // Missing await
this.localTracks.videoTrack?.close();
this.localTracks.videoTrack = undefined;
this.client.publish(this.localTracks.screenTrack); // Missing await

Issue: Async operations not awaited, causing potential race conditions and failed track switches.

Fix:

await this.client.unpublish(this.localTracks.videoTrack);
this.localTracks.videoTrack?.close();
this.localTracks.videoTrack = undefined;
await this.client.publish(this.localTracks.screenTrack);

6. Incorrect Error Handling

Location: frontend/src/app/api/agents/start/route.tsx:16,44-46

Issues:

  • Line 16: Throwing string instead of Error object
  • Lines 44-46: Assumes error instanceof Response which is incorrect for axios errors

Fix:

// Line 16:
if (!AGENT_SERVER_URL) {
  throw new Error("Environment variables are not available");
}

// Lines 43-52:
} catch (error) {
  if (axios.isAxiosError(error) && error.response) {
    return NextResponse.json(error.response.data, { status: error.response.status });
  } else {
    return NextResponse.json(
      { code: "1", data: null, msg: "Internal Server Error" },
      { status: 500 }
    );
  }
}

7. Memory Leak in Audio Hook

Location: frontend/src/common/hooks.ts:36

Issue: AudioContext never closed, causing memory leaks on component unmount.

Fix:

useEffect(() => {
  const audioContext = new AudioContext();
  const analyser = audioContext.createAnalyser();
  // ... rest of code

  return () => {
    audioContext.close(); // Add cleanup
  };
}, [track]);

8. Missing Try-Catch for JSON.parse

Locations:

  • frontend/src/manager/rtm/index.ts:98,107
  • frontend/src/manager/rtc/rtc.ts:241,256

Issue: Will crash application on malformed messages.

Fix:

async handleRtmMessage(e: TRTMMessageEvent) {
  const { message, messageType } = e;
  try {
    if (messageType === "STRING") {
      const msg: IRTMTextItem = JSON.parse(message as string);
      if (msg) {
        this.emit("rtmMessage", msg);
      }
    }
  } catch (error) {
    console.error("Failed to parse RTM message:", error);
  }
}

🟡 Medium Priority Issues (Code Quality)

9. Extensive Use of any Type

Location: frontend/src/common/request.ts (throughout)

Issue: Functions return Promise<any> and use any for response data, losing all type safety.

Example Issues:

  • Lines 36, 55, 67, 97, 110: let resp: any = await axios.post(...)
  • Lines 142-157: (graph: any) => in map functions
  • Lines 173, 189-273: Complex nested operations without type guards

Recommendation: Define proper TypeScript interfaces for all API responses and use type guards for validation.


10. React Strict Mode Disabled

Location: frontend/next.config.mjs:13

reactStrictMode: false,

Issue: Disabling Strict Mode hides potential bugs and prevents React from detecting unsafe lifecycle methods.

Fix: Remove this line or set to true.


11. Non-Cryptographic Random for UUIDs

Location: frontend/src/common/utils.ts:48-54

Issue: Using Math.random() for UUID generation, not cryptographically secure.

Fix:

export const genUUID = () => {
  if (typeof crypto !== 'undefined' && crypto.randomUUID) {
    return crypto.randomUUID();
  }
  // fallback to current implementation for older browsers
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, /* ... */);
};

12. Aggressive Performance Settings

Location: frontend/src/common/hooks.ts:69

Issue: 10ms interval for audio analysis is very aggressive and impacts performance.

Recommendation: Consider increasing to 50-100ms unless real-time precision is critical.


🟢 Security Best Practices

13. Docker Container Security

Location: Dockerfile

Issues:

  • Line 7: .env.example copied to .env - ensure it contains no actual secrets
  • Lines 56, 60-62: curl-pipe-bash installations - acceptable for official sources but inherently risky
  • No USER directive - container runs as root

Recommendations:

# Add before CMD
RUN useradd -m -u 1000 appuser && \
    chown -R appuser:appuser /app
USER appuser

14. Missing Null Checks

Location: frontend/src/components/Agent/StreamPlayer.tsx:38

videoTrack?.play(vidDiv.current!, config); // Non-null assertion dangerous

Fix:

if (!videoTrack?.isPlaying && vidDiv.current) {
  videoTrack?.play(vidDiv.current, config);
}

📊 Test Coverage

Finding: No test files found in this PR.

Recommendation: Add test coverage for:

  • API route handlers (especially error cases)
  • Utility functions (deepMerge, genUUID, etc.)
  • RTC/RTM manager connection logic
  • React component rendering and user interactions

Minimum recommended:

frontend/src/app/api/agents/start/__tests__/route.test.tsx
frontend/src/common/__tests__/utils.test.ts
frontend/src/manager/rtc/__tests__/rtc.test.ts

📝 Additional Recommendations

  1. Environment Variables: Consider using a .env.example template with clear placeholder values rather than actual defaults
  2. Error Boundaries: Add React Error Boundaries around major component trees
  3. Logging: Consider using structured logging instead of console.log for production
  4. Deep Cloning: Replace JSON.parse(JSON.stringify()) with structuredClone() or immer library
  5. Component Display Names: Add displayName to all forwardRef components for better debugging

✅ Positive Aspects

  • Good use of multi-stage Docker builds
  • Proper cleanup in useEffect hooks (mostly)
  • Redux toolkit with devTools configuration
  • Comprehensive example implementation
  • Good component structure and separation of concerns

Summary

This PR adds valuable functionality but requires addressing 4 critical security vulnerabilities before merging. The XSS issues and prototype pollution vulnerability could be exploited in production. Additionally, several bug fixes and code quality improvements would significantly improve maintainability.

Suggested Action Plan:

  1. Fix all Critical Issues (1-4)
  2. Fix High Priority Issues (5-8)
  3. Add basic test coverage for critical paths
  4. Consider Medium Priority improvements for code quality

Happy to review again once these issues are addressed! 🚀

@claude
Copy link

claude bot commented Feb 8, 2026

Code Review for PR #2043: Spatialwalk-Avatar Agent Example

Thank you for this comprehensive contribution! I've reviewed the code focusing on quality, security, performance, and framework conventions.

Overview

Strengths:

  • ✅ Follows TEN Framework patterns
  • ✅ Good documentation
  • ✅ Modern frontend stack
  • ✅ Modular architecture

Critical & High Priority Issues

🔴 HIGH: Unsafe Type Coercion

File: tenapp/ten_packages/extension/main_python/extension.py:85-86

stream_id = int(self.session_id)  # Unsafe - may raise ValueError

Fix: Add try-catch for safe type conversion.


🟡 MEDIUM: Missing Null Safety

File: tenapp/ten_packages/extension/main_python/agent/llm_exec.py:226-228

json.loads(r) called without checking if r is None.


🟡 MEDIUM: No Input Validation

File: frontend/src/app/api/agents/start/route.tsx:31-38

Request parameters passed directly without validation. Recommendation: Use Zod for schema validation.


🟡 MEDIUM: Error Data Exposure

File: frontend/src/app/api/agents/start/route.tsx:44-46

Error responses may contain sensitive information. Filter before returning to client.

Medium Priority Issues

Type Safety:

  • Loose typing in API responses (any used extensively)
  • Loose equality operators (!= instead of !==)

Error Handling:

  • Broad exception catching
  • Missing timeouts in RTC calls
  • Unvalidated JSON parsing

React Issues:

  • Dynamic import without error boundary
  • Memory leak in event listener cleanup

Security:

  • Missing env var validation
  • Dockerfile runs as root (add USER context)
  • localStorage without error handling

Configuration Issues

  1. README Title: Says "Voice Assistant" should be "Spatialwalk Avatar Voice Assistant"
  2. Inconsistent API Keys: Different naming across extensions (api_key vs key vs spatialreal_api_key)
  3. Hardcoded Values: Test values in property.json should be configurable
  4. Missing API Interface: manifest.json needs complete interface definitions

Low Priority

  • Console.log statements in production
  • TODO comments (change log level to INFO)
  • reactStrictMode disabled
  • Frontend Dockerfile stage naming issue

Test Coverage

⚠️ No test files included. Recommend adding:

  • tests/bin/start script
  • tests/conftest.py with fixtures
  • Unit tests for agent logic

Overall Assessment

Code Quality: ⭐⭐⭐⭐ (4/5)
Security: ⭐⭐⭐ (3/5)
Framework Adherence: ⭐⭐⭐⭐ (4/5)
Documentation: ⭐⭐⭐⭐ (4/5)
Test Coverage: ⭐⭐ (2/5)

Recommendation

Request changes to address the 4 critical/high-priority issues before merging. Medium and low-priority issues can be addressed in follow-up PRs.

Great work on this spatial avatar integration! 🚀

@claude
Copy link

claude bot commented Feb 9, 2026

Code Review Summary

Thank you for this substantial contribution! This PR adds a new spatialwalk-avatar example with a Next.js frontend and real-time communication capabilities. While the architectural patterns are solid, there are critical security vulnerabilities and quality issues that must be addressed before merging.


🔴 Critical Issues (Must Fix Before Merge)

1. Security: .env File Committed to Repository

File: ai_agents/agents/examples/spatialwalk-avatar/frontend/.env

The .env file is committed directly to the repository. This is a severe security anti-pattern that must be fixed immediately:

  • Remove .env from the repository
  • Ensure only .env.example is committed with placeholder values
  • Update documentation to reference .env.example

2. Security: No Input Validation in API Route

File: frontend/src/app/api/agents/start/route.tsx:10-52

All request parameters are directly forwarded to the backend without any validation:

  • No type checking at runtime
  • Vulnerable to injection attacks and SSRF
  • Missing rate limiting
  • String thrown as error instead of Error object (line 16)

Recommendation: Implement input validation using Zod or similar:

import { z } from 'zod';

const StartAgentSchema = z.object({
  request_id: z.string().uuid(),
  channel_name: z.string().min(1).max(64).regex(/^[a-zA-Z0-9_-]+$/),
  user_uid: z.number().int().positive(),
  graph_name: z.string().min(1).max(128),
  language: z.enum(['en-US', 'zh-CN', 'ko-KR', 'ja-JP']),
  voice_type: z.enum(['male', 'female']),
  properties: z.record(z.unknown()).optional(),
});

export async function POST(request: NextRequest) {
  try {
    const { AGENT_SERVER_URL } = process.env;
    if (!AGENT_SERVER_URL) {
      throw new Error("AGENT_SERVER_URL not configured");
    }
    
    const body = await request.json();
    const validatedData = StartAgentSchema.parse(body);
    
    const response = await axios.post(
      `${AGENT_SERVER_URL}/start`,
      validatedData,
      { timeout: 10000 }
    );
    
    return NextResponse.json(response.data, { status: response.status });
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { code: "VALIDATION_ERROR", msg: "Invalid input", errors: error.errors },
        { status: 400 }
      );
    }
    // ... handle other errors
  }
}

3. Test Coverage: No Tests Found

This PR adds 22,647 lines of code with zero test files. Minimum required:

  • Unit tests for utility functions (/common/utils.ts, /common/request.ts)
  • Unit tests for API routes with mocked axios
  • Integration tests for RTC/RTM managers
  • Component tests for critical UI components
  • At least one E2E test for the basic agent start/stop flow

4. Dockerfile: Incorrect Stage Name

File: frontend/Dockerfile:38

FROM base AS runner

The stage is named lorijenkins9511 (appears to be a username) instead of a descriptive name like runner or production.

5. Dockerfile: Path Inconsistency

File: Dockerfile:3

ARG USE_AGENT=agents/examples/spatial-walk-avatar

The path uses spatial-walk-avatar but the actual directory is spatialwalk-avatar. This will cause build failures.

6. Memory Leak: Untraceable Timeouts

File: frontend/src/manager/rtc/rtc.ts:189-230

Timeouts in handleChunk are created but not tracked. If the component unmounts, timeouts continue to execute, causing memory leaks.

Recommendation:

private timeouts = new Map<string, NodeJS.Timeout>();

handleChunk(formattedChunk: string) {
  const existingTimeout = this.timeouts.get(message_id);
  if (existingTimeout) {
    clearTimeout(existingTimeout);
  }

  const timeout = setTimeout(() => {
    if (this.messageCache[message_id]?.length !== total_parts) {
      console.warn(`Incomplete message with ID ${message_id} discarded`);
      delete this.messageCache[message_id];
    }
    this.timeouts.delete(message_id);
  }, TIMEOUT_MS);
  
  this.timeouts.set(message_id, timeout);
}

destroy() {
  this.timeouts.forEach(timeout => clearTimeout(timeout));
  this.timeouts.clear();
  this.messageCache = {};
  // ... existing cleanup
}

7. Debug Code in Production

File: frontend/src/manager/rtc/rtc.ts:174

console.log("[test] textstream raw data", ascii);

Remove all [test] console.log statements and other debug code before merging.


🟡 High Priority Issues (Should Fix)

Security & Configuration

  1. Missing CORS Configuration: No explicit CORS setup for API routes
  2. No Rate Limiting: API endpoints vulnerable to DoS attacks
  3. Axios Without Timeout: Requests can hang indefinitely (frontend/src/common/request.ts)
  4. URL Parameters Not Sanitized: frontend/src/components/authInitializer/index.tsx:58-70

Code Quality

  1. Excessive Use of any: All API functions in request.ts return any, defeating TypeScript's type safety
  2. Inconsistent Error Handling: Errors are logged but not propagated (rtc.ts:63-66)
  3. React Strict Mode Disabled: next.config.mjs:13 - Should be enabled
  4. Large Commented-Out Code Blocks: rtc.ts:174-186 - Remove dead code

Performance

  1. Large Dependencies: Multiple beta versions and heavy SDKs without bundle size monitoring
  2. Global Singleton Pattern: rtc.ts:323 - Can cause issues with SSR and testing

🟢 Positive Aspects

  • Good Docker Practices: Multi-stage builds, proper layer caching, non-root user
  • Clear Architecture: Well-organized component structure
  • Documentation: README has clear setup instructions
  • Modern Stack: Next.js 16, React 19, TypeScript

Recommendations

Overall Risk Level: HIGH (Security + No Tests + Quality Issues)

Recommendation: REQUEST CHANGES

This PR should not be merged until the critical issues are addressed. The security vulnerabilities alone (committed .env, no input validation, no rate limiting) are sufficient to block.

Action Items

Must Fix:

  1. Remove .env file from repository
  2. Add input validation to all API routes
  3. Add basic test coverage (at minimum, unit tests for critical paths)
  4. Fix Dockerfile issues (stage name, path inconsistency)
  5. Fix memory leak in timeout handling
  6. Remove all debug console.log statements
  7. Add proper TypeScript types (eliminate any returns)

Should Fix:

  1. Implement rate limiting
  2. Add CORS configuration
  3. Add axios timeouts
  4. Enable React strict mode
  5. Add JSDoc comments to public APIs
  6. Add bundle size monitoring

Future Improvements:

  1. Add E2E tests
  2. Implement proper logging system
  3. Add architecture documentation
  4. Create health check endpoints

Please address the critical issues and I'm happy to review again. The foundation is solid, but production readiness requires attention to security and testing.

@claude
Copy link

claude bot commented Feb 9, 2026

Code Review: spatialwalk-avatar Example

Thank you for this comprehensive new example! The spatialwalk-avatar implementation demonstrates solid architectural patterns with Redux state management and modular component structure. However, there are several important issues that should be addressed before merging.

🔴 Critical Security Issues

1. XSS Vulnerability in Image Rendering

File: frontend/src/components/Chat/MessageList.tsx:63

<img src={data.text} alt="chat" className="w-full" />

Risk: Direct src binding without URL validation. Malicious data could load resources from attacker servers or execute JavaScript.

Recommendation: Add URL validation/sanitization:

const isValidImageUrl = (url: string) => {
  try {
    const parsed = new URL(url);
    return ['http:', 'https:', 'data:'].includes(parsed.protocol);
  } catch {
    return false;
  }
};

// In component:
{data.text && isValidImageUrl(data.text) && (
  <img src={data.text} alt="chat" className="w-full" />
)}

2. Unsafe window.open() Usage

File: frontend/src/manager/rtc/rtc.ts:273

window.open(actionData.url, "_blank");

Risk: Opens URLs without validation - potential for phishing/malicious redirects.

Recommendation: Validate URLs before opening and add user confirmation for external links.

3. Unsafe JSON Parsing

File: frontend/src/manager/rtc/rtc.ts:240-241, 256

const { stream_id, is_final, text, text_ts, data_type, role } =
  JSON.parse(this.base64ToUtf8(completeMessage));

Risk: No error handling - malformed JSON crashes the application.

Recommendation: Wrap in try-catch and validate structure:

try {
  const decoded = this.base64ToUtf8(completeMessage);
  const parsed = JSON.parse(decoded);
  // Validate structure with Zod schema
  const validated = messageSchema.parse(parsed);
  // Use validated data
} catch (error) {
  console.error("Invalid message format:", error);
  return; // Gracefully handle
}

4. Missing Input Validation in API Route

File: frontend/src/app/api/agents/start/route.tsx:19-28

const body = await request.json();
const { request_id, channel_name, user_uid, graph_name, ... } = body;

Risk: No schema validation - accepts any malformed input.

Recommendation: Use Zod (already in dependencies) for validation:

import { z } from 'zod';

const startRequestSchema = z.object({
  request_id: z.string().uuid(),
  channel_name: z.string().min(1),
  user_uid: z.number().int().positive(),
  graph_name: z.string().min(1),
  // ... other fields
});

const body = await request.json();
const validated = startRequestSchema.parse(body); // Throws on invalid

5. Hardcoded Sensitive Configuration

File: tenapp/property.json

  • "channel": "ten_agent_test" - should use environment variable
  • "spatialreal_avatar_id": "799236a4-0263-4aee-b144-ab571c72d90c" - hardcoded UUID

Recommendation: Move to environment variables or runtime configuration.

🟡 High Priority Issues

6. Pervasive any Types

Files: frontend/src/common/request.ts (22 occurrences), rtc.ts, graph.ts

All API response handling uses any type, eliminating TypeScript's safety benefits:

let resp: any = await axios.post(url, data);
resp = resp.data || {};
return resp;

Recommendation: Define proper response interfaces:

interface StartServiceResponse {
  code: string;
  data: {
    task_id?: string;
    session_id?: string;
  } | null;
  msg: string;
}

export const apiStartService = async (
  config: StartRequestConfig
): Promise<StartServiceResponse> => {
  const { data } = await axios.post<StartServiceResponse>(url, payload);
  return data;
};

7. Poor Error Handling in API Route

File: frontend/src/app/api/agents/start/route.tsx:43-52

catch (error) {
  if (error instanceof Response) {
    const errorData = await error.json();
    return NextResponse.json(errorData, { status: error.status });
  } else {
    return NextResponse.json(
      { code: "1", data: null, msg: "Internal Server Error" },
      { status: 500 }
    );
  }
}

Issues:

  • Swallows error details (no logging for debugging)
  • error instanceof Response suggests architectural confusion
  • Throws string instead of Error: throw "Environment variables..."

Recommendation: Add structured logging and proper error types.

8. Memory Leak Risk in Message Cache

File: frontend/src/manager/rtc/rtc.ts:195-289

The incomplete message cache has timeout cleanup but no size limit:

private incompleteMessages: Map<string, IncompleteMessage> = new Map();

Risk: Corrupted total_parts header could cause unbounded growth.

Recommendation: Add max cache size (e.g., 100 entries) with LRU eviction.

🟢 Performance Concerns

9. Aggressive Polling Interval

File: frontend/src/common/hooks.ts:69

const interval = setInterval(updateVolume, 10); // 10ms interval

Impact: 100 updates/second causes excessive re-renders and CPU usage.

Recommendation: Increase to 50-100ms or use requestAnimationFrame.

10. Missing Memoization

  • MessageList.tsx: Conditional rendering without useMemo
  • Various components lack useCallback for event handlers

Recommendation: Add React.memo, useMemo, and useCallback where appropriate.

📋 Code Quality Issues

11. No Test Coverage

Status: No test files found (.test.ts, .spec.ts, __tests__/)

Critical untested code:

  • All API functions in request.ts
  • WebRTC message parsing logic in rtc.ts
  • Redux reducers (especially addChatItem)
  • All React components

Recommendation: Add at minimum:

  • Unit tests for request functions with mocked axios
  • Tests for message reconstruction logic in rtc.ts
  • Component snapshot tests

12. Unsafe Base64 Decoding

File: frontend/src/manager/rtc/rtc.ts:300-307

base64ToUtf8(base64: string): string {
  const binaryString = atob(base64); // No validation
  // ... encoding conversion
}

Issue: No validation - invalid base64 throws unhandled error.

Recommendation: Add try-catch and validation.

13. Incomplete Resource Cleanup

File: frontend/src/manager/rtc/rtc.ts:135-139

async destroy() {
  this.localTracks?.audioTrack?.close();
  this.localTracks?.videoTrack?.close();
  if (this._joined) {
    await this.client?.leave();
  }
  this._resetData();
}

Issue: screenTrack not cleaned up.

Recommendation: Add screenTrack cleanup.

🔍 Minor Issues

14. Fragile Path Dependencies

File: Taskfile.yml

- ../../../.env
- ../../../server

Hardcoded relative paths are fragile if directory structure changes.

15. Beta Dependency

File: frontend/package.json

"@spatialwalk/avatarkit": "^1.0.0-beta.80"

Using beta version in production-ready example.

✅ Positive Aspects

  • Clean separation of concerns (request layer, managers, components)
  • Modern React patterns with hooks
  • Redux Toolkit for state management
  • Proper cleanup in useEffect hooks
  • Next.js 15+ with React 19
  • TypeScript usage throughout (despite any issues)

📝 Recommendations Summary

Before merge:

  1. Fix XSS vulnerability in MessageList (image URLs)
  2. Add input validation to API endpoints
  3. Remove hardcoded IDs from property.json
  4. Add error handling to JSON parsing operations
  5. Replace critical any types with proper interfaces

Post-merge improvements:

  1. Add test coverage (at least for critical paths)
  2. Fix performance issues (polling interval, memoization)
  3. Add proper error logging throughout
  4. Document configuration options
  5. Add memory limits to message cache

Let me know if you'd like me to help address any of these issues!


Review conducted following: ai_agents/AGENTS.md guidelines (YAGNI, KISS principles)

@claude
Copy link

claude bot commented Feb 9, 2026

PR Review: Spatialwalk Avatar Example

Overview

This PR adds a new example demonstrating integration of a 3D animated avatar (spatialwalk) with the TEN Agent framework. The implementation includes a Next.js frontend with RTC/RTM communication and a complex module configuration system. While the feature is impressive, there are several critical security issues and code quality concerns that need to be addressed before merging.


🔴 Critical Issues (Must Fix Before Merge)

1. Exception Handling Anti-pattern

Location: frontend/src/app/api/agents/start/route.tsx:16

throw "Environment variables are not available";  // ❌ WRONG

Issue: Throwing a string instead of Error object breaks error handling contracts.

Impact: The catch block at line 44 checks error instanceof Response which will never match a string, causing the generic 500 error to always be returned even for environment configuration issues.

Fix:

throw new Error("Environment variables are not available");

2. Unvalidated Arbitrary URL Opening (Security Vulnerability)

Location: frontend/src/manager/rtc/rtc.ts:315-318

if (action === "browse_website") {
  console.log("Opening website", actionData.url);
  window.open(actionData.url, "_blank");  // ❌ Security Risk
  return;
}

Issue: Opens any URL received from remote messages without validation.

Risk: A malicious or compromised server could inject:

  • Phishing URLs
  • Malware download links
  • javascript: protocol URLs for XSS
  • data: URLs with malicious content

Fix: Add URL validation:

if (action === "browse_website") {
  const url = actionData.url;
  // Validate URL
  try {
    const parsed = new URL(url);
    if (!['http:', 'https:'].includes(parsed.protocol)) {
      console.error('Invalid protocol:', parsed.protocol);
      return;
    }
    // Optional: Add domain whitelist
    console.log("Opening website", url);
    window.open(url, "_blank");
  } catch (e) {
    console.error('Invalid URL:', url);
  }
}

3. Missing Error Handling in JSON Parsing (DoS Risk)

Location: frontend/src/manager/rtc/rtc.ts:284-285, 300

const { stream_id, is_final, text, text_ts, data_type, role } =
  JSON.parse(this.base64ToUtf8(completeMessage));  // ❌ No try-catch
// ...
const { data, type } = JSON.parse(text);  // ❌ No try-catch

Issue: JSON.parse on untrusted data without error handling will crash the application on malformed messages.

Fix: Already wrapped in try-catch at line 330, but should validate the structure:

try {
  const parsed = JSON.parse(this.base64ToUtf8(completeMessage));
  if (!parsed.stream_id || !parsed.text_ts) {
    console.error('Invalid message structure');
    return;
  }
  const { stream_id, is_final, text, text_ts, data_type, role } = parsed;
  // ...
}

4. Committed .env File (Security)

Location: frontend/.env

AGENT_SERVER_URL=http://localhost:8080
TEN_DEV_SERVER_URL=http://localhost:49483
NEXT_PUBLIC_EDIT_GRAPH_MODE=true

Issues:

  • .env files should NOT be committed to version control
  • Contains localhost URLs that won't work in production
  • Missing production configuration

Fix:

  1. Remove frontend/.env from git
  2. Create frontend/.env.example with template values
  3. Update .gitignore to exclude .env
  4. Document required environment variables in README

🟠 High Priority Issues

5. No Input Validation on API Endpoint

Location: frontend/src/app/api/agents/start/route.tsx:19-28

The endpoint accepts and forwards all request parameters without validation:

  • request_id, channel_name, user_uid - no length limits
  • properties - arbitrary object forwarded to backend
  • No CSRF protection
  • No rate limiting

Recommendation: Add input validation with a schema validator (zod, joi, etc.)


6. Memory Leak in Event Listeners

Location: frontend/src/manager/rtm/index.ts:132-138

this._client?.removeEventListener("message", this.handleRtmMessage.bind(this));

Issue: bind(this) creates a new function instance, so the listener is never actually removed.

Fix: Store bound functions as instance members:

constructor() {
  this.boundHandleRtmMessage = this.handleRtmMessage.bind(this);
}

// Then use:
this._client.addEventListener("message", this.boundHandleRtmMessage);
this._client.removeEventListener("message", this.boundHandleRtmMessage);

7. AudioContext Memory Leak

Location: frontend/src/common/hooks.ts:36

const ctx = new AudioContext();
// No cleanup on unmount

Creates a new AudioContext on each track change but never closes it.

Fix:

useEffect(() => {
  const ctx = new AudioContext();
  // ... use ctx
  return () => ctx.close();
}, [/* deps */]);

8. Sensitive Data Logging

Location: Multiple files

// rtc.ts:287
console.log(`[test] message_id: ${message_id} stream_id: ${stream_id}...`);

// rtm/index.ts:56
console.log("[RTM] [TRTMMessageEvent] RAW", JSON.stringify(e));

Issue: Logs may contain tokens, user data, or sensitive message content.

Fix: Use proper log levels and sanitize sensitive data before logging.


🟡 Code Quality Issues

9. Zero Test Coverage

  • No unit tests found for any components, managers, or utilities
  • Complex message chunking/reconstruction logic untested (rtc.ts:280-342)
  • API endpoint untested
  • High risk for regressions

Recommendation: Add tests for at least:

  • Message parsing and chunking logic
  • API route with mocked axios
  • RTC/RTM manager lifecycle

10. Type Safety Issues

  • Excessive use of any types (rtm/index.ts:9, rtc/types.ts)
  • Untyped message structures
  • Missing null checks for optional properties

11. Race Condition in Avatar Initialization

Location: frontend/src/components/Agent/AvatarSpatialwalk.tsx:18-33

Module-level mutable state shared across component instances:

let initKey: string | null = null;
let initPromise: Promise<void> | null = null;

If multiple components mount simultaneously, SDK cleanup might be called while another instance is initializing.


12. Inefficient Deep Clone

Location: frontend/src/components/Chat/ChatCfgModuleSelect.tsx

const selectedGraphCopy: Graph = JSON.parse(JSON.stringify(selectedGraph));

Using JSON serialization for cloning is slow and loses methods. Use structuredClone() instead.


📋 Additional Recommendations

Docker Security

  • Dockerfile:62,65: Installing software with curl ... | bash is risky
    • No signature verification
    • Subject to MITM attacks
    • Recommend: Use package manager or verify checksums

Missing Documentation

  • No architecture overview
  • No security guidelines
  • Incomplete API documentation
  • Missing deployment guide

Configuration

  • Hardcoded module registry (moduleConfig.ts)
  • No plugin mechanism for extensibility
  • Magic numbers and timeouts not configurable

Summary

Category Count
🔴 Critical Security Issues 4
🟠 High Priority 4
🟡 Code Quality 4
Missing Tests 100%

Blocking Issues

  1. Fix exception throwing (route.tsx:16)
  2. Validate URLs before window.open (rtc.ts:316)
  3. Remove committed .env file
  4. Add input validation to API endpoint

Recommended Before Merge

  1. Fix memory leaks (event listeners, AudioContext)
  2. Add basic test coverage for critical paths
  3. Remove sensitive data from logs
  4. Add proper error handling and validation

Positive Aspects ✅

  • Clean multi-stage Docker builds
  • Good use of TypeScript for type safety
  • Modern React patterns with hooks
  • Comprehensive module configuration system
  • Well-structured component hierarchy

Great work on this feature! The avatar integration is impressive. Please address the security issues before merging, and consider adding tests for the complex message handling logic.

🤖 Generated with Claude Code

@claude
Copy link

claude bot commented Feb 10, 2026

PR Review: Spatialwalk-Avatar Example

Thank you for this substantial contribution adding a new Spatialwalk avatar integration example. The overall architecture follows TEN Framework patterns well, but there are critical security issues and several code quality improvements needed before merging.


🔴 CRITICAL Issues (Must Fix Before Merge)

1. Environment File Committed to Repository

Files:

  • ai_agents/agents/examples/spatialwalk-avatar/frontend/.env
  • ai_agents/agents/examples/spatialwalk-avatar/frontend/.gitignore:77

Issue: The .env file is tracked in git due to a .gitignore negation rule:

# .env
!.env  #  This negates the ignore, exposing .env to git

Risk: High - Could expose API keys and credentials if developers commit sensitive data

Fix Required:

# Remove from repository
git rm --cached ai_agents/agents/examples/spatialwalk-avatar/frontend/.env

# Fix .gitignore - remove the negation line (!.env)

2. API Token Logged in Plaintext

File: ai_agents/agents/ten_packages/extension/spatialreal_avatar_python/extension.py:136

ten_env.log_info(
    f"[SpatialReal] Agora token: {self.config.agora_token}"  # ❌ Full token exposed
)

Risk: Medium-High - Tokens in logs could be exposed in CI/CD pipelines, monitoring systems, or log files

Fix Required: Redact sensitive values (following the pattern already used on line 98):

ten_env.log_info(
    f"[SpatialReal] Agora token: {'***' + self.config.agora_token[-8:] if len(self.config.agora_token) > 8 else '***'}"
)

🟡 HIGH Priority Issues

3. Missing Input Validation in API Route

File: ai_agents/agents/examples/spatialwalk-avatar/frontend/src/app/api/agents/start/route.tsx

Issues:

a) Line 16 - Throwing string instead of Error object:

throw "Environment variables are not available";  // ❌ Anti-pattern

b) Lines 19-28 - No validation on user input:

const { request_id, channel_name, user_uid, graph_name, ... } = body;
// No validation - accepts any malformed input

Recommendation:

// Fix error handling
if (!AGENT_SERVER_URL) {
  throw new Error("Environment variables are not available");
}

// Add zod validation
import { z } from 'zod';

const bodySchema = z.object({
  request_id: z.string(),
  channel_name: z.string().min(1).max(64),
  user_uid: z.number().int().positive(),
  graph_name: z.string().min(1),
  language: z.string().optional(),
  voice_type: z.enum(['male', 'female']).optional(),
  properties: z.record(z.any()).optional(),
});

const body = bodySchema.parse(await request.json());

4. Excessive Debug Logging in Production Code

Files: 30+ instances across frontend code

Examples:

  • frontend/src/manager/rtc/rtc.ts:221: console.log("[test] textstream raw data", ascii);
  • frontend/src/components/Layout/HeaderComponents.tsx:123: console.log(color);
  • frontend/src/store/reducers/global.ts:154: console.log("[test] addChatItem...

Recommendation: Remove debug logs or make them conditional:

if (process.env.NODE_ENV === 'development') {
  console.log('[debug] ...');
}

5. README Title Incorrect

File: ai_agents/agents/examples/spatialwalk-avatar/README.md:1-3

Issue: Title says "Voice Assistant" instead of "Spatialwalk Avatar"

Fix: Update the README title to accurately reflect this example.


🟢 MEDIUM Priority Issues

6. Missing Error Handling

File: ai_agents/agents/ten_packages/extension/spatialreal_avatar_python/extension.py:125-133

Token generation has no try/except block - could raise exceptions on invalid config:

self.config.agora_token = RtcTokenBuilder.build_token_with_user_account(
    self.config.agora_appid,  # Could fail with invalid values
    ...
)

Recommendation: Add error handling with descriptive messages.

7. Missing Frontend .env.example

The tenapp has .env.example, but the frontend directory doesn't. This makes it unclear what environment variables are needed for frontend development.

Recommendation: Create frontend/.env.example documenting required variables.


🔵 Optional Improvements

Dockerfile Security

File: ai_agents/agents/examples/spatialwalk-avatar/Dockerfile

  1. Line 60-62 - Unverified script execution:
RUN curl -fsSL https://bun.com/install | bash  # No version pinning or checksum verification
  1. Missing USER directive - Container runs as root

Recommendation:

  • Pin bun version or verify checksum
  • Add non-root user for runtime security

Code Organization

  1. Large file: frontend/src/common/graph.ts (578 lines) could be split into smaller, focused modules
  2. No rate limiting: API endpoints could benefit from rate limiting
  3. Custom frontend: Consider whether shared playground/ could be extended instead of maintaining separate frontend

✅ Strengths

Great work on:

  • Following TEN Framework extension patterns correctly
  • Proper use of Pydantic for config validation
  • Correct environment variable substitution (${env:SPATIALREAL_API_KEY})
  • Well-structured directory layout matching other examples
  • Good abstraction with AsyncAvatarBaseExtension base class
  • Proper audio frame handling following established patterns
  • Multi-stage Dockerfile for smaller images

Summary

Severity Count Must Fix Before Merge
🔴 Critical 2 ✅ Yes
🟡 High 3 ⚠️ Recommended
🟢 Medium 2 Optional
🔵 Low 3 Optional

Overall Assessment: This is a solid implementation that demonstrates good understanding of the TEN Framework architecture. However, the critical .env exposure and token logging issues must be resolved before merging to prevent potential security incidents.

Please address the critical and high-priority issues, and I'll be happy to review again.

@claude
Copy link

claude bot commented Feb 10, 2026

Pull Request Review: Spatialwalk Avatar Example

Overview

This PR adds a new comprehensive example application (spatialwalk-avatar) to the TEN framework, implementing a voice assistant with real-time avatar capabilities using Agora RTC, Deepgram STT, OpenAI LLM, and ElevenLabs TTS.

Scale: 166 files, 22,833 additions | Type: New example application


Critical Issues

1. Environment File Committed to Repository

Location: frontend/.env

The .env file should NEVER be committed to the repository. Please remove it and create frontend/.env.example instead.

2. Missing Error Response Validation

Location: frontend/src/common/request.ts

Most API functions don't validate response codes. Only apiGetDocumentList checks resp.code. Add validation to all API functions.

3. Inadequate Error Handling in API Route

Location: frontend/src/app/api/agents/start/route.tsx:16-17

Throwing a string instead of an Error object. Should return proper NextResponse with error details.


Significant Issues

4. Overly Permissive Type Usage

Extensive use of 'any' type throughout frontend/src/common/request.ts defeats TypeScript safety. Define proper response interfaces.

5. Incorrect Error Handling Pattern

Location: frontend/src/app/api/agents/start/route.tsx:43-52

Checks for 'error instanceof Response' but axios throws AxiosError, not Response. This catch block will never work correctly.

6. Hardcoded Base Directory

Multiple functions use hardcoded base_dir: "." which may not work in all deployments.


Minor Issues

  • README Inconsistency: Title says "Voice Assistant" but should be "Spatialwalk Avatar". Paths reference voice-assistant instead of spatialwalk-avatar
  • Missing Input Validation: API routes don't validate required fields from request body
  • Dependency Versions: Consider exact versions for critical dependencies instead of caret ranges
  • Missing Cleanup: Ensure RTC manager has proper destroy/cleanup method to prevent memory leaks

Positive Observations

  • Good Docker multi-stage build for minimal image size
  • Comprehensive Taskfile with well-organized development workflow
  • Clean component architecture with proper separation of concerns
  • Full TypeScript usage
  • Uses shadcn/ui for consistent UI components

Test Coverage

No test files visible in this 22k+ line PR. Consider adding unit tests for API functions, integration tests for RTC manager, and E2E tests.


Security

  • ✅ Environment variables for sensitive data
  • ✅ No hardcoded credentials
  • ⚠️ .env file committed (Critical Issue 1)
  • ⚠️ No rate limiting on API routes
  • ✅ HTTPS for external downloads

Summary

This is a substantial and well-structured example that demonstrates TEN framework capabilities well. Code quality is generally good.

Must fix before merging:

  1. Remove committed .env file
  2. Add response validation to API functions
  3. Fix error handling in API routes
  4. Improve TypeScript type usage
  5. Fix axios error handling pattern
  6. Update README paths

Effort: 2-3 hours for critical issues.

Great work on the implementation! 🚀

@claude
Copy link

claude bot commented Feb 10, 2026

Pull Request Review: Spatialwalk Avatar Example

Thank you for this comprehensive addition to the TEN Framework! This PR introduces a feature-rich spatialwalk avatar example with 166 files and 22,833 lines of code. The implementation demonstrates excellent understanding of the TEN Framework conventions and includes well-structured React/Next.js code with Agora RTC integration.

🎯 Overall Assessment

Status: APPROVE WITH REQUIRED CHANGES

The codebase is fundamentally sound with good architectural patterns, but there are several security and code quality issues that should be addressed before merging.


🔴 Critical Issues (Must Fix)

1. Unvalidated JSON Parsing in RTM Messages

File: frontend/src/manager/rtm/index.ts:98

const msg: IRTMTextItem = JSON.parse(message as string);

Issue: No validation of parsed JSON structure, potential for injection attacks.

Fix:

try {
  const parsed = JSON.parse(message as string);
  // Add schema validation here (e.g., Zod)
  const msg = IRTMTextItemSchema.parse(parsed);
  console.log("[RTM] Parsed message:", msg);
} catch (error) {
  console.error("[RTM] Invalid message format:", error);
  return;
}

2. Unsafe Image URL Rendering

File: frontend/src/components/Chat/MessageList.tsx:63

<img src={data.text} alt="chat" className="w-full" />

Issue: data.text used directly without URL validation. Could allow malicious URLs.

Fix:

const isValidImageUrl = (url: string): boolean => {
  try {
    const parsed = new URL(url);
    return ['http:', 'https:'].includes(parsed.protocol);
  } catch {
    return false;
  }
};

{data.data_type === EMessageDataType.IMAGE && isValidImageUrl(data.text) ? (
  <img src={data.text} alt="chat" className="w-full" />
) : (
  <p>{data.text}</p>
)}

3. No Input Validation in Start Agent API

File: frontend/src/app/api/agents/start/route.tsx:19-38

Issue: Request body parsed without validation.

Fix: Add Zod schema validation:

import { z } from "zod";

const StartAgentSchema = z.object({
  request_id: z.string().uuid(),
  channel_name: z.string().min(1).max(64),
  user_uid: z.number().min(0),
  graph_name: z.string().min(1),
  language: z.string().optional(),
  voice_type: z.enum(["male", "female"]).optional(),
  properties: z.record(z.any()).optional(),
});

const body = await request.json();
const validatedBody = StartAgentSchema.parse(body);

4. Throwing Strings Instead of Error Objects

Files: frontend/src/app/api/agents/start/route.tsx:16, frontend/src/proxy.tsx:7-8

throw "Environment variables are not available";  // ❌

Fix:

throw new Error("Environment variable AGENT_SERVER_URL is not configured");  // ✅

🟡 High Priority Issues

5. Axios Dependency Outdated

File: frontend/package.json

Current: axios: "^1.13.1"
Latest: axios: "^1.7.7"

Please update to the latest version for security patches.

6. Missing Request Timeouts

File: frontend/src/common/request.ts

Fix: Configure axios with timeouts:

const axiosInstance = axios.create({
  timeout: 30000, // 30 seconds
});

7. Loose Type Checking Operators

File: frontend/src/manager/rtc/rtc.ts:70, 92

if (code == 0) {  // Should be ===
if (code != 0) {  // Should be !==

Please use strict equality operators throughout.

8. Docker Security: Running as Root

File: Dockerfile

Recommendation: Create and use a non-root user:

RUN useradd -m -u 1000 appuser
USER appuser

🟢 Code Quality Suggestions

9. Excessive Use of any Type

Files: frontend/src/manager/rtm/index.ts:9, frontend/src/common/request.ts:36

Consider defining proper interfaces instead of any:

interface RTMMessagePayload {
  type: ERTMTextType;
  text: string;
  ts: number;
  stream_id: string;
  is_final: boolean;
}

rtmMessage: (text: RTMMessagePayload) => void;

10. Debug Logging in Production

File: frontend/src/manager/rtm/index.ts:56

logLevel: "debug", // TODO: use INFO

Recommendation:

logLevel: process.env.NODE_ENV === 'production' ? 'info' : 'debug',

11. Generic Error Messages

File: frontend/src/app/api/agents/start/route.tsx:50

Consider logging the actual error for debugging while returning safe messages to users:

} catch (error) {
  console.error('[API] Start agent error:', error);
  return NextResponse.json(
    { code: "1", data: null, msg: "Failed to start agent" },
    { status: 500 }
  );
}

✅ Positive Aspects

  1. Excellent Framework Compliance - Follows TEN Framework conventions perfectly
  2. Strong TypeScript Configuration - strict: true enabled
  3. Good Component Architecture - Clear separation of concerns
  4. Modern React Patterns - Proper hooks usage, dynamic imports, cleanup
  5. Comprehensive Documentation - Good README with setup instructions
  6. Docker Multi-stage Build - Optimized production builds
  7. Environment Variable Handling - Proper use of env variable syntax

📋 Review Checklist

Before merging, please ensure:

  • All critical security issues fixed (items 1-4)
  • Input validation added to all API endpoints
  • Axios dependency updated
  • Request timeouts configured
  • Strict equality operators used throughout
  • Docker runs as non-root user
  • any types replaced with proper interfaces
  • Production log levels configured
  • Run npm audit to check for dependency vulnerabilities

🎓 Additional Recommendations

  1. Add Tests - Consider adding test coverage for API routes and critical components
  2. API Documentation - Add JSDoc comments to API endpoints
  3. Error Boundary - Consider adding React error boundaries for better error handling
  4. Rate Limiting - Consider adding rate limiting to the proxy middleware

Summary

This is a high-quality contribution that demonstrates the TEN Framework's capabilities well. The implementation is solid, but the security issues around input validation and error handling should be addressed before production use. Once the critical items are fixed, this will be an excellent addition to the examples.

Estimated effort to address critical issues: 2-4 hours

Thank you for your contribution! 🚀

@claude
Copy link

claude bot commented Feb 10, 2026

PR Review: Spatialwalk Avatar Integration

Summary

This PR adds a new example agent that integrates Spatialwalk avatar functionality into the TEN framework. The implementation adds 22,833 lines across 97 files, including a complete frontend, Docker configuration, and custom Python extension for avatar control.

Code Quality & Best Practices

✅ Strengths

  1. Consistent Architecture: Follows the established TEN framework patterns correctly

    • Standard multi-stage Dockerfile using ten_agent_build:0.7.12
    • Proper Taskfile.yml structure with install/run/release tasks
    • Correct graph-based configuration in property.json
    • Extension structure follows framework conventions
  2. Good Separation of Concerns: The custom main_python extension is well-structured

    • Clean event-driven architecture with decorators
    • Proper separation between Agent class and Extension
    • Good use of async/await patterns
  3. Frontend Architecture: Modern Next.js 16 setup with good practices

    • TypeScript with strict typing
    • Radix UI components for accessibility
    • Redux Toolkit for state management
    • Biome for linting

⚠️ Issues & Concerns

1. Critical: Base Image Version Mismatch

Location: Dockerfile:1

FROM ghcr.io/ten-framework/ten_agent_build:0.7.12 AS builder

Issue: Using older base image (0.7.12) while the voice-assistant-live2d example uses 0.7.14
Recommendation: Update to the latest stable version for consistency and bug fixes.

2. Security: Environment Variable Exposure

Location: frontend/.env:1-3

AGENT_SERVER_URL=http://localhost:8080
TEN_DEV_SERVER_URL=http://localhost:49483
NEXT_PUBLIC_EDIT_GRAPH_MODE=true

Issues:

  • .env file is committed to the repository (should be .env.example)
  • NEXT_PUBLIC_EDIT_GRAPH_MODE=true in source control enables edit mode by default
  • Production builds override this correctly, but development mode exposes the graph editor

Recommendation:

  • Remove frontend/.env from git and add to .gitignore
  • Create frontend/.env.example instead
  • Set NEXT_PUBLIC_EDIT_GRAPH_MODE=false as the default in .env.example

3. Missing Documentation

Location: README.md:1-195

Issues:

  • README appears to be a copy of the voice-assistant README without customization
  • No mention of Spatialwalk-specific requirements
  • Missing documentation for SPATIALREAL_API_KEY and SPATIALREAL_APP_ID environment variables
  • No explanation of avatar-specific configuration options
  • Title is "Voice Assistant" instead of "Spatialwalk Avatar"

Recommendation: Update README to:

  • Change title to "Spatialwalk Avatar Voice Assistant"
  • Add Spatialwalk prerequisites section
  • Document all Spatialwalk-specific environment variables
  • Explain avatar configuration parameters (avatar_id, endpoints, etc.)
  • Add links to Spatialwalk documentation

4. Incomplete Environment Configuration

Location: tenapp/.env.example:1-2

SPATIALREAL_API_KEY=
SPATIALREAL_APP_ID=

Issues:

  • Missing other required environment variables (AGORA_APP_ID, DEEPGRAM_API_KEY, etc.)
  • Inconsistent with other examples that include all variables

Recommendation: Include all required environment variables in the example file with comments explaining each one.

5. Hardcoded Configuration Values

Location: tenapp/property.json:112-119

"spatialreal_console_endpoint_url": "https://console.us-west.spatialwalk.cloud/v1/console",
"spatialreal_ingress_endpoint_url": "wss://api.us-west.spatialwalk.cloud/v2/driveningress",
"spatialreal_avatar_id": "76f63fee-a6ed-4a79-b689-45f8211e3917"

Issues:

  • Hardcoded US West endpoints (no environment variable fallback)
  • Hardcoded avatar ID with no explanation or customization option
  • Region selection not configurable

Recommendation:

  • Make endpoints configurable via environment variables with defaults
  • Document how to obtain/customize avatar ID
  • Consider supporting multiple regions

6. Frontend Code Quality Issues

Location: frontend/src/app/api/agents/start/route.tsx:16-17

if (!AGENT_SERVER_URL) {
  throw "Environment variables are not available";
}

Issue: Throwing strings instead of Error objects

Recommendation:

throw new Error("AGENT_SERVER_URL environment variable is not configured");

Location: frontend/src/common/request.ts:36,50,69,81

let resp: any = await axios.post(url, data);

Issue: Extensive use of any type defeats TypeScript's type safety

Recommendation: Define proper response interfaces

Security Concerns

🔴 High Priority

  1. Committed .env file: frontend/.env contains configuration that should not be in source control

  2. No input validation: API route handlers don't validate request parameters

    • Missing validation in route.tsx for request body fields
    • No sanitization of user inputs before forwarding to backend
  3. Error Information Disclosure: Generic error handling may leak internal details

    • Consider implementing proper error sanitization for production

🟡 Medium Priority

  1. Axios without timeout: No timeout configuration could lead to hanging requests
  2. Missing CORS configuration: Frontend API routes don't explicitly configure CORS
  3. No rate limiting: API endpoints lack rate limiting protection

Performance Considerations

Frontend

  • ✅ Next.js production build with optimization enabled
  • ✅ Using Bun for faster package installation and builds
  • ✅ Proper code splitting with dynamic imports
  • ⚠️ Large bundle size (1158 lines in bun.lock) - consider lazy loading avatar components

Backend

  • ✅ Efficient async/await patterns in Python extension
  • ✅ Proper stream handling for audio processing
  • ✅ Multi-stage Docker build reduces final image size

Test Coverage

❌ Critical Gap: No Tests

  • No unit tests found for custom Python extension
  • No integration tests for avatar functionality
  • No frontend component tests
  • No API route tests

Recommendation: Add at minimum:

  • Unit tests for extension.py event handlers
  • Integration tests for Spatialwalk API communication
  • Frontend component tests for avatar rendering

Missing Components

  1. No .dockerignore file: Could result in unnecessary files in build context
  2. No CI/CD configuration: Other examples may have GitHub Actions workflows
  3. No CHANGELOG: Significant feature addition should be documented
  4. No example .env.local: Frontend needs example environment configuration

Recommendations Summary

Must Fix Before Merge

  1. ✅ Remove frontend/.env from git, create .env.example instead
  2. ✅ Update README with Spatialwalk-specific documentation
  3. ✅ Update base Docker image to latest version (0.7.14+)
  4. ✅ Fix TypeScript error handling (throw Error objects, not strings)
  5. ✅ Document all required environment variables properly

Should Fix

  1. Make Spatialwalk endpoints configurable via environment variables
  2. Add input validation to API routes
  3. Replace any types with proper TypeScript interfaces
  4. Add basic test coverage for critical paths
  5. Complete tenapp/.env.example with all required variables

Nice to Have

  1. Add request timeout and retry logic for external API calls
  2. Implement proper error logging and monitoring
  3. Add performance monitoring for avatar rendering
  4. Create troubleshooting guide in README
  5. Add example configurations for different use cases

Overall Assessment

This is a substantial addition that follows TEN framework conventions well. The core implementation is solid, but there are important issues around documentation, security configuration, and production readiness that should be addressed.

Recommendation: Request changes before merge to address the critical issues (particularly environment configuration and documentation).


🤖 Generated with Claude Code

@claude
Copy link

claude bot commented Feb 10, 2026

Code Review - PR #2043: Feat/spatialwalk

Thank you for this substantial contribution! This PR adds 166 files with a well-architected Next.js/React frontend. However, I have identified several security vulnerabilities and code quality issues that should be addressed before merging.

🔴 Critical Security Issues

1. XSS Vulnerability - Unvalidated window.open()

Location: frontend/src/manager/rtc/rtc.ts:317

The URL comes from untrusted stream data without validation. This allows execution of arbitrary JavaScript via javascript:, data:, or vbscript: protocols.

Fix: Validate URL protocol before opening:

if (action === "browse_website") {
  const url = new URL(actionData.url);
  const allowedProtocols = ["http:", "https:"];
  if (!allowedProtocols.includes(url.protocol)) {
    console.error("Invalid URL protocol:", url.protocol);
    return;
  }
  window.open(url.href, "_blank");
}

2. Unsafe JSON Parsing Without Validation

Locations: frontend/src/manager/rtm/index.ts:98,107 and frontend/src/manager/rtc/rtc.ts:285,300

JSON parsing on untrusted data without try-catch or schema validation can cause crashes or type confusion. Use Zod for runtime validation.

3. Missing CSRF Protection on API Routes

Location: frontend/src/app/api/agents/start/route.tsx

API route accepts POST from any origin, vulnerable to CSRF attacks. Add origin/referer validation.

4. Unvalidated URL Parameters

Location: frontend/src/components/Agent/AvatarSpatialwalk.tsx:66

URL parameter avatarId is used without validation. Add regex validation for expected format.

🟡 High Priority Issues

  • Unsafe Base64 decoding without error handling (rtc.ts:344-350)
  • 25+ instances of any type defeating TypeScript safety
  • Missing security headers in Next.js config
  • Memory leak in MutationObserver (missing cleanup in hooks.ts:94-107)
  • Generic error handling that does not distinguish error types
  • Missing input validation on chat input (no maxLength)

🐳 Docker Security

  • Container runs as root user (should create non-root user)
  • Base images not pinned to digest (reproducibility concern)

✅ Positive Findings

  1. Good TypeScript configuration with strict mode enabled
  2. Proper project structure and separation of concerns
  3. Dependency management using lock files
  4. Code splitting with dynamic imports
  5. Environment variable handling using Next.js conventions

📋 Recommendations

Before Merge (Required)

  1. Fix XSS vulnerability in window.open()
  2. Add validation to all JSON.parse() calls
  3. Implement CSRF protection on API routes
  4. Validate URL parameters (avatarId, graph)
  5. Add error handling to unsafe operations

After Merge (High Priority)

  1. Replace any types with proper interfaces
  2. Add security headers to Next.js config
  3. Fix memory leaks in React hooks
  4. Update Docker to run as non-root user
  5. Add input validation to all user inputs

Summary

This is a well-structured feature with good architectural decisions. However, the security vulnerabilities (especially the XSS risk in window.open()) must be addressed before merging to production.

Recommendation: Request changes for critical security issues, then approve once addressed.

@claude
Copy link

claude bot commented Feb 10, 2026

PR #2043 Code Review: Spatialwalk-Avatar Example Agent

Thank you for this contribution! I've conducted a comprehensive review of the PR. Below are my findings organized by category.

🔴 Critical Security Issues

1. Environment File Not Properly Ignored

Location: ai_agents/agents/examples/spatialwalk-avatar/frontend/.env

The .env file appears to be committed to the repository. This file should be added to .gitignore to prevent accidentally committing sensitive credentials.

Recommendation:

  • Remove .env from git tracking
  • Ensure .gitignore has .env listed
  • Create .env.example instead with placeholder values

2. No Input Validation in API Route

Location: frontend/src/app/api/agents/start/route.tsx:16-25

The API endpoint accepts all request body fields without validation:

const { request_id, channel_name, user_uid, graph_name, language, voice_type, properties } = body;

Recommendation: Add schema validation using Zod or similar:

import { z } from 'zod';

const startAgentSchema = z.object({
  request_id: z.string().uuid(),
  channel_name: z.string().min(1),
  user_uid: z.number().int().positive(),
  graph_name: z.string().min(1),
  // ... etc
});

3. XSS Vulnerability Risk

Location: frontend/src/components/Chat/MessageList.tsx:63

User-controlled content is directly used as image URL without validation:

<img src={data.text} alt="chat" className="w-full" />

Recommendation: Validate URLs against a whitelist of allowed protocols/domains, or use a Content Security Policy.

4. Plaintext Credential Storage

Location: frontend/src/common/storage.ts

Sensitive data stored in localStorage without encryption:

localStorage.setItem(OPTIONS_KEY, JSON.stringify(options));

Recommendation: Use secure, httpOnly cookies for auth tokens, or implement encryption for localStorage values.


⚠️ Code Quality Issues

TypeScript Type Safety

Problem: Pervasive use of any type defeats TypeScript's benefits

Locations:

  • frontend/src/common/request.ts: Lines 37, 51, 73, 85, 93, 115, 128, 137, 152
  • frontend/src/manager/rtc/rtc.ts: Multiple instances

Example:

let resp: any = await axios.get(url);  // No type safety!

Recommendation: Define proper interfaces for API responses:

interface GraphResponse {
  data: {
    data: Array<{ name: string }>;
  };
}

const resp = await axios.get<GraphResponse>(url);
return resp.data.data.map(graph => ({ name: graph.name }));

Error Handling Anti-patterns

Location: frontend/src/app/api/agents/start/route.tsx:16

Throwing strings instead of Error objects:

throw "Environment variables are not available";  // ❌
throw new Error("Environment variables are not available");  // ✅

Location: tenapp/ten_packages/extension/main_python/agent/agent.py:72-79

Generic exception handling without distinction:

except Exception as e:
    self.ten_env.log_error(f"Handler error for {etype}: {e}")

Recommendation: Create custom exception classes and handle specific errors differently.


🐛 Potential Bugs

1. Race Condition in Avatar Initialization

Location: frontend/src/components/Agent/AvatarSpatialwalk.tsx

Uses boolean flag for cancellation instead of AbortController:

let cancelled = false;
// ... multiple async operations
if (cancelled) return;

Recommendation: Use AbortController for proper cancellation:

const abortController = new AbortController();
// Pass signal to fetch calls
fetch(url, { signal: abortController.signal });

2. Unsafe Type Coercion

Location: tenapp/ten_packages/extension/main_python/extension.py:85

self.session_id = event.metadata.get("session_id", "100")
stream_id = int(self.session_id)  # Could raise ValueError

Recommendation: Add error handling:

try:
    stream_id = int(self.session_id)
except ValueError:
    self.ten_env.log_error(f"Invalid session_id: {self.session_id}")
    return

3. Non-unique React Keys

Location: frontend/src/components/Chat/MessageList.tsx:30

Using timestamp as key may not be unique:

{chatItems.map((item, index) => {
  return <MessageItem data={item} key={item.time} />;
})}

Recommendation: Use a unique identifier or generate UUIDs for messages.


🚀 Performance Issues

1. No Message List Virtualization

Location: frontend/src/components/Chat/MessageList.tsx

All messages rendered at once without virtualization. This will cause performance degradation with large chat histories.

Recommendation: Use react-window or react-virtual:

import { FixedSizeList } from 'react-window';

<FixedSizeList
  height={600}
  itemCount={chatItems.length}
  itemSize={80}
>
  {({ index, style }) => (
    <div style={style}>
      <MessageItem data={chatItems[index]} />
    </div>
  )}
</FixedSizeList>

2. Unbounded Queues in Python

Location: tenapp/ten_packages/extension/main_python/agent/agent.py

self._asr_queue: asyncio.Queue[ASRResultEvent] = asyncio.Queue()
self._llm_queue: asyncio.Queue[LLMResponseEvent] = asyncio.Queue()

Unbounded queues could grow indefinitely if consumer is slow.

Recommendation: Set maxsize:

self._asr_queue: asyncio.Queue[ASRResultEvent] = asyncio.Queue(maxsize=100)

🐳 Docker/Deployment Issues

1. Running as Root

Location: Dockerfile

No explicit USER directive; container runs as root.

Recommendation: Add non-root user:

RUN useradd -m -u 1000 appuser
USER appuser

2. Unnecessary Tools in Production

Location: Dockerfile:39-53

Installing development tools (vim, jq) in production image:

Recommendation: Remove unnecessary tools or create separate debug image.

3. Supply Chain Security

Location: Dockerfile:56-60

Piping curl to bash from third-party sources without verification:

RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
RUN curl -fsSL https://bun.com/install | bash

Recommendation: Use official base images or verify checksums of downloaded scripts.


📋 Additional Recommendations

Missing Components

  1. Tests: No test files visible in the PR
  2. Documentation: Missing API documentation and deployment guide
  3. Error Boundaries: React components lack error boundaries
  4. Rate Limiting: API endpoints not protected against abuse
  5. Monitoring: No structured logging or metrics collection

Code Organization

  1. Consider extracting common types to shared types file
  2. Create utility functions for repeated API patterns
  3. Add JSDoc comments to complex functions

Configuration

  1. Use environment variable validation library (e.g., envalid)
  2. Add runtime configuration validation in Python using Pydantic field validators

Summary

This PR adds substantial functionality but requires security and stability hardening before production use. The priority issues are:

Must Fix:

  1. ✅ Fix .env file exposure
  2. ✅ Add input validation to API routes
  3. ✅ Address XSS vulnerability in image rendering
  4. ✅ Implement proper TypeScript typing (remove any types)
  5. ✅ Add error handling with typed exceptions

Should Fix:

  1. Add comprehensive tests
  2. Implement message list virtualization
  3. Add proper configuration validation
  4. Improve Docker security
  5. Add request timeout handling

Nice to Have:

  1. Add monitoring and structured logging
  2. Implement rate limiting
  3. Add CORS configuration
  4. Create comprehensive documentation
  5. Add input sanitization utilities

Happy to discuss any of these findings or help with implementation! 🚀

@claude
Copy link

claude bot commented Feb 10, 2026

Pull Request Review: Spatialwalk Avatar Example

Thank you for this comprehensive contribution! This PR adds 167 files with 22,830 additions. I've completed a thorough security and code quality review.

Critical Security Vulnerabilities

1. Unsafe JSON.parse Without Validation - XSS Risk

Location: frontend/src/manager/rtc/rtc.ts:285, 300
Severity: HIGH

Parsing untrusted RTC stream messages without validation could lead to prototype pollution. No try-catch around JSON.parse can crash the application. Parsed text is directly used in UI without sanitization. window.open() can be triggered from remote messages without user confirmation.

Recommendation: Add Zod schema validation, wrap in try-catch, sanitize all text before rendering.

2. Insecure Type Coercion in Error Checks

Location: rtc.ts:70, 92, Action.tsx:50, 97, 98
Severity: MEDIUM-HIGH

Using == instead of === allows type coercion. API returns both string "0" and number 0 in different places.

Recommendation: Use strict equality (===) everywhere and ensure consistent API response types.

3. Weak Random Number Generation

Location: frontend/src/common/utils.ts:17-18
Severity: MEDIUM

Math.random() is not cryptographically secure. Only 6-digit range makes user IDs easily guessable.

Recommendation: Use crypto.getRandomValues() for cryptographically secure random generation.

4. Unsafe localStorage Without Validation

Location: frontend/src/common/storage.ts:13, 29
Severity: MEDIUM

localStorage can be poisoned by XSS attacks.

Recommendation: Add schema validation for all localStorage data.

5. No Input Validation on API Requests

Location: frontend/src/common/request.ts
Severity: MEDIUM

Properties object passed to backend without validation.

Recommendation: Add input validation using Zod before sending to API.

6. Prototype Pollution in Deep Merge

Location: frontend/src/common/utils.ts:92-103
Severity: LOW-MEDIUM

No safeguards against proto, constructor, prototype keys.

Recommendation: Add checks to skip dangerous keys or use a battle-tested library.

Code Quality Issues

7. Poor Error Handling

Throwing strings instead of Error objects. Many async functions lack try-catch blocks.

Recommendation: Always throw Error objects, add proper error handling and error boundaries.

8. Memory Leak Risks in RTC Manager

Location: frontend/src/manager/rtc/rtc.ts:268-273
Severity: MEDIUM

Timeouts not cleared when component unmounts. messageCache grows unbounded.

Recommendation: Track timeouts and clear them in cleanup, add max cache size limits.

9. Race Condition in Ping Interval

Location: frontend/src/components/Layout/Action.tsx:115-129
Severity: MEDIUM

Module-level variable can cause issues with multiple instances.

Recommendation: Move to component state, add cleanup in useEffect return.

10. Inconsistent Type Safety

Many functions return Promise. Extensive use of any type (37+ occurrences).

Recommendation: Define proper TypeScript interfaces for all API responses.

11. Missing CSRF Protection

Severity: MEDIUM

No CSRF tokens on state-changing operations.

Recommendation: Implement CSRF protection for all state-changing endpoints.

Performance Concerns

12. Inefficient State Updates in Redux

Location: frontend/src/store/reducers/global.ts:186-191

Expensive deep clone using JSON stringify/parse. Redux Toolkit includes Immer.

Recommendation: Remove manual cloning, use direct mutation (Immer handles it).

13. Missing Dependency Array Items

Location: frontend/src/components/Layout/Action.tsx:46

Recommendation: Include all dependencies or use useCallback for stable references.

Best Practice Violations

14. Environment Variables Not Validated

No check if URLs are valid format.

Recommendation: Validate URL format, not just existence.

15. Console Logging in Production

67+ console statements will leak data in production.

Recommendation: Remove or gate behind development checks.

16. No Content Security Policy

No CSP headers to prevent XSS attacks.

Recommendation: Add CSP headers in next.config.mjs.

17. .env File Committed

The .env file is committed which could expose secrets.

Recommendation: Move to .env.example and ensure .env is in .gitignore.

Positive Aspects

  • Well-structured component architecture
  • Good use of TypeScript in most places
  • Comprehensive Docker setup
  • Clear README documentation
  • Good separation of concerns

Summary

  • Critical Issues: 6
  • High Severity: 3
  • Medium Severity: 8
  • Low Severity: 6

Priority Recommendations

  1. Add input validation/sanitization for all JSON.parse calls (especially RTC messages)
  2. Use strict equality (===) for all comparisons
  3. Implement proper error handling with Error objects and try-catch blocks
  4. Add XSS protection via CSP headers and input sanitization
  5. Fix memory leaks in RTC manager (clear timeouts, bound cache size)
  6. Replace Math.random() with crypto.getRandomValues() for user IDs
  7. Add CSRF protection on API routes
  8. Remove console statements for production builds
  9. Validate environment variables for format
  10. Fix Redux state updates to use Immer properly

Would appreciate the team's thoughts on addressing these issues before merging. Happy to discuss any findings!

@claude
Copy link

claude bot commented Feb 10, 2026

PR Review: Spatialwalk-Avatar Example

Thank you for this comprehensive addition to the TEN Framework! This PR adds a complete spatialwalk-avatar example with real-time voice conversation and avatar rendering. I've conducted a thorough review and found several areas that need attention before merging.


Critical Issues (Must Fix Before Merge)

1. XSS Vulnerability in MessageList Component

File: frontend/src/components/Chat/MessageList.tsx:63
Issue: Directly using user-controlled data as an image source without validation can lead to XSS attacks.
Recommendation: Validate image URLs, use whitelist of allowed domains, sanitize all message content.

2. Unsafe JSON.parse Without Error Handling

Files: frontend/src/manager/rtm/index.ts:98,107 and frontend/src/manager/rtc/rtc.ts:285
Issue: Multiple JSON.parse() without try-catch blocks. Malformed JSON will crash the application.
Recommendation: Wrap all JSON.parse calls in try-catch blocks with validation.

3. Missing Input Validation for Channel/User IDs

File: frontend/src/manager/rtc/rtc.ts:45-102
Issue: No validation of channel or userId parameters before passing to Agora SDK.
Recommendation: Add regex validation for channel names and range checks for user IDs.

4. Improper Error Handling in API Route

File: frontend/src/app/api/agents/start/route.tsx:16-17
Issue: Throwing strings instead of Error objects is an anti-pattern.
Recommendation: Return proper NextResponse with error status instead of throwing.

High Priority Issues

5. Weak UUID Generation

File: frontend/src/common/utils.ts:48-54
Issue: Using Math.random() is not cryptographically secure. UUIDs can be predicted.
Recommendation: Use crypto.randomUUID() instead.

6. Missing CSRF Protection

Issue: No CSRF tokens or origin validation. API accepts requests from any origin.
Recommendation: Add CSRF token validation and proper CORS headers.

7. Missing Content Security Policy

Issue: No CSP headers configured, allowing various client-side attacks.
Recommendation: Add CSP headers in next.config.mjs.

8. Debug Logging in Production

File: frontend/src/manager/rtm/index.ts:56
Issue: Debug logging enabled in production leaks sensitive information.
Recommendation: Use conditional logging based on NODE_ENV.

9. Memory Leak Risk in Message Cache

File: frontend/src/manager/rtc/rtc.ts:236,265-274
Issue: messageCache could grow unbounded. No maximum size limit enforced.
Recommendation: Implement LRU cache with size limit.

Medium Priority Issues

  • Hardcoded Sensitive Configuration (tenapp/property.json:112-120): Avatar ID should use env vars
  • Unsafe Type Casting (AvatarSpatialwalk.tsx:106): Remove 'as any' usage
  • No Rate Limiting on API endpoints
  • Dockerfile Security: Curl-to-bash pattern and unpinned base images

Code Quality Improvements

  • Remove commented-out code
  • Add runtime type validation using Zod
  • Add unit tests for critical functions
  • Implement error recovery with retry logic

Summary

Category Critical High Medium Total
Security 4 5 4 13
Performance 0 1 0 1
Code Quality 0 0 3 3

Overall: This is a valuable addition but requires security hardening before merging. Please address all Critical and High priority issues.

Action Items Before Merge

  1. Fix XSS vulnerability in MessageList
  2. Add error handling to all JSON.parse calls
  3. Add input validation for channel/user IDs
  4. Fix error throwing in API routes
  5. Replace Math.random() UUID with crypto.randomUUID()
  6. Add CSRF protection
  7. Add Content Security Policy headers
  8. Fix debug logging in production
  9. Implement message cache size limits

@github-actions
Copy link

Code Review: PR #2043 - Spatialwalk Avatar Example

Thank you for this substantial contribution adding the spatialwalk-avatar example with 23,516 additions across 185 files. I've conducted a comprehensive review covering security, code quality, best practices, and potential bugs.


Summary

Overall Assessment: ⭐⭐⭐⭐ (4/5)

The code is generally well-structured with good React patterns and proper component architecture. However, there are several security hardening opportunities and code quality improvements needed before production deployment.

Risk Level: MODERATE


🔴 Critical Issues (Must Address)

1. Missing Input Validation in API Route Handler

Location: frontend/src/app/api/agents/start/route.tsx:19-37

Issue: The API route accepts and forwards user input to the backend without any validation or sanitization.

const body = await request.json();
const { request_id, channel_name, user_uid, graph_name, language, voice_type, properties } = body;

// ❌ No validation before forwarding
const response = await axios.post(`${AGENT_SERVER_URL}/start`, {
  request_id, channel_name, user_uid, graph_name, properties: properties
});

Risk: Malicious payloads could be injected through the properties object or other fields.

Recommendation:

  • Add input validation using Zod or Yup schema validation
  • Validate the structure of the properties object
  • Add rate limiting to prevent abuse
  • Sanitize all user inputs before forwarding

2. Sensitive Data Exposure via URL Parameters

Location: frontend/src/common/spatialwalk.ts:17-25

Issue: Sensitive configuration data (appId, avatarId) is read from URL query parameters.

const params = new URLSearchParams(window.location.search);
return {
  appId: params.get("appId")?.trim() || "",
  avatarId: params.get("avatarId")?.trim() || "",
};

Risk: These IDs can be leaked via:

  • Browser history
  • Server logs
  • Referrer headers
  • Shared URLs

Recommendation:

  • Move sensitive configuration to secure storage (environment variables, encrypted config)
  • Use POST body or secure cookies instead of URL parameters
  • Implement proper session management

3. Insecure Dockerfile Patterns

Locations:

  • Dockerfile:74 - curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
  • Dockerfile:78 - curl -fsSL https://bun.com/install | bash

Issue: Using curl-to-bash pattern without checksum verification, running as root.

Risk: If the source is compromised, malicious code could be executed during build.

Recommendation:

# Use specific version with checksum verification
RUN wget https://nodejs.org/dist/v20.x.x/node-v20.x.x-linux-x64.tar.xz \
    && echo "EXPECTED_CHECKSUM  node-v20.x.x-linux-x64.tar.xz" | sha256sum -c - \
    && tar xf node-v20.x.x-linux-x64.tar.xz

# Or use official Docker images
FROM node:20-alpine

🟡 High Priority Issues (Should Address)

4. Excessive Use of any Type

Locations: frontend/src/common/request.ts (lines 36, 50, 73, 84, 92+)

Issue: Using any bypasses TypeScript's type safety.

let resp: any = await axios.post(url, data);  // ❌
(playerRef.current as any).play();  // ❌

Recommendation:

  • Define proper TypeScript interfaces for API responses
  • Use unknown instead of any where appropriate and add type guards
  • Remove unnecessary type assertions

5. Error Information Disclosure

Location: frontend/src/app/api/agents/start/route.tsx:49

Issue: Generic error handling could expose stack traces in production.

} catch (error) {
  console.error("Error:", error);  // ❌ Logs full error
  return NextResponse.json({ error: "Request to agent server failed" }, { status: 500 });
}

Recommendation:

  • Log full errors server-side only
  • Return sanitized error messages to client
  • Use proper error monitoring service (Sentry, etc.)
  • Implement different error handling for development vs production

6. Beta Dependencies in Production

Location: frontend/package.json:30-31

Issue: Using beta packages in what appears to be production code.

"@spatialwalk/avatarkit-plugin-nextjs": "^1.0.0-beta.80",
"@spatialwalk/avatarkit-threejs": "^1.0.0-beta.80"

Recommendation:

  • Upgrade to stable versions when available
  • Document known issues with beta versions
  • Add monitoring for unexpected behavior
  • Consider vendor support agreements

🟢 Medium Priority Issues (Should Consider)

7. Token Management Security

Location: frontend/src/common/request.ts:29-47

Issue: Token generation uses hardcoded uid: 0 for Spatialwalk tokens.

const spatialwalkTokenUrl = `${WORKER_URL}/token/generate`;
const resp = await axios.post(spatialwalkTokenUrl, {
  uid: 0,  // ❌ Hardcoded
  channel_name: channelName,
  privileges_expire_time_sec,
});

Recommendation:

  • Use proper user identification
  • Implement token expiration and refresh
  • Consider JWT with proper claims

8. Dependency Security

Location: frontend/package.json

Issues:

  • axios: "^1.13.1" - Verify this is latest secure version
  • Many third-party dependencies without audit

Recommendation:

  • Run npm audit and address vulnerabilities
  • Set up Dependabot or Snyk for continuous monitoring
  • Pin major versions to prevent breaking changes
  • Regular dependency updates

9. Error Handling Improvements

Location: frontend/src/components/Agent/AvatarSpatialwalk.tsx:144-149

Issue: Generic error catching with console logging.

catch (error: any) {
  const message = error?.message || "Failed to initialize Spatialwalk Avatar.";
  console.error("[spatialwalk] init error:", error);  // ❌ Console in production
}

Recommendation:

  • Remove console.error in production builds
  • Use proper error reporting service
  • Add user-friendly error UI with retry mechanism

✅ Strengths

The PR demonstrates several good practices:

  1. Well-Organized Structure - Clear separation of concerns with organized directory structure
  2. Proper React Patterns - Good use of hooks, proper cleanup in useEffect
  3. Component Reusability - Well-designed reusable components
  4. Type Safety - TypeScript usage (except where any is used)
  5. No XSS Vulnerabilities - No use of dangerouslySetInnerHTML or eval()
  6. No SQL Injection - No direct database queries
  7. Clean Code - Generally readable and maintainable
  8. Proper Cleanup - Memory leak prevention with proper useEffect cleanup

🔍 Security Audit: ✅ NO MALICIOUS CODE DETECTED

I performed a security scan and found:

  • ✅ No obfuscated code
  • ✅ No suspicious network calls
  • ✅ No crypto mining patterns
  • ✅ No data exfiltration
  • ✅ No backdoors

📋 Test Coverage

Observation: No test files found in the PR.

Recommendation:

  • Add unit tests for React components
  • Add integration tests for API routes
  • Test error handling paths
  • Add E2E tests for critical user flows

📝 Additional Recommendations

Performance

  1. Consider lazy loading for large components
  2. Implement code splitting for bundle size optimization
  3. Add loading states for better UX

Documentation

  1. Add JSDoc comments for complex functions
  2. Document environment variables in README
  3. Add architecture diagram for Spatialwalk integration
  4. Document API endpoints and their contracts

Code Quality

  1. Extract magic numbers to named constants
  2. Refactor large useEffect hooks for better readability
  3. Consider using custom hooks for complex state logic

🎯 Recommended Action Items Before Merge

Must Fix:

  1. ✅ Add input validation to API routes
  2. ✅ Remove sensitive data from URL parameters
  3. ✅ Fix Dockerfile security issues

Should Fix:
4. Replace any types with proper TypeScript types
5. Implement proper error handling
6. Run npm audit and fix vulnerabilities

Nice to Have:
7. Add test coverage
8. Add comprehensive documentation
9. Implement monitoring/observability


Conclusion

This is a solid foundation for the spatialwalk-avatar example. The code follows good patterns and is generally well-written. With the security improvements and type safety enhancements addressed, this will be a strong addition to the TEN Framework examples.

The critical issues should be resolved before merging to prevent security vulnerabilities. The high priority items would significantly improve code quality and maintainability.

Great work on integrating Spatialwalk functionality! 🎉


Reviewed by: Claude Code (Sonnet 4.5)
Review Date: 2026-02-16

@github-actions
Copy link

Code Review - PR #2043: Spatialwalk Avatar Example

Thank you for this substantial contribution adding a new spatialwalk-avatar example! I've completed a comprehensive review of the 24,050 line addition. Here's my feedback:


✅ Strengths

Architecture & Code Quality:

  • Follows TEN Framework patterns consistently with other examples
  • Clean separation of concerns between frontend, API, and backend
  • Modern tech stack: Next.js 16, React 19.2, TypeScript with strict mode
  • Good state management with Redux Toolkit
  • Well-organized directory structure

Documentation:

  • Comprehensive README with setup instructions
  • Clear prerequisites and environment variable documentation
  • Example configurations provided

🔴 Critical Issues - Must Fix Before Merge

1. Security: Missing Input Validation (HIGH)

Location: frontend/src/common/spatialwalk.ts and URL parameter handling

The spatialwalk IDs from URL parameters lack proper validation:

appId: params.get("appId")?.trim() || "",
avatarId: params.get("avatarId")?.trim() || "",

Recommendation: Add validation:

  • Length limits (e.g., max 100 characters)
  • Character restrictions (alphanumeric + specific allowed chars)
  • Sanitization before use

2. Security: SSRF Potential in API Routes (HIGH)

Location: frontend/src/app/api/agents/start/route.tsx

API routes proxy requests to AGENT_SERVER_URL without validation:

const response = await axios.post(`${AGENT_SERVER_URL}/start`, {...})

Recommendation:

  • Validate AGENT_SERVER_URL is from an allowed domain/IP
  • Use allowlist for permitted backend URLs
  • Add timeout configuration

3. Security: No Authentication on API Routes (HIGH)

Location: /api/agents/start endpoint

The API routes appear to lack authentication:

  • No API key validation
  • No rate limiting
  • No authentication middleware visible

Recommendation:

  • Add API key or token-based authentication
  • Implement rate limiting (e.g., 10 req/min per IP)
  • Add request origin validation

4. Missing Test Coverage (CRITICAL)

This PR adds zero test files for 24k+ lines of code.

Recommendation: Add at minimum:

  • API route tests (start endpoint, error cases)
  • Redux reducer tests
  • Custom hook tests (useAgentConnect)
  • Component render tests for critical flows

🟡 High Priority Issues - Should Fix

5. Environment Variable Security

Location: Dockerfile line 7

COPY .env.example .env

This approach is risky for production deployments.

Recommendation:

  • Document that production deployments should use proper secret management
  • Consider Docker secrets or external secret injection
  • Add warning in README about not committing .env files

6. Code Quality: Loose Equality

Location: Multiple files (e.g., response validation)

if (resp?.code == 0) { // loose equality

Recommendation: Use strict equality (===) throughout

7. Error Handling Lacks Specificity

Location: api/agents/start/route.tsx

Generic error responses don't distinguish error types:

return NextResponse.json(
  { code: "1", data: null, msg: "Internal Server Error" },
  { status: 500 }
);

Recommendation:

  • Add specific error codes for different failure modes
  • Document error codes in README
  • Don't expose sensitive stack traces

🟢 Nice to Have - Future Improvements

  1. Performance: Consider WebSocket instead of 3s polling for apiPing
  2. Performance: Audit bundle size - 19 @radix-ui packages imported
  3. Documentation: Add troubleshooting section to README
  4. Documentation: Fix README title (currently generic "Voice Assistant")
  5. Code Quality: Add React.memo for performance-critical components
  6. DevOps: Update Docker base image from 0.7.12 to 0.7.14 (if stable)
  7. Security: Add security headers (CSP, X-Frame-Options, etc.)

📊 Risk Assessment

Category Risk Level Notes
Security MEDIUM Missing auth, input validation, SSRF concerns
Quality MEDIUM No tests, but good code structure
Performance LOW Reasonable optimizations in place
Overall MEDIUM Needs security hardening before production

🎯 Recommendations Summary

Before merging:

  1. ✅ Add input validation for URL parameters
  2. ✅ Add SSRF protection for backend URL calls
  3. ✅ Add authentication to API routes
  4. ✅ Add basic test coverage (at least API routes + critical functions)
  5. ✅ Fix loose equality operators
  6. ✅ Document error codes

Before production release:

  • Implement rate limiting
  • Add comprehensive test suite
  • Security audit and penetration testing
  • Performance profiling and optimization

Overall, this is a well-structured addition that follows the framework's patterns. The main concerns are around security hardening and test coverage, which are essential for production readiness.

Happy to discuss any of these points further!

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.

1 participant