From 90291b36f9b83ad7b045f5c8bee0b9ac82767909 Mon Sep 17 00:00:00 2001 From: jeff nasseri Date: Thu, 3 Apr 2025 01:26:14 +0200 Subject: [PATCH 1/6] Initialize .NET Generator Project for Agent Protocol SDK using NSwag This commit establishes a comprehensive CLI tool built with .NET 8 that generates C# client SDK for the Agent Protocol specification. The implementation leverages NSwag to process OpenAPI JSON input files and produce strongly-typed client libraries. Key components include: - Command-line interface with input/output parameter support - Service-oriented architecture with dependency injection - Structured logging implementation The tool can be invoked using `dotnet run -- -i -o ` to generate a ready-to-use C# client library. P.S. The author of this commit include the whole initial changes related to the `Generator` project and README.md in the current commit, check the readme in order to understanding the usage. Other files would be included in the up coming changes, like github actions, unit tests and etc --- .../Common/Configs/LoggingConfiguration.cs | 20 +++++ .../Extensions/ServiceCollectionExtensions.cs | 17 ++++ packages/sdk/C#/Generator/Generator.csproj | 26 ++++++ packages/sdk/C#/Generator/Options.cs | 15 ++++ packages/sdk/C#/Generator/Program.cs | 69 ++++++++++++++ .../Services/ApiClientGeneratorService.cs | 58 ++++++++++++ .../Services/IApiClientGeneratorService.cs | 6 ++ packages/sdk/C#/README.md | 89 +++++++++++++++++++ 8 files changed, 300 insertions(+) create mode 100644 packages/sdk/C#/Generator/Common/Configs/LoggingConfiguration.cs create mode 100644 packages/sdk/C#/Generator/Common/Extensions/ServiceCollectionExtensions.cs create mode 100644 packages/sdk/C#/Generator/Generator.csproj create mode 100644 packages/sdk/C#/Generator/Options.cs create mode 100644 packages/sdk/C#/Generator/Program.cs create mode 100644 packages/sdk/C#/Generator/Services/ApiClientGeneratorService.cs create mode 100644 packages/sdk/C#/Generator/Services/IApiClientGeneratorService.cs create mode 100644 packages/sdk/C#/README.md diff --git a/packages/sdk/C#/Generator/Common/Configs/LoggingConfiguration.cs b/packages/sdk/C#/Generator/Common/Configs/LoggingConfiguration.cs new file mode 100644 index 00000000..1d9e151a --- /dev/null +++ b/packages/sdk/C#/Generator/Common/Configs/LoggingConfiguration.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Generator.Common.Configs; + +public static class LoggingConfiguration +{ + public static IServiceCollection ConfigureLogging(this IServiceCollection services, LogLevel minimumLevel = LogLevel.Information) + { + services.AddLogging(builder => + { + builder.ClearProviders(); + builder.AddConsole(); + + builder.SetMinimumLevel(minimumLevel); + }); + + return services; + } +} \ No newline at end of file diff --git a/packages/sdk/C#/Generator/Common/Extensions/ServiceCollectionExtensions.cs b/packages/sdk/C#/Generator/Common/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 00000000..b1a503ae --- /dev/null +++ b/packages/sdk/C#/Generator/Common/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,17 @@ +using Generator.Common.Configs; +using Generator.Services; +using Microsoft.Extensions.DependencyInjection; + +namespace Generator.Common.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddApplicationServices(this IServiceCollection services) + { + services.ConfigureLogging(); + + services.AddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/packages/sdk/C#/Generator/Generator.csproj b/packages/sdk/C#/Generator/Generator.csproj new file mode 100644 index 00000000..bfa86ab5 --- /dev/null +++ b/packages/sdk/C#/Generator/Generator.csproj @@ -0,0 +1,26 @@ + + + + Exe + net8.0 + enable + enable + latest + true + openapi-generator | agent protocol + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/sdk/C#/Generator/Options.cs b/packages/sdk/C#/Generator/Options.cs new file mode 100644 index 00000000..f0b79cc7 --- /dev/null +++ b/packages/sdk/C#/Generator/Options.cs @@ -0,0 +1,15 @@ +using CommandLine; + +namespace Generator; + +public class Options +{ + [Option('i', "input", Required = true, HelpText = "Input OpenAPI JSON file path.")] + public string InputFilePath { get; set; } = string.Empty; + + [Option('o', "output", Required = false, HelpText = "Output directory for generated C# client.")] + public string? OutputDirectory { get; set; } + + [Option('n', "namespace", Required = false, Default = "GeneratedApiClient", HelpText = "Namespace for the generated client.")] + public string Namespace { get; set; } = "GeneratedApiClient"; +} \ No newline at end of file diff --git a/packages/sdk/C#/Generator/Program.cs b/packages/sdk/C#/Generator/Program.cs new file mode 100644 index 00000000..2593ebca --- /dev/null +++ b/packages/sdk/C#/Generator/Program.cs @@ -0,0 +1,69 @@ +using CommandLine; +using Generator.Common.Extensions; +using Generator.Services; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Generator; +// Command line options class + +public class Program +{ + public static async Task Main(string[] args) + { + // Setup dependency injection + IServiceProvider serviceProvider = ConfigureServices(); + + return await Parser.Default.ParseArguments(args) + .MapResult( + async (Options opts) => await RunWithOptionsAsync(opts, serviceProvider), + errs => Task.FromResult(1) + ); + } + + private static IServiceProvider ConfigureServices() + { + ServiceCollection services = new(); + + // Configure all services using the extension method + services.AddApplicationServices(); + + return services.BuildServiceProvider(); + } + + private static async Task RunWithOptionsAsync(Options options, IServiceProvider serviceProvider) + { + // Get logger + ILogger? logger = serviceProvider.GetService(typeof(ILogger)) as ILogger; + logger?.LogInformation("Starting OpenAPI Client Generator"); + + try + { + // Determine output directory + string outputDir = options.OutputDirectory ?? System.IO.Path.Combine( + System.IO.Directory.GetCurrentDirectory(), "Generated"); + + // Get the generator service + IApiClientGeneratorService? generatorService = serviceProvider.GetService(typeof(IApiClientGeneratorService)) as IApiClientGeneratorService; + if (generatorService == null) + { + logger?.LogError("Failed to resolve ApiClientGeneratorService"); + return 1; + } + + // Generate the client + bool result = await generatorService.GenerateClientAsync( + options.InputFilePath, + outputDir, + options.Namespace + ); + + return result ? 0 : 1; + } + catch (Exception ex) + { + logger?.LogError(ex, "Unhandled exception: {Message}", ex.Message); + return 1; + } + } +} \ No newline at end of file diff --git a/packages/sdk/C#/Generator/Services/ApiClientGeneratorService.cs b/packages/sdk/C#/Generator/Services/ApiClientGeneratorService.cs new file mode 100644 index 00000000..6c330b38 --- /dev/null +++ b/packages/sdk/C#/Generator/Services/ApiClientGeneratorService.cs @@ -0,0 +1,58 @@ +using Microsoft.Extensions.Logging; +using NSwag; +using NSwag.CodeGeneration.CSharp; + +namespace Generator.Services; + +public class ApiClientGeneratorService(ILogger logger) : IApiClientGeneratorService +{ + private readonly ILogger _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + + public async Task GenerateClientAsync(string inputFilePath, string outputDirectory, string namespaceName) + { + try + { + _logger.LogInformation("Loading OpenAPI specification from: {FilePath}", inputFilePath); + + if (!File.Exists(inputFilePath)) + { + _logger.LogError("Input file '{FilePath}' does not exist", inputFilePath); + return false; + } + + Directory.CreateDirectory(outputDirectory); + + _logger.LogDebug("Parsing OpenAPI document"); + OpenApiDocument? document = await OpenApiDocument.FromFileAsync(inputFilePath); + + CSharpClientGeneratorSettings settings = new() + { + ClassName = "ApiClient", + CSharpGeneratorSettings = + { + Namespace = namespaceName, + GenerateNullableReferenceTypes = true + }, + GenerateDtoTypes = true, + GenerateClientInterfaces = true, + GenerateOptionalParameters = true, + UseBaseUrl = false + }; + + _logger.LogInformation("Generating C# client code with namespace: {Namespace}", namespaceName); + CSharpClientGenerator generator = new(document, settings); + string? code = generator.GenerateFile(); + + string outputFile = Path.Combine(outputDirectory, "ApiClient.cs"); + await File.WriteAllTextAsync(outputFile, code); + + _logger.LogInformation("Client successfully generated at: {OutputPath}", outputFile); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error generating client: {ErrorMessage}", ex.Message); + return false; + } + } +} \ No newline at end of file diff --git a/packages/sdk/C#/Generator/Services/IApiClientGeneratorService.cs b/packages/sdk/C#/Generator/Services/IApiClientGeneratorService.cs new file mode 100644 index 00000000..245f83d5 --- /dev/null +++ b/packages/sdk/C#/Generator/Services/IApiClientGeneratorService.cs @@ -0,0 +1,6 @@ +namespace Generator.Services; + +public interface IApiClientGeneratorService +{ + Task GenerateClientAsync(string inputFilePath, string outputDirectory, string namespaceName); +} \ No newline at end of file diff --git a/packages/sdk/C#/README.md b/packages/sdk/C#/README.md new file mode 100644 index 00000000..b2372e47 --- /dev/null +++ b/packages/sdk/C#/README.md @@ -0,0 +1,89 @@ +# OpenAPI Client Generator + +A .NET console application that generates C# client libraries from OpenAPI JSON specifications using NSwag. Built with modern .NET practices including dependency injection, logging, and service-oriented architecture. + +## Features + +- Generates C# client code from OpenAPI specifications +- Well-structured application using dependency injection +- Comprehensive logging +- Service-oriented architecture for better maintainability +- Command-line interface with multiple options +- Centralized package version management using Directory.Packages.props +- Shared build properties using Directory.Build.props + +## Requirements + +- .NET 8.0 SDK + +## Installation + +1. Clone or download this repository +2. Navigate to the project directory +3. Build the project: + + ``` + dotnet build + ``` + +## Testing + +The solution includes a comprehensive test suite covering unit, integration, and command-line tests: + +1. Run all tests: + + ``` + dotnet test + ``` + +The test project demonstrates different + +## Usage + +Run the application using `dotnet run` with the required parameters: + +``` +dotnet run -- -i [-o ] [-n ] +``` + +Or build and run the executable: + +``` +dotnet build +dotnet run -- -i -o +``` + +### Parameters + +- `-i, --input`: (Required) Path to the OpenAPI JSON file +- `-o, --output`: (Optional) Output directory for the generated C# client code +- `-n, --namespace`: (Optional) Namespace for the generated client (default: "GeneratedApiClient") + +### Examples + +Generate a client with default settings: + +``` +dotnet run -- -i ./my-api-spec.json +``` + +Specify an output directory and namespace: + +``` +dotnet run -- -i ./my-api-spec.json -o ./MyClientLibrary -n MyCompany.ApiClient +``` + +## Installing as a Global Tool + +You can also install this application as a global .NET tool: + +``` +dotnet pack +dotnet tool install --global --add-source ./bin/Debug OpenApiClientGenerator +``` + +After installation, you can use it directly: + +``` +openapi-generator -i ./my-api-spec.json -o ./ClientLibrary +``` From adcee3ab12a4412e8f4d702a97fcd50d18e19503 Mon Sep 17 00:00:00 2001 From: jeff nasseri Date: Thu, 3 Apr 2025 01:28:29 +0200 Subject: [PATCH 2/6] Initialize .editorconfig for consistent coding standards in the C# SDK By implementing these standards through .editorconfig, we ensure that regardless of which IDE or editor developers use (Visual Studio, VS Code, Rider, etc.), the codebase remains consistent. This improves readability, reduces merge conflicts, and simplifies contributions from the community. --- packages/sdk/C#/.editorconfig | 223 ++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 packages/sdk/C#/.editorconfig diff --git a/packages/sdk/C#/.editorconfig b/packages/sdk/C#/.editorconfig new file mode 100644 index 00000000..a73739d0 --- /dev/null +++ b/packages/sdk/C#/.editorconfig @@ -0,0 +1,223 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = false +insert_final_newline = true +indent_style = space +indent_size = 4 +tab_width = 4 + +[{*.yml,*.yaml,*.har,*.inputactions,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}] +indent_size = 2 + +[{*.xml,*.csproj}] +indent_size = 2 +ij_xml_space_inside_empty_tag = true + +# C# files +[*.cs] +max_line_length = 140 +insert_final_newline = false +trim_trailing_whitespace = true + +#### .NET Coding Conventions #### + +dotnet_sort_system_directives_first = true + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:warning +dotnet_style_qualification_for_field = false:warning +dotnet_style_qualification_for_method = false:warning +dotnet_style_qualification_for_property = false:warning + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:warning +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning + +# Expression-level preferences +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_throw_expression = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:warning +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:suggestion + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:warning + +#### .NET Naming Rules #### + +dotnet_naming_rule.constant_rule.severity = warning +dotnet_naming_rule.constant_rule.symbols = constant +dotnet_naming_rule.constant_rule.style = underscore_case +dotnet_naming_symbols.constant.applicable_kinds = field +dotnet_naming_symbols.constant.applicable_accessibilities = * +dotnet_naming_symbols.constant.required_modifiers = const +dotnet_naming_style.underscore_case.word_separator = _ +dotnet_naming_style.underscore_case.capitalization = all_upper + +dotnet_naming_rule.interface_rule.severity = warning +dotnet_naming_rule.interface_rule.symbols = interface +dotnet_naming_rule.interface_rule.style = interface +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = * +dotnet_naming_style.interface.required_prefix = I +dotnet_naming_style.interface.capitalization = pascal_case + +dotnet_naming_rule.types_rule.severity = warning +dotnet_naming_rule.types_rule.symbols = types +dotnet_naming_rule.types_rule.style = pascal_case +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = * +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_rule.non_field_members_rule.severity = warning +dotnet_naming_rule.non_field_members_rule.symbols = non_field_members +dotnet_naming_rule.non_field_members_rule.style = pascal_case +dotnet_naming_symbols.non_field_members.applicable_kinds = property, method, event +dotnet_naming_symbols.non_field_members.applicable_accessibilities = * + +dotnet_naming_rule.type_parameter_rule.severity = warning +dotnet_naming_rule.type_parameter_rule.symbols = type_parameter +dotnet_naming_rule.type_parameter_rule.style = pascal_case +dotnet_naming_symbols.type_parameter.applicable_kinds = type_parameter +dotnet_naming_symbols.type_parameter.applicable_accessibilities = * + +dotnet_naming_rule.private_or_internal_field_rule.severity = warning +dotnet_naming_rule.private_or_internal_field_rule.symbols = private_or_internal_field +dotnet_naming_rule.private_or_internal_field_rule.style = private_or_internal_field +dotnet_naming_symbols.private_or_internal_field.applicable_kinds = field +dotnet_naming_symbols.private_or_internal_field.applicable_accessibilities = private, internal +dotnet_naming_style.private_or_internal_field.required_prefix = _ +dotnet_naming_style.private_or_internal_field.capitalization = camel_case + +dotnet_naming_rule.parameter_rule.severity = warning +dotnet_naming_rule.parameter_rule.symbols = parameter +dotnet_naming_rule.parameter_rule.style = camel_case +dotnet_naming_symbols.parameter.applicable_kinds = parameter +dotnet_naming_symbols.parameter.applicable_accessibilities = * +dotnet_naming_style.camel_case.capitalization = camel_case + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false:warning +csharp_style_var_for_built_in_types = false:warning +csharp_style_var_when_type_is_apparent = false:warning + +# Expression-bodied members +csharp_style_expression_bodied_accessors = false:suggestion +csharp_style_expression_bodied_constructors = false:suggestion +csharp_style_expression_bodied_indexers = true:suggestion +csharp_style_expression_bodied_lambdas = when_on_single_line:suggestion +csharp_style_expression_bodied_local_functions = false:suggestion +csharp_style_expression_bodied_methods = false:suggestion +csharp_style_expression_bodied_operators = false:suggestion +csharp_style_expression_bodied_properties = true:suggestion + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:warning +csharp_style_pattern_matching_over_is_with_cast_check = true:warning + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async + +# Code-block preferences +csharp_prefer_braces = true:warning + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:silent +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = false +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = false +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = false +csharp_prefer_simple_using_statement = false:suggestion + +# ReSharper inspection severities +resharper_csharp_object_creation_when_type_evident = target_typed +resharper_csharp_object_creation_when_type_not_evident = explicitly_typed +resharper_arrange_object_creation_when_type_evident_highlighting = suggestion +resharper_arrange_object_creation_when_type_not_evident_highlighting = suggestion +resharper_csharp_blank_lines_after_file_scoped_namespace_directive = 1 +resharper_not_accessed_field_local_highlighting = suggestion +resharper_unused_member_local_highlighting = suggestion +resharper_spec_flow_step_not_resolved_highlighting = suggestion +resharper_unused_auto_property_accessor_global_highlighting = suggestion +resharper_unused_member_local_highlighting = suggestion +resharper_blank_lines_before_block_statements = 1 +resharper_max_attribute_length_for_same_line = 120 +resharper_place_accessorholder_attribute_on_same_line = false +resharper_place_field_attribute_on_same_line = false +resharper_entity_framework_n_plus_one_incomplete_data_usage_highlighting = hint From ef6cce3b218c19969484bbe6b701425deadbb1cb Mon Sep 17 00:00:00 2001 From: jeff nasseri Date: Thu, 3 Apr 2025 01:31:11 +0200 Subject: [PATCH 3/6] Initialize comprehensive unit test structure for the Generator application This commit establishes a robust testing framework to validate the integrity and functionality of the Agent Protocol SDK Generator. The test suite encompasses multiple levels of testing including unit tests for core components and integration tests for the end-to-end generation process. Key aspects of the testing implementation: - Structured test organization following the AAA (Arrange-Act-Assert) pattern - Tests for the dependency injection container to verify proper service registration and resolution - Validation tests for command-line argument parsing and processing The test project is configured to run as part of the build pipeline, ensuring that all changes maintain compatibility with the core functionality. This testing foundation will facilitate future enhancements while safeguarding against regressions as the codebase evolves. --- .../Tests/ApiClientGeneratorServiceTests.cs | 81 + packages/sdk/C#/Tests/ProgramTests.cs | 52 + packages/sdk/C#/Tests/Tests.csproj | 31 + packages/sdk/C#/Tests/sample-api.json | 2166 +++++++++++++++++ 4 files changed, 2330 insertions(+) create mode 100644 packages/sdk/C#/Tests/ApiClientGeneratorServiceTests.cs create mode 100644 packages/sdk/C#/Tests/ProgramTests.cs create mode 100644 packages/sdk/C#/Tests/Tests.csproj create mode 100644 packages/sdk/C#/Tests/sample-api.json diff --git a/packages/sdk/C#/Tests/ApiClientGeneratorServiceTests.cs b/packages/sdk/C#/Tests/ApiClientGeneratorServiceTests.cs new file mode 100644 index 00000000..fd8c1366 --- /dev/null +++ b/packages/sdk/C#/Tests/ApiClientGeneratorServiceTests.cs @@ -0,0 +1,81 @@ +using FluentAssertions; +using Generator.Services; +using Microsoft.Extensions.Logging; +using Moq; +using Xunit; + +namespace Tests; + +public class ApiClientGeneratorServiceTests +{ + private readonly Mock> _loggerMock; + private readonly IApiClientGeneratorService _service; + private readonly string _testDataPath; + + public ApiClientGeneratorServiceTests() + { + _loggerMock = new Mock>(); + _service = new ApiClientGeneratorService(_loggerMock.Object); + + _testDataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestData"); + + Directory.CreateDirectory(_testDataPath); + + string sourceFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sample-api.json"); + string destFile = Path.Combine(_testDataPath, "sample-api.json"); + + if (File.Exists(sourceFile) && !File.Exists(destFile)) + { + File.Copy(sourceFile, destFile); + } + } + + [Fact] + public async Task GenerateClientAsync_WithValidInput_ShouldReturnTrue() + { + // Arrange + string inputFile = Path.Combine(_testDataPath, "sample-api.json"); + string outputDir = Path.Combine(_testDataPath, "Output"); + const string namespaceName = "TestNamespace"; + + // Cleanup before test + if (Directory.Exists(outputDir)) + { + Directory.Delete(outputDir, true); + } + + // Act + bool result = await _service.GenerateClientAsync(inputFile, outputDir, namespaceName); + + // Assert + result.Should().BeTrue(); + File.Exists(Path.Combine(outputDir, "ApiClient.cs")).Should().BeTrue(); + + // Verify the content has the correct namespace + string generatedCode = await File.ReadAllTextAsync(Path.Combine(outputDir, "ApiClient.cs")); + generatedCode.Should().Contain($"namespace {namespaceName}"); + } + + [Fact] + public async Task GenerateClientAsync_WithNonExistentFile_ShouldReturnFalse() + { + // Arrange + string inputFile = Path.Combine(_testDataPath, "non-existent-file.json"); + string outputDir = Path.Combine(_testDataPath, "Output"); + const string namespaceName = "TestNamespace"; + + // Act + bool result = await _service.GenerateClientAsync(inputFile, outputDir, namespaceName); + + // Assert + result.Should().BeFalse(); + _loggerMock.Verify( + x => x.Log( + LogLevel.Error, + It.IsAny(), + It.Is((o, t) => o.ToString()!.Contains("does not exist")), + It.IsAny(), + It.IsAny>()!), + Times.Once); + } +} \ No newline at end of file diff --git a/packages/sdk/C#/Tests/ProgramTests.cs b/packages/sdk/C#/Tests/ProgramTests.cs new file mode 100644 index 00000000..0626caca --- /dev/null +++ b/packages/sdk/C#/Tests/ProgramTests.cs @@ -0,0 +1,52 @@ +using FluentAssertions; +using Generator; +using Xunit; + +namespace Tests; + +public class ProgramTests +{ + [Fact] + public async Task Main_WithValidArguments_ShouldReturnZero() + { + // Arrange + string testDataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestData"); + Directory.CreateDirectory(testDataPath); + + string inputFile = Path.Combine(testDataPath, "sample-api.json"); + string outputDir = Path.Combine(testDataPath, "Output"); + + // Act + int result = await Program.Main(["-i", inputFile, "-o", outputDir, "-n", "TestNamespace"]); + + // Assert + result.Should().Be(0); + } + + [Fact] + public async Task Main_WithInvalidArguments_ShouldReturnNonZero() + { + // Arrange - No arguments provided + + // Act + int result = await Program.Main([]); + + // Assert + result.Should().NotBe(0); + } + + [Fact] + public async Task Main_WithNonExistentInputFile_ShouldReturnNonZero() + { + // Arrange + string testDataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestData"); + string inputFile = Path.Combine(testDataPath, "non-existent-file.json"); + string outputDir = Path.Combine(testDataPath, "Output"); + + // Act + int result = await Program.Main(["-i", inputFile, "-o", outputDir]); + + // Assert + result.Should().NotBe(0); + } +} \ No newline at end of file diff --git a/packages/sdk/C#/Tests/Tests.csproj b/packages/sdk/C#/Tests/Tests.csproj new file mode 100644 index 00000000..5ea78de3 --- /dev/null +++ b/packages/sdk/C#/Tests/Tests.csproj @@ -0,0 +1,31 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/packages/sdk/C#/Tests/sample-api.json b/packages/sdk/C#/Tests/sample-api.json new file mode 100644 index 00000000..685689a9 --- /dev/null +++ b/packages/sdk/C#/Tests/sample-api.json @@ -0,0 +1,2166 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Agent Protocol", + "description": "Specification of the API protocol for communication with an agent.", + "version": "v1" + }, + "servers": [ + { + "url": "http://0.0.0.0:8000", + "description": "Agent Protocol API" + } + ], + "paths": { + "/ap/v1/agent/tasks": { + "post": { + "operationId": "createAgentTask", + "summary": "Creates a task for the agent.", + "requestBody": { + "content": { + "application/json": { + "schema": { + "description": "Body of the task request.", + "type": "object", + "properties": { + "input": { + "description": "Input prompt for the task.", + "type": "string", + "example": "Write 'Washington' to the file 'output.txt'.", + "nullable": true + }, + "additional_input": { + "description": "Input parameters for the task. Any value is allowed.", + "type": "object", + "example": "{\n\"debug\": false,\n\"mode\": \"benchmarks\"\n}" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "A new agent task was successfully created.", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "description": "Body of the task request.", + "type": "object", + "properties": { + "input": { + "description": "Input prompt for the task.", + "type": "string", + "example": "Write 'Washington' to the file 'output.txt'.", + "nullable": true + }, + "additional_input": { + "description": "Input parameters for the task. Any value is allowed.", + "type": "object", + "example": "{\n\"debug\": false,\n\"mode\": \"benchmarks\"\n}" + } + } + }, + { + "type": "object", + "description": "Definition of an agent task.", + "required": [ + "task_id", + "artifacts" + ], + "properties": { + "task_id": { + "description": "The ID of the task.", + "type": "string", + "example": "50da533e-3904-4401-8a07-c49adf88b5eb" + }, + "artifacts": { + "description": "A list of artifacts that the task has produced.", + "type": "array", + "items": { + "description": "An Artifact either created by or submitted to the agent.", + "type": "object", + "properties": { + "artifact_id": { + "description": "ID of the artifact.", + "type": "string", + "example": "b225e278-8b4c-4f99-a696-8facf19f0e56" + }, + "agent_created": { + "description": "Whether the artifact has been created by the agent.", + "type": "boolean", + "example": false + }, + "file_name": { + "description": "Filename of the artifact.", + "type": "string", + "example": "main.py" + }, + "relative_path": { + "description": "Relative path of the artifact in the agent's workspace.", + "type": "string", + "example": "python/code/", + "nullable": true + } + }, + "required": [ + "artifact_id", + "agent_created", + "file_name" + ] + }, + "example": [ + "7a49f31c-f9c6-4346-a22c-e32bc5af4d8e", + "ab7b4091-2560-4692-a4fe-d831ea3ca7d6" + ], + "default": [] + } + } + } + ] + } + } + }, + "x-postman-variables": [ + { + "type": "save", + "name": "task_id", + "path": ".task_id" + } + ] + }, + "422": { + "description": "Unable to process request. Likely due to improperly formatted request.", + "content": { + "application/json": { + "schema": { + "description": "A generic JSON object without any specific requirements.", + "type": "object" + } + } + } + }, + "default": { + "description": "Internal Server Error" + } + }, + "tags": [ + "agent" + ] + }, + "get": { + "operationId": "listAgentTasks", + "summary": "List all tasks that have been created for the agent.", + "parameters": [ + { + "name": "current_page", + "in": "query", + "description": "Page number", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 1, + "minimum": 1 + }, + "example": 2 + }, + { + "name": "page_size", + "in": "query", + "description": "Number of items per page", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 10, + "minimum": 1 + }, + "example": 25 + } + ], + "responses": { + "200": { + "description": "Returned list of agent's tasks.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "tasks": { + "type": "array", + "items": { + "allOf": [ + { + "description": "Body of the task request.", + "type": "object", + "properties": { + "input": { + "description": "Input prompt for the task.", + "type": "string", + "example": "Write 'Washington' to the file 'output.txt'.", + "nullable": true + }, + "additional_input": { + "description": "Input parameters for the task. Any value is allowed.", + "type": "object", + "example": "{\n\"debug\": false,\n\"mode\": \"benchmarks\"\n}" + } + } + }, + { + "type": "object", + "description": "Definition of an agent task.", + "required": [ + "task_id", + "artifacts" + ], + "properties": { + "task_id": { + "description": "The ID of the task.", + "type": "string", + "example": "50da533e-3904-4401-8a07-c49adf88b5eb" + }, + "artifacts": { + "description": "A list of artifacts that the task has produced.", + "type": "array", + "items": { + "description": "An Artifact either created by or submitted to the agent.", + "type": "object", + "properties": { + "artifact_id": { + "description": "ID of the artifact.", + "type": "string", + "example": "b225e278-8b4c-4f99-a696-8facf19f0e56" + }, + "agent_created": { + "description": "Whether the artifact has been created by the agent.", + "type": "boolean", + "example": false + }, + "file_name": { + "description": "Filename of the artifact.", + "type": "string", + "example": "main.py" + }, + "relative_path": { + "description": "Relative path of the artifact in the agent's workspace.", + "type": "string", + "example": "python/code/", + "nullable": true + } + }, + "required": [ + "artifact_id", + "agent_created", + "file_name" + ] + }, + "example": [ + "7a49f31c-f9c6-4346-a22c-e32bc5af4d8e", + "ab7b4091-2560-4692-a4fe-d831ea3ca7d6" + ], + "default": [] + } + } + } + ] + } + }, + "pagination": { + "type": "object", + "properties": { + "total_items": { + "description": "Total number of items.", + "type": "integer", + "example": 42 + }, + "total_pages": { + "description": "Total number of pages.", + "type": "integer", + "example": 97 + }, + "current_page": { + "description": "Current_page page number.", + "type": "integer", + "example": 1 + }, + "page_size": { + "description": "Number of items per page.", + "type": "integer", + "example": 25 + } + }, + "required": [ + "total_items", + "total_pages", + "current_page", + "page_size" + ] + } + }, + "required": [ + "tasks", + "pagination" + ] + } + } + } + }, + "default": { + "description": "Internal Server Error" + } + }, + "tags": [ + "agent" + ] + } + }, + "/ap/v1/agent/tasks/{task_id}": { + "get": { + "operationId": "getAgentTask", + "summary": "Get details about a specified agent task.", + "parameters": [ + { + "name": "task_id", + "in": "path", + "description": "ID of the task", + "required": true, + "schema": { + "type": "string" + }, + "example": "1d5a533e-3904-4401-8a07-c49adf88b981", + "x-postman-variables": [ + { + "type": "load", + "name": "task_id" + } + ] + } + ], + "responses": { + "200": { + "description": "Returned details about an agent task.", + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "description": "Body of the task request.", + "type": "object", + "properties": { + "input": { + "description": "Input prompt for the task.", + "type": "string", + "example": "Write 'Washington' to the file 'output.txt'.", + "nullable": true + }, + "additional_input": { + "description": "Input parameters for the task. Any value is allowed.", + "type": "object", + "example": "{\n\"debug\": false,\n\"mode\": \"benchmarks\"\n}" + } + } + }, + { + "type": "object", + "description": "Definition of an agent task.", + "required": [ + "task_id", + "artifacts" + ], + "properties": { + "task_id": { + "description": "The ID of the task.", + "type": "string", + "example": "50da533e-3904-4401-8a07-c49adf88b5eb" + }, + "artifacts": { + "description": "A list of artifacts that the task has produced.", + "type": "array", + "items": { + "description": "An Artifact either created by or submitted to the agent.", + "type": "object", + "properties": { + "artifact_id": { + "description": "ID of the artifact.", + "type": "string", + "example": "b225e278-8b4c-4f99-a696-8facf19f0e56" + }, + "agent_created": { + "description": "Whether the artifact has been created by the agent.", + "type": "boolean", + "example": false + }, + "file_name": { + "description": "Filename of the artifact.", + "type": "string", + "example": "main.py" + }, + "relative_path": { + "description": "Relative path of the artifact in the agent's workspace.", + "type": "string", + "example": "python/code/", + "nullable": true + } + }, + "required": [ + "artifact_id", + "agent_created", + "file_name" + ] + }, + "example": [ + "7a49f31c-f9c6-4346-a22c-e32bc5af4d8e", + "ab7b4091-2560-4692-a4fe-d831ea3ca7d6" + ], + "default": [] + } + } + } + ] + } + } + } + }, + "404": { + "description": "Unable to find entity with a given identifier", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "description": "Message stating the entity was not found", + "type": "string", + "example": "Unable to find entity with the provided id" + } + }, + "required": [ + "message" + ] + } + } + } + }, + "default": { + "description": "Internal Server Error" + } + }, + "tags": [ + "agent" + ] + } + }, + "/ap/v1/agent/tasks/{task_id}/steps": { + "get": { + "operationId": "listAgentTaskSteps", + "summary": "List all steps for the specified task.", + "parameters": [ + { + "name": "task_id", + "in": "path", + "description": "ID of the task.", + "required": true, + "schema": { + "type": "string" + }, + "example": "50da533e-3904-4401-8a07-c49adf88b5eb", + "x-postman-variables": [ + { + "type": "load", + "name": "task_id" + } + ] + }, + { + "name": "current_page", + "in": "query", + "description": "Page number", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 1, + "minimum": 1 + }, + "example": 2 + }, + { + "name": "page_size", + "in": "query", + "description": "Number of items per page", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 10, + "minimum": 1 + }, + "example": 25 + } + ], + "responses": { + "200": { + "description": "Returned list of agent's steps for the specified task.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "steps": { + "type": "array", + "items": { + "allOf": [ + { + "description": "Body of the task request.", + "type": "object", + "properties": { + "input": { + "description": "Input prompt for the step.", + "type": "string", + "example": "Write the words you receive to the file 'output.txt'.", + "nullable": true + }, + "additional_input": { + "description": "Input parameters for the task step. Any value is allowed.", + "type": "object", + "example": "{\n\"file_to_refactor\": \"models.py\"\n}" + } + } + }, + { + "type": "object", + "required": [ + "step_id", + "task_id", + "status", + "is_last", + "artifacts" + ], + "properties": { + "task_id": { + "description": "The ID of the task this step belongs to.", + "type": "string", + "example": "50da533e-3904-4401-8a07-c49adf88b5eb" + }, + "step_id": { + "description": "The ID of the task step.", + "type": "string", + "example": "6bb1801a-fd80-45e8-899a-4dd723cc602e" + }, + "name": { + "description": "The name of the task step.", + "type": "string", + "example": "Write to file", + "nullable": true + }, + "status": { + "description": "The status of the task step.", + "type": "string", + "example": "created", + "enum": [ + "created", + "running", + "completed" + ] + }, + "output": { + "description": "Output of the task step.", + "type": "string", + "example": "I am going to use the write_to_file command and write Washington to a file called output.txt Date: Thu, 3 Apr 2025 01:34:24 +0200 Subject: [PATCH 4/6] Initialize early version of the C# SDK for Agent Protocol This commit introduces the foundational C# SDK for the Agent Protocol, generated using our custom OpenAPI generator tool. This independent project provides a strongly-typed client that enables seamless interaction with Agent Protocol-compatible APIs within .NET applications. P.S. This represents an early version of the SDK. Future improvements will include automating the generation process through GitHub Actions workflows to ensure the SDK remains synchronized with the OpenAPI specification as it evolves. This automation will encompass full CI/CD pipeline integration with automated versioning and package publishing to NuGet registries. --- packages/sdk/C#/Library/ApiClient.cs | 3343 ++++++++++++++++++++++++ packages/sdk/C#/Library/Library.csproj | 13 + 2 files changed, 3356 insertions(+) create mode 100644 packages/sdk/C#/Library/ApiClient.cs create mode 100644 packages/sdk/C#/Library/Library.csproj diff --git a/packages/sdk/C#/Library/ApiClient.cs b/packages/sdk/C#/Library/ApiClient.cs new file mode 100644 index 00000000..40745781 --- /dev/null +++ b/packages/sdk/C#/Library/ApiClient.cs @@ -0,0 +1,3343 @@ +//---------------------- +// +// Generated using the NSwag toolchain v14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org) +// +//---------------------- + +#nullable enable + +#pragma warning disable 108 // Disable "CS0108 '{derivedDto}.ToJson()' hides inherited member '{dtoBase}.ToJson()'. Use the new keyword if hiding was intended." +#pragma warning disable 114 // Disable "CS0114 '{derivedDto}.RaisePropertyChanged(String)' hides inherited member 'dtoBase.RaisePropertyChanged(String)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword." +#pragma warning disable 472 // Disable "CS0472 The result of the expression is always 'false' since a value of type 'Int32' is never equal to 'null' of type 'Int32?' +#pragma warning disable 612 // Disable "CS0612 '...' is obsolete" +#pragma warning disable 1573 // Disable "CS1573 Parameter '...' has no matching param tag in the XML comment for ... +#pragma warning disable 1591 // Disable "CS1591 Missing XML comment for publicly visible type or member ..." +#pragma warning disable 8073 // Disable "CS8073 The result of the expression is always 'false' since a value of type 'T' is never equal to 'null' of type 'T?'" +#pragma warning disable 3016 // Disable "CS3016 Arrays as attribute arguments is not CLS-compliant" +#pragma warning disable 8603 // Disable "CS8603 Possible null reference return" +#pragma warning disable 8604 // Disable "CS8604 Possible null reference argument for parameter" +#pragma warning disable 8625 // Disable "CS8625 Cannot convert null literal to non-nullable reference type" + +namespace AnotherAgentProtocolLibrary +{ + using System = global::System; + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial interface IApiClient + { + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Creates a task for the agent. + /// + /// A new agent task was successfully created. + /// A server side error occurred. + System.Threading.Tasks.Task CreateAgentTaskAsync(Body? body = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// List all tasks that have been created for the agent. + /// + /// Page number + /// Number of items per page + /// Returned list of agent's tasks. + /// A server side error occurred. + System.Threading.Tasks.Task ListAgentTasksAsync(int? current_page = null, int? page_size = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Get details about a specified agent task. + /// + /// ID of the task + /// Returned details about an agent task. + /// A server side error occurred. + System.Threading.Tasks.Task GetAgentTaskAsync(string task_id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// List all steps for the specified task. + /// + /// ID of the task. + /// Page number + /// Number of items per page + /// Returned list of agent's steps for the specified task. + /// A server side error occurred. + System.Threading.Tasks.Task ListAgentTaskStepsAsync(string task_id, int? current_page = null, int? page_size = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Execute a step in the specified agent task. + /// + /// ID of the task + /// Executed step for the agent task. + /// A server side error occurred. + System.Threading.Tasks.Task ExecuteAgentTaskStepAsync(string task_id, Body2? body = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Get details about a specified task step. + /// + /// ID of the task + /// ID of the step + /// Returned details about an agent task step. + /// A server side error occurred. + System.Threading.Tasks.Task GetAgentTaskStepAsync(string task_id, string step_id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// List all artifacts that have been created for the given task. + /// + /// ID of the task + /// Page number + /// Number of items per page + /// Returned the list of artifacts for the task. + /// A server side error occurred. + System.Threading.Tasks.Task ListAgentTaskArtifactsAsync(string task_id, int? current_page = null, int? page_size = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Upload an artifact for the specified task. + /// + /// ID of the task + /// File to upload. + /// Relative path of the artifact in the agent's workspace. + /// Returned the content of the artifact. + /// A server side error occurred. + System.Threading.Tasks.Task UploadAgentTaskArtifactsAsync(string task_id, FileParameter file = null, string? relative_path = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Download a specified artifact. + /// + /// ID of the task + /// ID of the artifact + /// Returned the content of the artifact. + /// A server side error occurred. + System.Threading.Tasks.Task DownloadAgentTaskArtifactAsync(string task_id, string artifact_id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); + + } + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class ApiClient : IApiClient + { + #pragma warning disable 8618 + private string _baseUrl; + #pragma warning restore 8618 + + private System.Net.Http.HttpClient _httpClient; + private static System.Lazy _settings = new System.Lazy(CreateSerializerSettings, true); + + public ApiClient(System.Net.Http.HttpClient httpClient) + { + _httpClient = httpClient; + } + + private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() + { + var settings = new Newtonsoft.Json.JsonSerializerSettings(); + UpdateJsonSerializerSettings(settings); + return settings; + } + + protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _settings.Value; } } + + static partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings); + + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url); + partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder); + partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response); + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Creates a task for the agent. + /// + /// A new agent task was successfully created. + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task CreateAgentTaskAsync(Body? body = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(body, _settings.Value); + var content_ = new System.Net.Http.StringContent(json_); + content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("POST"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "ap/v1/agent/tasks" + urlBuilder_.Append("ap/v1/agent/tasks"); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 422) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Unable to process request. Likely due to improperly formatted request.", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Internal Server Error", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// List all tasks that have been created for the agent. + /// + /// Page number + /// Number of items per page + /// Returned list of agent's tasks. + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task ListAgentTasksAsync(int? current_page = null, int? page_size = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + { + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "ap/v1/agent/tasks" + urlBuilder_.Append("ap/v1/agent/tasks"); + urlBuilder_.Append('?'); + if (current_page != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("current_page")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(current_page, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + if (page_size != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("page_size")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(page_size, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + urlBuilder_.Length--; + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Internal Server Error", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Get details about a specified agent task. + /// + /// ID of the task + /// Returned details about an agent task. + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task GetAgentTaskAsync(string task_id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + { + if (task_id == null) + throw new System.ArgumentNullException("task_id"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "ap/v1/agent/tasks/{task_id}" + urlBuilder_.Append("ap/v1/agent/tasks/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(task_id, System.Globalization.CultureInfo.InvariantCulture))); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Unable to find entity with a given identifier", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Internal Server Error", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// List all steps for the specified task. + /// + /// ID of the task. + /// Page number + /// Number of items per page + /// Returned list of agent's steps for the specified task. + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task ListAgentTaskStepsAsync(string task_id, int? current_page = null, int? page_size = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + { + if (task_id == null) + throw new System.ArgumentNullException("task_id"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "ap/v1/agent/tasks/{task_id}/steps" + urlBuilder_.Append("ap/v1/agent/tasks/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(task_id, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Append("/steps"); + urlBuilder_.Append('?'); + if (current_page != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("current_page")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(current_page, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + if (page_size != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("page_size")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(page_size, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + urlBuilder_.Length--; + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Unable to find entity with a given identifier", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Internal Server Error", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Execute a step in the specified agent task. + /// + /// ID of the task + /// Executed step for the agent task. + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task ExecuteAgentTaskStepAsync(string task_id, Body2? body = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + { + if (task_id == null) + throw new System.ArgumentNullException("task_id"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(body, _settings.Value); + var content_ = new System.Net.Http.StringContent(json_); + content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("POST"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "ap/v1/agent/tasks/{task_id}/steps" + urlBuilder_.Append("ap/v1/agent/tasks/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(task_id, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Append("/steps"); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Unable to find entity with a given identifier", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + if (status_ == 422) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Unable to process request. Likely due to improperly formatted request.", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Internal Server Error", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Get details about a specified task step. + /// + /// ID of the task + /// ID of the step + /// Returned details about an agent task step. + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task GetAgentTaskStepAsync(string task_id, string step_id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + { + if (task_id == null) + throw new System.ArgumentNullException("task_id"); + + if (step_id == null) + throw new System.ArgumentNullException("step_id"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "ap/v1/agent/tasks/{task_id}/steps/{step_id}" + urlBuilder_.Append("ap/v1/agent/tasks/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(task_id, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Append("/steps/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(step_id, System.Globalization.CultureInfo.InvariantCulture))); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Unable to find entity with a given identifier", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Internal Server Error", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// List all artifacts that have been created for the given task. + /// + /// ID of the task + /// Page number + /// Number of items per page + /// Returned the list of artifacts for the task. + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task ListAgentTaskArtifactsAsync(string task_id, int? current_page = null, int? page_size = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + { + if (task_id == null) + throw new System.ArgumentNullException("task_id"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "ap/v1/agent/tasks/{task_id}/artifacts" + urlBuilder_.Append("ap/v1/agent/tasks/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(task_id, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Append("/artifacts"); + urlBuilder_.Append('?'); + if (current_page != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("current_page")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(current_page, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + if (page_size != null) + { + urlBuilder_.Append(System.Uri.EscapeDataString("page_size")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(page_size, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); + } + urlBuilder_.Length--; + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Unable to find entity with a given identifier", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Internal Server Error", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Upload an artifact for the specified task. + /// + /// ID of the task + /// File to upload. + /// Relative path of the artifact in the agent's workspace. + /// Returned the content of the artifact. + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task UploadAgentTaskArtifactsAsync(string task_id, FileParameter file = null, string? relative_path = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + { + if (task_id == null) + throw new System.ArgumentNullException("task_id"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + var boundary_ = System.Guid.NewGuid().ToString(); + var content_ = new System.Net.Http.MultipartFormDataContent(boundary_); + content_.Headers.Remove("Content-Type"); + content_.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary_); + + if (file == null) + throw new System.ArgumentNullException("file"); + else + { + var content_file_ = new System.Net.Http.StreamContent(file.Data); + if (!string.IsNullOrEmpty(file.ContentType)) + content_file_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse(file.ContentType); + content_.Add(content_file_, "file", file.FileName ?? "file"); + } + + if (relative_path == null) + throw new System.ArgumentNullException("relative_path"); + else + { + content_.Add(new System.Net.Http.StringContent(ConvertToString(relative_path, System.Globalization.CultureInfo.InvariantCulture)), "relative_path"); + } + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("POST"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "ap/v1/agent/tasks/{task_id}/artifacts" + urlBuilder_.Append("ap/v1/agent/tasks/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(task_id, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Append("/artifacts"); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Unable to find entity with a given identifier", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Internal Server Error", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Download a specified artifact. + /// + /// ID of the task + /// ID of the artifact + /// Returned the content of the artifact. + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task DownloadAgentTaskArtifactAsync(string task_id, string artifact_id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + { + if (task_id == null) + throw new System.ArgumentNullException("task_id"); + + if (artifact_id == null) + throw new System.ArgumentNullException("artifact_id"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/octet-stream")); + + var urlBuilder_ = new System.Text.StringBuilder(); + + // Operation Path: "ap/v1/agent/tasks/{task_id}/artifacts/{artifact_id}" + urlBuilder_.Append("ap/v1/agent/tasks/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(task_id, System.Globalization.CultureInfo.InvariantCulture))); + urlBuilder_.Append("/artifacts/"); + urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(artifact_id, System.Globalization.CultureInfo.InvariantCulture))); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = new System.Collections.Generic.Dictionary>(); + foreach (var item_ in response_.Headers) + headers_[item_.Key] = item_.Value; + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200 || status_ == 206) + { + var responseStream_ = response_.Content == null ? System.IO.Stream.Null : await response_.Content.ReadAsStreamAsync().ConfigureAwait(false); + var fileResponse_ = new FileResponse(status_, headers_, responseStream_, null, response_); + disposeClient_ = false; disposeResponse_ = false; // response and client are disposed by FileResponse + return fileResponse_; + } + else + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Unable to find entity with a given identifier", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Internal Server Error", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + protected struct ObjectResponseResult + { + public ObjectResponseResult(T responseObject, string responseText) + { + this.Object = responseObject; + this.Text = responseText; + } + + public T Object { get; } + + public string Text { get; } + } + + public bool ReadResponseAsString { get; set; } + + protected virtual async System.Threading.Tasks.Task> ReadObjectResponseAsync(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Threading.CancellationToken cancellationToken) + { + if (response == null || response.Content == null) + { + return new ObjectResponseResult(default(T)!, string.Empty); + } + + if (ReadResponseAsString) + { + var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject(responseText, JsonSerializerSettings); + return new ObjectResponseResult(typedBody!, responseText); + } + catch (Newtonsoft.Json.JsonException exception) + { + var message = "Could not deserialize the response body string as " + typeof(T).FullName + "."; + throw new ApiException(message, (int)response.StatusCode, responseText, headers, exception); + } + } + else + { + try + { + using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) + using (var streamReader = new System.IO.StreamReader(responseStream)) + using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader)) + { + var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings); + var typedBody = serializer.Deserialize(jsonTextReader); + return new ObjectResponseResult(typedBody!, string.Empty); + } + } + catch (Newtonsoft.Json.JsonException exception) + { + var message = "Could not deserialize the response body stream as " + typeof(T).FullName + "."; + throw new ApiException(message, (int)response.StatusCode, string.Empty, headers, exception); + } + } + } + + private string ConvertToString(object? value, System.Globalization.CultureInfo cultureInfo) + { + if (value == null) + { + return ""; + } + + if (value is System.Enum) + { + var name = System.Enum.GetName(value.GetType(), value); + if (name != null) + { + var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name); + if (field != null) + { + var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute)) + as System.Runtime.Serialization.EnumMemberAttribute; + if (attribute != null) + { + return attribute.Value != null ? attribute.Value : name; + } + } + + var converted = System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo)); + return converted == null ? string.Empty : converted; + } + } + else if (value is bool) + { + return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant(); + } + else if (value is byte[]) + { + return System.Convert.ToBase64String((byte[]) value); + } + else if (value is string[]) + { + return string.Join(",", (string[])value); + } + else if (value.GetType().IsArray) + { + var valueArray = (System.Array)value; + var valueTextArray = new string[valueArray.Length]; + for (var i = 0; i < valueArray.Length; i++) + { + valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo); + } + return string.Join(",", valueTextArray); + } + + var result = System.Convert.ToString(value, cultureInfo); + return result == null ? "" : result; + } + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Pagination + { + /// + /// Total number of items. + /// + [Newtonsoft.Json.JsonProperty("total_items", Required = Newtonsoft.Json.Required.Always)] + public int Total_items { get; set; } = default!; + + /// + /// Total number of pages. + /// + [Newtonsoft.Json.JsonProperty("total_pages", Required = Newtonsoft.Json.Required.Always)] + public int Total_pages { get; set; } = default!; + + /// + /// Current_page page number. + /// + [Newtonsoft.Json.JsonProperty("current_page", Required = Newtonsoft.Json.Required.Always)] + public int Current_page { get; set; } = default!; + + /// + /// Number of items per page. + /// + [Newtonsoft.Json.JsonProperty("page_size", Required = Newtonsoft.Json.Required.Always)] + public int Page_size { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class TaskListResponse + { + [Newtonsoft.Json.JsonProperty("tasks", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Tasks { get; set; } = new System.Collections.ObjectModel.Collection(); + + [Newtonsoft.Json.JsonProperty("pagination", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public Pagination2 Pagination { get; set; } = new Pagination2(); + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class TaskStepsListResponse + { + [Newtonsoft.Json.JsonProperty("steps", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Steps { get; set; } = new System.Collections.ObjectModel.Collection(); + + [Newtonsoft.Json.JsonProperty("pagination", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public Pagination3 Pagination { get; set; } = new Pagination3(); + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class TaskArtifactsListResponse + { + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + [Newtonsoft.Json.JsonProperty("pagination", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public Pagination4 Pagination { get; set; } = new Pagination4(); + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Input parameters for the task. Any value is allowed. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class TaskInput + { + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Artifact + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Artifact to upload to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class ArtifactUpload + { + /// + /// File to upload. + /// + [Newtonsoft.Json.JsonProperty("file", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public byte[] File { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Input parameters for the task step. Any value is allowed. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class StepInput + { + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Output that the task step has produced. Any value is allowed. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class StepOutput + { + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class TaskRequestBody + { + /// + /// Input prompt for the task. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Task : Anonymous + { + /// + /// The ID of the task. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// A list of artifacts that the task has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class StepRequestBody + { + /// + /// Input prompt for the step. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task step. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Step : Anonymous2 + { + /// + /// The ID of the task this step belongs to. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// The ID of the task step. + /// + [Newtonsoft.Json.JsonProperty("step_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Step_id { get; set; } = default!; + + /// + /// The name of the task step. + /// + [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Name { get; set; } = default!; + + /// + /// The status of the task step. + /// + [Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public StepStatus Status { get; set; } = default!; + + /// + /// Output of the task step. + /// + [Newtonsoft.Json.JsonProperty("output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Output { get; set; } = default!; + + /// + /// Output that the task step has produced. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object? Additional_output { get; set; } = default!; + + /// + /// A list of artifacts that the step has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + /// + /// Whether this is the last step in the task. + /// + [Newtonsoft.Json.JsonProperty("is_last", Required = Newtonsoft.Json.Required.Always)] + public bool Is_last { get; set; } = false; + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Body + { + /// + /// Input prompt for the task. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Body2 + { + /// + /// Input prompt for the step. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task step. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response : Anonymous3 + { + /// + /// The ID of the task. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// A list of artifacts that the task has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response2 + { + [Newtonsoft.Json.JsonProperty("tasks", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Tasks { get; set; } = new System.Collections.ObjectModel.Collection(); + + [Newtonsoft.Json.JsonProperty("pagination", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public Pagination5 Pagination { get; set; } = new Pagination5(); + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response3 : Anonymous4 + { + /// + /// The ID of the task. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// A list of artifacts that the task has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response4 + { + [Newtonsoft.Json.JsonProperty("steps", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Steps { get; set; } = new System.Collections.ObjectModel.Collection(); + + [Newtonsoft.Json.JsonProperty("pagination", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public Pagination6 Pagination { get; set; } = new Pagination6(); + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response5 : Anonymous5 + { + /// + /// The ID of the task this step belongs to. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// The ID of the task step. + /// + [Newtonsoft.Json.JsonProperty("step_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Step_id { get; set; } = default!; + + /// + /// The name of the task step. + /// + [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Name { get; set; } = default!; + + /// + /// The status of the task step. + /// + [Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public Response5Status Status { get; set; } = default!; + + /// + /// Output of the task step. + /// + [Newtonsoft.Json.JsonProperty("output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Output { get; set; } = default!; + + /// + /// Output that the task step has produced. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object? Additional_output { get; set; } = default!; + + /// + /// A list of artifacts that the step has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + /// + /// Whether this is the last step in the task. + /// + [Newtonsoft.Json.JsonProperty("is_last", Required = Newtonsoft.Json.Required.Always)] + public bool Is_last { get; set; } = false; + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response6 : Anonymous6 + { + /// + /// The ID of the task this step belongs to. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// The ID of the task step. + /// + [Newtonsoft.Json.JsonProperty("step_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Step_id { get; set; } = default!; + + /// + /// The name of the task step. + /// + [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Name { get; set; } = default!; + + /// + /// The status of the task step. + /// + [Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public Response6Status Status { get; set; } = default!; + + /// + /// Output of the task step. + /// + [Newtonsoft.Json.JsonProperty("output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Output { get; set; } = default!; + + /// + /// Output that the task step has produced. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object? Additional_output { get; set; } = default!; + + /// + /// A list of artifacts that the step has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + /// + /// Whether this is the last step in the task. + /// + [Newtonsoft.Json.JsonProperty("is_last", Required = Newtonsoft.Json.Required.Always)] + public bool Is_last { get; set; } = false; + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response7 + { + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + [Newtonsoft.Json.JsonProperty("pagination", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public Pagination7 Pagination { get; set; } = new Pagination7(); + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response8 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response9 + { + /// + /// Message stating the entity was not found + /// + [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Message { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response10 + { + /// + /// Message stating the entity was not found + /// + [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Message { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response11 + { + /// + /// Message stating the entity was not found + /// + [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Message { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response12 + { + /// + /// Message stating the entity was not found + /// + [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Message { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response13 + { + /// + /// Message stating the entity was not found + /// + [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Message { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response14 + { + /// + /// Message stating the entity was not found + /// + [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Message { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Response15 + { + /// + /// Message stating the entity was not found + /// + [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Message { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Tasks : Anonymous7 + { + /// + /// The ID of the task. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// A list of artifacts that the task has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Pagination2 + { + /// + /// Total number of items. + /// + [Newtonsoft.Json.JsonProperty("total_items", Required = Newtonsoft.Json.Required.Always)] + public int Total_items { get; set; } = default!; + + /// + /// Total number of pages. + /// + [Newtonsoft.Json.JsonProperty("total_pages", Required = Newtonsoft.Json.Required.Always)] + public int Total_pages { get; set; } = default!; + + /// + /// Current_page page number. + /// + [Newtonsoft.Json.JsonProperty("current_page", Required = Newtonsoft.Json.Required.Always)] + public int Current_page { get; set; } = default!; + + /// + /// Number of items per page. + /// + [Newtonsoft.Json.JsonProperty("page_size", Required = Newtonsoft.Json.Required.Always)] + public int Page_size { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Steps : Anonymous8 + { + /// + /// The ID of the task this step belongs to. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// The ID of the task step. + /// + [Newtonsoft.Json.JsonProperty("step_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Step_id { get; set; } = default!; + + /// + /// The name of the task step. + /// + [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Name { get; set; } = default!; + + /// + /// The status of the task step. + /// + [Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public StepsStatus Status { get; set; } = default!; + + /// + /// Output of the task step. + /// + [Newtonsoft.Json.JsonProperty("output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Output { get; set; } = default!; + + /// + /// Output that the task step has produced. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object? Additional_output { get; set; } = default!; + + /// + /// A list of artifacts that the step has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + /// + /// Whether this is the last step in the task. + /// + [Newtonsoft.Json.JsonProperty("is_last", Required = Newtonsoft.Json.Required.Always)] + public bool Is_last { get; set; } = false; + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Pagination3 + { + /// + /// Total number of items. + /// + [Newtonsoft.Json.JsonProperty("total_items", Required = Newtonsoft.Json.Required.Always)] + public int Total_items { get; set; } = default!; + + /// + /// Total number of pages. + /// + [Newtonsoft.Json.JsonProperty("total_pages", Required = Newtonsoft.Json.Required.Always)] + public int Total_pages { get; set; } = default!; + + /// + /// Current_page page number. + /// + [Newtonsoft.Json.JsonProperty("current_page", Required = Newtonsoft.Json.Required.Always)] + public int Current_page { get; set; } = default!; + + /// + /// Number of items per page. + /// + [Newtonsoft.Json.JsonProperty("page_size", Required = Newtonsoft.Json.Required.Always)] + public int Page_size { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Artifacts + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Pagination4 + { + /// + /// Total number of items. + /// + [Newtonsoft.Json.JsonProperty("total_items", Required = Newtonsoft.Json.Required.Always)] + public int Total_items { get; set; } = default!; + + /// + /// Total number of pages. + /// + [Newtonsoft.Json.JsonProperty("total_pages", Required = Newtonsoft.Json.Required.Always)] + public int Total_pages { get; set; } = default!; + + /// + /// Current_page page number. + /// + [Newtonsoft.Json.JsonProperty("current_page", Required = Newtonsoft.Json.Required.Always)] + public int Current_page { get; set; } = default!; + + /// + /// Number of items per page. + /// + [Newtonsoft.Json.JsonProperty("page_size", Required = Newtonsoft.Json.Required.Always)] + public int Page_size { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous + { + /// + /// Input prompt for the task. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous2 + { + /// + /// Input prompt for the step. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task step. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public enum StepStatus + { + + [System.Runtime.Serialization.EnumMember(Value = @"created")] + Created = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"running")] + Running = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"completed")] + Completed = 2, + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts2 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous3 + { + /// + /// Input prompt for the task. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts3 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class tasks : Anonymous9 + { + /// + /// The ID of the task. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// A list of artifacts that the task has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Pagination5 + { + /// + /// Total number of items. + /// + [Newtonsoft.Json.JsonProperty("total_items", Required = Newtonsoft.Json.Required.Always)] + public int Total_items { get; set; } = default!; + + /// + /// Total number of pages. + /// + [Newtonsoft.Json.JsonProperty("total_pages", Required = Newtonsoft.Json.Required.Always)] + public int Total_pages { get; set; } = default!; + + /// + /// Current_page page number. + /// + [Newtonsoft.Json.JsonProperty("current_page", Required = Newtonsoft.Json.Required.Always)] + public int Current_page { get; set; } = default!; + + /// + /// Number of items per page. + /// + [Newtonsoft.Json.JsonProperty("page_size", Required = Newtonsoft.Json.Required.Always)] + public int Page_size { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous4 + { + /// + /// Input prompt for the task. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts4 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class steps : Anonymous10 + { + /// + /// The ID of the task this step belongs to. + /// + [Newtonsoft.Json.JsonProperty("task_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Task_id { get; set; } = default!; + + /// + /// The ID of the task step. + /// + [Newtonsoft.Json.JsonProperty("step_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Step_id { get; set; } = default!; + + /// + /// The name of the task step. + /// + [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Name { get; set; } = default!; + + /// + /// The status of the task step. + /// + [Newtonsoft.Json.JsonProperty("status", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public stepsStatus Status { get; set; } = default!; + + /// + /// Output of the task step. + /// + [Newtonsoft.Json.JsonProperty("output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Output { get; set; } = default!; + + /// + /// Output that the task step has produced. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_output", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object? Additional_output { get; set; } = default!; + + /// + /// A list of artifacts that the step has produced. + /// + [Newtonsoft.Json.JsonProperty("artifacts", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection Artifacts { get; set; } = new System.Collections.ObjectModel.Collection(); + + /// + /// Whether this is the last step in the task. + /// + [Newtonsoft.Json.JsonProperty("is_last", Required = Newtonsoft.Json.Required.Always)] + public bool Is_last { get; set; } = false; + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Pagination6 + { + /// + /// Total number of items. + /// + [Newtonsoft.Json.JsonProperty("total_items", Required = Newtonsoft.Json.Required.Always)] + public int Total_items { get; set; } = default!; + + /// + /// Total number of pages. + /// + [Newtonsoft.Json.JsonProperty("total_pages", Required = Newtonsoft.Json.Required.Always)] + public int Total_pages { get; set; } = default!; + + /// + /// Current_page page number. + /// + [Newtonsoft.Json.JsonProperty("current_page", Required = Newtonsoft.Json.Required.Always)] + public int Current_page { get; set; } = default!; + + /// + /// Number of items per page. + /// + [Newtonsoft.Json.JsonProperty("page_size", Required = Newtonsoft.Json.Required.Always)] + public int Page_size { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous5 + { + /// + /// Input prompt for the step. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task step. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public enum Response5Status + { + + [System.Runtime.Serialization.EnumMember(Value = @"created")] + Created = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"running")] + Running = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"completed")] + Completed = 2, + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts5 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous6 + { + /// + /// Input prompt for the step. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task step. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public enum Response6Status + { + + [System.Runtime.Serialization.EnumMember(Value = @"created")] + Created = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"running")] + Running = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"completed")] + Completed = 2, + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts6 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts7 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Pagination7 + { + /// + /// Total number of items. + /// + [Newtonsoft.Json.JsonProperty("total_items", Required = Newtonsoft.Json.Required.Always)] + public int Total_items { get; set; } = default!; + + /// + /// Total number of pages. + /// + [Newtonsoft.Json.JsonProperty("total_pages", Required = Newtonsoft.Json.Required.Always)] + public int Total_pages { get; set; } = default!; + + /// + /// Current_page page number. + /// + [Newtonsoft.Json.JsonProperty("current_page", Required = Newtonsoft.Json.Required.Always)] + public int Current_page { get; set; } = default!; + + /// + /// Number of items per page. + /// + [Newtonsoft.Json.JsonProperty("page_size", Required = Newtonsoft.Json.Required.Always)] + public int Page_size { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous7 + { + /// + /// Input prompt for the task. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts8 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous8 + { + /// + /// Input prompt for the step. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task step. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public enum StepsStatus + { + + [System.Runtime.Serialization.EnumMember(Value = @"created")] + Created = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"running")] + Running = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"completed")] + Completed = 2, + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts9 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous9 + { + /// + /// Input prompt for the task. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts10 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + /// + /// Body of the task request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class Anonymous10 + { + /// + /// Input prompt for the step. + /// + [Newtonsoft.Json.JsonProperty("input", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Input { get; set; } = default!; + + /// + /// Input parameters for the task step. Any value is allowed. + /// + [Newtonsoft.Json.JsonProperty("additional_input", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public object Additional_input { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public enum stepsStatus + { + + [System.Runtime.Serialization.EnumMember(Value = @"created")] + Created = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"running")] + Running = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"completed")] + Completed = 2, + + } + + /// + /// An Artifact either created by or submitted to the agent. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class artifacts11 + { + /// + /// ID of the artifact. + /// + [Newtonsoft.Json.JsonProperty("artifact_id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Artifact_id { get; set; } = default!; + + /// + /// Whether the artifact has been created by the agent. + /// + [Newtonsoft.Json.JsonProperty("agent_created", Required = Newtonsoft.Json.Required.Always)] + public bool Agent_created { get; set; } = default!; + + /// + /// Filename of the artifact. + /// + [Newtonsoft.Json.JsonProperty("file_name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string File_name { get; set; } = default!; + + /// + /// Relative path of the artifact in the agent's workspace. + /// + [Newtonsoft.Json.JsonProperty("relative_path", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string? Relative_path { get; set; } = default!; + + private System.Collections.Generic.IDictionary? _additionalProperties; + + [Newtonsoft.Json.JsonExtensionData] + public System.Collections.Generic.IDictionary AdditionalProperties + { + get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary()); } + set { _additionalProperties = value; } + } + + } + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class FileParameter + { + public FileParameter(System.IO.Stream data) + : this (data, null, null) + { + } + + public FileParameter(System.IO.Stream data, string? fileName) + : this (data, fileName, null) + { + } + + public FileParameter(System.IO.Stream data, string? fileName, string? contentType) + { + Data = data; + FileName = fileName; + ContentType = contentType; + } + + public System.IO.Stream Data { get; private set; } + + public string? FileName { get; private set; } + + public string? ContentType { get; private set; } + } + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class FileResponse : System.IDisposable + { + private System.IDisposable? _client; + private System.IDisposable? _response; + + public int StatusCode { get; private set; } + + public System.Collections.Generic.IReadOnlyDictionary> Headers { get; private set; } + + public System.IO.Stream Stream { get; private set; } + + public bool IsPartial + { + get { return StatusCode == 206; } + } + + public FileResponse(int statusCode, System.Collections.Generic.IReadOnlyDictionary> headers, System.IO.Stream stream, System.IDisposable? client, System.IDisposable? response) + { + StatusCode = statusCode; + Headers = headers; + Stream = stream; + _client = client; + _response = response; + } + + public void Dispose() + { + Stream.Dispose(); + if (_response != null) + _response.Dispose(); + if (_client != null) + _client.Dispose(); + } + } + + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class ApiException : System.Exception + { + public int StatusCode { get; private set; } + + public string? Response { get; private set; } + + public System.Collections.Generic.IReadOnlyDictionary> Headers { get; private set; } + + public ApiException(string message, int statusCode, string? response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Exception? innerException) + : base(message + "\n\nStatus: " + statusCode + "\nResponse: \n" + ((response == null) ? "(null)" : response.Substring(0, response.Length >= 512 ? 512 : response.Length)), innerException) + { + StatusCode = statusCode; + Response = response; + Headers = headers; + } + + public override string ToString() + { + return string.Format("HTTP Response: \n\n{0}\n\n{1}", Response, base.ToString()); + } + } + + [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.3.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class ApiException : ApiException + { + public TResult Result { get; private set; } + + public ApiException(string message, int statusCode, string? response, System.Collections.Generic.IReadOnlyDictionary> headers, TResult result, System.Exception? innerException) + : base(message, statusCode, response, headers, innerException) + { + Result = result; + } + } + +} + +#pragma warning restore 108 +#pragma warning restore 114 +#pragma warning restore 472 +#pragma warning restore 612 +#pragma warning restore 1573 +#pragma warning restore 1591 +#pragma warning restore 8073 +#pragma warning restore 3016 +#pragma warning restore 8603 +#pragma warning restore 8604 +#pragma warning restore 8625 \ No newline at end of file diff --git a/packages/sdk/C#/Library/Library.csproj b/packages/sdk/C#/Library/Library.csproj new file mode 100644 index 00000000..2f352285 --- /dev/null +++ b/packages/sdk/C#/Library/Library.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + From ae2a50a0568ae37820c30305e0e8ef43cf0f78e2 Mon Sep 17 00:00:00 2001 From: jeff nasseri Date: Thu, 3 Apr 2025 01:36:24 +0200 Subject: [PATCH 5/6] Initialize basic sample project demonstrating C# SDK usage for Agent Protocol This commit introduces a comprehensive sample application that showcases the practical implementation of the Agent Protocol C# SDK. The project serves as both documentation and a working reference implementation for developers integrating the SDK into their own .NET applications. The accompanying README provides detailed explanations of the project structure, architecture decisions, and step-by-step instructions for running the examples. This sample serves as the foundation for developers to understand the SDK's capabilities and adapt the patterns to their specific use cases. --- .../ConsoleApplication/AgentTaskModels.cs | 49 ++ .../ConsoleApplication/AgentTaskService.cs | 409 ++++++++++++++ .../ConsoleApplication.csproj | 29 + .../ConsoleApplication/IAgentTaskService.cs | 15 + .../C#/Examples/ConsoleApplication/Program.cs | 514 ++++++++++++++++++ .../C#/Examples/ConsoleApplication/README.md | 61 +++ .../ConsoleApplication/appsettings.json | 7 + 7 files changed, 1084 insertions(+) create mode 100644 packages/sdk/C#/Examples/ConsoleApplication/AgentTaskModels.cs create mode 100644 packages/sdk/C#/Examples/ConsoleApplication/AgentTaskService.cs create mode 100644 packages/sdk/C#/Examples/ConsoleApplication/ConsoleApplication.csproj create mode 100644 packages/sdk/C#/Examples/ConsoleApplication/IAgentTaskService.cs create mode 100644 packages/sdk/C#/Examples/ConsoleApplication/Program.cs create mode 100644 packages/sdk/C#/Examples/ConsoleApplication/README.md create mode 100644 packages/sdk/C#/Examples/ConsoleApplication/appsettings.json diff --git a/packages/sdk/C#/Examples/ConsoleApplication/AgentTaskModels.cs b/packages/sdk/C#/Examples/ConsoleApplication/AgentTaskModels.cs new file mode 100644 index 00000000..5574ee74 --- /dev/null +++ b/packages/sdk/C#/Examples/ConsoleApplication/AgentTaskModels.cs @@ -0,0 +1,49 @@ +// ReSharper disable All +#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. +namespace ConsoleApplication +{ + // Simplified model classes that wrap the SDK response types + // to make them easier to use in the console application + + public class AgentTask + { + public string Id { get; set; } + public string Input { get; set; } + public string Status { get; set; } + public DateTime CreatedAt { get; set; } + public List Artifacts { get; set; } = new(); + } + + public class AgentStep + { + public string Id { get; set; } + public string TaskId { get; set; } + public string Input { get; set; } + public string Output { get; set; } + public string Status { get; set; } + public object AdditionalOutput { get; set; } + public bool IsLast { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime? ExecutedAt { get; set; } + public List Artifacts { get; set; } = new(); + } + + public class AgentArtifact + { + public string Id { get; set; } + public bool AgentCreated { get; set; } + public string FileName { get; set; } + public string RelativePath { get; set; } + public long Size { get; set; } + public DateTime CreatedAt { get; set; } + } + + public class PaginatedData + { + public List Data { get; set; } = new(); + public int TotalCount { get; set; } + public int CurrentPage { get; set; } + public int PageSize { get; set; } + public int TotalPages { get; set; } + } +} \ No newline at end of file diff --git a/packages/sdk/C#/Examples/ConsoleApplication/AgentTaskService.cs b/packages/sdk/C#/Examples/ConsoleApplication/AgentTaskService.cs new file mode 100644 index 00000000..009e429c --- /dev/null +++ b/packages/sdk/C#/Examples/ConsoleApplication/AgentTaskService.cs @@ -0,0 +1,409 @@ +using AnotherAgentProtocolLibrary; +#pragma warning disable CS8601 // Possible null reference assignment. + +namespace ConsoleApplication +{ + public class AgentTaskService : IAgentTaskService + { + private readonly IApiClient _apiClient; + + public AgentTaskService(IApiClient apiClient) + { + _apiClient = apiClient ?? throw new ArgumentNullException(nameof(apiClient)); + } + + public async Task CreateTaskAsync(string input, object? additionalInput = null) + { + Body body = new() { Input = input }; + if (additionalInput != null) + { + body.Additional_input = additionalInput; + } + + Response response = await _apiClient.CreateAgentTaskAsync(body); + return MapToAgentTask(response); + } + + public async Task> GetTasksAsync(int? page = null, int? pageSize = null) + { + Response2 response = await _apiClient.ListAgentTasksAsync(page, pageSize); + + PaginatedData result = new() + { + CurrentPage = response.Pagination.Current_page, + PageSize = response.Pagination.Page_size, + TotalCount = response.Pagination.Total_items, + TotalPages = response.Pagination.Total_pages, + }; + + return result; + } + + public async Task GetTaskAsync(string taskId) + { + Response3 response = await _apiClient.GetAgentTaskAsync(taskId); + return MapToAgentTask(response); + } + + public async Task> GetTaskStepsAsync(string taskId, int? page = null, int? pageSize = null) + { + Response4 response = await _apiClient.ListAgentTaskStepsAsync(taskId, page, pageSize); + + PaginatedData result = new() + { + CurrentPage = response.Pagination.Current_page, + PageSize = response.Pagination.Page_size, + TotalCount = response.Pagination.Total_items, + TotalPages = response.Pagination.Total_pages, + }; + + return result; + } + + public async Task ExecuteTaskStepAsync(string taskId, string input, object? additionalInput = null) + { + Body2 body = new() { Input = input }; + if (additionalInput != null) + { + body.Additional_input = additionalInput; + } + + Response5 response = await _apiClient.ExecuteAgentTaskStepAsync(taskId, body); + return MapToAgentStep(response); + } + + public async Task GetTaskStepAsync(string taskId, string stepId) + { + Response6 response = await _apiClient.GetAgentTaskStepAsync(taskId, stepId); + return MapToAgentStep(response); + } + + public async Task> GetTaskArtifactsAsync(string taskId, int? page = null, int? pageSize = null) + { + Response7 response = await _apiClient.ListAgentTaskArtifactsAsync(taskId, page, pageSize); + + PaginatedData result = new() + { + CurrentPage = response.Pagination.Current_page, + PageSize = response.Pagination.Page_size, + TotalCount = response.Pagination.Total_items, + TotalPages = response.Pagination.Total_pages, + Data = response.Artifacts.Select(MapToAgentArtifact).ToList() + }; + + return result; + } + + public async Task UploadArtifactAsync(string taskId, string filePath, string relativePath) + { + // Read the file + byte[] fileBytes = await File.ReadAllBytesAsync(filePath); + string fileName = Path.GetFileName(filePath); + + // Create FileParameter + FileParameter fileParameter = new( + new MemoryStream(fileBytes), + fileName, + GetMimeType(fileName) + ); + + Response8 response = await _apiClient.UploadAgentTaskArtifactsAsync(taskId, fileParameter, relativePath); + return MapToAgentArtifact(response); + } + + public async Task DownloadArtifactAsync(string taskId, string artifactId, string outputPath) + { + FileResponse response = await _apiClient.DownloadAgentTaskArtifactAsync(taskId, artifactId); + + await using (FileStream fileStream = File.Create(outputPath)) + { + await response.Stream.CopyToAsync(fileStream); + } + + return new FileInfo(outputPath); + } + + #region Helper Methods + + private AgentTask MapToAgentTask(Response response) + { + return new AgentTask + { + Id = response.Task_id, + Input = response.Input, + Status = "Created", // Assuming status from Response, which isn't explicitly defined in SDK + CreatedAt = DateTime.Now, // SDK doesn't appear to provide creation time in the response + Artifacts = response.Artifacts?.Select(MapToAgentArtifact).ToList() ?? [] + }; + } + + private AgentTask MapToAgentTask(Response3 response) + { + return new AgentTask + { + Id = response.Task_id, + Input = response.Input, + Status = "Active", // Assuming status + CreatedAt = DateTime.Now, // SDK doesn't appear to provide creation time + Artifacts = response.Artifacts?.Select(MapToAgentArtifact).ToList() ?? [] + }; + } + + private AgentTask MapToAgentTask(Tasks task) + { + return new AgentTask + { + Id = task.Task_id, + Input = task.Input, + Status = "Active", // Assuming status + CreatedAt = DateTime.Now, // Not provided in SDK + Artifacts = task.Artifacts?.Select(MapToAgentArtifact).ToList() ?? [] + }; + } + + private AgentStep MapToAgentStep(Response5 response) + { + return new AgentStep + { + Id = response.Step_id, + TaskId = response.Task_id, + Input = response.Input, + Output = response.Output, + Status = response.Status.ToString(), + AdditionalOutput = response.Additional_output, + IsLast = response.Is_last, + CreatedAt = DateTime.Now, // Not provided in SDK + ExecutedAt = DateTime.Now, // Assuming just executed + Artifacts = response.Artifacts?.Select(MapToAgentArtifact).ToList() ?? [] + }; + } + + private AgentStep MapToAgentStep(Response6 response) + { + return new AgentStep + { + Id = response.Step_id, + TaskId = response.Task_id, + Input = response.Input, + Output = response.Output, + Status = response.Status.ToString(), + AdditionalOutput = response.Additional_output, + IsLast = response.Is_last, + CreatedAt = DateTime.Now, // Not provided in SDK + ExecutedAt = response.Status == Response6Status.Completed ? DateTime.Now : null, + Artifacts = response.Artifacts?.Select(MapToAgentArtifact).ToList() ?? [] + }; + } + + private AgentStep MapToAgentStep(Steps step) + { + return new AgentStep + { + Id = step.Step_id, + TaskId = step.Task_id, + Input = step.Input, + Output = step.Output, + Status = step.Status.ToString(), + AdditionalOutput = step.Additional_output, + IsLast = step.Is_last, + CreatedAt = DateTime.Now, // Not provided in SDK + ExecutedAt = step.Status == StepsStatus.Completed ? DateTime.Now : null, + Artifacts = step.Artifacts?.Select(MapToAgentArtifact).ToList() ?? [] + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, // Size not provided in SDK + CreatedAt = DateTime.Now // Not provided in SDK + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts2 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, // Size not provided + CreatedAt = DateTime.Now // Not provided + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts3 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, // Size not provided + CreatedAt = DateTime.Now // Not provided + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts4 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, + CreatedAt = DateTime.Now + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts5 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, + CreatedAt = DateTime.Now + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts6 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, + CreatedAt = DateTime.Now + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts7 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, + CreatedAt = DateTime.Now + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts8 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, + CreatedAt = DateTime.Now + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts9 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, + CreatedAt = DateTime.Now + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts10 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, + CreatedAt = DateTime.Now + }; + } + + private AgentArtifact MapToAgentArtifact(artifacts11 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, + CreatedAt = DateTime.Now + }; + } + + private AgentArtifact MapToAgentArtifact(Response8 artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, // Not available in response + CreatedAt = DateTime.Now // Not available in response + }; + } + + private AgentArtifact MapToAgentArtifact(Artifacts artifact) + { + return new AgentArtifact + { + Id = artifact.Artifact_id, + AgentCreated = artifact.Agent_created, + FileName = artifact.File_name, + RelativePath = artifact.Relative_path, + Size = 0, // Not available + CreatedAt = DateTime.Now // Not available + }; + } + + private string GetMimeType(string fileName) + { + string extension = Path.GetExtension(fileName).ToLowerInvariant(); + + return extension switch + { + ".txt" => "text/plain", + ".pdf" => "application/pdf", + ".doc" => "application/msword", + ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".xls" => "application/vnd.ms-excel", + ".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".png" => "image/png", + ".jpg" or ".jpeg" => "image/jpeg", + ".gif" => "image/gif", + ".csv" => "text/csv", + ".json" => "application/json", + ".xml" => "application/xml", + ".zip" => "application/zip", + _ => "application/octet-stream" + }; + } + + #endregion + } +} diff --git a/packages/sdk/C#/Examples/ConsoleApplication/ConsoleApplication.csproj b/packages/sdk/C#/Examples/ConsoleApplication/ConsoleApplication.csproj new file mode 100644 index 00000000..fa00ff37 --- /dev/null +++ b/packages/sdk/C#/Examples/ConsoleApplication/ConsoleApplication.csproj @@ -0,0 +1,29 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + + + PreserveNewest + + + + + + + + \ No newline at end of file diff --git a/packages/sdk/C#/Examples/ConsoleApplication/IAgentTaskService.cs b/packages/sdk/C#/Examples/ConsoleApplication/IAgentTaskService.cs new file mode 100644 index 00000000..59cf193b --- /dev/null +++ b/packages/sdk/C#/Examples/ConsoleApplication/IAgentTaskService.cs @@ -0,0 +1,15 @@ +namespace ConsoleApplication; + +#pragma warning disable CS8601 +public interface IAgentTaskService +{ + Task CreateTaskAsync(string input, object? additionalInput = null); + Task> GetTasksAsync(int? page = null, int? pageSize = null); + Task GetTaskAsync(string taskId); + Task> GetTaskStepsAsync(string taskId, int? page = null, int? pageSize = null); + Task ExecuteTaskStepAsync(string taskId, string input, object? additionalInput = null); + Task GetTaskStepAsync(string taskId, string stepId); + Task> GetTaskArtifactsAsync(string taskId, int? page = null, int? pageSize = null); + Task UploadArtifactAsync(string taskId, string filePath, string relativePath); + Task DownloadArtifactAsync(string taskId, string artifactId, string outputPath); +} \ No newline at end of file diff --git a/packages/sdk/C#/Examples/ConsoleApplication/Program.cs b/packages/sdk/C#/Examples/ConsoleApplication/Program.cs new file mode 100644 index 00000000..48557ec7 --- /dev/null +++ b/packages/sdk/C#/Examples/ConsoleApplication/Program.cs @@ -0,0 +1,514 @@ +using System.Net.Http.Headers; +using AnotherAgentProtocolLibrary; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Spectre.Console; +using Task = System.Threading.Tasks.Task; +// ReSharper disable All + +namespace ConsoleApplication; + +public class Program +{ + public static async Task Main(string[] args) + { + try + { + // Set up Configuration + IConfigurationRoot configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false) + .Build(); + + // Build service provider with DI + ServiceProvider serviceProvider = ConfigureServices(configuration); + + // Get the required services + serviceProvider.GetRequiredService(); + ILogger logger = serviceProvider.GetRequiredService>(); + IAgentTaskService agentService = serviceProvider.GetRequiredService(); + + // Main application loop + bool exit = false; + while (!exit) + { + exit = await RunMainMenuAsync(agentService, logger); + } + } + catch (Exception ex) + { + AnsiConsole.MarkupLine($"[bold red]Error:[/] {ex.Message}"); + AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything); + } + } + + private static ServiceProvider ConfigureServices(IConfiguration configuration) + { + ServiceCollection services = new(); + + // Add logging + services.AddLogging(builder => + { + builder.AddConsole(); + builder.SetMinimumLevel(LogLevel.Information); + }); + + // Add HttpClient for API Client + services.AddHttpClient(client => + { + string baseUrl = configuration["ApiSettings:BaseUrl"] ?? throw new InvalidOperationException("Base URL not configured"); + string apiKey = configuration["ApiSettings:ApiKey"] ?? throw new InvalidOperationException("API Key not configured"); + + client.BaseAddress = new Uri(baseUrl); + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey); + + if (int.TryParse(configuration["ApiSettings:DefaultTimeout"], out int timeout)) + { + client.Timeout = TimeSpan.FromSeconds(timeout); + } + }); + + // Register the agent task service + services.AddScoped(); + + return services.BuildServiceProvider(); + } + + private static async Task RunMainMenuAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.Clear(); + AnsiConsole.Write(new FigletText("Agent Tasks API").Centered().Color(Color.Blue)); + AnsiConsole.WriteLine(); + + string choice = AnsiConsole.Prompt( + new SelectionPrompt() + .Title("What would you like to do?") + .PageSize(10) + .AddChoices(new[] + { + "Create a New Task", + "List All Tasks", + "Get Task Details", + "List Task Steps", + "Execute Task Step", + "Get Step Details", + "List Task Artifacts", + "Upload Artifact", + "Download Artifact", + "Exit" + })); + + switch (choice) + { + case "Create a New Task": + await CreateNewTaskAsync(agentService, logger); + break; + case "List All Tasks": + await ListAllTasksAsync(agentService, logger); + break; + case "Get Task Details": + await GetTaskDetailsAsync(agentService, logger); + break; + case "List Task Steps": + await ListTaskStepsAsync(agentService, logger); + break; + case "Execute Task Step": + await ExecuteTaskStepAsync(agentService, logger); + break; + case "Get Step Details": + await GetStepDetailsAsync(agentService, logger); + break; + case "List Task Artifacts": + await ListTaskArtifactsAsync(agentService, logger); + break; + case "Upload Artifact": + await UploadArtifactAsync(agentService, logger); + break; + case "Download Artifact": + await DownloadArtifactAsync(agentService, logger); + break; + case "Exit": + return true; + } + + // Wait for user to press a key before returning to the menu + AnsiConsole.WriteLine(); + AnsiConsole.Markup("[dim]Press any key to continue...[/]"); + Console.ReadKey(true); + return false; + } + + private static async Task CreateNewTaskAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.MarkupLine("[bold]Create a New Task[/]"); + AnsiConsole.WriteLine(); + + string taskInput = AnsiConsole.Ask("Enter task input text:"); + + try + { + logger.LogInformation("Creating new task with input: {TaskInput}", taskInput); + AgentTask task = await agentService.CreateTaskAsync(taskInput); + + // Display the result + AnsiConsole.MarkupLine("[green]Task created successfully![/]"); + DisplayTask(task); + } + catch (ApiException ex) + { + logger.LogError(ex, "Failed to create task"); + AnsiConsole.MarkupLine($"[red]Error creating task: {ex.Message}[/]"); + } + } + + private static async Task ListAllTasksAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.MarkupLine("[bold]List All Tasks[/]"); + AnsiConsole.WriteLine(); + + int pageSize = AnsiConsole.Ask("Page size:", 10); + int currentPage = AnsiConsole.Ask("Page number:", 1); + + try + { + logger.LogInformation("Listing tasks (page {Page}, size {Size})", currentPage, pageSize); + PaginatedData pagedTasks = await agentService.GetTasksAsync(currentPage, pageSize); + + // Display the results + Table table = new Table() + .Border(TableBorder.Rounded) + .AddColumn("Task ID") + .AddColumn("Input") + .AddColumn("Status") + .AddColumn("Created At"); + + foreach (AgentTask task in pagedTasks.Data) + { + table.AddRow( + task.Id, + task.Input ?? "N/A", + task.Status ?? "N/A", + task.CreatedAt.ToString("g") + ); + } + + AnsiConsole.Write(table); + AnsiConsole.MarkupLine($"Page {pagedTasks.CurrentPage} of {pagedTasks.TotalPages} (Total: {pagedTasks.TotalCount} tasks)"); + } + catch (ApiException ex) + { + logger.LogError(ex, "Failed to list tasks"); + AnsiConsole.MarkupLine($"[red]Error listing tasks: {ex.Message}[/]"); + } + } + + private static async Task GetTaskDetailsAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.MarkupLine("[bold]Get Task Details[/]"); + AnsiConsole.WriteLine(); + + string taskId = AnsiConsole.Ask("Enter task ID:"); + + try + { + logger.LogInformation("Getting details for task {TaskId}", taskId); + AgentTask task = await agentService.GetTaskAsync(taskId); + + // Display the result + DisplayTask(task); + } + catch (ApiException ex) + { + logger.LogError(ex, "Failed to get task details"); + AnsiConsole.MarkupLine($"[red]Error getting task details: {ex.Message}[/]"); + } + } + + private static async Task ListTaskStepsAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.MarkupLine("[bold]List Task Steps[/]"); + AnsiConsole.WriteLine(); + + string taskId = AnsiConsole.Ask("Enter task ID:"); + int pageSize = AnsiConsole.Ask("Page size:", 10); + int currentPage = AnsiConsole.Ask("Page number:", 1); + + try + { + logger.LogInformation("Listing steps for task {TaskId}", taskId); + PaginatedData pagedSteps = await agentService.GetTaskStepsAsync(taskId, currentPage, pageSize); + + // Display the results + Table table = new Table() + .Border(TableBorder.Rounded) + .AddColumn("Step ID") + .AddColumn("Status") + .AddColumn("Is Last") + .AddColumn("Created At"); + + foreach (AgentStep step in pagedSteps.Data) + { + table.AddRow( + step.Id, + step.Status, + step.IsLast ? "Yes" : "No", + step.CreatedAt.ToString("g") + ); + } + + AnsiConsole.Write(table); + AnsiConsole.MarkupLine($"Page {pagedSteps.CurrentPage} of {pagedSteps.TotalPages} (Total: {pagedSteps.TotalCount} steps)"); + } + catch (ApiException ex) + { + logger.LogError(ex, "Failed to list task steps"); + AnsiConsole.MarkupLine($"[red]Error listing task steps: {ex.Message}[/]"); + } + } + + private static async Task ExecuteTaskStepAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.MarkupLine("[bold]Execute Task Step[/]"); + AnsiConsole.WriteLine(); + + string taskId = AnsiConsole.Ask("Enter task ID:"); + string input = AnsiConsole.Ask("Enter step input:"); + + try + { + logger.LogInformation("Executing step for task {TaskId}", taskId); + AgentStep step = await agentService.ExecuteTaskStepAsync(taskId, input); + + // Display the result + AnsiConsole.MarkupLine("[green]Step executed successfully![/]"); + DisplayStep(step); + } + catch (ApiException ex) + { + logger.LogError(ex, "Failed to execute task step"); + AnsiConsole.MarkupLine($"[red]Error executing task step: {ex.Message}[/]"); + } + } + + private static async Task GetStepDetailsAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.MarkupLine("[bold]Get Step Details[/]"); + AnsiConsole.WriteLine(); + + string taskId = AnsiConsole.Ask("Enter task ID:"); + string stepId = AnsiConsole.Ask("Enter step ID:"); + + try + { + logger.LogInformation("Getting details for step {StepId} in task {TaskId}", stepId, taskId); + AgentStep step = await agentService.GetTaskStepAsync(taskId, stepId); + + // Display the result + DisplayStep(step); + } + catch (ApiException ex) + { + logger.LogError(ex, "Failed to get step details"); + AnsiConsole.MarkupLine($"[red]Error getting step details: {ex.Message}[/]"); + } + } + + private static async Task ListTaskArtifactsAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.MarkupLine("[bold]List Task Artifacts[/]"); + AnsiConsole.WriteLine(); + + string taskId = AnsiConsole.Ask("Enter task ID:"); + int pageSize = AnsiConsole.Ask("Page size:", 10); + int currentPage = AnsiConsole.Ask("Page number:", 1); + + try + { + logger.LogInformation("Listing artifacts for task {TaskId}", taskId); + PaginatedData pagedArtifacts = await agentService.GetTaskArtifactsAsync(taskId, currentPage, pageSize); + + // Display the results + Table table = new Table() + .Border(TableBorder.Rounded) + .AddColumn("Artifact ID") + .AddColumn("Filename") + .AddColumn("Path") + .AddColumn("Agent Created") + .AddColumn("Created At"); + + foreach (AgentArtifact artifact in pagedArtifacts.Data) + { + table.AddRow( + artifact.Id, + artifact.FileName, + artifact.RelativePath ?? "-", + artifact.AgentCreated ? "Yes" : "No", + artifact.CreatedAt.ToString("g") + ); + } + + AnsiConsole.Write(table); + AnsiConsole.MarkupLine($"Page {pagedArtifacts.CurrentPage} of {pagedArtifacts.TotalPages} (Total: {pagedArtifacts.TotalCount} artifacts)"); + } + catch (ApiException ex) + { + logger.LogError(ex, "Failed to list task artifacts"); + AnsiConsole.MarkupLine($"[red]Error listing task artifacts: {ex.Message}[/]"); + } + } + + private static async Task UploadArtifactAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.MarkupLine("[bold]Upload Artifact[/]"); + AnsiConsole.WriteLine(); + + string taskId = AnsiConsole.Ask("Enter task ID:"); + string filePath = AnsiConsole.Ask("Enter file path:"); + string relativePath = AnsiConsole.Ask("Enter relative path in workspace:"); + + if (!File.Exists(filePath)) + { + AnsiConsole.MarkupLine("[red]File not found![/]"); + return; + } + + try + { + logger.LogInformation("Uploading artifact for task {TaskId}", taskId); + + AgentArtifact artifact = await agentService.UploadArtifactAsync(taskId, filePath, relativePath); + + // Display the result + AnsiConsole.MarkupLine("[green]Artifact uploaded successfully![/]"); + DisplayArtifact(artifact); + } + catch (ApiException ex) + { + logger.LogError(ex, "Failed to upload artifact"); + AnsiConsole.MarkupLine($"[red]Error uploading artifact: {ex.Message}[/]"); + } + } + + private static async Task DownloadArtifactAsync(IAgentTaskService agentService, ILogger logger) + { + AnsiConsole.MarkupLine("[bold]Download Artifact[/]"); + AnsiConsole.WriteLine(); + + string taskId = AnsiConsole.Ask("Enter task ID:"); + string artifactId = AnsiConsole.Ask("Enter artifact ID:"); + string outputPath = AnsiConsole.Ask("Enter download location:"); + + try + { + // Ensure directory exists + Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? "."); + + logger.LogInformation("Downloading artifact {ArtifactId} from task {TaskId}", artifactId, taskId); + + // Download the file + await agentService.DownloadArtifactAsync(taskId, artifactId, outputPath); + + // Display the result + AnsiConsole.MarkupLine("[green]Artifact downloaded successfully![/]"); + AnsiConsole.MarkupLine($"Saved to: {outputPath}"); + } + catch (ApiException ex) + { + logger.LogError(ex, "Failed to download artifact"); + AnsiConsole.MarkupLine($"[red]Error downloading artifact: {ex.Message}[/]"); + } + } + + private static void DisplayTask(AgentTask task) + { + Panel panel = new Panel( + Markup.Escape($"Task ID: {task.Id}\n" + + $"Input: {task.Input ?? "N/A"}\n" + + $"Status: {task.Status ?? "N/A"}\n" + + $"Created At: {task.CreatedAt}\n" + + $"Artifacts: {task.Artifacts.Count}") + ) + .Header("Task Details") + .Expand(); + + AnsiConsole.Write(panel); + + if (task.Artifacts.Count > 0) + { + AnsiConsole.MarkupLine("\n[bold]Task Artifacts:[/]"); + Table artifactsTable = new Table() + .Border(TableBorder.Rounded) + .AddColumn("Artifact ID") + .AddColumn("Filename") + .AddColumn("Path"); + + foreach (AgentArtifact artifact in task.Artifacts) + { + artifactsTable.AddRow( + artifact.Id, + artifact.FileName, + artifact.RelativePath ?? "-" + ); + } + + AnsiConsole.Write(artifactsTable); + } + } + + private static void DisplayStep(AgentStep step) + { + Panel panel = new Panel( + Markup.Escape($"Step ID: {step.Id}\n" + + $"Task ID: {step.TaskId}\n" + + $"Status: {step.Status}\n" + + $"Is Last: {(step.IsLast ? "Yes" : "No")}\n" + + $"Created At: {step.CreatedAt}\n" + + $"Executed At: {step.ExecutedAt ?? DateTime.MinValue}\n" + + $"Input: {step.Input ?? "N/A"}\n" + + $"Output: {step.Output ?? "N/A"}") + ) + .Header("Step Details") + .Expand(); + + AnsiConsole.Write(panel); + + if (step.Artifacts.Count > 0) + { + AnsiConsole.MarkupLine("\n[bold]Step Artifacts:[/]"); + Table artifactsTable = new Table() + .Border(TableBorder.Rounded) + .AddColumn("Artifact ID") + .AddColumn("Filename") + .AddColumn("Path"); + + foreach (AgentArtifact artifact in step.Artifacts) + { + artifactsTable.AddRow( + artifact.Id, + artifact.FileName, + artifact.RelativePath ?? "-" + ); + } + + AnsiConsole.Write(artifactsTable); + } + } + + private static void DisplayArtifact(AgentArtifact artifact) + { + Panel panel = new Panel( + Markup.Escape($"Artifact ID: {artifact.Id}\n" + + $"Filename: {artifact.FileName}\n" + + $"Path: {artifact.RelativePath ?? "N/A"}\n" + + $"Size: {artifact.Size / 1024.0:F2} KB\n" + + $"Agent Created: {(artifact.AgentCreated ? "Yes" : "No")}\n" + + $"Created At: {artifact.CreatedAt}") + ) + .Header("Artifact Details") + .Expand(); + + AnsiConsole.Write(panel); + } +} \ No newline at end of file diff --git a/packages/sdk/C#/Examples/ConsoleApplication/README.md b/packages/sdk/C#/Examples/ConsoleApplication/README.md new file mode 100644 index 00000000..8cd70368 --- /dev/null +++ b/packages/sdk/C#/Examples/ConsoleApplication/README.md @@ -0,0 +1,61 @@ +# Example Console Application + +This console application demonstrates how to use the generated Agent Protocol API client SDK to interact with the Agent Tasks API. The application provides a user-friendly command-line interface for performing various operations with agent tasks, steps, and artifacts. + +## Features + +- Create new agent tasks +- List all existing tasks with pagination +- View detailed information about a specific task +- List steps for a task with pagination +- Execute task steps +- View detailed information about a specific step +- List artifacts for a task with pagination +- Upload new artifacts to a task +- Download existing artifacts + +## Project Structure + +``` +ConsoleApplication/ +├── Program.cs # Main application entry point and UI +├── Models/ +│ └── AgentTaskModels.cs # Domain models for tasks, steps, and artifacts +├── Services/ +│ └── AgentTaskService.cs # Service layer for API interactions +├── appsettings.json # Application configuration +└── ConsoleApplication.csproj # Project file with dependencies +``` + +## Prerequisites + +- .NET 8.0 SDK +- Access to an Agent Protocol compatible API +- The generated API client SDK (referenced in the project) + +## Setup + +1. Clone this repository +2. Update the `appsettings.json` file with your API credentials: + + ```json + { + "ApiSettings": { + "BaseUrl": "https://api.example.com", + "ApiKey": "your-api-key-here", + "DefaultTimeout": 30 + } + } + ``` + +3. Build the project: + + ``` + dotnet build + ``` + +## Running the Application + +```bash +dotnet run +``` diff --git a/packages/sdk/C#/Examples/ConsoleApplication/appsettings.json b/packages/sdk/C#/Examples/ConsoleApplication/appsettings.json new file mode 100644 index 00000000..4bc146f7 --- /dev/null +++ b/packages/sdk/C#/Examples/ConsoleApplication/appsettings.json @@ -0,0 +1,7 @@ +{ + "ApiSettings": { + "BaseUrl": "https://api.example.com", + "ApiKey": "your-api-key-here", + "DefaultTimeout": 30 + } +} From 7fa985ecb02e834efc0c172d97d99cb70a278dcf Mon Sep 17 00:00:00 2001 From: jeff nasseri Date: Thu, 3 Apr 2025 01:38:21 +0200 Subject: [PATCH 6/6] Setup comprehensive solution file structure and standardized IDE configuration This commit establishes the foundational solution architecture for the Agent Protocol SDK ecosystem with properly configured solution files (.sln) and JetBrains Rider/Visual Studio settings (.dotsettings). The structured solution organization enables developers to work with all related projects simultaneously within a unified development environment. These configuration files ensure that regardless of which IDE developers use (Visual Studio, Rider, etc.), they will have a consistent experience with the properly structured projects and enforced coding standards across the entire codebase. --- packages/sdk/C#/AgentProtocolSdk.sln | 54 +++++++++++++++++++ .../sdk/C#/AgentProtocolSdk.sln.DotSettings | 3 ++ .../C#/AgentProtocolSdk.sln.DotSettings.user | 4 ++ packages/sdk/C#/Directory.Packages.props | 21 ++++++++ 4 files changed, 82 insertions(+) create mode 100644 packages/sdk/C#/AgentProtocolSdk.sln create mode 100644 packages/sdk/C#/AgentProtocolSdk.sln.DotSettings create mode 100644 packages/sdk/C#/AgentProtocolSdk.sln.DotSettings.user create mode 100644 packages/sdk/C#/Directory.Packages.props diff --git a/packages/sdk/C#/AgentProtocolSdk.sln b/packages/sdk/C#/AgentProtocolSdk.sln new file mode 100644 index 00000000..dedfc10f --- /dev/null +++ b/packages/sdk/C#/AgentProtocolSdk.sln @@ -0,0 +1,54 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{EAB2C585-38C6-436C-ABCA-357296235302}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApplication", "Examples\ConsoleApplication\ConsoleApplication.csproj", "{D7A41B8F-4BD5-4355-AFB4-FBF25A0CAD8D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Generator", "Generator\Generator.csproj", "{3405EF12-B29F-4420-8D4B-43B36F8CF63F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{2EE65CA0-4396-406B-9244-6D1E84BB2E24}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{18315049-926C-4168-A336-55F85DC8D5B5}" + ProjectSection(SolutionItems) = preProject + README.md = README.md + .editorconfig = .editorconfig + .gitignore = .gitignore + AgentProtocolSdk.sln = AgentProtocolSdk.sln + Directory.Packages.props = Directory.Packages.props + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Library", "Library\Library.csproj", "{65A4ED0F-B1ED-4B9C-93E7-43EBE2855496}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D7A41B8F-4BD5-4355-AFB4-FBF25A0CAD8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7A41B8F-4BD5-4355-AFB4-FBF25A0CAD8D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D7A41B8F-4BD5-4355-AFB4-FBF25A0CAD8D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7A41B8F-4BD5-4355-AFB4-FBF25A0CAD8D}.Release|Any CPU.Build.0 = Release|Any CPU + {3405EF12-B29F-4420-8D4B-43B36F8CF63F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3405EF12-B29F-4420-8D4B-43B36F8CF63F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3405EF12-B29F-4420-8D4B-43B36F8CF63F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3405EF12-B29F-4420-8D4B-43B36F8CF63F}.Release|Any CPU.Build.0 = Release|Any CPU + {2EE65CA0-4396-406B-9244-6D1E84BB2E24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2EE65CA0-4396-406B-9244-6D1E84BB2E24}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EE65CA0-4396-406B-9244-6D1E84BB2E24}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2EE65CA0-4396-406B-9244-6D1E84BB2E24}.Release|Any CPU.Build.0 = Release|Any CPU + {65A4ED0F-B1ED-4B9C-93E7-43EBE2855496}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {65A4ED0F-B1ED-4B9C-93E7-43EBE2855496}.Debug|Any CPU.Build.0 = Debug|Any CPU + {65A4ED0F-B1ED-4B9C-93E7-43EBE2855496}.Release|Any CPU.ActiveCfg = Release|Any CPU + {65A4ED0F-B1ED-4B9C-93E7-43EBE2855496}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {D7A41B8F-4BD5-4355-AFB4-FBF25A0CAD8D} = {EAB2C585-38C6-436C-ABCA-357296235302} + EndGlobalSection +EndGlobal diff --git a/packages/sdk/C#/AgentProtocolSdk.sln.DotSettings b/packages/sdk/C#/AgentProtocolSdk.sln.DotSettings new file mode 100644 index 00000000..8359f72b --- /dev/null +++ b/packages/sdk/C#/AgentProtocolSdk.sln.DotSettings @@ -0,0 +1,3 @@ + + False + True \ No newline at end of file diff --git a/packages/sdk/C#/AgentProtocolSdk.sln.DotSettings.user b/packages/sdk/C#/AgentProtocolSdk.sln.DotSettings.user new file mode 100644 index 00000000..38834976 --- /dev/null +++ b/packages/sdk/C#/AgentProtocolSdk.sln.DotSettings.user @@ -0,0 +1,4 @@ + + <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;Tests&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <Project Location="B:\root\agent-protocol\packages\sdk\C#\Tests" Presentation="&lt;Tests&gt;" /> +</SessionState> \ No newline at end of file diff --git a/packages/sdk/C#/Directory.Packages.props b/packages/sdk/C#/Directory.Packages.props new file mode 100644 index 00000000..c846d109 --- /dev/null +++ b/packages/sdk/C#/Directory.Packages.props @@ -0,0 +1,21 @@ + + + true + + + + + + + + + + + + + + + + + + \ No newline at end of file