@realtimex/email-automator 2.22.1 → 2.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/src/lib/setup-knowledge.generated.ts +2 -1
- package/api/src/routes/agent.ts +1 -0
- package/api/src/services/AgentService.ts +2 -0
- package/api/src/services/RAGService.ts +26 -3
- package/dist/api/src/lib/setup-knowledge.generated.js +2 -1
- package/dist/api/src/routes/agent.js +1 -0
- package/dist/api/src/services/AgentService.js +1 -0
- package/dist/api/src/services/RAGService.js +23 -4
- package/dist/assets/es-NQpkAluz.js +49 -0
- package/dist/assets/fr-Dt1serdG.js +49 -0
- package/dist/assets/{index-y96M9yNt.js → index-DR7Pa16U.js} +51 -41
- package/dist/assets/ja-46nRzsm5.js +49 -0
- package/dist/assets/ko-DUNCzc8F.js +49 -0
- package/dist/assets/vi-CA9x3uPA.js +49 -0
- package/dist/index.html +1 -1
- package/docs/README.md +9 -18
- package/docs/en/README.md +23 -0
- package/docs/{marketplace → en/marketplace}/listing.md +1 -1
- package/docs/{user-guide → en/user-guide}/GETTING-STARTED.md +2 -1
- package/docs/en/user-guide/GLOSSARY.md +163 -0
- package/docs/es/README.md +23 -0
- package/docs/es/marketplace/listing.md +34 -0
- package/docs/es/user-guide/ACCOUNT.md +52 -0
- package/docs/es/user-guide/AUTOMATION.md +93 -0
- package/docs/es/user-guide/CONFIGURATION.md +61 -0
- package/docs/es/user-guide/DASHBOARD.md +71 -0
- package/docs/es/user-guide/GETTING-STARTED.md +61 -0
- package/docs/es/user-guide/GLOSSARY.md +160 -0
- package/docs/es/user-guide/TROUBLESHOOTING.md +65 -0
- package/docs/fr/README.md +23 -0
- package/docs/fr/marketplace/listing.md +34 -0
- package/docs/fr/user-guide/ACCOUNT.md +52 -0
- package/docs/fr/user-guide/AUTOMATION.md +93 -0
- package/docs/fr/user-guide/CONFIGURATION.md +61 -0
- package/docs/fr/user-guide/DASHBOARD.md +71 -0
- package/docs/fr/user-guide/GETTING-STARTED.md +61 -0
- package/docs/fr/user-guide/GLOSSARY.md +160 -0
- package/docs/fr/user-guide/TROUBLESHOOTING.md +65 -0
- package/docs/ja/README.md +23 -0
- package/docs/ja/marketplace/listing.md +34 -0
- package/docs/ja/user-guide/ACCOUNT.md +52 -0
- package/docs/ja/user-guide/AUTOMATION.md +93 -0
- package/docs/ja/user-guide/CONFIGURATION.md +61 -0
- package/docs/ja/user-guide/DASHBOARD.md +71 -0
- package/docs/ja/user-guide/GETTING-STARTED.md +61 -0
- package/docs/ja/user-guide/GLOSSARY.md +160 -0
- package/docs/ja/user-guide/TROUBLESHOOTING.md +65 -0
- package/docs/ko/README.md +23 -0
- package/docs/ko/marketplace/listing.md +34 -0
- package/docs/ko/user-guide/ACCOUNT.md +52 -0
- package/docs/ko/user-guide/AUTOMATION.md +93 -0
- package/docs/ko/user-guide/CONFIGURATION.md +61 -0
- package/docs/ko/user-guide/DASHBOARD.md +71 -0
- package/docs/ko/user-guide/GETTING-STARTED.md +61 -0
- package/docs/ko/user-guide/GLOSSARY.md +160 -0
- package/docs/ko/user-guide/TROUBLESHOOTING.md +65 -0
- package/docs/vi/README.md +23 -0
- package/docs/vi/marketplace/listing.md +34 -0
- package/docs/vi/user-guide/ACCOUNT.md +52 -0
- package/docs/vi/user-guide/AUTOMATION.md +93 -0
- package/docs/vi/user-guide/CONFIGURATION.md +61 -0
- package/docs/vi/user-guide/DASHBOARD.md +71 -0
- package/docs/vi/user-guide/GETTING-STARTED.md +61 -0
- package/docs/vi/user-guide/GLOSSARY.md +160 -0
- package/docs/vi/user-guide/TROUBLESHOOTING.md +65 -0
- package/package.json +1 -1
- package/scripts/build-setup-knowledge.ts +1 -1
- package/scripts/ingest-knowledge-rag.ts +42 -26
- package/supabase/migrations/20260203150000_add_lang_to_knowledge_chunks.sql +49 -0
- package/dist/assets/es-BySeIenb.js +0 -4
- package/dist/assets/fr-Cj4xUTOj.js +0 -4
- package/dist/assets/ja-DeBZHkY-.js +0 -4
- package/dist/assets/ko-CHMiWHbo.js +0 -4
- package/dist/assets/vi-B4Rp8hRI.js +0 -4
- /package/docs/{user-guide → en/user-guide}/ACCOUNT.md +0 -0
- /package/docs/{user-guide → en/user-guide}/AUTOMATION.md +0 -0
- /package/docs/{user-guide → en/user-guide}/CONFIGURATION.md +0 -0
- /package/docs/{user-guide → en/user-guide}/DASHBOARD.md +0 -0
- /package/docs/{user-guide → en/user-guide}/TROUBLESHOOTING.md +0 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Thuật ngữ
|
|
2
|
+
|
|
3
|
+
Định nghĩa các thuật ngữ phổ biến được sử dụng trong Email Automator và Setup Wizard.
|
|
4
|
+
|
|
5
|
+
## Supabase
|
|
6
|
+
Một nền tảng backend cung cấp cơ sở dữ liệu Postgres được lưu trữ, xác thực, lưu trữ và các API. Email Automator sử dụng Supabase làm lớp cơ sở dữ liệu và xác thực.
|
|
7
|
+
|
|
8
|
+
## BYOK (Bring Your Own Key)
|
|
9
|
+
Một mô hình thiết lập nơi bạn kết nối dự án Supabase của riêng mình thay vì sử dụng một backend chung. Điều này giữ dữ liệu của bạn trong cơ sở hạ tầng của chính bạn.
|
|
10
|
+
|
|
11
|
+
## Supabase Project ID
|
|
12
|
+
Mã định danh duy nhất cho dự án Supabase của bạn (thường được hiển thị trong URL dự án hoặc cài đặt).
|
|
13
|
+
|
|
14
|
+
## Supabase Project URL
|
|
15
|
+
URL cơ sở cho dự án Supabase của bạn, được ứng dụng sử dụng để kết nối với cơ sở dữ liệu và các API.
|
|
16
|
+
|
|
17
|
+
## Anon Key (Public API Key)
|
|
18
|
+
Khóa API công khai cho dự án Supabase của bạn. Nó an toàn để sử dụng ở phía khách hàng nhưng vẫn tuân theo Row Level Security (RLS).
|
|
19
|
+
|
|
20
|
+
## Access Token
|
|
21
|
+
Một token từ tài khoản Supabase của bạn cho phép Setup Wizard tạo hoặc quản lý các dự án thay mặt bạn (được sử dụng trong Quick Start).
|
|
22
|
+
|
|
23
|
+
## Managed Provisioning (Quick Start)
|
|
24
|
+
Setup Wizard sử dụng Access Token của bạn để tự động tạo một dự án Supabase, áp dụng các di chuyển (migrations), triển khai Edge Functions và nạp cơ sở kiến thức.
|
|
25
|
+
|
|
26
|
+
## Manual Sync (Connect Existing Project)
|
|
27
|
+
Bạn kết nối một dự án Supabase hiện có bằng cách cung cấp Project URL và Anon Key. Các di chuyển có thể được chạy bởi wizard nếu Access Token được cung cấp.
|
|
28
|
+
|
|
29
|
+
## Managed Provisioning vs Manual Sync
|
|
30
|
+
**Managed Provisioning** tạo một dự án Supabase mới cho bạn bằng cách sử dụng Access Token.
|
|
31
|
+
**Manual Sync** kết nối với một dự án Supabase hiện có bằng Project URL và Anon Key của bạn.
|
|
32
|
+
|
|
33
|
+
## Migration (Di chuyển)
|
|
34
|
+
Các thay đổi cơ sở dữ liệu để tạo hoặc cập nhật các bảng, khung nhìn (views), hàm và chính sách. Các di chuyển giữ cho schema cơ sở dữ liệu của bạn đồng bộ với ứng dụng.
|
|
35
|
+
|
|
36
|
+
## Schema
|
|
37
|
+
Cấu trúc cơ sở dữ liệu của bạn: các bảng, cột, kiểu dữ liệu, chỉ mục, hàm và chính sách.
|
|
38
|
+
|
|
39
|
+
## SQL
|
|
40
|
+
Ngôn ngữ được sử dụng để định nghĩa và truy vấn các cấu trúc và dữ liệu cơ sở dữ liệu.
|
|
41
|
+
|
|
42
|
+
## Version Mismatch (Lệch phiên bản)
|
|
43
|
+
Khi phiên bản schema mong đợi của ứng dụng khác với phiên bản thực tế của cơ sở dữ liệu. Setup Wizard hoặc công cụ di chuyển sẽ nhắc bạn chuẩn hóa.
|
|
44
|
+
|
|
45
|
+
## Database Version (Cài đặt tài khoản)
|
|
46
|
+
Phiên bản chính của cơ sở dữ liệu được hiển thị trong Cài đặt tài khoản. Nó được sử dụng để hướng dẫn các di chuyển và phải khớp với phiên bản Postgres của dự án Supabase của bạn.
|
|
47
|
+
|
|
48
|
+
## Rollback
|
|
49
|
+
Hoàn tác một cuộc di chuyển. Trong Supabase, các lần rollback được thực hiện thủ công và nên được sử dụng cẩn thận.
|
|
50
|
+
|
|
51
|
+
## RLS (Row Level Security)
|
|
52
|
+
Một tính năng bảo mật của Postgres giới hạn hàng nào người dùng có thể đọc hoặc ghi. Supabase sử dụng RLS để bảo vệ dữ liệu.
|
|
53
|
+
|
|
54
|
+
## Edge Functions
|
|
55
|
+
Các hàm không máy chủ (serverless) được lưu trữ bởi Supabase. Email Automator sử dụng chúng cho các luồng OAuth và các hoạt động bảo mật.
|
|
56
|
+
|
|
57
|
+
## Service Role Key
|
|
58
|
+
Một khóa Supabase mạnh mẽ có thể bỏ qua RLS. Nó không bao giờ được để lộ cho khách hàng.
|
|
59
|
+
|
|
60
|
+
## Anon Key vs Service Role Key
|
|
61
|
+
**Anon key** an toàn cho việc sử dụng của khách hàng và tuân thủ RLS. **Service role key** bỏ qua RLS và chỉ được sử dụng trên các máy chủ đáng tin dậy.
|
|
62
|
+
|
|
63
|
+
## RealTimeX Desktop
|
|
64
|
+
Ứng dụng cục bộ cung cấp các dịch vụ AI (LLMs, embeddings, TTS) được sử dụng bởi Email Automator.
|
|
65
|
+
|
|
66
|
+
## Digital Persona (Cá tính kỹ thuật số)
|
|
67
|
+
Một hồ sơ xác định giọng điệu, phong cách và sở thích của bạn cho các bản nháp và câu trả lời do AI tạo ra.
|
|
68
|
+
|
|
69
|
+
## Persona Tone (Giọng điệu cá tính)
|
|
70
|
+
Tính chất cảm xúc của các câu trả lời (ví dụ: thân thiện, trang trọng, trực tiếp).
|
|
71
|
+
|
|
72
|
+
## Persona Style (Phong cách cá tính)
|
|
73
|
+
Các sở thích về phong cách viết (ví dụ: ngắn gọn, chi tiết, các điểm đầu dòng).
|
|
74
|
+
|
|
75
|
+
## Persona Voice (Tiếng nói cá tính)
|
|
76
|
+
"Âm thanh" tổng thể trong văn phong của bạn, bao gồm cách diễn đạt và nhịp điệu.
|
|
77
|
+
|
|
78
|
+
## Persona Signature (Chữ ký cá tính)
|
|
79
|
+
Một lời chào kết chuẩn hóa được sử dụng trong các câu trả lời (tên, chức danh, công ty).
|
|
80
|
+
|
|
81
|
+
## Persona Role (Vai trò cá tính)
|
|
82
|
+
Chức danh công việc hoặc vai trò của bạn, được sử dụng để định hình khung câu trả lời.
|
|
83
|
+
|
|
84
|
+
## Persona Company (Công ty cá tính)
|
|
85
|
+
Tên tổ chức được sử dụng trong các câu trả lời khi thích hợp.
|
|
86
|
+
|
|
87
|
+
## Persona Language (Ngôn ngữ cá tính)
|
|
88
|
+
Ngôn ngữ chính cho các bản nháp được tạo ra.
|
|
89
|
+
|
|
90
|
+
## Express API
|
|
91
|
+
Backend cục bộ xử lý việc đồng bộ hóa email, xử lý AI và thực thi tự động hóa.
|
|
92
|
+
|
|
93
|
+
## Realtime (Supabase)
|
|
94
|
+
Các cập nhật trực tiếp từ cơ sở dữ liệu đến ứng dụng. Được sử dụng để phản ánh các email mới, trạng thái đồng bộ hóa hoặc hoạt động mà không cần tải lại trang.
|
|
95
|
+
|
|
96
|
+
## LLM (Large Language Model)
|
|
97
|
+
Một mô hình AI được sử dụng để phân tích và tạo phản hồi (ví dụ: phân loại, soạn thảo câu trả lời).
|
|
98
|
+
|
|
99
|
+
## Embedding Model
|
|
100
|
+
Một mô hình chuyển đổi văn bản thành các vectơ để tìm kiếm ngữ nghĩa. Được sử dụng bởi cơ sở kiến thức và RAG.
|
|
101
|
+
|
|
102
|
+
## Embeddings
|
|
103
|
+
Các biểu diễn vectơ của văn bản được sử dụng để tìm kiếm ngữ nghĩa trong cơ sở kiến thức.
|
|
104
|
+
|
|
105
|
+
## RAG (Retrieval-Augmented Generation)
|
|
106
|
+
Một phương pháp truy xuất các tài liệu liên quan và cung cấp chúng cho AI để các câu trả lời bám sát vào tài liệu của bạn.
|
|
107
|
+
|
|
108
|
+
## Knowledge Base Ingestion (Nạp cơ sở kiến thức)
|
|
109
|
+
Quá trình chuyển đổi tài liệu thành các embeddings có thể tìm kiếm và lưu trữ chúng trong cơ sở dữ liệu.
|
|
110
|
+
|
|
111
|
+
## TTS (Text-to-Speech)
|
|
112
|
+
Chuyển đổi các phản hồi của AI thành âm thanh nói.
|
|
113
|
+
|
|
114
|
+
## TTS Provider vs Voice
|
|
115
|
+
Nhà cung cấp là dịch vụ tạo ra lời nói; giọng nói là người nói/cá tính cụ thể trong nhà cung cấp đó.
|
|
116
|
+
|
|
117
|
+
## OAuth
|
|
118
|
+
Một tiêu chuẩn ủy quyền cho phép ứng dụng truy cập tài khoản email của bạn mà không cần lưu trữ mật khẩu của bạn.
|
|
119
|
+
|
|
120
|
+
## OAuth Consent Screen
|
|
121
|
+
Màn hình nơi bạn cấp quyền cho Email Automator truy cập tài khoản email của bạn.
|
|
122
|
+
|
|
123
|
+
## Access Token (OAuth)
|
|
124
|
+
Một token ngắn hạn được sử dụng để gọi các API của nhà cung cấp email. Nó sẽ hết hạn và được làm mới tự động.
|
|
125
|
+
|
|
126
|
+
## Refresh Token
|
|
127
|
+
Một token dài hạn được sử dụng để nhận các access token mới mà không cần xác thực lại.
|
|
128
|
+
|
|
129
|
+
## Gmail API
|
|
130
|
+
API chính thức của Google để truy cập dữ liệu Gmail và gửi email.
|
|
131
|
+
|
|
132
|
+
## Microsoft Graph
|
|
133
|
+
API của Microsoft cho dữ liệu Outlook và Microsoft 365 (thư, lịch, danh bạ).
|
|
134
|
+
|
|
135
|
+
## IMAP / SMTP
|
|
136
|
+
Các giao thức email. IMAP đọc thư; SMTP gửi thư. (Email Automator sử dụng các API của nhà cung cấp thay vì IMAP/SMTP thô.)
|
|
137
|
+
|
|
138
|
+
## App Registration (Microsoft)
|
|
139
|
+
Một cấu hình ứng dụng trong Azure cung cấp thông tin xác thực cho quyền truy cập Microsoft Graph.
|
|
140
|
+
|
|
141
|
+
## Client ID
|
|
142
|
+
Mã định danh công khai cho ứng dụng OAuth của bạn (Google/Microsoft).
|
|
143
|
+
|
|
144
|
+
## Client Secret
|
|
145
|
+
Một bí mật riêng tư cho ứng dụng OAuth của bạn. Hãy coi nó như một mật khẩu.
|
|
146
|
+
|
|
147
|
+
## Redirect URI
|
|
148
|
+
URL gọi lại nơi nhà cung cấp email gửi người dùng đến sau khi ủy quyền OAuth.
|
|
149
|
+
|
|
150
|
+
## Device Code Flow
|
|
151
|
+
Một luồng OAuth nơi bạn xác thực trong trình duyệt bằng một mã ngắn, thường được sử dụng cho các ứng dụng máy để bàn.
|
|
152
|
+
|
|
153
|
+
## Tenant ID
|
|
154
|
+
Mã định danh đối tượng thuê (tenant) của Microsoft. Sử dụng "common" cho đa đối tượng thuê hoặc một ID đối tượng thuê cụ thể cho quyền truy cập chỉ dành cho tổ chức.
|
|
155
|
+
|
|
156
|
+
## Sync Scope
|
|
157
|
+
Xác định lượng lịch sử cần đồng bộ hóa (ví dụ: X ngày qua) và những tài khoản nào được bao gồm.
|
|
158
|
+
|
|
159
|
+
## Labels (Gmail) / Folders (Outlook)
|
|
160
|
+
Các cấu trúc tổ chức trong các nhà cung cấp email. Các nhãn (Labels) gắn thẻ cho các tin nhắn; các thư mục (folders) tổ chức chúng vào các thùng chứa.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Khắc phục sự cố & Hỗ trợ
|
|
2
|
+
|
|
3
|
+
Nếu bạn gặp sự cố, hướng dẫn này bao gồm các lỗi phổ biến nhất và giải pháp cho chúng.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 📡 Các vấn đề về đồng bộ hóa
|
|
8
|
+
|
|
9
|
+
### Email không xuất hiện trong Dashboard
|
|
10
|
+
* **Kiểm tra ngày "Sync From"**: AI chỉ xử lý các email nhận được *sau* ngày này.
|
|
11
|
+
* **Đặt lại Checkpoint**: Nếu bạn đã thay đổi ngày bắt đầu và muốn quét lại các email cũ, hãy nhấp vào nút **Reset Checkpoint** trong bảng Sync Scope.
|
|
12
|
+
* **Giới hạn đợt (Batch Limits)**: Cài đặt **Max Emails** giới hạn số lượng email được xử lý trong mỗi lần chạy. Nếu bạn có một lượng lớn thư tồn đọng, có thể mất vài chu kỳ đồng bộ hóa để bắt kịp.
|
|
13
|
+
* **Kích hoạt thủ công**: Nhấp vào **Run Sync Now** trên Dashboard để buộc kiểm tra ngay lập tức.
|
|
14
|
+
|
|
15
|
+
### "Sync Failed" hoặc "Backend Not Connected"
|
|
16
|
+
* **Máy chủ cục bộ**: Đảm bảo ứng dụng Email Automator đang mở và đang chạy.
|
|
17
|
+
* **Nguồn cấp dữ liệu hoạt động trực tiếp**: Mở terminal **Live Activity**. Nó thường chứa các thông báo lỗi kỹ thuật cụ thể (ví dụ: "Network Error" hoặc "401 Unauthorized").
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🔑 Xác thực & Quyền hạn
|
|
22
|
+
|
|
23
|
+
### Google/Gmail: `redirect_uri_mismatch`
|
|
24
|
+
* **Cách khắc phục**: Redirect URI của bạn trong Google Cloud Console phải khớp *chính xác* với URI hiển thị trong Email Automator.
|
|
25
|
+
* **Ví dụ**: `https://your-ref.supabase.co/functions/v1/auth-gmail/callback` (đảm bảo không có dấu gạch chéo hoặc dấu cách ở cuối).
|
|
26
|
+
|
|
27
|
+
### Microsoft/Outlook: Đăng nhập thất bại hoặc hết thời gian
|
|
28
|
+
* **Đăng ký ứng dụng**: Đảm bảo Đăng ký ứng dụng Azure của bạn đã đặt "Allow public client flows" thành **Yes**.
|
|
29
|
+
* **Account Type**: Đảm bảo bạn đã chọn "Accounts in any organizational directory and personal Microsoft accounts" trong quá trình đăng ký.
|
|
30
|
+
|
|
31
|
+
### Supabase: "Invalid API Key"
|
|
32
|
+
* **Cách khắc phục**: Luôn sử dụng khóa **anon (public)**. Khóa **service_role** sẽ bị ứng dụng từ chối vì lý do bảo mật.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 🤖 Tích hợp AI & RealTimeX
|
|
37
|
+
|
|
38
|
+
### AI chậm hoặc không phản hồi
|
|
39
|
+
* **Các mô hình cục bộ**: Nếu sử dụng Ollama hoặc LM Studio, hãy đảm bảo máy của bạn có đủ RAM và GPU không bị tải quá nặng.
|
|
40
|
+
* **Khám phá**: Nếu không có mô hình nào xuất hiện trong menu thả xuống, hãy đảm bảo **RealTimeX Desktop** đang chạy và bạn đã cấu hình ít nhất một nhà cung cấp AI trong đó.
|
|
41
|
+
|
|
42
|
+
### "Smart Drafts" không được tạo
|
|
43
|
+
* **Chuyển đổi hệ thống**: Đảm bảo **Smart Drafts** đã được bật (**ON**) trong tab Auto-Pilot.
|
|
44
|
+
* **Xung đột quy tắc**: Xác minh rằng quy tắc khớp với email thực sự bao gồm hành động **Draft**.
|
|
45
|
+
* **Bộ lọc an toàn**: AI sẽ tự động bỏ qua việc soạn nháp cho các địa chỉ `no-reply` và một số thông báo tự động nhất định để ngăn chặn "vòng lặp bot".
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 🗄️ Cơ sở dữ liệu & Di chuyển
|
|
50
|
+
|
|
51
|
+
### Biểu ngữ "Yêu cầu di chuyển cơ sở dữ liệu" (Database Migration Required)
|
|
52
|
+
* **Tại sao nó xảy ra**: Ứng dụng cục bộ của bạn đã được cập nhật và schema cơ sở dữ liệu Supabase của bạn cần được cập nhật để hỗ trợ các tính năng mới.
|
|
53
|
+
* **Cách khắc phục**: Nhấp vào **Update Now** trong biểu ngữ. Bạn sẽ cần **Supabase Access Token** để chạy cập nhật tự động.
|
|
54
|
+
|
|
55
|
+
### Live Terminal trống hoặc hiển thị "404"
|
|
56
|
+
* **Quyền Realtime**: Đảm bảo bạn đã chạy các bản di chuyển mới nhất. Bảng `processing_events` phải tồn tại và đã bật các chính sách RLS (Row Level Security) chính xác.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 🆘 Vẫn cần hỗ trợ?
|
|
61
|
+
|
|
62
|
+
Nếu vấn đề của bạn không được liệt kê ở đây:
|
|
63
|
+
1. Kiểm tra **System Logs** trong Cài đặt tài khoản để xem các dấu vết kỹ thuật (stack traces).
|
|
64
|
+
2. Xem lại [Tài liệu dành cho nhà phát triển](../docs-dev/README.md) để biết chi tiết thiết lập nâng cao.
|
|
65
|
+
3. Mở một yêu cầu (ticket) hoặc thảo luận trong kho lưu trữ dự án.
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
6
6
|
const __dirname = dirname(__filename);
|
|
7
7
|
|
|
8
8
|
// Paths
|
|
9
|
-
const DOCS_DIR = join(__dirname, '../docs/user-guide');
|
|
9
|
+
const DOCS_DIR = join(__dirname, '../docs/en/user-guide');
|
|
10
10
|
const OUTPUT_FILE = join(__dirname, '../api/src/lib/setup-knowledge.generated.ts');
|
|
11
11
|
|
|
12
12
|
function buildSetupKnowledge() {
|
|
@@ -14,10 +14,12 @@ import { SDKService } from '../api/src/services/SDKService.js';
|
|
|
14
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname = path.dirname(__filename);
|
|
16
16
|
const ROOT_DIR = path.join(__dirname, '..');
|
|
17
|
-
|
|
18
|
-
const USER_GUIDE_DIR = path.join(ROOT_DIR, 'docs/user-guide');
|
|
17
|
+
const DOCS_ROOT = path.join(ROOT_DIR, 'docs');
|
|
19
18
|
const packageJson = JSON.parse(fs.readFileSync(path.join(ROOT_DIR, 'package.json'), 'utf-8'));
|
|
20
19
|
|
|
20
|
+
// Supported languages for RAG
|
|
21
|
+
const SUPPORTED_LANGUAGES = ['en', 'fr', 'es', 'ja', 'ko', 'vi'];
|
|
22
|
+
|
|
21
23
|
// Initialize Supabase client
|
|
22
24
|
// Prefer SERVICE_ROLE_KEY for admin operations (bypasses RLS)
|
|
23
25
|
// Fallback to ANON_KEY only if service role not available
|
|
@@ -41,12 +43,13 @@ interface Chunk {
|
|
|
41
43
|
source_file: string;
|
|
42
44
|
section_title?: string;
|
|
43
45
|
doc_type: string;
|
|
46
|
+
lang: string;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
/**
|
|
47
50
|
* Split markdown content into chunks by sections
|
|
48
51
|
*/
|
|
49
|
-
function chunkMarkdown(content: string, sourceFile: string, docType: string = 'user_guide'): Chunk[] {
|
|
52
|
+
function chunkMarkdown(content: string, sourceFile: string, docType: string = 'user_guide', lang: string): Chunk[] {
|
|
50
53
|
const chunks: Chunk[] = [];
|
|
51
54
|
|
|
52
55
|
// Split by H2 headers (##)
|
|
@@ -61,7 +64,8 @@ function chunkMarkdown(content: string, sourceFile: string, docType: string = 'u
|
|
|
61
64
|
const normalizedTitle = titleMatch
|
|
62
65
|
? titleMatch[1]
|
|
63
66
|
// Strip non-ASCII to avoid lone surrogate issues in JSON payloads.
|
|
64
|
-
|
|
67
|
+
// EXCEPTION: Keep non-ASCII for non-English languages to preserve meaning
|
|
68
|
+
// .replace(/[^\x20-\x7E]/g, '')
|
|
65
69
|
.replace(/\s{2,}/g, ' ')
|
|
66
70
|
.trim()
|
|
67
71
|
: '';
|
|
@@ -79,7 +83,8 @@ function chunkMarkdown(content: string, sourceFile: string, docType: string = 'u
|
|
|
79
83
|
content: cleanedContent,
|
|
80
84
|
source_file: sourceFile,
|
|
81
85
|
section_title: sectionTitle,
|
|
82
|
-
doc_type: docType
|
|
86
|
+
doc_type: docType,
|
|
87
|
+
lang: lang
|
|
83
88
|
});
|
|
84
89
|
}
|
|
85
90
|
|
|
@@ -130,9 +135,9 @@ async function generateEmbedding(text: string): Promise<number[]> {
|
|
|
130
135
|
* Main ingestion function
|
|
131
136
|
*/
|
|
132
137
|
async function ingestKnowledge() {
|
|
133
|
-
console.log('📚 Starting knowledge base ingestion...');
|
|
138
|
+
console.log('📚 Starting multilingual knowledge base ingestion...');
|
|
134
139
|
console.log(` Version: ${packageJson.version}`);
|
|
135
|
-
console.log(`
|
|
140
|
+
console.log(` Languages: ${SUPPORTED_LANGUAGES.join(', ')}`);
|
|
136
141
|
|
|
137
142
|
// Initialize SDK
|
|
138
143
|
try {
|
|
@@ -147,29 +152,39 @@ async function ingestKnowledge() {
|
|
|
147
152
|
process.exit(1);
|
|
148
153
|
}
|
|
149
154
|
|
|
150
|
-
// Read all user guide files
|
|
151
|
-
const files = fs.readdirSync(USER_GUIDE_DIR).filter(f => f.endsWith('.md'));
|
|
152
|
-
console.log(`\n📖 Found ${files.length} user guide files`);
|
|
153
|
-
|
|
154
155
|
const allChunks: Array<Chunk & { content_hash: string; version: string }> = [];
|
|
155
156
|
|
|
156
|
-
//
|
|
157
|
-
for (const
|
|
158
|
-
const
|
|
159
|
-
|
|
157
|
+
// Process each language
|
|
158
|
+
for (const lang of SUPPORTED_LANGUAGES) {
|
|
159
|
+
const langDir = path.join(DOCS_ROOT, lang, 'user-guide');
|
|
160
|
+
|
|
161
|
+
if (!fs.existsSync(langDir)) {
|
|
162
|
+
console.warn(`⚠️ Warning: Documentation directory not found for language: ${lang} (${langDir})`);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Read all user guide files for this language
|
|
167
|
+
const files = fs.readdirSync(langDir).filter(f => f.endsWith('.md'));
|
|
168
|
+
console.log(`\n📖 Processing [${lang}]: Found ${files.length} user guide files`);
|
|
169
|
+
|
|
170
|
+
// Chunk all files
|
|
171
|
+
for (const file of files) {
|
|
172
|
+
const content = fs.readFileSync(path.join(langDir, file), 'utf-8');
|
|
173
|
+
const chunks = chunkMarkdown(content, file, 'user_guide', lang);
|
|
160
174
|
|
|
161
|
-
|
|
175
|
+
console.log(` [${lang}] ${file}: ${chunks.length} chunks`);
|
|
162
176
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
177
|
+
for (const chunk of chunks) {
|
|
178
|
+
allChunks.push({
|
|
179
|
+
...chunk,
|
|
180
|
+
content_hash: hashContent(chunk.content),
|
|
181
|
+
version: packageJson.version
|
|
182
|
+
});
|
|
183
|
+
}
|
|
169
184
|
}
|
|
170
185
|
}
|
|
171
186
|
|
|
172
|
-
console.log(`\n📦 Total chunks: ${allChunks.length}`);
|
|
187
|
+
console.log(`\n📦 Total chunks across all languages: ${allChunks.length}`);
|
|
173
188
|
|
|
174
189
|
// Clear existing chunks for this version
|
|
175
190
|
console.log('\n🧹 Clearing old chunks...');
|
|
@@ -206,19 +221,20 @@ async function ingestKnowledge() {
|
|
|
206
221
|
source_file: chunk.source_file,
|
|
207
222
|
section_title: chunk.section_title,
|
|
208
223
|
doc_type: chunk.doc_type,
|
|
224
|
+
lang: chunk.lang,
|
|
209
225
|
embedding: embedding,
|
|
210
226
|
version: chunk.version
|
|
211
227
|
});
|
|
212
228
|
|
|
213
229
|
if (insertError) {
|
|
214
|
-
console.error(`${progress} ❌ ${chunk.
|
|
230
|
+
console.error(`${progress} ❌ [${chunk.lang}] ${chunk.source_file}:`, insertError.message);
|
|
215
231
|
errorCount++;
|
|
216
232
|
} else {
|
|
217
|
-
console.log(`${progress} ✓ ${chunk.source_file} - ${chunk.section_title || 'Untitled'}`);
|
|
233
|
+
console.log(`${progress} ✓ [${chunk.lang}] ${chunk.source_file} - ${chunk.section_title || 'Untitled'}`);
|
|
218
234
|
successCount++;
|
|
219
235
|
}
|
|
220
236
|
} catch (error: any) {
|
|
221
|
-
console.error(`${progress} ❌ ${chunk.source_file}:`, error.message);
|
|
237
|
+
console.error(`${progress} ❌ [${chunk.lang}] ${chunk.source_file}:`, error.message);
|
|
222
238
|
errorCount++;
|
|
223
239
|
}
|
|
224
240
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
-- Add language column to knowledge_chunks for multilingual RAG.
|
|
2
|
+
-- Existing rows default to 'en'; re-run ingest:knowledge after deploying
|
|
3
|
+
-- to populate all language variants.
|
|
4
|
+
ALTER TABLE knowledge_chunks ADD COLUMN IF NOT EXISTS lang TEXT NOT NULL DEFAULT 'en';
|
|
5
|
+
|
|
6
|
+
-- Index for language filtering
|
|
7
|
+
CREATE INDEX IF NOT EXISTS knowledge_chunks_lang_idx ON knowledge_chunks(lang);
|
|
8
|
+
|
|
9
|
+
-- Drop the previous 4-param overload so CREATE OR REPLACE below is the only signature.
|
|
10
|
+
-- Without this, both overloads coexist and PostgREST raises PGRST203.
|
|
11
|
+
DROP FUNCTION IF EXISTS search_knowledge(vector, double precision, integer, text);
|
|
12
|
+
|
|
13
|
+
-- Replace search function with optional lang_filter.
|
|
14
|
+
-- NULL → search across all languages (original behaviour).
|
|
15
|
+
-- value → restrict to that language only.
|
|
16
|
+
-- Fallback (retry without filter when zero rows) is handled in application code.
|
|
17
|
+
CREATE OR REPLACE FUNCTION search_knowledge(
|
|
18
|
+
query_embedding vector,
|
|
19
|
+
match_threshold float DEFAULT 0.7,
|
|
20
|
+
match_count int DEFAULT 5,
|
|
21
|
+
model_filter text DEFAULT NULL,
|
|
22
|
+
lang_filter text DEFAULT NULL
|
|
23
|
+
)
|
|
24
|
+
RETURNS TABLE (
|
|
25
|
+
id UUID,
|
|
26
|
+
content TEXT,
|
|
27
|
+
source_file TEXT,
|
|
28
|
+
section_title TEXT,
|
|
29
|
+
similarity float
|
|
30
|
+
)
|
|
31
|
+
LANGUAGE plpgsql
|
|
32
|
+
AS $$
|
|
33
|
+
BEGIN
|
|
34
|
+
RETURN QUERY
|
|
35
|
+
SELECT
|
|
36
|
+
knowledge_chunks.id,
|
|
37
|
+
knowledge_chunks.content,
|
|
38
|
+
knowledge_chunks.source_file,
|
|
39
|
+
knowledge_chunks.section_title,
|
|
40
|
+
1 - (knowledge_chunks.embedding <=> query_embedding) AS similarity
|
|
41
|
+
FROM knowledge_chunks
|
|
42
|
+
WHERE
|
|
43
|
+
(model_filter IS NULL OR knowledge_chunks.version = model_filter)
|
|
44
|
+
AND (lang_filter IS NULL OR knowledge_chunks.lang = lang_filter)
|
|
45
|
+
AND 1 - (knowledge_chunks.embedding <=> query_embedding) > match_threshold
|
|
46
|
+
ORDER BY knowledge_chunks.embedding <=> query_embedding
|
|
47
|
+
LIMIT match_count;
|
|
48
|
+
END;
|
|
49
|
+
$$;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
const e={"app.name":"Email Automator","app.connecting":"Conectando cuenta...","app.loadingWorkspace":"Cargando tu espacio de trabajo...","app.loggedOut":"Sesión cerrada exitosamente","app.statusLive":"EN VIVO","app.statusOffline":"DESCONECTADO","common.loading":"Cargando...","common.save":"Guardar cambios","common.cancel":"Cancelar","common.delete":"Eliminar","common.success":"Éxito","common.error":"Error","common.warning":"Advertencia","common.syncNow":"Sincronizar ahora","common.syncing":"Sincronizando...","common.stopSync":"Detener sincronización","common.systemSync":"Sincronización del sistema","common.viewLogs":"Ver registros","common.saveChanges":"Guardar cambios","common.errorOccurred":"Ocurrió un error","common.previous":"Anterior","common.next":"Siguiente","common.of":"de","common.yes":"Sí","common.no":"No","common.archive":"Archivar","common.flag":"Marcar","common.on":"Activado","common.off":"Desactivado","common.enabled":"Habilitado","common.disabled":"Deshabilitado","common.active":"Activo","common.inactive":"Inactivo","common.draft":"Borrador","common.star":"Estrella","nav.dashboard":"Panel de control","nav.drafts":"Borradores","nav.autopilot":"Piloto automático","nav.analytics":"Analítica","nav.configuration":"Configuración","nav.accountSettings":"Configuración de cuenta","nav.signOut":"Cerrar sesión","drafts.title":"Centro de revisión de borradores","drafts.pending":"borradores pendientes","drafts.noDrafts":"No hay borradores pendientes","drafts.noDraftsDesc":"Las respuestas borrador generadas por IA aparecerán aquí para su revisión","drafts.send":"Enviar ahora","drafts.preview":"Vista previa","drafts.dismiss":"Descartar","drafts.regenerate":"Regenerar","drafts.selectAll":"Seleccionar todo","drafts.sendSelected":"Enviar seleccionados","drafts.dismissSelected":"Descartar seleccionados","drafts.filterByAccount":"Todas las cuentas","drafts.filterByDate":"Filtrar por fecha","drafts.originalEmail":"Correo electrónico original","drafts.aiReply":"Respuesta generada por IA","drafts.createdBy":"Creado por regla:","drafts.sendSuccess":"¡Borrador enviado con éxito!","drafts.sendError":"Error al enviar el borrador","drafts.dismissSuccess":"Borrador descartado","drafts.loadError":"Error al cargar borradores","login.title":"Bienvenido de nuevo","login.subtitle":"Inicia sesión en tu agente de email con IA","login.email":"Dirección de correo electrónico","login.password":"Contraseña","login.signIn":"Iniciar sesión","login.noAccount":"¿No tienes una cuenta?","login.alreadyHaveAccount":"¿Ya tienes una cuenta?","login.signUp":"Registrarse","login.forgotPassword":"¿Olvidaste tu contraseña?","login.initialize":"Inicializar Automator","login.secureLogin":"Inicio de sesión seguro","login.firstNamePlaceholder":"Juan","login.lastNamePlaceholder":"Pérez","login.emailPlaceholder":"admin@automator.ai","login.initializeMaster":"Inicializar maestro","login.sendMagicLink":"Enviar enlace mágico","login.openDashboard":"Abrir panel de control","setup.title":"Configuración del sistema","setup.initiation":"Bienvenido","setup.coordinates":"Detalles de conexión","setup.foundation":"Configuración de base de datos","setup.ignition":"Lanzamiento","setup.start":"Iniciar configuración","setup.welcomeTitle":"Inicializando Automator","setup.welcomeSubtitle":"Configurando tu entorno especializado para inteligencia de bandeja de entrada de alta frecuencia.","setup.encryptedTitle":"Encriptado","setup.encryptedDesc":"Seguridad de datos autoalojados.","setup.turboTitle":"Turbo","setup.turboDesc":"Inferencia de IA en menos de un segundo.","setup.getStarted":"Comenzar","setup.connectionMode":"Modo de conexión","setup.selectVector":"Seleccionar modo de implementación","setup.quickIgnition":"Inicio rápido","setup.autoProvision":"Aprovisionamiento automático mediante token","setup.manualSync":"Sincronización manual","setup.existingCredentials":"Credenciales existentes","setup.abortAccess":"Abortar acceso","setup.injectCoordinates":"Ingresar credenciales existentes","setup.platformUrl":"URL de la plataforma","setup.urlHelp":"Ingrese la URL completa o solo el ID del proyecto","setup.anonMatrixKey":"Clave anónima de Supabase","setup.keyHelp":"Se encuentra en la configuración de tu proyecto Supabase","setup.back":"Atrás","setup.engage":"Conectar","setup.installation":"Instalación","setup.applyingSchema":"Configurando base de datos...","setup.emptyProject":"Proyecto vacío detectado. La inicialización es obligatoria para instalar los sistemas de IA principales.","setup.versionMismatch":"Incompatibilidad de versión detectada. Se recomienda normalización.","setup.tokenRequired":"Token de gestión requerido","setup.migrateHelp":"Se usa una vez para ejecutar migraciones en tu backend.","setup.bypassRisk":"Omitir (Arriesgado)","setup.installSystems":"Instalar sistemas","setup.normalizeSystem":"Normalizar sistema","setup.retryInstallation":"Reintentar instalación","setup.agent.systemInstruction":'Eres el asistente del Asistente de configuración. Guía al usuario para conectar Supabase, elegir un modo de configuración y completar las migraciones. Pide solo el siguiente dato requerido y ofrece pasos claros. Si el usuario dice "ayúdame a configurar", enumera inmediatamente los pasos de este asistente.',"dashboard.recentAnalysis":"Análisis reciente","dashboard.emails":"correos electrónicos","dashboard.noEmails":"No se encontraron correos electrónicos","dashboard.noEmailsConnected":"Conecta tu cuenta de correo electrónico para comenzar.","dashboard.noEmailsFilters":"Intenta sincronizar o ajustar tus filtros.","dashboard.syncInProgress":"Sincronización en progreso...","dashboard.syncInProgressDesc":"Obteniendo y analizando correos electrónicos. Los nuevos correos aparecerán automáticamente a continuación.","dashboard.aiTrace":"Rastreo de procesamiento de IA","dashboard.aiTraceDesc":"Registros paso a paso de cómo la IA analizó y actuó sobre este correo electrónico.","dashboard.noTrace":"No se encontraron eventos de rastreo detallados para este correo electrónico.","dashboard.syncNow":"Sincronizar ahora","dashboard.syncing":"Sincronizando...","dashboard.searchPlaceholder":"Buscar correos electrónicos...","dashboard.search":"Buscar","dashboard.receivedTime":"Hora de recepción","dashboard.processedTime":"Hora de procesamiento","dashboard.receivedAbbr":"REC","dashboard.processedAbbr":"PROC","dashboard.sortOldest":"Ordenar: Más antiguo primero","dashboard.sortNewest":"Ordenar: Más reciente primero","dashboard.category.all":"Todos","dashboard.category.none":"ninguno","dashboard.emailDetails":"Detalles del correo electrónico","dashboard.emailContent":"Contenido del correo electrónico (enviado al LLM)","dashboard.from":"De:","dashboard.subject":"Asunto:","dashboard.summary":"Resumen:","dashboard.keyPoints":"Puntos clave:","dashboard.aiDraftReply":"Borrador de respuesta de IA","dashboard.draftSavedHelp":"* Este borrador ya está guardado en tu carpeta de Borradores de {provider}.","dashboard.syncScope":"Alcance de sincronización","dashboard.syncFrom":"Sincronizar desde","dashboard.maxEmails":"Correos electrónicos máximos","dashboard.lastSync":"Última sincronización:","dashboard.error":"Error:","dashboard.resetCheckpoint":"Restablecer punto de control (Forzar resincronización completa desde la fecha de inicio)","dashboard.syncHistory":"Historial de sincronización","dashboard.noSyncHistory":"No hay historial de sincronización disponible.","dashboard.processed":"Procesado:","dashboard.actioned":"Accionado:","dashboard.running":"En ejecución","dashboard.quickStats":"Estadísticas rápidas","dashboard.totalProcessed":"Total procesado","dashboard.connectedAccounts":"Cuentas conectadas","dashboard.activeRules":"Reglas activas","dashboard.noSubject":"Sin asunto","dashboard.queued":"En cola","dashboard.analyzing":"Analizando","dashboard.analyzed":"Analizado","dashboard.failed":"Fallido","dashboard.retryProcessing":"Reintentar procesamiento","dashboard.suggested":"Sugerido:","dashboard.done":"Hecho:","dashboard.deleteConfirm":"¿Eliminar?","dashboard.openIn":"Abrir en {provider}","dashboard.viewTraceTooltip":"Ver rastreo de IA (Prompt/Respuesta)","dashboard.syncSuccess":"¡Sincronización completada! Revisa tus correos electrónicos.","dashboard.syncFailed":"Sincronización fallida. Verifica el estado de la cuenta para más detalles.","config.title":"Automatización y reglas","config.rules":"Reglas de automatización","config.createRule":"Crear nueva regla","config.llmSettings":"Configuración de inteligencia de IA","config.accounts.title":"Cuentas de correo electrónico","config.accounts.desc":"Conectar y administrar tus cuentas de correo electrónico","config.accounts.addNew":"Agregar nueva cuenta","config.accounts.yourAccounts":"Tus cuentas conectadas","config.accounts.noAccounts":"Aún no hay cuentas de correo electrónico conectadas","config.accounts.connectHelp":"Conecta tu primera cuenta de correo electrónico para comenzar a automatizar","config.accounts.disconnect":"Desconectar","config.gmail.connect":"Conectar Gmail","config.gmail.connectDesc":"OAuth 2.0 o cuenta de servicio","config.gmail.credentialsDesc":"Pega el contenido JSON de las credenciales de Google Cloud","config.gmail.authCodeDesc":"Ingresa el código de autorización de Google","config.gmail.pasteJson":"Pega el contenido de credentials.json","config.gmail.downloadHelp":"Descarga desde Google Cloud Console → APIs & Services → Credentials","config.gmail.orEnterManually":"O ingresa manualmente","config.outlook.connect":"Conectar Outlook","config.outlook.connectDesc":"Microsoft 365 o Outlook.com","config.outlook.credentialsDesc":"Pega el contenido JSON de las credenciales de Azure App","config.outlook.instructions":"Sigue el flujo OAuth para conectarte","config.outlook.signinRequired":"Inicio de sesión requerido","config.outlook.waitingSignin":"Esperando inicio de sesión...","config.model.title":"Configuración del modelo de IA","config.model.desc":"Configura tu modelo de IA y ajustes de procesamiento","config.model.provider":"Proveedor de LLM","config.model.name":"Nombre del modelo","config.model.modelPlaceholder":"p. ej. gpt-4o-mini","config.model.selectModel":"Seleccionar un modelo","config.model.storagePath":"Ruta de almacenamiento","config.model.storagePlaceholder":"Ruta para almacenamiento del modelo","config.model.storageHelp":"Directorio local para almacenar en caché los modelos","config.model.syncInterval":"Intervalo de sincronización (minutos)","config.model.syncHelp":"Frecuencia de verificación de nuevos correos electrónicos","config.model.intelligentRename":"Renombrado inteligente","config.model.renameHelp":"Usar IA para sugerir mejores nombres de archivo","config.model.checkConnection":"Verificar conexión","config.model.saveConfig":"Guardar configuración","config.byok.title":"Trae tu propia clave (BYOK)","config.byok.desc":"Usa tus propias claves API para proveedores de IA","config.byok.systemDefault":"Usar predeterminado del sistema","config.byok.save":"Guardar clave API","config.rules.edit":"Editar regla","config.rules.create":"Crear regla","config.rules.createRule":"Crear regla","config.rules.desc":"Definir condiciones y acciones para la automatización de correo electrónico","config.rules.name":"Nombre de la regla","config.rules.namePlaceholder":"ej. Archivar boletines","config.rules.description":"Descripción","config.rules.descriptionPlaceholder":"Qué hace esta regla","config.rules.semanticHelp":"La IA coincidirá los correos electrónicos según esta descripción","config.rules.intent":"Intención","config.rules.intentPlaceholder":"Qué debería suceder cuando se active esta regla","config.rules.intentHelp":"Se usa para generar respuestas apropiadas","config.rules.conditionField":"Campo de condición","config.rules.aiAnalysis":"Análisis de IA","config.rules.metadata":"Metadatos","config.rules.category":"Categoría","config.rules.sentiment":"Sentimiento","config.rules.priority":"Prioridad","config.rules.senderEmail":"Correo electrónico del remitente","config.rules.senderDomain":"Dominio del remitente","config.rules.senderContains":"El remitente contiene","config.rules.subjectContains":"El asunto contiene","config.rules.bodyContains":"El cuerpo contiene","config.rules.equalsValue":"Valor igual","config.rules.keywordsPlaceholder":"Ingresa palabras clave...","config.rules.olderThan":"Solo si el correo electrónico es más antiguo que (días)","config.rules.olderThanHelp":"Deja vacío o 0 para aplicar inmediatamente","config.rules.performActions":"Luego realizar acciones","config.rules.draftInstructions":"Instrucciones de borrador","config.rules.contextHelp":"Contexto específico para que la IA use al redactar","config.rules.addAttachment":"Agregar archivo adjunto","config.rules.attachmentHelp":"Los archivos se adjuntarán a los borradores generados","config.rules.uploading":"Subiendo...","config.rules.saveChanges":"Guardar cambios","account.title":"Configuración de cuenta","account.subtitle":"Administra tu perfil y preferencias","account.profile":"Perfil","account.security":"Seguridad","account.database":"Supabase","account.logout":"Cerrar sesión","account.logoutSuccess":"Sesión cerrada exitosamente","account.version":"Versión","account.profile.title":"Información del perfil","account.profile.desc":"Actualiza tu información personal","account.profile.firstName":"Nombre","account.profile.firstNamePlaceholder":"Juan","account.profile.lastName":"Apellido","account.profile.lastNamePlaceholder":"Pérez","account.profile.email":"Correo electrónico","account.profile.emailHelp":"Este es tu correo electrónico de inicio de sesión y no se puede cambiar","account.profile.sounds":"Sonido y retroalimentación háptica","account.profile.soundsHelp":"Reproducir sonidos para notificaciones de correo electrónico","account.profile.soundsEnabled":"Sonidos habilitados","account.profile.soundsDisabled":"Sonidos deshabilitados","account.profile.updated":"Perfil actualizado exitosamente","account.profile.avatarUpdated":"Avatar actualizado exitosamente","account.profile.avatarError":"Error al actualizar el avatar","account.security.title":"Seguridad","account.security.desc":"Actualiza tu contraseña","account.security.newPassword":"Nueva contraseña","account.security.confirmPassword":"Confirmar contraseña","account.security.updatePassword":"Actualizar contraseña","account.security.enterPassword":"Por favor ingresa una contraseña","account.security.passwordsMismatch":"Las contraseñas no coinciden","account.security.passwordTooShort":"La contraseña debe tener al menos 6 caracteres","account.security.passwordChanged":"Contraseña cambiada exitosamente","account.database.title":"Conexión a la base de datos","account.database.desc":"Administra tu conexión Supabase","account.database.connected":"Conectado","account.database.noConnection":"Sin conexión","account.database.configureHelp":"Configura tu conexión Supabase en el asistente de configuración","account.database.anonKey":"Clave anónima","account.database.envAlert":"Conexión configurada mediante variables de entorno","account.database.changeConnection":"Cambiar conexión","account.database.clearConfig":"Borrar configuración","account.database.clearConfirm":"¿Estás seguro de que deseas borrar tu configuración de base de datos?","account.database.setup":"Configurar base de datos","trace.runTrace":"Rastreo de ejecución de sincronización","trace.fullLogFor":"Registro completo para la cuenta: {email}","trace.historicalLog":"Registro histórico para esta ejecución de sincronización.","trace.loadingTrace":"Cargando rastreo...","trace.noTraceEvents":"No se encontraron eventos de rastreo granulares para esta ejecución.","analytics.title":"Panel de analítica","analytics.totalEmails":"Total de correos electrónicos","analytics.spamCaught":"Spam capturado","analytics.actionsTaken":"Acciones tomadas","analytics.accounts":"Cuentas","analytics.categories":"Categorías de correo electrónico","analytics.recentActivity":"Actividad de sincronización reciente","analytics.noActivity":"Aún no hay actividad de sincronización","analytics.emails":"{count} correos electrónicos","analytics.deleted":"{count} eliminados","analytics.drafted":"{count} borradores","autopilot.title":"Reglas de piloto automático","autopilot.rulesEnabled":"{enabled} de {total} reglas habilitadas","autopilot.loadingRules":"Cargando reglas...","autopilot.loadError":"Error al cargar reglas","autopilot.deleteConfirm":"¿Estás seguro de que deseas eliminar esta regla?","autopilot.ruleDeleted":"Regla eliminada","autopilot.ruleDeleteFailed":"Error al eliminar regla","autopilot.ruleDeleteError":"Ocurrió un error al eliminar la regla","autopilot.ruleUpdated":"Regla actualizada","autopilot.ruleCreated":"Regla creada","autopilot.ruleUpdateFailed":"Error al actualizar regla","autopilot.ruleCreateFailed":"Error al crear regla","autopilot.ruleSaveError":"Ocurrió un error al guardar la regla","autopilot.fileUploaded":"Archivo subido","autopilot.fileUploadFailed":"Error al subir archivo","autopilot.noRulesTitle":"Aún no hay reglas","autopilot.noRulesDesc":"Las reglas se crearán automáticamente cuando te registres o conectes tu primera cuenta de correo electrónico.","autopilot.addCustomRule":"Agregar regla personalizada","autopilot.refresh":"Actualizar","autopilot.infoDesc":"Las reglas de piloto automático usan IA para organizar automáticamente tu bandeja de entrada. Activa o desactiva cualquier regla para personalizar el comportamiento.","autopilot.customRules":"Reglas personalizadas","autopilot.customRulesDesc":"Reglas que has creado manualmente","autopilot.category.email_organization.label":"Organización de correo electrónico","autopilot.category.email_organization.desc":"Organizar automáticamente tipos comunes de correo electrónico","autopilot.category.priority_alerts.label":"Prioridad y alertas","autopilot.category.priority_alerts.desc":"Resaltar mensajes urgentes e importantes","autopilot.category.development.label":"Desarrollo","autopilot.category.development.desc":"Notificaciones de GitHub, CI/CD y herramientas de desarrollo","autopilot.category.sales_business.label":"Ventas y negocios","autopilot.category.sales_business.desc":"Gestión de clientes potenciales y comunicaciones comerciales","autopilot.category.operations.label":"Operaciones","autopilot.category.operations.desc":"Soporte, solicitudes internas y alertas del sistema","autopilot.enabledCount":"({enabled}/{total} habilitadas)","autopilot.badge":"Piloto automático","autopilot.editRuleTooltip":"Editar regla","autopilot.deleteRuleTooltip":"Eliminar regla","autopilot.triggeredToday":"{count} hoy","autopilot.editDialog.editTitle":"Editar regla","autopilot.editDialog.createTitle":"Crear regla personalizada","autopilot.editDialog.desc":"Definir una condición basada en el análisis de IA para activar una acción.","autopilot.editDialog.ruleName":"Nombre de la regla","autopilot.editDialog.namePlaceholder":"ej. Archivar boletines","autopilot.editDialog.description":"Descripción","autopilot.editDialog.descPlaceholder":"ej. Manejar todos los boletines de marketing y contenido promocional de servicios de suscripción","autopilot.editDialog.descriptionHelp":"Describe para qué es esta regla. La IA usa esto para hacer coincidir semánticamente los correos electrónicos.","autopilot.editDialog.intent":"Intención","autopilot.editDialog.intentPlaceholder":"ej. Rechazar cortésmente todas las propuestas de ventas","autopilot.editDialog.intentHelp":"El objetivo de esta regla. Se usa para generar borradores de respuesta apropiados.","autopilot.editDialog.conditionField":"Campo de condición Si","autopilot.editDialog.aiAnalysisGroup":"Análisis de IA","autopilot.editDialog.metadataGroup":"Metadatos","autopilot.editDialog.category":"Categoría","autopilot.editDialog.sentiment":"Sentimiento","autopilot.editDialog.priority":"Prioridad","autopilot.editDialog.senderEmail":"Correo electrónico específico (Exacto)","autopilot.editDialog.senderDomain":"Dominio de correo electrónico (@...)","autopilot.editDialog.senderContains":"El remitente contiene...","autopilot.editDialog.subjectContains":"El asunto contiene...","autopilot.editDialog.bodyContains":"El cuerpo contiene...","autopilot.editDialog.equalsValue":"Valor igual","autopilot.editDialog.cat.newsletter":"Boletín","autopilot.editDialog.cat.news":"Noticias","autopilot.editDialog.cat.spam":"Spam","autopilot.editDialog.cat.promotional":"Promocional","autopilot.editDialog.cat.transactional":"Transaccional","autopilot.editDialog.cat.social":"Social","autopilot.editDialog.cat.support":"Soporte","autopilot.editDialog.cat.client":"Cliente","autopilot.editDialog.cat.internal":"Interno","autopilot.editDialog.cat.personal":"Personal","autopilot.editDialog.cat.other":"Otro","autopilot.editDialog.sent.positive":"Positivo","autopilot.editDialog.sent.neutral":"Neutral","autopilot.editDialog.sent.negative":"Negativo","autopilot.editDialog.prio.high":"Alto","autopilot.editDialog.prio.medium":"Medio","autopilot.editDialog.prio.low":"Bajo","autopilot.editDialog.keywordsPlaceholder":"Palabras clave...","autopilot.editDialog.olderThan":"Solo si el correo electrónico es más antiguo que... (Opcional)","autopilot.editDialog.days":"días","autopilot.editDialog.olderThanHelp":"Deja vacío o 0 para aplicar la regla inmediatamente al recibirlo.","autopilot.editDialog.performActions":"Luego realizar acción(es)","autopilot.editDialog.actionsDesc":"Selecciona una o más acciones para ejecutar cuando la regla coincida","autopilot.editDialog.action.archive":"Archivar correo electrónico","autopilot.editDialog.action.delete":"Eliminar correo electrónico","autopilot.editDialog.action.draft":"Borrador de respuesta","autopilot.editDialog.action.star":"Estrella / Marcar","autopilot.editDialog.draftInstructions":"Instrucciones de borrador (Contexto)","autopilot.editDialog.draftInstPlaceholder":"ej. Diles que estoy ocupado hasta el viernes, pero interesado en la propuesta.","autopilot.editDialog.draftInstHelp":"Contexto específico para el escritor fantasma de IA.","autopilot.editDialog.attachments":"Archivos adjuntos (Opcional)","autopilot.editDialog.uploading":"Subiendo...","autopilot.editDialog.addAttachment":"Agregar archivo adjunto","autopilot.editDialog.attachmentsHelp":"Los archivos se adjuntarán a cada borrador generado por esta regla.","autopilot.onboarding.allSet":"¡Todo listo!","autopilot.onboarding.enabledDesc":"Hemos habilitado {count} reglas de automatización para ti","autopilot.onboarding.rules":"reglas","autopilot.onboarding.universalDesc":"Reglas esenciales que ayudan a todos a mantenerse organizados","autopilot.onboarding.executiveDesc":"Enfocarse en comunicaciones de alta prioridad y asuntos estratégicos","autopilot.onboarding.developerDesc":"Resaltar alertas críticas y filtrar ruido de herramientas","autopilot.onboarding.salesDesc":"Priorizar clientes potenciales y comunicaciones con clientes","autopilot.onboarding.operationsDesc":"Organizar tickets y comunicaciones internas","autopilot.onboarding.tip":"Consejo: Todas las reglas están habilitadas por defecto, pero puedes personalizarlas o deshabilitarlas en cualquier momento en la sección de Piloto automático.","autopilot.onboarding.start":"Comenzar a usar Email Automator →","autopilot.role.title":"¡Un último paso!","autopilot.role.subtitle":"¿Qué describe mejor tu rol? Configuraremos las reglas de automatización adecuadas para ti.","autopilot.role.executive.label":"Ejecutivo / Liderazgo","autopilot.role.executive.desc":"Enfocarse en VIP, contratos y comunicaciones estratégicas","autopilot.role.executive.preview":"Priorizador de clientes VIP;Organizador de viajes;Legal y contratos","autopilot.role.sales.label":"Ventas / Desarrollo de negocios","autopilot.role.sales.desc":"Priorizar clientes potenciales y comunicaciones con clientes","autopilot.role.sales.preview":"Preguntas de clientes;Organizador de CRM;Seguimiento de propuestas","autopilot.role.developer.label":"Desarrollador / Ingeniero","autopilot.role.developer.desc":"Resaltar alertas críticas y filtrar ruido de herramientas","autopilot.role.developer.preview":"Alertas del sistema;Revisiones de código;Gestión de proyectos","autopilot.role.operations.label":"Operaciones / Soporte","autopilot.role.operations.desc":"Organizar tickets y comunicaciones internas","autopilot.role.operations.preview":"Tickets de soporte;Monitoreo del sistema;Comunicaciones internas","autopilot.role.marketing.label":"Marketing","autopilot.role.marketing.desc":"Seguir campañas y participación de clientes","autopilot.role.marketing.preview":"Seguimiento de campañas;Informes de analítica;Redes sociales","autopilot.role.other.label":"Otro / Configuración manual","autopilot.role.other.desc":"Configuraré mis propias reglas de automatización","autopilot.role.includes":"Incluye:","autopilot.role.skip":"Omitir por ahora","autopilot.role.settingUp":"Configurando...","autopilot.role.continue":"Continuar →","terminal.title":"Terminal del agente","terminal.liveActivity":"Actividad en vivo","terminal.syncing":"SINCRONIZANDO","terminal.live":"EN VIVO","terminal.stopSync":"DETENER SINCRONIZACIÓN","terminal.clear":"Borrar","terminal.waiting":"Esperando actividad del agente...","terminal.details":"Detalles","terminal.useless":"INÚTIL","terminal.relevant":"RELEVANTE","terminal.executionComplete":"Ejecución completada","terminal.batchFinished":"Sincronización por lotes finalizada","terminal.processed":"Procesado","terminal.actions":"Acciones","terminal.action.delete":"Movido a la papelera","terminal.action.archive":"Correo electrónico archivado","terminal.action.draft":"Borrador de respuesta creado","terminal.action.star":"Correo electrónico marcado con estrella","common.edit":"Editar","persona.title":"Persona Digital","persona.subtitle":"Gestiona cómo tu asistente de IA te representa.","persona.identity":"Identidad","persona.communication":"Comunicación","persona.automation":"Automatización","persona.network":"Red","persona.edit.title":"Editar Persona","persona.edit.desc":"Actualiza las preferencias de tu asistente digital.","config.outlook.openLogin":"Abrir inicio de sesión de Microsoft","config.llm.title":"LLM","config.model.defaultProvider":"RealTimeX AI (predeterminado)","config.model.discovering":"Descubriendo...","config.storage.title":"Ruta de almacenamiento","config.storage.desc":"Elige dónde se almacenan localmente los archivos de correo sin procesar","config.storage.label":"Ruta de almacenamiento local","config.storage.placeholder":"p. ej. /Users/you/Documents/email-archive","config.storage.help":"Debe tener permisos de escritura. Déjalo en blanco para usar la carpeta predeterminada de la aplicación.","config.rename.title":"Renombrado inteligente","config.rename.desc":"Controla el formato de nombres de archivo para los correos almacenados","config.rename.label":"Habilitar renombrado inteligente","config.rename.help":"Crea nombres legibles y con slug en lugar de ID de mensaje sin formato.","config.sync.title":"Intervalo de sincronización (minutos)","config.sync.desc":"Controla cada cuánto se ejecuta la sincronización en segundo plano","config.sync.label":"Minutos entre sincronizaciones","config.sync.help":"Valores más bajos aumentan la frescura pero pueden usar más recursos.","config.embed.title":"Embeddings (RAG)","config.embed.desc":"Configura embeddings para la búsqueda en la base de conocimiento (RAG).","config.embed.provider":"Proveedor de embeddings","config.embed.model":"Modelo de embeddings","config.embed.modelPlaceholder":"p. ej. text-embedding-3-small","config.embed.autoModel":"Auto (text-embedding-3-small)","config.embed.help":"Se usa para la búsqueda semántica en la base de conocimiento.","config.embed.discovering":"Descubriendo...","config.embed.defaultProvider":"RealTimeX AI (predeterminado)","config.byok.googleTitle":"Google / Gmail","config.byok.microsoftTitle":"Microsoft / Outlook","config.byok.clientId":"ID de cliente","config.byok.clientSecret":"Secreto de cliente","config.byok.clientSecretOptional":"Secreto de cliente (opcional)","config.byok.tenantId":"ID de inquilino","config.voice.title":"Voz y habla","config.voice.desc":"Configura texto a voz para las respuestas de IA","config.voice.autoTitle":"Auto‑hablar respuestas de IA","config.voice.autoHelp":"Leer automáticamente en voz alta las respuestas de la IA con texto a voz","config.voice.provider":"Proveedor TTS","config.voice.providerHelp":"Selecciona el proveedor de texto a voz","config.voice.loadingProviders":"Cargando proveedores...","config.voice.voice":"Voz","config.voice.selectVoice":"Selecciona una voz","config.voice.noVoices":"No hay voces disponibles","config.voice.voiceHelp":"Elige la personalidad de voz para la síntesis","config.voice.speed":"Velocidad","config.voice.speedSlow":"0.5x (Más lento)","config.voice.speedFast":"2.0x (Más rápido)","config.voice.quality":"Calidad","config.voice.qualityLow":"1 (Menor calidad, más rápido)","config.voice.qualityHigh":"20 (Mayor calidad, más lento)","config.voice.test":"Probar","config.voice.save":"Guardar ajustes","config.voice.testText":"¡Hola! Esta es una prueba del sistema de texto a voz.","config.voice.piperLocal":"Piper (Local)","config.voice.toast.providersFailed":"No se pudieron cargar los proveedores TTS. Asegúrate de que RealTimeX Desktop esté en ejecución.","config.voice.toast.serviceFailed":"No se pudo conectar al servicio TTS","config.voice.toast.testFailed":"No se pudo probar el texto a voz","config.voice.toast.saved":"Ajustes de voz y habla guardados","config.voice.toast.saveFailed":"No se pudieron guardar los ajustes","config.voice.toast.autoOn":"Auto‑hablar respuestas de IA activado","config.voice.toast.autoOff":"Auto‑hablar respuestas de IA desactivado","config.voice.toast.updateFailed":"No se pudo actualizar el ajuste","config.agent.systemInstruction":"Eres el asistente de configuración. Guía al usuario para configurar cuentas, reglas y preferencias del sistema. Explica cada ajuste y ayuda a solucionar conexiones.","config.toast.providersFailed":"No se pudieron cargar los proveedores","config.toast.providersFailedFallback":"No se pudieron cargar los proveedores. Se usan los valores predeterminados.","config.toast.embedProvidersFailed":"No se pudieron cargar los proveedores de embeddings","config.toast.embedProvidersFailedFallback":"No se pudieron cargar los proveedores de embeddings. Se usan los valores predeterminados.","config.toast.connectionFailed":"Conexión fallida","config.toast.systemRuleMissing":"Regla del sistema no encontrada. Sincroniza tu base de datos.","config.toast.startConnectionFailed":"No se pudo iniciar la conexión. Asegúrate de haber iniciado sesión.","config.toast.startGmailFailed":"No se pudo iniciar la conexión con Gmail","config.toast.detectedDesktopCreds":"Se detectaron credenciales de app de escritorio","config.toast.detectedWebCreds":"Se detectó una app web. Asegúrate de configurar el URI de redirección en Google Cloud Console","config.toast.missingGmailCreds":"Proporciona el ID de cliente y el secreto de cliente","config.toast.authorizeAndPaste":"Autoriza en la pestaña abierta y luego pega el código aquí","config.toast.oauthUrlFailed":"No se pudo obtener la URL de OAuth","config.toast.saveCredsFailed":"No se pudieron guardar las credenciales","config.toast.missingAuthCode":"Pega el código de autorización","config.toast.gmailConnected":"¡Cuenta de Gmail conectada correctamente!","config.toast.gmailConnectFailed":"No se pudo conectar Gmail","config.toast.missingOutlookClientId":"Proporciona el ID de cliente","config.toast.deviceFlowFailed":"No se pudo iniciar el flujo de dispositivo","config.toast.outlookStartFailed":"No se pudo iniciar la conexión con Outlook","config.toast.outlookConnected":"Cuenta de Outlook conectada","config.toast.connectionTimedOut":"La conexión agotó el tiempo. Inténtalo de nuevo.","config.toast.ruleNameRequired":"Asigna un nombre a tu regla","config.toast.ruleActionRequired":"Selecciona al menos una acción","config.toast.ruleUpdated":"Regla actualizada","config.toast.ruleCreated":"Regla creada","config.toast.ruleUpdateFailed":"No se pudo actualizar la regla","config.toast.ruleCreateFailed":"No se pudo crear la regla","config.toast.ruleSaveError":"Ocurrió un error al guardar la regla","config.toast.disconnectConfirm":"¿Seguro que quieres desconectar esta cuenta?","config.toast.accountDisconnected":"Cuenta desconectada","config.toast.settingsSaved":"Ajustes guardados","config.toast.fileUploaded":"Archivo subido","config.toast.fileUploadFailed":"No se pudo subir el archivo","config.providers.gmail":"Gmail","config.providers.outlook":"Outlook","config.gmail.authSteps":`1. Se abrió una nueva pestaña con Google Sign-In
|
|
2
|
-
2. Inicia sesión y autoriza la app
|
|
3
|
-
3. Copia el código de autorización mostrado
|
|
4
|
-
4. Pégalo abajo`,"config.gmail.authCode":"Código de autorización","config.gmail.clientIdPlaceholder":"xxx.apps.googleusercontent.com","config.gmail.clientSecretPlaceholder":"GOCSPX-...","config.gmail.authCodePlaceholder":"4/0AQlEd8x...","config.rules.actionsHelp":"Selecciona una o más acciones para ejecutar cuando la regla coincida","config.rules.instructionsPlaceholder":"p. ej. Diles que estoy ocupado hasta el viernes, pero interesado en la propuesta.","config.rules.attachmentsOptional":"Adjuntos (opcional)","config.rules.days":"días","config.rules.placeholder.domain":"rta.vn","config.rules.placeholder.email":"john@example.com","config.rules.category.newsletter":"Boletín","config.rules.category.spam":"Spam","config.rules.category.promotional":"Promocional","config.rules.category.transactional":"Transaccional","config.rules.category.social":"Social","config.rules.category.support":"Soporte","config.rules.category.client":"Cliente","config.rules.category.internal":"Interno","config.rules.category.personal":"Personal","config.rules.category.other":"Otro","config.rules.sentiment.positive":"Positivo","config.rules.sentiment.neutral":"Neutral","config.rules.sentiment.negative":"Negativo","config.rules.priority.high":"Alta","config.rules.priority.medium":"Media","config.rules.priority.low":"Baja","config.outlook.note":"Nota: Necesitas un registro de aplicación de Azure para que funcione.","config.outlook.clientId":"ID de cliente (ID de la aplicación)","config.outlook.tenantIdOptional":"ID de inquilino (opcional)","config.outlook.tenantHelp":'El valor predeterminado es "common". Usa tu ID de inquilino específico para cuentas de organización.',"config.outlook.saveConnect":"Guardar y conectar","config.outlook.actionRequired":"Acción requerida","config.outlook.waitingAuth":"Esperando autorización...","config.outlook.tenantPlaceholder":"common"};export{e as default};
|