diff --git a/.claude/agents/test-agent.md b/.claude/agents/test-agent.md deleted file mode 100644 index 6515827..0000000 --- a/.claude/agents/test-agent.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: test-agent -description: A simple test agent for SDK testing -tools: Read ---- - -# Test Agent - -You are a simple test agent. When asked a question, provide a brief, helpful answer. diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index d013f1b..0000000 --- a/.dockerignore +++ /dev/null @@ -1,49 +0,0 @@ -# Git -.git -.gitignore - -# Python -__pycache__ -*.py[cod] -*$py.class -*.so -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg - -# Virtual environments -.env -.venv -env/ -venv/ -ENV/ - -# IDE -.idea/ -.vscode/ -*.swp -*.swo - -# Testing/Coverage -.coverage -.pytest_cache/ -htmlcov/ -.tox/ -.nox/ - -# Misc -*.log -.DS_Store diff --git a/.github/workflows/create-release-tag.yml b/.github/workflows/create-release-tag.yml index c50abab..8d6b8e1 100644 --- a/.github/workflows/create-release-tag.yml +++ b/.github/workflows/create-release-tag.yml @@ -24,6 +24,12 @@ jobs: VERSION="${BRANCH_NAME#release/v}" echo "version=$VERSION" >> $GITHUB_OUTPUT + - name: Get previous release tag + id: previous_tag + run: | + PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD~1 2>/dev/null || echo "") + echo "previous_tag=$PREVIOUS_TAG" >> $GITHUB_OUTPUT + - name: Create and push tag run: | git config --local user.email "github-actions[bot]@users.noreply.github.com" @@ -40,34 +46,14 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - VERSION="${{ steps.extract_version.outputs.version }}" + # Create release with auto-generated notes + gh release create "v${{ steps.extract_version.outputs.version }}" \ + --title "Release v${{ steps.extract_version.outputs.version }}" \ + --generate-notes \ + --notes-start-tag "${{ steps.previous_tag.outputs.previous_tag }}" \ + --notes "Published to PyPI: https://pypi.org/project/claude-agent-sdk/${{ steps.extract_version.outputs.version }}/ - # Extract changelog section for this version to a temp file - awk -v ver="$VERSION" ' - /^## / { - if (found) exit - if ($2 == ver) found=1 - next - } - found { print } - ' CHANGELOG.md > release_notes.md - - # Append install instructions - { - echo "" - echo "---" - echo "" - echo "**PyPI:** https://pypi.org/project/claude-agent-sdk/VERSION/" - echo "" - echo '```bash' - echo "pip install claude-agent-sdk==VERSION" - echo '```' - } >> release_notes.md - - # Replace VERSION placeholder - sed -i "s/VERSION/$VERSION/g" release_notes.md - - # Create release with notes from file - gh release create "v$VERSION" \ - --title "v$VERSION" \ - --notes-file release_notes.md + ### Installation + \`\`\`bash + pip install claude-agent-sdk==${{ steps.extract_version.outputs.version }} + \`\`\`" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d581a8f..d78d425 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -81,24 +81,6 @@ jobs: run: | python -m pytest e2e-tests/ -v -m e2e - test-e2e-docker: - runs-on: ubuntu-latest - needs: test # Run after unit tests pass - # Run e2e tests in Docker to catch container-specific issues like #406 - - steps: - - uses: actions/checkout@v4 - - - name: Build Docker test image - run: docker build -f Dockerfile.test -t claude-sdk-test . - - - name: Run e2e tests in Docker - env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - run: | - docker run --rm -e ANTHROPIC_API_KEY \ - claude-sdk-test python -m pytest e2e-tests/ -v -m e2e - test-examples: runs-on: ubuntu-latest needs: test-e2e # Run after e2e tests diff --git a/CHANGELOG.md b/CHANGELOG.md index bfade18..32775ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,42 +1,5 @@ # Changelog -## 0.1.18 - -### Internal/Other Changes - -- **Docker-based test infrastructure**: Added Docker support for running e2e tests in containerized environments, helping catch Docker-specific issues (#424) -- Updated bundled Claude CLI to version 2.0.72 - -## 0.1.17 - -### New Features - -- **UserMessage UUID field**: Added `uuid` field to `UserMessage` response type, making it easier to use the `rewind_files()` method by providing direct access to message identifiers needed for file checkpointing (#418) - -### Internal/Other Changes - -- Updated bundled Claude CLI to version 2.0.70 - -## 0.1.16 - -### Bug Fixes - -- **Rate limit detection**: Fixed parsing of the `error` field in `AssistantMessage`, enabling applications to detect and handle API errors like rate limits. Previously, the `error` field was defined but never populated from CLI responses (#405) - -### Internal/Other Changes - -- Updated bundled Claude CLI to version 2.0.68 - -## 0.1.15 - -### New Features - -- **File checkpointing and rewind**: Added `enable_file_checkpointing` option to `ClaudeAgentOptions` and `rewind_files(user_message_id)` method to `ClaudeSDKClient` and `Query`. This enables reverting file changes made during a session back to a specific checkpoint, useful for exploring different approaches or recovering from unwanted modifications (#395) - -### Documentation - -- Added license and terms section to README (#399) - ## 0.1.14 ### Internal/Other Changes diff --git a/Dockerfile.test b/Dockerfile.test deleted file mode 100644 index 22adf2e..0000000 --- a/Dockerfile.test +++ /dev/null @@ -1,29 +0,0 @@ -# Dockerfile for running SDK tests in a containerized environment -# This helps catch Docker-specific issues like #406 - -FROM python:3.12-slim - -# Install dependencies for Claude CLI and git (needed for some tests) -RUN apt-get update && apt-get install -y \ - curl \ - git \ - && rm -rf /var/lib/apt/lists/* - -# Install Claude Code CLI -RUN curl -fsSL https://claude.ai/install.sh | bash -ENV PATH="/root/.local/bin:$PATH" - -# Set up working directory -WORKDIR /app - -# Copy the SDK source -COPY . . - -# Install SDK with dev dependencies -RUN pip install -e ".[dev]" - -# Verify CLI installation -RUN claude -v - -# Default: run unit tests -CMD ["python", "-m", "pytest", "tests/", "-v"] diff --git a/README.md b/README.md index bcbe969..2111986 100644 --- a/README.md +++ b/README.md @@ -351,6 +351,6 @@ The package is published to PyPI via the GitHub Actions workflow in `.github/wor The workflow tracks both the package version and the bundled CLI version separately, allowing you to release a new package version with an updated CLI without code changes. -## License and terms +## License -Use of this SDK is governed by Anthropic's [Commercial Terms of Service](https://www.anthropic.com/legal/commercial-terms), including when you use it to power products and services that you make available to your own customers and end users, except to the extent a specific component or dependency is covered by a different license as indicated in that component's LICENSE file. +MIT diff --git a/e2e-tests/test_agents_and_settings.py b/e2e-tests/test_agents_and_settings.py index 3f6fc80..6e04066 100644 --- a/e2e-tests/test_agents_and_settings.py +++ b/e2e-tests/test_agents_and_settings.py @@ -38,88 +38,15 @@ async def test_agent_definition(): async for message in client.receive_response(): if isinstance(message, SystemMessage) and message.subtype == "init": agents = message.data.get("agents", []) - assert isinstance(agents, list), ( - f"agents should be a list of strings, got: {type(agents)}" - ) - assert "test-agent" in agents, ( - f"test-agent should be available, got: {agents}" - ) + assert isinstance( + agents, list + ), f"agents should be a list of strings, got: {type(agents)}" + assert ( + "test-agent" in agents + ), f"test-agent should be available, got: {agents}" break -@pytest.mark.e2e -@pytest.mark.asyncio -async def test_filesystem_agent_loading(): - """Test that filesystem-based agents load via setting_sources and produce full response. - - This is the core test for issue #406. It verifies that when using - setting_sources=["project"] with a .claude/agents/ directory containing - agent definitions, the SDK: - 1. Loads the agents (they appear in init message) - 2. Produces a full response with AssistantMessage - 3. Completes with a ResultMessage - - The bug in #406 causes the iterator to complete after only the - init SystemMessage, never yielding AssistantMessage or ResultMessage. - """ - with tempfile.TemporaryDirectory() as tmpdir: - # Create a temporary project with a filesystem agent - project_dir = Path(tmpdir) - agents_dir = project_dir / ".claude" / "agents" - agents_dir.mkdir(parents=True) - - # Create a test agent file - agent_file = agents_dir / "fs-test-agent.md" - agent_file.write_text( - """--- -name: fs-test-agent -description: A filesystem test agent for SDK testing -tools: Read ---- - -# Filesystem Test Agent - -You are a simple test agent. When asked a question, provide a brief, helpful answer. -""" - ) - - options = ClaudeAgentOptions( - setting_sources=["project"], - cwd=project_dir, - max_turns=1, - ) - - messages = [] - async with ClaudeSDKClient(options=options) as client: - await client.query("Say hello in exactly 3 words") - async for msg in client.receive_response(): - messages.append(msg) - - # Must have at least init, assistant, result - message_types = [type(m).__name__ for m in messages] - - assert "SystemMessage" in message_types, "Missing SystemMessage (init)" - assert "AssistantMessage" in message_types, ( - f"Missing AssistantMessage - got only: {message_types}. " - "This may indicate issue #406 (silent failure with filesystem agents)." - ) - assert "ResultMessage" in message_types, "Missing ResultMessage" - - # Find the init message and check for the filesystem agent - for msg in messages: - if isinstance(msg, SystemMessage) and msg.subtype == "init": - agents = msg.data.get("agents", []) - # Agents are returned as strings (just names) - assert "fs-test-agent" in agents, ( - f"fs-test-agent not loaded from filesystem. Found: {agents}" - ) - break - - # On Windows, wait for file handles to be released before cleanup - if sys.platform == "win32": - await asyncio.sleep(0.5) - - @pytest.mark.e2e @pytest.mark.asyncio async def test_setting_sources_default(): @@ -147,12 +74,12 @@ async def test_setting_sources_default(): async for message in client.receive_response(): if isinstance(message, SystemMessage) and message.subtype == "init": output_style = message.data.get("output_style") - assert output_style != "local-test-style", ( - f"outputStyle should NOT be from local settings (default is no settings), got: {output_style}" - ) - assert output_style == "default", ( - f"outputStyle should be 'default', got: {output_style}" - ) + assert ( + output_style != "local-test-style" + ), f"outputStyle should NOT be from local settings (default is no settings), got: {output_style}" + assert ( + output_style == "default" + ), f"outputStyle should be 'default', got: {output_style}" break # On Windows, wait for file handles to be released before cleanup @@ -194,9 +121,9 @@ This is a test command. async for message in client.receive_response(): if isinstance(message, SystemMessage) and message.subtype == "init": commands = message.data.get("slash_commands", []) - assert "testcmd" not in commands, ( - f"testcmd should NOT be available with user-only sources, got: {commands}" - ) + assert ( + "testcmd" not in commands + ), f"testcmd should NOT be available with user-only sources, got: {commands}" break # On Windows, wait for file handles to be released before cleanup @@ -232,11 +159,11 @@ async def test_setting_sources_project_included(): async for message in client.receive_response(): if isinstance(message, SystemMessage) and message.subtype == "init": output_style = message.data.get("output_style") - assert output_style == "local-test-style", ( - f"outputStyle should be from local settings, got: {output_style}" - ) + assert ( + output_style == "local-test-style" + ), f"outputStyle should be from local settings, got: {output_style}" break # On Windows, wait for file handles to be released before cleanup if sys.platform == "win32": - await asyncio.sleep(0.5) + await asyncio.sleep(0.5) \ No newline at end of file diff --git a/examples/filesystem_agents.py b/examples/filesystem_agents.py deleted file mode 100644 index e5f6904..0000000 --- a/examples/filesystem_agents.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python3 -"""Example of loading filesystem-based agents via setting_sources. - -This example demonstrates how to load agents defined in .claude/agents/ files -using the setting_sources option. This is different from inline AgentDefinition -objects - these agents are loaded from markdown files on disk. - -This example tests the scenario from issue #406 where filesystem-based agents -loaded via setting_sources=["project"] may silently fail in certain environments. - -Usage: -./examples/filesystem_agents.py -""" - -import asyncio -from pathlib import Path - -from claude_agent_sdk import ( - AssistantMessage, - ClaudeAgentOptions, - ClaudeSDKClient, - ResultMessage, - SystemMessage, - TextBlock, -) - - -def extract_agents(msg: SystemMessage) -> list[str]: - """Extract agent names from system message init data.""" - if msg.subtype == "init": - agents = msg.data.get("agents", []) - # Agents can be either strings or dicts with a 'name' field - result = [] - for a in agents: - if isinstance(a, str): - result.append(a) - elif isinstance(a, dict): - result.append(a.get("name", "")) - return result - return [] - - -async def main(): - """Test loading filesystem-based agents.""" - print("=== Filesystem Agents Example ===") - print("Testing: setting_sources=['project'] with .claude/agents/test-agent.md") - print() - - # Use the SDK repo directory which has .claude/agents/test-agent.md - sdk_dir = Path(__file__).parent.parent - - options = ClaudeAgentOptions( - setting_sources=["project"], - cwd=sdk_dir, - ) - - message_types: list[str] = [] - agents_found: list[str] = [] - - async with ClaudeSDKClient(options=options) as client: - await client.query("Say hello in exactly 3 words") - - async for msg in client.receive_response(): - message_types.append(type(msg).__name__) - - if isinstance(msg, SystemMessage) and msg.subtype == "init": - agents_found = extract_agents(msg) - print(f"Init message received. Agents loaded: {agents_found}") - - elif isinstance(msg, AssistantMessage): - for block in msg.content: - if isinstance(block, TextBlock): - print(f"Assistant: {block.text}") - - elif isinstance(msg, ResultMessage): - print( - f"Result: subtype={msg.subtype}, cost=${msg.total_cost_usd or 0:.4f}" - ) - - print() - print("=== Summary ===") - print(f"Message types received: {message_types}") - print(f"Total messages: {len(message_types)}") - - # Validate the results - has_init = "SystemMessage" in message_types - has_assistant = "AssistantMessage" in message_types - has_result = "ResultMessage" in message_types - has_test_agent = "test-agent" in agents_found - - print() - if has_init and has_assistant and has_result: - print("SUCCESS: Received full response (init, assistant, result)") - else: - print("FAILURE: Did not receive full response") - print(f" - Init: {has_init}") - print(f" - Assistant: {has_assistant}") - print(f" - Result: {has_result}") - - if has_test_agent: - print("SUCCESS: test-agent was loaded from filesystem") - else: - print("WARNING: test-agent was NOT loaded (may not exist in .claude/agents/)") - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/pyproject.toml b/pyproject.toml index 9058f3e..5e39d17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "claude-agent-sdk" -version = "0.1.18" +version = "0.1.14" description = "Python SDK for Claude Code" readme = "README.md" requires-python = ">=3.10" diff --git a/scripts/test-docker.sh b/scripts/test-docker.sh deleted file mode 100755 index 2cf9889..0000000 --- a/scripts/test-docker.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash -# Run SDK tests in a Docker container -# This helps catch Docker-specific issues like #406 -# -# Usage: -# ./scripts/test-docker.sh [unit|e2e|all] -# -# Examples: -# ./scripts/test-docker.sh unit # Run unit tests only -# ANTHROPIC_API_KEY=sk-... ./scripts/test-docker.sh e2e # Run e2e tests -# ANTHROPIC_API_KEY=sk-... ./scripts/test-docker.sh all # Run all tests - -set -e - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_DIR="$(dirname "$SCRIPT_DIR")" - -cd "$PROJECT_DIR" - -usage() { - echo "Usage: $0 [unit|e2e|all]" - echo "" - echo "Commands:" - echo " unit - Run unit tests only (no API key needed)" - echo " e2e - Run e2e tests (requires ANTHROPIC_API_KEY)" - echo " all - Run both unit and e2e tests" - echo "" - echo "Examples:" - echo " $0 unit" - echo " ANTHROPIC_API_KEY=sk-... $0 e2e" - exit 1 -} - -echo "Building Docker test image..." -docker build -f Dockerfile.test -t claude-sdk-test . - -case "${1:-unit}" in - unit) - echo "" - echo "Running unit tests in Docker..." - docker run --rm claude-sdk-test \ - python -m pytest tests/ -v - ;; - e2e) - if [ -z "$ANTHROPIC_API_KEY" ]; then - echo "Error: ANTHROPIC_API_KEY environment variable is required for e2e tests" - echo "" - echo "Usage: ANTHROPIC_API_KEY=sk-... $0 e2e" - exit 1 - fi - echo "" - echo "Running e2e tests in Docker..." - docker run --rm -e ANTHROPIC_API_KEY \ - claude-sdk-test python -m pytest e2e-tests/ -v -m e2e - ;; - all) - echo "" - echo "Running unit tests in Docker..." - docker run --rm claude-sdk-test \ - python -m pytest tests/ -v - - echo "" - if [ -n "$ANTHROPIC_API_KEY" ]; then - echo "Running e2e tests in Docker..." - docker run --rm -e ANTHROPIC_API_KEY \ - claude-sdk-test python -m pytest e2e-tests/ -v -m e2e - else - echo "Skipping e2e tests (ANTHROPIC_API_KEY not set)" - fi - ;; - *) - usage - ;; -esac - -echo "" -echo "Done!" diff --git a/src/claude_agent_sdk/_cli_version.py b/src/claude_agent_sdk/_cli_version.py index 8e7a72d..4f74ef2 100644 --- a/src/claude_agent_sdk/_cli_version.py +++ b/src/claude_agent_sdk/_cli_version.py @@ -1,3 +1,3 @@ """Bundled Claude Code CLI version.""" -__cli_version__ = "2.0.74" +__cli_version__ = "2.0.62" diff --git a/src/claude_agent_sdk/_internal/message_parser.py b/src/claude_agent_sdk/_internal/message_parser.py index 4bfe814..694c52c 100644 --- a/src/claude_agent_sdk/_internal/message_parser.py +++ b/src/claude_agent_sdk/_internal/message_parser.py @@ -48,7 +48,6 @@ def parse_message(data: dict[str, Any]) -> Message: case "user": try: parent_tool_use_id = data.get("parent_tool_use_id") - uuid = data.get("uuid") if isinstance(data["message"]["content"], list): user_content_blocks: list[ContentBlock] = [] for block in data["message"]["content"]: @@ -75,12 +74,10 @@ def parse_message(data: dict[str, Any]) -> Message: ) return UserMessage( content=user_content_blocks, - uuid=uuid, parent_tool_use_id=parent_tool_use_id, ) return UserMessage( content=data["message"]["content"], - uuid=uuid, parent_tool_use_id=parent_tool_use_id, ) except KeyError as e: @@ -123,7 +120,6 @@ def parse_message(data: dict[str, Any]) -> Message: content=content_blocks, model=data["message"]["model"], parent_tool_use_id=data.get("parent_tool_use_id"), - error=data["message"].get("error"), ) except KeyError as e: raise MessageParseError( diff --git a/src/claude_agent_sdk/_internal/query.py b/src/claude_agent_sdk/_internal/query.py index c30fc15..8f0ac19 100644 --- a/src/claude_agent_sdk/_internal/query.py +++ b/src/claude_agent_sdk/_internal/query.py @@ -539,21 +539,6 @@ class Query: } ) - async def rewind_files(self, user_message_id: str) -> None: - """Rewind tracked files to their state at a specific user message. - - Requires file checkpointing to be enabled via the `enable_file_checkpointing` option. - - Args: - user_message_id: UUID of the user message to rewind to - """ - await self._send_control_request( - { - "subtype": "rewind_files", - "user_message_id": user_message_id, - } - ) - async def stream_input(self, stream: AsyncIterable[dict[str, Any]]) -> None: """Stream input messages to transport. diff --git a/src/claude_agent_sdk/_internal/transport/subprocess_cli.py b/src/claude_agent_sdk/_internal/transport/subprocess_cli.py index a4882db..c7c7420 100644 --- a/src/claude_agent_sdk/_internal/transport/subprocess_cli.py +++ b/src/claude_agent_sdk/_internal/transport/subprocess_cli.py @@ -384,10 +384,6 @@ class SubprocessCLITransport(Transport): "CLAUDE_AGENT_SDK_VERSION": __version__, } - # Enable file checkpointing if requested - if self._options.enable_file_checkpointing: - process_env["CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING"] = "true" - if self._cwd: process_env["PWD"] = self._cwd diff --git a/src/claude_agent_sdk/_version.py b/src/claude_agent_sdk/_version.py index de9a16c..b02a634 100644 --- a/src/claude_agent_sdk/_version.py +++ b/src/claude_agent_sdk/_version.py @@ -1,3 +1,3 @@ """Version information for claude-agent-sdk.""" -__version__ = "0.1.18" +__version__ = "0.1.14" diff --git a/src/claude_agent_sdk/client.py b/src/claude_agent_sdk/client.py index 18ab818..742d7d6 100644 --- a/src/claude_agent_sdk/client.py +++ b/src/claude_agent_sdk/client.py @@ -261,38 +261,6 @@ class ClaudeSDKClient: raise CLIConnectionError("Not connected. Call connect() first.") await self._query.set_model(model) - async def rewind_files(self, user_message_id: str) -> None: - """Rewind tracked files to their state at a specific user message. - - Requires: - - `enable_file_checkpointing=True` to track file changes - - `extra_args={"replay-user-messages": None}` to receive UserMessage - objects with `uuid` in the response stream - - Args: - user_message_id: UUID of the user message to rewind to. This should be - the `uuid` field from a `UserMessage` received during the conversation. - - Example: - ```python - options = ClaudeAgentOptions( - enable_file_checkpointing=True, - extra_args={"replay-user-messages": None}, - ) - async with ClaudeSDKClient(options) as client: - await client.query("Make some changes to my files") - async for msg in client.receive_response(): - if isinstance(msg, UserMessage) and msg.uuid: - checkpoint_id = msg.uuid # Save this for later - - # Later, rewind to that point - await client.rewind_files(checkpoint_id) - ``` - """ - if not self._query: - raise CLIConnectionError("Not connected. Call connect() first.") - await self._query.rewind_files(user_message_id) - async def get_server_info(self) -> dict[str, Any] | None: """Get server initialization info including available commands and output styles. diff --git a/src/claude_agent_sdk/types.py b/src/claude_agent_sdk/types.py index 9c09345..fa6ca35 100644 --- a/src/claude_agent_sdk/types.py +++ b/src/claude_agent_sdk/types.py @@ -562,7 +562,6 @@ class UserMessage: """User message.""" content: str | list[ContentBlock] - uuid: str | None = None parent_tool_use_id: str | None = None @@ -674,10 +673,6 @@ class ClaudeAgentOptions: # Output format for structured outputs (matches Messages API structure) # Example: {"type": "json_schema", "schema": {"type": "object", "properties": {...}}} output_format: dict[str, Any] | None = None - # Enable file checkpointing to track file changes during the session. - # When enabled, files can be rewound to their state at any user message - # using `ClaudeSDKClient.rewind_files()`. - enable_file_checkpointing: bool = False # SDK Control Protocol @@ -718,11 +713,6 @@ class SDKControlMcpMessageRequest(TypedDict): message: Any -class SDKControlRewindFilesRequest(TypedDict): - subtype: Literal["rewind_files"] - user_message_id: str - - class SDKControlRequest(TypedDict): type: Literal["control_request"] request_id: str @@ -733,7 +723,6 @@ class SDKControlRequest(TypedDict): | SDKControlSetPermissionModeRequest | SDKHookCallbackRequest | SDKControlMcpMessageRequest - | SDKControlRewindFilesRequest ) diff --git a/tests/test_message_parser.py b/tests/test_message_parser.py index cd18952..60bcc53 100644 --- a/tests/test_message_parser.py +++ b/tests/test_message_parser.py @@ -31,21 +31,6 @@ class TestMessageParser: assert isinstance(message.content[0], TextBlock) assert message.content[0].text == "Hello" - def test_parse_user_message_with_uuid(self): - """Test parsing a user message with uuid field (issue #414). - - The uuid field is needed for file checkpointing with rewind_files(). - """ - data = { - "type": "user", - "uuid": "msg-abc123-def456", - "message": {"content": [{"type": "text", "text": "Hello"}]}, - } - message = parse_message(data) - assert isinstance(message, UserMessage) - assert message.uuid == "msg-abc123-def456" - assert len(message.content) == 1 - def test_parse_user_message_with_tool_use(self): """Test parsing a user message with tool_use block.""" data = {