@link-assistant/hive-mind 1.23.11 → 1.23.13
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 +26 -0
- package/README.md +19 -8
- package/package.json +1 -1
- package/src/agent.lib.mjs +20 -5
- package/src/model-mapping.lib.mjs +20 -7
- package/src/model-validation.lib.mjs +27 -10
- package/src/solve.config.lib.mjs +1 -1
- package/src/telegram-bot.mjs +10 -7
- package/src/version.lib.mjs +16 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @link-assistant/hive-mind
|
|
2
2
|
|
|
3
|
+
## 1.23.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- af1f456: fix: suppress dotenvx MISSING_ENV_FILE warnings in hive-telegram-bot --version
|
|
8
|
+
- Add early --version handling before loading dotenvx to avoid warnings
|
|
9
|
+
- Add ignore: ['MISSING_ENV_FILE'] option to make .env file optional
|
|
10
|
+
- Add tests for version output in tests/test-telegram-bot-version.mjs
|
|
11
|
+
|
|
12
|
+
## 1.23.12
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 50a69ae: Update free models: replace minimax-m2.1-free with minimax-m2.5-free
|
|
17
|
+
|
|
18
|
+
OpenCode Zen:
|
|
19
|
+
- Replace `minimax-m2.1-free` with `minimax-m2.5-free` (M2.1 no longer free)
|
|
20
|
+
- Remove `glm-4.7-free` from recommended free models (no longer free)
|
|
21
|
+
|
|
22
|
+
Kilo Gateway:
|
|
23
|
+
- Add `glm-4.5-air-free` (agent-centric model)
|
|
24
|
+
- Add `minimax-m2.5-free` (upgraded from M2.1)
|
|
25
|
+
- Add `deepseek-r1-free` (advanced reasoning model)
|
|
26
|
+
|
|
27
|
+
Breaking change: Users relying on `minimax-m2.1-free` or `glm-4.7-free` should switch to the updated models. Deprecated models are kept for backward compatibility but may not work.
|
|
28
|
+
|
|
3
29
|
## 1.23.11
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -149,11 +149,14 @@ Run the Hive Mind using Docker for safer local installation - no manual setup re
|
|
|
149
149
|
# Pull the latest image from Docker Hub
|
|
150
150
|
docker pull konard/hive-mind:latest
|
|
151
151
|
|
|
152
|
-
#
|
|
153
|
-
docker run -
|
|
152
|
+
# Start hive-mind container
|
|
153
|
+
docker run -dit --name hive-mind konard/hive-mind:latest
|
|
154
154
|
|
|
155
|
-
#
|
|
156
|
-
|
|
155
|
+
# Verify container started
|
|
156
|
+
docker ps -a
|
|
157
|
+
|
|
158
|
+
# Enter additional terminal process to do installation
|
|
159
|
+
docker exec -it hive-mind /bin/bash
|
|
157
160
|
|
|
158
161
|
# Inside the container, authenticate with GitHub
|
|
159
162
|
gh-setup-git-identity
|
|
@@ -163,6 +166,15 @@ claude
|
|
|
163
166
|
|
|
164
167
|
# Now you can use hive and solve commands
|
|
165
168
|
solve https://github.com/owner/repo/issues/123
|
|
169
|
+
|
|
170
|
+
# Or you can run telegram bot:
|
|
171
|
+
|
|
172
|
+
# Run an to main process
|
|
173
|
+
docker attach hive-mind
|
|
174
|
+
|
|
175
|
+
# Run bot here
|
|
176
|
+
|
|
177
|
+
# Press Ctrl + P, Ctrl + Q to detach without destroying the container (no stopping of main bash process)
|
|
166
178
|
```
|
|
167
179
|
|
|
168
180
|
**Benefits of Docker:**
|
|
@@ -477,15 +489,14 @@ Examples:
|
|
|
477
489
|
|
|
478
490
|
Free Models (with --tool agent):
|
|
479
491
|
/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.
|
|
492
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model minimax-m2.5-free
|
|
481
493
|
/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
494
|
/solve https://github.com/owner/repo/issues/123 --tool agent --model big-pickle
|
|
484
495
|
|
|
485
496
|
Free Models via Kilo Gateway (with --tool agent):
|
|
486
497
|
/solve https://github.com/owner/repo/issues/123 --tool agent --model kilo/glm-5-free
|
|
487
|
-
/solve https://github.com/owner/repo/issues/123 --tool agent --model kilo/glm-4.
|
|
488
|
-
/solve https://github.com/owner/repo/issues/123 --tool agent --model kilo/
|
|
498
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model kilo/glm-4.5-air-free
|
|
499
|
+
/solve https://github.com/owner/repo/issues/123 --tool agent --model kilo/deepseek-r1-free
|
|
489
500
|
```
|
|
490
501
|
|
|
491
502
|
> **📖 Free Models Guide**: See [docs/FREE_MODELS.md](./docs/FREE_MODELS.md) for comprehensive information about all free models including OpenCode Zen and Kilo Gateway providers.
|
package/package.json
CHANGED
package/src/agent.lib.mjs
CHANGED
|
@@ -94,6 +94,7 @@ const getOriginalProviderName = providerId => {
|
|
|
94
94
|
moonshot: 'Moonshot AI',
|
|
95
95
|
google: 'Google',
|
|
96
96
|
opencode: 'OpenCode Zen',
|
|
97
|
+
kilo: 'Kilo Gateway',
|
|
97
98
|
grok: 'xAI',
|
|
98
99
|
};
|
|
99
100
|
|
|
@@ -210,9 +211,10 @@ export const calculateAgentPricing = async (modelId, tokenUsage) => {
|
|
|
210
211
|
|
|
211
212
|
const totalCost = inputCost + outputCost + cacheReadCost + cacheWriteCost + reasoningCost;
|
|
212
213
|
|
|
213
|
-
// Determine if this is a free model from OpenCode Zen
|
|
214
|
-
// Models accessed via OpenCode Zen are free, regardless of original provider pricing
|
|
215
|
-
|
|
214
|
+
// Determine if this is a free model from OpenCode Zen or Kilo Gateway
|
|
215
|
+
// Models accessed via OpenCode Zen or Kilo Gateway are free, regardless of original provider pricing
|
|
216
|
+
// Issue #1300: Added kilo provider detection for Kilo Gateway free models
|
|
217
|
+
const isOpencodeFreeModel = providerFromModel === 'opencode' || providerFromModel === 'kilo' || isFreeVariant || modelName.toLowerCase().includes('free') || modelName.toLowerCase().includes('grok') || providerFromModel === 'moonshot' || providerFromModel === 'openai' || providerFromModel === 'anthropic';
|
|
216
218
|
|
|
217
219
|
// Use base model's provider for original provider reference if available
|
|
218
220
|
const effectiveOriginalProvider = baseModelInfo?.provider || originalProvider || effectiveModelInfo?.provider || null;
|
|
@@ -282,23 +284,36 @@ export const calculateAgentPricing = async (modelId, tokenUsage) => {
|
|
|
282
284
|
// Model mapping to translate aliases to full model IDs for Agent
|
|
283
285
|
// Agent uses OpenCode Zen's JSON interface and models
|
|
284
286
|
// Issue #1185: Free models use opencode/ prefix (not openai/)
|
|
287
|
+
// Issue #1300: Updated mappings - use opencode/ and kilo/ prefixes only,
|
|
288
|
+
// short names for Kilo-exclusive models map to kilo/ prefix
|
|
285
289
|
export const mapModelToId = model => {
|
|
286
290
|
const modelMap = {
|
|
291
|
+
// OpenCode Zen free models
|
|
287
292
|
grok: 'opencode/grok-code',
|
|
288
293
|
'grok-code': 'opencode/grok-code',
|
|
289
294
|
'grok-code-fast-1': 'opencode/grok-code',
|
|
290
295
|
'big-pickle': 'opencode/big-pickle',
|
|
291
296
|
'gpt-5-nano': 'opencode/gpt-5-nano',
|
|
297
|
+
'minimax-m2.5-free': 'opencode/minimax-m2.5-free',
|
|
298
|
+
'kimi-k2.5-free': 'opencode/kimi-k2.5-free',
|
|
299
|
+
// Kilo Gateway free models - short names for Kilo-exclusive models (Issue #1300)
|
|
300
|
+
'glm-5-free': 'kilo/glm-5-free',
|
|
301
|
+
'glm-4.5-air-free': 'kilo/glm-4.5-air-free',
|
|
302
|
+
'deepseek-r1-free': 'kilo/deepseek-r1-free',
|
|
303
|
+
'giga-potato-free': 'kilo/giga-potato-free',
|
|
304
|
+
'trinity-large-preview': 'kilo/trinity-large-preview',
|
|
305
|
+
// Premium models
|
|
292
306
|
sonnet: 'anthropic/claude-3-5-sonnet',
|
|
293
307
|
haiku: 'anthropic/claude-3-5-haiku',
|
|
294
308
|
opus: 'anthropic/claude-3-opus',
|
|
295
309
|
'gemini-3-pro': 'google/gemini-3-pro',
|
|
296
|
-
// Free models mapping for issue #1250
|
|
297
|
-
'kimi-k2.5-free': 'moonshot/kimi-k2.5-free',
|
|
298
310
|
'gpt-4o-mini': 'openai/gpt-4o-mini',
|
|
299
311
|
'gpt-4o': 'openai/gpt-4o',
|
|
300
312
|
'claude-3.5-haiku': 'anthropic/claude-3.5-haiku',
|
|
301
313
|
'claude-3.5-sonnet': 'anthropic/claude-3.5-sonnet',
|
|
314
|
+
// Deprecated free models (backward compatibility)
|
|
315
|
+
'glm-4.7-free': 'opencode/glm-4.7-free',
|
|
316
|
+
'minimax-m2.1-free': 'opencode/minimax-m2.1-free',
|
|
302
317
|
};
|
|
303
318
|
|
|
304
319
|
// Return mapped model ID if it's an alias, otherwise return as-is
|
|
@@ -26,23 +26,36 @@ export const claudeModels = {
|
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
// Agent models (OpenCode API and Kilo Gateway via agent CLI)
|
|
29
|
+
// Issue #1300: Updated free models to match agent PR #191
|
|
29
30
|
export const agentModels = {
|
|
30
|
-
// OpenCode Zen free models
|
|
31
|
+
// OpenCode Zen free models (current)
|
|
31
32
|
grok: 'opencode/grok-code',
|
|
32
33
|
'grok-code': 'opencode/grok-code',
|
|
33
34
|
'grok-code-fast-1': 'opencode/grok-code',
|
|
34
35
|
'big-pickle': 'opencode/big-pickle',
|
|
35
36
|
'gpt-5-nano': 'opencode/gpt-5-nano',
|
|
36
|
-
'
|
|
37
|
-
'minimax-m2.1-free': 'opencode/minimax-m2.1-free',
|
|
37
|
+
'minimax-m2.5-free': 'opencode/minimax-m2.5-free', // New: upgraded from M2.1
|
|
38
38
|
'kimi-k2.5-free': 'opencode/kimi-k2.5-free',
|
|
39
|
-
// Kilo Gateway free models (Issue #1282)
|
|
39
|
+
// Kilo Gateway free models (Issue #1282, updated in #1300)
|
|
40
|
+
// Short names for Kilo-exclusive models (Issue #1300)
|
|
41
|
+
'glm-5-free': 'kilo/glm-5-free', // Kilo-exclusive
|
|
42
|
+
'glm-4.5-air-free': 'kilo/glm-4.5-air-free', // Kilo-exclusive: agent-centric model
|
|
43
|
+
'deepseek-r1-free': 'kilo/deepseek-r1-free', // Kilo-exclusive: reasoning model
|
|
44
|
+
'giga-potato-free': 'kilo/giga-potato-free', // Kilo-exclusive
|
|
45
|
+
'trinity-large-preview': 'kilo/trinity-large-preview', // Kilo-exclusive
|
|
46
|
+
// Full names with kilo/ prefix
|
|
40
47
|
'kilo/glm-5-free': 'kilo/glm-5-free',
|
|
41
|
-
'kilo/glm-4.
|
|
42
|
-
'kilo/
|
|
43
|
-
'kilo/
|
|
48
|
+
'kilo/glm-4.5-air-free': 'kilo/glm-4.5-air-free',
|
|
49
|
+
'kilo/minimax-m2.5-free': 'kilo/minimax-m2.5-free', // Also on OpenCode Zen
|
|
50
|
+
'kilo/deepseek-r1-free': 'kilo/deepseek-r1-free',
|
|
44
51
|
'kilo/giga-potato-free': 'kilo/giga-potato-free',
|
|
45
52
|
'kilo/trinity-large-preview': 'kilo/trinity-large-preview',
|
|
53
|
+
// Deprecated free models (kept for backward compatibility)
|
|
54
|
+
'glm-4.7-free': 'opencode/glm-4.7-free', // Deprecated: no longer free
|
|
55
|
+
'minimax-m2.1-free': 'opencode/minimax-m2.1-free', // Deprecated: replaced by m2.5
|
|
56
|
+
'kilo/glm-4.7-free': 'kilo/glm-4.7-free', // Deprecated: replaced by glm-4.5-air-free
|
|
57
|
+
'kilo/kimi-k2.5-free': 'kilo/kimi-k2.5-free', // Deprecated: not recommended
|
|
58
|
+
'kilo/minimax-m2.1-free': 'kilo/minimax-m2.1-free', // Deprecated: replaced by m2.5
|
|
46
59
|
// Premium models
|
|
47
60
|
sonnet: 'anthropic/claude-3-5-sonnet',
|
|
48
61
|
haiku: 'anthropic/claude-3-5-haiku',
|
|
@@ -94,23 +94,38 @@ export const CODEX_MODELS = {
|
|
|
94
94
|
export const AGENT_MODELS = {
|
|
95
95
|
// Free models (via OpenCode Zen)
|
|
96
96
|
// Issue #1185: Model IDs must use opencode/ prefix for OpenCode Zen models
|
|
97
|
+
// Issue #1300: Updated free models - minimax-m2.5-free replaces m2.1, glm-4.7-free removed
|
|
97
98
|
grok: 'opencode/grok-code',
|
|
98
99
|
'grok-code': 'opencode/grok-code',
|
|
99
100
|
'grok-code-fast-1': 'opencode/grok-code',
|
|
100
101
|
'big-pickle': 'opencode/big-pickle',
|
|
101
102
|
'gpt-5-nano': 'opencode/gpt-5-nano',
|
|
102
|
-
'
|
|
103
|
-
'minimax-m2.1-free': 'opencode/minimax-m2.1-free',
|
|
103
|
+
'minimax-m2.5-free': 'opencode/minimax-m2.5-free', // Upgraded from M2.1 (Issue #1300)
|
|
104
104
|
'kimi-k2.5-free': 'opencode/kimi-k2.5-free',
|
|
105
105
|
// Free models (via Kilo Gateway)
|
|
106
106
|
// Issue #1282: Kilo provider adds access to 500+ models including free tier
|
|
107
|
+
// Issue #1300: Updated Kilo free models with new offerings
|
|
107
108
|
// See: https://kilo.ai/docs/advanced-usage/free-and-budget-models
|
|
108
|
-
|
|
109
|
-
'
|
|
110
|
-
'
|
|
111
|
-
'
|
|
112
|
-
'
|
|
113
|
-
'
|
|
109
|
+
// Short names for Kilo-exclusive models (Issue #1300)
|
|
110
|
+
'glm-5-free': 'kilo/glm-5-free', // Kilo-exclusive: Z.AI flagship model
|
|
111
|
+
'glm-4.5-air-free': 'kilo/glm-4.5-air-free', // Kilo-exclusive: Z.AI agent-centric model
|
|
112
|
+
'deepseek-r1-free': 'kilo/deepseek-r1-free', // Kilo-exclusive: DeepSeek reasoning model
|
|
113
|
+
'giga-potato-free': 'kilo/giga-potato-free', // Kilo-exclusive: Evaluation model
|
|
114
|
+
'trinity-large-preview': 'kilo/trinity-large-preview', // Kilo-exclusive: Arcee AI preview
|
|
115
|
+
// Full names with kilo/ prefix
|
|
116
|
+
'kilo/glm-5-free': 'kilo/glm-5-free',
|
|
117
|
+
'kilo/glm-4.5-air-free': 'kilo/glm-4.5-air-free',
|
|
118
|
+
'kilo/minimax-m2.5-free': 'kilo/minimax-m2.5-free', // Also on OpenCode Zen
|
|
119
|
+
'kilo/deepseek-r1-free': 'kilo/deepseek-r1-free',
|
|
120
|
+
'kilo/giga-potato-free': 'kilo/giga-potato-free',
|
|
121
|
+
'kilo/trinity-large-preview': 'kilo/trinity-large-preview',
|
|
122
|
+
// Deprecated free models (kept for backward compatibility)
|
|
123
|
+
// These models are no longer the recommended options but may still work
|
|
124
|
+
'glm-4.7-free': 'opencode/glm-4.7-free', // Deprecated: no longer free on OpenCode Zen
|
|
125
|
+
'minimax-m2.1-free': 'opencode/minimax-m2.1-free', // Deprecated: replaced by m2.5
|
|
126
|
+
'kilo/glm-4.7-free': 'kilo/glm-4.7-free', // Deprecated: replaced by glm-4.5-air-free
|
|
127
|
+
'kilo/kimi-k2.5-free': 'kilo/kimi-k2.5-free', // Deprecated: not recommended
|
|
128
|
+
'kilo/minimax-m2.1-free': 'kilo/minimax-m2.1-free', // Deprecated: replaced by m2.5
|
|
114
129
|
// Premium models (requires OpenCode Zen subscription)
|
|
115
130
|
sonnet: 'anthropic/claude-3-5-sonnet',
|
|
116
131
|
haiku: 'anthropic/claude-3-5-haiku',
|
|
@@ -120,9 +135,11 @@ export const AGENT_MODELS = {
|
|
|
120
135
|
'opencode/grok-code': 'opencode/grok-code',
|
|
121
136
|
'opencode/big-pickle': 'opencode/big-pickle',
|
|
122
137
|
'opencode/gpt-5-nano': 'opencode/gpt-5-nano',
|
|
123
|
-
'opencode/
|
|
124
|
-
'opencode/minimax-m2.1-free': 'opencode/minimax-m2.1-free',
|
|
138
|
+
'opencode/minimax-m2.5-free': 'opencode/minimax-m2.5-free', // New (Issue #1300)
|
|
125
139
|
'opencode/kimi-k2.5-free': 'opencode/kimi-k2.5-free',
|
|
140
|
+
// Deprecated OpenCode Zen models (kept for backward compatibility)
|
|
141
|
+
'opencode/glm-4.7-free': 'opencode/glm-4.7-free', // Deprecated
|
|
142
|
+
'opencode/minimax-m2.1-free': 'opencode/minimax-m2.1-free', // Deprecated
|
|
126
143
|
// Premium models with provider prefix
|
|
127
144
|
'anthropic/claude-3-5-sonnet': 'anthropic/claude-3-5-sonnet',
|
|
128
145
|
'anthropic/claude-3-5-haiku': 'anthropic/claude-3-5-haiku',
|
package/src/solve.config.lib.mjs
CHANGED
|
@@ -400,7 +400,7 @@ export const createYargsConfig = yargsInstance => {
|
|
|
400
400
|
config = config
|
|
401
401
|
.option('model', {
|
|
402
402
|
type: 'string',
|
|
403
|
-
description: 'Model to use (for claude: opus, sonnet, haiku, haiku-3-5, haiku-3; for opencode: grok, gpt4o; for codex: gpt5, gpt5-codex, o3; for agent:
|
|
403
|
+
description: 'Model to use (for claude: opus, sonnet, haiku, haiku-3-5, haiku-3; for opencode: grok, gpt4o; for codex: gpt5, gpt5-codex, o3; for agent: kimi-k2.5-free, big-pickle, gpt-5-nano, minimax-m2.5-free, glm-5-free, deepseek-r1-free)',
|
|
404
404
|
alias: 'm',
|
|
405
405
|
default: currentParsedArgs => {
|
|
406
406
|
// Dynamic default based on tool selection
|
package/src/telegram-bot.mjs
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// Early exit for --version (issue #1318: avoid dotenvx MISSING_ENV_FILE warnings)
|
|
3
|
+
if (process.argv.includes('--version')) {
|
|
4
|
+
const v = await import('./version.lib.mjs').then(m => m.getVersion()).catch(() => 'unknown');
|
|
5
|
+
console.log(v);
|
|
6
|
+
process.exit(v === 'unknown' ? 1 : 0);
|
|
7
|
+
}
|
|
2
8
|
|
|
3
9
|
import { spawn } from 'child_process';
|
|
4
10
|
import { promisify } from 'util';
|
|
@@ -21,7 +27,9 @@ const dotenvx = dotenvxModule.default || dotenvxModule;
|
|
|
21
27
|
const getenv = await use('getenv');
|
|
22
28
|
|
|
23
29
|
// Load .env configuration as base
|
|
24
|
-
|
|
30
|
+
// quiet: true suppresses info messages, ignore: ['MISSING_ENV_FILE'] suppresses error when .env doesn't exist
|
|
31
|
+
// This makes .env file optional (issue #1318)
|
|
32
|
+
dotenvx.config({ quiet: true, ignore: ['MISSING_ENV_FILE'] });
|
|
25
33
|
|
|
26
34
|
// Load .lenv configuration (if exists)
|
|
27
35
|
// .lenv overrides .env
|
|
@@ -30,20 +38,15 @@ loadLenvConfig({ override: true, quiet: true });
|
|
|
30
38
|
const yargsModule = await use('yargs@17.7.2');
|
|
31
39
|
const yargs = yargsModule.default || yargsModule;
|
|
32
40
|
const { hideBin } = await use('yargs@17.7.2/helpers');
|
|
33
|
-
|
|
34
|
-
// Import solve and hive yargs configurations for validation
|
|
41
|
+
// Import yargs configurations, GitHub utilities, and telegram helpers
|
|
35
42
|
const { createYargsConfig: createSolveYargsConfig, detectMalformedFlags } = await import('./solve.config.lib.mjs');
|
|
36
43
|
const { createYargsConfig: createHiveYargsConfig } = await import('./hive.config.lib.mjs');
|
|
37
|
-
// Import GitHub URL parser for extracting URLs from messages
|
|
38
44
|
const { parseGitHubUrl } = await import('./github.lib.mjs');
|
|
39
|
-
// Import model validation for early validation with helpful error messages
|
|
40
45
|
const { validateModelName } = await import('./model-validation.lib.mjs');
|
|
41
|
-
// Import libraries for /limits, /version, and markdown escaping
|
|
42
46
|
const { formatUsageMessage, getAllCachedLimits } = await import('./limits.lib.mjs');
|
|
43
47
|
const { getVersionInfo, formatVersionMessage } = await import('./version-info.lib.mjs');
|
|
44
48
|
const { escapeMarkdown, escapeMarkdownV2, cleanNonPrintableChars, makeSpecialCharsVisible } = await import('./telegram-markdown.lib.mjs');
|
|
45
49
|
const { getSolveQueue, createQueueExecuteCallback } = await import('./telegram-solve-queue.lib.mjs');
|
|
46
|
-
// Import extracted message filter functions for testability (issue #1207)
|
|
47
50
|
const { isOldMessage: _isOldMessage, isGroupChat: _isGroupChat, isChatAuthorized: _isChatAuthorized, isForwardedOrReply: _isForwardedOrReply, extractCommandFromText } = await import('./telegram-message-filters.lib.mjs');
|
|
48
51
|
// Import bot launcher with exponential backoff retry (issue #1240)
|
|
49
52
|
const { launchBotWithRetry } = await import('./telegram-bot-launcher.lib.mjs');
|
package/src/version.lib.mjs
CHANGED
|
@@ -5,6 +5,11 @@ import { dirname, join } from 'path';
|
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { getGitVersion } from './git.lib.mjs';
|
|
7
7
|
|
|
8
|
+
// Cache for version (immutable after first read)
|
|
9
|
+
// This ensures the version remains consistent even if package.json changes during runtime
|
|
10
|
+
// See issue #1318: version should be cached in RAM at startup
|
|
11
|
+
let cachedVersion = null;
|
|
12
|
+
|
|
8
13
|
async function isRunningAsScript() {
|
|
9
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
15
|
const __dirname = dirname(__filename);
|
|
@@ -18,6 +23,11 @@ async function isRunningAsScript() {
|
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
export async function getVersion() {
|
|
26
|
+
// Return cached version if already computed (immutable after first read)
|
|
27
|
+
if (cachedVersion !== null) {
|
|
28
|
+
return cachedVersion;
|
|
29
|
+
}
|
|
30
|
+
|
|
21
31
|
const __filename = fileURLToPath(import.meta.url);
|
|
22
32
|
const __dirname = dirname(__filename);
|
|
23
33
|
const packagePath = join(__dirname, '..', 'package.json');
|
|
@@ -28,13 +38,15 @@ export async function getVersion() {
|
|
|
28
38
|
const currentVersion = packageJson.version;
|
|
29
39
|
|
|
30
40
|
if (await isRunningAsScript()) {
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
cachedVersion = await getGitVersion(undefined, currentVersion);
|
|
42
|
+
} else {
|
|
43
|
+
cachedVersion = currentVersion;
|
|
33
44
|
}
|
|
34
45
|
|
|
35
|
-
return
|
|
46
|
+
return cachedVersion;
|
|
36
47
|
} catch {
|
|
37
|
-
|
|
48
|
+
cachedVersion = 'unknown';
|
|
49
|
+
return cachedVersion;
|
|
38
50
|
}
|
|
39
51
|
}
|
|
40
52
|
|