alvin-bot 5.1.1 → 5.1.3
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
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Alvin Bot are documented here.
|
|
4
4
|
|
|
5
|
+
## [5.1.3] — 2026-05-13
|
|
6
|
+
|
|
7
|
+
### Stability hardening — runtime-header fallbacks
|
|
8
|
+
|
|
9
|
+
Small robustness pass on the runtime-header block that the bot uses to introduce itself. If the embedded version or install-path can't be resolved for any reason, those lines are now simply omitted instead of literally telling the model "I am version unknown". Node version and platform are still emitted so the bot can still describe its environment.
|
|
10
|
+
|
|
11
|
+
### Cleaner release notes for global users
|
|
12
|
+
|
|
13
|
+
Polished the release notes that surface inside the Telegram `/update` summary so non-technical users see a clear, English summary of what changed. No behaviour changes.
|
|
14
|
+
|
|
15
|
+
## [5.1.2] — 2026-05-13
|
|
16
|
+
|
|
17
|
+
### Bot now reports its real version after every update
|
|
18
|
+
|
|
19
|
+
If you asked the bot "what version are you?", it used to look up the version that someone had written into the project documentation by hand — which went out of date the moment a new release shipped. The bot would happily say "I'm v4.19.2" even though the running process was already on something newer.
|
|
20
|
+
|
|
21
|
+
Now the bot reads its version straight from the running code on disk, every single turn, regardless of provider (Claude SDK, Codex CLI, Groq, Gemini, OpenAI, Ollama, OpenRouter, NVIDIA NIM). It also includes its install path, Node version, and platform — so when something goes wrong you can ask the bot to introduce itself and get an honest answer.
|
|
22
|
+
|
|
23
|
+
### What does this mean for you
|
|
24
|
+
|
|
25
|
+
- Update via Telegram `/update` and the bot will pick up the new version on the next restart.
|
|
26
|
+
- Ask the bot in chat "which version are you running?" — the answer is now grounded in reality, not in a docs file that might be stale.
|
|
27
|
+
|
|
5
28
|
## [5.1.1] — 2026-05-13
|
|
6
29
|
|
|
7
30
|
### Audit baseline cleanup — 16 → 6 vulnerabilities via safe fixes
|
|
@@ -14,6 +14,7 @@ import { execFile } from "child_process";
|
|
|
14
14
|
import { promisify } from "util";
|
|
15
15
|
import { findClaudeBinary } from "../find-claude-binary.js";
|
|
16
16
|
import { buildAlvinMcpServer } from "../services/alvin-mcp-tools.js";
|
|
17
|
+
import { buildRuntimeHeader } from "./runtime-header.js";
|
|
17
18
|
const execFileAsync = promisify(execFile);
|
|
18
19
|
/**
|
|
19
20
|
* Detects the Claude CLI "Not logged in" error message. The CLI emits this
|
|
@@ -116,10 +117,13 @@ export class ClaudeSDKProvider {
|
|
|
116
117
|
prompt = `[CHECKPOINT] Du hast bereits ${sessionState.toolUseCount} Tool-Aufrufe und ${sessionState.messageCount} Nachrichten in dieser Session. Schreibe jetzt einen Checkpoint in deine Memory-Datei (docs/memory/YYYY-MM-DD.md) bevor du diese Anfrage bearbeitest.\n\n${prompt}`;
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
|
-
// Build system prompt
|
|
120
|
+
// Build system prompt. The runtime-header is injected ABOVE the CLAUDE.md
|
|
121
|
+
// contents so its values (BOT_VERSION, install path, runtime) outrank any
|
|
122
|
+
// stale "Version: x.y.z" line that may still live in CLAUDE.md.
|
|
123
|
+
const runtimeHeader = buildRuntimeHeader();
|
|
120
124
|
const systemPrompt = options.systemPrompt
|
|
121
|
-
? `${options.systemPrompt}\n\n${botClaudeMd}`
|
|
122
|
-
: botClaudeMd
|
|
125
|
+
? `${runtimeHeader}\n\n${options.systemPrompt}\n\n${botClaudeMd}`
|
|
126
|
+
: `${runtimeHeader}\n\n${botClaudeMd}`;
|
|
123
127
|
// Build a real AbortController the SDK can call .abort() on.
|
|
124
128
|
// The previous implementation cast a plain {signal} object to AbortController,
|
|
125
129
|
// which broke SDK-internal cancellation and left orphan subprocesses.
|
|
@@ -31,10 +31,17 @@ export class CodexCLIProvider {
|
|
|
31
31
|
if (options.workingDir) {
|
|
32
32
|
args.push("-C", options.workingDir);
|
|
33
33
|
}
|
|
34
|
-
// Build the prompt with system context
|
|
34
|
+
// Build the prompt with system context. The runtime-header is injected
|
|
35
|
+
// first so its version/install-path overrides any stale value that may
|
|
36
|
+
// appear later in the system prompt or CLAUDE.md.
|
|
37
|
+
const { buildRuntimeHeader } = await import("./runtime-header.js");
|
|
38
|
+
const runtimeHeader = buildRuntimeHeader();
|
|
35
39
|
let fullPrompt = options.prompt;
|
|
36
40
|
if (options.systemPrompt) {
|
|
37
|
-
fullPrompt = `${options.systemPrompt}\n\n${fullPrompt}`;
|
|
41
|
+
fullPrompt = `${runtimeHeader}\n\n${options.systemPrompt}\n\n${fullPrompt}`;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
fullPrompt = `${runtimeHeader}\n\n${fullPrompt}`;
|
|
38
45
|
}
|
|
39
46
|
args.push(fullPrompt);
|
|
40
47
|
try {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { AGENT_TOOLS, executeTool } from "./tool-executor.js";
|
|
11
11
|
import { updateRateLimits } from "../services/usage-tracker.js";
|
|
12
|
+
import * as runtimeHeader from "./runtime-header.js";
|
|
12
13
|
// Max tool call rounds to prevent infinite loops
|
|
13
14
|
const MAX_TOOL_ROUNDS = 10;
|
|
14
15
|
// Providers known to support function calling
|
|
@@ -355,8 +356,16 @@ export class OpenAICompatibleProvider {
|
|
|
355
356
|
}
|
|
356
357
|
buildMessages(options) {
|
|
357
358
|
const messages = [];
|
|
359
|
+
// Runtime-header (version, install path) prepended to the system prompt so
|
|
360
|
+
// its values outrank anything stale that may live later in CLAUDE.md.
|
|
361
|
+
// Synchronous-friendly: re-imported via a top-level import below.
|
|
362
|
+
const { buildRuntimeHeader } = runtimeHeader;
|
|
363
|
+
const header = buildRuntimeHeader();
|
|
358
364
|
if (options.systemPrompt) {
|
|
359
|
-
messages.push({ role: "system", content: options.systemPrompt });
|
|
365
|
+
messages.push({ role: "system", content: `${header}\n\n${options.systemPrompt}` });
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
messages.push({ role: "system", content: header });
|
|
360
369
|
}
|
|
361
370
|
if (options.history && options.history.length > 0) {
|
|
362
371
|
for (const msg of options.history) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-Header — a tiny block prepended to every provider's system prompt.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists: previously the bot answered "what version are you?" by
|
|
5
|
+
* reading whatever happened to be in the project's CLAUDE.md — which goes
|
|
6
|
+
* stale the moment a release ships. Now the truth lives next to the running
|
|
7
|
+
* code (`src/version.ts` → `BOT_VERSION`) and is injected into the system
|
|
8
|
+
* prompt every turn. The CLAUDE.md value is overridden by what's already
|
|
9
|
+
* earlier in the prompt.
|
|
10
|
+
*
|
|
11
|
+
* Keep this header small — it's burned into every conversation turn for
|
|
12
|
+
* every provider.
|
|
13
|
+
*/
|
|
14
|
+
import { BOT_VERSION } from "../version.js";
|
|
15
|
+
import { fileURLToPath } from "url";
|
|
16
|
+
import { dirname, resolve } from "path";
|
|
17
|
+
function getInstallPath() {
|
|
18
|
+
try {
|
|
19
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return "(unknown)";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function buildRuntimeHeader() {
|
|
26
|
+
const installPath = getInstallPath();
|
|
27
|
+
const lines = ["<bot_runtime>"];
|
|
28
|
+
// Only emit `version:` when we actually know it. Emitting "unknown" is worse
|
|
29
|
+
// than emitting nothing — the model will dutifully report "I am version
|
|
30
|
+
// unknown" instead of falling back to a reasonable hedge.
|
|
31
|
+
if (BOT_VERSION && BOT_VERSION !== "unknown") {
|
|
32
|
+
lines.push(`version: ${BOT_VERSION}`);
|
|
33
|
+
}
|
|
34
|
+
if (installPath && installPath !== "(unknown)") {
|
|
35
|
+
lines.push(`install_path: ${installPath}`);
|
|
36
|
+
}
|
|
37
|
+
if (process.version) {
|
|
38
|
+
lines.push(`node: ${process.version}`);
|
|
39
|
+
}
|
|
40
|
+
if (process.platform) {
|
|
41
|
+
lines.push(`platform: ${process.platform}`);
|
|
42
|
+
}
|
|
43
|
+
lines.push("</bot_runtime>", "", "When asked about your version, identity, or install path, use the values", "in <bot_runtime> above. Ignore any version number that appears in the", "project documentation (CLAUDE.md, README) — that file may be stale.");
|
|
44
|
+
return lines.join("\n");
|
|
45
|
+
}
|