@elvatis_com/openclaw-cli-bridge-elvatis 0.2.1 → 0.2.2

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/index.ts CHANGED
@@ -8,6 +8,14 @@
8
8
  * and configures OpenClaw's vllm provider to route through it. Model calls
9
9
  * are handled by the Gemini CLI and Claude Code CLI subprocesses.
10
10
  *
11
+ * Phase 3 (slash commands): registers /cli-* commands for instant model switching.
12
+ * /cli-sonnet → vllm/cli-claude/claude-sonnet-4-6
13
+ * /cli-opus → vllm/cli-claude/claude-opus-4-6
14
+ * /cli-haiku → vllm/cli-claude/claude-haiku-4-5
15
+ * /cli-gemini → vllm/cli-gemini/gemini-2.5-pro
16
+ * /cli-gemini-flash → vllm/cli-gemini/gemini-2.5-flash
17
+ * /cli-gemini3 → vllm/cli-gemini/gemini-3-pro
18
+ *
11
19
  * Provider / model naming:
12
20
  * vllm/cli-gemini/gemini-2.5-pro → `gemini -m gemini-2.5-pro -p "<prompt>"`
13
21
  * vllm/cli-claude/claude-opus-4-6 → `claude -p -m claude-opus-4-6 --output-format text "<prompt>"`
@@ -18,6 +26,12 @@ import type {
18
26
  ProviderAuthContext,
19
27
  ProviderAuthResult,
20
28
  } from "openclaw/plugin-sdk";
29
+
30
+ // Types derived from the plugin SDK (PluginCommandContext / PluginCommandResult are
31
+ // not re-exported from the package, so we infer them from the registerCommand signature).
32
+ type RegisterCommandParam = Parameters<OpenClawPluginApi["registerCommand"]>[0];
33
+ type PluginCommandContext = Parameters<RegisterCommandParam["handler"]>[0];
34
+ type PluginCommandResult = Awaited<ReturnType<RegisterCommandParam["handler"]>>;
21
35
  import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk";
22
36
  import {
23
37
  DEFAULT_CODEX_AUTH_PATH,
@@ -44,16 +58,94 @@ interface CliPluginConfig {
44
58
  const DEFAULT_PROXY_PORT = 31337;
45
59
  const DEFAULT_PROXY_API_KEY = "cli-bridge";
46
60
 
61
+ // ──────────────────────────────────────────────────────────────────────────────
62
+ // Phase 3: slash-command model table
63
+ // ──────────────────────────────────────────────────────────────────────────────
64
+
65
+ /** CLI bridge models available via /cli-* slash commands. */
66
+ const CLI_MODEL_COMMANDS = [
67
+ {
68
+ name: "cli-sonnet",
69
+ model: "vllm/cli-claude/claude-sonnet-4-6",
70
+ description: "Switch to Claude Sonnet 4.6 (CLI bridge)",
71
+ label: "Claude Sonnet 4.6 (CLI)",
72
+ },
73
+ {
74
+ name: "cli-opus",
75
+ model: "vllm/cli-claude/claude-opus-4-6",
76
+ description: "Switch to Claude Opus 4.6 (CLI bridge)",
77
+ label: "Claude Opus 4.6 (CLI)",
78
+ },
79
+ {
80
+ name: "cli-haiku",
81
+ model: "vllm/cli-claude/claude-haiku-4-5",
82
+ description: "Switch to Claude Haiku 4.5 (CLI bridge)",
83
+ label: "Claude Haiku 4.5 (CLI)",
84
+ },
85
+ {
86
+ name: "cli-gemini",
87
+ model: "vllm/cli-gemini/gemini-2.5-pro",
88
+ description: "Switch to Gemini 2.5 Pro (CLI bridge)",
89
+ label: "Gemini 2.5 Pro (CLI)",
90
+ },
91
+ {
92
+ name: "cli-gemini-flash",
93
+ model: "vllm/cli-gemini/gemini-2.5-flash",
94
+ description: "Switch to Gemini 2.5 Flash (CLI bridge)",
95
+ label: "Gemini 2.5 Flash (CLI)",
96
+ },
97
+ {
98
+ name: "cli-gemini3",
99
+ model: "vllm/cli-gemini/gemini-3-pro",
100
+ description: "Switch to Gemini 3 Pro (CLI bridge)",
101
+ label: "Gemini 3 Pro (CLI)",
102
+ },
103
+ ] as const;
104
+
105
+ // ──────────────────────────────────────────────────────────────────────────────
106
+ // Helper: run `openclaw models set <model>` and return result text
107
+ // ──────────────────────────────────────────────────────────────────────────────
108
+
109
+ async function switchModel(
110
+ api: OpenClawPluginApi,
111
+ model: string,
112
+ label: string,
113
+ _ctx: PluginCommandContext
114
+ ): Promise<PluginCommandResult> {
115
+ try {
116
+ const result = await api.runtime.system.runCommandWithTimeout(
117
+ ["openclaw", "models", "set", model],
118
+ { timeoutMs: 8_000 }
119
+ );
120
+
121
+ if (result.code !== 0) {
122
+ const err = (result.stderr || result.stdout || "unknown error").trim();
123
+ api.logger.warn(`[cli-bridge] models set failed (code ${result.code}): ${err}`);
124
+ return { text: `❌ Failed to switch to ${label}: ${err}` };
125
+ }
126
+
127
+ api.logger.info(`[cli-bridge] switched model → ${model}`);
128
+ return {
129
+ text: `✅ Switched to ${label}\n\`${model}\``,
130
+ };
131
+ } catch (err) {
132
+ const msg = (err as Error).message;
133
+ api.logger.warn(`[cli-bridge] models set error: ${msg}`);
134
+ return { text: `❌ Error switching model: ${msg}` };
135
+ }
136
+ }
137
+
47
138
  // ──────────────────────────────────────────────────────────────────────────────
48
139
  // Plugin definition
49
140
  // ──────────────────────────────────────────────────────────────────────────────
50
141
  const plugin = {
51
142
  id: "openclaw-cli-bridge-elvatis",
52
143
  name: "OpenClaw CLI Bridge",
53
- version: "0.2.0",
144
+ version: "0.2.1",
54
145
  description:
55
146
  "Phase 1: openai-codex auth bridge (reads ~/.codex/auth.json). " +
56
- "Phase 2: HTTP proxy server routing model calls through gemini/claude CLIs.",
147
+ "Phase 2: HTTP proxy server routing model calls through gemini/claude CLIs. " +
148
+ "Phase 3: /cli-* slash commands for instant model switching.",
57
149
 
58
150
  register(api: OpenClawPluginApi) {
59
151
  const cfg = (api.pluginConfig ?? {}) as CliPluginConfig;
@@ -154,6 +246,27 @@ const plugin = {
154
246
  );
155
247
  });
156
248
  }
249
+
250
+ // ── Phase 3: /cli-* slash commands ────────────────────────────────────────
251
+ for (const entry of CLI_MODEL_COMMANDS) {
252
+ // Capture entry in closure (const iteration variable is stable in TS/ESM)
253
+ const { name, model, description, label } = entry;
254
+
255
+ api.registerCommand({
256
+ name,
257
+ description,
258
+ requireAuth: true, // only authorized senders
259
+ handler: async (ctx: PluginCommandContext): Promise<PluginCommandResult> => {
260
+ api.logger.info(`[cli-bridge] /${name} triggered by ${ctx.senderId ?? "unknown"} (authorized=${ctx.isAuthorizedSender})`);
261
+ return switchModel(api, model, label, ctx);
262
+ },
263
+ });
264
+ }
265
+
266
+ api.logger.info(
267
+ `[cli-bridge] registered ${CLI_MODEL_COMMANDS.length} slash commands: ` +
268
+ CLI_MODEL_COMMANDS.map((c) => `/${c.name}`).join(", ")
269
+ );
157
270
  },
158
271
  };
159
272
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "openclaw-cli-bridge-elvatis",
3
3
  "name": "OpenClaw CLI Bridge",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "description": "Phase 1: openai-codex auth bridge. Phase 2: local HTTP proxy routing model calls through gemini/claude CLIs (vllm provider).",
6
6
  "providers": [
7
7
  "openai-codex"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elvatis_com/openclaw-cli-bridge-elvatis",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
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
  "scripts": {