Skip to content

Add comprehensive Skills API support#53

Merged
jamesrochabrun merged 4 commits intomainfrom
jorch-skills
Oct 26, 2025
Merged

Add comprehensive Skills API support#53
jamesrochabrun merged 4 commits intomainfrom
jorch-skills

Conversation

@jamesrochabrun
Copy link
Owner

@jamesrochabrun jamesrochabrun commented Oct 25, 2025

Overview

This PR adds full support for Anthropic's Skills API, enabling users to create, manage, and use skills in their SwiftAnthropic applications.

What's New

🎯 Core Features

Container Support

  • Add Container parameter to MessageParameter for specifying skills to load
  • Add Container response field to MessageResponse for reusing containers across conversations
  • Add SkillReference type for referencing both Anthropic-managed and custom skills
  • Support for version pinning (specific versions or "latest")

Skills Management

  • ✅ Create skills with file uploads (multipart/form-data)
  • ✅ List all available skills with filtering (source: custom/anthropic)
  • ✅ Retrieve individual skill details
  • ✅ Delete skills
  • ✅ Full version management (create, list, retrieve, delete)
  • ✅ Pagination support for large skill lists

📦 New API Types

Parameters:

  • SkillCreateParameter - Create new skills with files
  • SkillVersionCreateParameter - Create new skill versions
  • SkillFile - File data with metadata for uploads
  • ListSkillsParameter - Filter and paginate skill lists
  • ListSkillVersionsParameter - Paginate version lists

Responses:

  • SkillResponse - Individual skill metadata
  • ListSkillsResponse - Paginated skill results
  • SkillVersionResponse - Version-specific details
  • ListSkillVersionsResponse - Paginated version results

🔧 Implementation

Service Methods (8 new):

func createSkill(_:) async throws -> SkillResponse
func listSkills(parameter:) async throws -> ListSkillsResponse
func retrieveSkill(skillId:) async throws -> SkillResponse
func deleteSkill(skillId:) async throws

func createSkillVersion(skillId:_:) async throws -> SkillVersionResponse
func listSkillVersions(skillId:parameter:) async throws -> ListSkillVersionsResponse
func retrieveSkillVersion(skillId:version:) async throws -> SkillVersionResponse
func deleteSkillVersion(skillId:version:) async throws

Infrastructure:

  • Multipart/form-data encoding for file uploads
  • New API endpoints: /v1/skills, /v1/skills/{id}, /v1/skills/{id}/versions
  • Full AIProxy compatibility with device check support
  • Platform support: iOS 15+, macOS 12+, Linux

📱 Example Application Updates

New Skills Demo:

  • Interactive SkillsDemoView with UI for testing
  • SkillsDemoObservable with example implementations
  • Demonstrates listing available skills
  • Shows using skills in messages (XLSX spreadsheet example)
  • Demonstrates container reuse across multi-turn conversations
  • Includes streaming support with skills

Updated Files:

  • ApiKeyIntroView - Added Skills beta headers
  • OptionsListView - Added "Skills API" option

Usage Example

// List available skills
let skills = try await service.listSkills(parameter: nil)
print("Found \(skills.data.count) skills")

// Create a message using a skill
let parameter = MessageParameter(
    model: .claude37Sonnet,
    messages: [.init(role: .user, content: .text("Create a budget spreadsheet"))],
    maxTokens: 4096,
    tools: [.hosted(type: "code_execution_20250825", name: "code_execution")],
    container: .init(
        skills: [
            .init(type: .anthropic, skillId: "xlsx", version: "latest")
        ]
    )
)

let response = try await service.createMessage(parameter)

// Reuse container in follow-up
let followUp = MessageParameter(
    model: .claude37Sonnet,
    messages: updatedMessages,
    maxTokens: 4096,
    container: .init(
        id: response.container?.id,  // Reuse for performance
        skills: [.init(type: .anthropic, skillId: "xlsx")]
    )
)

Testing

Automated

  • ✅ Project builds successfully with no errors
  • ✅ All existing tests pass
  • ✅ Type-safe implementation with Swift enums

Manual Testing

Run the example app and:

  1. Select "Default Anthropic Service"
  2. Enter API key with Skills access
  3. Choose "Skills API" from the menu
  4. Test all three demo buttons

Technical Notes

  • Follows existing codebase patterns and conventions
  • Consistent documentation style with triple-slash comments
  • Proper error handling for all operations
  • Snake case conversion handled automatically
  • Full backward compatibility maintained

Files Changed

  • 10 modified files - Core API support
  • 4 new files - Skills parameters, responses, and demos
  • +1,242 lines added

Checklist

  • Code builds without errors
  • Follows existing code style
  • Documentation added
  • Example app updated
  • AIProxy compatibility maintained
  • Linux compatibility maintained

jamesrochabrun and others added 4 commits October 25, 2025 16:46
This PR adds full support for Anthropic's Skills API, enabling users to create, manage, and use skills in their applications.

## Features Added

### Core Skills Support
- Add Container parameter to MessageParameter for specifying skills
- Add Container response to MessageResponse for reusing containers
- Add SkillReference for referencing Anthropic and custom skills
- Support for skill versioning (latest or specific versions)

### Skills Management API
- Create skills with file uploads (multipart/form-data)
- List skills with filtering and pagination
- Retrieve individual skill details
- Delete skills
- Create, list, retrieve, and delete skill versions

### Implementation Details
- Add 8 new service methods to AnthropicService protocol
- Implement all methods in DefaultAnthropicService
- Implement all methods in AIProxyService for proxy compatibility
- Add multipart/form-data support for file uploads
- Add new endpoint paths: /v1/skills, /v1/skills/{id}, /v1/skills/{id}/versions
- Proper error handling for DELETE operations
- Query parameter support for pagination and filtering

### New Types
- SkillCreateParameter: Parameters for creating skills
- SkillVersionCreateParameter: Parameters for creating skill versions
- SkillFile: Represents files to upload
- ListSkillsParameter: Filtering and pagination options
- SkillResponse: Individual skill metadata
- ListSkillsResponse: Paginated skill list
- SkillVersionResponse: Version-specific metadata
- ListSkillVersionsResponse: Paginated version list

### Example Application
- Add SkillsDemoView with interactive UI
- Add SkillsDemoObservable with example implementations
- Demonstrate listing skills
- Demonstrate using skills in messages (XLSX example)
- Demonstrate container reuse across multi-turn conversations
- Demonstrate streaming with skills
- Update ApiKeyIntroView to include Skills beta headers

## Technical Notes
- Follows existing codebase patterns and conventions
- Full AIProxy compatibility
- Type-safe with proper Swift enums and structs
- Comprehensive documentation with API links
- Platform support: iOS 15+, macOS 12+, Linux

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The JSONDecoder already uses .convertFromSnakeCase strategy which automatically
handles snake_case to camelCase conversion. Explicit CodingKeys are redundant
and inconsistent with other response models in the codebase (e.g. TextCompletionResponse).

Changes:
- Remove CodingKeys from SkillResponse
- Remove CodingKeys from ListSkillsResponse
- Remove CodingKeys from SkillVersionResponse
- Remove CodingKeys from ListSkillVersionsResponse

This follows the existing pattern where displayTitle, latestVersion, createdAt,
updatedAt, hasMore, and nextPage are automatically mapped from their JSON
snake_case equivalents.
When using Skills with code execution, the API returns new content types:
- text_editor_code_execution_tool_result
- bash_code_execution_tool_result

These were not handled in MessageResponse.Content enum, causing decoding errors.

Changes:
- Add CodeExecutionToolResult struct to handle these results
- Add codeExecutionToolResult case to Content enum
- Update decoder to handle any *_tool_result types dynamically
- Update encoder to properly encode code execution results

This fixes the dataCorrupted error when decoding Skills API responses.
- Add Skills API to table of contents
- Add detailed Skills API section with:
  - Introduction and beta access instructions
  - Basic usage examples with container management
  - Container reuse pattern for multi-turn conversations
  - Skills management examples (create, list, retrieve, delete)
  - Skill versions management examples
  - Complete parameter and response model documentation
- Update Xcode project to include Skills demo files
- Add code execution tool result handling in MessageFunctionCallingObservable

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@jamesrochabrun jamesrochabrun merged commit 4f9e21b into main Oct 26, 2025
2 checks passed
@jamesrochabrun jamesrochabrun deleted the jorch-skills branch October 26, 2025 05:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant