super-backlog 0.3.3 → 0.4.0
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/models/config.js +40 -0
- package/dist/models/defaults.js +16 -0
- package/dist/models/family.js +14 -0
- package/dist/models/resolve.js +22 -0
- package/dist/models/types.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { DEFAULT_CONFIG, DEFAULT_FAMILIES } from './defaults.js';
|
|
4
|
+
const CONFIG_PATH = '.super-backlog/models.json';
|
|
5
|
+
export function loadConfig(cwd) {
|
|
6
|
+
const path = join(cwd, CONFIG_PATH);
|
|
7
|
+
if (!existsSync(path))
|
|
8
|
+
return { ...DEFAULT_CONFIG };
|
|
9
|
+
try {
|
|
10
|
+
const raw = JSON.parse(readFileSync(path, 'utf8'));
|
|
11
|
+
if (!raw || typeof raw !== 'object')
|
|
12
|
+
return { ...DEFAULT_CONFIG };
|
|
13
|
+
return normalizeConfig(raw);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return { ...DEFAULT_CONFIG, enabled: false };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function normalizeConfig(partial) {
|
|
20
|
+
return {
|
|
21
|
+
version: typeof partial.version === 'number' ? partial.version : DEFAULT_CONFIG.version,
|
|
22
|
+
enabled: partial.enabled === true,
|
|
23
|
+
mode: ['auto', 'family', 'individual'].includes(partial.mode) ? partial.mode : 'family',
|
|
24
|
+
tiers: partial.tiers && typeof partial.tiers === 'object' ? partial.tiers : {},
|
|
25
|
+
individual: partial.individual && typeof partial.individual === 'object' ? partial.individual : {},
|
|
26
|
+
families: partial.families && typeof partial.families === 'object' ? partial.families : {},
|
|
27
|
+
resolved: partial.resolved && typeof partial.resolved === 'object' ? partial.resolved : {},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function getFamilyTable(config) {
|
|
31
|
+
const merged = {};
|
|
32
|
+
for (const [name, tiers] of Object.entries(DEFAULT_FAMILIES)) {
|
|
33
|
+
merged[name] = { ...tiers, ...(config.families[name] || {}) };
|
|
34
|
+
}
|
|
35
|
+
for (const [name, tiers] of Object.entries(config.families)) {
|
|
36
|
+
if (!merged[name])
|
|
37
|
+
merged[name] = { workhorse: '', budget: '', ...tiers };
|
|
38
|
+
}
|
|
39
|
+
return merged;
|
|
40
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const DEFAULT_FAMILIES = {
|
|
2
|
+
kimi: { workhorse: 'opencode/kimi-k2.7-code', budget: 'opencode/kimi-k2.5' },
|
|
3
|
+
grok: { workhorse: 'xai/grok-4.5', budget: 'xai/grok-4.3' },
|
|
4
|
+
claude: { workhorse: 'opencode/claude-sonnet-4-6', budget: 'opencode/claude-haiku-4-5' },
|
|
5
|
+
gpt: { workhorse: 'opencode/gpt-5.1-codex-mini', budget: 'opencode/gpt-5-nano' },
|
|
6
|
+
gemini: { workhorse: 'opencode/gemini-3.5-flash', budget: 'opencode/gemini-3.5-flash-lite' },
|
|
7
|
+
};
|
|
8
|
+
export const DEFAULT_CONFIG = {
|
|
9
|
+
version: 1,
|
|
10
|
+
enabled: false,
|
|
11
|
+
mode: 'family',
|
|
12
|
+
tiers: {},
|
|
13
|
+
individual: {},
|
|
14
|
+
families: {},
|
|
15
|
+
resolved: {},
|
|
16
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function detectFamily(modelId) {
|
|
2
|
+
const lower = modelId.toLowerCase();
|
|
3
|
+
if (lower.includes('kimi'))
|
|
4
|
+
return 'kimi';
|
|
5
|
+
if (lower.includes('grok'))
|
|
6
|
+
return 'grok';
|
|
7
|
+
if (lower.includes('claude'))
|
|
8
|
+
return 'claude';
|
|
9
|
+
if (lower.includes('gemini'))
|
|
10
|
+
return 'gemini';
|
|
11
|
+
if (lower.includes('gpt'))
|
|
12
|
+
return 'gpt';
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { getFamilyTable } from './config.js';
|
|
2
|
+
import { detectFamily } from './family.js';
|
|
3
|
+
export { detectFamily } from './family.js';
|
|
4
|
+
export function resolveTier(mainModel, tier, config) {
|
|
5
|
+
if (!config.enabled)
|
|
6
|
+
return null;
|
|
7
|
+
if (config.mode === 'individual') {
|
|
8
|
+
return config.individual[tier] || null;
|
|
9
|
+
}
|
|
10
|
+
const family = detectFamily(mainModel);
|
|
11
|
+
if (!family)
|
|
12
|
+
return null;
|
|
13
|
+
if (config.mode === 'family') {
|
|
14
|
+
const table = getFamilyTable(config);
|
|
15
|
+
const entry = table[family];
|
|
16
|
+
if (!entry)
|
|
17
|
+
return null;
|
|
18
|
+
return config.tiers[tier] || entry[tier] || null;
|
|
19
|
+
}
|
|
20
|
+
// auto mode falls back to family table when discovery is not populated
|
|
21
|
+
return config.resolved[tier] || config.tiers[tier] || null;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DEFAULT_CONFIG } from './defaults.js';
|