anthropics / anthropics/claude-agent-sdk-python

Claude Agent SDK import hangs under `tsx watch` + `concurrently` on Windows

未關閉
#1,239 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
invalid question
主要語言
Python
星號
8.1k
分支
1.3k
PR 合併指標
PR 指標待擷取

描述

## Summary

Importing `@anthropic-ai/claude-agent-sdk` can cause a Node.js/TypeScript service to hang indefinitely during module initialization when the service is run with `tsx watch` under `concurrently` on Windows.

The same service starts successfully when run directly with `tsx watch`, and also starts successfully when using `concurrently --raw`.

This appears to be an interaction between:

1. Windows process/stdio handling
2. `tsx watch`
3. `concurrently`'s piped/prefixed stdio
4. `@anthropic-ai/claude-agent-sdk`

## Environment

* OS: Windows
* Runtime: Node.js
* TypeScript runner: `tsx`
* Process runner: `concurrently`
* Claude dependency: `@anthropic-ai/claude-agent-sdk`

## Expected behavior

The service should finish importing its dependencies and reach:

```ts
app.listen(4001)
```

regardless of whether it is launched directly or through `concurrently`.

## Actual behavior

When launched through the normal `concurrently` configuration, the ingest process remains alive but hangs during module loading.

It never reaches `app.listen(4001)`.

As a result, nothing is listening on port `4001`, and another service attempting to call the ingest API receives a connection failure.

The process does not appear to crash or throw an exception. It remains alive with negligible CPU activity.

## Process setup

The development command runs three services:

```text
concurrently
├── web → next dev
├── ingest → tsx watch
└── worker → tsx
```

Only the ingest service uses `tsx watch`.

The relevant dependency chain was:

```text
ingest

@relay/agents

providers/claude.ts

@anthropic-ai/claude-agent-sdk
```

## Reproduction / isolation

The issue was isolated by testing the imports individually.

The hang occurs when importing:

```ts
@anthropic-ai/claude-agent-sdk
```

through the Claude provider.

The sibling Gemini provider using:

```ts
@google/genai
```

does not exhibit the same behavior.

### Test 1: Run ingest directly

```bash
tsx watch packages/ingest/src/server.ts
```

Result:

```text
Works
```

The server successfully reaches `app.listen(4001)`.

### Test 2: Run through concurrently

```bash
concurrently ...
```

with the normal piped/prefixed output.

Result:

```text
Hangs during module initialization
```

The process remains alive but never reaches `app.listen(4001)`.

### Test 3: Run through concurrently with `--raw`

```bash
concurrently --raw ...
```

Result:

```text
Works
```

This suggests that `concurrently`'s normal stdio handling/prefixing is involved in the interaction.

## Why this is significant

The Claude provider was statically imported by the provider registry:

```ts
import { ClaudeProvider } from "./providers/claude";
```

Although the registry constructs providers lazily, the static import causes the Claude provider and its dependency tree to be loaded during application startup.

In this application, ingest only uses the analyst and clarifier roles, both of which default to Gemini. A `ClaudeProvider` is therefore not constructed during ingest startup.

The Claude Agent SDK was nevertheless being loaded on every boot.

## Workaround

The Claude provider was changed from an eager static dependency to a dynamic import inside the execution path:

```ts
const { ClaudeProvider } = await import("./providers/claude");
```

This removes the Claude Agent SDK from the ingest/web startup path.

The resulting behavior is:

```text
Application startup

Registry loads

Gemini provider available

app.listen(4001)

Server ready

Claude requested later

dynamic import()

Claude Agent SDK loaded

ClaudeProvider executes
```

This preserves:

* `concurrently`
* prefixed `[web]`, `[ingest]`, `[worker]` logs
* `tsx watch`
* ingest hot reload

without loading the Claude SDK during startup.

## Questions

1. Is `@anthropic-ai/claude-agent-sdk` expected to perform any process/stdio initialization during module import?
2. Could the SDK's initialization interact with piped stdout/stderr or non-TTY streams?
3. Is this combination of Windows + `tsx watch` + `concurrently` known to cause an import hang?
4. If the SDK requires specific stdin/stdout behavior, could the import avoid performing that initialization until the SDK is actually instantiated/used?
5. Is there any recommended configuration for running the SDK under `concurrently` and `tsx watch` on Windows?

貢獻指南

這個儲存庫沒有索引到貢獻指南

評估

這個 Issue 還沒有評估資料。

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。