lonny-agent 0.1.2 → 0.1.9
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/.kilo/plans/1780064105789-mighty-pixel.md +171 -0
- package/.lonny/fix-new-command-session-cleanup.md +65 -0
- package/.lonny/tui-autocomplete-above.md +62 -0
- package/dist/agent/__tests__/compaction.test.js +6 -4
- package/dist/agent/__tests__/compaction.test.js.map +1 -1
- package/dist/agent/llm.d.ts +1 -1
- package/dist/agent/llm.d.ts.map +1 -1
- package/dist/agent/prompt-builder.d.ts.map +1 -1
- package/dist/agent/prompt-builder.js +26 -8
- package/dist/agent/prompt-builder.js.map +1 -1
- package/dist/agent/providers/anthropic.d.ts +1 -1
- package/dist/agent/providers/anthropic.d.ts.map +1 -1
- package/dist/agent/providers/anthropic.js +2 -2
- package/dist/agent/providers/anthropic.js.map +1 -1
- package/dist/agent/providers/google.d.ts +1 -1
- package/dist/agent/providers/google.d.ts.map +1 -1
- package/dist/agent/providers/google.js +2 -1
- package/dist/agent/providers/google.js.map +1 -1
- package/dist/agent/providers/ollama.d.ts +1 -1
- package/dist/agent/providers/ollama.d.ts.map +1 -1
- package/dist/agent/providers/ollama.js +2 -1
- package/dist/agent/providers/ollama.js.map +1 -1
- package/dist/agent/providers/openai.d.ts +1 -1
- package/dist/agent/providers/openai.d.ts.map +1 -1
- package/dist/agent/providers/openai.js +2 -2
- package/dist/agent/providers/openai.js.map +1 -1
- package/dist/agent/session.d.ts +1 -0
- package/dist/agent/session.d.ts.map +1 -1
- package/dist/agent/session.js +8 -2
- package/dist/agent/session.js.map +1 -1
- package/dist/pi-tui/autocomplete.d.ts +54 -0
- package/dist/pi-tui/autocomplete.d.ts.map +1 -0
- package/dist/pi-tui/autocomplete.js +636 -0
- package/dist/pi-tui/autocomplete.js.map +1 -0
- package/dist/pi-tui/components/box.d.ts +22 -0
- package/dist/pi-tui/components/box.d.ts.map +1 -0
- package/dist/pi-tui/components/box.js +104 -0
- package/dist/pi-tui/components/box.js.map +1 -0
- package/dist/pi-tui/components/cancellable-loader.d.ts +22 -0
- package/dist/pi-tui/components/cancellable-loader.d.ts.map +1 -0
- package/dist/pi-tui/components/cancellable-loader.js +35 -0
- package/dist/pi-tui/components/cancellable-loader.js.map +1 -0
- package/dist/pi-tui/components/editor.d.ts +249 -0
- package/dist/pi-tui/components/editor.d.ts.map +1 -0
- package/dist/pi-tui/components/editor.js +1883 -0
- package/dist/pi-tui/components/editor.js.map +1 -0
- package/dist/pi-tui/components/image.d.ts +28 -0
- package/dist/pi-tui/components/image.d.ts.map +1 -0
- package/dist/pi-tui/components/image.js +90 -0
- package/dist/pi-tui/components/image.js.map +1 -0
- package/dist/pi-tui/components/input.d.ts +37 -0
- package/dist/pi-tui/components/input.d.ts.map +1 -0
- package/dist/pi-tui/components/input.js +382 -0
- package/dist/pi-tui/components/input.js.map +1 -0
- package/dist/pi-tui/components/loader.d.ts +31 -0
- package/dist/pi-tui/components/loader.d.ts.map +1 -0
- package/dist/pi-tui/components/loader.js +70 -0
- package/dist/pi-tui/components/loader.js.map +1 -0
- package/dist/pi-tui/components/markdown.d.ts +96 -0
- package/dist/pi-tui/components/markdown.d.ts.map +1 -0
- package/dist/pi-tui/components/markdown.js +647 -0
- package/dist/pi-tui/components/markdown.js.map +1 -0
- package/dist/pi-tui/components/select-list.d.ts +50 -0
- package/dist/pi-tui/components/select-list.d.ts.map +1 -0
- package/dist/pi-tui/components/select-list.js +167 -0
- package/dist/pi-tui/components/select-list.js.map +1 -0
- package/dist/pi-tui/components/settings-list.d.ts +50 -0
- package/dist/pi-tui/components/settings-list.d.ts.map +1 -0
- package/dist/pi-tui/components/settings-list.js +189 -0
- package/dist/pi-tui/components/settings-list.js.map +1 -0
- package/dist/pi-tui/components/spacer.d.ts +12 -0
- package/dist/pi-tui/components/spacer.d.ts.map +1 -0
- package/dist/pi-tui/components/spacer.js +23 -0
- package/dist/pi-tui/components/spacer.js.map +1 -0
- package/dist/pi-tui/components/text.d.ts +19 -0
- package/dist/pi-tui/components/text.d.ts.map +1 -0
- package/dist/pi-tui/components/text.js +91 -0
- package/dist/pi-tui/components/text.js.map +1 -0
- package/dist/pi-tui/components/truncated-text.d.ts +13 -0
- package/dist/pi-tui/components/truncated-text.d.ts.map +1 -0
- package/dist/pi-tui/components/truncated-text.js +51 -0
- package/dist/pi-tui/components/truncated-text.js.map +1 -0
- package/dist/pi-tui/editor-component.d.ts +39 -0
- package/dist/pi-tui/editor-component.d.ts.map +1 -0
- package/dist/pi-tui/editor-component.js +2 -0
- package/dist/pi-tui/editor-component.js.map +1 -0
- package/dist/pi-tui/fuzzy.d.ts +16 -0
- package/dist/pi-tui/fuzzy.d.ts.map +1 -0
- package/dist/pi-tui/fuzzy.js +110 -0
- package/dist/pi-tui/fuzzy.js.map +1 -0
- package/dist/pi-tui/index.d.ts +23 -0
- package/dist/pi-tui/index.d.ts.map +1 -0
- package/dist/pi-tui/index.js +32 -0
- package/dist/pi-tui/index.js.map +1 -0
- package/dist/pi-tui/keybindings.d.ts +193 -0
- package/dist/pi-tui/keybindings.d.ts.map +1 -0
- package/dist/pi-tui/keybindings.js +174 -0
- package/dist/pi-tui/keybindings.js.map +1 -0
- package/dist/pi-tui/keys.d.ts +184 -0
- package/dist/pi-tui/keys.d.ts.map +1 -0
- package/dist/pi-tui/keys.js +1182 -0
- package/dist/pi-tui/keys.js.map +1 -0
- package/dist/pi-tui/kill-ring.d.ts +28 -0
- package/dist/pi-tui/kill-ring.d.ts.map +1 -0
- package/dist/pi-tui/kill-ring.js +44 -0
- package/dist/pi-tui/kill-ring.js.map +1 -0
- package/dist/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
- package/dist/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
- package/dist/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/dist/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/dist/pi-tui/native-modifiers.d.ts +3 -0
- package/dist/pi-tui/native-modifiers.d.ts.map +1 -0
- package/dist/pi-tui/native-modifiers.js +53 -0
- package/dist/pi-tui/native-modifiers.js.map +1 -0
- package/dist/pi-tui/stdin-buffer.d.ts +50 -0
- package/dist/pi-tui/stdin-buffer.d.ts.map +1 -0
- package/dist/pi-tui/stdin-buffer.js +361 -0
- package/dist/pi-tui/stdin-buffer.js.map +1 -0
- package/dist/pi-tui/terminal-image.d.ts +90 -0
- package/dist/pi-tui/terminal-image.d.ts.map +1 -0
- package/dist/pi-tui/terminal-image.js +343 -0
- package/dist/pi-tui/terminal-image.js.map +1 -0
- package/dist/pi-tui/terminal.d.ts +113 -0
- package/dist/pi-tui/terminal.d.ts.map +1 -0
- package/dist/pi-tui/terminal.js +478 -0
- package/dist/pi-tui/terminal.js.map +1 -0
- package/dist/pi-tui/tui.d.ts +227 -0
- package/dist/pi-tui/tui.d.ts.map +1 -0
- package/dist/pi-tui/tui.js +1091 -0
- package/dist/pi-tui/tui.js.map +1 -0
- package/dist/pi-tui/undo-stack.d.ts +17 -0
- package/dist/pi-tui/undo-stack.d.ts.map +1 -0
- package/dist/pi-tui/undo-stack.js +25 -0
- package/dist/pi-tui/undo-stack.js.map +1 -0
- package/dist/pi-tui/utils.d.ts +84 -0
- package/dist/pi-tui/utils.d.ts.map +1 -0
- package/dist/pi-tui/utils.js +1024 -0
- package/dist/pi-tui/utils.js.map +1 -0
- package/dist/pi-tui/word-navigation.d.ts +25 -0
- package/dist/pi-tui/word-navigation.d.ts.map +1 -0
- package/dist/pi-tui/word-navigation.js +98 -0
- package/dist/pi-tui/word-navigation.js.map +1 -0
- package/dist/tools/__tests__/edit.test.js +85 -0
- package/dist/tools/__tests__/edit.test.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +23 -1
- package/dist/tools/edit.js.map +1 -1
- package/dist/tui/components.d.ts +1 -1
- package/dist/tui/components.d.ts.map +1 -1
- package/dist/tui/components.js +1 -1
- package/dist/tui/components.js.map +1 -1
- package/dist/tui/editor-patch.d.ts +13 -0
- package/dist/tui/editor-patch.d.ts.map +1 -0
- package/dist/tui/editor-patch.js +41 -0
- package/dist/tui/editor-patch.js.map +1 -0
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +15 -3
- package/dist/tui/index.js.map +1 -1
- package/dist/web/index.d.ts.map +1 -1
- package/dist/web/index.js +9 -2
- package/dist/web/index.js.map +1 -1
- package/dist/web/public/app.js +65 -4
- package/dist/web/public/style.css +49 -0
- package/dist/web/session-bridge.d.ts +0 -4
- package/dist/web/session-bridge.d.ts.map +1 -1
- package/dist/web/session-bridge.js +16 -2
- package/dist/web/session-bridge.js.map +1 -1
- package/package.json +5 -3
- package/src/agent/__tests__/compaction.test.ts +6 -4
- package/src/agent/llm.ts +5 -1
- package/src/agent/prompt-builder.ts +27 -8
- package/src/agent/providers/anthropic.ts +15 -8
- package/src/agent/providers/google.ts +6 -1
- package/src/agent/providers/ollama.ts +6 -1
- package/src/agent/providers/openai.ts +21 -12
- package/src/agent/session.ts +12 -2
- package/src/pi-tui/autocomplete.ts +808 -0
- package/src/pi-tui/components/box.ts +137 -0
- package/src/pi-tui/components/cancellable-loader.ts +40 -0
- package/src/pi-tui/components/editor.ts +2321 -0
- package/src/pi-tui/components/image.ts +130 -0
- package/src/pi-tui/components/input.ts +456 -0
- package/src/pi-tui/components/loader.ts +93 -0
- package/src/pi-tui/components/markdown.ts +839 -0
- package/src/pi-tui/components/select-list.ts +263 -0
- package/src/pi-tui/components/settings-list.ts +264 -0
- package/src/pi-tui/components/spacer.ts +28 -0
- package/src/pi-tui/components/text.ts +113 -0
- package/src/pi-tui/components/truncated-text.ts +65 -0
- package/src/pi-tui/editor-component.ts +74 -0
- package/src/pi-tui/fuzzy.ts +137 -0
- package/src/pi-tui/index.ts +115 -0
- package/src/pi-tui/keybindings.ts +245 -0
- package/src/pi-tui/keys.ts +1440 -0
- package/src/pi-tui/kill-ring.ts +46 -0
- package/src/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
- package/src/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
- package/src/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/src/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/src/pi-tui/native-modifiers.ts +65 -0
- package/src/pi-tui/stdin-buffer.ts +434 -0
- package/src/pi-tui/terminal-image.ts +469 -0
- package/src/pi-tui/terminal.ts +594 -0
- package/src/pi-tui/tui.ts +1376 -0
- package/src/pi-tui/undo-stack.ts +28 -0
- package/src/pi-tui/utils.ts +1176 -0
- package/src/pi-tui/word-navigation.ts +127 -0
- package/src/tools/__tests__/edit.test.ts +91 -0
- package/src/tools/edit.ts +27 -1
- package/src/tui/components.ts +2 -2
- package/src/tui/index.ts +24 -10
- package/src/web/index.ts +9 -2
- package/src/web/public/app.js +65 -4
- package/src/web/public/style.css +49 -0
- package/src/web/session-bridge.ts +13 -2
- package/tsconfig.json +2 -2
|
@@ -26,7 +26,19 @@ export function buildSystemPrompt(config: Config): string {
|
|
|
26
26
|
- \`search\`: Search the web using Tavily (query: string, search_depth?: string, include_answer?: boolean, max_results?: number, topic?: string, days?: number)
|
|
27
27
|
`
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
if (mode === 'plan') {
|
|
30
|
+
return `Available tools (read-only investigation + write_plan):
|
|
31
|
+
- \`read\`: Read file contents (paths: string[])
|
|
32
|
+
- \`glob\`: Find files by glob pattern (pattern: string)
|
|
33
|
+
- \`grep\`: Search file content by regex (pattern: string, include?: string, path?: string)
|
|
34
|
+
- \`ls\`: List directory (path?: string)
|
|
35
|
+
- \`bash\`: Execute read-only shell commands for investigation (NEVER modify files)
|
|
36
|
+
- \`find\`: Find files by name pattern (pattern: string, path?: string, maxResults?: number)
|
|
37
|
+
- \`git\`: Run read-only git commands (command: string)
|
|
38
|
+
- \`search\`: Search the web using Tavily (query: string, search_depth?: string, include_answer?: boolean, max_results?: number, topic?: string, days?: number)
|
|
39
|
+
- \`write_plan\`: Save plan/todo markdown into .lonny/ folder
|
|
40
|
+
`
|
|
41
|
+
}
|
|
30
42
|
return `Available tools:
|
|
31
43
|
- \`read\`: Read file contents (paths: string[])
|
|
32
44
|
- \`glob\`: Find files by glob pattern (pattern: string)
|
|
@@ -34,7 +46,7 @@ export function buildSystemPrompt(config: Config): string {
|
|
|
34
46
|
- \`ls\`: List directory (path?: string)
|
|
35
47
|
- \`bash\`: Execute a shell command
|
|
36
48
|
- \`edit\`: Replace text in files — call with {"edits": [{"file_path", "old_string", "new_string"}]} (array required)
|
|
37
|
-
|
|
49
|
+
- \`install_skill\`: Install an npm package as a skill — fetches package info from npm, runs npm install, and creates a .lonny/skills/ file with usage instructions for the AI
|
|
38
50
|
- \`find\`: Find files by name pattern (pattern: string, path?: string, maxResults?: number)
|
|
39
51
|
- \`git\`: Run read-only git commands (command: string)
|
|
40
52
|
- \`search\`: Search the web using Tavily (query: string, search_depth?: string, include_answer?: boolean, max_results?: number, topic?: string, days?: number)
|
|
@@ -59,10 +71,12 @@ ${getToolListForMode(config.mode)}`
|
|
|
59
71
|
|
|
60
72
|
RULES (plan-specific):
|
|
61
73
|
1. Read first: Use read/grep/glob tools to gather all context you need before planning.
|
|
62
|
-
2. You
|
|
63
|
-
3. Use \`bash\` for
|
|
64
|
-
4.
|
|
65
|
-
5. You MUST
|
|
74
|
+
2. You NEVER edit source files. You ONLY use read-only tools (read/glob/grep/ls/find/git/search) and bash (read-only commands only). You do NOT have access to edit, install_skill, or exec.
|
|
75
|
+
3. Use \`bash\` for investigation only — NEVER to modify files, install packages, or run write operations.
|
|
76
|
+
4. Your ONLY output is a plan file saved via \`write_plan\`. You CANNOT modify the codebase directly.
|
|
77
|
+
5. You MUST persist the final plan AND todo list to a file in \`.lonny/\` using \`write_plan\`. The \`write_plan\` content MUST include both ## Plan and ## Todo List sections.
|
|
78
|
+
6. You MUST also include the todo list in your text response to the user (not just in the file).
|
|
79
|
+
7. If the user asks you to modify files, run write commands, or install packages — refuse and explain they need to switch to code mode (\`/mode code\`).
|
|
66
80
|
|
|
67
81
|
OUTPUT FORMAT (you MUST include both in write_plan AND in your response text):
|
|
68
82
|
|
|
@@ -113,8 +127,13 @@ RULES (code-specific):
|
|
|
113
127
|
${isWindows ? ' - Use PowerShell. Do NOT use Unix commands like `cat`, `ls`, `grep`, `which`, `chmod`, `mv`, `cp`, `rm`, `touch`, `mkdir`, `uname`, etc.' : ''}
|
|
114
128
|
${isWindows ? ' - Use `type` instead of `cat`, `dir` instead of `ls`, `where` instead of `which`' : ''}`
|
|
115
129
|
|
|
130
|
+
// Plan mode uses its own standalone tool list inside modeInstructions — skip sharedRules
|
|
131
|
+
const rulesSection =
|
|
132
|
+
config.mode === 'plan'
|
|
133
|
+
? ''
|
|
134
|
+
: `
|
|
135
|
+
${sharedRules}`
|
|
116
136
|
return `${modeInstructions}
|
|
117
137
|
|
|
118
|
-
${envSection}
|
|
119
|
-
${sharedRules}${skillsSection}`
|
|
138
|
+
${envSection}${rulesSection}${skillsSection}`
|
|
120
139
|
}
|
|
@@ -12,7 +12,11 @@ export class AnthropicProvider implements LLMProvider {
|
|
|
12
12
|
this.model = model || 'claude-sonnet-4-20250514'
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
async *chat(
|
|
15
|
+
async *chat(
|
|
16
|
+
messages: LLMMessage[],
|
|
17
|
+
tools: ToolDefinition[],
|
|
18
|
+
signal?: AbortSignal,
|
|
19
|
+
): AsyncGenerator<LLMChunk> {
|
|
16
20
|
const anthropicTools: Anthropic.Tool[] = tools.map(t => {
|
|
17
21
|
const properties: Record<string, unknown> = {}
|
|
18
22
|
for (const [key, param] of Object.entries(t.parameters)) {
|
|
@@ -71,13 +75,16 @@ export class AnthropicProvider implements LLMProvider {
|
|
|
71
75
|
return { role: 'user' as const, content: '' }
|
|
72
76
|
})
|
|
73
77
|
|
|
74
|
-
const stream = this.client.messages.stream(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
const stream = this.client.messages.stream(
|
|
79
|
+
{
|
|
80
|
+
model: this.model,
|
|
81
|
+
system: systemMsg?.content || '',
|
|
82
|
+
messages: anthropicMessages,
|
|
83
|
+
tools: anthropicTools.length > 0 ? anthropicTools : undefined,
|
|
84
|
+
max_tokens: 8192,
|
|
85
|
+
},
|
|
86
|
+
signal ? { signal } : undefined,
|
|
87
|
+
)
|
|
81
88
|
|
|
82
89
|
let currentToolUse: {
|
|
83
90
|
id: string
|
|
@@ -48,7 +48,11 @@ export class GoogleProvider implements LLMProvider {
|
|
|
48
48
|
this.baseUrl = baseURL || 'https://generativelanguage.googleapis.com/v1beta'
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
async *chat(
|
|
51
|
+
async *chat(
|
|
52
|
+
messages: LLMMessage[],
|
|
53
|
+
tools: ToolDefinition[],
|
|
54
|
+
signal?: AbortSignal,
|
|
55
|
+
): AsyncGenerator<LLMChunk> {
|
|
52
56
|
const systemInstruction = messages.find(m => m.role === 'system')?.content || ''
|
|
53
57
|
const nonSystemMessages = messages.filter(m => m.role !== 'system')
|
|
54
58
|
|
|
@@ -135,6 +139,7 @@ export class GoogleProvider implements LLMProvider {
|
|
|
135
139
|
'Content-Type': 'application/json',
|
|
136
140
|
'x-goog-api-key': this.apiKey,
|
|
137
141
|
},
|
|
142
|
+
signal,
|
|
138
143
|
body: JSON.stringify(body),
|
|
139
144
|
})
|
|
140
145
|
|
|
@@ -40,7 +40,11 @@ export class OllamaProvider implements LLMProvider {
|
|
|
40
40
|
this.model = model || 'llama3.2'
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
async *chat(
|
|
43
|
+
async *chat(
|
|
44
|
+
messages: LLMMessage[],
|
|
45
|
+
tools: ToolDefinition[],
|
|
46
|
+
signal?: AbortSignal,
|
|
47
|
+
): AsyncGenerator<LLMChunk> {
|
|
44
48
|
// Build Ollama-format messages
|
|
45
49
|
const ollamaMessages: OllamaMessage[] = messages.map(m => {
|
|
46
50
|
if (m.role === 'system') {
|
|
@@ -108,6 +112,7 @@ export class OllamaProvider implements LLMProvider {
|
|
|
108
112
|
const response = await fetch(`${this.baseUrl}/api/chat`, {
|
|
109
113
|
method: 'POST',
|
|
110
114
|
headers: { 'Content-Type': 'application/json' },
|
|
115
|
+
signal,
|
|
111
116
|
body: JSON.stringify(body),
|
|
112
117
|
})
|
|
113
118
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import OpenAI from 'openai'
|
|
2
|
+
import type { RequestOptions } from 'openai/core.js'
|
|
2
3
|
import type {
|
|
3
4
|
ChatCompletionChunk,
|
|
4
5
|
ChatCompletionMessageParam,
|
|
@@ -47,7 +48,11 @@ export class OpenAIProvider implements LLMProvider {
|
|
|
47
48
|
this.strictTools = strictTools ?? (baseURL ? /beta/i.test(baseURL) : false)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
async *chat(
|
|
51
|
+
async *chat(
|
|
52
|
+
messages: LLMMessage[],
|
|
53
|
+
tools: ToolDefinition[],
|
|
54
|
+
signal?: AbortSignal,
|
|
55
|
+
): AsyncGenerator<LLMChunk> {
|
|
51
56
|
const openAIFormattedTools: ChatCompletionTool[] = tools.map(t => {
|
|
52
57
|
const properties: Record<string, unknown> = {}
|
|
53
58
|
for (const [key, param] of Object.entries(t.parameters)) {
|
|
@@ -117,18 +122,22 @@ export class OpenAIProvider implements LLMProvider {
|
|
|
117
122
|
const stream: Stream<ChatCompletionChunk> = await (
|
|
118
123
|
this.client.chat.completions.create as (
|
|
119
124
|
params: ExtendedCreateParams,
|
|
125
|
+
options?: RequestOptions,
|
|
120
126
|
) => Promise<Stream<ChatCompletionChunk>>
|
|
121
|
-
)(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
)(
|
|
128
|
+
{
|
|
129
|
+
model: this.model,
|
|
130
|
+
messages: openAIMessages,
|
|
131
|
+
tools: openAIFormattedTools.length > 0 ? openAIFormattedTools : undefined,
|
|
132
|
+
stream: true,
|
|
133
|
+
stream_options: { include_usage: true },
|
|
134
|
+
...(this.thinking
|
|
135
|
+
? { thinking: { type: 'enabled' }, reasoning_effort: this.reasoningEffort || 'high' }
|
|
136
|
+
: {}),
|
|
137
|
+
...(this.enableCache ? { enable_cache: true } : {}),
|
|
138
|
+
},
|
|
139
|
+
signal ? { signal } : undefined,
|
|
140
|
+
)
|
|
132
141
|
|
|
133
142
|
let currentToolCall: {
|
|
134
143
|
id: string
|
package/src/agent/session.ts
CHANGED
|
@@ -155,7 +155,7 @@ function printToolResult(tc: ToolCall, result: ToolResult, output?: SessionOutpu
|
|
|
155
155
|
writeOut(` ${GY}│${RS} ${GR}✔${RS} edit\n`, output)
|
|
156
156
|
if (result.output) {
|
|
157
157
|
for (const l of result.output.split('\n')) {
|
|
158
|
-
if (l.trim()) writeOut(` ${GY}│${RS}
|
|
158
|
+
if (l.trim()) writeOut(` ${GY}│${RS} ${l.trim()}\n`, output)
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
} else if (tc.name === 'write_plan') {
|
|
@@ -259,6 +259,7 @@ export class Session {
|
|
|
259
259
|
turnApiCalls: number = 0
|
|
260
260
|
totalApiCalls: number = 0
|
|
261
261
|
private stopped: boolean = false
|
|
262
|
+
private abortController: AbortController | null = null
|
|
262
263
|
|
|
263
264
|
constructor(config: Config, output?: SessionOutput) {
|
|
264
265
|
this.config = config
|
|
@@ -368,6 +369,8 @@ export class Session {
|
|
|
368
369
|
/** Stop the current conversation gracefully */
|
|
369
370
|
stop(): void {
|
|
370
371
|
this.stopped = true
|
|
372
|
+
// Abort any in-flight LLM stream to stop token consumption immediately
|
|
373
|
+
this.abortController?.abort()
|
|
371
374
|
}
|
|
372
375
|
|
|
373
376
|
/** Check if the session was stopped */
|
|
@@ -396,6 +399,9 @@ export class Session {
|
|
|
396
399
|
|
|
397
400
|
// Reset stopped flag for new conversation
|
|
398
401
|
this.resetStopped()
|
|
402
|
+
// Create a new AbortController for this chat invocation
|
|
403
|
+
// (a new controller is needed each time because abort() is one-shot)
|
|
404
|
+
this.abortController = new AbortController()
|
|
399
405
|
|
|
400
406
|
// Declare toolCalls outside the loop so we can reference it in stop check
|
|
401
407
|
let toolCalls: ToolCall[] = []
|
|
@@ -419,7 +425,11 @@ export class Session {
|
|
|
419
425
|
bus.emit(EventChannels.TURN_START, { prompt: userPrompt, iteration: iterations })
|
|
420
426
|
bus.emit(EventChannels.LLM_STREAM_START, { iteration: iterations })
|
|
421
427
|
|
|
422
|
-
const stream = this.provider.chat(
|
|
428
|
+
const stream = this.provider.chat(
|
|
429
|
+
this.messages,
|
|
430
|
+
this.registry.getDefinitions(),
|
|
431
|
+
this.abortController.signal,
|
|
432
|
+
)
|
|
423
433
|
|
|
424
434
|
for await (const chunk of stream) {
|
|
425
435
|
if (chunk.reasoning_content) {
|