llmverify
Version:
AI Output Verification Toolkit — Local-first LLM safety, hallucination detection, PII redaction, prompt injection defense, and runtime monitoring. Zero telemetry. OWASP LLM Top 10 aligned.
84 lines • 8.76 kB
JavaScript
;
/**
* Custom Adapter
*
* Adapter for any custom LLM provider or API.
*
* @module adapters/providers/custom
* @author Haiec
* @license MIT
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildCustomAdapter = buildCustomAdapter;
const types_1 = require("../types");
/**
* Builds a custom adapter.
*
* @param config - Adapter configuration
* @returns LLM client for custom provider
*
* @example
* // Wrap any API
* const llm = buildCustomAdapter({
* provider: 'custom',
* providerName: 'My API',
* client: {
* async generate(request) {
* const res = await fetch('https://my-api.com/generate', {
* method: 'POST',
* body: JSON.stringify({ prompt: request.prompt })
* });
* const data = await res.json();
* return { text: data.output, tokens: data.tokens };
* }
* }
* });
*
* @example
* // Wrap existing SDK
* const llm = buildCustomAdapter({
* provider: 'custom',
* providerName: 'Together AI',
* client: {
* async generate(request) {
* const response = await togetherClient.chat.completions.create({
* model: request.model ?? 'meta-llama/Llama-3-70b-chat-hf',
* messages: [{ role: 'user', content: request.prompt }]
* });
* return {
* text: response.choices[0].message.content,
* tokens: response.usage?.completion_tokens ?? 0
* };
* }
* }
* });
*/
function buildCustomAdapter(config) {
const client = config.client;
if (!client || typeof client.generate !== 'function') {
throw new types_1.AdapterConfigError('custom', 'Custom adapter requires client with generate(request: LlmRequest): Promise<LlmResponse> method');
}
return {
provider: 'custom',
providerName: config.providerName ?? 'Custom Provider',
async generate(request) {
const response = await client.generate(request);
// Ensure response has required fields
return {
text: response.text ?? '',
tokens: response.tokens ?? estimateTokens(response.text ?? ''),
totalTokens: response.totalTokens,
model: response.model ?? request.model,
finishReason: response.finishReason,
raw: response.raw
};
},
embed: client.embed ? async (input) => client.embed(input) : undefined,
stream: client.stream ? (request) => client.stream(request) : undefined,
healthCheck: client.healthCheck ? async () => client.healthCheck() : undefined
};
}
function estimateTokens(text) {
return Math.ceil(text.split(/\s+/).length * 1.3);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FkYXB0ZXJzL3Byb3ZpZGVycy9jdXN0b20udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7OztHQVFHOztBQXdESCxnREFnQ0M7QUF0RkQsb0NBQWlHO0FBWWpHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlDRztBQUNILFNBQWdCLGtCQUFrQixDQUFDLE1BQXFCO0lBQ3RELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFzQixDQUFDO0lBRTdDLElBQUksQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLENBQUMsUUFBUSxLQUFLLFVBQVUsRUFBRSxDQUFDO1FBQ3JELE1BQU0sSUFBSSwwQkFBa0IsQ0FDMUIsUUFBUSxFQUNSLGdHQUFnRyxDQUNqRyxDQUFDO0lBQ0osQ0FBQztJQUVELE9BQU87UUFDTCxRQUFRLEVBQUUsUUFBUTtRQUNsQixZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVksSUFBSSxpQkFBaUI7UUFFdEQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFtQjtZQUNoQyxNQUFNLFFBQVEsR0FBRyxNQUFNLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFaEQsc0NBQXNDO1lBQ3RDLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJLElBQUksRUFBRTtnQkFDekIsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNLElBQUksY0FBYyxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO2dCQUM5RCxXQUFXLEVBQUUsUUFBUSxDQUFDLFdBQVc7Z0JBQ2pDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxJQUFJLE9BQU8sQ0FBQyxLQUFLO2dCQUN0QyxZQUFZLEVBQUUsUUFBUSxDQUFDLFlBQVk7Z0JBQ25DLEdBQUcsRUFBRSxRQUFRLENBQUMsR0FBRzthQUNsQixDQUFDO1FBQ0osQ0FBQztRQUVELEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO1FBQ3ZFLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztRQUN4RSxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVM7S0FDaEYsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLGNBQWMsQ0FBQyxJQUFZO0lBQ2xDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQztBQUNuRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDdXN0b20gQWRhcHRlclxuICogXG4gKiBBZGFwdGVyIGZvciBhbnkgY3VzdG9tIExMTSBwcm92aWRlciBvciBBUEkuXG4gKiBcbiAqIEBtb2R1bGUgYWRhcHRlcnMvcHJvdmlkZXJzL2N1c3RvbVxuICogQGF1dGhvciBIYWllY1xuICogQGxpY2Vuc2UgTUlUXG4gKi9cblxuaW1wb3J0IHsgTGxtQ2xpZW50LCBMbG1SZXF1ZXN0LCBMbG1SZXNwb25zZSwgQWRhcHRlckNvbmZpZywgQWRhcHRlckNvbmZpZ0Vycm9yIH0gZnJvbSAnLi4vdHlwZXMnO1xuXG4vKipcbiAqIEN1c3RvbSBjbGllbnQgaW50ZXJmYWNlIC0gbXVzdCBpbXBsZW1lbnQgZ2VuZXJhdGUgbWV0aG9kLlxuICovXG5pbnRlcmZhY2UgQ3VzdG9tQ2xpZW50IHtcbiAgZ2VuZXJhdGUocmVxdWVzdDogTGxtUmVxdWVzdCk6IFByb21pc2U8TGxtUmVzcG9uc2U+O1xuICBlbWJlZD8oaW5wdXQ6IHN0cmluZyB8IHN0cmluZ1tdKTogUHJvbWlzZTxudW1iZXJbXVtdPjtcbiAgc3RyZWFtPyhyZXF1ZXN0OiBMbG1SZXF1ZXN0KTogQXN5bmNJdGVyYWJsZTxzdHJpbmc+O1xuICBoZWFsdGhDaGVjaz8oKTogUHJvbWlzZTxib29sZWFuPjtcbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBjdXN0b20gYWRhcHRlci5cbiAqIFxuICogQHBhcmFtIGNvbmZpZyAtIEFkYXB0ZXIgY29uZmlndXJhdGlvblxuICogQHJldHVybnMgTExNIGNsaWVudCBmb3IgY3VzdG9tIHByb3ZpZGVyXG4gKiBcbiAqIEBleGFtcGxlXG4gKiAvLyBXcmFwIGFueSBBUElcbiAqIGNvbnN0IGxsbSA9IGJ1aWxkQ3VzdG9tQWRhcHRlcih7XG4gKiAgIHByb3ZpZGVyOiAnY3VzdG9tJyxcbiAqICAgcHJvdmlkZXJOYW1lOiAnTXkgQVBJJyxcbiAqICAgY2xpZW50OiB7XG4gKiAgICAgYXN5bmMgZ2VuZXJhdGUocmVxdWVzdCkge1xuICogICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vbXktYXBpLmNvbS9nZW5lcmF0ZScsIHtcbiAqICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gKiAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcHJvbXB0OiByZXF1ZXN0LnByb21wdCB9KVxuICogICAgICAgfSk7XG4gKiAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzLmpzb24oKTtcbiAqICAgICAgIHJldHVybiB7IHRleHQ6IGRhdGEub3V0cHV0LCB0b2tlbnM6IGRhdGEudG9rZW5zIH07XG4gKiAgICAgfVxuICogICB9XG4gKiB9KTtcbiAqIFxuICogQGV4YW1wbGVcbiAqIC8vIFdyYXAgZXhpc3RpbmcgU0RLXG4gKiBjb25zdCBsbG0gPSBidWlsZEN1c3RvbUFkYXB0ZXIoe1xuICogICBwcm92aWRlcjogJ2N1c3RvbScsXG4gKiAgIHByb3ZpZGVyTmFtZTogJ1RvZ2V0aGVyIEFJJyxcbiAqICAgY2xpZW50OiB7XG4gKiAgICAgYXN5bmMgZ2VuZXJhdGUocmVxdWVzdCkge1xuICogICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0b2dldGhlckNsaWVudC5jaGF0LmNvbXBsZXRpb25zLmNyZWF0ZSh7XG4gKiAgICAgICAgIG1vZGVsOiByZXF1ZXN0Lm1vZGVsID8/ICdtZXRhLWxsYW1hL0xsYW1hLTMtNzBiLWNoYXQtaGYnLFxuICogICAgICAgICBtZXNzYWdlczogW3sgcm9sZTogJ3VzZXInLCBjb250ZW50OiByZXF1ZXN0LnByb21wdCB9XVxuICogICAgICAgfSk7XG4gKiAgICAgICByZXR1cm4ge1xuICogICAgICAgICB0ZXh0OiByZXNwb25zZS5jaG9pY2VzWzBdLm1lc3NhZ2UuY29udGVudCxcbiAqICAgICAgICAgdG9rZW5zOiByZXNwb25zZS51c2FnZT8uY29tcGxldGlvbl90b2tlbnMgPz8gMFxuICogICAgICAgfTtcbiAqICAgICB9XG4gKiAgIH1cbiAqIH0pO1xuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDdXN0b21BZGFwdGVyKGNvbmZpZzogQWRhcHRlckNvbmZpZyk6IExsbUNsaWVudCB7XG4gIGNvbnN0IGNsaWVudCA9IGNvbmZpZy5jbGllbnQgYXMgQ3VzdG9tQ2xpZW50O1xuICBcbiAgaWYgKCFjbGllbnQgfHwgdHlwZW9mIGNsaWVudC5nZW5lcmF0ZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBBZGFwdGVyQ29uZmlnRXJyb3IoXG4gICAgICAnY3VzdG9tJyxcbiAgICAgICdDdXN0b20gYWRhcHRlciByZXF1aXJlcyBjbGllbnQgd2l0aCBnZW5lcmF0ZShyZXF1ZXN0OiBMbG1SZXF1ZXN0KTogUHJvbWlzZTxMbG1SZXNwb25zZT4gbWV0aG9kJ1xuICAgICk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHByb3ZpZGVyOiAnY3VzdG9tJyxcbiAgICBwcm92aWRlck5hbWU6IGNvbmZpZy5wcm92aWRlck5hbWUgPz8gJ0N1c3RvbSBQcm92aWRlcicsXG5cbiAgICBhc3luYyBnZW5lcmF0ZShyZXF1ZXN0OiBMbG1SZXF1ZXN0KTogUHJvbWlzZTxMbG1SZXNwb25zZT4ge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZ2VuZXJhdGUocmVxdWVzdCk7XG4gICAgICBcbiAgICAgIC8vIEVuc3VyZSByZXNwb25zZSBoYXMgcmVxdWlyZWQgZmllbGRzXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0ZXh0OiByZXNwb25zZS50ZXh0ID8/ICcnLFxuICAgICAgICB0b2tlbnM6IHJlc3BvbnNlLnRva2VucyA/PyBlc3RpbWF0ZVRva2VucyhyZXNwb25zZS50ZXh0ID8/ICcnKSxcbiAgICAgICAgdG90YWxUb2tlbnM6IHJlc3BvbnNlLnRvdGFsVG9rZW5zLFxuICAgICAgICBtb2RlbDogcmVzcG9uc2UubW9kZWwgPz8gcmVxdWVzdC5tb2RlbCxcbiAgICAgICAgZmluaXNoUmVhc29uOiByZXNwb25zZS5maW5pc2hSZWFzb24sXG4gICAgICAgIHJhdzogcmVzcG9uc2UucmF3XG4gICAgICB9O1xuICAgIH0sXG5cbiAgICBlbWJlZDogY2xpZW50LmVtYmVkID8gYXN5bmMgKGlucHV0KSA9PiBjbGllbnQuZW1iZWQhKGlucHV0KSA6IHVuZGVmaW5lZCxcbiAgICBzdHJlYW06IGNsaWVudC5zdHJlYW0gPyAocmVxdWVzdCkgPT4gY2xpZW50LnN0cmVhbSEocmVxdWVzdCkgOiB1bmRlZmluZWQsXG4gICAgaGVhbHRoQ2hlY2s6IGNsaWVudC5oZWFsdGhDaGVjayA/IGFzeW5jICgpID0+IGNsaWVudC5oZWFsdGhDaGVjayEoKSA6IHVuZGVmaW5lZFxuICB9O1xufVxuXG5mdW5jdGlvbiBlc3RpbWF0ZVRva2Vucyh0ZXh0OiBzdHJpbmcpOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5jZWlsKHRleHQuc3BsaXQoL1xccysvKS5sZW5ndGggKiAxLjMpO1xufVxuIl19