@link-assistant/hive-mind 1.46.9 → 1.47.1
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/CHANGELOG.md +17 -0
- package/README.md +3 -2
- package/package.json +1 -1
- package/src/claude.budget-stats.lib.mjs +32 -31
- package/src/models/index.mjs +10 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 1.47.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3bbd66e: Improve Context and tokens usage output format: move percentage before unit label, parenthesize cached tokens in Total line, use consistent X / Y (Z%) format for output tokens when limit is known, and show sub-sessions under model heading instead of globally
|
|
8
|
+
|
|
9
|
+
## 1.47.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 7997308: feat: update free models for --tool agent, set qwen3.6-plus-free as default (#1543)
|
|
14
|
+
- Change default agent model from `minimax-m2.5-free` to `qwen3.6-plus-free` (~1M context window)
|
|
15
|
+
- Add `qwen3.6-plus-free` (Alibaba Qwen, ~1M context) to free models
|
|
16
|
+
- Add `nemotron-3-super-free` (NVIDIA hybrid Mamba-Transformer, ~262K context) to free models
|
|
17
|
+
- Update documentation, tests, and provider priority lists
|
|
18
|
+
- Syncs with upstream agent PR #234
|
|
19
|
+
|
|
3
20
|
## 1.46.9
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -445,10 +445,11 @@ Examples:
|
|
|
445
445
|
/solve https://github.com/owner/repo/issues/123 --model opus --think max
|
|
446
446
|
|
|
447
447
|
Free Models (with --tool agent):
|
|
448
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model qwen3.6-plus-free
|
|
449
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model opencode/qwen3.6-plus-free
|
|
450
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model nemotron-3-super-free
|
|
448
451
|
/solve https://github.com/owner/repo/issues/123 --tool agent --model minimax-m2.5-free
|
|
449
|
-
/solve https://github.com/owner/repo/issues/123 --tool agent --model opencode/minimax-m2.5-free
|
|
450
452
|
/solve https://github.com/owner/repo/issues/123 --tool agent --model gpt-5-nano
|
|
451
|
-
/solve https://github.com/owner/repo/issues/123 --tool agent --model big-pickle
|
|
452
453
|
|
|
453
454
|
Free Models via Kilo Gateway (with --tool agent):
|
|
454
455
|
/solve https://github.com/owner/repo/issues/123 --tool agent --model kilo/glm-5-free
|
package/package.json
CHANGED
|
@@ -165,16 +165,15 @@ export const displayBudgetStats = async (usage, tokenUsage, log) => {
|
|
|
165
165
|
const sub = subSessions[i];
|
|
166
166
|
const subPeak = sub.peakContextUsage || 0;
|
|
167
167
|
// Issue #1539: Only use peak per-request context for context window display.
|
|
168
|
-
//
|
|
169
|
-
// impossible percentages (e.g. 250%). When peak is unknown, skip context display.
|
|
168
|
+
// Issue #1547: Percentage before unit label: X / Y (Z%) input tokens
|
|
170
169
|
const parts = [];
|
|
171
170
|
if (contextLimit && subPeak > 0) {
|
|
172
171
|
const pct = ((subPeak / contextLimit) * 100).toFixed(0);
|
|
173
|
-
parts.push(`${formatNumber(subPeak)} / ${formatNumber(contextLimit)}
|
|
172
|
+
parts.push(`${formatNumber(subPeak)} / ${formatNumber(contextLimit)} (${pct}%) input tokens`);
|
|
174
173
|
}
|
|
175
174
|
if (outputLimit) {
|
|
176
175
|
const outPct = ((sub.outputTokens / outputLimit) * 100).toFixed(0);
|
|
177
|
-
parts.push(`${formatNumber(sub.outputTokens)} / ${formatNumber(outputLimit)}
|
|
176
|
+
parts.push(`${formatNumber(sub.outputTokens)} / ${formatNumber(outputLimit)} (${outPct}%) output tokens`);
|
|
178
177
|
}
|
|
179
178
|
if (parts.length > 0) {
|
|
180
179
|
await log(` ${i + 1}. Context window: ${parts.join(', ')}`);
|
|
@@ -182,14 +181,15 @@ export const displayBudgetStats = async (usage, tokenUsage, log) => {
|
|
|
182
181
|
}
|
|
183
182
|
} else if (peakContext > 0) {
|
|
184
183
|
// Single sub-session with known peak: single-line format
|
|
184
|
+
// Issue #1547: Percentage before unit label
|
|
185
185
|
const parts = [];
|
|
186
186
|
if (contextLimit) {
|
|
187
187
|
const pct = ((peakContext / contextLimit) * 100).toFixed(0);
|
|
188
|
-
parts.push(`${formatNumber(peakContext)} / ${formatNumber(contextLimit)}
|
|
188
|
+
parts.push(`${formatNumber(peakContext)} / ${formatNumber(contextLimit)} (${pct}%) input tokens`);
|
|
189
189
|
}
|
|
190
190
|
if (outputLimit) {
|
|
191
191
|
const outPct = ((usage.outputTokens / outputLimit) * 100).toFixed(0);
|
|
192
|
-
parts.push(`${formatNumber(usage.outputTokens)} / ${formatNumber(outputLimit)}
|
|
192
|
+
parts.push(`${formatNumber(usage.outputTokens)} / ${formatNumber(outputLimit)} (${outPct}%) output tokens`);
|
|
193
193
|
}
|
|
194
194
|
if (parts.length > 0) {
|
|
195
195
|
await log(` Context window: ${parts.join(', ')}`);
|
|
@@ -199,15 +199,20 @@ export const displayBudgetStats = async (usage, tokenUsage, log) => {
|
|
|
199
199
|
// Cumulative totals are shown on the Total line below — no duplication needed.
|
|
200
200
|
|
|
201
201
|
// Cumulative totals — single line
|
|
202
|
+
// Issue #1547: Parenthesized cached format and consistent output format
|
|
202
203
|
const totalInputNonCached = usage.inputTokens + usage.cacheCreationTokens;
|
|
203
204
|
const cachedTokens = usage.cacheReadTokens;
|
|
204
|
-
let totalLine
|
|
205
|
-
if (cachedTokens > 0)
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
let totalLine;
|
|
206
|
+
if (cachedTokens > 0) {
|
|
207
|
+
totalLine = `(${formatNumber(totalInputNonCached)} + ${formatNumber(cachedTokens)} cached) input tokens`;
|
|
208
|
+
} else {
|
|
209
|
+
totalLine = `${formatNumber(totalInputNonCached)} input tokens`;
|
|
210
|
+
}
|
|
208
211
|
if (peakContext === 0 && outputLimit) {
|
|
209
212
|
const outPct = ((usage.outputTokens / outputLimit) * 100).toFixed(0);
|
|
210
|
-
totalLine +=
|
|
213
|
+
totalLine += `, ${formatNumber(usage.outputTokens)} / ${formatNumber(outputLimit)} (${outPct}%) output tokens`;
|
|
214
|
+
} else {
|
|
215
|
+
totalLine += `, ${formatNumber(usage.outputTokens)} output tokens`;
|
|
211
216
|
}
|
|
212
217
|
await log(` Total: ${totalLine}`);
|
|
213
218
|
};
|
|
@@ -325,12 +330,12 @@ const formatContextOutputLine = (peakContext, contextLimit, outputTokens, output
|
|
|
325
330
|
// context window metrics and produce impossible percentages (e.g. 250%).
|
|
326
331
|
if (peakContext > 0) {
|
|
327
332
|
const pct = ((peakContext / contextLimit) * 100).toFixed(0);
|
|
328
|
-
parts.push(`${formatTokensCompact(peakContext)} / ${formatTokensCompact(contextLimit)}
|
|
333
|
+
parts.push(`${formatTokensCompact(peakContext)} / ${formatTokensCompact(contextLimit)} (${pct}%) input tokens`);
|
|
329
334
|
}
|
|
330
335
|
}
|
|
331
336
|
if (outputLimit) {
|
|
332
337
|
const outPct = ((outputTokens / outputLimit) * 100).toFixed(0);
|
|
333
|
-
parts.push(`${formatTokensCompact(outputTokens)} / ${formatTokensCompact(outputLimit)}
|
|
338
|
+
parts.push(`${formatTokensCompact(outputTokens)} / ${formatTokensCompact(outputLimit)} (${outPct}%) output tokens`);
|
|
334
339
|
}
|
|
335
340
|
if (parts.length === 0) return '';
|
|
336
341
|
return `\n${prefix}Context window: ${parts.join(', ')}`;
|
|
@@ -364,15 +369,6 @@ export const buildBudgetStatsString = tokenUsage => {
|
|
|
364
369
|
const subSessions = tokenUsage.subSessions || [];
|
|
365
370
|
const hasMultipleSubSessions = subSessions.length > 1;
|
|
366
371
|
|
|
367
|
-
if (isMultiModel && hasMultipleSubSessions) {
|
|
368
|
-
// Issue #1508: For multi-model sessions, show global sub-sessions once (not per-model),
|
|
369
|
-
// since sub-sessions track compactification boundaries which are session-wide.
|
|
370
|
-
// Per-model context/output limits are shown below under each model heading.
|
|
371
|
-
const primaryModelId = modelIds[0];
|
|
372
|
-
const primaryUsage = tokenUsage.modelUsage[primaryModelId];
|
|
373
|
-
stats += formatSubSessionsList(subSessions, primaryUsage.modelInfo?.limit?.context, primaryUsage.modelInfo?.limit?.output);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
372
|
for (const modelId of modelIds) {
|
|
377
373
|
const usage = tokenUsage.modelUsage[modelId];
|
|
378
374
|
const modelName = usage.modelName || modelId;
|
|
@@ -383,8 +379,9 @@ export const buildBudgetStatsString = tokenUsage => {
|
|
|
383
379
|
|
|
384
380
|
const peakContext = usage.peakContextUsage || 0;
|
|
385
381
|
|
|
386
|
-
if (!isMultiModel
|
|
387
|
-
//
|
|
382
|
+
if (hasMultipleSubSessions && (!isMultiModel || modelId === modelIds[0])) {
|
|
383
|
+
// Issue #1547: Show sub-sessions under the primary model heading (not globally).
|
|
384
|
+
// For single-model sessions, show under that model. For multi-model, under the first model.
|
|
388
385
|
stats += formatSubSessionsList(subSessions, contextLimit, outputLimit);
|
|
389
386
|
} else if (peakContext > 0) {
|
|
390
387
|
// Issue #1526: Single line format for context window + output tokens
|
|
@@ -394,18 +391,22 @@ export const buildBudgetStatsString = tokenUsage => {
|
|
|
394
391
|
// Cumulative totals are shown on the Total line below — no duplication needed.
|
|
395
392
|
|
|
396
393
|
// Cumulative totals per model: input tokens + cached shown separately
|
|
397
|
-
// Issue #
|
|
394
|
+
// Issue #1547: Parenthesized cached format: (X + Y cached) input tokens
|
|
398
395
|
const totalInputNonCached = usage.inputTokens + usage.cacheCreationTokens;
|
|
399
396
|
const cachedTokens = usage.cacheReadTokens;
|
|
400
|
-
let totalLine
|
|
401
|
-
if (cachedTokens > 0)
|
|
402
|
-
|
|
397
|
+
let totalLine;
|
|
398
|
+
if (cachedTokens > 0) {
|
|
399
|
+
totalLine = `(${formatTokensCompact(totalInputNonCached)} + ${formatTokensCompact(cachedTokens)} cached) input tokens`;
|
|
400
|
+
} else {
|
|
401
|
+
totalLine = `${formatTokensCompact(totalInputNonCached)} input tokens`;
|
|
402
|
+
}
|
|
403
403
|
|
|
404
|
-
// Issue #
|
|
405
|
-
// output token percentage in the Total line so no data is lost.
|
|
404
|
+
// Issue #1547: Consistent output format — use X / Y (Z%) output tokens when limit known
|
|
406
405
|
if (peakContext === 0 && outputLimit) {
|
|
407
406
|
const outPct = ((usage.outputTokens / outputLimit) * 100).toFixed(0);
|
|
408
|
-
totalLine +=
|
|
407
|
+
totalLine += `, ${formatTokensCompact(usage.outputTokens)} / ${formatTokensCompact(outputLimit)} (${outPct}%) output tokens`;
|
|
408
|
+
} else {
|
|
409
|
+
totalLine += `, ${formatTokensCompact(usage.outputTokens)} output tokens`;
|
|
409
410
|
}
|
|
410
411
|
|
|
411
412
|
// Issue #1508: Show per-model cost when available
|
package/src/models/index.mjs
CHANGED
|
@@ -47,6 +47,7 @@ export const claudeModels = {
|
|
|
47
47
|
|
|
48
48
|
// Agent models (OpenCode API and Kilo Gateway via agent CLI)
|
|
49
49
|
// Issue #1300: Updated free models to match agent PR #191
|
|
50
|
+
// Issue #1543: Added qwen3.6-plus-free (new default) and nemotron-3-super-free per agent PR #234
|
|
50
51
|
export const agentModels = {
|
|
51
52
|
// OpenCode Zen free models (current)
|
|
52
53
|
grok: 'opencode/grok-code',
|
|
@@ -54,7 +55,9 @@ export const agentModels = {
|
|
|
54
55
|
'grok-code-fast-1': 'opencode/grok-code',
|
|
55
56
|
'big-pickle': 'opencode/big-pickle',
|
|
56
57
|
'gpt-5-nano': 'opencode/gpt-5-nano',
|
|
57
|
-
'minimax-m2.5-free': 'opencode/minimax-m2.5-free', //
|
|
58
|
+
'minimax-m2.5-free': 'opencode/minimax-m2.5-free', // Upgraded from M2.1 (Issue #1391)
|
|
59
|
+
'qwen3.6-plus-free': 'opencode/qwen3.6-plus-free', // New: ~1M context, default (Issue #1543)
|
|
60
|
+
'nemotron-3-super-free': 'opencode/nemotron-3-super-free', // New: NVIDIA hybrid Mamba-Transformer (Issue #1543)
|
|
58
61
|
// Kilo Gateway free models (Issue #1282, updated in #1300)
|
|
59
62
|
// Short names for Kilo-exclusive models (Issue #1300)
|
|
60
63
|
'glm-5-free': 'kilo/glm-5-free', // Kilo-exclusive
|
|
@@ -112,7 +115,7 @@ export const codexModels = {
|
|
|
112
115
|
// Default model for each tool (Issue #1473: centralized to avoid scattered hardcoded defaults)
|
|
113
116
|
export const defaultModels = {
|
|
114
117
|
claude: 'sonnet',
|
|
115
|
-
agent: 'minimax-m2.5-free
|
|
118
|
+
agent: 'qwen3.6-plus-free', // Issue #1543: changed from minimax-m2.5-free per agent PR #234
|
|
116
119
|
opencode: 'grok-code-fast-1',
|
|
117
120
|
codex: 'gpt-5',
|
|
118
121
|
};
|
|
@@ -140,6 +143,8 @@ export const freeToBaseModelMap = {
|
|
|
140
143
|
'glm-4.7-free': 'glm-4.7',
|
|
141
144
|
'minimax-m2.1-free': 'minimax-m2.1',
|
|
142
145
|
'minimax-m2.5-free': 'minimax-m2.5',
|
|
146
|
+
'qwen3.6-plus-free': 'qwen3.6-plus', // Issue #1543
|
|
147
|
+
'nemotron-3-super-free': 'nemotron-3-super', // Issue #1543
|
|
143
148
|
'glm-5-free': 'glm-5',
|
|
144
149
|
'glm-4.5-air-free': 'glm-4.5-air',
|
|
145
150
|
'deepseek-r1-free': 'deepseek-r1',
|
|
@@ -187,6 +192,8 @@ export const AGENT_MODELS = {
|
|
|
187
192
|
'opencode/big-pickle': 'opencode/big-pickle',
|
|
188
193
|
'opencode/gpt-5-nano': 'opencode/gpt-5-nano',
|
|
189
194
|
'opencode/minimax-m2.5-free': 'opencode/minimax-m2.5-free',
|
|
195
|
+
'opencode/qwen3.6-plus-free': 'opencode/qwen3.6-plus-free', // Issue #1543
|
|
196
|
+
'opencode/nemotron-3-super-free': 'opencode/nemotron-3-super-free', // Issue #1543
|
|
190
197
|
'opencode/kimi-k2.5-free': 'opencode/kimi-k2.5-free', // Deprecated
|
|
191
198
|
'opencode/glm-4.7-free': 'opencode/glm-4.7-free', // Deprecated
|
|
192
199
|
'opencode/minimax-m2.1-free': 'opencode/minimax-m2.1-free', // Deprecated
|
|
@@ -297,7 +304,7 @@ export const primaryModelNames = {
|
|
|
297
304
|
claude: ['opus', 'sonnet', 'haiku', 'opusplan'],
|
|
298
305
|
opencode: ['grok', 'gpt4o'],
|
|
299
306
|
codex: ['gpt5', 'gpt5-codex', 'o3'],
|
|
300
|
-
agent: ['minimax-m2.5-free', 'big-pickle', 'gpt-5-nano', 'glm-5-free', 'deepseek-r1-free'],
|
|
307
|
+
agent: ['qwen3.6-plus-free', 'nemotron-3-super-free', 'minimax-m2.5-free', 'big-pickle', 'gpt-5-nano', 'glm-5-free', 'deepseek-r1-free'],
|
|
301
308
|
};
|
|
302
309
|
|
|
303
310
|
/**
|