gotta fix storage.

This commit is contained in:
red
2026-02-25 04:35:46 +00:00
parent e2d89d99bb
commit 7092749876
5 changed files with 135 additions and 20 deletions

View File

@@ -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());
},
};
}

View File

@@ -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) {

View File

@@ -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";

View File

@@ -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
View 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"}
]
}'