diff --git a/.github/workflows/create-archives.yml b/.github/workflows/create-archives.yml index 220a9c18..91759ad7 100644 --- a/.github/workflows/create-archives.yml +++ b/.github/workflows/create-archives.yml @@ -10,8 +10,29 @@ concurrency: cancel-in-progress: true jobs: + check_changes: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + bootstrap: ${{ steps.filter.outputs.bootstrap }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Filter changed files + uses: dorny/paths-filter@v2 + id: filter + with: + filters: | + bootstrap: + - 'bootstrap*/**' + create-archives: runs-on: ubuntu-latest + if: ${{ needs.check_changes.outputs.bootstrap == 'true' }} permissions: contents: write steps: diff --git a/archives/bootstrap-dotnet.zip b/archives/bootstrap-dotnet.zip index 8ecca56e..27e6cfd1 100644 Binary files a/archives/bootstrap-dotnet.zip and b/archives/bootstrap-dotnet.zip differ diff --git a/archives/bootstrap-go.zip b/archives/bootstrap-go.zip index 9b83ff4f..488ef866 100644 Binary files a/archives/bootstrap-go.zip and b/archives/bootstrap-go.zip differ diff --git a/archives/bootstrap-node.zip b/archives/bootstrap-node.zip index d1d48d5c..284f0f80 100644 Binary files a/archives/bootstrap-node.zip and b/archives/bootstrap-node.zip differ diff --git a/sdk-dotnet/src/API/APIClient.cs b/sdk-dotnet/src/API/APIClient.cs index 9b73522a..426c5a1e 100644 --- a/sdk-dotnet/src/API/APIClient.cs +++ b/sdk-dotnet/src/API/APIClient.cs @@ -77,7 +77,7 @@ async public Task CreateCallResult(string clusterId, string callId, CreateResult } } - async public Task CreateRun(string clusterId, CreateRunInput input) + async public Task CreateRunAsync(string clusterId, CreateRunInput input) { string jsonData = JsonSerializer.Serialize(input); diff --git a/sdk-dotnet/src/Inferable.cs b/sdk-dotnet/src/Inferable.cs index 5f936c08..07c1c7cb 100644 --- a/sdk-dotnet/src/Inferable.cs +++ b/sdk-dotnet/src/Inferable.cs @@ -49,9 +49,21 @@ public struct PollRunOptions public class RunReference { public required string ID { get; set; } - public required Func> Poll { get; set; } + public required Func> PollAsync { get; set; } } + /// + /// The Inferable client. This is the main entry point for using Inferable. + /// + /// Basic usage: + /// + /// // create a new Inferable instance + /// var client = new InferableClient(new InferableOptions { + /// ApiSecret = "API_SECRET" + /// }); + /// + /// + /// public class InferableClient { public static string DefaultBaseUrl = "https://api.inferable.ai/"; @@ -65,6 +77,33 @@ public class InferableClient private List _services = new List(); + /// + /// Convenience reference to a service with the name 'default'. + /// + /// + /// // Create a new Inferable instance with an API secret + /// var client = new InferableClient(new InferableOptions { + /// ApiSecret = "API_SECRET" + /// }); + /// + /// client.Default.RegisterFunction(new FunctionRegistration + /// { + /// Name = "SayHello", + /// Description = "A simple greeting function", + /// Func = new Func((input) => { + /// didCallSayHello = true; + /// return $"Hello {input.testString}"; + /// }), + /// }); + /// + /// // Start the service + /// await client.Default.StartAsync(); + /// + /// // Stop the service on shutdown + /// await client.Default.StopAsync(); + /// + /// + /// public RegisteredService Default { get @@ -73,6 +112,23 @@ public RegisteredService Default } } + /// + /// Initializes a new instance of the InferableClient class. + /// + /// Basic usage: + /// + /// // Create a new Inferable instance with an API secret + /// var client = new InferableClient(new InferableOptions { + /// ApiSecret = "API_SECRET" + /// }); + /// + /// // OR + /// + /// Environment.SetEnvironmentVariable("INFERABLE_API_SECRET", "API_SECRET"); + /// var client = new InferableClient(); + /// + /// + /// public InferableClient(InferableOptions? options = null, ILogger? logger = null) { string? apiSecret = options?.ApiSecret ?? Environment.GetEnvironmentVariable("INFERABLE_API_SECRET"); @@ -100,22 +156,51 @@ public InferableClient(InferableOptions? options = null, ILogger.Instance; } + /// + /// Registers a service with Inferable. + /// + /// + /// // Create a new Inferable instance with an API secret + /// var client = new Inferable(new InferableOptions { + /// ApiSecret = "API_SECRET" + /// }); + /// + /// // Define and register the service + /// var service = client.RegisterService("MyService"); + /// + /// service.RegisterFunction(new FunctionRegistration + /// { + /// Name = "SayHello", + /// Description = "A simple greeting function", + /// Func = new Func((input) => { + /// didCallSayHello = true; + /// return $"Hello {input.testString}"; + /// }), + /// }); + /// + /// // Start the service + /// await service.StartAsync(); + /// + /// // Stop the service on shutdown + /// await service.StopAsync(); + /// + /// + /// public RegisteredService RegisterService(string name) - { - return new RegisteredService(name, this); + { return new RegisteredService(name, this); } - async public Task CreateRun(CreateRunInput input) + async public Task CreateRunAsync(CreateRunInput input) { if (this._clusterId == null) { throw new ArgumentException("Cluster ID must be provided to manage runs"); } - var result = await this._client.CreateRun(this._clusterId, input); + var result = await this._client.CreateRunAsync(this._clusterId, input); return new RunReference { ID = result.ID, - Poll = async (PollRunOptions? options) => { + PollAsync = async (PollRunOptions? options) => { var MaxWaitTime = options?.MaxWaitTime ?? TimeSpan.FromSeconds(60); var Interval = options?.Interval ?? TimeSpan.FromMilliseconds(500); @@ -137,6 +222,9 @@ async public Task CreateRun(CreateRunInput input) }; } + /// + /// An array containing the names of all services currently polling. + /// public IEnumerable ActiveServices { get @@ -145,6 +233,12 @@ public IEnumerable ActiveServices } } + /// + /// An array containing the names of all services that are not currently polling. + /// + /// + /// Note that this will only include services that have been started (i.e., StartAsync() method called). + /// public IEnumerable InactiveServices { get @@ -153,6 +247,9 @@ public IEnumerable InactiveServices } } + /// + /// An array containing the names of all functions that have been registered. + /// public IEnumerable RegisteredFunctions { get @@ -176,7 +273,7 @@ internal void RegisterFunction(string serviceName, FunctionRegistration fu } - internal async Task StartService(string name) { + internal async Task StartServiceAsync(string name) { var existing = this._services.FirstOrDefault(s => s.Name == name); if (existing != null) { throw new Exception("Service is already started"); @@ -194,7 +291,7 @@ internal async Task StartService(string name) { await service.Start(); } - internal async Task StopService(string name) { + internal async Task StopServiceAsync(string name) { var existing = this._services.FirstOrDefault(s => s.Name == name); if (existing == null) { throw new Exception("Service is not started"); @@ -213,6 +310,22 @@ internal RegisteredService(string name, InferableClient inferable) { this._inferable = inferable; } + /// + /// Registers a function against the Service. + /// + /// + /// service.RegisterFunction(new FunctionRegistration + /// { + /// Name = "SayHello", + /// Description = "A simple greeting function", + /// Func = new Func((input) => { + /// didCallSayHello = true; + /// return $"Hello {input.testString}"; + /// }), + /// }); + /// + /// + /// public FunctionReference RegisterFunction(FunctionRegistration function) where T : struct { this._inferable.RegisterFunction(this._name, function); @@ -222,12 +335,18 @@ public FunctionReference RegisterFunction(FunctionRegistration function) w }; } - async public Task Start() { - await this._inferable.StartService(this._name); + /// + /// Starts the service + /// + async public Task StartAsync() { + await this._inferable.StartServiceAsync(this._name); } - async public Task Stop() { - await this._inferable.StopService(this._name); + /// + /// Stops the service + /// + async public Task StopAsync() { + await this._inferable.StopServiceAsync(this._name); } } diff --git a/sdk-dotnet/src/Inferable.csproj b/sdk-dotnet/src/Inferable.csproj index 09a595cd..5a95882a 100644 --- a/sdk-dotnet/src/Inferable.csproj +++ b/sdk-dotnet/src/Inferable.csproj @@ -6,7 +6,7 @@ enable Inferable - 0.0.12 + 0.0.13 Inferable Inferable Client library for interacting with the Inferable API diff --git a/sdk-dotnet/tests/Inferable.Tests/InferableTest.cs b/sdk-dotnet/tests/Inferable.Tests/InferableTest.cs index b2f63aa4..04e014a7 100644 --- a/sdk-dotnet/tests/Inferable.Tests/InferableTest.cs +++ b/sdk-dotnet/tests/Inferable.Tests/InferableTest.cs @@ -135,8 +135,8 @@ async public void Inferable_Can_Register_Function() inferable.Default.RegisterFunction(registration); - await inferable.Default.Start(); - await inferable.Default.Stop(); + await inferable.Default.StartAsync(); + await inferable.Default.StopAsync(); } [Fact] @@ -158,7 +158,7 @@ async public void Inferable_Can_Handle_Functions() try { - await inferable.Default.Start(); + await inferable.Default.StartAsync(); var result = ApiClient.CreateCall(TestClusterId, new CreateCallInput { @@ -177,7 +177,7 @@ async public void Inferable_Can_Handle_Functions() } finally { - await inferable.Default.Stop(); + await inferable.Default.StopAsync(); } } @@ -200,7 +200,7 @@ async public void Inferable_Can_Handle_Functions_Failure() try { - await inferable.Default.Start(); + await inferable.Default.StartAsync(); var result = ApiClient.CreateCall(TestClusterId, new CreateCallInput { @@ -219,7 +219,7 @@ async public void Inferable_Can_Handle_Functions_Failure() } finally { - await inferable.Default.Stop(); + await inferable.Default.StopAsync(); } } @@ -260,9 +260,9 @@ async public void Inferable_Run_E2E() try { - await client.Default.Start(); + await client.Default.StartAsync(); - var run = await client.CreateRun(new CreateRunInput + var run = await client.CreateRunAsync(new CreateRunInput { Message = "Say hello to John", AttachedFunctions = new List @@ -276,7 +276,7 @@ async public void Inferable_Run_E2E() ResultSchema = JsonSchema.FromType(), }); - var result = await run.Poll(null); + var result = await run.PollAsync(null); await Task.Delay(500); @@ -286,7 +286,7 @@ async public void Inferable_Run_E2E() } finally { - await client.Default.Stop(); + await client.Default.StopAsync(); } } } diff --git a/sdk-node/src/Inferable.ts b/sdk-node/src/Inferable.ts index fa878e1b..f9844239 100644 --- a/sdk-node/src/Inferable.ts +++ b/sdk-node/src/Inferable.ts @@ -40,20 +40,15 @@ type RunInput = Omit { + * client.default.register("hello", z.object({name: z.string()}), async ({name}: {name: string}) => { * return `Hello ${name}`; * }); * * // start the service - * await d.default.start(); + * await client.default.start(); * * // stop the service on shutdown * process.on("beforeExit", async () => { - * await d.default.stop(); + * await client.default.stop(); * }); * */ @@ -218,9 +204,9 @@ export class Inferable { * @returns A run reference. * @example * ```ts - * const d = new Inferable({apiSecret: "API_SECRET"}); + * const client = new Inferable({apiSecret: "API_SECRET"}); * - * const run = await d.run({ message: "Hello world" }); + * const run = await client.run({ message: "Hello world" }); * * console.log("Started run with ID:", run.id); * @@ -325,9 +311,9 @@ export class Inferable { * @returns A registered service instance. * @example * ```ts - * const d = new Inferable({apiSecret: "API_SECRET"}); + * const client = new Inferable({apiSecret: "API_SECRET"}); * - * const service = d.service({ + * const service = client.service({ * name: "my-service", * }); *