From 42f0818c3691479af0df55b990bb1a53612d6630 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 1 Nov 2024 08:52:23 +1030 Subject: [PATCH 1/3] docs(dotnet): Add some function comments --- sdk-dotnet/src/API/APIClient.cs | 2 +- sdk-dotnet/src/Inferable.cs | 143 ++++++++++++++++-- sdk-dotnet/src/Inferable.csproj | 2 +- .../tests/Inferable.Tests/InferableTest.cs | 20 +-- sdk-node/src/Inferable.ts | 38 ++--- 5 files changed, 155 insertions(+), 50 deletions(-) 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", * }); * From 043ad91acb459dc0588ee995a34ba623ffa91a45 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 31 Oct 2024 22:23:09 +0000 Subject: [PATCH 2/3] [skip ci] Update bootstrap project archives --- archives/bootstrap-dotnet.zip | Bin 4508 -> 4508 bytes archives/bootstrap-go.zip | Bin 5995761 -> 5995761 bytes archives/bootstrap-node.zip | Bin 6743 -> 6743 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/archives/bootstrap-dotnet.zip b/archives/bootstrap-dotnet.zip index 8ecca56eca45ad16adb41ccdaa63d278f51a79fa..27e6cfd171c97923a3f52ee902f2ff519e64d8a4 100644 GIT binary patch delta 329 zcmbQEJV%))z?+$civa|lY?{cU!S2nhk`BZZt)-ZN0^vq5fsGUN8G#~`4>Ib*gf@R? zyu}O>yUc127n5Yu2CH*pcY%pbp2(gHR5ppj0!hSlatTKWNb@NUW0)|+(#Z;(ZZMI} zxtt|n;~sOtU9wq*`vDV3=RaOEW}s6iFA$IcaYOkWkh$CVY>~Ml{JzNCCjKB~?pJ;{ dC|8UF78;Xd1RRmo>=Ot<<{Aq^tSb{#0{{|{VeJ3_ delta 329 zcmbQEJV%))z?+$civa`@S4`y5U~m1PoDRejt)-ZN0^vq5fsGUN8G#~`4>Ib*gf@R? zyu}O>yUc127n5Yu2CH*pcY%pbp2(gHR5ppj0!hSlatTKWNb@NUW0)|+(#Z;(ZZMI} zxtt|n;~sOtU9wq*`vDV3=RaOEW}s6iFA$IcaYOkWkh$CVY>~Ml{JzNCCjKB~?pJ;{ dC|8UF78;Xd1RRmo>=Ot<<{Aq^tSb{#0{}*ccLe|d diff --git a/archives/bootstrap-go.zip b/archives/bootstrap-go.zip index 9b83ff4f2afdf15ed280509094a35969d4fe5966..488ef866782962fc3fd2cb0ec8dcdb615e476339 100644 GIT binary patch delta 576 zcmZ9}OK*%(9Dwned52az)TQo4=@_)sw5XO|+>3E3bw4YSkZ3~}CTaRkQWnqVS+Oyn z!lsGzBUtzZRyN&OSkw+1^Gb_xl7CL}J5SEyoW<{7GmEv!jg_KoQz}^tb8m9_j#89= zl1zEJIhD?SiBhTTZ0#_~T5Ee_l8qM|ma z7mwgkJcfOE9Q$zqPvA)$#33BU5j=&b@eH2Db9f#v;3!_iOL!Secm=QGHN1{vcmr?Z zINrkBcn9y|J-m+(-Wy&%%`D7Sa}%L+`H`wa6X9EeJ(Hnp8Rs8OhPRnSe?AM{f3)~K z#OXxeP5sk;o(hk%iH?^4UOPWs4nKbDimjU zbYm&~2o^qpm9>RL?XWSgv=}G(=On-L8rNV8uElk@ z9yeesZp2Nv8Mok8+=kn+4R_#9+=cD98~0!yJ8&-+a3Ai+1K5dOcn}X^Hy*|!_Fyj_ z!J~K#`|vpS;{cw(lQ@V&IE*8B3Qyx1Jd5Y>JYK+2yoi_ZGLGRDyo%TGI*#KFyonQd z3vc5cyo>knK0bJ7c=04tny=<2L+A1%Rfi_Sw*-5pLf0}bJe&$|GKv0t8oK{z@mYw| ziN2lwr~Nb?9z}_cmj7P6FjEdce(Uqu(3`FONVOD)wj_H$8;0wk5QqLcn2W)>T{wrQpmhSja358!oGUclP diff --git a/archives/bootstrap-node.zip b/archives/bootstrap-node.zip index d1d48d5caa514efaa0a80ae5bc8d3e897c41d36f..284f0f801549961fe673356580b7b84ba811cab7 100644 GIT binary patch delta 277 zcmca^a@~X{z?+$civa|lY?{cU#_r9mk`Ba^;{>IcfFhwrFp-IU_kjYF^BE0bBAb^n zrZa-X_?gY&V!q7xctK*if?6;!s9BS%1Px(An>PtMF!Mdx6d&nrVN#gS#J~{FHZf6j zvaA#z7bgQV)DfF?MZ1|mhV2qJ0f|liC@urGPr?D2TOeVF%snsR3gwD%zIcfFhwrFp-IU_kjYF^BE0bBAb^n zrZa-X_?gY&V!q7xctK*if?6;!s9BS%1Px(An>PtMF!Lp@h>!HPFe%JuVqgeoo0up% zSyqaVi<5yF>WIy{qTNg&!*+?AfW#($6qfuC>U_P5{DrteN Rrccrynfp!>VxXav8UVMhVPOCO From 592d21e06722aeddc2e6f58f674420bd765ab425 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 1 Nov 2024 08:56:44 +1030 Subject: [PATCH 3/3] chore: Only create archives if changes --- .github/workflows/create-archives.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) 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: