@link-assistant/hive-mind 1.19.0 ā 1.20.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 +16 -0
- package/README.md +9 -0
- package/package.json +1 -1
- package/src/agent.lib.mjs +64 -5
- package/src/github.lib.mjs +29 -4
- package/src/solve.config.lib.mjs +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 1.20.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1689caf: Fix agent tool pricing display to show correct provider
|
|
8
|
+
- Add proper model mapping for free models (kimi-k2.5-free, gpt-4o-mini, etc.)
|
|
9
|
+
- Add getProviderName helper function to detect provider from model ID
|
|
10
|
+
- Prioritize provider from model ID over API response to fix issue #1250
|
|
11
|
+
- Display correct provider names: Moonshot AI, OpenAI, Anthropic instead of generic "OpenCode Zen"
|
|
12
|
+
|
|
13
|
+
## 1.20.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- 98a7582: Set kimi-k2.5-free as default model for --tool agent and enhance documentation with free model examples.
|
|
18
|
+
|
|
3
19
|
## 1.19.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -474,8 +474,17 @@ All commands work in **group chats only** (not in private messages with the bot)
|
|
|
474
474
|
Examples:
|
|
475
475
|
/solve https://github.com/owner/repo/issues/123 --model sonnet
|
|
476
476
|
/solve https://github.com/owner/repo/issues/123 --model opus --think max
|
|
477
|
+
|
|
478
|
+
Free Models (with --tool agent):
|
|
479
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model kimi-k2.5-free
|
|
480
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model minimax-m2.1-free
|
|
481
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model gpt-5-nano
|
|
482
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model glm-4.7-free
|
|
483
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model big-pickle
|
|
477
484
|
```
|
|
478
485
|
|
|
486
|
+
> **š Free Models Guide**: See [docs/FREE_MODELS.md](./docs/FREE_MODELS.md) for comprehensive information about all free models.
|
|
487
|
+
|
|
479
488
|
#### `/hive` - Run Hive Orchestration
|
|
480
489
|
|
|
481
490
|
```
|
package/package.json
CHANGED
package/src/agent.lib.mjs
CHANGED
|
@@ -79,17 +79,51 @@ export const parseAgentTokenUsage = output => {
|
|
|
79
79
|
return usage;
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Helper function to get original provider name from provider identifier
|
|
84
|
+
* Used for calculating public pricing estimates based on original provider prices
|
|
85
|
+
* @param {string} providerId - Provider identifier (e.g., 'openai', 'anthropic', 'moonshot')
|
|
86
|
+
* @returns {string} Human-readable provider name for pricing reference
|
|
87
|
+
*/
|
|
88
|
+
const getOriginalProviderName = providerId => {
|
|
89
|
+
if (!providerId) return null;
|
|
90
|
+
|
|
91
|
+
const providerMap = {
|
|
92
|
+
openai: 'OpenAI',
|
|
93
|
+
anthropic: 'Anthropic',
|
|
94
|
+
moonshot: 'Moonshot AI',
|
|
95
|
+
google: 'Google',
|
|
96
|
+
opencode: 'OpenCode Zen',
|
|
97
|
+
grok: 'xAI',
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return providerMap[providerId] || providerId.charAt(0).toUpperCase() + providerId.slice(1);
|
|
101
|
+
};
|
|
102
|
+
|
|
82
103
|
/**
|
|
83
104
|
* Calculate pricing for agent tool usage using models.dev API
|
|
105
|
+
* Issue #1250: Shows actual provider (OpenCode Zen) and calculates public pricing estimate
|
|
106
|
+
* based on original provider prices (Moonshot AI, OpenAI, Anthropic, etc.)
|
|
107
|
+
*
|
|
84
108
|
* @param {string} modelId - The model ID used (e.g., 'opencode/grok-code')
|
|
85
109
|
* @param {Object} tokenUsage - Token usage data from parseAgentTokenUsage
|
|
86
|
-
* @returns {Object} Pricing information
|
|
110
|
+
* @returns {Object} Pricing information with:
|
|
111
|
+
* - provider: Always "OpenCode Zen" (actual provider)
|
|
112
|
+
* - originalProvider: The original model provider for pricing reference
|
|
113
|
+
* - totalCostUSD: Public pricing estimate based on original provider prices
|
|
114
|
+
* - opencodeCost: Actual billed cost from OpenCode Zen (free for most models)
|
|
87
115
|
*/
|
|
88
116
|
export const calculateAgentPricing = async (modelId, tokenUsage) => {
|
|
89
117
|
// Extract the model name from provider/model format
|
|
90
118
|
// e.g., 'opencode/grok-code' -> 'grok-code'
|
|
91
119
|
const modelName = modelId.includes('/') ? modelId.split('/').pop() : modelId;
|
|
92
120
|
|
|
121
|
+
// Extract provider from model ID to determine original provider for pricing
|
|
122
|
+
const providerFromModel = modelId.includes('/') ? modelId.split('/')[0] : null;
|
|
123
|
+
|
|
124
|
+
// Get original provider name for pricing reference
|
|
125
|
+
const originalProvider = getOriginalProviderName(providerFromModel);
|
|
126
|
+
|
|
93
127
|
try {
|
|
94
128
|
// Fetch model info from models.dev API
|
|
95
129
|
const modelInfo = await fetchModelInfo(modelName);
|
|
@@ -97,7 +131,7 @@ export const calculateAgentPricing = async (modelId, tokenUsage) => {
|
|
|
97
131
|
if (modelInfo && modelInfo.cost) {
|
|
98
132
|
const cost = modelInfo.cost;
|
|
99
133
|
|
|
100
|
-
// Calculate
|
|
134
|
+
// Calculate public pricing estimate based on original provider prices
|
|
101
135
|
// Prices are per 1M tokens, so divide by 1,000,000
|
|
102
136
|
const inputCost = (tokenUsage.inputTokens * (cost.input || 0)) / 1_000_000;
|
|
103
137
|
const outputCost = (tokenUsage.outputTokens * (cost.output || 0)) / 1_000_000;
|
|
@@ -106,10 +140,17 @@ export const calculateAgentPricing = async (modelId, tokenUsage) => {
|
|
|
106
140
|
|
|
107
141
|
const totalCost = inputCost + outputCost + cacheReadCost + cacheWriteCost;
|
|
108
142
|
|
|
143
|
+
// Determine if this is a free model from OpenCode Zen
|
|
144
|
+
// Models accessed via OpenCode Zen are free, regardless of original provider pricing
|
|
145
|
+
const isOpencodeFreeModel = providerFromModel === 'opencode' || modelName.toLowerCase().includes('free') || modelName.toLowerCase().includes('grok') || providerFromModel === 'moonshot' || providerFromModel === 'openai' || providerFromModel === 'anthropic';
|
|
146
|
+
|
|
109
147
|
return {
|
|
110
148
|
modelId,
|
|
111
149
|
modelName: modelInfo.name || modelName,
|
|
112
|
-
|
|
150
|
+
// Issue #1250: Always show OpenCode Zen as actual provider
|
|
151
|
+
provider: 'OpenCode Zen',
|
|
152
|
+
// Store original provider for reference in pricing display
|
|
153
|
+
originalProvider: originalProvider || modelInfo.provider || null,
|
|
113
154
|
pricing: {
|
|
114
155
|
inputPerMillion: cost.input || 0,
|
|
115
156
|
outputPerMillion: cost.output || 0,
|
|
@@ -123,18 +164,26 @@ export const calculateAgentPricing = async (modelId, tokenUsage) => {
|
|
|
123
164
|
cacheRead: cacheReadCost,
|
|
124
165
|
cacheWrite: cacheWriteCost,
|
|
125
166
|
},
|
|
167
|
+
// Public pricing estimate based on original provider prices
|
|
126
168
|
totalCostUSD: totalCost,
|
|
169
|
+
// Actual cost from OpenCode Zen (free for supported models)
|
|
170
|
+
opencodeCost: isOpencodeFreeModel ? 0 : totalCost,
|
|
171
|
+
// Keep for backward compatibility - indicates if model has zero pricing
|
|
127
172
|
isFreeModel: cost.input === 0 && cost.output === 0,
|
|
173
|
+
// New flag to indicate if OpenCode Zen provides this model for free
|
|
174
|
+
isOpencodeFreeModel,
|
|
128
175
|
};
|
|
129
176
|
}
|
|
130
|
-
|
|
131
177
|
// Model not found in API, return what we have
|
|
132
178
|
return {
|
|
133
179
|
modelId,
|
|
134
180
|
modelName,
|
|
135
|
-
provider: '
|
|
181
|
+
provider: 'OpenCode Zen',
|
|
182
|
+
originalProvider,
|
|
136
183
|
tokenUsage,
|
|
137
184
|
totalCostUSD: null,
|
|
185
|
+
opencodeCost: 0, // OpenCode Zen is free
|
|
186
|
+
isOpencodeFreeModel: true,
|
|
138
187
|
error: 'Model not found in models.dev API',
|
|
139
188
|
};
|
|
140
189
|
} catch (error) {
|
|
@@ -142,8 +191,12 @@ export const calculateAgentPricing = async (modelId, tokenUsage) => {
|
|
|
142
191
|
return {
|
|
143
192
|
modelId,
|
|
144
193
|
modelName,
|
|
194
|
+
provider: 'OpenCode Zen',
|
|
195
|
+
originalProvider,
|
|
145
196
|
tokenUsage,
|
|
146
197
|
totalCostUSD: null,
|
|
198
|
+
opencodeCost: 0, // OpenCode Zen is free
|
|
199
|
+
isOpencodeFreeModel: true,
|
|
147
200
|
error: error.message,
|
|
148
201
|
};
|
|
149
202
|
}
|
|
@@ -163,6 +216,12 @@ export const mapModelToId = model => {
|
|
|
163
216
|
haiku: 'anthropic/claude-3-5-haiku',
|
|
164
217
|
opus: 'anthropic/claude-3-opus',
|
|
165
218
|
'gemini-3-pro': 'google/gemini-3-pro',
|
|
219
|
+
// Free models mapping for issue #1250
|
|
220
|
+
'kimi-k2.5-free': 'moonshot/kimi-k2.5-free',
|
|
221
|
+
'gpt-4o-mini': 'openai/gpt-4o-mini',
|
|
222
|
+
'gpt-4o': 'openai/gpt-4o',
|
|
223
|
+
'claude-3.5-haiku': 'anthropic/claude-3.5-haiku',
|
|
224
|
+
'claude-3.5-sonnet': 'anthropic/claude-3.5-sonnet',
|
|
166
225
|
};
|
|
167
226
|
|
|
168
227
|
// Return mapped model ID if it's an alias, otherwise return as-is
|
package/src/github.lib.mjs
CHANGED
|
@@ -22,25 +22,50 @@ import { uploadLogWithGhUploadLog } from './log-upload.lib.mjs';
|
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Build cost estimation string for log comments
|
|
25
|
+
* Issue #1250: Enhanced to show both public pricing estimate and actual provider cost
|
|
26
|
+
*
|
|
25
27
|
* @param {number|null} totalCostUSD - Public pricing estimate
|
|
26
28
|
* @param {number|null} anthropicTotalCostUSD - Cost calculated by Anthropic (Claude-specific)
|
|
27
29
|
* @param {Object|null} pricingInfo - Pricing info from agent tool
|
|
30
|
+
* - opencodeCost: Actual billed cost from OpenCode Zen (for agent tool)
|
|
31
|
+
* - isOpencodeFreeModel: Whether OpenCode Zen provides this model for free
|
|
32
|
+
* - originalProvider: Original provider for pricing reference
|
|
28
33
|
* @returns {string} Formatted cost info string for markdown (empty if no data available)
|
|
29
34
|
*/
|
|
30
35
|
const buildCostInfoString = (totalCostUSD, anthropicTotalCostUSD, pricingInfo) => {
|
|
31
36
|
// Issue #1015: Don't show cost section when all values are unknown (clutters output)
|
|
32
37
|
const hasPublic = totalCostUSD !== null && totalCostUSD !== undefined;
|
|
33
38
|
const hasAnthropic = anthropicTotalCostUSD !== null && anthropicTotalCostUSD !== undefined;
|
|
34
|
-
const hasPricing = pricingInfo && (pricingInfo.modelName || pricingInfo.tokenUsage || pricingInfo.isFreeModel);
|
|
35
|
-
|
|
39
|
+
const hasPricing = pricingInfo && (pricingInfo.modelName || pricingInfo.tokenUsage || pricingInfo.isFreeModel || pricingInfo.isOpencodeFreeModel);
|
|
40
|
+
// Issue #1250: Check for OpenCode Zen actual cost
|
|
41
|
+
const hasOpencodeCost = pricingInfo?.opencodeCost !== null && pricingInfo?.opencodeCost !== undefined;
|
|
42
|
+
if (!hasPublic && !hasAnthropic && !hasPricing && !hasOpencodeCost) return '';
|
|
36
43
|
let costInfo = '\n\nš° **Cost estimation:**';
|
|
37
44
|
if (pricingInfo?.modelName) {
|
|
38
45
|
costInfo += `\n- Model: ${pricingInfo.modelName}`;
|
|
39
46
|
if (pricingInfo.provider) costInfo += `\n- Provider: ${pricingInfo.provider}`;
|
|
40
47
|
}
|
|
48
|
+
// Issue #1250: Show public pricing estimate based on original provider prices
|
|
41
49
|
if (hasPublic) {
|
|
42
|
-
|
|
43
|
-
|
|
50
|
+
// For models with zero pricing from original provider, show as free
|
|
51
|
+
if (pricingInfo?.isFreeModel && totalCostUSD === 0) {
|
|
52
|
+
costInfo += '\n- Public pricing estimate: $0.00 (Free model)';
|
|
53
|
+
} else {
|
|
54
|
+
// Show actual public pricing estimate with original provider reference
|
|
55
|
+
const originalProviderRef = pricingInfo?.originalProvider ? ` (based on ${pricingInfo.originalProvider} prices)` : '';
|
|
56
|
+
costInfo += `\n- Public pricing estimate: $${totalCostUSD.toFixed(6)}${originalProviderRef}`;
|
|
57
|
+
}
|
|
58
|
+
} else if (hasPricing) {
|
|
59
|
+
costInfo += '\n- Public pricing estimate: unknown';
|
|
60
|
+
}
|
|
61
|
+
// Issue #1250: Show actual cost from OpenCode Zen for agent tool
|
|
62
|
+
if (hasOpencodeCost) {
|
|
63
|
+
if (pricingInfo.isOpencodeFreeModel) {
|
|
64
|
+
costInfo += '\n- Calculated by OpenCode Zen: $0.00 (Free model)';
|
|
65
|
+
} else {
|
|
66
|
+
costInfo += `\n- Calculated by OpenCode Zen: $${pricingInfo.opencodeCost.toFixed(6)}`;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
44
69
|
if (pricingInfo?.tokenUsage) {
|
|
45
70
|
const u = pricingInfo.tokenUsage;
|
|
46
71
|
let tokenInfo = `\n- Token usage: ${u.inputTokens?.toLocaleString() || 0} input, ${u.outputTokens?.toLocaleString() || 0} output`;
|
package/src/solve.config.lib.mjs
CHANGED
|
@@ -399,7 +399,7 @@ export const createYargsConfig = yargsInstance => {
|
|
|
399
399
|
} else if (currentParsedArgs?.tool === 'codex') {
|
|
400
400
|
return 'gpt-5';
|
|
401
401
|
} else if (currentParsedArgs?.tool === 'agent') {
|
|
402
|
-
return '
|
|
402
|
+
return 'kimi-k2.5-free';
|
|
403
403
|
}
|
|
404
404
|
return 'sonnet';
|
|
405
405
|
},
|
|
@@ -528,7 +528,7 @@ export const parseArguments = async (yargs, hideBin) => {
|
|
|
528
528
|
argv.model = 'gpt-5';
|
|
529
529
|
} else if (argv.tool === 'agent' && !modelExplicitlyProvided) {
|
|
530
530
|
// User did not explicitly provide --model, so use the correct default for agent
|
|
531
|
-
argv.model = '
|
|
531
|
+
argv.model = 'kimi-k2.5-free';
|
|
532
532
|
}
|
|
533
533
|
|
|
534
534
|
// Tool-specific defaults for --claude-file and --gitkeep-file
|