mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-03 00:17:47 +00:00
fix(test): stabilize proxy integration server ports
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
|
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
|
||||||
import getPort from 'get-port';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
@@ -16,6 +15,29 @@ let tempDir: string;
|
|||||||
let originalTimeoutEnv: string | undefined;
|
let originalTimeoutEnv: string | undefined;
|
||||||
let originalCcsHome: string | undefined;
|
let originalCcsHome: string | undefined;
|
||||||
|
|
||||||
|
function resolveListeningPort(server: http.Server): number {
|
||||||
|
const address = server.address();
|
||||||
|
if (!address || typeof address === 'string') {
|
||||||
|
throw new Error('Failed to resolve server port');
|
||||||
|
}
|
||||||
|
return address.port;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function waitForServerListening(server: http.Server): Promise<number> {
|
||||||
|
if (server.listening) {
|
||||||
|
return resolveListeningPort(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise<number>((resolve, reject) => {
|
||||||
|
const onError = (error: Error) => reject(error);
|
||||||
|
server.once('error', onError);
|
||||||
|
server.once('listening', () => {
|
||||||
|
server.off('error', onError);
|
||||||
|
resolve(resolveListeningPort(server));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function startUpstream(
|
async function startUpstream(
|
||||||
handler: (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void> | void
|
handler: (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void> | void
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@@ -28,9 +50,8 @@ async function startUpstream(
|
|||||||
upstreamSockets.delete(socket);
|
upstreamSockets.delete(socket);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
await new Promise<void>((resolve) =>
|
upstreamServer.listen(0, '127.0.0.1');
|
||||||
upstreamServer.listen(upstreamPort, '127.0.0.1', () => resolve())
|
upstreamPort = await waitForServerListening(upstreamServer);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function requestProxy(payload: unknown, signal?: AbortSignal): Promise<Response> {
|
async function requestProxy(payload: unknown, signal?: AbortSignal): Promise<Response> {
|
||||||
@@ -46,8 +67,6 @@ async function requestProxy(payload: unknown, signal?: AbortSignal): Promise<Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
upstreamPort = await getPort();
|
|
||||||
proxyPort = await getPort();
|
|
||||||
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-proxy-edge-'));
|
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-proxy-edge-'));
|
||||||
originalTimeoutEnv = process.env.CCS_OPENAI_PROXY_REQUEST_TIMEOUT_MS;
|
originalTimeoutEnv = process.env.CCS_OPENAI_PROXY_REQUEST_TIMEOUT_MS;
|
||||||
originalCcsHome = process.env.CCS_HOME;
|
originalCcsHome = process.env.CCS_HOME;
|
||||||
@@ -94,9 +113,10 @@ describe('openai proxy message edge cases', () => {
|
|||||||
};
|
};
|
||||||
proxyServer = startOpenAICompatProxyServer({
|
proxyServer = startOpenAICompatProxyServer({
|
||||||
profile,
|
profile,
|
||||||
port: proxyPort,
|
port: 0,
|
||||||
authToken: 'test-proxy-token',
|
authToken: 'test-proxy-token',
|
||||||
});
|
});
|
||||||
|
proxyPort = await waitForServerListening(proxyServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
it('preserves rate-limit errors from the upstream provider', async () => {
|
it('preserves rate-limit errors from the upstream provider', async () => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
|
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
|
||||||
import getPort from 'get-port';
|
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
import { startOpenAICompatProxyServer } from '../../../src/proxy/server/proxy-server';
|
import { startOpenAICompatProxyServer } from '../../../src/proxy/server/proxy-server';
|
||||||
import type { OpenAICompatProfileConfig } from '../../../src/proxy/profile-router';
|
import type { OpenAICompatProfileConfig } from '../../../src/proxy/profile-router';
|
||||||
@@ -10,52 +9,64 @@ let upstreamBody: unknown;
|
|||||||
let upstreamPort: number;
|
let upstreamPort: number;
|
||||||
let proxyPort: number;
|
let proxyPort: number;
|
||||||
|
|
||||||
function startMockUpstream(): Promise<void> {
|
function resolveListeningPort(server: http.Server): number {
|
||||||
return new Promise((resolve) => {
|
const address = server.address();
|
||||||
upstreamServer = http.createServer(async (req, res) => {
|
if (!address || typeof address === 'string') {
|
||||||
if (req.method !== 'POST' || req.url !== '/v1/chat/completions') {
|
throw new Error('Failed to resolve server port');
|
||||||
res.writeHead(404).end();
|
}
|
||||||
return;
|
return address.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = '';
|
async function waitForServerListening(server: http.Server): Promise<number> {
|
||||||
for await (const chunk of req) {
|
if (server.listening) {
|
||||||
body += chunk.toString();
|
return resolveListeningPort(server);
|
||||||
}
|
}
|
||||||
upstreamBody = JSON.parse(body);
|
|
||||||
const parsed = upstreamBody as {
|
|
||||||
stream?: boolean;
|
|
||||||
messages?: Array<{ role?: string; content?: string | Array<{ type?: string; text?: string }> }>;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (parsed.stream) {
|
return new Promise<number>((resolve, reject) => {
|
||||||
res.writeHead(200, { 'Content-Type': 'text/event-stream' });
|
const onError = (error: Error) => reject(error);
|
||||||
|
server.once('error', onError);
|
||||||
|
server.once('listening', () => {
|
||||||
|
server.off('error', onError);
|
||||||
|
resolve(resolveListeningPort(server));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (parsed.messages?.[0]?.content === 'interleaved tool fragments') {
|
async function startMockUpstream(): Promise<void> {
|
||||||
res.write(
|
upstreamServer = http.createServer(async (req, res) => {
|
||||||
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_1","type":"function","function":{"name":"search"}}]}}]}\n\n'
|
if (req.method !== 'POST' || req.url !== '/v1/chat/completions') {
|
||||||
);
|
res.writeHead(404).end();
|
||||||
res.write(
|
return;
|
||||||
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_2","type":"function","function":{"name":"open"}}]}}]}\n\n'
|
}
|
||||||
);
|
|
||||||
res.write(
|
|
||||||
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\\"path\\":\\"a.ts\\"}"}}]}}]}\n\n'
|
|
||||||
);
|
|
||||||
res.write(
|
|
||||||
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\\"path\\":\\"b.ts\\"}"}}]}}]}\n\n'
|
|
||||||
);
|
|
||||||
res.write(
|
|
||||||
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":9,"completion_tokens":4}}\n\n'
|
|
||||||
);
|
|
||||||
res.end('data: [DONE]\n\n');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let body = '';
|
||||||
|
for await (const chunk of req) {
|
||||||
|
body += chunk.toString();
|
||||||
|
}
|
||||||
|
upstreamBody = JSON.parse(body);
|
||||||
|
const parsed = upstreamBody as {
|
||||||
|
stream?: boolean;
|
||||||
|
messages?: Array<{
|
||||||
|
role?: string;
|
||||||
|
content?: string | Array<{ type?: string; text?: string }>;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (parsed.stream) {
|
||||||
|
res.writeHead(200, { 'Content-Type': 'text/event-stream' });
|
||||||
|
|
||||||
|
if (parsed.messages?.[0]?.content === 'interleaved tool fragments') {
|
||||||
res.write(
|
res.write(
|
||||||
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"role":"assistant","content":"Hello"}}]}\n\n'
|
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_1","type":"function","function":{"name":"search"}}]}}]}\n\n'
|
||||||
);
|
);
|
||||||
res.write(
|
res.write(
|
||||||
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_1","type":"function","function":{"name":"search","arguments":"{\\"q\\":\\"docs\\"}"}}]}}]}\n\n'
|
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_2","type":"function","function":{"name":"open"}}]}}]}\n\n'
|
||||||
|
);
|
||||||
|
res.write(
|
||||||
|
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\\"path\\":\\"a.ts\\"}"}}]}}]}\n\n'
|
||||||
|
);
|
||||||
|
res.write(
|
||||||
|
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\\"path\\":\\"b.ts\\"}"}}]}}]}\n\n'
|
||||||
);
|
);
|
||||||
res.write(
|
res.write(
|
||||||
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":9,"completion_tokens":4}}\n\n'
|
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":9,"completion_tokens":4}}\n\n'
|
||||||
@@ -64,25 +75,38 @@ function startMockUpstream(): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
res.write(
|
||||||
res.end(
|
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"role":"assistant","content":"Hello"}}]}\n\n'
|
||||||
JSON.stringify({
|
|
||||||
id: 'chatcmpl_1',
|
|
||||||
model: 'hf-model',
|
|
||||||
choices: [
|
|
||||||
{
|
|
||||||
index: 0,
|
|
||||||
message: { role: 'assistant', content: 'Plain answer' },
|
|
||||||
finish_reason: 'stop',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
usage: { prompt_tokens: 2, completion_tokens: 3 },
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
});
|
res.write(
|
||||||
|
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_1","type":"function","function":{"name":"search","arguments":"{\\"q\\":\\"docs\\"}"}}]}}]}\n\n'
|
||||||
|
);
|
||||||
|
res.write(
|
||||||
|
'data: {"id":"chatcmpl_1","model":"hf-model","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":9,"completion_tokens":4}}\n\n'
|
||||||
|
);
|
||||||
|
res.end('data: [DONE]\n\n');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
upstreamServer.listen(upstreamPort, '127.0.0.1', () => resolve());
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(
|
||||||
|
JSON.stringify({
|
||||||
|
id: 'chatcmpl_1',
|
||||||
|
model: 'hf-model',
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
message: { role: 'assistant', content: 'Plain answer' },
|
||||||
|
finish_reason: 'stop',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
usage: { prompt_tokens: 2, completion_tokens: 3 },
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
upstreamServer.listen(0, '127.0.0.1');
|
||||||
|
upstreamPort = await waitForServerListening(upstreamServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function requestProxy(payload: unknown): Promise<Response> {
|
async function requestProxy(payload: unknown): Promise<Response> {
|
||||||
@@ -98,8 +122,6 @@ async function requestProxy(payload: unknown): Promise<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
upstreamPort = await getPort();
|
|
||||||
proxyPort = await getPort();
|
|
||||||
upstreamBody = undefined;
|
upstreamBody = undefined;
|
||||||
await startMockUpstream();
|
await startMockUpstream();
|
||||||
const profile: OpenAICompatProfileConfig = {
|
const profile: OpenAICompatProfileConfig = {
|
||||||
@@ -112,9 +134,10 @@ beforeEach(async () => {
|
|||||||
};
|
};
|
||||||
proxyServer = startOpenAICompatProxyServer({
|
proxyServer = startOpenAICompatProxyServer({
|
||||||
profile,
|
profile,
|
||||||
port: proxyPort,
|
port: 0,
|
||||||
authToken: 'test-proxy-token',
|
authToken: 'test-proxy-token',
|
||||||
});
|
});
|
||||||
|
proxyPort = await waitForServerListening(proxyServer);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
|
import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
|
||||||
import getPort from 'get-port';
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
@@ -13,40 +12,61 @@ let proxyServer: http.Server;
|
|||||||
let upstreamServers: http.Server[] = [];
|
let upstreamServers: http.Server[] = [];
|
||||||
let proxyPort: number;
|
let proxyPort: number;
|
||||||
|
|
||||||
function startMockUpstream(
|
function resolveListeningPort(server: http.Server): number {
|
||||||
port: number,
|
const address = server.address();
|
||||||
|
if (!address || typeof address === 'string') {
|
||||||
|
throw new Error('Failed to resolve server port');
|
||||||
|
}
|
||||||
|
return address.port;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function waitForServerListening(server: http.Server): Promise<number> {
|
||||||
|
if (server.listening) {
|
||||||
|
return resolveListeningPort(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise<number>((resolve, reject) => {
|
||||||
|
const onError = (error: Error) => reject(error);
|
||||||
|
server.once('error', onError);
|
||||||
|
server.once('listening', () => {
|
||||||
|
server.off('error', onError);
|
||||||
|
resolve(resolveListeningPort(server));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function startMockUpstream(
|
||||||
hitLabel: string,
|
hitLabel: string,
|
||||||
hits: string[],
|
hits: string[],
|
||||||
bodies: Array<{ label: string; body: unknown }>
|
bodies: Array<{ label: string; body: unknown }>
|
||||||
): Promise<void> {
|
): Promise<number> {
|
||||||
return new Promise((resolve) => {
|
const server = http.createServer(async (req, res) => {
|
||||||
const server = http.createServer(async (req, res) => {
|
let body = '';
|
||||||
let body = '';
|
for await (const chunk of req) {
|
||||||
for await (const chunk of req) {
|
body += chunk.toString();
|
||||||
body += chunk.toString();
|
}
|
||||||
}
|
hits.push(hitLabel);
|
||||||
hits.push(hitLabel);
|
bodies.push({ label: hitLabel, body: JSON.parse(body) });
|
||||||
bodies.push({ label: hitLabel, body: JSON.parse(body) });
|
|
||||||
|
|
||||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
res.end(
|
res.end(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
id: `chatcmpl_${hitLabel}`,
|
id: `chatcmpl_${hitLabel}`,
|
||||||
model: hitLabel,
|
model: hitLabel,
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
message: { role: 'assistant', content: `Reply from ${hitLabel}` },
|
message: { role: 'assistant', content: `Reply from ${hitLabel}` },
|
||||||
finish_reason: 'stop',
|
finish_reason: 'stop',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
usage: { prompt_tokens: 2, completion_tokens: 3 },
|
usage: { prompt_tokens: 2, completion_tokens: 3 },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
|
||||||
upstreamServers.push(server);
|
|
||||||
server.listen(port, '127.0.0.1', () => resolve());
|
|
||||||
});
|
});
|
||||||
|
upstreamServers.push(server);
|
||||||
|
server.listen(0, '127.0.0.1');
|
||||||
|
return waitForServerListening(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeSettings(profileName: string, env: Record<string, string>): string {
|
function writeSettings(profileName: string, env: Record<string, string>): string {
|
||||||
@@ -71,7 +91,7 @@ beforeEach(async () => {
|
|||||||
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-proxy-routing-'));
|
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-proxy-routing-'));
|
||||||
fs.mkdirSync(path.join(tempDir, '.ccs'), { recursive: true });
|
fs.mkdirSync(path.join(tempDir, '.ccs'), { recursive: true });
|
||||||
process.env.CCS_HOME = tempDir;
|
process.env.CCS_HOME = tempDir;
|
||||||
proxyPort = await getPort();
|
proxyPort = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -97,12 +117,10 @@ afterEach(async () => {
|
|||||||
|
|
||||||
describe('openai proxy request routing', () => {
|
describe('openai proxy request routing', () => {
|
||||||
it('routes explicit profile:model selectors to the matching upstream profile', async () => {
|
it('routes explicit profile:model selectors to the matching upstream profile', async () => {
|
||||||
const primaryPort = await getPort();
|
|
||||||
const secondaryPort = await getPort();
|
|
||||||
const hits: string[] = [];
|
const hits: string[] = [];
|
||||||
const bodies: Array<{ label: string; body: unknown }> = [];
|
const bodies: Array<{ label: string; body: unknown }> = [];
|
||||||
await startMockUpstream(primaryPort, 'primary', hits, bodies);
|
const primaryPort = await startMockUpstream('primary', hits, bodies);
|
||||||
await startMockUpstream(secondaryPort, 'secondary', hits, bodies);
|
const secondaryPort = await startMockUpstream('secondary', hits, bodies);
|
||||||
|
|
||||||
const primarySettings = writeSettings('hf', {
|
const primarySettings = writeSettings('hf', {
|
||||||
ANTHROPIC_BASE_URL: `http://127.0.0.1:${primaryPort}`,
|
ANTHROPIC_BASE_URL: `http://127.0.0.1:${primaryPort}`,
|
||||||
@@ -133,9 +151,10 @@ describe('openai proxy request routing', () => {
|
|||||||
};
|
};
|
||||||
proxyServer = startOpenAICompatProxyServer({
|
proxyServer = startOpenAICompatProxyServer({
|
||||||
profile,
|
profile,
|
||||||
port: proxyPort,
|
port: 0,
|
||||||
authToken: 'test-proxy-token',
|
authToken: 'test-proxy-token',
|
||||||
});
|
});
|
||||||
|
proxyPort = await waitForServerListening(proxyServer);
|
||||||
|
|
||||||
const response = await requestProxy({
|
const response = await requestProxy({
|
||||||
model: 'deepseek:deepseek-reasoner',
|
model: 'deepseek:deepseek-reasoner',
|
||||||
@@ -150,12 +169,10 @@ describe('openai proxy request routing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('routes thinking requests through the configured think scenario', async () => {
|
it('routes thinking requests through the configured think scenario', async () => {
|
||||||
const primaryPort = await getPort();
|
|
||||||
const thinkPort = await getPort();
|
|
||||||
const hits: string[] = [];
|
const hits: string[] = [];
|
||||||
const bodies: Array<{ label: string; body: unknown }> = [];
|
const bodies: Array<{ label: string; body: unknown }> = [];
|
||||||
await startMockUpstream(primaryPort, 'primary', hits, bodies);
|
const primaryPort = await startMockUpstream('primary', hits, bodies);
|
||||||
await startMockUpstream(thinkPort, 'thinker', hits, bodies);
|
const thinkPort = await startMockUpstream('thinker', hits, bodies);
|
||||||
|
|
||||||
const primarySettings = writeSettings('hf', {
|
const primarySettings = writeSettings('hf', {
|
||||||
ANTHROPIC_BASE_URL: `http://127.0.0.1:${primaryPort}`,
|
ANTHROPIC_BASE_URL: `http://127.0.0.1:${primaryPort}`,
|
||||||
@@ -197,9 +214,10 @@ describe('openai proxy request routing', () => {
|
|||||||
};
|
};
|
||||||
proxyServer = startOpenAICompatProxyServer({
|
proxyServer = startOpenAICompatProxyServer({
|
||||||
profile,
|
profile,
|
||||||
port: proxyPort,
|
port: 0,
|
||||||
authToken: 'test-proxy-token',
|
authToken: 'test-proxy-token',
|
||||||
});
|
});
|
||||||
|
proxyPort = await waitForServerListening(proxyServer);
|
||||||
|
|
||||||
const response = await requestProxy({
|
const response = await requestProxy({
|
||||||
model: 'hf-default',
|
model: 'hf-default',
|
||||||
@@ -216,12 +234,10 @@ describe('openai proxy request routing', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('routes adaptive thinking requests through the configured think scenario', async () => {
|
it('routes adaptive thinking requests through the configured think scenario', async () => {
|
||||||
const primaryPort = await getPort();
|
|
||||||
const thinkPort = await getPort();
|
|
||||||
const hits: string[] = [];
|
const hits: string[] = [];
|
||||||
const bodies: Array<{ label: string; body: unknown }> = [];
|
const bodies: Array<{ label: string; body: unknown }> = [];
|
||||||
await startMockUpstream(primaryPort, 'primary', hits, bodies);
|
const primaryPort = await startMockUpstream('primary', hits, bodies);
|
||||||
await startMockUpstream(thinkPort, 'thinker', hits, bodies);
|
const thinkPort = await startMockUpstream('thinker', hits, bodies);
|
||||||
|
|
||||||
const primarySettings = writeSettings('hf', {
|
const primarySettings = writeSettings('hf', {
|
||||||
ANTHROPIC_BASE_URL: `http://127.0.0.1:${primaryPort}`,
|
ANTHROPIC_BASE_URL: `http://127.0.0.1:${primaryPort}`,
|
||||||
@@ -263,9 +279,10 @@ describe('openai proxy request routing', () => {
|
|||||||
};
|
};
|
||||||
proxyServer = startOpenAICompatProxyServer({
|
proxyServer = startOpenAICompatProxyServer({
|
||||||
profile,
|
profile,
|
||||||
port: proxyPort,
|
port: 0,
|
||||||
authToken: 'test-proxy-token',
|
authToken: 'test-proxy-token',
|
||||||
});
|
});
|
||||||
|
proxyPort = await waitForServerListening(proxyServer);
|
||||||
|
|
||||||
const response = await requestProxy({
|
const response = await requestProxy({
|
||||||
model: 'hf-default',
|
model: 'hf-default',
|
||||||
|
|||||||
Reference in New Issue
Block a user