openclaw-stepfun 0.2.2
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/LICENSE +21 -0
- package/README.md +61 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +18 -0
- package/dist/src/accounts.d.ts +22 -0
- package/dist/src/accounts.js +43 -0
- package/dist/src/bot.d.ts +16 -0
- package/dist/src/bot.js +100 -0
- package/dist/src/channel.d.ts +4 -0
- package/dist/src/channel.js +206 -0
- package/dist/src/client.d.ts +51 -0
- package/dist/src/client.js +206 -0
- package/dist/src/monitor.d.ts +19 -0
- package/dist/src/monitor.js +153 -0
- package/dist/src/proto/capy/botauth/auth_common_pb.d.ts +82 -0
- package/dist/src/proto/capy/botauth/auth_common_pb.js +35 -0
- package/dist/src/proto/capy/botauth/botauth_connect.d.ts +118 -0
- package/dist/src/proto/capy/botauth/botauth_connect.js +118 -0
- package/dist/src/proto/capy/botauth/botauth_pb.d.ts +1065 -0
- package/dist/src/proto/capy/botauth/botauth_pb.js +348 -0
- package/dist/src/proto/capy/botauth/public_connect.d.ts +62 -0
- package/dist/src/proto/capy/botauth/public_connect.js +62 -0
- package/dist/src/proto/capy/botauth/public_pb.d.ts +254 -0
- package/dist/src/proto/capy/botauth/public_pb.js +105 -0
- package/dist/src/proto/capy/botmsg/botmsg_connect.d.ts +72 -0
- package/dist/src/proto/capy/botmsg/botmsg_connect.js +72 -0
- package/dist/src/proto/capy/botmsg/botmsg_pb.d.ts +426 -0
- package/dist/src/proto/capy/botmsg/botmsg_pb.js +160 -0
- package/dist/src/proto/capy/botway/ctrl_connect.d.ts +61 -0
- package/dist/src/proto/capy/botway/ctrl_connect.js +61 -0
- package/dist/src/proto/capy/botway/ctrl_pb.d.ts +267 -0
- package/dist/src/proto/capy/botway/ctrl_pb.js +120 -0
- package/dist/src/proto/capy/botway/stream_connect.d.ts +26 -0
- package/dist/src/proto/capy/botway/stream_connect.js +26 -0
- package/dist/src/proto/capy/botway/stream_pb.d.ts +495 -0
- package/dist/src/proto/capy/botway/stream_pb.js +165 -0
- package/dist/src/reply-dispatcher.d.ts +17 -0
- package/dist/src/reply-dispatcher.js +234 -0
- package/dist/src/runtime.d.ts +4 -0
- package/dist/src/runtime.js +11 -0
- package/dist/src/send.d.ts +19 -0
- package/dist/src/send.js +66 -0
- package/dist/src/types.d.ts +65 -0
- package/dist/src/types.js +2 -0
- package/dist/src/websocket/cacheEvent.d.ts +17 -0
- package/dist/src/websocket/cacheEvent.js +61 -0
- package/dist/src/websocket/connect.d.ts +32 -0
- package/dist/src/websocket/connect.js +79 -0
- package/dist/src/websocket/constant.d.ts +8 -0
- package/dist/src/websocket/constant.js +10 -0
- package/dist/src/websocket/eventBus.d.ts +15 -0
- package/dist/src/websocket/eventBus.js +46 -0
- package/dist/src/websocket/index.d.ts +117 -0
- package/dist/src/websocket/index.js +637 -0
- package/dist/src/websocket/service.d.ts +36 -0
- package/dist/src/websocket/service.js +4 -0
- package/dist/src/websocket/stream.d.ts +10 -0
- package/dist/src/websocket/stream.js +24 -0
- package/dist/src/websocket/streamConnect.d.ts +40 -0
- package/dist/src/websocket/streamConnect.js +48 -0
- package/openclaw.plugin.json +23 -0
- package/package.json +69 -0
- package/scripts/setup.mjs +381 -0
- package/scripts/switch-env.mjs +98 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const stream = (method, payload) => {
|
|
2
|
+
// const createRequest = () => { }
|
|
3
|
+
// const request = method(payload, {
|
|
4
|
+
// })
|
|
5
|
+
const callbacks = {};
|
|
6
|
+
return {
|
|
7
|
+
start(cb) {
|
|
8
|
+
callbacks.onStart = cb;
|
|
9
|
+
return this;
|
|
10
|
+
},
|
|
11
|
+
on(cb) {
|
|
12
|
+
callbacks.onData = cb;
|
|
13
|
+
return this;
|
|
14
|
+
},
|
|
15
|
+
do() {
|
|
16
|
+
return method(payload, callbacks, false);
|
|
17
|
+
},
|
|
18
|
+
error(cb) {
|
|
19
|
+
callbacks.onError = cb;
|
|
20
|
+
return this;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { MethodKind } from "@bufbuild/protobuf";
|
|
2
|
+
import { Empty } from "@bufbuild/protobuf";
|
|
3
|
+
import { AuthBindReq, AuthBindRes, ErrorRes, HeartbeatReq, HeartbeatRes, LogoutReq, StreamMsg } from "../proto/capy/botway/stream_pb.js";
|
|
4
|
+
/**
|
|
5
|
+
* @generated from service step.raccoon.gateway.Stream
|
|
6
|
+
*/
|
|
7
|
+
export declare const Stream: {
|
|
8
|
+
typeName: string;
|
|
9
|
+
methods: {
|
|
10
|
+
auth: {
|
|
11
|
+
name: string;
|
|
12
|
+
I: typeof AuthBindReq;
|
|
13
|
+
O: typeof AuthBindRes;
|
|
14
|
+
kind: MethodKind;
|
|
15
|
+
};
|
|
16
|
+
logout: {
|
|
17
|
+
name: string;
|
|
18
|
+
I: typeof LogoutReq;
|
|
19
|
+
O: typeof Empty;
|
|
20
|
+
kind: MethodKind;
|
|
21
|
+
};
|
|
22
|
+
heartbeat: {
|
|
23
|
+
name: string;
|
|
24
|
+
I: typeof HeartbeatReq;
|
|
25
|
+
O: typeof HeartbeatRes;
|
|
26
|
+
kind: MethodKind;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* @generated from rpc step.raccoon.gateway.Stream.Process
|
|
30
|
+
*/
|
|
31
|
+
process: {
|
|
32
|
+
name: string;
|
|
33
|
+
I: typeof StreamMsg;
|
|
34
|
+
O: typeof StreamMsg;
|
|
35
|
+
kind: MethodKind;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export { ErrorRes, StreamMsg, AuthBindReq, AuthBindRes, HeartbeatReq, HeartbeatRes, LogoutReq, };
|
|
40
|
+
//# sourceMappingURL=streamConnect.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { MethodKind } from "@bufbuild/protobuf";
|
|
2
|
+
import { Empty } from "@bufbuild/protobuf";
|
|
3
|
+
import { AuthBindReq, AuthBindRes, ErrorRes, HeartbeatReq, HeartbeatRes, LogoutReq, StreamMsg, } from "../proto/capy/botway/stream_pb.js";
|
|
4
|
+
/**
|
|
5
|
+
* @generated from service step.raccoon.gateway.Stream
|
|
6
|
+
*/
|
|
7
|
+
export const Stream = {
|
|
8
|
+
typeName: "step.capy.botway.Stream",
|
|
9
|
+
methods: {
|
|
10
|
+
auth: {
|
|
11
|
+
name: "Auth",
|
|
12
|
+
// biome-ignore lint/style/useNamingConvention: <explanation>
|
|
13
|
+
I: AuthBindReq,
|
|
14
|
+
// biome-ignore lint/style/useNamingConvention: <explanation>
|
|
15
|
+
O: AuthBindRes,
|
|
16
|
+
kind: MethodKind.Unary,
|
|
17
|
+
},
|
|
18
|
+
logout: {
|
|
19
|
+
name: "Logout",
|
|
20
|
+
// biome-ignore lint/style/useNamingConvention: <explanation>
|
|
21
|
+
I: LogoutReq,
|
|
22
|
+
// biome-ignore lint/style/useNamingConvention: <explanation>
|
|
23
|
+
O: Empty,
|
|
24
|
+
kind: MethodKind.Unary,
|
|
25
|
+
},
|
|
26
|
+
heartbeat: {
|
|
27
|
+
name: "Heartbeat",
|
|
28
|
+
// biome-ignore lint/style/useNamingConvention: <explanation>
|
|
29
|
+
I: HeartbeatReq,
|
|
30
|
+
// biome-ignore lint/style/useNamingConvention: <explanation>
|
|
31
|
+
O: HeartbeatRes,
|
|
32
|
+
kind: MethodKind.Unary,
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* @generated from rpc step.raccoon.gateway.Stream.Process
|
|
36
|
+
*/
|
|
37
|
+
process: {
|
|
38
|
+
name: "Process",
|
|
39
|
+
// biome-ignore lint/style/useNamingConvention: <explanation>
|
|
40
|
+
I: StreamMsg,
|
|
41
|
+
// biome-ignore lint/style/useNamingConvention: <explanation>
|
|
42
|
+
O: StreamMsg,
|
|
43
|
+
kind: MethodKind.BiDiStreaming,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
export { ErrorRes, StreamMsg, AuthBindReq, AuthBindRes, HeartbeatReq, HeartbeatRes, LogoutReq, };
|
|
48
|
+
//# sourceMappingURL=streamConnect.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "openclaw-stepfun",
|
|
3
|
+
"channels": ["stepfun"],
|
|
4
|
+
"configSchema": {
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"properties": {
|
|
8
|
+
"enabled": {
|
|
9
|
+
"type": "boolean",
|
|
10
|
+
"description": "Enable Stepfun channel",
|
|
11
|
+
"default": false
|
|
12
|
+
},
|
|
13
|
+
"appId": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "App ID for bot authentication"
|
|
16
|
+
},
|
|
17
|
+
"appToken": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "App token for WebSocket connection authentication"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openclaw-stepfun",
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "OpenClaw Stepfun WebSocket gateway channel plugin",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"openclaw",
|
|
9
|
+
"openclaw-plugin",
|
|
10
|
+
"stepfun",
|
|
11
|
+
"websocket",
|
|
12
|
+
"gateway",
|
|
13
|
+
"channel"
|
|
14
|
+
],
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist/**/*.js",
|
|
24
|
+
"dist/**/*.d.ts",
|
|
25
|
+
"scripts/setup.mjs",
|
|
26
|
+
"scripts/switch-env.mjs",
|
|
27
|
+
"openclaw.plugin.json",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc",
|
|
33
|
+
"prepublishOnly": "npm run build",
|
|
34
|
+
"switch:env:dev": "node scripts/switch-env.mjs dev",
|
|
35
|
+
"switch:env:publish": "node scripts/switch-env.mjs publish"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@bufbuild/protobuf": "1.7.2",
|
|
39
|
+
"@connectrpc/connect": "1.4.0",
|
|
40
|
+
"ws": "^8.18.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/ws": "^8.5.13",
|
|
44
|
+
"typescript": "^5.3.0"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"registry": "https://registry.npmjs.org/"
|
|
48
|
+
},
|
|
49
|
+
"openclaw": {
|
|
50
|
+
"extensions": [
|
|
51
|
+
"./dist/index.js"
|
|
52
|
+
],
|
|
53
|
+
"channel": {
|
|
54
|
+
"id": "stepfun",
|
|
55
|
+
"label": "OpenClaw Stepfun",
|
|
56
|
+
"selectionLabel": "OpenClaw Stepfun Gateway",
|
|
57
|
+
"docsPath": "/channels/openclaw-stepfun",
|
|
58
|
+
"docsLabel": "openclaw-stepfun",
|
|
59
|
+
"blurb": "Stepfun WebSocket gateway integration.",
|
|
60
|
+
"aliases": [],
|
|
61
|
+
"order": 80
|
|
62
|
+
},
|
|
63
|
+
"install": {
|
|
64
|
+
"npmSpec": "@openclaw/openclaw-stepfun",
|
|
65
|
+
"localPath": "extensions/openclaw-stepfun",
|
|
66
|
+
"defaultChoice": "local"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* OpenClaw Stepfun Plugin 安装配置脚本
|
|
4
|
+
* 在插件安装时交互式获取 appId、appToken
|
|
5
|
+
* 并自动配置 provider 和模型
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as readline from "readline";
|
|
9
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
10
|
+
import { join } from "path";
|
|
11
|
+
import { homedir } from "os";
|
|
12
|
+
|
|
13
|
+
// OpenClaw 配置文件路径
|
|
14
|
+
const OPENCLAW_CONFIG_DIR = join(homedir(), ".openclaw");
|
|
15
|
+
const OPENCLAW_CONFIG_FILE = join(OPENCLAW_CONFIG_DIR, "openclaw.json");
|
|
16
|
+
|
|
17
|
+
// 平台配置
|
|
18
|
+
const PLATFORMS = {
|
|
19
|
+
openrouter: {
|
|
20
|
+
name: "OpenRouter (限时免费)",
|
|
21
|
+
description: "通过 OpenRouter 接入,目前限时免费使用",
|
|
22
|
+
model: "openrouter/stepfun/step-3.5-flash:free",
|
|
23
|
+
},
|
|
24
|
+
stepfun: {
|
|
25
|
+
name: "StepFun 官方平台",
|
|
26
|
+
description: "直接使用 StepFun 官方 API",
|
|
27
|
+
model: "stepfun/step-3.5-flash",
|
|
28
|
+
// StepFun 自定义 provider 配置
|
|
29
|
+
provider: {
|
|
30
|
+
baseUrl: "https://api.stepfun.com/v1",
|
|
31
|
+
auth: "api-key",
|
|
32
|
+
api: "openai-completions"
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 异步提问
|
|
39
|
+
*/
|
|
40
|
+
function question(prompt) {
|
|
41
|
+
const rl = readline.createInterface({
|
|
42
|
+
input: process.stdin,
|
|
43
|
+
output: process.stdout,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return new Promise((resolve) => {
|
|
47
|
+
rl.question(prompt, (answer) => {
|
|
48
|
+
rl.close();
|
|
49
|
+
resolve(answer.trim());
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 隐藏输入的提问(用于敏感信息)
|
|
56
|
+
*/
|
|
57
|
+
function questionHidden(prompt) {
|
|
58
|
+
return new Promise((resolve) => {
|
|
59
|
+
const rl = readline.createInterface({
|
|
60
|
+
input: process.stdin,
|
|
61
|
+
output: process.stdout,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// 保存原始的 _writeToOutput
|
|
65
|
+
const originalWrite = rl._writeToOutput;
|
|
66
|
+
|
|
67
|
+
rl._writeToOutput = function (str) {
|
|
68
|
+
// 只显示 prompt,隐藏用户输入
|
|
69
|
+
if (str === prompt) {
|
|
70
|
+
originalWrite.call(rl, str);
|
|
71
|
+
} else if (str.includes("\n") || str.includes("\r")) {
|
|
72
|
+
// 回车时换行
|
|
73
|
+
originalWrite.call(rl, "\n");
|
|
74
|
+
} else {
|
|
75
|
+
// 用 * 替代输入字符
|
|
76
|
+
originalWrite.call(rl, "*");
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
rl.question(prompt, (answer) => {
|
|
81
|
+
rl._writeToOutput = originalWrite;
|
|
82
|
+
rl.close();
|
|
83
|
+
resolve(answer.trim());
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* 读取现有配置
|
|
90
|
+
*/
|
|
91
|
+
function loadConfig() {
|
|
92
|
+
try {
|
|
93
|
+
if (existsSync(OPENCLAW_CONFIG_FILE)) {
|
|
94
|
+
const content = readFileSync(OPENCLAW_CONFIG_FILE, "utf-8");
|
|
95
|
+
return JSON.parse(content);
|
|
96
|
+
}
|
|
97
|
+
} catch (err) {
|
|
98
|
+
console.warn("⚠️ 无法读取现有配置:", err.message);
|
|
99
|
+
}
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 保存配置
|
|
105
|
+
*/
|
|
106
|
+
function saveConfig(config) {
|
|
107
|
+
try {
|
|
108
|
+
// 确保配置目录存在
|
|
109
|
+
if (!existsSync(OPENCLAW_CONFIG_DIR)) {
|
|
110
|
+
mkdirSync(OPENCLAW_CONFIG_DIR, { recursive: true });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
writeFileSync(OPENCLAW_CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
|
|
114
|
+
return true;
|
|
115
|
+
} catch (err) {
|
|
116
|
+
console.error("✗ 保存配置失败:", err.message);
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* 配置环境变量(仅 OpenRouter 需要)
|
|
123
|
+
*/
|
|
124
|
+
function configureEnv(config, platform, apiKey) {
|
|
125
|
+
if (platform === "openrouter") {
|
|
126
|
+
if (!config.env) {
|
|
127
|
+
config.env = {};
|
|
128
|
+
}
|
|
129
|
+
config.env.OPENROUTER_API_KEY = apiKey;
|
|
130
|
+
}
|
|
131
|
+
return config;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 配置 Provider(写入顶层 models.providers)
|
|
136
|
+
*/
|
|
137
|
+
function configureProvider(config, platform, apiKey) {
|
|
138
|
+
// 初始化 models 对象
|
|
139
|
+
if (!config.models) {
|
|
140
|
+
config.models = {};
|
|
141
|
+
}
|
|
142
|
+
if (!config.models.providers) {
|
|
143
|
+
config.models.providers = {};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// 设置 merge 模式
|
|
147
|
+
config.models.mode = "merge";
|
|
148
|
+
|
|
149
|
+
if (platform === "stepfun") {
|
|
150
|
+
// StepFun: 将 provider 配置写入 models.providers.stepfun
|
|
151
|
+
const platformConfig = PLATFORMS[platform];
|
|
152
|
+
config.models.providers.stepfun = {
|
|
153
|
+
...platformConfig.provider,
|
|
154
|
+
apiKey,
|
|
155
|
+
"models": [
|
|
156
|
+
{
|
|
157
|
+
"id": "step-3.5-flash",
|
|
158
|
+
"name": "Step 3.5 Flash",
|
|
159
|
+
"contextWindow": 256000,
|
|
160
|
+
"maxTokens": 8192,
|
|
161
|
+
"reasoning": true,
|
|
162
|
+
"input": [
|
|
163
|
+
"text"
|
|
164
|
+
],
|
|
165
|
+
"cost": {
|
|
166
|
+
"input": 0,
|
|
167
|
+
"output": 0,
|
|
168
|
+
"cacheRead": 0,
|
|
169
|
+
"cacheWrite": 0
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
// OpenRouter 使用内置 provider,不需要额外配置
|
|
176
|
+
|
|
177
|
+
return config;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* 配置模型
|
|
182
|
+
*/
|
|
183
|
+
function configureModel(config, platform) {
|
|
184
|
+
const platformConfig = PLATFORMS[platform];
|
|
185
|
+
const modelId = platformConfig.model;
|
|
186
|
+
|
|
187
|
+
// 初始化 agents.defaults 对象
|
|
188
|
+
if (!config.agents) {
|
|
189
|
+
config.agents = {};
|
|
190
|
+
}
|
|
191
|
+
if (!config.agents.defaults) {
|
|
192
|
+
config.agents.defaults = {};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 设置主模型
|
|
196
|
+
if (!config.agents.defaults.model) {
|
|
197
|
+
config.agents.defaults.model = {};
|
|
198
|
+
}
|
|
199
|
+
config.agents.defaults.model.primary = modelId;
|
|
200
|
+
|
|
201
|
+
// 添加模型到可用模型列表
|
|
202
|
+
if (!config.agents.defaults.models) {
|
|
203
|
+
config.agents.defaults.models = {};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// 只设置简单的模型配置(可选添加 alias)
|
|
207
|
+
config.agents.defaults.models[modelId] = {};
|
|
208
|
+
|
|
209
|
+
return config;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* 配置插件
|
|
214
|
+
*/
|
|
215
|
+
function configurePlugin(config, enabled) {
|
|
216
|
+
// 初始化 plugins.entries 对象
|
|
217
|
+
if (!config.plugins) {
|
|
218
|
+
config.plugins = {};
|
|
219
|
+
}
|
|
220
|
+
if (!config.plugins.entries) {
|
|
221
|
+
config.plugins.entries = {};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
config.plugins.entries.stepfun = {
|
|
225
|
+
enabled,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
return config;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* 配置渠道
|
|
233
|
+
*/
|
|
234
|
+
function configureChannel(config, platform, appId, appToken, enabled) {
|
|
235
|
+
// 初始化 channels 对象
|
|
236
|
+
if (!config.channels) {
|
|
237
|
+
config.channels = {};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const existingStepfun = config.channels.stepfun || {};
|
|
241
|
+
|
|
242
|
+
config.channels.stepfun = {
|
|
243
|
+
...existingStepfun,
|
|
244
|
+
platform,
|
|
245
|
+
appId,
|
|
246
|
+
appToken,
|
|
247
|
+
enabled,
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
return config;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* 主函数
|
|
255
|
+
*/
|
|
256
|
+
async function main() {
|
|
257
|
+
console.log("\n╭─────────────────────────────────────────╮");
|
|
258
|
+
console.log("│ OpenClaw Stepfun Plugin 配置向导 │");
|
|
259
|
+
console.log("╰─────────────────────────────────────────╯\n");
|
|
260
|
+
|
|
261
|
+
// 检查是否在 TTY 环境中(交互式终端)
|
|
262
|
+
if (!process.stdin.isTTY) {
|
|
263
|
+
console.log("⚠️ 非交互式环境,跳过配置向导");
|
|
264
|
+
console.log(" 请手动编辑配置文件:", OPENCLAW_CONFIG_FILE);
|
|
265
|
+
console.log(" 或运行: npm run setup\n");
|
|
266
|
+
process.exit(0);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
// 加载现有配置
|
|
271
|
+
let config = loadConfig();
|
|
272
|
+
const existingStepfun = config.channels?.stepfun || {};
|
|
273
|
+
|
|
274
|
+
// 显示当前配置状态
|
|
275
|
+
if (existingStepfun.appId) {
|
|
276
|
+
console.log("📋 检测到现有配置:");
|
|
277
|
+
console.log(` 平台: ${existingStepfun.platform === "stepfun" ? "StepFun 官方" : "OpenRouter"}`);
|
|
278
|
+
console.log(` App ID: ${existingStepfun.appId}`);
|
|
279
|
+
console.log(` App Token: ${existingStepfun.appToken ? "******(已设置)" : "(未设置)"}`);
|
|
280
|
+
console.log("");
|
|
281
|
+
|
|
282
|
+
const overwrite = await question("是否覆盖现有配置? (y/N): ");
|
|
283
|
+
if (overwrite.toLowerCase() !== "y") {
|
|
284
|
+
console.log("\n✓ 保留现有配置\n");
|
|
285
|
+
process.exit(0);
|
|
286
|
+
}
|
|
287
|
+
console.log("");
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// 选择平台
|
|
291
|
+
console.log("请选择接入平台:\n");
|
|
292
|
+
console.log(" [1] OpenRouter (限时免费)");
|
|
293
|
+
console.log(" 通过 OpenRouter 接入,目前限时免费使用\n");
|
|
294
|
+
console.log(" [2] StepFun 官方平台");
|
|
295
|
+
console.log(" 直接使用 StepFun 官方 API\n");
|
|
296
|
+
|
|
297
|
+
const platformChoice = await question("请输入选项 (1/2) [默认: 1]: ");
|
|
298
|
+
const platform = platformChoice === "2" ? "stepfun" : "openrouter";
|
|
299
|
+
const platformConfig = PLATFORMS[platform];
|
|
300
|
+
|
|
301
|
+
console.log(`\n✓ 已选择: ${platformConfig.name}\n`);
|
|
302
|
+
|
|
303
|
+
// 获取 API Key(选择平台后立即填入)
|
|
304
|
+
const apiKeyPrompt = platform === "openrouter"
|
|
305
|
+
? "请输入 OpenRouter API Key: "
|
|
306
|
+
: "请输入 StepFun API Key: ";
|
|
307
|
+
const apiKey = await questionHidden(apiKeyPrompt);
|
|
308
|
+
if (!apiKey) {
|
|
309
|
+
console.log("\n✗ API Key 不能为空\n");
|
|
310
|
+
process.exit(1);
|
|
311
|
+
}
|
|
312
|
+
console.log("✓ API Key 已设置\n");
|
|
313
|
+
|
|
314
|
+
// 获取网关配置信息
|
|
315
|
+
console.log("请输入网关应用配置信息:\n");
|
|
316
|
+
|
|
317
|
+
// 获取 appId
|
|
318
|
+
const appId = await question("App ID: ");
|
|
319
|
+
if (!appId) {
|
|
320
|
+
console.log("\n✗ App ID 不能为空\n");
|
|
321
|
+
process.exit(1);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// 获取 appToken(隐藏输入)
|
|
325
|
+
const appToken = await questionHidden("App Token: ");
|
|
326
|
+
if (!appToken) {
|
|
327
|
+
console.log("\n✗ App Token 不能为空\n");
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// 询问是否启用
|
|
332
|
+
const enableStr = await question("是否立即启用此渠道? (Y/n): ");
|
|
333
|
+
const enabled = enableStr.toLowerCase() !== "n";
|
|
334
|
+
|
|
335
|
+
// 应用所有配置
|
|
336
|
+
console.log("\n正在配置...");
|
|
337
|
+
|
|
338
|
+
// 1. 配置 Provider(写入 models.providers)
|
|
339
|
+
config = configureProvider(config, platform, apiKey);
|
|
340
|
+
console.log(" ✓ Provider 配置完成");
|
|
341
|
+
|
|
342
|
+
// 2. 配置模型
|
|
343
|
+
config = configureModel(config, platform);
|
|
344
|
+
console.log(` ✓ 模型已设置为: ${platformConfig.model}`);
|
|
345
|
+
|
|
346
|
+
// 3. 配置环境变量(仅 OpenRouter 需要)
|
|
347
|
+
config = configureEnv(config, platform, apiKey);
|
|
348
|
+
console.log(" ✓ 环境变量配置完成");
|
|
349
|
+
|
|
350
|
+
// 4. 配置插件
|
|
351
|
+
config = configurePlugin(config, enabled);
|
|
352
|
+
console.log(" ✓ 插件配置完成");
|
|
353
|
+
|
|
354
|
+
// 5. 配置渠道
|
|
355
|
+
config = configureChannel(config, platform, appId, appToken, enabled);
|
|
356
|
+
console.log(" ✓ 渠道配置完成");
|
|
357
|
+
|
|
358
|
+
// 保存配置
|
|
359
|
+
if (saveConfig(config)) {
|
|
360
|
+
console.log("\n╭─────────────────────────────────────────╮");
|
|
361
|
+
console.log("│ ✓ 配置保存成功! │");
|
|
362
|
+
console.log("╰─────────────────────────────────────────╯");
|
|
363
|
+
console.log(`\n📁 配置文件: ${OPENCLAW_CONFIG_FILE}`);
|
|
364
|
+
console.log(`🤖 主模型: ${platformConfig.model}`);
|
|
365
|
+
console.log(`🔌 渠道状态: ${enabled ? "已启用" : "未启用"}`);
|
|
366
|
+
console.log("\n使用以下命令启动 OpenClaw:");
|
|
367
|
+
console.log(" openclaw start\n");
|
|
368
|
+
} else {
|
|
369
|
+
process.exit(1);
|
|
370
|
+
}
|
|
371
|
+
} catch (err) {
|
|
372
|
+
console.error("\n✗ 配置失败:", err.message);
|
|
373
|
+
process.exit(1);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// 运行主函数
|
|
378
|
+
main().catch((err) => {
|
|
379
|
+
console.error("✗ 发生错误:", err);
|
|
380
|
+
process.exit(1);
|
|
381
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 切换开发和发布环境配置
|
|
4
|
+
* Usage: node switch-env.mjs [dev|publish]
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { copyFileSync, existsSync, rmSync } from "fs";
|
|
8
|
+
import { join, dirname } from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
|
|
11
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const rootDir = join(__dirname, "..");
|
|
13
|
+
|
|
14
|
+
const env = process.argv[2];
|
|
15
|
+
|
|
16
|
+
if (!env || (env !== "dev" && env !== "publish")) {
|
|
17
|
+
console.error("Usage: node switch-env.mjs [dev|publish]");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const isDev = env === "dev";
|
|
22
|
+
|
|
23
|
+
console.log(`Switching to ${env} environment...`);
|
|
24
|
+
|
|
25
|
+
// 1. 切换 package.json
|
|
26
|
+
const sourcePackage = join(rootDir, `package.${env}.json`);
|
|
27
|
+
const targetPackage = join(rootDir, "package.json");
|
|
28
|
+
|
|
29
|
+
if (!existsSync(sourcePackage)) {
|
|
30
|
+
console.error(`Error: ${sourcePackage} not found`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
copyFileSync(sourcePackage, targetPackage);
|
|
35
|
+
console.log(`✓ package.json → ${isDev ? "dev" : "publish"} mode`);
|
|
36
|
+
|
|
37
|
+
// 2. 切换 tsconfig.json
|
|
38
|
+
const sourceTsConfig = join(rootDir, `tsconfig.${env}.json`);
|
|
39
|
+
const targetTsConfig = join(rootDir, "tsconfig.json");
|
|
40
|
+
|
|
41
|
+
if (!existsSync(sourceTsConfig)) {
|
|
42
|
+
console.error(`Error: ${sourceTsConfig} not found`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
copyFileSync(sourceTsConfig, targetTsConfig);
|
|
47
|
+
console.log(`✓ tsconfig.json → ${isDev ? "dev" : "publish"} mode`);
|
|
48
|
+
|
|
49
|
+
// 3. 处理 pnpmfile(开发环境需要跳过 openclaw 依赖解析)
|
|
50
|
+
const pnpmfile = join(rootDir, ".pnpmfile.cjs");
|
|
51
|
+
const pnpmfileBackup = join(rootDir, ".pnpmfile.cjs.bak");
|
|
52
|
+
|
|
53
|
+
if (isDev) {
|
|
54
|
+
// 开发模式:启用 pnpmfile
|
|
55
|
+
if (existsSync(pnpmfileBackup)) {
|
|
56
|
+
copyFileSync(pnpmfileBackup, pnpmfile);
|
|
57
|
+
console.log("✓ Enabled pnpmfile (skip openclaw dependency resolution)");
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
// 发布模式:禁用 pnpmfile
|
|
61
|
+
if (existsSync(pnpmfile)) {
|
|
62
|
+
copyFileSync(pnpmfile, pnpmfileBackup);
|
|
63
|
+
rmSync(pnpmfile);
|
|
64
|
+
console.log("✓ Disabled pnpmfile for publish");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 4. 处理类型存根文件
|
|
69
|
+
const stubFile = join(rootDir, "src", "types", "openclaw-stub.d.ts");
|
|
70
|
+
const stubBackup = join(rootDir, "src", "types", "openclaw-stub.d.ts.bak");
|
|
71
|
+
|
|
72
|
+
if (isDev) {
|
|
73
|
+
// 开发模式:禁用类型存根(重命名为备份)
|
|
74
|
+
if (existsSync(stubFile)) {
|
|
75
|
+
copyFileSync(stubFile, stubBackup);
|
|
76
|
+
rmSync(stubFile);
|
|
77
|
+
console.log("✓ Disabled type stub (using actual openclaw types)");
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
// 发布模式:启用类型存根
|
|
81
|
+
if (existsSync(stubBackup)) {
|
|
82
|
+
copyFileSync(stubBackup, stubFile);
|
|
83
|
+
console.log("✓ Enabled type stub for publish");
|
|
84
|
+
} else if (!existsSync(stubFile)) {
|
|
85
|
+
console.warn("⚠ Warning: Type stub file not found. Run 'pnpm run switch:env:publish' to generate it.");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log("\n✅ Environment switched successfully!");
|
|
90
|
+
console.log(`\nNext steps:`);
|
|
91
|
+
if (isDev) {
|
|
92
|
+
console.log(" 1. Run 'pnpm install' to link local openclaw");
|
|
93
|
+
console.log(" 2. Start development");
|
|
94
|
+
} else {
|
|
95
|
+
console.log(" 1. Run 'pnpm install' to clean up local dependencies");
|
|
96
|
+
console.log(" 2. Run 'pnpm build' to verify everything works");
|
|
97
|
+
console.log(" 3. Run 'pnpm publish' to publish to npm");
|
|
98
|
+
}
|