mirror of
https://github.com/Routstr/routstrd.git
synced 2026-10-05 20:38:22 +00:00
fixed init
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "routstrd",
|
||||
"dependencies": {
|
||||
"@cashu/cashu-ts": "^3.1.1",
|
||||
"@routstr/sdk": "^0.1.2",
|
||||
"@routstr/sdk": "^0.1.4",
|
||||
"applesauce-core": "^5.1.0",
|
||||
"applesauce-relay": "^5.1.0",
|
||||
"better-sqlite3": "^11.7.2",
|
||||
@@ -31,7 +30,7 @@
|
||||
|
||||
"@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="],
|
||||
|
||||
"@routstr/sdk": ["@routstr/sdk@0.1.2", "", { "dependencies": { "@cashu/cashu-ts": "^3.1.1", "applesauce-core": "^5.1.0", "applesauce-relay": "^5.1.0", "rxjs": "^7.8.1", "zustand": "^5.0.5" }, "optionalDependencies": { "better-sqlite3": "^11.7.2" }, "peerDependencies": { "typescript": ">=5.0.0" } }, "sha512-KzcEVAPaQTV9V/AKpAJLQ0YiCjXX4t2Ebz1t+id5dSl/YqTPHZZXm2HA+mT2xKlqcf8GK7hTdj312WxVji1nWQ=="],
|
||||
"@routstr/sdk": ["@routstr/sdk@0.1.4", "", { "dependencies": { "@cashu/cashu-ts": "^3.1.1", "applesauce-core": "^5.1.0", "applesauce-relay": "^5.1.0", "rxjs": "^7.8.1", "zustand": "^5.0.5" }, "optionalDependencies": { "better-sqlite3": "^11.7.2" }, "peerDependencies": { "typescript": ">=5.0.0" } }, "sha512-4NQV7IcB1UkiO2HQa0as5OBu0v3pZ7TO265oTjMNYPtYMdYOSXjF+uPBcHCRJLfVhnTN4OOCmUQnnhYM0gR6Zw=="],
|
||||
|
||||
"@scure/base": ["@scure/base@2.0.0", "", {}, "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w=="],
|
||||
|
||||
|
||||
+44
-9
@@ -251,13 +251,29 @@ async function main(): Promise<void> {
|
||||
const discoveryAdapter = createDiscoveryAdapterFromStore(store);
|
||||
const providerRegistry = createProviderRegistryFromStore(store);
|
||||
const storageAdapter = createStorageAdapterFromStore(store);
|
||||
|
||||
logger.log("Bootstrapping providers...");
|
||||
const modelManager = new ModelManager(discoveryAdapter);
|
||||
const providers = await modelManager.bootstrapProviders(false);
|
||||
logger.log(`Bootstrapped ${providers.length} providers`);
|
||||
await modelManager.fetchModels(providers);
|
||||
logger.log("Provider bootstrap complete.");
|
||||
|
||||
let providerBootstrapPromise: Promise<void> | null = null;
|
||||
const ensureProvidersBootstrapped = (): Promise<void> => {
|
||||
if (!providerBootstrapPromise) {
|
||||
providerBootstrapPromise = (async () => {
|
||||
logger.log("Bootstrapping providers...");
|
||||
const providers = await modelManager.bootstrapProviders(false);
|
||||
logger.log(`Bootstrapped ${providers.length} providers`);
|
||||
await modelManager.fetchModels(providers);
|
||||
logger.log("Provider bootstrap complete.");
|
||||
})().catch((error) => {
|
||||
logger.error("Provider bootstrap failed:", error);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
return providerBootstrapPromise;
|
||||
};
|
||||
|
||||
// Start bootstrap in background so daemon can become healthy quickly.
|
||||
void ensureProvidersBootstrapped().catch(() => {
|
||||
// Error is already logged; keep daemon alive for troubleshooting/retries.
|
||||
});
|
||||
|
||||
let activeMintUrl: string | null = null;
|
||||
let mintUnits: Record<string, "sat" | "msat"> = {};
|
||||
@@ -378,6 +394,7 @@ async function main(): Promise<void> {
|
||||
|
||||
if (req.method === "GET" && url.pathname === "/models") {
|
||||
try {
|
||||
await ensureProvidersBootstrapped();
|
||||
await modelManager.fetchRoutstr21Models();
|
||||
const models = discoveryAdapter.getRoutstr21Models();
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
@@ -581,6 +598,7 @@ async function main(): Promise<void> {
|
||||
undefined;
|
||||
|
||||
try {
|
||||
await ensureProvidersBootstrapped();
|
||||
const response = await routeRequests({
|
||||
modelId,
|
||||
requestBody,
|
||||
@@ -665,6 +683,8 @@ async function main(): Promise<void> {
|
||||
export async function startDaemon(options: { port?: string; provider?: string } = {}): Promise<void> {
|
||||
const args: string[] = [];
|
||||
const port = options.port || "8008";
|
||||
const pollIntervalMs = 250;
|
||||
const startupTimeoutMs = 10 * 60 * 1000;
|
||||
|
||||
try {
|
||||
const existing = await fetch(`http://localhost:${port}/health`);
|
||||
@@ -697,9 +717,22 @@ export async function startDaemon(options: { port?: string; provider?: string }
|
||||
|
||||
proc.unref();
|
||||
|
||||
let exitCode: number | null = null;
|
||||
proc.exited.then((code) => {
|
||||
exitCode = code;
|
||||
});
|
||||
|
||||
// Poll until the daemon is healthy
|
||||
for (let i = 0; i < 100; i++) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
const maxPolls = Math.ceil(startupTimeoutMs / pollIntervalMs);
|
||||
for (let i = 0; i < maxPolls; i++) {
|
||||
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
||||
|
||||
if (exitCode !== null) {
|
||||
throw new Error(
|
||||
`Daemon process exited early with code ${exitCode}. Check logs at ${LOG_FILE}`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch(`http://localhost:${port}/health`);
|
||||
if (res.ok) {
|
||||
@@ -711,7 +744,9 @@ export async function startDaemon(options: { port?: string; provider?: string }
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("Daemon failed to start within 20 seconds");
|
||||
throw new Error(
|
||||
`Daemon failed to start within ${Math.round(startupTimeoutMs / 1000)} seconds. Check logs at ${LOG_FILE}`
|
||||
);
|
||||
}
|
||||
|
||||
// Only auto-run main() when this file is executed directly (not imported)
|
||||
|
||||
+13
-1
@@ -16,7 +16,19 @@ async function writeLog(level: string, ...args: unknown[]) {
|
||||
await ensureLogDir();
|
||||
const timestamp = new Date().toISOString();
|
||||
const message = args
|
||||
.map((a) => (typeof a === "object" ? JSON.stringify(a) : String(a)))
|
||||
.map((a) => {
|
||||
if (a instanceof Error) {
|
||||
return `${a.message}${a.stack ? `\n${a.stack}` : ""}`;
|
||||
}
|
||||
if (typeof a === "object") {
|
||||
try {
|
||||
return JSON.stringify(a);
|
||||
} catch {
|
||||
return String(a);
|
||||
}
|
||||
}
|
||||
return String(a);
|
||||
})
|
||||
.join(" ");
|
||||
const line = `[${timestamp}] [${level}] ${message}\n`;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user