From e694d435fdf7e249ffea5428b484402c7ba70ad2 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Thu, 20 Nov 2025 18:56:27 +0100 Subject: [PATCH] Release v0.7.27 - Fix slash command submission requiring two Enter presses (#30) - Fix slash command autocomplete not re-triggering after typos (#29) --- package-lock.json | 14 +- packages/agent/package.json | 6 +- packages/ai/package.json | 2 +- packages/ai/src/models.generated.ts | 240 +++++++++++++------------- packages/coding-agent/CHANGELOG.md | 7 + packages/coding-agent/package.json | 6 +- packages/pods/package.json | 4 +- packages/proxy/package.json | 2 +- packages/tui/package.json | 2 +- packages/tui/src/components/editor.ts | 48 +++++- packages/tui/src/tui.ts | 3 - packages/web-ui/package.json | 6 +- 12 files changed, 189 insertions(+), 151 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7f3c9e1c..fd91261a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5413,7 +5413,7 @@ }, "packages/agent": { "name": "@mariozechner/pi-agent", - "version": "0.7.26", + "version": "0.7.27", "license": "MIT", "dependencies": { "@mariozechner/pi-ai": "^0.7.26", @@ -5443,7 +5443,7 @@ }, "packages/ai": { "name": "@mariozechner/pi-ai", - "version": "0.7.26", + "version": "0.7.27", "license": "MIT", "dependencies": { "@anthropic-ai/sdk": "^0.61.0", @@ -5490,7 +5490,7 @@ }, "packages/coding-agent": { "name": "@mariozechner/pi-coding-agent", - "version": "0.7.26", + "version": "0.7.27", "license": "MIT", "dependencies": { "@mariozechner/pi-agent": "^0.7.26", @@ -5537,7 +5537,7 @@ }, "packages/pods": { "name": "@mariozechner/pi", - "version": "0.7.26", + "version": "0.7.27", "license": "MIT", "dependencies": { "@mariozechner/pi-agent": "^0.7.26", @@ -5563,7 +5563,7 @@ }, "packages/proxy": { "name": "@mariozechner/pi-proxy", - "version": "0.7.26", + "version": "0.7.27", "dependencies": { "@hono/node-server": "^1.14.0", "hono": "^4.6.16" @@ -5579,7 +5579,7 @@ }, "packages/tui": { "name": "@mariozechner/pi-tui", - "version": "0.7.26", + "version": "0.7.27", "license": "MIT", "dependencies": { "@types/mime-types": "^2.1.4", @@ -5661,7 +5661,7 @@ }, "packages/web-ui": { "name": "@mariozechner/pi-web-ui", - "version": "0.7.26", + "version": "0.7.27", "license": "MIT", "dependencies": { "@lmstudio/sdk": "^1.5.0", diff --git a/packages/agent/package.json b/packages/agent/package.json index 986d4a6c..6a0107fb 100644 --- a/packages/agent/package.json +++ b/packages/agent/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi-agent", - "version": "0.7.26", + "version": "0.7.27", "description": "General-purpose agent with transport abstraction, state management, and attachment support", "type": "module", "main": "./dist/index.js", @@ -18,8 +18,8 @@ "prepublishOnly": "npm run clean && npm run build" }, "dependencies": { - "@mariozechner/pi-ai": "^0.7.26", - "@mariozechner/pi-tui": "^0.7.26" + "@mariozechner/pi-ai": "^0.7.27", + "@mariozechner/pi-tui": "^0.7.27" }, "keywords": [ "ai", diff --git a/packages/ai/package.json b/packages/ai/package.json index 43d5e2fd..abe95b76 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi-ai", - "version": "0.7.26", + "version": "0.7.27", "description": "Unified LLM API with automatic model discovery and provider configuration", "type": "module", "main": "./dist/index.js", diff --git a/packages/ai/src/models.generated.ts b/packages/ai/src/models.generated.ts index c795a872..b0ba6c1b 100644 --- a/packages/ai/src/models.generated.ts +++ b/packages/ai/src/models.generated.ts @@ -1630,23 +1630,6 @@ export const MODELS = { contextWindow: 8192, maxTokens: 4096, } satisfies Model<"openai-completions">, - "grok-4.1-fast-non-reasoning": { - id: "grok-4.1-fast-non-reasoning", - name: "Grok 4.1 Fast (Non-Reasoning)", - api: "openai-completions", - provider: "xai", - baseUrl: "https://api.x.ai/v1", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.2, - output: 0.5, - cacheRead: 0.05, - cacheWrite: 0, - }, - contextWindow: 2000000, - maxTokens: 30000, - } satisfies Model<"openai-completions">, "grok-3": { id: "grok-3", name: "Grok 3", @@ -1698,6 +1681,23 @@ export const MODELS = { contextWindow: 131072, maxTokens: 8192, } satisfies Model<"openai-completions">, + "grok-4-1-fast": { + id: "grok-4-1-fast", + name: "Grok 4.1 Fast", + api: "openai-completions", + provider: "xai", + baseUrl: "https://api.x.ai/v1", + reasoning: true, + input: ["text", "image"], + cost: { + input: 0.2, + output: 0.5, + cacheRead: 0.05, + cacheWrite: 0, + }, + contextWindow: 2000000, + maxTokens: 30000, + } satisfies Model<"openai-completions">, "grok-2-1212": { id: "grok-2-1212", name: "Grok 2 (1212)", @@ -1817,23 +1817,6 @@ export const MODELS = { contextWindow: 131072, maxTokens: 4096, } satisfies Model<"openai-completions">, - "grok-4.1-fast": { - id: "grok-4.1-fast", - name: "Grok 4.1 Fast", - api: "openai-completions", - provider: "xai", - baseUrl: "https://api.x.ai/v1", - reasoning: true, - input: ["text", "image"], - cost: { - input: 0.2, - output: 0.5, - cacheRead: 0.05, - cacheWrite: 0, - }, - contextWindow: 2000000, - maxTokens: 30000, - } satisfies Model<"openai-completions">, "grok-3-mini-latest": { id: "grok-3-mini-latest", name: "Grok 3 Mini Latest", @@ -1851,6 +1834,23 @@ export const MODELS = { contextWindow: 131072, maxTokens: 8192, } satisfies Model<"openai-completions">, + "grok-4-1-fast-non-reasoning": { + id: "grok-4-1-fast-non-reasoning", + name: "Grok 4.1 Fast (Non-Reasoning)", + api: "openai-completions", + provider: "xai", + baseUrl: "https://api.x.ai/v1", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.2, + output: 0.5, + cacheRead: 0.05, + cacheWrite: 0, + }, + contextWindow: 2000000, + maxTokens: 30000, + } satisfies Model<"openai-completions">, "grok-3-mini-fast": { id: "grok-3-mini-fast", name: "Grok 3 Mini Fast", @@ -4830,23 +4830,6 @@ export const MODELS = { contextWindow: 200000, maxTokens: 8192, } satisfies Model<"openai-completions">, - "mistralai/ministral-3b": { - id: "mistralai/ministral-3b", - name: "Mistral: Ministral 3B", - api: "openai-completions", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - reasoning: false, - input: ["text"], - cost: { - input: 0.04, - output: 0.04, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 131072, - maxTokens: 4096, - } satisfies Model<"openai-completions">, "mistralai/ministral-8b": { id: "mistralai/ministral-8b", name: "Mistral: Ministral 8B", @@ -4864,6 +4847,23 @@ export const MODELS = { contextWindow: 131072, maxTokens: 4096, } satisfies Model<"openai-completions">, + "mistralai/ministral-3b": { + id: "mistralai/ministral-3b", + name: "Mistral: Ministral 3B", + api: "openai-completions", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + reasoning: false, + input: ["text"], + cost: { + input: 0.04, + output: 0.04, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 131072, + maxTokens: 4096, + } satisfies Model<"openai-completions">, "qwen/qwen-2.5-7b-instruct": { id: "qwen/qwen-2.5-7b-instruct", name: "Qwen: Qwen2.5 7B Instruct", @@ -5068,22 +5068,22 @@ export const MODELS = { contextWindow: 128000, maxTokens: 16384, } satisfies Model<"openai-completions">, - "meta-llama/llama-3.1-70b-instruct": { - id: "meta-llama/llama-3.1-70b-instruct", - name: "Meta: Llama 3.1 70B Instruct", + "meta-llama/llama-3.1-8b-instruct": { + id: "meta-llama/llama-3.1-8b-instruct", + name: "Meta: Llama 3.1 8B Instruct", api: "openai-completions", provider: "openrouter", baseUrl: "https://openrouter.ai/api/v1", reasoning: false, input: ["text"], cost: { - input: 0.39999999999999997, - output: 0.39999999999999997, + input: 0.02, + output: 0.03, cacheRead: 0, cacheWrite: 0, }, contextWindow: 131072, - maxTokens: 4096, + maxTokens: 16384, } satisfies Model<"openai-completions">, "meta-llama/llama-3.1-405b-instruct": { id: "meta-llama/llama-3.1-405b-instruct", @@ -5102,22 +5102,22 @@ export const MODELS = { contextWindow: 130815, maxTokens: 4096, } satisfies Model<"openai-completions">, - "meta-llama/llama-3.1-8b-instruct": { - id: "meta-llama/llama-3.1-8b-instruct", - name: "Meta: Llama 3.1 8B Instruct", + "meta-llama/llama-3.1-70b-instruct": { + id: "meta-llama/llama-3.1-70b-instruct", + name: "Meta: Llama 3.1 70B Instruct", api: "openai-completions", provider: "openrouter", baseUrl: "https://openrouter.ai/api/v1", reasoning: false, input: ["text"], cost: { - input: 0.02, - output: 0.03, + input: 0.39999999999999997, + output: 0.39999999999999997, cacheRead: 0, cacheWrite: 0, }, contextWindow: 131072, - maxTokens: 16384, + maxTokens: 4096, } satisfies Model<"openai-completions">, "mistralai/mistral-nemo": { id: "mistralai/mistral-nemo", @@ -5136,9 +5136,9 @@ export const MODELS = { contextWindow: 131072, maxTokens: 16384, } satisfies Model<"openai-completions">, - "openai/gpt-4o-mini": { - id: "openai/gpt-4o-mini", - name: "OpenAI: GPT-4o-mini", + "openai/gpt-4o-mini-2024-07-18": { + id: "openai/gpt-4o-mini-2024-07-18", + name: "OpenAI: GPT-4o-mini (2024-07-18)", api: "openai-completions", provider: "openrouter", baseUrl: "https://openrouter.ai/api/v1", @@ -5153,9 +5153,9 @@ export const MODELS = { contextWindow: 128000, maxTokens: 16384, } satisfies Model<"openai-completions">, - "openai/gpt-4o-mini-2024-07-18": { - id: "openai/gpt-4o-mini-2024-07-18", - name: "OpenAI: GPT-4o-mini (2024-07-18)", + "openai/gpt-4o-mini": { + id: "openai/gpt-4o-mini", + name: "OpenAI: GPT-4o-mini", api: "openai-completions", provider: "openrouter", baseUrl: "https://openrouter.ai/api/v1", @@ -5255,6 +5255,23 @@ export const MODELS = { contextWindow: 128000, maxTokens: 4096, } satisfies Model<"openai-completions">, + "openai/gpt-4o-2024-05-13": { + id: "openai/gpt-4o-2024-05-13", + name: "OpenAI: GPT-4o (2024-05-13)", + api: "openai-completions", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + reasoning: false, + input: ["text", "image"], + cost: { + input: 5, + output: 15, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 128000, + maxTokens: 4096, + } satisfies Model<"openai-completions">, "openai/gpt-4o": { id: "openai/gpt-4o", name: "OpenAI: GPT-4o", @@ -5289,23 +5306,6 @@ export const MODELS = { contextWindow: 128000, maxTokens: 64000, } satisfies Model<"openai-completions">, - "openai/gpt-4o-2024-05-13": { - id: "openai/gpt-4o-2024-05-13", - name: "OpenAI: GPT-4o (2024-05-13)", - api: "openai-completions", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - reasoning: false, - input: ["text", "image"], - cost: { - input: 5, - output: 15, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 4096, - } satisfies Model<"openai-completions">, "meta-llama/llama-3-70b-instruct": { id: "meta-llama/llama-3-70b-instruct", name: "Meta: Llama 3 70B Instruct", @@ -5425,23 +5425,6 @@ export const MODELS = { contextWindow: 128000, maxTokens: 4096, } satisfies Model<"openai-completions">, - "openai/gpt-4-turbo-preview": { - id: "openai/gpt-4-turbo-preview", - name: "OpenAI: GPT-4 Turbo Preview", - api: "openai-completions", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - reasoning: false, - input: ["text"], - cost: { - input: 10, - output: 30, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 4096, - } satisfies Model<"openai-completions">, "openai/gpt-3.5-turbo-0613": { id: "openai/gpt-3.5-turbo-0613", name: "OpenAI: GPT-3.5 Turbo (older v0613)", @@ -5459,6 +5442,23 @@ export const MODELS = { contextWindow: 4095, maxTokens: 4096, } satisfies Model<"openai-completions">, + "openai/gpt-4-turbo-preview": { + id: "openai/gpt-4-turbo-preview", + name: "OpenAI: GPT-4 Turbo Preview", + api: "openai-completions", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + reasoning: false, + input: ["text"], + cost: { + input: 10, + output: 30, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 128000, + maxTokens: 4096, + } satisfies Model<"openai-completions">, "mistralai/mistral-small": { id: "mistralai/mistral-small", name: "Mistral Small", @@ -5561,23 +5561,6 @@ export const MODELS = { contextWindow: 8191, maxTokens: 4096, } satisfies Model<"openai-completions">, - "openai/gpt-3.5-turbo": { - id: "openai/gpt-3.5-turbo", - name: "OpenAI: GPT-3.5 Turbo", - api: "openai-completions", - provider: "openrouter", - baseUrl: "https://openrouter.ai/api/v1", - reasoning: false, - input: ["text"], - cost: { - input: 0.5, - output: 1.5, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 16385, - maxTokens: 4096, - } satisfies Model<"openai-completions">, "openai/gpt-4": { id: "openai/gpt-4", name: "OpenAI: GPT-4", @@ -5595,6 +5578,23 @@ export const MODELS = { contextWindow: 8191, maxTokens: 4096, } satisfies Model<"openai-completions">, + "openai/gpt-3.5-turbo": { + id: "openai/gpt-3.5-turbo", + name: "OpenAI: GPT-3.5 Turbo", + api: "openai-completions", + provider: "openrouter", + baseUrl: "https://openrouter.ai/api/v1", + reasoning: false, + input: ["text"], + cost: { + input: 0.5, + output: 1.5, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 16385, + maxTokens: 4096, + } satisfies Model<"openai-completions">, "openrouter/auto": { id: "openrouter/auto", name: "OpenRouter: Auto Router", diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 88edd444..981d6bcc 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,13 @@ ## [Unreleased] +## [0.7.27] - 2025-11-20 + +### Fixed + +- **Slash Command Submission**: Fixed issue where slash commands required two Enter presses to execute. Now pressing Enter on a slash command autocomplete suggestion immediately submits the command, while Tab still applies the completion for adding arguments. ([#30](https://github.com/badlogic/pi-mono/issues/30)) +- **Slash Command Autocomplete**: Fixed issue where typing a typo then correcting it would not show autocomplete suggestions. Autocomplete now re-triggers when typing or backspacing in a slash command context. ([#29](https://github.com/badlogic/pi-mono/issues/29)) + ## [0.7.26] - 2025-11-20 ### Added diff --git a/packages/coding-agent/package.json b/packages/coding-agent/package.json index b0b7aa63..c9ab0e2b 100644 --- a/packages/coding-agent/package.json +++ b/packages/coding-agent/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi-coding-agent", - "version": "0.7.26", + "version": "0.7.27", "description": "Coding agent CLI with read, bash, edit, write tools and session management", "type": "module", "bin": { @@ -21,8 +21,8 @@ "prepublishOnly": "npm run clean && npm run build" }, "dependencies": { - "@mariozechner/pi-agent": "^0.7.26", - "@mariozechner/pi-ai": "^0.7.26", + "@mariozechner/pi-agent": "^0.7.27", + "@mariozechner/pi-ai": "^0.7.27", "chalk": "^5.5.0", "diff": "^8.0.2", "glob": "^11.0.3" diff --git a/packages/pods/package.json b/packages/pods/package.json index 116cb5fa..f46209f2 100644 --- a/packages/pods/package.json +++ b/packages/pods/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi", - "version": "0.7.26", + "version": "0.7.27", "description": "CLI tool for managing vLLM deployments on GPU pods", "type": "module", "bin": { @@ -34,7 +34,7 @@ "node": ">=20.0.0" }, "dependencies": { - "@mariozechner/pi-agent": "^0.7.26", + "@mariozechner/pi-agent": "^0.7.27", "chalk": "^5.5.0" }, "devDependencies": {} diff --git a/packages/proxy/package.json b/packages/proxy/package.json index 6caa40a5..06a1489c 100644 --- a/packages/proxy/package.json +++ b/packages/proxy/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi-proxy", - "version": "0.7.26", + "version": "0.7.27", "type": "module", "description": "CORS and authentication proxy for pi-ai", "main": "dist/index.js", diff --git a/packages/tui/package.json b/packages/tui/package.json index 15e5a544..cf8cd713 100644 --- a/packages/tui/package.json +++ b/packages/tui/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi-tui", - "version": "0.7.26", + "version": "0.7.27", "description": "Terminal User Interface library with differential rendering for efficient text-based applications", "type": "module", "main": "dist/index.js", diff --git a/packages/tui/src/components/editor.ts b/packages/tui/src/components/editor.ts index 6195e404..053704aa 100644 --- a/packages/tui/src/components/editor.ts +++ b/packages/tui/src/components/editor.ts @@ -195,8 +195,8 @@ export class Editor implements Component { this.autocompleteList.handleInput(data); } - // If Tab or Enter was pressed, apply the selection - if (data === "\t" || data === "\r") { + // If Tab was pressed, always apply the selection + if (data === "\t") { const selected = this.autocompleteList.getSelectedItem(); if (selected && this.autocompleteProvider) { const result = this.autocompleteProvider.applyCompletion( @@ -218,8 +218,35 @@ export class Editor implements Component { } } return; - } else { - // For other keys, handle normally within autocomplete + } + + // If Enter was pressed on a slash command, cancel autocomplete and let it submit + if (data === "\r" && this.autocompletePrefix.startsWith("/")) { + this.cancelAutocomplete(); + // Don't return - fall through to submission logic + } + // If Enter was pressed on a file path, apply completion + else if (data === "\r") { + const selected = this.autocompleteList.getSelectedItem(); + if (selected && this.autocompleteProvider) { + const result = this.autocompleteProvider.applyCompletion( + this.state.lines, + this.state.cursorLine, + this.state.cursorCol, + selected, + this.autocompletePrefix, + ); + + this.state.lines = result.lines; + this.state.cursorLine = result.cursorLine; + this.state.cursorCol = result.cursorCol; + + this.cancelAutocomplete(); + + if (this.onChange) { + this.onChange(this.getText()); + } + } return; } } @@ -455,8 +482,8 @@ export class Editor implements Component { else if (/[a-zA-Z0-9]/.test(char)) { const currentLine = this.state.lines[this.state.cursorLine] || ""; const textBeforeCursor = currentLine.slice(0, this.state.cursorCol); - // Check if we're in a slash command with a space (i.e., typing arguments) - if (textBeforeCursor.startsWith("/") && textBeforeCursor.includes(" ")) { + // Check if we're in a slash command (with or without space for arguments) + if (textBeforeCursor.trimStart().startsWith("/")) { this.tryTriggerAutocomplete(); } } @@ -598,9 +625,16 @@ export class Editor implements Component { this.onChange(this.getText()); } - // Update autocomplete after backspace + // Update or re-trigger autocomplete after backspace if (this.isAutocompleting) { this.updateAutocomplete(); + } else { + // If autocomplete was cancelled (no matches), re-trigger if we're in slash command context + const currentLine = this.state.lines[this.state.cursorLine] || ""; + const textBeforeCursor = currentLine.slice(0, this.state.cursorCol); + if (textBeforeCursor.trimStart().startsWith("/")) { + this.tryTriggerAutocomplete(); + } } } diff --git a/packages/tui/src/tui.ts b/packages/tui/src/tui.ts index f49c3626..43fdbca2 100644 --- a/packages/tui/src/tui.ts +++ b/packages/tui/src/tui.ts @@ -150,8 +150,6 @@ export class TUI extends Container { // Find first and last changed lines let firstChanged = -1; - let lastChanged = -1; - const maxLines = Math.max(newLines.length, this.previousLines.length); for (let i = 0; i < maxLines; i++) { const oldLine = i < this.previousLines.length ? this.previousLines[i] : ""; @@ -161,7 +159,6 @@ export class TUI extends Container { if (firstChanged === -1) { firstChanged = i; } - lastChanged = i; } } diff --git a/packages/web-ui/package.json b/packages/web-ui/package.json index 862c195a..7c6875db 100644 --- a/packages/web-ui/package.json +++ b/packages/web-ui/package.json @@ -1,6 +1,6 @@ { "name": "@mariozechner/pi-web-ui", - "version": "0.7.26", + "version": "0.7.27", "description": "Reusable web UI components for AI chat interfaces powered by @mariozechner/pi-ai", "type": "module", "main": "dist/index.js", @@ -18,8 +18,8 @@ }, "dependencies": { "@lmstudio/sdk": "^1.5.0", - "@mariozechner/pi-ai": "^0.7.26", - "@mariozechner/pi-tui": "^0.7.26", + "@mariozechner/pi-ai": "^0.7.27", + "@mariozechner/pi-tui": "^0.7.27", "docx-preview": "^0.3.7", "jszip": "^3.10.1", "lucide": "^0.544.0",