@x-all-in-one/coding-helper 0.4.3 → 0.4.5
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.
|
@@ -30,6 +30,10 @@ export interface OpenCodeModelEntry {
|
|
|
30
30
|
input?: string[];
|
|
31
31
|
output?: string[];
|
|
32
32
|
};
|
|
33
|
+
reasoning?: boolean;
|
|
34
|
+
interleaved?: {
|
|
35
|
+
field: string;
|
|
36
|
+
};
|
|
33
37
|
}
|
|
34
38
|
export interface OpenCodeProviderConfig {
|
|
35
39
|
npm: string;
|
|
@@ -84,13 +88,10 @@ export declare class OpenCodeTool extends BaseTool {
|
|
|
84
88
|
* Fetch available models from API
|
|
85
89
|
*/
|
|
86
90
|
fetchAvailableModels(): Promise<string[]>;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
private
|
|
91
|
-
/**
|
|
92
|
-
* Build models object from fetched model list
|
|
93
|
-
*/
|
|
91
|
+
private hasTag;
|
|
92
|
+
private isVisionModelByTag;
|
|
93
|
+
private isReasoningModel;
|
|
94
|
+
private isInterleavedReasoningModel;
|
|
94
95
|
private buildModelsConfig;
|
|
95
96
|
/**
|
|
96
97
|
* Save model config to OpenCode (merge, not overwrite)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
|
+
import { deepmergeCustom } from 'deepmerge-ts';
|
|
4
5
|
import { configManager } from '../config.js';
|
|
5
6
|
import { modelService } from '../model-service.js';
|
|
6
7
|
import { BaseTool } from './base-tool.js';
|
|
@@ -15,9 +16,15 @@ const OH_MY_OPENCODE_AGENTS = [
|
|
|
15
16
|
'frontend-ui-ux-engineer',
|
|
16
17
|
'document-writer',
|
|
17
18
|
'multimodal-looker',
|
|
19
|
+
'atlas',
|
|
18
20
|
];
|
|
19
21
|
// Unified output token limit for all models
|
|
20
22
|
const OUTPUT_TOKEN_LIMIT = 32000;
|
|
23
|
+
// Model tag constants
|
|
24
|
+
const TAG_VISION = '视觉';
|
|
25
|
+
const TAG_REASONING = '推理';
|
|
26
|
+
const TAG_INTERLEAVED_REASONING = '交替推理';
|
|
27
|
+
const deepmerge = deepmergeCustom({ mergeArrays: false });
|
|
21
28
|
// Default configuration
|
|
22
29
|
export const OPENCODE_DEFAULT_CONFIG = {
|
|
23
30
|
BASE_URL: 'https://code-api.x-aio.com/v1',
|
|
@@ -101,32 +108,33 @@ export class OpenCodeTool extends BaseTool {
|
|
|
101
108
|
async fetchAvailableModels() {
|
|
102
109
|
return modelService.fetchModels();
|
|
103
110
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
hasTag(tags, tag) {
|
|
112
|
+
return Array.isArray(tags) && tags.includes(tag);
|
|
113
|
+
}
|
|
114
|
+
isVisionModelByTag(tags) {
|
|
115
|
+
return this.hasTag(tags, TAG_VISION);
|
|
116
|
+
}
|
|
117
|
+
isReasoningModel(tags) {
|
|
118
|
+
return this.hasTag(tags, TAG_REASONING) && !this.hasTag(tags, TAG_INTERLEAVED_REASONING);
|
|
119
|
+
}
|
|
120
|
+
isInterleavedReasoningModel(tags) {
|
|
121
|
+
return this.hasTag(tags, TAG_INTERLEAVED_REASONING);
|
|
110
122
|
}
|
|
111
|
-
/**
|
|
112
|
-
* Build models object from fetched model list
|
|
113
|
-
*/
|
|
114
123
|
buildModelsConfig(modelInfos) {
|
|
115
124
|
const models = {};
|
|
116
125
|
for (const info of modelInfos) {
|
|
117
126
|
const entry = {};
|
|
118
|
-
const isVision = this.
|
|
119
|
-
|
|
127
|
+
const isVision = this.isVisionModelByTag(info.tags);
|
|
128
|
+
const isReasoning = this.isReasoningModel(info.tags);
|
|
129
|
+
const isInterleavedReasoning = this.isInterleavedReasoningModel(info.tags);
|
|
120
130
|
if (info.name && info.name !== info.id) {
|
|
121
131
|
entry.name = info.name;
|
|
122
132
|
}
|
|
123
|
-
// Set limits (context from API, output always use unified limit)
|
|
124
133
|
if (isVision) {
|
|
125
134
|
entry.limit = {
|
|
126
135
|
context: info.context_length || OPENCODE_DEFAULT_CONFIG.VISION_CONTEXT,
|
|
127
136
|
output: OUTPUT_TOKEN_LIMIT,
|
|
128
137
|
};
|
|
129
|
-
// Add modalities for vision models
|
|
130
138
|
entry.modalities = {
|
|
131
139
|
input: ['text', 'image', 'video'],
|
|
132
140
|
output: ['text'],
|
|
@@ -138,6 +146,13 @@ export class OpenCodeTool extends BaseTool {
|
|
|
138
146
|
output: OUTPUT_TOKEN_LIMIT,
|
|
139
147
|
};
|
|
140
148
|
}
|
|
149
|
+
if (isInterleavedReasoning) {
|
|
150
|
+
entry.reasoning = true;
|
|
151
|
+
entry.interleaved = { field: 'reasoning_content' };
|
|
152
|
+
}
|
|
153
|
+
else if (isReasoning) {
|
|
154
|
+
entry.reasoning = true;
|
|
155
|
+
}
|
|
141
156
|
models[info.id] = entry;
|
|
142
157
|
}
|
|
143
158
|
return models;
|
|
@@ -160,7 +175,8 @@ export class OpenCodeTool extends BaseTool {
|
|
|
160
175
|
}
|
|
161
176
|
// Read current config (preserve user's other settings)
|
|
162
177
|
const currentConfig = this.getConfig();
|
|
163
|
-
|
|
178
|
+
const existingModels = currentConfig.provider?.[XAIO_PROVIDER_ID]?.models || {};
|
|
179
|
+
const mergedModels = deepmerge(existingModels, modelsConfig);
|
|
164
180
|
const xaioProvider = {
|
|
165
181
|
npm: '@ai-sdk/openai-compatible',
|
|
166
182
|
name: OPENCODE_DEFAULT_CONFIG.PROVIDER_NAME,
|
|
@@ -168,7 +184,7 @@ export class OpenCodeTool extends BaseTool {
|
|
|
168
184
|
baseURL: `https://${configManager.baseUrl}/v1`,
|
|
169
185
|
apiKey: modelConfig.apiKey,
|
|
170
186
|
},
|
|
171
|
-
models:
|
|
187
|
+
models: mergedModels,
|
|
172
188
|
};
|
|
173
189
|
// Merge config: only update xaio provider, preserve other providers
|
|
174
190
|
const newConfig = {
|
|
@@ -259,9 +275,8 @@ export class OpenCodeTool extends BaseTool {
|
|
|
259
275
|
}
|
|
260
276
|
currentConfig.provider[XAIO_PROVIDER_ID] = xaioProvider;
|
|
261
277
|
}
|
|
262
|
-
// 更新 models 部分
|
|
263
278
|
const modelsConfig = this.buildModelsConfig(modelInfos);
|
|
264
|
-
xaioProvider.models = modelsConfig;
|
|
279
|
+
xaioProvider.models = deepmerge(xaioProvider.models || {}, modelsConfig);
|
|
265
280
|
this.saveConfig(currentConfig);
|
|
266
281
|
}
|
|
267
282
|
// ==================== Oh My OpenCode 相关方法 ====================
|
|
@@ -19,6 +19,7 @@ export async function fetchModelsFromApi() {
|
|
|
19
19
|
name: m.real_model_name,
|
|
20
20
|
context_length: m.context ? m.context * 1000 : undefined,
|
|
21
21
|
max_output_tokens: m.context ? m.context * 500 : undefined,
|
|
22
|
+
tags: Array.isArray(m.tags) ? m.tags : null,
|
|
22
23
|
}));
|
|
23
24
|
}
|
|
24
25
|
return [];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x-all-in-one/coding-helper",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.5",
|
|
5
5
|
"description": "X All In One Coding Helper",
|
|
6
6
|
"author": "X.AIO",
|
|
7
7
|
"homepage": "https://docs.x-aio.com/zh/docs",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"chalk": "^5.3.0",
|
|
35
35
|
"commander": "^12.1.0",
|
|
36
|
+
"deepmerge-ts": "^7.1.5",
|
|
36
37
|
"inquirer": "^9.2.12",
|
|
37
38
|
"js-yaml": "^4.1.0",
|
|
38
39
|
"open": "^11.0.0",
|