@goodandready/dsh-moa 0.2.22 → 0.2.24
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/lib/client.js +4 -4
- package/lib/pricing.js +93 -6
- package/package.json +3 -2
package/lib/client.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// - Segmented preset selectors and count pills
|
|
7
7
|
// - Refined temperature sliders and searchable model picker
|
|
8
8
|
// - Telemetry summary grid fed by /dsh-moa/history
|
|
9
|
-
// - Robust error boundary and
|
|
9
|
+
// - Robust error boundary and configForms reactivity
|
|
10
10
|
//
|
|
11
11
|
// English is the canonical source language; the ru translation is provided
|
|
12
12
|
// by the DSH translation plugin at runtime (no bundled ru duplicate).
|
|
@@ -1776,8 +1776,8 @@ window.__ModuleLoader__.load({
|
|
|
1776
1776
|
|
|
1777
1777
|
const scope = React.useMemo(() => {
|
|
1778
1778
|
if (!effectiveCtx) return undefined
|
|
1779
|
-
const s = effectiveCtx.get ? effectiveCtx.get('
|
|
1780
|
-
return s && typeof s.
|
|
1779
|
+
const s = effectiveCtx.get ? effectiveCtx.get('configForms') : effectiveCtx.configForms
|
|
1780
|
+
return s && typeof s.get === 'function' ? s.get(NS) : undefined
|
|
1781
1781
|
}, [effectiveCtx])
|
|
1782
1782
|
|
|
1783
1783
|
const snapshot = React.useSyncExternalStore
|
|
@@ -2135,7 +2135,7 @@ window.__ModuleLoader__.load({
|
|
|
2135
2135
|
)
|
|
2136
2136
|
}
|
|
2137
2137
|
|
|
2138
|
-
exports.inject = ['slots', 'locale', 'inputTriggers', '
|
|
2138
|
+
exports.inject = ['slots', 'locale', 'inputTriggers', 'configForms']
|
|
2139
2139
|
exports.apply = function apply(ctx) {
|
|
2140
2140
|
rootCtx = ctx
|
|
2141
2141
|
|
package/lib/pricing.js
CHANGED
|
@@ -28,6 +28,7 @@ export const DIRECT_VENDOR_RATES = {
|
|
|
28
28
|
export const FALLBACK_RATES = { input: 0.50, output: 1.50, cacheHit: 0.15 }
|
|
29
29
|
|
|
30
30
|
let memoryCatalog = null
|
|
31
|
+
let memoryCachePath = null
|
|
31
32
|
let lastFetchedAt = 0
|
|
32
33
|
|
|
33
34
|
/**
|
|
@@ -35,6 +36,7 @@ let lastFetchedAt = 0
|
|
|
35
36
|
*/
|
|
36
37
|
export function resetMemoryCatalog() {
|
|
37
38
|
memoryCatalog = null
|
|
39
|
+
memoryCachePath = null
|
|
38
40
|
lastFetchedAt = 0
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -42,13 +44,14 @@ export function resetMemoryCatalog() {
|
|
|
42
44
|
* Load cached catalog from disk into memory.
|
|
43
45
|
*/
|
|
44
46
|
export function loadCachedCatalog(cachePath = CACHE_FILE) {
|
|
45
|
-
if (memoryCatalog) return memoryCatalog
|
|
47
|
+
if (memoryCatalog && memoryCachePath === cachePath) return memoryCatalog
|
|
46
48
|
try {
|
|
47
49
|
if (existsSync(cachePath)) {
|
|
48
50
|
const raw = readFileSync(cachePath, 'utf8')
|
|
49
51
|
const parsed = JSON.parse(raw)
|
|
50
52
|
if (parsed && typeof parsed.models === 'object') {
|
|
51
53
|
memoryCatalog = parsed.models
|
|
54
|
+
memoryCachePath = cachePath
|
|
52
55
|
lastFetchedAt = parsed.updatedAt || 0
|
|
53
56
|
return memoryCatalog
|
|
54
57
|
}
|
|
@@ -57,6 +60,7 @@ export function loadCachedCatalog(cachePath = CACHE_FILE) {
|
|
|
57
60
|
// Ignore read/parse errors
|
|
58
61
|
}
|
|
59
62
|
memoryCatalog = {}
|
|
63
|
+
memoryCachePath = cachePath
|
|
60
64
|
return memoryCatalog
|
|
61
65
|
}
|
|
62
66
|
|
|
@@ -154,20 +158,103 @@ export function resolveModelRates(slot = {}, customPrices = {}, cachePath = CACH
|
|
|
154
158
|
if (catalog[fullKey]) return { ...catalog[fullKey] }
|
|
155
159
|
if (catalog[model]) return { ...catalog[model] }
|
|
156
160
|
|
|
157
|
-
|
|
161
|
+
if (!model) return { ...FALLBACK_RATES }
|
|
162
|
+
|
|
163
|
+
const entries = Object.entries(catalog)
|
|
164
|
+
if (entries.length === 0) return { ...FALLBACK_RATES }
|
|
165
|
+
|
|
166
|
+
// 3a. Exact case-insensitive fullKey match
|
|
167
|
+
for (const [catId, catRate] of entries) {
|
|
158
168
|
const catLower = catId.toLowerCase()
|
|
159
|
-
if (catLower
|
|
160
|
-
|
|
169
|
+
if (catLower === fullKey) return { ...catRate }
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 3b. Exact model match with provider matching
|
|
173
|
+
if (provider) {
|
|
174
|
+
for (const [catId, catRate] of entries) {
|
|
175
|
+
const catLower = catId.toLowerCase()
|
|
176
|
+
const slash = catLower.indexOf('/')
|
|
177
|
+
const catProv = slash !== -1 ? catLower.slice(0, slash) : ''
|
|
178
|
+
const catMod = slash !== -1 ? catLower.slice(slash + 1) : catLower
|
|
179
|
+
if (catProv === provider && (catMod === model || catLower.endsWith(`/${model}`))) {
|
|
180
|
+
return { ...catRate }
|
|
181
|
+
}
|
|
161
182
|
}
|
|
162
183
|
}
|
|
163
184
|
|
|
164
|
-
|
|
185
|
+
// 3c. Exact model match across providers or suffix match
|
|
186
|
+
for (const [catId, catRate] of entries) {
|
|
165
187
|
const catLower = catId.toLowerCase()
|
|
166
|
-
|
|
188
|
+
const slash = catLower.indexOf('/')
|
|
189
|
+
const catMod = slash !== -1 ? catLower.slice(slash + 1) : catLower
|
|
190
|
+
if (catMod === model || catLower.endsWith(`/${model}`)) {
|
|
167
191
|
return { ...catRate }
|
|
168
192
|
}
|
|
169
193
|
}
|
|
170
194
|
|
|
195
|
+
// 3d. Candidate resolution: prioritize same provider, select longest matching ID,
|
|
196
|
+
// and avoid bare substring collisions across distinct models with different rates.
|
|
197
|
+
let pool = entries
|
|
198
|
+
if (provider) {
|
|
199
|
+
const provEntries = entries.filter(([catId]) => {
|
|
200
|
+
const catLower = catId.toLowerCase()
|
|
201
|
+
const slash = catLower.indexOf('/')
|
|
202
|
+
return slash !== -1 && catLower.slice(0, slash) === provider
|
|
203
|
+
})
|
|
204
|
+
if (provEntries.length > 0) {
|
|
205
|
+
pool = provEntries
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
let bestCandidates = []
|
|
210
|
+
let bestScore = 0
|
|
211
|
+
|
|
212
|
+
for (const [catId, catRate] of pool) {
|
|
213
|
+
const catLower = catId.toLowerCase()
|
|
214
|
+
const slash = catLower.indexOf('/')
|
|
215
|
+
const catMod = slash !== -1 ? catLower.slice(slash + 1) : catLower
|
|
216
|
+
|
|
217
|
+
let score = 0
|
|
218
|
+
if (model.startsWith(catMod + '-') || model.startsWith(catMod + ':') || model.startsWith(catMod + '.')) {
|
|
219
|
+
// Query model is a specific variant/revision of catalog model (e.g. model="claude-3-sonnet-20240229", catMod="claude-3-sonnet")
|
|
220
|
+
score = 10000 + catMod.length
|
|
221
|
+
} else if (catMod.startsWith(model + '-') || catMod.startsWith(model + ':') || catMod.startsWith(model + '.')) {
|
|
222
|
+
// Catalog model is a revision/variant of query model
|
|
223
|
+
score = 5000 + model.length
|
|
224
|
+
} else if (model.includes(catMod) && catMod.length >= 4) {
|
|
225
|
+
score = 2000 + catMod.length
|
|
226
|
+
} else if (catMod.includes(model) && model.length >= 4) {
|
|
227
|
+
score = 1000 + model.length
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (score > 0) {
|
|
231
|
+
if (score > bestScore) {
|
|
232
|
+
bestScore = score
|
|
233
|
+
bestCandidates = [{ catId, catRate, score, catMod }]
|
|
234
|
+
} else if (score === bestScore) {
|
|
235
|
+
bestCandidates.push({ catId, catRate, score, catMod })
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (bestCandidates.length === 1) {
|
|
241
|
+
return { ...bestCandidates[0].catRate }
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (bestCandidates.length > 1) {
|
|
245
|
+
const firstRate = bestCandidates[0].catRate
|
|
246
|
+
const allAgree = bestCandidates.every(c =>
|
|
247
|
+
c.catRate.input === firstRate.input &&
|
|
248
|
+
c.catRate.output === firstRate.output
|
|
249
|
+
)
|
|
250
|
+
if (allAgree) {
|
|
251
|
+
return { ...firstRate }
|
|
252
|
+
}
|
|
253
|
+
// Conflict between different models with different pricing sharing a substring:
|
|
254
|
+
// return safe fallback rate instead of assigning a wrong model's price.
|
|
255
|
+
return { ...FALLBACK_RATES }
|
|
256
|
+
}
|
|
257
|
+
|
|
171
258
|
// 4. Fallback rate
|
|
172
259
|
return { ...FALLBACK_RATES }
|
|
173
260
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-moa",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.24",
|
|
4
4
|
"description": "Mixture of Agents (MoA) plugin for DeepSeek Harness with /moa slash command",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
"inject": [
|
|
49
49
|
"@deepseek-ai/dsh-client-locale",
|
|
50
50
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
51
|
-
"@deepseek-ai/dsh-client-ui-input-trigger"
|
|
51
|
+
"@deepseek-ai/dsh-client-ui-input-trigger",
|
|
52
|
+
"@deepseek-ai/dsh-client-ui-slots"
|
|
52
53
|
]
|
|
53
54
|
}
|
|
54
55
|
},
|