duojie-helper 0.2.21 → 0.2.22

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.
@@ -1,216 +1,216 @@
1
- import fs from 'fs-extra';
2
- import path from 'path';
3
- import os from 'os';
4
- import { API_CONFIG, getModels } from '../index.js';
5
-
6
- /**
7
- * 获取 OpenCode 配置路径
8
- */
9
- function getOpenCodeConfigPaths() {
10
- const home = os.homedir();
11
-
12
- // OpenCode 统一使用 ~/.config/opencode 目录
13
- const configDir = path.join(home, '.config', 'opencode');
14
-
15
- return {
16
- configDir,
17
- configFile: path.join(configDir, 'opencode.json'),
18
- };
19
- }
20
-
21
- /**
22
- * 配置 OpenCode
23
- * 自动配置所有可用模型
24
- */
25
- export async function configureOpenCode(apiKey) {
26
- const paths = getOpenCodeConfigPaths();
27
-
28
- try {
29
- // 确保目录存在
30
- await fs.ensureDir(paths.configDir);
31
-
32
- // 1. 读取现有配置(如果存在)
33
- let existingConfig = {};
34
- if (await fs.pathExists(paths.configFile)) {
35
- try {
36
- existingConfig = await fs.readJson(paths.configFile);
37
- } catch {
38
- existingConfig = {};
39
- }
40
- }
41
-
42
- // 2. 获取模型列表
43
- const models = getModels();
44
-
45
- // 3. 构建 Duojie provider 的模型配置
46
- const duojieModels = {};
47
-
48
- // Claude 模型
49
- for (const m of (models.claude || [])) {
50
- duojieModels[m.id] = {
51
- limit: {
52
- context: 200000,
53
- output: 16384,
54
- },
55
- modalities: {
56
- input: ['text', 'image'],
57
- output: ['text'],
58
- },
59
- };
60
- }
61
-
62
- // GPT 模型
63
- for (const m of (models.gpt || [])) {
64
- duojieModels[m.id] = {
65
- limit: {
66
- context: 128000,
67
- output: 16384,
68
- },
69
- modalities: {
70
- input: ['text', 'image'],
71
- output: ['text'],
72
- },
73
- };
74
- }
75
-
76
- // Gemini 模型
77
- for (const m of (models.gemini || [])) {
78
- duojieModels[m.id] = {
79
- limit: {
80
- context: 1000000,
81
- output: 16384,
82
- },
83
- modalities: {
84
- input: ['text', 'image'],
85
- output: ['text'],
86
- },
87
- };
88
- }
89
-
90
- // 其他模型
91
- for (const m of (models.other || [])) {
92
- duojieModels[m.id] = {
93
- limit: {
94
- context: 128000,
95
- output: 4096,
96
- },
97
- modalities: {
98
- input: ['text', 'image'],
99
- output: ['text'],
100
- },
101
- };
102
- }
103
-
104
- const totalModels = Object.keys(duojieModels).length;
105
-
106
- if (totalModels === 0) {
107
- return {
108
- success: false,
109
- message: '没有可用的模型',
110
- };
111
- }
112
-
113
- // 4. 构建 Duojie provider 配置
114
- const duojieProvider = {
115
- npm: '@ai-sdk/anthropic',
116
- name: 'Duojie API',
117
- options: {
118
- baseURL: API_CONFIG.baseUrl,
119
- },
120
- models: duojieModels,
121
- };
122
-
123
- // 5. 合并配置(保留用户其他配置)
124
- // 删除旧的 duojie provider
125
- if (existingConfig.provider?.duojie) {
126
- delete existingConfig.provider.duojie;
127
- }
128
-
129
- const preferredModel = duojieModels['gpt-5.2'] ? 'duojie/gpt-5.2' : null;
130
-
131
- const newConfig = {
132
- ...existingConfig,
133
- $schema: existingConfig.$schema || 'https://opencode.ai/config.json',
134
- provider: {
135
- ...existingConfig.provider,
136
- duojie: duojieProvider,
137
- },
138
- ...(preferredModel ? { model: preferredModel } : {}),
139
- };
140
-
141
- // 6. 写入配置文件
142
- await fs.writeJson(paths.configFile, newConfig, { spaces: 2 });
143
-
144
- // 7. 提示用户设置环境变量
145
- return {
146
- success: true,
147
- message: `已配置 ${totalModels} 个模型 → ${paths.configFile}`,
148
- configPath: paths.configFile,
149
- hint: '请设置环境变量 ANTHROPIC_API_KEY 或在 OpenCode 中配置 API Key',
150
- };
151
- } catch (error) {
152
- return {
153
- success: false,
154
- message: `配置失败: ${error.message}`,
155
- };
156
- }
157
- }
158
-
159
- /**
160
- * 检查 OpenCode 配置状态
161
- */
162
- configureOpenCode.checkStatus = async function() {
163
- const paths = getOpenCodeConfigPaths();
164
-
165
- if (await fs.pathExists(paths.configFile)) {
166
- try {
167
- const config = await fs.readJson(paths.configFile);
168
-
169
- if (config.provider?.duojie) {
170
- const modelCount = Object.keys(config.provider.duojie.models || {}).length;
171
- return {
172
- configured: true,
173
- message: `已配置 ${modelCount} 个 Duojie 模型`,
174
- };
175
- } else if (config.provider && Object.keys(config.provider).length > 0) {
176
- return {
177
- configured: true,
178
- message: '已配置(非 Duojie)',
179
- };
180
- }
181
- } catch {
182
- // ignore
183
- }
184
- }
185
-
186
- return { configured: false };
187
- };
188
-
189
- /**
190
- * 撤销 OpenCode 配置
191
- */
192
- configureOpenCode.revoke = async function() {
193
- const paths = getOpenCodeConfigPaths();
194
-
195
- // 清理配置文件中的 duojie provider
196
- if (await fs.pathExists(paths.configFile)) {
197
- try {
198
- const config = await fs.readJson(paths.configFile);
199
-
200
- if (config.provider?.duojie) {
201
- delete config.provider.duojie;
202
- }
203
-
204
- // 如果默认模型是 duojie 的,清除它
205
- if (config.model?.startsWith('duojie/')) {
206
- delete config.model;
207
- }
208
-
209
- await fs.writeJson(paths.configFile, config, { spaces: 2 });
210
- } catch {
211
- // ignore
212
- }
213
- }
214
- };
215
-
216
- export default configureOpenCode;
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ import { API_CONFIG, getModels } from '../index.js';
5
+
6
+ /**
7
+ * 获取 OpenCode 配置路径
8
+ */
9
+ function getOpenCodeConfigPaths() {
10
+ const home = os.homedir();
11
+
12
+ // OpenCode 统一使用 ~/.config/opencode 目录
13
+ const configDir = path.join(home, '.config', 'opencode');
14
+
15
+ return {
16
+ configDir,
17
+ configFile: path.join(configDir, 'opencode.json'),
18
+ };
19
+ }
20
+
21
+ /**
22
+ * 配置 OpenCode
23
+ * 自动配置所有可用模型
24
+ */
25
+ export async function configureOpenCode(apiKey) {
26
+ const paths = getOpenCodeConfigPaths();
27
+
28
+ try {
29
+ // 确保目录存在
30
+ await fs.ensureDir(paths.configDir);
31
+
32
+ // 1. 读取现有配置(如果存在)
33
+ let existingConfig = {};
34
+ if (await fs.pathExists(paths.configFile)) {
35
+ try {
36
+ existingConfig = await fs.readJson(paths.configFile);
37
+ } catch {
38
+ existingConfig = {};
39
+ }
40
+ }
41
+
42
+ // 2. 获取模型列表
43
+ const models = getModels();
44
+
45
+ // 3. 构建 Duojie provider 的模型配置
46
+ const duojieModels = {};
47
+
48
+ // Claude 模型
49
+ for (const m of (models.claude || [])) {
50
+ duojieModels[m.id] = {
51
+ limit: {
52
+ context: 200000,
53
+ output: 16384,
54
+ },
55
+ modalities: {
56
+ input: ['text', 'image'],
57
+ output: ['text'],
58
+ },
59
+ };
60
+ }
61
+
62
+ // GPT 模型
63
+ for (const m of (models.gpt || [])) {
64
+ duojieModels[m.id] = {
65
+ limit: {
66
+ context: 128000,
67
+ output: 16384,
68
+ },
69
+ modalities: {
70
+ input: ['text', 'image'],
71
+ output: ['text'],
72
+ },
73
+ };
74
+ }
75
+
76
+ // Gemini 模型
77
+ for (const m of (models.gemini || [])) {
78
+ duojieModels[m.id] = {
79
+ limit: {
80
+ context: 1000000,
81
+ output: 16384,
82
+ },
83
+ modalities: {
84
+ input: ['text', 'image'],
85
+ output: ['text'],
86
+ },
87
+ };
88
+ }
89
+
90
+ // 其他模型
91
+ for (const m of (models.other || [])) {
92
+ duojieModels[m.id] = {
93
+ limit: {
94
+ context: 128000,
95
+ output: 4096,
96
+ },
97
+ modalities: {
98
+ input: ['text', 'image'],
99
+ output: ['text'],
100
+ },
101
+ };
102
+ }
103
+
104
+ const totalModels = Object.keys(duojieModels).length;
105
+
106
+ if (totalModels === 0) {
107
+ return {
108
+ success: false,
109
+ message: '没有可用的模型',
110
+ };
111
+ }
112
+
113
+ // 4. 构建 Duojie provider 配置
114
+ const duojieProvider = {
115
+ npm: '@ai-sdk/anthropic',
116
+ name: 'Duojie API',
117
+ options: {
118
+ baseURL: API_CONFIG.baseUrl,
119
+ },
120
+ models: duojieModels,
121
+ };
122
+
123
+ // 5. 合并配置(保留用户其他配置)
124
+ // 删除旧的 duojie provider
125
+ if (existingConfig.provider?.duojie) {
126
+ delete existingConfig.provider.duojie;
127
+ }
128
+
129
+ const preferredModel = duojieModels['gpt-5.2'] ? 'duojie/gpt-5.2' : null;
130
+
131
+ const newConfig = {
132
+ ...existingConfig,
133
+ $schema: existingConfig.$schema || 'https://opencode.ai/config.json',
134
+ provider: {
135
+ ...existingConfig.provider,
136
+ duojie: duojieProvider,
137
+ },
138
+ ...(preferredModel ? { model: preferredModel } : {}),
139
+ };
140
+
141
+ // 6. 写入配置文件
142
+ await fs.writeJson(paths.configFile, newConfig, { spaces: 2 });
143
+
144
+ // 7. 提示用户设置环境变量
145
+ return {
146
+ success: true,
147
+ message: `已配置 ${totalModels} 个模型 → ${paths.configFile}`,
148
+ configPath: paths.configFile,
149
+ hint: '请设置环境变量 ANTHROPIC_API_KEY 或在 OpenCode 中配置 API Key',
150
+ };
151
+ } catch (error) {
152
+ return {
153
+ success: false,
154
+ message: `配置失败: ${error.message}`,
155
+ };
156
+ }
157
+ }
158
+
159
+ /**
160
+ * 检查 OpenCode 配置状态
161
+ */
162
+ configureOpenCode.checkStatus = async function() {
163
+ const paths = getOpenCodeConfigPaths();
164
+
165
+ if (await fs.pathExists(paths.configFile)) {
166
+ try {
167
+ const config = await fs.readJson(paths.configFile);
168
+
169
+ if (config.provider?.duojie) {
170
+ const modelCount = Object.keys(config.provider.duojie.models || {}).length;
171
+ return {
172
+ configured: true,
173
+ message: `已配置 ${modelCount} 个 Duojie 模型`,
174
+ };
175
+ } else if (config.provider && Object.keys(config.provider).length > 0) {
176
+ return {
177
+ configured: true,
178
+ message: '已配置(非 Duojie)',
179
+ };
180
+ }
181
+ } catch {
182
+ // ignore
183
+ }
184
+ }
185
+
186
+ return { configured: false };
187
+ };
188
+
189
+ /**
190
+ * 撤销 OpenCode 配置
191
+ */
192
+ configureOpenCode.revoke = async function() {
193
+ const paths = getOpenCodeConfigPaths();
194
+
195
+ // 清理配置文件中的 duojie provider
196
+ if (await fs.pathExists(paths.configFile)) {
197
+ try {
198
+ const config = await fs.readJson(paths.configFile);
199
+
200
+ if (config.provider?.duojie) {
201
+ delete config.provider.duojie;
202
+ }
203
+
204
+ // 如果默认模型是 duojie 的,清除它
205
+ if (config.model?.startsWith('duojie/')) {
206
+ delete config.model;
207
+ }
208
+
209
+ await fs.writeJson(paths.configFile, config, { spaces: 2 });
210
+ } catch {
211
+ // ignore
212
+ }
213
+ }
214
+ };
215
+
216
+ export default configureOpenCode;