ai-world-sdk 1.5.12 → 1.5.15
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/dist/__tests__/config-dotenv.test.d.ts +1 -0
- package/dist/__tests__/config-dotenv.test.js +131 -0
- package/dist/cli/commands/config-cmd.js +1 -1
- package/dist/cli/config.js +3 -2
- package/dist/config.d.ts +9 -3
- package/dist/config.js +47 -6
- package/dist/llm.js +3 -3
- package/dist/login.js +6 -2
- package/dist/vite-plugin.js +3 -1
- package/package.json +2 -3
- package/skills/ai-world-sdk/SKILL.md +1 -0
- package/skills/ai-world-sdk/docs/cli-usage.md +7 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const fs = __importStar(require("fs"));
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const TEST_DIR = path.join(__dirname, "__config_dotenv_test_tmp__");
|
|
39
|
+
beforeEach(() => {
|
|
40
|
+
if (!fs.existsSync(TEST_DIR)) {
|
|
41
|
+
fs.mkdirSync(TEST_DIR, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
// 清除相关环境变量
|
|
44
|
+
delete process.env.AI_WORLD_TOKEN;
|
|
45
|
+
delete process.env.DEBUG_TOKEN;
|
|
46
|
+
delete process.env.DEBUG;
|
|
47
|
+
delete process.env.PLUGIN_ID;
|
|
48
|
+
delete process.env.AI_WORLD_BASE_URL;
|
|
49
|
+
delete process.env.AI_WORLD_ENV_FILE;
|
|
50
|
+
});
|
|
51
|
+
afterEach(() => {
|
|
52
|
+
if (fs.existsSync(TEST_DIR)) {
|
|
53
|
+
fs.rmSync(TEST_DIR, { recursive: true, force: true });
|
|
54
|
+
}
|
|
55
|
+
delete process.env.AI_WORLD_TOKEN;
|
|
56
|
+
delete process.env.DEBUG_TOKEN;
|
|
57
|
+
delete process.env.DEBUG;
|
|
58
|
+
delete process.env.PLUGIN_ID;
|
|
59
|
+
delete process.env.AI_WORLD_BASE_URL;
|
|
60
|
+
delete process.env.AI_WORLD_ENV_FILE;
|
|
61
|
+
jest.resetModules();
|
|
62
|
+
});
|
|
63
|
+
describe("SDKConfig dotenv loading", () => {
|
|
64
|
+
it("loads AI_WORLD_TOKEN from .env file", () => {
|
|
65
|
+
const envPath = path.join(TEST_DIR, ".env");
|
|
66
|
+
fs.writeFileSync(envPath, "AI_WORLD_TOKEN=token-from-env\n");
|
|
67
|
+
const originalCwd = process.cwd();
|
|
68
|
+
jest.spyOn(process, "cwd").mockReturnValue(TEST_DIR);
|
|
69
|
+
jest.resetModules();
|
|
70
|
+
const { sdkConfig } = require("../config");
|
|
71
|
+
expect(sdkConfig.getToken()).toBe("token-from-env");
|
|
72
|
+
jest.spyOn(process, "cwd").mockReturnValue(originalCwd);
|
|
73
|
+
});
|
|
74
|
+
it(".env.local overrides .env", () => {
|
|
75
|
+
fs.writeFileSync(path.join(TEST_DIR, ".env"), "AI_WORLD_TOKEN=from-env\n");
|
|
76
|
+
fs.writeFileSync(path.join(TEST_DIR, ".env.local"), "AI_WORLD_TOKEN=from-env-local\n");
|
|
77
|
+
jest.spyOn(process, "cwd").mockReturnValue(TEST_DIR);
|
|
78
|
+
jest.resetModules();
|
|
79
|
+
const { sdkConfig } = require("../config");
|
|
80
|
+
expect(sdkConfig.getToken()).toBe("from-env-local");
|
|
81
|
+
});
|
|
82
|
+
it("process.env overrides .env.local", () => {
|
|
83
|
+
fs.writeFileSync(path.join(TEST_DIR, ".env.local"), "AI_WORLD_TOKEN=from-file\n");
|
|
84
|
+
process.env.AI_WORLD_TOKEN = "from-process-env";
|
|
85
|
+
jest.spyOn(process, "cwd").mockReturnValue(TEST_DIR);
|
|
86
|
+
jest.resetModules();
|
|
87
|
+
const { sdkConfig } = require("../config");
|
|
88
|
+
expect(sdkConfig.getToken()).toBe("from-process-env");
|
|
89
|
+
});
|
|
90
|
+
it("loads custom env file via AI_WORLD_ENV_FILE (lowest priority)", () => {
|
|
91
|
+
const customPath = path.join(TEST_DIR, ".env.custom");
|
|
92
|
+
fs.writeFileSync(customPath, "AI_WORLD_TOKEN=from-custom\nPLUGIN_ID=custom-plugin\n");
|
|
93
|
+
process.env.AI_WORLD_ENV_FILE = customPath;
|
|
94
|
+
jest.spyOn(process, "cwd").mockReturnValue(TEST_DIR);
|
|
95
|
+
jest.resetModules();
|
|
96
|
+
const { sdkConfig } = require("../config");
|
|
97
|
+
expect(sdkConfig.getToken()).toBe("from-custom");
|
|
98
|
+
expect(sdkConfig.getPluginId()).toBe("custom-plugin");
|
|
99
|
+
});
|
|
100
|
+
it("custom env file does not override .env.local", () => {
|
|
101
|
+
fs.writeFileSync(path.join(TEST_DIR, ".env.local"), "AI_WORLD_TOKEN=from-local\n");
|
|
102
|
+
const customPath = path.join(TEST_DIR, ".env.custom");
|
|
103
|
+
fs.writeFileSync(customPath, "AI_WORLD_TOKEN=from-custom\nPLUGIN_ID=custom-plugin\n");
|
|
104
|
+
process.env.AI_WORLD_ENV_FILE = customPath;
|
|
105
|
+
jest.spyOn(process, "cwd").mockReturnValue(TEST_DIR);
|
|
106
|
+
jest.resetModules();
|
|
107
|
+
const { sdkConfig } = require("../config");
|
|
108
|
+
expect(sdkConfig.getToken()).toBe("from-local");
|
|
109
|
+
expect(sdkConfig.getPluginId()).toBe("custom-plugin");
|
|
110
|
+
});
|
|
111
|
+
it("loads AI_WORLD_BASE_URL from .env", () => {
|
|
112
|
+
fs.writeFileSync(path.join(TEST_DIR, ".env"), "AI_WORLD_BASE_URL=https://my-server.com/\n");
|
|
113
|
+
jest.spyOn(process, "cwd").mockReturnValue(TEST_DIR);
|
|
114
|
+
jest.resetModules();
|
|
115
|
+
const { sdkConfig } = require("../config");
|
|
116
|
+
expect(sdkConfig.getServerUrl()).toBe("https://my-server.com");
|
|
117
|
+
});
|
|
118
|
+
it("loads DEBUG_TOKEN as fallback when AI_WORLD_TOKEN is not set", () => {
|
|
119
|
+
fs.writeFileSync(path.join(TEST_DIR, ".env.local"), "DEBUG_TOKEN=debug-fallback\n");
|
|
120
|
+
jest.spyOn(process, "cwd").mockReturnValue(TEST_DIR);
|
|
121
|
+
jest.resetModules();
|
|
122
|
+
const { sdkConfig } = require("../config");
|
|
123
|
+
expect(sdkConfig.getToken()).toBe("debug-fallback");
|
|
124
|
+
});
|
|
125
|
+
it("works when no .env files exist", () => {
|
|
126
|
+
jest.spyOn(process, "cwd").mockReturnValue(TEST_DIR);
|
|
127
|
+
jest.resetModules();
|
|
128
|
+
const { sdkConfig } = require("../config");
|
|
129
|
+
expect(sdkConfig.getToken()).toBeNull();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
@@ -72,7 +72,7 @@ function registerConfigCommands(program) {
|
|
|
72
72
|
merged[key] = {
|
|
73
73
|
value: val,
|
|
74
74
|
source: key === 'token'
|
|
75
|
-
? (saved.token ? 'config' : (process.env.DEBUG_TOKEN ? 'env' : 'none'))
|
|
75
|
+
? (saved.token ? 'config' : (process.env.AI_WORLD_TOKEN || process.env.DEBUG_TOKEN ? 'env' : 'none'))
|
|
76
76
|
: (hasSaved ? 'config' : (val !== null ? 'default' : 'none')),
|
|
77
77
|
};
|
|
78
78
|
}
|
package/dist/cli/config.js
CHANGED
|
@@ -95,7 +95,7 @@ function getEffectiveConfig() {
|
|
|
95
95
|
const result = {};
|
|
96
96
|
for (const key of VALID_KEYS) {
|
|
97
97
|
if (key === 'token') {
|
|
98
|
-
result[key] = config.token || process.env.DEBUG_TOKEN || null;
|
|
98
|
+
result[key] = config.token || process.env.AI_WORLD_TOKEN || process.env.DEBUG_TOKEN || null;
|
|
99
99
|
}
|
|
100
100
|
else {
|
|
101
101
|
result[key] = config[key] || DEFAULTS[key] || null;
|
|
@@ -109,7 +109,7 @@ function getConfigValue(key) {
|
|
|
109
109
|
function getEffectiveValue(key) {
|
|
110
110
|
const config = readConfig();
|
|
111
111
|
if (key === 'token') {
|
|
112
|
-
return config.token || process.env.DEBUG_TOKEN || null;
|
|
112
|
+
return config.token || process.env.AI_WORLD_TOKEN || process.env.DEBUG_TOKEN || null;
|
|
113
113
|
}
|
|
114
114
|
return config[key] || DEFAULTS[key] || null;
|
|
115
115
|
}
|
|
@@ -144,6 +144,7 @@ function resolveAuth(opts) {
|
|
|
144
144
|
config['base-url'] ||
|
|
145
145
|
'https://aiworld.local:8000',
|
|
146
146
|
token: opts.token ||
|
|
147
|
+
process.env.AI_WORLD_TOKEN ||
|
|
147
148
|
process.env.DEBUG_TOKEN ||
|
|
148
149
|
config.token ||
|
|
149
150
|
null,
|
package/dist/config.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 注意: {VERSION} 占位符会在构建时被替换为实际版本号
|
|
11
11
|
*/
|
|
12
|
-
export declare const SDK_SIGNATURE = "AI_WORLD_SDK_V:1.5.
|
|
12
|
+
export declare const SDK_SIGNATURE = "AI_WORLD_SDK_V:1.5.15";
|
|
13
13
|
/**
|
|
14
14
|
* 版本兼容性错误
|
|
15
15
|
*/
|
|
@@ -35,8 +35,8 @@ declare class SDKConfig {
|
|
|
35
35
|
private _authCheckPromise;
|
|
36
36
|
private _currentUser;
|
|
37
37
|
private _cliMode;
|
|
38
|
-
readonly sdkSignature = "AI_WORLD_SDK_V:1.5.
|
|
39
|
-
readonly sdkVersion = "1.5.
|
|
38
|
+
readonly sdkSignature = "AI_WORLD_SDK_V:1.5.15";
|
|
39
|
+
readonly sdkVersion = "1.5.15";
|
|
40
40
|
constructor();
|
|
41
41
|
/**
|
|
42
42
|
* Set global base URL
|
|
@@ -94,6 +94,12 @@ declare class SDKConfig {
|
|
|
94
94
|
*/
|
|
95
95
|
checkAuthentication(): Promise<boolean>;
|
|
96
96
|
private _performAuthCheck;
|
|
97
|
+
/**
|
|
98
|
+
* 加载 .env 文件到 process.env
|
|
99
|
+
* 优先级(高 → 低):已有 process.env > .env.local > .env > AI_WORLD_ENV_FILE 指定文件
|
|
100
|
+
* dotenv 默认不覆盖已存在的环境变量,按优先级从高到低加载即可
|
|
101
|
+
*/
|
|
102
|
+
private _loadDotenv;
|
|
97
103
|
private _nodeAuthCheck;
|
|
98
104
|
/**
|
|
99
105
|
* 获取当前登录状态
|
package/dist/config.js
CHANGED
|
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.sdkConfig = exports.VersionCompatibilityError = exports.SDK_SIGNATURE = void 0;
|
|
8
8
|
// SDK 版本号(构建时自动从 package.json 更新)
|
|
9
9
|
// 此版本号会在运行 npm run build 时自动从 package.json 读取并更新
|
|
10
|
-
const SDK_VERSION = "1.5.
|
|
10
|
+
const SDK_VERSION = "1.5.15";
|
|
11
11
|
/**
|
|
12
12
|
* SDK 特征码 - 用于在构建后的 JS 文件中识别 SDK 版本
|
|
13
13
|
* 格式: AI_WORLD_SDK_V:版本号
|
|
@@ -15,7 +15,7 @@ const SDK_VERSION = "1.5.12";
|
|
|
15
15
|
*
|
|
16
16
|
* 注意: {VERSION} 占位符会在构建时被替换为实际版本号
|
|
17
17
|
*/
|
|
18
|
-
exports.SDK_SIGNATURE = "AI_WORLD_SDK_V:1.5.
|
|
18
|
+
exports.SDK_SIGNATURE = "AI_WORLD_SDK_V:1.5.15";
|
|
19
19
|
/**
|
|
20
20
|
* 版本兼容性错误
|
|
21
21
|
*/
|
|
@@ -95,11 +95,18 @@ class SDKConfig {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
else {
|
|
98
|
-
// 非浏览器环境(Node.js / Vite dev
|
|
98
|
+
// 非浏览器环境(Node.js / Vite dev):先加载 .env 文件,再从 process.env 读取
|
|
99
99
|
try {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
this._loadDotenv();
|
|
101
|
+
const token = typeof process !== 'undefined' && process.env?.AI_WORLD_TOKEN;
|
|
102
|
+
if (token) {
|
|
103
|
+
this._token = token;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
const debugToken = typeof process !== 'undefined' && process.env?.DEBUG_TOKEN;
|
|
107
|
+
if (debugToken) {
|
|
108
|
+
this._token = debugToken;
|
|
109
|
+
}
|
|
103
110
|
}
|
|
104
111
|
const debugFlag = typeof process !== 'undefined' && process.env?.DEBUG;
|
|
105
112
|
if (debugFlag === 'true') {
|
|
@@ -273,6 +280,40 @@ class SDKConfig {
|
|
|
273
280
|
return false;
|
|
274
281
|
}
|
|
275
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* 加载 .env 文件到 process.env
|
|
285
|
+
* 优先级(高 → 低):已有 process.env > .env.local > .env > AI_WORLD_ENV_FILE 指定文件
|
|
286
|
+
* dotenv 默认不覆盖已存在的环境变量,按优先级从高到低加载即可
|
|
287
|
+
*/
|
|
288
|
+
_loadDotenv() {
|
|
289
|
+
try {
|
|
290
|
+
const dotenv = require('dotenv');
|
|
291
|
+
const path = require('path');
|
|
292
|
+
const fs = require('fs');
|
|
293
|
+
const cwd = process.cwd();
|
|
294
|
+
// .env.local 优先级最高(仅次于已有 process.env)
|
|
295
|
+
const envLocalPath = path.resolve(cwd, '.env.local');
|
|
296
|
+
if (fs.existsSync(envLocalPath)) {
|
|
297
|
+
dotenv.config({ path: envLocalPath });
|
|
298
|
+
}
|
|
299
|
+
// .env 次之
|
|
300
|
+
const envPath = path.resolve(cwd, '.env');
|
|
301
|
+
if (fs.existsSync(envPath)) {
|
|
302
|
+
dotenv.config({ path: envPath });
|
|
303
|
+
}
|
|
304
|
+
// 用户通过 AI_WORLD_ENV_FILE 指定自定义 .env 文件(最低优先级)
|
|
305
|
+
const customEnvFile = process.env.AI_WORLD_ENV_FILE;
|
|
306
|
+
if (customEnvFile) {
|
|
307
|
+
const customPath = path.isAbsolute(customEnvFile) ? customEnvFile : path.resolve(cwd, customEnvFile);
|
|
308
|
+
if (fs.existsSync(customPath)) {
|
|
309
|
+
dotenv.config({ path: customPath });
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
// dotenv 不可用或文件加载失败时静默忽略
|
|
315
|
+
}
|
|
316
|
+
}
|
|
276
317
|
_nodeAuthCheck(baseUrl, token) {
|
|
277
318
|
return new Promise((resolve) => {
|
|
278
319
|
try {
|
package/dist/llm.js
CHANGED
|
@@ -7,7 +7,7 @@ const google_1 = require("@ai-sdk/google");
|
|
|
7
7
|
const openai_1 = require("@ai-sdk/openai");
|
|
8
8
|
const config_1 = require("./config");
|
|
9
9
|
const ai_1 = require("ai");
|
|
10
|
-
const
|
|
10
|
+
const dist_1 = require("../pacakges/ai-sdk-provider/dist");
|
|
11
11
|
/**
|
|
12
12
|
* 根据端点类型创建 ai-sdk ProviderV3
|
|
13
13
|
* 所有请求会通过后端代理(/api/llm/{endpointType})转发到实际 API
|
|
@@ -30,11 +30,11 @@ function createProvider(provider, endpointType, pluginId) {
|
|
|
30
30
|
};
|
|
31
31
|
if (provider === "openrouter") {
|
|
32
32
|
settings.baseURL = `${serverUrl}/api/llm/openrouter`;
|
|
33
|
-
return (0,
|
|
33
|
+
return (0, dist_1.createOpenRouter)(settings);
|
|
34
34
|
}
|
|
35
35
|
else if (provider === "kunpo") {
|
|
36
36
|
settings.baseURL = `${serverUrl}/api/llm/kunpo`;
|
|
37
|
-
return (0,
|
|
37
|
+
return (0, dist_1.createOpenRouter)(settings);
|
|
38
38
|
}
|
|
39
39
|
switch (endpointType) {
|
|
40
40
|
case "openai":
|
package/dist/login.js
CHANGED
|
@@ -98,9 +98,13 @@ function validateToken(baseUrl, token) {
|
|
|
98
98
|
res.resume();
|
|
99
99
|
resolve(res.statusCode !== undefined && res.statusCode >= 200 && res.statusCode < 300);
|
|
100
100
|
});
|
|
101
|
-
req.on("error", () =>
|
|
101
|
+
req.on("error", (e) => {
|
|
102
|
+
console.error(`[ai-world] 验证 token 失败: `, e);
|
|
103
|
+
resolve(false);
|
|
104
|
+
});
|
|
102
105
|
}
|
|
103
|
-
catch {
|
|
106
|
+
catch (e) {
|
|
107
|
+
console.error(`[ai-world] 验证 token 失败: `, e);
|
|
104
108
|
resolve(false);
|
|
105
109
|
}
|
|
106
110
|
});
|
package/dist/vite-plugin.js
CHANGED
|
@@ -26,6 +26,8 @@ function aiWorldPlugin(options = {}) {
|
|
|
26
26
|
const config = { baseUrl };
|
|
27
27
|
if (env["DEBUG_TOKEN"])
|
|
28
28
|
config.token = env["DEBUG_TOKEN"];
|
|
29
|
+
if (env["AI_WORLD_TOKEN"])
|
|
30
|
+
config.token = env["AI_WORLD_TOKEN"];
|
|
29
31
|
if (env["PLUGIN_ID"])
|
|
30
32
|
config.pluginId = env["PLUGIN_ID"];
|
|
31
33
|
if (env["DEBUG"] === "true")
|
|
@@ -43,7 +45,7 @@ function aiWorldPlugin(options = {}) {
|
|
|
43
45
|
if (hasLoggedIn)
|
|
44
46
|
return;
|
|
45
47
|
const env = (0, login_1.readEnvLocal)(projectRoot);
|
|
46
|
-
const existingToken = env["DEBUG_TOKEN"] || process.env.DEBUG_TOKEN;
|
|
48
|
+
const existingToken = env["DEBUG_TOKEN"] || process.env.DEBUG_TOKEN || env["AI_WORLD_TOKEN"] || process.env.AI_WORLD_TOKEN;
|
|
47
49
|
// 确保 PLUGIN_ID 存在,不存在则从 plugin.json 或目录名推断
|
|
48
50
|
if (!env["PLUGIN_ID"] && !process.env.PLUGIN_ID) {
|
|
49
51
|
const pluginId = (0, login_1.resolvePluginId)(projectRoot);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-world-sdk",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.15",
|
|
4
4
|
"description": "TypeScript SDK for AI World Platform - Chat Models, Image Generation, and Video Generation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -63,11 +63,9 @@
|
|
|
63
63
|
"author": "ai-world",
|
|
64
64
|
"license": "MIT",
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@types/dotenv": "^8.2.0",
|
|
67
66
|
"@types/jest": "^29.5.0",
|
|
68
67
|
"@types/node": "^20.0.0",
|
|
69
68
|
"@types/vscode": "^1.110.0",
|
|
70
|
-
"dotenv": "^16.0.0",
|
|
71
69
|
"jest": "^29.5.0",
|
|
72
70
|
"ts-jest": "^29.1.0",
|
|
73
71
|
"ts-node": "^10.9.2",
|
|
@@ -86,6 +84,7 @@
|
|
|
86
84
|
"@openrouter/ai-sdk-provider": "./pacakges/ai-sdk-provider",
|
|
87
85
|
"ai": "^6.0.162",
|
|
88
86
|
"commander": "^14.0.3",
|
|
87
|
+
"dotenv": "^16.0.0",
|
|
89
88
|
"undici": "^8.1.0"
|
|
90
89
|
}
|
|
91
90
|
}
|
|
@@ -5,12 +5,15 @@
|
|
|
5
5
|
## 安装
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
#
|
|
8
|
+
# 全局安装(CLI 工具)
|
|
9
9
|
npm install -g ai-world-sdk
|
|
10
10
|
|
|
11
11
|
# 或临时使用(无需安装)
|
|
12
12
|
npx ai-world-sdk <command>
|
|
13
13
|
npx ai-world <command>
|
|
14
|
+
|
|
15
|
+
# 项目中作为依赖安装(用于打包/开发)
|
|
16
|
+
npm install ai-world-sdk ai
|
|
14
17
|
```
|
|
15
18
|
|
|
16
19
|
## 认证
|
|
@@ -33,14 +36,14 @@ ai-world login --token <your-jwt-token>
|
|
|
33
36
|
|
|
34
37
|
```bash
|
|
35
38
|
export AI_WORLD_BASE_URL=https://aiworld.local:8000
|
|
36
|
-
export
|
|
39
|
+
export AI_WORLD_TOKEN=your-jwt-token
|
|
37
40
|
export PLUGIN_ID=my-plugin
|
|
38
41
|
```
|
|
39
42
|
|
|
40
43
|
### 认证优先级(从高到低)
|
|
41
44
|
|
|
42
45
|
1. 命令行参数:`--token`、`--base-url`、`--plugin-id`
|
|
43
|
-
2. 环境变量:`
|
|
46
|
+
2. 环境变量:`AI_WORLD_TOKEN`、`AI_WORLD_BASE_URL`、`PLUGIN_ID`
|
|
44
47
|
3. 本地配置文件:`~/.ai-world/config.json`
|
|
45
48
|
4. 默认值:base-url=`https://aiworld.local:8000`,plugin-id=`cli`,provider=`kunpo`,endpoint=`openai`,model=`deepseek/deepseek-v4-pro`
|
|
46
49
|
|
|
@@ -114,7 +117,7 @@ $ ai-world plugin list --format table
|
|
|
114
117
|
"code": "AUTH_REQUIRED",
|
|
115
118
|
"message": "未认证",
|
|
116
119
|
"details": {
|
|
117
|
-
"checked_sources": ["--token flag", "
|
|
120
|
+
"checked_sources": ["--token flag", "AI_WORLD_TOKEN env", "~/.ai-world/config.json"],
|
|
118
121
|
"suggestion": "运行 `ai-world auth login`"
|
|
119
122
|
},
|
|
120
123
|
"command": "ai-world resource list",
|