@goodandready/dsh-moa 0.2.51 → 0.2.52

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/moa-budget.js CHANGED
@@ -87,15 +87,38 @@ export function estimatePanelCost(judges = [], numCandidates = 1, prices = {}, m
87
87
  * Calculates accurate synthesis prompt tokens accounting for full user prompt,
88
88
  * judge criteria, and reference candidate texts (#158).
89
89
  */
90
- export function calcSynthesisPromptTokens(userPrompt = '', referenceOutputs = [], judgeCriteria = '', overhead = 2600, options = {}) {
91
- const opts = (typeof overhead === 'object' && overhead !== null) ? overhead : (options || {})
92
- const baseOverhead = typeof overhead === 'number' ? overhead : 2600
93
- let promptChars = (typeof userPrompt === 'string' ? userPrompt.length : 0) +
94
- (typeof judgeCriteria === 'string' ? judgeCriteria.length : 0) +
95
- baseOverhead
90
+ export function calcSynthesisPromptTokens(firstArg = '', maybeRefs = [], maybeCriteria = '', maybeOverhead = 2600, maybeOptions = {}) {
91
+ let userPrompt, referenceOutputs, judgeCriteria, projectContext, priorTurnBaseline, consensusReport, compositeMergeDirective, baseOverhead
92
+
93
+ if (typeof firstArg === 'object' && firstArg !== null) {
94
+ userPrompt = firstArg.userPrompt || ''
95
+ referenceOutputs = firstArg.referenceOutputs || []
96
+ judgeCriteria = firstArg.judgeCriteria || ''
97
+ projectContext = firstArg.projectContext || ''
98
+ priorTurnBaseline = firstArg.priorTurnBaseline
99
+ consensusReport = firstArg.consensusReport
100
+ compositeMergeDirective = firstArg.compositeMergeDirective
101
+ baseOverhead = typeof firstArg.overhead === 'number' ? firstArg.overhead : 2600
102
+ } else {
103
+ userPrompt = typeof firstArg === 'string' ? firstArg : ''
104
+ referenceOutputs = Array.isArray(maybeRefs) ? maybeRefs : []
105
+ judgeCriteria = typeof maybeCriteria === 'string' ? maybeCriteria : ''
106
+ const opts = (typeof maybeOverhead === 'object' && maybeOverhead !== null) ? maybeOverhead : (maybeOptions || {})
107
+ projectContext = opts.projectContext || ''
108
+ priorTurnBaseline = opts.priorTurnBaseline
109
+ consensusReport = opts.consensusReport
110
+ compositeMergeDirective = opts.compositeMergeDirective
111
+ baseOverhead = typeof maybeOverhead === 'number' ? maybeOverhead : 2600
112
+ }
113
+
114
+ let promptChars = userPrompt.length + judgeCriteria.length + (projectContext?.length || 0) + baseOverhead
96
115
 
97
116
  if (Array.isArray(referenceOutputs)) {
117
+ if (referenceOutputs.some((r) => r && r.testResult)) {
118
+ promptChars += 550 // TEST_GATE_DIRECTIVE overhead
119
+ }
98
120
  for (const r of referenceOutputs) {
121
+ if (!r) continue
99
122
  promptChars += (r.text?.length || 0)
100
123
  if (r.testResult) {
101
124
  promptChars += 150 + (r.testResult.output?.length || 0)
@@ -105,12 +128,12 @@ export function calcSynthesisPromptTokens(userPrompt = '', referenceOutputs = []
105
128
  }
106
129
  }
107
130
  }
108
- if (opts.priorTurnBaseline) promptChars += opts.priorTurnBaseline.length + 50
109
- if (opts.consensusReport) {
110
- const crText = typeof opts.consensusReport === 'string' ? opts.consensusReport : JSON.stringify(opts.consensusReport)
131
+ if (priorTurnBaseline) promptChars += priorTurnBaseline.length + 50
132
+ if (consensusReport) {
133
+ const crText = typeof consensusReport === 'string' ? consensusReport : JSON.stringify(consensusReport)
111
134
  promptChars += crText.length + 50
112
135
  }
113
- if (opts.compositeMergeDirective) promptChars += opts.compositeMergeDirective.length + 50
136
+ if (compositeMergeDirective) promptChars += compositeMergeDirective.length + 50
114
137
 
115
138
  return Math.max(50, Math.ceil(promptChars / 4))
116
139
  }
@@ -301,8 +324,23 @@ export function createBudgetAbortPayload({
301
324
  multiJudgeResult = null,
302
325
  }) {
303
326
  const aggLabel = (primaryJudge?.provider && primaryJudge?.model) ? `${primaryJudge.provider}:${primaryJudge.model}` : "none";
304
- const refTokens = referenceOutputs.reduce((acc, r) => acc + (r.usage?.totalTokens || 0), 0);
305
- const panelTokens = multiJudgeResult?.totalUsage?.totalTokens || 0;
327
+ const refTokens = referenceOutputs.reduce((acc, r) => acc + (r.usage?.totalTokens ?? ((r.usage?.inputTokens || 0) + (r.usage?.outputTokens || 0))), 0);
328
+ const refInTokens = referenceOutputs.reduce((acc, r) => acc + (r.usage?.inputTokens || r.usage?.promptTokens || 0), 0);
329
+ const refOutTokens = referenceOutputs.reduce((acc, r) => acc + (r.usage?.outputTokens || r.usage?.completionTokens || 0), 0);
330
+
331
+ const mjUsage = multiJudgeResult?.totalUsage;
332
+ const panelTokens = mjUsage?.totalTokens ?? ((mjUsage?.inputTokens || 0) + (mjUsage?.outputTokens || 0));
333
+ const panelInTokens = mjUsage?.inputTokens || mjUsage?.promptTokens || 0;
334
+ const panelOutTokens = mjUsage?.outputTokens || mjUsage?.completionTokens || 0;
335
+ const panelCostUsd = mjUsage?.costUsd || multiJudgeResult?.totalCostUsd || 0;
336
+
337
+ const refCost = referenceOutputs.reduce((acc, r) => acc + (r.costUsd || 0), 0);
338
+ const totalCostUsd = Number(Math.max(currentSpentUsd, refCost + panelCostUsd).toFixed(5));
339
+
340
+ const totalTokens = refTokens + panelTokens;
341
+ const totalInputTokens = refInTokens + panelInTokens;
342
+ const totalOutputTokens = refOutTokens + panelOutTokens;
343
+
306
344
  return {
307
345
  kind: "failure",
308
346
  content: `🛑 Budget Guardrail Abort: ${reason}`,
@@ -315,11 +353,13 @@ export function createBudgetAbortPayload({
315
353
  winnerModel: "none",
316
354
  promotedFiles: [],
317
355
  usage: {
318
- totalTokens: refTokens + panelTokens,
319
- totalCostUsd: Number(currentSpentUsd.toFixed(5)),
356
+ totalTokens,
357
+ totalInputTokens,
358
+ totalOutputTokens,
359
+ totalCostUsd,
320
360
  candidates: referenceOutputs.map((r) => ({ label: r.label, usage: r.usage, costUsd: r.costUsd })),
321
361
  aggregator: { inputTokens: 0, outputTokens: 0, totalTokens: 0, costUsd: 0 },
322
- ...(multiJudgeResult ? { multiJudge: multiJudgeResult.totalUsage || { totalTokens: panelTokens } } : {}),
362
+ ...(multiJudgeResult ? { multiJudge: mjUsage || { inputTokens: panelInTokens, outputTokens: panelOutTokens, totalTokens: panelTokens, costUsd: panelCostUsd } } : {}),
323
363
  },
324
364
  multiJudgeResult: multiJudgeResult || undefined,
325
365
  skippedFiles: collectedCtx?.skippedFiles || 0,
@@ -420,7 +420,11 @@ export async function runMultiJudgePhase({
420
420
  const panelMaxTokens = Math.min(typeof preset.max_tokens === 'number' && preset.max_tokens > 0 ? preset.max_tokens : 2048, 2048)
421
421
 
422
422
  if (preset?.budget_guard_enabled && preset?.max_budget_usd > 0) {
423
- const promptTokens = calcSynthesisPromptTokens(userPrompt, successfulRefs, judgeCriteria)
423
+ const promptTokens = calcSynthesisPromptTokens({
424
+ userPrompt,
425
+ referenceOutputs: successfulRefs,
426
+ judgeCriteria,
427
+ })
424
428
  const panelEst = estimatePanelCost(panelJudges, successfulRefs.length, prices, panelMaxTokens, promptTokens)
425
429
  const downEst = estimateDownstreamCost(primaryJudge, [], successfulRefs.length, prices, maxTokens, promptTokens)
426
430
  const phaseCheck = checkPhaseBudget({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-moa",
3
- "version": "0.2.51",
3
+ "version": "0.2.52",
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",