Skip to content

Conversation

@inoribea
Copy link

@inoribea inoribea commented Oct 7, 2025

Summary

Add comprehensive Chinese (Simplified) translations for memory-related settings pages.

Changes

  • ✅ Short-term memory configuration translations
    • Provider selection (Local Redis, Upstash Redis, Vercel KV)
    • TTL, namespace, and retention settings
    • Session controls and history preview
  • ✅ Long-term memory configuration translations
    • Database connection settings (Postgres + pgvector, Qdrant)
    • Embedding provider configuration (OpenAI, Cloudflare AI)
    • Memory search and export functionality
  • ✅ All UI labels, descriptions, hints, and error messages
  • ✅ Follows existing i18n patterns and terminology used throughout the project

Testing

  • Verified all translation keys match the code usage
  • Consistent with other Chinese translations in the codebase

Related

This improves Chinese language support for the memory system configuration UI, making it more accessible to Chinese-speaking users.

inoribea and others added 23 commits October 6, 2025 08:31
- Add URL import dialog for VRM and Live2D models
- Support VPM JSON format parsing
- Implement model caching with IndexedDB
- Auto-detect model format from URL extension
- Support direct .vrm, .zip, and .json URLs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix CORS font loading from jsdelivr.net by using local Kiwi Maru
- Add smart WebSocket URL detection (disabled in production)
- Add CORS headers to Vercel configuration
- Support auto-switching between ws:// and wss:// protocols

Fixes font loading errors and WebSocket connection failures on deployed instances.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Auto-select default chat provider when configured
- Auto-select default speech provider when configured
- Auto-select default transcription provider when configured
- Add watcher to set active provider from env variables

Improves onboarding UX by pre-selecting providers based on deployment configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add provider API keys to Vite define config
- Add default provider selection environment variables
- Update .gitignore for build artifacts
- Update stage-web README and type definitions

Enables deploying with pre-configured provider credentials via environment variables.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add comprehensive Vercel deployment section to README
- Document all LLM provider environment variables
- Add default provider selection variables
- Include configuration examples
- Support multiple languages (EN, ZH-CN, JA-JP, FR)

This helps users deploy AIRI to Vercel with pre-configured providers, improving the deployment experience.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add globalEnv variables to turbo.json to pass environment to build
- Add dependsOn to build task to ensure proper dependency order
- Fix vercel.json buildCommand to use 'pnpm run build:web'

Fixes:
- Turborepo warning about missing environment variables
- Build command execution issues on Vercel

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Change buildCommand to use 'pnpm -w run build:web'
- Ensures build script runs at workspace root level
- Fixes 'ERR_PNPM_NO_SCRIPT Missing script: build:web' error
- Add all provider env vars to turbo.json globalEnv
- Add build task dependencies to turbo.json

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…nings

- Change globalEnv to globalPassThroughEnv in turbo.json
- Prevents warnings for optional provider environment variables
- These variables are not required and warnings are unnecessary

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Disable Turbo remote cache to fix 400 error with Vercel artifacts API
- Update build command to use turbo filter syntax for better integration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Set vite output directory to project root dist folder for Vercel
- Add empty env array to turbo build task to suppress unnecessary environment variable warnings
- Update vercel.json outputDirectory to match new build output location

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add empty passThroughEnv array to build task to override globalPassThroughEnv,
preventing unnecessary environment variable warnings for packages that don't need them.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Revert to original output directory setup where Vite outputs to apps/stage-web/dist
to match Turbo's outputs configuration and ensure proper build artifact tracking.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fix build error where @proj-airi/memory-system was imported but not
declared as a dependency in server-runtime/package.json. This caused
unresolved import warnings during build:

[UNRESOLVED_IMPORT] Could not resolve '@proj-airi/memory-system' in src/services/memory.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Merged latest changes from moeru-ai/airi upstream including:
- feat(injecta): new dependency injection package
- refactor(stage-tamagotchi): improved structure
- Various fixes and improvements

Preserved local changes:
- Memory system (@proj-airi/memory-system)
- Memory UI components and configuration
- All memory-related functionality

Resolved conflicts by regenerating pnpm-lock.yaml

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive Chinese (Simplified) translations for memory-related
settings pages, including:
- Short-term memory configuration (providers, TTL, namespace, etc.)
- Long-term memory configuration (database, embeddings, search, etc.)
- All labels, descriptions, hints, and error messages

Translations follow the existing i18n patterns and terminology used
throughout the project.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@netlify
Copy link

netlify bot commented Oct 7, 2025

Deploy Preview for airi-docs ready!

Name Link
🔨 Latest commit 62d491a
🔍 Latest deploy log https://app.netlify.com/projects/airi-docs/deploys/68e50f1f31fc9000081c4750
😎 Deploy Preview https://deploy-preview-639--airi-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @inoribea, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a robust and configurable memory system for the application, encompassing both short-term and long-term conversational memory. It provides new backend API endpoints for managing memory, a comprehensive frontend UI for configuring various memory providers (Redis, Postgres, Qdrant), and integrates this memory directly into the chat flow to enhance LLM context. Additionally, it improves display model import capabilities by allowing URL-based imports with caching and streamlines environment variable handling for provider configurations, especially for Vercel deployments. The PR title and description, which mention Chinese translations, appear to be outdated or incorrect, as the primary focus of the changes is the new memory system and related infrastructure.

Highlights

  • New Memory System Implementation: A new monorepo package, packages/memory, has been introduced to provide a unified memory system. This system supports both short-term memory (using providers like Redis, Upstash, or Vercel KV) and long-term memory (using Postgres with pgvector or Qdrant), complete with embedding generation capabilities.
  • Backend API for Memory Management: The packages/server-runtime now includes new API endpoints (/api/memory/*) that allow for dynamic configuration, saving, retrieval, searching, clearing, and exporting of memory data.
  • Frontend Memory Settings UI: A comprehensive user interface for configuring both short-term and long-term memory settings has been added to apps/stage-web. This UI replaces a previous placeholder and offers options for provider selection, retention settings, session controls, and memory search/export functionality.
  • Chat Integration with Memory: The chat functionality in packages/stage-ui has been integrated with the new memory system. This enables automatic saving of user and assistant messages and the incorporation of relevant long-term memories as context for Large Language Model (LLM) prompts.
  • Enhanced Model Import (URL): Users can now import display models (such as VRM and Live2D) directly from URLs. This feature includes support for VPM JSON manifests and local caching of imported models.
  • Environment Variable Integration for Providers: Default LLM, speech, and transcription providers and models can now be pre-configured using environment variables. This significantly enhances deployment flexibility, particularly for platforms like Vercel.
  • Vercel Deployment Guide: New documentation (docs/content/en/docs/guides/deploy/vercel.md) and updates to existing README files (French, Japanese, Chinese) provide detailed instructions for deploying the web application on Vercel, including comprehensive environment variable configurations.
  • Font Management Improvements: New font dependencies have been added, and font loading has been optimized to preload locally bundled fonts, which helps reduce reliance on CDN requests and improves performance.
Ignored Files
  • Ignored by pattern: packages/i18n/src/** (1)
    • packages/i18n/src/locales/zh-Hans/settings.yaml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@netlify
Copy link

netlify bot commented Oct 7, 2025

Deploy Preview for airi-vtuber ready!

Name Link
🔨 Latest commit 62d491a
🔍 Latest deploy log https://app.netlify.com/projects/airi-vtuber/deploys/68e50f1fe70f4300082ad8e4
😎 Deploy Preview https://deploy-preview-639--airi-vtuber.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive memory system, including short-term and long-term storage capabilities, along with the corresponding UI for configuration. It also includes significant refactoring of environment variable handling for provider configuration and updates to documentation. My review focuses on ensuring the correctness and maintainability of the new memory system and its integration. I've found a few issues, including a logic bug that makes a provider unreachable, some UI template syntax errors, and a TypeScript error due to undefined types. Addressing these will improve the stability and correctness of this new feature.

Comment on lines +292 to +294
if (config.provider !== 'postgres-pgvector') {
throw new Error(`Unsupported long-term memory provider: ${config.provider}`)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This check makes the qdrant provider logic unreachable. The LongTermProviderConfiguration type is a union of PostgresLongTermConfiguration and QdrantLongTermConfiguration. This condition incorrectly throws an error for the qdrant provider, preventing it from ever being configured through a configuration object. Removing this check will allow both providers to be handled by their respective if blocks, and the satisfies never check at the end of the function will ensure all provider types are handled.

}
}
}

Copy link
Contributor

Choose a reason for hiding this comment

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

high

The types QdrantLongTermPayload and PostgresLongTermPayload used with the satisfies keyword later in this file are not defined or imported, which will cause a TypeScript compilation error. You can define these types by extracting them from the MemoryConfigurationPayload interface. This will ensure type safety and fix the compilation issue.

type LongTermConfig = NonNullable<MemoryConfigurationPayload['longTerm']>
type PostgresLongTermPayload = Extract<LongTermConfig, { provider: 'postgres-pgvector' }>
type QdrantLongTermPayload = Extract<LongTermConfig, { provider: 'qdrant' }>


import * as zodCore from 'zod/v4/core'

void zodCore // ensure bundlers keep the zod v4 helper chunk for xsschema imports
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The comment is a bit brief. For better maintainability, it would be helpful to expand on why this workaround is necessary. Explaining that xsschema has a dynamic import that bundlers like Vite might miss during tree-shaking provides valuable context for future developers who might wonder about this line.

// This is a workaround to prevent tree-shaking from removing the `zod/v4/core` module.
// The `xsschema` library dynamically imports this module at runtime, but some bundlers
// (like Vite) may not detect this dynamic usage and will prune it from the final bundle,
// causing a runtime error. This explicit import and usage ensures the module is included.
void zodCore;

Comment on lines +123 to +163
function resolveShortTermConfigurationFromEnv(): ShortTermProviderConfiguration {
const envProvider = (env.MEMORY_PROVIDER
?? env.SHORT_TERM_MEMORY_PROVIDER
?? 'local-redis') as ShortTermProviderType

const provider = normalizeShortTermProvider(envProvider)

const configuration: ShortTermProviderConfiguration = {
provider,
namespace: env.MEMORY_NAMESPACE ?? 'memory',
maxMessages: parseOptionalInteger(env.SHORT_TERM_MEMORY_MAX_MESSAGES) ?? 20,
ttlSeconds: parseOptionalInteger(env.SHORT_TERM_MEMORY_TTL_SECONDS) ?? (60 * 30),
}

if (provider === 'upstash-redis') {
configuration.upstash = {
url: env.UPSTASH_REDIS_REST_URL ?? '',
token: env.UPSTASH_REDIS_REST_TOKEN ?? '',
}
}

if (provider === 'local-redis') {
configuration.redis = {
host: env.REDIS_HOST,
port: parseOptionalInteger(env.REDIS_PORT) ?? 6379,
password: env.REDIS_PASSWORD,
}
}

return configuration
}

function normalizeShortTermProvider(provider: ShortTermProviderType): ShortTermProviderType {
if (provider === 'upstash-redis') {
if (!env.UPSTASH_REDIS_REST_URL || !env.UPSTASH_REDIS_REST_TOKEN) {
return 'local-redis'
}
}

return provider
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The logic to determine the short-term memory provider from environment variables here is inconsistent with the more robust logic in MemorySystemFactory. Specifically, this implementation doesn't account for VERCEL_ENV to default to vercel-kv, which could lead to incorrect provider selection in a Vercel environment. To ensure consistent behavior and correct configuration reporting, this logic should mirror the provider resolution strategy in MemorySystemFactory.

function resolveShortTermConfigurationFromEnv(): ShortTermProviderConfiguration {
  const envProvider = (env.MEMORY_PROVIDER
    ?? env.SHORT_TERM_MEMORY_PROVIDER)?.toLowerCase() as ShortTermProviderType | undefined

  let provider: ShortTermProviderType

  if (envProvider === 'vercel-kv') {
    provider = 'vercel-kv'
  }
  else if (envProvider === 'upstash-redis') {
    provider = 'upstash-redis'
  }
  else if (envProvider === 'local-redis') {
    provider = 'local-redis'
  }
  else if (env.VERCEL_ENV) {
    provider = 'vercel-kv'
  }
  else if (env.UPSTASH_REDIS_REST_URL && env.UPSTASH_REDIS_REST_TOKEN) {
    provider = 'upstash-redis'
  }
  else {
    provider = 'local-redis'
  }

  const configuration: ShortTermProviderConfiguration = {
    provider,
    namespace: env.MEMORY_NAMESPACE ?? 'memory',
    maxMessages: parseOptionalInteger(env.SHORT_TERM_MEMORY_MAX_MESSAGES) ?? 20,
    ttlSeconds: parseOptionalInteger(env.SHORT_TERM_MEMORY_TTL_SECONDS) ?? (60 * 30),
  }

  if (provider === 'upstash-redis') {
    configuration.upstash = {
      url: env.UPSTASH_REDIS_REST_URL ?? '',
      token: env.UPSTASH_REDIS_REST_TOKEN ?? '',
    }
  }

  if (provider === 'local-redis') {
    configuration.redis = {
      host: env.REDIS_HOST,
      port: parseOptionalInteger(env.REDIS_PORT) ?? 6379,
      password: env.REDIS_PASSWORD,
    }
  }

  return configuration
}

v-model="longTermQdrantApiKey"
type="password"
class="w-full border border-neutral-200 rounded-md bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"
placeholder="{{ t('settings.memory.long_term.qdrantApiKeyPlaceholder', 'Optional if public instance') }}"
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The placeholder attribute is using mustache syntax {{ ... }} which will render the literal string instead of the translated value. To correctly bind the result of the t() function, you should use v-bind: or its shorthand :. This issue is also present on lines 353 and 400.

              :placeholder="t('settings.memory.long_term.qdrantApiKeyPlaceholder', 'Optional if public instance')"

v-model="shortTermRedisPassword"
type="password"
class="w-full border border-neutral-200 rounded-md bg-white px-3 py-2 text-sm dark:border-neutral-700 dark:bg-neutral-900"
placeholder="{{ t('settings.memory.short_term.redisPasswordPlaceholder', 'Optional password') }}"
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The placeholder attribute is using mustache syntax {{ ... }} which will render the literal string instead of the translated value. To correctly bind the result of the t() function, you should use v-bind: or its shorthand :.

              :placeholder="t('settings.memory.short_term.redisPasswordPlaceholder', 'Optional password')"

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