mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
Merge branch 'codex/investigate-desktop-first-token-latency'
This commit is contained in:
commit
c69c07fcfe
@ -39,7 +39,7 @@ type SettingsStore = {
|
||||
export const useSettingsStore = create<SettingsStore>((set, get) => ({
|
||||
permissionMode: 'default',
|
||||
currentModel: null,
|
||||
effortLevel: 'high',
|
||||
effortLevel: 'medium',
|
||||
availableModels: [],
|
||||
activeProviderName: null,
|
||||
locale: getStoredLocale(),
|
||||
|
||||
22
src/main.tsx
22
src/main.tsx
@ -2723,16 +2723,30 @@ async function run(): Promise<CommanderCommand> {
|
||||
}));
|
||||
}, configs).catch(err => logForDebugging(`[MCP] ${label} connect error: ${err}`));
|
||||
};
|
||||
// Await all MCP configs — print mode is often single-turn, so
|
||||
// "late-connecting servers visible next turn" doesn't help. SDK init
|
||||
// message and turn-1 tool list both need configured MCP tools present.
|
||||
// Await all MCP configs for regular print-mode sessions — they're
|
||||
// often single-turn, so "late-connecting servers visible next turn"
|
||||
// doesn't help. SDK init message and turn-1 tool list should include
|
||||
// configured MCP tools when running plain `claude -p`.
|
||||
//
|
||||
// Desktop/bridge sessions (`--sdk-url`) are different: the user is
|
||||
// waiting on the first visible assistant token, not a fully populated
|
||||
// MCP inventory. Blocking startup on slow or failing MCP servers (for
|
||||
// example a local `chatlog` HTTP endpoint timing out) makes the whole
|
||||
// chat feel frozen before the first word appears. In that mode we still
|
||||
// kick off the connections immediately, but let them settle in the
|
||||
// background so headlessStore picks them up after the session starts.
|
||||
//
|
||||
// Zero-server case is free via the early return in connectMcpBatch.
|
||||
// Connectors parallelize inside getMcpToolsCommandsAndResources
|
||||
// (processBatched with Promise.all). claude.ai is awaited too — its
|
||||
// fetch was kicked off early (line ~2558) so only residual time blocks
|
||||
// here. --bare skips claude.ai entirely for perf-sensitive scripts.
|
||||
profileCheckpoint('before_connectMcp');
|
||||
await connectMcpBatch(regularMcpConfigs, 'regular');
|
||||
if (sdkUrl) {
|
||||
void connectMcpBatch(regularMcpConfigs, 'regular');
|
||||
} else {
|
||||
await connectMcpBatch(regularMcpConfigs, 'regular');
|
||||
}
|
||||
profileCheckpoint('after_connectMcp');
|
||||
// Dedup: suppress plugin MCP servers that duplicate a claude.ai
|
||||
// connector (connector wins), then connect claude.ai servers.
|
||||
|
||||
@ -170,4 +170,18 @@ describe('ConversationService', () => {
|
||||
expect(args[0]).toContain(path.join('bin', 'claude-haha'))
|
||||
}
|
||||
})
|
||||
|
||||
test('buildSessionCliArgs enables partial assistant messages for desktop streaming', () => {
|
||||
const service = new ConversationService() as any
|
||||
const args = service.buildSessionCliArgs(
|
||||
'123e4567-e89b-12d3-a456-426614174000',
|
||||
'ws://127.0.0.1:3456/sdk/test-session?token=test-token',
|
||||
false,
|
||||
{ permissionMode: 'bypassPermissions' },
|
||||
) as string[]
|
||||
|
||||
expect(args).toContain('--include-partial-messages')
|
||||
expect(args).toContain('--sdk-url')
|
||||
expect(args).toContain('--replay-user-messages')
|
||||
})
|
||||
})
|
||||
|
||||
@ -38,7 +38,7 @@ const DEFAULT_MODELS = [
|
||||
const EFFORT_LEVELS = ['low', 'medium', 'high', 'max'] as const
|
||||
|
||||
const DEFAULT_MODEL = 'claude-opus-4-7'
|
||||
const DEFAULT_EFFORT = 'max'
|
||||
const DEFAULT_EFFORT = 'medium'
|
||||
|
||||
const settingsService = new SettingsService()
|
||||
const providerService = new ProviderService()
|
||||
|
||||
@ -64,6 +64,33 @@ export class ConversationStartupError extends Error {
|
||||
export class ConversationService {
|
||||
private sessions = new Map<string, SessionProcess>()
|
||||
|
||||
private buildSessionCliArgs(
|
||||
sessionId: string,
|
||||
sdkUrl: string,
|
||||
shouldResume: boolean,
|
||||
options?: SessionStartOptions,
|
||||
): string[] {
|
||||
const dangerousMode = process.env.CLAUDE_DANGEROUS_MODE === '1'
|
||||
return this.resolveCliArgs([
|
||||
'--print',
|
||||
'--verbose',
|
||||
'--sdk-url',
|
||||
sdkUrl,
|
||||
'--enable-auth-status',
|
||||
'--input-format',
|
||||
'stream-json',
|
||||
'--output-format',
|
||||
'stream-json',
|
||||
// Desktop chat depends on partial assistant deltas; without this the
|
||||
// server only sees the completed assistant message at turn end.
|
||||
'--include-partial-messages',
|
||||
...(shouldResume ? ['--resume', sessionId] : ['--session-id', sessionId]),
|
||||
'--replay-user-messages',
|
||||
...this.getRuntimeArgs(options),
|
||||
...this.getPermissionArgs(options?.permissionMode, dangerousMode),
|
||||
])
|
||||
}
|
||||
|
||||
async startSession(
|
||||
sessionId: string,
|
||||
workDir: string,
|
||||
@ -88,22 +115,12 @@ export class ConversationService {
|
||||
)
|
||||
}
|
||||
|
||||
const dangerousMode = process.env.CLAUDE_DANGEROUS_MODE === '1'
|
||||
const args = this.resolveCliArgs([
|
||||
'--print',
|
||||
'--verbose',
|
||||
'--sdk-url',
|
||||
const args = this.buildSessionCliArgs(
|
||||
sessionId,
|
||||
sdkUrl,
|
||||
'--enable-auth-status',
|
||||
'--input-format',
|
||||
'stream-json',
|
||||
'--output-format',
|
||||
'stream-json',
|
||||
...(shouldResume ? ['--resume', sessionId] : ['--session-id', sessionId]),
|
||||
'--replay-user-messages',
|
||||
...this.getRuntimeArgs(options),
|
||||
...this.getPermissionArgs(options?.permissionMode, dangerousMode),
|
||||
])
|
||||
shouldResume,
|
||||
options,
|
||||
)
|
||||
|
||||
console.log(
|
||||
`[ConversationService] Starting CLI for ${sessionId}, cwd: ${workDir} (process.cwd()=${process.cwd()}, CALLER_DIR will be pinned to workDir)`,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user