trinity-config 1.2.4 → 1.2.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.
- package/README.md +1 -1
- package/dist/chunk-5WZW5Y4W.js +45 -0
- package/dist/index.js +42 -10
- package/dist/{merge-openclaw-config-KMG3FYK6.js → merge-openclaw-config-F77TZKPG.js} +3 -12
- package/dist/{merge-opencode-config-XGIZYPOW.js → merge-opencode-config-JTWAGCET.js} +3 -6
- package/dist/{merge-zcode-config-PTPY6RXN.js → merge-zcode-config-LGTBU4UC.js} +2 -6
- package/package.json +1 -1
- package/dist/chunk-QS4QYSMM.js +0 -26
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
协议按 `GET /v1/models/{code}` 的 `capabilities.text.interfaces` **自动择优**(Anthropic → Responses → Completions),再与工具能力求交。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
写入客户端的模型列表来自该 API Key 的 `GET /v1/models?modality=text`(Call Allowlist 内生文/多模态;不含生图/生视频,也不含无权限模型)。
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npx -y trinity-config --type zcode -k xh-你的key --model gpt-5.4
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// src/text-models.ts
|
|
2
|
+
function isLikelyNonTextModel(id) {
|
|
3
|
+
const lower = id.toLowerCase();
|
|
4
|
+
return lower.includes("image") || lower.includes("video") || lower.includes("seedance") || lower.includes("wan-") || lower.includes("kling") || lower.includes("og-image") || lower.includes("midjourney") || lower.includes("flux");
|
|
5
|
+
}
|
|
6
|
+
function filterTextModelIds(primaryModel, modelIds, limit = 80) {
|
|
7
|
+
const ids = [];
|
|
8
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9
|
+
const push = (raw, enforceTextHeuristic) => {
|
|
10
|
+
const trimmed = raw?.trim();
|
|
11
|
+
if (!trimmed || seen.has(trimmed)) return;
|
|
12
|
+
if (enforceTextHeuristic && isLikelyNonTextModel(trimmed)) return;
|
|
13
|
+
seen.add(trimmed);
|
|
14
|
+
ids.push(trimmed);
|
|
15
|
+
};
|
|
16
|
+
if (modelIds && modelIds.length > 0) {
|
|
17
|
+
const allow = new Set(
|
|
18
|
+
modelIds.map((id) => id?.trim()).filter((id) => Boolean(id))
|
|
19
|
+
);
|
|
20
|
+
if (allow.has(primaryModel.trim())) {
|
|
21
|
+
push(primaryModel, false);
|
|
22
|
+
}
|
|
23
|
+
for (const id of modelIds) {
|
|
24
|
+
if (ids.length >= limit) break;
|
|
25
|
+
push(id, true);
|
|
26
|
+
}
|
|
27
|
+
return ids;
|
|
28
|
+
}
|
|
29
|
+
push(primaryModel, true);
|
|
30
|
+
return ids;
|
|
31
|
+
}
|
|
32
|
+
function pickAllowedDefaultModel(preferred, allowlist, candidates) {
|
|
33
|
+
const allow = new Set(allowlist.map((id) => id.trim()).filter(Boolean));
|
|
34
|
+
if (allow.has(preferred.trim())) return preferred.trim();
|
|
35
|
+
for (const c of candidates) {
|
|
36
|
+
const t = c?.trim();
|
|
37
|
+
if (t && allow.has(t)) return t;
|
|
38
|
+
}
|
|
39
|
+
return allowlist.map((id) => id.trim()).find(Boolean);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export {
|
|
43
|
+
filterTextModelIds,
|
|
44
|
+
pickAllowedDefaultModel
|
|
45
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
pickAllowedDefaultModel
|
|
4
|
+
} from "./chunk-5WZW5Y4W.js";
|
|
5
|
+
|
|
2
6
|
// src/index.ts
|
|
3
7
|
import * as p from "@clack/prompts";
|
|
4
8
|
import pc from "picocolors";
|
|
5
9
|
|
|
6
10
|
// src/constants.ts
|
|
7
11
|
var PACKAGE_NAME = "trinity-config";
|
|
8
|
-
var PACKAGE_VERSION = "1.2.
|
|
12
|
+
var PACKAGE_VERSION = "1.2.5";
|
|
9
13
|
var TRINITY_BASE_URL = "https://api.trinitydesk.ai";
|
|
10
14
|
var DEFAULT_CLAUDE_MODEL = "claude-sonnet-4-6";
|
|
11
15
|
var DEFAULT_CLAUDE_FAST_MODEL = "claude-sonnet-4-6";
|
|
@@ -422,7 +426,7 @@ async function configureCodex(apiKey, codexBaseUrl, codexModel, _verbose) {
|
|
|
422
426
|
return configureCodexDirect(apiKey, codexBaseUrl, codexModel);
|
|
423
427
|
}
|
|
424
428
|
async function configureOpenCode(apiKey, openCodeBaseUrl, model, modelIds, protocol) {
|
|
425
|
-
const { configureOpenCodeDirect } = await import("./merge-opencode-config-
|
|
429
|
+
const { configureOpenCodeDirect } = await import("./merge-opencode-config-JTWAGCET.js");
|
|
426
430
|
return configureOpenCodeDirect({
|
|
427
431
|
apiKey,
|
|
428
432
|
baseUrl: openCodeBaseUrl,
|
|
@@ -432,7 +436,7 @@ async function configureOpenCode(apiKey, openCodeBaseUrl, model, modelIds, proto
|
|
|
432
436
|
});
|
|
433
437
|
}
|
|
434
438
|
async function configureOpenClaw(apiKey, openClawBaseUrl, model, modelIds, protocol) {
|
|
435
|
-
const { configureOpenClawDirect } = await import("./merge-openclaw-config-
|
|
439
|
+
const { configureOpenClawDirect } = await import("./merge-openclaw-config-F77TZKPG.js");
|
|
436
440
|
return configureOpenClawDirect({
|
|
437
441
|
apiKey,
|
|
438
442
|
baseUrl: openClawBaseUrl,
|
|
@@ -442,7 +446,7 @@ async function configureOpenClaw(apiKey, openClawBaseUrl, model, modelIds, proto
|
|
|
442
446
|
});
|
|
443
447
|
}
|
|
444
448
|
async function configureZCode(apiKey, zcodeBaseUrl, model, modelIds, protocol) {
|
|
445
|
-
const { configureZCodeDirect } = await import("./merge-zcode-config-
|
|
449
|
+
const { configureZCodeDirect } = await import("./merge-zcode-config-LGTBU4UC.js");
|
|
446
450
|
return configureZCodeDirect({
|
|
447
451
|
apiKey,
|
|
448
452
|
baseUrl: zcodeBaseUrl,
|
|
@@ -532,7 +536,7 @@ async function verifyTrinityApi(apiKey, baseUrl = TRINITY_BASE_URL) {
|
|
|
532
536
|
return {
|
|
533
537
|
ok: true,
|
|
534
538
|
statusCode,
|
|
535
|
-
message: `\u8FDE\u901A\u6210\u529F\uFF08
|
|
539
|
+
message: `\u8FDE\u901A\u6210\u529F\uFF08\u8BE5 Key \u53EF\u7528\u751F\u6587\u6A21\u578B ${modelIds.length} \u4E2A\uFF09`,
|
|
536
540
|
modelIds
|
|
537
541
|
};
|
|
538
542
|
} catch (error) {
|
|
@@ -642,7 +646,7 @@ async function run() {
|
|
|
642
646
|
p.intro(pc.bgCyan(pc.black(` ${PACKAGE_NAME} v${PACKAGE_VERSION} `)));
|
|
643
647
|
const toolType = await promptToolType(opts.type);
|
|
644
648
|
const apiKey = await promptApiKey(opts.apiKey);
|
|
645
|
-
|
|
649
|
+
let model = opts.model?.trim() ? opts.model.trim() : opts.apiKey ? resolveModel(toolType) : await promptModel(toolType);
|
|
646
650
|
const apiRoot = rootBaseUrl(opts.baseUrl);
|
|
647
651
|
p.log.info(`\u5DE5\u5177: ${toolLabel(toolType)} \xB7 \u6A21\u578B: ${model}`);
|
|
648
652
|
const spinner2 = p.spinner();
|
|
@@ -653,20 +657,48 @@ async function run() {
|
|
|
653
657
|
const result = await verifyTrinityApi(apiKey, apiRoot);
|
|
654
658
|
if (result.ok) {
|
|
655
659
|
spinner2.stop(pc.green(result.message));
|
|
656
|
-
verifiedModelIds = result.modelIds;
|
|
657
|
-
|
|
660
|
+
verifiedModelIds = result.modelIds ?? [];
|
|
661
|
+
if (verifiedModelIds.length === 0) {
|
|
662
|
+
p.outro(pc.red("\u8BE5 API Key \u6CA1\u6709\u53EF\u7528\u7684\u751F\u6587\u6A21\u578B\uFF08Call Allowlist \u4E3A\u7A7A\uFF09"));
|
|
663
|
+
return 1;
|
|
664
|
+
}
|
|
665
|
+
const recommended = pickRecommendedModels(verifiedModelIds);
|
|
658
666
|
const hint = recommendedHint(toolType, recommended);
|
|
659
|
-
|
|
667
|
+
const allowed = pickAllowedDefaultModel(model, verifiedModelIds, [
|
|
668
|
+
hint,
|
|
669
|
+
recommended.claude,
|
|
670
|
+
recommended.codex,
|
|
671
|
+
recommended.opencode,
|
|
672
|
+
recommended.openclaw,
|
|
673
|
+
recommended.zcode,
|
|
674
|
+
defaultModelForType(toolType)
|
|
675
|
+
]);
|
|
676
|
+
if (!allowed) {
|
|
677
|
+
p.outro(pc.red("\u65E0\u6CD5\u5728\u8BE5 API Key \u7684\u53EF\u7528\u751F\u6587\u6A21\u578B\u4E2D\u9009\u51FA\u9ED8\u8BA4\u6A21\u578B"));
|
|
678
|
+
return 1;
|
|
679
|
+
}
|
|
680
|
+
if (allowed !== model) {
|
|
681
|
+
p.note(
|
|
682
|
+
`\u6A21\u578B ${model} \u4E0D\u5728\u8BE5 Key \u53EF\u7528\u5217\u8868\u4E2D\uFF0C\u5DF2\u6539\u4E3A ${allowed}\uFF08\u5171 ${verifiedModelIds.length} \u4E2A\u53EF\u7528\u751F\u6587\u6A21\u578B\uFF09`,
|
|
683
|
+
"\u6743\u9650"
|
|
684
|
+
);
|
|
685
|
+
model = allowed;
|
|
686
|
+
} else if (hint && hint !== model) {
|
|
660
687
|
p.note(`\u540C\u7C7B\u578B\u63A8\u8350\u6A21\u578B: ${hint}`, "\u6A21\u578B");
|
|
661
688
|
}
|
|
662
689
|
} else {
|
|
663
690
|
verifyFailed = true;
|
|
664
691
|
spinner2.stop(pc.yellow(result.message));
|
|
665
692
|
p.note(
|
|
666
|
-
"\u8FDE\u901A\u6027\u68C0\u67E5\u672A\u901A\u8FC7\uFF1B\u4ECD\u5C06\u5C1D\u8BD5\u5199\u5165\u672C\u5730\u914D\u7F6E\u3002\u8BF7\u68C0\u67E5 API Key\u3001\u7F51\u7EDC\uFF0C\u6216\u5728\u63A7\u5236\u53F0\u786E\u8BA4 Key \u6709\u6548\u3002",
|
|
693
|
+
"\u8FDE\u901A\u6027\u68C0\u67E5\u672A\u901A\u8FC7\uFF1B\u4ECD\u5C06\u5C1D\u8BD5\u5199\u5165\u672C\u5730\u914D\u7F6E\uFF08\u4E0D\u4F1A\u540C\u6B65\u6A21\u578B\u5217\u8868\uFF09\u3002\u8BF7\u68C0\u67E5 API Key\u3001\u7F51\u7EDC\uFF0C\u6216\u5728\u63A7\u5236\u53F0\u786E\u8BA4 Key \u6709\u6548\u3002",
|
|
667
694
|
"\u63D0\u793A"
|
|
668
695
|
);
|
|
669
696
|
}
|
|
697
|
+
} else {
|
|
698
|
+
p.note(
|
|
699
|
+
"--skip-verify \u5DF2\u8DF3\u8FC7\uFF1A\u65E0\u6CD5\u6309 Key \u6743\u76CA\u62C9\u53D6\u53EF\u7528\u6A21\u578B\u5217\u8868\uFF0C\u4EC5\u5199\u5165\u6307\u5B9A\u9ED8\u8BA4\u6A21\u578B\u3002",
|
|
700
|
+
"\u63D0\u793A"
|
|
701
|
+
);
|
|
670
702
|
}
|
|
671
703
|
spinner2.start("\u89E3\u6790\u6A21\u578B\u534F\u8BAE\u2026");
|
|
672
704
|
let protocolRes;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
filterTextModelIds
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5WZW5Y4W.js";
|
|
4
4
|
|
|
5
5
|
// src/merge-openclaw-config.ts
|
|
6
6
|
import fs from "fs";
|
|
@@ -71,22 +71,13 @@ function mergeOpenClawConfig(options) {
|
|
|
71
71
|
modelsBlock.mode = modelsBlock.mode ?? "merge";
|
|
72
72
|
const providers = modelsBlock.providers && typeof modelsBlock.providers === "object" ? { ...modelsBlock.providers } : {};
|
|
73
73
|
const existing = providers[TRINITY_OPENCLAW_PROVIDER] ?? {};
|
|
74
|
-
const
|
|
75
|
-
const byId = /* @__PURE__ */ new Map();
|
|
76
|
-
for (const m of existingModels) {
|
|
77
|
-
if (m && typeof m === "object" && typeof m.id === "string") {
|
|
78
|
-
byId.set(m.id, m);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
for (const m of buildModelEntries(options.model, options.modelIds)) {
|
|
82
|
-
byId.set(m.id, { ...byId.get(m.id), ...m });
|
|
83
|
-
}
|
|
74
|
+
const nextModels = buildModelEntries(options.model, options.modelIds);
|
|
84
75
|
providers[TRINITY_OPENCLAW_PROVIDER] = {
|
|
85
76
|
...existing,
|
|
86
77
|
baseUrl: options.baseUrl.replace(/\/+$/, ""),
|
|
87
78
|
apiKey: options.apiKey,
|
|
88
79
|
api,
|
|
89
|
-
models:
|
|
80
|
+
models: nextModels
|
|
90
81
|
};
|
|
91
82
|
modelsBlock.providers = providers;
|
|
92
83
|
doc.models = modelsBlock;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
filterTextModelIds
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5WZW5Y4W.js";
|
|
4
4
|
|
|
5
5
|
// src/merge-opencode-config.ts
|
|
6
6
|
import fs from "fs";
|
|
@@ -65,7 +65,7 @@ function mergeOpenCodeConfig(options) {
|
|
|
65
65
|
doc.model = `${TRINITY_OPENCODE_PROVIDER}/${options.model}`;
|
|
66
66
|
const providers = doc.provider && typeof doc.provider === "object" ? { ...doc.provider } : {};
|
|
67
67
|
const existing = providers[TRINITY_OPENCODE_PROVIDER] ?? {};
|
|
68
|
-
const
|
|
68
|
+
const nextModels = buildModelMap(options.model, options.modelIds);
|
|
69
69
|
providers[TRINITY_OPENCODE_PROVIDER] = {
|
|
70
70
|
...existing,
|
|
71
71
|
npm,
|
|
@@ -75,10 +75,7 @@ function mergeOpenCodeConfig(options) {
|
|
|
75
75
|
baseURL: options.baseUrl.replace(/\/+$/, ""),
|
|
76
76
|
apiKey: options.apiKey
|
|
77
77
|
},
|
|
78
|
-
models:
|
|
79
|
-
...existingModels,
|
|
80
|
-
...buildModelMap(options.model, options.modelIds)
|
|
81
|
-
}
|
|
78
|
+
models: nextModels
|
|
82
79
|
};
|
|
83
80
|
doc.provider = providers;
|
|
84
81
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
filterTextModelIds
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5WZW5Y4W.js";
|
|
4
4
|
|
|
5
5
|
// src/merge-zcode-config.ts
|
|
6
6
|
import fs from "fs";
|
|
@@ -108,17 +108,13 @@ function mergeZCodeConfig(options) {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
const existing = providers[TRINITY_ZCODE_PROVIDER] ?? {};
|
|
111
|
-
const existingModels = existing.models && typeof existing.models === "object" ? existing.models : {};
|
|
112
111
|
const root = options.baseUrl.replace(/\/v1\/?$/, "").replace(/\/+$/, "");
|
|
113
112
|
const withV1 = `${root}/v1`;
|
|
114
113
|
const withoutV1 = root;
|
|
115
114
|
const binding = zcodeProtocolBinding(options.protocol);
|
|
116
115
|
const primaryBase = options.protocol === "anthropic_messages" ? withoutV1 : withV1;
|
|
117
116
|
const now = Date.now();
|
|
118
|
-
const models =
|
|
119
|
-
...existingModels,
|
|
120
|
-
...buildModels(options.model, options.modelIds, binding)
|
|
121
|
-
};
|
|
117
|
+
const models = buildModels(options.model, options.modelIds, binding);
|
|
122
118
|
providers[TRINITY_ZCODE_PROVIDER] = {
|
|
123
119
|
...existing,
|
|
124
120
|
enabled: true,
|
package/package.json
CHANGED
package/dist/chunk-QS4QYSMM.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// src/text-models.ts
|
|
2
|
-
function isLikelyNonTextModel(id) {
|
|
3
|
-
const lower = id.toLowerCase();
|
|
4
|
-
return lower.includes("image") || lower.includes("video") || lower.includes("seedance") || lower.includes("wan-") || lower.includes("kling") || lower.includes("og-image") || lower.includes("midjourney") || lower.includes("flux");
|
|
5
|
-
}
|
|
6
|
-
function filterTextModelIds(primaryModel, modelIds, limit = 80) {
|
|
7
|
-
const ids = [];
|
|
8
|
-
const seen = /* @__PURE__ */ new Set();
|
|
9
|
-
const push = (raw) => {
|
|
10
|
-
const trimmed = raw?.trim();
|
|
11
|
-
if (!trimmed || seen.has(trimmed)) return;
|
|
12
|
-
if (ids.length > 0 && isLikelyNonTextModel(trimmed)) return;
|
|
13
|
-
seen.add(trimmed);
|
|
14
|
-
ids.push(trimmed);
|
|
15
|
-
};
|
|
16
|
-
push(primaryModel);
|
|
17
|
-
for (const id of modelIds ?? []) {
|
|
18
|
-
if (ids.length >= limit) break;
|
|
19
|
-
push(id);
|
|
20
|
-
}
|
|
21
|
-
return ids;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
filterTextModelIds
|
|
26
|
-
};
|