Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 1x 1x 1x 1x 5x 5x 5x 5x 1x 1x 5x 1x 2x 1x 1x 3x 3x 7x 7x 7x 7x 2x 2x 2x 2x 7x 5x 5x 7x 7x 3x 3x 3x 7x 7x 7x 7x 7x 3x | import type {} from '@shared/types/api/request/body';
import type { ChatCompletionRequestBody } from '@shared/types/api/routes/chat-completions-api';
import type { CompletionRequestBody } from '@shared/types/api/routes/completions-api';
import { AIProvider } from '@shared/types/constants';
export const getStreamModeSplitPattern = (
provider: string,
aiProviderRequestURL: string,
): SplitPatternType => {
let splitPattern: SplitPatternType = '\n\n';
if (
provider === AIProvider.ANTHROPIC &&
aiProviderRequestURL.endsWith('/complete')
) {
splitPattern = '\r\n\r\n';
}
if (provider === AIProvider.COHERE) {
splitPattern = '\n';
}
if (provider === AIProvider.GOOGLE) {
splitPattern = '\r\n';
}
// In Vertex Anthropic and LLama have \n\n as the pattern only Gemini has \r\n\r\n
if (
provider === AIProvider.GOOGLE_VERTEX_AI &&
aiProviderRequestURL.includes('/publishers/google')
) {
splitPattern = '\r\n\r\n';
}
if (provider === AIProvider.PERPLEXITY_AI) {
splitPattern = '\r\n\r\n';
}
if (provider === AIProvider.DEEPINFRA) {
splitPattern = '\n';
}
if (provider === AIProvider.SAMBANOVA) {
splitPattern = '\n';
}
return splitPattern;
};
export type SplitPatternType = '\n\n' | '\r\n\r\n' | '\n' | '\r\n';
export const getStreamingMode = (
saRequestBody: ChatCompletionRequestBody | CompletionRequestBody,
provider: AIProvider,
aiProviderRequestURL: string,
): boolean | undefined => {
if (
provider === AIProvider.GOOGLE ||
(provider === AIProvider.GOOGLE_VERTEX_AI &&
aiProviderRequestURL.indexOf('stream') > -1)
) {
return true;
}
if (
provider === AIProvider.BEDROCK &&
(aiProviderRequestURL.indexOf('invoke-with-response-stream') > -1 ||
aiProviderRequestURL.indexOf('converse-stream') > -1)
) {
return true;
}
return saRequestBody.stream;
};
export function convertKeysToCamelCase(
obj: Record<string, unknown>,
parentKeysToPreserve: string[] = [],
): Record<string, unknown> | Record<string, unknown>[] {
if (typeof obj !== 'object' || obj === null) {
return obj; // Return unchanged for non-objects or null
}
if (Array.isArray(obj)) {
// If it's an array, recursively convert each element
return obj.map((item) =>
convertKeysToCamelCase(item, parentKeysToPreserve),
) as Record<string, unknown>[];
}
return Object.keys(obj).reduce(
(result: Record<string, unknown>, key: string) => {
const value = obj[key];
const camelCaseKey = toCamelCase(key);
const isParentKeyToPreserve = parentKeysToPreserve.includes(key);
if (typeof value === 'object' && !isParentKeyToPreserve) {
// Recursively convert child objects
result[camelCaseKey] = convertKeysToCamelCase(
value as Record<string, unknown>,
parentKeysToPreserve,
);
} else {
// Add key in camelCase to the result
result[camelCaseKey] = value;
}
return result;
},
{},
);
function toCamelCase(snakeCase: string): string {
// Remove any leading underscores first, then replace one or more
// underscores with the following alphanumeric character's uppercase
// version and strip any trailing underscores.
return snakeCase
.replace(/^_+/, '')
.replace(/_+([a-zA-Z0-9])/g, (_, c) => c.toUpperCase())
.replace(/_+$/g, '');
}
}
|