Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/usr/bin/env tsx
import { Command } from 'commander';
import chalk from 'chalk';
import { readFileSync } from 'node:fs';

const { version: pkgVersion } = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8')) as { version: string };
import { makeAuthCommand } from './commands/auth.js';
import { makeModelCommand } from './commands/model.js';
import { makeProjectCommand } from './commands/project.js';
Expand All @@ -18,7 +21,7 @@ program
chalk.bold('Routerly.ai') + ' — One gateway. Any AI model. Total control.\n' +
chalk.gray('Proxy, route and cost-track AI model calls from OpenAI/Anthropic-compatible clients.')
)
.version('0.0.1');
.version(pkgVersion);

program.addCommand(makeStatusCommand());
program.addCommand(makeAuthCommand());
Expand Down
2 changes: 1 addition & 1 deletion packages/dashboard/src/pages/TestPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export function TestPage() {
abortControllerRef.current = controller;

const payload = {
model: 'gpt-4o',
model: matchedProject?.routingModelId || matchedProject?.models?.[0]?.modelId || '',
messages: newMessages,
stream: true,
};
Expand Down
2 changes: 1 addition & 1 deletion packages/dashboard/src/pages/project/ProjectGeneralTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function ProjectGeneralTab() {
const payload = isEdit
? {
name: form.name,
routingModelId: project!.routingModelId || 'gpt-4o',
...(project!.routingModelId ? { routingModelId: project!.routingModelId } : {}),
models: project!.models.map(m => ({ modelId: m.modelId })),
timeoutMs: parseInt(form.timeoutMs),
}
Expand Down
2 changes: 1 addition & 1 deletion packages/dashboard/src/pages/project/ProjectTestTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export function ProjectTestTab() {
abortControllerRef.current = controller;

const payload = {
model: project?.routingModelId || 'gpt-4o',
model: project?.routingModelId || project?.models?.[0]?.modelId || '',
messages: newMessages,
stream: true,
};
Expand Down
22 changes: 20 additions & 2 deletions packages/dashboard/src/pages/project/ProjectTokenCreatePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,26 @@ export function ProjectTokenCreatePage() {
const allLabels = Array.from(new Set((project.tokens || []).flatMap(t => t.labels || []))).sort();

async function copyToClipboard(token: string) {
try { await navigator.clipboard.writeText(token); setCopied(true); setTimeout(() => setCopied(false), 2000); }
catch { setErr('Failed to copy to clipboard.'); }
const success = () => { setCopied(true); setTimeout(() => setCopied(false), 2000); };
try {
await navigator.clipboard.writeText(token);
success();
} catch {
// Fallback for non-secure contexts (HTTP, docker self-hosted via IP)
try {
const el = document.createElement('textarea');
el.value = token;
el.style.cssText = 'position:fixed;top:0;left:0;opacity:0;pointer-events:none';
document.body.appendChild(el);
el.focus();
el.select();
const ok = document.execCommand('copy');
document.body.removeChild(el);
if (ok) { success(); } else { setErr('Copy failed — please select and copy the token manually.'); }
} catch {
setErr('Copy failed — please select and copy the token manually.');
}
}
}

async function handleCreate(e: React.FormEvent) {
Expand Down
5 changes: 4 additions & 1 deletion packages/service/src/routes/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { FastifyPluginAsync, FastifyReply, FastifyRequest } from 'fastify';
import { createHash } from 'node:crypto';
import { readFileSync } from 'node:fs';
import bcrypt from 'bcrypt';
import { v4 as uuidv4 } from 'uuid';
import { randomBytes } from 'node:crypto';
Expand All @@ -10,6 +11,8 @@ import type { ModelConfig, ProjectConfig, UserConfig, RoleConfig, Permission, Pr
import { getTrace } from '../routing/traceStore.js';
import { sendTestNotification } from '../notifications/sender.js';

const { version: pkgVersion } = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf-8')) as { version: string };

// SHA-256 for random tokens only (refresh tokens are not user-chosen passwords)
function hashToken(t: string): string {
return createHash('sha256').update(t).digest('hex');
Expand Down Expand Up @@ -805,7 +808,7 @@ export const apiRoutes: FastifyPluginAsync = async (fastify) => {
// ─── GET /api/system/info ───────────────────────────────────────────────────
fastify.get('/api/system/info', async (_req, reply) => {
return reply.send({
version: '0.0.1',
version: pkgVersion,
nodeVersion: process.version,
platform: process.platform,
configDir: CONFIG_PATHS.config,
Expand Down
4 changes: 3 additions & 1 deletion packages/service/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import cors from '@fastify/cors';
import staticFiles from '@fastify/static';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { readFileSync } from 'node:fs';
import authPlugin from './plugins/auth.js';
import { loadSecret } from './plugins/jwt.js';
import { openaiRoutes } from './routes/openai.js';
Expand All @@ -11,6 +12,7 @@ import { apiRoutes } from './routes/api.js';
import { initConfigDirs, readConfig } from './config/loader.js';

const __dirname = dirname(fileURLToPath(import.meta.url));
const { version: pkgVersion } = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8')) as { version: string };

export async function buildServer() {
const settings = await readConfig('settings');
Expand Down Expand Up @@ -72,7 +74,7 @@ export async function buildServer() {
// ─── Health check ─────────────────────────────────────────────────────────
fastify.get('/health', async () => ({
status: 'ok',
version: '0.0.1',
version: pkgVersion,
timestamp: new Date().toISOString(),
}));

Expand Down
Loading