@oh-my-pi/pi-coding-agent 6.8.4 → 6.9.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/CHANGELOG.md +21 -0
- package/package.json +5 -6
- package/src/core/python-executor.ts +6 -10
- package/src/core/sdk.ts +0 -2
- package/src/core/settings-manager.ts +0 -105
- package/src/core/streaming-output.ts +10 -19
- package/src/core/tools/index.ts +0 -4
- package/src/core/tools/python.ts +3 -3
- package/src/index.ts +0 -2
- package/src/modes/interactive/components/settings-defs.ts +0 -70
- package/src/modes/interactive/components/settings-selector.ts +0 -1
- package/src/modes/interactive/controllers/event-controller.ts +0 -11
- package/src/modes/interactive/controllers/selector-controller.ts +0 -9
- package/src/modes/interactive/interactive-mode.ts +0 -58
- package/src/modes/interactive/types.ts +0 -15
- package/src/core/custom-commands/bundled/wt/index.ts +0 -435
- package/src/core/tools/git.ts +0 -213
- package/src/core/voice-controller.ts +0 -135
- package/src/core/voice-supervisor.ts +0 -976
- package/src/core/voice.ts +0 -314
- package/src/lib/worktree/collapse.ts +0 -180
- package/src/lib/worktree/constants.ts +0 -14
- package/src/lib/worktree/errors.ts +0 -23
- package/src/lib/worktree/git.ts +0 -60
- package/src/lib/worktree/index.ts +0 -15
- package/src/lib/worktree/operations.ts +0 -216
- package/src/lib/worktree/session.ts +0 -114
- package/src/lib/worktree/stats.ts +0 -67
- package/src/modes/interactive/utils/voice-manager.ts +0 -96
- package/src/prompts/tools/git.md +0 -9
- package/src/prompts/voice-summary.md +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [6.9.0] - 2026-01-21
|
|
6
|
+
### Removed
|
|
7
|
+
|
|
8
|
+
- Removed Git tool and all related functionality
|
|
9
|
+
- Removed voice control and TTS features
|
|
10
|
+
- Removed worktree management system
|
|
11
|
+
- Removed bundled wt custom command
|
|
12
|
+
- Removed voice-related settings and configuration options
|
|
13
|
+
- Removed @oh-my-pi/pi-git-tool dependency
|
|
14
|
+
|
|
15
|
+
## [6.8.5] - 2026-01-21
|
|
16
|
+
### Breaking Changes
|
|
17
|
+
|
|
18
|
+
- Changed timeout parameter from seconds to milliseconds in Python tool
|
|
19
|
+
- Updated PythonExecutorOptions interface to use timeoutMs instead of timeout
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Updated default timeout to 30000ms (30 seconds) for Python tool
|
|
24
|
+
- Improved streaming output handling and buffer management
|
|
25
|
+
|
|
5
26
|
## [6.8.4] - 2026-01-21
|
|
6
27
|
### Changed
|
|
7
28
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.9.0",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"ompConfig": {
|
|
@@ -40,11 +40,10 @@
|
|
|
40
40
|
"prepublishOnly": "bun run generate-template && bun run clean && bun run build"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@oh-my-pi/pi-agent-core": "6.
|
|
44
|
-
"@oh-my-pi/pi-ai": "6.
|
|
45
|
-
"@oh-my-pi/pi-
|
|
46
|
-
"@oh-my-pi/pi-
|
|
47
|
-
"@oh-my-pi/pi-utils": "6.8.4",
|
|
43
|
+
"@oh-my-pi/pi-agent-core": "6.9.0",
|
|
44
|
+
"@oh-my-pi/pi-ai": "6.9.0",
|
|
45
|
+
"@oh-my-pi/pi-tui": "6.9.0",
|
|
46
|
+
"@oh-my-pi/pi-utils": "6.9.0",
|
|
48
47
|
"@openai/agents": "^0.3.7",
|
|
49
48
|
"@sinclair/typebox": "^0.34.46",
|
|
50
49
|
"ajv": "^8.17.1",
|
|
@@ -14,9 +14,9 @@ export interface PythonExecutorOptions {
|
|
|
14
14
|
/** Working directory for command execution */
|
|
15
15
|
cwd?: string;
|
|
16
16
|
/** Timeout in milliseconds */
|
|
17
|
-
|
|
17
|
+
timeoutMs?: number;
|
|
18
18
|
/** Callback for streaming output chunks (already sanitized) */
|
|
19
|
-
onChunk?: (chunk: string) => void;
|
|
19
|
+
onChunk?: (chunk: string) => Promise<void> | void;
|
|
20
20
|
/** AbortSignal for cancellation */
|
|
21
21
|
signal?: AbortSignal;
|
|
22
22
|
/** Session identifier for kernel reuse */
|
|
@@ -216,17 +216,13 @@ async function executeWithKernel(
|
|
|
216
216
|
try {
|
|
217
217
|
const result = await kernel.execute(code, {
|
|
218
218
|
signal: options?.signal,
|
|
219
|
-
timeoutMs: options?.
|
|
220
|
-
onChunk: (text) =>
|
|
221
|
-
|
|
222
|
-
},
|
|
223
|
-
onDisplay: (output) => {
|
|
224
|
-
displayOutputs.push(output);
|
|
225
|
-
},
|
|
219
|
+
timeoutMs: options?.timeoutMs,
|
|
220
|
+
onChunk: (text) => sink.push(text),
|
|
221
|
+
onDisplay: (output) => void displayOutputs.push(output),
|
|
226
222
|
});
|
|
227
223
|
|
|
228
224
|
if (result.cancelled) {
|
|
229
|
-
const secs = options?.
|
|
225
|
+
const secs = options?.timeoutMs ? Math.round(options.timeoutMs / 1000) : undefined;
|
|
230
226
|
const annotation =
|
|
231
227
|
result.timedOut && secs !== undefined ? `Command timed out after ${secs} seconds` : undefined;
|
|
232
228
|
return {
|
package/src/core/sdk.ts
CHANGED
|
@@ -86,7 +86,6 @@ import {
|
|
|
86
86
|
createTools,
|
|
87
87
|
EditTool,
|
|
88
88
|
FindTool,
|
|
89
|
-
GitTool,
|
|
90
89
|
GrepTool,
|
|
91
90
|
getWebSearchTools,
|
|
92
91
|
LsTool,
|
|
@@ -218,7 +217,6 @@ export {
|
|
|
218
217
|
createTools,
|
|
219
218
|
EditTool,
|
|
220
219
|
FindTool,
|
|
221
|
-
GitTool,
|
|
222
220
|
GrepTool,
|
|
223
221
|
loadSshTool,
|
|
224
222
|
LsTool,
|
|
@@ -98,10 +98,6 @@ export interface BashInterceptorSettings {
|
|
|
98
98
|
patterns?: BashInterceptorRule[]; // default: built-in rules
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
export interface GitSettings {
|
|
102
|
-
enabled?: boolean; // default: false (structured git tool; use bash for git commands when disabled)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
101
|
export interface MCPSettings {
|
|
106
102
|
enableProjectConfig?: boolean; // default: true (load .mcp.json from project root)
|
|
107
103
|
}
|
|
@@ -145,15 +141,6 @@ export interface TodoCompletionSettings {
|
|
|
145
141
|
maxReminders?: number; // default: 3 - maximum reminders before giving up
|
|
146
142
|
}
|
|
147
143
|
|
|
148
|
-
export interface VoiceSettings {
|
|
149
|
-
enabled?: boolean; // default: false
|
|
150
|
-
transcriptionModel?: string; // default: "whisper-1"
|
|
151
|
-
transcriptionLanguage?: string; // optional language hint (e.g., "en")
|
|
152
|
-
ttsModel?: string; // default: "gpt-4o-mini-tts"
|
|
153
|
-
ttsVoice?: string; // default: "alloy"
|
|
154
|
-
ttsFormat?: "wav" | "mp3" | "opus" | "aac" | "flac"; // default: "wav"
|
|
155
|
-
}
|
|
156
|
-
|
|
157
144
|
export type StatusLineSegmentId =
|
|
158
145
|
| "pi"
|
|
159
146
|
| "model"
|
|
@@ -224,14 +211,12 @@ export interface Settings {
|
|
|
224
211
|
enabledModels?: string[]; // Model patterns for cycling (same format as --models CLI flag)
|
|
225
212
|
exa?: ExaSettings;
|
|
226
213
|
bashInterceptor?: BashInterceptorSettings;
|
|
227
|
-
git?: GitSettings;
|
|
228
214
|
mcp?: MCPSettings;
|
|
229
215
|
lsp?: LspSettings;
|
|
230
216
|
python?: PythonSettings;
|
|
231
217
|
edit?: EditSettings;
|
|
232
218
|
ttsr?: TtsrSettings;
|
|
233
219
|
todoCompletion?: TodoCompletionSettings;
|
|
234
|
-
voice?: VoiceSettings;
|
|
235
220
|
providers?: ProviderSettings;
|
|
236
221
|
disabledProviders?: string[]; // Discovery provider IDs that are disabled
|
|
237
222
|
disabledExtensions?: string[]; // Individual extension IDs that are disabled (e.g., "skill:commit")
|
|
@@ -252,12 +237,6 @@ export const DEFAULT_BASH_INTERCEPTOR_RULES: BashInterceptorRule[] = [
|
|
|
252
237
|
tool: "grep",
|
|
253
238
|
message: "Use the `grep` tool instead of grep/rg. It respects .gitignore and provides structured output.",
|
|
254
239
|
},
|
|
255
|
-
{
|
|
256
|
-
pattern: "^\\s*git(\\s+|$)",
|
|
257
|
-
tool: "git",
|
|
258
|
-
message:
|
|
259
|
-
"Use the `git` tool instead of running git in bash. It provides structured output and safety confirmations.",
|
|
260
|
-
},
|
|
261
240
|
{
|
|
262
241
|
pattern: "^\\s*(find|fd|locate)\\s+.*(-name|-iname|-type|--type|-glob)",
|
|
263
242
|
tool: "find",
|
|
@@ -319,19 +298,11 @@ const DEFAULT_SETTINGS: Settings = {
|
|
|
319
298
|
enableWebsets: false,
|
|
320
299
|
},
|
|
321
300
|
bashInterceptor: DEFAULT_BASH_INTERCEPTOR_SETTINGS,
|
|
322
|
-
git: { enabled: false },
|
|
323
301
|
mcp: { enableProjectConfig: true },
|
|
324
302
|
lsp: { formatOnWrite: false, diagnosticsOnWrite: true, diagnosticsOnEdit: false },
|
|
325
303
|
python: { toolMode: "both", kernelMode: "session", sharedGateway: true },
|
|
326
304
|
edit: { fuzzyMatch: true, fuzzyThreshold: 0.95, streamingAbort: false },
|
|
327
305
|
ttsr: { enabled: true, contextMode: "discard", repeatMode: "once", repeatGap: 10 },
|
|
328
|
-
voice: {
|
|
329
|
-
enabled: false,
|
|
330
|
-
transcriptionModel: "whisper-1",
|
|
331
|
-
ttsModel: "gpt-4o-mini-tts",
|
|
332
|
-
ttsVoice: "alloy",
|
|
333
|
-
ttsFormat: "wav",
|
|
334
|
-
},
|
|
335
306
|
providers: { webSearch: "auto", image: "auto" },
|
|
336
307
|
} satisfies Settings;
|
|
337
308
|
|
|
@@ -1170,10 +1141,6 @@ export class SettingsManager {
|
|
|
1170
1141
|
await this.save();
|
|
1171
1142
|
}
|
|
1172
1143
|
|
|
1173
|
-
getGitToolEnabled(): boolean {
|
|
1174
|
-
return this.settings.git?.enabled ?? false;
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
1144
|
getPythonToolMode(): PythonToolMode {
|
|
1178
1145
|
return this.settings.python?.toolMode ?? "both";
|
|
1179
1146
|
}
|
|
@@ -1210,14 +1177,6 @@ export class SettingsManager {
|
|
|
1210
1177
|
await this.save();
|
|
1211
1178
|
}
|
|
1212
1179
|
|
|
1213
|
-
async setGitToolEnabled(enabled: boolean): Promise<void> {
|
|
1214
|
-
if (!this.globalSettings.git) {
|
|
1215
|
-
this.globalSettings.git = {};
|
|
1216
|
-
}
|
|
1217
|
-
this.globalSettings.git.enabled = enabled;
|
|
1218
|
-
await this.save();
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
1180
|
getMCPProjectConfigEnabled(): boolean {
|
|
1222
1181
|
return this.settings.mcp?.enableProjectConfig ?? true;
|
|
1223
1182
|
}
|
|
@@ -1430,70 +1389,6 @@ export class SettingsManager {
|
|
|
1430
1389
|
await this.save();
|
|
1431
1390
|
}
|
|
1432
1391
|
|
|
1433
|
-
getVoiceSettings(): Required<VoiceSettings> {
|
|
1434
|
-
return {
|
|
1435
|
-
enabled: this.settings.voice?.enabled ?? false,
|
|
1436
|
-
transcriptionModel: this.settings.voice?.transcriptionModel ?? "whisper-1",
|
|
1437
|
-
transcriptionLanguage: this.settings.voice?.transcriptionLanguage ?? "",
|
|
1438
|
-
ttsModel: this.settings.voice?.ttsModel ?? "tts-1",
|
|
1439
|
-
ttsVoice: this.settings.voice?.ttsVoice ?? "alloy",
|
|
1440
|
-
ttsFormat: this.settings.voice?.ttsFormat ?? "wav",
|
|
1441
|
-
};
|
|
1442
|
-
}
|
|
1443
|
-
|
|
1444
|
-
async setVoiceSettings(settings: VoiceSettings): Promise<void> {
|
|
1445
|
-
this.globalSettings.voice = { ...this.globalSettings.voice, ...settings };
|
|
1446
|
-
await this.save();
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
getVoiceEnabled(): boolean {
|
|
1450
|
-
return this.settings.voice?.enabled ?? false;
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
async setVoiceEnabled(enabled: boolean): Promise<void> {
|
|
1454
|
-
if (!this.globalSettings.voice) {
|
|
1455
|
-
this.globalSettings.voice = {};
|
|
1456
|
-
}
|
|
1457
|
-
this.globalSettings.voice.enabled = enabled;
|
|
1458
|
-
await this.save();
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
getVoiceTtsModel(): string {
|
|
1462
|
-
return this.settings.voice?.ttsModel ?? "gpt-4o-mini-tts";
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
async setVoiceTtsModel(model: string): Promise<void> {
|
|
1466
|
-
if (!this.globalSettings.voice) {
|
|
1467
|
-
this.globalSettings.voice = {};
|
|
1468
|
-
}
|
|
1469
|
-
this.globalSettings.voice.ttsModel = model;
|
|
1470
|
-
await this.save();
|
|
1471
|
-
}
|
|
1472
|
-
|
|
1473
|
-
getVoiceTtsVoice(): string {
|
|
1474
|
-
return this.settings.voice?.ttsVoice ?? "alloy";
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
async setVoiceTtsVoice(voice: string): Promise<void> {
|
|
1478
|
-
if (!this.globalSettings.voice) {
|
|
1479
|
-
this.globalSettings.voice = {};
|
|
1480
|
-
}
|
|
1481
|
-
this.globalSettings.voice.ttsVoice = voice;
|
|
1482
|
-
await this.save();
|
|
1483
|
-
}
|
|
1484
|
-
|
|
1485
|
-
getVoiceTtsFormat(): "wav" | "mp3" | "opus" | "aac" | "flac" {
|
|
1486
|
-
return this.settings.voice?.ttsFormat ?? "wav";
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
|
-
async setVoiceTtsFormat(format: "wav" | "mp3" | "opus" | "aac" | "flac"): Promise<void> {
|
|
1490
|
-
if (!this.globalSettings.voice) {
|
|
1491
|
-
this.globalSettings.voice = {};
|
|
1492
|
-
}
|
|
1493
|
-
this.globalSettings.voice.ttsFormat = format;
|
|
1494
|
-
await this.save();
|
|
1495
|
-
}
|
|
1496
|
-
|
|
1497
1392
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
1498
1393
|
// Status Line Settings
|
|
1499
1394
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -33,8 +33,6 @@ export class OutputSink {
|
|
|
33
33
|
path: string;
|
|
34
34
|
sink: Bun.FileSink;
|
|
35
35
|
};
|
|
36
|
-
#bytesWritten: number = 0;
|
|
37
|
-
#pending: Promise<void> = Promise.resolve();
|
|
38
36
|
|
|
39
37
|
readonly #allocateFilePath: () => string;
|
|
40
38
|
readonly #spillThreshold: number;
|
|
@@ -54,15 +52,16 @@ export class OutputSink {
|
|
|
54
52
|
|
|
55
53
|
async #pushSanitized(data: string): Promise<void> {
|
|
56
54
|
this.#onChunk?.(data);
|
|
57
|
-
|
|
58
|
-
const
|
|
55
|
+
|
|
56
|
+
const bufferOverflow = data.length + this.#buffer.length > this.#spillThreshold;
|
|
57
|
+
const overflow = this.#file || bufferOverflow;
|
|
59
58
|
|
|
60
59
|
const sink = overflow ? await this.#fileSink() : null;
|
|
61
60
|
|
|
62
61
|
this.#buffer += data;
|
|
63
62
|
await sink?.write(data);
|
|
64
63
|
|
|
65
|
-
if (
|
|
64
|
+
if (bufferOverflow) {
|
|
66
65
|
this.#buffer = this.#buffer.slice(-this.#spillThreshold);
|
|
67
66
|
}
|
|
68
67
|
}
|
|
@@ -81,28 +80,21 @@ export class OutputSink {
|
|
|
81
80
|
|
|
82
81
|
async push(chunk: string): Promise<void> {
|
|
83
82
|
chunk = sanitizeText(chunk);
|
|
84
|
-
|
|
85
|
-
this.#pending = op.catch(() => {});
|
|
86
|
-
await op;
|
|
83
|
+
await this.#pushSanitized(chunk);
|
|
87
84
|
}
|
|
88
85
|
|
|
89
86
|
createInput(): WritableStream<Uint8Array | string> {
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
const dec = new TextDecoder("utf-8", { ignoreBOM: true });
|
|
88
|
+
const finalize = async () => {
|
|
89
|
+
await this.push(dec.decode());
|
|
90
|
+
};
|
|
92
91
|
|
|
93
92
|
return new WritableStream<Uint8Array | string>({
|
|
94
93
|
write: async (chunk) => {
|
|
95
94
|
if (typeof chunk === "string") {
|
|
96
95
|
await this.push(chunk);
|
|
97
96
|
} else {
|
|
98
|
-
|
|
99
|
-
const dec = new TextDecoder("utf-8", { ignoreBOM: true });
|
|
100
|
-
decoder = dec;
|
|
101
|
-
finalize = async () => {
|
|
102
|
-
await this.push(dec.decode());
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
await this.push(decoder.decode(chunk, { stream: true }));
|
|
97
|
+
await this.push(dec.decode(chunk, { stream: true }));
|
|
106
98
|
}
|
|
107
99
|
},
|
|
108
100
|
close: finalize,
|
|
@@ -111,7 +103,6 @@ export class OutputSink {
|
|
|
111
103
|
}
|
|
112
104
|
|
|
113
105
|
async dump(notice?: string): Promise<OutputResult> {
|
|
114
|
-
await this.#pending;
|
|
115
106
|
const noticeLine = notice ? `[${notice}]\n` : "";
|
|
116
107
|
|
|
117
108
|
if (this.#file) {
|
package/src/core/tools/index.ts
CHANGED
|
@@ -7,7 +7,6 @@ export { exaTools } from "./exa/index";
|
|
|
7
7
|
export type { ExaRenderDetails, ExaSearchResponse, ExaSearchResult } from "./exa/types";
|
|
8
8
|
export { type FindOperations, FindTool, type FindToolDetails, type FindToolOptions } from "./find";
|
|
9
9
|
export { setPreferredImageProvider } from "./gemini-image";
|
|
10
|
-
export { GitTool, type GitToolDetails } from "./git";
|
|
11
10
|
export { type GrepOperations, GrepTool, type GrepToolDetails, type GrepToolOptions } from "./grep";
|
|
12
11
|
export { type LsOperations, LsTool, type LsToolDetails, type LsToolOptions } from "./ls";
|
|
13
12
|
export {
|
|
@@ -72,7 +71,6 @@ import { BashTool } from "./bash";
|
|
|
72
71
|
import { CalculatorTool } from "./calculator";
|
|
73
72
|
import { CompleteTool } from "./complete";
|
|
74
73
|
import { FindTool } from "./find";
|
|
75
|
-
import { GitTool } from "./git";
|
|
76
74
|
import { GrepTool } from "./grep";
|
|
77
75
|
import { LsTool } from "./ls";
|
|
78
76
|
import { LspTool } from "./lsp/index";
|
|
@@ -132,7 +130,6 @@ export interface ToolSession {
|
|
|
132
130
|
getEditFuzzyMatch(): boolean;
|
|
133
131
|
getEditFuzzyThreshold?(): number;
|
|
134
132
|
getEditPatchMode?(): boolean;
|
|
135
|
-
getGitToolEnabled(): boolean;
|
|
136
133
|
getBashInterceptorEnabled(): boolean;
|
|
137
134
|
getBashInterceptorSimpleLsEnabled(): boolean;
|
|
138
135
|
getBashInterceptorRules(): BashInterceptorRule[];
|
|
@@ -152,7 +149,6 @@ export const BUILTIN_TOOLS: Record<string, ToolFactory> = {
|
|
|
152
149
|
ssh: loadSshTool,
|
|
153
150
|
edit: (s) => new EditTool(s),
|
|
154
151
|
find: (s) => new FindTool(s),
|
|
155
|
-
git: GitTool.createIf,
|
|
156
152
|
grep: (s) => new GrepTool(s),
|
|
157
153
|
ls: (s) => new LsTool(s),
|
|
158
154
|
lsp: LspTool.createIf,
|
package/src/core/tools/python.ts
CHANGED
|
@@ -40,7 +40,7 @@ function groupPreludeHelpers(helpers: PreludeHelper[]): PreludeCategory[] {
|
|
|
40
40
|
|
|
41
41
|
export const pythonSchema = Type.Object({
|
|
42
42
|
code: Type.String({ description: "Python code to execute" }),
|
|
43
|
-
|
|
43
|
+
timeoutMs: Type.Optional(Type.Number({ description: "Timeout in milliseconds (default: 30000)" })),
|
|
44
44
|
workdir: Type.Optional(
|
|
45
45
|
Type.String({ description: "Working directory for the command (default: current directory)" }),
|
|
46
46
|
),
|
|
@@ -151,7 +151,7 @@ export class PythonTool implements AgentTool<typeof pythonSchema> {
|
|
|
151
151
|
throw new Error("Python tool requires a session when not using proxy executor");
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
const { code,
|
|
154
|
+
const { code, timeoutMs = 30000, workdir, reset } = params;
|
|
155
155
|
const controller = new AbortController();
|
|
156
156
|
const onAbort = () => controller.abort();
|
|
157
157
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
@@ -182,7 +182,7 @@ export class PythonTool implements AgentTool<typeof pythonSchema> {
|
|
|
182
182
|
const sessionId = sessionFile ? `session:${sessionFile}:workdir:${commandCwd}` : `cwd:${commandCwd}`;
|
|
183
183
|
const executorOptions: PythonExecutorOptions = {
|
|
184
184
|
cwd: commandCwd,
|
|
185
|
-
|
|
185
|
+
timeoutMs,
|
|
186
186
|
signal: controller.signal,
|
|
187
187
|
sessionId,
|
|
188
188
|
kernelMode: this.session.settings?.getPythonKernelMode?.() ?? "session",
|
package/src/index.ts
CHANGED
|
@@ -83,7 +83,6 @@ const THINKING_DESCRIPTIONS: Record<ThinkingLevel, string> = {
|
|
|
83
83
|
* - behavior: Core agent behavior (compaction, modes, retries, notifications)
|
|
84
84
|
* - tools: Tool-specific settings (bash, git, python, edit, MCP, skills)
|
|
85
85
|
* - display: Visual/UI settings (theme, images, thinking)
|
|
86
|
-
* - voice: Voice mode and TTS settings
|
|
87
86
|
* - ttsr: Time Traveling Stream Rules settings
|
|
88
87
|
* - status: Status line configuration
|
|
89
88
|
* - lsp: LSP integration settings
|
|
@@ -250,15 +249,6 @@ export const SETTINGS_DEFS: SettingDef[] = [
|
|
|
250
249
|
get: (sm) => sm.getBashInterceptorSimpleLsEnabled(),
|
|
251
250
|
set: (sm, v) => sm.setBashInterceptorSimpleLsEnabled(v),
|
|
252
251
|
},
|
|
253
|
-
{
|
|
254
|
-
id: "gitTool",
|
|
255
|
-
tab: "tools",
|
|
256
|
-
type: "boolean",
|
|
257
|
-
label: "Git tool",
|
|
258
|
-
description: "Enable structured Git tool",
|
|
259
|
-
get: (sm) => sm.getGitToolEnabled(),
|
|
260
|
-
set: (sm, v) => sm.setGitToolEnabled(v),
|
|
261
|
-
},
|
|
262
252
|
{
|
|
263
253
|
id: "pythonToolMode",
|
|
264
254
|
tab: "tools",
|
|
@@ -494,66 +484,6 @@ export const SETTINGS_DEFS: SettingDef[] = [
|
|
|
494
484
|
set: (sm, v) => sm.setShowHardwareCursor(v),
|
|
495
485
|
},
|
|
496
486
|
|
|
497
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
498
|
-
// Voice tab - Voice mode and TTS settings
|
|
499
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
500
|
-
{
|
|
501
|
-
id: "voiceEnabled",
|
|
502
|
-
tab: "voice",
|
|
503
|
-
type: "boolean",
|
|
504
|
-
label: "Voice mode",
|
|
505
|
-
description: "Enable realtime voice input/output (Ctrl+Y toggle, auto-send on silence)",
|
|
506
|
-
get: (sm) => sm.getVoiceEnabled(),
|
|
507
|
-
set: (sm, v) => sm.setVoiceEnabled(v),
|
|
508
|
-
},
|
|
509
|
-
{
|
|
510
|
-
id: "voiceTtsModel",
|
|
511
|
-
tab: "voice",
|
|
512
|
-
type: "submenu",
|
|
513
|
-
label: "TTS model",
|
|
514
|
-
description: "Text-to-speech model for voice output",
|
|
515
|
-
get: (sm) => sm.getVoiceTtsModel(),
|
|
516
|
-
set: (sm, v) => sm.setVoiceTtsModel(v),
|
|
517
|
-
getOptions: () => [
|
|
518
|
-
{ value: "gpt-4o-mini-tts", label: "GPT-4o Mini TTS", description: "Fast and efficient" },
|
|
519
|
-
{ value: "tts-1", label: "TTS-1", description: "Standard quality" },
|
|
520
|
-
{ value: "tts-1-hd", label: "TTS-1 HD", description: "Higher quality" },
|
|
521
|
-
],
|
|
522
|
-
},
|
|
523
|
-
{
|
|
524
|
-
id: "voiceTtsVoice",
|
|
525
|
-
tab: "voice",
|
|
526
|
-
type: "submenu",
|
|
527
|
-
label: "TTS voice",
|
|
528
|
-
description: "Voice for text-to-speech output",
|
|
529
|
-
get: (sm) => sm.getVoiceTtsVoice(),
|
|
530
|
-
set: (sm, v) => sm.setVoiceTtsVoice(v),
|
|
531
|
-
getOptions: () => [
|
|
532
|
-
{ value: "alloy", label: "Alloy", description: "Neutral" },
|
|
533
|
-
{ value: "echo", label: "Echo", description: "Male" },
|
|
534
|
-
{ value: "fable", label: "Fable", description: "British" },
|
|
535
|
-
{ value: "onyx", label: "Onyx", description: "Deep male" },
|
|
536
|
-
{ value: "nova", label: "Nova", description: "Female" },
|
|
537
|
-
{ value: "shimmer", label: "Shimmer", description: "Female" },
|
|
538
|
-
],
|
|
539
|
-
},
|
|
540
|
-
{
|
|
541
|
-
id: "voiceTtsFormat",
|
|
542
|
-
tab: "voice",
|
|
543
|
-
type: "submenu",
|
|
544
|
-
label: "TTS format",
|
|
545
|
-
description: "Audio format for voice output",
|
|
546
|
-
get: (sm) => sm.getVoiceTtsFormat(),
|
|
547
|
-
set: (sm, v) => sm.setVoiceTtsFormat(v as "wav" | "mp3" | "opus" | "aac" | "flac"),
|
|
548
|
-
getOptions: () => [
|
|
549
|
-
{ value: "wav", label: "WAV", description: "Uncompressed, best quality" },
|
|
550
|
-
{ value: "mp3", label: "MP3", description: "Compressed, widely compatible" },
|
|
551
|
-
{ value: "opus", label: "Opus", description: "Efficient compression" },
|
|
552
|
-
{ value: "aac", label: "AAC", description: "Apple-friendly" },
|
|
553
|
-
{ value: "flac", label: "FLAC", description: "Lossless compression" },
|
|
554
|
-
],
|
|
555
|
-
},
|
|
556
|
-
|
|
557
487
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
558
488
|
// TTSR tab - Time Traveling Stream Rules
|
|
559
489
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -117,7 +117,6 @@ const SETTINGS_TABS: Tab[] = [
|
|
|
117
117
|
{ id: "behavior", label: "Behavior" },
|
|
118
118
|
{ id: "tools", label: "Tools" },
|
|
119
119
|
{ id: "display", label: "Display" },
|
|
120
|
-
{ id: "voice", label: "Voice" },
|
|
121
120
|
{ id: "ttsr", label: "TTSR" },
|
|
122
121
|
{ id: "status", label: "Status" },
|
|
123
122
|
{ id: "lsp", label: "LSP" },
|
|
@@ -68,7 +68,6 @@ export class EventController {
|
|
|
68
68
|
getSymbolTheme().spinnerFrames,
|
|
69
69
|
);
|
|
70
70
|
this.ctx.statusContainer.addChild(this.ctx.loadingAnimation);
|
|
71
|
-
this.ctx.startVoiceProgressTimer();
|
|
72
71
|
this.ctx.ui.requestRender();
|
|
73
72
|
break;
|
|
74
73
|
|
|
@@ -250,7 +249,6 @@ export class EventController {
|
|
|
250
249
|
}
|
|
251
250
|
|
|
252
251
|
case "agent_end":
|
|
253
|
-
this.ctx.stopVoiceProgressTimer();
|
|
254
252
|
if (this.ctx.loadingAnimation) {
|
|
255
253
|
this.ctx.loadingAnimation.stop();
|
|
256
254
|
this.ctx.loadingAnimation = undefined;
|
|
@@ -262,15 +260,6 @@ export class EventController {
|
|
|
262
260
|
this.ctx.streamingMessage = undefined;
|
|
263
261
|
}
|
|
264
262
|
this.ctx.pendingTools.clear();
|
|
265
|
-
if (this.ctx.settingsManager.getVoiceEnabled() && this.ctx.voiceAutoModeEnabled) {
|
|
266
|
-
const lastAssistant = this.ctx.findLastAssistantMessage();
|
|
267
|
-
if (lastAssistant && lastAssistant.stopReason !== "aborted" && lastAssistant.stopReason !== "error") {
|
|
268
|
-
const text = this.ctx.extractAssistantText(lastAssistant);
|
|
269
|
-
if (text) {
|
|
270
|
-
this.ctx.voiceSupervisor.notifyResult(text);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
263
|
this.ctx.ui.requestRender();
|
|
275
264
|
this.sendCompletionNotification();
|
|
276
265
|
break;
|
|
@@ -199,15 +199,6 @@ export class SelectorController {
|
|
|
199
199
|
this.ctx.ui.invalidate();
|
|
200
200
|
break;
|
|
201
201
|
}
|
|
202
|
-
case "voiceEnabled": {
|
|
203
|
-
if (!value) {
|
|
204
|
-
this.ctx.voiceAutoModeEnabled = false;
|
|
205
|
-
this.ctx.stopVoiceProgressTimer();
|
|
206
|
-
void this.ctx.voiceSupervisor.stop();
|
|
207
|
-
this.ctx.setVoiceStatus(undefined);
|
|
208
|
-
}
|
|
209
|
-
break;
|
|
210
|
-
}
|
|
211
202
|
case "statusLinePreset":
|
|
212
203
|
case "statusLineSeparator":
|
|
213
204
|
case "statusLineShowHooks":
|