Repository: MarcoDotIO/OpenAIKit Branch: main Commit: 0aed4b9a087e Files: 250 Total size: 665.2 KB Directory structure: gitextract_yuqwznni/ ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ └── feature_request.yml │ ├── pull_request_template.md │ └── workflows/ │ └── swift.yml ├── .gitignore ├── .swiftpm/ │ └── xcode/ │ └── package.xcworkspace/ │ └── contents.xcworkspacedata ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Examples/ │ ├── iOS_Example/ │ │ ├── iOS_Example/ │ │ │ ├── Assets.xcassets/ │ │ │ │ ├── AccentColor.colorset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── Audio/ │ │ │ │ ├── AudioPlayerViewModel.swift │ │ │ │ └── CreateTranscription.swift │ │ │ ├── Chat/ │ │ │ │ ├── ChatMainView.swift │ │ │ │ ├── CreateChatCompletion.swift │ │ │ │ ├── CreateChatCompletionStreaming.swift │ │ │ │ └── CreateChatFunctionCallExample.swift │ │ │ ├── Completion/ │ │ │ │ ├── CompletionMainView.swift │ │ │ │ └── GenerateCompletionExample.swift │ │ │ ├── Content Policy/ │ │ │ │ └── ContentPolicyExample.swift │ │ │ ├── ContentView.swift │ │ │ ├── Embeddings/ │ │ │ │ └── CreateEmbeddingsExample.swift │ │ │ ├── File/ │ │ │ │ ├── DeleteFileExample.swift │ │ │ │ ├── File/ │ │ │ │ │ └── SampleData.jsonl │ │ │ │ ├── FileDetailsView.swift │ │ │ │ ├── FileMainView.swift │ │ │ │ ├── ListFilesExample.swift │ │ │ │ ├── RetrieveFileContentsExample.swift │ │ │ │ ├── RetrieveFileExample.swift │ │ │ │ └── UploadFileExample.swift │ │ │ ├── Image/ │ │ │ │ ├── EditImageExample.swift │ │ │ │ ├── GenerateImageExample.swift │ │ │ │ ├── GenerateImageVariationsExample.swift │ │ │ │ └── ImageMainView.swift │ │ │ ├── Model/ │ │ │ │ ├── ListModelsExample.swift │ │ │ │ ├── ModelMainView.swift │ │ │ │ └── RetrieveModelExample.swift │ │ │ ├── Preview Content/ │ │ │ │ └── Preview Assets.xcassets/ │ │ │ │ └── Contents.json │ │ │ └── iOS_ExampleApp.swift │ │ └── iOS_Example.xcodeproj/ │ │ ├── project.pbxproj │ │ └── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── macOS_Example/ │ │ ├── macOS_Example/ │ │ │ ├── Assets.xcassets/ │ │ │ │ ├── AccentColor.colorset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── ContentView.swift │ │ │ ├── Preview Content/ │ │ │ │ └── Preview Assets.xcassets/ │ │ │ │ └── Contents.json │ │ │ ├── macOS_Example.entitlements │ │ │ └── macOS_ExampleApp.swift │ │ └── macOS_Example.xcodeproj/ │ │ ├── project.pbxproj │ │ └── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ ├── tvOS_Example/ │ │ ├── tvOS_Example/ │ │ │ ├── Assets.xcassets/ │ │ │ │ ├── AccentColor.colorset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── App Icon & Top Shelf Image.brandassets/ │ │ │ │ │ ├── App Icon - App Store.imagestack/ │ │ │ │ │ │ ├── Back.imagestacklayer/ │ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ ├── Contents.json │ │ │ │ │ │ ├── Front.imagestacklayer/ │ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ └── Middle.imagestacklayer/ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ └── Contents.json │ │ │ │ │ ├── App Icon.imagestack/ │ │ │ │ │ │ ├── Back.imagestacklayer/ │ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ ├── Contents.json │ │ │ │ │ │ ├── Front.imagestacklayer/ │ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ └── Middle.imagestacklayer/ │ │ │ │ │ │ ├── Content.imageset/ │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ └── Contents.json │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── Top Shelf Image Wide.imageset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── Top Shelf Image.imageset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── Contents.json │ │ │ ├── ContentView.swift │ │ │ ├── Preview Content/ │ │ │ │ └── Preview Assets.xcassets/ │ │ │ │ └── Contents.json │ │ │ └── tvOS_ExampleApp.swift │ │ └── tvOS_Example.xcodeproj/ │ │ ├── project.pbxproj │ │ └── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── IDEWorkspaceChecks.plist │ └── watchOS_Example/ │ ├── watchOS_Example Watch App/ │ │ ├── Assets.xcassets/ │ │ │ ├── AccentColor.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── ContentView.swift │ │ ├── Preview Content/ │ │ │ └── Preview Assets.xcassets/ │ │ │ └── Contents.json │ │ └── watchOS_ExampleApp.swift │ └── watchOS_Example.xcodeproj/ │ ├── project.pbxproj │ └── project.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── LICENSE ├── Package.swift ├── Package@swift-5.5.swift ├── Package@swift-5.6.swift ├── Package@swift-5.7.swift ├── Package@swift-5.8.swift ├── README.md ├── SECURITY.md ├── Sources/ │ └── OpenAIKit/ │ ├── Client/ │ │ ├── AudioSpeechResource+API.swift │ │ ├── BatchesResource+API.swift │ │ ├── BetaResources+API.swift │ │ ├── ContainersResource+API.swift │ │ ├── ConversationsResource+API.swift │ │ ├── EvalsResource+API.swift │ │ ├── FineTuningResource+API.swift │ │ ├── RealtimeResource+API.swift │ │ ├── ResourceNamespaces.swift │ │ ├── ResponsesResource+API.swift │ │ ├── SkillsAndVideosResource+API.swift │ │ ├── UploadsResource+API.swift │ │ ├── VectorStoresResource+API.swift │ │ └── WebhooksResource+Helpers.swift │ ├── Extensions/ │ │ ├── NSImageExtension.swift │ │ ├── NSMutableDataExtension.swift │ │ ├── String.swift │ │ └── StringPropertyMap.swift │ ├── OpenAI.swift │ ├── Protocols/ │ │ ├── Chat/ │ │ │ └── Property.swift │ │ └── OpenAIProtocol.swift │ ├── Types/ │ │ ├── Enums/ │ │ │ ├── Audio/ │ │ │ │ └── AudioResponseFormat.swift │ │ │ ├── Chat/ │ │ │ │ ├── ChatModels.swift │ │ │ │ └── ChatRole.swift │ │ │ ├── Completions/ │ │ │ │ └── CompletionModels.swift │ │ │ ├── Files/ │ │ │ │ └── FileStatus.swift │ │ │ ├── Images/ │ │ │ │ ├── ImageData.swift │ │ │ │ ├── ImageModel.swift │ │ │ │ ├── ImageQuality.swift │ │ │ │ ├── ImageResolutions.swift │ │ │ │ ├── ImageStyle.swift │ │ │ │ └── ResponseFormat.swift │ │ │ ├── Moderations/ │ │ │ │ └── ContentPolicyModels.swift │ │ │ └── OpenAI/ │ │ │ ├── OpenAIErrors.swift │ │ │ └── OpenAIObject.swift │ │ └── Structs/ │ │ ├── Parameters/ │ │ │ ├── Audio/ │ │ │ │ ├── SpeechParameters.swift │ │ │ │ └── TranscriptionParameters.swift │ │ │ ├── Batches/ │ │ │ │ └── BatchParameters.swift │ │ │ ├── Beta/ │ │ │ │ └── AssistantParameters.swift │ │ │ ├── Chat/ │ │ │ │ ├── ChatParameters.swift │ │ │ │ ├── ChatResponseFormat.swift │ │ │ │ ├── ChatTool.swift │ │ │ │ ├── Function.swift │ │ │ │ ├── Parameter.swift │ │ │ │ └── ParameterDetail.swift │ │ │ ├── Completions/ │ │ │ │ └── CompletionParameters.swift │ │ │ ├── Containers/ │ │ │ │ └── ContainerParameters.swift │ │ │ ├── Conversations/ │ │ │ │ └── ConversationParameters.swift │ │ │ ├── Embeddings/ │ │ │ │ └── EmbeddingsParameters.swift │ │ │ ├── Evals/ │ │ │ │ └── EvalParameters.swift │ │ │ ├── Files/ │ │ │ │ └── UploadFileParameters.swift │ │ │ ├── FineTuning/ │ │ │ │ └── FineTuningParameters.swift │ │ │ ├── Images/ │ │ │ │ ├── ImageEditParameters.swift │ │ │ │ ├── ImageParameters.swift │ │ │ │ └── ImageVariationParameters.swift │ │ │ ├── Moderations/ │ │ │ │ └── ConentPolicyParameters.swift │ │ │ ├── Realtime/ │ │ │ │ └── RealtimeParameters.swift │ │ │ ├── Responses/ │ │ │ │ └── ResponseParameters.swift │ │ │ ├── Skills/ │ │ │ │ └── SkillParameters.swift │ │ │ ├── Uploads/ │ │ │ │ └── UploadParameters.swift │ │ │ ├── VectorStores/ │ │ │ │ └── VectorStoreParameters.swift │ │ │ └── Videos/ │ │ │ └── VideoParameters.swift │ │ └── Schemas/ │ │ ├── Audio/ │ │ │ └── TranscriptionResponse.swift │ │ ├── Batches/ │ │ │ └── BatchModels.swift │ │ ├── Beta/ │ │ │ └── AssistantModels.swift │ │ ├── Chat/ │ │ │ └── ChatResponse.swift │ │ ├── Completions/ │ │ │ └── CompletionResponse.swift │ │ ├── Containers/ │ │ │ └── ContainerModels.swift │ │ ├── Conversations/ │ │ │ └── ConversationModels.swift │ │ ├── Embeddings/ │ │ │ ├── EmbeddingsData.swift │ │ │ ├── EmbeddingsResponse.swift │ │ │ └── EmbeddingsUsage.swift │ │ ├── Evals/ │ │ │ └── EvalModels.swift │ │ ├── Files/ │ │ │ ├── File.swift │ │ │ ├── FileContent.swift │ │ │ └── ListFilesResponse.swift │ │ ├── FineTuning/ │ │ │ └── FineTuningModels.swift │ │ ├── Images/ │ │ │ └── ImageResponse.swift │ │ ├── Models/ │ │ │ ├── ListModelResponse.swift │ │ │ └── Model.swift │ │ ├── Moderations/ │ │ │ ├── ContentPolicyCategories.swift │ │ │ ├── ContentPolicyCategoryScore.swift │ │ │ ├── ContentPolicyResponse.swift │ │ │ └── ContentPolicyResult.swift │ │ ├── OpenAI/ │ │ │ ├── ChatChoice.swift │ │ │ ├── ChatMessage.swift │ │ │ ├── Choice.swift │ │ │ ├── Configuration.swift │ │ │ ├── DeleteObject.swift │ │ │ ├── FormData.swift │ │ │ ├── FunctionCall.swift │ │ │ ├── OpenAIErrorMessage.swift │ │ │ ├── OpenAIErrorResponse.swift │ │ │ ├── OpenAIRequestOptions.swift │ │ │ └── Usage.swift │ │ ├── Realtime/ │ │ │ └── RealtimeModels.swift │ │ ├── Responses/ │ │ │ └── ResponseModels.swift │ │ ├── Skills/ │ │ │ └── SkillModels.swift │ │ ├── Uploads/ │ │ │ └── UploadModels.swift │ │ ├── VectorStores/ │ │ │ └── VectorStoreModels.swift │ │ └── Videos/ │ │ └── VideoModels.swift │ └── Utils/ │ ├── ClampedPropertyWrapper.swift │ ├── FormDataHelper.swift │ ├── GenericCodingKeys.swift │ ├── OpenAIKitSession.swift │ ├── OpenAIStreamer/ │ │ ├── OpenAIEvent.swift │ │ ├── OpenAISource.swift │ │ └── OpenAIStreamParser.swift │ └── Whisper/ │ ├── SRT.swift │ └── WebVTT.swift └── Tests/ ├── OpenAIKitTests/ │ ├── Client/ │ │ ├── OpenAIAudioSpeechTests.swift │ │ ├── OpenAIBatchesTests.swift │ │ ├── OpenAIBetaAssistantsTests.swift │ │ ├── OpenAIClientScaffoldTests.swift │ │ ├── OpenAIContainersTests.swift │ │ ├── OpenAIConversationsTests.swift │ │ ├── OpenAIEncodingMigrationTests.swift │ │ ├── OpenAIEvalsTests.swift │ │ ├── OpenAIFineTuningTests.swift │ │ ├── OpenAIRealtimeTests.swift │ │ ├── OpenAIResponsesTests.swift │ │ ├── OpenAISkillsAndVideosTests.swift │ │ ├── OpenAITransportOptionsTests.swift │ │ ├── OpenAIUploadsTests.swift │ │ ├── OpenAIVectorStoresTests.swift │ │ └── OpenAIWebhooksTests.swift │ ├── Extension/ │ │ └── BundleExtension.swift │ ├── Mocks/ │ │ └── MockOpenAI.swift │ ├── OpenAIKitTests.swift │ └── Types/ │ └── Enums/ │ └── MockOpenAIError.swift ├── Resources/ │ └── JSON Responses/ │ ├── Completions/ │ │ └── CompletionResponse.json │ ├── Content Policy/ │ │ └── ContentPolicyResponse.json │ ├── Delete File/ │ │ └── DeleteFileResponse.json │ ├── Images/ │ │ ├── Embeddings/ │ │ │ └── EmbeddingsResponse.json │ │ ├── NumberOfImages/ │ │ │ ├── ImageURL-1.json │ │ │ ├── ImageURL0.json │ │ │ ├── ImageURL1.json │ │ │ ├── ImageURL10.json │ │ │ ├── ImageURL11.json │ │ │ └── ImageURL2.json │ │ ├── Prompt/ │ │ │ ├── ImageApple.json │ │ │ └── ImageOtter.json │ │ ├── Resolution/ │ │ │ ├── Large/ │ │ │ │ ├── ImageB64Large.json │ │ │ │ └── ImageURLLarge.json │ │ │ ├── Medium/ │ │ │ │ ├── ImageB64Medium.json │ │ │ │ └── ImageURLMedium.json │ │ │ └── Small/ │ │ │ ├── ImageB64Small.json │ │ │ └── ImageURLSmall.json │ │ └── ResponseFormat/ │ │ ├── ImageB64.json │ │ └── ImageURL.json │ ├── List Files/ │ │ └── ListFilesResponse.json │ ├── List Models/ │ │ └── ModelsResponse.json │ └── Retrieve Model/ │ └── RetrieveModelResponse.json └── Test Plans/ └── iOS-TS.xctestplan ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/FUNDING.yml ================================================ github: MarcoDotIO ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: Bug report description: Create a report to help us improve labels: ["bug"] body: - type: markdown attributes: value: | Thanks for taking the time to fill out this bug report! - type: textarea id: what-happened attributes: label: Describe the bug description: A clear and concise description of what the bug is, and any additional context. placeholder: Tell us what you see! validations: required: true - type: textarea id: repro-steps attributes: label: To Reproduce description: Steps to reproduce the behavior. placeholder: | 1. Fetch a '...' 2. Update the '....' 3. See error validations: required: true - type: textarea id: code-snippets attributes: label: Code snippets description: If applicable, add code snippets to help explain your problem. render: Swift validations: required: false - type: input id: os attributes: label: OS placeholder: macOS validations: required: true - type: input id: language-version attributes: label: Swift Version placeholder: Swift 5.7 validations: required: true - type: input id: xcode-version attributes: label: Xcode Version placeholder: Xcode 14.1 validations: required: true - type: input id: lib-version attributes: label: Library version placeholder: OpenAIKit v1.0.0 validations: required: true ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.yml ================================================ name: Feature request description: Suggest an idea for this library labels: ["feature-request"] body: - type: markdown attributes: value: | Thanks for taking the time to fill out this feature request! - type: textarea id: feature attributes: label: Describe the feature or improvement you're requesting description: A clear and concise description of what you want to happen. validations: required: true - type: textarea id: context attributes: label: Additional context description: Add any other context about the feature request here. ================================================ FILE: .github/pull_request_template.md ================================================ ## Describe your changes ## Issue ticket number and link ## Checklist before requesting a review - [ ] I have performed a self-review of my code - [ ] If it is a core feature, I have added thorough tests. - [ ] Do we need to implement analytics? - [ ] Will this be part of a product update? If yes, please write one phrase about this update. ================================================ FILE: .github/workflows/swift.yml ================================================ # This workflow will build a Swift project # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift name: Swift on: push: branches: [ "main" ] pull_request: branches: [ "main" ] jobs: build: runs-on: macos-latest steps: - uses: actions/checkout@v3 - name: Build run: swift build -v - name: Run tests run: swift test -v ================================================ FILE: .gitignore ================================================ # Mac OS X .DS_Store # Cursor IDE .cursor/ # Xcode ## Build generated build/ DerivedData ## Various settings *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata ## Other *.xccheckout *.moved-aside *.xcuserstate *.xcscmblueprint ## Obj-C/Swift specific *.hmap *.ipa ## Playgrounds timeline.xctimeline playground.xcworkspace # Swift Package Manager .build/ # Carthage Carthage/Build .UlyssesRoot .Ulysses-Settings.plist .Ulysses-Group.plist ================================================ FILE: .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: CHANGELOG.md ================================================ # Changelog All notable changes to this project are documented in this file. ## 3.0.0 - 2026-02-19 ### Breaking Changes - Introduced a modular resource-first client surface (for example `client.chat.completions`, `client.responses`, `client.uploads`) as the primary 3.x API. - Migrated core request payloads from manual dictionaries to strongly typed `Encodable` request models. - Updated package language mode to Swift 6.2 with Swift 6 concurrency checks enabled. ### Added - Added Responses resources (`create`, `stream`, `parse`, `retrieve`, `cancel`, `delete`) and typed input item/token helpers. - Added Realtime resources with calls, client secret support, and connection manager abstractions. - Added Uploads resources with upload parts and upload completion flows. - Added Conversations resources with nested conversation items APIs. - Added Containers resources with nested files/content APIs. - Added Evals resources with runs and output items APIs. - Added Skills resources (including versions and content APIs) and Videos resources. - Added webhook signature verification and typed `unwrap` helpers. - Added/expanded resource coverage for Audio speech, Vector stores, Batches, Fine-tuning jobs, and Beta assistants/threads. ### Changed - Improved transport configuration with typed request options (timeouts, retries, additional headers) and typed status error mapping. - Expanded `Configuration` to include project ID, webhook secret, base URL, and richer request options. - Modernized chat parameter modeling to cover current chat completion fields (tools, response format, token controls, etc.). ### Concurrency and Hardening - Hardened streaming and transport internals for Swift 6.2 concurrency compatibility. - Added `Sendable` conformances and safe type constraints across streamed/response model surfaces. ### Docs and Tests - Added migration guidance for 2.x -> 3.x in the README. - Added comprehensive step-based tests for each newly introduced resource area and compatibility behavior. ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: * Demonstrating empathy and kindness toward other people * Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at @OpenDive on Twitter. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to Transcriptase We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: - Reporting a bug - Discussing the current state of the code - Submitting a fix - Proposing new features - Becoming a maintainer ## We Develop with Github We use github to host code, to track issues and feature requests, as well as accept pull requests. ## We Use [Github Flow](https://docs.github.com/en/get-started/quickstart/github-flow), So All Code Changes Happen Through Pull Requests Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://docs.github.com/en/get-started/quickstart/github-flow). We actively welcome your pull requests: 1. Fork the repo and create your branch from `main`. 2. If you've added code that should be tested, add tests. 3. If you've changed APIs, update the documentation. 4. Ensure the test suite passes. 5. Make sure your code lints. 6. Issue that pull request! ## Any contributions you make will be under the MIT Software License In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. ## Report bugs using Github's [issues](https://github.com/OpenDive/OpenAIKit/issues) We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/OpenDive/OpenAIKit/issues/new/choose); it's that easy! ## Write bug reports with detail, background, and sample code [This is an example](http://stackoverflow.com/q/12488905/180626) of a bug report Brian A. Danielak wrote, and I think it's not a bad model. Here's [another example from Craig Hockenberry](http://www.openradar.me/11905408), an app developer whom I greatly respect. **Great Bug Reports** tend to have: - A quick summary and/or background - Steps to reproduce - Be specific! - Give sample code if you can. [My stackoverflow question](http://stackoverflow.com/q/12488905/180626) includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing - What you expected would happen - What actually happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) People *love* thorough bug reports. I'm not even kidding. ## Use a Consistent Coding Style I'm again borrowing these from [Facebook's Guidelines](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) * 2 spaces for indentation rather than tabs * You can try running `swiftlint` for style unification ## License By contributing, you agree that your contributions will be licensed under its MIT License. ## References This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) ================================================ FILE: Examples/iOS_Example/iOS_Example/Assets.xcassets/AccentColor.colorset/Contents.json ================================================ { "colors" : [ { "idiom" : "universal" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Assets.xcassets/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Audio/AudioPlayerViewModel.swift ================================================ // // AudioPlayerViewModel.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import AVFoundation class AudioPlayerViewModel: ObservableObject { private var audioPlayer: AVAudioPlayer? func play(audioData: Data?) { guard let data = audioData else { print("No audio data set") return } do { audioPlayer = try AVAudioPlayer(data: data) audioPlayer?.play() } catch { print("Error initializing audio player: \(error.localizedDescription)") } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Audio/CreateTranscription.swift ================================================ // // CreateTranscription.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit import AVFoundation enum TranscriptionType: String, CaseIterable, Identifiable { case english case dutch var id: Self { self } } struct CreateTranscriptionExample: View { @StateObject private var viewModel = AudioPlayerViewModel() @State private var isCompleting: Bool = false @State private var transcription: String = "" @State private var selectedLanguage: TranscriptionType = .english var audioData: Data? { switch selectedLanguage { case .english: return self.retrieveAudio(type: .english) case .dutch: return self.retrieveAudio(type: .dutch) } } // English Audio Source: https://librivox.org/12-creepy-tales-by-edgar-allan-poe/ // 12 - THE PIT AND THE PENDULUM -- Narrator: Eden Rea-Hedrick // --------------------------------------------------------------------------------------- // Dutch Audio Source: https://librivox.org/the-raven-multilingual-by-edgar-allan-poe/ // 04 - Dutch: De Raaf (John F. Malta) -- Narrator: Julie VW private func retrieveAudio(type: TranscriptionType) -> Data? { guard let filePath = Bundle.main.path( forResource: type == .english ? "audio" : "audio_translation", ofType: "mp3" ), let audio = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else { return nil } return audio } var body: some View { VStack { Picker("Transcription Type", selection: $selectedLanguage) { Text("Regular Transcription").tag(TranscriptionType.english) Text("Translation Transcription").tag(TranscriptionType.dutch) } .padding(.bottom, 90) Button { self.viewModel.play(audioData: self.audioData) } label: { Text("Play Audio") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } if isCompleting { VStack { Text(transcription) } .padding() } else { VStack { Button { isCompleting = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration( organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAI = OpenAI(config) guard let audio = self.audioData else { throw OpenAIError.invalidData } let audioParameters = TranscriptionParameters(file: audio) let transcriptionCompletion = try await self.selectedLanguage == .english ? openAI.createTranscription(parameters: audioParameters) : openAI.createTranslation(parameters: audioParameters) if let text = transcriptionCompletion.text { self.transcription = text } } catch { print("ERROR DETAILS - \(error)") } } } label: { Text("Generate Transcription") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } } #Preview { CreateTranscriptionExample() } ================================================ FILE: Examples/iOS_Example/iOS_Example/Chat/ChatMainView.swift ================================================ // // ChatMainView.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI struct ChatMainView: View { var body: some View { List { NavigationLink(destination: CreateChatCompletionExample()) { Text("Generate Chat Completion Example") } NavigationLink(destination: CreateChatCompletionStreamingExample()) { Text("Generate Chat Completion Streaming Example") } NavigationLink(destination: CreateChatFunctionCallExample()) { Text("Generate Chat Completion Function Call Example") } } .listStyle(.plain) .navigationTitle("Chat") } } struct ChatMainView_Previews: PreviewProvider { static var previews: some View { NavigationStack { ChatMainView() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Chat/CreateChatCompletion.swift ================================================ // // CreateChatCompletion.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct CreateChatCompletionExample: View { @State private var responseText: String? @State private var isCompleting: Bool = false let chat: [ChatMessage] = [ ChatMessage(role: .system, content: "You are a helpful assistant."), ChatMessage(role: .user, content: "Who won the world series in 2020?"), ChatMessage(role: .assistant, content: "The Los Angeles Dodgers won the World Series in 2020."), ChatMessage(role: .user, content: "Where was it played?") ] var body: some View { VStack { VStack(alignment: .leading) { ForEach(chat) { message in Text("\(message.role.rawValue.capitalized): \(message.content ?? "NO CONTENT")") .padding(.vertical, 10) } } .padding(20) if isCompleting { VStack { if let responseText = self.responseText { Text("Assistant: \(responseText)") } else { Text("Assistant: ...") } } .padding() } else { VStack { Button { isCompleting = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration( organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAI = OpenAI(config) let chatParameters = ChatParameters(model: .chatGPTTurbo, messages: chat) let chatCompletion = try await openAI.generateChatCompletion( parameters: chatParameters ) if let message = chatCompletion.choices[0].message { self.responseText = message.content } } catch { print("ERROR DETAILS - \(error)") } } } label: { Text("Generate Completion") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } Spacer() } } struct CreateChatCompletionExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { CreateChatCompletionExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Chat/CreateChatCompletionStreaming.swift ================================================ // // CreateChatCompletionStreaming.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct CreateChatCompletionStreamingExample: View { @State private var responseText: String = "" @State private var isCompleting: Bool = false let chat: [ChatMessage] = [ ChatMessage(role: .system, content: "You are a helpful assistant."), ChatMessage(role: .user, content: "Who won the world series in 2020?"), ChatMessage(role: .assistant, content: "The Los Angeles Dodgers won the World Series in 2020."), ChatMessage(role: .user, content: "Where was it played?") ] var body: some View { VStack { VStack(alignment: .leading) { ForEach(chat) { message in Text("\(message.role.rawValue.capitalized): \(message.content ?? "NO CONTENT")") .padding(.vertical, 10) } } .padding(20) if isCompleting { VStack { Text(responseText) } .padding() } else { VStack { Button { self.isCompleting = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration( organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAI = OpenAI(config) let chatParameters = ChatParameters(model: .chatGPTTurbo, messages: chat) let stream = try openAI.generateChatCompletionStreaming( parameters: chatParameters ) for try await result in stream { if let delta = result.choices[0].delta { if let role = delta.role { self.responseText += "\(role.rawValue.capitalized): " } else if let content = delta.content { self.responseText += content } } } } catch { print("ERROR DETAILS - \(error)") } } } label: { Text("Stream Completion") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } Spacer() } } struct CreateChatCompletionStreamingExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { CreateChatCompletionStreamingExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Chat/CreateChatFunctionCallExample.swift ================================================ // // CreateChatFunctionCallExample.swift // iOS_Example // // Created by Marcus Arnett on 10/9/23. // import SwiftUI import OpenAIKit struct CreateChatFunctionCallExample: View { @State private var isCompleting: Bool = false @State private var weatherInfo: WeatherInfo? = nil enum TemperatureUnit: String, Codable { case fahrenheit case celsius } struct WeatherInfo: Codable { let location: String let temperature: String let unit: TemperatureUnit let forecast: [String] } func getCurrentWeather(location: String, unit: TemperatureUnit = .fahrenheit) -> WeatherInfo { return WeatherInfo(location: location, temperature: "72", unit: unit, forecast: ["sunny", "windy"]) } let messages: [ChatMessage] = [ChatMessage(role: .user, content: "What's the weather like in Boston?")] let functions: [Function] = [ Function( name: "getCurrentWeather", description: "Get the current weather in a given location", parameters: Parameters( type: "object", properties: [ "location": ParameterDetail(type: "string", description: "The city and state, e.g. San Francisco, CA"), "unit": ParameterDetail(type: "string", enumValues: ["fahrenheit", "celsius"]) ], required: ["location"] ) ) ] var body: some View { VStack { VStack(alignment: .leading) { ForEach(messages) { message in Text("\(message.role.rawValue.capitalized): \(message.content ?? "NO CONTENT")") .padding(.vertical, 10) } } .padding(20) if isCompleting { VStack { if let weatherInfo { Text("Assistant: The current weather in \(weatherInfo.location) is \(weatherInfo.temperature) degrees \(weatherInfo.unit.rawValue).") } else { Text("Assistant: ...") } } .padding() } else { VStack { Button { isCompleting = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration( organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAI = OpenAI(config) let chatParameters = ChatParameters( model: .chatGPTTurbo, messages: messages, functionCall: "auto", functions: functions ) let chatCompletion = try await openAI.generateChatCompletion( parameters: chatParameters ) if let message = chatCompletion.choices[0].message, let functionCall = message.functionCall { let jsonString = functionCall.arguments if let data = jsonString.data(using: .utf8) { do { if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let location = json["location"] as? String { self.weatherInfo = self.getCurrentWeather(location: location) } } catch { print("Error parsing JSON: \(error)") } } } } catch { print("ERROR DETAILS - \(error)") } } } label: { Text("Generate Completion") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } Spacer() } } struct CreateChatFunctionCallExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { CreateChatFunctionCallExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Completion/CompletionMainView.swift ================================================ // // CompletionMainView.swift // iOS_Example // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI struct CompletionMainView: View { var body: some View { List { NavigationLink(destination: GenerateCompletionExample()) { Text("Generate Completion Example") } } .listStyle(.plain) .navigationTitle("Completion") } } struct CompletionMainView_Previews: PreviewProvider { static var previews: some View { NavigationStack { CompletionMainView() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Completion/GenerateCompletionExample.swift ================================================ // // GenerateCompletionExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct GenerateCompletionExample: View { @State private var responseText: String? @State private var isCompleting: Bool = false let prompt = "Say this is a test" var body: some View { if isCompleting { VStack { Text("Input Prompt: \(prompt)") if let responseText = self.responseText { Text("Output Text: \(responseText)") } else { Text("Output Text: ...") } } .padding() } else { VStack { Button { isCompleting = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration( organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAI = OpenAI(config) let completionParameter = CompletionParameters( model: .davinci, prompt: [prompt], maxTokens: 20, temperature: 0.98 ) let completionResponse = try await openAI.generateCompletion( parameters: completionParameter ) self.responseText = completionResponse .choices[0] .text .replacingOccurrences(of: "\n", with: "") } catch { print("ERROR DETAILS - \(error)") } } } label: { Text("Generate Completion") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct GenerateCompletionExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { GenerateCompletionExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Content Policy/ContentPolicyExample.swift ================================================ // // ContentPolicyExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct ContentPolicyExample: View { @State private var isFlagged: Bool? @State private var isEvaluating: Bool = false let input = "I want to kill them." var body: some View { if isEvaluating { VStack { Text("Input Text: \(input)") if let isFlagged = isFlagged { Text("Flagged: \(isFlagged ? "Yes" : "No")") } } .padding() } else { VStack { Button { isEvaluating = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let openAI = OpenAI(Configuration(organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY")) let contentParameter = ContentPolicyParameters(input: input) let contentResult = try await openAI.checkContentPolicy(parameters: contentParameter) self.isFlagged = contentResult.results[0].flagged } catch { print("CRASHED WITH ERROR - \(error)") } } } label: { Text("Evaluate Prompt") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct ContentPolicyExample_Preview: PreviewProvider { static var previews: some View { ContentPolicyExample() } } ================================================ FILE: Examples/iOS_Example/iOS_Example/ContentView.swift ================================================ // // ContentView.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI struct ContentView: View { var body: some View { NavigationStack { List { NavigationLink(destination: ModelMainView()) { Text("Model") } NavigationLink(destination: CompletionMainView()) { Text("Completion") } NavigationLink(destination: ChatMainView()) { Text("Chat") } NavigationLink(destination: ImageMainView()) { Text("Image") } NavigationLink(destination: CreateEmbeddingsExample()) { Text("Embeddings") } NavigationLink(destination: CreateTranscriptionExample()) { Text("Audio") } NavigationLink(destination: FileMainView()) { Text("File") } NavigationLink(destination: ContentPolicyExample()) { Text("Content Policy") } } .navigationTitle("OpenAIKit Examples") .listStyle(.plain) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Embeddings/CreateEmbeddingsExample.swift ================================================ // // CreateEmbeddingsExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct CreateEmbeddingsExample: View { @State private var embeddingsResponse: EmbeddingsResponse? @State private var isCreatingEmbeds: Bool = false let input: String = "The food was delicious and the waiter..." var body: some View { if isCreatingEmbeds { VStack { Text("Input: \(input)") if let embeddingsResponse = self.embeddingsResponse { Text("Object Type: \(embeddingsResponse.object.rawValue)") .padding(.bottom) Text("Embeddings Details").bold().font(.title) Text("Object Type: \(embeddingsResponse.data[0].object.rawValue)") Text("First Embedding (See Print For Full Embedding output):") .multilineTextAlignment(.center) Text("\(embeddingsResponse.data[0].embedding[0])") Text("Index: \(embeddingsResponse.data[0].index)") Text("Embeddings Usage").bold().font(.title).padding(.top) Text("Prompt Tokens: \(embeddingsResponse.usage.promptTokens)") Text("Total Tokens: \(embeddingsResponse.usage.totalTokens)") } else { Text("Loading Embeddings...") } } .padding() } else { VStack { Button { isCreatingEmbeds = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration(organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY") let openAI = OpenAI(config) let embeddingsParam = EmbeddingsParameters(model: "text-similarity-ada-002", input: input) self.embeddingsResponse = try await openAI.createEmbeddings(parameters: embeddingsParam) print("Embeddings Result: ") self.embeddingsResponse?.data[0].embedding.forEach { embed in print("\(embed)") } } catch { print("ERROR - \(error)") } } } label: { Text("Create Embeddings") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct CreateEmbeddingsExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { CreateEmbeddingsExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/File/DeleteFileExample.swift ================================================ // // DeleteFileExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct DeleteFileExample: View { @State private var deleteFileResponse: DeleteObject? @State private var isDeleting: Bool = false var body: some View { if isDeleting { VStack { if let deleteFileResponse = deleteFileResponse { Text("File deletion complete!") Text("ID: \(deleteFileResponse.id)") Text("Object: \(deleteFileResponse.object.rawValue)") Text("Deleted: \(String(deleteFileResponse.deleted))") } else { Text("Deleting file...") } } .padding() } else { VStack { Button { isDeleting = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration(organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY") let openAI = OpenAI(config) self.deleteFileResponse = try await openAI.deleteFile(fileId: "INSERT-FILE-ID") } catch { print("ERROR - \(error)") } } } label: { Text("Delete File") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct DeleteFileExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { DeleteFileExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/File/File/SampleData.jsonl ================================================ {"prompt":"Ian Knox (admiral)\n\n###\n\n","completion":" Vice Admiral Ian Warren Knox AC is a retired senior officer of the Royal Australian Navy. END"} {"prompt":"Porsche Supercup\n\n###\n\n","completion":" The Porsche Supercup is an international One-make GT3 production stock car racing premier series supporting the Formula One World Championship organized by Porsche Motorsport GmbH. END"} {"prompt":"Monaco Grand Prix\n\n###\n\n","completion":" The Monaco Grand Prix is a Formula One motor race held annually on the Circuit de Monaco on the last weekend in May. END"} {"prompt":"Fonteia (gens)\n\n###\n\n","completion":" The gens Fonteia was a plebeian family at Rome. END"} {"prompt":"Aihole\n\n###\n\n","completion":" Aihole, also referred to as Aivalli, Ahivolal or Aryapura, is a historic site of ancient and medieval era Buddhist, Hindu and Jain monuments in Karnataka, India that dates from the sixth century through the twelfth century CE. END"} {"prompt":"Lewis Seiler\n\n###\n\n","completion":" Lewis Seiler was an American film director. END"} {"prompt":"Tyrrhenian-Adriatic sclerophyllous and mixed forests\n\n###\n\n","completion":" The Tyrrhenian-Adriatic sclerophyllous and mixed forests is an ecoregion in southern Italy, Sicily, Sardinia, Corsica, the Dalmatian Islands of Croatia, and Malta. END"} {"prompt":"Port Aransas, Texas\n\n###\n\n","completion":" Port Aransas is a city in Nueces County, Texas, United States. END"} {"prompt":"Bellocq\n\n###\n\n","completion":" Bellocq is a commune of the Pyrénées-Atlantiques department in southwestern France. END"} {"prompt":"List of birds of Sweden\n\n###\n\n","completion":" This is a list of the bird species recorded in Sweden. END"} {"prompt":"Poles Coppice countryside site\n\n###\n\n","completion":" Poles Coppice countryside site is an area of ancient oak woodland with disused quarry workings, located around 0.5 miles south of Pontesbury, Shropshire. END"} {"prompt":"Karoi Rydings\n\n###\n\n","completion":" Karoi Rydings is a school in Zimbabwe that was attacked by \"squatters\" in the year 2000 and thus closed. END"} {"prompt":"1913\n\n###\n\n","completion":" 1913 was a common year starting on Wednesday of the Gregorian calendar and a common year starting on Tuesday of the Julian calendar, the 1913th year of the Common Era and Anno Domini designations, the 913th year of the 2nd millennium, the 13th year of the 20th century, and the 4th year of the 1910s decade. END"} {"prompt":"Guglielmo Achille Cavellini\n\n###\n\n","completion":" Guglielmo Achille Cavellini, also known as GAC, was an Italian artist and art collector. END"} {"prompt":"New College Lane\n\n###\n\n","completion":" New College Lane is a historic street in central Oxford, England, named after New College, one of the older Oxford colleges, adjacent to the north. END"} {"prompt":"London Charterhouse\n\n###\n\n","completion":" The London Charterhouse is a historic complex of buildings in Smithfield, London, dating back to the 14th century. END"} {"prompt":"Pride parade\n\n###\n\n","completion":" Pride parades are outdoor events celebrating lesbian, gay, bisexual, transgender, non-binary and queer social and self acceptance, achievements, legal rights, and pride. END"} {"prompt":"Sør Arena\n\n###\n\n","completion":" Sparebanken Sør Arena is a football stadium located at Torsvika in Kristiansand, Norway. END"} {"prompt":"Piatnik\n\n###\n\n","completion":" Wiener Spielkartenfabrik Ferd. END"} {"prompt":"List of mammals of Mexico\n\n###\n\n","completion":" This is a list of the native wild mammal species recorded in Mexico. END"} {"prompt":"List of beaches\n\n###\n\n","completion":" This is a list of beaches of the world, sorted by country. END"} {"prompt":"Rufous-chinned laughingthrush\n\n###\n\n","completion":" The rufous-chinned laughingthrush is a bird species in the family Leiothrichidae. END"} {"prompt":"Ciqikou, Chongqing\n\n###\n\n","completion":" Ciqikou is an ancient town in the Shapingba District of Chongqing Municipality, People's Republic of China. END"} {"prompt":"Ramtek\n\n###\n\n","completion":" Ramtek is a city and municipal council in Nagpur district of the Maharashtra, India. END"} {"prompt":"USS Portland (CA-33)\n\n###\n\n","completion":" USS Portland was the lead ship of the Portland class of cruiser and the first ship of the United States Navy named after the city of Portland, Maine. END"} {"prompt":"Hôtel-Dieu, Paris\n\n###\n\n","completion":" The Hôtel-Dieu is a hospital located on the Île de la Cité in the 4th arrondissement of Paris, on the parvise of Notre-Dame. END"} {"prompt":"Kapp Putsch\n\n###\n\n","completion":" The Kapp Putsch, also known as the Kapp–Lüttwitz Putsch, named after its leaders Wolfgang Kapp and Walther von Lüttwitz, was an attempted coup in Berlin on 13 March 1920. END"} {"prompt":"BFI London Film Festival\n\n###\n\n","completion":" The BFI London Film Festival is an annual film festival founded in 1957 and held in the United Kingdom, running for two weeks in October with co-operation from the British Film Institute. END"} {"prompt":"Tyco International\n\n###\n\n","completion":" Tyco International plc was a security systems company incorporated in the Republic of Ireland, with operational headquarters in Princeton, New Jersey, United States. END"} {"prompt":"Lifeboat (shipboard)\n\n###\n\n","completion":" A lifeboat or life raft is a small, rigid or inflatable boat carried for emergency evacuation in the event of a disaster aboard a ship. END"} {"prompt":"Lepotrema acanthochromidis\n\n###\n\n","completion":" Lepotrema acanthochromidis is a species of lepocreadiid digenean parasitic in the intestine of marine fish. END"} {"prompt":"Textiles of Sumba\n\n###\n\n","completion":" The textiles of Sumba, an island in eastern Indonesia, represent the means by which the present generation passes on its messages to future generations. END"} {"prompt":"Kaj Munk\n\n###\n\n","completion":" Kaj Harald Leininger Munk was a Danish playwright and Lutheran pastor, known for his cultural engagement and his martyrdom during the Occupation of Denmark of World War II. END"} {"prompt":"Free Royal Cities Act\n\n###\n\n","completion":" The Free Royal Cities Act was an act adopted by the Four-Year Sejm of the Polish-Lithuanian Commonwealth on April 18, 1791, in the run-up to the adoption of the Constitution of May 3, 1791. END"} {"prompt":"Alt Empordà\n\n###\n\n","completion":" Alt Empordà is a comarca in Girona, Catalonia, Spain, one of two into which Empordà was divided by the comarcal division of Catalonia in 1936, the other one being Baix Empordà. END"} {"prompt":"Structural engineering theory\n\n###\n\n","completion":" Structural engineering depends upon a detailed knowledge of loads, physics and materials to understand and predict how structures support and resist self-weight and imposed loads. END"} {"prompt":"List of Donald Trump 2020 presidential campaign endorsements\n\n###\n\n","completion":" This is a list of notable individuals and organizations who voiced their endorsement for the office of the president of Donald Trump as the Republican Party's presidential candidate for the 2020 United States presidential election. END"} {"prompt":"List of moths of South Africa (Geometridae)\n\n###\n\n","completion":" This is a list of moths of the family Geometridae that are found in South Africa. END"} {"prompt":"Flag of Estonia\n\n###\n\n","completion":" The national flag of Estonia is a tricolour featuring three equal horizontal bands of blue, black, and white. END"} {"prompt":"Southern Pacific Transportation Company\n\n###\n\n","completion":" The Southern Pacific was an American Class I railroad network that existed from 1865 to 1996 and operated in the Western United States. END"} {"prompt":"Columbina\n\n###\n\n","completion":" Columbina is a stock character in the Commedia dell'Arte. END"} {"prompt":"Pietro I Orseolo\n\n###\n\n","completion":" Pietro I Orseolo, O.S.B. END"} {"prompt":"Galisteo, Cáceres\n\n###\n\n","completion":" Galisteo is a municipality located in the province of Cáceres, Extremadura, Spain. END"} {"prompt":"Anti-Americanism\n\n###\n\n","completion":" Anti-Americanism is a sentiment which espouses dislike of the American government or opposes its policies, especially its foreign policy, or espouses dislike or hatred of the American people and the United States in general. END"} {"prompt":"Alisagar lift irrigation scheme\n\n###\n\n","completion":" Alisagar is a park, tourist attraction and an irrigation project which is 13 km from Nizamabad and 2 km off the Nizamabad-Bodhan road. END"} {"prompt":"Circular Quay\n\n###\n\n","completion":" Circular Quay is a harbour, former working port and now international passenger shipping port, public piazza and tourism precinct, heritage area, and transport node located in Sydney, New South Wales, Australia on the northern edge of the Sydney central business district on Sydney Cove, between Bennelong Point and The Rocks. END"} {"prompt":"9951 Tyrannosaurus\n\n###\n\n","completion":" 9951 Tyrannosaurus, provisional designation 1990 VK₅, is a stony Vestian asteroid from the inner regions of the asteroid belt, approximately 17 kilometers in diameter. END"} {"prompt":"Ornamental plant\n\n###\n\n","completion":" Ornamental plants are plants that are grown for decorative purposes in gardens and landscape design projects, as houseplants, cut flowers and specimen display. END"} {"prompt":"List of awards and nominations received by Doctor Who\n\n###\n\n","completion":" Doctor Who is a British science fiction television programme produced and aired by the BBC since 1963. END"} {"prompt":"Jean-Baptiste Debret\n\n###\n\n","completion":" Jean-Baptiste Debret was a French painter, who produced many valuable lithographs depicting the people of Brazil. END"} {"prompt":"Santiago de los Caballeros\n\n###\n\n","completion":" Santiago de los Caballeros, also known as Santiago de los Treinta Caballeros or simply Santiago, is the second-largest city in the Dominican Republic and the fourth-largest city in the Caribbean. END"} {"prompt":"Cumans\n\n###\n\n","completion":" The Cumans, also known as Polovtsians or Polovtsy, were a Turkic nomadic people comprising the western branch of the Cuman–Kipchak confederation. END"} {"prompt":"Staten Island Ferry\n\n###\n\n","completion":" The Staten Island Ferry is a passenger ferry route operated by the New York City Department of Transportation. END"} {"prompt":"New Order (Indonesia)\n\n###\n\n","completion":" The New Order is the term coined by the second Indonesian President Suharto to characterise his regime as he came to power in 1966. END"} {"prompt":"Ranger School\n\n###\n\n","completion":" The United States Army Ranger School is a 62-day small unit tactics and leadership course that develops functional skills directly related to units whose mission is to engage the enemy in close combat and direct fire battles. END"} {"prompt":"Liam Hendriks\n\n###\n\n","completion":" Liam Johnson Hendriks, nicknamed \"Slydah\", is an Australian professional baseball pitcher for the Oakland Athletics of Major League Baseball. END"} {"prompt":"Bèze (river)\n\n###\n\n","completion":" The Bèze is a French river in the Côte-d'Or department, in the Bourgogne-Franche-Comté region. END"} {"prompt":"Battle of Killdeer Mountain\n\n###\n\n","completion":" The Battle of Killdeer Mountain took place during Brig. END"} {"prompt":"Bomb (tank)\n\n###\n\n","completion":" Bomb is a Canadian Army Sherman Tank of the 27th Armoured Regiment which landed at D-Day and fought across northwest Europe until the end of World War II, one of the few Canadian tanks that fought without interruption from D-Day to VE Day. END"} {"prompt":"Bradenham, Buckinghamshire\n\n###\n\n","completion":" Bradenham is a village and civil parish within Wycombe district in Buckinghamshire, England. END"} {"prompt":"Walim, Lower Silesian Voivodeship\n\n###\n\n","completion":" Walim is a village in Wałbrzych County, Lower Silesian Voivodeship, in south-western Poland. END"} {"prompt":"Art of Birmingham\n\n###\n\n","completion":" Birmingham has a distinctive culture of art and design that emerged in the 1750s, driven by the historic importance of the applied arts to the city's manufacturing economy. END"} {"prompt":"Danny Rozin\n\n###\n\n","completion":" Daniel Rozin is an Israeli-American artist working in the area of interactive digital art. END"} {"prompt":"Frédéric Antonetti\n\n###\n\n","completion":" Frédéric Antonetti is a French professional football manager and former player. END"} {"prompt":"LGBT rights in Mexico\n\n###\n\n","completion":" Lesbian, gay, bisexual, and transgender rights in Mexico have expanded in recent years, in keeping with worldwide legal trends. END"} {"prompt":"Central Tool Room and Training Centre, Bhubaneswar\n\n###\n\n","completion":" Central Tool Room and Training Centre, Bhubaneswar is an autonomous body under the Ministry of MSME, Government of India. END"} {"prompt":"Sergeant Major's Row\n\n###\n\n","completion":" The Sergeant Major's Row are heritage-listed former terrace houses and now shops and offices located in a row at 33-41 George Street in the inner city Sydney suburb of The Rocks in the City of Sydney local government area of New South Wales, Australia. END"} {"prompt":"Ancestor veneration in China\n\n###\n\n","completion":" Chinese ancestor worship or Chinese ancestor veneration, also called the Chinese patriarchal religion, is an aspect of the Chinese traditional religion which revolves around the ritual celebration of the deified ancestors and tutelary deities of people with the same surname organised into lineage societies in ancestral shrines. END"} {"prompt":"Haverford Township, Delaware County, Pennsylvania\n\n###\n\n","completion":" Haverford Township is a Home Rule Municipality township in Delaware County, Pennsylvania, United States. END"} {"prompt":"George Washington Rains\n\n###\n\n","completion":" George Washington Rains was a United States Army and later Confederate States Army officer. END"} {"prompt":"Death Valley National Park\n\n###\n\n","completion":" Death Valley National Park is an American national park that straddles the California–Nevada border, east of the Sierra Nevada. END"} {"prompt":"Cariad Lloyd\n\n###\n\n","completion":" Katie Cariad Lloyd is a British comedian, actress, writer, and podcaster who has been performing since 2007. END"} {"prompt":"Melothria scabra\n\n###\n\n","completion":" Melothria scabra, also known as the cucamelon, is a vine grown for its edible fruit. END"} {"prompt":"Sunda Kingdom\n\n###\n\n","completion":" The Sunda Kingdom was a Sundanese Hindu kingdom located in the western portion of the island of Java from 669 to around 1579, covering the area of present-day Banten, Jakarta, West Java, and the western part of Central Java. END"} {"prompt":"Rarotonga\n\n###\n\n","completion":" Rarotonga is the most populous of the Cook Islands, with a population of 10,649, out of the country's total resident population of 14,802. END"} {"prompt":"San Germán, Puerto Rico\n\n###\n\n","completion":" San Germán is a municipality located in the southwestern region of Puerto Rico, south of Mayagüez and Maricao, north of Lajas, east of Hormigueros and Cabo Rojo, and west of Sabana Grande. END"} {"prompt":"Prydain\n\n###\n\n","completion":" Prydain is the modern Welsh name for Great Britain. END"} {"prompt":"Deep Springs Valley\n\n###\n\n","completion":" Deep Springs Valley is a high desert valley in the Inyo-White Mountains of Inyo County, California. END"} {"prompt":"Alija Izetbegović\n\n###\n\n","completion":" Alija Izetbegović was a Bosnian politician, lawyer and author, who in 1992 became the first president of the Presidency of the newly independent Republic of Bosnia and Herzegovina. END"} {"prompt":"Orange County, New York\n\n###\n\n","completion":" Orange County is a county located in the U.S. state of New York. END"} {"prompt":"List of historic properties in Black Canyon City, Arizona\n\n###\n\n","completion":" This is a list, which includes a photographic gallery, of some of the remaining structures and monuments, of historic significance in Black Canyon City, a town in Yavapai County, Arizona. END"} {"prompt":"Queen Mother Reservoir\n\n###\n\n","completion":" The Queen Mother Reservoir is a public water supply reservoir that lies between the M4 and the M25 to the west of London. END"} {"prompt":"Frank D. Thompson\n\n###\n\n","completion":" Frank D. Thompson was a Vermont attorney and judge. END"} {"prompt":"Medical jurisprudence\n\n###\n\n","completion":" Medical jurisprudence or legal medicine is the branch of science and medicine involving the study and application of scientific and medical knowledge to legal problems, such as inquests, and in the field of law. END"} {"prompt":"St. Louis\n\n###\n\n","completion":" St. Louis is a city in Missouri, on the western bank of the Mississippi River, which forms the state line between Illinois and Missouri. END"} {"prompt":"Social Democratic Labour Party of Norway\n\n###\n\n","completion":" The Social Democratic Labour Party of Norway was a Norwegian political party in the 1920s. END"} {"prompt":"Ramsey Island\n\n###\n\n","completion":" Ramsey Island is an island about 1 kilometre off St David's Head in Pembrokeshire on the northern side of St Brides Bay, in southwest Wales. END"} {"prompt":"Raaberbahn\n\n###\n\n","completion":" The Raaberbahn or GySEV is a Hungarian-Austrian railway company based in Sopron, Hungary. END"} {"prompt":"Paul Judge\n\n###\n\n","completion":" Sir Paul Rupert Judge was an English business and political figure. END"} {"prompt":"Clifton Reynes\n\n###\n\n","completion":" Clifton Reynes is a village and civil parish in the Borough of Milton Keynes, Buckinghamshire, England. END"} {"prompt":"Võõpste\n\n###\n\n","completion":" Võõpste is a village in Kastre Parish, Tartu County in eastern Estonia. END"} {"prompt":"Leningrad Oblast\n\n###\n\n","completion":" Leningrad Oblast is a federal subject of Russia. END"} {"prompt":"Hoboken Terminal\n\n###\n\n","completion":" Hoboken Terminal is a commuter-oriented intermodal passenger station in Hoboken, Hudson County, New Jersey, United States. END"} {"prompt":"Reid and Sigrist R.S.3\n\n###\n\n","completion":" The Reid and Sigrist R.S.3 Desford was a British twin-engined, three-seat advanced trainer developed in the Second World War for postwar use. END"} {"prompt":"Carrie Gracie\n\n###\n\n","completion":" Carrie Gracie is a Scottish journalist and newsreader best-known as having been China Editor for BBC News. END"} {"prompt":"Scottish Reformation\n\n###\n\n","completion":" The Scottish Reformation was the process by which Scotland broke with the Papacy and developed a predominantly Calvinist national Kirk, which was strongly Presbyterian in its outlook. END"} {"prompt":"Ornithomimus\n\n###\n\n","completion":" Ornithomimus is a genus of ornithomimid dinosaurs from the Late Cretaceous Period of what is now North America. END"} {"prompt":"Lars Fredrik Nilson\n\n###\n\n","completion":" Lars Fredrik Nilson was a Swedish chemist, professor at Uppsala University, and later Director of the Agricultural Chemical Experiment Station at the Royal Swedish Academy of Agriculture and Forestry in Stockholm. END"} {"prompt":"2006 Rally Argentina\n\n###\n\n","completion":" The 26° Rally Argentina, the sixth round of the 2006 World Rally Championship season took place between April 27 and April 30, 2006. END"} {"prompt":"2002 FA Community Shield\n\n###\n\n","completion":" The 2002 FA Community Shield was the 80th FA Community Shield, an annual English football match played between the winners of the previous season's Premier League and FA Cup. END"} ================================================ FILE: Examples/iOS_Example/iOS_Example/File/FileDetailsView.swift ================================================ // // FileDetailsView.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct FileDetailsView: View { var file: File var body: some View { VStack { Text("ID: \(file.id)") Text("Object: \(file.object.rawValue)") Text("Bytes: \(file.bytes)") Text("Created At: \(String(file.createdAt))") Text("Filename: \(file.filename)") Text("Purpose: \(file.purpose)") } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/File/FileMainView.swift ================================================ // // FileMainView.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI struct FileMainView: View { var body: some View { List { NavigationLink(destination: DeleteFileExample()) { Text("Delete File Example") } NavigationLink(destination: ListFilesExample()) { Text("List Files Example") } NavigationLink(destination: RetrieveFileExample()) { Text("Retrieve File Example") } NavigationLink(destination: RetrieveFileContentsExample()) { Text("Retrieve File Contents Example") } NavigationLink(destination: UploadFileExample()) { Text("Upload File Example") } } .listStyle(.plain) .navigationTitle("File") } } struct FileMainView_Previews: PreviewProvider { static var previews: some View { NavigationStack { FileMainView() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/File/ListFilesExample.swift ================================================ // // ListFilesExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct ListFilesExample: View { @State private var files: [File]? @State private var isListing: Bool = false var body: some View { if isListing { if let files = files { if files.isEmpty { Text("No files found.") } else { List(files) { file in NavigationLink(file.id) { FileDetailsView(file: file) } } .padding() } } else { Text("Loading files...") } } else { VStack { Button { isListing = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration(organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY") let openAI = OpenAI(config) let filesResponse = try await openAI.listFiles() self.files = filesResponse.data } catch { print("ERROR - \(error)") } } } label: { Text("List Files") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct ListFilesExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { ListFilesExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/File/RetrieveFileContentsExample.swift ================================================ // // RetrieveFileContentsExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct RetrieveFileContentsExample: View { @State private var files: [FileContent]? @State private var isRetrieving: Bool = false var body: some View { if isRetrieving { VStack { if let files = self.files { Text("Retrieved file!") Text("Files size: \(files.count)") Text("First three indexes (see log for full object): ") Text("\(files[0].prompt) - \(files[0].completion)") Text("\(files[1].prompt) - \(files[1].completion)") Text("\(files[2].prompt) - \(files[2].completion)") } else { Text("Retrieving file...") } } .padding() } else { VStack { Button { isRetrieving = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration(organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY") let openAI = OpenAI(config) self.files = try await openAI.retrieveFileContent(fileId: "INSERT-FILE-ID") } catch { print("ERROR - \(error)") } } } label: { Text("Retrieve File Contents") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct RetrieveFileContentsExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { RetrieveFileContentsExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/File/RetrieveFileExample.swift ================================================ // // RetrieveFileExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct RetrieveFileExample: View { @State private var file: File? @State private var isRetrieving: Bool = false var body: some View { if isRetrieving { VStack { if let file = file { Text("Loading file complete!") Text("ID: \(file.id)") Text("Object: \(file.object.rawValue)") Text("Size: \(file.bytes)") Text("Created At: \(String(file.createdAt))") Text("Filename: \(file.filename)") Text("Purpose: \(file.purpose)") } else { Text("Loading file...") } } .padding() } else { VStack { Button { isRetrieving = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration(organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY") let openAI = OpenAI(config) self.file = try await openAI.retrieveFile(fileId: "INSERT-FILE-ID") } catch { print("ERROR - \(error)") } } } label: { Text("Retrieve File") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct RetrieveFileExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { RetrieveFileExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/File/UploadFileExample.swift ================================================ // // UploadFileExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct UploadFileExample: View { @State private var file: File? @State private var isUploading: Bool = false var body: some View { if isUploading { VStack { if let file = file { Text("Upload complete!") Text("ID: \(file.id)") Text("Object: \(file.object.rawValue)") Text("Size: \(file.bytes)") Text("Created At: \(String(file.createdAt))") Text("Filename: \(file.filename)") Text("Purpose: \(file.purpose)") } else { Text("Uploading file...") } } .padding() } else { VStack { Button { isUploading = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration(organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY") let openAI = OpenAI(config) guard let urlFile = Bundle.main.url( forResource: "SampleData", withExtension: "jsonl" ) else { throw OpenAIError.invalidData } guard let jsonData = try? Data(contentsOf: urlFile) else { throw OpenAIError.invalidUrl } let uploadFileParam = UploadFileParameters( file: jsonData, fileName: "SampleData.jsonl", purpose: "fine-tune" ) self.file = try await openAI.uploadFile(parameters: uploadFileParam) } catch { print("ERROR - \(error)") } } } label: { Text("Upload File") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct UploadFileExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { UploadFileExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Image/EditImageExample.swift ================================================ // // EditImageExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct EditImageExample: View { @State private var image: UIImage = UIImage() @State private var isEditing: Bool = false var body: some View { if isEditing { VStack { if image == UIImage() { Text("Loading edit...") } else { Image(uiImage: image) } } .padding() } else { VStack { Button { isEditing = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration( organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAI = OpenAI(config) guard let image = UIImage(named: "image") else { throw OpenAIError.invalidData } guard let mask = UIImage(named: "mask") else { throw OpenAIError.invalidData } let imageEditParam = try ImageEditParameters( image: image, mask: mask, prompt: "A cute baby sea otter wearing a beret", resolution: .small, responseFormat: .base64Json ) let imageResponse = try await openAI.generateImageEdits( parameters: imageEditParam ) self.image = try openAI .decodeBase64Image(imageResponse.data[0].image) } catch { print("ERROR - \(error)") } } } label: { Text("Edit Image") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct EditImageExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { EditImageExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Image/GenerateImageExample.swift ================================================ // // GenerateImageExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct GenerateImageExample: View { @State private var image: UIImage = UIImage() @State private var isGenerating: Bool = false var body: some View { if isGenerating { VStack { Image(uiImage: image) } .padding() } else { VStack { Button { isGenerating = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration( organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAi = OpenAI(config) let imageParam = ImageParameters( prompt: "an avocado chair", resolution: .extraLargePortrait, quality: .hd, model: .dalle3, responseFormat: .base64Json ) let result = try await openAi.createImage(parameters: imageParam) let b64Image = result.data[0].image self.image = try openAi.decodeBase64Image(b64Image) } catch { print("ERROR DETAILS - \(error)") } } } label: { Text("Generate Image") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct GenerateImageExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { GenerateImageExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Image/GenerateImageVariationsExample.swift ================================================ // // GenerateImageVariationExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct GenerateImageVariationExample: View { @State private var image: UIImage = UIImage() @State private var isGeneratingVariation: Bool = false var body: some View { if isGeneratingVariation { VStack { if image == UIImage() { Text("Variation is loading...") } else { Image(uiImage: image) } } .padding() } else { VStack { Button { isGeneratingVariation = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration( organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAI = OpenAI(config) guard let image = UIImage(named: "variation") else { throw OpenAIError.invalidData } let imageVariationParam = try ImageVariationParameters( image: image, resolution: .small, responseFormat: .base64Json ) let variationResponse = try await openAI.generateImageVariations( parameters: imageVariationParam ) self.image = try openAI.decodeBase64Image( variationResponse.data[0].image ) } catch { print("ERROR - \(error)") } } } label: { Text("Generate Variations") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct GenerateImageVariationExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { GenerateImageVariationExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Image/ImageMainView.swift ================================================ // // ImageMainView.swift // iOS_Example // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI struct ImageMainView: View { var body: some View { List { NavigationLink(destination: GenerateImageExample()) { Text("Generate Image Example") } NavigationLink(destination: EditImageExample()) { Text("Edit Image Example") } NavigationLink(destination: GenerateImageVariationExample()) { Text("Generate Image Variation Example") } } .listStyle(.plain) .navigationTitle("Image") } } struct ImageMainView_Previews: PreviewProvider { static var previews: some View { NavigationStack { ImageMainView() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Model/ListModelsExample.swift ================================================ // // ListModelsExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct ListModelsExample: View { @State private var models = [Model]() @State private var isListing: Bool = false var body: some View { if isListing { if !models.isEmpty { List(models) { model in Text("\(model.id)") } } else { Text("Loading Models...") } } else { VStack { Button { isListing = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration( organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAi = OpenAI(config) let modelsResponse = try await openAi.listModels() self.models = modelsResponse.data } catch { print("ERROR DETAILS - \(error)") } } } label: { Text("List Models") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct ListModelsExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { ListModelsExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Model/ModelMainView.swift ================================================ // // ModelMainView.swift // iOS_Example // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI struct ModelMainView: View { var body: some View { List { NavigationLink(destination: ListModelsExample()) { Text("List Models Example") } NavigationLink(destination: RetrieveModelExample()) { Text("Retrieve Model Example") } } .listStyle(.plain) .navigationTitle("Model") } } struct ModelMainView_Previews: PreviewProvider { static var previews: some View { NavigationStack { ModelMainView() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Model/RetrieveModelExample.swift ================================================ // // RetrieveModelExample.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct RetrieveModelExample: View { @State private var model: Model? @State private var isRetrieving: Bool = false var body: some View { if isRetrieving { VStack { if let model = model { Text("Model Details").bold().font(.title) Text("Name: \(model.id)") Text("Object: \(model.object.rawValue)") Text("Owned By: \(model.ownedBy)") } else { Text("Loading Model...") } } .padding() } else { VStack { Button { isRetrieving = true Task { do { // ⚠️🔑 NEVER store OpenAI API keys directly in code. Use environment variables or secrets management. Avoid git commits of keys! 🔑⚠️ let config = Configuration(organizationId: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY") let openAI = OpenAI(config) self.model = try await openAI.retrieveModel(modelId: "text-davinci-001") } catch { print("ERROR WITH - \(error)") } } } label: { Text("Retrieve Model") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct RetrieveModelExample_Previews: PreviewProvider { static var previews: some View { NavigationStack { RetrieveModelExample() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example/Preview Content/Preview Assets.xcassets/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/iOS_Example/iOS_Example/iOS_ExampleApp.swift ================================================ // // iOS_ExampleApp.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI @main struct iOS_ExampleApp: App { var body: some Scene { WindowGroup { ContentView() } } } ================================================ FILE: Examples/iOS_Example/iOS_Example.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 56; objects = { /* Begin PBXBuildFile section */ 761C250429403883005066C2 /* EditImageExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C250329403883005066C2 /* EditImageExample.swift */; }; 761C250B2940392F005066C2 /* GenerateCompletionExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C250A2940392F005066C2 /* GenerateCompletionExample.swift */; }; 761C250D294039A8005066C2 /* GenerateImageVariationsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C250C294039A8005066C2 /* GenerateImageVariationsExample.swift */; }; 761C251329403AC7005066C2 /* GenerateImageExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C251229403AC7005066C2 /* GenerateImageExample.swift */; }; 761C251729403CA0005066C2 /* ListFilesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C251629403CA0005066C2 /* ListFilesExample.swift */; }; 761C251B29403CD2005066C2 /* FileDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C251A29403CD2005066C2 /* FileDetailsView.swift */; }; 761C252429403EDC005066C2 /* ListModelsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C252329403EDC005066C2 /* ListModelsExample.swift */; }; 761C252629403F3F005066C2 /* RetrieveFileContentsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C252529403F3F005066C2 /* RetrieveFileContentsExample.swift */; }; 761C252829403F7D005066C2 /* RetrieveFileExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C252729403F7D005066C2 /* RetrieveFileExample.swift */; }; 761C252C2940400B005066C2 /* RetrieveModelExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C252B2940400B005066C2 /* RetrieveModelExample.swift */; }; 761C253129404086005066C2 /* SampleData.jsonl in Resources */ = {isa = PBXBuildFile; fileRef = 761C253029404086005066C2 /* SampleData.jsonl */; }; 761C2533294040A8005066C2 /* UploadFileExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C2532294040A8005066C2 /* UploadFileExample.swift */; }; 765BB1D7294049B4000BF124 /* FileMainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB1D6294049B4000BF124 /* FileMainView.swift */; }; 765BB1D929404D52000BF124 /* CompletionMainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB1D829404D52000BF124 /* CompletionMainView.swift */; }; 765BB1DB29404F7C000BF124 /* ImageMainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB1DA29404F7C000BF124 /* ImageMainView.swift */; }; 765BB1DD29405126000BF124 /* ModelMainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB1DC29405126000BF124 /* ModelMainView.swift */; }; 765BB20129405723000BF124 /* variation.png in Resources */ = {isa = PBXBuildFile; fileRef = 765BB1FE29405723000BF124 /* variation.png */; }; 765BB20229405723000BF124 /* mask.png in Resources */ = {isa = PBXBuildFile; fileRef = 765BB1FF29405723000BF124 /* mask.png */; }; 765BB20329405723000BF124 /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = 765BB20029405723000BF124 /* image.png */; }; 76C0C254293FB7CC003075D2 /* iOS_ExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76C0C253293FB7CC003075D2 /* iOS_ExampleApp.swift */; }; 76C0C256293FB7CC003075D2 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76C0C255293FB7CC003075D2 /* ContentView.swift */; }; 76C0C258293FB7CE003075D2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 76C0C257293FB7CE003075D2 /* Assets.xcassets */; }; 76C0C25B293FB7CE003075D2 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 76C0C25A293FB7CE003075D2 /* Preview Assets.xcassets */; }; 76C0C265293FB8B6003075D2 /* OpenAIKit in Frameworks */ = {isa = PBXBuildFile; productRef = 76C0C264293FB8B6003075D2 /* OpenAIKit */; }; 76C0C26A293FC8FC003075D2 /* ContentPolicyExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76C0C269293FC8FC003075D2 /* ContentPolicyExample.swift */; }; 76C0C26D293FC9B5003075D2 /* CreateEmbeddingsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76C0C26C293FC9B5003075D2 /* CreateEmbeddingsExample.swift */; }; 76C0C274293FDA7B003075D2 /* DeleteFileExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76C0C273293FDA7B003075D2 /* DeleteFileExample.swift */; }; 7D3E2ED72A7F228E0014174B /* CreateChatCompletionStreaming.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D3E2ED62A7F228E0014174B /* CreateChatCompletionStreaming.swift */; }; 7D3E2ED92A7F262A0014174B /* ChatMainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D3E2ED82A7F262A0014174B /* ChatMainView.swift */; }; 7D4A91082A87DE7E000A138A /* AudioPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D4A91072A87DE7E000A138A /* AudioPlayerViewModel.swift */; }; 7D4A910A2A87E110000A138A /* audio_translation.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 7D4A91092A87E110000A138A /* audio_translation.mp3 */; }; 7D6C8EB92B689D750049AC43 /* audio.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 7D6C8EB82B689D750049AC43 /* audio.mp3 */; }; 7D76E4F82AD46B7500E2F4C3 /* CreateChatFunctionCallExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D76E4F72AD46B7500E2F4C3 /* CreateChatFunctionCallExample.swift */; }; 7DC0E9082A87CF97005C8763 /* CreateTranscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DC0E9072A87CF97005C8763 /* CreateTranscription.swift */; }; 7DDE422E29AFE567000BBB01 /* CreateChatCompletion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DDE422D29AFE567000BBB01 /* CreateChatCompletion.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 761C250329403883005066C2 /* EditImageExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditImageExample.swift; sourceTree = ""; }; 761C250A2940392F005066C2 /* GenerateCompletionExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerateCompletionExample.swift; sourceTree = ""; }; 761C250C294039A8005066C2 /* GenerateImageVariationsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerateImageVariationsExample.swift; sourceTree = ""; }; 761C251229403AC7005066C2 /* GenerateImageExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerateImageExample.swift; sourceTree = ""; }; 761C251629403CA0005066C2 /* ListFilesExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFilesExample.swift; sourceTree = ""; }; 761C251A29403CD2005066C2 /* FileDetailsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileDetailsView.swift; sourceTree = ""; }; 761C252329403EDC005066C2 /* ListModelsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListModelsExample.swift; sourceTree = ""; }; 761C252529403F3F005066C2 /* RetrieveFileContentsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RetrieveFileContentsExample.swift; sourceTree = ""; }; 761C252729403F7D005066C2 /* RetrieveFileExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RetrieveFileExample.swift; sourceTree = ""; }; 761C252B2940400B005066C2 /* RetrieveModelExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RetrieveModelExample.swift; sourceTree = ""; }; 761C253029404086005066C2 /* SampleData.jsonl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SampleData.jsonl; sourceTree = ""; }; 761C2532294040A8005066C2 /* UploadFileExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadFileExample.swift; sourceTree = ""; }; 765BB1D6294049B4000BF124 /* FileMainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileMainView.swift; sourceTree = ""; }; 765BB1D829404D52000BF124 /* CompletionMainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionMainView.swift; sourceTree = ""; }; 765BB1DA29404F7C000BF124 /* ImageMainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageMainView.swift; sourceTree = ""; }; 765BB1DC29405126000BF124 /* ModelMainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelMainView.swift; sourceTree = ""; }; 765BB1FE29405723000BF124 /* variation.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = variation.png; sourceTree = ""; }; 765BB1FF29405723000BF124 /* mask.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = mask.png; sourceTree = ""; }; 765BB20029405723000BF124 /* image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = image.png; sourceTree = ""; }; 76C0C250293FB7CC003075D2 /* iOS_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOS_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 76C0C253293FB7CC003075D2 /* iOS_ExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOS_ExampleApp.swift; sourceTree = ""; }; 76C0C255293FB7CC003075D2 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 76C0C257293FB7CE003075D2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 76C0C25A293FB7CE003075D2 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 76C0C263293FB8B0003075D2 /* OpenAIKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = OpenAIKit; path = ../..; sourceTree = ""; }; 76C0C269293FC8FC003075D2 /* ContentPolicyExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentPolicyExample.swift; sourceTree = ""; }; 76C0C26C293FC9B5003075D2 /* CreateEmbeddingsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateEmbeddingsExample.swift; sourceTree = ""; }; 76C0C273293FDA7B003075D2 /* DeleteFileExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteFileExample.swift; sourceTree = ""; }; 7D3E2ED62A7F228E0014174B /* CreateChatCompletionStreaming.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateChatCompletionStreaming.swift; sourceTree = ""; }; 7D3E2ED82A7F262A0014174B /* ChatMainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMainView.swift; sourceTree = ""; }; 7D4A91072A87DE7E000A138A /* AudioPlayerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayerViewModel.swift; sourceTree = ""; }; 7D4A91092A87E110000A138A /* audio_translation.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = audio_translation.mp3; sourceTree = ""; }; 7D6C8EB82B689D750049AC43 /* audio.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = audio.mp3; path = "../../../../../../../Library/Mobile Documents/com~apple~CloudDocs/Desktop/Desktop - Marcus’s Mac mini/OpenAIKit/Examples/iOS_Example/iOS_Example/Audio/audio.mp3"; sourceTree = ""; }; 7D76E4F72AD46B7500E2F4C3 /* CreateChatFunctionCallExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateChatFunctionCallExample.swift; sourceTree = ""; }; 7DC0E9072A87CF97005C8763 /* CreateTranscription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateTranscription.swift; sourceTree = ""; }; 7DDE422D29AFE567000BBB01 /* CreateChatCompletion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateChatCompletion.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 76C0C24D293FB7CC003075D2 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 76C0C265293FB8B6003075D2 /* OpenAIKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 761C24FE2940347A005066C2 /* Completion */ = { isa = PBXGroup; children = ( 761C250A2940392F005066C2 /* GenerateCompletionExample.swift */, 765BB1D829404D52000BF124 /* CompletionMainView.swift */, ); path = Completion; sourceTree = ""; }; 761C250229403873005066C2 /* Image */ = { isa = PBXGroup; children = ( 765BB1FD29405723000BF124 /* Images */, 761C251229403AC7005066C2 /* GenerateImageExample.swift */, 761C250329403883005066C2 /* EditImageExample.swift */, 761C250C294039A8005066C2 /* GenerateImageVariationsExample.swift */, 765BB1DA29404F7C000BF124 /* ImageMainView.swift */, ); path = Image; sourceTree = ""; }; 761C252229403ECF005066C2 /* Model */ = { isa = PBXGroup; children = ( 761C252329403EDC005066C2 /* ListModelsExample.swift */, 761C252B2940400B005066C2 /* RetrieveModelExample.swift */, 765BB1DC29405126000BF124 /* ModelMainView.swift */, ); path = Model; sourceTree = ""; }; 761C252F29404086005066C2 /* File */ = { isa = PBXGroup; children = ( 761C253029404086005066C2 /* SampleData.jsonl */, ); path = File; sourceTree = ""; }; 765BB1FD29405723000BF124 /* Images */ = { isa = PBXGroup; children = ( 765BB1FE29405723000BF124 /* variation.png */, 765BB1FF29405723000BF124 /* mask.png */, 765BB20029405723000BF124 /* image.png */, ); path = Images; sourceTree = ""; }; 76C0C247293FB7CC003075D2 = { isa = PBXGroup; children = ( 76C0C252293FB7CC003075D2 /* iOS_Example */, 76C0C251293FB7CC003075D2 /* Products */, 76C0C262293FB8AF003075D2 /* Frameworks */, ); sourceTree = ""; }; 76C0C251293FB7CC003075D2 /* Products */ = { isa = PBXGroup; children = ( 76C0C250293FB7CC003075D2 /* iOS_Example.app */, ); name = Products; sourceTree = ""; }; 76C0C252293FB7CC003075D2 /* iOS_Example */ = { isa = PBXGroup; children = ( 7DC0E9062A87CF6F005C8763 /* Audio */, 7DDE422C29AFE54C000BBB01 /* Chat */, 761C252229403ECF005066C2 /* Model */, 761C250229403873005066C2 /* Image */, 761C24FE2940347A005066C2 /* Completion */, 76C0C26B293FC9A6003075D2 /* Embeddings */, 76C0C272293FDA65003075D2 /* File */, 76C0C268293FC8DF003075D2 /* Content Policy */, 76C0C253293FB7CC003075D2 /* iOS_ExampleApp.swift */, 76C0C255293FB7CC003075D2 /* ContentView.swift */, 76C0C257293FB7CE003075D2 /* Assets.xcassets */, 76C0C259293FB7CE003075D2 /* Preview Content */, ); path = iOS_Example; sourceTree = ""; }; 76C0C259293FB7CE003075D2 /* Preview Content */ = { isa = PBXGroup; children = ( 76C0C25A293FB7CE003075D2 /* Preview Assets.xcassets */, ); path = "Preview Content"; sourceTree = ""; }; 76C0C262293FB8AF003075D2 /* Frameworks */ = { isa = PBXGroup; children = ( 76C0C263293FB8B0003075D2 /* OpenAIKit */, ); name = Frameworks; sourceTree = ""; }; 76C0C268293FC8DF003075D2 /* Content Policy */ = { isa = PBXGroup; children = ( 76C0C269293FC8FC003075D2 /* ContentPolicyExample.swift */, ); path = "Content Policy"; sourceTree = ""; }; 76C0C26B293FC9A6003075D2 /* Embeddings */ = { isa = PBXGroup; children = ( 76C0C26C293FC9B5003075D2 /* CreateEmbeddingsExample.swift */, ); path = Embeddings; sourceTree = ""; }; 76C0C272293FDA65003075D2 /* File */ = { isa = PBXGroup; children = ( 761C252F29404086005066C2 /* File */, 761C251A29403CD2005066C2 /* FileDetailsView.swift */, 76C0C273293FDA7B003075D2 /* DeleteFileExample.swift */, 761C251629403CA0005066C2 /* ListFilesExample.swift */, 761C252529403F3F005066C2 /* RetrieveFileContentsExample.swift */, 761C252729403F7D005066C2 /* RetrieveFileExample.swift */, 761C2532294040A8005066C2 /* UploadFileExample.swift */, 765BB1D6294049B4000BF124 /* FileMainView.swift */, ); path = File; sourceTree = ""; }; 7DC0E9062A87CF6F005C8763 /* Audio */ = { isa = PBXGroup; children = ( 7DC0E90B2A87D04D005C8763 /* Sound */, 7DC0E9072A87CF97005C8763 /* CreateTranscription.swift */, 7D4A91072A87DE7E000A138A /* AudioPlayerViewModel.swift */, ); path = Audio; sourceTree = ""; }; 7DC0E90B2A87D04D005C8763 /* Sound */ = { isa = PBXGroup; children = ( 7D6C8EB82B689D750049AC43 /* audio.mp3 */, 7D4A91092A87E110000A138A /* audio_translation.mp3 */, ); path = Sound; sourceTree = ""; }; 7DDE422C29AFE54C000BBB01 /* Chat */ = { isa = PBXGroup; children = ( 7DDE422D29AFE567000BBB01 /* CreateChatCompletion.swift */, 7D3E2ED62A7F228E0014174B /* CreateChatCompletionStreaming.swift */, 7D3E2ED82A7F262A0014174B /* ChatMainView.swift */, 7D76E4F72AD46B7500E2F4C3 /* CreateChatFunctionCallExample.swift */, ); path = Chat; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 76C0C24F293FB7CC003075D2 /* iOS_Example */ = { isa = PBXNativeTarget; buildConfigurationList = 76C0C25E293FB7CE003075D2 /* Build configuration list for PBXNativeTarget "iOS_Example" */; buildPhases = ( 76C0C24C293FB7CC003075D2 /* Sources */, 76C0C24D293FB7CC003075D2 /* Frameworks */, 76C0C24E293FB7CC003075D2 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = iOS_Example; packageProductDependencies = ( 76C0C264293FB8B6003075D2 /* OpenAIKit */, ); productName = iOS_Example; productReference = 76C0C250293FB7CC003075D2 /* iOS_Example.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 76C0C248293FB7CC003075D2 /* Project object */ = { isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1410; LastUpgradeCheck = 1520; TargetAttributes = { 76C0C24F293FB7CC003075D2 = { CreatedOnToolsVersion = 14.1; }; }; }; buildConfigurationList = 76C0C24B293FB7CC003075D2 /* Build configuration list for PBXProject "iOS_Example" */; compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 76C0C247293FB7CC003075D2; productRefGroup = 76C0C251293FB7CC003075D2 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 76C0C24F293FB7CC003075D2 /* iOS_Example */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 76C0C24E293FB7CC003075D2 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 76C0C25B293FB7CE003075D2 /* Preview Assets.xcassets in Resources */, 765BB20229405723000BF124 /* mask.png in Resources */, 765BB20129405723000BF124 /* variation.png in Resources */, 7D6C8EB92B689D750049AC43 /* audio.mp3 in Resources */, 7D4A910A2A87E110000A138A /* audio_translation.mp3 in Resources */, 76C0C258293FB7CE003075D2 /* Assets.xcassets in Resources */, 761C253129404086005066C2 /* SampleData.jsonl in Resources */, 765BB20329405723000BF124 /* image.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 76C0C24C293FB7CC003075D2 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 7D3E2ED92A7F262A0014174B /* ChatMainView.swift in Sources */, 76C0C26D293FC9B5003075D2 /* CreateEmbeddingsExample.swift in Sources */, 76C0C274293FDA7B003075D2 /* DeleteFileExample.swift in Sources */, 765BB1DB29404F7C000BF124 /* ImageMainView.swift in Sources */, 761C250D294039A8005066C2 /* GenerateImageVariationsExample.swift in Sources */, 761C252629403F3F005066C2 /* RetrieveFileContentsExample.swift in Sources */, 7D76E4F82AD46B7500E2F4C3 /* CreateChatFunctionCallExample.swift in Sources */, 765BB1DD29405126000BF124 /* ModelMainView.swift in Sources */, 76C0C26A293FC8FC003075D2 /* ContentPolicyExample.swift in Sources */, 765BB1D929404D52000BF124 /* CompletionMainView.swift in Sources */, 76C0C256293FB7CC003075D2 /* ContentView.swift in Sources */, 761C251329403AC7005066C2 /* GenerateImageExample.swift in Sources */, 761C251B29403CD2005066C2 /* FileDetailsView.swift in Sources */, 761C252C2940400B005066C2 /* RetrieveModelExample.swift in Sources */, 761C251729403CA0005066C2 /* ListFilesExample.swift in Sources */, 7DDE422E29AFE567000BBB01 /* CreateChatCompletion.swift in Sources */, 7D3E2ED72A7F228E0014174B /* CreateChatCompletionStreaming.swift in Sources */, 7DC0E9082A87CF97005C8763 /* CreateTranscription.swift in Sources */, 761C252829403F7D005066C2 /* RetrieveFileExample.swift in Sources */, 7D4A91082A87DE7E000A138A /* AudioPlayerViewModel.swift in Sources */, 761C2533294040A8005066C2 /* UploadFileExample.swift in Sources */, 761C252429403EDC005066C2 /* ListModelsExample.swift in Sources */, 76C0C254293FB7CC003075D2 /* iOS_ExampleApp.swift in Sources */, 765BB1D7294049B4000BF124 /* FileMainView.swift in Sources */, 761C250429403883005066C2 /* EditImageExample.swift in Sources */, 761C250B2940392F005066C2 /* GenerateCompletionExample.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 76C0C25C293FB7CE003075D2 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 76C0C25D293FB7CE003075D2 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; VALIDATE_PRODUCT = YES; }; name = Release; }; 76C0C25F293FB7CE003075D2 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"iOS_Example/Preview Content\""; DEVELOPMENT_TEAM = 8GNE6ML5WX; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = "com.MarcoDotIO.iOS-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 76C0C260293FB7CE003075D2 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"iOS_Example/Preview Content\""; DEVELOPMENT_TEAM = 8GNE6ML5WX; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = "com.MarcoDotIO.iOS-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 76C0C24B293FB7CC003075D2 /* Build configuration list for PBXProject "iOS_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( 76C0C25C293FB7CE003075D2 /* Debug */, 76C0C25D293FB7CE003075D2 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 76C0C25E293FB7CE003075D2 /* Build configuration list for PBXNativeTarget "iOS_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( 76C0C25F293FB7CE003075D2 /* Debug */, 76C0C260293FB7CE003075D2 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ 76C0C264293FB8B6003075D2 /* OpenAIKit */ = { isa = XCSwiftPackageProductDependency; productName = OpenAIKit; }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 76C0C248293FB7CC003075D2 /* Project object */; } ================================================ FILE: Examples/iOS_Example/iOS_Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Examples/iOS_Example/iOS_Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: Examples/macOS_Example/macOS_Example/Assets.xcassets/AccentColor.colorset/Contents.json ================================================ { "colors" : [ { "idiom" : "universal" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/macOS_Example/macOS_Example/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "mac", "scale" : "1x", "size" : "16x16" }, { "idiom" : "mac", "scale" : "2x", "size" : "16x16" }, { "idiom" : "mac", "scale" : "1x", "size" : "32x32" }, { "idiom" : "mac", "scale" : "2x", "size" : "32x32" }, { "idiom" : "mac", "scale" : "1x", "size" : "128x128" }, { "idiom" : "mac", "scale" : "2x", "size" : "128x128" }, { "idiom" : "mac", "scale" : "1x", "size" : "256x256" }, { "idiom" : "mac", "scale" : "2x", "size" : "256x256" }, { "idiom" : "mac", "scale" : "1x", "size" : "512x512" }, { "idiom" : "mac", "scale" : "2x", "size" : "512x512" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/macOS_Example/macOS_Example/Assets.xcassets/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/macOS_Example/macOS_Example/ContentView.swift ================================================ // // ContentView.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct ContentView: View { @State private var image: NSImage = NSImage() @State private var isGenerating: Bool = false var body: some View { if isGenerating { VStack { Image(nsImage: image) } .padding() } else { VStack { Button { isGenerating = true Task { do { let config = Configuration( organization: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAi = OpenAI(config) let imageParam = ImageParameters( prompt: "an avocado chair", resolution: .small, responseFormat: .base64Json ) let result = try await openAi.createImage(parameters: imageParam) let b64Image = result.data[0].image self.image = try openAi.decodeBase64Image(b64Image) } catch { print("ERROR DETAILS - \(error)") } } } label: { Text("Generate Image") .font(.headline) .foregroundColor(.white) .frame(width: 270, height: 50) .background(.blue) .clipShape(Capsule()) .padding(.top, 8) } } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } ================================================ FILE: Examples/macOS_Example/macOS_Example/Preview Content/Preview Assets.xcassets/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/macOS_Example/macOS_Example/macOS_Example.entitlements ================================================ com.apple.security.app-sandbox com.apple.security.files.user-selected.read-only com.apple.security.network.client com.apple.security.network.server ================================================ FILE: Examples/macOS_Example/macOS_Example/macOS_ExampleApp.swift ================================================ // // macOS_ExampleApp.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI @main struct macOS_ExampleApp: App { var body: some Scene { WindowGroup { ContentView() } } } ================================================ FILE: Examples/macOS_Example/macOS_Example.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 56; objects = { /* Begin PBXBuildFile section */ 765BB1EB29405298000BF124 /* macOS_ExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB1EA29405298000BF124 /* macOS_ExampleApp.swift */; }; 765BB1ED29405298000BF124 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB1EC29405298000BF124 /* ContentView.swift */; }; 765BB1EF29405299000BF124 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 765BB1EE29405299000BF124 /* Assets.xcassets */; }; 765BB1F229405299000BF124 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 765BB1F129405299000BF124 /* Preview Assets.xcassets */; }; 765BB1FC29405308000BF124 /* OpenAIKit in Frameworks */ = {isa = PBXBuildFile; productRef = 765BB1FB29405308000BF124 /* OpenAIKit */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 765BB1E729405298000BF124 /* macOS_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = macOS_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 765BB1EA29405298000BF124 /* macOS_ExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = macOS_ExampleApp.swift; sourceTree = ""; }; 765BB1EC29405298000BF124 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 765BB1EE29405299000BF124 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 765BB1F129405299000BF124 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 765BB1F329405299000BF124 /* macOS_Example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS_Example.entitlements; sourceTree = ""; }; 765BB1FA29405304000BF124 /* OpenAIKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = OpenAIKit; path = ../..; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 765BB1E429405298000BF124 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 765BB1FC29405308000BF124 /* OpenAIKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 765BB1DE29405298000BF124 = { isa = PBXGroup; children = ( 765BB1E929405298000BF124 /* macOS_Example */, 765BB1E829405298000BF124 /* Products */, 765BB1F929405304000BF124 /* Frameworks */, ); sourceTree = ""; }; 765BB1E829405298000BF124 /* Products */ = { isa = PBXGroup; children = ( 765BB1E729405298000BF124 /* macOS_Example.app */, ); name = Products; sourceTree = ""; }; 765BB1E929405298000BF124 /* macOS_Example */ = { isa = PBXGroup; children = ( 765BB1EA29405298000BF124 /* macOS_ExampleApp.swift */, 765BB1EC29405298000BF124 /* ContentView.swift */, 765BB1EE29405299000BF124 /* Assets.xcassets */, 765BB1F329405299000BF124 /* macOS_Example.entitlements */, 765BB1F029405299000BF124 /* Preview Content */, ); path = macOS_Example; sourceTree = ""; }; 765BB1F029405299000BF124 /* Preview Content */ = { isa = PBXGroup; children = ( 765BB1F129405299000BF124 /* Preview Assets.xcassets */, ); path = "Preview Content"; sourceTree = ""; }; 765BB1F929405304000BF124 /* Frameworks */ = { isa = PBXGroup; children = ( 765BB1FA29405304000BF124 /* OpenAIKit */, ); name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 765BB1E629405298000BF124 /* macOS_Example */ = { isa = PBXNativeTarget; buildConfigurationList = 765BB1F629405299000BF124 /* Build configuration list for PBXNativeTarget "macOS_Example" */; buildPhases = ( 765BB1E329405298000BF124 /* Sources */, 765BB1E429405298000BF124 /* Frameworks */, 765BB1E529405298000BF124 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = macOS_Example; packageProductDependencies = ( 765BB1FB29405308000BF124 /* OpenAIKit */, ); productName = macOS_Example; productReference = 765BB1E729405298000BF124 /* macOS_Example.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 765BB1DF29405298000BF124 /* Project object */ = { isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1410; LastUpgradeCheck = 1410; TargetAttributes = { 765BB1E629405298000BF124 = { CreatedOnToolsVersion = 14.1; }; }; }; buildConfigurationList = 765BB1E229405298000BF124 /* Build configuration list for PBXProject "macOS_Example" */; compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 765BB1DE29405298000BF124; productRefGroup = 765BB1E829405298000BF124 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 765BB1E629405298000BF124 /* macOS_Example */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 765BB1E529405298000BF124 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 765BB1F229405299000BF124 /* Preview Assets.xcassets in Resources */, 765BB1EF29405299000BF124 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 765BB1E329405298000BF124 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 765BB1ED29405298000BF124 /* ContentView.swift in Sources */, 765BB1EB29405298000BF124 /* macOS_ExampleApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 765BB1F429405299000BF124 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 765BB1F529405299000BF124 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; }; name = Release; }; 765BB1F729405299000BF124 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = macOS_Example/macOS_Example.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"macOS_Example/Preview Content\""; DEVELOPMENT_TEAM = 8GNE6ML5WX; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = "com.MarcoDotIO.macOS-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; }; name = Debug; }; 765BB1F829405299000BF124 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = macOS_Example/macOS_Example.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"macOS_Example/Preview Content\""; DEVELOPMENT_TEAM = 8GNE6ML5WX; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = "com.MarcoDotIO.macOS-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 765BB1E229405298000BF124 /* Build configuration list for PBXProject "macOS_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( 765BB1F429405299000BF124 /* Debug */, 765BB1F529405299000BF124 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 765BB1F629405299000BF124 /* Build configuration list for PBXNativeTarget "macOS_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( 765BB1F729405299000BF124 /* Debug */, 765BB1F829405299000BF124 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ 765BB1FB29405308000BF124 /* OpenAIKit */ = { isa = XCSwiftPackageProductDependency; productName = OpenAIKit; }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 765BB1DF29405298000BF124 /* Project object */; } ================================================ FILE: Examples/macOS_Example/macOS_Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Examples/macOS_Example/macOS_Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/AccentColor.colorset/Contents.json ================================================ { "colors" : [ { "idiom" : "universal" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 }, "layers" : [ { "filename" : "Front.imagestacklayer" }, { "filename" : "Middle.imagestacklayer" }, { "filename" : "Back.imagestacklayer" } ] } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" }, { "idiom" : "tv-marketing", "scale" : "1x" }, { "idiom" : "tv-marketing", "scale" : "2x" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 }, "layers" : [ { "filename" : "Front.imagestacklayer" }, { "filename" : "Middle.imagestacklayer" }, { "filename" : "Back.imagestacklayer" } ] } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" }, { "idiom" : "tv-marketing", "scale" : "1x" }, { "idiom" : "tv-marketing", "scale" : "2x" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" }, { "idiom" : "tv-marketing", "scale" : "1x" }, { "idiom" : "tv-marketing", "scale" : "2x" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json ================================================ { "assets" : [ { "filename" : "App Icon - App Store.imagestack", "idiom" : "tv", "role" : "primary-app-icon", "size" : "1280x768" }, { "filename" : "App Icon.imagestack", "idiom" : "tv", "role" : "primary-app-icon", "size" : "400x240" }, { "filename" : "Top Shelf Image Wide.imageset", "idiom" : "tv", "role" : "top-shelf-image-wide", "size" : "2320x720" }, { "filename" : "Top Shelf Image.imageset", "idiom" : "tv", "role" : "top-shelf-image", "size" : "1920x720" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" }, { "idiom" : "tv-marketing", "scale" : "1x" }, { "idiom" : "tv-marketing", "scale" : "2x" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "tv", "scale" : "1x" }, { "idiom" : "tv", "scale" : "2x" }, { "idiom" : "tv-marketing", "scale" : "1x" }, { "idiom" : "tv-marketing", "scale" : "2x" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Assets.xcassets/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/ContentView.swift ================================================ // // ContentView.swift // tvOS_Example // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct ContentView: View { @State private var image: UIImage = UIImage() var body: some View { VStack { Image(uiImage: image) } .padding() .task { do { let config = Configuration( organization: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAi = OpenAI(config) let imageParam = ImageParameters( prompt: "an avocado chair", resolution: .small, responseFormat: .base64Json ) let result = try await openAi.createImage(parameters: imageParam) let b64Image = result.data[0].image self.image = try openAi.decodeBase64Image(b64Image) } catch { print("ERROR DETAILS - \(error)") } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/Preview Content/Preview Assets.xcassets/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example/tvOS_ExampleApp.swift ================================================ // // tvOS_ExampleApp.swift // tvOS_Example // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI @main struct tvOS_ExampleApp: App { var body: some Scene { WindowGroup { ContentView() } } } ================================================ FILE: Examples/tvOS_Example/tvOS_Example.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 56; objects = { /* Begin PBXBuildFile section */ 765BB22F2940599A000BF124 /* tvOS_ExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB22E2940599A000BF124 /* tvOS_ExampleApp.swift */; }; 765BB2312940599A000BF124 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB2302940599A000BF124 /* ContentView.swift */; }; 765BB2332940599C000BF124 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 765BB2322940599C000BF124 /* Assets.xcassets */; }; 765BB2362940599C000BF124 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 765BB2352940599C000BF124 /* Preview Assets.xcassets */; }; 765BB23F294059DD000BF124 /* OpenAIKit in Frameworks */ = {isa = PBXBuildFile; productRef = 765BB23E294059DD000BF124 /* OpenAIKit */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 765BB22B2940599A000BF124 /* tvOS_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = tvOS_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 765BB22E2940599A000BF124 /* tvOS_ExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = tvOS_ExampleApp.swift; sourceTree = ""; }; 765BB2302940599A000BF124 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 765BB2322940599C000BF124 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 765BB2352940599C000BF124 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 765BB23D294059D9000BF124 /* OpenAIKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = OpenAIKit; path = ../..; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 765BB2282940599A000BF124 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 765BB23F294059DD000BF124 /* OpenAIKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 765BB2222940599A000BF124 = { isa = PBXGroup; children = ( 765BB22D2940599A000BF124 /* tvOS_Example */, 765BB22C2940599A000BF124 /* Products */, 765BB23C294059D9000BF124 /* Frameworks */, ); sourceTree = ""; }; 765BB22C2940599A000BF124 /* Products */ = { isa = PBXGroup; children = ( 765BB22B2940599A000BF124 /* tvOS_Example.app */, ); name = Products; sourceTree = ""; }; 765BB22D2940599A000BF124 /* tvOS_Example */ = { isa = PBXGroup; children = ( 765BB22E2940599A000BF124 /* tvOS_ExampleApp.swift */, 765BB2302940599A000BF124 /* ContentView.swift */, 765BB2322940599C000BF124 /* Assets.xcassets */, 765BB2342940599C000BF124 /* Preview Content */, ); path = tvOS_Example; sourceTree = ""; }; 765BB2342940599C000BF124 /* Preview Content */ = { isa = PBXGroup; children = ( 765BB2352940599C000BF124 /* Preview Assets.xcassets */, ); path = "Preview Content"; sourceTree = ""; }; 765BB23C294059D9000BF124 /* Frameworks */ = { isa = PBXGroup; children = ( 765BB23D294059D9000BF124 /* OpenAIKit */, ); name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 765BB22A2940599A000BF124 /* tvOS_Example */ = { isa = PBXNativeTarget; buildConfigurationList = 765BB2392940599C000BF124 /* Build configuration list for PBXNativeTarget "tvOS_Example" */; buildPhases = ( 765BB2272940599A000BF124 /* Sources */, 765BB2282940599A000BF124 /* Frameworks */, 765BB2292940599A000BF124 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = tvOS_Example; packageProductDependencies = ( 765BB23E294059DD000BF124 /* OpenAIKit */, ); productName = tvOS_Example; productReference = 765BB22B2940599A000BF124 /* tvOS_Example.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 765BB2232940599A000BF124 /* Project object */ = { isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1410; LastUpgradeCheck = 1410; TargetAttributes = { 765BB22A2940599A000BF124 = { CreatedOnToolsVersion = 14.1; }; }; }; buildConfigurationList = 765BB2262940599A000BF124 /* Build configuration list for PBXProject "tvOS_Example" */; compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 765BB2222940599A000BF124; productRefGroup = 765BB22C2940599A000BF124 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 765BB22A2940599A000BF124 /* tvOS_Example */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 765BB2292940599A000BF124 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 765BB2362940599C000BF124 /* Preview Assets.xcassets in Resources */, 765BB2332940599C000BF124 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 765BB2272940599A000BF124 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 765BB2312940599A000BF124 /* ContentView.swift in Sources */, 765BB22F2940599A000BF124 /* tvOS_ExampleApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 765BB2372940599C000BF124 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = appletvos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TVOS_DEPLOYMENT_TARGET = 16.1; }; name = Debug; }; 765BB2382940599C000BF124 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = appletvos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; TVOS_DEPLOYMENT_TARGET = 16.1; VALIDATE_PRODUCT = YES; }; name = Release; }; 765BB23A2940599C000BF124 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"tvOS_Example/Preview Content\""; DEVELOPMENT_TEAM = 8GNE6ML5WX; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = "com.MarcoDotIO.tvOS-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; }; name = Debug; }; 765BB23B2940599C000BF124 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"tvOS_Example/Preview Content\""; DEVELOPMENT_TEAM = 8GNE6ML5WX; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UIUserInterfaceStyle = Automatic; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = "com.MarcoDotIO.tvOS-Example"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 765BB2262940599A000BF124 /* Build configuration list for PBXProject "tvOS_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( 765BB2372940599C000BF124 /* Debug */, 765BB2382940599C000BF124 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 765BB2392940599C000BF124 /* Build configuration list for PBXNativeTarget "tvOS_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( 765BB23A2940599C000BF124 /* Debug */, 765BB23B2940599C000BF124 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ 765BB23E294059DD000BF124 /* OpenAIKit */ = { isa = XCSwiftPackageProductDependency; productName = OpenAIKit; }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 765BB2232940599A000BF124 /* Project object */; } ================================================ FILE: Examples/tvOS_Example/tvOS_Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Examples/tvOS_Example/tvOS_Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: Examples/watchOS_Example/watchOS_Example Watch App/Assets.xcassets/AccentColor.colorset/Contents.json ================================================ { "colors" : [ { "idiom" : "universal" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/watchOS_Example/watchOS_Example Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "platform" : "watchos", "size" : "1024x1024" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/watchOS_Example/watchOS_Example Watch App/Assets.xcassets/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/watchOS_Example/watchOS_Example Watch App/ContentView.swift ================================================ // // ContentView.swift // watchOS_Example Watch App // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI import OpenAIKit struct ContentView: View { @State private var image: UIImage = UIImage() var body: some View { VStack { Image(uiImage: image) } .padding() .task { do { let config = Configuration( organization: "INSERT-ORGANIZATION-ID", apiKey: "INSERT-API-KEY" ) let openAi = OpenAI(config) let imageParam = ImageParameters( prompt: "an avocado chair", resolution: .small, responseFormat: .base64Json ) let result = try await openAi.createImage(parameters: imageParam) let b64Image = result.data[0].image self.image = try openAi.decodeBase64Image(b64Image) } catch { print("ERROR DETAILS - \(error)") } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } ================================================ FILE: Examples/watchOS_Example/watchOS_Example Watch App/Preview Content/Preview Assets.xcassets/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: Examples/watchOS_Example/watchOS_Example Watch App/watchOS_ExampleApp.swift ================================================ // // watchOS_ExampleApp.swift // watchOS_Example Watch App // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI @main struct watchOS_Example_Watch_AppApp: App { var body: some Scene { WindowGroup { ContentView() } } } ================================================ FILE: Examples/watchOS_Example/watchOS_Example.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 56; objects = { /* Begin PBXBuildFile section */ 765BB21129405873000BF124 /* watchOS_ExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB21029405873000BF124 /* watchOS_ExampleApp.swift */; }; 765BB21329405873000BF124 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765BB21229405873000BF124 /* ContentView.swift */; }; 765BB21529405874000BF124 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 765BB21429405874000BF124 /* Assets.xcassets */; }; 765BB21829405874000BF124 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 765BB21729405874000BF124 /* Preview Assets.xcassets */; }; 765BB2212940589A000BF124 /* OpenAIKit in Frameworks */ = {isa = PBXBuildFile; productRef = 765BB2202940589A000BF124 /* OpenAIKit */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 765BB20D29405873000BF124 /* watchOS_Example Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "watchOS_Example Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 765BB21029405873000BF124 /* watchOS_ExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = watchOS_ExampleApp.swift; sourceTree = ""; }; 765BB21229405873000BF124 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 765BB21429405874000BF124 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 765BB21729405874000BF124 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 765BB21F29405896000BF124 /* OpenAIKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = OpenAIKit; path = ../..; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 765BB20A29405873000BF124 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 765BB2212940589A000BF124 /* OpenAIKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 765BB20429405873000BF124 = { isa = PBXGroup; children = ( 765BB20F29405873000BF124 /* watchOS_Example Watch App */, 765BB20E29405873000BF124 /* Products */, 765BB21E29405896000BF124 /* Frameworks */, ); sourceTree = ""; }; 765BB20E29405873000BF124 /* Products */ = { isa = PBXGroup; children = ( 765BB20D29405873000BF124 /* watchOS_Example Watch App.app */, ); name = Products; sourceTree = ""; }; 765BB20F29405873000BF124 /* watchOS_Example Watch App */ = { isa = PBXGroup; children = ( 765BB21029405873000BF124 /* watchOS_ExampleApp.swift */, 765BB21229405873000BF124 /* ContentView.swift */, 765BB21429405874000BF124 /* Assets.xcassets */, 765BB21629405874000BF124 /* Preview Content */, ); path = "watchOS_Example Watch App"; sourceTree = ""; }; 765BB21629405874000BF124 /* Preview Content */ = { isa = PBXGroup; children = ( 765BB21729405874000BF124 /* Preview Assets.xcassets */, ); path = "Preview Content"; sourceTree = ""; }; 765BB21E29405896000BF124 /* Frameworks */ = { isa = PBXGroup; children = ( 765BB21F29405896000BF124 /* OpenAIKit */, ); name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 765BB20C29405873000BF124 /* watchOS_Example Watch App */ = { isa = PBXNativeTarget; buildConfigurationList = 765BB21B29405874000BF124 /* Build configuration list for PBXNativeTarget "watchOS_Example Watch App" */; buildPhases = ( 765BB20929405873000BF124 /* Sources */, 765BB20A29405873000BF124 /* Frameworks */, 765BB20B29405873000BF124 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "watchOS_Example Watch App"; packageProductDependencies = ( 765BB2202940589A000BF124 /* OpenAIKit */, ); productName = "watchOS_Example Watch App"; productReference = 765BB20D29405873000BF124 /* watchOS_Example Watch App.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 765BB20529405873000BF124 /* Project object */ = { isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1410; LastUpgradeCheck = 1410; TargetAttributes = { 765BB20C29405873000BF124 = { CreatedOnToolsVersion = 14.1; }; }; }; buildConfigurationList = 765BB20829405873000BF124 /* Build configuration list for PBXProject "watchOS_Example" */; compatibilityVersion = "Xcode 14.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 765BB20429405873000BF124; productRefGroup = 765BB20E29405873000BF124 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 765BB20C29405873000BF124 /* watchOS_Example Watch App */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 765BB20B29405873000BF124 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 765BB21829405874000BF124 /* Preview Assets.xcassets in Resources */, 765BB21529405874000BF124 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 765BB20929405873000BF124 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 765BB21329405873000BF124 /* ContentView.swift in Sources */, 765BB21129405873000BF124 /* watchOS_ExampleApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ 765BB21929405874000BF124 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 765BB21A29405874000BF124 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; }; name = Release; }; 765BB21C29405874000BF124 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"watchOS_Example Watch App/Preview Content\""; DEVELOPMENT_TEAM = 8GNE6ML5WX; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = watchOS_Example; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = ""; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = .watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 9.1; }; name = Debug; }; 765BB21D29405874000BF124 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"watchOS_Example Watch App/Preview Content\""; DEVELOPMENT_TEAM = 8GNE6ML5WX; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = watchOS_Example; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = ""; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = .watchkitapp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; VALIDATE_PRODUCT = YES; WATCHOS_DEPLOYMENT_TARGET = 9.1; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 765BB20829405873000BF124 /* Build configuration list for PBXProject "watchOS_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( 765BB21929405874000BF124 /* Debug */, 765BB21A29405874000BF124 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 765BB21B29405874000BF124 /* Build configuration list for PBXNativeTarget "watchOS_Example Watch App" */ = { isa = XCConfigurationList; buildConfigurations = ( 765BB21C29405874000BF124 /* Debug */, 765BB21D29405874000BF124 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ /* Begin XCSwiftPackageProductDependency section */ 765BB2202940589A000BF124 /* OpenAIKit */ = { isa = XCSwiftPackageProductDependency; productName = OpenAIKit; }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 765BB20529405873000BF124 /* Project object */; } ================================================ FILE: Examples/watchOS_Example/watchOS_Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Examples/watchOS_Example/watchOS_Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: LICENSE ================================================ Copyright (c) OpenDive 2023 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Package.swift ================================================ // swift-tools-version: 6.2 // // Package.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import PackageDescription let package = Package( name: "OpenAIKit", platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6), .tvOS(.v13)], products: [ .library( name: "OpenAIKit", targets: ["OpenAIKit"]) ], dependencies: [ ], targets: [ .target( name: "OpenAIKit", dependencies: [], path: "Sources", swiftSettings: [ .swiftLanguageMode(.v6) ] ), .testTarget( name: "OpenAIKitTests", dependencies: ["OpenAIKit"], path: "Tests", resources: [.process("Resources")], swiftSettings: [ .swiftLanguageMode(.v6) ] ) ], swiftLanguageVersions: [.v6] ) ================================================ FILE: Package@swift-5.5.swift ================================================ // swift-tools-version: 5.5 // // Package@swift-5.5.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import PackageDescription let package = Package( name: "OpenAIKit", platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6), .tvOS(.v13)], products: [ .library( name: "OpenAIKit", targets: ["OpenAIKit"]) ], dependencies: [ ], targets: [ .target( name: "OpenAIKit", dependencies: [], path: "Sources" ), .testTarget( name: "OpenAIKitTests", dependencies: ["OpenAIKit"], path: "Tests", resources: [.process("Resources")] ) ], swiftLanguageVersions: [.v5] ) ================================================ FILE: Package@swift-5.6.swift ================================================ // swift-tools-version: 5.6 // // Package@swift-5.6.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import PackageDescription let package = Package( name: "OpenAIKit", platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6), .tvOS(.v13)], products: [ .library( name: "OpenAIKit", targets: ["OpenAIKit"]) ], dependencies: [ ], targets: [ .target( name: "OpenAIKit", dependencies: [], path: "Sources" ), .testTarget( name: "OpenAIKitTests", dependencies: ["OpenAIKit"], path: "Tests", resources: [.process("Resources")] ) ], swiftLanguageVersions: [.v5] ) ================================================ FILE: Package@swift-5.7.swift ================================================ // swift-tools-version: 5.7 // // Package@swift-5.7.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import PackageDescription let package = Package( name: "OpenAIKit", platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6), .tvOS(.v13)], products: [ .library( name: "OpenAIKit", targets: ["OpenAIKit"]) ], dependencies: [ ], targets: [ .target( name: "OpenAIKit", dependencies: [], path: "Sources" ), .testTarget( name: "OpenAIKitTests", dependencies: ["OpenAIKit"], path: "Tests", resources: [.process("Resources")] ) ], swiftLanguageVersions: [.v5] ) ================================================ FILE: Package@swift-5.8.swift ================================================ // swift-tools-version: 5.8 // // Package@swift-5.8.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import PackageDescription let package = Package( name: "OpenAIKit", platforms: [.iOS(.v13), .macOS(.v10_15), .watchOS(.v6), .tvOS(.v13)], products: [ .library( name: "OpenAIKit", targets: ["OpenAIKit"]) ], dependencies: [ ], targets: [ .target( name: "OpenAIKit", dependencies: [], path: "Sources" ), .testTarget( name: "OpenAIKitTests", dependencies: ["OpenAIKit"], path: "Tests", resources: [.process("Resources")] ) ], swiftLanguageVersions: [.v5] ) ================================================ FILE: README.md ================================================ [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FOpenDive%2FOpenAIKit%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/OpenDive/OpenAIKit) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FOpenDive%2FOpenAIKit%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/OpenDive/OpenAIKit) [![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-orange?style=flat-square)](https://img.shields.io/badge/Swift_Package_Manager-compatible-orange?style=flat-square) [![Swift](https://github.com/OpenDive/OpenAIKit/actions/workflows/swift.yml/badge.svg?branch=main)](https://github.com/OpenDive/OpenAIKit/actions/workflows/swift.yml) [![Twitter](https://img.shields.io/static/v1?label=Twitter&message=@OpenDiveHQ&color=ca333b)](https://twitter.com/OpenDiveHQ)
OpenAIKit Logo

OpenAIKit

A community-maintained Swift SDK for the OpenAI API.

Report Bug · Request Feature

## Table of Contents - [About the Project](#about-the-project) - [Motivation](#motivation) - [Our Vision](#our-vision) - [Features](#features) - [Requirements](#requirements) - [Installation](#installation) - [Swift Package Manager](#swift-package-manager) - [SPM Through Xcode Project](#spm-through-xcode-project) - [SPM Through Xcode Package](#spm-through-xcode-package) - [Using OpenAIKit](#using-openaikit) - [Obtaining API Keys](#obtaining-api-keys) - [Image](#image) - [Chat](#chat) - [Audio](#audio) - [Utilities](#utilities) - [Embeddings](#embeddings) - [Models](#models) - [Completion](#completion) - [Migration From 2.x to 3.x](#migration-from-2.x-to-3.x) - [Migration From 1.x to 2.x](#migration-from-1.x-to-2.x) - [Example Projects](#example-projects) - [Development and Testing](#development-and-testing) - [License](#license) ## About the Project **OpenAIKit** is a community-driven Swift SDK designed to provide Swift developers with a seamless, efficient, and Swifty way to interact with the OpenAI REST endpoint. Our aim is to lower the barrier for Swift developers, enabling them to integrate the power of OpenAI into their apps without delving deep into the intricacies of RESTful services. ### Motivation With the increasing demand for AI-powered features in modern applications, it's crucial for developers to have access to tools that simplify the integration process. While OpenAI offers an incredible suite of capabilities, there was a clear need for a dedicated Swift SDK that aligns with the idiomatic practices of the language and the expectations of the Swift developer community. ### Our Vision We envisioned a tool that not only provides raw access to OpenAI functionalities but also enhances the developer experience with a clear and intuitive API. Our ultimate goal is to foster innovation by providing the Swift community with the right tools to integrate AI capabilities into their applications effortlessly. ## Features - [x] Generate new, edited, and variations of images using Dall-E 2 (with Dall-E 3 coming soon). - [x] Generate edits and completions using GPT-3 and GPT-4. - [x] List avaiable models for use with GPT-3 and GPT-4. - [x] Retrieve embeddings for GPT-3 and GPT-4 prompts. - [x] Stream data for GPT-3 and GPT-4 completions. - [x] Generate Chat responses using ChatGPT. - [x] View and Upload training files. - [x] View whether a prompt is flagged by the Moderations endpoint or not. - [x] Comprehensive Unit and Integration Test coverage. - [x] Swift Concurrency compatibility back to iOS 13, macOS 10.15, tvOS 13, watchOS 6, and visionOS 1.0. - [x] Complete documentation of OpenAIKit. ## Requirements | Platform | Minimum Swift Version | Installation | Status | | ------------------------------------------------------------ | --------------------- | ----------------------------------------------- | ------------ | | iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+ / visionOS 1.0+ | 6.2 | [Swift Package Manager](#swift-package-manager) | Fully Tested | ## Installation ### Swift Package Manager The [Swift Package Manager](https://swift.org/package-manager/) allows for developers to easily integrate packages into their Xcode projects and packages; and is also fully integrated into the `swift` compiler. #### SPM Through XCode Project * File > Swift Packages > Add Package Dependency * Add `https://github.com/OpenDive/OpenAIKit.git` * Select "Up to next Major" with "3.0.0" #### SPM Through Xcode Package Once you have your Swift package set up, add the Git link within the `dependencies` value of your `Package.swift` file. ```swift dependencies: [ .package(url: "https://github.com/OpenDive/OpenAIKit.git", .upToNextMajor(from: "3.0.0")) ] ``` ## Using OpenAIKit ### Obtaining API Keys To obtain an API Key, go to your `API Keys` page on your account page [here](https://platform.openai.com/account/api-keys). API Keys Page > ## ⚠️ 🔑 **Important: Do Not Store OpenAI API Keys Directly in Code!** 🔑⚠️ > > When working with OpenAI's API, it's essential for security reasons not to embed your API keys directly within the codebase of your application. Embedding keys directly in your source code can expose them to unauthorized users and malicious actors, leading to potential misuse. > > **Best Practices:** > > 1. **Environment Variables:** Store your API keys in environment variables and access them in your code. This way, they aren't hard-coded into your application and can be managed securely. > 2. **Secrets Management:** Use a secure secrets management tool or service to store and retrieve your API keys. Tools like AWS Secrets Manager, HashiCorp Vault, Firebase, CloudKit, or Azure Key Vault are designed to store, manage, and retrieve sensitive data. This way, the user does not have on-device access to the keys. > 3. **.gitignore:** If you store your API keys in a configuration file, always ensure that this file is added to `.gitignore` or a similar mechanism to prevent it from being accidentally committed to a source control system. > 4. **Regularly Rotate Keys:** Rotate your API keys periodically to mitigate the potential impact of a leak. > > Remember, security is of utmost importance. Always prioritize the safe handling of sensitive information like API keys! > > For more information, check out [this article](https://nshipster.com/secrets/) all about API key management for Swift developers. ### Image Dive into the next evolution of AI-powered image generation with DALL-E 2 (and coming soon, DALL-E 3), brought to you by OpenAI. Building upon the legacy of its predecessor, DALL-E 2 offers enhanced capabilities to materialize intricate visuals from textual prompts, creating a seamless bridge between language and imagery. Developers can harness this groundbreaking technology to enrich user experiences, craft dynamic content, and inspire new avenues of creativity. Revolutionize your applications and projects by integrating the cutting-edge power of DALL-E 2. There are three endpoints provided by OpenAI to interact with DALL-E 2: - `createImage` is the main endpoint that allows direct image generation from a text prompt. Here's an example on how to use the endpoint, along with the correlating output: ```swift do { let imageParam = ImageParameters( // A text description of the desired image(s). prompt: "An armchair in the shape of an avocado", // The size of the generated images. resolution: .large, // The format in which the generated images are returned. responseFormat: .base64Json ) let result = try await openAi.createImage( parameters: imageParam ) let b64Image = result.data[0].image let image = try openAi.decodeBase64Image(b64Image) } catch { // Insert your own error handling method here. } ``` Avocado Chair ​ ​ - `createImageEdit` allows the developer to create edits based on the original image inputted, along with a transparent-enabled image, with the transparent portions being the areas to edit in; and a prompt of the original image with the edit the developer wants. Here's an example on how to use the endpoint, along with the correlating output: ```swift do { let imageEditParam = try ImageEditParameters( // The image to edit. image: image, // An additional image whose fully transparent areas indicate where image should be edited. mask: mask, // A text description of the desired image(s). prompt: "The Mona Lisa wearing a beret, in the style of Leonardo DaVinci", // The size of the generated images. resolution: .large, // The format in which the generated images are returned. responseFormat: .base64Json ) let imageResponse = try await openAI.generateImageEdits( parameters: imageEditParam ) let image = try openAI.decodeBase64Image(imageResponse.data[0].image) } catch { // Insert your own error handling method here. } ``` | ![Original](Resources/OriginalMonaLisa.png) | ![Mask](Resources/MonaLisaMask.png) | ![Edit](Resources/MonaLisaBeret.png) | |-----------------------|---------------------------|---------------------------------| | **Original** | **Mask** | **Edit** | ​ - `createImageVariation` allows the developer to create variations of a given input image. Here's an example on how to use the endpoint, along with the correlating output: ```swift do { let imageVariationParam = try ImageVariationParameters( // The image to use as the basis for the variation(s). image: image, // The size of the generated images. resolution: .large, // The format in which the generated images are returned. responseFormat: .base64Json ) let variationResponse = try await openAI.generateImageVariations( parameters: imageVariationParam ) self.image = try openAI.decodeBase64Image( variationResponse.data[0].image ) } catch { // Insert your own error handling method here. } ``` | ![Original](Resources/OriginalWave.png) | ![Variation](Resources/WaveVariation.png) | |-----------------------|---------------------------------| | **Original** | **Variation** | ### Chat ChatGPT, built on OpenAI's GPT-4 architecture, is a cutting-edge conversational AI model. It provides developers with a robust tool for integrating advanced natural language processing capabilities into applications. Using ChatGPT can enhance user interactions, improve efficiency, and offer AI-driven solutions in various use cases. Incorporate GPT-4's strength into your projects for tangible results. There is a single endpoint for this feature, however, this SDK splits the endpoint into two functions with three separate features in total: - `generateChatCompletion` allows the developer to generate chat completions using the provided models from OpenAI; or the developer's owned fine tuned models. Here's an example on how to use the endpoint, along with the correlating output: ```swift do { let chat: [ChatMessage] = [ ChatMessage(role: .system, content: "You are a helpful assistant."), ChatMessage(role: .user, content: "Who won the world series in 2020?"), ChatMessage(role: .assistant, content: "The Los Angeles Dodgers won the World Series in 2020."), ChatMessage(role: .user, content: "Where was it played?") ] let chatParameters = ChatParameters( model: .gpt4, // ID of the model to use. messages: chat // A list of messages comprising the conversation so far. ) let chatCompletion = try await openAI.generateChatCompletion( parameters: chatParameters ) if let message = chatCompletion.choices[0].message { let content = message.content } } catch { // Insert your own error handling method here. } ``` ``` ChatResponse( id: "chatcmpl-88eG5VruffcNHPNVGBKGVAV5HGk4j", object: OpenAIKit.OpenAIObject.chatCompletion, created: 1697072069, choices: [ OpenAIKit.ChatChoice( message: Optional( OpenAIKit.ChatMessage( id: "250FDA2D-2F38-4E6F-B97E-DAD74FED1FB6", role: OpenAIKit.ChatRole.assistant, content: Optional( "The 2020 World Series was played at Globe Life Field in Arlington, Texas." ), functionCall: nil ) ), delta: nil, index: 0, logprobs: nil, finishReason: Optional("stop") ) ], usage: Optional( OpenAIKit.Usage( promptTokens: 53, completionTokens: 17, totalTokens: 70 ) ) ) ``` The developer is also able to use function calls to execute various functions (i.e., fetching weather info, uploading files, etc). Here's an example on how to use the parameter, the corresponding response, and example usage with a local function. ```swift do { let functions: [Function] = [ Function( name: "getCurrentWeather", description: "Get the current weather in a given location", parameters: Parameters( type: "object", properties: [ "location": ParameterDetail( type: "string", description: "The city and state, e.g. San Francisco, CA" ), "unit": ParameterDetail( type: "string", enumValues: ["fahrenheit", "celsius"] ) ], required: ["location"] ) ) ] let messages: [ChatMessage] = [ ChatMessage(role: .user, content: "What's the weather like in Boston?") ] let chatParameters = ChatParameters( model: .gpt4, // ID of the model to use. messages: messages, // A list of messages comprising the conversation so far. functionCall: "auto", // Controls how the model calls functions. functions: functions // A list of functions the model may generate JSON inputs for. ) let chatCompletion = try await openAI.generateChatCompletion( parameters: chatParameters ) } catch { // Insert your own error handling method here. } ``` ``` ChatResponse( id: "chatcmpl-88eVjsHEPtDDiSEuCexsqO8iuhnfG", object: OpenAIKit.OpenAIObject.chatCompletion, created: 1697073039, choices: [ OpenAIKit.ChatChoice( message: Optional( OpenAIKit.ChatMessage( id: "DCE5EECB-9521-481D-9E75-C7FF9390E4CF", role: OpenAIKit.ChatRole.assistant, content: nil, functionCall: Optional( OpenAIKit.FunctionCall( arguments: "{\n\"location\": \"Boston, MA\"\n}", name: "getCurrentWeather" ) ) ) ), delta: nil, index: 0, logprobs: nil, finishReason: Optional("function_call") ) ], usage: Optional(OpenAIKit.Usage(promptTokens: 81, completionTokens: 16, totalTokens: 97)) ) ``` ```swift func getCurrentWeather(location: String, unit: TemperatureUnit = .fahrenheit) -> WeatherInfo { return WeatherInfo(location: location, temperature: "72", unit: unit, forecast: ["sunny", "windy"]) } if let message = chatCompletion.choices[0].message, let functionCall = message.functionCall { let jsonString = functionCall.arguments if let data = jsonString.data(using: .utf8) { do { if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let location = json["location"] as? String { self.weatherInfo = self.getCurrentWeather(location: location) } } catch { // Insert your own error handling method here. } } } ``` ​ - `generateChatCompletionStreaming` allows the developr to stream chat completion data from the endpoint. Here's an example on how to use the endpoint, along with the correlating output: ```swift do { let chat: [ChatMessage] = [ ChatMessage(role: .system, content: "You are a helpful assistant."), ChatMessage(role: .user, content: "Who won the world series in 2020?"), ChatMessage(role: .assistant, content: "The Los Angeles Dodgers won the World Series in 2020."), ChatMessage(role: .user, content: "Where was it played?") ] let chatParameters = ChatParameters(model: .chatGPTTurbo, messages: chat) let stream = try openAI.generateChatCompletionStreaming( parameters: chatParameters ) } catch { // Insert your own error handling method here. } ``` ``` ChatResponse( id: "chatcmpl-88enklY0vmc4fNkM1mJQCkzW6hcST", object: OpenAIKit.OpenAIObject.chatCompletionChunk, created: 1697074156, choices: [ OpenAIKit.ChatChoice( message: nil, delta: Optional( OpenAIKit.ChatDelta( role: Optional(OpenAIKit.ChatRole.assistant), content: Optional("") ) ), index: 0, logprobs: nil, finishReason: nil ) ], usage: nil ) ChatResponse( id: "chatcmpl-88enklY0vmc4fNkM1mJQCkzW6hcST", object: OpenAIKit.OpenAIObject.chatCompletionChunk, created: 1697074156, choices: [ OpenAIKit.ChatChoice( message: nil, delta: Optional( OpenAIKit.ChatDelta( role: nil, content: Optional("The") ) ), index: 0, logprobs: nil, finishReason: nil ) ], usage: nil ) // ... ChatResponse( id: "chatcmpl-88enklY0vmc4fNkM1mJQCkzW6hcST", object: OpenAIKit.OpenAIObject.chatCompletionChunk, created: 1697074156, choices: [ OpenAIKit.ChatChoice( message: nil, delta: Optional( OpenAIKit.ChatDelta( role: nil, content: Optional(".") ) ), index: 0, logprobs: nil, finishReason: nil ) ], usage: nil ) ChatResponse( id: "chatcmpl-88enklY0vmc4fNkM1mJQCkzW6hcST", object: OpenAIKit.OpenAIObject.chatCompletionChunk, created: 1697074156, choices: [ OpenAIKit.ChatChoice( message: nil, delta: Optional( OpenAIKit.ChatDelta( role: nil, content: nil ) ), index: 0, logprobs: nil, finishReason: Optional("stop") ) ], usage: nil ) ``` ### Audio Whisper is OpenAI's speech-to-text AI model, designed for accurate transcription of spoken content. By converting audio into text, it offers developers a straightforward tool for tasks like transcription services, voice commands, vocal language translations, or audio indexing. Implementing Whisper can help streamline processes, make applications more accessible, and leverage voice data efficiently. There are the two main endpoints that use the Whisper model: - `createTranscription` is the main endpoint that allows developers to transcribe spoken audio into text. Here's an example on how to use the endpoint, and the corresponding returned item: ```swift do { let audioParameters = TranscriptionParameters(file: audio) let transcriptionCompletion = try await openAI.createTranscription(parameters: audioParameters) } catch { // Insert your own error handling method here. } ``` ``` Arousing from the most profound of slumbers, we break the gossamer web of some dream. Yet in a second afterward, so frail may that web have been, we remember not that we have dreamed. In the return to life from the swoon there are two stages, first, that of the sense of mental or spiritual, secondly, that of the sense of physical existence. It seems probable that if, upon reaching the second stage, we could recall the impressions of the first, we should find these impressions eloquent in memories of the gulf beyond. And that gulf is what? How at least shall we distinguish its shadows from those of the tomb? ``` ​ - `createTranslation` is the second endpoint that allows developers to translate any non-English audio into transcribed English text. Here's an example on how to use the endpoint, and the corresponding returned item: ```swift do { let audioParameters = TranscriptionParameters(file: audio) let transcriptionCompletion = try await openAI.createTranslation(parameters: audioParameters) } catch { // Insert your own error handling method here. } ``` ``` In the night, when I was out of my mind, and I, pained, numb and tired, thought about the beauty and goodness of a long-forgotten lesson, and my head began to shake, I suddenly heard something tick that scared me out of my sleep. Who could it be in that weather? A visitor is knocking, I thought, at my room in that weather. That's all it is, and nothing more. ``` ### Utilities #### Embeddings Embeddings utilize OpenAI's GPT models to generate dense vector representations for text. These embeddings capture semantic information, enabling developers to perform tasks like similarity search, clustering, or fine-tuning on specific tasks. By integrating GPT Embeddings into applications, developers can enhance text analysis and retrieval capabilities, leading to more effective data processing and insights. Here's an example on how to use it, and the expected output for the endpoint: ```swift do { let embeddingsParam = EmbeddingsParameters(model: "text-similarity-ada-002", input: input) self.embeddingsResponse = try await openAI.createEmbeddings(parameters: embeddingsParam) } catch { // Insert your own error handling method here. } ``` ``` OpenAIKit.EmbeddingsResponse( object: OpenAIKit.OpenAIObject.list, data: [ OpenAIKit.EmbeddingsData( object: OpenAIKit.OpenAIObject.embedding, embedding: [ 0.0028667077, 0.018867997, -0.030135695, // ... -0.004177677, -0.015615467, -0.008131327 ], index: 0 ) ], model: "text-similarity-ada:002", usage: OpenAIKit.EmbeddingsUsage( promptTokens: 8, totalTokens: 8 ) ) ``` #### Models The models endpoint allows developers to fetch the currently available models from OpenAI, along with their own fine-tuned models. There are two endpoints available for use with this feature: - `listModels` fetches the entire list of models avaialbe to the developer. Here's an example usage, along with the corresponding output: ```swift do { let modelsResponse = try await openAi.listModels() } catch { // Insert your own error handling method here. } ``` ``` ListModelResponse( object: OpenAIKit.OpenAIObject.list, data: [ OpenAIKit.Model( id: "text-search-babbage-doc-001", object: OpenAIKit.OpenAIObject.model, created: 1651172509, ownedBy: "openai-dev" ), OpenAIKit.Model( id: "curie-search-query", object: OpenAIKit.OpenAIObject.model, created: 1651172509, ownedBy: "openai-dev" ), OpenAIKit.Model( id: "text-search-babbage-query-001", object: OpenAIKit.OpenAIObject.model, created: 1651172509, ownedBy: "openai-dev" ), OpenAIKit.Model( id: "babbage", object: OpenAIKit.OpenAIObject.model, created: 1649358449, ownedBy: "openai" ), OpenAIKit.Model( id: "gpt-3.5-turbo-instruct-0914", object: OpenAIKit.OpenAIObject.model, created: 1694122472, ownedBy: "system" ) // ... ] ) ``` - `retrieveModels` fetches a single model, given the input model's ID. Here's an example usage, along with the corresponding output: ```swift do { let model = try await openAI.retrieveModel(modelId: "text-davinci-001") } catch { // Insert your own error handling method here. } ``` ``` OpenAIKit.Model( id: "text-davinci-001", object: OpenAIKit.OpenAIObject.model, created: 1649364042, ownedBy: "openai" ) ``` ### Completion #### ⚠️ Deprecation Notice for Completion API ⚠️ As of July 6, 2023, OpenAI has announced the deprecation of the older models in the Completions API, which are set to retire at the beginning of 2024. It's highly recommended to transition to the Chat Completions API which provides a more structured prompt interface and multi-turn conversation capabilities. The Chat Completions API has proven to handle a vast majority of previous use cases and new conversational needs with higher flexibility and specificity, significantly enhancing the developer experience. For more details, refer to the [official announcement](https://openai.com/blog/gpt-4-api-general-availability). ### Migration From 2.x to 3.x OpenAIKit 3.x aligns with the modern OpenAI SDK shape and adopts Swift 6.2 concurrency checks. Core usage is now centered around namespaced resources (for example `openAI.responses.create(...)`), while some legacy flat methods are still available for compatibility during migration. #### 1) Move from flat client methods to namespaced resources ```swift // ❌ 2.x style let audio = try await openAI.createSpeech(parameters: speechParameters) // ✅ 3.x style let audio = try await openAI.audio.speech.create(parameters: speechParameters) ``` #### 2) Prefer typed, resource-based APIs ```swift // ✅ 3.x responses API let response = try await openAI.responses.create( parameters: ResponseCreateParameters( model: "gpt-5.2", input: "Summarize this document" ) ) // ✅ 3.x uploads API let upload = try await openAI.uploads.create( parameters: UploadCreateParameters( bytes: fileSize, filename: "training.jsonl", purpose: "fine-tune" ) ) // ✅ 3.x webhook verification let event = try openAI.webhooks.unwrap( payload: rawBody, headers: requestHeaders, as: MyWebhookEvent.self ) ``` #### 3) Prefer typed `Encodable` payloads over dictionary bodies 3.x request models use `Encodable` throughout, which improves compile-time safety and keeps payload mapping consistent. #### 4) Use richer client configuration when needed ```swift let openAI = OpenAI( .init( apiKey: apiKey, organizationId: organizationID, projectId: projectID, webhookSecret: webhookSecret, requestOptions: .init(timeoutInterval: 600, maxRetries: 2) ) ) ``` #### 5) Swift 6.2 concurrency OpenAIKit 3.x is built and tested in Swift 6.2 language mode. If your package graph still targets an older Swift language version, update your `Package.swift` toolchain/language settings before migrating. ### Migration From 1.x to 2.x As of 2.x, Chat Completion Models use enums to label each available model for the main usage of default models. Here is an example on how to migrate from using the older initializer for `ChatParameter` to the initializer for 2.x: ```swift // ❌ 1.x implementation let chatParameters = ChatParameters(model: "gpt4", messages: chat) // ✅ 2.x implementation let chatParameters = ChatParameters(model: .gpt4, messages: chat) ``` If you need a custom string for fine-tuned models, use the `customModel` parameter: ```swift // ✅ 2.x implementation for custom model IDs let chatParameters = ChatParameters(customModel: "INSERT-MODEL-ID", message: chat) ``` ## Example Projects (TBD) ## Development And Testing We welcome anyone to contribute to the project through posting issues, if they encounter any bugs / glitches while using OpenAIKit; and as well with creating pull issues that add any additional features to OpenAIKit. ## License OpenAIKit is released under the MIT license, and any use of OpenAI's REST endpoint will be under the [Usage policies](https://beta.openai.com/docs/usage-policies) set by them. ``` Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Supported Versions | Version | Supported | | ------- | ------------------ | | 2.0.1 | :white_check_mark: | | 2.0 | :x: | | 1.2 | :x: | | 1.1.3 | :x: | | 1.1.2 | :x: | | 1.1.1 | :x: | | 1.1.0 | :x: | | 1.0.0 | :x: | ## Reporting a Vulnerability Please create a GitHub issue or a GitHub Pull Request with a write up for the security vulnerability. ================================================ FILE: Sources/OpenAIKit/Client/AudioSpeechResource+API.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension AudioSpeechResource { func create(parameters: SpeechParameters) async throws -> Data { let url = try client.getServerUrl(path: "/audio/speech") return try await OpenAIKitSession.shared.decodeRawUrl( with: url, configuration: client.configuration, body: parameters, acceptHeader: "application/octet-stream" ) } } ================================================ FILE: Sources/OpenAIKit/Client/BatchesResource+API.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension BatchesResource { func create(parameters: BatchCreateParameters) async throws -> BatchObject { let url = try client.getServerUrl(path: "/batches") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list() async throws -> BatchListResponse { let url = try client.getServerUrl(path: "/batches") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(id: String) async throws -> BatchObject { let url = try client.getServerUrl(path: "/batches/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func cancel(id: String) async throws -> BatchObject { let url = try client.getServerUrl(path: "/batches/\(id)/cancel") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } } ================================================ FILE: Sources/OpenAIKit/Client/BetaResources+API.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension BetaAssistantsResource { func create(parameters: AssistantCreateParameters) async throws -> AssistantObject { let url = try client.getServerUrl(path: "/assistants") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list() async throws -> AssistantListResponse { let url = try client.getServerUrl(path: "/assistants") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(id: String) async throws -> AssistantObject { let url = try client.getServerUrl(path: "/assistants/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func update(id: String, parameters: AssistantUpdateParameters) async throws -> AssistantObject { let url = try client.getServerUrl(path: "/assistants/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func delete(id: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/assistants/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension BetaThreadsResource { func create(parameters: ThreadCreateParameters = .init()) async throws -> ThreadObject { let url = try client.getServerUrl(path: "/threads") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func retrieve(id: String) async throws -> ThreadObject { let url = try client.getServerUrl(path: "/threads/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func update(id: String, parameters: ThreadUpdateParameters) async throws -> ThreadObject { let url = try client.getServerUrl(path: "/threads/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func delete(id: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/threads/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension BetaThreadRunsResource { func create(threadID: String, parameters: ThreadRunCreateParameters) async throws -> ThreadRunObject { let url = try client.getServerUrl(path: "/threads/\(threadID)/runs") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list(threadID: String) async throws -> ThreadRunListResponse { let url = try client.getServerUrl(path: "/threads/\(threadID)/runs") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(threadID: String, runID: String) async throws -> ThreadRunObject { let url = try client.getServerUrl(path: "/threads/\(threadID)/runs/\(runID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func cancel(threadID: String, runID: String) async throws -> ThreadRunObject { let url = try client.getServerUrl(path: "/threads/\(threadID)/runs/\(runID)/cancel") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension BetaThreadRunStepsResource { func list(threadID: String, runID: String) async throws -> ThreadRunStepListResponse { let url = try client.getServerUrl(path: "/threads/\(threadID)/runs/\(runID)/steps") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(threadID: String, runID: String, stepID: String) async throws -> ThreadRunStepObject { let url = try client.getServerUrl(path: "/threads/\(threadID)/runs/\(runID)/steps/\(stepID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } } ================================================ FILE: Sources/OpenAIKit/Client/ContainersResource+API.swift ================================================ import Foundation private struct EmptyContainerContentBody: Encodable { init() {} } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension ContainersResource { func create(parameters: ContainerCreateParameters) async throws -> ContainerObject { let url = try client.getServerUrl(path: "/containers") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list() async throws -> ContainerListResponse { let url = try client.getServerUrl(path: "/containers") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(id: String) async throws -> ContainerObject { let url = try client.getServerUrl(path: "/containers/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func delete(id: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/containers/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension ContainerFilesResource { func create(containerID: String, parameters: ContainerFileCreateParameters) async throws -> ContainerFileObject { let url = try client.getServerUrl(path: "/containers/\(containerID)/files") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list(containerID: String) async throws -> ContainerFileListResponse { let url = try client.getServerUrl(path: "/containers/\(containerID)/files") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(containerID: String, fileID: String) async throws -> ContainerFileObject { let url = try client.getServerUrl(path: "/containers/\(containerID)/files/\(fileID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func delete(containerID: String, fileID: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/containers/\(containerID)/files/\(fileID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension ContainerFileContentResource { func retrieve(containerID: String, fileID: String) async throws -> Data { let url = try client.getServerUrl(path: "/containers/\(containerID)/files/\(fileID)/content") return try await OpenAIKitSession.shared.decodeRawUrl( with: url, configuration: client.configuration, body: EmptyContainerContentBody(), method: .get ) } } ================================================ FILE: Sources/OpenAIKit/Client/ConversationsResource+API.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension ConversationsResource { func create(parameters: ConversationCreateParameters = .init()) async throws -> ConversationObject { let url = try client.getServerUrl(path: "/conversations") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list() async throws -> ConversationListResponse { let url = try client.getServerUrl(path: "/conversations") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(id: String) async throws -> ConversationObject { let url = try client.getServerUrl(path: "/conversations/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func delete(id: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/conversations/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension ConversationItemsResource { func list(conversationID: String) async throws -> ConversationItemListResponse { let url = try client.getServerUrl(path: "/conversations/\(conversationID)/items") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func create( conversationID: String, parameters: ConversationItemCreateParameters ) async throws -> ConversationItemObject { let url = try client.getServerUrl(path: "/conversations/\(conversationID)/items") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func retrieve(conversationID: String, itemID: String) async throws -> ConversationItemObject { let url = try client.getServerUrl(path: "/conversations/\(conversationID)/items/\(itemID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func delete(conversationID: String, itemID: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/conversations/\(conversationID)/items/\(itemID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } ================================================ FILE: Sources/OpenAIKit/Client/EvalsResource+API.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension EvalsResource { func create(parameters: EvalCreateParameters) async throws -> EvalObject { let url = try client.getServerUrl(path: "/evals") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list() async throws -> EvalListResponse { let url = try client.getServerUrl(path: "/evals") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(id: String) async throws -> EvalObject { let url = try client.getServerUrl(path: "/evals/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func delete(id: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/evals/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension EvalRunsResource { func create(evalID: String, parameters: EvalRunCreateParameters) async throws -> EvalRunObject { let url = try client.getServerUrl(path: "/evals/\(evalID)/runs") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list(evalID: String) async throws -> EvalRunListResponse { let url = try client.getServerUrl(path: "/evals/\(evalID)/runs") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(evalID: String, runID: String) async throws -> EvalRunObject { let url = try client.getServerUrl(path: "/evals/\(evalID)/runs/\(runID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func cancel(evalID: String, runID: String) async throws -> EvalRunObject { let url = try client.getServerUrl(path: "/evals/\(evalID)/runs/\(runID)/cancel") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension EvalRunOutputItemsResource { func list(evalID: String, runID: String) async throws -> EvalRunOutputItemListResponse { let url = try client.getServerUrl(path: "/evals/\(evalID)/runs/\(runID)/output_items") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } } ================================================ FILE: Sources/OpenAIKit/Client/FineTuningResource+API.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension FineTuningJobsResource { func create(parameters: FineTuningJobCreateParameters) async throws -> FineTuningJobObject { let url = try client.getServerUrl(path: "/fine_tuning/jobs") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list() async throws -> FineTuningJobListResponse { let url = try client.getServerUrl(path: "/fine_tuning/jobs") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(id: String) async throws -> FineTuningJobObject { let url = try client.getServerUrl(path: "/fine_tuning/jobs/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func cancel(id: String) async throws -> FineTuningJobObject { let url = try client.getServerUrl(path: "/fine_tuning/jobs/\(id)/cancel") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } func listEvents(jobID: String) async throws -> FineTuningJobEventListResponse { let url = try client.getServerUrl(path: "/fine_tuning/jobs/\(jobID)/events") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func listCheckpoints(jobID: String) async throws -> FineTuningCheckpointListResponse { let url = try client.getServerUrl(path: "/fine_tuning/jobs/\(jobID)/checkpoints") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } } ================================================ FILE: Sources/OpenAIKit/Client/RealtimeResource+API.swift ================================================ import Foundation public struct RealtimeConnectionOptions: Sendable { public var model: String? public var callID: String? public init(model: String? = nil, callID: String? = nil) { self.model = model self.callID = callID } } public struct RealtimeConnectionEvent: Sendable { public let type: String public let payload: String? public init(type: String, payload: String? = nil) { self.type = type self.payload = payload } } public actor RealtimeConnection { private var isClosed = false private let options: RealtimeConnectionOptions init(options: RealtimeConnectionOptions) { self.options = options } public func receive() -> RealtimeConnectionEvent? { guard !isClosed else { return nil } return RealtimeConnectionEvent(type: "connected", payload: options.model) } public func send(_ event: RealtimeConnectionEvent) { _ = event } public func close() { isClosed = true } } public struct RealtimeConnectionManager { private let options: RealtimeConnectionOptions init(options: RealtimeConnectionOptions) { self.options = options } public func enter() async -> RealtimeConnection { RealtimeConnection(options: options) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension RealtimeResource { func connect(options: RealtimeConnectionOptions = .init()) -> RealtimeConnectionManager { RealtimeConnectionManager(options: options) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension RealtimeCallsResource { func create(parameters: RealtimeCallCreateParameters = .init()) async throws -> RealtimeCallObject { let url = try client.getServerUrl(path: "/realtime/calls") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func accept(callID: String) async throws -> RealtimeCallObject { let url = try client.getServerUrl(path: "/realtime/calls/\(callID)/accept") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } func hangup(callID: String) async throws -> RealtimeCallObject { let url = try client.getServerUrl(path: "/realtime/calls/\(callID)/hangup") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } func refer(callID: String, parameters: RealtimeCallReferParameters) async throws -> RealtimeCallObject { let url = try client.getServerUrl(path: "/realtime/calls/\(callID)/refer") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func reject(callID: String) async throws -> RealtimeCallObject { let url = try client.getServerUrl(path: "/realtime/calls/\(callID)/reject") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension RealtimeClientSecretsResource { func create(parameters: RealtimeClientSecretCreateParameters = .init()) async throws -> RealtimeClientSecretResponse { let url = try client.getServerUrl(path: "/realtime/client_secrets") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } } ================================================ FILE: Sources/OpenAIKit/Client/ResourceNamespaces.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public class OpenAIResource { internal unowned let client: OpenAI internal init(_ client: OpenAI) { self.client = client } } // MARK: Top-level resources @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class CompletionsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ChatResource: OpenAIResource { public lazy var completions = ChatCompletionsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class EmbeddingsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class FilesResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ImagesResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class AudioResource: OpenAIResource { public lazy var speech = AudioSpeechResource(client) public lazy var transcriptions = AudioTranscriptionsResource(client) public lazy var translations = AudioTranslationsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ModerationsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ModelsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class FineTuningResource: OpenAIResource { public lazy var jobs = FineTuningJobsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class VectorStoresResource: OpenAIResource { public lazy var files = VectorStoreFilesResource(client) public lazy var fileBatches = VectorStoreFileBatchesResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class WebhooksResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BatchesResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class UploadsResource: OpenAIResource { public lazy var parts = UploadPartsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ResponsesResource: OpenAIResource { public lazy var inputItems = ResponseInputItemsResource(client) public lazy var inputTokens = ResponseInputTokensResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class RealtimeResource: OpenAIResource { public lazy var calls = RealtimeCallsResource(client) public lazy var clientSecrets = RealtimeClientSecretsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ConversationsResource: OpenAIResource { public lazy var items = ConversationItemsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class EvalsResource: OpenAIResource { public lazy var runs = EvalRunsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ContainersResource: OpenAIResource { public lazy var files = ContainerFilesResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class SkillsResource: OpenAIResource { public lazy var versions = SkillVersionsResource(client) public lazy var content = SkillContentResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class VideosResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaResource: OpenAIResource { public lazy var assistants = BetaAssistantsResource(client) public lazy var threads = BetaThreadsResource(client) public lazy var chatkit = BetaChatKitResource(client) public lazy var realtime = BetaRealtimeResource(client) } // MARK: Nested resources @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ChatCompletionsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class AudioSpeechResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class AudioTranscriptionsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class AudioTranslationsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class VectorStoreFilesResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class VectorStoreFileBatchesResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class UploadPartsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ResponseInputItemsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ResponseInputTokensResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class RealtimeCallsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class RealtimeClientSecretsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ConversationItemsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class EvalRunsResource: OpenAIResource { public lazy var outputItems = EvalRunOutputItemsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class EvalRunOutputItemsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ContainerFilesResource: OpenAIResource { public lazy var content = ContainerFileContentResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class ContainerFileContentResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class SkillVersionsResource: OpenAIResource { public lazy var content = SkillVersionContentResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class SkillVersionContentResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class SkillContentResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaAssistantsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaThreadsResource: OpenAIResource { public lazy var messages = BetaThreadMessagesResource(client) public lazy var runs = BetaThreadRunsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaThreadMessagesResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaThreadRunsResource: OpenAIResource { public lazy var steps = BetaThreadRunStepsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaThreadRunStepsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaChatKitResource: OpenAIResource { public lazy var sessions = BetaChatKitSessionsResource(client) public lazy var threads = BetaChatKitThreadsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaChatKitSessionsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaChatKitThreadsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaRealtimeResource: OpenAIResource { public lazy var sessions = BetaRealtimeSessionsResource(client) public lazy var transcriptionSessions = BetaRealtimeTranscriptionSessionsResource(client) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaRealtimeSessionsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class BetaRealtimeTranscriptionSessionsResource: OpenAIResource {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class FineTuningJobsResource: OpenAIResource {} ================================================ FILE: Sources/OpenAIKit/Client/ResponsesResource+API.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension ResponsesResource { func create(parameters: ResponseCreateParameters) async throws -> ResponseObject { let url = try client.getServerUrl(path: "/responses") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func stream(parameters: ResponseCreateParameters) throws -> AsyncThrowingStream { let url = try client.getServerUrl(path: "/responses") var streamingParameters = parameters streamingParameters.stream = true return try OpenAIKitSession.shared.streamData( with: url, configuration: client.configuration, body: streamingParameters ) } func parse(parameters: ResponseCreateParameters) async throws -> ResponseObject { try await create(parameters: parameters) } func retrieve(id: String) async throws -> ResponseObject { let url = try client.getServerUrl(path: "/responses/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func delete(id: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/responses/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } func cancel(id: String) async throws -> ResponseObject { let url = try client.getServerUrl(path: "/responses/\(id)/cancel") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension ResponseInputItemsResource { func list(responseID: String) async throws -> ResponseInputItemListResponse { let url = try client.getServerUrl(path: "/responses/\(responseID)/input_items") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension ResponseInputTokensResource { func create(parameters: ResponseInputTokensParameters) async throws -> ResponseInputTokenCount { let url = try client.getServerUrl(path: "/responses/input_tokens") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } } ================================================ FILE: Sources/OpenAIKit/Client/SkillsAndVideosResource+API.swift ================================================ import Foundation private struct EmptySkillBody: Encodable { init() {} } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension SkillsResource { func create(parameters: SkillCreateParameters) async throws -> SkillObject { let url = try client.getServerUrl(path: "/skills") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list() async throws -> SkillListResponse { let url = try client.getServerUrl(path: "/skills") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(id: String) async throws -> SkillObject { let url = try client.getServerUrl(path: "/skills/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func update(id: String, parameters: SkillUpdateParameters) async throws -> SkillObject { let url = try client.getServerUrl(path: "/skills/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func delete(id: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/skills/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension SkillContentResource { func retrieve(skillID: String) async throws -> Data { let url = try client.getServerUrl(path: "/skills/\(skillID)/content") return try await OpenAIKitSession.shared.decodeRawUrl( with: url, configuration: client.configuration, body: EmptySkillBody(), method: .get ) } func update(skillID: String, parameters: SkillContentUpdateParameters) async throws -> SkillObject { let url = try client.getServerUrl(path: "/skills/\(skillID)/content") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension SkillVersionsResource { func list(skillID: String) async throws -> SkillVersionListResponse { let url = try client.getServerUrl(path: "/skills/\(skillID)/versions") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(skillID: String, versionID: String) async throws -> SkillVersionObject { let url = try client.getServerUrl(path: "/skills/\(skillID)/versions/\(versionID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension SkillVersionContentResource { func retrieve(skillID: String, versionID: String) async throws -> Data { let url = try client.getServerUrl(path: "/skills/\(skillID)/versions/\(versionID)/content") return try await OpenAIKitSession.shared.decodeRawUrl( with: url, configuration: client.configuration, body: EmptySkillBody(), method: .get ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension VideosResource { func create(parameters: VideoCreateParameters) async throws -> VideoObject { let url = try client.getServerUrl(path: "/videos") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list() async throws -> VideoListResponse { let url = try client.getServerUrl(path: "/videos") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(id: String) async throws -> VideoObject { let url = try client.getServerUrl(path: "/videos/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func cancel(id: String) async throws -> VideoObject { let url = try client.getServerUrl(path: "/videos/\(id)/cancel") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } } ================================================ FILE: Sources/OpenAIKit/Client/UploadsResource+API.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension UploadsResource { func create(parameters: UploadCreateParameters) async throws -> UploadObject { let url = try client.getServerUrl(path: "/uploads") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func retrieve(id: String) async throws -> UploadObject { let url = try client.getServerUrl(path: "/uploads/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func cancel(id: String) async throws -> UploadObject { let url = try client.getServerUrl(path: "/uploads/\(id)/cancel") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } func complete(id: String, parameters: UploadCompleteParameters) async throws -> UploadObject { let url = try client.getServerUrl(path: "/uploads/\(id)/complete") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension UploadPartsResource { func create(uploadID: String, parameters: UploadPartCreateParameters) async throws -> UploadPartObject { let url = try client.getServerUrl(path: "/uploads/\(uploadID)/parts") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } } ================================================ FILE: Sources/OpenAIKit/Client/VectorStoresResource+API.swift ================================================ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension VectorStoresResource { func create(parameters: VectorStoreCreateParameters) async throws -> VectorStoreObject { let url = try client.getServerUrl(path: "/vector_stores") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list() async throws -> VectorStoreListResponse { let url = try client.getServerUrl(path: "/vector_stores") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(id: String) async throws -> VectorStoreObject { let url = try client.getServerUrl(path: "/vector_stores/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func update(id: String, parameters: VectorStoreUpdateParameters) async throws -> VectorStoreObject { let url = try client.getServerUrl(path: "/vector_stores/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func delete(id: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/vector_stores/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension VectorStoreFilesResource { func create(vectorStoreID: String, parameters: VectorStoreFileCreateParameters) async throws -> VectorStoreFileObject { let url = try client.getServerUrl(path: "/vector_stores/\(vectorStoreID)/files") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list(vectorStoreID: String) async throws -> VectorStoreFileListResponse { let url = try client.getServerUrl(path: "/vector_stores/\(vectorStoreID)/files") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(vectorStoreID: String, fileID: String) async throws -> VectorStoreFileObject { let url = try client.getServerUrl(path: "/vector_stores/\(vectorStoreID)/files/\(fileID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func delete(vectorStoreID: String, fileID: String) async throws -> DeleteObject { let url = try client.getServerUrl(path: "/vector_stores/\(vectorStoreID)/files/\(fileID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .delete, bodyRequired: false ) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public extension VectorStoreFileBatchesResource { func create(vectorStoreID: String, parameters: VectorStoreFileBatchCreateParameters) async throws -> VectorStoreFileBatchObject { let url = try client.getServerUrl(path: "/vector_stores/\(vectorStoreID)/file_batches") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, body: parameters ) } func list(vectorStoreID: String) async throws -> VectorStoreFileBatchListResponse { let url = try client.getServerUrl(path: "/vector_stores/\(vectorStoreID)/file_batches") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func retrieve(vectorStoreID: String, fileBatchID: String) async throws -> VectorStoreFileBatchObject { let url = try client.getServerUrl(path: "/vector_stores/\(vectorStoreID)/file_batches/\(fileBatchID)") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .get, bodyRequired: false ) } func cancel(vectorStoreID: String, fileBatchID: String) async throws -> VectorStoreFileBatchObject { let url = try client.getServerUrl(path: "/vector_stores/\(vectorStoreID)/file_batches/\(fileBatchID)/cancel") return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: client.configuration, method: .post, bodyRequired: false ) } } ================================================ FILE: Sources/OpenAIKit/Client/WebhooksResource+Helpers.swift ================================================ import CryptoKit import Foundation public enum OpenAIWebhookError: Error { case missingWebhookSecret case missingTimestamp case missingSignature case invalidSignature case invalidPayload } private extension String { var openAIWebhookHexData: Data? { let clean = self.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() guard clean.count % 2 == 0 else { return nil } var data = Data() data.reserveCapacity(clean.count / 2) var index = clean.startIndex while index < clean.endIndex { let next = clean.index(index, offsetBy: 2) let byteString = clean[index.. String? { var lowercaseMap: [String: String] = [:] for (key, value) in self { lowercaseMap[key.lowercased()] = value } for candidate in candidates { if let value = lowercaseMap[candidate.lowercased()] { return value } } return nil } } public extension WebhooksResource { func verifySignature( payload: String, headers: [String: String], secret: String? = nil ) throws { let resolvedSecret = secret ?? client.configuration.webhookSecret guard let webhookSecret = resolvedSecret, !webhookSecret.isEmpty else { throw OpenAIWebhookError.missingWebhookSecret } guard let timestamp = headers.openAIWebhookValue(for: ["openai-timestamp", "webhook-timestamp"]) else { throw OpenAIWebhookError.missingTimestamp } guard let signatureHeader = headers.openAIWebhookValue(for: ["openai-signature", "webhook-signature"]) else { throw OpenAIWebhookError.missingSignature } let signatureValue: String if let valueRange = signatureHeader.range(of: "v1=") { signatureValue = String(signatureHeader[valueRange.upperBound...]).split(separator: ",").first.map(String.init) ?? "" } else { signatureValue = signatureHeader } guard let providedSignature = signatureValue.openAIWebhookHexData else { throw OpenAIWebhookError.invalidSignature } let message = "\(timestamp).\(payload)" let key = SymmetricKey(data: Data(webhookSecret.utf8)) let digest = HMAC.authenticationCode(for: Data(message.utf8), using: key) let expected = Data(digest) guard expected == providedSignature else { throw OpenAIWebhookError.invalidSignature } } func unwrap( payload: String, headers: [String: String], as type: Event.Type = Event.self, secret: String? = nil ) throws -> Event { try verifySignature(payload: payload, headers: headers, secret: secret) guard let data = payload.data(using: .utf8) else { throw OpenAIWebhookError.invalidPayload } return try JSONDecoder().decode(type, from: data) } } ================================================ FILE: Sources/OpenAIKit/Extensions/NSImageExtension.swift ================================================ // // NSImageExtension.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #if os(macOS) import Cocoa extension NSImage { public func pngData( size: ImageResolutions, imageInterpolation: NSImageInterpolation = .high ) -> Data? { var cgSize = CGSize() switch size { case .small: cgSize.width = 256 cgSize.height = 256 break case .medium: cgSize.width = 512 cgSize.height = 512 break case .large: cgSize.width = 1024 cgSize.height = 1024 break case .extraLargeLandscape: cgSize.width = 1792 cgSize.height = 1024 break case .extraLargePortrait: cgSize.width = 1024 cgSize.height = 1792 break } guard let bitmap = NSBitmapImageRep( bitmapDataPlanes: nil, pixelsWide: Int(cgSize.width), pixelsHigh: Int(cgSize.height), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: .deviceRGB, bitmapFormat: [], bytesPerRow: 0, bitsPerPixel: 0 ) else { return nil } bitmap.size = cgSize NSGraphicsContext.saveGraphicsState() NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: bitmap) NSGraphicsContext.current?.imageInterpolation = imageInterpolation draw( in: NSRect(origin: .zero, size: cgSize), from: .zero, operation: .copy, fraction: 1.0 ) NSGraphicsContext.restoreGraphicsState() return bitmap.representation(using: .png, properties: [:]) } } #endif ================================================ FILE: Sources/OpenAIKit/Extensions/NSMutableDataExtension.swift ================================================ // // NSMutableDataExtension.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation // Used for the form data to append strings to the data variable of NSMutableData type. extension NSMutableData { func append(_ string: String) { if let data = string.data(using: .utf8) { self.append(data) } } } ================================================ FILE: Sources/OpenAIKit/Extensions/String.swift ================================================ // // File.swift // // // Created by Marcus Arnett on 8/12/23. // import Foundation extension String { internal var surroundingWords: [String] { let words = self.split(separator: " ") guard let index = words.firstIndex(where: { String($0) == self }) else { return [] } var surrounding: [String] = [] if index > 0 { surrounding.append(String(words[index - 1])) } if index < words.count - 1 { surrounding.append(String(words[index + 1])) } return surrounding } public var subtitleDate: Date? { let formatter = DateFormatter() formatter.dateFormat = "HH:mm:ss,SSS" formatter.timeZone = TimeZone(secondsFromGMT: 0) formatter.locale = Locale(identifier: "en_US_POSIX") return formatter.date(from: self) } } ================================================ FILE: Sources/OpenAIKit/Extensions/StringPropertyMap.swift ================================================ // // SwiftUIView.swift // // // Created by Marcus Arnett on 10/10/23. // import SwiftUI internal extension [String: Property] { var body: [String: Any] { var result: [String: Any] = [:] for key in self.keys { let value = self[key] if let value { result[key] = value.body } } return result } } ================================================ FILE: Sources/OpenAIKit/OpenAI.swift ================================================ // // OpenAI.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) import UIKit import SwiftUI #endif #if os(macOS) import Foundation import AppKit #endif #if os(Linux) || SERVER import Foundation #endif /// OpenAI provides the needed core functions of OpenAIKit. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) public final class OpenAI { /// The configuration object used to store the API Key and Organization ID. private var config: Configuration // MARK: Resource namespaces public lazy var completions = CompletionsResource(self) public lazy var chat = ChatResource(self) public lazy var embeddings = EmbeddingsResource(self) public lazy var files = FilesResource(self) public lazy var images = ImagesResource(self) public lazy var audio = AudioResource(self) public lazy var moderations = ModerationsResource(self) public lazy var models = ModelsResource(self) public lazy var fineTuning = FineTuningResource(self) public lazy var vectorStores = VectorStoresResource(self) public lazy var webhooks = WebhooksResource(self) public lazy var beta = BetaResource(self) public lazy var batches = BatchesResource(self) public lazy var uploads = UploadsResource(self) public lazy var responses = ResponsesResource(self) public lazy var realtime = RealtimeResource(self) public lazy var conversations = ConversationsResource(self) public lazy var evals = EvalsResource(self) public lazy var containers = ContainersResource(self) public lazy var skills = SkillsResource(self) public lazy var videos = VideosResource(self) public init(_ config: Configuration) { self.config = config } internal var configuration: Configuration { self.config } #if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) /// Input a `Base64` image binary `String` to receive an `UIImage` object. /// - Parameter b64Data: The `Base64` data itself in `String` form. /// - Returns: A `UIImage` object. public func decodeBase64Image(_ b64Data: String) throws -> UIImage { do { guard let data = Data(base64Encoded: b64Data) else { throw OpenAIError.invalidData } guard let image = UIImage(data: data) else { throw OpenAIError.invalidData } return image } catch { throw OpenAIError.invalidData } } #endif #if os(macOS) /// Input a `Base64` image binary `String` to receive an `NSImage` object. /// - Parameter b64Data: The `Base64` data itself in `String` form. /// - Returns: An `NSImage` object. public func decodeBase64Image(_ b64Data: String) throws -> NSImage { do { guard let data = Data(base64Encoded: b64Data) else { throw OpenAIError.invalidData } guard let image = NSImage(data: data) else { throw OpenAIError.invalidData } return image } catch { throw OpenAIError.invalidData } } #endif /// Return a `URL` with the OpenAI API endpoint as the `URL` /// - Parameter path: The `String` path. /// - Returns: An `URL` object. internal func getServerUrl(path: String) throws -> URL { let fullPath = path.hasPrefix("/") ? path : "/\(path)" guard let result = URL(string: fullPath, relativeTo: config.baseURL)?.absoluteURL else { throw OpenAIError.invalidUrl } return result } } extension OpenAI: OpenAIProtocol { public func listModels() async throws -> ListModelResponse { let serverUrl = try getServerUrl(path: "/models") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, method: .get, bodyRequired: false ) } public func retrieveModel(modelId id: String) async throws -> Model { let serverUrl = try getServerUrl(path: "/models/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, method: .get, bodyRequired: false ) } public func generateCompletion(parameters param: CompletionParameters) async throws -> CompletionResponse { let serverUrl = try getServerUrl(path: "/completions") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, body: param ) } public func generateCompletionStreaming( parameters param: CompletionParameters ) throws -> AsyncThrowingStream { let serverUrl = try getServerUrl(path: "/completions") var parameter = param parameter.stream = true return try OpenAIKitSession.shared.streamData( with: serverUrl, configuration: config, body: parameter ) } public func generateChatCompletion(parameters param: ChatParameters) async throws -> ChatResponse { let serverUrl = try getServerUrl(path: "/chat/completions") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, body: param ) } public func generateChatCompletionStreaming( parameters param: ChatParameters ) throws -> AsyncThrowingStream { let serverUrl = try getServerUrl(path: "/chat/completions") var parameter = param parameter.stream = true return try OpenAIKitSession.shared.streamData( with: serverUrl, configuration: config, body: parameter ) } public func createImage(parameters param: ImageParameters) async throws -> ImageResponse { try param.checkForCompatibility() let serverUrl = try getServerUrl(path: "/images/generations") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, body: param ) } public func generateImageEdits(parameters param: ImageEditParameters) async throws -> ImageResponse { let serverUrl = try getServerUrl(path: "/images/edits") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, body: param.body, formSubmission: true ) } public func generateImageVariations(parameters param: ImageVariationParameters) async throws -> ImageResponse { let serverUrl = try getServerUrl(path: "/images/variations") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, body: param.body, formSubmission: true ) } public func createEmbeddings(parameters param: EmbeddingsParameters) async throws -> EmbeddingsResponse { let serverUrl = try getServerUrl(path: "/embeddings") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, body: param ) } public func createTranscription(parameters param: TranscriptionParameters) async throws -> TranscriptionResponse { let serverUrl = try getServerUrl(path: "/audio/transcriptions") return try await param.retrieveResponse(using: serverUrl, self.config) } public func createTranslation(parameters param: TranscriptionParameters) async throws -> TranscriptionResponse { let serverUrl = try getServerUrl(path: "/audio/translations") var newParam = param newParam.language = nil return try await newParam.retrieveResponse(using: serverUrl, self.config) } public func createSpeech(parameters param: SpeechParameters) async throws -> Data { let serverUrl = try getServerUrl(path: "/audio/speech") return try await OpenAIKitSession.shared.decodeRawUrl( with: serverUrl, configuration: config, body: param, acceptHeader: "application/octet-stream" ) } public func listFiles() async throws -> ListFilesResponse { let serverUrl = try getServerUrl(path: "/files") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, method: .get, bodyRequired: false ) } public func uploadFile(parameters param: UploadFileParameters) async throws -> File { let serverUrl = try getServerUrl(path: "/files") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, body: param.body, formSubmission: true ) } public func deleteFile(fileId id: String) async throws -> DeleteObject { let serverUrl = try getServerUrl(path: "/files/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, method: .delete, bodyRequired: false ) } public func retrieveFile(fileId id: String) async throws -> File { let serverUrl = try getServerUrl(path: "/files/\(id)") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, method: .get, bodyRequired: false ) } public func retrieveFileContent(fileId id: String) async throws -> [FileContent] { let serverUrl = try getServerUrl(path: "/files/\(id)/content") return try await OpenAIKitSession.shared.retrieveJsonLine( with: serverUrl, configuration: config ) } public func deleteModel(model: String) async throws -> DeleteObject { let serverUrl = try getServerUrl(path: "/models/\(model)") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, method: .delete, bodyRequired: false ) } public func checkContentPolicy( parameters param: OpenAIKit.ContentPolicyParameters ) async throws -> ContentPolicyResponse { let serverUrl = try getServerUrl(path: "/moderations") return try await OpenAIKitSession.shared.decodeUrl( with: serverUrl, configuration: config, body: param.body ) } } ================================================ FILE: Sources/OpenAIKit/Protocols/Chat/Property.swift ================================================ // // Property.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// The properties used for a function call public protocol Property: Codable { /// The type used for the property var type: String { get } var body: [String: Any] { get } } ================================================ FILE: Sources/OpenAIKit/Protocols/OpenAIProtocol.swift ================================================ // // OpenAIProtocol.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation public protocol OpenAIProtocol { // MARK: Models Functions /// List and describe the various models available in the API. You can refer to the [Models](https://beta.openai.com/docs/models) /// documentation to understand what models are available and the differences between them. /// Lists the currently available models, and provides basic information about each one such as the owner and availability. /// - Returns: A `ListModelResponse` object. func listModels() async throws -> ListModelResponse /// Retrieves a model instance, providing basic information about the model such as the owner and permissioning. /// - Parameter id: The `String` of ID of the model. /// - Returns: A `Model` object. func retrieveModel(modelId id: String) async throws -> Model // MARK: Completion Function /// Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position. /// Using GPT3, Generate completions based on the input. /// - Parameter param: A `CompletionParameters` object containing the parameters for the call. /// - Returns: A `CompletionResponse` object. func generateCompletion(parameters param: CompletionParameters) async throws -> CompletionResponse /// Using GPT3, Generate completions based on the input. This function streams the output. /// - Parameter param: A `CompletionParameters` object containing the parameters for the call. /// - Returns: An `AsyncThrowingStream` with either a `CompletionResponse` object or an `Error` object. func generateCompletionStreaming( parameters param: CompletionParameters ) throws -> AsyncThrowingStream // MARK: Chat Function /// Creates a completion for the chat message /// Using ChatGPT, generate completions based on message history. /// - Parameter param: A `ChatParameters` object containing the parameters for the call. /// - Returns: A `ChatResponse` object. func generateChatCompletion(parameters param: ChatParameters) async throws -> ChatResponse /// Using ChatGPT, generate completions based on message history. This function is for users to stream data as its generated. /// - Parameter param: A `ChatParameters` object containing the parameters for the call. /// - Returns: An `AsyncThrowingStream` with either a `ChatResponse` object or an `Error` object. func generateChatCompletionStreaming( parameters param: ChatParameters ) throws -> AsyncThrowingStream // MARK: Image Functions /// Given a prompt and/or an input image, the model will generate a new image. /// Related guide: [Image generation](https://beta.openai.com/docs/guides/images) /// Creates an image given a prompt. /// - Parameter param: An `ImageParameters` object containing the parameters for the call. /// - Returns: An `ImageResponse` object. func createImage(parameters param: ImageParameters) async throws -> ImageResponse /// Creates an edited or extended image given an original image and a prompt. /// - Parameter param: An `ImageEditParameters` object containing the parameters for the call. /// - Returns: An `ImageResponse` object. func generateImageEdits(parameters param: ImageEditParameters) async throws -> ImageResponse /// Creates a variation of a given image. /// - Parameter param: An `ImageVariationParameters` object containing the parameters for the call. /// - Returns: An `ImageResponse` object. func generateImageVariations(parameters param: ImageVariationParameters) async throws -> ImageResponse // MARK: Embeddings Function /// Get a vector representation of a given input that can be easily consumed by machine learning models and algorithms. /// Relarted guide: [Embeddings](https://beta.openai.com/docs/guides/embeddings) /// Creates an embedding vector representing the input text. /// - Parameter param: An `EmbeddingsParameters` object containing the parameters for the call. /// - Returns: An `EmbeddingsResponse` object. func createEmbeddings(parameters param: EmbeddingsParameters) async throws -> EmbeddingsResponse // MARK: Audio Functions /// Get text from an audio source /// Related guide: [Speech to text](https://platform.openai.com/docs/guides/speech-to-text) /// Transcribes audio into the input language. /// - Parameter param: A `TranscriptionParameters` object containing the parameters for the call. /// - Returns: A `TranscriptionResponse` object. func createTranscription(parameters param: TranscriptionParameters) async throws -> TranscriptionResponse /// Translates audio into English. /// - Parameter param: A `TranscriptionParameters` object containing the parameters for the call. /// - Returns: A `TranscriptionResponse` object. func createTranslation(parameters param: TranscriptionParameters) async throws -> TranscriptionResponse /// Generates speech audio from text input. /// - Parameter param: A `SpeechParameters` object containing the parameters for the call. /// - Returns: Raw audio data from the API. func createSpeech(parameters param: SpeechParameters) async throws -> Data // MARK: Files Functions /// Files are used to upload documents for training and fine-tuning models. /// Returns a list of files that belong to the user's organization. /// - Returns: A `ListFilesResponse` object. func listFiles() async throws -> ListFilesResponse /// Upload a file that contains document(s) to be used across various endpoints/features. /// Currently, the size of all the files uploaded by one organization /// can be up to 1 GB. Please contact us if you need to increase the storage limit. /// - Parameter param: A `UploadFileParameters` object containing the parameters for the call. /// - Returns: A `File` object. func uploadFile(parameters param: UploadFileParameters) async throws -> File /// Delete a file. /// - Parameter id: A `String` value representing the ID of the file. /// - Returns: A `DeleteObject` object. func deleteFile(fileId id: String) async throws -> DeleteObject /// Returns information about a specific file. /// - Parameter id: A `String` value representing the ID of the file. /// - Returns: A `File` object. func retrieveFile(fileId id: String) async throws -> File /// Returns the contents of the specified file. /// - Parameter id: A `String` value representing the ID of the file. /// - Returns: An array of `FineTuneTraining` objects. func retrieveFileContent(fileId id: String) async throws -> [FileContent] // MARK: Fine-tune Functions. /// Manage fine-tuning jobs to tailor a model to your specific training data. /// Related guide: [Fine-tune models](https://beta.openai.com/docs/guides/fine-tuning) /// Deletes the Fine-tune model from storage. /// - Parameter model: The string of the model's name being deleted. /// - Returns: A `DeleteObject` object. func deleteModel(model: String) async throws -> DeleteObject // MARK: Moderation Function /// Given a input text, outputs if the model classifies it as violating OpenAI's content policy. /// Related guide: [Moderations](https://beta.openai.com/docs/guides/moderation) /// Classifies if text violates OpenAI's Content Policy /// - Parameter param: A `ContentPolicyParameters` object containing parameters for the call. /// - Returns: A `ContentPolicyResponse` object. func checkContentPolicy(parameters param: ContentPolicyParameters) async throws -> ContentPolicyResponse } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Audio/AudioResponseFormat.swift ================================================ // // AudioResponseFormat.swift // // // Created by Marcus Arnett on 8/6/23. // import Foundation public enum AudioResponseFormat: String, Codable { enum CodingKeys: String, CodingKey { case json case text case srt case verboseJson = "verbose_json" case vtt } case json case text case srt case verboseJson case vtt } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Chat/ChatModels.swift ================================================ // // ChatModels.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// Models used for the Chat Endpoint. public enum ChatModels: String, Codable, CustomStringConvertible { // MARK: ChatGPT Models /// Most capable GPT-3.5 model and optimized for chat at 1/10th the cost of text-davinci-003. Will be updated with our latest model iteration 2 weeks after it is released. case chatGPTTurbo = "gpt-3.5-turbo" /// Same capabilities as the standard gpt-3.5-turbo model but with 4 times the context. case chatGPTTurbo16k = "gpt-3.5-turbo-16k" /// Snapshot of gpt-3.5-turbo from June 13th 2023 with function calling data. Unlike gpt-3.5-turbo, this model will not receive updates, and will be deprecated 3 months after a new version is released. case chatGPTTurbo0613 = "gpt-3.5-turbo-0613" /// Snapshot of gpt-3.5-turbo-16k from June 13th 2023. Unlike gpt-3.5-turbo-16k, this model will not receive updates, and will be deprecated 3 months after a new version is released. case chatGPTTurbo16k0613 = "gpt-3.5-turbo-16k-0613" /// Can do any language task with better quality, longer output, and consistent instruction-following than the curie, babbage, or ada models. Also supports some additional features such as [inserting text](https://platform.openai.com/docs/guides/gpt/inserting-text). case textDavinci003 = "text-davinci-003" /// Similar capabilities to text-davinci-003 but trained with supervised fine-tuning instead of reinforcement learning case textDavinci002 = "text-davinci-002" // MARK: GPT-4 Models /// More capable than any GPT-3.5 model, able to do more complex tasks, and optimized for chat. Will be updated with our latest model iteration 2 weeks after it is released. case gpt4 = "gpt-4" /// Snapshot of gpt-4 from June 13th 2023 with function calling data. Unlike gpt-4, this model will not receive updates, and will be deprecated 3 months after a new version is released. case gpt4_0613 = "gpt-4-0613" /// Same capabilities as the base gpt-4 mode but with 4x the context length. Will be updated with our latest model iteration. case gpt4_32k = "gpt-4-32k" /// Snapshot of gpt-4-32 from June 13th 2023. Unlike gpt-4-32k, this model will not receive updates, and will be deprecated 3 months after a new version is released. case gpt4_32k0613 = "gpt-4-32k-0613" /// The maximum tokens the models can read public var maxTokens: [String : Int] { [ "gpt-3.5-turbo": 4096, "gpt-3.5-turbo-16k": 16384, "gpt-3.5-turbo-0613": 4096, "gpt-3.5-turbo-16k-0613": 16384, "text-davinci-003": 4097, "text-davinci-002": 4097, "gpt-4": 8192, "gpt-4-0613": 8192, "gpt-4-32k": 32768, "gpt-4-32k-0613": 32768 ] } public var description: String { self.rawValue } } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Chat/ChatRole.swift ================================================ // // ChatRole.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// Used for selecting who sent the message public enum ChatRole: String, Codable, Sendable { /// The context of the chat case system /// The main user chatting case user /// The main AI chatting case assistant } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Completions/CompletionModels.swift ================================================ // // CompletionModels.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// Models used for the Completion endpoint public enum CompletionModels: String, Codable, CustomStringConvertible { /// Very capable, faster and lower cost than Davinci. case textCurie001 = "text-curie-001" /// Capable of straightforward tasks, very fast, and lower cost. case textBabbage001 = "text-babbage-001" /// Capable of very simple tasks, usually the fastest model in the GPT-3 series, and lowest cost. case textAda001 = "text-ada-001" /// Most capable GPT-3 model. Can do any task the other models can do, often with higher quality. case davinci /// Very capable, but faster and lower cost than Davinci. case curie /// Capable of straightforward tasks, very fast, and lower cost. case babbage /// Capable of very simple tasks, usually the fastest model in the GPT-3 series, and lowest cost. case ada /// The maximum tokens the models can read public var maxTokens: [String : Int] { [ "text-curie-001": 2049, "text-babbage-001": 2049, "text-ada-001": 2049, "davinci": 2049, "curie": 2049, "babbage": 2049, "ada": 2049 ] } public var description: String { self.rawValue } } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Files/FileStatus.swift ================================================ // // FileStatus.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The uploaded status of the file. public enum FileStatus: String, Codable { /// The file is uplodaded. case uploaded /// The file is being processed. case processed } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Images/ImageData.swift ================================================ // // ImageData.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The image type of the image response data. public enum ImageData: Codable { enum CodingKeys: String, CodingKey { case url case b64Json = "b64_json" } /// The image is stored as a URL string. case url(String) /// The image is stored as a Base64 binary. case b64Json(String) /// The image itself. public var image: String { switch self { case let .b64Json(b64Json): return b64Json case let .url(url): return url } } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) do { let urlAssociate = try container.decode(String.self, forKey: .url) self = .url(urlAssociate) } catch { let b64Associate = try container.decode(String.self, forKey: .b64Json) self = .b64Json(b64Associate) } } } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Images/ImageModel.swift ================================================ // // ImageModel.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The model to use for image generation. public enum ImageModel: String, Codable, Sendable { /// The DALL-E 2 model. case dalle2 = "dall-e-2" /// The DALL-E 3 model. case dalle3 = "dall-e-3" } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Images/ImageQuality.swift ================================================ // // ImageQuality.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The quality of the image that will be generated. public enum ImageQuality: String, Codable, Sendable { /// Creates images with finer details and greater consistency across the image. case hd /// Creates images with less detail and less consistency across the image. case standard } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Images/ImageResolutions.swift ================================================ // // ImageResolutions.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The image resolution being requested. public enum ImageResolutions: String, Codable, Sendable { /// A 256x256 pixel image request. case small = "256x256" /// A 512x512 pixel image request. case medium = "512x512" /// A 1024x1024 pixel image request. case large = "1024x1024" /// A 1792x1024 pixel image request. case extraLargeLandscape = "1792x1024" /// A 1024x1792 pixel image request. case extraLargePortrait = "1024x1792" } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Images/ImageStyle.swift ================================================ // // ImageStyle.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The style of the generated images. public enum ImageStyle: String, Codable, Sendable { /// Generates hyper-real and dramatic images. case vivid /// Generates more natural, less hyper-real looking images. case natural } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Images/ResponseFormat.swift ================================================ // // ResponseFormat.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The type of image of the response data that will be returned public enum ResponseFormat: String, Codable { /// The image is stored as a URL string. case url = "url" /// The image is stored as a Base64 binary. case base64Json = "b64_json" } ================================================ FILE: Sources/OpenAIKit/Types/Enums/Moderations/ContentPolicyModels.swift ================================================ // // ContentPolicyModels.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// Two content moderations models are available: `text-moderation-stable` and `text-moderation-latest`. /// The default is `text-moderation-latest` which will be automatically upgraded over time. /// This ensures you are always using our most accurate model. /// If you use `text-moderation-stable`, we will provide advanced notice before updating the model. /// Accuracy of `text-moderation-stable` may be slightly lower than for `text-moderation-latest`. public enum ContentPolicyModels: String, Codable { /// The latest model that gets automatically upgraded over time. case latest = "text-moderation-latest" /// The stable model that gets prior notification before being upgraded. case stable = "text-moderation-stable" } ================================================ FILE: Sources/OpenAIKit/Types/Enums/OpenAI/OpenAIErrors.swift ================================================ // // OpenAIError.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// OpenAIKit errors that are thrown depending on the context. public enum OpenAIError: Error { /// No API Key was provided to the OpenAIKit object. case noApiKey /// No body was provided to a decode URL request. case noBody /// The amount of prompts being requested have exceeded the amount OpenAI allocates per time frame. case promptThreshold /// An invalid URL was unwrapped / used. case invalidUrl /// Invalid data was decoded / encoded. case invalidData /// The function has not been implemented yet. case notImplemented /// An incorrect input was found in the ImageParameter. Please edit the input and try submitting again. case incompatibleImageParameter(incorrctInput: (any Sendable)?) /// An unknown error has occured. Please create an issue on [Github](https://github.com/OpenDive/OpenAIKit) if this error is thrown. case unknownError } /// HTTP status-aware API errors mapped from OpenAI responses. public enum OpenAIAPIError: Error { case badRequest(OpenAIErrorResponse?) case authentication(OpenAIErrorResponse?) case permissionDenied(OpenAIErrorResponse?) case notFound(OpenAIErrorResponse?) case conflict(OpenAIErrorResponse?) case unprocessableEntity(OpenAIErrorResponse?) case rateLimit(OpenAIErrorResponse?) case internalServer(statusCode: Int, payload: OpenAIErrorResponse?) case unexpectedStatusCode(statusCode: Int, payload: OpenAIErrorResponse?) } ================================================ FILE: Sources/OpenAIKit/Types/Enums/OpenAI/OpenAIObject.swift ================================================ // // OpenAIObject.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// A specific type of object that OpenAI has responded with. public enum OpenAIObject: String, Codable, Sendable { /// A list object. case list /// A model object. case model /// A model permission object. case modelPermission = "model_permission" /// A text completion object. case textCompletion = "text_completion" /// A Chat Completion. case chatCompletion = "chat.completion" /// An edit object. case edit /// An embedding object. case embedding /// A file object. case file /// A Chat Completion chunk. case chatCompletionChunk = "chat.completion.chunk" } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Audio/SpeechParameters.swift ================================================ import Foundation /// Parameters for text-to-speech generation. public struct SpeechParameters: Encodable { enum CodingKeys: String, CodingKey { case input case model case voice case instructions case responseFormat = "response_format" case speed case streamFormat = "stream_format" } /// Input text to synthesize. public var input: String /// TTS model identifier. public var model: String /// Voice identifier. public var voice: String /// Optional voice instructions. public var instructions: String? /// Output audio format. public var responseFormat: String? /// Playback speed multiplier. public var speed: Double? /// Optional stream format (`audio` or `sse`). public var streamFormat: String? public init( input: String, model: String = "gpt-4o-mini-tts", voice: String = "alloy", instructions: String? = nil, responseFormat: String? = nil, speed: Double? = nil, streamFormat: String? = nil ) { self.input = input self.model = model self.voice = voice self.instructions = instructions self.responseFormat = responseFormat self.speed = speed self.streamFormat = streamFormat } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Audio/TranscriptionParameters.swift ================================================ // // TranscriptionParameters.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation public struct TranscriptionParameters { /// The audio file object (not file name) translate, in one of these formats: mp3, mp4, mpeg, mpga, m4a, wav, or webm. public var file: FormData /// ID of the model to use. Only `whisper-1` is currently available. public var model: String /// An optional text to guide the model's style or continue a previous audio segment. /// The [prompt](https://platform.openai.com/docs/guides/speech-to-text/prompting) should be in English. public var prompt: String? /// The format of the transcript output, in one of these options: json, text, srt, verbose_json, or vtt. public var responseFormat: AudioResponseFormat /// The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. /// If set to 0, the model will use [log probability](https://en.wikipedia.org/wiki/Log_probability) to automatically increase the temperature until certain thresholds are hit. public var temperature: Double /// The language of the input audio. Supplying the input language in /// [ISO-639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) format will improve accuracy and latency. public var language: String? public init( file: Data, model: String = "whisper-1", prompt: String? = nil, responseFormat: AudioResponseFormat = .json, @Clamped(range: 0...1) temperature: Double = 0.0, language: String? = nil ) { self.file = FormData(data: file, mimeType: "audio/mpeg", fileName: "audio.mp3") self.model = model self.prompt = prompt self.responseFormat = responseFormat self.temperature = temperature self.language = language } /// The body of the URL used for OpenAI API requests. internal var body: [String: Any] { var result: [String: Any] = [ "file": self.file, "model": self.model, "response_format": self.responseFormat.rawValue, "temperature": self.temperature ] if let prompt = prompt { result["prompt"] = prompt } if let language = language { result["language"] = language } return result } /// Retrieve the Response object for the request /// - Parameters: /// - url: The `URL` of the request endpoint /// - config: The configuration options for OpenAI's API /// - Returns: A `TransactionResponse` object. internal func retrieveResponse(using url: URL, _ config: Configuration) async throws -> TranscriptionResponse { switch self.responseFormat { case .json, .verboseJson: return try await OpenAIKitSession.shared.decodeUrl( with: url, configuration: config, body: self.body, formSubmission: true ) case .text: let data = try await OpenAIKitSession.shared.decodeUrlTranscriptions( with: url, configuration: config, body: self.body ) return TranscriptionResponse(text: String(decoding: data, as: UTF8.self)) case .srt: let data = try await OpenAIKitSession.shared.decodeUrlTranscriptions( with: url, configuration: config, body: self.body ) return TranscriptionResponse(srt: SRT.parseSRT(from: String(decoding: data, as: UTF8.self))) case .vtt: let data = try await OpenAIKitSession.shared.decodeUrlTranscriptions( with: url, configuration: config, body: self.body ) return TranscriptionResponse(vtt: WebVTTCue.parseWebVTT(from: String(decoding: data, as: UTF8.self))) } } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Batches/BatchParameters.swift ================================================ import Foundation public struct BatchCreateParameters: Encodable { enum CodingKeys: String, CodingKey { case inputFileID = "input_file_id" case endpoint case completionWindow = "completion_window" case metadata } public var inputFileID: String public var endpoint: String public var completionWindow: String public var metadata: [String: String]? public init( inputFileID: String, endpoint: String, completionWindow: String = "24h", metadata: [String: String]? = nil ) { self.inputFileID = inputFileID self.endpoint = endpoint self.completionWindow = completionWindow self.metadata = metadata } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Beta/AssistantParameters.swift ================================================ import Foundation public struct AssistantCreateParameters: Encodable { public var model: String public var name: String? public var description: String? public var instructions: String? public var tools: [AssistantTool]? public var metadata: [String: String]? public init( model: String, name: String? = nil, description: String? = nil, instructions: String? = nil, tools: [AssistantTool]? = nil, metadata: [String: String]? = nil ) { self.model = model self.name = name self.description = description self.instructions = instructions self.tools = tools self.metadata = metadata } } public struct AssistantUpdateParameters: Encodable { public var model: String? public var name: String? public var description: String? public var instructions: String? public var tools: [AssistantTool]? public var metadata: [String: String]? public init( model: String? = nil, name: String? = nil, description: String? = nil, instructions: String? = nil, tools: [AssistantTool]? = nil, metadata: [String: String]? = nil ) { self.model = model self.name = name self.description = description self.instructions = instructions self.tools = tools self.metadata = metadata } } public struct ThreadCreateParameters: Encodable { public var metadata: [String: String]? public init(metadata: [String: String]? = nil) { self.metadata = metadata } } public struct ThreadUpdateParameters: Encodable { public var metadata: [String: String]? public init(metadata: [String: String]? = nil) { self.metadata = metadata } } public struct ThreadRunCreateParameters: Encodable { enum CodingKeys: String, CodingKey { case assistantId = "assistant_id" case model case instructions case metadata } public var assistantId: String public var model: String? public var instructions: String? public var metadata: [String: String]? public init( assistantId: String, model: String? = nil, instructions: String? = nil, metadata: [String: String]? = nil ) { self.assistantId = assistantId self.model = model self.instructions = instructions self.metadata = metadata } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Chat/ChatParameters.swift ================================================ // // ChatParameters.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation public struct ChatParameters: Encodable { enum CodingKeys: String, CodingKey { case model case messages case temperature case topP = "top_p" case numberOfCompletions = "n" case stream case stop case presencePenalty = "presence_penalty" case frequencyPenalty = "frequency_penalty" case logitBias = "logit_bias" case user case functionCall = "function_call" case functions case tools case toolChoice = "tool_choice" case responseFormat = "response_format" case seed case maxCompletionTokens = "max_completion_tokens" case maxTokens = "max_tokens" case parallelToolCalls = "parallel_tool_calls" case logprobs case topLogprobs = "top_logprobs" } /// ID of the model to use. public var model: ChatModels /// ID of the custom model created from fine-tuning. public var customModel: String? /// The messages to generate chat completions for, in the /// [chat format](https://platform.openai.com/docs/guides/chat/introduction). public var messages: [ChatMessage] /// What [sampling temperature](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277) /// to use. /// /// Higher values means the model will take more risks. /// Try 0.9 for more creative applications, and 0 (argmax sampling) for ones with a well-defined answer. /// /// We generally recommend altering this or `top_p` but not both. public var temperature: Double /// An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with `top_p` probability mass. /// /// So 0.1 means only the tokens comprising the top 10% probability mass are considered. /// We generally recommend altering this or `temperature` but not both. public var topP: Double /// How many completions to generate for each prompt. /// /// **Note:** Because this parameter generates many completions, it can quickly consume your token quota. /// Use carefully and ensure that you have reasonable settings for `max_tokens` and `stop`. public var numberOfCompletions: Int /// Whether to stream back partial progress. If set, tokens will be sent as data-only /// [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format) /// as they become available, with the stream terminated by a data: [DONE] message. public var stream: Bool /// Up to 4 sequences where the API will stop generating further tokens. /// The returned text will not contain the stop sequence. public var stop: [String]? /// Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, /// increasing the model's likelihood to talk about new topics. /// /// [See more information about frequency and presence penalties.](https://beta.openai.com/docs/api-reference/parameter-details) public var presencePenalty: Double /// Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, /// decreasing the model's likelihood to repeat the same line verbatim. /// /// [See more information about frequency and presence penalties.](https://beta.openai.com/docs/api-reference/parameter-details) public var frequencyPenalty: Double /// Modify the likelihood of specified tokens appearing in the completion. /// /// Accepts a json object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. /// You can use this [tokenizer tool](https://beta.openai.com/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. /// Mathematically, the bias is added to the logits generated by the model prior to sampling. /// The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; /// values like -100 or 100 should result in a ban or exclusive selection of the relevant token. /// /// As an example, you can pass `{"50256": -100}` to prevent the `<|endoftext|>` token from being generated. public var logitBias: [String: Int]? /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. /// [Learn more.](https://beta.openai.com/docs/guides/safety-best-practices/end-user-ids) public var user: String? /// Controls how the model calls functions. "none" means the model will not call a function and instead generates a message. /// "auto" means the model can pick between generating a message or calling a function. Specifying a particular function via /// {"name": "my_function"} forces the model to call that function. "none" is the default when no functions are present. "auto" is /// the default if functions are present. public var functionCall: String? /// A list of functions the model may generate JSON inputs for. public var functions: [Function]? /// A list of modern tools the model may call. public var tools: [ChatTool]? /// Controls which tool should be used by the model (`none`, `auto`, `required`). public var toolChoice: String? /// Structured output response format configuration. public var responseFormat: ChatResponseFormat? /// Optional deterministic seed. public var seed: Int? /// Upper bound for completion tokens. public var maxCompletionTokens: Int? /// Legacy max tokens field. public var maxTokens: Int? /// Controls whether the model can call tools in parallel. public var parallelToolCalls: Bool? /// Whether to include token log probabilities. public var logprobs: Bool? /// Number of top log probabilities to return. public var topLogprobs: Int? public init( model: ChatModels, customModel: String? = nil, messages: [ChatMessage], temperature: Double = 1.0, topP: Double = 1.0, numberOfCompletions: Int = 1, stream: Bool = false, stop: [String]? = nil, presencePenalty: Double = 0.0, frequencyPenalty: Double = 0.0, logitBias: [String : Int]? = nil, user: String? = nil, functionCall: String? = nil, functions: [Function]? = nil, tools: [ChatTool]? = nil, toolChoice: String? = nil, responseFormat: ChatResponseFormat? = nil, seed: Int? = nil, maxCompletionTokens: Int? = nil, maxTokens: Int? = nil, parallelToolCalls: Bool? = nil, logprobs: Bool? = nil, topLogprobs: Int? = nil ) { self.model = model self.customModel = customModel self.messages = messages self.temperature = temperature self.topP = topP self.numberOfCompletions = numberOfCompletions self.stream = stream self.stop = stop self.presencePenalty = presencePenalty self.frequencyPenalty = frequencyPenalty self.logitBias = logitBias self.user = user self.functionCall = functionCall self.functions = functions self.tools = tools self.toolChoice = toolChoice self.responseFormat = responseFormat self.seed = seed self.maxCompletionTokens = maxCompletionTokens self.maxTokens = maxTokens self.parallelToolCalls = parallelToolCalls self.logprobs = logprobs self.topLogprobs = topLogprobs } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) let selectedModel = self.customModel ?? self.model.rawValue try container.encode(selectedModel, forKey: .model) try container.encode(self.messages, forKey: .messages) try container.encode(self.temperature, forKey: .temperature) try container.encode(self.topP, forKey: .topP) try container.encode(self.numberOfCompletions, forKey: .numberOfCompletions) try container.encode(self.stream, forKey: .stream) try container.encode(self.presencePenalty, forKey: .presencePenalty) try container.encode(self.frequencyPenalty, forKey: .frequencyPenalty) try container.encodeIfPresent(self.stop, forKey: .stop) try container.encodeIfPresent(self.logitBias, forKey: .logitBias) try container.encodeIfPresent(self.user, forKey: .user) try container.encodeIfPresent(self.functionCall, forKey: .functionCall) try container.encodeIfPresent(self.functions, forKey: .functions) try container.encodeIfPresent(self.tools, forKey: .tools) try container.encodeIfPresent(self.toolChoice, forKey: .toolChoice) try container.encodeIfPresent(self.responseFormat, forKey: .responseFormat) try container.encodeIfPresent(self.seed, forKey: .seed) try container.encodeIfPresent(self.maxCompletionTokens, forKey: .maxCompletionTokens) try container.encodeIfPresent(self.maxTokens, forKey: .maxTokens) try container.encodeIfPresent(self.parallelToolCalls, forKey: .parallelToolCalls) try container.encodeIfPresent(self.logprobs, forKey: .logprobs) try container.encodeIfPresent(self.topLogprobs, forKey: .topLogprobs) } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Chat/ChatResponseFormat.swift ================================================ import Foundation /// Response format options for chat completions. public struct ChatResponseFormat: Codable { public enum Kind: String, Codable { case text case jsonObject = "json_object" case jsonSchema = "json_schema" } public var type: Kind public init(type: Kind) { self.type = type } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Chat/ChatTool.swift ================================================ import Foundation /// Tool definition for modern chat completions. public struct ChatTool: Codable { /// Tool type. Defaults to `function`. public var type: String /// Function tool payload. public var function: Function public init(type: String = "function", function: Function) { self.type = type self.function = function } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Chat/Function.swift ================================================ // // Function.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// A function object used within a Chat Completion endpoint. public struct Function: Codable { /// The name of the function to be called. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64. public var name: String /// A description of what the function does, used by the model to choose when and how to call the function. public var description: String? /// The parameters the functions accepts, described as a JSON Schema object. See the [guide](https://platform.openai.com/docs/guides/gpt/function-calling) for examples, /// and the [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for documentation about the format. /// To describe a function that accepts no parameters, provide the value {"type": "object", "properties": {}}. public var parameters: Parameters public init(name: String, description: String? = nil, parameters: Parameters) { self.name = name self.description = description self.parameters = parameters } internal var body: [String: Any] { var result: [String: Any] = [ "name": self.name, "parameters": self.parameters.body ] if let description = self.description { result["description"] = description } return result } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Chat/Parameter.swift ================================================ // // Parameter.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// Function parameter used for Chat Completion endpoint. public struct Parameters: Codable { enum CodingKeys: String, CodingKey { case type, properties, required } /// The variable type of the parameter public var type: String /// Parameters used within the function object call public var properties: [String: Property] /// The required parameters public var required: [String]? public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) type = try container.decode(String.self, forKey: .type) properties = [:] let propertiesContainer = try container.nestedContainer(keyedBy: GenericCodingKeys.self, forKey: .properties) for key in propertiesContainer.allKeys { let decodedProperty = try propertiesContainer.decode(ParameterDetail.self, forKey: key) properties[key.stringValue] = decodedProperty } required = try container.decodeIfPresent([String].self, forKey: .required) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(type, forKey: .type) var propertiesContainer = container.nestedContainer(keyedBy: GenericCodingKeys.self, forKey: .properties) for (key, value) in properties { try propertiesContainer.encode(value, forKey: GenericCodingKeys(key: key)) } try container.encode(required, forKey: .required) } public init(type: String, properties: [String: Property], required: [String]? = nil) { self.type = type self.properties = properties self.required = required } internal var body: [String: Any] { var result: [String: Any] = [ "type": self.type, "properties": self.properties.body ] if let required = self.required { result["required"] = required } return result } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Chat/ParameterDetail.swift ================================================ // // ParameterDetail.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// The variable used for the parameter within a Chat Completion endpoint public struct ParameterDetail: Property { /// The variable type of the parameter variable public var type: String /// A description of the parameter public var description: String? /// If the parameter is an enum, this is used to determine what type of cases could be used public var enumValues: [String]? enum CodingKeys: String, CodingKey { case type, description case enumValues = "enum" } public init(type: String, description: String? = nil, enumValues: [String]? = nil) { self.type = type self.description = description self.enumValues = enumValues } public var body: [String: Any] { var result: [String: Any] = [ "type": self.type, ] if let description = self.description { result["description"] = description } if let enumValues = self.enumValues { result["enum"] = enumValues } return result } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Completions/CompletionParameters.swift ================================================ // // CompletionParameters.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// Parameter struct used for creating GPT3 completions. public struct CompletionParameters: Encodable { enum CodingKeys: String, CodingKey { case model case prompt case suffix case maxTokens = "max_tokens" case temperature case topP = "top_p" case numberOfCompletions = "n" case logprobs case echo case stop case presencePenalty = "presence_penalty" case frequencyPenalty = "frequency_penalty" case bestOf = "best_of" case logitBias = "logit_bias" case user case stream } /// ID of the model to use. /// /// You can use the [List models](https://beta.openai.com/docs/api-reference/models/list) /// API to see all of your available models, or see our [Model overview](https://beta.openai.com/docs/models/overview) /// for descriptions of them. public var model: CompletionModels /// The prompt(s) to generate completions for, encoded as a string, array of strings, array of tokens, or array of token arrays. /// /// Note that `<|endoftext|>` is the document separator that the model sees during training, so if a prompt is not specified the /// model will generate as if from the beginning of a new document. public var prompt: [String] /// The suffix that comes after a completion of inserted text. public var suffix: String? /// The maximum number of [tokens](https://beta.openai.com/tokenizer) to generate in the completion. /// /// The token count of your prompt plus `max_tokens` cannot exceed the model's context length. Most models have /// a context length of 2048 tokens (except for the newest models, which support 4096). public var maxTokens: Int /// What [sampling temperature](https://towardsdatascience.com/how-to-sample-from-language-models-682bceb97277) /// to use. /// /// Higher values means the model will take more risks. /// Try 0.9 for more creative applications, and 0 (argmax sampling) for ones with a well-defined answer. /// /// We generally recommend altering this or `top_p` but not both. public var temperature: Double /// An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with `top_p` probability mass. /// /// So 0.1 means only the tokens comprising the top 10% probability mass are considered. /// We generally recommend altering this or `temperature` but not both. public var topP: Double /// How many completions to generate for each prompt. /// /// **Note:** Because this parameter generates many completions, it can quickly consume your token quota. /// Use carefully and ensure that you have reasonable settings for `max_tokens` and `stop`. public var numberOfCompletions: Int /// Include the log probabilities on the `logprobs` most likely tokens, as well the chosen tokens. /// /// For example, if `logprobs` is 5, the API will return a list of the 5 most likely tokens. /// The API will always return the `logprob` of the sampled token, /// so there may be up to `logprobs+1` elements in the response. /// /// The maximum value for `logprobs is 5`. If you need more than this, /// please contact us through our [Help center](https://help.openai.com/) and describe your use case. public var logprobs: Int? /// Echo back the prompt in addition to the completion. public var echo: Bool /// Up to 4 sequences where the API will stop generating further tokens. /// The returned text will not contain the stop sequence. public var stop: [String]? /// Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, /// increasing the model's likelihood to talk about new topics. /// /// [See more information about frequency and presence penalties.](https://beta.openai.com/docs/api-reference/parameter-details) public var presencePenalty: Double /// Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, /// decreasing the model's likelihood to repeat the same line verbatim. /// /// [See more information about frequency and presence penalties.](https://beta.openai.com/docs/api-reference/parameter-details) public var frequencyPenalty: Double /// Generates `best_of` completions server-side and returns the "best" (the one with the highest log probability per token). Results cannot be streamed. /// When used with `n`, `best_of` controls the number of candidate completions and `n` specifies how many to return – `best_of` must be greater than `n`. /// /// **Note:** Because this parameter generates many completions, it can quickly consume your token quota. Use carefully and ensure that you have reasonable settings for /// `max_tokens` and `stop`. public var bestOf: Int /// Modify the likelihood of specified tokens appearing in the completion. /// /// Accepts a json object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. /// You can use this [tokenizer tool](https://beta.openai.com/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. /// Mathematically, the bias is added to the logits generated by the model prior to sampling. /// The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; /// values like -100 or 100 should result in a ban or exclusive selection of the relevant token. /// /// As an example, you can pass `{"50256": -100}` to prevent the `<|endoftext|>` token from being generated. public var logitBias: [String: Int]? /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. /// [Learn more.](https://beta.openai.com/docs/guides/safety-best-practices/end-user-ids) public var user: String? /// Whether to stream partial completion deltas. public var stream: Bool? public init( model: CompletionModels, prompt: [String] = ["<|endoftext|>"], suffix: String? = nil, maxTokens: Int = 16, temperature: Double = 1.0, topP: Double = 1.0, @Clamped(range: 1...10) numberOfCompletions: Int = 1, logprobs: Int? = nil, maxLogprobs: Int = 5, echo: Bool = false, stop: [String]? = nil, @Clamped(range: -2.0...2.0) presencePenalty: Double = 0.0, @Clamped(range: -2.0...2.0) frequencyPenalty: Double = 0.0, bestOf: Int = 1, logitBias: [String: Int]? = nil, user: String? = nil, stream: Bool? = nil ) { self.model = model self.prompt = prompt self.suffix = suffix self.maxTokens = maxTokens self.temperature = temperature self.topP = topP self.numberOfCompletions = numberOfCompletions self.echo = echo self.stop = stop self.presencePenalty = presencePenalty self.frequencyPenalty = frequencyPenalty self.bestOf = bestOf self.logitBias = logitBias self.user = user self.stream = stream if let logprobs = logprobs { if logprobs > maxLogprobs { self.logprobs = maxLogprobs } else if logprobs < 1 { self.logprobs = 1 } else { self.logprobs = logprobs } } else { self.logprobs = nil } } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Containers/ContainerParameters.swift ================================================ import Foundation public struct ContainerCreateParameters: Encodable { public var name: String public var metadata: [String: String]? public init(name: String, metadata: [String: String]? = nil) { self.name = name self.metadata = metadata } } public struct ContainerFileCreateParameters: Encodable { enum CodingKeys: String, CodingKey { case fileID = "file_id" } public var fileID: String public init(fileID: String) { self.fileID = fileID } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Conversations/ConversationParameters.swift ================================================ import Foundation public struct ConversationCreateParameters: Encodable { public var metadata: [String: String]? public init(metadata: [String: String]? = nil) { self.metadata = metadata } } public struct ConversationItemCreateParameters: Encodable { public var type: String public var role: String? public var content: String public init(type: String = "message", role: String? = nil, content: String) { self.type = type self.role = role self.content = content } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Embeddings/EmbeddingsParameters.swift ================================================ // // EmbeddingsParameters.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// Parameter used for the Embeddings endpoint. public struct EmbeddingsParameters: Encodable { /// ID of the model to use. /// /// You can use the [List models](https://beta.openai.com/docs/api-reference/models/list) /// API to see all of your available models, or see our [Model overview](https://beta.openai.com/docs/models/overview) /// for descriptions of them. public var model: String /// Input text to get embeddings for, encoded as a string or array of tokens. /// /// To get embeddings for multiple inputs in a single request, pass an array of strings or array of token arrays. /// Each input must not exceed 2048 tokens in length. /// /// Unless you are embedding code, we suggest replacing newlines (`\n`) in your input with a single space, /// as we have observed inferior results when newlines are present. public var input: String /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. /// [Learn more.](https://beta.openai.com/docs/guides/safety-best-practices/end-user-ids) public var user: String? public init( model: String = "text-embedding-ada-002", input: String, user: String? = nil ) { self.model = model self.input = input self.user = user } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Evals/EvalParameters.swift ================================================ import Foundation public struct EvalCreateParameters: Encodable { public var name: String public var metadata: [String: String]? public init(name: String, metadata: [String: String]? = nil) { self.name = name self.metadata = metadata } } public struct EvalRunCreateParameters: Encodable { enum CodingKeys: String, CodingKey { case input case model case metadata } public var input: String public var model: String? public var metadata: [String: String]? public init(input: String, model: String? = nil, metadata: [String: String]? = nil) { self.input = input self.model = model self.metadata = metadata } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Files/UploadFileParameters.swift ================================================ // // UploadFileParameters.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// Parameter used for uploading files. public struct UploadFileParameters { /// Name of the [JSON Lines](https://jsonlines.readthedocs.io/en/latest/) file to be uploaded. /// /// If the `purpose` is set to "fine-tune", each line is a JSON record with "prompt" and "completion" fields /// representing your [training examples](https://beta.openai.com/docs/guides/fine-tuning/prepare-training-data). public var file: FormData /// The intended purpose of the uploaded documents. /// /// Use "fine-tune" for [Fine-tuning](https://beta.openai.com/docs/api-reference/fine-tunes). /// This allows us to validate the format of the uploaded file. public var purpose: String public init( file: Data, fileName: String, purpose: String ) { self.file = FormData(data: file, mimeType: "application/octet-stream", fileName: fileName) self.purpose = purpose } internal var body: [String: Any] { return ["file": self.file, "purpose": self.purpose] } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/FineTuning/FineTuningParameters.swift ================================================ import Foundation public struct FineTuningJobCreateParameters: Encodable { enum CodingKeys: String, CodingKey { case model case trainingFileID = "training_file" case validationFileID = "validation_file" case suffix } public var model: String public var trainingFileID: String public var validationFileID: String? public var suffix: String? public init( model: String, trainingFileID: String, validationFileID: String? = nil, suffix: String? = nil ) { self.model = model self.trainingFileID = trainingFileID self.validationFileID = validationFileID self.suffix = suffix } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Images/ImageEditParameters.swift ================================================ // // ImageEditParameters.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) import SwiftUI #endif #if os(macOS) import Foundation import AppKit #endif #if os(Linux) || SERVER import Foundation #endif /// Parameter used for creating image edits public struct ImageEditParameters { /// The image to edit. /// /// Must be a valid PNG file, less than 4MB, and square. If mask is not provided, /// image must have transparency, which will be used as the mask. public var image: FormData /// An additional image whose fully transparent areas (e.g. where alpha is zero) indicate where `image` should be edited. /// /// Must be a valid PNG file, less than 4MB, and have the same dimensions as `image`. public var mask: FormData /// A text description of the desired image(s). /// /// The maximum length is 1000 characters. public var prompt: String /// The number of images to generate. /// /// Must be between 1 and 10. public var numberOfImages: Int /// The size of the generated images. /// /// Must be one of `.small`, `.medium`, or `.large`. public var resolution: ImageResolutions /// The format in which the generated images are returned. /// /// Must be one of `url` or `b64_json`. public var responseFormat: ResponseFormat /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. /// [Learn more.](https://beta.openai.com/docs/guides/safety-best-practices/end-user-ids) public var user: String? public init( image: Data, mask: Data, prompt: String, @Clamped(range: 1...10) numberOfImages: Int = 1, resolution: ImageResolutions = .large, responseFormat: ResponseFormat = .url, user: String? = nil ) throws { self.image = FormData(data: image, mimeType: "image/png", fileName: "image.png") self.mask = FormData(data: mask, mimeType: "image/png", fileName: "mask.png") self.prompt = prompt self.numberOfImages = numberOfImages self.resolution = resolution self.responseFormat = responseFormat self.user = user } #if os(iOS) || os(tvOS) || os(watchOS) public init( image: UIImage, mask: UIImage, prompt: String, @Clamped(range: 1...10) numberOfImages: Int = 1, resolution: ImageResolutions = .large, responseFormat: ResponseFormat = .url, user: String? = nil ) throws { do { guard let imageData = image.pngData() else { throw OpenAIError.invalidData } guard let maskData = mask.pngData() else { throw OpenAIError.invalidData } self.image = FormData(data: imageData, mimeType: "image/png", fileName: "image.png") self.mask = FormData(data: maskData, mimeType: "image/png", fileName: "mask.png") self.prompt = prompt self.numberOfImages = numberOfImages self.resolution = resolution self.responseFormat = responseFormat self.user = user } catch { throw OpenAIError.invalidData } } #endif #if os(macOS) public init( image: NSImage, mask: NSImage, prompt: String, @Clamped(range: 1...10) numberOfImages: Int = 1, resolution: ImageResolutions = .large, responseFormat: ResponseFormat = .url, user: String? = nil ) throws { do { guard let imageData = image.pngData(size: resolution) else { throw OpenAIError.invalidData } guard let maskData = mask.pngData(size: resolution) else { throw OpenAIError.invalidData } self.image = FormData(data: imageData, mimeType: "image/png", fileName: "image.png") self.mask = FormData(data: maskData, mimeType: "image/png", fileName: "mask.png") self.prompt = prompt self.numberOfImages = numberOfImages self.resolution = resolution self.responseFormat = responseFormat self.user = user } catch { throw OpenAIError.invalidData } } #endif /// The body of the URL used for OpenAI API requests. internal var body: [String: Any] { var result: [String: Any] = [ "image": self.image, "mask": self.mask, "prompt": self.prompt, "n": self.numberOfImages, "size": self.resolution.rawValue, "response_format": self.responseFormat.rawValue ] if let user = self.user { result["user"] = user } return result } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Images/ImageParameters.swift ================================================ // // ImageParameters.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// Parameter used for generating images given a prompt. public struct ImageParameters: Encodable { enum CodingKeys: String, CodingKey { case prompt case numberOfImages = "n" case resolution = "size" case quality case model case style case responseFormat = "response_format" case user } /// A text description of the desired image(s). /// /// The maximum length is 1000 characters. public var prompt: String /// The number of images to generate. /// /// Must be between 1 and 10. public var numberOfImages: Int /// The size of the generated images. /// /// Must be one of `.small`, `.medium`, `.large` for `.dalle2`. Must be one of `.large`, `.extraLargeLandscape`, or `.extraLargePortrait` for `.dalle3`. public var resolution: ImageResolutions /// The quality of the image that will be generated. /// /// `hd` creates images with finer details and greater consistency across the image. /// /// **Note:** This param is only supported for dall-e-3. public var quality: ImageQuality? /// The model to use for image generation. public var model: ImageModel /// The style of the generated images. /// /// Must be one of vivid or natural. Vivid causes the model to lean towards generating hyper-real and dramatic images. Natural causes the model to produce more natural, less hyper-real looking images. /// /// **Note:** This param is only supported for dall-e-3. public var style: ImageStyle? /// The format in which the generated images are returned. /// /// Must be one of `url` or `b64_json`. public var responseFormat: ResponseFormat /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. /// [Learn more.](https://beta.openai.com/docs/guides/safety-best-practices/end-user-ids) public var user: String? public init( prompt: String, @Clamped(range: 1...10) numberofImages: Int = 1, resolution: ImageResolutions = .large, quality: ImageQuality? = nil, style: ImageStyle? = nil, model: ImageModel = .dalle2, responseFormat: ResponseFormat = .url, user: String? = nil ) { self.prompt = prompt self.numberOfImages = numberofImages self.resolution = resolution self.quality = quality self.style = style self.model = model self.responseFormat = responseFormat self.user = user } /// Checks to verify that the user hasn't inputted any incorrect parameters for the endpoint. /// - Throws: An `OpenAIError` if any of the parameters are incompatible with the inputted model. internal func checkForCompatibility() throws { switch self.model { case .dalle2: guard self.prompt.count <= 1_000 else { throw OpenAIError.incompatibleImageParameter(incorrctInput: self.prompt) } guard self.quality == nil else { throw OpenAIError.incompatibleImageParameter(incorrctInput: self.quality) } guard self.style == nil else { throw OpenAIError.incompatibleImageParameter(incorrctInput: self.style) } guard self.resolution == .small || self.resolution == .medium || self.resolution == .large else { throw OpenAIError.incompatibleImageParameter(incorrctInput: self.resolution) } case .dalle3: guard self.prompt.count <= 4_000 else { throw OpenAIError.incompatibleImageParameter(incorrctInput: self.prompt) } guard self.numberOfImages == 1 else { throw OpenAIError.incompatibleImageParameter(incorrctInput: self.numberOfImages) } guard self.resolution == .large || self.resolution == .extraLargePortrait || self.resolution == .extraLargeLandscape else { throw OpenAIError.incompatibleImageParameter(incorrctInput: self.resolution) } } } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Images/ImageVariationParameters.swift ================================================ // // ImageVariationParameters.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) import SwiftUI #endif #if os(macOS) import Foundation import AppKit #endif #if os(Linux) || SERVER import Foundation #endif /// Parameter struct used for generating image variation(s). public struct ImageVariationParameters { /// The image to use as the basis for the variation(s). /// /// Must be a valid PNG file, less than 4MB, and square. public var image: FormData /// The number of images to generate. /// /// Must be between 1 and 10. public var numberOfImages: Int /// The size of the generated images. /// /// Must be one of `.small`, `.medium`, or `.large`. public var resolution: ImageResolutions /// The format in which the generated images are returned. /// /// Must be one of `url` or `b64_json`. public var responseFormat: ResponseFormat /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. /// [Learn more.](https://beta.openai.com/docs/guides/safety-best-practices/end-user-ids) public var user: String? public init( imageData: Data, @Clamped(range: 1...10) numberOfImages: Int = 1, resolution: ImageResolutions = .large, responseFormat: ResponseFormat = .url, user: String? = nil ) throws { self.image = FormData(data: imageData, mimeType: "image/png", fileName: "image.png") self.numberOfImages = numberOfImages self.resolution = resolution self.responseFormat = responseFormat self.user = user } #if os(iOS) || os(tvOS) || os(watchOS) || os(visionOS) public init( image: UIImage, @Clamped(range: 1...10) numberOfImages: Int = 1, resolution: ImageResolutions = .large, responseFormat: ResponseFormat = .url, user: String? = nil ) throws { do { guard let imageData = image.pngData() else { throw OpenAIError.invalidData } self.image = FormData(data: imageData, mimeType: "image/png", fileName: "image.png") self.numberOfImages = numberOfImages self.resolution = resolution self.responseFormat = responseFormat self.user = user } catch { throw OpenAIError.invalidData } } #endif #if os(macOS) public init( image: NSImage, @Clamped(range: 1...10) numberOfImages: Int = 1, resolution: ImageResolutions = .large, responseFormat: ResponseFormat = .url, user: String? = nil ) throws { do { guard let imageData = image.pngData(size: resolution) else { throw OpenAIError.invalidData } self.image = FormData(data: imageData, mimeType: "image/png", fileName: "image.png") self.numberOfImages = numberOfImages self.resolution = resolution self.responseFormat = responseFormat self.user = user } catch { throw OpenAIError.invalidData } } #endif /// The body of the URL used for OpenAI API requests. internal var body: [String: Any] { var result: [String: Any] = [ "image": self.image, "n": self.numberOfImages, "size": self.resolution.rawValue, "response_format": self.responseFormat.rawValue ] if let user = self.user { result["user"] = user } return result } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Moderations/ConentPolicyParameters.swift ================================================ // // ContentPolicyParameters.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The parameter struct used for the Moderations endpoint public struct ContentPolicyParameters { /// The input text to classify. public var input: String /// Two content moderations models are available: `text-moderation-stable` and `text-moderation-latest`. /// /// The default is `text-moderation-latest` which will be automatically upgraded over time. /// This ensures you are always using our most accurate model. If you use `text-moderation-stable`, /// we will provide advanced notice before updating the model. Accuracy of `text-moderation-stable` /// may be slightly lower than for `text-moderation-latest`. public var model: ContentPolicyModels public init( input: String, model: ContentPolicyModels = .latest ) { self.input = input self.model = model } /// The body of the URL used for OpenAI API requests. internal var body: [String: Any] { return ["input": self.input, "model": self.model.rawValue] } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Realtime/RealtimeParameters.swift ================================================ import Foundation public struct RealtimeCallCreateParameters: Encodable { public var model: String? public var metadata: [String: String]? public init(model: String? = nil, metadata: [String: String]? = nil) { self.model = model self.metadata = metadata } } public struct RealtimeCallReferParameters: Encodable { public var target: String public var reason: String? public init(target: String, reason: String? = nil) { self.target = target self.reason = reason } } public struct RealtimeClientSecretCreateParameters: Encodable { public var model: String? public var voice: String? public init(model: String? = nil, voice: String? = nil) { self.model = model self.voice = voice } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Responses/ResponseParameters.swift ================================================ import Foundation public struct ResponseCreateParameters: Encodable { public var model: String public var input: String public var instructions: String? public var stream: Bool? public var metadata: [String: String]? public init( model: String, input: String, instructions: String? = nil, stream: Bool? = nil, metadata: [String: String]? = nil ) { self.model = model self.input = input self.instructions = instructions self.stream = stream self.metadata = metadata } } public struct ResponseInputTokensParameters: Encodable { public var model: String public var input: String public init(model: String, input: String) { self.model = model self.input = input } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Skills/SkillParameters.swift ================================================ import Foundation public struct SkillCreateParameters: Encodable { public var name: String public var description: String? public var metadata: [String: String]? public init(name: String, description: String? = nil, metadata: [String: String]? = nil) { self.name = name self.description = description self.metadata = metadata } } public struct SkillUpdateParameters: Encodable { public var name: String? public var description: String? public var metadata: [String: String]? public init(name: String? = nil, description: String? = nil, metadata: [String: String]? = nil) { self.name = name self.description = description self.metadata = metadata } } public struct SkillContentUpdateParameters: Encodable { public var content: String public init(content: String) { self.content = content } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Uploads/UploadParameters.swift ================================================ import Foundation public struct UploadCreateParameters: Encodable { enum CodingKeys: String, CodingKey { case bytes case filename case purpose case mimeType = "mime_type" } public var bytes: Int public var filename: String public var purpose: String public var mimeType: String? public init(bytes: Int, filename: String, purpose: String, mimeType: String? = nil) { self.bytes = bytes self.filename = filename self.purpose = purpose self.mimeType = mimeType } } public struct UploadCompleteParameters: Encodable { enum CodingKeys: String, CodingKey { case partIDs = "part_ids" } public var partIDs: [String] public init(partIDs: [String]) { self.partIDs = partIDs } } public struct UploadPartCreateParameters: Encodable { public var data: String public init(data: String) { self.data = data } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/VectorStores/VectorStoreParameters.swift ================================================ import Foundation public struct VectorStoreCreateParameters: Encodable { enum CodingKeys: String, CodingKey { case name case fileIDs = "file_ids" case metadata } public var name: String? public var fileIDs: [String]? public var metadata: [String: String]? public init(name: String? = nil, fileIDs: [String]? = nil, metadata: [String: String]? = nil) { self.name = name self.fileIDs = fileIDs self.metadata = metadata } } public struct VectorStoreUpdateParameters: Encodable { public var name: String? public var metadata: [String: String]? public init(name: String? = nil, metadata: [String: String]? = nil) { self.name = name self.metadata = metadata } } public struct VectorStoreFileCreateParameters: Encodable { enum CodingKeys: String, CodingKey { case fileID = "file_id" } public var fileID: String public init(fileID: String) { self.fileID = fileID } } public struct VectorStoreFileBatchCreateParameters: Encodable { enum CodingKeys: String, CodingKey { case fileIDs = "file_ids" } public var fileIDs: [String] public init(fileIDs: [String]) { self.fileIDs = fileIDs } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Parameters/Videos/VideoParameters.swift ================================================ import Foundation public struct VideoCreateParameters: Encodable { public var model: String public var prompt: String public init(model: String, prompt: String) { self.model = model self.prompt = prompt } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Audio/TranscriptionResponse.swift ================================================ // // TranscriptionResponse.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation public struct TranscriptionResponse: Codable { /// The text content of the transcription public let text: String? /// What type of task was performed (transcribe or translate) public let task: String? /// What language was the audio in public let language: String? /// The duration of the audio source public let duration: Double? /// Transcription details on each sentence public let segments: [TranscriptionSegment]? /// The WebVTT formatted text public let vtt: [WebVTTCue]? /// The SRT formatted text public let srt: [SRT]? public init( text: String? = nil, task: String? = nil, language: String? = nil, duration: Double? = nil, segments: [TranscriptionSegment]? = nil, vtt: [WebVTTCue]? = nil, srt: [SRT]? = nil ) { self.text = text self.task = task self.language = language self.duration = duration self.segments = segments self.vtt = vtt self.srt = srt } } public struct TranscriptionSegment: Codable { enum CodingKeys: String, CodingKey { case id case seek case start case end case text case tokens case temperature case averageLogprob = "avg_logprob" case compressionRatio = "compression_ratio" case noSpeechProb = "no_speech_prob" } public let id: Int public let seek: Int public let start: Double public let end: Double public let text: String public let tokens: [Int] public let temperature: Double public let averageLogprob: Double public let compressionRatio: Double public let noSpeechProb: Double } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Batches/BatchModels.swift ================================================ import Foundation public struct BatchObject: Codable { enum CodingKeys: String, CodingKey { case id case object case endpoint case inputFileID = "input_file_id" case completionWindow = "completion_window" case status case createdAt = "created_at" case outputFileID = "output_file_id" case errorFileID = "error_file_id" } public let id: String public let object: String? public let endpoint: String? public let inputFileID: String? public let completionWindow: String? public let status: String? public let createdAt: Int? public let outputFileID: String? public let errorFileID: String? } public struct BatchListResponse: Codable { public let object: String public let data: [BatchObject] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Beta/AssistantModels.swift ================================================ import Foundation public struct AssistantTool: Codable { public var type: String public init(type: String) { self.type = type } } public struct AssistantObject: Codable { enum CodingKeys: String, CodingKey { case id case object case createdAt = "created_at" case name case description case model case instructions case tools case metadata } public let id: String public let object: String? public let createdAt: Int? public let name: String? public let description: String? public let model: String public let instructions: String? public let tools: [AssistantTool]? public let metadata: [String: String]? } public struct AssistantListResponse: Codable { public let object: String public let data: [AssistantObject] } public struct ThreadObject: Codable { enum CodingKeys: String, CodingKey { case id case object case createdAt = "created_at" case metadata } public let id: String public let object: String? public let createdAt: Int? public let metadata: [String: String]? } public struct ThreadListResponse: Codable { public let object: String public let data: [ThreadObject] } public struct ThreadRunObject: Codable { enum CodingKeys: String, CodingKey { case id case object case createdAt = "created_at" case status case model case assistantId = "assistant_id" case threadId = "thread_id" } public let id: String public let object: String? public let createdAt: Int? public let status: String? public let model: String? public let assistantId: String? public let threadId: String? } public struct ThreadRunListResponse: Codable { public let object: String public let data: [ThreadRunObject] } public struct ThreadRunStepObject: Codable { public let id: String public let object: String? public let type: String? public let status: String? } public struct ThreadRunStepListResponse: Codable { public let object: String public let data: [ThreadRunStepObject] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Chat/ChatResponse.swift ================================================ // // ChatResponse.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // public struct ChatResponse: Codable, Identifiable, Sendable { /// The ID of the Completion public let id: String /// The `OpenAIObject` type of the Completion public let object: OpenAIObject /// The creation date of the Completion public let created: Int /// The output of choices the `model` made. public let choices: [ChatChoice] /// The token usage of the Completion. public let usage: Usage? } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Completions/CompletionResponse.swift ================================================ // // CompletionResponse.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// Completion Response from OpenAI public struct CompletionResponse: Codable, Identifiable, Sendable { /// The ID of the Completion public let id: String /// The `OpenAIObject` type of the Completion public let object: OpenAIObject /// The creation date of the Completion public let created: Int /// The model used for the Completion. public let model: String /// The output of choices the `model` made. public let choices: [Choice] /// The token usage of the Completion. public let usage: Usage } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Containers/ContainerModels.swift ================================================ import Foundation public struct ContainerObject: Codable { enum CodingKeys: String, CodingKey { case id case object case name case status case createdAt = "created_at" } public let id: String public let object: String? public let name: String? public let status: String? public let createdAt: Int? } public struct ContainerListResponse: Codable { public let object: String public let data: [ContainerObject] } public struct ContainerFileObject: Codable { enum CodingKeys: String, CodingKey { case id case object case filename case bytes case createdAt = "created_at" } public let id: String public let object: String? public let filename: String? public let bytes: Int? public let createdAt: Int? } public struct ContainerFileListResponse: Codable { public let object: String public let data: [ContainerFileObject] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Conversations/ConversationModels.swift ================================================ import Foundation public struct ConversationObject: Codable { enum CodingKeys: String, CodingKey { case id case object case createdAt = "created_at" case metadata } public let id: String public let object: String? public let createdAt: Int? public let metadata: [String: String]? } public struct ConversationListResponse: Codable { public let object: String public let data: [ConversationObject] } public struct ConversationItemObject: Codable { enum CodingKeys: String, CodingKey { case id case object case type case role case content case createdAt = "created_at" } public let id: String public let object: String? public let type: String? public let role: String? public let content: String? public let createdAt: Int? } public struct ConversationItemListResponse: Codable { public let object: String public let data: [ConversationItemObject] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Embeddings/EmbeddingsData.swift ================================================ // // EmbeddingsData.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// Contains the raw embeddings for the Embeddings endpoint public struct EmbeddingsData: Codable { /// The `OpenAIObject` object type of the Embeddings public let object: OpenAIObject /// The embeddings themselves public let embedding: [Double] /// The index of the embedding object within the data array. public let index: Int } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Embeddings/EmbeddingsResponse.swift ================================================ // // EmbeddingsResponse.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The response sent by the Embeddings endpoint. public struct EmbeddingsResponse: Codable { /// The `OpenAIObject` object type of this response. public let object: OpenAIObject /// The parameter containing the embedding data. public let data: [EmbeddingsData] /// The model used to generate the embeddings. public let model: String /// The amount of tokens used by the embeddings. public let usage: EmbeddingsUsage } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Embeddings/EmbeddingsUsage.swift ================================================ // // EmbeddingsUsage.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The token usage of the Embeddings endpoint. public struct EmbeddingsUsage: Codable { enum CodingKeys: String, CodingKey { case promptTokens = "prompt_tokens" case totalTokens = "total_tokens" } /// The amount of tokens used by the prompt. public let promptTokens: Int /// The total amount of tokens used. public let totalTokens: Int } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Evals/EvalModels.swift ================================================ import Foundation public struct EvalObject: Codable { enum CodingKeys: String, CodingKey { case id case object case name case createdAt = "created_at" } public let id: String public let object: String? public let name: String? public let createdAt: Int? } public struct EvalListResponse: Codable { public let object: String public let data: [EvalObject] } public struct EvalRunObject: Codable { enum CodingKeys: String, CodingKey { case id case object case status case evalID = "eval_id" case createdAt = "created_at" } public let id: String public let object: String? public let status: String? public let evalID: String? public let createdAt: Int? } public struct EvalRunListResponse: Codable { public let object: String public let data: [EvalRunObject] } public struct EvalRunOutputItem: Codable { enum CodingKeys: String, CodingKey { case id case object case type } public let id: String public let object: String? public let type: String? } public struct EvalRunOutputItemListResponse: Codable { public let object: String public let data: [EvalRunOutputItem] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Files/File.swift ================================================ // // File.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The file object used to read file information from the Files endpoint. public struct File: Codable, Identifiable { enum CodingKeys: String, CodingKey { case id case object case bytes case createdAt = "created_at" case filename case purpose case status case statusDetails = "status_details" } /// The ID of the file. public let id: String /// The `OpenAIObject` object type of the file. public let object: OpenAIObject /// The amount of storage the file takes up in bytes. public let bytes: Int /// The creation date of the file. public let createdAt: Int /// The file's name. public let filename: String /// The purpose the file has. public let purpose: String /// The upload status of the file. public let status: FileStatus? /// The status detail when uploading the file. public let statusDetails: String? } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Files/FileContent.swift ================================================ // // FileContent.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The struct representing each data point within a training file. public struct FileContent: Codable { /// The input the user would give to the model public let prompt: String /// The training parameter the model will learn to match from the prompt. public let completion: String } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Files/ListFilesResponse.swift ================================================ // // ListFilesResponse.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The response object sent by the File endpoint public struct ListFilesResponse: Codable { /// The `OpenAIObject` type of the response. public let object: OpenAIObject /// The array of files sent from the server. public let data: [File] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/FineTuning/FineTuningModels.swift ================================================ import Foundation public struct FineTuningJobObject: Codable { enum CodingKeys: String, CodingKey { case id case object case model case status case createdAt = "created_at" case fineTunedModel = "fine_tuned_model" } public let id: String public let object: String? public let model: String? public let status: String? public let createdAt: Int? public let fineTunedModel: String? } public struct FineTuningJobListResponse: Codable { public let object: String public let data: [FineTuningJobObject] } public struct FineTuningJobEvent: Codable { enum CodingKeys: String, CodingKey { case id case object case createdAt = "created_at" case level case message } public let id: String? public let object: String? public let createdAt: Int? public let level: String? public let message: String? } public struct FineTuningJobEventListResponse: Codable { public let object: String public let data: [FineTuningJobEvent] } public struct FineTuningCheckpointObject: Codable { enum CodingKeys: String, CodingKey { case id case object case createdAt = "created_at" case fineTunedModelCheckpoint = "fine_tuned_model_checkpoint" } public let id: String public let object: String? public let createdAt: Int? public let fineTunedModelCheckpoint: String? } public struct FineTuningCheckpointListResponse: Codable { public let object: String public let data: [FineTuningCheckpointObject] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Images/ImageResponse.swift ================================================ // // ImageResponse.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The struct sent by the Images Endpoint public struct ImageResponse: Codable { /// The creation date of the response. public let created: Int /// The data sent within the response containing either `URL` or `Base64` data. public let data: [ImageData] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Models/ListModelResponse.swift ================================================ // // ListModelResponse.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The struct sent by the List Models Endpoint public struct ListModelResponse: Codable { /// The `OpenAIObject` object type of the response. public let object: OpenAIObject /// The array of models that OpenAI has for use. public let data: [Model] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Models/Model.swift ================================================ // // Model.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The GPT3 models used for text and code completions. public struct Model: Codable, Identifiable { enum CodingKeys: String, CodingKey { case id, object, created case ownedBy = "owned_by" } /// The ID of the model. public let id: String /// The `OpenAIObject` object type of the model. public let object: OpenAIObject /// The creation date of the model. public let created: Int /// The owner of the model. public let ownedBy: String } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Moderations/ContentPolicyCategories.swift ================================================ // // ContentPolicyCategories.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The categories flagged by the Moderations endpoint. public struct ContentPolicyCategories: Codable { enum CodingKeys: String, CodingKey { case hate case hateWithThreatening = "hate/threatening" case selfHarm = "self-harm" case sexual case sexualWithMinors = "sexual/minors" case violence case violenceWithGraphic = "violence/graphic" } /// Content that expresses, incites, or promotes hate based on race, gender, ethnicity, religion, /// nationality, sexual orientation, disability status, or caste. public let hate: Bool /// Hateful content that also includes violence or serious harm towards the targeted group. public let hateWithThreatening: Bool /// Content that promotes, encourages, or depicts acts of self-harm, such as suicide, /// cutting, and eating disorders. public let selfHarm: Bool /// Content meant to arouse sexual excitement, such as the description of sexual activity, /// or that promotes sexual services (excluding sex education and wellness). public let sexual: Bool /// Sexual content that includes an individual who is under 18 years old. public let sexualWithMinors: Bool /// Content that promotes or glorifies violence or celebrates the suffering or /// humiliation of others. public let violence: Bool /// Violent content that depicts death, violence, or serious physical injury in /// extreme graphic detail. public let violenceWithGraphic: Bool } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Moderations/ContentPolicyCategoryScore.swift ================================================ // // ContentPolicyCategoryScore.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The moderation score amount associated with a prompt. public struct ContentPolicyCategoryScore: Codable { enum CodingKeys: String, CodingKey { case hate case hateWithThreatening = "hate/threatening" case selfHarm = "self-harm" case sexual case sexualWithMinors = "sexual/minors" case violence case violenceWithGraphic = "violence/graphic" } /// Content that expresses, incites, or promotes hate based on race, gender, ethnicity, religion, /// nationality, sexual orientation, disability status, or caste. public let hate: Double /// Hateful content that also includes violence or serious harm towards the targeted group. public let hateWithThreatening: Double /// Content that promotes, encourages, or depicts acts of self-harm, such as suicide, /// cutting, and eating disorders. public let selfHarm: Double /// Content meant to arouse sexual excitement, such as the description of sexual activity, /// or that promotes sexual services (excluding sex education and wellness). public let sexual: Double /// Sexual content that includes an individual who is under 18 years old. public let sexualWithMinors: Double /// Content that promotes or glorifies violence or celebrates the suffering or /// humiliation of others. public let violence: Double /// Violent content that depicts death, violence, or serious physical injury in /// extreme graphic detail. public let violenceWithGraphic: Double } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Moderations/ContentPolicyResponse.swift ================================================ // // ContentPolicyResponse.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The struct sent from the Moderations endpoint. public struct ContentPolicyResponse: Codable, Identifiable { /// The ID of the Moderation response. public let id: String /// The model used for the moderation check. public let model: String /// The array of results associated with the prompt(s). public let results: [ContentPolicyResult] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Moderations/ContentPolicyResult.swift ================================================ // // ContentPolicyResult.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The result of the moderation check from the Moderations endpoint. public struct ContentPolicyResult: Codable { enum CodingKeys: String, CodingKey { case categories case categoryScores = "category_scores" case flagged } /// The flagged categories. public let categories: ContentPolicyCategories /// The score associated with each category. public let categoryScores: ContentPolicyCategoryScore /// Is the prompt flagged by the Moderations endpoint? public let flagged: Bool } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/ChatChoice.swift ================================================ // // ChatChoice.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The output choice for the Chat Ednpoint. public struct ChatChoice: Codable, Sendable { enum CodingKeys: String, CodingKey { case message case delta case index case logprobs case finishReason = "finish_reason" } /// The choice output itself. public let message: ChatMessage? /// The streamed output if chosen to stream. public let delta: ChatDelta? /// The index of the choice within the data array. public let index: Int /// The logprobs used for the choice. public let logprobs: Int? /// The choice end reason. public let finishReason: String? } public struct ChatDelta: Codable, Sendable { enum CodingKeys: String, CodingKey { case role case content } public let role: ChatRole? public let content: String? } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/ChatMessage.swift ================================================ // // ChatMessage.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// The chat message object used for each chat conversation message. public struct ChatMessage: Codable, Identifiable, Sendable { private enum CodingKeys: String, CodingKey { case role, content case functionCall = "function_call" } /// ID used for iterating through list of chat messages public var id = UUID().uuidString /// The person sending the message public let role: ChatRole /// The message itself public let content: String? /// The name and arguments of a function that should be called, as generated by the model. public let functionCall: FunctionCall? public init(role: ChatRole, content: String? = nil, functionCall: FunctionCall? = nil) { self.role = role self.content = content self.functionCall = functionCall } public var body: [String: String] { if let content { return [ "role": self.role.rawValue, "content": content ] } return ["role": self.role.rawValue, "content": ""] } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/Choice.swift ================================================ // // Choice.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The output completion / edit of the Completions and Edits endpoints. public struct Choice: Codable, Sendable { enum CodingKeys: String, CodingKey { case text case index case logprobs case finishReason = "finish_reason" } /// The choice output itself. public let text: String /// The index of the choice within the data array. public let index: Int /// The logprobs used for the choice. public let logprobs: Int? /// The choice end reason. public let finishReason: String? } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/Configuration.swift ================================================ // // Configuration.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The configuration object used for the OpenAIKit object to represent the organization of the user. import Foundation public struct Configuration: Sendable { /// The API key associated with the user. public let apiKey: String /// Optional organization header value. public let organizationId: String? /// Optional project header value. public let projectId: String? /// Optional webhook secret used by webhook verification helpers. public let webhookSecret: String? /// Base URL for all API requests. public let baseURL: URL /// Request behavior defaults used by the transport layer. public let requestOptions: OpenAIRequestOptions /// Backward-compatible initializer used by existing call sites. public init(organizationId: String, apiKey: String) { self.init( apiKey: apiKey, organizationId: organizationId, projectId: nil, webhookSecret: nil, baseURL: URL(string: "https://api.openai.com/v1")!, requestOptions: OpenAIRequestOptions() ) } public init( apiKey: String, organizationId: String? = nil, projectId: String? = nil, webhookSecret: String? = nil, baseURL: URL = URL(string: "https://api.openai.com/v1")!, requestOptions: OpenAIRequestOptions = OpenAIRequestOptions() ) { self.apiKey = apiKey self.organizationId = organizationId self.projectId = projectId self.webhookSecret = webhookSecret self.baseURL = baseURL self.requestOptions = requestOptions } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/DeleteObject.swift ================================================ // // DeleteObject.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The struct returned from deleting a file or Fine-tune from their associated endpoints. public struct DeleteObject: Codable { /// The ID of the deletion object. public let id: String /// The `OpenAIObject` object type of the deletion. public let object: OpenAIObject /// Is the item deleted? public let deleted: Bool } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/FormData.swift ================================================ // // FormData.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// The form query parameter used for submitting images and files with their associated endpoints. public struct FormData { /// The binary data itself. public var data: Data /// The MIME type used for the HTTP request. public var mimeType: String /// The name of the file. public var fileName: String } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/FunctionCall.swift ================================================ // // FunctionCall.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import SwiftUI public struct FunctionCall: Codable, Sendable { /// The arguments to call the function with, as generated by the model in JSON format. /// /// - Note: The model does not always generate valid JSON, and may hallucinate parameters not /// defined by your function schema. Validate the arguments in your code before calling your function. public let arguments: String /// The name of the function to call. public let name: String } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/OpenAIErrorMessage.swift ================================================ // // OpenAIErrorMessage.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The struct sent if the request is malformed, or if OpenAI's server isn't functioning correctly. public struct OpenAIErrorMessage: Error, Codable { /// The message associated with the error. public let message: String /// The type of error the object is. public let type: String /// The parameters of the error. public let param: String? /// The code associated with the error. public let code: String? } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/OpenAIErrorResponse.swift ================================================ // // OpenAIErrorResponse.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The response struct itself when an error is thrown. public struct OpenAIErrorResponse: Error, Codable { /// The error object itself. public let error: OpenAIErrorMessage } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/OpenAIRequestOptions.swift ================================================ import Foundation /// Request behavior options used by OpenAIKit transport calls. public struct OpenAIRequestOptions: Sendable { /// Per-request timeout interval in seconds. public let timeoutInterval: TimeInterval /// Number of retries to apply for transient transport failures. public let maxRetries: Int /// Additional HTTP headers merged into each request. public let additionalHeaders: [String: String] public init( timeoutInterval: TimeInterval = 600, maxRetries: Int = 2, additionalHeaders: [String: String] = [:] ) { self.timeoutInterval = timeoutInterval self.maxRetries = max(maxRetries, 0) self.additionalHeaders = additionalHeaders } } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/OpenAI/Usage.swift ================================================ // // Usage.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // /// The amount of tokens used with any GPT3 function. public struct Usage: Codable, Sendable { enum CodingKeys: String, CodingKey { case promptTokens = "prompt_tokens" case completionTokens = "completion_tokens" case totalTokens = "total_tokens" } /// The amount of tokens used by a prompt. public let promptTokens: Int /// The amount of tokens used by the completion. public let completionTokens: Int /// The total amount of tokens used by the request. public let totalTokens: Int } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Realtime/RealtimeModels.swift ================================================ import Foundation public struct RealtimeCallObject: Codable { enum CodingKeys: String, CodingKey { case id case object case status case model case createdAt = "created_at" } public let id: String public let object: String? public let status: String? public let model: String? public let createdAt: Int? } public struct RealtimeClientSecretObject: Codable { enum CodingKeys: String, CodingKey { case value case expiresAt = "expires_at" } public let value: String public let expiresAt: Int? } public struct RealtimeClientSecretResponse: Codable { enum CodingKeys: String, CodingKey { case clientSecret = "client_secret" } public let clientSecret: RealtimeClientSecretObject } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Responses/ResponseModels.swift ================================================ import Foundation public struct ResponseObject: Codable, Sendable { enum CodingKeys: String, CodingKey { case id case object case model case status case outputText = "output_text" case createdAt = "created_at" } public let id: String public let object: String? public let model: String? public let status: String? public let outputText: String? public let createdAt: Int? } public struct ResponseInputItem: Codable, Sendable { public let id: String? public let type: String? public let role: String? public let content: String? } public struct ResponseInputItemListResponse: Codable, Sendable { public let object: String public let data: [ResponseInputItem] } public struct ResponseInputTokenCount: Codable, Sendable { enum CodingKeys: String, CodingKey { case totalTokens = "total_tokens" } public let totalTokens: Int } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Skills/SkillModels.swift ================================================ import Foundation public struct SkillObject: Codable { enum CodingKeys: String, CodingKey { case id case object case name case description case createdAt = "created_at" } public let id: String public let object: String? public let name: String? public let description: String? public let createdAt: Int? } public struct SkillListResponse: Codable { public let object: String public let data: [SkillObject] } public struct SkillVersionObject: Codable { enum CodingKeys: String, CodingKey { case id case object case version case createdAt = "created_at" } public let id: String public let object: String? public let version: String? public let createdAt: Int? } public struct SkillVersionListResponse: Codable { public let object: String public let data: [SkillVersionObject] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Uploads/UploadModels.swift ================================================ import Foundation public struct UploadObject: Codable { enum CodingKeys: String, CodingKey { case id case object case bytes case filename case status case createdAt = "created_at" } public let id: String public let object: String? public let bytes: Int? public let filename: String? public let status: String? public let createdAt: Int? } public struct UploadPartObject: Codable { enum CodingKeys: String, CodingKey { case id case object case createdAt = "created_at" case uploadID = "upload_id" } public let id: String public let object: String? public let createdAt: Int? public let uploadID: String? } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/VectorStores/VectorStoreModels.swift ================================================ import Foundation public struct VectorStoreObject: Codable { enum CodingKeys: String, CodingKey { case id case object case name case createdAt = "created_at" case status case metadata } public let id: String public let object: String? public let name: String? public let createdAt: Int? public let status: String? public let metadata: [String: String]? } public struct VectorStoreListResponse: Codable { public let object: String public let data: [VectorStoreObject] } public struct VectorStoreFileObject: Codable { enum CodingKeys: String, CodingKey { case id case object case createdAt = "created_at" case status case vectorStoreId = "vector_store_id" } public let id: String public let object: String? public let createdAt: Int? public let status: String? public let vectorStoreId: String? } public struct VectorStoreFileListResponse: Codable { public let object: String public let data: [VectorStoreFileObject] } public struct VectorStoreFileBatchObject: Codable { enum CodingKeys: String, CodingKey { case id case object case createdAt = "created_at" case status case vectorStoreId = "vector_store_id" } public let id: String public let object: String? public let createdAt: Int? public let status: String? public let vectorStoreId: String? } public struct VectorStoreFileBatchListResponse: Codable { public let object: String public let data: [VectorStoreFileBatchObject] } ================================================ FILE: Sources/OpenAIKit/Types/Structs/Schemas/Videos/VideoModels.swift ================================================ import Foundation public struct VideoObject: Codable { enum CodingKeys: String, CodingKey { case id case object case status case model case createdAt = "created_at" } public let id: String public let object: String? public let status: String? public let model: String? public let createdAt: Int? } public struct VideoListResponse: Codable { public let object: String public let data: [VideoObject] } ================================================ FILE: Sources/OpenAIKit/Utils/ClampedPropertyWrapper.swift ================================================ // // ClampedPropertyWrapper.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// A property wrapper that enforces values to be in a specified range of `T`. @propertyWrapper struct Clamped { let wrappedValue: T init(wrappedValue: T, range: ClosedRange) { self.wrappedValue = min(max(wrappedValue, range.lowerBound), range.upperBound) } } ================================================ FILE: Sources/OpenAIKit/Utils/FormDataHelper.swift ================================================ // // FormDataHelper.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation #if os(Linux) || SERVER import FoundationNetworking #endif /// The struct used to help with submitting data as a form query. struct FormDataHelper { /// The UUID of the parameter. private let boundary: String = UUID().uuidString /// The HTTP body containing data of `NSMutableData` type. private let formBody = NSMutableData() /// The URL of the request. let formUrl: URL init(formUrl: URL) { self.formUrl = formUrl } /// Add text to the form query /// - Parameters: /// - name: The name of the request. /// - value: The data contained in the request. func addTextField(named name: String, value: String) { self.formBody.append(textFormField(named: name, value: value)) } /// Add data to the form query of `Data` type /// - Parameters: /// - name: The name of the request. /// - formData: The data itself. func addDataField(named name: String, formData: FormData) { self.formBody.append(dataFormField(named: name, formData: formData)) } /// Convert the form query request to a `URLRequest`. /// - Parameter apiKey: The API key associated with the request. /// - Returns: An `URLRequest` object. func asURLRequest(apiKey: String) -> URLRequest { self.asURLRequest(headers: ["Authorization": "Bearer \(apiKey)"]) } /// Convert the form query request to a `URLRequest`. /// - Parameter headers: Headers associated with the request. /// - Returns: An `URLRequest` object. func asURLRequest(headers: [String: String]) -> URLRequest { var request = URLRequest(url: formUrl) request.httpMethod = "POST" request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") self.formBody.append("--\(boundary)--") request.httpBody = self.formBody as Data request.allHTTPHeaderFields = headers return request } private func textFormField(named name: String, value: String) -> String { var fieldString = "--\(boundary)\r\n" fieldString += "Content-Disposition: form-data; name=\"\(name)\"\r\n" fieldString += "\r\n" fieldString += "\(value)\r\n" return fieldString } private func dataFormField(named name: String, formData: FormData) -> Data { let fieldData = NSMutableData() fieldData.append("--\(boundary)\r\n") fieldData.append("Content-Disposition: form-data; name=\"\(name)\"; filename=\"\(formData.fileName)\"\r\n") fieldData.append("Content-Type: \(formData.mimeType)\r\n") fieldData.append("\r\n") fieldData.append(formData.data) fieldData.append("\r\n") return fieldData as Data } } ================================================ FILE: Sources/OpenAIKit/Utils/GenericCodingKeys.swift ================================================ // // GenericCodingKeys.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation public struct GenericCodingKeys: CodingKey { public var stringValue: String public var intValue: Int? // Int type public init?(intValue: Int) { self.intValue = intValue self.stringValue = "\(intValue)" } // String type (including typical parameter types) public init?(stringValue: String) { switch stringValue { case "int", "date", "array", "boolean", "string", "data": self.stringValue = stringValue default: return nil } } // Flexible key public init(key: String) { self.stringValue = key } } ================================================ FILE: Sources/OpenAIKit/Utils/OpenAIKitSession.swift ================================================ // // URLSessionExtension.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation #if os(Linux) || SERVER import FoundationNetworking #endif // Extensions used to help better streamline the main OpenAIKit class. // Most are private to help with having better Access Control. final class OpenAIKitSession: @unchecked Sendable { /// Shared Singleton object for use within the OpenAIKit API Module internal static let shared = OpenAIKitSession() /// Conforming to the Singleton Design Pattern private init() { } /// Uses URLRequest to set up a HTTPMethod, and implement default values for the method cases. public enum HTTPMethod: String { case get = "GET" case post = "POST" case delete = "DELETE" } internal func headers(for configuration: Configuration) -> [String: String] { var result: [String: String] = [ "Authorization": "Bearer \(configuration.apiKey)" ] if let organizationId = configuration.organizationId, !organizationId.isEmpty { result["OpenAI-Organization"] = organizationId } if let projectId = configuration.projectId, !projectId.isEmpty { result["OpenAI-Project"] = projectId } configuration.requestOptions.additionalHeaders.forEach { key, value in result[key] = value } return result } internal static func statusError(for statusCode: Int, data: Data) -> OpenAIAPIError { let payload = try? OpenAIKitSession.decodeData(OpenAIErrorResponse.self, with: data) switch statusCode { case 400: return .badRequest(payload) case 401: return .authentication(payload) case 403: return .permissionDenied(payload) case 404: return .notFound(payload) case 409: return .conflict(payload) case 422: return .unprocessableEntity(payload) case 429: return .rateLimit(payload) case 500...599: return .internalServer(statusCode: statusCode, payload: payload) default: return .unexpectedStatusCode(statusCode: statusCode, payload: payload) } } internal static func validateStatus(_ response: URLResponse?, data: Data) throws { guard let httpResponse = response as? HTTPURLResponse else { return } guard (200...299).contains(httpResponse.statusCode) else { throw OpenAIKitSession.statusError(for: httpResponse.statusCode, data: data) } } private func resolveRequestConfiguration( apiKey: String?, configuration: Configuration? ) throws -> (headers: [String: String], options: OpenAIRequestOptions) { if let configuration = configuration { return (self.headers(for: configuration), configuration.requestOptions) } guard let apiKey = apiKey else { throw OpenAIError.noApiKey } return ( ["Authorization": "Bearer \(apiKey)"], OpenAIRequestOptions() ) } /// Decode a data object using `JSONDecoder.decode()`. /// - Parameters: /// - type: The type of `T` that the data will decode to. /// - data: `Data` input object. /// - keyDecodingStrategy: Default is `.useDefaultKeys`. /// - dataDecodingStrategy: Default is `.deferredToData`. /// - dateDecodingStrategy: Default is `.deferredToDate`. /// - Returns: Decoded data of `T` type, or throws an `OpenAIErrorRaesponse` object. internal static func decodeData( _ type: T.Type = T.self, with data: Data, keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys, dataDecodingStrategy: JSONDecoder.DataDecodingStrategy = .deferredToData, dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate ) throws -> T { let decoder = JSONDecoder() decoder.keyDecodingStrategy = keyDecodingStrategy decoder.dataDecodingStrategy = dataDecodingStrategy decoder.dateDecodingStrategy = dateDecodingStrategy guard let decoded = try? decoder.decode(type, from: data) else { throw try decoder.decode(OpenAIErrorResponse.self, from: data) } return decoded } /// Takes a `URL` input, along with header information, and converts it into a `URLRequest`; /// and fetches the data using an `Async` `Await` wrapper for the older `dataTask` handler. /// - Parameters: /// - url: `URL` to convert to a `URLRequest`. /// - method: Input can be either a `.get` or a `.post` method, with the default being `.post`. /// - headers: Header data for the request that uses a `[string:string]` dictionary, /// and the default is set to an empty dictionary. /// - body: Body data that defaults to `nil`. /// - Returns: The data that was fetched typed as a `Data` object. internal func asyncData( with url: URL, method: HTTPMethod = .post, headers: [String: String] = [:], body: Data? = nil, timeoutInterval: TimeInterval? = nil, maxRetries: Int = 0 ) async throws -> (Data, URLResponse?) { var request = URLRequest(url: url) request.httpMethod = method.rawValue request.allHTTPHeaderFields = [ "Content-Type": "application/json" ] request.httpBody = body if let timeoutInterval = timeoutInterval { request.timeoutInterval = timeoutInterval } headers.forEach { key, value in request.allHTTPHeaderFields?[key] = value } return try await self.asyncData(with: request, maxRetries: maxRetries) } /// An Async Await wrapper for the older `dataTask` handler. /// - Parameter request: `URLRequest` to be fetched from. /// - Returns: A Data object fetched from the` URLRequest`. private func asyncData( with request: URLRequest, maxRetries: Int = 0 ) async throws -> (Data, URLResponse?) { var attempt = 0 while true { do { return try await self.performDataTask(with: request) } catch { if attempt >= maxRetries { throw error } attempt += 1 } } } private func performDataTask(with request: URLRequest) async throws -> (Data, URLResponse?) { try await withCheckedThrowingContinuation { (con: CheckedContinuation<(Data, URLResponse?), Error>) in let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { con.resume(throwing: error) } else if let data = data { con.resume(returning: (data, response)) } else { con.resume(returning: (Data(), response)) } } task.resume() } } /// Used for parsing `.jsonl` files when retrieving fine-tuning files from OpenAI's server. /// - Parameters: /// - type: The type of `T` that the data will decode to. /// - with: The input url of type `URL` that will be fetched. /// - apiKey: The API Key for use with the server. /// - Returns: The decoded object of array type `T`. public func retrieveJsonLine( _ type: T.Type = T.self, with url: URL, apiKey: String? = nil, configuration: Configuration? = nil ) async throws -> [T] { let requestConfiguration = try self.resolveRequestConfiguration( apiKey: apiKey, configuration: configuration ) let jsonDecoder = JSONDecoder() let (genData, response) = try await self.asyncData( with: url, method: .get, headers: requestConfiguration.headers, timeoutInterval: requestConfiguration.options.timeoutInterval, maxRetries: requestConfiguration.options.maxRetries ) try OpenAIKitSession.validateStatus(response, data: genData) let genString = String(decoding: genData, as: UTF8.self) return try genString.components(separatedBy: .newlines) .filter { $0 != "" } .compactMap { gen -> T? in guard let data = gen.data(using: .utf8) else { throw OpenAIError.invalidData } return try? jsonDecoder.decode(T.self, from: data) } } /// Stream Data from a server using Server Side Events. /// - Parameters: /// - type: The type of `T` that the data will decode to. /// - with: The input url of type `URL` that will be fetched. /// - apiKey: The API Key for use with the server. /// - body: The POST body used to add parameters, defaults to `nil`. /// - method: The method used for the function, defaults to `.post`. /// - Returns: An `AsyncThrowingStream` object with either type `T` object or type `Error` object. public func streamData( _ type: T.Type = T.self, with url: URL, apiKey: String? = nil, configuration: Configuration? = nil, body: Body, method: HTTPMethod = .post ) throws -> AsyncThrowingStream { let requestConfiguration = try self.resolveRequestConfiguration( apiKey: apiKey, configuration: configuration ) let jsonData = try JSONEncoder().encode(body) var request = URLRequest(url: url) request.httpMethod = method.rawValue request.allHTTPHeaderFields = [ "Content-Type": "application/json" ] request.httpBody = jsonData request.timeoutInterval = requestConfiguration.options.timeoutInterval requestConfiguration.headers.forEach { key, value in request.allHTTPHeaderFields?[key] = value } return OpenAISource(url: request).streamData() } /// Stream data using an untyped dictionary payload. public func streamData( _ type: T.Type = T.self, with url: URL, apiKey: String? = nil, configuration: Configuration? = nil, body: [String: Any], method: HTTPMethod = .post ) throws -> AsyncThrowingStream { let requestConfiguration = try self.resolveRequestConfiguration( apiKey: apiKey, configuration: configuration ) let jsonData = try? JSONSerialization.data(withJSONObject: body) var request = URLRequest(url: url) request.httpMethod = method.rawValue request.allHTTPHeaderFields = [ "Content-Type": "application/json" ] request.httpBody = jsonData request.timeoutInterval = requestConfiguration.options.timeoutInterval requestConfiguration.headers.forEach { key, value in request.allHTTPHeaderFields?[key] = value } return OpenAISource(url: request).streamData() } /// Decode a `URL` to the type `Data` using `asyncData()` /// - Parameters: /// - with: The input url of type `URL` that will be fetched. /// - apiKey: The API Key for use with the server. /// - body: The POST body used to add parameters, defaults to `nil`. /// - method: The method used for the function, defaults to `.post`. /// - Returns: The decoded object of type `Data`. public func decodeUrlTranscriptions( with url: URL, apiKey: String? = nil, configuration: Configuration? = nil, body: [String: Any] ) async throws -> Data { let requestConfiguration = try self.resolveRequestConfiguration( apiKey: apiKey, configuration: configuration ) let formRequest = FormDataHelper(formUrl: url) body.forEach { (key, value) in if let dataValue = value as? FormData { formRequest.addDataField(named: key, formData: dataValue) } else { formRequest.addTextField(named: key, value: "\(value)") } } var request = formRequest.asURLRequest(headers: requestConfiguration.headers) request.timeoutInterval = requestConfiguration.options.timeoutInterval let (data, response) = try await self.asyncData( with: request, maxRetries: requestConfiguration.options.maxRetries ) try OpenAIKitSession.validateStatus(response, data: data) return data } /// Decode a URL to raw data using an encodable JSON body. public func decodeRawUrl( with url: URL, apiKey: String? = nil, configuration: Configuration? = nil, body: Body, method: HTTPMethod = .post, acceptHeader: String? = nil ) async throws -> Data { let requestConfiguration = try self.resolveRequestConfiguration( apiKey: apiKey, configuration: configuration ) let jsonData = try JSONEncoder().encode(body) var headers = requestConfiguration.headers if let acceptHeader = acceptHeader { headers["Accept"] = acceptHeader } let (data, response) = try await self.asyncData( with: url, method: method, headers: headers, body: jsonData, timeoutInterval: requestConfiguration.options.timeoutInterval, maxRetries: requestConfiguration.options.maxRetries ) try OpenAIKitSession.validateStatus(response, data: data) return data } /// Decode a `URL` to the type `T` using either `asyncData()` for the Production Server; /// or using `decode()` for the Mock Server. /// - Parameters: /// - type: The type of `T` that the data will decode to. /// - with: The input url of type `URL` that will be fetched. /// - apiKey: The API Key for use with the server. /// - body: The POST body used to add parameters, defaults to `nil`. /// - method: The method used for the function, defaults to `.post`. /// - bodyRequired: Is the body required or not, used for `.get` and `.delete`, defaults to `false`. /// - formSubmission: Is the body actually a form submission? Used for image submissionss, defaults to `false`. /// - Returns: The decoded object of type `T`. public func decodeUrl( _ type: T.Type = T.self, with url: URL, apiKey: String? = nil, configuration: Configuration? = nil, body: Body, method: HTTPMethod = .post ) async throws -> T { let requestConfiguration = try self.resolveRequestConfiguration( apiKey: apiKey, configuration: configuration ) let jsonData = try JSONEncoder().encode(body) let (data, response) = try await self.asyncData( with: url, method: method, headers: requestConfiguration.headers, body: jsonData, timeoutInterval: requestConfiguration.options.timeoutInterval, maxRetries: requestConfiguration.options.maxRetries ) try OpenAIKitSession.validateStatus(response, data: data) return try OpenAIKitSession.decodeData(with: data) } /// Decode a `URL` using an untyped dictionary payload. public func decodeUrl( _ type: T.Type = T.self, with url: URL, apiKey: String? = nil, configuration: Configuration? = nil, body: [String: Any]? = nil, method: HTTPMethod = .post, bodyRequired: Bool = true, formSubmission: Bool = false ) async throws -> T { let requestConfiguration = try self.resolveRequestConfiguration( apiKey: apiKey, configuration: configuration ) if bodyRequired { guard let body = body else { throw OpenAIError.noBody } if formSubmission { let formRequest = FormDataHelper(formUrl: url) body.forEach { (key, value) in if let dataValue = value as? FormData { formRequest.addDataField(named: key, formData: dataValue) } else { formRequest.addTextField(named: key, value: "\(value)") } } var request = formRequest.asURLRequest(headers: requestConfiguration.headers) request.timeoutInterval = requestConfiguration.options.timeoutInterval let (data, response) = try await self.asyncData( with: request, maxRetries: requestConfiguration.options.maxRetries ) try OpenAIKitSession.validateStatus(response, data: data) return try OpenAIKitSession.decodeData(with: data) } else { let jsonData = try? JSONSerialization.data(withJSONObject: body) let (data, response) = try await self.asyncData( with: url, method: method, headers: requestConfiguration.headers, body: jsonData, timeoutInterval: requestConfiguration.options.timeoutInterval, maxRetries: requestConfiguration.options.maxRetries ) try OpenAIKitSession.validateStatus(response, data: data) return try OpenAIKitSession.decodeData(with: data) } } if !bodyRequired && !formSubmission { let (data, response) = try await self.asyncData( with: url, method: method, headers: requestConfiguration.headers, timeoutInterval: requestConfiguration.options.timeoutInterval, maxRetries: requestConfiguration.options.maxRetries ) try OpenAIKitSession.validateStatus(response, data: data) return try OpenAIKitSession.decodeData(with: data) } throw OpenAIError.noBody } } ================================================ FILE: Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAIEvent.swift ================================================ // // OpenAIEvent.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation #if os(Linux) || SERVER import FoundationNetworking #endif enum OpenAIEvent { case event(id: String?, event: String?, data: String?, time: String?) init?(eventString: String?, newLineCharacters: [String]) { guard let eventString = eventString else { return nil } if eventString.hasPrefix(":") { return nil } self = OpenAIEvent.parseEvent(eventString, newLineCharacters: newLineCharacters) } var id: String? { guard case let .event(eventId, _, _, _) = self else { return nil } return eventId } var event: String? { guard case let .event(_, eventName, _, _) = self else { return nil } return eventName } var data: String? { guard case let .event(_, _, eventData, _) = self else { return nil } return eventData } var retryTime: Int? { guard case let .event(_, _, _, aTime) = self, let time = aTime else { return nil } return Int(time.trimmingCharacters(in: CharacterSet.whitespaces)) } var onlyRetryEvent: Bool? { guard case let .event(id, name, data, time) = self else { return nil } let otherThanTime = id ?? name ?? data if otherThanTime == nil && time != nil { return true } return false } } private extension OpenAIEvent { static func parseEvent(_ eventString: String, newLineCharacters: [String]) -> OpenAIEvent { var event: [String: String?] = [:] for line in eventString.components(separatedBy: CharacterSet.newlines) as [String] { let (akey, value) = OpenAIEvent.parseLine(line, newLineCharacters: newLineCharacters) guard let key = akey else { continue } if let value = value, let previousValue = event[key] ?? nil { event[key] = "\(previousValue)\n\(value)" } else if let value = value { event[key] = value } else { event[key] = nil } } // the only possible field names for events are: id, event and data. Everything else is ignored. return .event( id: event["id"] ?? nil, event: event["event"] ?? nil, data: event["data"] ?? nil, time: event["retry"] ?? nil ) } static func parseLine(_ line: String, newLineCharacters: [String]) -> (key: String?, value: String?) { var key: String?, value: String? let scanner = Scanner(string: line) key = scanner.scanUpToString(":") let _ = scanner.scanString(":") for newline in newLineCharacters { if let scannedValue = scanner.scanUpToString(newline) { value = scannedValue break } } // for id and data if they come empty they should return an empty string value. if key != "event" && value == nil { value = "" } return (key, value) } } ================================================ FILE: Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift ================================================ // // OpenAISource.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation #if os(Linux) || SERVER import FoundationNetworking #endif public enum OpenAISourceState: Sendable { case connecting case open case closed } public struct Message: Sendable { public let id: String? public let event: String? public let data: String? } open class OpenAISource: NSObject, URLSessionDataDelegate, @unchecked Sendable { let headers: [String: String] static let DefaultRetryTime = 3000 public let url: URLRequest private(set) public var lastEventId: String? private(set) public var retryTime = OpenAISource.DefaultRetryTime private(set) public var readyState: OpenAISourceState private var onOpenCallback: (@Sendable () -> Void)? private var onComplete: (@Sendable (Int?, Bool?, NSError?) -> Void)? private var onMessageCallback: (@Sendable (Message) -> Void)? private var eventListeners: [String: @Sendable (Message) -> Void] = [:] private var openAiStreamParser: OpenAIStreamParser? private var operationQueue: OperationQueue private var mainQueue = DispatchQueue.main private var urlSession: URLSession? public init(url: URLRequest) { self.url = url self.headers = url.allHTTPHeaderFields ?? [:] self.readyState = .closed self.operationQueue = OperationQueue() self.operationQueue.maxConcurrentOperationCount = 1 super.init() } public func connect(lastEventId: String? = nil) { self.openAiStreamParser = OpenAIStreamParser() self.readyState = .connecting let configuration = self.sessionConfiguration(lastEventId: lastEventId) self.urlSession = URLSession( configuration: configuration, delegate: self, delegateQueue: self.operationQueue ) self.urlSession? .dataTask(with: self.url) .resume() } public func disconnect() { self.readyState = .closed self.urlSession?.invalidateAndCancel() } public func onOpen(_ onOpenCallback: @escaping @Sendable () -> Void) { self.onOpenCallback = onOpenCallback } public func onComplete(_ onComplete: @escaping @Sendable (Int?, Bool?, NSError?) -> Void) { self.onComplete = onComplete } public func onMessage(_ onMessageCallback: @escaping @Sendable (Message) -> Void) { self.onMessageCallback = onMessageCallback } public func addEventListener(_ event: String, handler: @escaping @Sendable (Message) -> Void) { self.eventListeners[event] = handler } public func removeEventListener(_ event: String) { self.eventListeners.removeValue(forKey: event) } public func events() -> [String] { return Array(self.eventListeners.keys) } open func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { if self.readyState != .open { return } if let events = self.openAiStreamParser?.append(data: data) { self.notifyReceivedEvents(events) } } open func urlSession( _ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void ) { completionHandler(URLSession.ResponseDisposition.allow) self.readyState = .open self.mainQueue.async { [weak self] in self?.onOpenCallback?() } } open func urlSession( _ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error? ) { guard let responseStatusCode = (task.response as? HTTPURLResponse)?.statusCode else { mainQueue.async { [weak self] in self?.onComplete?(nil, nil, error as NSError?) } return } let reconnect = shouldReconnect(statusCode: responseStatusCode) mainQueue.async { [weak self] in self?.onComplete?(responseStatusCode, reconnect, nil) } } open func urlSession( _ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void ) { var newRequest = request self.headers.forEach { newRequest.setValue($1, forHTTPHeaderField: $0) } completionHandler(newRequest) } } internal extension OpenAISource { func sessionConfiguration(lastEventId: String?) -> URLSessionConfiguration { var additionalHeaders = headers if let eventID = lastEventId { additionalHeaders["Last-Event-Id"] = eventID } additionalHeaders["Accept"] = "text/event-stream" additionalHeaders["Cache-Control"] = "no-cache" let sessionConfiguration = URLSessionConfiguration.default sessionConfiguration.timeoutIntervalForRequest = TimeInterval(INT_MAX) sessionConfiguration.timeoutIntervalForResource = TimeInterval(INT_MAX) sessionConfiguration.httpAdditionalHeaders = additionalHeaders return sessionConfiguration } func readyStateOpen() { self.readyState = .open } } private extension OpenAISource { func notifyReceivedEvents(_ events: [OpenAIEvent]) { for event in events { lastEventId = event.id retryTime = event.retryTime ?? OpenAISource.DefaultRetryTime if event.onlyRetryEvent == true { continue } if event.event == nil || event.event == "message" { mainQueue.async { [weak self] in self?.onMessageCallback?(Message(id: event.id, event: "message", data: event.data)) } } if let eventName = event.event, let eventHandler = eventListeners[eventName] { mainQueue.async { eventHandler(Message(id: event.id, event: event.event, data: event.data)) } } } } // Following "5 Processing model" from: // https://www.w3.org/TR/2009/WD-eventsource-20090421/#handler-eventsource-onerror func shouldReconnect(statusCode: Int) -> Bool { switch statusCode { case 200: return false case _ where statusCode > 200 && statusCode < 300: return true default: return false } } } public extension OpenAISource { @preconcurrency func streamData() -> AsyncThrowingStream { return AsyncThrowingStream { continuation in let connection = OpenAISource(url: self.url) connection.onMessageCallback = { message in do { if message.data != nil, message.data! == "[DONE]" { continuation.finish() } guard let data = message.data?.data(using: .utf8) else { throw OpenAIError.invalidData } let result = try OpenAIKitSession.decodeData(T.self, with: data) continuation.yield(result) } catch { do { guard let data = message.data?.data(using: .utf8) else { throw OpenAIError.invalidData } let errorOpenAI = try JSONDecoder().decode(OpenAIErrorResponse.self, from: data) continuation.finish(throwing: errorOpenAI) } catch { continuation.finish(throwing: error) } } } continuation.onTermination = { @Sendable _ in connection.disconnect() } connection.connect() } } } ================================================ FILE: Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAIStreamParser.swift ================================================ // // OpenAIStreamParser.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation #if os(Linux) || SERVER import FoundationNetworking #endif public final class OpenAIStreamParser { // Events are separated by end of line. End of line can be: // \r = CR (Carriage Return) → Used as a new line character in Mac OS before X // \n = LF (Line Feed) → Used as a new line character in Unix/Mac OS X // \r\n = CR + LF → Used as a new line character in Windows private let validNewlineCharacters = ["\r\n", "\n", "\r"] private let dataBuffer: NSMutableData init() { dataBuffer = NSMutableData() } var currentBuffer: String? { return NSString(data: dataBuffer as Data, encoding: String.Encoding.utf8.rawValue) as String? } func append(data: Data?) -> [OpenAIEvent] { guard let data = data else { return [] } dataBuffer.append(data) let events = extractEventsFromBuffer().compactMap { [weak self] eventString -> OpenAIEvent? in guard let self = self else { return nil } return OpenAIEvent(eventString: eventString, newLineCharacters: self.validNewlineCharacters) } return events } private func extractEventsFromBuffer() -> [String] { var events = [String]() var searchRange = NSRange(location: 0, length: dataBuffer.length) while let foundRange = searchFirstEventDelimiter(in: searchRange) { // if we found a delimiter range that means that from the beggining of the buffer // until the beggining of the range where the delimiter was found we have an event. // The beggining of the event is: searchRange.location // The lenght of the event is the position where the foundRange was found. let dataChunk = dataBuffer.subdata( with: NSRange(location: searchRange.location, length: foundRange.location - searchRange.location) ) if let text = String(bytes: dataChunk, encoding: .utf8) { events.append(text) } // We move the searchRange start position (location) after the fundRange we just found and searchRange.location = foundRange.location + foundRange.length searchRange.length = dataBuffer.length - searchRange.location } // We empty the piece of the buffer we just search in. dataBuffer.replaceBytes(in: NSRange(location: 0, length: searchRange.location), withBytes: nil, length: 0) return events } // This methods returns the range of the first delimiter found in the buffer. For example: // If in the buffer we have: `id: event-id-1\ndata:event-data-first\n\n` // This method will return the range for the `\n\n`. private func searchFirstEventDelimiter(in range: NSRange) -> NSRange? { let delimiters = validNewlineCharacters.map { "\($0)\($0)".data(using: String.Encoding.utf8)! } for delimiter in delimiters { let foundRange = dataBuffer.range( of: delimiter, options: NSData.SearchOptions(), in: range ) if foundRange.location != NSNotFound { return foundRange } } return nil } } ================================================ FILE: Sources/OpenAIKit/Utils/Whisper/SRT.swift ================================================ // // SRT.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation public struct SRT: Codable { public let id: Int public let start: String public let end: String public let content: String public static func parseSRT(from input: String) -> [SRT] { let lines = input.split(separator: "\n").map(String.init) var subtitles: [SRT] = [] var index = 0 while index < lines.count { if let id = Int(lines[index]), let range = lines[index + 1] .split(separator: " ") .first(where: { $0 == "-->" }) .map(String.init)? .surroundingWords, range.count == 2 { let content = lines[index + 2] let subtitle = SRT(id: id, start: range[0], end: range[1], content: content) subtitles.append(subtitle) index += 3 } else { index += 1 } } return subtitles } public static func exportSRT(subtitles: [SRT]) -> String { return subtitles.map { "\($0.id)\n\($0.start) --> \($0.end)\n\($0.content)" } .joined(separator: "\n\n") } } ================================================ FILE: Sources/OpenAIKit/Utils/Whisper/WebVTT.swift ================================================ // // WebVTTCue.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation public struct WebVTTCue: Codable { public let startTime: String public let endTime: String public let text: String public static func parseWebVTT(from input: String) -> [WebVTTCue] { var cues: [WebVTTCue] = [] let lines = input.split(separator: "\n") var index = 0 // Skip the "WEBVTT" header if lines.count > 0 && lines[0] == "WEBVTT" { index += 1 } while index < lines.count { let timeRange = lines[index].components(separatedBy: " --> ") if timeRange.count == 2 { let startTime = String(timeRange[0]) let endTime = String(timeRange[1]) index += 1 var text = "" while index < lines.count && !lines[index].isEmpty { text += (text.isEmpty ? "" : "\n") + lines[index] index += 1 } let cue = WebVTTCue(startTime: startTime, endTime: endTime, text: text) cues.append(cue) } index += 1 } return cues } public static func exportCuesToWebVTT(_ cues: [WebVTTCue]) -> String { var output = "WEBVTT\n\n" for cue in cues { output += "\(cue.startTime) --> \(cue.endTime)\n" output += cue.text + "\n\n" } return output } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIAudioSpeechTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIAudioSpeechTests: XCTestCase { func testSpeechParametersEncodeExpectedKeys() throws { let params = SpeechParameters( input: "Hello world", model: "gpt-4o-mini-tts", voice: "alloy", instructions: "Calm voice", responseFormat: "mp3", speed: 1.2, streamFormat: "audio" ) let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["input"] as? String, "Hello world") XCTAssertEqual(object["model"] as? String, "gpt-4o-mini-tts") XCTAssertEqual(object["voice"] as? String, "alloy") XCTAssertEqual(object["instructions"] as? String, "Calm voice") XCTAssertEqual(object["response_format"] as? String, "mp3") XCTAssertEqual(object["speed"] as? Double, 1.2) XCTAssertEqual(object["stream_format"] as? String, "audio") } func testMockSpeechReturnsData() async throws { let mock = MockOpenAI() let data = try await mock.createSpeech(parameters: SpeechParameters(input: "test")) XCTAssertFalse(data.isEmpty) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIBatchesTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIBatchesTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testBatchCreateParametersEncodeInputFileId() throws { let params = BatchCreateParameters( inputFileID: "file_123", endpoint: "/v1/responses", completionWindow: "24h" ) let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["input_file_id"] as? String, "file_123") XCTAssertEqual(object["endpoint"] as? String, "/v1/responses") XCTAssertEqual(object["completion_window"] as? String, "24h") } func testBatchMethodsAreExposed() { let client = makeClient() let createBatch: (BatchCreateParameters) async throws -> BatchObject = client.batches.create let listBatches: () async throws -> BatchListResponse = client.batches.list let retrieveBatch: (String) async throws -> BatchObject = client.batches.retrieve let cancelBatch: (String) async throws -> BatchObject = client.batches.cancel XCTAssertNotNil(createBatch) XCTAssertNotNil(listBatches) XCTAssertNotNil(retrieveBatch) XCTAssertNotNil(cancelBatch) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIBetaAssistantsTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIBetaAssistantsTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testThreadRunCreateParametersEncodeAssistantId() throws { let params = ThreadRunCreateParameters(assistantId: "asst_123", model: "gpt-4o-mini") let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["assistant_id"] as? String, "asst_123") XCTAssertEqual(object["model"] as? String, "gpt-4o-mini") } func testBetaAssistantAndThreadMethodsAreExposed() { let client = makeClient() let createAssistant: (AssistantCreateParameters) async throws -> AssistantObject = client.beta.assistants.create let listAssistants: () async throws -> AssistantListResponse = client.beta.assistants.list let retrieveAssistant: (String) async throws -> AssistantObject = client.beta.assistants.retrieve let updateAssistant: (String, AssistantUpdateParameters) async throws -> AssistantObject = client.beta.assistants.update let deleteAssistant: (String) async throws -> DeleteObject = client.beta.assistants.delete let createThread: (ThreadCreateParameters) async throws -> ThreadObject = client.beta.threads.create let retrieveThread: (String) async throws -> ThreadObject = client.beta.threads.retrieve let updateThread: (String, ThreadUpdateParameters) async throws -> ThreadObject = client.beta.threads.update let deleteThread: (String) async throws -> DeleteObject = client.beta.threads.delete let createRun: (String, ThreadRunCreateParameters) async throws -> ThreadRunObject = client.beta.threads.runs.create let listRuns: (String) async throws -> ThreadRunListResponse = client.beta.threads.runs.list let retrieveRun: (String, String) async throws -> ThreadRunObject = client.beta.threads.runs.retrieve let cancelRun: (String, String) async throws -> ThreadRunObject = client.beta.threads.runs.cancel let listSteps: (String, String) async throws -> ThreadRunStepListResponse = client.beta.threads.runs.steps.list let retrieveStep: (String, String, String) async throws -> ThreadRunStepObject = client.beta.threads.runs.steps.retrieve XCTAssertNotNil(createAssistant) XCTAssertNotNil(listAssistants) XCTAssertNotNil(retrieveAssistant) XCTAssertNotNil(updateAssistant) XCTAssertNotNil(deleteAssistant) XCTAssertNotNil(createThread) XCTAssertNotNil(retrieveThread) XCTAssertNotNil(updateThread) XCTAssertNotNil(deleteThread) XCTAssertNotNil(createRun) XCTAssertNotNil(listRuns) XCTAssertNotNil(retrieveRun) XCTAssertNotNil(cancelRun) XCTAssertNotNil(listSteps) XCTAssertNotNil(retrieveStep) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIClientScaffoldTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIClientScaffoldTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testTopLevelResourcesAreAccessible() { let client = makeClient() XCTAssertNotNil(client.completions) XCTAssertNotNil(client.chat) XCTAssertNotNil(client.embeddings) XCTAssertNotNil(client.files) XCTAssertNotNil(client.images) XCTAssertNotNil(client.audio) XCTAssertNotNil(client.moderations) XCTAssertNotNil(client.models) XCTAssertNotNil(client.fineTuning) XCTAssertNotNil(client.vectorStores) XCTAssertNotNil(client.webhooks) XCTAssertNotNil(client.beta) XCTAssertNotNil(client.batches) XCTAssertNotNil(client.uploads) XCTAssertNotNil(client.responses) XCTAssertNotNil(client.realtime) XCTAssertNotNil(client.conversations) XCTAssertNotNil(client.evals) XCTAssertNotNil(client.containers) XCTAssertNotNil(client.skills) XCTAssertNotNil(client.videos) } func testNestedResourcesAreAccessible() { let client = makeClient() XCTAssertNotNil(client.chat.completions) XCTAssertNotNil(client.audio.speech) XCTAssertNotNil(client.audio.transcriptions) XCTAssertNotNil(client.audio.translations) XCTAssertNotNil(client.vectorStores.files) XCTAssertNotNil(client.vectorStores.fileBatches) XCTAssertNotNil(client.uploads.parts) XCTAssertNotNil(client.responses.inputItems) XCTAssertNotNil(client.responses.inputTokens) XCTAssertNotNil(client.realtime.calls) XCTAssertNotNil(client.realtime.clientSecrets) XCTAssertNotNil(client.conversations.items) XCTAssertNotNil(client.evals.runs.outputItems) XCTAssertNotNil(client.containers.files.content) XCTAssertNotNil(client.skills.versions.content) XCTAssertNotNil(client.skills.content) XCTAssertNotNil(client.beta.assistants) XCTAssertNotNil(client.beta.threads.messages) XCTAssertNotNil(client.beta.threads.runs.steps) XCTAssertNotNil(client.beta.chatkit.sessions) XCTAssertNotNil(client.beta.chatkit.threads) XCTAssertNotNil(client.beta.realtime.sessions) XCTAssertNotNil(client.beta.realtime.transcriptionSessions) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIContainersTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIContainersTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testContainerFileCreateParametersEncodeFileId() throws { let params = ContainerFileCreateParameters(fileID: "file_123") let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["file_id"] as? String, "file_123") } func testContainerMethodsAreExposed() { let client = makeClient() let createContainer: (ContainerCreateParameters) async throws -> ContainerObject = client.containers.create let listContainers: () async throws -> ContainerListResponse = client.containers.list let retrieveContainer: (String) async throws -> ContainerObject = client.containers.retrieve let deleteContainer: (String) async throws -> DeleteObject = client.containers.delete let createContainerFile: (String, ContainerFileCreateParameters) async throws -> ContainerFileObject = client.containers.files.create let listContainerFiles: (String) async throws -> ContainerFileListResponse = client.containers.files.list let retrieveContainerFile: (String, String) async throws -> ContainerFileObject = client.containers.files.retrieve let deleteContainerFile: (String, String) async throws -> DeleteObject = client.containers.files.delete let retrieveContainerFileContent: (String, String) async throws -> Data = client.containers.files.content.retrieve XCTAssertNotNil(createContainer) XCTAssertNotNil(listContainers) XCTAssertNotNil(retrieveContainer) XCTAssertNotNil(deleteContainer) XCTAssertNotNil(createContainerFile) XCTAssertNotNil(listContainerFiles) XCTAssertNotNil(retrieveContainerFile) XCTAssertNotNil(deleteContainerFile) XCTAssertNotNil(retrieveContainerFileContent) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIConversationsTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIConversationsTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testConversationItemCreateParametersEncode() throws { let params = ConversationItemCreateParameters(role: "user", content: "hello") let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["type"] as? String, "message") XCTAssertEqual(object["role"] as? String, "user") XCTAssertEqual(object["content"] as? String, "hello") } func testConversationMethodsAreExposed() { let client = makeClient() let createConversation: (ConversationCreateParameters) async throws -> ConversationObject = client.conversations.create let listConversation: () async throws -> ConversationListResponse = client.conversations.list let retrieveConversation: (String) async throws -> ConversationObject = client.conversations.retrieve let deleteConversation: (String) async throws -> DeleteObject = client.conversations.delete let listItems: (String) async throws -> ConversationItemListResponse = client.conversations.items.list let createItem: (String, ConversationItemCreateParameters) async throws -> ConversationItemObject = client.conversations.items.create let retrieveItem: (String, String) async throws -> ConversationItemObject = client.conversations.items.retrieve let deleteItem: (String, String) async throws -> DeleteObject = client.conversations.items.delete XCTAssertNotNil(createConversation) XCTAssertNotNil(listConversation) XCTAssertNotNil(retrieveConversation) XCTAssertNotNil(deleteConversation) XCTAssertNotNil(listItems) XCTAssertNotNil(createItem) XCTAssertNotNil(retrieveItem) XCTAssertNotNil(deleteItem) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIEncodingMigrationTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIEncodingMigrationTests: XCTestCase { private func jsonObject(_ value: T) throws -> [String: Any] { let data = try JSONEncoder().encode(value) guard let object = try JSONSerialization.jsonObject(with: data) as? [String: Any] else { XCTFail("Expected JSON dictionary") return [:] } return object } func testCompletionParametersEncodeSnakeCaseKeys() throws { let params = CompletionParameters( model: .textCurie001, prompt: ["hello"], maxTokens: 32, temperature: 0.5, topP: 0.9, numberOfCompletions: 2, stream: true ) let encoded = try jsonObject(params) XCTAssertEqual(encoded["model"] as? String, "text-curie-001") XCTAssertEqual(encoded["max_tokens"] as? Int, 32) XCTAssertEqual(encoded["top_p"] as? Double, 0.9) XCTAssertEqual(encoded["n"] as? Int, 2) XCTAssertEqual(encoded["stream"] as? Bool, true) } func testChatParametersEncodeModelAndFunctions() throws { let parameters = Parameters( type: "object", properties: [ "location": ParameterDetail(type: "string") ], required: ["location"] ) let function = Function( name: "lookup_weather", description: "Find weather for city", parameters: parameters ) let tool = ChatTool(function: function) let params = ChatParameters( model: .gpt4, customModel: "gpt-5.2", messages: [ChatMessage(role: .user, content: "hello")], functionCall: "auto", functions: [function], tools: [tool], toolChoice: "required", responseFormat: ChatResponseFormat(type: .jsonObject), seed: 7, maxCompletionTokens: 128, parallelToolCalls: true, logprobs: true, topLogprobs: 2 ) let encoded = try jsonObject(params) XCTAssertEqual(encoded["model"] as? String, "gpt-5.2") XCTAssertEqual(encoded["function_call"] as? String, "auto") XCTAssertNotNil(encoded["functions"]) XCTAssertEqual(encoded["tool_choice"] as? String, "required") XCTAssertEqual(encoded["seed"] as? Int, 7) XCTAssertEqual(encoded["max_completion_tokens"] as? Int, 128) XCTAssertEqual(encoded["parallel_tool_calls"] as? Bool, true) XCTAssertEqual(encoded["logprobs"] as? Bool, true) XCTAssertEqual(encoded["top_logprobs"] as? Int, 2) XCTAssertNotNil(encoded["tools"]) XCTAssertNotNil(encoded["response_format"]) } func testImageParametersEncodeExpectedKeyNames() throws { let params = ImageParameters( prompt: "A test image", numberofImages: 1, resolution: .large, quality: .hd, style: .vivid, model: .dalle3, responseFormat: .url ) let encoded = try jsonObject(params) XCTAssertEqual(encoded["prompt"] as? String, "A test image") XCTAssertEqual(encoded["n"] as? Int, 1) XCTAssertEqual(encoded["size"] as? String, "1024x1024") XCTAssertEqual(encoded["response_format"] as? String, "url") XCTAssertEqual(encoded["model"] as? String, "dall-e-3") } func testEmbeddingsParametersEncodeDirectly() throws { let params = EmbeddingsParameters(model: "text-embedding-3-small", input: "hello", user: "u1") let encoded = try jsonObject(params) XCTAssertEqual(encoded["model"] as? String, "text-embedding-3-small") XCTAssertEqual(encoded["input"] as? String, "hello") XCTAssertEqual(encoded["user"] as? String, "u1") } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIEvalsTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIEvalsTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testEvalRunCreateParametersEncodeInput() throws { let params = EvalRunCreateParameters(input: "sample-input", model: "gpt-5.2") let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["input"] as? String, "sample-input") XCTAssertEqual(object["model"] as? String, "gpt-5.2") } func testEvalMethodsAreExposed() { let client = makeClient() let createEval: (EvalCreateParameters) async throws -> EvalObject = client.evals.create let listEvals: () async throws -> EvalListResponse = client.evals.list let retrieveEval: (String) async throws -> EvalObject = client.evals.retrieve let deleteEval: (String) async throws -> DeleteObject = client.evals.delete let createRun: (String, EvalRunCreateParameters) async throws -> EvalRunObject = client.evals.runs.create let listRuns: (String) async throws -> EvalRunListResponse = client.evals.runs.list let retrieveRun: (String, String) async throws -> EvalRunObject = client.evals.runs.retrieve let cancelRun: (String, String) async throws -> EvalRunObject = client.evals.runs.cancel let listOutputItems: (String, String) async throws -> EvalRunOutputItemListResponse = client.evals.runs.outputItems.list XCTAssertNotNil(createEval) XCTAssertNotNil(listEvals) XCTAssertNotNil(retrieveEval) XCTAssertNotNil(deleteEval) XCTAssertNotNil(createRun) XCTAssertNotNil(listRuns) XCTAssertNotNil(retrieveRun) XCTAssertNotNil(cancelRun) XCTAssertNotNil(listOutputItems) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIFineTuningTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIFineTuningTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testFineTuningParametersEncodeTrainingFileKey() throws { let params = FineTuningJobCreateParameters( model: "gpt-4o-mini", trainingFileID: "file_train", validationFileID: "file_val" ) let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["training_file"] as? String, "file_train") XCTAssertEqual(object["validation_file"] as? String, "file_val") } func testFineTuningMethodsAreExposed() { let client = makeClient() let createJob: (FineTuningJobCreateParameters) async throws -> FineTuningJobObject = client.fineTuning.jobs.create let listJobs: () async throws -> FineTuningJobListResponse = client.fineTuning.jobs.list let retrieveJob: (String) async throws -> FineTuningJobObject = client.fineTuning.jobs.retrieve let cancelJob: (String) async throws -> FineTuningJobObject = client.fineTuning.jobs.cancel let listEvents: (String) async throws -> FineTuningJobEventListResponse = client.fineTuning.jobs.listEvents let listCheckpoints: (String) async throws -> FineTuningCheckpointListResponse = client.fineTuning.jobs.listCheckpoints XCTAssertNotNil(createJob) XCTAssertNotNil(listJobs) XCTAssertNotNil(retrieveJob) XCTAssertNotNil(cancelJob) XCTAssertNotNil(listEvents) XCTAssertNotNil(listCheckpoints) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIRealtimeTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIRealtimeTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testRealtimeReferParameterEncoding() throws { let params = RealtimeCallReferParameters(target: "agent-2", reason: "escalation") let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["target"] as? String, "agent-2") XCTAssertEqual(object["reason"] as? String, "escalation") } func testRealtimeMethodsAreExposed() async throws { let client = makeClient() let createCall: (RealtimeCallCreateParameters) async throws -> RealtimeCallObject = client.realtime.calls.create let acceptCall: (String) async throws -> RealtimeCallObject = client.realtime.calls.accept let hangupCall: (String) async throws -> RealtimeCallObject = client.realtime.calls.hangup let referCall: (String, RealtimeCallReferParameters) async throws -> RealtimeCallObject = client.realtime.calls.refer let rejectCall: (String) async throws -> RealtimeCallObject = client.realtime.calls.reject let createSecret: (RealtimeClientSecretCreateParameters) async throws -> RealtimeClientSecretResponse = client.realtime.clientSecrets.create XCTAssertNotNil(createCall) XCTAssertNotNil(acceptCall) XCTAssertNotNil(hangupCall) XCTAssertNotNil(referCall) XCTAssertNotNil(rejectCall) XCTAssertNotNil(createSecret) let connection = await client.realtime.connect(options: .init(model: "gpt-realtime")).enter() let event = await connection.receive() XCTAssertEqual(event?.type, "connected") await connection.close() } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIResponsesTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIResponsesTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testResponseInputTokenParametersEncode() throws { let params = ResponseInputTokensParameters(model: "gpt-5.2", input: "hello") let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["model"] as? String, "gpt-5.2") XCTAssertEqual(object["input"] as? String, "hello") } func testResponseResourceMethodsAreExposed() { let client = makeClient() let createResponse: (ResponseCreateParameters) async throws -> ResponseObject = client.responses.create let parseResponse: (ResponseCreateParameters) async throws -> ResponseObject = client.responses.parse let streamResponse: (ResponseCreateParameters) throws -> AsyncThrowingStream = client.responses.stream let retrieveResponse: (String) async throws -> ResponseObject = client.responses.retrieve let cancelResponse: (String) async throws -> ResponseObject = client.responses.cancel let deleteResponse: (String) async throws -> DeleteObject = client.responses.delete let listInputItems: (String) async throws -> ResponseInputItemListResponse = client.responses.inputItems.list let countInputTokens: (ResponseInputTokensParameters) async throws -> ResponseInputTokenCount = client.responses.inputTokens.create XCTAssertNotNil(createResponse) XCTAssertNotNil(parseResponse) XCTAssertNotNil(streamResponse) XCTAssertNotNil(retrieveResponse) XCTAssertNotNil(cancelResponse) XCTAssertNotNil(deleteResponse) XCTAssertNotNil(listInputItems) XCTAssertNotNil(countInputTokens) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAISkillsAndVideosTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAISkillsAndVideosTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testVideoCreateParametersEncodePrompt() throws { let params = VideoCreateParameters(model: "sora-1", prompt: "A fast river in spring") let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) XCTAssertEqual(object["model"] as? String, "sora-1") XCTAssertEqual(object["prompt"] as? String, "A fast river in spring") } func testSkillsAndVideosMethodsAreExposed() { let client = makeClient() let createSkill: (SkillCreateParameters) async throws -> SkillObject = client.skills.create let listSkills: () async throws -> SkillListResponse = client.skills.list let retrieveSkill: (String) async throws -> SkillObject = client.skills.retrieve let updateSkill: (String, SkillUpdateParameters) async throws -> SkillObject = client.skills.update let deleteSkill: (String) async throws -> DeleteObject = client.skills.delete let retrieveSkillContent: (String) async throws -> Data = client.skills.content.retrieve let updateSkillContent: (String, SkillContentUpdateParameters) async throws -> SkillObject = client.skills.content.update let listVersions: (String) async throws -> SkillVersionListResponse = client.skills.versions.list let retrieveVersion: (String, String) async throws -> SkillVersionObject = client.skills.versions.retrieve let retrieveVersionContent: (String, String) async throws -> Data = client.skills.versions.content.retrieve let createVideo: (VideoCreateParameters) async throws -> VideoObject = client.videos.create let listVideos: () async throws -> VideoListResponse = client.videos.list let retrieveVideo: (String) async throws -> VideoObject = client.videos.retrieve let cancelVideo: (String) async throws -> VideoObject = client.videos.cancel XCTAssertNotNil(createSkill) XCTAssertNotNil(listSkills) XCTAssertNotNil(retrieveSkill) XCTAssertNotNil(updateSkill) XCTAssertNotNil(deleteSkill) XCTAssertNotNil(retrieveSkillContent) XCTAssertNotNil(updateSkillContent) XCTAssertNotNil(listVersions) XCTAssertNotNil(retrieveVersion) XCTAssertNotNil(retrieveVersionContent) XCTAssertNotNil(createVideo) XCTAssertNotNil(listVideos) XCTAssertNotNil(retrieveVideo) XCTAssertNotNil(cancelVideo) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAITransportOptionsTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAITransportOptionsTests: XCTestCase { func testConfigurationHeadersIncludeOrganizationProjectAndCustomHeaders() { let config = Configuration( apiKey: "test_key", organizationId: "org_test", projectId: "proj_test", webhookSecret: "whsec_test", baseURL: URL(string: "https://example.com/v1")!, requestOptions: OpenAIRequestOptions( timeoutInterval: 42, maxRetries: 3, additionalHeaders: ["X-Test-Header": "value"] ) ) let headers = OpenAIKitSession.shared.headers(for: config) XCTAssertEqual(headers["Authorization"], "Bearer test_key") XCTAssertEqual(headers["OpenAI-Organization"], "org_test") XCTAssertEqual(headers["OpenAI-Project"], "proj_test") XCTAssertEqual(headers["X-Test-Header"], "value") } func testStatusErrorMappingUsesTypedCases() { let payload = """ { "error": { "message": "invalid request", "type": "invalid_request_error", "param": null, "code": "bad_request" } } """.data(using: .utf8)! let badRequest = OpenAIKitSession.statusError(for: 400, data: payload) if case .badRequest(let response) = badRequest { XCTAssertEqual(response?.error.message, "invalid request") } else { XCTFail("Expected .badRequest") } let unauthorized = OpenAIKitSession.statusError(for: 401, data: payload) if case .authentication = unauthorized { XCTAssertTrue(true) } else { XCTFail("Expected .authentication") } let rateLimited = OpenAIKitSession.statusError(for: 429, data: payload) if case .rateLimit = rateLimited { XCTAssertTrue(true) } else { XCTFail("Expected .rateLimit") } let server = OpenAIKitSession.statusError(for: 503, data: payload) if case .internalServer(let code, _) = server { XCTAssertEqual(code, 503) } else { XCTFail("Expected .internalServer") } let unexpected = OpenAIKitSession.statusError(for: 418, data: payload) if case .unexpectedStatusCode(let code, _) = unexpected { XCTAssertEqual(code, 418) } else { XCTFail("Expected .unexpectedStatusCode") } } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIUploadsTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIUploadsTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testUploadCompleteParametersEncodePartIds() throws { let params = UploadCompleteParameters(partIDs: ["part_1", "part_2"]) let data = try JSONEncoder().encode(params) let object = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) let partIDs = object["part_ids"] as? [String] XCTAssertEqual(partIDs?.count, 2) } func testUploadMethodsAreExposed() { let client = makeClient() let createUpload: (UploadCreateParameters) async throws -> UploadObject = client.uploads.create let retrieveUpload: (String) async throws -> UploadObject = client.uploads.retrieve let cancelUpload: (String) async throws -> UploadObject = client.uploads.cancel let completeUpload: (String, UploadCompleteParameters) async throws -> UploadObject = client.uploads.complete let createPart: (String, UploadPartCreateParameters) async throws -> UploadPartObject = client.uploads.parts.create XCTAssertNotNil(createUpload) XCTAssertNotNil(retrieveUpload) XCTAssertNotNil(cancelUpload) XCTAssertNotNil(completeUpload) XCTAssertNotNil(createPart) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIVectorStoresTests.swift ================================================ import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIVectorStoresTests: XCTestCase { private func makeClient() -> OpenAI { OpenAI(.init(organizationId: "org_test", apiKey: "test_key")) } func testVectorStoreParametersEncodeFileIdsKey() throws { let createParams = VectorStoreCreateParameters(name: "Docs", fileIDs: ["file_1", "file_2"]) let createData = try JSONEncoder().encode(createParams) let createObject = try XCTUnwrap(try JSONSerialization.jsonObject(with: createData) as? [String: Any]) XCTAssertNotNil(createObject["file_ids"]) let fileParams = VectorStoreFileCreateParameters(fileID: "file_123") let fileData = try JSONEncoder().encode(fileParams) let fileObject = try XCTUnwrap(try JSONSerialization.jsonObject(with: fileData) as? [String: Any]) XCTAssertEqual(fileObject["file_id"] as? String, "file_123") } func testVectorStoreMethodsAreExposed() { let client = makeClient() let createStore: (VectorStoreCreateParameters) async throws -> VectorStoreObject = client.vectorStores.create let listStores: () async throws -> VectorStoreListResponse = client.vectorStores.list let retrieveStore: (String) async throws -> VectorStoreObject = client.vectorStores.retrieve let updateStore: (String, VectorStoreUpdateParameters) async throws -> VectorStoreObject = client.vectorStores.update let deleteStore: (String) async throws -> DeleteObject = client.vectorStores.delete let createFile: (String, VectorStoreFileCreateParameters) async throws -> VectorStoreFileObject = client.vectorStores.files.create let listFiles: (String) async throws -> VectorStoreFileListResponse = client.vectorStores.files.list let retrieveFile: (String, String) async throws -> VectorStoreFileObject = client.vectorStores.files.retrieve let deleteFile: (String, String) async throws -> DeleteObject = client.vectorStores.files.delete let createBatch: (String, VectorStoreFileBatchCreateParameters) async throws -> VectorStoreFileBatchObject = client.vectorStores.fileBatches.create let listBatches: (String) async throws -> VectorStoreFileBatchListResponse = client.vectorStores.fileBatches.list let retrieveBatch: (String, String) async throws -> VectorStoreFileBatchObject = client.vectorStores.fileBatches.retrieve let cancelBatch: (String, String) async throws -> VectorStoreFileBatchObject = client.vectorStores.fileBatches.cancel XCTAssertNotNil(createStore) XCTAssertNotNil(listStores) XCTAssertNotNil(retrieveStore) XCTAssertNotNil(updateStore) XCTAssertNotNil(deleteStore) XCTAssertNotNil(createFile) XCTAssertNotNil(listFiles) XCTAssertNotNil(retrieveFile) XCTAssertNotNil(deleteFile) XCTAssertNotNil(createBatch) XCTAssertNotNil(listBatches) XCTAssertNotNil(retrieveBatch) XCTAssertNotNil(cancelBatch) } } ================================================ FILE: Tests/OpenAIKitTests/Client/OpenAIWebhooksTests.swift ================================================ import CryptoKit import XCTest @testable import OpenAIKit @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) final class OpenAIWebhooksTests: XCTestCase { private struct TestWebhookEvent: Decodable { let type: String } private let secret = "whsec_test_123" private func makeClient() -> OpenAI { OpenAI( .init( apiKey: "test_key", organizationId: "org_test", webhookSecret: secret ) ) } private func signature(timestamp: String, payload: String) -> String { let message = "\(timestamp).\(payload)" let key = SymmetricKey(data: Data(secret.utf8)) let digest = HMAC.authenticationCode(for: Data(message.utf8), using: key) return Data(digest).map { String(format: "%02x", $0) }.joined() } func testVerifySignatureAcceptsValidHeaders() throws { let client = makeClient() let payload = #"{"type":"response.completed"}"# let timestamp = "1700000000" let sig = signature(timestamp: timestamp, payload: payload) let headers = [ "OpenAI-Timestamp": timestamp, "OpenAI-Signature": "v1=\(sig)" ] XCTAssertNoThrow(try client.webhooks.verifySignature(payload: payload, headers: headers)) } func testVerifySignatureRejectsInvalidSignature() { let client = makeClient() let payload = #"{"type":"response.completed"}"# let headers = [ "OpenAI-Timestamp": "1700000000", "OpenAI-Signature": "v1=deadbeef" ] XCTAssertThrowsError(try client.webhooks.verifySignature(payload: payload, headers: headers)) } func testUnwrapVerifiesAndDecodes() throws { let client = makeClient() let payload = #"{"type":"response.completed"}"# let timestamp = "1700000000" let sig = signature(timestamp: timestamp, payload: payload) let headers = [ "webhook-timestamp": timestamp, "webhook-signature": sig ] let event = try client.webhooks.unwrap(payload: payload, headers: headers, as: TestWebhookEvent.self) XCTAssertEqual(event.type, "response.completed") } } ================================================ FILE: Tests/OpenAIKitTests/Extension/BundleExtension.swift ================================================ // // BundleExtension.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation extension Bundle { static var test: Bundle { let bundle: Bundle #if SWIFT_PACKAGE bundle = Bundle.module #else bundle = Bundle(for: OpenAIKitTests.self) #endif return bundle } } ================================================ FILE: Tests/OpenAIKitTests/Mocks/MockOpenAI.swift ================================================ // // MockOpenAI.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation @testable import OpenAIKit class MockOpenAI: OpenAIProtocol { func getDecodedData(_ type: T.Type = T.self, with jsonData: String) async throws -> T { guard let url = Bundle.test.url(forResource: jsonData, withExtension: "json") else { print("Getting Url for bundle has failed.") throw MockOpenAIError.urlBundleFailed } guard let data = try? Data(contentsOf: url) else { print("Setting data using contents of url has failed.") throw MockOpenAIError.dataCoersionFailed } let decoder = JSONDecoder() decoder.keyDecodingStrategy = .useDefaultKeys guard let result = try? decoder.decode(T.self, from: data) else { print("Decoding data has failed.") throw MockOpenAIError.dataCodingFailed } return result } func listModels() async throws -> ListModelResponse { return try await getDecodedData(with: "ModelsResponse") as ListModelResponse } func retrieveModel(modelId id: String) async throws -> Model { return try await getDecodedData(with: "RetrieveModelResponse") as Model } func generateCompletion(parameters param: CompletionParameters) async throws -> CompletionResponse { return try await getDecodedData(with: "CompletionResponse") as CompletionResponse } func generateCompletionStreaming( parameters param: OpenAIKit.CompletionParameters ) throws -> AsyncThrowingStream { throw MockOpenAIError.notImplemented } func createImage(parameters param: ImageParameters) async throws -> ImageResponse { if let user = param.user { switch user { case "promptApple": return try await getDecodedData(with: "ImageApple") as ImageResponse case "promptOtter": return try await getDecodedData(with: "ImageOtter") as ImageResponse case "promptEmpty": throw MockOpenAIError.invalidPrompt case "number1": return try await getDecodedData(with: "ImageURL1") as ImageResponse case "number2": return try await getDecodedData(with: "ImageURL2") as ImageResponse case "number10": return try await getDecodedData(with: "ImageURL10") as ImageResponse case "number11": return try await getDecodedData(with: "ImageURL11") as ImageResponse case "number0": return try await getDecodedData(with: "ImageURL0") as ImageResponse case "number-1": return try await getDecodedData(with: "ImageURL-1") as ImageResponse case "sizeSmallURL": return try await getDecodedData(with: "ImageURLSmall") as ImageResponse case "sizeSmallB64": return try await getDecodedData(with: "ImageB64Small") as ImageResponse case "sizeMediumURL": return try await getDecodedData(with: "ImageURLMedium") as ImageResponse case "sizeMediumB64": return try await getDecodedData(with: "ImageB64Medium") as ImageResponse case "sizeLargeURL": return try await getDecodedData(with: "ImageURLLarge") as ImageResponse case "sizeLargeB64": return try await getDecodedData(with: "ImageB64Large") as ImageResponse case "responseURL": return try await getDecodedData(with: "ImageURL") as ImageResponse case "responseB64": return try await getDecodedData(with: "ImageB64") as ImageResponse default: throw MockOpenAIError.invalidUser } } throw MockOpenAIError.invalidUser } func generateChatCompletion(parameters param: ChatParameters) async throws -> ChatResponse { throw MockOpenAIError.notImplemented } func generateChatCompletionStreaming( parameters param: ChatParameters ) throws -> AsyncThrowingStream { throw MockOpenAIError.notImplemented } func generateImageEdits(parameters param: ImageEditParameters) async throws -> ImageResponse { throw MockOpenAIError.notImplemented } func generateImageVariations(parameters param: ImageVariationParameters) async throws -> ImageResponse { throw MockOpenAIError.notImplemented } func createEmbeddings(parameters param: EmbeddingsParameters) async throws -> EmbeddingsResponse { return try await getDecodedData(with: "EmbeddingsResponse") as EmbeddingsResponse } func createTranscription(parameters param: TranscriptionParameters) async throws -> TranscriptionResponse { throw MockOpenAIError.notImplemented } func createTranslation(parameters param: TranscriptionParameters) async throws -> TranscriptionResponse { throw MockOpenAIError.notImplemented } func createSpeech(parameters param: SpeechParameters) async throws -> Data { Data("audio".utf8) } func listFiles() async throws -> ListFilesResponse { return try await getDecodedData(with: "ListFilesResponse") as ListFilesResponse } func uploadFile(parameters param: UploadFileParameters) async throws -> File { throw MockOpenAIError.notImplemented } func deleteFile(fileId id: String) async throws -> DeleteObject { return try await getDecodedData(with: "DeleteFileResponse") as DeleteObject } func retrieveFile(fileId id: String) async throws -> File { throw MockOpenAIError.notImplemented } func retrieveFileContent(fileId id: String) async throws -> [OpenAIKit.FileContent] { throw MockOpenAIError.notImplemented } func deleteModel(model: String) async throws -> DeleteObject { throw MockOpenAIError.notImplemented } func checkContentPolicy(parameters param: ContentPolicyParameters) async throws -> ContentPolicyResponse { return try await getDecodedData(with: "ContentPolicyResponse") as ContentPolicyResponse } } ================================================ FILE: Tests/OpenAIKitTests/OpenAIKitTests.swift ================================================ // // OpenAIKitTests.swift // OpenAIKit // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import XCTest @testable import OpenAIKit final class OpenAIKitTests: XCTestCase { func testThatVerifiesOpenAIIsAbleToFetchAListOfModels() async { do { // Given let mockOpenAI = MockOpenAI() // When let modelsResponse = try await mockOpenAI.listModels() // Then XCTAssertEqual( modelsResponse.object, .list, "Model Response is not a list object." ) XCTAssertFalse( modelsResponse.data.isEmpty, "Model Response data is empty." ) XCTAssertEqual( modelsResponse.data[0].id, "model-id-0", "Model Response doesn't contain the named model." ) XCTAssertEqual( modelsResponse.data[0].object, .model, "Model type isn't a model." ) XCTAssertEqual( modelsResponse.data[0].created, 1686935002, "Model doesn't contain correct creation date." ) XCTAssertEqual( modelsResponse.data[0].ownedBy, "organization-owner", "Model doesn't have correct owner." ) } catch { XCTFail("LIST MODELS TEST FAILED WITH ERROR: \(error)") } } func testThatVerifiesOpenAIIsAbleToRetrieveModelUsingID() async { do { // Given let mockOpenAI = MockOpenAI() // When let model = try await mockOpenAI.retrieveModel( modelId: "davinci" ) // Then XCTAssertEqual( model.id, "davinci", "Model Response doesn't contain the Davinvi model." ) XCTAssertEqual( model.object, .model, "Model type isn't a model." ) XCTAssertEqual( model.created, 1686935002, "Model doesn't contain correct creation date." ) XCTAssertEqual( model.ownedBy, "openai", "Model doesn't have correct owner." ) } catch { XCTFail("RETRIEVE MODEL TEST FAILED WITH ERROR: \(error)") } } func testThatVerifiesOpenAIIsAbleToCompleteTextPrompts() async { do { // Given let mockOpenAI = MockOpenAI() let completionParameter = CompletionParameters(model: .davinci) // When let completionResponse = try await mockOpenAI.generateCompletion( parameters: completionParameter ) // Then XCTAssertEqual( completionResponse.id, "cmpl-69nq0IKF1lwssd3QdLnz4fQ4yCt4O", "Completion Response has incorrect ID." ) XCTAssertEqual( completionResponse.object, .textCompletion, "Completion Response has incorrect object type." ) XCTAssertEqual( completionResponse.created, 1667794548, "Completion Response has incorrect creation date." ) XCTAssertEqual( completionResponse.model, "text-davinci-002", "Completion Response has incorrect model." ) XCTAssertTrue( completionResponse.choices[0].text.contains("This is a test"), "Completion Response has incorrect completion." ) XCTAssertEqual( completionResponse.choices[0].index, 0, "Completion Response has incorrect index." ) XCTAssertNil( completionResponse.choices[0].logprobs, "Completion Response shouldn't have logprobs." ) XCTAssertEqual( completionResponse.choices[0].finishReason!, "length", "Completion Response has incorrect finish reason." ) XCTAssertEqual( completionResponse.usage.promptTokens, 5, "Completion Response has incorrect prompt token usage." ) XCTAssertEqual( completionResponse.usage.completionTokens, 6, "Completion Response has incorrect completion token usage." ) XCTAssertEqual( completionResponse.usage.totalTokens, 11, "Completion Response has incorrect total token usage." ) } catch { XCTFail("COMPLETION PROMPT TEST FAILED WITH ERROR: \(error)") } } func testThatVerifiesOpenAIIsAbleToGenerateImagesUsingGivenPrompts() async { do { // Given let mockOpenAI = MockOpenAI() let parameterApple = ImageParameters( prompt: "A red apple.", user: "promptApple" ) let parameterOtter = ImageParameters( prompt: "A cute baby sea otter", user: "promptOtter" ) // When let apple = try await mockOpenAI.createImage( parameters: parameterApple ) let otter = try await mockOpenAI.createImage( parameters: parameterOtter ) // Then XCTAssertEqual( apple.created, 1667676516, "Created date of Apple is incorrect." ) XCTAssertFalse( apple.data.isEmpty, "Contents of Apple is empty." ) XCTAssertTrue( apple.data[0].image.contains("img-nsJnMAwG1wUsEx5kem6LWGvJ.png"), "Contents of Apple URL isn't valid." ) XCTAssertEqual( otter.created, 1667661280, "Created date of Otter is incorrect." ) XCTAssertFalse( otter.data.isEmpty, "Contents of Otter is empty." ) XCTAssertTrue( otter.data[0].image.contains("img-byoTBAgSaGlyyTCGjnFhbSVx.png"), "Contents of Otter URL isn't valid." ) } catch { XCTFail("PROMPT TEST FAILED WITH ERROR: \(error)") } } func testThatVerifiesEmptyPromptsThrowAnError() async { do { // Given let mockOpenAI = MockOpenAI() // When let parameterEmptyPrompt = ImageParameters( prompt: "", user: "promptEmpty" ) // Then _ = try await mockOpenAI.createImage( parameters: parameterEmptyPrompt ) } catch MockOpenAIError.invalidPrompt { XCTAssertTrue(true) } catch { XCTFail("EMPTY PROMPT TEST FAILED WITH ERROR: \(error)") } } func testThatVerifiesOpenAIIsAbleToGenerateImagesGivenDifferentResponseTypes() async { do { // Given let mockOpenAI = MockOpenAI() let parameterUrl = ImageParameters( prompt: "A cute baby sea otter", responseFormat: .url, user: "responseURL" ) let parameterB64 = ImageParameters( prompt: "A cute baby sea otter", responseFormat: .base64Json, user: "responseB64" ) // When let url = try await mockOpenAI.createImage( parameters: parameterUrl ) let b64 = try await mockOpenAI.createImage( parameters: parameterB64 ) // Then XCTAssertEqual( url.created, 1667661280, "Created date of url is incorrect." ) XCTAssertFalse( url.data.isEmpty, "Contents of url is empty." ) XCTAssertTrue( url.data[0].image.contains("img-byoTBAgSaGlyyTCGjnFhbSVx.png"), "Contents of url URL isn't valid." ) XCTAssertEqual( b64.created, 1667615111, "Created date of b64 is incorrect." ) XCTAssertFalse( b64.data.isEmpty, "Contents of b64 is empty." ) XCTAssertTrue( b64.data[0].image.contains("CAQAAAf8C/wL9AAACAQEA////AAH+/gD+/wD+AAH+AAD+Af//A"), "Contents of b64 data isn't valid." ) } catch { XCTFail("RESPONSE TYPE TEST FAILED WITH ERROR: \(error)") } } func testThatVerifiesOpenAIIsAbleToGenerateDifferentResolutions() async { do { // Given let mockOpenAI = MockOpenAI() let parameterSmallUrl = ImageParameters( prompt: "A cute baby sea otter", resolution: .small, user: "sizeSmallURL" ) let parameterSmallB64 = ImageParameters( prompt: "A cute baby sea otter", resolution: .small, user: "sizeSmallB64" ) let parameterMediumUrl = ImageParameters( prompt: "A cute baby sea otter", resolution: .medium, user: "sizeMediumURL" ) let parameterMediumB64 = ImageParameters( prompt: "A cute baby sea otter", resolution: .medium, user: "sizeMediumB64" ) let parameterLargeUrl = ImageParameters( prompt: "A cute baby sea otter", resolution: .large, user: "sizeLargeURL" ) let parameterLargeB64 = ImageParameters( prompt: "A cute baby sea otter", resolution: .large, user: "sizeLargeB64" ) // When let smallUrl = try await mockOpenAI.createImage( parameters: parameterSmallUrl ) let smallB64 = try await mockOpenAI.createImage( parameters: parameterSmallB64 ) let mediumUrl = try await mockOpenAI.createImage( parameters: parameterMediumUrl ) let mediumB64 = try await mockOpenAI.createImage( parameters: parameterMediumB64 ) let largeUrl = try await mockOpenAI.createImage( parameters: parameterLargeUrl ) let largeB64 = try await mockOpenAI.createImage( parameters: parameterLargeB64 ) // Then XCTAssertEqual( smallUrl.created, 1667661280, "Created date of smallUrl is incorrect." ) XCTAssertFalse( smallUrl.data.isEmpty, "Contents of smallUrl is empty." ) XCTAssertTrue( smallUrl.data[0].image.contains("img-byoTBAgSaGlyyTCGjnFhbSVx.png"), "Contents of smallUrl URL isn't valid." ) XCTAssertEqual( smallB64.created, 1667615111, "Created date of smallB64 is incorrect." ) XCTAssertFalse( smallB64.data.isEmpty, "Contents of smallB64 is empty." ) XCTAssertTrue( smallB64.data[0].image.contains("CAQAAAf8C/wL9AAACAQEA////AAH+/gD+/wD+AAH+AAD+Af//A"), "Contents of smallB64 data isn't valid." ) XCTAssertEqual( mediumUrl.created, 1667674510, "Created date of mediumUrl is incorrect." ) XCTAssertFalse( mediumUrl.data.isEmpty, "Contents of mediumUrl is empty." ) XCTAssertTrue( mediumUrl.data[0].image.contains("img-euW0HHRIAcFPddYSrH88KT5m.png"), "Contents of mediumUrl URL isn't valid." ) XCTAssertEqual( mediumB64.created, 1667674568, "Created date of mediumB64 is incorrect." ) XCTAssertFalse( mediumB64.data.isEmpty, "Contents of mediumB64 is empty." ) XCTAssertTrue( mediumB64.data[0].image.contains("+/v/7AP0CAwL+9/3x8vL3+PoFBQr+Afj8AgEB/wEFAAMAAwcIB"), "Contents of mediumB64 data isn't valid." ) XCTAssertEqual( largeUrl.created, 1667674848, "Created date of largeUrl is incorrect." ) XCTAssertFalse( largeUrl.data.isEmpty, "Contents of largeUrl is empty." ) XCTAssertTrue( largeUrl.data[0].image.contains("img-8cl5NT9LdOxfxtb50M3SoMtg.png"), "Contents of largeUrl URL isn't valid." ) XCTAssertEqual( largeB64.created, 1667674929, "Created date of smallB64 is incorrect." ) XCTAssertFalse( largeB64.data.isEmpty, "Contents of smallB64 is empty." ) XCTAssertTrue( largeB64.data[0].image.contains("+BAEDAf7+/vv//gYAAQAB/gID/v38AgAA/v/+Af8BBPwA/AIAA"), "Contents of smallB64 data isn't valid." ) } catch { XCTFail("RESOLUTION TEST FAILED WITH ERROR: \(error)") } } func testThatVerifiesOpenAIIsAbleToGenerateImageGivenDifferentImageAmountsAndDoesNotGoOverNorUnderLimits() async { do { // Given let mockOpenAI = MockOpenAI() let image1Parameter = ImageParameters( prompt: "A cute baby sea otter", numberofImages: 1, user: "number1" ) let image2Parameter = ImageParameters( prompt: "A cute baby sea otter", numberofImages: 2, user: "number2" ) let image10Parameter = ImageParameters( prompt: "A cute baby sea otter", numberofImages: 10, user: "number10" ) let image11Parameter = ImageParameters( prompt: "A cute baby sea otter", numberofImages: 11, user: "number11" ) let image0Parameter = ImageParameters( prompt: "A cute baby sea otter", numberofImages: 0, user: "number0" ) let imageNegative1Parameter = ImageParameters( prompt: "A cute baby sea otter", numberofImages: -1, user: "number-1" ) // When let image1 = try await mockOpenAI.createImage( parameters: image1Parameter ) let image2 = try await mockOpenAI.createImage( parameters: image2Parameter ) let image10 = try await mockOpenAI.createImage( parameters: image10Parameter ) let image11 = try await mockOpenAI.createImage( parameters: image11Parameter ) let image0 = try await mockOpenAI.createImage( parameters: image0Parameter ) let imageNegative1 = try await mockOpenAI.createImage( parameters: imageNegative1Parameter ) // Then XCTAssertEqual( image1.created, 1667661280, "Created date of image1 is incorrect." ) XCTAssertFalse( image1.data.isEmpty, "Contents of image1 is empty." ) XCTAssertTrue( image1.data[0].image.contains("img-byoTBAgSaGlyyTCGjnFhbSVx.png"), "Contents of image1 URL isn't valid." ) XCTAssertEqual( image2.created, 1667676103, "Created date of image2 is incorrect." ) XCTAssertFalse( image2.data.isEmpty, "Contents of image2 is empty." ) image2.data.enumerated().forEach { (idx, response) in XCTAssertTrue( response.image.contains("org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M"), "URL of image2 at index \(idx) isn't valid." ) } XCTAssertEqual( image10.created, 1667676139, "Created date of image10 is incorrect." ) XCTAssertFalse( image10.data.isEmpty, "Contents of image10 is empty." ) image10.data.enumerated().forEach { (idx, response) in XCTAssertTrue( response.image.contains("org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M"), "URL of image10 at index \(idx) isn't valid." ) } XCTAssertEqual( image11Parameter.numberOfImages, 10, "Image11's parameters wasn't set correctly." ) XCTAssertEqual( image11.created, 1667676139, "Created date of image11 is incorrect." ) XCTAssertFalse( image11.data.isEmpty, "Contents of image11 is empty." ) image11.data.enumerated().forEach { (idx, response) in XCTAssertTrue( response.image.contains("org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M"), "URL of image11 at index \(idx) isn't valid." ) } XCTAssertEqual( image0Parameter.numberOfImages, 1, "Image0's parameters wasn't set correctly." ) XCTAssertEqual( image0.created, 1667661280, "Created date of image0 is incorrect." ) XCTAssertFalse( image0.data.isEmpty, "Contents of image0 is empty." ) XCTAssertTrue( image0.data[0].image.contains("img-byoTBAgSaGlyyTCGjnFhbSVx.png"), "Contents of image0 URL isn't valid." ) XCTAssertEqual( imageNegative1Parameter.numberOfImages, 1, "imageNegative1's parameters wasn't set correctly." ) XCTAssertEqual( imageNegative1.created, 1667661280, "Created date of imageNegative1 is incorrect." ) XCTAssertFalse( imageNegative1.data.isEmpty, "Contents of imageNegative1 is empty." ) XCTAssertTrue( imageNegative1.data[0].image.contains("img-byoTBAgSaGlyyTCGjnFhbSVx.png"), "Contents of imageNegative1 URL isn't valid." ) } catch { XCTFail("IMAGE NUMBER TEST FAILED WITH ERROR: \(error)") } } func testThatVerifiesOpenAIIsAbleToReturnEmbeddingsForInput() async { do { // Given let mockOpenAI = MockOpenAI() let embeddingsParam = EmbeddingsParameters( model: "text-similarity-babbage-001", input: "The food was delicious and the waiter..." ) // When let embeddingsResponse = try await mockOpenAI.createEmbeddings( parameters: embeddingsParam ) // Then XCTAssertEqual( embeddingsResponse.object, .list, "Embeddings Response is not a list object." ) XCTAssertEqual( embeddingsResponse.data[0].object, .embedding, "Embeddings data is not an embedding object." ) XCTAssertEqual( embeddingsResponse.data[0].embedding.count, 2048, "Embeddings data doesn't contain correct amount of floats." ) XCTAssertEqual( embeddingsResponse.data[0].embedding[0], 0.0028667077, "Embeddings data isn't correct." ) XCTAssertEqual( embeddingsResponse.data[0].index, 0, "Embeddings data index isn't correct." ) XCTAssertEqual( embeddingsResponse.usage.promptTokens, 8, "Prompt token amount isn't correct." ) XCTAssertEqual( embeddingsResponse.usage.totalTokens, 8, "Total token amount isn't correct." ) } catch { XCTFail("EMBEDDINGS CREATION FAILED WITH ERROR - \(error)") } } func testThatVerifiesOpenAIIsAbleToReturnListedFiles() async { do { // Given let mockOpenAI = MockOpenAI() // When let filesResponse = try await mockOpenAI.listFiles() // Then XCTAssertEqual( filesResponse.object, .list, "Files Response isn't list object." ) XCTAssertEqual( filesResponse.data[0].id, "file-uvdyS3qukzhVrcvxOcjk0Xss", "File ID isn't correct." ) XCTAssertEqual( filesResponse.data[0].object, .file, "File isn't file object." ) XCTAssertEqual( filesResponse.data[0].purpose, "fine-tune", "File Purpose isn't correct." ) XCTAssertEqual( filesResponse.data[0].filename, "sampleData.jsonl", "File name isn't correct" ) XCTAssertEqual( filesResponse.data[0].bytes, 18950, "File size isn't correct." ) XCTAssertEqual( filesResponse.data[0].createdAt, 1668098746, "File creation date isn't correct." ) XCTAssertEqual( filesResponse.data[0].status, .processed, "File status isn't correct." ) XCTAssertNil( filesResponse.data[0].statusDetails, "File status details isn't nil." ) } catch { XCTFail("LIST FILES FAILED WITH ERROR - \(error)") } } func testThatVerifiesOpenAIIsAbleToDeleteFileAndRespondWithResponse() async { do { // Given let mockOpenAI = MockOpenAI() // When let deleteFileResponse = try await mockOpenAI.deleteFile( fileId: "file-XjGxS3KTG0uNmNOK362iJua3" ) // Then XCTAssertEqual( deleteFileResponse.id, "file-XjGxS3KTG0uNmNOK362iJua3", "File ID isn't correct." ) XCTAssertEqual( deleteFileResponse.object, .file, "File isn't file object." ) XCTAssertTrue( deleteFileResponse.deleted, "File isn't deleted." ) } catch { XCTFail("DELETE FILE FAILED WITH ERROR - \(error)") } } func testThatVerifiesOpenAIIsAbleToSendContentPolicyResult() async { do { // Given let mockOpenAI = MockOpenAI() let contentPolicyParameter = ContentPolicyParameters( input: "I want to kill them." ) // When let contentPolicyResult = try await mockOpenAI.checkContentPolicy( parameters: contentPolicyParameter ) // Then XCTAssertEqual( contentPolicyResult.id, "modr-69OQBfTkTYrcLo7k3oL3PxmpkUeoL", "Content Policy ID doesn't match." ) XCTAssertEqual( contentPolicyResult.model, "text-moderation-003", "Content Policy Model doesn't match." ) XCTAssertFalse( contentPolicyResult.results.isEmpty, "Content Policy Result is empty." ) XCTAssertEqual( contentPolicyResult.results[0].flagged, true, "Content Policy Flag doesn't match." ) XCTAssertEqual( contentPolicyResult.results[0].categories.hate, true, "Content Policy Category doesn't match." ) XCTAssertEqual( contentPolicyResult.results[0].categoryScores.hate, 0.4068171977996826, "Content Policy Category Score doesn't match." ) } catch { XCTFail("CONTENT POLICY TEST FAILED WITH ERROR: \(error)") } } } ================================================ FILE: Tests/OpenAIKitTests/Types/Enums/MockOpenAIError.swift ================================================ // // File.swift // // // Copyright (c) 2023 OpenDive // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // enum MockOpenAIError: Error { case urlBundleFailed case dataCoersionFailed case dataCodingFailed case invalidUser case invalidPrompt case notImplemented } ================================================ FILE: Tests/Resources/JSON Responses/Completions/CompletionResponse.json ================================================ { "id": "cmpl-69nq0IKF1lwssd3QdLnz4fQ4yCt4O", "object": "text_completion", "created": 1667794548, "model": "text-davinci-002", "choices": [ { "text": "\n\nThis is a test", "index": 0, "logprobs": null, "finish_reason": "length" } ], "usage": { "prompt_tokens": 5, "completion_tokens": 6, "total_tokens": 11 } } ================================================ FILE: Tests/Resources/JSON Responses/Content Policy/ContentPolicyResponse.json ================================================ { "id": "modr-69OQBfTkTYrcLo7k3oL3PxmpkUeoL", "model": "text-moderation-003", "results": [ { "categories": { "hate": true, "hate/threatening": true, "self-harm": false, "sexual": false, "sexual/minors": false, "violence": true, "violence/graphic": false }, "category_scores": { "hate": 0.4068171977996826, "hate/threatening": 0.6911801695823669, "self-harm": 6.969435344217345e-05, "sexual": 0.00024072942323982716, "sexual/minors": 7.919080962892622e-05, "violence": 0.9743136763572693, "violence/graphic": 0.0014632269740104675 }, "flagged": true } ] } ================================================ FILE: Tests/Resources/JSON Responses/Delete File/DeleteFileResponse.json ================================================ { "id": "file-XjGxS3KTG0uNmNOK362iJua3", "object": "file", "deleted": true } ================================================ FILE: Tests/Resources/JSON Responses/Images/Embeddings/EmbeddingsResponse.json ================================================ { "object": "list", "data": [ { "object": "embedding", "index": 0, "embedding": [ 0.0028667077, 0.018867997, -0.030135695, -0.004034549, 0.024676088, -0.0030139843, -0.012645043, 0.0063681565, 0.007314046, -0.021091666, -0.004127893, 0.019979833, 0.020792965, 0.030384613, 0.01447874, -0.013682202, -0.007085871, -0.02077637, 0.026335543, 0.04732764, 0.13069864, 0.03191131, 0.005542578, -0.0015619616, -0.0035947934, -0.0041444874, -0.056686968, -0.0140887685, -0.036773514, -0.010512644, 0.008218449, 0.015764818, 0.00985716, -0.017789353, 0.012827584, -0.014196633, 0.032541905, -0.02314939, -0.002360574, -0.029123427, 0.0073970184, 0.01356604, 0.03547914, -0.020311723, -0.030285046, 0.02300004, -0.01150002, 0.032044068, -0.015565683, 0.024062091, -0.019730914, 0.008048355, -0.0030222815, 0.0001533699, 0.026335543, 0.040457502, 0.014080471, 0.027463973, 0.011275994, 0.060370956, 0.0026385328, -0.019266266, 0.028077971, 0.009649728, 0.027497161, 0.029057048, 0.01861908, 0.026219381, -0.008985946, 0.012346341, 0.0046049864, 0.011450237, 0.009052324, 0.025489222, 0.025406249, 0.008637461, -0.006413792, -0.02704911, 0.02266815, -0.0025223708, 0.022551987, -0.02756354, -0.007911449, 0.02457652, -0.004770932, -0.014470443, -0.018137839, 0.0022195205, -0.014636389, 0.029040454, 0.02358085, -0.029073643, -0.004239906, 0.004787526, 0.01934924, 0.029671047, 0.019432213, 0.06103474, -0.0001505177, 0.0013918675, 0.011748938, -0.006650264, 0.020162372, -0.0032753483, -0.02570495, -0.03161261, 0.010379888, 0.03172877, 0.008259935, 0.0020846897, 0.00611509, -0.018867997, -0.033471197, -0.0012103646, -0.022917068, 0.010047997, 0.042183332, 0.007928044, -0.038001508, 0.022170313, -0.007961233, -0.024178252, -0.03760324, -0.023813173, -0.0075920043, 0.01679368, 0.00035522698, 0.01971432, -0.021672476, 0.019083727, 0.0045012706, 0.018453134, 0.0246429, -0.017125571, -0.03401882, 0.020610426, 0.009965024, 0.017075786, 0.0063059274, -0.03245893, 0.014312795, 0.0038354143, -0.05074612, -0.019963238, 0.0121886935, -0.0419842, 0.015101036, 0.027231649, -0.0070319385, -0.013823256, 0.03976053, -0.02902386, -0.011632776, 0.019979833, 0.024360793, 0.023381714, -0.0033541725, -0.02318258, -0.001297486, 0.016071817, 0.0246429, -0.047360834, 0.011466831, 0.013350312, 0.0061773197, 0.009160189, -0.0029579776, 0.042880304, 0.028758347, -0.01648668, 0.019382428, 0.0006233326, 0.008720433, -0.007770396, 0.01828719, 0.032575093, 0.033902656, 0.036673944, 0.040689826, 0.00079290813, -0.0057002264, -0.019930048, 0.011599587, 0.0069863037, -0.04244885, -0.016768787, 0.013756878, -0.00014001648, 0.0048331614, -0.0052646194, 0.015026361, -0.057151612, 0.0023170135, 0.013989202, 0.0012923002, 0.0057334155, -0.057383936, -0.03114796, -0.03753686, -0.0072518163, 0.01989686, 0.01989686, -0.008164517, -0.004770932, -0.023531064, -0.028526023, 0.00173413, 0.020610426, -0.034549844, -0.0054347133, -0.008454921, -0.023896145, 0.0047833775, 0.023232363, -0.023813173, 0.035280004, -0.023431499, -0.005828834, 0.010164159, -0.02358085, 0.0021987772, -0.019415617, 0.0077952878, 0.008127178, -0.0313305, 0.0014852118, -0.006903331, -0.018867997, -0.022784311, 0.005165052, 0.008023462, 0.029073643, -0.003893495, 0.006625372, -0.015275279, -0.0035367124, 0.013507959, -0.025754735, -0.011159832, -0.009840566, 0.01700941, -0.050181903, 0.008554488, -0.0011470979, -0.030500773, -0.01617968, 0.024294414, -0.011616182, 0.02245242, -0.00026499413, 0.0071605463, 0.030716503, 0.0034454425, -0.008160368, -0.03730454, 0.044606138, -0.008297273, 0.009533566, 0.0014043134, 0.0191667, -0.008695542, 0.03401882, -0.011989559, 0.0014063877, -0.019681131, 0.028559212, 0.01646179, 0.044805273, 0.026368732, -0.01752384, -0.00049109483, 0.0011574696, -0.008318015, -0.0052106874, 0.06203041, 0.006766426, 0.016768787, -0.00438096, 0.0073513836, -0.011607884, -0.018336972, -0.00237302, 0.005040593, -0.029588073, -0.0067000478, -0.010944103, 0.05064655, 0.03806789, 0.010396482, -0.019100321, 0.034383897, 0.0050571878, -0.017407678, 0.005376633, 0.025505817, -0.02665084, 0.013491365, 0.004237832, 0.020510858, -0.010155861, 0.019697726, -0.004505419, 0.008417583, -0.0032546052, -0.003945353, -0.0017424272, 0.049650878, -0.014702767, -0.028343484, -0.01268653, -0.0073057488, -0.011483425, 0.0030658422, 0.039163128, -0.040125612, 0.0155159, -0.0099401325, -0.04819056, -0.008629164, -0.01104367, -0.010288618, 0.012213585, -0.0051152688, -0.026003653, -0.012387828, 0.012794394, -0.02387955, 0.044805273, 0.00593255, -0.0073264916, -0.0018907409, 0.019531779, 0.0129935285, -0.00012277371, 0.008994243, -0.017789353, 0.0003573013, -0.0070485333, -0.0133420145, 0.008927865, 0.010927508, -0.0047833775, -0.010927508, 0.015283576, 0.008471515, 0.0118982885, 0.0071149115, 0.01919989, 0.008226746, 0.018552702, 0.024228036, -0.0063391165, -0.009467188, 0.024593117, 0.012371234, 0.01609671, -0.01597225, 0.04155274, 0.013275636, 0.0255556, 0.0037980767, 0.010720076, 0.0057583074, -0.016544761, 0.001871035, -0.027795862, -0.016694112, -0.013001827, 0.0072601135, -0.019515185, -0.01432939, -0.015374846, 0.0076376395, -0.014155147, -0.015856087, 0.03264147, -0.027779268, -0.0154163325, 0.012396125, 0.02522371, -0.02522371, -0.009118702, 0.020792965, -0.026634244, -0.007890706, 0.020909127, 0.06730747, 0.0016179682, -0.014843821, -0.011491722, -0.011997856, -0.014603199, -0.00958335, 0.010661995, -0.0065341024, 0.0331559, -0.008911271, -0.012487396, 0.0050613363, -0.042216524, 0.0136905, -0.040888958, -0.019946644, 0.0025306682, -0.0062146573, 0.044207867, 0.0035885705, 0.00723937, 0.07202033, 0.0014032762, -0.00017644669, 0.032077257, 0.021075072, 0.03264147, -0.0019788996, -0.011300885, 0.019448807, 0.0057251183, -0.021290801, -0.028758347, 0.0067622773, -0.01865227, 0.01876843, 0.005882766, 0.012761205, -0.0020971356, -0.009865457, 0.0067581288, -0.012221882, 0.036673944, -0.018171027, -0.0059449957, -0.02957148, 0.0052853627, -0.004974215, 0.025837706, -0.008562786, -0.018751835, 0.02139037, 0.009326135, -0.026783597, -0.004009657, 0.005314403, 0.016204573, 0.020444479, 0.0076583824, 0.026601056, 0.035280004, -0.011466831, 0.017424272, 0.042249713, -0.013433284, -0.013980905, -0.0035968677, -0.0055508753, -0.0122467745, 0.023763388, 0.017175354, -0.00034615185, 0.005866172, -0.022419231, 0.0062063597, -0.04971726, -0.011815316, 0.032259796, 0.006969709, -0.018668864, -0.00739287, -0.02774608, -0.014702767, 0.027994998, 0.024211442, 0.037735995, -0.045402676, 0.0019498591, 0.0055135377, 0.015291873, -0.0041693794, 0.022717932, 0.0069531146, 0.0051360116, -0.010686887, 0.0060404143, -0.016403709, -0.020510858, 0.0046464726, 0.01661114, -0.019830482, -0.0015474414, -0.013806662, -0.00087328797, 0.038466156, -0.01989686, 0.007853368, -0.0037960021, -0.038632102, 0.010354997, 0.0063930484, -0.014254714, 0.022933662, -0.010081186, 0.03172877, -0.031645797, 0.020195562, -0.020975506, 0.014404065, -0.003976468, 0.016619436, -0.005235579, 0.022286475, -0.014652983, 0.0023916888, 0.0017351671, 0.023763388, -0.022485608, 0.028293699, -0.001356604, 0.018552702, 0.008977649, 0.01715876, -0.0036590972, 0.0322432, 0.015175711, 0.0031073287, 0.032575093, 0.009002541, 0.030434396, -0.012752908, -0.018901188, -0.007608599, 0.01737449, 0.022800906, -0.0003881568, 0.024725873, -0.03723816, 0.028243916, -0.019000754, 0.013068205, -0.048124183, -0.0062063597, -0.000007231754, -0.004903688, 0.007314046, 0.038432967, -0.011060264, -0.017324705, -0.13660629, -0.0015681845, 0.007558815, 0.046464726, 0.022120528, -0.03501449, -0.020328319, 0.014993171, -0.014935091, 0.019249672, 0.0069987494, 0.008355354, 0.01971432, 0.01880162, -0.017623408, -0.022867283, -0.00876192, 0.022983445, 0.012221882, -0.016362222, 0.014030688, 0.0020774296, 0.0037939278, -0.0034454425, 0.019764103, -0.031247528, -0.009093811, -0.01183191, 0.012437612, 0.0051857955, -0.014213228, -0.0061233873, 0.013126285, 0.03581103, 0.0034599628, 0.022883877, -0.0056421454, 0.0011242804, -0.0012819286, -0.04523673, 0.0050447416, -0.10753265, 0.035313193, -0.009757592, 0.025837706, -0.038798045, -0.021954583, -0.000019511555, -0.038200643, 0.057549883, -0.023116201, 0.00048668688, -0.003820894, -0.003945353, 0.005007404, 0.024211442, 0.028144348, 0.020278534, 0.031181151, -0.0018005081, 0.012346341, 0.0027609174, -0.0038457857, -0.0022921215, -0.018137839, 0.0090772165, 0.023630632, -0.020593831, -0.016196277, -0.0024539183, 0.0310318, -0.010446266, -0.0161216, -0.05472881, 0.0057209693, -0.013242447, 0.0071439515, -0.0023564254, 0.032375958, -0.011516615, 0.0077040177, -0.018502917, -0.015266982, -0.016528167, 0.005189944, 0.022485608, 0.00063474133, 0.019681131, -0.02333193, 0.0099982135, 0.008712136, 0.004920283, -0.020909127, -0.011184723, -0.027546946, -0.01843654, 0.0077247606, -0.01767319, -0.0099401325, 0.039959665, 0.021025289, 0.002960052, -0.03176196, -0.004405852, -0.016810274, 0.018785026, -0.005484497, 0.0067041963, -0.042581603, 0.022469014, 0.017772758, -0.008911271, 0.025356466, -0.0016916065, 0.02208734, -0.006127536, 0.0061067925, -0.0071149115, 0.017474055, 0.0036715432, 0.042050578, -0.0018108798, 0.0026717219, -0.012586962, -0.011417047, 0.036043353, 0.011450237, -0.01737449, -0.0029890924, 0.0059491443, 0.008878082, -0.016445193, -0.007816031, 0.010072889, 0.07613578, 0.017805947, 0.005849577, -0.0110934535, 0.04082258, -0.016478384, -0.014735956, 0.00093396177, 0.018834809, -0.0030471734, -0.03750367, 0.004505419, -0.0112096155, 0.010238835, 0.014677876, -0.0016190053, 0.004675513, -0.011051967, -0.011624479, 0.0072933026, -0.013084799, -0.04304625, -0.013159474, -0.029040454, -0.0029807952, 0.028990671, -0.043643653, -0.00035833847, -0.02314939, 0.0035035233, -0.029455317, -0.00027718078, -0.006841101, -0.00575001, -0.003976468, -0.0058786175, 0.020095995, -0.0070402357, 0.009060621, 0.008475664, -0.023315337, -0.016685816, -0.0048497557, 0.018967565, -0.0022091488, -0.022684744, 0.018818215, -0.020212157, 0.017357895, 0.013715392, -0.0048580533, -0.040590256, 0.038764857, 0.020394696, 0.027679702, -0.002263081, -0.004011731, 0.01773957, -0.004146562, 0.0013534926, 0.006364008, -0.01013097, -0.030699909, -0.016204573, 0.036275677, -0.028642185, 0.00459254, 0.028874509, 0.00483731, 0.011549803, 0.009782485, 0.011856803, -0.03322228, 0.003696435, 0.012296558, -0.00032722368, 0.028741753, 0.031114772, 0.007459248, -0.00061244244, -0.030218666, -0.012006153, -0.011516615, -0.002034906, 0.0120725315, -0.00200794, 0.014570011, -0.010811347, 0.021108262, 0.025605382, 0.01858589, 0.034848545, 0.018901188, 0.021937989, 0.022020962, 0.059640795, -0.0037462185, -0.0492858, -0.0028189984, -0.05731756, -0.009956727, 0.009691214, -0.036673944, 0.0054388624, 0.016295843, 0.0069157765, -0.0006337042, 0.012205288, 0.016528167, 0.000619184, 0.007372127, -0.020228751, -0.21041884, 0.047925048, 0.015656954, -0.025140736, 0.004314582, -0.019100321, 0.003905941, -0.0071937353, -0.01323415, -0.0012829658, -0.008085692, 0.024676088, -0.0010283432, 0.0151840085, -0.021075072, 0.006455278, 0.0061814683, 0.0005496943, 0.016229466, 0.00084580324, 0.002236115, -0.004820715, -0.019631347, -0.0016241911, 0.0077247606, -0.007052682, -0.0020763925, 0.0019508962, -0.0004993921, 0.001428168, 0.039295882, 0.0012840029, -0.0011470979, 0.044971216, 0.036275677, -0.01432939, -0.01661114, 0.0051111197, 0.024344198, 0.022037556, -0.010321807, -0.029305967, -0.041486364, -0.012802691, -0.0029683493, 0.01572333, -0.01843654, 0.00083335734, 0.0014738031, 0.036176108, 0.015466116, -0.007272559, -0.0013929047, -0.02643511, 0.009848863, 0.007152249, 0.026036842, 0.008595974, -0.010703482, 0.0110934535, 0.017391084, -0.01140875, -0.015366549, -0.015225495, 0.0025389653, -0.008496407, 0.014769145, 0.0028376672, -0.001838883, 0.006774723, -0.008434177, 0.0040386976, 0.00666271, -0.021008695, -0.009989916, 0.021556314, 0.013300528, 0.0014105364, 0.021241019, 0.021838421, 0.013474771, -0.018917782, 0.0016812349, 0.053102545, 0.01837016, -0.009981619, 0.021888206, 0.034848545, 0.0022050003, -0.006579737, -0.0019654164, -0.011641073, 0.024659494, -0.019913454, -0.0011906587, 0.022402637, 0.00006683194, -0.023614038, 0.014304498, 0.040656637, -0.0024145064, 0.0021033585, -0.0011201318, -0.042847116, -0.010968994, -0.027098892, -0.025721544, -0.032757632, -0.011848506, 0.0014323167, 0.0005079486, 0.039926477, -0.007567113, 0.10089484, -0.032591686, -0.051907737, 0.021075072, 0.01934924, 0.0031384435, 0.033338442, -0.027829053, -0.03866529, 0.0047045536, -0.0024601414, -0.029770615, 0.02902386, -0.009624836, -0.02409528, 0.029953154, -0.04158593, 0.017175354, -0.020461075, 0.0017040523, -0.009525269, -0.015167414, -0.006293481, -0.0043975543, -0.024676088, 0.023763388, -0.004119596, -0.021937989, 0.0076957205, -0.02260177, 0.020311723, -0.014337687, -0.008011017, 0.02354766, 0.013715392, 0.017590217, -0.0255556, -0.0145534165, 0.023381714, -0.0033873615, -0.0021106186, 0.023597443, -0.0078658145, 0.0035450098, 0.025588788, 0.011450237, -0.008927865, -0.01919989, 0.0191667, -0.031977687, -0.008392692, 0.0038291912, 0.0068286555, -0.00054762, 0.0029579776, 0.023697011, 0.0007311971, 0.005588213, 0.034516655, -0.015449521, 0.0072269244, 0.013449879, 0.006227103, 0.0026696476, -0.023381714, 0.01767319, -0.034251142, -0.006596332, 0.0072476678, 0.010794751, -0.022618365, -0.0014914348, 0.018785026, 0.0044805272, 0.009326135, 0.01341669, -0.023398308, -0.0088448925, 0.028592402, 0.030533964, 0.018303784, -0.013848148, 0.0026696476, 0.006102644, -0.03571146, 0.01752384, -0.040557068, -0.02427782, 0.008795109, 0.00041901227, -0.0059491443, -0.0012300707, 0.03264147, 0.01986367, -0.019697726, 0.020494264, 0.008255786, 0.016735598, -0.008803406, 0.016569654, -0.038499344, -0.0017216841, 0.0011989559, -0.03023526, 0.009317837, 0.010844535, 0.022103934, 0.013259042, 0.026003653, 0.025837706, 0.013159474, -0.05250514, 0.0063391165, -0.037005834, -0.023929333, -0.013549446, -0.003976468, -0.008176962, -0.004372663, 0.00391009, -0.029339155, -0.009923538, 0.004600838, -0.021788638, -0.033753306, 0.01487701, -0.015266982, -0.022634959, 0.01770638, 0.013798364, -0.013756878, 0.015432927, 0.021971177, 0.03292358, 0.03537957, 0.020743182, -0.017789353, 0.015988844, 0.012412719, 0.026451705, 0.009865457, 0.0032504566, -0.0054554567, -0.021655882, 0.052040495, -0.01657795, 0.032741036, 0.008483961, 0.01934924, -0.045900512, -0.011168129, -0.0074426536, 0.024327604, 0.04125404, 0.009848863, 0.036507998, 0.0021552166, -0.00775795, -0.002242338, -0.03581103, 0.038466156, 0.020212157, -0.01013097, -0.009749295, -0.006546548, -0.004994958, -0.017822541, 0.018253999, 0.02095891, 0.02062702, 0.0035325638, 0.0133835, 0.032691255, 0.009732701, 0.12651682, 0.03610973, -0.003526341, -0.0075007346, -0.031496447, 0.009906944, -0.006251995, 0.023630632, 0.0055508753, 0.01895097, -0.077264205, -0.01928286, -0.011757235, 0.023929333, 0.018237405, 0.014180039, -0.0014592828, 0.009375918, -0.0073513836, -0.047991425, 0.0120144505, -0.011765532, -0.033769898, -0.0043353247, 0.019697726, 0.012089126, -0.02628576, 0.038532533, 0.010628806, 0.0014084621, -0.00006456315, -0.007567113, 0.024891818, 0.018187622, -0.009525269, -0.013624121, 0.0022008514, 0.014038986, 0.0046298783, 0.04274755, 0.008160368, -0.006538251, 0.0057790503, -0.0121306125, -0.0061731706, -0.0099982135, 0.04377641, -0.021622693, -0.010330104, -0.035445947, 0.005148458, -0.014893604, -0.0020587607, 0.021705665, -0.00391009, -0.021191234, -0.040258367, -0.0048414585, -0.027497161, 0.018386757, -0.046331972, -0.045369487, 0.009118702, 0.0068120607, 0.023796577, -0.0029061197, -0.014628092, -0.005268768, 0.019100321, 0.022950256, 0.028227322, 0.015042955, 0.043278575, -0.008247489, 0.011475128, 0.012736313, -0.008027611, -0.034151573, 0.009160189, 0.012794394, 0.0018627377, -0.0014717288, -0.0032587538, -0.008280678, 0.00073534576, 0.01676049, -0.005907658, 0.006413792, 0.0003694879, -0.006409643, -0.03640843, -0.01861908, -0.0018990383, 0.027762674, 0.003395659, -0.02625257, 0.0022340408, 0.0052397274, 0.0074302074, 0.009093811, 0.026086625, -0.013856445, -0.007890706, 0.041718688, 0.0006570403, 0.011441939, -0.029820397, 0.021423558, -0.025057763, -0.037005834, -0.032989956, 0.037271347, 0.015930763, -0.00921827, -0.0041507105, 0.0013441582, -0.011234507, -0.025057763, -0.003957799, -0.03008591, -0.0071812896, 0.0005761419, 0.024311008, 0.017490651, 0.028874509, -0.014860415, 0.0027298026, -0.013059907, 0.008479812, -0.028774941, 0.0038250426, 0.029405534, -0.0027941065, -0.00091633, 0.013217555, -0.036308866, 0.0018098425, -0.015656954, 0.012097424, 0.008168665, 0.0459337, 0.020178966, -0.01168256, 0.023016633, 0.03806789, -0.00007033235, -0.012379531, 0.040125612, -0.005144309, 0.0121306125, 0.035445947, 0.008093989, 0.01213891, 0.030069316, 0.012172099, -0.005534281, 0.045369487, -0.03216023, 0.014445552, -0.0023419051, -0.03836659, -0.0004861683, -0.022684744, 0.035147246, -0.009450594, 0.0022485608, -0.027613323, 0.001519438, -0.0073638293, 0.017142165, -0.0022132974, -0.0060279686, -0.01013097, -0.004787526, 0.012752908, 0.028210727, -0.005281214, -0.0024476955, -0.026883163, -0.014719361, 0.0044307434, 0.030069316, 0.035246816, -0.022867283, 0.0035678272, -0.017789353, 0.019233078, 0.013491365, -0.0059864824, -0.0065175076, 0.011300885, 0.007890706, 0.023713605, 0.025671761, -0.0036985092, -0.016685816, 0.012279963, 0.020643614, 0.011599587, 0.024891818, -0.024510143, -0.012412719, 0.016171385, -0.003024356, -0.03221001, -0.000033286324, -0.011292588, -0.0037794076, 0.011466831, 0.07593664, 0.031778555, -0.03081607, -0.0070900195, 0.003182004, -0.027463973, 0.007264262, -0.004721148, -0.023265552, -0.009367621, 0.02358085, -0.025439437, -0.0014914348, 0.017772758, 0.0132258525, 0.0039826906, 0.003051322, -0.029521696, -0.049385365, 0.022485608, 0.011657668, 0.01150002, 0.0034578883, 0.012645043, 0.0021406964, -0.012105721, -0.020394696, 0.011259399, -0.015582278, 0.024908412, 0.017557029, -0.03793513, -0.006733237, 0.0039889137, -0.0038686034, -0.0031073287, -0.009525269, 0.008662352, 0.018486323, -0.0012549625, 0.0036466513, 0.00183266, 0.025057763, -0.008197705, -0.003428848, 0.023779983, 0.018386757, 0.03380309, 0.01657795, 0.005600659, -0.011508317, -0.019399023, 0.00012666306, 0.027596729, 0.030500773, -0.035611894, 0.002300419, -0.047659535, -0.013798364, -0.045834135, -0.01655306, 0.0022215948, -0.0058371313, 0.02972083, -0.008936163, 0.014586605, -0.015955655, 0.019598158, 0.009649728, -0.000032346397, -0.006148279, -0.033935845, 0.009292945, -0.010579023, -0.025539005, -0.004974215, 0.0071563977, 0.024028901, 0.014760848, -0.009533566, 0.0013078576, -0.0012269592, -0.0046049864, 0.042581603, 0.01700941, 0.013864743, -0.02026194, 0.043013062, -0.023763388, 0.013524555, 0.0029455319, 0.025140736, -0.02351447, -0.017208543, 0.0068701417, -0.025688356, -0.07082552, 0.008687245, -0.0067290883, -0.052704275, -0.024991386, 0.010960697, 0.020095995, -0.0002342683, -0.020129183, 0.03139688, 0.025140736, -0.042150144, 0.00014688766, 0.014254714, 0.005588213, -0.020942315, -0.018187622, 0.0017123496, -0.0018948896, -0.004088481, 0.014047283, -0.012371234, 0.029853586, -0.017391084, 0.013350312, -0.017905515, 0.025870897, 0.011168129, 0.012728016, 0.006944817, 0.041021716, -0.011491722, -0.0032006728, -0.009110405, -0.0038976439, -0.0038997182, -0.04115447, -0.0022941958, -0.019880265, 0.01049605, 0.012711422, -0.027812459, 0.02917321, 0.0010838312, 0.015225495, 0.0045095677, 0.0032649767, -0.03571146, -0.023016633, 0.0018865924, 0.025173925, 0.009425702, 0.019614752, 0.0038748262, 0.017075786, -0.015383143, -0.018088054, 0.013532852, 0.011342372, 0.004331176, 0.06438684, 0.011798722, -0.021406963, 0.0517086, -0.0124708, -0.005268768, -0.017507246, 0.01073667, 0.0133835, -0.024062091, -0.051774982, 0.02771289, -0.033355035, 0.0035906448, -0.027546946, -0.006853547, -0.0046215807, 0.0025472627, -0.01630414, 0.002178034, -0.018137839, -0.030467585, 0.0057997936, 0.027629917, 0.03245893, 0.0076625315, -0.0063059274, -0.011466831, 0.021191234, -0.007459248, -0.0077662473, 0.0007503846, -0.0035968677, -0.013897931, -0.0012684455, 0.00061503536, 0.010462861, -0.0124708, 0.011840208, 0.00949208, -0.0044348924, 0.018171027, 0.016752193, 0.0059781848, 0.0040055085, -0.004526162, 0.009010838, -0.0014426883, -0.06050371, 0.0011097603, 0.030899042, -0.047360834, -0.02084275, -0.020792965, 0.00011155942, 0.031894717, 0.0048829447, -0.0017590218, -0.03325547, 0.0322432, 0.040258367, -0.0013140806, -0.023481281, -0.0013120063, 0.006853547, 0.0237302, -0.004113373, -0.015764818, 0.018867997, 0.013756878, 0.012728016, 0.021241019, 0.009110405, -0.0033811387, -0.026767, 0.014105364, 0.0063474136, 0.014810632, 0.028924292, -0.007504883, 0.0072269244, 0.017606812, 0.012952043, -0.02734781, 0.019017348, 0.01557398, -0.019299457, -0.024875224, 0.0062105088, -0.024676088, -0.0109772915, -0.03260828, -0.0042689466, -0.00782018, 0.011624479, 0.0152420895, 0.008280678, -0.016171385, 0.014428957, -0.0097658895, 0.018270595, 0.038499344, 0.013275636, 0.021738853, 0.030915638, -0.019614752, 0.029671047, 0.03541276, 0.014644686, -0.014470443, 0.0060943468, 0.0048580533, -0.01876843, 0.025273493, -0.036242485, -0.0015049179, 0.025572194, -0.018685458, 0.013731986, -0.015441224, 0.01934924, 0.00046049862, 0.009906944, -0.0018969639, 0.0010267874, 0.0015816676, -0.038798045, 0.01296034, 0.0039930623, 0.010106078, 0.023979118, -0.026750406, -0.013839851, -0.004721148, -0.006579737, -0.0027298026, 0.0024331752, 0.05320211, 0.00092047866, -0.018005082, -0.046099648, -0.045469053, 0.004559351, 0.03157942, -0.009989916, -0.013267339, 0.010321807, 0.0020566864, 0.0063349674, 0.018021677, 0.0072269244, -0.008226746, 0.016694112, -0.01140875, 0.0034724085, 0.023497876, 0.002601195, -0.038831234, -0.017756164, 0.016586248, -0.027364405, -0.012827584, -0.008400989, 0.03793513, -0.019415617, 0.005990631, -0.018386757, -0.022253284, 0.007712315, -0.019233078, -0.01150002, -0.027447378, 0.080715865, 0.0002994797, 0.0012269592, 0.02333193, -0.022352852, -0.06136663, 0.019847076, 0.028509429, -0.007878261, 0.015648656, 0.012437612, 0.0026094923, 0.037437294, 0.029621264, 0.009326135, 0.026750406, -0.029671047, 0.0034433682, -0.025671761, -0.013159474, 0.02056064, 0.00030829554, 0.005849577, 0.011732344, -0.0066710073, -0.001303709, 0.006318373, 0.003657023, -0.0048995395, 0.0038872722, -0.02625257, 0.0072601135, 0.0013763101, 0.035114057, 0.028277105, 0.007438505, -0.028492834, -0.029803803, 0.021921394, -0.0037980767, -0.048588827, -0.03939545, 0.021489937, -0.013906229, 0.0087287305, 0.009359323, -0.018867997, 0.03547914, 0.0022651553, 0.0034744828, -0.0068369526, -0.025472626, -0.016378816, -0.011840208, -0.01949859, -0.013026718, -0.00015298097, 0.015706737, 0.013308825, -0.018735241, 0.031230934, 0.01752384, -0.013308825, -0.010628806, -0.0017766535, -0.03084926, -0.009143595, 0.0025534856, 0.0043519195, -0.009160189, 0.018785026, 0.05004915, 0.026700623, -0.027546946, 0.0030762139, 0.014312795, 0.006364008, -0.016022034, -0.025406249, -0.013267339, 0.0054803486, 0.027098892, -0.0154744135, -0.022734527, 0.021108262, -0.033504386, 0.015507602, -0.04115447, 0.01228826, 0.00030077613, -0.0219048, -0.006081901, -0.0034993747, 0.023116201, 0.006430386, -0.012429315, -0.049385365, -0.011292588, -0.016901545, -0.052737463, -0.0021261761, -0.008620867, 0.00088002946, 0.029256184, -0.015200604, 0.0058454284, -0.0069655604, -0.010247132, -0.004053218, -0.016619436, 0.024759062, 0.027480567, -0.040623445, 0.0069821547, -0.004484676, -0.00903573, 0.011242804, 0.012603557, -0.0118651, -0.0035781988, 0.027032515, -0.02117464, -0.0027173567, -0.017988486, -0.038598914, -0.020178966, -0.021091666, 0.01159129, -0.00045972076, -0.005189944, 0.010205645, 0.00047994536, -0.015922466, -0.011400453, -0.015491008, -0.042847116, -0.021772044, -0.020245345, 0.002014163, 0.023614038, -0.014976577, 0.022186907, 0.009409107, 0.010504347, 0.008886379, 0.040026043, 0.03015229, 0.009691214, -0.008620867, 0.013117988, -0.019996427, 0.00059999654, 0.019216483, -0.019316051, -0.0017590218, 0.029836992, 0.0005652517, -0.0064345347, 0.010645401, 0.020013021, -0.04271436, 0.03730454, 0.01934924, 0.012479098, -0.023979118, -0.014943388, 0.024410576, 0.01341669, -0.016685816, -0.01697622, 0.043477707, -0.00520239, -0.008828298, -0.010620509, -0.017424272, 0.006285184, -0.02275112, 0.0031052544, -0.03912994, 0.0310318, -0.009027433, 0.013001827, -0.0006114053, -0.016138196, -0.0011159831, 0.030202072, -0.01861908, 0.010695185, 0.0017828764, -0.00008874192, -0.014926793, 0.031977687, 0.0063847513, -0.007347235, 0.03368693, 0.0003954169, 0.0032234904, 0.0066544125, 0.018403351, 0.011599587, 0.0043602167, 0.0043602167, -0.003331355, 0.011143237, 0.03401882, -0.009898646, -0.05227282, -0.008936163, -0.050845686, -0.01232145, 0.006430386, -0.023348525, -0.027065704, -0.03932907, 0.003808448, 0.016412005, 0.012354639, -0.02865878, -0.03674032, 0.004903688, -0.0024954048, 0.04852245, 0.020394696, 0.024194848, -0.009873754, 0.011740641, -0.021108262, -0.011417047, 0.014843821, 0.0067581288, -0.008687245, -0.060072254, -0.011516615, -0.03856572, 0.0027878836, 0.021440152, 0.023431499, 0.009898646, 0.00918508, 0.008919568, -0.014370876, 0.0076210448, -0.022618365, -0.0025016277, -0.013914526, 0.0048912424, -0.0113257775, 0.010753266, 0.0025410398, -0.011881694, 0.0075712614, -0.008239192, 0.016735598, 0.010819644, -0.027596729, -0.0035221921, -0.038831234, 0.027845647, 0.004028326, -0.028210727, 0.014155147, 0.022286475, 0.0022527096, 0.023647226, 0.039528206, -0.01323415, 0.014138552, -0.0055384296, -0.0049327286, -0.009176783, 0.005745861, 0.042083766, -0.016080115, -0.004725297, -0.02260177, 0.02041129, -0.0035657529, -0.015549089, -0.008496407, 0.0052978084, -0.013117988, -0.0040386976, 0.0018897038, -0.010794751, -0.020444479, -0.023697011, -0.0024248778, -0.004273095, 0.011433641, 0.017540434, 0.036773514, 0.018204216, 0.027215054, 0.02175545, 0.022684744, 0.015109333, -0.008251637, -0.0056089563, 0.015507602, -0.013333717, -0.018917782, -0.007928044, 0.031629205, 0.010703482, -0.017722974, -0.0007197884, -0.0059698876, 0.05582405, 0.011425344, 0.007434356, -0.0027920322, -0.03327206, 0.01807146, -0.022717932, -0.015715035, 0.013997499, 0.017075786, -0.004113373, -0.014520227, -0.00438096, -0.00077735074, -0.024228036, -0.00048331614, 0.018403351, -0.003937056, 0.0022485608, 0.024028901, -0.020942315, 0.017905515, -0.010968994, 0.011217913, -0.00033189091, 0.01655306, 0.0036922863, -0.020544047, -0.034450278, 0.03428433, -0.012952043, 0.029554885, 0.024593117, -0.027414188, 0.02811116, -0.00046542514, 0.028874509, -0.0047999723, 0.0141468495, -0.0043062847, -0.013333717, 0.022834094, 0.018336972, -0.014287903, -0.035114057, 0.03312271, 0.011193021, -0.0012404423, 0.024078686, 0.034383897, 0.034052007, 0.005443011, -0.026302354, -0.017507246, 0.03206066, -0.02026194, -0.037404105, 0.0031571123, 0.012578665, 0.011300885, -0.02953829, -0.029505102, 0.010894319, 0.0028625592, -0.008475664, -0.02643511, -0.008927865, 0.0033603953, 0.000022509594, -0.012736313, 0.0313305, 0.029372346, -0.005534281, -0.026335543, -0.01837016, 0.020361507, -0.0130516095, 0.003084511, -0.005443011, 0.032259796, -0.005679483, -0.0032110445, 0.0003705251, -0.0034392194, 0.020361507, 0.0131096905, 0.024493549, -0.013939418, 0.0024663643, -0.042515226, -0.026783597, 0.042548414, -0.012645043, 0.008035908, 0.0058537256, 0.005646294, -0.018735241, 0.005281214, 0.013640716, 0.0040905555, 0.024476955, -0.0026115666, 0.017606812, 0.031795148, -0.005339295, 0.012628449, -0.013192664, -0.060769226, 0.004878796, 0.012869069, -0.016984517, -0.0056296997, 0.020178966, 0.032259796, -0.007948787, 0.012404422, 0.003005687, -0.008637461, 0.054330543, 0.009226567, 0.02114145, 0.020925721, -0.004177677, -0.015615467, -0.008131327 ] } ], "model": "text-similarity-babbage:001", "usage": { "prompt_tokens": 8, "total_tokens": 8 } } ================================================ FILE: Tests/Resources/JSON Responses/Images/NumberOfImages/ImageURL-1.json ================================================ { "created": 1667661280, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-byoTBAgSaGlyyTCGjnFhbSVx.png?st=2022-11-05T14%3A14%3A40Z&se=2022-11-05T16%3A14%3A40Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T02%3A20%3A52Z&ske=2022-11-06T02%3A20%3A52Z&sks=b&skv=2021-08-06&sig=Gb%2BBa63eW2kp8cZlD7Kmkz7BhtiRKmKgxnvds1mqA6A%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/NumberOfImages/ImageURL0.json ================================================ { "created": 1667661280, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-byoTBAgSaGlyyTCGjnFhbSVx.png?st=2022-11-05T14%3A14%3A40Z&se=2022-11-05T16%3A14%3A40Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T02%3A20%3A52Z&ske=2022-11-06T02%3A20%3A52Z&sks=b&skv=2021-08-06&sig=Gb%2BBa63eW2kp8cZlD7Kmkz7BhtiRKmKgxnvds1mqA6A%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/NumberOfImages/ImageURL1.json ================================================ { "created": 1667661280, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-byoTBAgSaGlyyTCGjnFhbSVx.png?st=2022-11-05T14%3A14%3A40Z&se=2022-11-05T16%3A14%3A40Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T02%3A20%3A52Z&ske=2022-11-06T02%3A20%3A52Z&sks=b&skv=2021-08-06&sig=Gb%2BBa63eW2kp8cZlD7Kmkz7BhtiRKmKgxnvds1mqA6A%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/NumberOfImages/ImageURL10.json ================================================ { "created": 1667676139, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-9zZUe6K4CTKwiFVtCTPhAEMK.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=GSG1TvHGYZkFBNMPF1mFj/IHW3Cv38qrEf5rOLjtKOE%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-TBCCe12ag8BHOfNqjU8tS9jy.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=73LhuURgM8VT8HxjOk8V5EFG9e/wSv%2BMcsKSqwtVv1c%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-1QFf5erj73pVtUrPRvKXyY0R.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=nKZcUc8OzsXsqCKHarzBSDqU%2By5lGVuvkzYjzatw7bs%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-JO5HiAWyRkmEF9mZVWN81WRw.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=X8XoFhNnqi0fJEI9qZtmp8Ig6XBC6Wz7bzCacbj%2BP7w%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-CIZdrniO1nbRSHRasJvhO5VI.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=gzvv2YGW/e0J9FKb1M1DoV%2BeEv8uWHFuHS3OebpbhsM%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-G7RFB3ZkcRFeeaWK5mn6CTAu.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=aYRcwd%2BvGRtVf75f8ABCL0zrzQxiVEjpwikQhhQ4EXA%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-T3PieacwGynP6zfeytLJoWZ5.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=78i4lL2P6Avm63VDro9ZSqs/tgHlDpJ2Tule3CQ7crg%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-CweooP1vUz9sMWdfTqqODIBa.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=ZtfKnYWzqRUttn3PPMUDDKxpSUm98mDCNbh1B1C8H/U%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-J1xND8faZLkSbBZxcknKXnfR.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=6aIeRYmy4Iv4LznnMmMqe0zSHP9GVQmASM5nm3LpR8k%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-kMEOILQHM0mPgnK9zOM1XOjc.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=rJIAe5Bw3InLynaIvZlPZPj%2BIS9SnA8wxSuRu3CA9DM%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/NumberOfImages/ImageURL11.json ================================================ { "created": 1667676139, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-9zZUe6K4CTKwiFVtCTPhAEMK.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=GSG1TvHGYZkFBNMPF1mFj/IHW3Cv38qrEf5rOLjtKOE%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-TBCCe12ag8BHOfNqjU8tS9jy.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=73LhuURgM8VT8HxjOk8V5EFG9e/wSv%2BMcsKSqwtVv1c%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-1QFf5erj73pVtUrPRvKXyY0R.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=nKZcUc8OzsXsqCKHarzBSDqU%2By5lGVuvkzYjzatw7bs%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-JO5HiAWyRkmEF9mZVWN81WRw.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=X8XoFhNnqi0fJEI9qZtmp8Ig6XBC6Wz7bzCacbj%2BP7w%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-CIZdrniO1nbRSHRasJvhO5VI.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=gzvv2YGW/e0J9FKb1M1DoV%2BeEv8uWHFuHS3OebpbhsM%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-G7RFB3ZkcRFeeaWK5mn6CTAu.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=aYRcwd%2BvGRtVf75f8ABCL0zrzQxiVEjpwikQhhQ4EXA%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-T3PieacwGynP6zfeytLJoWZ5.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=78i4lL2P6Avm63VDro9ZSqs/tgHlDpJ2Tule3CQ7crg%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-CweooP1vUz9sMWdfTqqODIBa.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=ZtfKnYWzqRUttn3PPMUDDKxpSUm98mDCNbh1B1C8H/U%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-J1xND8faZLkSbBZxcknKXnfR.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=6aIeRYmy4Iv4LznnMmMqe0zSHP9GVQmASM5nm3LpR8k%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-kMEOILQHM0mPgnK9zOM1XOjc.png?st=2022-11-05T18%3A22%3A19Z&se=2022-11-05T20%3A22%3A19Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A26%3A08Z&ske=2022-11-06T01%3A26%3A08Z&sks=b&skv=2021-08-06&sig=rJIAe5Bw3InLynaIvZlPZPj%2BIS9SnA8wxSuRu3CA9DM%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/NumberOfImages/ImageURL2.json ================================================ { "created": 1667676103, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-P3mDeKMbJ63GMw7fVozuEEYj.png?st=2022-11-05T18%3A21%3A43Z&se=2022-11-05T20%3A21%3A43Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T02%3A31%3A42Z&ske=2022-11-06T02%3A31%3A42Z&sks=b&skv=2021-08-06&sig=01gs1eE8/w%2BtLtIb4IzRLOmafbH4somfktvUNzB%2BUw0%3D" }, { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-pPmibgcYrjAmxDy9WMEVhchU.png?st=2022-11-05T18%3A21%3A43Z&se=2022-11-05T20%3A21%3A43Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T02%3A31%3A42Z&ske=2022-11-06T02%3A31%3A42Z&sks=b&skv=2021-08-06&sig=YVgHqL0%2BO%2BHqcvrbvvEPrx0/C2cGmHpCFKbF0YLGbYc%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/Prompt/ImageApple.json ================================================ { "created": 1667676516, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-nsJnMAwG1wUsEx5kem6LWGvJ.png?st=2022-11-05T18%3A28%3A36Z&se=2022-11-05T20%3A28%3A36Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A38%3A29Z&ske=2022-11-06T01%3A38%3A29Z&sks=b&skv=2021-08-06&sig=vcMLSEIudZIXGC5Zl2PlCkDehCLllTGrj99V06oAjGw%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/Prompt/ImageOtter.json ================================================ { "created": 1667661280, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-byoTBAgSaGlyyTCGjnFhbSVx.png?st=2022-11-05T14%3A14%3A40Z&se=2022-11-05T16%3A14%3A40Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T02%3A20%3A52Z&ske=2022-11-06T02%3A20%3A52Z&sks=b&skv=2021-08-06&sig=Gb%2BBa63eW2kp8cZlD7Kmkz7BhtiRKmKgxnvds1mqA6A%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/Resolution/Large/ImageB64Large.json ================================================ { "created": 1667674929, "data": [ { "b64_json": "+BAEDAf7+/vv//gYAAQAB/gID/v38AgAA/v/+Af8BBPwA/AIAAwIB/wD++v3+AAAA/gH/A/3//P8A/v7/AwEGAAAEAgP//Pr7AwQG/f7+/fj6/QP8/wIIAQD+Afn8/AMAAv8CAQEA/fz//wH/AQEAwMDAP8ABf8A/QD+/fv5AgQD/f4DBAIA/v4C/QD9/v//BP8DAgT+/vsC/gD8AAEE/v/9AgAE/wH++P3/BAcDAvz++f39AvwFAAD+Av7/+fb98e/zAAQD8gABDgH9BggFAgMC/wD+A/4EAP/9+vv7/QH+//35AQEB//8BCAkD9vn9/f//BAMCBAP/AQH+/QECBgIC/P/9/v39BAH//AABAQICA/8A/wX/AP8GAQECAgH//gH9Af//Av4DAgYC9/r5AwEBBgID//0B/gL9APwEAAP//wH/AwABAQEEAQUC/Pn/BQUD+f3+////AwACBQMG/P/7/wIBBf4A/QQA9fL3/fr4CQIAIBsc6Ofp7+72AwIE4eDm8u70AwoEFhkQAQAAAwMI7O3yFhv+APT51tXdExoODPwC/v0B/f//8fLxAf//DAkC/v77BAEL/gf8BQEFBAgGBgUNAgEEBAT/+fr9BAMC/fv+/wP+/AQECwgK/fz+/f3+AAEEBAIA/f8ABAECAgMD/gAB/vv+/QD8AAAEAQAA+Pn7BAUCAQQC//8A/fj9BQABAgIA/QUBBAEIBgj++vz8Av38/wYF/fwABAH/+v37+vb4+fP7/PsB/vv57+76Bf0IAwgDBgEBCQgLBQcF/fz6AQIB/f/8AwMH/Pr78vb1BQQF+gH8CQMF///6/f8BAQAD/wMEAwD+9/b4BQL/AwgFAQECAf8B/wAB/v39/P0AAgMAAQH/AQAB/wMAAQABAAQEBQMEBwQIAv4BAAIE/P3/AgAFAf8CAwIB+fv5AQUFBQgGAwIB+vf3AAUE/gIFAv4A/wEAAAAAAwMF/wL+/vn/BAcD/gAC/v36/P8A/gIBBQAGAwgBAP8B/P38A/8AAgYC//j/AwD7+wAG/gIABAAB/wEABgIC/QAB/wICAAH9/gUH/wT9//j8Af8D/Pv+AQQCAP77/QAC/f398vb0BwcFAAD8+vz9/vv/Cg0J9fD1/vn57/4ACgoH9/j3AP7+AQL/+vgADBMR/fv7+vj4BgYK+f7/9/byBAIQBQMC+//9+/z8AfwBAwQD/Pv6/wL/AwQC//z/9fv1//r+BQMEAAD9CggK8/PxBAQGBAUD/wH+Af0B+/36/v/8AgEE/f38AP/+//3///wAAAQC+/v8AP4DAwUHBAAF/gADAf/9AP3+/f388/MACQsKCQ7++fX4/wEEAgME+vb5Av4DCgVQvZMAAAXcSURBVAkE///+9vjyDAoTAAP+A/4DBP4BExAO9ff3+/n/9vj4AAD2GRkR3eHx9gEE/ggI7vP3A/j4DAQECA4RDA0C9fXr+fn9Cv8F7vLuAwMDBgQD8/Hz9fP1+Pn5BwUI+f3/+/8ABgUE/QEDAQIDBQEJ+Pv5CAcD+vf8BwgC+vX98vnyBf0CBg0E/PwAA/8D/v/9AwT+/f8EAv368vTyCwcLAPr3CgUFBBEMAgUH/v788fH0CQwF9PXz+vfzCAoNDQ8QDA4P9fX2/f375ebkDAsLCxIT+vv9/P37CgkNBwsMAQICAv4E5eDb9fXz+vn47uzmBAMKCQwQIygl+v4A6eXkA/z5DAMC+vr3DhcZ8fLw8/DzCQYHBf8F8u/r+fj7/QoL/vv5/Pf28/3//vf3Eg4L/Pn3CQUCAP8B+/b3/AAAAwMJAAP9/v7+/vjx8fD08vX1APwE+QUG2u7vCgYJAwYF/gME+f/7AfLvAgH+BgUBEBMPC/gH9vf67urx+Pv0CAgR+fz8/f4AA/79BwkG//kA/Pf8/f729/n98/Dy9fz6+gAA+v3/8OvsDxELAPwB2Nve8/P4AgQE+Pz5GRcT+vv4Af0B8fHz//v7CgYF7ejjCgT7/Pf0CQEA+PX2EBELERUVBAMD///+BgME+AML+v0A8/T0BwIBAgD8AgL8CwoJ/v/8CQECDwgO/fsA6OvmCgUHCQ0GBf0A9vPy+Pj2CQwLCAoHAgUE/vkH+vz89vX3BfsJAwcJAv0A+/z59fX0CwoJCQgJ+v76+vT2+/MA9fP5+voE7vD3+PkAAwcB7uvrCAwGCwwM/f0B//wD/P79AwP9AAH++Pv6/vv5/v8AAwYABAYGAAT/+Pf3AwIG/QH+AgIB/P//DhISAQAB/fj7BAsDCgcLCgj9+/8B/v36AgEI/gD59fr9AQEA9vX1AAD7EAsJCgkBBP/8/v38/P7/+v369PT1//v7/AX7//oDAQX+//sC/P0DAQMGEBMK9vkDBQT/BgIFBQUG/QL+AwP+CwkLCQsDAP79/vn9/wQFAwH//QADAgYEAgH9APwA+fz59/b+/Pv/CAYFBQYDAgEBAP0F/fr39PH0//0A//8A+/X0/gMCBhQV9PTyBQgL/PD08fP1+QcHAv789Pj4BQgD7+/tAAIBCAgHBQcE9vr6BwUABgL//AEFBAsFAQP+/f38+/7/FAsS+f75//8BAgMF+QIC/fj6AwQEBQkIAP4ABgsI9fr8AwUF9vj3AQYHBwYJ7e/0+Pv/CwgF+vn3//gDAwEBCQoL+/v4DQsK4eTkA/z/BgwN9vb4/Pz6EhIS8fXv//v8BPgE/gDxAgAB/P8CCAYM9vn1DgsNBgkK7vHx8vHvBgMIAfkJ+Pv7+fz6BQ8KCwEMFhcZ9/Hu+ffx9PYE6OfpDw0Q+fLv/f/8Dg8M+fv1/Pn9+vv9AQb/8vb6/P389wMJ+vj09PTv9fHz+/n3AQsJ9fD2/wEA9fX3/fv7/wEACQwLFRIT+Pv99vX0+fsBAwD/Av//CAEGAQEBDQ8IAgIGAwAD8e7vBQcJBAQE+/v3AwMFCQYJ+ff++vz5BfoFAwEA5+vq8/H3//z/+Pj4CQgIBAQAGRcQ/f4B8/TyCQQKBgQE9PX2//wB8fnyDhIQ9fT18PDvDg4L9PHy7u/6+voA8/H0CggN6vLq7fDvA/4CGCUT7uz0+/72AAIDEhca+PX1+/n/AwUBDQgN9fj5+ff6+/r8/v8B7+zvBwwCFRoX9PH4+fb1DAgJ9Qr5/v0A8/rz/vj4+vn2BAYDEBIPBwkF+fr47O7s8vXu+fz7BQQE9Pj3AQYF///+BwsICQsJJyQo2dbaAQH/9fT27/LzHh0c9PT2//vyFBIU6/n5BAMEBgT/FBMQ6ejn8/L3EBYAAP8DB" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/Resolution/Large/ImageURLLarge.json ================================================ { "created": 1667674848, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-8cl5NT9LdOxfxtb50M3SoMtg.png?st=2022-11-05T18%3A00%3A48Z&se=2022-11-05T20%3A00%3A48Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T00%3A57%3A59Z&ske=2022-11-06T00%3A57%3A59Z&sks=b&skv=2021-08-06&sig=mlcctWBT0JdMKoa2bvqoFtMqSrleUTESgJkYljxPlEg%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/Resolution/Medium/ImageB64Medium.json ================================================ { "created": 1667674568, "data": [ { "b64_json": "+/v/7AP0CAwL+9/3x8vL3+PoFBQr+Afj8AgEB/wEFAAMAAwcIBwUCBRMQAwMDBQMBAwf+/wH8AQAA/f/++/wDBAL+/v78+/kEAwIICAr//vsGBwf+/v8EAgINDw/+/wH59/f5+/n//v//A///AgMCAAACBggOExgA/vwDAgIIDxP/BAX3+vsCAQQBAf//Af8BAgL+/fz/AAABAP8BAQMDAwIA/wD+AP4C/wAA/QD/AP4EAQT7Avn/AP8EBQMGAwT9AP7//v79AQAEAwf8/vsFAgX7APj7+PwDCgYGBQcCAwT//v0CAAD9/wADAwQAAAAEAgIBBgH//gL//////wADAgAEBQMD/gL3/PkA//7+/QAAAQcGAwX+Afr9+/0BBQb8/P4AAQIDBQT///8BAgIA/wH++/4CBgQDBAMBAAD7/P0BAAH//v7+AQECAAL+/f7/AwD7+fwB/PwEBP4IBAYCAgL8+/38/fkFAQYCAgMB/v7+/fv+AgAB/QD+AP8CAQL+Af///P39/f3+/v8D//v+/wMCAgD+//r6AQEEBQP9//79/v79+vwBBQUFBQD9/gD8/Pv6+fv+AP3+/P4FBgL+///+/v4CAAH9/vz//f8CAgEB///+AAEBAf//AQAD/wD//v/+/f38/Pv9/QH8/f0EAgACAP///f/+AgL/AAABAv8A/wECAP//AAL//wAB/gABAwEA/v/+AQAA/P4BAQEAAwIE/gD+AAAA/v/9//8ABP8CAwEBAAD+Af7//gEAAAIC/f//AwICAAEC/fz+AwD//f/8AgID/v/8/wAB/wEAAQEB/v/+AQAA//4AAAEBBQAB/gD//wAAAAEC//79AQEA/gABAwD//v7/AAABAQABAAEAAP7+/wAAAgIC/v3+AAL//v//AgEC/gAAAQEB/gD/AwEC/v//AQAB//8BAgEA/v///wABAv//AQIC/////wH/AwAB/v//AwID/v39AAEBAAABAAAA///9AP8CAgIAAAH+Av8E/wEA//39AQP+/QABAf4F/gD+Av0BAQD/AQEA/gAAAP8BAQABBgMB+/v8/gAAAgED/v8AAQH//gD+AAD/Af4C/wEBAAEAAQD/Af4A/wL/AgAFAAD9/wEBAAAAAwIA/f4BAgAA/wEB/v3+AQEAAAAAAAAA/v3+AQIC/wEB/f/9BAAC/wEBAQEAAf7//wD//P8AAwAAAAIAAgEC/v//AAH//gAAA//9//8BAAL/AP//AAIBAP4BAQIC/wD/AP7+AAEA/wD/AP////7+AgIEAAH+AP/+/wEBAQAB/v//AQH+AgEB//3//wD/AP4BAAEBAgL/AAH+/f0AAQEA/wEBAQAAAAEDAAH9AQEC/gD+AgEB/wH/AwAD/v///////QD+AgECAP8AAAEAAQEA/wAAAQICAQEBAP///wD//wAAAAH+/wD/AP4BAQEC/wL+/v8BAgD+AQEBAQEB/wD9AQEDAv79/v//AAEBAgIE///+/wEBAQEA/wH9AQECAf8BAAEB/v7+AP0BAQEA////+fn5AgIE/v7//wH/AAAAAgACAP4BAgAA/gAB+/z8/wICAQEB/f3//wD+AAAD/f/+AQD/AAEBAwEE/v7+AAAD///9AwME/////QAA/wL+AP4B/v///gMCAgAE/wQB/QEC/v0AAQAAAQADAgIB//7/AP8A/wD9/QAAAAICAQAC/v3+/wD//fz9//8ABQIEBgoCAQD///7+/f3/AwUAAQEB/fr9/QD+AwMC/wAA///+AQEA/f7//wH9BP8DAgIBAQMDAQIEBAIB/v4B+vr/+//9Af8A/wEB/wD9Af0CAQMBAAL//vz+AQMC/wH//v7+AAP/+vz+AwL//v4ABAACAAD+AAAA/gEAAf////8B/fv7AQMFAP8A/P/8AQD/AwMDAP//AQEDAP/9//79AQIB/f3+BAT/AAMB+/v5+vz+AQEAAwICAQIAAQEA/Pv8/QABAAD9AP8D/gL////+/wD+/v7+AP7/+/4BAwMBAQMBAgACAwUDAf0CAf/++/37CAMGAAMC/P78//39/v3/AQD/AAID//z98ezr/fn4CQUE/gMDAwECBQUGAgUGBwoNBgkJAQIA/v0C+/37/f/8////Af/+//77BAIJ/P39AgEACAcF/v/+AAEDAwIDBwcGBQQDBwcH/v7++fX9//z8//7/AAIFAv8AAgQGCgsPFhwkDg8R/v79BwoPAwYJAQICAQIB/fz7//z8/v8BAP8ABAME/v/9AQEB/f8BAgD/AP8CAAAABwcE/wH+Af8AAvwA+/v8/wIC/gAA/v7+AgEDBQcGBwkJ+vz7/fz+Av/7Avz9/f8ABQICAgED/gH/AQcDAfz9+Pj4BAUEBAQFAf0A+v37+/z7AAABCgoKAgACAQAADAsKAgIC9/f5AgD+AgIDAQEA/v4A+/0AAwUFAP/+AAABAAEB//7/BQUEAAD/+/v7BAIDAgQEAgH/Af4B/f39AQD/AgQBAgEFAfwC+QL3/fz9AgME/wEA+/v9/v38BAMHAgEC/wIBBQAE+v39/fv6AQIDAgEC/QD+AP4B//7+/v3+/P36AQME//4AAP4DAwMAAgAA/Pz+AAEAAf8C+f78BPz///7/AQEA+/v8/f39/v/8/v4ABAYI/wMEA/z7/wMD/Pz8/f39/v8BAwMC//0AAQEEAwMBAgQB/Pr6+Pj4AQIB+/z8Af/8BP///v4BAQH/Av8A//4BAQD9/v8B/gIDAf/9/gAAAAD/Af0CAf8AAv0AAQMCAAMBAv8C/wD///8AAQMCAQEBAAD//v7/AgMAAAACAAEAAAD/AAEBAv/+/wAB/wMCAf7+AAACAP8A/gH/AwACAP8A/wH+/gECAAD+//8AAAIBAP7//wEA/wD/AgAA/wEBAQABAAIBAf7//v8AAAEBAf7/AAD+/gABAv/+/v79//8BAP//AAICAf7+/wEAAAEBAf7//f7+/wECAwAAAAEAAP///gABAQL/AAEAAQD+/wAAAAD/AP8A/wIA//0B/wL+AP4BAAMBAQEAAP/+/wEBAP39/gEB/wEEAAIA/gAAAQD/AAMCAv7+/QEBAP8BAf//AP7+AAIBAP3//gEBAPz+/QEEAgP+/v0A/wAB/v/+AQAB/wEBAv4AAAD9/wEBAP//AP0A/wMAAQIA//8AAv79/gABAAABAgEC/f8AAgD+/wEBAgAB/wACAQH9AP8B//7//gP/AQMBAf8AAf///gABAv4BAQIAAQP/AAABAAEBBP8A/wH//wECAgH9AAAC" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/Resolution/Medium/ImageURLMedium.json ================================================ { "created": 1667674510, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-euW0HHRIAcFPddYSrH88KT5m.png?st=2022-11-05T17%3A55%3A10Z&se=2022-11-05T19%3A55%3A10Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T01%3A59%3A18Z&ske=2022-11-06T01%3A59%3A18Z&sks=b&skv=2021-08-06&sig=MKT7ppV/JsOoB1%2BqdLhW4NUliwk3emt2TVZHzKxyPsE%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/Resolution/Small/ImageB64Small.json ================================================ { "created": 1667615111, "data": [ { "b64_json": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAaGVYSWZNTQAqAAAACAACknwAAgAAACkAAAAmkoYAAgAAABgAAABQAAAAAE9wZW5BSS0tMzA4ZTg2NzZiNWMwMjE4OTE4NmViMGNhYTRmOTViYzgAAE1hZGUgd2l0aCBPcGVuQUkgREFMTC1FAC/8JS8AAQAASURBVHgBACuB1H4BQiIkAAEBAAAAAAAAAQEBAAAAAQABAAAAAAAB/wAAAAEBAP8A/wD/AAEAAAAAAAAA//8AAAEAAP8BAAEAAf8BAAEAAQAB/wEAAAAAAQEAAP8AAAABAAD/AAABAAEAAP8AAAIBAQAAAAD///8AAAAAAP8AAQEA/wAAAP8AAAEAAP8AAAEAAAAAAQEBAAAAAQAB/wEAAQABAAD//wD/AAAAAQAAAAABAAABAAD+/wEAAQABAP8AAQEB/wD/AQAA/wABAAH//wABAAAA/wEAAQABAAEBAQEAAAABAQICAgIBAgECAAEBAAAA/////v8A//7////9/v//AP//AAABAQIBAgECAQEBAgMDAgMCAwQDAQEBAQEBAwMCAAAAAQECAAD//////f39/vz9/wD//vz+/v79/v//////AQAAAQEBAQAAAgICAQIAAQD/AAAAAAAAAAAAAQEB/wAAAP//AAAA/////v7/AAEBAgIBAQAAAQEAAQEBAQEAAQEAAgICAgICAQEA/wD///79/f3//f38/v7///8AAgD+AgEBAwMCBAICAwQDBAMDAQEBAgEAAAAAAP8A/////v7+//7+/v/+AQAAAAD/AAH/AgEAAgICBAIDAQIBAQEAAQAA//////4A/f79+/z9/QAB/f38/fz+AP8A/wEAAAAAAQIBAwMBBAQCBgUEBgUFBQYEBAMEBAMDAQIBAQEB/v/+/f38/f39AQEAAwICBQUECAcEBwYEBAICAQEA/f7++/z9+/v++/v7/fz++fr5+fj4/Pz7+/v7+/z8+vn8+vv7/f39Af//AAD/AgIBBgUDCAYFBwcDBgQEBAMBAQEAAP8A/v////8A/wD//v///f3//P39+/38+/v9/v7+AAD/AgEBBAMBBAQBBAIBBgUEBQQDAgIAAQD/AgEB//8AAP8A/Pz8/v7+/f7+/v8A////AAAAAAEAAQEAAQAAAAD/AgEBAQEAAP///gD///7//f3++/z9/P3//P3//P4A/f///v7//wH//v//BAECAgEBAQABAAD/AAEBAAABAQD/AAAAAAAAAQEAAQAAAAABAP8AAAEBAf//Af8A/gEBAQAAAAAAAAABAAEBAQABAQD/AAECAQD/AAABAQABAAAA/wD/Af8BAAEAAAABAAEBAf8AAAH/Af8B/wEAAAABAAAAAAH/AAACAAAA/wABAQAAAAABAQEAAAEBAQAA/wAAAAAAAAAAAQIAAf8BAAD//wAAAQAAAAAAAgIAAP8BAQEBAAD//wAAAf8AAAABAAD/AQACAQAAAAAAAP8BAQEAAf//AAEAAQD/AP//AP4A/wD/AAAAAP8AAP8A//8A//4AAQAAAP8BAQIAAQEAAQABAQABAQABAAACAgAAAQABAQECAgACAwEBAQEAAP7//wAA/wECAAAD///8/v4A//7/Af3+/gD/////AAEA/wEBAQH//wH+AAAA//8A/wH///8AAAICAQH/AQAB//8AAQD///3+/wAA/wICAgAAAAIAAAECAP///wD//gABAQMCAQEC////Af7//v/////+/////wD//wAAAAMCAf7+//0C/gT+Af0CAAECAAEAAQABAAAA/wD/AP/////+//////8A/v///gEA/wEAAAICAQMC/QICAgMCAQAAAAAAAP3+/v3+//7///7+//z9//7/AP7+/gEAAf///wECAf8AAQABAAEB/gEB/gAB/v/+//7//gIBAQABAP7//v7//v39/wAAAAIC/f7/AAAA/v/+/QQEAwICAP7+//v7/fn6/Pn4+fv8/f38/P7+//3+////AP/+Af7/AP//Af/+Af7//wAAAP8AAP3/Af3/AP7+AP////7//gIAAf//AP////8AAP///wD+AP///v///f/+/v8A/v7///////4B////AAAAAgADAQIC/QIBAf4AAAEAAAIBAAD/AP7+//z+//3+//7+//8AAP7+/wEBAAIAAQD//wICAgEBAQACAQAAAAAA/wD+/v7+/v39//7+//7/AP//AP7+/f/+AP8AAAEBAf///wQCAgEBAQIBAAH/Af8AAAAAAAABAgEAAP8BAAL/AAEBAAD/AAAAAAD/AQAB/wAAAAP/AP8BAAD/AAEBAAEAAAEAAAAAAgAAAQEBAQD//wAAAQAA/wEAAAD/AP8AAAEBAAD/AAACAAAAAgAD/wH/AAABAAAAAAAA//8AAQEAAAEAAP8AAAEAAP8BAQEAAAD/AQECAAAA/wAAAQH/AP8B/wAAAQEAAP8A/wEAAgAA/wABAQEA/wAAAgAB/wEBAQD+AAAAAQAB/wEAAgABAAAAAAH/AQABAAAAAQEAAgIBAAEAAAEAAQAAAAAB/wD///8AAQECAAH/Af8BAAAAAQEAAQH/AAABAgIAAQIBAQIAAgMBAgEBAgIBAgIBAAEBAAAAAP4AAAH/AQAAAAL/Af//AAL+AP0AAAH/AAD/AP7/AAEA/wAB/v8CAQH/AP8AAP/+//8A//8D/wIAAAD/AP4A/wH///8AAAD/AAD9/v0AAQAA/wABAQD///8AAAEBAP8AAQEAAQAAAP4AAAAAAAAA/wEAAQAA/gEBAQD//gH+Af8C/wD9//4DAgACAQEAAP8AAQAA/wAAAP8A////////////AP7///////4AAP8DAQEDAv8CAv8CAQEBAQH/AAD/AP8A///+///9/v/9/v/+/v/+/gAAAf8A//8A/wAAAgEA/gEA/f//Af79//0EBQED/wIDAgIBAQD/AP/+/v79/f3//v8CAQD9Av79/AD7BAMDBAIDAQL/AP/7/P37+/z7+vz7/P3//v7//v3+/gD+/wH+/wD+/wD+/v/9/wD//gH/AP8DAP/+/v7+///+///+/v0CAQH9Af8AAAH///7//wH//v79/wD+/v/+/gD+///+/v///v7/AP/+/gD/Af/+//79/QH/AAD+/wAD/QEBAQEBAQD+/v///v/////9/v7///7+/wAA//8BAgH+AAACAQAAAf8C/wL9AAACAQEA////AAH+/gD+/wD+AAH+AAD+Af//A" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/Resolution/Small/ImageURLSmall.json ================================================ { "created": 1667661280, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-byoTBAgSaGlyyTCGjnFhbSVx.png?st=2022-11-05T14%3A14%3A40Z&se=2022-11-05T16%3A14%3A40Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T02%3A20%3A52Z&ske=2022-11-06T02%3A20%3A52Z&sks=b&skv=2021-08-06&sig=Gb%2BBa63eW2kp8cZlD7Kmkz7BhtiRKmKgxnvds1mqA6A%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/ResponseFormat/ImageB64.json ================================================ { "created": 1667615111, "data": [ { "b64_json": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAAAaGVYSWZNTQAqAAAACAACknwAAgAAACkAAAAmkoYAAgAAABgAAABQAAAAAE9wZW5BSS0tMzA4ZTg2NzZiNWMwMjE4OTE4NmViMGNhYTRmOTViYzgAAE1hZGUgd2l0aCBPcGVuQUkgREFMTC1FAC/8JS8AAQAASURBVHgBACuB1H4BQiIkAAEBAAAAAAAAAQEBAAAAAQABAAAAAAAB/wAAAAEBAP8A/wD/AAEAAAAAAAAA//8AAAEAAP8BAAEAAf8BAAEAAQAB/wEAAAAAAQEAAP8AAAABAAD/AAABAAEAAP8AAAIBAQAAAAD///8AAAAAAP8AAQEA/wAAAP8AAAEAAP8AAAEAAAAAAQEBAAAAAQAB/wEAAQABAAD//wD/AAAAAQAAAAABAAABAAD+/wEAAQABAP8AAQEB/wD/AQAA/wABAAH//wABAAAA/wEAAQABAAEBAQEAAAABAQICAgIBAgECAAEBAAAA/////v8A//7////9/v//AP//AAABAQIBAgECAQEBAgMDAgMCAwQDAQEBAQEBAwMCAAAAAQECAAD//////f39/vz9/wD//vz+/v79/v//////AQAAAQEBAQAAAgICAQIAAQD/AAAAAAAAAAAAAQEB/wAAAP//AAAA/////v7/AAEBAgIBAQAAAQEAAQEBAQEAAQEAAgICAgICAQEA/wD///79/f3//f38/v7///8AAgD+AgEBAwMCBAICAwQDBAMDAQEBAgEAAAAAAP8A/////v7+//7+/v/+AQAAAAD/AAH/AgEAAgICBAIDAQIBAQEAAQAA//////4A/f79+/z9/QAB/f38/fz+AP8A/wEAAAAAAQIBAwMBBAQCBgUEBgUFBQYEBAMEBAMDAQIBAQEB/v/+/f38/f39AQEAAwICBQUECAcEBwYEBAICAQEA/f7++/z9+/v++/v7/fz++fr5+fj4/Pz7+/v7+/z8+vn8+vv7/f39Af//AAD/AgIBBgUDCAYFBwcDBgQEBAMBAQEAAP8A/v////8A/wD//v///f3//P39+/38+/v9/v7+AAD/AgEBBAMBBAQBBAIBBgUEBQQDAgIAAQD/AgEB//8AAP8A/Pz8/v7+/f7+/v8A////AAAAAAEAAQEAAQAAAAD/AgEBAQEAAP///gD///7//f3++/z9/P3//P3//P4A/f///v7//wH//v//BAECAgEBAQABAAD/AAEBAAABAQD/AAAAAAAAAQEAAQAAAAABAP8AAAEBAf//Af8A/gEBAQAAAAAAAAABAAEBAQABAQD/AAECAQD/AAABAQABAAAA/wD/Af8BAAEAAAABAAEBAf8AAAH/Af8B/wEAAAABAAAAAAH/AAACAAAA/wABAQAAAAABAQEAAAEBAQAA/wAAAAAAAAAAAQIAAf8BAAD//wAAAQAAAAAAAgIAAP8BAQEBAAD//wAAAf8AAAABAAD/AQACAQAAAAAAAP8BAQEAAf//AAEAAQD/AP//AP4A/wD/AAAAAP8AAP8A//8A//4AAQAAAP8BAQIAAQEAAQABAQABAQABAAACAgAAAQABAQECAgACAwEBAQEAAP7//wAA/wECAAAD///8/v4A//7/Af3+/gD/////AAEA/wEBAQH//wH+AAAA//8A/wH///8AAAICAQH/AQAB//8AAQD///3+/wAA/wICAgAAAAIAAAECAP///wD//gABAQMCAQEC////Af7//v/////+/////wD//wAAAAMCAf7+//0C/gT+Af0CAAECAAEAAQABAAAA/wD/AP/////+//////8A/v///gEA/wEAAAICAQMC/QICAgMCAQAAAAAAAP3+/v3+//7///7+//z9//7/AP7+/gEAAf///wECAf8AAQABAAEB/gEB/gAB/v/+//7//gIBAQABAP7//v7//v39/wAAAAIC/f7/AAAA/v/+/QQEAwICAP7+//v7/fn6/Pn4+fv8/f38/P7+//3+////AP/+Af7/AP//Af/+Af7//wAAAP8AAP3/Af3/AP7+AP////7//gIAAf//AP////8AAP///wD+AP///v///f/+/v8A/v7///////4B////AAAAAgADAQIC/QIBAf4AAAEAAAIBAAD/AP7+//z+//3+//7+//8AAP7+/wEBAAIAAQD//wICAgEBAQACAQAAAAAA/wD+/v7+/v39//7+//7/AP//AP7+/f/+AP8AAAEBAf///wQCAgEBAQIBAAH/Af8AAAAAAAABAgEAAP8BAAL/AAEBAAD/AAAAAAD/AQAB/wAAAAP/AP8BAAD/AAEBAAEAAAEAAAAAAgAAAQEBAQD//wAAAQAA/wEAAAD/AP8AAAEBAAD/AAACAAAAAgAD/wH/AAABAAAAAAAA//8AAQEAAAEAAP8AAAEAAP8BAQEAAAD/AQECAAAA/wAAAQH/AP8B/wAAAQEAAP8A/wEAAgAA/wABAQEA/wAAAgAB/wEBAQD+AAAAAQAB/wEAAgABAAAAAAH/AQABAAAAAQEAAgIBAAEAAAEAAQAAAAAB/wD///8AAQECAAH/Af8BAAAAAQEAAQH/AAABAgIAAQIBAQIAAgMBAgEBAgIBAgIBAAEBAAAAAP4AAAH/AQAAAAL/Af//AAL+AP0AAAH/AAD/AP7/AAEA/wAB/v8CAQH/AP8AAP/+//8A//8D/wIAAAD/AP4A/wH///8AAAD/AAD9/v0AAQAA/wABAQD///8AAAEBAP8AAQEAAQAAAP4AAAAAAAAA/wEAAQAA/gEBAQD//gH+Af8C/wD9//4DAgACAQEAAP8AAQAA/wAAAP8A////////////AP7///////4AAP8DAQEDAv8CAv8CAQEBAQH/AAD/AP8A///+///9/v/9/v/+/v/+/gAAAf8A//8A/wAAAgEA/gEA/f//Af79//0EBQED/wIDAgIBAQD/AP/+/v79/f3//v8CAQD9Av79/AD7BAMDBAIDAQL/AP/7/P37+/z7+vz7/P3//v7//v3+/gD+/wH+/wD+/wD+/v/9/wD//gH/AP8DAP/+/v7+///+///+/v0CAQH9Af8AAAH///7//wH//v79/wD+/v/+/gD+///+/v///v7/AP/+/gD/Af/+//79/QH/AAD+/wAD/QEBAQEBAQD+/v///v/////9/v7///7+/wAA//8BAgH+AAACAQAAAf8C/wL9AAACAQEA////AAH+/gD+/wD+AAH+AAD+Af//A" } ] } ================================================ FILE: Tests/Resources/JSON Responses/Images/ResponseFormat/ImageURL.json ================================================ { "created": 1667661280, "data": [ { "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-3JlqS7fDgniMfkzHfwwEdBm3/user-a1pfIvdAwqSA0RVdjzqH921M/img-byoTBAgSaGlyyTCGjnFhbSVx.png?st=2022-11-05T14%3A14%3A40Z&se=2022-11-05T16%3A14%3A40Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2022-11-05T02%3A20%3A52Z&ske=2022-11-06T02%3A20%3A52Z&sks=b&skv=2021-08-06&sig=Gb%2BBa63eW2kp8cZlD7Kmkz7BhtiRKmKgxnvds1mqA6A%3D" } ] } ================================================ FILE: Tests/Resources/JSON Responses/List Files/ListFilesResponse.json ================================================ { "object": "list", "data": [ { "object": "file", "id": "file-uvdyS3qukzhVrcvxOcjk0Xss", "purpose": "fine-tune", "filename": "sampleData.jsonl", "bytes": 18950, "created_at": 1668098746, "status": "processed", "status_details": null } ] } ================================================ FILE: Tests/Resources/JSON Responses/List Models/ModelsResponse.json ================================================ { "object": "list", "data": [ { "id": "model-id-0", "object": "model", "created": 1686935002, "owned_by": "organization-owner" }, { "id": "model-id-1", "object": "model", "created": 1686935002, "owned_by": "organization-owner", }, { "id": "model-id-2", "object": "model", "created": 1686935002, "owned_by": "openai" }, ], "object": "list" } ================================================ FILE: Tests/Resources/JSON Responses/Retrieve Model/RetrieveModelResponse.json ================================================ { "id": "davinci", "object": "model", "created": 1686935002, "owned_by": "openai" } ================================================ FILE: Tests/Test Plans/iOS-TS.xctestplan ================================================ { "configurations" : [ { "id" : "34DFFD4E-7557-4BE2-9AE5-AC7A0EBFC98A", "name" : "Default", "options" : { } } ], "defaultOptions" : { "codeCoverage" : false }, "testTargets" : [ { "target" : { "containerPath" : "container:", "identifier" : "OpenAIKitTests", "name" : "OpenAITests" } } ], "version" : 1 }