# Technical Documentation: iflytek/astron-rpa

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/iflytek/astron-rpa)

### Overview (README.md)

# AstronRPA

<div align="center">



**🤖 Pioneering Open-Source Enterprise RPA Desktop Application**

<a href="https://trendshift.io/repositories/17279?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-17279" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/17279" alt="iflytek%2Fastron-rpa | Trendshift" width="250" height="55"/></a>

<p align="center">
  <a href="https://www.iflyrpa.com">Astron RPA Official Site</a> ·
  <a href="./BUILD_GUIDE.md">Deployment Guide</a> ·
  <a href="https://www.iflyrpa.com/docs/">User Documentation</a> ·
  <a href="./FAQ.md">FAQ</a>
</p>

[](LICENSE)
[](https://github.com/iflytek/astron-rpa/releases)
[](https://www.python.org/)
[](https://github.com/iflytek/astron-rpa/stargazers)

English | [简体中文](README.zh.md)

</div>

## 📋 Overview

AstronRPA is an enterprise-grade Robotic Process Automation (RPA) desktop application. Through a visual designer, it supports low-code/no-code development, enabling users to rapidly build workflows and automate desktop software and web pages.

[Astron Agent](https://github.com/iflytek/astron-agent) is the native Agent platform supported by this project. Users can directly call RPA workflow nodes in Astron Agent, and also use Agent workflows in AstronRPA, achieving efficient collaboration between automation processes and intelligent agent systems, empowering broader business automation scenarios.

### 🎯 Why Choose AstronRPA?

- **🛠️ Comprehensive Automation Support**: Comprehensive coverage of Windows desktop applications and web page automation. Supports common office software like WPS and Office, financial and ERP systems like Kingdee and YonYou, and various browsers like IE, Edge, and Chrome, enabling end-to-end cross-application automation.
- **🧩 Highly Component-based**: 300+ pre-built atomic capabilities covering UI operations, data processing, and system interactions. Supports visual orchestration and custom component extensions with high flexibility and maintainability.
- **🏭 Enterprise-grade Security & Collaboration**: Built-in excellence center and team marketplace with enterprise modules. Provides terminal monitoring, scheduling modes, robot team sharing and collaborative functions. Build a complete enterprise automation management ecosystem with process security, permission control, and cross-team collaboration.
- **👨‍💻 Developer-friendly Experience**: Low-code, visual process design and debugging environment. Quickly build automation workflows through intuitive drag-and-drop methods, reducing development barriers, improving development efficiency, and enabling business users to participate in automation creation.
- **🤖 Native Agent Empowerment**: Deep integration with Astron Agent platform supporting bi-directional calls between automation processes and AI agents with capability fusion. Achieve seamless connection between task reasoning, decision making, and automated execution, expanding automation boundaries.
- **🌐 Multi-channel Trigger Integration**: Supports direct execution, scheduled tasks, scheduling modes, API calls, and MCP services. Flexible integration capabilities to quickly respond to third-party system integration needs and easily embed in complex business scenarios.

## 🚀 Quick Start

### System Requirements
- 💻 **Client Operating System**: Windows 10/11 (primary support)
- 🧠 **RAM** >= 8 GiB

### **Server**: Deploy with Docker

Recommended for quick deployment:

For self-hosting, prepare your own server and domain, add gateway/authentication
DNS records at the authoritative DNS provider, and obtain a certificate covering
both names. The deployer maintains DNS, private keys, public ports, and renewals.
See [DNS and HTTPS setup](docker/HTTPS_DEPLOYMENT.md) before running the commands
below; replace all `example.com` names with your own.

```bash
# Clone the repository
git clone https://github.com/iflytek/astron-rpa.git
cd astron-rpa

# Enter docker directory
cd docker

# Copy .env
cp .env.example .env

# Configure the public HTTPS names in .env
RPA_SERVER_NAME="rpa.example.com"
CASDOOR_SERVER_NAME="auth.example.com"
RPA_HTTPS_REDIRECT_AUTHORITY="rpa.example.com"
CASDOOR_HTTPS_REDIRECT_AUTHORITY="auth.example.com:8443"
CASDOOR_EXTERNAL_ENDPOINT="https://auth.example.com:8443"

# Copy a certificate covering both names and its private key
# to docker/certs/tls.crt and docker/certs/tls.key

# 🚀 Start all services
# Initialize independent Casdoor credentials (see docker/HTTPS_DEPLOYMENT.md 1.3)
docker compose up -d mysql casdoor
# Wait for Casdoor initialization
python3 scripts/sync-casdoor-credentials.py
docker compose up -d

# 📊 Check service status
docker compose ps
```

- After all services have started, open your browser and go to: `https://rpa.example.com/api/rpa-auth/user/login-check`.
- If you see `{"code":"900001","data":null,"message":"unauthorized"}`, it means the deployment is correct and the connection is working properly.
- Open your browser and go to: `https://auth.example.com:8443`.
- If you see the Casdoor login page, it means Casdoor is deployed correctly.
- For production deployment and security hardening, refer to the [Deployment Guide](./docker/QUICK_START.md).

### **Client**: Source Deployment/Binary Deployment

#### Environment Dependencies
| Tool | Version | Description |
|-----|---------|------------|
| **Node.js** | >= 22 | JavaScript runtime |
| **Python** | 3.13.x | RPA engine core |
| **Java** | JDK 8+ | Backend runtime |
| **pnpm** | >= 9 | Node.js package manager |
| **UV** | 0.8+ | Python package management tool |
| **7-Zip** | - | Create deployment archives |
| **SWIG** | - | Connect Python with C/C++ |

For specific installation instructions and common issues, refer to [Build Guide](./BUILD_GUIDE.md).

#### Direct Download (Recommended)

Download the latest [Release Package](https://github.com/iflytek/astron-rpa/releases)

#### One-Click Build

1. **Prepare Python Environment**
   ```bash
   # Prepare a Python 3.13.x installation directory (can be a local folder or system installation path)
   # The script will copy this directory to create python_core
   ```

2. **Run Build Script**
   ```bash
   # Full build (engine + frontend + desktop app) from project root directory
   ./build.bat --python-exe "C:\Program Files\Python313\python.exe"
   
   # Or use default configuration (if Python is in default path)
   ./build.bat
   
   # Wait for completion
   # Build successful when console displays "Full Build Complete!"
   ```

   > **Note:** Please ensure the specified Python interpreter is a clean installation without additional third-party packages to minimize package size.

   **Build process includes:**
   1. ✅ Detect/copy Python environment to `build/python_core`
   2. ✅ Install RPA engine dependencies
   3. ✅ Compress Python core to `resources/python_core.7z`
   4. ✅ Install frontend dependencies
   5. ✅ Build frontend web application
   6. ✅ Build desktop application

3. 📦 Install the packaged client

#### ⚙️ After installation, modify the server address in `resources/conf.yaml` in the installation directory:

    ```yaml
    remote_addr: https://rpa.example.com/
    skip_engine_start: false
    ```

## 🏗️ Architecture Overview

The project adopts a frontend-backend separation architecture. The frontend is built with Vue 3 + TypeScript and Electron for desktop applications; the backend uses Java Spring Boot and Python FastAPI to build microservices supporting business and AI capabilities. The engine layer is based on Python, integrating 20+ RPA components with support for image recognition and UI automation. The entire system is deployed via Docker with high observability and scalability, designed for complex RPA scenarios.



## 📦 Component Ecosystem

### Core Component Packages
- **astronverse.system**: System operations, process management, screenshots
- **astronverse.browser**: Browser automation, web page operations
- **astronverse.gui**: GUI automation, mouse and keyboard operations
- **astronverse.excel**: Excel spreadsheet operations, data processing
- **astronverse.vision**: Computer vision, image recognition
- **astronverse.ai**: AI intelligent service integration
- **astronverse.network**: Network requests, API calls
- **astronverse.email**: Email sending and receiving
- **astronverse.docx**: Word document processing
- **astronverse.pdf**: PDF document operations
- **astronverse.encrypt**: Encryption and decryption functions

### Execution Framework
- **astronverse.actionlib**: Atomic operation definition and execution
- **astronverse.executor**: Workflow execution engine
- **astronverse.picker**: Workflow element picker engine
- **astronverse.scheduler**: Engine scheduler
- **astronverse.trigger**: Engine trigger

### Shared Libraries
- **astronverse.baseline**: RPA framework core
- **astronverse.websocketserver**: WebSocket communication
- **astronverse.websocketclient**: WebSocket communication
- **astronverse.locator**: Element locating technology


## 📚 Documentation

- [📖 User Guide](https://www.iflyrpa.com/docs/)
- [🚀 Deployment Guide](docker/QUICK_START.md)
- [📖 API Documentation](backend/openapi-service/api.yaml)
- [🔧 Component Development Guide](engine/components/)
- [🐛 Troubleshooting](docs/TROUBLESHOOTING.md)
- [📝 Changelog](CHANGELOG.md)

## 🤝 Contributing

We welcome any form of contribution! Please check [Contributing Guide](CONTRIBUTING.md)

### Development Guidelines
- ✅ Follow existing code style
- ✅ Add necessary test cases
- ✅ Update relevant documentation
- ✅ Ensure all checks pass

### Contributing Steps
1. 🍴 Fork the repository
2. 🌿 Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. 💾 Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. 🚀 Push to the branch (`git push origin feature/AmazingFeature`)
5. 📝 Open a Pull Request

## 🌟 Star History

If AstronRPA saves you time, consider giving it a ⭐ — it is the simplest way to support the project and helps other automation builders discover it.

<div align="center">
  <img src="https://api.star-history.com/svg?repos=iflytek/astron-rpa&type=Date" alt="Star History Chart" width="600">
</div>

## 💖 Sponsorship

<div align="center">
  <a href="https://github.com/sponsors/iflytek">
    <img src="https://img.shields.io/badge/Sponsor-GitHub%20Sponsors-pink?style=for-the-badge&logo=github" alt="GitHub Sponsors">
  </a>
  <a href="https://opencollective.com/astronrpa">
    <img src="https://img.shields.io/badge/Sponsor-Open%20Collective-blue?style=for-the-badge&logo=opencollective" alt="Open Collective">
  </a>
</div>

## 📞 Getting Help

- 📧 **Technical Support**: [cbg_rpa_ml@iflytek.com](mailto:cbg_rpa_ml@iflytek.com)
- 💬 **Community Discussion**: [GitHub Discussions](https://github.com/iflytek/astron-rpa/discussions)
- 🐛 **Bug Reports**: [Issues](https://github.com/iflytek/astron-rpa/issues)
- 👥 **WeChat Work Group**:

<div align="center">
  <img src="./docs/images/WeCom_Group.png" alt="WeChat Work Group" width="300">
</div>

## 📄 License

This project is open source under the [Open Source License](LICENSE).

---

<div align="center">

**Developed and maintained by iFlytek**

[](https://github.com/iflytek)
[](https://github.com/iflytek/astron-rpa)
[](https://github.com/iflytek/astron-rpa/fork)
[](https://github.com/iflytek/astron-rpa/watchers)

**AstronRPA** - Making RPA development simple and powerful!

If you find this project helpful, please give us a ⭐ Star!

</div>

---

### JEV SEMANTIC CHOICE (`docs/JEV_SEMANTIC_CHOICE.md`)

# Optional Jev provider

The generic [semantic choice component](SEMANTIC_CHOICE.md) defaults to the
existing OpenAI-compatible service. To explicitly select Jev, add these values
to `docker/.env`:

```dotenv
SEMANTIC_CHOICE_ENABLED=true
SEMANTIC_CHOICE_PROVIDER=jev
JEV_API_KEY=your-typesafe-api-key
JEV_MODEL=jev-latest
```

The shared `SEMANTIC_CHOICE_TIMEOUT_SECONDS` and `SEMANTIC_CHOICE_POINTS_COST`
settings also apply. Restart the AI and robot services after changing settings.
A missing key disables availability and execution reports `JEV_API_KEY`.
The provider uses `https://api.typesafe.ai/v1/systemone` directly; no SDK is
required. Credentials never belong in client metadata or workflow variables.

`jev-latest` follows stable model releases. Pin a supported version through
`JEV_MODEL` when reproducibility is required. Responses preserve Jev's native
confidence; it is distinct from the winning option's probability. Probability
distributions and token usage are not exposed in the workflow result.

There are at most 254 business options plus an explicit abstention option.
`__abstain__` is an integration-defined choice, not a native API response status.
Unlike the SDK, this integration does not retry 429/529 responses automatically;
provider failures remain workflow errors and do not deduct application points.
Jev 1.13 supports text inputs and limits state plus the longest question to 32k
tokens. Application character bounds cannot guarantee that token limit.

English is the model's strongest documented language; evaluate Chinese inputs
on actual workload samples. Three live Chinese smoke examples previously
validated refund/shipping/abstention with `jev-1.13.0`; this is not a quality or
speed benchmark and does not validate subsequent alias changes.

References: [Quick start](https://docs.typesafe.ai/introduction/quickstart),
[API](https://docs.typesafe.ai/api), [Models](https://docs.typesafe.ai/models).

---

### RISCV64 (`docs/RISCV64.md`)

# RISC-V (`linux/riscv64`) support

## Current scope

RISC-V support is incremental and currently applies only to the server-side
`resource-service` image. It does not add RISC-V support for the Astron RPA
Windows desktop client or automation engine, and it does not make the complete
Docker Compose stack supported on RISC-V.

| Component | `linux/riscv64` status | Notes |
| --- | --- | --- |
| `resource-service` | Supported image path | The architecture-neutral Java 21 JAR is built on the Buildx host and copied into a target-architecture Eclipse Temurin runtime. |
| `ai-service` and `openapi-service` | Not yet verified | Python 3.13 native dependencies and the bundled wheel require an architecture audit. |
| `robot-service` and `rpa-auth` | Not yet verified | Their Java 8 build/runtime images require a separate RISC-V compatibility path. |
| MySQL, Redis, MinIO, Casdoor, Atlas, and OpenResty | Not yet verified as a stack | Each external image and its runtime behavior must be checked on the target system. |
| Windows desktop client and automation engine | Unsupported | These components depend on Windows desktop and UI automation capabilities and are outside this server-image adaptation. |
| Complete Compose deployment | Unsupported | Do not deploy `docker/docker-compose.yml` unchanged as a supported RISC-V stack. |

## Build the supported image

Run the build from the repository root. Register a RISC-V QEMU handler first
when the Buildx host is not RISC-V:

```bash
docker run --privileged --rm tonistiigi/binfmt --install riscv64
docker buildx create --use --name astron-rpa-riscv64

docker buildx build \
  --platform linux/riscv64 \
  --file backend/resource-service/Dockerfile \
  --tag astron-rpa/resource-service:riscv64 \
  --load \
  .
```

The backend publishing workflow produces `resource-service` for
`linux/amd64`, `linux/arm64`, and `linux/riscv64`. The other backend service
jobs retain the existing AMD64/ARM64 platform list.

## Build design

The Maven stage runs on `$BUILDPLATFORM` because the Spring Boot JAR is
architecture-neutral. Only the Eclipse Temurin Java 21 runtime stage targets
`linux/riscv64`. This avoids emulating dependency resolution and compilation
while preserving the existing application entry point and JVM options.

## Verification boundary

The pull-request workflow builds and loads the target image, checks its OCI
architecture metadata, and executes the Java runtime under RISC-V emulation.
This is a component-image guardrail, not a full application integration test.

A native RISC-V smoke test with the database, cache, object storage,
authentication service, reverse proxy, and an RPA client remains required
before claiming end-to-end or production support.

---

### SEMANTIC CHOICE (`docs/SEMANTIC_CHOICE.md`)

# Semantic choice

The **AI语义判断 → 语义选择** component selects a stable option ID from text,
or explicitly abstains. Existing workflow conditions decide what to do next.
It uses the authenticated desktop gateway and `POST /v1/decision/choice`.

## Enable and publish

The feature is disabled by default. Configure the existing OpenAI-compatible
service in `docker/.env`, then enable semantic choice:

```dotenv
AICHAT_BASE_URL=https://your-provider.example/v1
AICHAT_API_KEY=your-server-key
SEMANTIC_CHOICE_ENABLED=true
SEMANTIC_CHOICE_PROVIDER=openai_compatible
SEMANTIC_CHOICE_MODEL=maas/deepseek-v3.2
SEMANTIC_CHOICE_TIMEOUT_SECONDS=10
SEMANTIC_CHOICE_POINTS_COST=100
```

Set the model to a model your service supports. It must support strict
`response_format.type=json_schema` output. Compatibility with chat completions
alone does not establish this capability. Unsupported structured output,
refusals, truncated responses and invalid output fail explicitly; there is no
fallback to free-text parsing, another provider, or another paid attempt.

The timeout must be positive and at most 30 seconds; the point cost must be
positive. Keep credentials on the server. The robot service runs a compiled image, so recreating its existing container
alone does not install this Java change. From the repository root, build this
revision and use a Compose override (or deploy a released image containing it):

```sh
docker build -f backend/robot-service/Dockerfile -t astron-robot-semantic:local .
cat > docker/compose.semantic.local.yml <<'YAML'
services:
  robot-service:
    image: astron-robot-semantic:local
YAML
cd docker
docker compose -f docker-compose.yml -f compose.semantic.local.yml up -d --force-recreate ai-service robot-service openresty-nginx
```

Keep this local deployment override outside commits. On later configuration
changes, use the same Compose files when recreating services. The AI service
source and gateway Lua are mounted by the supplied Compose configuration.
For non-Compose deployments, the robot service capability URL can be set with
`AI_SERVICE_DECISION_CAPABILITIES_URL`; its default is
`http://ai-service:8010/v1/decision/capabilities`.

For a fresh database, initialization publishes the metadata. For an existing
database, take your normal backup and apply the additive migration:

```sh
docker compose exec -T mysql sh -c \
  'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -uroot --default-character-set=utf8mb4' \
  < migrations/20260923_add_semantic_choice.sql
```

Rebuild/install the client from this revision and reopen the designer.
Metadata alone does not update an installed engine. The service owns readiness:
`GET /v1/decision/capabilities` returns `{ "enabled": false, "reason": "..." }`
or `{ "enabled": true, "reason": null }`. It checks configuration, not provider
reachability or model quality, and never makes a paid call.

When unavailable, the component tree hides this node. Its definition remains
available so saved workflows can open; the designer warns about unavailable
semantic nodes, and execution reports the configuration variable to change.
Other nodes remain available if the capability service cannot be reached.

## Example: route a support ticket

1. Read a ticket's text with the existing browser component, or use the text
   `订单重复扣款，请退回多扣的钱。`.
2. Create a List variable containing:

   ```python
   [
       {"id": "refund", "label": "退款、重复扣款、退回费用"},
       {"id": "shipping", "label": "物流、配送进度、未收到包裹"},
       {"id": "invoice", "label": "发票开具或修改"},
       {"id": "other", "label": "明确属于其他客服事项"},
   ]
   ```

3. Add **语义选择**, set **判断说明** to
   `按工单主要诉求分类；信息不足或不属于客服事项时不要猜测。`, reference the
   ticket in **待判断文本**, and reference the List in **候选列表**.
4. Save the output as `semantic_result` and branch on its fields:
   - `semantic_result["status"] == "abstain"`: route for manual review.
   - `semantic_result["selected_id"] == "refund"`: enter the refund-handling
     workflow, including its existing business checks.
   - Handle the other IDs in their corresponding branches.

For this example, `refund` is the expected classification, not a guaranteed
model result. A domain label such as `other` is different from abstention.
Confidence describes the model's choice certainty, not verified accuracy;
evaluate thresholds on your own samples before using decisions for actions.

## API contract

```json
{
  "instruction": "按工单主要诉求分类；信息不足时不要猜测。",
  "text": "订单重复扣款，请退回多扣的钱。",
  "options": [
    {"id": "refund", "label": "退款"},
    {"id": "shipping", "label": "物流"}
  ]
}
```

The response is a plain object, without a `data` envelope:

```json
{"status": "matched", "selected_id": "refund", "confidence": null}
```

An explicit model abstention returns:

```json
{"status": "abstain", "selected_id": null, "confidence": null}
```

- Supply 1–254 options with unique, nonempty IDs; `__abstain__` is reserved by
  this integration for the additional refusal option, not a native provider token.
- Strings are trimmed; maximum lengths are 2,048 characters for instruction,
  32,768 for text, 128 for IDs, and 512 for labels.
- Valid decisions, including abstentions, consume `SEMANTIC_CHOICE_POINTS_COST` points
  under the existing `semantic_choice_cost` transaction category, after inference.
- Invalid input (422), missing identity (401), insufficient points (403),
  disabled integration (503), provider timeout (504), and provider/protocol
  errors (502) are errors; provider failures do not deduct points.
- The component propagates errors to normal workflow exception handling; it
  does not silently convert a failure into abstention or retry paid inference.
- Only the supplied text and candidate descriptions go to the configured provider; minimize
  business data in these inputs. The adapter does not log the payload or key.

The OpenAI-compatible provider returns `confidence: null`: model-generated
self-assessments are not treated as calibrated confidence. Workflow expressions
must check for null before using confidence thresholds. Existing option IDs and
matched/abstain semantics remain unchanged.

Character limits do not guarantee that a request fits a provider's token budget.
Keep descriptions concise and evaluate classification on representative data.
For the optional provider, see [provider configuration](JEV_SEMANTIC_CHOICE.md).

## Verification

### Offline checks

Offline backend tests use the real ASGI routes with a mock provider transport
and point service; they need neither model credentials nor MySQL/Redis:

```sh
cd backend/ai-service
uv run pytest --confcutdir=tests/unit tests/unit -q
```

Engine tests mock the atomic runtime and HTTP boundary and execute the actual
component method:

```sh
uv run --project engine pytest engine/components/astronverse-ai/tests -q
```

Gateway identity regressions run in disposable Docker containers:

```sh
sh docker/tests/test-auth-handler.sh
```

The production-route smoke test loads the complete production gateway route
include and real authentication Lua in OpenResty, then proxies HTTP requests to
the real FastAPI decision router, identity dependency, point checker and OpenAI-compatible
adapter. Only the remote authentication service, provider transport and points store
are mocked; no credentials or paid API are needed:

```sh
# Prerequisites: Docker, the ai-service Python environment, and the cached image.
docker pull openresty/openresty:1.27.1.1-alpine
backend/ai-service/.venv/bin/python docker/tests/test-semantic-choice-gateway.py
```

`OPENRESTY_IMAGE` can select another locally cached OpenResty image. The script
creates a disposable Docker network and containers and removes them on exit.
Its temporary host HTTP listener binds all interfaces so Docker Desktop and
Linux Docker can reach it; it serves synthetic fixtures only. The gateway is
published on a random loopback port. The 15 cases cover token and session-cookie
identity forwarding despite spoofed headers, credential rejection without
inference or charging, matched and abstained results, provider failures and
selection of the unchanged sibling AI route. This is an HTTP route smoke test;
it does not validate the deployment's TLS certificates or live model quality.

The identity policy also has an offline Lua/LuaJIT check with mocked gateway
and authentication-service boundaries: `lua docker/tests/decision_auth_spec.lua`.

These tests establish protocol and error-handling behavior, not model quality
or speed. For a live comparison, run the same labeled Chinese tickets through
the configured providers, recording accuracy, abstention rate, decision and
whole-workflow P50/P95 latency, and cost; do not infer workflow speed from
provider latency alone.

---

### Frontend Docs I18n (`frontend/docs/I18n.md`)

# 项目国际化 (i18n) 操作文档

## 概述

本项目使用 `@lobehub/i18n-cli` 工具和 `i18next` 库实现国际化功能，支持中文（zh-CN）和英文（en-US）两种语言。

## 目录结构

```
locales/
├── package.json       # 语言包配置
├── zh-CN.json        # 中文语言包（主语言包）
└── en-US.json        # 英文语言包（自动翻译生成）
```

## 配置文件

### 1. `.i18nrc.cjs` - i18n 工具配置

```javascript
const { env } = require('node:process')

const { defineConfig } = require('@lobehub/i18n-cli')

const modelName = env.OPENAI_MODEL_NAME || 'azure/gpt-4o-mini'

module.exports = defineConfig({
  modelName, // AI 翻译模型
  entry: 'locales/zh-CN.json', // 源语言文件
  entryLocale: 'zh-CN', // 源语言
  output: 'locales', // 输出目录
  outputLocales: ['en-US'], // 目标语言
  saveImmediately: true, // 每个翻译块完成后立即保存
  concurrency: 5, // 并发翻译数量
  temperature: 0.3, // AI 翻译温度参数
})
```

### 2. `locales/package.json` - 语言包模块配置

```json
{
  "name": "@rpa/locales",
  "private": true,
  "version": "1.0.0",
  "exports": {
    "./zh-CN.json": "./zh-CN.json",
    "./en-US.json": "./en-US.json"
  }
}
```

## 项目实现方案

### 1. 语言包加载 (`packages/web-app/src/config/i18n.ts`)

```typescript
import enUS from '@rpa/locales/en-US.json'
import zhCN from '@rpa/locales/zh-CN.json'

const locales = {
  'en-US': {
    lng: 'en-US',
    lang: 'English',
    value: enUS,
  },
  'zh-CN': {
    lng: 'zh-CN',
    lang: '简体中文',
    value: zhCN,
  },
}

export default locales
```

### 2. i18next 初始化 (`packages/web-app/src/plugins/i18next.ts`)

```typescript
import i18next from 'i18next'

// 语言检测：优先使用中文，其他情况使用英文
const language = navigator.language === 'zh-CN' ? 'zh-CN' : 'en-US'

i18next.init({
  debug: false,
  lng: language,
  resources: {
    [language]: {
      translation: locales[language].value,
    },
  },
  interpolation: {
    escapeValue: false,
  },
})

// 翻译函数
export function translate(str: string | languageType, variables?: Record<string, string>): string {
  // 支持字符串插值，如: t('tableTotal', { count: 10 })
}

// 语言切换
export async function changeLanguage(lang: string) {
  i18next.addResourceBundle(lang, 'translation', locales[lang].value)
  await i18next.changeLanguage(lang)
}
```

### 3. Vue 组件中的使用

项目中主要有两种使用方式：

1. **使用 `useTranslation` hook**（推荐用法）
2. **直接导入特定函数**（如语言切换功能）

#### 模板中使用：

```vue
<template>
  
  <div>{{ $t('projectName') }}</div>

  
  <div>{{ $t('tableTotal', { count: 10 }) }}</div>

  
  <a-input :placeholder="$t('enterProjectNameKeyword')" />

  
  <div>{{ $i18next.language }}</div>
</template>
```

#### Script 中使用：

```vue
<script setup lang="ts">
import { useTranslation } from 'i18next-vue'

// 使用 useTranslation hook 获取翻译函数
const { t, i18next } = useTranslation()

// 在逻辑中使用翻译
const rules = [
  { required: true, message: t('projectNameCannotBeEmpty') },
  { max: 32, message: t('cannotExceed32Chars') }
]

// 在函数中使用
function showMessage() {
  message.success(t('createSuccess'))
}

// 获取当前语言
console.log(i18next.language)
</script>
```

#### 语言切换组件：

```vue
<script setup lang="ts">
import { useTranslation } from 'i18next-vue'

const { i18next } = useTranslation()
</script>

<template>
  <Select
    :default-value="$i18next.language"
    @change="(lng: string) => i18next.changeLanguage(lng)"
  >
    <Select.Option value="zh-CN">
      简体中文
    </Select.Option>
    <Select.Option value="en-US">
      English
    </Select.Option>
  </Select>
</template>
```

#### 其他导入方式：

```vue
<script setup lang="ts">
// 1. 使用 useTranslation hook（推荐）
import { useTranslation } from 'i18next-vue'

// 2. 导入特定函数
import { changeLanguage } from '@/plugins/i18next'
// 3. 导入自定义翻译函数（用于特殊场景）
// import { translate } from '@/plugins/i18next'

const { t, i18next } = useTranslation()
</script>
```

## 操作指南

### 1. 添加新的翻译文本

1. **在中文语言包中添加新条目**

   ```bash
   # 编辑 locales/zh-CN.json
   {
     "newKey": "新的中文文本",
     "withVariable": "包含变量的文本: {{value}}"
   }
   ```

2. **运行翻译命令生成英文版本**

   ```bash
   pnpm run i18n
   ```

   > 该命令会调用 `env-cmd lobe-i18n locale`，使用 AI 自动翻译新增的文本

3. **在代码中使用**

   ```vue
   
   <div>
    {{ $t('newKey') }}
    </div>

   <div>
    {{ $t('withVariable', { value: 'test' }) }}
    </div>

   
   <script setup>
   import { useTranslation } from 'i18next-vue'

   const { t } = useTranslation()
   console.log(t('newKey'))
   </script>
   ```

### 2. 修改现有翻译

1. **修改中文语言包** (`locales/zh-CN.json`)
2. **运行翻译命令更新英文版本**
   ```bash
   pnpm run i18n
   ```

### 3. 批量翻译

如果有大量新增文本需要翻译：

```bash
# 设置环境变量指定翻译模型（可选）
export OPENAI_MODEL_NAME=azure/gpt-4o-mini

# 运行翻译
pnpm run i18n
```

### 4. 环境配置

确保设置正确的 AI 翻译服务配置：

```bash
# 创建 .env 文件设置翻译相关环境变量
# 具体变量请参考 .env.example 中的相关注释
```

## 语言包结构规范

### 1. 命名规范

- 使用小驼峰命名：`projectName`
- 功能相关的分组：`setting.appearance.theme.dark`
- 避免过长的嵌套，保持结构清晰

### 2. 文本规范

- 中文语言包作为主要维护对象
- 支持变量插值：`"tableTotal": "总共 {{count}} 个项目"`
- 保持简洁明了，避免冗余

### 3. 分类建议

```json
{
  "common": {
    "confirm": "确认",
    "cancel": "取消"
  },
  "project": {
    "name": "项目名称",
    "create": "创建项目"
  },
  "error": {
    "networkError": "网络错误"
  }
}
```

## 开发流程

### 日常开发流程

1. 在 `locales/zh-CN.json` 中添加新的翻译键值
2. 运行 `pnpm run i18n` 生成英文翻译
3. 在代码中使用 `$t()` 或 `t()` 函数
4. 提交代码时包含翻译文件的更改

### 注意事项

- 不要直接修改 `en-US.json`，它由工具自动生成
- 翻译完成后检查生成的英文文本是否准确
- 变量插值格式：`{{variableName}}`
- 保持翻译键名的语义化和可维护性

## 故障排除

### 常见问题

1. **翻译命令执行失败**

   - 检查网络连接和 AI 服务配置
   - 确认 `.i18nrc.cjs` 配置正确

2. **翻译结果不准确**

   - 调整 `temperature` 参数（0-1，越小越稳定）
   - 检查源文本是否准确清晰

3. **某些文本未被翻译**

   - 确认新增的文本格式正确
   - 检查 JSON 语法是否有错误

4. **开发环境中翻译不生效**
   - 确认 i18next 初始化正确
   - 检查语言包是否正确导入
   - 重启开发服务器

### 调试方法

1. **开启调试模式**

   ```typescript
   i18next.init({
     debug: true, // 开启调试日志
     // ...
   })
   ```

2. **检查当前语言设置**
   ```javascript
   console.log(i18next.language) // 当前语言
   console.log(i18next.store.data) // 所有语言数据
   ```

## 相关命令

| 命令                       | 说明                             |
| -------------------------- | -------------------------------- |
| `pnpm run i18n`            | 执行国际化翻译，将中文翻译为英文 |
| `env-cmd lobe-i18n locale` | 直接调用翻译工具                 |

## 参考资源

- [@lobehub/i18n-cli 文档](https://github.com/lobehub/lobe-cli-toolbox/tree/master/packages/lobe-i18n)
- [i18next 官方文档](https://www.i18next.com/)

---

### Frontend Docs Nice Modal (`frontend/docs/nice-modal.md`)

# Vue Nice Modal

**[@ebay/nice-modal-react](https://github.com/eBay/nice-modal-react) Vue 版本。**

vue-nice-modal 是一个工具库,可以将 Vue.js 的 modal 组件转换为基于 Promise 的 API。

## 使用方式

### 1. Provider 包裹应用

```html

<template>
  <NiceModalProvider>
    <router-view />
  </NiceModalProvider>
</template>

<script setup>
  import { NiceModal } from '@rpa/components'
  const NiceModalProvider = NiceModal.Provider
</script>
```

### 2. 创建模态框组件

```html

<template>
  <van-dialog
    show-cancel-button
    :value="modal.visible"
    :close-on-click-overlay="false"
    :title="title"
    :message="content"
    @closed="modal.remove"
    @confirm="handleConfirm"
    @cancel="handleCancel"
  />
</template>

<script setup>
  import { NiceModal } from '@rpa/components'

  const modal = NiceModal.useModal()
  defineProps(['title', 'content'])

  const handleCancel = () => {
    modal.reject('cancel')
    modal.hide()
  }

  const handleConfirm = () => {
    modal.resolve('confirm')
    modal.hide()
  }
</script>
```

> 可与任何 UI 库配合使用，如 antdv

```html

<template>
  <a-drawer v-bind="NiceModal.antdDrawer(modal)">xxx</a-drawer>
</template>
```

```html

<a-modal v-bind="NiceModal.antdModal(modal)">xxx</a-modal>
```

> 最后使用 NiceModal.create 创建模态框高阶组件

```js
// my-modal.js
import { NiceModal } from '@rpa/components'

import _MyModal from './my-modal.vue'

export const MyModal = NiceModal.create(_MyModal)
```

### 3. 使用模态框

#### 3.1 基础用法 - 直接使用组件

```js
async function showModal() {
  try {
    const res = await NiceModal.show(MyModal, {
      title: '标题',
      content: '内容',
    })
    console.log('结果:', res)
  }
  catch (error) {
    console.log('取消:', error)
  }
}
```

#### 3.2 声明式用法 - 通过 ID 引用已声明的模态框

> 可继承声明处上下文

```html
<template>
  <MyModal id="my-modal" />
</template>

<script setup>
  const showModal = async () => {
    try {
      const res = await NiceModal.show('my-modal', {
        title: '标题',
        content: '内容',
      })
      console.log('结果:', res)
    } catch (error) {
      console.log('取消:', error)
    }
  }
</script>
```

#### 3.3 Hook 用法 - 使用 useModal 组合式 API

```js
const modal = NiceModal.useModal(MyModal)

async function showModal() {
  try {
    const res = await modal.show({
      title: '标题',
      content: '内容',
    })
    console.log('结果:', res)
  }
  catch (error) {
    console.log('取消:', error)
  }
}
```

#### 3.4 注册用法 - 通过注册后使用 ID 调用

```js
// 预先注册模态框
NiceModal.register('register-modal', MyModal)

async function showModal() {
  try {
    const res = await NiceModal.show('register-modal', {
      title: '标题',
      content: '内容',
    })
    console.log('结果:', res)
  }
  catch (error) {
    console.log('取消:', error)
  }
}
```

## API 参考

### 组件

#### `NiceModal.Provider`

模态框容器组件，需要包裹在应用最外层。

#### `NiceModal.create(Component)`

高阶组件，用于创建模态框组件。

### 方法

#### `show(modalId, args?)`

显示模态框，支持传入参数。

- `modalId`: 模态框 ID 或组件
- `args`: 传递给模态框的参数
- 返回: Promise

#### `hide(modalId)`

隐藏模态框。

- `modalId`: 模态框 ID 或组件
- 返回: Promise

#### `remove(modalId)`

从 DOM 中移除模态框。

- `modalId`: 模态框 ID 或组件

#### `register(id, component, props?)`

注册模态框组件。

- `id`: 模态框 ID
- `component`: 模态框组件
- `props`: 默认 props

#### `unregister(id)`

注销模态框组件。

- `id`: 模态框 ID

### Hook

#### `useModal(modal?, args?)`

返回值:

- `id`: 模态框 ID
- `args`: 模态框参数
- `visible`: 可见状态
- `show(args?)`: 显示模态框
- `hide()`: 隐藏模态框
- `remove()`: 移除模态框
- `resolve(value)`: 解析模态框 Promise
- `reject(reason)`: 拒绝模态框 Promise
- `resolveHide(value)`: 解析隐藏 Promise

---

--- METRICS ---
- Files Extracted: 6
- Estimated Token Budget: ~8681 tokens
- Canonical Reference: https://codewiki.google/github.com/iflytek/astron-rpa
