@atlisp/agent 0.1.12 → 0.1.14

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 CHANGED
@@ -100,23 +100,52 @@ mcp:
100
100
 
101
101
  ## 环境变量
102
102
 
103
- 配置可被环境变量覆盖(优先级最高):
103
+ 配置可被环境变量覆盖(优先级最高)。支持两种方式:
104
+
105
+ ### 方式1: 命令行环境变量
104
106
 
105
107
  ```bash
106
108
  # LLM
107
109
  export LLM_PROVIDER=deepseek
110
+ export LLM_BASE_URL=https://api.deepseek.com
108
111
  export LLM_MODEL=deepseek-v4-flash
109
- export DEEPSEEK_API_KEY=sk-xxxxx
112
+ export LLM_API_KEY=sk-xxxxx
110
113
  export LLM_TEMPERATURE=0.7
111
114
  export LLM_MAX_TOKENS=2048
112
115
 
113
116
  # MCP
114
117
  export MCP_MODE=stdio
118
+ export MCP_URL=http://localhost:8120
115
119
  export MCP_COMMAND=atlisp-mcp
116
- export MCP_ARGS="--stdio"
117
120
 
118
121
  # Agent
122
+ export AGENT_ENABLED=true
123
+ export AGENT_MAX_STEPS=500
119
124
  export AGENT_VERBOSE=true
125
+ ```
126
+
127
+ ### 方式2: .env 文件
128
+
129
+ 在 `~/.atlisp/.env` 文件中配置:
130
+
131
+ ```env
132
+ # LLM 配置
133
+ LLM_PROVIDER=deepseek
134
+ LLM_BASE_URL=https://api.deepseek.com
135
+ LLM_MODEL=deepseek-v4-flash
136
+ LLM_API_KEY=sk-xxxxx
137
+ LLM_TEMPERATURE=0.7
138
+ LLM_MAX_TOKENS=2048
139
+
140
+ # MCP 配置
141
+ MCP_MODE=stdio
142
+ MCP_URL=http://localhost:8120
143
+
144
+ # Agent 配置
145
+ AGENT_VERBOSE=true
146
+ ```
147
+
148
+ 优先级: 命令行环境变量 > .env 文件 > atlisp.json
120
149
  export AGENT_MAX_STEPS=20
121
150
  ```
122
151
 
package/agent.js CHANGED
@@ -19,7 +19,8 @@ export class Agent {
19
19
  return new Promise((resolve, reject) => {
20
20
  console.error('[Agent] 正在启动 npx @atlisp/mcp...');
21
21
 
22
- const mcpProc = spawn('npx', ['-y', '@atlisp/mcp', '--http'], {
22
+ const npxCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
23
+ const mcpProc = spawn(`${npxCmd} -y @atlisp/mcp --http`, {
23
24
  stdio: ['ignore', 'pipe', 'pipe'],
24
25
  detached: true,
25
26
  shell: true,
package/config.js CHANGED
@@ -15,6 +15,45 @@ function getConfigDir() {
15
15
  return path.join(os.homedir(), '.atlisp');
16
16
  }
17
17
 
18
+ function getEnvPath() {
19
+ return path.join(os.homedir(), '.atlisp', '.env');
20
+ }
21
+
22
+ function loadEnvFile() {
23
+ const envPath = getEnvPath();
24
+ const envVars = {};
25
+
26
+ if (fs.existsSync(envPath)) {
27
+ try {
28
+ const content = fs.readFileSync(envPath, 'utf-8');
29
+ const lines = content.split('\n');
30
+ for (const line of lines) {
31
+ const trimmed = line.trim();
32
+ if (!trimmed || trimmed.startsWith('#')) continue;
33
+ const idx = trimmed.indexOf('=');
34
+ if (idx > 0) {
35
+ const key = trimmed.substring(0, idx).trim();
36
+ let val = trimmed.substring(idx + 1).trim();
37
+ if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
38
+ val = val.slice(1, -1);
39
+ }
40
+ envVars[key] = val;
41
+ }
42
+ }
43
+ } catch (e) {
44
+ console.error(`[Config] .env 文件加载失败: ${e.message}`);
45
+ }
46
+ }
47
+
48
+ for (const [key, val] of Object.entries(process.env)) {
49
+ if (val !== undefined && val !== '') {
50
+ envVars[key] = val;
51
+ }
52
+ }
53
+
54
+ return envVars;
55
+ }
56
+
18
57
  function getDefaultConfig() {
19
58
  return {
20
59
  agent: {
@@ -108,15 +147,42 @@ function getConfig() {
108
147
  }
109
148
 
110
149
  export function getAgentConfig() {
111
- return getConfig().agent;
150
+ const config = getConfig().agent;
151
+ const envVars = loadEnvFile();
152
+
153
+ const envOverrides = {};
154
+ if (envVars.AGENT_ENABLED) envOverrides.enabled = envVars.AGENT_ENABLED === 'true';
155
+ if (envVars.AGENT_MAX_STEPS) envOverrides.maxSteps = parseInt(envVars.AGENT_MAX_STEPS);
156
+ if (envVars.AGENT_VERBOSE) envOverrides.verbose = envVars.AGENT_VERBOSE === 'true';
157
+
158
+ return { ...config, ...envOverrides };
112
159
  }
113
160
 
114
161
  export function getLlmConfig() {
115
- return getConfig().llm;
162
+ const config = getConfig().llm;
163
+ const envVars = loadEnvFile();
164
+
165
+ const envOverrides = {};
166
+ if (envVars.LLM_PROVIDER) envOverrides.provider = envVars.LLM_PROVIDER;
167
+ if (envVars.LLM_BASE_URL) envOverrides.baseURL = envVars.LLM_BASE_URL;
168
+ if (envVars.LLM_MODEL) envOverrides.model = envVars.LLM_MODEL;
169
+ if (envVars.LLM_API_KEY) envOverrides.apiKey = envVars.LLM_API_KEY;
170
+ if (envVars.LLM_TEMPERATURE) envOverrides.temperature = parseFloat(envVars.LLM_TEMPERATURE);
171
+ if (envVars.LLM_MAX_TOKENS) envOverrides.maxTokens = parseInt(envVars.LLM_MAX_TOKENS);
172
+
173
+ return { ...config, ...envOverrides };
116
174
  }
117
175
 
118
176
  export function getMcpConfig() {
119
- return getConfig().mcp;
177
+ const config = getConfig().mcp;
178
+ const envVars = loadEnvFile();
179
+
180
+ const envOverrides = {};
181
+ if (envVars.MCP_MODE) envOverrides.mode = envVars.MCP_MODE;
182
+ if (envVars.MCP_URL) envOverrides.url = envVars.MCP_URL;
183
+ if (envVars.MCP_COMMAND) envOverrides.command = envVars.MCP_COMMAND;
184
+
185
+ return { ...config, ...envOverrides };
120
186
  }
121
187
 
122
188
  export { getConfig };
@@ -16,8 +16,9 @@ export class StdioMcpClient {
16
16
  async connect() {
17
17
  return new Promise((resolve, reject) => {
18
18
  try {
19
- const npxPath = process.platform === 'win32' ? 'npx.cmd' : 'npx';
20
- this.proc = spawn(npxPath, ['-y', this.command, ...this.args], {
19
+ const npxCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
20
+ const cmdStr = `${npxCmd} -y ${this.command} ${this.args.join(' ')}`;
21
+ this.proc = spawn(cmdStr, {
21
22
  stdio: ['pipe', 'pipe', 'pipe'],
22
23
  shell: true,
23
24
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlisp/agent",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "AI Agent for @lisp - Connects to MCP Server for CAD operations",
5
5
  "type": "module",
6
6
  "main": "index.js",