opc-agent 3.0.1 → 4.0.1

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.
Files changed (216) hide show
  1. package/README.md +404 -74
  2. package/README.zh-CN.md +82 -0
  3. package/dist/channels/dingtalk.d.ts +17 -0
  4. package/dist/channels/dingtalk.js +38 -0
  5. package/dist/channels/googlechat.d.ts +14 -0
  6. package/dist/channels/googlechat.js +37 -0
  7. package/dist/channels/imessage.d.ts +13 -0
  8. package/dist/channels/imessage.js +28 -0
  9. package/dist/channels/irc.d.ts +20 -0
  10. package/dist/channels/irc.js +71 -0
  11. package/dist/channels/line.d.ts +14 -0
  12. package/dist/channels/line.js +28 -0
  13. package/dist/channels/matrix.d.ts +15 -0
  14. package/dist/channels/matrix.js +28 -0
  15. package/dist/channels/mattermost.d.ts +18 -0
  16. package/dist/channels/mattermost.js +49 -0
  17. package/dist/channels/msteams.d.ts +14 -0
  18. package/dist/channels/msteams.js +28 -0
  19. package/dist/channels/nostr.d.ts +14 -0
  20. package/dist/channels/nostr.js +28 -0
  21. package/dist/channels/qq.d.ts +15 -0
  22. package/dist/channels/qq.js +28 -0
  23. package/dist/channels/signal.d.ts +14 -0
  24. package/dist/channels/signal.js +28 -0
  25. package/dist/channels/sms.d.ts +15 -0
  26. package/dist/channels/sms.js +28 -0
  27. package/dist/channels/twitch.d.ts +17 -0
  28. package/dist/channels/twitch.js +59 -0
  29. package/dist/channels/voice-call.d.ts +27 -0
  30. package/dist/channels/voice-call.js +82 -0
  31. package/dist/channels/whatsapp.d.ts +14 -0
  32. package/dist/channels/whatsapp.js +28 -0
  33. package/dist/cli/chat.d.ts +2 -0
  34. package/dist/cli/chat.js +134 -0
  35. package/dist/cli/setup.d.ts +4 -0
  36. package/dist/cli/setup.js +303 -0
  37. package/dist/cli.js +142 -6
  38. package/dist/core/api-server.d.ts +25 -0
  39. package/dist/core/api-server.js +286 -0
  40. package/dist/core/audio.d.ts +50 -0
  41. package/dist/core/audio.js +68 -0
  42. package/dist/core/context-discovery.d.ts +16 -0
  43. package/dist/core/context-discovery.js +107 -0
  44. package/dist/core/context-refs.d.ts +29 -0
  45. package/dist/core/context-refs.js +162 -0
  46. package/dist/core/gateway.d.ts +53 -0
  47. package/dist/core/gateway.js +80 -0
  48. package/dist/core/heartbeat.d.ts +19 -0
  49. package/dist/core/heartbeat.js +50 -0
  50. package/dist/core/hooks.d.ts +28 -0
  51. package/dist/core/hooks.js +82 -0
  52. package/dist/core/ide-bridge.d.ts +53 -0
  53. package/dist/core/ide-bridge.js +97 -0
  54. package/dist/core/node-network.d.ts +23 -0
  55. package/dist/core/node-network.js +77 -0
  56. package/dist/core/profiles.d.ts +27 -0
  57. package/dist/core/profiles.js +131 -0
  58. package/dist/core/sandbox.d.ts +25 -0
  59. package/dist/core/sandbox.js +84 -1
  60. package/dist/core/session-manager.d.ts +33 -0
  61. package/dist/core/session-manager.js +157 -0
  62. package/dist/core/vision.d.ts +45 -0
  63. package/dist/core/vision.js +177 -0
  64. package/dist/hub/brain-seed.d.ts +14 -0
  65. package/dist/hub/brain-seed.js +77 -0
  66. package/dist/hub/client.d.ts +25 -0
  67. package/dist/hub/client.js +44 -0
  68. package/dist/index.d.ts +66 -1
  69. package/dist/index.js +95 -3
  70. package/dist/memory/context-compressor.d.ts +43 -0
  71. package/dist/memory/context-compressor.js +167 -0
  72. package/dist/memory/index.d.ts +4 -0
  73. package/dist/memory/index.js +5 -1
  74. package/dist/memory/user-profiler.d.ts +50 -0
  75. package/dist/memory/user-profiler.js +201 -0
  76. package/dist/providers/index.d.ts +1 -1
  77. package/dist/providers/index.js +54 -1
  78. package/dist/scheduler/cron-engine.d.ts +41 -0
  79. package/dist/scheduler/cron-engine.js +200 -0
  80. package/dist/scheduler/index.d.ts +3 -0
  81. package/dist/scheduler/index.js +7 -0
  82. package/dist/schema/oad.d.ts +12 -12
  83. package/dist/security/approvals.d.ts +53 -0
  84. package/dist/security/approvals.js +115 -0
  85. package/dist/security/elevated.d.ts +41 -0
  86. package/dist/security/elevated.js +89 -0
  87. package/dist/security/index.d.ts +6 -0
  88. package/dist/security/index.js +7 -1
  89. package/dist/security/secrets.d.ts +34 -0
  90. package/dist/security/secrets.js +115 -0
  91. package/dist/skills/builtin/index.d.ts +6 -0
  92. package/dist/skills/builtin/index.js +402 -0
  93. package/dist/skills/marketplace.d.ts +30 -0
  94. package/dist/skills/marketplace.js +142 -0
  95. package/dist/skills/types.d.ts +34 -0
  96. package/dist/skills/types.js +16 -0
  97. package/dist/studio/server.d.ts +25 -0
  98. package/dist/studio/server.js +780 -0
  99. package/dist/studio/templates-data.d.ts +21 -0
  100. package/dist/studio/templates-data.js +148 -0
  101. package/dist/studio-ui/index.html +2502 -1073
  102. package/dist/tools/builtin/browser.d.ts +47 -0
  103. package/dist/tools/builtin/browser.js +284 -0
  104. package/dist/tools/builtin/home-assistant.d.ts +12 -0
  105. package/dist/tools/builtin/home-assistant.js +126 -0
  106. package/dist/tools/builtin/index.d.ts +7 -1
  107. package/dist/tools/builtin/index.js +23 -2
  108. package/dist/tools/builtin/rl-tools.d.ts +13 -0
  109. package/dist/tools/builtin/rl-tools.js +228 -0
  110. package/dist/tools/builtin/vision.d.ts +6 -0
  111. package/dist/tools/builtin/vision.js +61 -0
  112. package/dist/tools/builtin/web-search.d.ts +9 -0
  113. package/dist/tools/builtin/web-search.js +150 -0
  114. package/dist/tools/document-processor.d.ts +39 -0
  115. package/dist/tools/document-processor.js +188 -0
  116. package/dist/tools/image-generator.d.ts +42 -0
  117. package/dist/tools/image-generator.js +136 -0
  118. package/dist/tools/web-scraper.d.ts +20 -0
  119. package/dist/tools/web-scraper.js +148 -0
  120. package/dist/tools/web-search.d.ts +51 -0
  121. package/dist/tools/web-search.js +152 -0
  122. package/install.ps1 +154 -0
  123. package/install.sh +164 -0
  124. package/package.json +63 -52
  125. package/src/channels/dingtalk.ts +46 -0
  126. package/src/channels/googlechat.ts +42 -0
  127. package/src/channels/imessage.ts +32 -0
  128. package/src/channels/irc.ts +82 -0
  129. package/src/channels/line.ts +33 -0
  130. package/src/channels/matrix.ts +34 -0
  131. package/src/channels/mattermost.ts +57 -0
  132. package/src/channels/msteams.ts +33 -0
  133. package/src/channels/nostr.ts +33 -0
  134. package/src/channels/qq.ts +34 -0
  135. package/src/channels/signal.ts +33 -0
  136. package/src/channels/sms.ts +34 -0
  137. package/src/channels/twitch.ts +65 -0
  138. package/src/channels/voice-call.ts +100 -0
  139. package/src/channels/whatsapp.ts +33 -0
  140. package/src/cli/chat.ts +99 -0
  141. package/src/cli/setup.ts +314 -0
  142. package/src/cli.ts +148 -6
  143. package/src/core/api-server.ts +277 -0
  144. package/src/core/audio.ts +98 -0
  145. package/src/core/context-discovery.ts +85 -0
  146. package/src/core/context-refs.ts +140 -0
  147. package/src/core/gateway.ts +106 -0
  148. package/src/core/heartbeat.ts +51 -0
  149. package/src/core/hooks.ts +105 -0
  150. package/src/core/ide-bridge.ts +133 -0
  151. package/src/core/node-network.ts +86 -0
  152. package/src/core/profiles.ts +122 -0
  153. package/src/core/sandbox.ts +100 -0
  154. package/src/core/session-manager.ts +137 -0
  155. package/src/core/vision.ts +180 -0
  156. package/src/hub/brain-seed.ts +54 -0
  157. package/src/hub/client.ts +60 -0
  158. package/src/index.ts +86 -1
  159. package/src/memory/context-compressor.ts +189 -0
  160. package/src/memory/index.ts +4 -0
  161. package/src/memory/user-profiler.ts +215 -0
  162. package/src/providers/index.ts +64 -1
  163. package/src/scheduler/cron-engine.ts +191 -0
  164. package/src/scheduler/index.ts +2 -0
  165. package/src/security/approvals.ts +143 -0
  166. package/src/security/elevated.ts +105 -0
  167. package/src/security/index.ts +6 -0
  168. package/src/security/secrets.ts +129 -0
  169. package/src/skills/builtin/index.ts +408 -0
  170. package/src/skills/marketplace.ts +113 -0
  171. package/src/skills/types.ts +42 -0
  172. package/src/studio/server.ts +1591 -791
  173. package/src/studio/templates-data.ts +178 -0
  174. package/src/studio-ui/index.html +2502 -1073
  175. package/src/tools/builtin/browser.ts +299 -0
  176. package/src/tools/builtin/home-assistant.ts +116 -0
  177. package/src/tools/builtin/index.ts +37 -28
  178. package/src/tools/builtin/rl-tools.ts +243 -0
  179. package/src/tools/builtin/vision.ts +64 -0
  180. package/src/tools/builtin/web-search.ts +126 -0
  181. package/src/tools/document-processor.ts +213 -0
  182. package/src/tools/image-generator.ts +150 -0
  183. package/src/tools/web-scraper.ts +179 -0
  184. package/src/tools/web-search.ts +180 -0
  185. package/tests/api-server.test.ts +148 -0
  186. package/tests/approvals.test.ts +89 -0
  187. package/tests/audio.test.ts +40 -0
  188. package/tests/browser.test.ts +179 -0
  189. package/tests/builtin-tools.test.ts +83 -83
  190. package/tests/channels-extra.test.ts +45 -0
  191. package/tests/context-compressor.test.ts +172 -0
  192. package/tests/context-refs.test.ts +121 -0
  193. package/tests/cron-engine.test.ts +101 -0
  194. package/tests/document-processor.test.ts +69 -0
  195. package/tests/e2e-nocode.test.ts +442 -0
  196. package/tests/elevated.test.ts +69 -0
  197. package/tests/gateway.test.ts +63 -71
  198. package/tests/home-assistant.test.ts +40 -0
  199. package/tests/hooks.test.ts +79 -0
  200. package/tests/ide-bridge.test.ts +38 -0
  201. package/tests/image-generator.test.ts +84 -0
  202. package/tests/node-network.test.ts +74 -0
  203. package/tests/profiles.test.ts +61 -0
  204. package/tests/rl-tools.test.ts +93 -0
  205. package/tests/sandbox-manager.test.ts +46 -0
  206. package/tests/secrets.test.ts +107 -0
  207. package/tests/settings-api.test.ts +148 -0
  208. package/tests/setup.test.ts +73 -0
  209. package/tests/studio.test.ts +402 -229
  210. package/tests/tools/builtin-extended.test.ts +138 -138
  211. package/tests/user-profiler.test.ts +169 -0
  212. package/tests/v090-features.test.ts +254 -0
  213. package/tests/vision.test.ts +61 -0
  214. package/tests/voice-call.test.ts +47 -0
  215. package/tests/voice-interaction.test.ts +38 -0
  216. package/tests/web-search.test.ts +155 -0
package/install.ps1 ADDED
@@ -0,0 +1,154 @@
1
+ # ============================================================================
2
+ # OPC Agent 一键安装脚本 for Windows
3
+ # 用法: irm https://raw.githubusercontent.com/Deepleaper/opc-agent/main/install.ps1 | iex
4
+ # 高级: $env:OPC_YES='1'; $env:OPC_NO_OLLAMA='1'; irm ... | iex
5
+ # ============================================================================
6
+
7
+ $ErrorActionPreference = "Stop"
8
+
9
+ # ── 颜色输出 ──────────────────────────────────────────────────
10
+ function Write-Step($msg) { Write-Host "`n━━━ $msg ━━━" -ForegroundColor Blue }
11
+ function Write-Ok($msg) { Write-Host "✅ $msg" -ForegroundColor Green }
12
+ function Write-Warn($msg) { Write-Host "⚠️ $msg" -ForegroundColor Yellow }
13
+ function Write-Err($msg) { Write-Host "❌ $msg" -ForegroundColor Red }
14
+ function Write-Info($msg) { Write-Host "ℹ️ $msg" -ForegroundColor Cyan }
15
+
16
+ $AutoYes = $env:OPC_YES -eq '1'
17
+ $SkipOllama = $env:OPC_NO_OLLAMA -eq '1'
18
+
19
+ function Confirm-Action($prompt) {
20
+ if ($AutoYes) { return $true }
21
+ $choice = Read-Host "❓ $prompt [Y/n]"
22
+ return ($choice -ne 'n' -and $choice -ne 'N' -and $choice -ne 'no')
23
+ }
24
+
25
+ # ── 检测操作系统 ──────────────────────────────────────────────
26
+ Write-Step "🔍 检测操作系统 / Detecting OS"
27
+ Write-Ok "Windows $([System.Environment]::OSVersion.Version) detected"
28
+
29
+ # ── 检测 & 安装 Node.js ──────────────────────────────────────
30
+ Write-Step "📦 检测 Node.js / Checking Node.js"
31
+ $NeedNode = $false
32
+
33
+ try {
34
+ $nodeVer = (node -v) -replace 'v','' -split '\.' | Select-Object -First 1
35
+ if ([int]$nodeVer -ge 18) {
36
+ Write-Ok "Node.js $(node -v) 已安装 / installed"
37
+ } else {
38
+ Write-Warn "Node.js $(node -v) 版本过低,需要 18+ / version too old"
39
+ $NeedNode = $true
40
+ }
41
+ } catch {
42
+ Write-Warn "未检测到 Node.js / Node.js not found"
43
+ $NeedNode = $true
44
+ }
45
+
46
+ if ($NeedNode) {
47
+ Write-Info "将安装 Node.js 22 LTS / Installing Node.js 22 LTS"
48
+ if (Confirm-Action "安装 Node.js 22? / Install Node.js 22?") {
49
+ $installed = $false
50
+ # 尝试 winget
51
+ try {
52
+ winget install OpenJS.NodeJS.LTS --accept-package-agreements --accept-source-agreements
53
+ $installed = $true
54
+ Write-Ok "Node.js 通过 winget 安装成功 / installed via winget"
55
+ } catch {}
56
+
57
+ # 尝试 choco
58
+ if (-not $installed) {
59
+ try {
60
+ choco install nodejs-lts -y
61
+ $installed = $true
62
+ Write-Ok "Node.js 通过 Chocolatey 安装成功 / installed via Chocolatey"
63
+ } catch {}
64
+ }
65
+
66
+ if (-not $installed) {
67
+ Write-Err "自动安装失败 / Auto-install failed"
68
+ Write-Info "请手动下载安装 / Please download manually: https://nodejs.org/"
69
+ Start-Process "https://nodejs.org/en/download/"
70
+ exit 1
71
+ }
72
+
73
+ # 刷新 PATH
74
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
75
+ } else {
76
+ Write-Err "Node.js 是必需的 / Node.js is required"
77
+ Write-Info "下载地址 / Download: https://nodejs.org/"
78
+ exit 1
79
+ }
80
+ }
81
+
82
+ # ── 安装 OPC Agent ────────────────────────────────────────────
83
+ Write-Step "🚀 安装 OPC Agent / Installing OPC Agent"
84
+ Write-Info "npm install -g opc-agent ..."
85
+ npm install -g opc-agent
86
+ Write-Ok "OPC Agent 安装成功 / installed"
87
+
88
+ # ── Ollama(可选)─────────────────────────────────────────────
89
+ if (-not $SkipOllama) {
90
+ Write-Step "🦙 检测 Ollama / Checking Ollama"
91
+
92
+ $hasOllama = $false
93
+ try { ollama --version 2>$null; $hasOllama = $true } catch {}
94
+
95
+ if ($hasOllama) {
96
+ Write-Ok "Ollama 已安装 / installed"
97
+ } else {
98
+ Write-Warn "未检测到 Ollama / Ollama not found"
99
+ Write-Info "Ollama 可让你在本地运行 AI 模型(免费、数据不出门)"
100
+ Write-Info "Ollama lets you run AI models locally (free, private)"
101
+
102
+ if (Confirm-Action "安装 Ollama? / Install Ollama?") {
103
+ try {
104
+ winget install Ollama.Ollama --accept-package-agreements --accept-source-agreements
105
+ $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
106
+ Write-Ok "Ollama 安装成功 / installed"
107
+ $hasOllama = $true
108
+ } catch {
109
+ Write-Warn "winget 安装失败,请手动下载 / Please download manually: https://ollama.com/download"
110
+ Start-Process "https://ollama.com/download"
111
+ }
112
+ }
113
+ }
114
+
115
+ # 拉取推荐模型
116
+ if ($hasOllama) {
117
+ Write-Step "🧠 推荐模型 / Recommended Models"
118
+ Write-Info "推荐拉取以下模型用于本地 Agent:"
119
+ Write-Info " • qwen2.5:7b — 中英文对话(4.7GB)"
120
+ Write-Info " • nomic-embed-text — 文本向量化(274MB)"
121
+
122
+ if (Confirm-Action "拉取推荐模型? / Pull recommended models?") {
123
+ Write-Info "拉取 qwen2.5:7b ... (可能需要几分钟)"
124
+ try { ollama pull qwen2.5:7b; Write-Ok "qwen2.5:7b ✓" } catch { Write-Warn "拉取失败,可稍后手动: ollama pull qwen2.5:7b" }
125
+
126
+ Write-Info "拉取 nomic-embed-text ..."
127
+ try { ollama pull nomic-embed-text; Write-Ok "nomic-embed-text ✓" } catch { Write-Warn "拉取失败,可稍后手动: ollama pull nomic-embed-text" }
128
+ }
129
+ }
130
+ }
131
+
132
+ # ── 完成 ──────────────────────────────────────────────────────
133
+ Write-Step "🎉 安装完成!/ Installation Complete!"
134
+ Write-Host ""
135
+ Write-Host "┌─────────────────────────────────────────────────┐" -ForegroundColor Green
136
+ Write-Host "│ OPC Agent 已安装成功! │" -ForegroundColor Green
137
+ Write-Host "│ OPC Agent installed successfully! │" -ForegroundColor Green
138
+ Write-Host "│ │" -ForegroundColor Green
139
+ Write-Host "│ 快速开始 / Quick Start: │" -ForegroundColor Green
140
+ Write-Host "│ opc init my-agent # 创建 Agent │" -ForegroundColor Green
141
+ Write-Host "│ cd my-agent; npm i │" -ForegroundColor Green
142
+ Write-Host "│ opc chat # 开始对话 │" -ForegroundColor Green
143
+ Write-Host "│ │" -ForegroundColor Green
144
+ Write-Host "│ 可视化面板 / Dashboard: │" -ForegroundColor Green
145
+ Write-Host "│ opc studio │" -ForegroundColor Green
146
+ Write-Host "│ │" -ForegroundColor Green
147
+ Write-Host "│ 交互式设置 / Setup wizard: │" -ForegroundColor Green
148
+ Write-Host "│ opc setup │" -ForegroundColor Green
149
+ Write-Host "└─────────────────────────────────────────────────┘" -ForegroundColor Green
150
+ Write-Host ""
151
+
152
+ if (Confirm-Action "现在打开 OPC Studio? / Open OPC Studio now?") {
153
+ opc studio
154
+ }
package/install.sh ADDED
@@ -0,0 +1,164 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # OPC Agent 一键安装脚本 (macOS / Linux / WSL)
4
+ # 用法: curl -fsSL https://raw.githubusercontent.com/Deepleaper/opc-agent/main/install.sh | bash
5
+ # 高级: curl -fsSL ... | bash -s -- --yes --no-ollama
6
+ # ============================================================================
7
+
8
+ set -e
9
+
10
+ # ── 颜色 & Emoji ──────────────────────────────────────────────
11
+ RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; CYAN='\033[0;36m'; NC='\033[0m'
12
+ info() { echo -e "${CYAN}ℹ️ $1${NC}"; }
13
+ ok() { echo -e "${GREEN}✅ $1${NC}"; }
14
+ warn() { echo -e "${YELLOW}⚠️ $1${NC}"; }
15
+ err() { echo -e "${RED}❌ $1${NC}"; }
16
+ step() { echo -e "\n${BLUE}━━━ $1 ━━━${NC}"; }
17
+
18
+ # ── 参数解析 ──────────────────────────────────────────────────
19
+ AUTO_YES=false
20
+ SKIP_OLLAMA=false
21
+ for arg in "$@"; do
22
+ case "$arg" in
23
+ --yes|-y) AUTO_YES=true ;;
24
+ --no-ollama) SKIP_OLLAMA=true ;;
25
+ esac
26
+ done
27
+
28
+ confirm() {
29
+ if $AUTO_YES; then return 0; fi
30
+ read -r -p "$(echo -e "${YELLOW}❓ $1 [Y/n]: ${NC}")" choice
31
+ case "$choice" in n|N|no|NO) return 1 ;; *) return 0 ;; esac
32
+ }
33
+
34
+ # ── 检测操作系统 ──────────────────────────────────────────────
35
+ step "🔍 检测操作系统 / Detecting OS"
36
+ OS="unknown"
37
+ if [[ "$OSTYPE" == "darwin"* ]]; then
38
+ OS="macos"
39
+ ok "macOS detected"
40
+ elif grep -qi microsoft /proc/version 2>/dev/null; then
41
+ OS="wsl"
42
+ ok "WSL (Windows Subsystem for Linux) detected"
43
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
44
+ OS="linux"
45
+ ok "Linux detected"
46
+ else
47
+ err "不支持的操作系统 / Unsupported OS: $OSTYPE"
48
+ exit 1
49
+ fi
50
+
51
+ # ── 检测 & 安装 Node.js ──────────────────────────────────────
52
+ step "📦 检测 Node.js / Checking Node.js"
53
+ NEED_NODE=false
54
+
55
+ if command -v node &>/dev/null; then
56
+ NODE_VER=$(node -v | sed 's/v//' | cut -d. -f1)
57
+ if [ "$NODE_VER" -ge 18 ]; then
58
+ ok "Node.js $(node -v) 已安装 / installed"
59
+ else
60
+ warn "Node.js $(node -v) 版本过低,需要 18+ / version too old, need 18+"
61
+ NEED_NODE=true
62
+ fi
63
+ else
64
+ warn "未检测到 Node.js / Node.js not found"
65
+ NEED_NODE=true
66
+ fi
67
+
68
+ if $NEED_NODE; then
69
+ info "将通过 nvm 安装 Node.js 22 LTS / Installing Node.js 22 via nvm"
70
+ if confirm "安装 Node.js 22? / Install Node.js 22?"; then
71
+ if command -v nvm &>/dev/null || [ -s "$HOME/.nvm/nvm.sh" ]; then
72
+ [ -s "$HOME/.nvm/nvm.sh" ] && . "$HOME/.nvm/nvm.sh"
73
+ info "nvm 已存在,安装 Node 22... / nvm found, installing Node 22..."
74
+ else
75
+ info "安装 nvm... / Installing nvm..."
76
+ curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
77
+ export NVM_DIR="$HOME/.nvm"
78
+ [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
79
+ fi
80
+ nvm install 22
81
+ nvm use 22
82
+ ok "Node.js $(node -v) 安装成功 / installed successfully"
83
+ else
84
+ err "Node.js 是必需的 / Node.js is required"
85
+ echo "手动安装 / Manual install: https://nodejs.org/"
86
+ exit 1
87
+ fi
88
+ fi
89
+
90
+ # ── 安装 OPC Agent ────────────────────────────────────────────
91
+ step "🚀 安装 OPC Agent / Installing OPC Agent"
92
+ info "npm install -g opc-agent ..."
93
+ npm install -g opc-agent
94
+ ok "OPC Agent $(opc --version 2>/dev/null || echo '') 安装成功 / installed"
95
+
96
+ # ── Ollama(可选)─────────────────────────────────────────────
97
+ if ! $SKIP_OLLAMA; then
98
+ step "🦙 检测 Ollama / Checking Ollama"
99
+
100
+ if command -v ollama &>/dev/null; then
101
+ ok "Ollama 已安装 / installed ($(ollama --version 2>/dev/null || echo 'ok'))"
102
+ else
103
+ warn "未检测到 Ollama / Ollama not found"
104
+ info "Ollama 可让你在本地运行 AI 模型(免费、数据不出门)"
105
+ info "Ollama lets you run AI models locally (free, private)"
106
+
107
+ if confirm "安装 Ollama? / Install Ollama?"; then
108
+ if [ "$OS" = "macos" ]; then
109
+ if command -v brew &>/dev/null; then
110
+ brew install ollama
111
+ else
112
+ info "请从 https://ollama.com/download 下载安装"
113
+ info "Download from https://ollama.com/download"
114
+ open "https://ollama.com/download" 2>/dev/null || true
115
+ fi
116
+ else
117
+ curl -fsSL https://ollama.com/install.sh | sh
118
+ fi
119
+ ok "Ollama 安装成功 / installed"
120
+ else
121
+ info "跳过 Ollama / Skipping Ollama"
122
+ fi
123
+ fi
124
+
125
+ # 拉取推荐模型
126
+ if command -v ollama &>/dev/null; then
127
+ step "🧠 推荐模型 / Recommended Models"
128
+ info "推荐拉取以下模型用于本地 Agent:"
129
+ info " • qwen2.5:7b — 中英文对话(4.7GB)"
130
+ info " • nomic-embed-text — 文本向量化(274MB)"
131
+
132
+ if confirm "拉取推荐模型? / Pull recommended models?"; then
133
+ info "拉取 qwen2.5:7b ... (可能需要几分钟)"
134
+ ollama pull qwen2.5:7b && ok "qwen2.5:7b ✓" || warn "qwen2.5:7b 拉取失败,可稍后手动: ollama pull qwen2.5:7b"
135
+
136
+ info "拉取 nomic-embed-text ..."
137
+ ollama pull nomic-embed-text && ok "nomic-embed-text ✓" || warn "拉取失败,可稍后手动: ollama pull nomic-embed-text"
138
+ fi
139
+ fi
140
+ fi
141
+
142
+ # ── 启动 Studio ───────────────────────────────────────────────
143
+ step "🎉 安装完成!/ Installation Complete!"
144
+ echo ""
145
+ echo -e "${GREEN}┌─────────────────────────────────────────────────┐${NC}"
146
+ echo -e "${GREEN}│ OPC Agent 已安装成功! │${NC}"
147
+ echo -e "${GREEN}│ OPC Agent installed successfully! │${NC}"
148
+ echo -e "${GREEN}│ │${NC}"
149
+ echo -e "${GREEN}│ 快速开始 / Quick Start: │${NC}"
150
+ echo -e "${GREEN}│ opc init my-agent # 创建 Agent │${NC}"
151
+ echo -e "${GREEN}│ cd my-agent && npm i │${NC}"
152
+ echo -e "${GREEN}│ opc chat # 开始对话 │${NC}"
153
+ echo -e "${GREEN}│ │${NC}"
154
+ echo -e "${GREEN}│ 可视化面板 / Dashboard: │${NC}"
155
+ echo -e "${GREEN}│ opc studio │${NC}"
156
+ echo -e "${GREEN}│ │${NC}"
157
+ echo -e "${GREEN}│ 交互式设置 / Setup wizard: │${NC}"
158
+ echo -e "${GREEN}│ opc setup │${NC}"
159
+ echo -e "${GREEN}└─────────────────────────────────────────────────┘${NC}"
160
+ echo ""
161
+
162
+ if confirm "现在打开 OPC Studio? / Open OPC Studio now?"; then
163
+ opc studio
164
+ fi
package/package.json CHANGED
@@ -1,52 +1,63 @@
1
- {
2
- "name": "opc-agent",
3
- "version": "3.0.1",
4
- "description": "Open Agent Framework — Build, test, and run AI Agents for business workstations",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "bin": {
8
- "opc": "dist/cli.js"
9
- },
10
- "scripts": {
11
- "build": "tsc",
12
- "postbuild": "xcopy /E /I /Y src\\studio-ui dist\\studio-ui",
13
- "test": "vitest run",
14
- "dev": "tsc --watch",
15
- "lint": "tsc --noEmit",
16
- "docs:dev": "vitepress dev docs",
17
- "docs:build": "vitepress build docs",
18
- "docs:preview": "vitepress preview docs"
19
- },
20
- "keywords": [
21
- "agent",
22
- "ai",
23
- "llm",
24
- "framework",
25
- "typescript",
26
- "agent-framework"
27
- ],
28
- "author": "Deepleaper",
29
- "license": "Apache-2.0",
30
- "repository": {
31
- "type": "git",
32
- "url": "https://github.com/Deepleaper/opc-agent.git"
33
- },
34
- "dependencies": {
35
- "agent-workstation": "^2.0.1",
36
- "agentkits": "^1.10.2",
37
- "commander": "^12.0.0",
38
- "express": "^4.21.0",
39
- "js-yaml": "^4.1.0",
40
- "ws": "^8.20.0",
41
- "zod": "^3.23.0"
42
- },
43
- "devDependencies": {
44
- "@types/express": "^4.17.21",
45
- "@types/js-yaml": "^4.0.9",
46
- "@types/node": "^20.11.0",
47
- "@types/ws": "^8.18.1",
48
- "typescript": "^5.5.0",
49
- "vitepress": "^1.5.0",
50
- "vitest": "^2.0.0"
51
- }
52
- }
1
+ {
2
+ "name": "opc-agent",
3
+ "version": "4.0.1",
4
+ "description": "Open Agent Framework — Build, test, and run AI Agents for business workstations",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "opc": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "postbuild": "xcopy /E /I /Y src\\studio-ui dist\\studio-ui",
13
+ "test": "vitest run",
14
+ "dev": "tsc --watch",
15
+ "lint": "tsc --noEmit",
16
+ "setup": "opc setup",
17
+ "docs:dev": "vitepress dev docs",
18
+ "docs:build": "vitepress build docs",
19
+ "docs:preview": "vitepress preview docs"
20
+ },
21
+ "keywords": [
22
+ "agent",
23
+ "ai",
24
+ "llm",
25
+ "framework",
26
+ "typescript",
27
+ "agent-framework"
28
+ ],
29
+ "author": "Deepleaper",
30
+ "license": "Apache-2.0",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/Deepleaper/opc-agent.git"
34
+ },
35
+ "dependencies": {
36
+ "agent-workstation": "^2.0.1",
37
+ "agentkits": "^2.0.0",
38
+ "commander": "^12.0.0",
39
+ "express": "^4.21.0",
40
+ "js-yaml": "^4.1.0",
41
+ "mammoth": "^1.12.0",
42
+ "pdf-parse": "^1.1.4",
43
+ "ws": "^8.20.0",
44
+ "zod": "^3.23.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/express": "^4.17.21",
48
+ "@types/js-yaml": "^4.0.9",
49
+ "@types/node": "^20.11.0",
50
+ "@types/ws": "^8.18.1",
51
+ "typescript": "^5.5.0",
52
+ "vitepress": "^1.5.0",
53
+ "vitest": "^2.0.0"
54
+ },
55
+ "peerDependencies": {
56
+ "deepbrain": "^2.0.0"
57
+ },
58
+ "peerDependenciesMeta": {
59
+ "deepbrain": {
60
+ "optional": true
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,46 @@
1
+ import { BaseChannel } from './index';
2
+ import type { Message } from '../core/types';
3
+
4
+ export interface DingTalkChannelConfig {
5
+ webhookUrl: string;
6
+ secret?: string;
7
+ appKey?: string;
8
+ appSecret?: string;
9
+ }
10
+
11
+ export class DingTalkChannel extends BaseChannel {
12
+ readonly type = 'dingtalk';
13
+ private config: DingTalkChannelConfig;
14
+ private running = false;
15
+
16
+ constructor(config: DingTalkChannelConfig) {
17
+ super();
18
+ if (!config.webhookUrl) {
19
+ throw new Error('DingTalkChannel requires webhookUrl in config');
20
+ }
21
+ this.config = config;
22
+ }
23
+
24
+ async start(): Promise<void> {
25
+ this.running = true;
26
+ }
27
+
28
+ async stop(): Promise<void> {
29
+ this.running = false;
30
+ }
31
+
32
+ async send(chatId: string, text: string): Promise<void> {
33
+ if (!this.running) {
34
+ throw new Error('DingTalkChannel: not started. Call start() first.');
35
+ }
36
+ const body = JSON.stringify({ msgtype: 'text', text: { content: text } });
37
+ const res = await fetch(this.config.webhookUrl, {
38
+ method: 'POST',
39
+ headers: { 'Content-Type': 'application/json' },
40
+ body,
41
+ });
42
+ if (!res.ok) {
43
+ throw new Error(`DingTalk webhook failed: ${res.status}`);
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,42 @@
1
+ import { BaseChannel } from './index';
2
+ import type { Message } from '../core/types';
3
+
4
+ export interface GoogleChatChannelConfig {
5
+ webhookUrl: string;
6
+ }
7
+
8
+ export class GoogleChatChannel extends BaseChannel {
9
+ readonly type = 'googlechat';
10
+ private config: GoogleChatChannelConfig;
11
+ private running = false;
12
+
13
+ constructor(config: GoogleChatChannelConfig) {
14
+ super();
15
+ if (!config.webhookUrl) {
16
+ throw new Error('GoogleChatChannel requires webhookUrl in config');
17
+ }
18
+ this.config = config;
19
+ }
20
+
21
+ async start(): Promise<void> {
22
+ this.running = true;
23
+ }
24
+
25
+ async stop(): Promise<void> {
26
+ this.running = false;
27
+ }
28
+
29
+ async send(spaceId: string, text: string): Promise<void> {
30
+ if (!this.running) {
31
+ throw new Error('GoogleChatChannel: not started. Call start() first.');
32
+ }
33
+ const res = await fetch(this.config.webhookUrl, {
34
+ method: 'POST',
35
+ headers: { 'Content-Type': 'application/json' },
36
+ body: JSON.stringify({ text }),
37
+ });
38
+ if (!res.ok) {
39
+ throw new Error(`Google Chat webhook failed: ${res.status}`);
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,32 @@
1
+ import { BaseChannel } from './index';
2
+ import type { Message } from '../core/types';
3
+
4
+ export interface IMessageChannelConfig {
5
+ applescriptPath?: string;
6
+ }
7
+
8
+ export class IMessageChannel extends BaseChannel {
9
+ readonly type = 'imessage';
10
+ private config: IMessageChannelConfig;
11
+
12
+ constructor(config: IMessageChannelConfig = {}) {
13
+ super();
14
+ this.config = config;
15
+ }
16
+
17
+ async start(): Promise<void> {
18
+ try {
19
+ require('macOS iMessage CLI');
20
+ } catch {
21
+ throw new Error('Install macOS iMessage CLI to use the IMessageChannel. Run: npm install macOS iMessage CLI');
22
+ }
23
+ }
24
+
25
+ async stop(): Promise<void> {
26
+ // cleanup
27
+ }
28
+
29
+ async send(chatId: string, text: string): Promise<void> {
30
+ throw new Error('IMessageChannel: not yet connected. Call start() first.');
31
+ }
32
+ }
@@ -0,0 +1,82 @@
1
+ import { BaseChannel } from './index';
2
+ import type { Message } from '../core/types';
3
+
4
+ export interface IRCChannelConfig {
5
+ host: string;
6
+ port?: number;
7
+ nick: string;
8
+ channels: string[];
9
+ tls?: boolean;
10
+ password?: string;
11
+ }
12
+
13
+ export class IRCChannel extends BaseChannel {
14
+ readonly type = 'irc';
15
+ private config: IRCChannelConfig;
16
+ private client: any = null;
17
+ private running = false;
18
+
19
+ constructor(config: IRCChannelConfig) {
20
+ super();
21
+ if (!config.host || !config.nick || !config.channels?.length) {
22
+ throw new Error('IRCChannel requires host, nick, and channels in config');
23
+ }
24
+ this.config = config;
25
+ }
26
+
27
+ async start(): Promise<void> {
28
+ let IRC: any;
29
+ try {
30
+ IRC = require('irc-framework');
31
+ } catch {
32
+ throw new Error('Install irc-framework to use the IRCChannel. Run: npm install irc-framework');
33
+ }
34
+ this.client = new IRC.Client();
35
+ this.client.connect({
36
+ host: this.config.host,
37
+ port: this.config.port ?? (this.config.tls ? 6697 : 6667),
38
+ nick: this.config.nick,
39
+ tls: this.config.tls ?? false,
40
+ password: this.config.password,
41
+ });
42
+
43
+ await new Promise<void>((resolve, reject) => {
44
+ this.client.on('registered', () => {
45
+ for (const ch of this.config.channels) {
46
+ this.client.join(ch);
47
+ }
48
+ resolve();
49
+ });
50
+ this.client.on('error', (err: any) => reject(new Error(`IRC connection error: ${err.message || err}`)));
51
+ });
52
+
53
+ this.running = true;
54
+
55
+ this.client.on('privmsg', async (event: any) => {
56
+ if (!this.handler) return;
57
+ const msg: Message = {
58
+ id: Date.now().toString(),
59
+ role: 'user',
60
+ content: event.message,
61
+ timestamp: Date.now(),
62
+ metadata: { channel: event.target, nick: event.nick },
63
+ };
64
+ await this.handler(msg);
65
+ });
66
+ }
67
+
68
+ async stop(): Promise<void> {
69
+ if (this.client) {
70
+ this.client.quit('Goodbye');
71
+ this.client = null;
72
+ }
73
+ this.running = false;
74
+ }
75
+
76
+ async send(target: string, text: string): Promise<void> {
77
+ if (!this.running || !this.client) {
78
+ throw new Error('IRCChannel: not started. Call start() first.');
79
+ }
80
+ this.client.say(target, text);
81
+ }
82
+ }
@@ -0,0 +1,33 @@
1
+ import { BaseChannel } from './index';
2
+ import type { Message } from '../core/types';
3
+
4
+ export interface LINEChannelConfig {
5
+ channelAccessToken?: string;
6
+ channelSecret?: string;
7
+ }
8
+
9
+ export class LINEChannel extends BaseChannel {
10
+ readonly type = 'line';
11
+ private config: LINEChannelConfig;
12
+
13
+ constructor(config: LINEChannelConfig = {}) {
14
+ super();
15
+ this.config = config;
16
+ }
17
+
18
+ async start(): Promise<void> {
19
+ try {
20
+ require('@line/bot-sdk');
21
+ } catch {
22
+ throw new Error('Install @line/bot-sdk to use the LINEChannel. Run: npm install @line/bot-sdk');
23
+ }
24
+ }
25
+
26
+ async stop(): Promise<void> {
27
+ // cleanup
28
+ }
29
+
30
+ async send(chatId: string, text: string): Promise<void> {
31
+ throw new Error('LINEChannel: not yet connected. Call start() first.');
32
+ }
33
+ }