@atlisp/agent 0.1.6 → 0.1.9

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/agent.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createProvider } from './providers/index.js';
2
2
  import { createMcpClient, connectMcp } from './mcp/index.js';
3
- import { buildSystemMessage, buildToolsDescription, TOOL_DESCRIPTIONS } from './prompt.js';
3
+ import { buildSystemMessage, buildToolsDescription } from './prompt.js';
4
4
  import { getAgentConfig } from './config.js';
5
5
 
6
6
  export class Agent {
@@ -10,7 +10,7 @@ export class Agent {
10
10
  this.config = { ...getAgentConfig(), ...options.agentConfig };
11
11
  this.messages = [];
12
12
  this.tools = null;
13
- this.maxSteps = this.config.maxSteps || 10;
13
+ this.maxSteps = this.config.maxSteps || 500;
14
14
  this.verbose = this.config.verbose || false;
15
15
  }
16
16
 
package/config.js CHANGED
@@ -31,7 +31,7 @@ function getDefaultConfig() {
31
31
  maxTokens: 2048,
32
32
  },
33
33
  mcp: {
34
- mode: 'stdio',
34
+ mode: 'http',
35
35
  url: 'http://localhost:8110',
36
36
  command: 'atlisp-mcp',
37
37
  args: ['--stdio'],
@@ -79,7 +79,7 @@ function deepMerge(target, source) {
79
79
  const result = { ...target };
80
80
  for (const key of Object.keys(source)) {
81
81
  if (source[key] !== null && typeof source[key] === 'object' && !Array.isArray(source[key])) {
82
- result[key] = deepMerge(target[key] || {}, source[key]);
82
+ result[key] = deepMerge(target[key] ?? {}, source[key]);
83
83
  } else if (source[key] !== undefined) {
84
84
  result[key] = source[key];
85
85
  }
@@ -93,29 +93,6 @@ function loadConfig() {
93
93
  const fileConfig = loadConfigFile();
94
94
  let merged = deepMerge(getDefaultConfig(), fileConfig);
95
95
 
96
- merged.agent = {
97
- enabled: process.env.AGENT_ENABLED !== 'false',
98
- historyLimit: parseInt(process.env.AGENT_HISTORY_LIMIT || String(merged.agent.historyLimit), 10),
99
- maxSteps: parseInt(process.env.AGENT_MAX_STEPS || String(merged.agent.maxSteps), 10),
100
- verbose: process.env.AGENT_VERBOSE === 'true' || merged.agent.verbose,
101
- };
102
-
103
- merged.llm = {
104
- provider: process.env.LLM_PROVIDER || merged.llm.provider,
105
- baseURL: process.env.VLLM_BASE_URL || merged.llm.baseURL,
106
- model: process.env.LLM_MODEL || merged.llm.model,
107
- apiKey: process.env.DEEPSEEK_API_KEY || merged.llm.apiKey,
108
- temperature: parseFloat(process.env.LLM_TEMPERATURE || String(merged.llm.temperature)),
109
- maxTokens: parseInt(process.env.LLM_MAX_TOKENS || String(merged.llm.maxTokens)),
110
- };
111
-
112
- merged.mcp = {
113
- mode: process.env.MCP_MODE || merged.mcp.mode,
114
- url: process.env.MCP_URL || merged.mcp.url,
115
- command: process.env.MCP_COMMAND || merged.mcp.command,
116
- args: process.env.MCP_ARGS ? process.env.MCP_ARGS.split(' ') : merged.mcp.args,
117
- };
118
-
119
96
  return merged;
120
97
  }
121
98
 
package/index.js CHANGED
@@ -12,7 +12,7 @@ program
12
12
  .version('1.0.0');
13
13
 
14
14
  program
15
- .option('-m, --mode <mode>', 'MCP mode: http or stdio', 'http')
15
+ .option('-m, --mode <mode>', 'MCP mode: http or stdio', 'stdio')
16
16
  .option('-u, --mcp-url <url>', 'MCP HTTP URL', getMcpConfig().url)
17
17
  .option('-c, --mcp-command <cmd>', 'MCP stdio command', getMcpConfig().command)
18
18
  .option('--mcp-args <args>', 'MCP stdio args', '')
@@ -46,17 +46,19 @@ program
46
46
  program.parse(process.argv);
47
47
 
48
48
  async function getAgent() {
49
- const config = program.opts();
49
+ const opts = program.opts();
50
+ const fileMcpConfig = getMcpConfig();
51
+
50
52
  const mcpConfig = {
51
- mode: config.mode,
52
- url: config.mcpUrl,
53
- command: config.mcpCommand,
54
- args: config.mcpArgs ? config.mcpArgs.split(' ') : [],
53
+ mode: opts.mode !== 'stdio' ? opts.mode : fileMcpConfig.mode,
54
+ url: opts.mcpUrl || fileMcpConfig.url,
55
+ command: opts.mcpCommand || fileMcpConfig.command,
56
+ args: opts.mcpArgs ? opts.mcpArgs.split(' ') : fileMcpConfig.args,
55
57
  };
56
58
 
57
59
  return createAgent({
58
60
  mcpConfig,
59
- agentConfig: { verbose: config.verbose },
61
+ agentConfig: { verbose: opts.verbose },
60
62
  });
61
63
  }
62
64
 
package/install.ps1 ADDED
@@ -0,0 +1,247 @@
1
+ # @atlisp/mcp PowerShell Installation Script
2
+ # For installing @lisp MCP Server and its dependencies
3
+
4
+ $ErrorActionPreference = "Stop"
5
+ $packageName = "@atlisp/agent"
6
+ $minNodeVersion = 18
7
+
8
+ Write-Host "=== $packageName Installation Script ===" -ForegroundColor Cyan
9
+ Write-Host ""
10
+
11
+ function Get-NodeLtsVersion {
12
+ try {
13
+ $response = Invoke-WebRequest -Uri "https://nodejs.org/dist/index.json" -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop
14
+ $versions = $response.Content | ConvertFrom-Json
15
+ $lts = $versions | Where-Object { $_.lts -ne $false } | Select-Object -First 1
16
+ if ($lts) {
17
+ $nodeVersion = $lts.version -replace '^v'
18
+ Write-Host "Found Node.js LTS: $nodeVersion" -ForegroundColor Cyan
19
+ return $nodeVersion
20
+ }
21
+ }
22
+ catch {
23
+ Write-Host "Failed to fetch LTS version, using default" -ForegroundColor Yellow
24
+ }
25
+ return "22.17.0"
26
+ }
27
+
28
+ function Add-NodeToPath {
29
+ $nodePaths = @(
30
+ "${env:ProgramFiles}\nodejs",
31
+ "${env:ProgramFiles(x86)}\nodejs",
32
+ "${env:APPDATA}\npm",
33
+ "${env:ProgramFiles}\nodejs"
34
+ )
35
+ $added = $false
36
+ foreach ($nodePath in $nodePaths) {
37
+ if ((Test-Path "$nodePath\node.exe") -and ($env:Path -notlike "*$nodePath*")) {
38
+ $env:Path = "$nodePath;" + $env:Path
39
+ $added = $true
40
+ Write-Host "Added to PATH: $nodePath" -ForegroundColor Cyan
41
+ }
42
+ }
43
+ return $added
44
+ }
45
+
46
+ function Install-NodeJS {
47
+ Write-Host "Node.js not found, starting automatic installation..." -ForegroundColor Yellow
48
+
49
+ if (Get-Command winget -ErrorAction SilentlyContinue) {
50
+ Write-Host "Installing Node.js LTS via winget..." -ForegroundColor Cyan
51
+ winget install OpenJS.NodeJS.LTS --accept-source-agreements --accept-package-agreements
52
+ if ($LASTEXITCODE -eq 0) {
53
+ Write-Host "Node.js installed via winget, detecting..." -ForegroundColor Green
54
+ Start-Sleep -Seconds 3
55
+ Add-NodeToPath
56
+ return $true
57
+ }
58
+ Write-Host "winget install failed" -ForegroundColor Yellow
59
+ }
60
+
61
+ if (Get-Command choco -ErrorAction SilentlyContinue) {
62
+ Write-Host "Installing Node.js LTS via choco..." -ForegroundColor Cyan
63
+ choco install nodejs-lts -y
64
+ if ($LASTEXITCODE -eq 0) {
65
+ Write-Host "Node.js installed via choco, detecting..." -ForegroundColor Green
66
+ Start-Sleep -Seconds 3
67
+ Add-NodeToPath
68
+ return $true
69
+ }
70
+ Write-Host "choco install failed" -ForegroundColor Yellow
71
+ }
72
+
73
+ if (Get-Command scoop -ErrorAction SilentlyContinue) {
74
+ Write-Host "Installing Node.js LTS via scoop..." -ForegroundColor Cyan
75
+ scoop install nodejs-lts
76
+ if ($LASTEXITCODE -eq 0) {
77
+ Write-Host "Node.js installed via scoop, detecting..." -ForegroundColor Green
78
+ Start-Sleep -Seconds 3
79
+ Add-NodeToPath
80
+ return $true
81
+ }
82
+ Write-Host "scoop install failed" -ForegroundColor Yellow
83
+ }
84
+
85
+ $nodeVersion = Get-NodeLtsVersion
86
+ Write-Host "Downloading Node.js v$nodeVersion..." -ForegroundColor Cyan
87
+ $nodeUrl = "https://nodejs.org/dist/v$nodeVersion/node-v$nodeVersion-x64.msi"
88
+ $installer = "$env:TEMP\node-setup.msi"
89
+ try {
90
+ Invoke-WebRequest -Uri $nodeUrl -OutFile $installer -UseBasicParsing
91
+ Write-Host "Running installer..." -ForegroundColor Cyan
92
+ $proc = Start-Process msiexec.exe -Wait -ArgumentList "/i `"$installer`" /quiet /norestart" -PassThru
93
+ Remove-Item $installer -Force -ErrorAction SilentlyContinue
94
+ if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
95
+ Write-Host "MSI install failed with code: $($proc.ExitCode)" -ForegroundColor Red
96
+ exit 1
97
+ }
98
+ Write-Host "Node.js installed via MSI" -ForegroundColor Green
99
+ Add-NodeToPath
100
+ return $true
101
+ }
102
+ catch {
103
+ Write-Host "Automatic installation failed. Please download manually: https://nodejs.org/" -ForegroundColor Red
104
+ exit 1
105
+ }
106
+ }
107
+
108
+ function Test-NodeInstalled {
109
+ $nodeVersion = $null
110
+ $checkedPaths = @()
111
+
112
+ Add-NodeToPath | Out-Null
113
+
114
+ for ($retry = 0; $retry -lt 5; $retry++) {
115
+ if ($retry -gt 0) {
116
+ Write-Host "Retrying detection (attempt $retry/5)..." -ForegroundColor Yellow
117
+ Start-Sleep -Seconds 2
118
+ Add-NodeToPath | Out-Null
119
+ }
120
+ try {
121
+ $result = node --version 2>$null
122
+ if ($result) {
123
+ $str = $result.ToString().Trim()
124
+ $nodeVersion = $str.TrimStart("v")
125
+ if (-not [string]::IsNullOrEmpty($nodeVersion)) {
126
+ Write-Host "Node.js detected: v$nodeVersion" -ForegroundColor Green
127
+ return $nodeVersion
128
+ }
129
+ }
130
+ }
131
+ catch {
132
+ }
133
+ }
134
+
135
+ Write-Host "Node.js not found, installing..." -ForegroundColor Yellow
136
+ $installed = Install-NodeJS
137
+ if ($installed) {
138
+ for ($retry = 0; $retry -lt 5; $retry++) {
139
+ Start-Sleep -Seconds 2
140
+ Add-NodeToPath | Out-Null
141
+ try {
142
+ $result = node --version 2>$null
143
+ if ($result) {
144
+ $nodeVersion = $result.ToString().Trim().TrimStart("v")
145
+ if (-not [string]::IsNullOrEmpty($nodeVersion)) {
146
+ Write-Host "Node.js detected after install: v$nodeVersion" -ForegroundColor Green
147
+ return $nodeVersion
148
+ }
149
+ }
150
+ }
151
+ catch {
152
+ }
153
+ }
154
+ }
155
+
156
+ Write-Host "Failed to detect Node.js" -ForegroundColor Red
157
+ exit 1
158
+ }
159
+
160
+ function Test-NodeVersion {
161
+ param([string]$version)
162
+ Write-Host "Validating Node.js version: [$version]" -ForegroundColor Cyan
163
+ if ([string]::IsNullOrEmpty($version)) {
164
+ Write-Host "Error: Invalid Node.js version (empty)" -ForegroundColor Red
165
+ exit 1
166
+ }
167
+ if ($version.Length -lt 3) {
168
+ Write-Host "Error: Invalid Node.js version (too short): $version" -ForegroundColor Red
169
+ exit 1
170
+ }
171
+ $ver = $version.Trim()
172
+ $parts = $ver.Split(".")
173
+ if ($parts.Length -eq 0) {
174
+ Write-Host "Error: Invalid Node.js version format" -ForegroundColor Red
175
+ exit 1
176
+ }
177
+ $firstPart = $parts[0]
178
+ try {
179
+ $major = [int]::Parse($firstPart)
180
+ }
181
+ catch {
182
+ Write-Host "Error: Cannot parse major version: '$firstPart'" -ForegroundColor Red
183
+ exit 1
184
+ }
185
+ if ($major -lt $minNodeVersion) {
186
+ Write-Host "Error: Node.js version too low (current: $ver, required: >= $minNodeVersion)" -ForegroundColor Red
187
+ exit 1
188
+ }
189
+ }
190
+
191
+ function Test-NpmAvailable {
192
+ try {
193
+ $npmVersion = (npm --version 2>$null).ToString().Trim()
194
+ if ($npmVersion) {
195
+ Write-Host "npm detected: v$npmVersion" -ForegroundColor Green
196
+ $globalPath = npm root -g
197
+ if ($globalPath) {
198
+ if ($env:Path -notlike "*$globalPath*") {
199
+ $env:Path = "$globalPath;" + $env:Path
200
+ Write-Host "Added npm global path to PATH: $globalPath" -ForegroundColor Cyan
201
+ }
202
+ }
203
+ }
204
+ else {
205
+ Write-Host "Error: npm not available" -ForegroundColor Red
206
+ exit 1
207
+ }
208
+ }
209
+ catch {
210
+ Write-Host "Error: npm not available" -ForegroundColor Red
211
+ exit 1
212
+ }
213
+ }
214
+
215
+ function Install-Package {
216
+ $nodeVersion = Test-NodeInstalled
217
+ Test-NodeVersion $nodeVersion
218
+ Test-NpmAvailable
219
+
220
+ Write-Host ""
221
+ Write-Host "Installing $packageName from npm registry..." -ForegroundColor Cyan
222
+ npm install -g @atlisp/agent --silent
223
+
224
+ if ($LASTEXITCODE -ne 0) {
225
+ Write-Host "Error: npm install failed" -ForegroundColor Red
226
+ exit 1
227
+ }
228
+
229
+ Add-NodeToPath | Out-Null
230
+ $globalPath = (npm root -g).ToString()
231
+ if ($globalPath -and ($env:Path -notlike "*$globalPath*")) {
232
+ $env:Path = "$globalPath;" + $env:Path
233
+ Write-Host "Added npm global path to PATH: $globalPath" -ForegroundColor Cyan
234
+ }
235
+
236
+ Write-Host ""
237
+ Write-Host "=== Installation Complete ===" -ForegroundColor Green
238
+
239
+ $runMcp = Read-Host "Start atlisp-agent now? (Y/N)"
240
+ if ($runMcp -eq "Y" -or $runMcp -eq "y") {
241
+ $env:Path = "$env:APPDATA\npm;" + $env:Path
242
+ Write-Host "Starting atlisp-agent ..." -ForegroundColor Cyan
243
+ atlisp-agent chat
244
+ }
245
+ }
246
+
247
+ Install-Package
package/install.ps1~ ADDED
@@ -0,0 +1,247 @@
1
+ # @atlisp/mcp PowerShell Installation Script
2
+ # For installing @lisp MCP Server and its dependencies
3
+
4
+ $ErrorActionPreference = "Stop"
5
+ $packageName = "@atlisp/mcp"
6
+ $minNodeVersion = 18
7
+
8
+ Write-Host "=== $packageName Installation Script ===" -ForegroundColor Cyan
9
+ Write-Host ""
10
+
11
+ function Get-NodeLtsVersion {
12
+ try {
13
+ $response = Invoke-WebRequest -Uri "https://nodejs.org/dist/index.json" -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop
14
+ $versions = $response.Content | ConvertFrom-Json
15
+ $lts = $versions | Where-Object { $_.lts -ne $false } | Select-Object -First 1
16
+ if ($lts) {
17
+ $nodeVersion = $lts.version -replace '^v'
18
+ Write-Host "Found Node.js LTS: $nodeVersion" -ForegroundColor Cyan
19
+ return $nodeVersion
20
+ }
21
+ }
22
+ catch {
23
+ Write-Host "Failed to fetch LTS version, using default" -ForegroundColor Yellow
24
+ }
25
+ return "22.17.0"
26
+ }
27
+
28
+ function Add-NodeToPath {
29
+ $nodePaths = @(
30
+ "${env:ProgramFiles}\nodejs",
31
+ "${env:ProgramFiles(x86)}\nodejs",
32
+ "${env:APPDATA}\npm",
33
+ "${env:ProgramFiles}\nodejs"
34
+ )
35
+ $added = $false
36
+ foreach ($nodePath in $nodePaths) {
37
+ if ((Test-Path "$nodePath\node.exe") -and ($env:Path -notlike "*$nodePath*")) {
38
+ $env:Path = "$nodePath;" + $env:Path
39
+ $added = $true
40
+ Write-Host "Added to PATH: $nodePath" -ForegroundColor Cyan
41
+ }
42
+ }
43
+ return $added
44
+ }
45
+
46
+ function Install-NodeJS {
47
+ Write-Host "Node.js not found, starting automatic installation..." -ForegroundColor Yellow
48
+
49
+ if (Get-Command winget -ErrorAction SilentlyContinue) {
50
+ Write-Host "Installing Node.js LTS via winget..." -ForegroundColor Cyan
51
+ winget install OpenJS.NodeJS.LTS --accept-source-agreements --accept-package-agreements
52
+ if ($LASTEXITCODE -eq 0) {
53
+ Write-Host "Node.js installed via winget, detecting..." -ForegroundColor Green
54
+ Start-Sleep -Seconds 3
55
+ Add-NodeToPath
56
+ return $true
57
+ }
58
+ Write-Host "winget install failed" -ForegroundColor Yellow
59
+ }
60
+
61
+ if (Get-Command choco -ErrorAction SilentlyContinue) {
62
+ Write-Host "Installing Node.js LTS via choco..." -ForegroundColor Cyan
63
+ choco install nodejs-lts -y
64
+ if ($LASTEXITCODE -eq 0) {
65
+ Write-Host "Node.js installed via choco, detecting..." -ForegroundColor Green
66
+ Start-Sleep -Seconds 3
67
+ Add-NodeToPath
68
+ return $true
69
+ }
70
+ Write-Host "choco install failed" -ForegroundColor Yellow
71
+ }
72
+
73
+ if (Get-Command scoop -ErrorAction SilentlyContinue) {
74
+ Write-Host "Installing Node.js LTS via scoop..." -ForegroundColor Cyan
75
+ scoop install nodejs-lts
76
+ if ($LASTEXITCODE -eq 0) {
77
+ Write-Host "Node.js installed via scoop, detecting..." -ForegroundColor Green
78
+ Start-Sleep -Seconds 3
79
+ Add-NodeToPath
80
+ return $true
81
+ }
82
+ Write-Host "scoop install failed" -ForegroundColor Yellow
83
+ }
84
+
85
+ $nodeVersion = Get-NodeLtsVersion
86
+ Write-Host "Downloading Node.js v$nodeVersion..." -ForegroundColor Cyan
87
+ $nodeUrl = "https://nodejs.org/dist/v$nodeVersion/node-v$nodeVersion-x64.msi"
88
+ $installer = "$env:TEMP\node-setup.msi"
89
+ try {
90
+ Invoke-WebRequest -Uri $nodeUrl -OutFile $installer -UseBasicParsing
91
+ Write-Host "Running installer..." -ForegroundColor Cyan
92
+ $proc = Start-Process msiexec.exe -Wait -ArgumentList "/i `"$installer`" /quiet /norestart" -PassThru
93
+ Remove-Item $installer -Force -ErrorAction SilentlyContinue
94
+ if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
95
+ Write-Host "MSI install failed with code: $($proc.ExitCode)" -ForegroundColor Red
96
+ exit 1
97
+ }
98
+ Write-Host "Node.js installed via MSI" -ForegroundColor Green
99
+ Add-NodeToPath
100
+ return $true
101
+ }
102
+ catch {
103
+ Write-Host "Automatic installation failed. Please download manually: https://nodejs.org/" -ForegroundColor Red
104
+ exit 1
105
+ }
106
+ }
107
+
108
+ function Test-NodeInstalled {
109
+ $nodeVersion = $null
110
+ $checkedPaths = @()
111
+
112
+ Add-NodeToPath | Out-Null
113
+
114
+ for ($retry = 0; $retry -lt 5; $retry++) {
115
+ if ($retry -gt 0) {
116
+ Write-Host "Retrying detection (attempt $retry/5)..." -ForegroundColor Yellow
117
+ Start-Sleep -Seconds 2
118
+ Add-NodeToPath | Out-Null
119
+ }
120
+ try {
121
+ $result = node --version 2>$null
122
+ if ($result) {
123
+ $str = $result.ToString().Trim()
124
+ $nodeVersion = $str.TrimStart("v")
125
+ if (-not [string]::IsNullOrEmpty($nodeVersion)) {
126
+ Write-Host "Node.js detected: v$nodeVersion" -ForegroundColor Green
127
+ return $nodeVersion
128
+ }
129
+ }
130
+ }
131
+ catch {
132
+ }
133
+ }
134
+
135
+ Write-Host "Node.js not found, installing..." -ForegroundColor Yellow
136
+ $installed = Install-NodeJS
137
+ if ($installed) {
138
+ for ($retry = 0; $retry -lt 5; $retry++) {
139
+ Start-Sleep -Seconds 2
140
+ Add-NodeToPath | Out-Null
141
+ try {
142
+ $result = node --version 2>$null
143
+ if ($result) {
144
+ $nodeVersion = $result.ToString().Trim().TrimStart("v")
145
+ if (-not [string]::IsNullOrEmpty($nodeVersion)) {
146
+ Write-Host "Node.js detected after install: v$nodeVersion" -ForegroundColor Green
147
+ return $nodeVersion
148
+ }
149
+ }
150
+ }
151
+ catch {
152
+ }
153
+ }
154
+ }
155
+
156
+ Write-Host "Failed to detect Node.js" -ForegroundColor Red
157
+ exit 1
158
+ }
159
+
160
+ function Test-NodeVersion {
161
+ param([string]$version)
162
+ Write-Host "Validating Node.js version: [$version]" -ForegroundColor Cyan
163
+ if ([string]::IsNullOrEmpty($version)) {
164
+ Write-Host "Error: Invalid Node.js version (empty)" -ForegroundColor Red
165
+ exit 1
166
+ }
167
+ if ($version.Length -lt 3) {
168
+ Write-Host "Error: Invalid Node.js version (too short): $version" -ForegroundColor Red
169
+ exit 1
170
+ }
171
+ $ver = $version.Trim()
172
+ $parts = $ver.Split(".")
173
+ if ($parts.Length -eq 0) {
174
+ Write-Host "Error: Invalid Node.js version format" -ForegroundColor Red
175
+ exit 1
176
+ }
177
+ $firstPart = $parts[0]
178
+ try {
179
+ $major = [int]::Parse($firstPart)
180
+ }
181
+ catch {
182
+ Write-Host "Error: Cannot parse major version: '$firstPart'" -ForegroundColor Red
183
+ exit 1
184
+ }
185
+ if ($major -lt $minNodeVersion) {
186
+ Write-Host "Error: Node.js version too low (current: $ver, required: >= $minNodeVersion)" -ForegroundColor Red
187
+ exit 1
188
+ }
189
+ }
190
+
191
+ function Test-NpmAvailable {
192
+ try {
193
+ $npmVersion = (npm --version 2>$null).ToString().Trim()
194
+ if ($npmVersion) {
195
+ Write-Host "npm detected: v$npmVersion" -ForegroundColor Green
196
+ $globalPath = npm root -g
197
+ if ($globalPath) {
198
+ if ($env:Path -notlike "*$globalPath*") {
199
+ $env:Path = "$globalPath;" + $env:Path
200
+ Write-Host "Added npm global path to PATH: $globalPath" -ForegroundColor Cyan
201
+ }
202
+ }
203
+ }
204
+ else {
205
+ Write-Host "Error: npm not available" -ForegroundColor Red
206
+ exit 1
207
+ }
208
+ }
209
+ catch {
210
+ Write-Host "Error: npm not available" -ForegroundColor Red
211
+ exit 1
212
+ }
213
+ }
214
+
215
+ function Install-Package {
216
+ $nodeVersion = Test-NodeInstalled
217
+ Test-NodeVersion $nodeVersion
218
+ Test-NpmAvailable
219
+
220
+ Write-Host ""
221
+ Write-Host "Installing $packageName from npm registry..." -ForegroundColor Cyan
222
+ npm install -g @atlisp/mcp --silent
223
+
224
+ if ($LASTEXITCODE -ne 0) {
225
+ Write-Host "Error: npm install failed" -ForegroundColor Red
226
+ exit 1
227
+ }
228
+
229
+ Add-NodeToPath | Out-Null
230
+ $globalPath = (npm root -g).ToString()
231
+ if ($globalPath -and ($env:Path -notlike "*$globalPath*")) {
232
+ $env:Path = "$globalPath;" + $env:Path
233
+ Write-Host "Added npm global path to PATH: $globalPath" -ForegroundColor Cyan
234
+ }
235
+
236
+ Write-Host ""
237
+ Write-Host "=== Installation Complete ===" -ForegroundColor Green
238
+
239
+ $runMcp = Read-Host "Start atlisp-mcp now? (Y/N)"
240
+ if ($runMcp -eq "Y" -or $runMcp -eq "y") {
241
+ $env:Path = "$env:APPDATA\npm;" + $env:Path
242
+ Write-Host "Starting atlisp-mcp..." -ForegroundColor Cyan
243
+ atlisp-mcp
244
+ }
245
+ }
246
+
247
+ Install-Package
package/mcp/index.js CHANGED
@@ -7,10 +7,10 @@ export function createMcpClient(config = {}) {
7
7
  const mode = mcpConfig.mode || 'http';
8
8
 
9
9
  if (mode === 'stdio') {
10
- return new StdioMcpClient(config);
10
+ return new StdioMcpClient(mcpConfig);
11
11
  }
12
12
 
13
- return new HttpMcpClient(config);
13
+ return new HttpMcpClient(mcpConfig);
14
14
  }
15
15
 
16
16
  export async function connectMcp(client) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlisp/agent",
3
- "version": "0.1.6",
3
+ "version": "0.1.9",
4
4
  "description": "AI Agent for @lisp - Connects to MCP Server for CAD operations",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -50,55 +50,6 @@ export class DeepseekProvider {
50
50
  }
51
51
  }
52
52
 
53
- async chatStream(messages, onChunk, options = {}) {
54
- const url = `${this.baseURL}/chat/completions`;
55
- const body = {
56
- model: this.model,
57
- messages: messages,
58
- temperature: options.temperature ?? this.temperature,
59
- max_tokens: options.maxTokens ?? this.maxTokens,
60
- stream: true,
61
- };
62
-
63
- const response = await fetch(url, {
64
- method: 'POST',
65
- headers: {
66
- 'Content-Type': 'application/json',
67
- 'Authorization': `Bearer ${this.apiKey}`,
68
- },
69
- body: JSON.stringify(body),
70
- });
71
-
72
- if (!response.ok) {
73
- throw new Error(`DeepSeek API error: ${response.status}`);
74
- }
75
-
76
- const reader = response.body.getReader();
77
- const decoder = new TextDecoder();
78
- let buffer = '';
79
-
80
- while (true) {
81
- const { done, value } = await reader.read();
82
- if (done) break;
83
-
84
- buffer += decoder.decode(value, { stream: true });
85
- const lines = buffer.split('\n');
86
- buffer = lines.pop() || '';
87
-
88
- for (const line of lines) {
89
- if (line.startsWith('data: ')) {
90
- const data = line.slice(6);
91
- if (data === '[DONE]') return;
92
- try {
93
- const obj = JSON.parse(data);
94
- const content = obj.choices?.[0]?.delta?.content;
95
- if (content) onChunk(content);
96
- } catch (e) {}
97
- }
98
- }
99
- }
100
- }
101
-
102
53
  getName() {
103
54
  return 'deepseek';
104
55
  }
@@ -1,10 +1,12 @@
1
1
  import { VllmProvider } from './vllm.js';
2
2
  import { DeepseekProvider } from './deepseek.js';
3
+ import { OpenAIProvider } from './openai.js';
3
4
  import { getLlmConfig } from '../config.js';
4
5
 
5
6
  const PROVIDERS = {
6
7
  vllm: VllmProvider,
7
8
  deepseek: DeepseekProvider,
9
+ openai: OpenAIProvider,
8
10
  };
9
11
 
10
12
  export function createProvider(config = {}) {
@@ -15,7 +17,7 @@ export function createProvider(config = {}) {
15
17
  throw new Error(`Unknown LLM provider: ${llmConfig.provider}. Available: ${Object.keys(PROVIDERS).join(', ')}`);
16
18
  }
17
19
 
18
- return new ProviderClass(config);
20
+ return new ProviderClass(llmConfig);
19
21
  }
20
22
 
21
23
  export function listProviders() {
@@ -0,0 +1,63 @@
1
+ import { getLlmConfig } from '../config.js';
2
+
3
+ export class OpenAIProvider {
4
+ constructor(config = {}) {
5
+ this.config = { ...getLlmConfig(), ...config };
6
+ this.baseURL = this.config.baseURL || 'https://api.openai.com/v1';
7
+ this.model = this.config.model || 'gpt-4';
8
+ this.apiKey = this.config.apiKey;
9
+ this.temperature = this.config.temperature;
10
+ this.maxTokens = this.config.maxTokens;
11
+ }
12
+
13
+ async chat(messages, options = {}) {
14
+ const url = `${this.baseURL}/chat/completions`;
15
+ const body = {
16
+ model: this.model,
17
+ messages: messages,
18
+ temperature: options.temperature ?? this.temperature,
19
+ max_tokens: options.maxTokens ?? this.maxTokens,
20
+ ...(options.stop && { stop: options.stop }),
21
+ };
22
+
23
+ const headers = {
24
+ 'Content-Type': 'application/json',
25
+ };
26
+
27
+ if (this.apiKey) {
28
+ headers['Authorization'] = `Bearer ${this.apiKey}`;
29
+ }
30
+
31
+ try {
32
+ const response = await fetch(url, {
33
+ method: 'POST',
34
+ headers: headers,
35
+ body: JSON.stringify(body),
36
+ });
37
+
38
+ if (!response.ok) {
39
+ const errorText = await response.text();
40
+ throw new Error(`OpenAI API error: ${response.status} ${errorText}`);
41
+ }
42
+
43
+ const data = await response.json();
44
+
45
+ if (data.choices && data.choices.length > 0) {
46
+ return data.choices[0].message.content;
47
+ }
48
+
49
+ throw new Error('No response content from OpenAI');
50
+ } catch (error) {
51
+ if (error.message.includes('fetch')) {
52
+ throw new Error(`无法连接到 OpenAI 兼容 API: ${error.message}`);
53
+ }
54
+ throw error;
55
+ }
56
+ }
57
+
58
+ getName() {
59
+ return 'openai';
60
+ }
61
+ }
62
+
63
+ export default OpenAIProvider;
package/providers/vllm.js CHANGED
@@ -50,55 +50,6 @@ export class VllmProvider {
50
50
  }
51
51
  }
52
52
 
53
- async chatStream(messages, onChunk, options = {}) {
54
- const url = `${this.baseURL}/chat/completions`;
55
- const body = {
56
- model: this.model,
57
- messages: messages,
58
- temperature: options.temperature ?? this.temperature,
59
- max_tokens: options.maxTokens ?? this.maxTokens,
60
- stream: true,
61
- };
62
-
63
- const response = await fetch(url, {
64
- method: 'POST',
65
- headers: {
66
- 'Content-Type': 'application/json',
67
- 'Authorization': `Bearer ${this.apiKey}`,
68
- },
69
- body: JSON.stringify(body),
70
- });
71
-
72
- if (!response.ok) {
73
- throw new Error(`vLLM API error: ${response.status}`);
74
- }
75
-
76
- const reader = response.body.getReader();
77
- const decoder = new TextDecoder();
78
- let buffer = '';
79
-
80
- while (true) {
81
- const { done, value } = await reader.read();
82
- if (done) break;
83
-
84
- buffer += decoder.decode(value, { stream: true });
85
- const lines = buffer.split('\n');
86
- buffer = lines.pop() || '';
87
-
88
- for (const line of lines) {
89
- if (line.startsWith('data: ')) {
90
- const data = line.slice(6);
91
- if (data === '[DONE]') return;
92
- try {
93
- const obj = JSON.parse(data);
94
- const content = obj.choices?.[0]?.delta?.content;
95
- if (content) onChunk(content);
96
- } catch (e) {}
97
- }
98
- }
99
- }
100
- }
101
-
102
53
  getName() {
103
54
  return 'vllm';
104
55
  }
package/README.md~ DELETED
@@ -1,215 +0,0 @@
1
- # @lisp Agent
2
-
3
- AI Agent for @lisp - 通过 MCP 连接到 CAD 执行 AI 辅助操作。
4
-
5
- ## 安装
6
-
7
- ### Windows (PowerShell)
8
-
9
- ```powershell
10
- iwr -useb https://atlisp.cn/install.ps1 | iex
11
- ```
12
-
13
- ### 手动安装
14
-
15
- ```bash
16
- npm i -g @atlisp/agent
17
- ```
18
-
19
- ## 配置
20
-
21
- 配置文件位置: `~/.atlisp/atlisp.json` 或 `~/.atlisp/atlisp.yaml`
22
-
23
- ### 配置示例 (JSON)
24
-
25
- ```json
26
- {
27
- "agent": {
28
- "enabled": true,
29
- "maxSteps": 10,
30
- "verbose": false
31
- },
32
- "llm": {
33
- "provider": "deepseek",
34
- "baseURL": "",
35
- "model": "deepseek-v4-flash",
36
- "apiKey": "sk-xxxxx",
37
- "temperature": 0.7,
38
- "maxTokens": 2048
39
- },
40
- "mcp": {
41
- "mode": "stdio",
42
- "command": "atlisp-mcp",
43
- "args": ["--stdio"]
44
- }
45
- }
46
- ```
47
-
48
- ### 配置示例 (YAML)
49
-
50
- ```yaml
51
- agent:
52
- enabled: true
53
- maxSteps: 10
54
- verbose: false
55
-
56
- llm:
57
- provider: deepseek
58
- baseURL: ""
59
- model: deepseek-v4-flash
60
- apiKey: sk-xxxxx
61
- temperature: 0.7
62
- maxTokens: 2048
63
-
64
- mcp:
65
- mode: stdio
66
- command: atlisp-mcp
67
- args:
68
- - --stdio
69
- ```
70
-
71
- ## 配置说明
72
-
73
- ### Agent 配置
74
-
75
- | 配置项 | 类型 | 默认值 | 说明 |
76
- |--------|------|--------|------|
77
- | enabled | boolean | true | 是否启用 agent |
78
- | maxSteps | number | 10 | 最大执行步数 |
79
- | verbose | boolean | false | 调试模式 |
80
-
81
- ### LLM 配置
82
-
83
- | 配置项 | 类型 | 默认值 | 说明 |
84
- |--------|------|--------|------|
85
- | provider | string | deepseek | LLM 提供商: deepseek, vllm |
86
- | baseURL | string | 空 | API 地址(留空使用默认值) |
87
- | model | string | deepseek-v4-flash | 模型名称 |
88
- | apiKey | string | 空 | API Key |
89
- | temperature | number | 0.7 | 温度参数 |
90
- | maxTokens | number | 2048 | 最大 token 数 |
91
-
92
- ### MCP 配置
93
-
94
- | 配置项 | 类型 | 默认值 | 说明 |
95
- |--------|------|--------|------|
96
- | mode | string | stdio | 连接模式: http, stdio |
97
- | url | string | http://localhost:8110 | HTTP 模式端点 |
98
- | command | string | atlisp-mcp | stdio 模式命令 |
99
- | args | array | ["--stdio"] | stdio 模式参数 |
100
-
101
- ## 环境变量
102
-
103
- 配置可被环境变量覆盖(优先级最高):
104
-
105
- ```bash
106
- # LLM
107
- export LLM_PROVIDER=deepseek
108
- export LLM_MODEL=deepseek-v4-flash
109
- export DEEPSEEK_API_KEY=sk-xxxxx
110
- export LLM_TEMPERATURE=0.7
111
- export LLM_MAX_TOKENS=2048
112
-
113
- # MCP
114
- export MCP_MODE=stdio
115
- export MCP_COMMAND=atlisp-mcp
116
- export MCP_ARGS="--stdio"
117
-
118
- # Agent
119
- export AGENT_VERBOSE=true
120
- export AGENT_MAX_STEPS=20
121
- ```
122
-
123
- ## 使用方式
124
-
125
- ### CLI 交互模式
126
-
127
- ```bash
128
- npx atlisp-agent chat
129
- ```
130
-
131
- ### 单次执行
132
-
133
- ```bash
134
- npx atlisp-agent exec "查询 CAD 版本"
135
- ```
136
-
137
- ### 列出工具
138
-
139
- ```bash
140
- npx atlisp-agent tools
141
- ```
142
-
143
- ### HTTP Server 模式
144
-
145
- ```bash
146
- npm run server
147
- # 启动在 http://0.0.0.0:8120
148
- ```
149
-
150
- ### API 端点
151
-
152
- | 方法 | 路径 | 说明 |
153
- |------|------|------|
154
- | POST | /chat | AI 对话 |
155
- | POST | /exec | 单次执行 |
156
- | GET | /tools | 列出工具 |
157
- | GET | /health | 健康检查 |
158
- | GET | /history | 获取历史 |
159
- | DELETE | /history | 清除历史 |
160
-
161
- ### API 调用示例
162
-
163
- ```bash
164
- curl -X POST http://localhost:8120/chat \
165
- -H "Content-Type: application/json" \
166
- -d '{"message": "查询 CAD 版本"}'
167
- ```
168
-
169
- ## MCP 工具
170
-
171
- | 工具名 | 说明 |
172
- |--------|------|
173
- | connect_cad | 连接 CAD |
174
- | eval_lisp | 执行 LISP 代码(无返回) |
175
- | eval_lisp_with_result | 执行 LISP 代码(返回结果) |
176
- | get_cad_info | 获取 CAD 信息 |
177
- | list_packages | 列出已安装包 |
178
- | search_packages | 搜索包 |
179
- | install_package | 安装包 |
180
- | get_platform_info | 获取平台信息 |
181
- | at_command | 执行 @lisp 命令 |
182
-
183
- ## LLM Provider
184
-
185
- ### deepseek
186
-
187
- 使用 DeepSeek API。
188
-
189
- ```json
190
- {
191
- "llm": {
192
- "provider": "deepseek",
193
- "apiKey": "sk-xxxxx",
194
- "model": "deepseek-v4-flash"
195
- }
196
- }
197
- ```
198
-
199
- ### vllm
200
-
201
- 使用本地 vLLM 服务器。
202
-
203
- ```json
204
- {
205
- "llm": {
206
- "provider": "vllm",
207
- "baseURL": "http://192.168.1.8:8001/v1",
208
- "model": "your-model"
209
- }
210
- }
211
- ```
212
-
213
- ## 许可证
214
-
215
- ISC
package/package.json~ DELETED
@@ -1,32 +0,0 @@
1
- {
2
- "name": "@atlisp/agent",
3
- "version": "0.1.5",
4
- "description": "AI Agent for @lisp - Connects to MCP Server for CAD operations",
5
- "type": "module",
6
- "main": "index.js",
7
- "bin": {
8
- "atlisp-agent": "./index.js",
9
- "atlisp-agent-server": "./server.js"
10
- },
11
- "scripts": {
12
- "start": "node index.js",
13
- "server": "node server.js",
14
- "test": "echo \"No tests yet\""
15
- },
16
- "keywords": [
17
- "atlisp",
18
- "agent",
19
- "ai",
20
- "cad",
21
- "autolisp",
22
- "mcp"
23
- ],
24
- "author": "vitalgg",
25
- "license": "ISC",
26
- "dependencies": {
27
- "@atlisp/mcp": "file:../mcp-server",
28
- "commander": "^11.1.0",
29
- "express": "^5.2.1",
30
- "yaml": "^2.6.1"
31
- }
32
- }