Skip to content

Commit 4316280

Browse files
committed
feat: Updated
1 parent 4cb5bd4 commit 4316280

78 files changed

Lines changed: 319 additions & 293 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
C# SDK for the [Ideogram](https://ideogram.ai/) AI image generation platform, auto-generated from the Ideogram OpenAPI specification using [AutoSDK](https://github.com/HavenDV/AutoSDK). Published as a NuGet package under the `tryAGI` organization.
8+
9+
## Build Commands
10+
11+
```bash
12+
# Build the solution
13+
dotnet build Ideogram.sln
14+
15+
# Build for release (also produces NuGet package)
16+
dotnet build Ideogram.sln -c Release
17+
18+
# Run integration tests (requires IDEOGRAM_API_KEY env var)
19+
dotnet test src/tests/IntegrationTests/Ideogram.IntegrationTests.csproj
20+
21+
# Regenerate SDK from OpenAPI spec
22+
cd src/libs/Ideogram && ./generate.sh
23+
```
24+
25+
## Architecture
26+
27+
### Code Generation Pipeline
28+
29+
The SDK code is **entirely auto-generated** — do not manually edit files in `src/libs/Ideogram/Generated/`.
30+
31+
1. `src/libs/Ideogram/openapi.yaml` — the Ideogram OpenAPI spec (fetched from `https://api.ideogram.ai/openapi.json`)
32+
2. `src/helpers/FixOpenApiSpec/` — converts OpenAPI 3.1 → 3.0 format for compatibility
33+
3. `src/libs/Ideogram/generate.sh` — orchestrates: download spec → fix spec → run AutoSDK CLI → output to `Generated/`
34+
4. CI auto-updates the spec every 3 hours and creates PRs if changes are detected
35+
36+
### Project Layout
37+
38+
| Project | Purpose |
39+
|---------|---------|
40+
| `src/libs/Ideogram/` | Main SDK library (`IdeogramApi`) |
41+
| `src/tests/IntegrationTests/` | Integration tests against real Ideogram API |
42+
| `src/helpers/FixOpenApiSpec/` | OpenAPI spec fixer tool |
43+
| `src/helpers/GenerateDocs/` | Documentation generator from integration tests |
44+
| `src/helpers/TrimmingHelper/` | NativeAOT/trimming compatibility validator |
45+
46+
### Build Configuration
47+
48+
- **Target:** `net10.0` (single target)
49+
- **Language:** C# 13 preview with nullable reference types
50+
- **Signing:** Strong-named assemblies via `src/key.snk`
51+
- **Versioning:** Semantic versioning from git tags (`v` prefix) via MinVer
52+
- **Analysis:** All .NET analyzers enabled, AOT/trimming compatibility enforced
53+
- **Testing:** MSTest + FluentAssertions
54+
55+
### CI/CD
56+
57+
- Uses shared workflows from `HavenDV/workflows` repo
58+
- Dependabot updates NuGet packages weekly (auto-merged)
59+
- Documentation deployed to GitHub Pages via MkDocs Material

Ideogram.sln

Lines changed: 0 additions & 84 deletions
This file was deleted.

Ideogram.slnx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<Solution>
2+
<Folder Name="/helpers/">
3+
<Project Path="src/helpers/FixOpenApiSpec/FixOpenApiSpec.csproj" />
4+
<Project Path="src/helpers/GenerateDocs/GenerateDocs.csproj" />
5+
<Project Path="src/helpers/TrimmingHelper/TrimmingHelper.csproj" />
6+
</Folder>
7+
<Folder Name="/libs/">
8+
<File Path="src/libs/Directory.Build.props" />
9+
<Project Path="src/libs/Ideogram/Ideogram.csproj" />
10+
</Folder>
11+
<Folder Name="/Solution Items/">
12+
<File Path=".github/dependabot.yml" />
13+
<File Path=".gitignore" />
14+
<File Path="LICENSE" />
15+
<File Path="README.md" />
16+
<File Path="src/Directory.Build.props" />
17+
</Folder>
18+
<Folder Name="/Solution Items/workflows/">
19+
<File Path=".github/workflows/auto-merge.yml" />
20+
<File Path=".github/workflows/auto-update.yml" />
21+
<File Path=".github/workflows/dotnet.yml" />
22+
<File Path=".github/workflows/mkdocs.yml" />
23+
<File Path=".github/workflows/pull-request.yml" />
24+
</Folder>
25+
<Folder Name="/tests/">
26+
<Project Path="src/tests/IntegrationTests/Ideogram.IntegrationTests.csproj" />
27+
</Folder>
28+
</Solution>

src/helpers/FixOpenApiSpec/FixOpenApiSpec.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.6.28" />
12+
<PackageReference Include="Microsoft.OpenApi" Version="3.3.1" />
13+
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.3.1" />
14+
<PackageReference Include="AutoSDK" Version="0.28.1-dev.114" />
1315
</ItemGroup>
1416

1517
</Project>
Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,57 @@
1+
using AutoSDK.Extensions;
2+
using AutoSDK.Models;
13
using Microsoft.OpenApi;
2-
using Microsoft.OpenApi.Any;
3-
using Microsoft.OpenApi.Extensions;
4-
using Microsoft.OpenApi.Models;
5-
using Microsoft.OpenApi.Readers;
64

75
var path = args[0];
8-
var text = await File.ReadAllTextAsync(path);
6+
var yamlOrJson = await File.ReadAllTextAsync(path);
97

10-
text = text
11-
.Replace("openapi: 3.1.0", "openapi: 3.0.1")
12-
;
8+
yamlOrJson = yamlOrJson
9+
.Replace(" v1beta", " ")
10+
.Replace("#/definitions/v1beta", "#/definitions/")
11+
.Replace("MgmtPublicService_", string.Empty)
12+
.Replace("mgmtv1beta", string.Empty)
13+
.Replace(" v1alpha", " ")
14+
.Replace("#/definitions/v1alpha", "#/definitions/")
15+
.Replace(" ArtifactPublicService", " ")
16+
.Replace("#/definitions/ArtifactPublicService", "#/definitions/")
17+
.Replace("ArtifactPublicService_", string.Empty)
18+
.Replace("artifactv1alpha", string.Empty)
19+
20+
// Fixing the Task schema because it conflicts with the Task class in C#
21+
.Replace("#/definitions/Task", "#/definitions/AITask")
22+
.Replace(" Task:", " AITask:")
1323

14-
var openApiDocument = new OpenApiStringReader().Read(text, out var diagnostics);
24+
// Fixing the Object schema because it conflicts with the Object class in C#
25+
.Replace("'#/definitions/Object'", "'#/definitions/AIObject'")
26+
.Replace(" Object:", " AIObject:")
27+
;
1528

16-
//openApiDocument.Components.Schemas["GenerateCompletionRequest"]!.Properties["stream"]!.Default = new OpenApiBoolean(true);
29+
var openApiDocument = yamlOrJson.GetOpenApiDocument(Settings.Default);
1730

18-
text = openApiDocument.SerializeAsYaml(OpenApiSpecVersion.OpenApi3_0);
19-
_ = new OpenApiStringReader().Read(text, out diagnostics);
31+
var schemas = openApiDocument.Components?.Schemas;
32+
var securitySchemes = openApiDocument.Components?.SecuritySchemes;
2033

21-
if (diagnostics.Errors.Count > 0)
34+
if (securitySchemes?.ContainsKey("Bearer") == true)
2235
{
23-
foreach (var error in diagnostics.Errors)
24-
{
25-
Console.WriteLine(error.Message);
26-
}
27-
// Return Exit code 1
28-
Environment.Exit(1);
36+
((OpenApiSecurityScheme)securitySchemes["Bearer"]!).Type = SecuritySchemeType.Http;
37+
((OpenApiSecurityScheme)securitySchemes["Bearer"]!).Scheme = "bearer";
2938
}
3039

31-
await File.WriteAllTextAsync(path, text);
32-
return;
40+
if (schemas?.ContainsKey("CreateCatalogResponse") == true)
41+
((OpenApiSchema)schemas["CreateCatalogResponse"]!).Required!.Add("catalog");
42+
43+
if (schemas?.ContainsKey("UploadCatalogFileResponse") == true)
44+
((OpenApiSchema)schemas["UploadCatalogFileResponse"]!).Required!.Add("file");
45+
46+
if (schemas?.ContainsKey("File") == true)
47+
((OpenApiSchema)schemas["File"]!).Required!.Add("fileUid");
48+
49+
if (schemas?.ContainsKey("ProcessCatalogFilesResponse") == true)
50+
((OpenApiSchema)schemas["ProcessCatalogFilesResponse"]!).Required!.Add("files");
51+
52+
if (schemas?.ContainsKey("ListCatalogFilesResponse") == true)
53+
((OpenApiSchema)schemas["ListCatalogFilesResponse"]!).Required!.Add("files");
54+
55+
yamlOrJson = await openApiDocument.SerializeAsYamlAsync(OpenApiSpecVersion.OpenApi3_2);
56+
57+
await File.WriteAllTextAsync(path, yamlOrJson);

src/helpers/TrimmingHelper/TrimmingHelper.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
</ItemGroup>
1414

1515
<ItemGroup>
16-
<PackageReference Include="Microsoft.NET.ILLink.Tasks" Version="10.0.3" />
1716
<TrimmerRootAssembly Include="Ideogram" />
1817
</ItemGroup>
1918

src/libs/Ideogram/Generated/Ideogram.Models.AddOrganizationMembersRequest.g.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public sealed partial class AddOrganizationMembersRequest
1313
/// </summary>
1414
[global::System.Text.Json.Serialization.JsonPropertyName("members")]
1515
[global::System.Text.Json.Serialization.JsonRequired]
16-
public required global::System.Collections.Generic.IList<global::Ideogram.LiteOrganizationMember> Members { get; set; }
16+
public global::System.Collections.Generic.IList<global::Ideogram.LiteOrganizationMember> Members { get; set; } = default!;
1717

1818
/// <summary>
1919
/// Additional properties that are not explicitly defined in the schema

src/libs/Ideogram/Generated/Ideogram.Models.ApiOrganizationUserSuggestion.g.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public sealed partial class ApiOrganizationUserSuggestion
1515
/// <example>john_doe</example>
1616
[global::System.Text.Json.Serialization.JsonPropertyName("display_handle")]
1717
[global::System.Text.Json.Serialization.JsonRequired]
18-
public required string DisplayHandle { get; set; }
18+
public string DisplayHandle { get; set; } = default!;
1919

2020
/// <summary>
2121
/// Whether the user has already joined the organization<br/>
@@ -24,7 +24,7 @@ public sealed partial class ApiOrganizationUserSuggestion
2424
/// <example>false</example>
2525
[global::System.Text.Json.Serialization.JsonPropertyName("joined")]
2626
[global::System.Text.Json.Serialization.JsonRequired]
27-
public required bool Joined { get; set; }
27+
public bool Joined { get; set; } = default!;
2828

2929
/// <summary>
3030
/// URL to the user's profile picture<br/>

src/libs/Ideogram/Generated/Ideogram.Models.ApiProfile.g.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public sealed partial class ApiProfile
1616
[global::System.Text.Json.Serialization.JsonPropertyName("type")]
1717
[global::System.Text.Json.Serialization.JsonConverter(typeof(global::Ideogram.JsonConverters.ApiProfileTypeJsonConverter))]
1818
[global::System.Text.Json.Serialization.JsonRequired]
19-
public required global::Ideogram.ApiProfileType Type { get; set; }
19+
public global::Ideogram.ApiProfileType Type { get; set; } = default!;
2020

2121
/// <summary>
2222
/// The display name of the profile<br/>
@@ -25,7 +25,7 @@ public sealed partial class ApiProfile
2525
/// <example>Gamma</example>
2626
[global::System.Text.Json.Serialization.JsonPropertyName("name")]
2727
[global::System.Text.Json.Serialization.JsonRequired]
28-
public required string Name { get; set; }
28+
public string Name { get; set; } = default!;
2929

3030
/// <summary>
3131
/// URL to the profile avatar<br/>
@@ -42,7 +42,7 @@ public sealed partial class ApiProfile
4242
/// <example>b3JnYW5pemF0aW9uXzEyMw</example>
4343
[global::System.Text.Json.Serialization.JsonPropertyName("organization_id")]
4444
[global::System.Text.Json.Serialization.JsonRequired]
45-
public required string OrganizationId { get; set; }
45+
public string OrganizationId { get; set; } = default!;
4646

4747
/// <summary>
4848
/// Role within an enterprise organization profile<br/>
@@ -52,21 +52,21 @@ public sealed partial class ApiProfile
5252
[global::System.Text.Json.Serialization.JsonPropertyName("role")]
5353
[global::System.Text.Json.Serialization.JsonConverter(typeof(global::Ideogram.JsonConverters.ApiProfileRoleJsonConverter))]
5454
[global::System.Text.Json.Serialization.JsonRequired]
55-
public required global::Ideogram.ApiProfileRole Role { get; set; }
55+
public global::Ideogram.ApiProfileRole Role { get; set; } = default!;
5656

5757
/// <summary>
5858
/// List of API keys associated with this profile
5959
/// </summary>
6060
[global::System.Text.Json.Serialization.JsonPropertyName("api_keys")]
6161
[global::System.Text.Json.Serialization.JsonRequired]
62-
public required global::System.Collections.Generic.IList<global::Ideogram.ApiProfileApiKey> ApiKeys { get; set; }
62+
public global::System.Collections.Generic.IList<global::Ideogram.ApiProfileApiKey> ApiKeys { get; set; } = default!;
6363

6464
/// <summary>
6565
/// Whether the user is on Metronome 2.0
6666
/// </summary>
6767
[global::System.Text.Json.Serialization.JsonPropertyName("is_metronome_2_user")]
6868
[global::System.Text.Json.Serialization.JsonRequired]
69-
public required bool IsMetronome2User { get; set; }
69+
public bool IsMetronome2User { get; set; } = default!;
7070

7171
/// <summary>
7272
/// The maximum number of inflight requests permitted for the profile<br/>
@@ -75,7 +75,7 @@ public sealed partial class ApiProfile
7575
/// <example>10</example>
7676
[global::System.Text.Json.Serialization.JsonPropertyName("max_num_inflight_requests_permitted")]
7777
[global::System.Text.Json.Serialization.JsonRequired]
78-
public required int MaxNumInflightRequestsPermitted { get; set; }
78+
public int MaxNumInflightRequestsPermitted { get; set; } = default!;
7979

8080
/// <summary>
8181
/// Additional properties that are not explicitly defined in the schema

src/libs/Ideogram/Generated/Ideogram.Models.ApiProfileApiKey.g.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public sealed partial class ApiProfileApiKey
1515
/// <example>JRPVD7jWR1aTBYiJ0UFVOg</example>
1616
[global::System.Text.Json.Serialization.JsonPropertyName("api_key_id")]
1717
[global::System.Text.Json.Serialization.JsonRequired]
18-
public required string ApiKeyId { get; set; }
18+
public string ApiKeyId { get; set; } = default!;
1919

2020
/// <summary>
2121
/// A redacted text snippet of the API key. Contains the first 4 characters of the API key<br/>
@@ -24,22 +24,22 @@ public sealed partial class ApiProfileApiKey
2424
/// <example>ATG56•••••••••••••</example>
2525
[global::System.Text.Json.Serialization.JsonPropertyName("redacted_api_key")]
2626
[global::System.Text.Json.Serialization.JsonRequired]
27-
public required string RedactedApiKey { get; set; }
27+
public string RedactedApiKey { get; set; } = default!;
2828

2929
/// <summary>
3030
/// The date at which the API key was created
3131
/// </summary>
3232
[global::System.Text.Json.Serialization.JsonPropertyName("creation_time")]
3333
[global::System.Text.Json.Serialization.JsonRequired]
34-
public required global::System.DateTime CreationTime { get; set; }
34+
public global::System.DateTime CreationTime { get; set; } = default!;
3535

3636
/// <summary>
3737
/// Status of the API key
3838
/// </summary>
3939
[global::System.Text.Json.Serialization.JsonPropertyName("status")]
4040
[global::System.Text.Json.Serialization.JsonConverter(typeof(global::Ideogram.JsonConverters.ApiKeyStatusJsonConverter))]
4141
[global::System.Text.Json.Serialization.JsonRequired]
42-
public required global::Ideogram.ApiKeyStatus Status { get; set; }
42+
public global::Ideogram.ApiKeyStatus Status { get; set; } = default!;
4343

4444
/// <summary>
4545
/// Additional properties that are not explicitly defined in the schema

0 commit comments

Comments
 (0)