官方sdk测试
This commit is contained in:
104
src/protocols.ts
Normal file
104
src/protocols.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import type { ServerResponse } from 'node:http';
|
||||
import { anthropicMessagesToPrompt, openAIChatToPrompt, type ChatMessage } from './prompt';
|
||||
|
||||
export type OpenAIChatRequest = {
|
||||
model?: string;
|
||||
messages?: ChatMessage[];
|
||||
stream?: boolean;
|
||||
};
|
||||
|
||||
export type AnthropicMessagesRequest = {
|
||||
model?: string;
|
||||
system?: unknown;
|
||||
messages?: ChatMessage[];
|
||||
stream?: boolean;
|
||||
};
|
||||
|
||||
export function openAIPrompt(req: OpenAIChatRequest): string {
|
||||
return openAIChatToPrompt(req.messages ?? []);
|
||||
}
|
||||
|
||||
export function anthropicPrompt(req: AnthropicMessagesRequest): string {
|
||||
return anthropicMessagesToPrompt(req.system, req.messages ?? []);
|
||||
}
|
||||
|
||||
export function writeOpenAIResponse(res: ServerResponse, model: string, text: string): void {
|
||||
writeJson(res, 200, {
|
||||
id: `chatcmpl-${randomUUID()}`,
|
||||
object: 'chat.completion',
|
||||
created: Math.floor(Date.now() / 1000),
|
||||
model,
|
||||
choices: [{ index: 0, message: { role: 'assistant', content: text }, finish_reason: 'stop' }],
|
||||
usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
|
||||
});
|
||||
}
|
||||
|
||||
export function startOpenAIStream(res: ServerResponse, model: string): (text: string) => void {
|
||||
const id = `chatcmpl-${randomUUID()}`;
|
||||
sseHeaders(res);
|
||||
return (text: string) => {
|
||||
res.write(`data: ${JSON.stringify({
|
||||
id,
|
||||
object: 'chat.completion.chunk',
|
||||
created: Math.floor(Date.now() / 1000),
|
||||
model,
|
||||
choices: [{ index: 0, delta: { content: text }, finish_reason: null }],
|
||||
})}\n\n`);
|
||||
};
|
||||
}
|
||||
|
||||
export function endOpenAIStream(res: ServerResponse): void {
|
||||
res.write('data: [DONE]\n\n');
|
||||
res.end();
|
||||
}
|
||||
|
||||
export function writeAnthropicResponse(res: ServerResponse, model: string, text: string): void {
|
||||
writeJson(res, 200, {
|
||||
id: `msg_${randomUUID().replaceAll('-', '')}`,
|
||||
type: 'message',
|
||||
role: 'assistant',
|
||||
model,
|
||||
content: [{ type: 'text', text }],
|
||||
stop_reason: 'end_turn',
|
||||
stop_sequence: null,
|
||||
usage: { input_tokens: 0, output_tokens: 0 },
|
||||
});
|
||||
}
|
||||
|
||||
export function startAnthropicStream(res: ServerResponse, model: string): (text: string) => void {
|
||||
const id = `msg_${randomUUID().replaceAll('-', '')}`;
|
||||
sseHeaders(res);
|
||||
res.write(`event: message_start\ndata: ${JSON.stringify({
|
||||
type: 'message_start',
|
||||
message: { id, type: 'message', role: 'assistant', model, content: [], stop_reason: null, stop_sequence: null, usage: { input_tokens: 0, output_tokens: 0 } },
|
||||
})}\n\n`);
|
||||
res.write(`event: content_block_start\ndata: ${JSON.stringify({ type: 'content_block_start', index: 0, content_block: { type: 'text', text: '' } })}\n\n`);
|
||||
return (text: string) => {
|
||||
res.write(`event: content_block_delta\ndata: ${JSON.stringify({ type: 'content_block_delta', index: 0, delta: { type: 'text_delta', text } })}\n\n`);
|
||||
};
|
||||
}
|
||||
|
||||
export function endAnthropicStream(res: ServerResponse): void {
|
||||
res.write(`event: content_block_stop\ndata: ${JSON.stringify({ type: 'content_block_stop', index: 0 })}\n\n`);
|
||||
res.write(`event: message_delta\ndata: ${JSON.stringify({ type: 'message_delta', delta: { stop_reason: 'end_turn', stop_sequence: null }, usage: { output_tokens: 0 } })}\n\n`);
|
||||
res.write(`event: message_stop\ndata: ${JSON.stringify({ type: 'message_stop' })}\n\n`);
|
||||
res.end();
|
||||
}
|
||||
|
||||
export function writeJson(res: ServerResponse, statusCode: number, value: unknown): void {
|
||||
res.writeHead(statusCode, { 'content-type': 'application/json; charset=utf-8' });
|
||||
res.end(JSON.stringify(value));
|
||||
}
|
||||
|
||||
export function writeError(res: ServerResponse, statusCode: number, message: string): void {
|
||||
writeJson(res, statusCode, { error: { type: 'api_error', message } });
|
||||
}
|
||||
|
||||
function sseHeaders(res: ServerResponse): void {
|
||||
res.writeHead(200, {
|
||||
'content-type': 'text/event-stream; charset=utf-8',
|
||||
'cache-control': 'no-cache, no-transform',
|
||||
connection: 'keep-alive',
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user