feihong-code 7.0.0 → 7.2.0
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/.github/workflows/release.yml +173 -0
- package/CHANGELOG.md +50 -0
- package/dist/agent/browser-agent.js +354 -0
- package/dist/agent/browser-agent.js.map +1 -0
- package/dist/agent/change-manager.js +433 -0
- package/dist/agent/change-manager.js.map +1 -0
- package/dist/agent/code-rag.js +293 -0
- package/dist/agent/code-rag.js.map +1 -0
- package/dist/agent/code-writer.js +13 -1
- package/dist/agent/code-writer.js.map +1 -1
- package/dist/agent/completion-engine.js +522 -0
- package/dist/agent/completion-engine.js.map +1 -0
- package/dist/agent/context-compactor.js +188 -10
- package/dist/agent/context-compactor.js.map +1 -1
- package/dist/agent/custom-agent.js +368 -0
- package/dist/agent/custom-agent.js.map +1 -0
- package/dist/agent/design-to-code.js +218 -0
- package/dist/agent/design-to-code.js.map +1 -0
- package/dist/agent/event-driven-agent.js +359 -0
- package/dist/agent/event-driven-agent.js.map +1 -0
- package/dist/agent/git-integration.js +324 -0
- package/dist/agent/git-integration.js.map +1 -0
- package/dist/agent/layered-memory.js +329 -0
- package/dist/agent/layered-memory.js.map +1 -0
- package/dist/agent/multi-agent.js +359 -0
- package/dist/agent/multi-agent.js.map +1 -0
- package/dist/agent/orchestrator.js +127 -16
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/quality-gate.js +139 -0
- package/dist/agent/quality-gate.js.map +1 -1
- package/dist/agent/self-correction.js +274 -0
- package/dist/agent/self-correction.js.map +1 -0
- package/dist/agent/self-heal.js +40 -10
- package/dist/agent/self-heal.js.map +1 -1
- package/dist/agent/solo-agent.js +321 -0
- package/dist/agent/solo-agent.js.map +1 -0
- package/dist/agent/symbol-index.js +258 -28
- package/dist/agent/symbol-index.js.map +1 -1
- package/dist/agent/team-collaboration.js +252 -0
- package/dist/agent/team-collaboration.js.map +1 -0
- package/dist/agent/type-checker.js +229 -0
- package/dist/agent/type-checker.js.map +1 -0
- package/dist/cli/run.js +1 -0
- package/dist/cli/run.js.map +1 -1
- package/dist/integrations/collaboration.js +219 -0
- package/dist/integrations/collaboration.js.map +1 -0
- package/dist/integrations/figma.js +307 -0
- package/dist/integrations/figma.js.map +1 -0
- package/dist/integrations/sso.js +327 -0
- package/dist/integrations/sso.js.map +1 -0
- package/dist/knowledge/library.js +301 -0
- package/dist/knowledge/library.js.map +1 -0
- package/dist/plugins/manager.js +332 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/runtime/event-log.js.map +1 -1
- package/dist/tools/browser/browser.tool.js +217 -0
- package/dist/tools/browser/browser.tool.js.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/shell/exec.js +50 -10
- package/dist/tools/shell/exec.js.map +1 -1
- package/dist/tools/shell/run-shell.tool.js +8 -2
- package/dist/tools/shell/run-shell.tool.js.map +1 -1
- package/dist/training/completion-evaluator.js +213 -0
- package/dist/training/completion-evaluator.js.map +1 -0
- package/dist/training/fim-data.js +248 -0
- package/dist/training/fim-data.js.map +1 -0
- package/dist/voice/voice-programming.js +223 -0
- package/dist/voice/voice-programming.js.map +1 -0
- package/dist/web/public/css/style.css +58 -0
- package/dist/web/public/index.html +210 -0
- package/dist/web/public/js/api.js +115 -1
- package/dist/web/public/js/mock-api.js +234 -0
- package/dist/web/public/js/monaco-editor.js +203 -0
- package/dist/web/public/js/ui.js +926 -4
- package/dist/web/public/manifest.json +59 -0
- package/dist/web/public/service-worker.js +173 -0
- package/dist/web/public/vendor/monaco/vs/abap-D-t0cyap.js +1 -0
- package/dist/web/public/vendor/monaco/vs/apex-CcIm7xu6.js +1 -0
- package/dist/web/public/vendor/monaco/vs/assets/css.worker-URu8fCFR.js +97 -0
- package/dist/web/public/vendor/monaco/vs/assets/editor.worker-lj3bdIIn.js +30 -0
- package/dist/web/public/vendor/monaco/vs/assets/editorWebWorkerMain-CA_vMoUU.js +30 -0
- package/dist/web/public/vendor/monaco/vs/assets/html.worker-D1SL3iM8.js +474 -0
- package/dist/web/public/vendor/monaco/vs/assets/json.worker-CoJx_OPf.js +62 -0
- package/dist/web/public/vendor/monaco/vs/assets/ts.worker-BWKtMYOk.js +67722 -0
- package/dist/web/public/vendor/monaco/vs/azcli-BA0tQDCg.js +1 -0
- package/dist/web/public/vendor/monaco/vs/basic-languages/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/bat-C397hTD6.js +1 -0
- package/dist/web/public/vendor/monaco/vs/bicep-DF5aW17k.js +2 -0
- package/dist/web/public/vendor/monaco/vs/cameligo-plsz8qhj.js +1 -0
- package/dist/web/public/vendor/monaco/vs/clojure-Y2auQMzK.js +1 -0
- package/dist/web/public/vendor/monaco/vs/coffee-Bu45yuWE.js +1 -0
- package/dist/web/public/vendor/monaco/vs/cpp-CkKPQIni.js +1 -0
- package/dist/web/public/vendor/monaco/vs/csharp-CX28MZyh.js +1 -0
- package/dist/web/public/vendor/monaco/vs/csp-D8uWnyxW.js +1 -0
- package/dist/web/public/vendor/monaco/vs/css-CaeNmE3S.js +3 -0
- package/dist/web/public/vendor/monaco/vs/css.worker-CyhWkhHo.js +1 -0
- package/dist/web/public/vendor/monaco/vs/cssMode-CV6Ay48H.js +1 -0
- package/dist/web/public/vendor/monaco/vs/cypher-DVThT8BS.js +1 -0
- package/dist/web/public/vendor/monaco/vs/dart-CmGfCvrO.js +1 -0
- package/dist/web/public/vendor/monaco/vs/dockerfile-CZqqYdch.js +1 -0
- package/dist/web/public/vendor/monaco/vs/ecl-30fUercY.js +1 -0
- package/dist/web/public/vendor/monaco/vs/editor/editor.main.css +1 -0
- package/dist/web/public/vendor/monaco/vs/editor/editor.main.js +1 -0
- package/dist/web/public/vendor/monaco/vs/editor/editor.worker.js +1 -0
- package/dist/web/public/vendor/monaco/vs/editor-KLE6jdfb.js +831 -0
- package/dist/web/public/vendor/monaco/vs/editor.js +1 -0
- package/dist/web/public/vendor/monaco/vs/editorWorkerHost-fVE1cjcC.js +35 -0
- package/dist/web/public/vendor/monaco/vs/elixir-xjPaIfzF.js +1 -0
- package/dist/web/public/vendor/monaco/vs/flow9-DqtmStfK.js +1 -0
- package/dist/web/public/vendor/monaco/vs/freemarker2-FWreY7v7.js +3 -0
- package/dist/web/public/vendor/monaco/vs/fsharp-BOMdg4U1.js +1 -0
- package/dist/web/public/vendor/monaco/vs/go-D_hbi-Jt.js +1 -0
- package/dist/web/public/vendor/monaco/vs/graphql-CKUU4kLG.js +1 -0
- package/dist/web/public/vendor/monaco/vs/handlebars-CZi4pHCH.js +1 -0
- package/dist/web/public/vendor/monaco/vs/hcl-DTaboeZW.js +1 -0
- package/dist/web/public/vendor/monaco/vs/html-j_7ZTNRU.js +1 -0
- package/dist/web/public/vendor/monaco/vs/html.worker-CA3iAimZ.js +1 -0
- package/dist/web/public/vendor/monaco/vs/htmlMode-27by_KM4.js +1 -0
- package/dist/web/public/vendor/monaco/vs/index-049xrXrp.js +1 -0
- package/dist/web/public/vendor/monaco/vs/index-CBVt3dzv.js +5 -0
- package/dist/web/public/vendor/monaco/vs/index.js +1 -0
- package/dist/web/public/vendor/monaco/vs/ini-CsNwO04R.js +1 -0
- package/dist/web/public/vendor/monaco/vs/initialize-DL0l1TGY.js +1 -0
- package/dist/web/public/vendor/monaco/vs/java-CI4ZMsH9.js +1 -0
- package/dist/web/public/vendor/monaco/vs/javascript-DTJl4Jn1.js +1 -0
- package/dist/web/public/vendor/monaco/vs/json.worker-BizpAl9O.js +1 -0
- package/dist/web/public/vendor/monaco/vs/jsonMode-DLUiMUrI.js +1 -0
- package/dist/web/public/vendor/monaco/vs/julia-BwzEvaQw.js +1 -0
- package/dist/web/public/vendor/monaco/vs/kotlin-IUYPiTV8.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/css/css.worker.js +66 -0
- package/dist/web/public/vendor/monaco/vs/language/css/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/html/html.worker.js +443 -0
- package/dist/web/public/vendor/monaco/vs/language/html/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/json/json.worker.js +17 -0
- package/dist/web/public/vendor/monaco/vs/language/json/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/typescript/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/typescript/ts.worker.js +67693 -0
- package/dist/web/public/vendor/monaco/vs/less-C0eDYdqa.js +2 -0
- package/dist/web/public/vendor/monaco/vs/lexon-iON-Kj97.js +1 -0
- package/dist/web/public/vendor/monaco/vs/liquid-CLJYelW6.js +1 -0
- package/dist/web/public/vendor/monaco/vs/loader.js +1368 -0
- package/dist/web/public/vendor/monaco/vs/lspLanguageFeatures-BIkJOWLw.js +2 -0
- package/dist/web/public/vendor/monaco/vs/lua-DtygF91M.js +1 -0
- package/dist/web/public/vendor/monaco/vs/m3-CsR4AuFi.js +1 -0
- package/dist/web/public/vendor/monaco/vs/main-BEx-Fmlo.js +15 -0
- package/dist/web/public/vendor/monaco/vs/main-DsK8pnKg.js +3 -0
- package/dist/web/public/vendor/monaco/vs/markdown-C_rD0bIw.js +1 -0
- package/dist/web/public/vendor/monaco/vs/mdx-CpzZIPHF.js +1 -0
- package/dist/web/public/vendor/monaco/vs/mips-CiYP61RB.js +1 -0
- package/dist/web/public/vendor/monaco/vs/monaco.contribution-9cKT3C7t.js +1 -0
- package/dist/web/public/vendor/monaco/vs/monaco.contribution-BE88ZNGY.js +1 -0
- package/dist/web/public/vendor/monaco/vs/monaco.contribution-BPhsneLd.js +1 -0
- package/dist/web/public/vendor/monaco/vs/monaco.contribution-BgRy6xDf.js +1 -0
- package/dist/web/public/vendor/monaco/vs/msdax-C38-sJlp.js +1 -0
- package/dist/web/public/vendor/monaco/vs/mysql-CdtbpvbG.js +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/cs.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/cs.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/de.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/de.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/es.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/es.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/fr.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/fr.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/it.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/it.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ja.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ja.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ko.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ko.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/pl.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/pl.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/pt-br.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/pt-br.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ru.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ru.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/tr.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/tr.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/zh-cn.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/zh-cn.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/zh-tw.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/zh-tw.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls.messages-loader.js +1 -0
- package/dist/web/public/vendor/monaco/vs/objective-c-CntZFaHX.js +1 -0
- package/dist/web/public/vendor/monaco/vs/pascal-r6kuqfl_.js +1 -0
- package/dist/web/public/vendor/monaco/vs/pascaligo-BiXoTmXh.js +1 -0
- package/dist/web/public/vendor/monaco/vs/perl-DABw_TcH.js +1 -0
- package/dist/web/public/vendor/monaco/vs/pgsql-me_jFXeX.js +1 -0
- package/dist/web/public/vendor/monaco/vs/php-D_kh-9LK.js +1 -0
- package/dist/web/public/vendor/monaco/vs/pla-VfZjczW0.js +1 -0
- package/dist/web/public/vendor/monaco/vs/postiats-BBSzz8Pk.js +1 -0
- package/dist/web/public/vendor/monaco/vs/powerquery-Dt-g_2cc.js +1 -0
- package/dist/web/public/vendor/monaco/vs/powershell-B-7ap1zc.js +1 -0
- package/dist/web/public/vendor/monaco/vs/protobuf-BmtuEB1A.js +2 -0
- package/dist/web/public/vendor/monaco/vs/pug-BRpRNeEb.js +1 -0
- package/dist/web/public/vendor/monaco/vs/python-CqWUUgfu.js +1 -0
- package/dist/web/public/vendor/monaco/vs/qsharp-BzsFaUU9.js +1 -0
- package/dist/web/public/vendor/monaco/vs/r-f8dDdrp4.js +1 -0
- package/dist/web/public/vendor/monaco/vs/razor-hok5y9Km.js +1 -0
- package/dist/web/public/vendor/monaco/vs/redis-fvZQY4PI.js +1 -0
- package/dist/web/public/vendor/monaco/vs/redshift-45Et0LQi.js +1 -0
- package/dist/web/public/vendor/monaco/vs/restructuredtext-C7UUFKFD.js +1 -0
- package/dist/web/public/vendor/monaco/vs/ruby-CZO8zYTz.js +1 -0
- package/dist/web/public/vendor/monaco/vs/rust-Bfetafyc.js +1 -0
- package/dist/web/public/vendor/monaco/vs/sb-3GYllVck.js +1 -0
- package/dist/web/public/vendor/monaco/vs/scala-foMgrKo1.js +1 -0
- package/dist/web/public/vendor/monaco/vs/scheme-CHdMtr7p.js +1 -0
- package/dist/web/public/vendor/monaco/vs/scss-C1cmLt9V.js +3 -0
- package/dist/web/public/vendor/monaco/vs/shell-ClXCKCEW.js +1 -0
- package/dist/web/public/vendor/monaco/vs/solidity-MZ6ExpPy.js +1 -0
- package/dist/web/public/vendor/monaco/vs/sophia-DWkuSsPQ.js +1 -0
- package/dist/web/public/vendor/monaco/vs/sparql-AUGFYSyk.js +1 -0
- package/dist/web/public/vendor/monaco/vs/sql-32GpJSV2.js +1 -0
- package/dist/web/public/vendor/monaco/vs/st-CuDFIVZ_.js +1 -0
- package/dist/web/public/vendor/monaco/vs/swift-t-PfMj7W.js +1 -0
- package/dist/web/public/vendor/monaco/vs/systemverilog-Ch4vA8Yt.js +1 -0
- package/dist/web/public/vendor/monaco/vs/tcl-D74tq1nH.js +1 -0
- package/dist/web/public/vendor/monaco/vs/toggleHighContrast-qGX7E9o7.js +61 -0
- package/dist/web/public/vendor/monaco/vs/ts.worker-2QLmBukE.js +1 -0
- package/dist/web/public/vendor/monaco/vs/tsMode-B0S_kp2q.js +11 -0
- package/dist/web/public/vendor/monaco/vs/twig-C6taOxMV.js +1 -0
- package/dist/web/public/vendor/monaco/vs/typescript-_2t_511t.js +1 -0
- package/dist/web/public/vendor/monaco/vs/typespec-8OfoLt6R.js +1 -0
- package/dist/web/public/vendor/monaco/vs/vb-Dyb2648j.js +1 -0
- package/dist/web/public/vendor/monaco/vs/wgsl-BhLXMOR0.js +298 -0
- package/dist/web/public/vendor/monaco/vs/workers-BBttULjf.js +1 -0
- package/dist/web/public/vendor/monaco/vs/xml-cZjNDqDT.js +1 -0
- package/dist/web/public/vendor/monaco/vs/yaml-A1fOIdH6.js +1 -0
- package/dist/web/server.js +1019 -0
- package/dist/web/server.js.map +1 -1
- package/dist/web/task-queue.js +22 -2
- package/dist/web/task-queue.js.map +1 -1
- package/docs/DEPLOYMENT.md +382 -0
- package/docs/MODEL_FINETUNING.md +405 -0
- package/electron/main.js +202 -4
- package/package.json +6 -1
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
# 飞虹 Code - 专用补全模型微调指南 (P3-1)
|
|
2
|
+
|
|
3
|
+
> 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
|
|
4
|
+
|
|
5
|
+
## 目录
|
|
6
|
+
|
|
7
|
+
1. [概述](#1-概述)
|
|
8
|
+
2. [环境准备](#2-环境准备)
|
|
9
|
+
3. [数据准备](#3-数据准备)
|
|
10
|
+
4. [模型训练](#4-模型训练)
|
|
11
|
+
5. [模型评估](#5-模型评估)
|
|
12
|
+
6. [模型导出与部署](#6-模型导出与部署)
|
|
13
|
+
7. [集成到飞虹 Code](#7-集成到飞虹-code)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. 概述
|
|
18
|
+
|
|
19
|
+
飞虹 Code 支持使用专用微调的代码补全模型,通过 FIM (Fill-In-the-Middle) 格式训练,提升代码补全的准确率和上下文理解能力。
|
|
20
|
+
|
|
21
|
+
### 1.1 技术方案
|
|
22
|
+
|
|
23
|
+
| 组件 | 说明 |
|
|
24
|
+
|---|---|
|
|
25
|
+
| **基础模型** | bigcode/starcoderbase-1b(或其他代码生成模型) |
|
|
26
|
+
| **微调方法** | LoRA (Low-Rank Adaptation),仅训练少量参数 |
|
|
27
|
+
| **训练格式** | FIM (Fill-In-the-Middle),prefix/suffix/middle 三部分 |
|
|
28
|
+
| **评估指标** | 精确匹配率、编辑相似度、前缀匹配率、延迟 |
|
|
29
|
+
| **部署格式** | 合并模型 / GGUF / ONNX |
|
|
30
|
+
|
|
31
|
+
### 1.2 硬件要求
|
|
32
|
+
|
|
33
|
+
| 配置 | 最低 | 推荐 |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| GPU 显存 | 8GB (RTX 3060/4060) | 16GB+ (RTX 3090/4090/A10) |
|
|
36
|
+
| 内存 | 16GB | 32GB+ |
|
|
37
|
+
| 磁盘空间 | 20GB | 50GB+ |
|
|
38
|
+
| 训练时间 | 4-8 小时 (1B 模型) | 1-2 小时 |
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 2. 环境准备
|
|
43
|
+
|
|
44
|
+
### 2.1 安装 Python 依赖
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# 创建虚拟环境
|
|
48
|
+
python -m venv .venv
|
|
49
|
+
source .venv/bin/activate # Linux/Mac
|
|
50
|
+
# .venv\Scripts\activate # Windows
|
|
51
|
+
|
|
52
|
+
# 安装 PyTorch(根据 CUDA 版本选择)
|
|
53
|
+
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118
|
|
54
|
+
|
|
55
|
+
# 安装训练依赖
|
|
56
|
+
pip install transformers peft datasets accelerate evaluate sentencepiece
|
|
57
|
+
pip install tensorboard wandb # 可选:可视化工具
|
|
58
|
+
|
|
59
|
+
# 安装导出依赖(可选)
|
|
60
|
+
pip install optimum onnxruntime # ONNX 导出
|
|
61
|
+
pip install llama-cpp-python # GGUF 导出
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2.2 验证环境
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python -c "import torch; print(f'PyTorch: {torch.__version__}'); print(f'CUDA: {torch.cuda.is_available()}')"
|
|
68
|
+
python -c "import transformers; print(f'Transformers: {transformers.__version__}')"
|
|
69
|
+
python -c "import peft; print(f'PEFT: {peft.__version__}')"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 3. 数据准备
|
|
75
|
+
|
|
76
|
+
### 3.1 使用飞虹 Code 内置数据准备工具
|
|
77
|
+
|
|
78
|
+
飞虹 Code 提供了 TypeScript 版本的 FIM 数据准备工具,可以直接从代码库生成训练数据。
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# 编译项目
|
|
82
|
+
npm run build
|
|
83
|
+
|
|
84
|
+
# 准备 FIM 训练数据
|
|
85
|
+
node dist/cli/index.js fim-prepare \
|
|
86
|
+
--source-dir ./your-codebase \
|
|
87
|
+
--output ./data/fim/dataset.jsonl \
|
|
88
|
+
--samples-per-file 10 \
|
|
89
|
+
--languages typescript,javascript,python
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 3.2 数据格式
|
|
93
|
+
|
|
94
|
+
输出为 JSONL 格式,每行一个样本:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"prefix": "function calculateSum(a: number, b: number): number {\n return ",
|
|
99
|
+
"suffix": "\n}\n\n// 其他代码...",
|
|
100
|
+
"middle": "a + b",
|
|
101
|
+
"file_path": "src/math.ts",
|
|
102
|
+
"language": "typescript",
|
|
103
|
+
"cursor_offset": 1234,
|
|
104
|
+
"middle_length": 5
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 3.3 数据划分
|
|
109
|
+
|
|
110
|
+
工具会自动生成三个文件:
|
|
111
|
+
- `dataset.train.jsonl` - 训练集(90%)
|
|
112
|
+
- `dataset.val.jsonl` - 验证集(10%)
|
|
113
|
+
- `dataset.meta.json` - 元数据(统计信息、配置)
|
|
114
|
+
|
|
115
|
+
### 3.4 数据质量建议
|
|
116
|
+
|
|
117
|
+
1. **代码质量**:使用高质量的代码库作为数据源
|
|
118
|
+
2. **语言覆盖**:确保覆盖目标编程语言
|
|
119
|
+
3. **数据量**:建议至少 10,000+ 样本
|
|
120
|
+
4. **去重**:避免重复或高度相似的样本
|
|
121
|
+
5. **过滤**:排除自动生成的代码、minified 文件、测试快照
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 4. 模型训练
|
|
126
|
+
|
|
127
|
+
### 4.1 配置训练参数
|
|
128
|
+
|
|
129
|
+
编辑 `training/lora-config.json`:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"base_model": "bigcode/starcoderbase-1b",
|
|
134
|
+
"output_dir": "./models/feihong-code-completion",
|
|
135
|
+
"num_train_epochs": 3,
|
|
136
|
+
"per_device_train_batch_size": 4,
|
|
137
|
+
"gradient_accumulation_steps": 4,
|
|
138
|
+
"learning_rate": 2e-4,
|
|
139
|
+
"max_seq_length": 2048,
|
|
140
|
+
"lora": {
|
|
141
|
+
"r": 16,
|
|
142
|
+
"lora_alpha": 32,
|
|
143
|
+
"lora_dropout": 0.05,
|
|
144
|
+
"target_modules": ["q_proj", "v_proj", "k_proj", "o_proj"]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 4.2 关键参数说明
|
|
150
|
+
|
|
151
|
+
| 参数 | 说明 | 推荐值 |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| `num_train_epochs` | 训练轮数 | 2-5 |
|
|
154
|
+
| `learning_rate` | 学习率 | 1e-4 ~ 3e-4 |
|
|
155
|
+
| `per_device_train_batch_size` | 每设备批大小 | 2-8(根据显存) |
|
|
156
|
+
| `gradient_accumulation_steps` | 梯度累积步数 | 2-8 |
|
|
157
|
+
| `max_seq_length` | 最大序列长度 | 1024-4096 |
|
|
158
|
+
| `lora.r` | LoRA 秩 | 8-32 |
|
|
159
|
+
| `lora.lora_alpha` | LoRA alpha | 16-64(通常为 r 的 2 倍) |
|
|
160
|
+
| `lora.lora_dropout` | LoRA dropout | 0.05-0.1 |
|
|
161
|
+
|
|
162
|
+
### 4.3 开始训练
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
cd training
|
|
166
|
+
|
|
167
|
+
# 使用默认配置训练
|
|
168
|
+
python train.py --config lora-config.json
|
|
169
|
+
|
|
170
|
+
# 指定基础模型
|
|
171
|
+
python train.py --config lora-config.json --base_model bigcode/starcoderbase-3b
|
|
172
|
+
|
|
173
|
+
# 从检查点恢复
|
|
174
|
+
python train.py --config lora-config.json --resume ./models/feihong-code-completion/checkpoint-1000
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### 4.4 监控训练
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# TensorBoard
|
|
181
|
+
tensorboard --logdir ./models/feihong-code-completion/runs
|
|
182
|
+
|
|
183
|
+
# 查看训练日志
|
|
184
|
+
tail -f ./models/feihong-code-complement/train_log.txt
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 4.5 训练技巧
|
|
188
|
+
|
|
189
|
+
1. **梯度检查点**:启用 `gradient_checkpointing: true` 节省显存
|
|
190
|
+
2. **混合精度**:启用 `bf16: true`(Ampere 及以上 GPU)或 `fp16: true`
|
|
191
|
+
3. **学习率调度**:使用 cosine 调度器,warmup 比例 3%
|
|
192
|
+
4. **早停**:监控验证损失,3 轮无提升则停止
|
|
193
|
+
5. **保存最佳模型**:`load_best_model_at_end: true`
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## 5. 模型评估
|
|
198
|
+
|
|
199
|
+
### 5.1 使用飞虹 Code 评估工具
|
|
200
|
+
|
|
201
|
+
飞虹 Code 提供了 TypeScript 版本的补全模型评估工具。
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# 编译项目
|
|
205
|
+
npm run build
|
|
206
|
+
|
|
207
|
+
# 运行评估
|
|
208
|
+
node dist/cli/index.js fim-evaluate \
|
|
209
|
+
--samples ./data/fim/dataset.val.jsonl \
|
|
210
|
+
--model ./models/feihong-code-completion \
|
|
211
|
+
--output ./evaluation/result.json \
|
|
212
|
+
--max-samples 500
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 5.2 评估指标
|
|
216
|
+
|
|
217
|
+
| 指标 | 说明 | 目标值 |
|
|
218
|
+
|---|---|---|
|
|
219
|
+
| **精确匹配率** | 预测与期望完全一致的比例 | > 30% |
|
|
220
|
+
| **编辑相似度** | 1 - 编辑距离/最大长度 | > 70% |
|
|
221
|
+
| **前缀匹配率** | 预测前缀与期望前缀的匹配度 | > 60% |
|
|
222
|
+
| **首 Token 匹配率** | 第一个 token 是否匹配 | > 50% |
|
|
223
|
+
| **平均延迟** | 单次补全的平均耗时 | < 500ms |
|
|
224
|
+
|
|
225
|
+
### 5.3 评估结果示例
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
=== 补全模型评估结果 ===
|
|
229
|
+
样本数: 500
|
|
230
|
+
精确匹配率: 32.40%
|
|
231
|
+
编辑相似度: 74.56%
|
|
232
|
+
前缀匹配率: 62.30%
|
|
233
|
+
首Token匹配率: 54.80%
|
|
234
|
+
平均延迟: 320.50ms
|
|
235
|
+
|
|
236
|
+
--- 按语言统计 ---
|
|
237
|
+
typescript: 200 样本, 精确匹配 35.0%, 编辑相似度 76.2%
|
|
238
|
+
javascript: 150 样本, 精确匹配 30.7%, 编辑相似度 73.1%
|
|
239
|
+
python: 100 样本, 精确匹配 28.0%, 编辑相似度 71.5%
|
|
240
|
+
其他: 50 样本, 精确匹配 24.0%, 编辑相似度 68.3%
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 5.4 与基线模型对比
|
|
244
|
+
|
|
245
|
+
建议在相同数据集上评估基线模型(未微调),对比提升效果:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# 评估基线模型
|
|
249
|
+
node dist/cli/index.js fim-evaluate \
|
|
250
|
+
--samples ./data/fim/dataset.val.jsonl \
|
|
251
|
+
--model bigcode/starcoderbase-1b \
|
|
252
|
+
--output ./evaluation/baseline.json
|
|
253
|
+
|
|
254
|
+
# 对比结果
|
|
255
|
+
node dist/cli/index.js fim-compare \
|
|
256
|
+
--baseline ./evaluation/baseline.json \
|
|
257
|
+
--finetuned ./evaluation/result.json
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## 6. 模型导出与部署
|
|
263
|
+
|
|
264
|
+
### 6.1 合并 LoRA 权重
|
|
265
|
+
|
|
266
|
+
训练完成后,需要将 LoRA 权重合并到基础模型:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
cd training
|
|
270
|
+
|
|
271
|
+
# 合并 LoRA 并导出
|
|
272
|
+
python export.py \
|
|
273
|
+
--model_path ./models/feihong-code-completion \
|
|
274
|
+
--output ./models/exported \
|
|
275
|
+
--format merged
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### 6.2 导出格式
|
|
279
|
+
|
|
280
|
+
| 格式 | 用途 | 命令 |
|
|
281
|
+
|---|---|---|
|
|
282
|
+
| **merged** | 通用部署(Transformers) | `--format merged` |
|
|
283
|
+
| **GGUF** | llama.cpp 本地推理 | `--format gguf` |
|
|
284
|
+
| **ONNX** | Web / 跨平台部署 | `--format onnx` |
|
|
285
|
+
| **all** | 导出所有格式 | `--format all` |
|
|
286
|
+
|
|
287
|
+
### 6.3 导出产物
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
models/exported/
|
|
291
|
+
├── merged/ # 合并后的模型
|
|
292
|
+
│ ├── config.json
|
|
293
|
+
│ ├── model.safetensors
|
|
294
|
+
│ ├── tokenizer.json
|
|
295
|
+
│ └── training_config.json
|
|
296
|
+
├── gguf/ # GGUF 格式(可选)
|
|
297
|
+
│ └── model.gguf
|
|
298
|
+
├── onnx/ # ONNX 格式(可选)
|
|
299
|
+
│ ├── model.onnx
|
|
300
|
+
│ └── tokenizer.json
|
|
301
|
+
└── feihong-model-config.json # 飞虹 Code 模型配置
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## 7. 集成到飞虹 Code
|
|
307
|
+
|
|
308
|
+
### 7.1 配置本地模型
|
|
309
|
+
|
|
310
|
+
编辑飞虹 Code 配置文件(`~/.feihong-code/config.json`):
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"completion": {
|
|
315
|
+
"provider": "local",
|
|
316
|
+
"model_path": "./models/exported/merged",
|
|
317
|
+
"model_config": "./models/exported/feihong-model-config.json",
|
|
318
|
+
"max_tokens": 100,
|
|
319
|
+
"temperature": 0.2,
|
|
320
|
+
"top_p": 0.95,
|
|
321
|
+
"context_window": 2048
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### 7.2 启动本地推理服务
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
# 使用飞虹 Code 内置的本地模型服务
|
|
330
|
+
node dist/cli/index.js serve-local-model \
|
|
331
|
+
--model ./models/exported/merged \
|
|
332
|
+
--port 8081
|
|
333
|
+
|
|
334
|
+
# 或使用 vLLM(推荐,性能更好)
|
|
335
|
+
pip install vllm
|
|
336
|
+
vllm serve ./models/exported/merged --port 8081 --dtype bfloat16
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### 7.3 配置飞虹 Code 使用本地服务
|
|
340
|
+
|
|
341
|
+
```json
|
|
342
|
+
{
|
|
343
|
+
"completion": {
|
|
344
|
+
"provider": "openai-compatible",
|
|
345
|
+
"base_url": "http://localhost:8081/v1",
|
|
346
|
+
"model": "feihong-code-completion",
|
|
347
|
+
"api_key": "not-needed"
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### 7.4 验证集成
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
# 启动飞虹 Code Web 控制台
|
|
356
|
+
node dist/cli/index.js serve --port 8080
|
|
357
|
+
|
|
358
|
+
# 测试补全
|
|
359
|
+
curl -X POST http://localhost:8080/api/completion \
|
|
360
|
+
-H "Content-Type: application/json" \
|
|
361
|
+
-d '{
|
|
362
|
+
"filePath": "test.ts",
|
|
363
|
+
"fileContent": "function sum(a: number, b: number): number { return ",
|
|
364
|
+
"cursorOffset": 50,
|
|
365
|
+
"language": "typescript"
|
|
366
|
+
}'
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## 附录:常见问题
|
|
372
|
+
|
|
373
|
+
### Q1: 训练时 OOM (Out of Memory) 怎么办?
|
|
374
|
+
|
|
375
|
+
A:
|
|
376
|
+
1. 减小 `per_device_train_batch_size`(如 1 或 2)
|
|
377
|
+
2. 增大 `gradient_accumulation_steps` 保持有效批大小
|
|
378
|
+
3. 减小 `max_seq_length`(如 1024)
|
|
379
|
+
4. 启用 `gradient_checkpointing: true`
|
|
380
|
+
5. 使用更小的基础模型(如 350M 或 1B)
|
|
381
|
+
|
|
382
|
+
### Q2: 训练后模型效果不好怎么办?
|
|
383
|
+
|
|
384
|
+
A:
|
|
385
|
+
1. 检查数据质量,确保样本多样化且高质量
|
|
386
|
+
2. 增加训练轮数(如 5-10 轮)
|
|
387
|
+
3. 调整学习率(如 1e-4 或 5e-5)
|
|
388
|
+
4. 增大 LoRA rank(如 32 或 64)
|
|
389
|
+
5. 增加 target_modules(包含更多层)
|
|
390
|
+
6. 对比基线模型,确认确实有提升
|
|
391
|
+
|
|
392
|
+
### Q3: 如何支持更多编程语言?
|
|
393
|
+
|
|
394
|
+
A:
|
|
395
|
+
1. 在数据准备时指定 `--languages` 参数
|
|
396
|
+
2. 确保训练数据包含目标语言的代码
|
|
397
|
+
3. 使用支持多语言的基础模型(如 StarCoder、CodeLlama)
|
|
398
|
+
4. 评估时按语言分别统计,针对性优化
|
|
399
|
+
|
|
400
|
+
### Q4: 可以在 CPU 上训练吗?
|
|
401
|
+
|
|
402
|
+
A: 可以,但非常慢。建议:
|
|
403
|
+
1. 使用 Google Colab (免费 T4 GPU)
|
|
404
|
+
2. 使用云 GPU 服务(如 AutoDL、RunPod、Vast.ai)
|
|
405
|
+
3. 使用更小的模型和数据集进行验证
|
package/electron/main.js
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
* 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const { app, BrowserWindow, shell, Tray, Menu, ipcMain, dialog, clipboard, Notification, session, desktopCapturer, screen } = require('electron');
|
|
6
|
+
const { app, BrowserWindow, shell, Tray, Menu, ipcMain, dialog, clipboard, Notification, session, desktopCapturer, screen, globalShortcut } = require('electron');
|
|
7
7
|
const { spawn } = require('child_process');
|
|
8
|
-
const { existsSync } = require('fs');
|
|
9
|
-
const { join } = require('path');
|
|
8
|
+
const { existsSync, writeFileSync, readFileSync } = require('fs');
|
|
9
|
+
const { join, resolve } = require('path');
|
|
10
10
|
const http = require('http');
|
|
11
|
+
const os = require('os');
|
|
11
12
|
|
|
12
13
|
// 禁用安全警告
|
|
13
14
|
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true';
|
|
@@ -176,9 +177,27 @@ function createTray() {
|
|
|
176
177
|
tray = new Tray(trayIcon);
|
|
177
178
|
tray.setToolTip('飞虹 Code');
|
|
178
179
|
|
|
180
|
+
const isAutoLaunch = app.getLoginItemSettings().openAtLogin;
|
|
181
|
+
|
|
179
182
|
const contextMenu = Menu.buildFromTemplate([
|
|
180
183
|
{ label: '显示主窗口', click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); } } },
|
|
184
|
+
{ label: '隐藏到托盘', click: () => { if (mainWindow) mainWindow.hide(); } },
|
|
185
|
+
{ type: 'separator' },
|
|
186
|
+
{ label: '新建任务', click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); mainWindow.webContents.send('app:new-task'); } } },
|
|
187
|
+
{ label: '快速补全', click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); mainWindow.webContents.send('app:quick-complete'); } } },
|
|
181
188
|
{ type: 'separator' },
|
|
189
|
+
{
|
|
190
|
+
label: '开机自启动',
|
|
191
|
+
type: 'checkbox',
|
|
192
|
+
checked: isAutoLaunch,
|
|
193
|
+
click: (menuItem) => {
|
|
194
|
+
app.setLoginItemSettings({ openAtLogin: menuItem.checked });
|
|
195
|
+
console.log('[Electron] 开机自启动设置:', menuItem.checked);
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
{ label: '检查更新', click: () => { checkForUpdates(); } },
|
|
199
|
+
{ type: 'separator' },
|
|
200
|
+
{ label: '关于飞虹 Code', click: () => { showAboutDialog(); } },
|
|
182
201
|
{ label: '退出', click: () => { app.isQuitting = true; app.quit(); } }
|
|
183
202
|
]);
|
|
184
203
|
tray.setContextMenu(contextMenu);
|
|
@@ -189,6 +208,11 @@ function createTray() {
|
|
|
189
208
|
else { mainWindow.show(); mainWindow.focus(); }
|
|
190
209
|
}
|
|
191
210
|
});
|
|
211
|
+
|
|
212
|
+
// 双击托盘显示主窗口
|
|
213
|
+
tray.on('double-click', () => {
|
|
214
|
+
if (mainWindow) { mainWindow.show(); mainWindow.focus(); }
|
|
215
|
+
});
|
|
192
216
|
} catch (e) {
|
|
193
217
|
console.warn('[Electron] 创建托盘失败: ' + e.message);
|
|
194
218
|
}
|
|
@@ -334,6 +358,159 @@ function setupIpc() {
|
|
|
334
358
|
return { success: false, error: err.message };
|
|
335
359
|
}
|
|
336
360
|
});
|
|
361
|
+
|
|
362
|
+
// 全局快捷键
|
|
363
|
+
ipcMain.handle('shortcuts:getAll', () => {
|
|
364
|
+
return [
|
|
365
|
+
{ accelerator: 'Ctrl+Shift+Space', description: '显示/隐藏主窗口' },
|
|
366
|
+
{ accelerator: 'Ctrl+Shift+K', description: '新建任务' },
|
|
367
|
+
{ accelerator: 'Ctrl+Shift+L', description: '快速补全' },
|
|
368
|
+
];
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// 开机自启
|
|
372
|
+
ipcMain.handle('autolaunch:get', () => {
|
|
373
|
+
return app.getLoginItemSettings().openAtLogin;
|
|
374
|
+
});
|
|
375
|
+
ipcMain.handle('autolaunch:set', (_, enabled) => {
|
|
376
|
+
app.setLoginItemSettings({ openAtLogin: enabled });
|
|
377
|
+
return app.getLoginItemSettings().openAtLogin;
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
// 应用信息
|
|
381
|
+
ipcMain.handle('app:info', () => {
|
|
382
|
+
return {
|
|
383
|
+
version: app.getVersion(),
|
|
384
|
+
name: app.getName(),
|
|
385
|
+
path: app.getAppPath(),
|
|
386
|
+
userData: app.getPath('userData'),
|
|
387
|
+
platform: process.platform,
|
|
388
|
+
arch: process.arch,
|
|
389
|
+
nodeVersion: process.versions.node,
|
|
390
|
+
electronVersion: process.versions.electron,
|
|
391
|
+
chromeVersion: process.versions.chrome,
|
|
392
|
+
};
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* 注册全局快捷键
|
|
398
|
+
*/
|
|
399
|
+
function registerGlobalShortcuts() {
|
|
400
|
+
try {
|
|
401
|
+
// Ctrl+Shift+Space: 快速唤起飞虹 Code(显示/隐藏主窗口)
|
|
402
|
+
const ret1 = globalShortcut.register('CommandOrControl+Shift+Space', () => {
|
|
403
|
+
if (mainWindow) {
|
|
404
|
+
if (mainWindow.isVisible() && mainWindow.isFocused()) {
|
|
405
|
+
mainWindow.hide();
|
|
406
|
+
} else {
|
|
407
|
+
mainWindow.show();
|
|
408
|
+
mainWindow.focus();
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// Ctrl+Shift+K: 新建任务
|
|
414
|
+
const ret2 = globalShortcut.register('CommandOrControl+Shift+K', () => {
|
|
415
|
+
if (mainWindow) {
|
|
416
|
+
mainWindow.show();
|
|
417
|
+
mainWindow.focus();
|
|
418
|
+
mainWindow.webContents.send('app:new-task');
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
// Ctrl+Shift+L: 快速补全
|
|
423
|
+
const ret3 = globalShortcut.register('CommandOrControl+Shift+L', () => {
|
|
424
|
+
if (mainWindow) {
|
|
425
|
+
mainWindow.show();
|
|
426
|
+
mainWindow.focus();
|
|
427
|
+
mainWindow.webContents.send('app:quick-complete');
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
if (ret1 && ret2 && ret3) {
|
|
432
|
+
console.log('[Electron] 全局快捷键注册成功');
|
|
433
|
+
} else {
|
|
434
|
+
console.warn('[Electron] 部分全局快捷键注册失败');
|
|
435
|
+
}
|
|
436
|
+
} catch (e) {
|
|
437
|
+
console.warn('[Electron] 全局快捷键注册异常: ' + e.message);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* 检查更新(简化版,实际应使用 electron-updater)
|
|
443
|
+
*/
|
|
444
|
+
function checkForUpdates() {
|
|
445
|
+
console.log('[Electron] 检查更新...');
|
|
446
|
+
// 简化版:显示当前版本,实际应使用 electron-updater
|
|
447
|
+
const version = app.getVersion();
|
|
448
|
+
dialog.showMessageBox(mainWindow, {
|
|
449
|
+
type: 'info',
|
|
450
|
+
title: '检查更新',
|
|
451
|
+
message: `当前版本: v${version}`,
|
|
452
|
+
detail: '飞虹 Code 会在有新版本时自动通知您。\n\n您也可以访问官网下载最新版本。',
|
|
453
|
+
buttons: ['确定', '访问官网'],
|
|
454
|
+
defaultId: 0,
|
|
455
|
+
cancelId: 0
|
|
456
|
+
}).then(({ response }) => {
|
|
457
|
+
if (response === 1) {
|
|
458
|
+
shell.openExternal('https://feihong-code.com');
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* 显示关于对话框
|
|
465
|
+
*/
|
|
466
|
+
function showAboutDialog() {
|
|
467
|
+
const version = app.getVersion();
|
|
468
|
+
dialog.showMessageBox(mainWindow, {
|
|
469
|
+
type: 'info',
|
|
470
|
+
title: '关于飞虹 Code',
|
|
471
|
+
message: `飞虹 Code v${version}`,
|
|
472
|
+
detail: '终端 AI 编程智能体\n晋江市飞虹智科技企业管理有限公司\n飞扬企源研发中心 · 负责人:吴赐虹\n\n技术栈:TypeScript + Electron + Express\n核心能力:多模型路由、企业级 RBAC、全自动 SWE Agent',
|
|
473
|
+
buttons: ['确定', '官方网站', 'GitHub'],
|
|
474
|
+
defaultId: 0,
|
|
475
|
+
cancelId: 0
|
|
476
|
+
}).then(({ response }) => {
|
|
477
|
+
if (response === 1) shell.openExternal('https://feihong-code.com');
|
|
478
|
+
if (response === 2) shell.openExternal('https://github.com/feihong-code');
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* 设置深度链接(fhcode:// 协议)
|
|
484
|
+
*/
|
|
485
|
+
function setupDeepLink() {
|
|
486
|
+
if (process.defaultApp) {
|
|
487
|
+
if (process.argv.length >= 2) {
|
|
488
|
+
app.setAsDefaultProtocolClient('fhcode', process.execPath, [resolve(process.argv[1])]);
|
|
489
|
+
}
|
|
490
|
+
} else {
|
|
491
|
+
app.setAsDefaultProtocolClient('fhcode');
|
|
492
|
+
}
|
|
493
|
+
console.log('[Electron] 深度链接协议已注册: fhcode://');
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* 处理深度链接 URL
|
|
498
|
+
*/
|
|
499
|
+
function handleDeepLink(url) {
|
|
500
|
+
console.log('[Electron] 深度链接:', url);
|
|
501
|
+
try {
|
|
502
|
+
const parsed = new URL(url);
|
|
503
|
+
const action = parsed.hostname;
|
|
504
|
+
const params = Object.fromEntries(parsed.searchParams);
|
|
505
|
+
|
|
506
|
+
if (mainWindow) {
|
|
507
|
+
mainWindow.show();
|
|
508
|
+
mainWindow.focus();
|
|
509
|
+
mainWindow.webContents.send('app:deep-link', { action, params });
|
|
510
|
+
}
|
|
511
|
+
} catch (e) {
|
|
512
|
+
console.error('[Electron] 深度链接解析失败:', e.message);
|
|
513
|
+
}
|
|
337
514
|
}
|
|
338
515
|
|
|
339
516
|
// App 就绪
|
|
@@ -344,10 +521,12 @@ app.whenReady().then(async () => {
|
|
|
344
521
|
try {
|
|
345
522
|
setupIpc();
|
|
346
523
|
setupPermissions();
|
|
524
|
+
setupDeepLink();
|
|
347
525
|
createMenu();
|
|
348
526
|
await startServer();
|
|
349
527
|
createWindow();
|
|
350
528
|
createTray();
|
|
529
|
+
registerGlobalShortcuts();
|
|
351
530
|
|
|
352
531
|
app.on('activate', () => {
|
|
353
532
|
if (BrowserWindow.getAllWindows().length === 0) createWindow();
|
|
@@ -380,15 +559,34 @@ app.whenReady().then(async () => {
|
|
|
380
559
|
// 所有窗口关闭时不退出(保持托盘运行)
|
|
381
560
|
app.on('window-all-closed', () => {});
|
|
382
561
|
|
|
383
|
-
//
|
|
562
|
+
// 退出前注销全局快捷键并停止服务器
|
|
384
563
|
app.on('before-quit', () => {
|
|
385
564
|
app.isQuitting = true;
|
|
565
|
+
globalShortcut.unregisterAll();
|
|
386
566
|
if (serverProcess) {
|
|
387
567
|
serverProcess.kill();
|
|
388
568
|
serverProcess = null;
|
|
389
569
|
}
|
|
390
570
|
});
|
|
391
571
|
|
|
572
|
+
// 处理深度链接(Windows/Linux)
|
|
573
|
+
app.on('second-instance', (event, commandLine) => {
|
|
574
|
+
if (mainWindow) {
|
|
575
|
+
if (mainWindow.isMinimized()) mainWindow.restore();
|
|
576
|
+
mainWindow.show();
|
|
577
|
+
mainWindow.focus();
|
|
578
|
+
}
|
|
579
|
+
// 查找深度链接 URL
|
|
580
|
+
const deepLink = commandLine.find(arg => arg.startsWith('fhcode://'));
|
|
581
|
+
if (deepLink) handleDeepLink(deepLink);
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
// 处理深度链接(macOS)
|
|
585
|
+
app.on('open-url', (event, url) => {
|
|
586
|
+
event.preventDefault();
|
|
587
|
+
handleDeepLink(url);
|
|
588
|
+
});
|
|
589
|
+
|
|
392
590
|
// 防止多开
|
|
393
591
|
const gotLock = app.requestSingleInstanceLock();
|
|
394
592
|
if (!gotLock) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "feihong-code",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.2.0",
|
|
4
4
|
"description": "fhcode(飞虹 Code)— 终端 AI 编程智能体,对标 Muse Code / Cursor CLI:多模型路由(DeepSeek/通义/Ollama/OpenAI)、企业级 RBAC 审计、全自动 SWE Agent、支持离线私有化",
|
|
5
5
|
"bin": {
|
|
6
6
|
"fhcode": "dist/cli/index.js"
|
|
@@ -98,6 +98,8 @@
|
|
|
98
98
|
"url": "https://www.klai.top"
|
|
99
99
|
},
|
|
100
100
|
"devDependencies": {
|
|
101
|
+
"@capacitor/android": "^8.5.0",
|
|
102
|
+
"@capacitor/cli": "^7.6.8",
|
|
101
103
|
"@types/express": "^5.0.6",
|
|
102
104
|
"@types/node": "^26.2.0",
|
|
103
105
|
"electron": "^41.7.1",
|
|
@@ -106,7 +108,10 @@
|
|
|
106
108
|
"typescript": "^5.6.3"
|
|
107
109
|
},
|
|
108
110
|
"dependencies": {
|
|
111
|
+
"@capacitor/core": "^8.5.0",
|
|
109
112
|
"express": "^4.21.2",
|
|
113
|
+
"monaco-editor": "^0.56.0",
|
|
114
|
+
"playwright-core": "^1.62.1",
|
|
110
115
|
"zod": "^4.4.3"
|
|
111
116
|
},
|
|
112
117
|
"publishConfig": {
|