ai-helper-agent 2.1.0 → 2.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/README.md +20 -1
- package/README.zh-CN.md +20 -1
- package/bin/agent.js +150 -0
- package/dist/assets/{agent-store-C4hZkQT5.js → agent-store-DOyMdB_7.js} +2 -2
- package/dist/assets/{agent-store-C4hZkQT5.js.map → agent-store-DOyMdB_7.js.map} +1 -1
- package/dist/assets/background.js +84 -85
- package/dist/assets/background.js.map +1 -1
- package/dist/assets/content.js +80 -78
- package/dist/assets/{i18n-CAh-vB_T.js → i18n-MmYITlVj.js} +5 -5
- package/dist/assets/i18n-MmYITlVj.js.map +1 -0
- package/dist/assets/model-profiles-CV_sUuPf.js +25 -0
- package/dist/assets/model-profiles-CV_sUuPf.js.map +1 -0
- package/dist/assets/options.js +56 -56
- package/dist/assets/options.js.map +1 -1
- package/dist/assets/page-snapshot-renderer-CE53ibi-.js +4 -0
- package/dist/assets/page-snapshot-renderer-CE53ibi-.js.map +1 -0
- package/dist/assets/{session-store-uZ_LNasH.js → session-store-B0ZPGm7d.js} +4 -4
- package/dist/assets/{session-store-uZ_LNasH.js.map → session-store-B0ZPGm7d.js.map} +1 -1
- package/dist/assets/side_panel.css +1 -1
- package/dist/assets/side_panel.js +177 -171
- package/dist/assets/side_panel.js.map +1 -1
- package/dist/manifest.json +6 -3
- package/dist/offscreen/offscreen.js +6 -6
- package/dist/options.html +2 -11
- package/dist/side_panel.html +6 -6
- package/package.json +1 -1
- package/src/install-mode.js +128 -0
- package/src/locales/cli.json +24 -0
- package/src/rag/install.js +4 -0
- package/src/server.js +3 -1
- package/dist/assets/i18n-CAh-vB_T.js.map +0 -1
- package/dist/assets/model-profiles-CGxULM3O.js +0 -25
- package/dist/assets/model-profiles-CGxULM3O.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,11 +6,27 @@ AI Helper Agent — a local proxy service that provides the [AI Helper Chrome Ex
|
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
|
+
### One-click install (recommended)
|
|
10
|
+
|
|
11
|
+
Automatically detects network environment, downloads Node.js runtime, installs Agent, and configures auto-start — no Node.js knowledge required.
|
|
12
|
+
|
|
13
|
+
**macOS / Linux:**
|
|
14
|
+
```bash
|
|
15
|
+
curl -fsSL https://raw.githubusercontent.com/xiweicheng/ai-helper/main/install.sh | bash
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Windows (PowerShell):**
|
|
19
|
+
```powershell
|
|
20
|
+
irm https://raw.githubusercontent.com/xiweicheng/ai-helper/main/install.ps1 | iex
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Manual install (npm)
|
|
24
|
+
|
|
9
25
|
```bash
|
|
10
26
|
npm install -g ai-helper-agent
|
|
11
27
|
```
|
|
12
28
|
|
|
13
|
-
Requires Node.js >= 18.0.0.
|
|
29
|
+
Requires Node.js >= 18.0.0 (>= 22.13.0 for Knowledge Base / RAG features).
|
|
14
30
|
|
|
15
31
|
## Quick Start
|
|
16
32
|
|
|
@@ -40,6 +56,9 @@ After startup, the terminal will display a 6-digit pairing code. Enter it in the
|
|
|
40
56
|
| `paircode` | Show pairing code |
|
|
41
57
|
| `config` | View current configuration |
|
|
42
58
|
| `rag status` / `rag install` | Check RAG dependency availability / one-click install |
|
|
59
|
+
| `update` | Check and update to latest version (`--check` for info only) |
|
|
60
|
+
| `uninstall` | One-click uninstall (keeps user data) |
|
|
61
|
+
| `autostart off` | Disable auto-start at boot |
|
|
43
62
|
| `help` | Show help information |
|
|
44
63
|
| `--version` / `-v` | Show version number |
|
|
45
64
|
|
package/README.zh-CN.md
CHANGED
|
@@ -6,11 +6,27 @@ AI Helper 代理服务,为 [AI Helper Chrome 扩展](https://github.com/xiweic
|
|
|
6
6
|
|
|
7
7
|
## 安装
|
|
8
8
|
|
|
9
|
+
### 一键安装(推荐)
|
|
10
|
+
|
|
11
|
+
自动检测网络环境、下载 Node.js 运行时、安装 Agent 并配置开机自启——无需任何 Node.js 知识。
|
|
12
|
+
|
|
13
|
+
**macOS / Linux:**
|
|
14
|
+
```bash
|
|
15
|
+
curl -fsSL https://raw.githubusercontent.com/xiweicheng/ai-helper/main/install.sh | bash
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Windows(PowerShell):**
|
|
19
|
+
```powershell
|
|
20
|
+
irm https://raw.githubusercontent.com/xiweicheng/ai-helper/main/install.ps1 | iex
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 手动安装(npm)
|
|
24
|
+
|
|
9
25
|
```bash
|
|
10
26
|
npm install -g ai-helper-agent
|
|
11
27
|
```
|
|
12
28
|
|
|
13
|
-
要求 Node.js >= 18.0.0
|
|
29
|
+
要求 Node.js >= 18.0.0(知识库/RAG 功能要求 >= 22.13.0)。
|
|
14
30
|
|
|
15
31
|
## 快速开始
|
|
16
32
|
|
|
@@ -40,6 +56,9 @@ ai-helper-agent start --workdir /path/to/your/project --port 18911
|
|
|
40
56
|
| `paircode` | 查看配对码提示 |
|
|
41
57
|
| `config` | 查看当前配置 |
|
|
42
58
|
| `rag status` / `rag install` | 检测 RAG 依赖可用性 / 一键安装 RAG 依赖 |
|
|
59
|
+
| `update` | 检查并更新到最新版本(`--check` 仅查看) |
|
|
60
|
+
| `uninstall` | 一键卸载(保留用户数据) |
|
|
61
|
+
| `autostart off` | 关闭开机自启 |
|
|
43
62
|
| `help` | 显示帮助信息 |
|
|
44
63
|
| `--version` / `-v` | 显示版本号 |
|
|
45
64
|
|
package/bin/agent.js
CHANGED
|
@@ -237,6 +237,9 @@ function printHelp() {
|
|
|
237
237
|
console.log(t('cmdPaircode'));
|
|
238
238
|
console.log(t('cmdConfig'));
|
|
239
239
|
console.log(t('cmdRag'));
|
|
240
|
+
console.log(t('cmdUpdate'));
|
|
241
|
+
console.log(t('cmdUninstall'));
|
|
242
|
+
console.log(t('cmdAutostart'));
|
|
240
243
|
console.log(t('cmdHelp'));
|
|
241
244
|
console.log('');
|
|
242
245
|
console.log(t('startupOptions'));
|
|
@@ -300,6 +303,9 @@ if (command === '--version' || command === '-v') {
|
|
|
300
303
|
if (command === 'start') {
|
|
301
304
|
const isBg = process.argv.includes('--background') || process.argv.includes('-b');
|
|
302
305
|
|
|
306
|
+
// 用户主动启动时清除 .stopped 标记(否则 autostart guard 会阻止启动)
|
|
307
|
+
try { const stopped = join(AGENT_DIR, '.stopped'); if (existsSync(stopped)) unlinkSync(stopped); } catch {}
|
|
308
|
+
|
|
303
309
|
if (isBg) {
|
|
304
310
|
ensureAgentDir();
|
|
305
311
|
|
|
@@ -677,6 +683,150 @@ if (command === 'start') {
|
|
|
677
683
|
console.log(JSON.stringify(config, null, 2));
|
|
678
684
|
console.log(`[Agent] ${t('configFileLocation', { path: CONFIG_FILE })}`);
|
|
679
685
|
|
|
686
|
+
// ==================== update ====================
|
|
687
|
+
} else if (command === 'update') {
|
|
688
|
+
const checkOnly = rawArgs.includes('--check');
|
|
689
|
+
const { getRegistryUrl, getNpmPath, isEmbedded, getAgentPackageRoot } = await import('../src/install-mode.js');
|
|
690
|
+
const { spawnSync } = await import('child_process');
|
|
691
|
+
|
|
692
|
+
const npmPath = getNpmPath();
|
|
693
|
+
const registry = getRegistryUrl();
|
|
694
|
+
const registryArg = registry ? [`--registry=${registry}`] : [];
|
|
695
|
+
const pkgRoot = getAgentPackageRoot();
|
|
696
|
+
|
|
697
|
+
// 当前版本
|
|
698
|
+
const pkgJson = JSON.parse(readFileSync(join(pkgRoot, 'package.json'), 'utf-8'));
|
|
699
|
+
const currentVersion = pkgJson.version;
|
|
700
|
+
|
|
701
|
+
// 查询最新版
|
|
702
|
+
const viewArgs = ['view', 'ai-helper-agent', 'version', ...registryArg];
|
|
703
|
+
const viewResult = spawnSync(npmPath, viewArgs, { encoding: 'utf-8', shell: process.platform === 'win32' });
|
|
704
|
+
const latestVersion = (viewResult.stdout || '').trim().split('\n').pop();
|
|
705
|
+
|
|
706
|
+
if (!latestVersion || latestVersion === currentVersion) {
|
|
707
|
+
console.log(`[Agent] ${t('updateLatest', { version: currentVersion })}`);
|
|
708
|
+
process.exit(0);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
if (checkOnly) {
|
|
712
|
+
console.log(`[Agent] ${t('updateAvailable', { current: currentVersion, latest: latestVersion })}`);
|
|
713
|
+
process.exit(0);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
console.log(`[Agent] ${t('updateInstalling', { current: currentVersion, latest: latestVersion })}`);
|
|
717
|
+
|
|
718
|
+
// 停止服务
|
|
719
|
+
const config = readAgentConfig();
|
|
720
|
+
if (await isRunning(config)) {
|
|
721
|
+
try { await fetch(`http://${config.host}:${config.port}/api/shutdown`, { method: 'POST' }); } catch {}
|
|
722
|
+
await waitForExit(config, 5000);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// 执行更新
|
|
726
|
+
let installArgs;
|
|
727
|
+
if (isEmbedded()) {
|
|
728
|
+
// 内嵌模式:更新到 app/ 目录
|
|
729
|
+
const appDir = join(AGENT_DIR, 'app');
|
|
730
|
+
installArgs = ['install', 'ai-helper-agent@latest', ...registryArg, '--no-audit', '--no-fund', '--prefix', appDir];
|
|
731
|
+
} else {
|
|
732
|
+
// npm -g 模式:全局更新
|
|
733
|
+
installArgs = ['install', '-g', 'ai-helper-agent@latest', ...registryArg, '--no-audit', '--no-fund'];
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const installResult = spawnSync(npmPath, installArgs, { stdio: 'inherit', shell: process.platform === 'win32' });
|
|
737
|
+
if (installResult.status !== 0) {
|
|
738
|
+
console.error(`[Agent] ${t('updateFailed')}`);
|
|
739
|
+
process.exit(1);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// 重启
|
|
743
|
+
console.log(`[Agent] ${t('updateSuccess', { version: latestVersion })}`);
|
|
744
|
+
const agentScript = resolve(process.argv[1]);
|
|
745
|
+
spawn(process.execPath, [agentScript, 'start', '-b'], { detached: true, stdio: 'ignore', windowsHide: true }).unref();
|
|
746
|
+
|
|
747
|
+
// ==================== uninstall ====================
|
|
748
|
+
} else if (command === 'uninstall') {
|
|
749
|
+
const isWin = process.platform === 'win32';
|
|
750
|
+
|
|
751
|
+
// 停止服务
|
|
752
|
+
const config = readAgentConfig();
|
|
753
|
+
if (await isRunning(config)) {
|
|
754
|
+
try { await fetch(`http://${config.host}:${config.port}/api/shutdown`, { method: 'POST' }); } catch {}
|
|
755
|
+
await waitForExit(config, 5000);
|
|
756
|
+
}
|
|
757
|
+
const pid = getPidFromFile();
|
|
758
|
+
if (pid) { killByPid(pid); removePidFile(); }
|
|
759
|
+
|
|
760
|
+
// 移除自启
|
|
761
|
+
const { homedir } = await import('os');
|
|
762
|
+
if (!isWin) {
|
|
763
|
+
const plist = join(homedir(), 'Library', 'LaunchAgents', 'com.ai-helper.agent.plist');
|
|
764
|
+
if (existsSync(plist)) {
|
|
765
|
+
spawnSync('launchctl', ['unload', plist], { stdio: 'ignore' });
|
|
766
|
+
try { unlinkSync(plist); } catch {}
|
|
767
|
+
}
|
|
768
|
+
const service = join(homedir(), '.config', 'systemd', 'user', 'ai-helper-agent.service');
|
|
769
|
+
if (existsSync(service)) {
|
|
770
|
+
spawnSync('systemctl', ['--user', 'disable', 'ai-helper-agent'], { stdio: 'ignore' });
|
|
771
|
+
try { unlinkSync(service); } catch {}
|
|
772
|
+
}
|
|
773
|
+
} else {
|
|
774
|
+
spawnSync('schtasks', ['/Delete', '/TN', 'AIHelperAgent', '/F'], { windowsHide: true, stdio: 'ignore' });
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
console.log(`[Agent] ${t('uninstallAutostartRemoved')}`);
|
|
778
|
+
|
|
779
|
+
// 移除 runtime/ app/ bin/ (保留数据)
|
|
780
|
+
const { rmSync } = await import('fs');
|
|
781
|
+
const dirsToRemove = [join(AGENT_DIR, 'runtime'), join(AGENT_DIR, 'app'), join(AGENT_DIR, 'bin')];
|
|
782
|
+
for (const dir of dirsToRemove) {
|
|
783
|
+
try { rmSync(dir, { recursive: true, force: true }); } catch {}
|
|
784
|
+
}
|
|
785
|
+
try { unlinkSync(join(AGENT_DIR, 'INSTALL_MANIFEST.json')); } catch {}
|
|
786
|
+
try { unlinkSync(join(AGENT_DIR, 'mirrors.json')); } catch {}
|
|
787
|
+
try { unlinkSync(join(AGENT_DIR, '.stopped')); } catch {}
|
|
788
|
+
|
|
789
|
+
console.log(`[Agent] ${t('uninstallComplete', { dataDir: AGENT_DIR })}`);
|
|
790
|
+
process.exit(0);
|
|
791
|
+
|
|
792
|
+
// ==================== autostart ====================
|
|
793
|
+
} else if (command === 'autostart') {
|
|
794
|
+
const sub = rawArgs[1]; // 'on' | 'off'
|
|
795
|
+
const isWin = process.platform === 'win32';
|
|
796
|
+
const { homedir } = await import('os');
|
|
797
|
+
|
|
798
|
+
if (sub === 'off') {
|
|
799
|
+
if (!isWin && process.platform === 'darwin') {
|
|
800
|
+
const plist = join(homedir(), 'Library', 'LaunchAgents', 'com.ai-helper.agent.plist');
|
|
801
|
+
spawnSync('launchctl', ['unload', plist], { stdio: 'ignore' });
|
|
802
|
+
try { unlinkSync(plist); } catch {}
|
|
803
|
+
} else if (!isWin) {
|
|
804
|
+
spawnSync('systemctl', ['--user', 'disable', 'ai-helper-agent'], { stdio: 'ignore' });
|
|
805
|
+
const service = join(homedir(), '.config', 'systemd', 'user', 'ai-helper-agent.service');
|
|
806
|
+
try { unlinkSync(service); } catch {}
|
|
807
|
+
} else {
|
|
808
|
+
spawnSync('schtasks', ['/Delete', '/TN', 'AIHelperAgent', '/F'], { windowsHide: true, stdio: 'ignore' });
|
|
809
|
+
}
|
|
810
|
+
console.log(`[Agent] ${t('autostartDisabled')}`);
|
|
811
|
+
} else {
|
|
812
|
+
console.log(`[Agent] ${t('autostartUseScript')}`);
|
|
813
|
+
}
|
|
814
|
+
process.exit(0);
|
|
815
|
+
|
|
816
|
+
// ==================== _autostart-guard (internal, autostart wrapper) ====================
|
|
817
|
+
} else if (command === '_autostart-guard') {
|
|
818
|
+
// 检查 .stopped 标记:用户主动停止后不自启
|
|
819
|
+
const stoppedFile = join(AGENT_DIR, '.stopped');
|
|
820
|
+
if (existsSync(stoppedFile)) {
|
|
821
|
+
process.exit(0);
|
|
822
|
+
}
|
|
823
|
+
// 正常启动
|
|
824
|
+
const agentScript = resolve(process.argv[1]);
|
|
825
|
+
spawn(process.execPath, [agentScript, 'start', '-b'], {
|
|
826
|
+
detached: true, stdio: 'ignore', windowsHide: true
|
|
827
|
+
}).unref();
|
|
828
|
+
process.exit(0);
|
|
829
|
+
|
|
680
830
|
// ==================== rag ====================
|
|
681
831
|
} else if (command === 'rag') {
|
|
682
832
|
// 子命令:status(检测能力)/ install(一键安装 RAG 依赖)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-C0FnF6B9.js";import{a as t,c as n}from"./i18n-
|
|
2
|
-
//# sourceMappingURL=agent-store-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-C0FnF6B9.js";import{a as t,c as n}from"./i18n-MmYITlVj.js";import{_ as r,g as i}from"./session-store-B0ZPGm7d.js";var a=e({createAgent:()=>m,deleteAgent:()=>g,getActiveAgentId:()=>_,getAgent:()=>p,getAllAgents:()=>d,getCustomAgents:()=>f,setActiveAgentId:()=>v,updateAgent:()=>h});t(`zh`,{agentStore:{unnamedAgent:`未命名Agent`}}),t(`en`,{agentStore:{unnamedAgent:`Unnamed Agent`}});var o=`customAgents`,s=`activeAssistantId`,c=`activeAgentId`,l=!1;async function u(){if(l)return;l=!0;let e=await chrome.storage.local.get([c,s]),t=e[c],n=e[s];t&&!n&&!t.startsWith(`pa_`)&&(await chrome.storage.local.set({[s]:t}),await chrome.storage.local.remove(c))}async function d(){let e=(await chrome.storage.local.get([o]))[o]||[];return[...i,...e]}async function f(){return(await chrome.storage.local.get([o]))[o]||[]}async function p(e){return e&&(await d()).find(t=>t.id===e)||null}async function m(e){let t=await f(),i={id:r(),name:e.name||n(`agentStore.unnamedAgent`),description:e.description||``,icon:e.icon||`🤖`,systemPrompt:e.systemPrompt||``,toolIds:e.toolIds||null,skillIds:e.skillIds||null,mcpExcludedServerIds:e.mcpExcludedServerIds??null,isBuiltin:!1,allowSubDispatch:e.allowSubDispatch!==void 0&&e.allowSubDispatch,model:e.model||null,temperature:e.temperature===void 0?null:e.temperature,topP:e.topP===void 0?null:e.topP,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};return t.push(i),await chrome.storage.local.set({[o]:t}),i}async function h(e,t){let n=await f(),r=n.findIndex(t=>t.id===e);return r===-1?null:(n[r]={...n[r],...t,id:e,isBuiltin:!1,updatedAt:new Date().toISOString()},await chrome.storage.local.set({[o]:n}),n[r])}async function g(e){let t=await f(),n=t.findIndex(t=>t.id===e);return n!==-1&&(t.splice(n,1),await chrome.storage.local.set({[o]:t}),(await chrome.storage.local.get([s]))[s]===e&&await chrome.storage.local.remove(s),!0)}async function _(){return await u(),(await chrome.storage.local.get([s]))[s]||null}async function v(e){e?await chrome.storage.local.set({[s]:e}):await chrome.storage.local.remove(s)}export{p as a,h as c,_ as i,m as n,d as o,g as r,v as s,a as t};
|
|
2
|
+
//# sourceMappingURL=agent-store-DOyMdB_7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-store-
|
|
1
|
+
{"version":3,"file":"agent-store-DOyMdB_7.js","names":[],"sources":["../../src/side_panel/agent-store.js"],"sourcesContent":["// side_panel/agent-store.js - Agent 数据持久化\nimport { BUILTIN_AGENTS, generateAgentId } from '../shared/agent-defaults.js';\nimport { t, registerTranslations } from '../shared/i18n.js';\n\nregisterTranslations('zh', {\n agentStore: {\n unnamedAgent: '未命名Agent',\n },\n});\nregisterTranslations('en', {\n agentStore: {\n unnamedAgent: 'Unnamed Agent',\n },\n});\n\nconst STORAGE_KEY = 'customAgents';\nconst ACTIVE_KEY = 'activeAssistantId';\nconst LEGACY_ACTIVE_KEY = 'activeAgentId';\n\nlet migratedActiveKey = false;\n\nasync function migrateLegacyActiveKey() {\n if (migratedActiveKey) return;\n migratedActiveKey = true;\n\n const result = await chrome.storage.local.get([LEGACY_ACTIVE_KEY, ACTIVE_KEY]);\n const legacyValue = result[LEGACY_ACTIVE_KEY];\n const newValue = result[ACTIVE_KEY];\n\n if (legacyValue && !newValue && !legacyValue.startsWith('pa_')) {\n await chrome.storage.local.set({ [ACTIVE_KEY]: legacyValue });\n await chrome.storage.local.remove(LEGACY_ACTIVE_KEY);\n }\n}\n\n/**\n * 获取所有 Agent(内置 + 用户自定义)\n * @returns {Promise<Array>}\n */\nexport async function getAllAgents() {\n const result = await chrome.storage.local.get([STORAGE_KEY]);\n const customAgents = result[STORAGE_KEY] || [];\n return [...BUILTIN_AGENTS, ...customAgents];\n}\n\n/**\n * 仅获取用户自定义的 Agent\n * @returns {Promise<Array>}\n */\nexport async function getCustomAgents() {\n const result = await chrome.storage.local.get([STORAGE_KEY]);\n return result[STORAGE_KEY] || [];\n}\n\n/**\n * 根据 ID 获取单个 Agent\n * @param {string} agentId\n * @returns {Promise<Object|null>}\n */\nexport async function getAgent(agentId) {\n if (!agentId) return null;\n const all = await getAllAgents();\n return all.find(a => a.id === agentId) || null;\n}\n\n/**\n * 创建新的自定义 Agent\n * @param {Object} agentData - 不含 id 的 Agent 数据\n * @returns {Promise<Object>}\n */\nexport async function createAgent(agentData) {\n const agents = await getCustomAgents();\n const newAgent = {\n id: generateAgentId(),\n name: agentData.name || t('agentStore.unnamedAgent'),\n description: agentData.description || '',\n icon: agentData.icon || '🤖',\n systemPrompt: agentData.systemPrompt || '',\n toolIds: agentData.toolIds || null, // null = 继承全局\n skillIds: agentData.skillIds || null, // null = 继承全部启用技能\n mcpExcludedServerIds: agentData.mcpExcludedServerIds ?? null, // MCP 服务排除列表(服务级 deny-list)\n isBuiltin: false,\n allowSubDispatch: agentData.allowSubDispatch !== undefined ? agentData.allowSubDispatch : false,\n model: agentData.model || null,\n temperature: agentData.temperature !== undefined ? agentData.temperature : null,\n topP: agentData.topP !== undefined ? agentData.topP : null,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n agents.push(newAgent);\n await chrome.storage.local.set({ [STORAGE_KEY]: agents });\n return newAgent;\n}\n\n/**\n * 更新已有的自定义 Agent\n * @param {string} agentId\n * @param {Object} updates\n * @returns {Promise<Object|null>}\n */\nexport async function updateAgent(agentId, updates) {\n const agents = await getCustomAgents();\n const idx = agents.findIndex(a => a.id === agentId);\n if (idx === -1) return null;\n \n agents[idx] = {\n ...agents[idx],\n ...updates,\n id: agentId, // id 不可变\n isBuiltin: false, // 不可变\n updatedAt: new Date().toISOString(),\n };\n await chrome.storage.local.set({ [STORAGE_KEY]: agents });\n return agents[idx];\n}\n\n/**\n * 删除自定义 Agent\n * @param {string} agentId\n * @returns {Promise<boolean>}\n */\nexport async function deleteAgent(agentId) {\n const agents = await getCustomAgents();\n const idx = agents.findIndex(a => a.id === agentId);\n if (idx === -1) return false;\n \n agents.splice(idx, 1);\n await chrome.storage.local.set({ [STORAGE_KEY]: agents });\n\n // 如果删除的 Agent 是当前选中的,重置为默认\n const result = await chrome.storage.local.get([ACTIVE_KEY]);\n if (result[ACTIVE_KEY] === agentId) {\n await chrome.storage.local.remove(ACTIVE_KEY);\n }\n \n return true;\n}\n\n/**\n * 获取当前选中的 Agent ID\n * @returns {Promise<string|null>}\n */\nexport async function getActiveAgentId() {\n await migrateLegacyActiveKey();\n const result = await chrome.storage.local.get([ACTIVE_KEY]);\n return result[ACTIVE_KEY] || null;\n}\n\n/**\n * 设置当前选中的 Agent ID\n * @param {string|null} agentId\n */\nexport async function setActiveAgentId(agentId) {\n if (agentId) {\n await chrome.storage.local.set({ [ACTIVE_KEY]: agentId });\n } else {\n await chrome.storage.local.remove(ACTIVE_KEY);\n }\n}\n\n/**\n * 从模板创建 Agent\n * @param {Object} template\n * @returns {Promise<Object>}\n */\nexport async function createAgentFromTemplate(template) {\n return createAgent({\n name: template.name,\n icon: template.icon,\n description: template.description,\n systemPrompt: template.systemPrompt,\n toolIds: template.toolIds ? [...template.toolIds] : null,\n allowSubDispatch: template.allowSubDispatch || false,\n });\n}\n"],"mappings":"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"}
|