fix(integrations): use remote daemon URL and callDaemon for client setups

- Export getDaemonBaseUrl from daemon-client for shared URL resolution
- Replace all hardcoded http://localhost: in client integrations
  (opencode, claudecode, openclaw, pi) with getDaemonBaseUrl(config)
- Replace raw fetch(http://localhost:/models) with callDaemon("/models")
  so model fetching works with remote daemons and gets NIP-98 signed
- Fix clients add command output to print the actual daemon base URL
  instead of hardcoded localhost
This commit is contained in:
redshift
2026-04-28 10:07:06 +05:30
parent 8d6a7d7f21
commit 6461b0f84a
6 changed files with 23 additions and 23 deletions

View File

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

View File

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

View File

@@ -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,

View File

@@ -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,
},

View File

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

View File

@@ -28,7 +28,7 @@ export async function loadConfig(): Promise<RoutstrdConfig> {
return DEFAULT_CONFIG;
}
function getDaemonBaseUrl(config: RoutstrdConfig): string {
export function getDaemonBaseUrl(config: RoutstrdConfig): string {
return config.daemonUrl?.replace(/\/$/, "") || `http://localhost:${config.port}`;
}