@leejungkiin/awkit 1.7.4 → 1.7.5

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/core/GEMINI.md CHANGED
@@ -152,6 +152,10 @@ symphony-orchestrator → awf-session-restore (gitnexus state) → nm-memory-syn
152
152
  - Định nghĩa custom subagent bằng `define_subagent` (ví dụ: `critic` phải cấu hình read-only toolsets).
153
153
  - Tái sử dụng subagent ở trạng thái `Idle` qua việc gửi tin nhắn thay vì tạo mới.
154
154
  - Tuân thủ giới hạn lồng tác tử (nesting limit) tối đa 10 cấp.
155
+ - **Tận dụng Multi-Agent CLI Pipeline (Claude, Codex, Qwen):**
156
+ - Tích hợp điều phối liên hoàn để tăng tốc độ: **Claude CLI** (Lập kế hoạch/Architect), **Qwen CLI** (Viết code/Executor), và **Codex CLI** (UI preview/GUI assets & review).
157
+ - Tự động kiểm tra cấu hình (`audioAlerts`, `runners.claude`, `runners.codex`, `runners.qwen`) và độ khả dụng của binary CLI để điều phối/tự động fallback về **Gemini Flash** (`agy`) khi runner bị tắt hoặc chưa cài đặt.
158
+ - Các lệnh quản lý: `awkit config <runner> <on|off>`, `awkit config list`, `awkit config runners` và `awkit config models`.
155
159
 
156
160
  ### Mandatory Check-Then-Act Protocol (🔥 BẮT BUỘC)
157
161
  - TRƯỚC khi dùng công cụ sửa code/run command lần đầu mỗi task, PHẢI tự trả lời trong `<thought>` (KHÔNG in ra chat):
@@ -152,6 +152,10 @@ symphony-orchestrator → awf-session-restore (gitnexus state) → nm-memory-syn
152
152
  - Định nghĩa custom subagent bằng `define_subagent` (ví dụ: `critic` phải cấu hình read-only toolsets).
153
153
  - Tái sử dụng subagent ở trạng thái `Idle` qua việc gửi tin nhắn thay vì tạo mới.
154
154
  - Tuân thủ giới hạn lồng tác tử (nesting limit) tối đa 10 cấp.
155
+ - **Tận dụng Multi-Agent CLI Pipeline (Claude, Codex, Qwen):**
156
+ - Tích hợp điều phối liên hoàn để tăng tốc độ: **Claude CLI** (Lập kế hoạch/Architect), **Qwen CLI** (Viết code/Executor), và **Codex CLI** (UI preview/GUI assets & review).
157
+ - Tự động kiểm tra cấu hình (`audioAlerts`, `runners.claude`, `runners.codex`, `runners.qwen`) và độ khả dụng của binary CLI để điều phối/tự động fallback về **Gemini Flash** (`agy`) khi runner bị tắt hoặc chưa cài đặt.
158
+ - Các lệnh quản lý: `awkit config <runner> <on|off>`, `awkit config list`, `awkit config runners` và `awkit config models`.
155
159
 
156
160
  ### Mandatory Check-Then-Act Protocol (🔥 BẮT BUỘC)
157
161
  - TRƯỚC khi dùng công cụ sửa code/run command lần đầu mỗi task, PHẢI tự trả lời trong `<thought>` (KHÔNG in ra chat):
@@ -0,0 +1,225 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const crypto = require('crypto');
4
+
5
+ const HOME = process.env.HOME || process.env.USERPROFILE;
6
+ const GLOBAL_LOG_DIR = path.join(HOME, '.gemini', 'antigravity');
7
+ const DEFAULT_LOCAL_PATH = path.join(__dirname, '..', '..', 'greeting_history.jsonl');
8
+
9
+ /**
10
+ * Resolves the path to the history file.
11
+ */
12
+ function getHistoryFilePath() {
13
+ if (fs.existsSync(GLOBAL_LOG_DIR)) {
14
+ return path.join(GLOBAL_LOG_DIR, 'greeting_history.jsonl');
15
+ }
16
+ // Consistent fallback to workspace root
17
+ return DEFAULT_LOCAL_PATH;
18
+ }
19
+
20
+ /**
21
+ * Strips HTML tags and escapes dangerous characters to prevent XSS and injection.
22
+ */
23
+ function sanitizeName(name) {
24
+ if (!name) return 'Guest';
25
+ const clean = name.replace(/<[^>]*>/g, '').trim();
26
+ if (!clean) return 'Guest';
27
+ return clean.replace(/[&<>"']/g, (m) => ({
28
+ '&': '&amp;',
29
+ '<': '&lt;',
30
+ '>': '&gt;',
31
+ '"': '&quot;',
32
+ "'": '&#39;'
33
+ })[m]);
34
+ }
35
+
36
+ /**
37
+ * Detect time of day category based on hour.
38
+ * Morning: 05:00 - 11:59
39
+ * Afternoon: 12:00 - 17:59
40
+ * Evening: 18:00 - 21:59
41
+ * Night: 22:00 - 04:59
42
+ */
43
+ function getTimeOfDay(hour) {
44
+ if (hour >= 5 && hour < 12) return 'morning';
45
+ if (hour >= 12 && hour < 18) return 'afternoon';
46
+ if (hour >= 18 && hour < 22) return 'evening';
47
+ return 'night';
48
+ }
49
+
50
+ /**
51
+ * Returns local hour for the given timezone, or falls back to server local hour.
52
+ */
53
+ function getHourInTimezone(date, timezone) {
54
+ if (timezone) {
55
+ try {
56
+ const parts = new Intl.DateTimeFormat('en-US', {
57
+ timeZone: timezone,
58
+ hour: 'numeric',
59
+ hour12: false
60
+ }).formatToParts(date);
61
+ const hourPart = parts.find(p => p.type === 'hour');
62
+ if (hourPart) {
63
+ return parseInt(hourPart.value, 10);
64
+ }
65
+ } catch (e) {
66
+ console.warn(`[GreetingEngine] Invalid timezone: "${timezone}". Falling back to system timezone.`);
67
+ }
68
+ }
69
+ return date.getHours();
70
+ }
71
+
72
+ const LOCALES = {
73
+ en: require('./locales/en.json'),
74
+ vi: require('./locales/vi.json'),
75
+ ja: require('./locales/ja.json')
76
+ };
77
+
78
+ /**
79
+ * Load localization dictionary. Falls back to 'en' if lang is invalid.
80
+ */
81
+ function getLocaleTemplates(lang) {
82
+ let resolvedLang = lang || 'en';
83
+ if (!LOCALES[resolvedLang]) {
84
+ console.warn(`[GreetingEngine] Locale "${resolvedLang}" not found. Falling back to "en".`);
85
+ resolvedLang = 'en';
86
+ }
87
+ return { templates: LOCALES[resolvedLang], lang: resolvedLang };
88
+ }
89
+
90
+ /**
91
+ * Generates greeting message, logs to file, and returns structured data.
92
+ */
93
+ function generateGreeting({ name, lang, timezone }) {
94
+ const rawName = (name && name.trim()) || 'Guest';
95
+ const resolvedName = sanitizeName(rawName);
96
+ const rawLang = (lang && lang.trim().toLowerCase()) || 'en';
97
+ const date = new Date();
98
+
99
+ const hour = getHourInTimezone(date, timezone);
100
+ const timeOfDay = getTimeOfDay(hour);
101
+
102
+ const { templates, lang: resolvedLang } = getLocaleTemplates(rawLang);
103
+ const template = templates[timeOfDay] || templates['morning'];
104
+
105
+ const message = template.replace(/{name}/g, resolvedName);
106
+ const timestamp = date.toISOString();
107
+
108
+ const record = {
109
+ id: crypto.randomUUID(),
110
+ name: resolvedName,
111
+ language: resolvedLang,
112
+ timestamp,
113
+ time_of_day: timeOfDay,
114
+ greeting_message: message
115
+ };
116
+
117
+ saveGreetingToHistory(record);
118
+
119
+ return {
120
+ status: 'success',
121
+ data: {
122
+ message,
123
+ name: resolvedName,
124
+ lang: resolvedLang,
125
+ timestamp,
126
+ timeOfDay,
127
+ timezone: timezone || 'system'
128
+ }
129
+ };
130
+ }
131
+
132
+ /**
133
+ * Save record into history.jsonl
134
+ */
135
+ function saveGreetingToHistory(record) {
136
+ const logPath = getHistoryFilePath();
137
+ try {
138
+ const dir = path.dirname(logPath);
139
+ if (!fs.existsSync(dir)) {
140
+ fs.mkdirSync(dir, { recursive: true });
141
+ }
142
+ fs.appendFileSync(logPath, JSON.stringify(record) + '\n', 'utf8');
143
+ } catch (e) {
144
+ console.error(`[GreetingEngine] Failed to log greeting to history: ${e.message}`);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Reads and returns history records from jsonl.
150
+ */
151
+ function getGreetingHistory() {
152
+ const logPath = getHistoryFilePath();
153
+ if (!fs.existsSync(logPath)) {
154
+ return [];
155
+ }
156
+
157
+ try {
158
+ const content = fs.readFileSync(logPath, 'utf8');
159
+ return content
160
+ .split('\n')
161
+ .filter(line => line.trim().length > 0)
162
+ .map(line => JSON.parse(line));
163
+ } catch (e) {
164
+ console.error(`[GreetingEngine] Failed to read greeting history: ${e.message}`);
165
+ return [];
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Aggregates statistics based on history.
171
+ */
172
+ function getGreetingStats() {
173
+ const history = getGreetingHistory();
174
+ const totalGreetings = history.length;
175
+
176
+ if (totalGreetings === 0) {
177
+ return {
178
+ totalGreetings: 0,
179
+ mostActiveUser: 'N/A',
180
+ mostUsedLanguage: 'N/A',
181
+ popularTimeOfDay: 'N/A'
182
+ };
183
+ }
184
+
185
+ const userCounts = {};
186
+ const langCounts = {};
187
+ const timeOfDayCounts = { morning: 0, afternoon: 0, evening: 0, night: 0 };
188
+
189
+ history.forEach(record => {
190
+ userCounts[record.name] = (userCounts[record.name] || 0) + 1;
191
+ langCounts[record.language] = (langCounts[record.language] || 0) + 1;
192
+
193
+ // Use stored time_of_day for 100% accuracy, fallback to client parsing if old log
194
+ const tod = record.time_of_day || 'morning';
195
+ if (timeOfDayCounts[tod] !== undefined) {
196
+ timeOfDayCounts[tod]++;
197
+ }
198
+ });
199
+
200
+ const getMaxKey = (obj) => {
201
+ let maxKey = 'N/A';
202
+ let maxVal = -1;
203
+ Object.entries(obj).forEach(([key, val]) => {
204
+ if (val > maxVal) {
205
+ maxVal = val;
206
+ maxKey = key;
207
+ }
208
+ });
209
+ return maxKey;
210
+ };
211
+
212
+ return {
213
+ totalGreetings,
214
+ mostActiveUser: getMaxKey(userCounts),
215
+ mostUsedLanguage: getMaxKey(langCounts),
216
+ popularTimeOfDay: getMaxKey(timeOfDayCounts)
217
+ };
218
+ }
219
+
220
+ module.exports = {
221
+ generateGreeting,
222
+ getGreetingHistory,
223
+ getGreetingStats,
224
+ getHistoryFilePath
225
+ };
@@ -0,0 +1,6 @@
1
+ {
2
+ "morning": "Good morning, {name}!",
3
+ "afternoon": "Good afternoon, {name}!",
4
+ "evening": "Good evening, {name}!",
5
+ "night": "Good night, {name}!"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "morning": "おはようございます、{name}さん!",
3
+ "afternoon": "こんにちは、{name}さん!",
4
+ "evening": "こんばんは、{name}さん!",
5
+ "night": "おやすみなさい、{name}さん!"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "morning": "Chào buổi sáng, {name}!",
3
+ "afternoon": "Chào buổi chiều, {name}!",
4
+ "evening": "Chào buổi tối, {name}!",
5
+ "night": "Chúc {name} ngủ ngon!"
6
+ }
@@ -0,0 +1,37 @@
1
+ const { generateGreeting, getGreetingHistory, getGreetingStats } = require('./index');
2
+ const fs = require('fs');
3
+
4
+ function runTests() {
5
+ console.log("🧪 Testing Qwen's Generated GreetingEngine...");
6
+
7
+ // Run a few greetings
8
+ const g1 = generateGreeting({ name: "Alice", lang: "en" });
9
+ console.log(`✅ Greeting 1: "${g1.data.message}"`);
10
+
11
+ const g2 = generateGreeting({ name: "Bình", lang: "vi" });
12
+ console.log(`✅ Greeting 2: "${g2.data.message}"`);
13
+
14
+ const g3 = generateGreeting({ name: "Yamada", lang: "ja" });
15
+ console.log(`✅ Greeting 3: "${g3.data.message}"`);
16
+
17
+ // Language fallback test
18
+ const g4 = generateGreeting({ name: "Charlie", lang: "fr" }); // French not supported, should fallback to English
19
+ console.log(`✅ Greeting 4 (Fallback): "${g4.data.message}" (Language: ${g4.data.lang})`);
20
+
21
+ // Verify history
22
+ const history = getGreetingHistory();
23
+ console.log(`📊 History has ${history.length} records.`);
24
+
25
+ // Verify stats
26
+ const stats = getGreetingStats();
27
+ console.log("📈 Statistics:", stats);
28
+
29
+ if (history.length >= 4 && stats.totalGreetings >= 4) {
30
+ console.log("🎉 Qwen's GreetingEngine verified successfully!");
31
+ } else {
32
+ console.error("❌ Stats or history mismatch!");
33
+ process.exit(1);
34
+ }
35
+ }
36
+
37
+ runTests();
package/docs/PRD.md ADDED
@@ -0,0 +1,57 @@
1
+ # Product Requirement Document (PRD) - GreetingApp
2
+
3
+ ## Revision History
4
+ | Version | Date | Description | Author |
5
+ |---|---|---|---|
6
+ | v1.0 | 2026-06-22 | Initial PRD for GreetingApp | Antigravity Orchestrator |
7
+
8
+ ---
9
+
10
+ ## 1. Executive Summary
11
+ GreetingApp is a micro-application designed to deliver personalized, localized, and dynamic greetings to users. It adapts to the user's name, current time of day, and language preferences.
12
+
13
+ ## 2. Objectives & Goals
14
+ - Provide dynamic greetings based on user local time (Morning, Afternoon, Evening, Night).
15
+ - Support multi-language greetings (English, Vietnamese, Japanese).
16
+ - Track user greeting history and statistics.
17
+ - Expose both CLI and REST API interfaces.
18
+
19
+ ## 3. User Personas & Use Cases
20
+ - **End User:** Wants to see a welcoming, contextual message when logging in or using the CLI.
21
+ - **Developer:** Wants an easy-to-integrate greeting microservice API for downstream services.
22
+
23
+ ## 4. Functional Requirements
24
+ 1. **Dynamic Greeting Generation:**
25
+ - Detects local time of user.
26
+ - Personalizes with name (fallback to "Guest").
27
+ 2. **Localization (i18n):**
28
+ - Supports: English (`en`), Vietnamese (`vi`), Japanese (`ja`).
29
+ 3. **Greeting Analytics / History:**
30
+ - Stores logs of generated greetings (User, Timestamp, Language).
31
+ - Exposes statistics (e.g., total greetings generated, most active user).
32
+ 4. **Interfaces:**
33
+ - Command Line Interface (CLI): `awkit greet --name=Alice`
34
+ - REST API endpoint: `GET /api/greet?name=Alice&lang=vi`
35
+
36
+ ## 5. Non-Functional Requirements
37
+ - **Performance:** Response time for greeting generation under 50ms.
38
+ - **Reliability:** Storage fallback to memory if database/file storage is offline.
39
+ - **Extensibility:** Easy configuration to add new languages.
40
+
41
+ ## 6. System Flow & Sequence Diagram
42
+ ```mermaid
43
+ sequenceDiagram
44
+ autonumber
45
+ actor User
46
+ participant Client as CLI / API Client
47
+ participant Engine as Greeting Engine
48
+ participant DB as Storage / History DB
49
+
50
+ User->>Client: Triggers greeting command/request (name, lang)
51
+ Client->>Engine: Resolve greeting configuration
52
+ Engine->>Engine: Validate input & detect Time of Day
53
+ Engine->>DB: Log transaction (user, time, format)
54
+ DB-->>Engine: Log confirmation
55
+ Engine->>Client: Return formatted greeting string
56
+ Client->>User: Display greeting output
57
+ ```
@@ -0,0 +1,211 @@
1
+ # Brainstorming: Tích Hợp Đa Tác Tử (Multi-Agent CLI Pipeline) để Tối Ưu Chi Phí và Hiệu Năng trong AWKit
2
+
3
+ > **Tác giả:** Antigravity Orchestrator
4
+ > **Ngày cập nhật:** 2026-06-22
5
+ > **Phiên bản:** v1.0
6
+ > **Trạng thái:** Thảo luận / Ý tưởng thiết kế
7
+
8
+ ---
9
+
10
+ ## 1. Mục tiêu (Objective)
11
+
12
+ Tối ưu hóa chi phí API và nâng cao hiệu suất làm việc bằng cách định tuyến thông minh (Smart Routing) các tác vụ phát triển phần mềm trong framework AWKit đến ba nhóm CLI agents khác nhau:
13
+
14
+ 1. **Claude Code CLI (`claude`)** — Nhóm siêu trí tuệ (Premium Model).
15
+ 2. **Codex CLI (`codex`)** — Nhóm kiểm thử & thẩm định (Intermediate/Audit Model).
16
+ 3. **Qwen Code CLI (`qwen-code` hoặc runner tương đương)** — Nhóm mã nguồn mở hiệu năng cao, chi phí rẻ (Cost-optimized Open-Source).
17
+
18
+ ---
19
+
20
+ ## 2. Phân tích Thế mạnh & Định vị Vai trò (Agent Capabilities & Roles)
21
+
22
+ Dựa trên đặc điểm kỹ thuật và chi phí của từng mô hình, ta phân chia vai trò như sau:
23
+
24
+ | CLI Agent | Model Phía Sau | Thế mạnh Đặc trưng | Vai trò trong Hệ thống | Chiến lược Chi phí |
25
+ | :---------------- | :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------- | :------------------------------------------------------------ |
26
+ | **Claude Code** | Claude 3.5 Sonnet / Opus | - Suy luận logic phức tạp cực tốt.<br>- Lập kế hoạch kiến trúc chính xác.<br>- Khả năng giải quyết bug khó tốt nhất. | **Architect (Kiến trúc sư)** & **Complex Solver (Giải quyết sự cố lớn)** | Hạn chế số lần gọi (chỉ dùng cho Gate 2 & Gate 4 Complex). |
27
+ | **Codex CLI** | GPT-4o / Codex custom | - Review code khách quan với [$code-review](~/.agents/skills/code-review/SKILL.md).<br>- Thiết kế UI & Character assets chuyên sâu bằng [$hatch-pet](~/.codex/skills/hatch-pet/SKILL.md) và [$generate-gui-assets](~/.agents/skills/generate-gui-assets/SKILL.md).<br>- Tạo UI Shell tĩnh, HTML/CSS, Mockup nhanh.<br>- Sinh unit/integration tests chuẩn xác. | **Inspector (Kiểm định viên)** & **UI/Asset Builder (Tạo giao diện & Asset)** | Sử dụng trung bình (Gate 2.5 & Gate 5). |
28
+ | **Qwen Code CLI** | Qwen 2.5 Coder (32B/72B) | - Viết code boilerplate rất nhanh.<br>- Hiểu tốt nhiều ngôn ngữ lập trình.<br>- Tốc độ phản hồi cực nhanh, chi phí siêu rẻ hoặc miễn phí (tự host). | **Boilerplate Generator (Sinh mã nền)** & **Local Executor (Thực thi cục bộ)** | Sử dụng tối đa cho các task đơn giản, viết code thô ở Gate 4. |
29
+ | **Gemini (IDE)** | Gemini 3.5 Flash | - Context window khổng lồ (2M+).<br>- Tổng hợp và phân tích log/dữ liệu cực lớn.<br>- Phân tích codebase toàn diện. | **Central Orchestrator (Điều phối viên trung tâm)** & **Context Sync** | Chạy nền liên tục (chi phí cực rẻ). |
30
+
31
+ ---
32
+
33
+ ## 3. Quy trình Điều phối Đa Tác tử theo Hệ thống 7-Gate (7-Gate Routing Pipeline)
34
+
35
+ Để tối ưu hóa chi phí, quy trình xử lý một Task (đi qua các Gate) sẽ được định tuyến tự động như sau:
36
+
37
+ ```mermaid
38
+ graph TD
39
+ A[Bắt đầu Task] --> B{Phân loại độ khó Task}
40
+
41
+ B -->|Trivial / Simple| C[Qwen Code / Gemini Flash]
42
+ B -->|Moderate| D[Phối hợp Qwen & Codex]
43
+ B -->|Complex| E[Claude Code CLI]
44
+
45
+ subgraph Gate_2 [Gate 2: Spec & Architecture Planning]
46
+ E -->|Lập kế hoạch chính| F[Claude Code: claude-plan.js]
47
+ F --> G[Tạo implementation_plan.md]
48
+ end
49
+
50
+ subgraph Gate_2.5 [Gate 2.5: UI Shell & Assets]
51
+ G --> H[Codex CLI: codex exec GUI asset]
52
+ end
53
+
54
+ subgraph Gate_4 [Gate 4: Code Implementation]
55
+ H --> I{Phân rã Component}
56
+ I -->|Core Logic phức tạp| J[Claude Code CLI]
57
+ I -->|Boilerplate / Simple UI| K[Qwen Code CLI]
58
+ end
59
+
60
+ subgraph Gate_5 [Gate 5: Verification & QA]
61
+ J & K --> L[Codex CLI: Chạy Test & Code Review]
62
+ L --> M[Hoàn thành Task]
63
+ end
64
+ ```
65
+
66
+ ### Chi tiết Phân phối theo từng Gate:
67
+
68
+ 1. **Gate 1 & 1.5 (Brainstorm & Module Spec)**:
69
+ - **Tác tử**: Gemini Flash (Tích hợp sẵn trong IDE) làm việc trực tiếp với User.
70
+ - **Lý do**: Cần context lớn để hiểu toàn bộ yêu cầu của User và đọc tài liệu cũ. Chi phí cực thấp.
71
+
72
+ 2. **Gate 2 (Spec & Architecture Planning)**:
73
+ - **Tác tử**: **Claude Code CLI** (`node scripts/claude-plan.js`).
74
+ - **Lý do**: Lập kế hoạch sai sẽ dẫn đến viết code sai, gây lãng phí lớn chi phí API sau đó. Claude sẽ tạo ra `implementation_plan.md` cực kỳ chuẩn xác và hạn chế tối đa rủi ro regression.
75
+
76
+ 3. **Gate 2.5 (Visual Design & Asset Generation)**:
77
+ - **Tác tử**: **Codex CLI** (`codex exec`).
78
+ - **Lý do**: Codex thực hiện xuất sắc việc sinh UI shell/mockup và thiết kế UI & Character assets thông qua tích hợp các kỹ thuật chuyên sâu như [$hatch-pet](~/.codex/skills/hatch-pet/SKILL.md) (cho nhân vật/thú cưng) và [$generate-gui-assets](~/.agents/skills/generate-gui-assets/SKILL.md) (cho các thành phần giao diện).
79
+
80
+ 4. **Gate 4 (Execution - Viết Code)**:
81
+ - **Task Trivial (Dưới 3 files / Boilerplate)**: Định tuyến 100% qua **Qwen Code CLI** hoặc Gemini Flash.
82
+ - **Task Moderate/Complex**:
83
+ - **Qwen Code CLI** sẽ viết các file cấu trúc, helper, boilerplate và shell UI (Phase A + Phase B).
84
+ - **Claude Code CLI** sẽ được gọi để chèn logic cốt lõi (Core Business Logic) và giải quyết các phần tích hợp phức tạp (Phase C).
85
+
86
+ 5. **Gate 5 (Verification & QA)**:
87
+ - **Tác tử**: **Codex CLI** (phục vụ thẩm định chất lượng cao).
88
+ - **Lý do**: Codex có kỹ năng rà soát chất lượng code xuất sắc nhờ kỹ thuật [$code-review](~/.agents/skills/code-review/SKILL.md). Nó cũng rà soát sự tuân thủ các quy tắc coding (như Ponytail rules) và tự động sinh unit/integration tests để giảm thiểu rủi ro regression trước khi tích hợp vào nhánh chính.
89
+
90
+ ---
91
+
92
+ ## 4. Giải pháp Tích hợp Kỹ thuật vào AWKit (Technical Integration)
93
+
94
+ Để triển khai ý tưởng này vào AWKit hiện tại, chúng ta cần thực hiện các bước sau:
95
+
96
+ ### Bước 4.1: Bổ sung cấu hình điều hướng trong `.project-identity`
97
+ Thêm cấu hình điều phối đa tác tử để dễ dàng chuyển đổi chế độ hoạt động:
98
+ ```json
99
+ "automation": {
100
+ "multiAgent": {
101
+ "enabled": true,
102
+ "routingMode": "cost-optimized", // "cost-optimized" hoặc "quality-first"
103
+ "audioAlerts": true, // Bật/tắt âm thanh thông báo cấp độ project (override)
104
+ "runners": {
105
+ "codex": "codex"
106
+ }
107
+ }
108
+ }
109
+ ```
110
+
111
+ ### Bước 4.1.2: Cấu hình cấp độ Global (`~/.awkit_config.json`)
112
+ Để bật/tắt hoặc tinh chỉnh các tính năng CLI (như âm thanh thông báo) trên toàn bộ thiết bị (global), ta sử dụng tệp cấu hình `~/.awkit_config.json` thông qua lệnh CLI:
113
+ ```bash
114
+ # Xem toàn bộ cấu hình global hiện tại
115
+ awkit config-global list
116
+
117
+ # Bật hoặc tắt âm thanh thông báo hệ thống
118
+ awkit config-global set audioAlerts false
119
+ awkit config-global set audioAlerts true
120
+
121
+ # Lấy giá trị của một cấu hình cụ thể
122
+ awkit config-global get audioAlerts
123
+ ```
124
+ *Ghi chú:* Cấu hình `audioAlerts` cục bộ trong `.project-identity` của dự án sẽ được ưu tiên cao hơn cấu hình global này.
125
+
126
+ ### Bước 4.2: Xây dựng Qwen CLI Wrapper (`scripts/qwen-plan.js` hoặc `scripts/qwen-exec.js`)
127
+
128
+ Do Qwen CLI có thể chạy thông qua Ollama (local) hoặc qua API của các nhà cung cấp giá rẻ (OpenRouter, TogetherAI, v.v.), ta có thể viết một script trung gian để gọi:
129
+
130
+ ```javascript
131
+ // scripts/qwen-exec.js
132
+ const { execSync } = require("child_process");
133
+ // Ví dụ: gọi Ollama chạy local model qwen2.5-coder:32b
134
+ const prompt = process.argv[2];
135
+ try {
136
+ const output = execSync(`ollama run qwen2.5-coder "${prompt}"`, {
137
+ encoding: "utf8",
138
+ });
139
+ console.log(output);
140
+ } catch (e) {
141
+ // Fallback sang API hoặc Gemini Flash
142
+ }
143
+ ```
144
+
145
+ ### Bước 4.3: Cập nhật Multi-Model Pipeline (`scripts/multi-model-pipeline.js`)
146
+
147
+ Chỉnh sửa pipeline hiện tại để tích hợp tác tử Qwen vào giai đoạn Code Step:
148
+
149
+ - **Trước đây**: Chỉ dùng `gemini-2.5-flash` hoặc `claude-opus`.
150
+ - **Mới**: Định tuyến thông minh:
151
+ ```javascript
152
+ if (taskDifficulty === "trivial" || routingMode === "cost-optimized") {
153
+ runQwenCodeStep(featureName);
154
+ } else {
155
+ runClaudeCodeStep(featureName);
156
+ }
157
+ ```
158
+
159
+ ---
160
+
161
+ ## 5. Đánh giá Hiệu quả Chi phí (Cost-Benefit Analysis)
162
+
163
+ Giả sử một task phát triển tính năng trung bình tiêu tốn khoảng **100,000 input tokens** và **10,000 output tokens**:
164
+
165
+ | Chiến lược | Chi tiết phân phối | Chi phí ước tính (USD/Task) | Tỷ lệ Tiết kiệm |
166
+ | :----------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------- | :---------------------------------------------------------------------------------------------------- |
167
+ | **Chỉ dùng Claude 3.5** | 100% sử dụng Claude | ~$0.45 | 0% (Mốc chuẩn) |
168
+ | **Chỉ dùng Gemini Flash** | 100% sử dụng Gemini Flash | ~$0.012 | 97% (Nhưng chất lượng logic phức tạp có thể giảm) |
169
+ | **Đa Tác tử (Multi-Agent Pipeline)** | - **Claude** (10% tokens cho Planning)<br>- **Qwen Coder** (80% tokens cho Boilerplate & Coding - Local/Free)<br>- **Codex** (10% tokens cho Review & Test) | **~$0.07** | **~85% Tiết kiệm** mà vẫn giữ được chất lượng kiến trúc của Claude và chất lượng kiểm định của Codex. |
170
+
171
+ ---
172
+
173
+ ## 6. Cơ Chế Hoạt Động Chi Tiết (How it Works)
174
+
175
+ Cơ chế điều phối sub-agent CLI trong AWKit hoạt động theo 6 bước tuần tự:
176
+ 1. **Nhận diện và Kích hoạt (Trigger Detection)**: Dựa trên Gate hiện tại (Gate 2, 2.5, 4, 5) hoặc độ phức tạp của task (Trivial, Moderate, Complex), Central Agent (Gemini Flash) xác định CLI agent cần dùng.
177
+ 2. **Thu thập Ngữ cảnh (Context Gathering)**: Central Agent tự động đóng gói các tài liệu liên quan (`.project-identity`, `implementation_plan.md`, `git diff`...) thành một prompt có cấu trúc.
178
+ 3. **Chạy Trực Tiếp / Ủy quyền (Execution Delegation)**: Chạy CLI qua terminal bằng lệnh `run_command` hoặc thông qua các wrapper script chuyên dụng (như `scripts/multi-model-pipeline.js`, `scripts/claude-plan.js`).
179
+ 4. **Cơ chế Dự phòng (Graceful Fallback)**: Nếu CLI không được cài đặt (Exit code `127`) hoặc gặp lỗi xác thực (Exit code `2`), hệ thống sẽ tự động chuyển sang mô hình mặc định trong IDE mà không làm gián đoạn luồng làm việc.
180
+ 5. **Ghi nhận & Tiêu thụ Báo cáo (Result Consumption)**: Kết quả từ CLI được lưu dưới dạng file báo cáo (`.md` hoặc `.json`) trong thư mục `codex-reports/` hoặc `brain/`. Central Agent sẽ đọc báo cáo này để cập nhật ngữ cảnh và tiếp tục thực hiện mã nguồn.
181
+ 6. **Thông Báo Hoàn Tất Bằng Âm Thanh (Audio Notification)**: Đối với các tác vụ chạy nền (background tasks) tốn thời gian, hệ thống tự động phát âm thanh hệ thống (ví dụ: `afplay /System/Library/Sounds/Glass.aiff`) và thông báo bằng giọng nói (ví dụ: `say "Done"`) trên macOS để thông báo cho người dùng khi quy trình hoàn thành.
182
+
183
+ ---
184
+
185
+ ## 7. Khảo Sát Môi Trường Thực Tế & Thử Nghiệm (Environment Audit & Prototype)
186
+
187
+ Kết quả khảo sát môi trường tại máy local `/Users/trungkientn/Dev/NodeJS/main-awf`:
188
+ * **Codex CLI**: ✅ Đã được cài đặt tại `/Users/trungkientn/.nvm/versions/node/v22.22.0/bin/codex`.
189
+ * **agy CLI (Gemini)**: ✅ Đã được cài đặt tại `/Users/trungkientn/.local/bin/agy` (Version 1.0.0).
190
+ * **Claude Code CLI**: ✅ Đã cài đặt dưới dạng alias, trỏ trực tiếp đến `/Users/trungkientn/.claude/local/claude` (Sử dụng đường dẫn tuyệt đối này trong các script tự động hóa).
191
+ * **Qwen Code CLI**: ✅ Đã được cài đặt với tên lệnh `qwen` tại `/Users/trungkientn/.nvm/versions/node/v22.22.0/bin/qwen`.
192
+
193
+ ### Kết Quả Thử Nghiệm Thực Tế (Test Run Results - 2026-06-22):
194
+
195
+ #### 1. Kiểm thử đơn lẻ (Unit Test Run):
196
+ - **agy CLI (Gemini)**: ✅ Thành công phản hồi câu hỏi lý thuyết sau `20,195ms`.
197
+ - **Codex CLI (OpenAI - Model: `gpt-5.5`)**: ✅ Thành công review mã nguồn cứng API key sau `10,182ms`.
198
+
199
+ #### 2. Kiểm thử phối hợp chuỗi (Multi-Agent Pipeline Test Run):
200
+ Đã chạy thành công kịch bản lập kế hoạch, sinh mã nguồn và rà soát tự động cho hàm Fibonacci memoization thông qua script `run_multi_agent_pipeline.js`:
201
+ - **Bước 1: Claude CLI (Architect)**: ✅ Thành công thiết kế sơ đồ logic và kế hoạch memoization lưu tại [test_plan.md](file:///Users/trungkientn/.gemini/antigravity-ide/brain/c843a673-f692-4562-a065-0000e76bff71/scratch/test_plan.md).
202
+ - **Bước 2: Qwen CLI (Executor)**: ✅ Thành công đọc kế hoạch của Claude và viết mã nguồn JavaScript tương thích 100%, lưu tại [test_code.js](file:///Users/trungkientn/.gemini/antigravity-ide/brain/c843a673-f692-4562-a065-0000e76bff71/scratch/test_code.js) (`21,237ms`).
203
+ - **Bước 3: Codex CLI (Inspector)**: ✅ Thành công đối chiếu `test_code.js` với `test_plan.md`, chỉ ra 2 cảnh báo độ ưu tiên Medium (tràn số khi `n >= 79` và lỗi call stack đệ quy sâu) kèm 2 nhận xét Low, lưu tại [test_review.md](file:///Users/trungkientn/.gemini/antigravity-ide/brain/c843a673-f692-4562-a065-0000e76bff71/scratch/test_review.md) (`23,250ms`).
204
+ - **Kết luận**: Quy trình hoạt động đồng bộ hoàn hảo. Sự phối hợp giúp phân tách trách nhiệm rõ rệt: thiết kế cao cấp (Claude) -> lập trình cơ bản (Qwen) -> rà soát chi tiết (Codex). Log đầy đủ tại [pipeline_run_log.json](file:///Users/trungkientn/.gemini/antigravity-ide/brain/c843a673-f692-4562-a065-0000e76bff71/scratch/pipeline_run_log.json).
205
+
206
+ ---
207
+
208
+ ## 8. Các Bước Tiếp Theo Đề Xuất (Next Steps)
209
+ 1. **Tạo kịch bản thử nghiệm thực tế (Test Run Script)**: Viết script `test_sub_agents.js` trong thư mục `scratch/` để gọi thử `codex` và `agy` kiểm tra logic review/plan thô.
210
+ 2. **Cập nhật wrapper script gọi Claude và Qwen**: Thiết lập đường dẫn tuyệt đối `/Users/trungkientn/.claude/local/claude` cho Claude và tên lệnh `qwen` cho Qwen trong hệ thống multi-model routing của AWKit.
211
+ 3. **Đóng gói Skill**: Phát triển `skills/qwen-conductor/SKILL.md` để tự động hóa định tuyến.
@@ -0,0 +1,55 @@
1
+ # Product Requirements Document (PRD) — MemoizedFibonacci
2
+
3
+ ## Revision History
4
+
5
+ | Version | Date | Author | Description |
6
+ | :--- | :--- | :--- | :--- |
7
+ | 1.0 | 2026-06-22 | Antigravity Orchestrator | Initial draft for MemoizedFibonacci feature. |
8
+
9
+ ---
10
+
11
+ ## 1. Vision & Objectives
12
+
13
+ * **Project Summary:** The `MemoizedFibonacci` feature provides a highly optimized, high-performance utility class/module for calculating Fibonacci sequences. It leverages an advanced caching (memoization) mechanism to avoid the exponential time complexity $O(2^n)$ associated with naive recursive methods, turning sequence generation into a linear time $O(n)$ or constant-time $O(1)$ operation for subsequent lookups.
14
+ * **Problem Statement:** Standard recursive calculations of Fibonacci numbers quickly exhaust CPU resources and crash due to call stack size limits or integer overflows when $n \ge 79$ in standard floating-point representation. Naive memory caches can also grow indefinitely, leading to memory leaks in server environments.
15
+ * **Target Audience:** Core application developers, backend engineers running mathematical modeling services, and background agents requiring sequence calculations.
16
+
17
+ ---
18
+
19
+ ## 2. Core Principles & Philosophy
20
+
21
+ * **Performance & Scalability:** Constant lookups $O(1)$ for cached values, linear complexity $O(n)$ for first-time calculations.
22
+ * **Robustness & Accuracy:** Complete support for `BigInt` calculations to prevent integer overflow beyond JS safe limit ($n > 78$).
23
+ * **Memory Safety & Self-Regulation:** Integrated Least Recently Used (LRU) cache eviction strategy to guarantee a fixed maximum memory footprint.
24
+ * **Non-Blocking Operation:** Heavy calculations ($n \ge 100,000$) must run asynchronously (chunked loops or offloaded execution) to prevent thread/event-loop blockage.
25
+
26
+ ---
27
+
28
+ ## 3. Scope & Feature List
29
+
30
+ ### In Scope
31
+ * **Multiple Calculation Modes:** Synchronous calculations for small inputs; asynchronous (non-blocking) computation for larger values.
32
+ * **Flexible Precision:** Standard JS numbers for fast calculations ($n \le 78$) and `BigInt` for arbitrarily large numbers.
33
+ * **LRU Caching Strategy:** A bounded in-memory cache that automatically evicts least recently accessed Fibonacci numbers when the maximum cache capacity is reached.
34
+ * **Cache Metrics:** Reporting of cache metrics such as hit rate, miss rate, current size, and eviction count.
35
+ * **Resource Guardrails:** Hard limits on inputs to prevent CPU exhaustion.
36
+
37
+ ### Out of Scope
38
+ * **Negative/Fractional Fibonacci:** No support for negative numbers or fractional inputs (standard integer sequence only).
39
+ * **Distributed Cache integration:** No built-in Redis/Memcached integration (limited to localized, bounded memory cache with extensible hooks).
40
+
41
+ ---
42
+
43
+ ## 4. Key Performance Indicators (KPIs)
44
+
45
+ * **Execution Time (Cached):** Sub-microsecond response time for any cached value.
46
+ * **Execution Time (Uncached):** Linear scaling $O(n)$. Computing $F(10000)$ uncached must complete in under 5 milliseconds.
47
+ * **Call Stack Safety:** Zero recursion-based Call Stack Size Exceeded errors.
48
+ * **Memory Limit:** Strict enforcement of maximum cache entries (e.g. defaults to 1,000 values), keeping peak memory consumption under 25MB even for large BigInts.
49
+
50
+ ---
51
+
52
+ ## 5. Anti-Patterns (What NOT to do)
53
+ * Do not use recursive calls without tail call optimization or loop conversion. Recursion is forbidden for calculations.
54
+ * Do not store calculated BigInt values as standard floats since precision is lost.
55
+ * Do not allow the cache size to grow indefinitely (bounded cache is mandatory).