boostrap docs, tests, basic code and dev plans
This commit is contained in:
@@ -2,5 +2,6 @@
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<Solution>
|
||||
<Folder Name="/docs/">
|
||||
<File Path="docs/development-plan.md" />
|
||||
<File Path="docs/device-bootstrap.md" />
|
||||
<File Path="docs/protocol-inventory.md" />
|
||||
<File Path="docs/public-site-plan.md" />
|
||||
<File Path="docs/support-tiers.md" />
|
||||
</Folder>
|
||||
<Folder Name="/scripts/" />
|
||||
<Folder Name="/scripts/boostrap/">
|
||||
<Folder Name="/scripts/bootstrap/">
|
||||
<File Path="scripts/bootstrap/Discover-JiboHosts.ps1" />
|
||||
<File Path="scripts/bootstrap/Generate-JiboDnsOverrides.ps1" />
|
||||
<File Path="scripts/bootstrap/README.md" />
|
||||
@@ -28,6 +29,9 @@
|
||||
<Project Path="src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Jibo.Cloud.Api.csproj" />
|
||||
<Project Path="src/Playground/Playground.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/tests/">
|
||||
<Project Path="tests/Jibo.Cloud.Tests/Jibo.Cloud.Tests.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/src/OpenJibo.Site/">
|
||||
<File Path="src/OpenJibo.Site/index.html" />
|
||||
<File Path="src/OpenJibo.Site/site.css" />
|
||||
|
||||
@@ -36,7 +36,7 @@ Jibo device -> OpenJibo cloud -> normalized runtime contracts -> capabilities an
|
||||
The first supported recovery path is enthusiast-friendly, not zero-touch:
|
||||
|
||||
```text
|
||||
QR Wi-Fi -> controlled router/DNS -> redirect legacy Jibo hosts ->
|
||||
QR Wi-Fi -> inject OpenJibo region config -> set robot region ->
|
||||
RCM/device patch for TLS and host acceptance -> OpenJibo cloud on Azure
|
||||
```
|
||||
|
||||
@@ -47,6 +47,7 @@ That path is documented in [docs/device-bootstrap.md](C:/Projects/JiboExperiment
|
||||
```text
|
||||
OpenJibo/
|
||||
docs/
|
||||
development-plan.md
|
||||
device-bootstrap.md
|
||||
protocol-inventory.md
|
||||
public-site-plan.md
|
||||
@@ -78,12 +79,14 @@ OpenJibo/
|
||||
- port required endpoint and WebSocket behavior from Node to .NET
|
||||
- keep protocol captures and replay fixtures current
|
||||
- harden device bootstrap documentation and scripts
|
||||
- map more endpoints and behaviors beyond the current Node coverage
|
||||
- stand up the initial `openjibo.com` information site
|
||||
|
||||
## Important Docs
|
||||
|
||||
- [Cloud overview](/src/Jibo.Cloud/README.md)
|
||||
- [Development plan](/docs/development-plan.md)
|
||||
- [Protocol inventory](/docs/protocol-inventory.md)
|
||||
- [Support tiers](/docs/support-tiers.md)
|
||||
- [Device bootstrap path](/docs/device-bootstrap.md)
|
||||
- [Public site plan](/docs/public-site-plan.md)
|
||||
- [Public site plan](/docs/public-site-plan.md)
|
||||
|
||||
65
OpenJibo/docs/development-plan.md
Normal file
65
OpenJibo/docs/development-plan.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Development Plan
|
||||
|
||||
## Summary
|
||||
|
||||
This document is the working implementation plan after the initial hosted-cloud scaffold.
|
||||
|
||||
It is intentionally broader than the current Node server. The Node server is a protocol oracle and discovery tool, not the complete map of Jibo.
|
||||
|
||||
## Current Scope
|
||||
|
||||
- stable .NET cloud scaffold
|
||||
- Azure-oriented architecture and data ownership
|
||||
- normalized runtime contracts for cloud-to-runtime handoff
|
||||
- bootstrap documentation for region injection and targeted device patching
|
||||
- starter endpoint coverage for account, notification, robot, loop, update, uploads, and core WebSocket acceptance
|
||||
- starter xUnit coverage for the .NET application layer
|
||||
|
||||
## Next Implementation Scope
|
||||
|
||||
- expand HTTP `X-Amz-Target` coverage from observed traffic and fixtures
|
||||
- grow WebSocket compatibility from stub acceptance into realistic turn orchestration
|
||||
- replace in-memory state with Azure SQL-backed persistence
|
||||
- add structured fixture replay tests
|
||||
- harden region/bootstrap docs by software version
|
||||
|
||||
## Discovery Scope
|
||||
|
||||
We still need to map more than the current Node server expresses. Priority discovery areas:
|
||||
|
||||
- all hostnames and service prefixes observed in real startup and turn traffic
|
||||
- skill launch and skill lifecycle flows
|
||||
- interactivity command families beyond the current joke flow
|
||||
- richer embodied speech and animation behaviors
|
||||
- upload, logging, backup, and key-sharing flows
|
||||
- per-version configuration differences and region handling
|
||||
|
||||
## Speech, Animation, And ESML
|
||||
|
||||
The current joke flow is only a small foothold into Jibo expressiveness.
|
||||
|
||||
Future work should map:
|
||||
|
||||
- direct speech modifiers
|
||||
- animation selection and filtering
|
||||
- embodied speech behaviors
|
||||
- ESML and SSML subsets
|
||||
- interactions between speech, visuals, and timing
|
||||
|
||||
Useful external references:
|
||||
|
||||
- [Speak-Tweak Docs](https://hri2024.jibo.media.mit.edu/Speak-Tweak-Docs)
|
||||
- [ESML PDF](https://hri2024.jibo.media.mit.edu/attachments/SDK-SDK---ESML-121023-203758.pdf)
|
||||
|
||||
## Future Scope
|
||||
|
||||
- full endpoint inventory beyond the current Node mapping
|
||||
- OTA-driven recovery
|
||||
- paid hosted plans or donation-supported hosting
|
||||
- deeper on-device bridge and OS modernization
|
||||
- more capable skill/runtime integration
|
||||
- possible LLM or tool-use patterns inspired by workshop-era experimentation
|
||||
|
||||
## MCP-Like Ideas
|
||||
|
||||
Recent MIT workshop materials suggest experimentation around modern AI tooling for Jibo, including an MCP-oriented idea. We should treat that as inspiration for future OpenJibo directions, not as a present dependency or supported integration.
|
||||
@@ -5,7 +5,7 @@
|
||||
The first supported OpenJibo recovery path is:
|
||||
|
||||
```text
|
||||
QR Wi-Fi -> controlled router/DNS -> redirect Jibo hosts ->
|
||||
QR Wi-Fi -> inject OpenJibo region config -> set robot region ->
|
||||
RCM/device patch -> Azure-hosted OpenJibo cloud
|
||||
```
|
||||
|
||||
@@ -13,26 +13,44 @@ This is the path we can document, repeat, and improve.
|
||||
|
||||
## Why This Path Comes First
|
||||
|
||||
- it matches what the current Node prototype already requires
|
||||
- it matches the region-driven configuration seams observed on the robot
|
||||
- it keeps the hosted cloud work grounded in real device traffic
|
||||
- it avoids blocking the entire revival on OTA before cloud compatibility exists
|
||||
|
||||
## Bootstrap Checklist
|
||||
|
||||
1. Connect the robot to a controlled Wi-Fi network.
|
||||
2. Redirect legacy cloud hostnames to the OpenJibo environment.
|
||||
3. Prevent fallback DNS from bypassing the controlled resolver.
|
||||
2. Add an OpenJibo region entry to `/etc/jibo-jetstream-service.json`.
|
||||
3. Set the robot `region` field in `/var/jibo/credentials.json` to the OpenJibo region.
|
||||
4. Gain RCM/device access for targeted TLS or host validation changes.
|
||||
5. Verify robot startup, token flow, socket flow, and first-turn behavior.
|
||||
|
||||
## Required Host Routing
|
||||
## Region-Driven Configuration
|
||||
|
||||
At minimum, watch and validate:
|
||||
Current findings suggest the preferred OpenJibo bootstrap path is to inject a new region configuration rather than override every hostname manually.
|
||||
|
||||
Confirmed paths:
|
||||
|
||||
- `/etc/jibo-jetstream-service.json`
|
||||
Add an OpenJibo region definition that points Jibo to our cloud.
|
||||
- `/var/jibo/credentials.json`
|
||||
Set the robot `region` field to the injected OpenJibo region.
|
||||
|
||||
Observed additional region-related files worth documenting and auditing:
|
||||
|
||||
- `/etc/jibo-ssm/*.json`
|
||||
- `/skills/jibo/Jibo/Skills/@be/be/node_modules/language-subtag-registry/data/json/registry.json`
|
||||
- `/skills/jibo/Jibo/Skills/oobe-config/config.json`
|
||||
|
||||
These should be treated as configuration discovery targets, not yet as the authoritative complete list.
|
||||
|
||||
## Required Hosts
|
||||
|
||||
The currently relevant public hostnames for the OpenJibo cloud path are:
|
||||
|
||||
- `api.jibo.com`
|
||||
- `api-socket.jibo.com`
|
||||
- `neo-hub.jibo.com`
|
||||
- `neohub.jibo.com`
|
||||
|
||||
## Scripted Helpers
|
||||
|
||||
@@ -42,7 +60,7 @@ Bootstrap helper scripts live in [scripts/bootstrap](C:/Projects/JiboExperiments
|
||||
- `Generate-JiboDnsOverrides.ps1`
|
||||
- `Test-OpenJiboRouting.ps1`
|
||||
|
||||
These are intentionally conservative helpers for discovery and verification, not destructive patch tools.
|
||||
These are intentionally conservative helpers for discovery and verification, not destructive patch tools. They remain useful for controlled-network testing, even though the preferred long-term device path is region injection.
|
||||
|
||||
## TLS And Runtime Patching
|
||||
|
||||
@@ -53,6 +71,7 @@ Near-term guidance:
|
||||
- record each patch location by software version
|
||||
- prefer small, repeatable changes over ad hoc edits
|
||||
- keep a versioned host inventory and patch checklist
|
||||
- keep a versioned region-config checklist
|
||||
- do not describe OTA as the primary bootstrap method until the hosted cloud is stable
|
||||
|
||||
## Smoke Test Goals
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
This document tracks the currently observed cloud surface area for Jibo and helps keep the .NET port aligned with real behavior captured by the Node prototype.
|
||||
|
||||
It is not a claim that the current Node server covers all Jibo endpoints or behaviors. It reflects only the portions mapped so far.
|
||||
|
||||
Confidence levels:
|
||||
|
||||
- `high`: observed in code and currently represented in the .NET scaffold
|
||||
@@ -17,7 +19,20 @@ Confidence levels:
|
||||
| `api.jibo.com` | HTTPS API target for `X-Amz-Target` operations | high | Main request dispatch path in the Node prototype |
|
||||
| `api-socket.jibo.com` | token-authenticated WebSocket path | medium | Node accepts tokenized connections and intentionally sends no greeting |
|
||||
| `neo-hub.jibo.com` | listen and proactive WebSocket traffic | medium | Path-driven split between listen and `/v1/proactive` |
|
||||
| `neohub.jibo.com` | likely alias/spelling variant to watch | low | Mentioned in docs; validate against real traffic |
|
||||
|
||||
## Region Configuration
|
||||
|
||||
Current robot findings suggest the preferred OpenJibo bootstrap path is to inject a new region configuration rather than treat host overrides as the only integration seam.
|
||||
|
||||
Confirmed or strongly observed files:
|
||||
|
||||
- `/etc/jibo-jetstream-service.json`
|
||||
- `/var/jibo/credentials.json`
|
||||
- `/etc/jibo-ssm/*.json`
|
||||
- `/skills/jibo/Jibo/Skills/@be/be/node_modules/language-subtag-registry/data/json/registry.json`
|
||||
- `/skills/jibo/Jibo/Skills/oobe-config/config.json`
|
||||
|
||||
The first two are the clearest current OpenJibo injection points. The others should remain on the audit list while endpoint and behavior mapping continues.
|
||||
|
||||
## HTTP Dispatch Families
|
||||
|
||||
@@ -65,6 +80,22 @@ The first .NET hosted milestone should fully support:
|
||||
- basic listen/proactive WebSocket acceptance
|
||||
- normalized turn and reply mapping for simple chat
|
||||
|
||||
## Known Beyond Current Node Coverage
|
||||
|
||||
The platform scope is broader than the endpoints currently modeled in `open-jibo-link.js`. Known areas that still need mapping include:
|
||||
|
||||
- broader skill launch and lifecycle behavior
|
||||
- interactivity command families beyond the joke starter path
|
||||
- richer animation and expression control
|
||||
- ESML and embodied speech features
|
||||
- additional service families and region-specific endpoint behavior
|
||||
- startup and configuration differences across Jibo software variants
|
||||
|
||||
Useful external references for future mapping:
|
||||
|
||||
- [Speak-Tweak Docs](https://hri2024.jibo.media.mit.edu/Speak-Tweak-Docs)
|
||||
- [ESML PDF](https://hri2024.jibo.media.mit.edu/attachments/SDK-SDK---ESML-121023-203758.pdf)
|
||||
|
||||
## Fixture Source
|
||||
|
||||
Sanitized fixtures live under [src/Jibo.Cloud/node/fixtures](C:/Projects/JiboExperiments/OpenJibo/src/Jibo.Cloud/node/fixtures) and should be expanded as real traffic is captured.
|
||||
|
||||
@@ -3,8 +3,7 @@ param(
|
||||
[string[]]$KnownHosts = @(
|
||||
"api.jibo.com",
|
||||
"api-socket.jibo.com",
|
||||
"neo-hub.jibo.com",
|
||||
"neohub.jibo.com"
|
||||
"neo-hub.jibo.com"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ param(
|
||||
[string[]]$HostNames = @(
|
||||
"api.jibo.com",
|
||||
"api-socket.jibo.com",
|
||||
"neo-hub.jibo.com",
|
||||
"neohub.jibo.com"
|
||||
"neo-hub.jibo.com"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -20,8 +20,7 @@ public sealed class InMemoryCloudStateStore : ICloudStateStore
|
||||
{
|
||||
["api.jibo.com"] = "openjibo.com",
|
||||
["api-socket.jibo.com"] = "openjibo.com",
|
||||
["neo-hub.jibo.com"] = "openjibo.com",
|
||||
["neohub.jibo.com"] = "openjibo.com"
|
||||
["neo-hub.jibo.com"] = "openjibo.com"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
1
OpenJibo/tests/Jibo.Cloud.Tests/GlobalUsings.cs
Normal file
1
OpenJibo/tests/Jibo.Cloud.Tests/GlobalUsings.cs
Normal file
@@ -0,0 +1 @@
|
||||
global using Xunit;
|
||||
22
OpenJibo/tests/Jibo.Cloud.Tests/Jibo.Cloud.Tests.csproj
Normal file
22
OpenJibo/tests/Jibo.Cloud.Tests/Jibo.Cloud.Tests.csproj
Normal file
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Jibo.Cloud\dotnet\src\Jibo.Cloud.Application\Jibo.Cloud.Application.csproj" />
|
||||
<ProjectReference Include="..\..\src\Jibo.Cloud\dotnet\src\Jibo.Cloud.Infrastructure\Jibo.Cloud.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\src\Jibo.Runtime.Abstractions\Jibo.Runtime.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,64 @@
|
||||
using System.Text.Json;
|
||||
using Jibo.Cloud.Application.Services;
|
||||
using Jibo.Cloud.Domain.Models;
|
||||
using Jibo.Cloud.Infrastructure.Persistence;
|
||||
|
||||
namespace Jibo.Cloud.Tests.Protocol;
|
||||
|
||||
public sealed class JiboCloudProtocolServiceTests
|
||||
{
|
||||
private readonly JiboCloudProtocolService _service = new(new InMemoryCloudStateStore());
|
||||
|
||||
[Fact]
|
||||
public async Task CreateHubToken_ReturnsTokenAndExpiry()
|
||||
{
|
||||
var result = await _service.DispatchAsync(new ProtocolEnvelope
|
||||
{
|
||||
HostName = "api.jibo.com",
|
||||
Method = "POST",
|
||||
ServicePrefix = "Account_20160715",
|
||||
Operation = "CreateHubToken",
|
||||
BodyText = "{}"
|
||||
});
|
||||
|
||||
using var payload = JsonDocument.Parse(result.BodyText);
|
||||
Assert.Equal(200, result.StatusCode);
|
||||
Assert.StartsWith("hub-", payload.RootElement.GetProperty("token").GetString());
|
||||
Assert.True(payload.RootElement.GetProperty("expires").GetInt64() > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task NewRobotToken_UsesBodyDeviceId()
|
||||
{
|
||||
var result = await _service.DispatchAsync(new ProtocolEnvelope
|
||||
{
|
||||
HostName = "api.jibo.com",
|
||||
Method = "POST",
|
||||
ServicePrefix = "Notification_20160715",
|
||||
Operation = "NewRobotToken",
|
||||
BodyText = """{"deviceId":"robot-123"}"""
|
||||
});
|
||||
|
||||
using var payload = JsonDocument.Parse(result.BodyText);
|
||||
Assert.Equal(200, result.StatusCode);
|
||||
Assert.Contains("robot-123", payload.RootElement.GetProperty("token").GetString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetUpdateFrom_ReturnsNoOpUpdate()
|
||||
{
|
||||
var result = await _service.DispatchAsync(new ProtocolEnvelope
|
||||
{
|
||||
HostName = "api.jibo.com",
|
||||
Method = "POST",
|
||||
ServicePrefix = "Update_20160715",
|
||||
Operation = "GetUpdateFrom",
|
||||
BodyText = """{"subsystem":"robot","fromVersion":"1.0.0"}"""
|
||||
});
|
||||
|
||||
using var payload = JsonDocument.Parse(result.BodyText);
|
||||
Assert.Equal(200, result.StatusCode);
|
||||
Assert.Equal("robot", payload.RootElement.GetProperty("subsystem").GetString());
|
||||
Assert.True(payload.RootElement.TryGetProperty("url", out _));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Text.Json;
|
||||
using Jibo.Cloud.Application.Services;
|
||||
using Jibo.Cloud.Domain.Models;
|
||||
using Jibo.Cloud.Infrastructure.Persistence;
|
||||
|
||||
namespace Jibo.Cloud.Tests.WebSockets;
|
||||
|
||||
public sealed class JiboWebSocketServiceTests
|
||||
{
|
||||
private readonly JiboWebSocketService _service;
|
||||
|
||||
public JiboWebSocketServiceTests()
|
||||
{
|
||||
var store = new InMemoryCloudStateStore();
|
||||
_service = new JiboWebSocketService(
|
||||
store,
|
||||
new ProtocolToTurnContextMapper(),
|
||||
new DemoConversationBroker(),
|
||||
new ResponsePlanToSocketMessagesMapper());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListenMessage_ReturnsResponseAndEos()
|
||||
{
|
||||
var replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||
{
|
||||
HostName = "neo-hub.jibo.com",
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = "hub-test-token",
|
||||
Text = """{"type":"LISTEN","data":{"text":"hello jibo"}}"""
|
||||
});
|
||||
|
||||
Assert.Equal(2, replies.Count);
|
||||
Assert.Contains("OPENJIBO_RESPONSE", replies[0].Text);
|
||||
Assert.Contains("EOS", replies[1].Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BinaryMessage_ReturnsAcknowledgementPayload()
|
||||
{
|
||||
var replies = await _service.HandleMessageAsync(new WebSocketMessageEnvelope
|
||||
{
|
||||
HostName = "neo-hub.jibo.com",
|
||||
Path = "/listen",
|
||||
Kind = "neo-hub-listen",
|
||||
Token = "hub-test-token",
|
||||
Binary = [1, 2, 3, 4]
|
||||
});
|
||||
|
||||
using var payload = JsonDocument.Parse(replies[0].Text!);
|
||||
Assert.Equal("OPENJIBO_AUDIO_RECEIVED", payload.RootElement.GetProperty("type").GetString());
|
||||
Assert.Equal(4, payload.RootElement.GetProperty("data").GetProperty("bytes").GetInt32());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user