added cloud versioning

This commit is contained in:
Jacob Dubin
2026-04-20 22:13:37 -05:00
parent efdb5bcf01
commit 2ea7afe2e7
6 changed files with 55 additions and 1 deletions

View File

@@ -8,6 +8,12 @@ It is intentionally broader than the current Node server. The Node server is a p
Day-to-day feature sequencing now lives in [feature-backlog.md](/C:/Projects/JiboExperiments/OpenJibo/docs/feature-backlog.md).
Cloud release hygiene:
- keep a visible OpenJibo Cloud version string
- expose it through diagnostics such as `/health` and the spoken `cloud version` command
- bump the shared version constant whenever we deploy a meaningful hosted-cloud change
## Current Scope
- stable .NET cloud scaffold

View File

@@ -6,6 +6,13 @@
This is the production-oriented path for restoring device connectivity and creating a foundation for future runtime, AI, and OTA work.
Current spoken cloud version: `Open Jibo Cloud version 1.0.10.`
Release hygiene reminder:
- bump [OpenJiboCloudBuildInfo.cs](/C:/Projects/JiboExperiments/OpenJibo/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Application/Services/OpenJiboCloudBuildInfo.cs) whenever we ship a meaningful hosted-cloud update
- keep the spoken version response and `/health` version field aligned from that single source of truth
## Architecture
The first implementation is a modular monolith:

View File

@@ -125,7 +125,12 @@ app.Use(async (context, next) =>
await telemetrySink.RecordConnectionClosedAsync(closeEnvelope, closeSession, $"socket-loop-ended{(isPrematureClose ? "-prematurely" : string.Empty)}", context.RequestAborted);
});
app.MapGet("/health", () => Results.Json(new { ok = true, service = "OpenJibo Cloud Api" }));
app.MapGet("/health", () => Results.Json(new
{
ok = true,
service = "OpenJibo Cloud Api",
version = OpenJiboCloudBuildInfo.Version
}));
app.MapMethods("/{**path}", ["GET", "POST", "PUT"], async (HttpContext context, JiboCloudProtocolService service, IProtocolTelemetrySink telemetrySink, CancellationToken cancellationToken) =>
{

View File

@@ -29,6 +29,7 @@ public sealed class JiboInteractionService(
"dance" => BuildDanceDecision(catalog),
"time" => new JiboInteractionDecision("time", $"It is {DateTime.Now:h:mm tt}."),
"date" => new JiboInteractionDecision("date", $"Today is {DateTime.Now:dddd, MMMM d}."),
"cloud_version" => new JiboInteractionDecision("cloud_version", OpenJiboCloudBuildInfo.SpokenVersion),
"radio" => BuildRadioLaunchDecision(),
"radio_genre" => BuildRadioGenreLaunchDecision(lowered),
"hello" => new JiboInteractionDecision("hello", randomizer.Choose(catalog.GreetingReplies)),
@@ -169,6 +170,18 @@ public sealed class JiboInteractionService(
return "joke";
}
if (MatchesAny(
loweredTranscript,
"cloud version",
"open jibo cloud version",
"openjibo cloud version",
"what version is the cloud",
"what s the cloud version",
"what's the cloud version"))
{
return "cloud_version";
}
if (TryResolveRadioGenre(loweredTranscript) is not null)
{
return "radio_genre";

View File

@@ -0,0 +1,8 @@
namespace Jibo.Cloud.Application.Services;
public static class OpenJiboCloudBuildInfo
{
public const string Version = "1.0.10";
public static string SpokenVersion => $"Open Jibo Cloud version {Version}.";
}

View File

@@ -200,6 +200,21 @@ public sealed class JiboInteractionServiceTests
Assert.DoesNotContain("future cloud integration", decision.ReplyText, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public async Task BuildDecisionAsync_CloudVersion_UsesSharedBuildInfo()
{
var service = CreateService();
var decision = await service.BuildDecisionAsync(new TurnContext
{
RawTranscript = "what's the cloud version",
NormalizedTranscript = "what's the cloud version"
});
Assert.Equal("cloud_version", decision.IntentName);
Assert.Equal(OpenJiboCloudBuildInfo.SpokenVersion, decision.ReplyText);
}
[Fact]
public async Task BuildDecisionAsync_WordOfDayGuess_UsesStructuredClientNluGuess()
{