(opts: {
method: string;
path: string;
model: string;
stream: boolean;
hasTools: boolean;
toolCount: number;
messageCount: number;
apiFormat?: 'anthropic' | 'openai' | 'responses';
systemPromptLength?: number;
})
| 721 | // ==================== 核心 API ==================== |
| 722 | |
| 723 | export function createRequestLogger(opts: { |
| 724 | method: string; |
| 725 | path: string; |
| 726 | model: string; |
| 727 | stream: boolean; |
| 728 | hasTools: boolean; |
| 729 | toolCount: number; |
| 730 | messageCount: number; |
| 731 | apiFormat?: 'anthropic' | 'openai' | 'responses'; |
| 732 | systemPromptLength?: number; |
| 733 | }): RequestLogger { |
| 734 | const requestId = shortId(); |
| 735 | const summary: RequestSummary = { |
| 736 | requestId, startTime: Date.now(), |
| 737 | method: opts.method, path: opts.path, model: opts.model, |
| 738 | stream: opts.stream, |
| 739 | apiFormat: opts.apiFormat || (opts.path.includes('chat/completions') ? 'openai' : |
| 740 | opts.path.includes('responses') ? 'responses' : 'anthropic'), |
| 741 | hasTools: opts.hasTools, toolCount: opts.toolCount, |
| 742 | messageCount: opts.messageCount, |
| 743 | status: 'processing', responseChars: 0, |
| 744 | retryCount: 0, continuationCount: 0, toolCallsDetected: 0, |
| 745 | phaseTimings: [], thinkingChars: 0, |
| 746 | systemPromptLength: opts.systemPromptLength || 0, |
| 747 | }; |
| 748 | const payload: RequestPayload = {}; |
| 749 | |
| 750 | requestSummaries.set(requestId, summary); |
| 751 | requestPayloads.set(requestId, payload); |
| 752 | requestOrder.push(requestId); |
| 753 | |
| 754 | while (requestOrder.length > MAX_REQUESTS) { |
| 755 | const oldId = requestOrder.shift()!; |
| 756 | requestSummaries.delete(oldId); |
| 757 | requestPayloads.delete(oldId); |
| 758 | } |
| 759 | |
| 760 | const toolMode = (() => { |
| 761 | const cfg = getConfig().tools; |
| 762 | if (cfg?.disabled) return '(跳过)'; |
| 763 | if (cfg?.passthrough) return '(透传)'; |
| 764 | return ''; |
| 765 | })(); |
| 766 | const toolInfo = opts.hasTools ? ` tools=${opts.toolCount}${toolMode}` : ''; |
| 767 | const fmtTag = summary.apiFormat === 'openai' ? ' [OAI]' : summary.apiFormat === 'responses' ? ' [RSP]' : ''; |
| 768 | console.log(`\x1b[36m⟶\x1b[0m [${requestId}] ${opts.method} ${opts.path}${fmtTag} | model=${opts.model} stream=${opts.stream}${toolInfo} msgs=${opts.messageCount}`); |
| 769 | |
| 770 | return new RequestLogger(requestId, summary, payload); |
| 771 | } |
| 772 | |
| 773 | export function getAllLogs(opts?: { requestId?: string; level?: LogLevel; source?: LogSource; limit?: number; since?: number }): LogEntry[] { |
| 774 | let result = logEntries; |
no test coverage detected