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 { existsSync } from "fs";
|
||||
import { existsSync, createWriteStream } from "fs";
|
||||
import { appendFile } from "fs/promises";
|
||||
import {
|
||||
CONFIG_FILE,
|
||||
DEFAULT_CONFIG,
|
||||
LOG_FILE,
|
||||
type RoutstrdConfig,
|
||||
} from "./utils/config";
|
||||
|
||||
@@ -55,12 +57,27 @@ export async function isDaemonRunning(): Promise<boolean> {
|
||||
}
|
||||
|
||||
export async function startDaemonProcess(): Promise<void> {
|
||||
const proc = Bun.spawn({
|
||||
cmd: ["bun", "run", `${import.meta.dir}/index.ts`, "daemon"],
|
||||
stdout: "ignore",
|
||||
stderr: "ignore",
|
||||
const logWriter = createLogWriter();
|
||||
const proc = Bun.spawn([
|
||||
"bun", "run", `${import.meta.dir}/index.ts`, "daemon"
|
||||
], {
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
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();
|
||||
|
||||
for (let i = 0; i < 50; i++) {
|
||||
@@ -121,3 +138,25 @@ export async function handleDaemonCommand(
|
||||
}
|
||||
|
||||
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,
|
||||
isDaemonRunning,
|
||||
} from "./cli-shared";
|
||||
import { existsSync, mkdirSync } from "fs";
|
||||
import { existsSync, mkdirSync, createWriteStream } from "fs";
|
||||
import { appendFile } from "fs/promises";
|
||||
import { join } from "path";
|
||||
import {
|
||||
CONFIG_DIR,
|
||||
DB_PATH,
|
||||
CONFIG_FILE,
|
||||
LOG_FILE,
|
||||
DEFAULT_CONFIG,
|
||||
type RoutstrdConfig,
|
||||
} from "./utils/config";
|
||||
@@ -40,12 +42,43 @@ async function initDaemon(): Promise<void> {
|
||||
console.log(`Database will be stored at: ${DB_PATH}`);
|
||||
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
|
||||
const initProc = Bun.spawn({
|
||||
cmd: ["cocod", "init"],
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
const initProc = Bun.spawn(["cocod", "init"], {
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
if (initCode !== 0) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Readable } from "stream";
|
||||
import { ReadableStream as WebReadableStream } from "stream/web";
|
||||
import { spawn } from "child_process";
|
||||
import { getDecodedToken } from "@cashu/cashu-ts";
|
||||
import { mkdir } from "fs/promises";
|
||||
import { mkdir, appendFile } from "fs/promises";
|
||||
import { join } from "path";
|
||||
import { existsSync } from "fs";
|
||||
import SQLite from "bun:sqlite";
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
SOCKET_PATH,
|
||||
PID_FILE,
|
||||
CONFIG_FILE,
|
||||
LOG_FILE,
|
||||
DEFAULT_CONFIG,
|
||||
type RoutstrdConfig,
|
||||
} from "./utils/config";
|
||||
@@ -32,7 +33,7 @@ async function loadSdk() {
|
||||
function createBunSqliteDriver(dbPath: string) {
|
||||
const db = new SQLite(dbPath);
|
||||
|
||||
db.exec(`
|
||||
db.run(`
|
||||
CREATE TABLE IF NOT EXISTS sdk_storage (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL
|
||||
@@ -245,11 +246,10 @@ async function main(): Promise<void> {
|
||||
saveConfig(updatedConfig);
|
||||
|
||||
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 memoryDriver = createMemoryDriver();
|
||||
const store = createSdkStore({ driver: memoryDriver });
|
||||
const sqliteDriver = createBunSqliteDriver(DB_PATH);
|
||||
const store = createSdkStore({ driver: sqliteDriver });
|
||||
|
||||
// Get adapters (these use the default store, but we'll work with what we have)
|
||||
const discoveryAdapter = getDefaultDiscoveryAdapter();
|
||||
@@ -590,13 +590,44 @@ export async function startDaemon(options: { port?: string; provider?: string }
|
||||
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
|
||||
const proc = Bun.spawn({
|
||||
cmd: ["bun", "run", `${import.meta.dir}/daemon.ts`, ...args],
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
const proc = Bun.spawn(["bun", "run", `${import.meta.dir}/daemon.ts`, ...args], {
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
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();
|
||||
|
||||
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 DB_PATH = `${CONFIG_DIR}/routstr.db`;
|
||||
export const CONFIG_FILE = `${CONFIG_DIR}/config.json`;
|
||||
export const LOG_FILE = `${CONFIG_DIR}/routstrd.log`;
|
||||
|
||||
export interface RoutstrdConfig {
|
||||
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