perf improvements + /login fix

This commit is contained in:
x1xhlol
2026-04-01 17:12:45 +02:00
Unverified
parent 7282a40549
commit c5912b625e
21 changed files with 942 additions and 198 deletions

View File

@@ -9,6 +9,7 @@ import { findToolByName, type Tools, type ToolUseContext } from '../../Tool.js'
import { BASH_TOOL_NAME } from '../../tools/BashTool/toolName.js'
import type { AssistantMessage, Message } from '../../types/message.js'
import { createChildAbortController } from '../../utils/abortController.js'
import { getMaxToolUseConcurrency } from './toolConcurrency.js'
import { runToolUse } from './toolExecution.js'
type MessageUpdate = {
@@ -31,6 +32,20 @@ type TrackedTool = {
contextModifiers?: Array<(context: ToolUseContext) => ToolUseContext>
}
const EPHEMERAL_PROGRESS_TYPES = new Set([
'bash_progress',
'powershell_progress',
'mcp_progress',
'sleep_progress',
])
function isEphemeralProgressMessage(message: Message): boolean {
return (
message.type === 'progress' &&
EPHEMERAL_PROGRESS_TYPES.has(message.data.type)
)
}
/**
* Executes tools as they stream in with concurrency control.
* - Concurrent-safe tools can execute in parallel with other concurrent-safe tools
@@ -128,10 +143,13 @@ export class StreamingToolExecutor {
*/
private canExecuteTool(isConcurrencySafe: boolean): boolean {
const executingTools = this.tools.filter(t => t.status === 'executing')
return (
executingTools.length === 0 ||
(isConcurrencySafe && executingTools.every(t => t.isConcurrencySafe))
)
if (executingTools.length === 0) {
return true
}
if (!isConcurrencySafe || !executingTools.every(t => t.isConcurrencySafe)) {
return false
}
return executingTools.length < getMaxToolUseConcurrency()
}
/**
@@ -366,7 +384,17 @@ export class StreamingToolExecutor {
if (update.message) {
// Progress messages go to pendingProgress for immediate yielding
if (update.message.type === 'progress') {
tool.pendingProgress.push(update.message)
const lastPending = tool.pendingProgress.at(-1)
if (
isEphemeralProgressMessage(update.message) &&
lastPending?.type === 'progress' &&
lastPending.data.type === update.message.data.type
) {
tool.pendingProgress[tool.pendingProgress.length - 1] =
update.message
} else {
tool.pendingProgress.push(update.message)
}
// Signal that progress is available
if (this.progressAvailableResolve) {
this.progressAvailableResolve()

View File

@@ -0,0 +1,8 @@
export const DEFAULT_MAX_TOOL_USE_CONCURRENCY = 4
export function getMaxToolUseConcurrency(): number {
const parsed = parseInt(process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY || '', 10)
return Number.isFinite(parsed) && parsed > 0
? parsed
: DEFAULT_MAX_TOOL_USE_CONCURRENCY
}

View File

@@ -0,0 +1,33 @@
import { afterEach, expect, test } from 'bun:test'
import {
DEFAULT_MAX_TOOL_USE_CONCURRENCY,
getMaxToolUseConcurrency,
} from './toolConcurrency.js'
const ORIGINAL_CONCURRENCY = process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY
afterEach(() => {
if (ORIGINAL_CONCURRENCY === undefined) {
delete process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY
} else {
process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY = ORIGINAL_CONCURRENCY
}
})
test('defaults tool concurrency to a bounded budget', () => {
delete process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY
expect(getMaxToolUseConcurrency()).toBe(DEFAULT_MAX_TOOL_USE_CONCURRENCY)
})
test('allows an explicit positive concurrency override', () => {
process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY = '7'
expect(getMaxToolUseConcurrency()).toBe(7)
})
test('ignores invalid concurrency overrides', () => {
process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY = '0'
expect(getMaxToolUseConcurrency()).toBe(DEFAULT_MAX_TOOL_USE_CONCURRENCY)
process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY = 'not-a-number'
expect(getMaxToolUseConcurrency()).toBe(DEFAULT_MAX_TOOL_USE_CONCURRENCY)
})

View File

@@ -4,12 +4,10 @@ import { findToolByName, type ToolUseContext } from '../../Tool.js'
import type { AssistantMessage, Message } from '../../types/message.js'
import { all } from '../../utils/generators.js'
import { type MessageUpdateLazy, runToolUse } from './toolExecution.js'
function getMaxToolUseConcurrency(): number {
return (
parseInt(process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY || '', 10) || 10
)
}
export {
DEFAULT_MAX_TOOL_USE_CONCURRENCY,
getMaxToolUseConcurrency,
} from './toolConcurrency.js'
export type MessageUpdate = {
message?: Message