diff --git a/src/cli.ts b/src/cli.ts index 5780245..7b0f7b9 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -6,6 +6,7 @@ import { ensureDaemonRunning, isDaemonRunning, loadConfig, + getDaemonBaseUrl, } from "./utils/daemon-client"; import { existsSync, mkdirSync } from "fs"; import { execSync } from "child_process"; @@ -820,7 +821,7 @@ clientsCmd } console.log( - `\n Access Routstr at: http://localhost:${config.port || 8008}/v1`, + `\n Access Routstr at: ${getDaemonBaseUrl(config)}/v1`, ); return; } @@ -860,7 +861,7 @@ clientsCmd console.log(` Name: ${output.client.name}`); console.log(` API Key: ${output.client.apiKey}`); console.log( - `\n Access Routstr at: http://localhost:${config.port || 8008}/v1`, + `\n Access Routstr at: ${getDaemonBaseUrl(config)}/v1`, ); } }); diff --git a/src/integrations/claudecode.ts b/src/integrations/claudecode.ts index 0a4e5c5..22bfb64 100644 --- a/src/integrations/claudecode.ts +++ b/src/integrations/claudecode.ts @@ -6,6 +6,7 @@ import { logger } from "../utils/logger"; import type { SdkStore } from "@routstr/sdk"; import type { IntegrationConfig, RoutstrModel } from "./registry"; import { generateApiKey } from "./registry"; +import { callDaemon, getDaemonBaseUrl } from "../utils/daemon-client"; export async function installClaudeCodeIntegration( config: RoutstrdConfig, @@ -16,7 +17,7 @@ export async function installClaudeCodeIntegration( logger.log(`\nInstalling routstr configuration in ${configPath}...`); - const port = config.port || 8008; + const baseUrl = getDaemonBaseUrl(config); // Get or create clientId entry const state = store.getState(); @@ -60,12 +61,11 @@ export async function installClaudeCodeIntegration( } settings.env["ANTHROPIC_AUTH_TOKEN"] = apiKey; - settings.env["ANTHROPIC_BASE_URL"] = `http://localhost:${port}`; + settings.env["ANTHROPIC_BASE_URL"] = baseUrl; try { - const response = await fetch(`http://localhost:${port}/models`); - const data = await response.json() as { output?: { models: RoutstrModel[] } }; - const models = data.output?.models || []; + const data = await callDaemon("/models"); + const models = (data.output as { models: RoutstrModel[] } | undefined)?.models || []; if (models.length >= 3) { settings.env["ANTHROPIC_DEFAULT_OPUS_MODEL"] = models[0].id; diff --git a/src/integrations/openclaw.ts b/src/integrations/openclaw.ts index b16a204..c8de2bb 100644 --- a/src/integrations/openclaw.ts +++ b/src/integrations/openclaw.ts @@ -6,6 +6,7 @@ import { logger } from "../utils/logger"; import type { SdkStore } from "@routstr/sdk"; import type { IntegrationConfig, RoutstrModel } from "./registry"; import { generateApiKey } from "./registry"; +import { callDaemon, getDaemonBaseUrl } from "../utils/daemon-client"; const OPENCLAW_PROVIDER_ID = "routstr"; const OPENCLAW_DEFAULT_PRIMARY_MODEL = "routstr/minimax-m2.5"; @@ -59,7 +60,7 @@ export async function installOpenClawIntegration( logger.log("\nInstalling routstr models in openclaw.json..."); - const port = config.port || 8008; + const baseUrl = getDaemonBaseUrl(config); // Get or create clientId entry for OpenClaw const state = store.getState(); @@ -113,9 +114,8 @@ export async function installOpenClawIntegration( try { mkdirSync(dirname(configPath), { recursive: true }); - const response = await fetch(`http://localhost:${port}/models`); - const data = await response.json() as { output?: { models: RoutstrModel[] } }; - const models = data.output?.models || []; + const data = await callDaemon("/models"); + const models = (data.output as { models: RoutstrModel[] } | undefined)?.models || []; if (models.length === 0) { logger.log("No models found from routstr daemon."); @@ -129,7 +129,7 @@ export async function installOpenClawIntegration( })); openclawConfig.models.providers[OPENCLAW_PROVIDER_ID] = { - baseUrl: `http://localhost:${port}/v1`, + baseUrl: `${baseUrl}/v1`, apiKey, api: "openai-completions", models: providerModels, diff --git a/src/integrations/opencode.ts b/src/integrations/opencode.ts index 325becf..b725017 100644 --- a/src/integrations/opencode.ts +++ b/src/integrations/opencode.ts @@ -6,6 +6,7 @@ import { logger } from "../utils/logger"; import type { SdkStore } from "@routstr/sdk"; import type { IntegrationConfig, RoutstrModel } from "./registry"; import { generateApiKey } from "./registry"; +import { callDaemon, getDaemonBaseUrl } from "../utils/daemon-client"; const OPENCODE_SMALL_MODEL = "routstr/minimax-m2.5"; @@ -18,7 +19,7 @@ export async function installOpencodeIntegration( logger.log("\nInstalling routstr models in opencode.json..."); - const port = config.port || 8008; + const baseUrl = getDaemonBaseUrl(config); // Get or create clientId entry for OpenCode const state = store.getState(); @@ -77,9 +78,8 @@ export async function installOpencodeIntegration( try { mkdirSync(dirname(configPath), { recursive: true }); - const response = await fetch(`http://localhost:${port}/models`); - const data = await response.json() as { output?: { models: RoutstrModel[] } }; - const models = data.output?.models || []; + const data = await callDaemon("/models"); + const models = (data.output as { models: RoutstrModel[] } | undefined)?.models || []; if (models.length === 0) { logger.log("No models found from routstr daemon."); @@ -95,7 +95,7 @@ export async function installOpencodeIntegration( npm: "@ai-sdk/openai-compatible", name: "routstr", options: { - baseURL: `http://localhost:${port}/`, + baseURL: `${baseUrl}/`, apiKey, includeUsage: true, }, diff --git a/src/integrations/pi.ts b/src/integrations/pi.ts index 2823010..7e99b68 100644 --- a/src/integrations/pi.ts +++ b/src/integrations/pi.ts @@ -6,6 +6,7 @@ import { logger } from "../utils/logger"; import type { SdkStore } from "@routstr/sdk"; import type { IntegrationConfig, RoutstrModel } from "./registry"; import { generateApiKey } from "./registry"; +import { callDaemon, getDaemonBaseUrl } from "../utils/daemon-client"; type PiModelEntry = { id: string; @@ -31,8 +32,7 @@ export async function installPiIntegration( logger.log("\nInstalling routstr models in pi models.json..."); - const port = config.port || 8008; - const baseUrl = `http://localhost:${port}/v1`; + const baseUrl = `${getDaemonBaseUrl(config)}/v1`; // Get or create clientId entry for Pi Agent const state = store.getState(); @@ -78,9 +78,8 @@ export async function installPiIntegration( // Ensure directory exists mkdirSync(dirname(configPath), { recursive: true }); - const response = await fetch(`http://localhost:${port}/models`); - const data = await response.json() as { output?: { models: RoutstrModel[] } }; - const models = data.output?.models || []; + const data = await callDaemon("/models"); + const models = (data.output as { models: RoutstrModel[] } | undefined)?.models || []; if (models.length === 0) { logger.log("No models found from routstr daemon."); diff --git a/src/utils/daemon-client.ts b/src/utils/daemon-client.ts index 7c0ae7e..aeb9826 100644 --- a/src/utils/daemon-client.ts +++ b/src/utils/daemon-client.ts @@ -28,7 +28,7 @@ export async function loadConfig(): Promise { return DEFAULT_CONFIG; } -function getDaemonBaseUrl(config: RoutstrdConfig): string { +export function getDaemonBaseUrl(config: RoutstrdConfig): string { return config.daemonUrl?.replace(/\/$/, "") || `http://localhost:${config.port}`; }