mirror of
https://github.com/Routstr/routstrd.git
synced 2026-07-22 12:22:20 +00:00
gotta fix storage.
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
import { program } from "commander";
|
import { program } from "commander";
|
||||||
import { existsSync } from "fs";
|
import { existsSync, createWriteStream } from "fs";
|
||||||
|
import { appendFile } from "fs/promises";
|
||||||
import {
|
import {
|
||||||
CONFIG_FILE,
|
CONFIG_FILE,
|
||||||
DEFAULT_CONFIG,
|
DEFAULT_CONFIG,
|
||||||
|
LOG_FILE,
|
||||||
type RoutstrdConfig,
|
type RoutstrdConfig,
|
||||||
} from "./utils/config";
|
} from "./utils/config";
|
||||||
|
|
||||||
@@ -55,12 +57,27 @@ export async function isDaemonRunning(): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function startDaemonProcess(): Promise<void> {
|
export async function startDaemonProcess(): Promise<void> {
|
||||||
const proc = Bun.spawn({
|
const logWriter = createLogWriter();
|
||||||
cmd: ["bun", "run", `${import.meta.dir}/index.ts`, "daemon"],
|
const proc = Bun.spawn([
|
||||||
stdout: "ignore",
|
"bun", "run", `${import.meta.dir}/index.ts`, "daemon"
|
||||||
stderr: "ignore",
|
], {
|
||||||
|
stdout: "pipe",
|
||||||
|
stderr: "pipe",
|
||||||
stdin: "ignore",
|
stdin: "ignore",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
proc.stdout?.pipeTo(new WritableStream({
|
||||||
|
write(data) {
|
||||||
|
logWriter.write(data.toString());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
proc.stderr?.pipeTo(new WritableStream({
|
||||||
|
write(data) {
|
||||||
|
logWriter.writeError(data.toString());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
proc.unref();
|
proc.unref();
|
||||||
|
|
||||||
for (let i = 0; i < 50; i++) {
|
for (let i = 0; i < 50; i++) {
|
||||||
@@ -121,3 +138,25 @@ export async function handleDaemonCommand(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export { program, callDaemon };
|
export { program, callDaemon };
|
||||||
|
|
||||||
|
async function writeToLog(line: string): Promise<void> {
|
||||||
|
try {
|
||||||
|
await appendFile(LOG_FILE, line + "\n");
|
||||||
|
} catch {
|
||||||
|
// Ignore log errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createLogWriter() {
|
||||||
|
let logStream: ReturnType<typeof createWriteStream> | null = null;
|
||||||
|
return {
|
||||||
|
write(data: string) {
|
||||||
|
process.stdout.write(data);
|
||||||
|
writeToLog(data.trimEnd());
|
||||||
|
},
|
||||||
|
writeError(data: string) {
|
||||||
|
process.stderr.write(data);
|
||||||
|
writeToLog(data.trimEnd());
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
43
src/cli.ts
43
src/cli.ts
@@ -6,12 +6,14 @@ import {
|
|||||||
ensureDaemonRunning,
|
ensureDaemonRunning,
|
||||||
isDaemonRunning,
|
isDaemonRunning,
|
||||||
} from "./cli-shared";
|
} from "./cli-shared";
|
||||||
import { existsSync, mkdirSync } from "fs";
|
import { existsSync, mkdirSync, createWriteStream } from "fs";
|
||||||
|
import { appendFile } from "fs/promises";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import {
|
import {
|
||||||
CONFIG_DIR,
|
CONFIG_DIR,
|
||||||
DB_PATH,
|
DB_PATH,
|
||||||
CONFIG_FILE,
|
CONFIG_FILE,
|
||||||
|
LOG_FILE,
|
||||||
DEFAULT_CONFIG,
|
DEFAULT_CONFIG,
|
||||||
type RoutstrdConfig,
|
type RoutstrdConfig,
|
||||||
} from "./utils/config";
|
} from "./utils/config";
|
||||||
@@ -40,12 +42,43 @@ async function initDaemon(): Promise<void> {
|
|||||||
console.log(`Database will be stored at: ${DB_PATH}`);
|
console.log(`Database will be stored at: ${DB_PATH}`);
|
||||||
console.log("\nInitializing cocod...");
|
console.log("\nInitializing cocod...");
|
||||||
|
|
||||||
|
async function writeToLog(line: string): Promise<void> {
|
||||||
|
try {
|
||||||
|
await appendFile(LOG_FILE, line + "\n");
|
||||||
|
} catch {
|
||||||
|
// Ignore log errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logWriter = {
|
||||||
|
write(data: string) {
|
||||||
|
process.stdout.write(data);
|
||||||
|
writeToLog(data.trimEnd());
|
||||||
|
},
|
||||||
|
writeError(data: string) {
|
||||||
|
process.stderr.write(data);
|
||||||
|
writeToLog(data.trimEnd());
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// Initialize cocod
|
// Initialize cocod
|
||||||
const initProc = Bun.spawn({
|
const initProc = Bun.spawn(["cocod", "init"], {
|
||||||
cmd: ["cocod", "init"],
|
stdout: "pipe",
|
||||||
stdout: "inherit",
|
stderr: "pipe",
|
||||||
stderr: "inherit",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
initProc.stdout?.pipeTo(new WritableStream({
|
||||||
|
write(data) {
|
||||||
|
logWriter.write(data.toString());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
initProc.stderr?.pipeTo(new WritableStream({
|
||||||
|
write(data) {
|
||||||
|
logWriter.writeError(data.toString());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
const initCode = await initProc.exited;
|
const initCode = await initProc.exited;
|
||||||
|
|
||||||
if (initCode !== 0) {
|
if (initCode !== 0) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Readable } from "stream";
|
|||||||
import { ReadableStream as WebReadableStream } from "stream/web";
|
import { ReadableStream as WebReadableStream } from "stream/web";
|
||||||
import { spawn } from "child_process";
|
import { spawn } from "child_process";
|
||||||
import { getDecodedToken } from "@cashu/cashu-ts";
|
import { getDecodedToken } from "@cashu/cashu-ts";
|
||||||
import { mkdir } from "fs/promises";
|
import { mkdir, appendFile } from "fs/promises";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { existsSync } from "fs";
|
import { existsSync } from "fs";
|
||||||
import SQLite from "bun:sqlite";
|
import SQLite from "bun:sqlite";
|
||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
SOCKET_PATH,
|
SOCKET_PATH,
|
||||||
PID_FILE,
|
PID_FILE,
|
||||||
CONFIG_FILE,
|
CONFIG_FILE,
|
||||||
|
LOG_FILE,
|
||||||
DEFAULT_CONFIG,
|
DEFAULT_CONFIG,
|
||||||
type RoutstrdConfig,
|
type RoutstrdConfig,
|
||||||
} from "./utils/config";
|
} from "./utils/config";
|
||||||
@@ -32,7 +33,7 @@ async function loadSdk() {
|
|||||||
function createBunSqliteDriver(dbPath: string) {
|
function createBunSqliteDriver(dbPath: string) {
|
||||||
const db = new SQLite(dbPath);
|
const db = new SQLite(dbPath);
|
||||||
|
|
||||||
db.exec(`
|
db.run(`
|
||||||
CREATE TABLE IF NOT EXISTS sdk_storage (
|
CREATE TABLE IF NOT EXISTS sdk_storage (
|
||||||
key TEXT PRIMARY KEY,
|
key TEXT PRIMARY KEY,
|
||||||
value TEXT NOT NULL
|
value TEXT NOT NULL
|
||||||
@@ -245,11 +246,10 @@ async function main(): Promise<void> {
|
|||||||
saveConfig(updatedConfig);
|
saveConfig(updatedConfig);
|
||||||
|
|
||||||
const sdkModule = await loadSdk();
|
const sdkModule = await loadSdk();
|
||||||
const { ModelManager, getDefaultDiscoveryAdapter, getDefaultProviderRegistry, getDefaultStorageAdapter, createMemoryDriver, createSdkStore } = sdkModule;
|
const { ModelManager, getDefaultDiscoveryAdapter, getDefaultProviderRegistry, getDefaultStorageAdapter, createSdkStore } = sdkModule;
|
||||||
|
|
||||||
// For now, use memory driver (can be upgraded to sqlite later)
|
const sqliteDriver = createBunSqliteDriver(DB_PATH);
|
||||||
const memoryDriver = createMemoryDriver();
|
const store = createSdkStore({ driver: sqliteDriver });
|
||||||
const store = createSdkStore({ driver: memoryDriver });
|
|
||||||
|
|
||||||
// Get adapters (these use the default store, but we'll work with what we have)
|
// Get adapters (these use the default store, but we'll work with what we have)
|
||||||
const discoveryAdapter = getDefaultDiscoveryAdapter();
|
const discoveryAdapter = getDefaultDiscoveryAdapter();
|
||||||
@@ -590,13 +590,44 @@ export async function startDaemon(options: { port?: string; provider?: string }
|
|||||||
args.push("--provider", options.provider);
|
args.push("--provider", options.provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function writeToLog(line: string): Promise<void> {
|
||||||
|
try {
|
||||||
|
await appendFile(LOG_FILE, line + "\n");
|
||||||
|
} catch {
|
||||||
|
// Ignore log errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logWriter = {
|
||||||
|
write(data: string) {
|
||||||
|
process.stdout.write(data);
|
||||||
|
writeToLog(data.trimEnd());
|
||||||
|
},
|
||||||
|
writeError(data: string) {
|
||||||
|
process.stderr.write(data);
|
||||||
|
writeToLog(data.trimEnd());
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// Spawn daemon.ts directly as a detached background process
|
// Spawn daemon.ts directly as a detached background process
|
||||||
const proc = Bun.spawn({
|
const proc = Bun.spawn(["bun", "run", `${import.meta.dir}/daemon.ts`, ...args], {
|
||||||
cmd: ["bun", "run", `${import.meta.dir}/daemon.ts`, ...args],
|
stdout: "pipe",
|
||||||
stdout: "inherit",
|
stderr: "pipe",
|
||||||
stderr: "inherit",
|
|
||||||
stdin: "ignore",
|
stdin: "ignore",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
proc.stdout?.pipeTo(new WritableStream({
|
||||||
|
write(data) {
|
||||||
|
logWriter.write(data.toString());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
proc.stderr?.pipeTo(new WritableStream({
|
||||||
|
write(data) {
|
||||||
|
logWriter.writeError(data.toString());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
proc.unref();
|
proc.unref();
|
||||||
|
|
||||||
const port = options.port || "8008";
|
const port = options.port || "8008";
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const SOCKET_PATH = process.env.ROUTSTRD_SOCKET || `${CONFIG_DIR}/routstr
|
|||||||
export const PID_FILE = process.env.ROUTSTRD_PID || `${CONFIG_DIR}/routstrd.pid`;
|
export const PID_FILE = process.env.ROUTSTRD_PID || `${CONFIG_DIR}/routstrd.pid`;
|
||||||
export const DB_PATH = `${CONFIG_DIR}/routstr.db`;
|
export const DB_PATH = `${CONFIG_DIR}/routstr.db`;
|
||||||
export const CONFIG_FILE = `${CONFIG_DIR}/config.json`;
|
export const CONFIG_FILE = `${CONFIG_DIR}/config.json`;
|
||||||
|
export const LOG_FILE = `${CONFIG_DIR}/routstrd.log`;
|
||||||
|
|
||||||
export interface RoutstrdConfig {
|
export interface RoutstrdConfig {
|
||||||
port: number;
|
port: number;
|
||||||
|
|||||||
11
test_curl.sh
Executable file
11
test_curl.sh
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
curl -X POST "http://localhost:8008/v1/chat/completions" \
|
||||||
|
-H "Authorization: Bearer YOUR_API_KEY" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"model": "gemma-3n-e4b-it",
|
||||||
|
"messages": [
|
||||||
|
{"role":"system","content":"You are Routstr."},
|
||||||
|
{"role":"user","content":"Ping the node"}
|
||||||
|
]
|
||||||
|
}'
|
||||||
Reference in New Issue
Block a user