From 3b81feec2b757caa22b4e2732b2fd189e1cc8036 Mon Sep 17 00:00:00 2001 From: axel7083 <42176370+axel7083@users.noreply.github.com> Date: Tue, 10 Sep 2024 11:07:24 +0200 Subject: [PATCH] fix: uses sha512 instead of model-id Signed-off-by: axel7083 <42176370+axel7083@users.noreply.github.com> --- .../managers/inference/inferenceManager.ts | 4 +- .../backend/src/managers/modelsManager.ts | 7 +- .../src/managers/playgroundV2Manager.ts | 21 +++--- packages/backend/src/utils/sha.ts | 4 ++ .../backend/src/utils/telemetry-utils.spec.ts | 68 ------------------- packages/backend/src/utils/telemetry-utils.ts | 30 -------- 6 files changed, 17 insertions(+), 117 deletions(-) delete mode 100644 packages/backend/src/utils/telemetry-utils.spec.ts delete mode 100644 packages/backend/src/utils/telemetry-utils.ts diff --git a/packages/backend/src/managers/inference/inferenceManager.ts b/packages/backend/src/managers/inference/inferenceManager.ts index 399373440..9f4ac42d0 100644 --- a/packages/backend/src/managers/inference/inferenceManager.ts +++ b/packages/backend/src/managers/inference/inferenceManager.ts @@ -32,7 +32,7 @@ import type { InferenceProviderRegistry } from '../../registries/InferenceProvid import type { InferenceProvider } from '../../workers/provider/InferenceProvider'; import type { ModelInfo } from '@shared/src/models/IModelInfo'; import type { CatalogManager } from '../catalogManager'; -import { anonymiseModel } from '../../utils/telemetry-utils'; +import { getHash } from '../../utils/sha'; export class InferenceManager extends Publisher implements Disposable { // Inference server map (containerId -> InferenceServer) @@ -232,7 +232,7 @@ export class InferenceManager extends Publisher implements Di // Log usage this.telemetry.logUsage('inference.start', { - models: config.modelsInfo.map(model => anonymiseModel(model)), + models: config.modelsInfo.map(model => getHash(model.id)), }); this.notify(); diff --git a/packages/backend/src/managers/modelsManager.ts b/packages/backend/src/managers/modelsManager.ts index 60fc74555..49c2f7f85 100644 --- a/packages/backend/src/managers/modelsManager.ts +++ b/packages/backend/src/managers/modelsManager.ts @@ -33,12 +33,11 @@ import { Uploader } from '../utils/uploader'; import { deleteRemoteModel, getLocalModelFile, isModelUploaded } from '../utils/modelsUtils'; import { getPodmanMachineName } from '../utils/podman'; import type { CancellationTokenRegistry } from '../registries/CancellationTokenRegistry'; -import { hasValidSha } from '../utils/sha'; +import { getHash, hasValidSha } from '../utils/sha'; import type { GGUFParseOutput } from '@huggingface/gguf'; import { gguf } from '@huggingface/gguf'; import type { PodmanConnection } from './podmanConnection'; import { VMType } from '@shared/src/models/IPodman'; -import { anonymiseModel } from '../utils/telemetry-utils'; export class ModelsManager implements Disposable { #models: Map; @@ -199,7 +198,7 @@ export class ModelsManager implements Disposable { } await fs.promises.rm(modelPath, { recursive: true, force: true, maxRetries: 3 }); - this.telemetry.logUsage('model.delete', { 'model.id': anonymiseModel(model) }); + this.telemetry.logUsage('model.delete', { 'model.id': getHash(modelId) }); model.file = model.state = undefined; } catch (err: unknown) { this.telemetry.logError('model.delete', { @@ -445,7 +444,7 @@ export class ModelsManager implements Disposable { const before = performance.now(); const data: Record = { - 'model-id': anonymiseModel(model), // filter imported models + 'model-id': getHash(modelId), }; try { diff --git a/packages/backend/src/managers/playgroundV2Manager.ts b/packages/backend/src/managers/playgroundV2Manager.ts index 8cec3054b..4a030e6fa 100644 --- a/packages/backend/src/managers/playgroundV2Manager.ts +++ b/packages/backend/src/managers/playgroundV2Manager.ts @@ -35,8 +35,7 @@ import { withDefaultConfiguration } from '../utils/inferenceUtils'; import { getRandomString } from '../utils/randomUtils'; import type { TaskRegistry } from '../registries/TaskRegistry'; import type { CancellationTokenRegistry } from '../registries/CancellationTokenRegistry'; -import { anonymiseModel, IMPORTED_PLACEHOLDER } from '../utils/telemetry-utils'; -import { isAbsolute } from 'node:path'; +import { getHash } from '../utils/sha'; export class PlaygroundV2Manager implements Disposable { #conversationRegistry: ConversationRegistry; @@ -55,7 +54,7 @@ export class PlaygroundV2Manager implements Disposable { const conversation = this.#conversationRegistry.get(conversationId); this.telemetry.logUsage('playground.delete', { totalMessages: conversation.messages.length, - modelId: isAbsolute(conversation.modelId) ? IMPORTED_PLACEHOLDER : conversation.modelId, + modelId: getHash(conversation.modelId), }); this.#conversationRegistry.deleteConversation(conversationId); } @@ -68,7 +67,7 @@ export class PlaygroundV2Manager implements Disposable { const telemetry: Record = { hasName: !!name, - modelId: anonymiseModel(model), + modelId: getHash(model.id), }; this.createPlayground(name, model, trackingId) .then((playgroundId: string) => { @@ -151,12 +150,8 @@ export class PlaygroundV2Manager implements Disposable { id: this.#conversationRegistry.getUniqueId(), timestamp: Date.now(), } as SystemPrompt); - - const conversation = this.#conversationRegistry.get(conversationId); - if (!conversation) return; - this.telemetry.logUsage('playground.system-prompt.create', { - modelId: isAbsolute(conversation.modelId) ? IMPORTED_PLACEHOLDER : conversation.modelId, + modelId: getHash(this.#conversationRegistry.get(conversationId).modelId), }); } @@ -172,7 +167,7 @@ export class PlaygroundV2Manager implements Disposable { if (content === undefined || content.length === 0) { this.#conversationRegistry.removeMessage(conversationId, conversation.messages[0].id); this.telemetry.logUsage('playground.system-prompt.delete', { - modelId: isAbsolute(conversation.modelId) ? IMPORTED_PLACEHOLDER : conversation.modelId, + modelId: getHash(conversation.modelId), }); return; } @@ -184,7 +179,7 @@ export class PlaygroundV2Manager implements Disposable { content, }); this.telemetry.logUsage('playground.system-prompt.update', { - modelId: isAbsolute(conversation.modelId) ? IMPORTED_PLACEHOLDER : conversation.modelId, + modelId: getHash(conversation.modelId), }); } else { throw new Error('Cannot change system prompt on started conversation.'); @@ -233,7 +228,7 @@ export class PlaygroundV2Manager implements Disposable { conversationId: conversationId, ...options, promptLength: userInput.length, - modelId: anonymiseModel(modelInfo), + modelId: getHash(modelInfo.id), }; // create an abort controller @@ -318,7 +313,7 @@ export class PlaygroundV2Manager implements Disposable { this.#conversationRegistry.completeMessage(conversationId, messageId); this.telemetry.logUsage('playground.message.complete', { duration: Date.now() - start, - modelId: isAbsolute(conversation.modelId) ? IMPORTED_PLACEHOLDER : conversation.modelId, + modelId: getHash(conversation.modelId), }); } diff --git a/packages/backend/src/utils/sha.ts b/packages/backend/src/utils/sha.ts index cea62f9b5..126332bbd 100644 --- a/packages/backend/src/utils/sha.ts +++ b/packages/backend/src/utils/sha.ts @@ -27,3 +27,7 @@ export async function hasValidSha(filePath: string, expectedSha: string): Promis const actualSha = checkSum.digest('hex'); return actualSha === expectedSha; } + +export function getHash(content: string): string { + return crypto.createHash('sha512').update(content).digest('hex'); +} diff --git a/packages/backend/src/utils/telemetry-utils.spec.ts b/packages/backend/src/utils/telemetry-utils.spec.ts deleted file mode 100644 index f0a105a2a..000000000 --- a/packages/backend/src/utils/telemetry-utils.spec.ts +++ /dev/null @@ -1,68 +0,0 @@ -/********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ***********************************************************************/ - -import { beforeEach, expect, test, vi } from 'vitest'; -import { anonymiseModel, IMPORTED_PLACEHOLDER } from './telemetry-utils'; - -beforeEach(() => { - vi.resetAllMocks(); -}); - -test('model without url should be anonymised', () => { - const result = anonymiseModel({ - name: '', - url: undefined, - id: '', - description: '', - }); - - expect(result).toBe(IMPORTED_PLACEHOLDER); -}); - -test('model with absolute path in id should be anonymised', () => { - const result = anonymiseModel({ - id: '/home/file.guff', - url: 'https://real-website.does-not-exist', - name: '', - description: '', - }); - - expect(result).toBe(IMPORTED_PLACEHOLDER); -}); - -test('model with basic id and no url should be anonymised', () => { - const result = anonymiseModel({ - id: 'random-file.guff', - url: undefined, - name: '', - description: '', - }); - - expect(result).toBe(IMPORTED_PLACEHOLDER); -}); - -test('model with basic id and url should not be anonymised', () => { - const result = anonymiseModel({ - id: 'random-file.guff', - url: 'https://real-website.does-not-exist', - name: '', - description: '', - }); - - expect(result).toBe('random-file.guff'); -}); diff --git a/packages/backend/src/utils/telemetry-utils.ts b/packages/backend/src/utils/telemetry-utils.ts deleted file mode 100644 index f41716e67..000000000 --- a/packages/backend/src/utils/telemetry-utils.ts +++ /dev/null @@ -1,30 +0,0 @@ -/********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ***********************************************************************/ -import type { ModelInfo } from '@shared/src/models/IModelInfo'; -import { isAbsolute } from 'node:path'; - -export const IMPORTED_PLACEHOLDER = ''; - -/** - * This function is used to remove any information related to the user - * @param model - */ -export function anonymiseModel(model: ModelInfo): string { - const imported: boolean = isAbsolute(model.id) || !model.url; - return imported ? IMPORTED_PLACEHOLDER : model.id; -}