@elvatis_com/openclaw-cli-bridge-elvatis 3.4.1 → 3.5.0
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/README.md +1 -1
- package/SKILL.md +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/cli-runner.ts +7 -2
- package/test/cli-runner.test.ts +6 -4
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> OpenClaw plugin that bridges locally installed AI CLIs (Codex, Gemini, Claude Code, OpenCode, Pi) as model providers — with slash commands for instant model switching, restore, health testing, and model listing.
|
|
4
4
|
|
|
5
|
-
**Current version:** `3.
|
|
5
|
+
**Current version:** `3.5.0`
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
package/SKILL.md
CHANGED
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "openclaw-cli-bridge-elvatis",
|
|
3
3
|
"slug": "openclaw-cli-bridge-elvatis",
|
|
4
4
|
"name": "OpenClaw CLI Bridge",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.5.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"description": "Phase 1: openai-codex auth bridge. Phase 2: local HTTP proxy routing model calls through gemini/claude CLIs (vllm provider).",
|
|
8
8
|
"providers": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elvatis_com/openclaw-cli-bridge-elvatis",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "Bridges gemini, claude, and codex CLI tools as OpenClaw model providers. Reads existing CLI auth without re-login.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"openclaw": {
|
package/src/cli-runner.ts
CHANGED
|
@@ -80,11 +80,16 @@ export function formatPrompt(messages: ChatMessage[], toolCount = 0): string {
|
|
|
80
80
|
// Reduce history when tool schemas dominate the prompt
|
|
81
81
|
const maxMsgs = toolCount > TOOL_HEAVY_THRESHOLD ? MAX_MESSAGES_HEAVY_TOOLS : MAX_MESSAGES;
|
|
82
82
|
|
|
83
|
-
// Keep system message (if any) + last N non-system messages
|
|
83
|
+
// Keep system message (if any) + first user message (original request) + last N non-system messages
|
|
84
84
|
const system = messages.find((m) => m.role === "system");
|
|
85
85
|
const nonSystem = messages.filter((m) => m.role !== "system");
|
|
86
|
+
const firstUser = nonSystem.find((m) => m.role === "user");
|
|
86
87
|
const recent = nonSystem.slice(-maxMsgs);
|
|
87
|
-
|
|
88
|
+
// Pin the first user message so the model never loses the original request
|
|
89
|
+
const pinned = firstUser && !recent.includes(firstUser)
|
|
90
|
+
? [firstUser, ...recent]
|
|
91
|
+
: recent;
|
|
92
|
+
const truncated = system ? [system, ...pinned] : pinned;
|
|
88
93
|
|
|
89
94
|
// Single short user message — send bare (no wrapping needed)
|
|
90
95
|
if (truncated.length === 1 && truncated[0].role === "user") {
|
package/test/cli-runner.test.ts
CHANGED
|
@@ -19,18 +19,19 @@ describe("formatPrompt", () => {
|
|
|
19
19
|
expect(result).toBe("hello");
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
it("truncates to MAX_MESSAGES (20) non-system messages", () => {
|
|
22
|
+
it("truncates to MAX_MESSAGES (20) non-system messages but pins first user message", () => {
|
|
23
23
|
const messages = Array.from({ length: 30 }, (_, i) => ({
|
|
24
24
|
role: "user" as const,
|
|
25
25
|
content: `msg ${i}`,
|
|
26
26
|
}));
|
|
27
27
|
const result = formatPrompt(messages);
|
|
28
28
|
expect(result).toContain("msg 29");
|
|
29
|
-
expect(result).
|
|
29
|
+
expect(result).toContain("msg 0"); // first user message is always pinned
|
|
30
|
+
expect(result).not.toContain("msg 1\n"); // but intermediate messages are truncated
|
|
30
31
|
expect(result).toContain("[User]");
|
|
31
32
|
});
|
|
32
33
|
|
|
33
|
-
it("keeps system message + last 20 non-system messages", () => {
|
|
34
|
+
it("keeps system message + first user message + last 20 non-system messages", () => {
|
|
34
35
|
const sys = { role: "system" as const, content: "You are helpful" };
|
|
35
36
|
const msgs = Array.from({ length: 25 }, (_, i) => ({
|
|
36
37
|
role: "user" as const,
|
|
@@ -40,7 +41,8 @@ describe("formatPrompt", () => {
|
|
|
40
41
|
expect(result).toContain("[System]");
|
|
41
42
|
expect(result).toContain("You are helpful");
|
|
42
43
|
expect(result).toContain("msg 24");
|
|
43
|
-
expect(result).
|
|
44
|
+
expect(result).toContain("msg 0"); // first user message is always pinned
|
|
45
|
+
expect(result).not.toContain("msg 1\n"); // but intermediate messages are truncated
|
|
44
46
|
});
|
|
45
47
|
|
|
46
48
|
it("truncates individual message content at MAX_MSG_CHARS (4000)", () => {
|