fix: fixes name in various files
Build & Deploy / build (push) Failing after 1m13s

This commit is contained in:
lucretia.dietz
2026-07-20 07:54:02 +02:00
parent 31aed75ee4
commit 6278bfbcfc
39 changed files with 112 additions and 112 deletions
+5 -5
View File
@@ -18,13 +18,13 @@ jobs:
dotnet-version: '10.0.x' dotnet-version: '10.0.x'
- name: Restore dependencies - name: Restore dependencies
run: dotnet restore src/ReverseLlama.Server run: dotnet restore src/Ngino.Server
- name: Build - name: Build
run: dotnet build src/ReverseLlama.Server --configuration Release --no-restore run: dotnet build src/Ngino.Server --configuration Release --no-restore
- name: Publish - name: Publish
run: dotnet publish src/ReverseLlama.Server -c Release -o publish run: dotnet publish src/Ngino.Server -c Release -o publish
- name: Copy files to server - name: Copy files to server
uses: appleboy/scp-action@v1.0.0 uses: appleboy/scp-action@v1.0.0
@@ -34,7 +34,7 @@ jobs:
password: ${{ secrets.DEPLOY_SSH_PASSWORD }} password: ${{ secrets.DEPLOY_SSH_PASSWORD }}
port: ${{ secrets.DEPLOY_SSH_PORT }} port: ${{ secrets.DEPLOY_SSH_PORT }}
source: "publish/*" source: "publish/*"
target: "/var/www/ReverseLlama" target: "/var/www/Ngino"
strip_components: 1 strip_components: 1
- name: Restart app - name: Restart app
@@ -45,4 +45,4 @@ jobs:
password: ${{ secrets.DEPLOY_SSH_PASSWORD }} password: ${{ secrets.DEPLOY_SSH_PASSWORD }}
port: ${{ secrets.DEPLOY_SSH_PORT }} port: ${{ secrets.DEPLOY_SSH_PORT }}
script: | script: |
sudo systemctl restart ReverseLlama.service sudo systemctl restart Ngino.service
+4 -4
View File
@@ -5,15 +5,15 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReverseLlama.Protocol", "src\ReverseLlama.Protocol\ReverseLlama.Protocol.csproj", "{D85E1D3C-0AC3-4810-8285-16BE903EC8AB}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ngino.Protocol", "src\Ngino.Protocol\Ngino.Protocol.csproj", "{D85E1D3C-0AC3-4810-8285-16BE903EC8AB}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReverseLlama.Server", "src\ReverseLlama.Server\ReverseLlama.Server.csproj", "{FB853CB0-5AEF-4278-82E7-3C8E506F9DFE}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ngino.Server", "src\Ngino.Server\Ngino.Server.csproj", "{FB853CB0-5AEF-4278-82E7-3C8E506F9DFE}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReverseLlama.Client", "src\ReverseLlama.Client\ReverseLlama.Client.csproj", "{0633EAE6-B82A-4A27-851C-B5D6E11CBE03}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ngino.Client", "src\Ngino.Client\Ngino.Client.csproj", "{0633EAE6-B82A-4A27-851C-B5D6E11CBE03}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0AB3BF05-4346-4AA6-1389-037BE0695223}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{0AB3BF05-4346-4AA6-1389-037BE0695223}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReverseLlama.Client.Tests", "tests\ReverseLlama.Client.Tests\ReverseLlama.Client.Tests.csproj", "{B03E7794-2888-4B56-A30F-B6C25BCFB89A}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ngino.Client.Tests", "tests\Ngino.Client.Tests\Ngino.Client.Tests.csproj", "{B03E7794-2888-4B56-A30F-B6C25BCFB89A}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
+11 -11
View File
@@ -62,14 +62,14 @@ dotnet run --project src/Ngino.Client -- --server http://your-server:5050 --upst
Call Ollama through the server. Model-bearing requests on the root path are routed to a connected client that reports that model, preferring the client with the fewest in-flight requests. You can still address one client explicitly by id: Call Ollama through the server. Model-bearing requests on the root path are routed to a connected client that reports that model, preferring the client with the fewest in-flight requests. You can still address one client explicitly by id:
```powershell ```powershell
curl.exe -H "X-Reverse-Llama-Token: change-me" http://your-server:5050/api/tags curl.exe -H "X-Ngino-Token: change-me" http://your-server:5050/api/tags
curl.exe -H "X-Reverse-Llama-Token: change-me" http://your-server:5050/clients/gpu-01/api/tags curl.exe -H "X-Ngino-Token: change-me" http://your-server:5050/clients/gpu-01/api/tags
curl.exe http://your-server:5050/token/change-me/api/tags curl.exe http://your-server:5050/token/change-me/api/tags
curl.exe http://your-server:5050/token/change-me/clients/gpu-01/api/tags curl.exe http://your-server:5050/token/change-me/clients/gpu-01/api/tags
``` ```
```powershell ```powershell
curl.exe -H "X-Reverse-Llama-Token: change-me" ` curl.exe -H "X-Ngino-Token: change-me" `
-H "Content-Type: application/json" ` -H "Content-Type: application/json" `
-d '{"model":"llama3.1","prompt":"hello"}' ` -d '{"model":"llama3.1","prompt":"hello"}' `
http://your-server:5050/api/generate http://your-server:5050/api/generate
@@ -79,9 +79,9 @@ curl.exe -H "X-Reverse-Llama-Token: change-me" `
Server options: Server options:
- `--token <value>` or `REVERSE_LLAMA_TOKEN`: optional shared token. If set, proxy calls must authenticate with `X-Reverse-Llama-Token`, `Authorization: Bearer <token>`, or the `/token/<token>/...` path prefix. - `--token <value>` or `REVERSE_LLAMA_TOKEN`: optional shared token. If set, proxy calls must authenticate with `X-Ngino-Token`, `Authorization: Bearer <token>`, or the `/token/<token>/...` path prefix.
- `--tunnel-path <path>`: defaults to `/_reverse-llama/tunnel`. - `--tunnel-path <path>`: defaults to `/_ngino/tunnel`.
- `--status-path <path>`: defaults to `/_reverse-llama/status`. - `--status-path <path>`: defaults to `/_ngino/status`.
- `--chunk-size <bytes>` or `REVERSE_LLAMA_CHUNK_SIZE`: defaults to `65536`. - `--chunk-size <bytes>` or `REVERSE_LLAMA_CHUNK_SIZE`: defaults to `65536`.
- `--embedding-cache-path <path>` or `REVERSE_LLAMA_EMBEDDING_CACHE_PATH`: SQLite cache file for embedding vectors. Defaults to `App_Data\embedding-cache.sqlite` under the server app directory. - `--embedding-cache-path <path>` or `REVERSE_LLAMA_EMBEDDING_CACHE_PATH`: SQLite cache file for embedding vectors. Defaults to `App_Data\embedding-cache.sqlite` under the server app directory.
- `--management-database-path <path>` or `REVERSE_LLAMA_MANAGEMENT_DATABASE_PATH`: SQLite database for admin user keys, client keys, client disable state, and request/model metrics. Defaults to `App_Data\management.sqlite` under the server app directory. - `--management-database-path <path>` or `REVERSE_LLAMA_MANAGEMENT_DATABASE_PATH`: SQLite database for admin user keys, client keys, client disable state, and request/model metrics. Defaults to `App_Data\management.sqlite` under the server app directory.
@@ -91,7 +91,7 @@ Admin UI:
- `GET /admin` opens the Keycloak-protected management UI. - `GET /admin` opens the Keycloak-protected management UI.
- The temporary Keycloak settings live under `Authentication:Keycloak` in `appsettings.json`. - The temporary Keycloak settings live under `Authentication:Keycloak` in `appsettings.json`.
- User keys created in the UI are accepted anywhere the shared token is accepted: `X-Reverse-Llama-Token`, `Authorization: Bearer <key>`, `?token=...`, and `/token/<key>/...`. - User keys created in the UI are accepted anywhere the shared token is accepted: `X-Ngino-Token`, `Authorization: Bearer <key>`, `?token=...`, and `/token/<key>/...`.
- Model add/remove/load/unload commands are sent through the connected tunnel client to Ollama (`/api/pull`, `/api/delete`, `/api/generate`, and `/api/show`). - Model add/remove/load/unload commands are sent through the connected tunnel client to Ollama (`/api/pull`, `/api/delete`, `/api/generate`, and `/api/show`).
Client options: Client options:
@@ -100,11 +100,11 @@ Client options:
- `--upstream <url>` or `REVERSE_LLAMA_UPSTREAM`: local Ollama URL, defaults to `http://localhost:11434`. - `--upstream <url>` or `REVERSE_LLAMA_UPSTREAM`: local Ollama URL, defaults to `http://localhost:11434`.
- `--token <value>` or `REVERSE_LLAMA_TOKEN`: optional shared token. - `--token <value>` or `REVERSE_LLAMA_TOKEN`: optional shared token.
- `--client-id <name>` or `REVERSE_LLAMA_CLIENT_ID`: identifies this machine on the server; defaults to the machine name. - `--client-id <name>` or `REVERSE_LLAMA_CLIENT_ID`: identifies this machine on the server; defaults to the machine name.
- `--tunnel-path <path>` or `REVERSE_LLAMA_TUNNEL_PATH`: defaults to `/_reverse-llama/tunnel`. - `--tunnel-path <path>` or `REVERSE_LLAMA_TUNNEL_PATH`: defaults to `/_ngino/tunnel`.
- `--reconnect-delay <seconds>` or `REVERSE_LLAMA_RECONNECT_DELAY_SECONDS`: defaults to `5`. - `--reconnect-delay <seconds>` or `REVERSE_LLAMA_RECONNECT_DELAY_SECONDS`: defaults to `5`.
- `--chunk-size <bytes>` or `REVERSE_LLAMA_CHUNK_SIZE`: defaults to `65536`. - `--chunk-size <bytes>` or `REVERSE_LLAMA_CHUNK_SIZE`: defaults to `65536`.
The token is accepted as `X-Reverse-Llama-Token`, as `Authorization: Bearer <token>`, or as a path prefix like `/token/<token>/api/tags` or `/token/<token>/clients/{id}/v1`. The Bearer form lets OpenAI-compatible clients (e.g. n8n's OpenAI nodes pointed at `/clients/{id}/v1`) authenticate with their API-key field. The path-token form is useful for clients that cannot send custom headers. The server strips its own token header/Bearer value and removes the path prefix before forwarding; any other `Authorization` value is forwarded untouched. The token is accepted as `X-Ngino-Token`, as `Authorization: Bearer <token>`, or as a path prefix like `/token/<token>/api/tags` or `/token/<token>/clients/{id}/v1`. The Bearer form lets OpenAI-compatible clients (e.g. n8n's OpenAI nodes pointed at `/clients/{id}/v1`) authenticate with their API-key field. The path-token form is useful for clients that cannot send custom headers. The server strips its own token header/Bearer value and removes the path prefix before forwarding; any other `Authorization` value is forwarded untouched.
## Multiple clients ## Multiple clients
@@ -118,7 +118,7 @@ Any number of machines can connect at the same time; each registers under its cl
## Embedding cache ## Embedding cache
The server keeps an in-memory KV cache for embedding vectors and persists it to SQLite. The cache key is the requested `model` plus the exact input text. It applies to `POST /api/embed`, `POST /api/embeddings`, and `POST /v1/embeddings`; cache hits return JSON in the same endpoint family shape and include `X-Reverse-Llama-Embedding-Cache: hit`. The server keeps an in-memory KV cache for embedding vectors and persists it to SQLite. The cache key is the requested `model` plus the exact input text. It applies to `POST /api/embed`, `POST /api/embeddings`, and `POST /v1/embeddings`; cache hits return JSON in the same endpoint family shape and include `X-Ngino-Embedding-Cache: hit`.
The authenticated status endpoint reports whether the cache is available, plus the cache count and database path. If SQLite cannot be initialized, proxy traffic continues without embedding-cache writes. The authenticated status endpoint reports whether the cache is available, plus the cache count and database path. If SQLite cannot be initialized, proxy traffic continues without embedding-cache writes.
@@ -141,7 +141,7 @@ The script ensures .NET 10 and Ollama are installed, builds the client self-cont
## Security notes ## Security notes
- Use HTTPS or a private network/VPN when exposing this outside a trusted network. - Use HTTPS or a private network/VPN when exposing this outside a trusted network.
- **Tokens in URLs** (`/token/<token>/...` and `?token=...`) are logged by web servers (Apache, Nginx, Kestrel), reverse proxies, and browsers (history). Malicious MITM proxies can also read them. Prefer header-based auth (`X-Reverse-Llama-Token` or `Authorization: Bearer`) when your client supports it. - **Tokens in URLs** (`/token/<token>/...` and `?token=...`) are logged by web servers (Apache, Nginx, Kestrel), reverse proxies, and browsers (history). Malicious MITM proxies can also read them. Prefer header-based auth (`X-Ngino-Token` or `Authorization: Bearer`) when your client supports it.
- The token is simple shared-secret protection, not a full access-control system. - The token is simple shared-secret protection, not a full access-control system.
## AI Disclosure ## AI Disclosure
+11 -11
View File
@@ -33,10 +33,10 @@ usage() {
cat <<EOF cat <<EOF
Usage: $0 [OPTIONS] Usage: $0 [OPTIONS]
Installs the ReverseLlama client as a systemd service on Linux. Installs the Ngino client as a systemd service on Linux.
Required: Required:
--server <url> ReverseLlama server URL (e.g. http://my-server:5050) --server <url> Ngino server URL (e.g. http://my-server:5050)
--token <value> Shared secret token for the server --token <value> Shared secret token for the server
Optional: Optional:
@@ -71,7 +71,7 @@ done
# ── Prompt for missing required values ─────────────────────────────────────── # ── Prompt for missing required values ───────────────────────────────────────
if [[ -z "$SERVER_URL" ]]; then if [[ -z "$SERVER_URL" ]]; then
read -rp "ReverseLlama server URL (e.g. http://my-server:5050): " SERVER_URL read -rp "Ngino server URL (e.g. http://my-server:5050): " SERVER_URL
fi fi
if [[ -z "$SERVER_URL" ]]; then if [[ -z "$SERVER_URL" ]]; then
die "Server URL is required." die "Server URL is required."
@@ -225,7 +225,7 @@ else
fi fi
# ── Build client from source ───────────────────────────────────────────────── # ── Build client from source ─────────────────────────────────────────────────
CLIENT_SRC="$REPO_ROOT/src/ReverseLlama.Client" CLIENT_SRC="$REPO_ROOT/src/Ngino.Client"
if [[ ! -d "$CLIENT_SRC" ]]; then if [[ ! -d "$CLIENT_SRC" ]]; then
die "Client source not found at $CLIENT_SRC. Run this script from the repository or pass --install-dir." die "Client source not found at $CLIENT_SRC. Run this script from the repository or pass --install-dir."
fi fi
@@ -238,18 +238,18 @@ case "$ARCH" in
*) die "Unsupported architecture: $ARCH" ;; *) die "Unsupported architecture: $ARCH" ;;
esac esac
info "Building ReverseLlama client (self-contained, $DOTNET_RID)..." info "Building Ngino client (self-contained, $DOTNET_RID)..."
BUILD_DIR="$(mktemp -d /tmp/ngino-build.XXXXXX)" BUILD_DIR="$(mktemp -d /tmp/ngino-build.XXXXXX)"
trap 'rm -rf "$BUILD_DIR"' EXIT trap 'rm -rf "$BUILD_DIR"' EXIT
"$DOTNET_CMD" publish "$CLIENT_SRC/ReverseLlama.Client.csproj" \ "$DOTNET_CMD" publish "$CLIENT_SRC/Ngino.Client.csproj" \
-c Release \ -c Release \
-r "$DOTNET_RID" \ -r "$DOTNET_RID" \
--self-contained true \ --self-contained true \
-o "$BUILD_DIR" -o "$BUILD_DIR"
if [[ ! -f "$BUILD_DIR/ReverseLlama.Client" ]]; then if [[ ! -f "$BUILD_DIR/Ngino.Client" ]]; then
die "Build failed. ReverseLlama.Client binary not found in output." die "Build failed. Ngino.Client binary not found in output."
fi fi
info "Build successful." info "Build successful."
@@ -258,7 +258,7 @@ info "Build successful."
info "Installing to $INSTALL_DIR..." info "Installing to $INSTALL_DIR..."
mkdir -p "$INSTALL_DIR" mkdir -p "$INSTALL_DIR"
cp -a "$BUILD_DIR"/. "$INSTALL_DIR/" cp -a "$BUILD_DIR"/. "$INSTALL_DIR/"
chmod +x "$INSTALL_DIR/ReverseLlama.Client" chmod +x "$INSTALL_DIR/Ngino.Client"
info "Client installed to $INSTALL_DIR." info "Client installed to $INSTALL_DIR."
@@ -279,7 +279,7 @@ fi
cat > "$SERVICE_FILE" <<EOF cat > "$SERVICE_FILE" <<EOF
[Unit] [Unit]
Description=ReverseLlama Tunnel Client Description=Ngino Tunnel Client
After=network-online.target After=network-online.target
Wants=network-online.target Wants=network-online.target
$([ "$SKIP_OLLAMA" = "false" ] && echo "After=ollama.service") $([ "$SKIP_OLLAMA" = "false" ] && echo "After=ollama.service")
@@ -287,7 +287,7 @@ $([ "$SKIP_OLLAMA" = "false" ] && echo "Wants=ollama.service")
[Service] [Service]
Type=simple Type=simple
ExecStart=$INSTALL_DIR/ReverseLlama.Client --server "$SERVER_URL" --upstream "$UPSTREAM" --client-id "$CLIENT_ID" ExecStart=$INSTALL_DIR/Ngino.Client --server "$SERVER_URL" --upstream "$UPSTREAM" --client-id "$CLIENT_ID"
Restart=always Restart=always
RestartSec=5 RestartSec=5
Environment=DOTNET_CLI_TELEMETRY_OPTOUT=1 Environment=DOTNET_CLI_TELEMETRY_OPTOUT=1
+1 -1
View File
@@ -1,7 +1,7 @@
using System.Net; using System.Net;
using System.Threading.Channels; using System.Threading.Channels;
namespace ReverseLlama.Client; namespace Ngino.Client;
internal sealed class ChannelHttpContent : HttpContent internal sealed class ChannelHttpContent : HttpContent
{ {
+4 -4
View File
@@ -1,6 +1,6 @@
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Client; namespace Ngino.Client;
internal sealed class ClientOptions internal sealed class ClientOptions
{ {
@@ -59,12 +59,12 @@ internal sealed class ClientOptions
public static string Usage => public static string Usage =>
""" """
ReverseLlama.Client options: Ngino.Client options:
--server <url> Server base URL, e.g. http://my-server:5050 --server <url> Server base URL, e.g. http://my-server:5050
--upstream <url> Local upstream URL, e.g. http://localhost:11434 --upstream <url> Local upstream URL, e.g. http://localhost:11434
--token <value> Optional token matching the server --token <value> Optional token matching the server
--client-id <name> Identifies this machine on the server; defaults to the machine name --client-id <name> Identifies this machine on the server; defaults to the machine name
--tunnel-path <path> Defaults to /_reverse-llama/tunnel --tunnel-path <path> Defaults to /_ngino/tunnel
--reconnect-delay <sec> Defaults to 5 --reconnect-delay <sec> Defaults to 5
--chunk-size <bytes> Defaults to 65536 --chunk-size <bytes> Defaults to 65536
"""; """;
+1 -1
View File
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ReverseLlama.Protocol\ReverseLlama.Protocol.csproj" /> <ProjectReference Include="..\Ngino.Protocol\Ngino.Protocol.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
+4 -4
View File
@@ -1,13 +1,13 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using ReverseLlama.Client; using Ngino.Client;
try try
{ {
var options = ClientOptions.Parse(args); var options = ClientOptions.Parse(args);
Console.WriteLine("ReverseLlama client"); Console.WriteLine("Ngino client");
Console.WriteLine($" client id: {options.ClientId}"); Console.WriteLine($" client id: {options.ClientId}");
Console.WriteLine($" server tunnel: {options.TunnelUri}"); Console.WriteLine($" server tunnel: {options.TunnelUri}");
Console.WriteLine($" local upstream: {options.Upstream}"); Console.WriteLine($" local upstream: {options.Upstream}");
@@ -17,9 +17,9 @@ try
builder.Services.AddSingleton(options); builder.Services.AddSingleton(options);
builder.Services.AddSingleton<TunnelClient>(); builder.Services.AddSingleton<TunnelClient>();
builder.Services.AddHostedService<TunnelWorker>(); builder.Services.AddHostedService<TunnelWorker>();
builder.Services.AddWindowsService(service => service.ServiceName = "ReverseLlamaClient"); builder.Services.AddWindowsService(service => service.ServiceName = "NginoClient");
// The EventLog provider defaults to Warning; connection state is worth seeing there. // The EventLog provider defaults to Warning; connection state is worth seeing there.
builder.Logging.AddFilter<Microsoft.Extensions.Logging.EventLog.EventLogLoggerProvider>("ReverseLlama.Client", LogLevel.Information); builder.Logging.AddFilter<Microsoft.Extensions.Logging.EventLog.EventLogLoggerProvider>("Ngino.Client", LogLevel.Information);
await builder.Build().RunAsync(); await builder.Build().RunAsync();
return 0; return 0;
+1 -1
View File
@@ -1,3 +1,3 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("ReverseLlama.Client.Tests")] [assembly: InternalsVisibleTo("Ngino.Client.Tests")]
+3 -3
View File
@@ -4,16 +4,16 @@ using System.Text;
using System.Text.Json; using System.Text.Json;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Client; namespace Ngino.Client;
internal sealed class TunnelClient internal sealed class TunnelClient
{ {
private static readonly TimeSpan ModelRefreshInterval = TimeSpan.FromSeconds(15); private static readonly TimeSpan ModelRefreshInterval = TimeSpan.FromSeconds(15);
private static readonly TimeSpan ModelRefreshTimeout = TimeSpan.FromSeconds(10); private static readonly TimeSpan ModelRefreshTimeout = TimeSpan.FromSeconds(10);
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web); private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
private const string EmbeddingWarmupInput = "ReverseLlama warmup"; private const string EmbeddingWarmupInput = "Ngino warmup";
private readonly ConcurrentDictionary<string, UpstreamRequest> _activeRequests = new(); private readonly ConcurrentDictionary<string, UpstreamRequest> _activeRequests = new();
private readonly HttpClient _httpClient; private readonly HttpClient _httpClient;
+1 -1
View File
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
namespace ReverseLlama.Client; namespace Ngino.Client;
internal sealed class TunnelWorker : BackgroundService internal sealed class TunnelWorker : BackgroundService
{ {
+2 -2
View File
@@ -1,8 +1,8 @@
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Threading.Channels; using System.Threading.Channels;
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Client; namespace Ngino.Client;
internal sealed class UpstreamRequest internal sealed class UpstreamRequest
{ {
+1 -1
View File
@@ -1,4 +1,4 @@
namespace ReverseLlama.Protocol; namespace Ngino.Protocol;
public sealed class HeaderPair public sealed class HeaderPair
{ {
+5 -5
View File
@@ -1,10 +1,10 @@
namespace ReverseLlama.Protocol; namespace Ngino.Protocol;
public static class ProtocolConstants public static class ProtocolConstants
{ {
public const string DefaultStatusPath = "/_reverse-llama/status"; public const string DefaultStatusPath = "/_ngino/status";
public const string DefaultTunnelPath = "/_reverse-llama/tunnel"; public const string DefaultTunnelPath = "/_ngino/tunnel";
public const string TokenHeader = "X-Reverse-Llama-Token"; public const string TokenHeader = "X-Ngino-Token";
public const string ClientIdHeader = "X-Reverse-Llama-Client-Id"; public const string ClientIdHeader = "X-Ngino-Client-Id";
public const string ReplacedCloseDescription = "reverse-llama-replaced"; public const string ReplacedCloseDescription = "reverse-llama-replaced";
} }
+1 -1
View File
@@ -1,4 +1,4 @@
namespace ReverseLlama.Protocol; namespace Ngino.Protocol;
public sealed class TunnelMessage public sealed class TunnelMessage
{ {
+1 -1
View File
@@ -1,4 +1,4 @@
namespace ReverseLlama.Protocol; namespace Ngino.Protocol;
public static class TunnelMessageTypes public static class TunnelMessageTypes
{ {
@@ -1,7 +1,7 @@
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Text.Json; using System.Text.Json;
namespace ReverseLlama.Protocol; namespace Ngino.Protocol;
public static class WebSocketMessageTransport public static class WebSocketMessageTransport
{ {
+3 -3
View File
@@ -9,10 +9,10 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles; using Microsoft.AspNetCore.StaticFiles;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using ReverseLlama.Server.Data; using Ngino.Server.Data;
using ReverseLlama.Server.Models; using Ngino.Server.Models;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal static class AdminEndpoints internal static class AdminEndpoints
{ {
+1 -1
View File
@@ -1,7 +1,7 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using ElmahCore; using ElmahCore;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal sealed class AuthRateLimiter internal sealed class AuthRateLimiter
{ {
@@ -1,8 +1,8 @@
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using ReverseLlama.Server.Models; using Ngino.Server.Models;
namespace ReverseLlama.Server.Data; namespace Ngino.Server.Data;
internal sealed class ApplicationDbContext : IdentityDbContext<ApplicationUser> internal sealed class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{ {
+3 -3
View File
@@ -2,9 +2,9 @@ using System.Collections.Concurrent;
using System.Text.Json; using System.Text.Json;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal sealed class EmbeddingCache internal sealed class EmbeddingCache
{ {
@@ -121,7 +121,7 @@ internal sealed class EmbeddingCache
context.Response.StatusCode = StatusCodes.Status200OK; context.Response.StatusCode = StatusCodes.Status200OK;
context.Response.ContentType = JsonContentType; context.Response.ContentType = JsonContentType;
context.Response.ContentLength = body.Length; context.Response.ContentLength = body.Length;
context.Response.Headers["X-Reverse-Llama-Embedding-Cache"] = "hit"; context.Response.Headers["X-Ngino-Embedding-Cache"] = "hit";
await context.Response.Body.WriteAsync(body, context.RequestAborted); await context.Response.Body.WriteAsync(body, context.RequestAborted);
return true; return true;
+1 -1
View File
@@ -3,7 +3,7 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal sealed class ManagementStore internal sealed class ManagementStore
{ {
+1 -1
View File
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
namespace ReverseLlama.Server.Models; namespace Ngino.Server.Models;
internal sealed class ApplicationUser : IdentityUser internal sealed class ApplicationUser : IdentityUser
{ {
+1 -1
View File
@@ -10,7 +10,7 @@
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.3" /> <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.3" />
<PackageReference Include="System.Text.Encodings.Web" Version="8.0.0" /> <PackageReference Include="System.Text.Encodings.Web" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.5" /> <PackageReference Include="System.Text.Json" Version="8.0.5" />
<ProjectReference Include="..\ReverseLlama.Protocol\ReverseLlama.Protocol.csproj" /> <ProjectReference Include="..\Ngino.Protocol\Ngino.Protocol.csproj" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
+2 -2
View File
@@ -1,6 +1,6 @@
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal sealed class PendingCommand internal sealed class PendingCommand
{ {
+2 -2
View File
@@ -1,7 +1,7 @@
using System.Threading.Channels; using System.Threading.Channels;
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal sealed class PendingProxyRequest internal sealed class PendingProxyRequest
{ {
+6 -6
View File
@@ -7,10 +7,10 @@ using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using ReverseLlama.Protocol; using Ngino.Protocol;
using ReverseLlama.Server; using Ngino.Server;
using ReverseLlama.Server.Data; using Ngino.Server.Data;
using ReverseLlama.Server.Models; using Ngino.Server.Models;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
var settings = ServerSettings.FromConfiguration(builder.Configuration); var settings = ServerSettings.FromConfiguration(builder.Configuration);
@@ -33,7 +33,7 @@ if (settings.Keycloak.IsConfigured)
}) })
.AddCookie(options => .AddCookie(options =>
{ {
options.Cookie.Name = "ReverseLlama.Admin"; options.Cookie.Name = "Ngino.Admin";
options.Cookie.SameSite = SameSiteMode.Lax; options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.SecurePolicy = settings.SecureCookies ? CookieSecurePolicy.Always : CookieSecurePolicy.None; options.Cookie.SecurePolicy = settings.SecureCookies ? CookieSecurePolicy.Always : CookieSecurePolicy.None;
options.LoginPath = "/admin/login"; options.LoginPath = "/admin/login";
@@ -103,7 +103,7 @@ if (!settings.Keycloak.IsConfigured)
builder.Services.ConfigureApplicationCookie(options => builder.Services.ConfigureApplicationCookie(options =>
{ {
options.Cookie.Name = "ReverseLlama.Admin"; options.Cookie.Name = "Ngino.Admin";
options.Cookie.SameSite = SameSiteMode.Lax; options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.SecurePolicy = settings.SecureCookies ? CookieSecurePolicy.Always : CookieSecurePolicy.None; options.Cookie.SecurePolicy = settings.SecureCookies ? CookieSecurePolicy.Always : CookieSecurePolicy.None;
options.LoginPath = "/admin/login"; options.LoginPath = "/admin/login";
+1 -1
View File
@@ -1,7 +1,7 @@
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal sealed class ResponseTokenCounter internal sealed class ResponseTokenCounter
{ {
+4 -4
View File
@@ -2,13 +2,13 @@ using System.Text.Json;
using ElmahCore; using ElmahCore;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal static class ReverseProxyEndpoint internal static class ReverseProxyEndpoint
{ {
private const string UnauthorizedMessage = "Missing or invalid ReverseLlama token."; private const string UnauthorizedMessage = "Missing or invalid Ngino token.";
private static readonly HashSet<string> HopByHopHeaders = new(StringComparer.OrdinalIgnoreCase) private static readonly HashSet<string> HopByHopHeaders = new(StringComparer.OrdinalIgnoreCase)
{ {
@@ -501,7 +501,7 @@ internal static class ReverseProxyEndpoint
ManagementStore managementStore, ManagementStore managementStore,
string? userKeyId = null) string? userKeyId = null)
{ {
var logger = loggerFactory.CreateLogger("ReverseLlama.Server.ReverseProxy"); var logger = loggerFactory.CreateLogger("Ngino.Server.ReverseProxy");
var requestId = Guid.NewGuid().ToString("n"); var requestId = Guid.NewGuid().ToString("n");
var pending = connection.RegisterPending(requestId); var pending = connection.RegisterPending(requestId);
var startedAt = DateTimeOffset.UtcNow; var startedAt = DateTimeOffset.UtcNow;
+10 -10
View File
@@ -1,7 +1,7 @@
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal sealed class ServerSettings internal sealed class ServerSettings
{ {
@@ -29,22 +29,22 @@ internal sealed class ServerSettings
{ {
return new ServerSettings return new ServerSettings
{ {
StatusPath = NormalizePath(Read(configuration, "ReverseLlama:StatusPath", "status-path") ?? ProtocolConstants.DefaultStatusPath), StatusPath = NormalizePath(Read(configuration, "Ngino:StatusPath", "status-path") ?? ProtocolConstants.DefaultStatusPath),
TunnelPath = NormalizePath(Read(configuration, "ReverseLlama:TunnelPath", "tunnel-path") ?? ProtocolConstants.DefaultTunnelPath), TunnelPath = NormalizePath(Read(configuration, "Ngino:TunnelPath", "tunnel-path") ?? ProtocolConstants.DefaultTunnelPath),
Token = Read(configuration, "ReverseLlama:Token", "token") ?? Environment.GetEnvironmentVariable("REVERSE_LLAMA_TOKEN"), Token = Read(configuration, "Ngino:Token", "token") ?? Environment.GetEnvironmentVariable("REVERSE_LLAMA_TOKEN"),
ClientToken = Read(configuration, "ReverseLlama:ClientToken", "client-token") ?? Environment.GetEnvironmentVariable("REVERSE_LLAMA_CLIENT_TOKEN"), ClientToken = Read(configuration, "Ngino:ClientToken", "client-token") ?? Environment.GetEnvironmentVariable("REVERSE_LLAMA_CLIENT_TOKEN"),
ChunkSize = ReadInt(configuration, 64 * 1024, "ReverseLlama:ChunkSize", "chunk-size", "REVERSE_LLAMA_CHUNK_SIZE"), ChunkSize = ReadInt(configuration, 64 * 1024, "Ngino:ChunkSize", "chunk-size", "REVERSE_LLAMA_CHUNK_SIZE"),
EmbeddingCachePath = Read( EmbeddingCachePath = Read(
configuration, configuration,
"ReverseLlama:EmbeddingCachePath", "Ngino:EmbeddingCachePath",
"embedding-cache-path", "embedding-cache-path",
"REVERSE_LLAMA_EMBEDDING_CACHE_PATH"), "REVERSE_LLAMA_EMBEDDING_CACHE_PATH"),
ManagementDatabasePath = Read( ManagementDatabasePath = Read(
configuration, configuration,
"ReverseLlama:ManagementDatabasePath", "Ngino:ManagementDatabasePath",
"management-database-path", "management-database-path",
"REVERSE_LLAMA_MANAGEMENT_DATABASE_PATH"), "REVERSE_LLAMA_MANAGEMENT_DATABASE_PATH"),
SecureCookies = ReadBool(configuration, true, "ReverseLlama:SecureCookies", "secure-cookies", "REVERSE_LLAMA_SECURE_COOKIES"), SecureCookies = ReadBool(configuration, true, "Ngino:SecureCookies", "secure-cookies", "REVERSE_LLAMA_SECURE_COOKIES"),
Keycloak = new KeycloakSettings Keycloak = new KeycloakSettings
{ {
Authority = Read(configuration, "Authentication:Keycloak:Authority", "REVERSE_LLAMA_KEYCLOAK_AUTHORITY"), Authority = Read(configuration, "Authentication:Keycloak:Authority", "REVERSE_LLAMA_KEYCLOAK_AUTHORITY"),
+2 -2
View File
@@ -1,8 +1,8 @@
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal static class TokenAuthentication internal static class TokenAuthentication
{ {
+2 -2
View File
@@ -1,8 +1,8 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net.WebSockets; using System.Net.WebSockets;
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal sealed class TunnelConnection internal sealed class TunnelConnection
{ {
+2 -2
View File
@@ -1,9 +1,9 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net.WebSockets; using System.Net.WebSockets;
using System.Threading; using System.Threading;
using ReverseLlama.Protocol; using Ngino.Protocol;
namespace ReverseLlama.Server; namespace Ngino.Server;
internal sealed class TunnelHub internal sealed class TunnelHub
{ {
+1 -1
View File
@@ -11,7 +11,7 @@
"Authentication": { "Authentication": {
"Keycloak": { "Keycloak": {
"Authority": "http://your-keycloak-server/realms/master", "Authority": "http://your-keycloak-server/realms/master",
"ClientId": "ReverseLlama", "ClientId": "Ngino",
"ClientSecret": "YOUR-Client-SECRET-GOES-HERE-AND-YES-ITS-VERY-LONG", "ClientSecret": "YOUR-Client-SECRET-GOES-HERE-AND-YES-ITS-VERY-LONG",
"RequireHttpsMetadata": false "RequireHttpsMetadata": false
} }
+2 -2
View File
@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>ReverseLlama Admin</title> <title>Ngino Admin</title>
<link rel="stylesheet" href="/admin/app.css"> <link rel="stylesheet" href="/admin/app.css">
</head> </head>
<body> <body>
@@ -12,7 +12,7 @@
<div class="brand"> <div class="brand">
<span class="brand-mark">RL</span> <span class="brand-mark">RL</span>
<span> <span>
<strong>ReverseLlama</strong> <strong>Ngino</strong>
<small>Admin</small> <small>Admin</small>
</span> </span>
</div> </div>
@@ -2,7 +2,7 @@ using System.Diagnostics;
using System.Text.Json; using System.Text.Json;
using Xunit; using Xunit;
namespace ReverseLlama.Client.Tests; namespace Ngino.Client.Tests;
public sealed class PackageAuditTests public sealed class PackageAuditTests
{ {
@@ -32,7 +32,7 @@ public sealed class PackageAuditTests
var directory = new DirectoryInfo(AppContext.BaseDirectory); var directory = new DirectoryInfo(AppContext.BaseDirectory);
while (directory is not null) while (directory is not null)
{ {
var solutionPath = Path.Combine(directory.FullName, "ReverseLlama.sln"); var solutionPath = Path.Combine(directory.FullName, "Ngino.sln");
if (File.Exists(solutionPath)) if (File.Exists(solutionPath))
{ {
return solutionPath; return solutionPath;
@@ -41,7 +41,7 @@ public sealed class PackageAuditTests
directory = directory.Parent; directory = directory.Parent;
} }
throw new InvalidOperationException("Could not find ReverseLlama.sln from the test output directory."); throw new InvalidOperationException("Could not find Ngino.sln from the test output directory.");
} }
private static async Task<CommandResult> RunDotnetPackageAuditAsync(string solutionPath) private static async Task<CommandResult> RunDotnetPackageAuditAsync(string solutionPath)
@@ -18,7 +18,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\ReverseLlama.Client\ReverseLlama.Client.csproj" /> <ProjectReference Include="..\..\src\Ngino.Client\Ngino.Client.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -1,8 +1,8 @@
using System.Text.Json; using System.Text.Json;
using ReverseLlama.Client; using Ngino.Client;
using Xunit; using Xunit;
namespace ReverseLlama.Client.Tests; namespace Ngino.Client.Tests;
public sealed class TunnelClientModelTests public sealed class TunnelClientModelTests
{ {
@@ -56,7 +56,7 @@ public sealed class TunnelClientModelTests
Assert.Equal(HttpMethod.Post, request.Method); Assert.Equal(HttpMethod.Post, request.Method);
Assert.Equal("http://localhost:11434/api/embed", request.RequestUri!.AbsoluteUri); Assert.Equal("http://localhost:11434/api/embed", request.RequestUri!.AbsoluteUri);
Assert.Equal("bge-m3:latest", document.RootElement.GetProperty("model").GetString()); Assert.Equal("bge-m3:latest", document.RootElement.GetProperty("model").GetString());
Assert.Equal("ReverseLlama warmup", document.RootElement.GetProperty("input").GetString()); Assert.Equal("Ngino warmup", document.RootElement.GetProperty("input").GetString());
Assert.Equal(expectedKeepAlive, document.RootElement.GetProperty("keep_alive").GetInt32()); Assert.Equal(expectedKeepAlive, document.RootElement.GetProperty("keep_alive").GetInt32());
} }
} }
@@ -1,7 +1,7 @@
using ReverseLlama.Client; using Ngino.Client;
using Xunit; using Xunit;
namespace ReverseLlama.Client.Tests; namespace Ngino.Client.Tests;
public sealed class UpstreamRequestTests public sealed class UpstreamRequestTests
{ {