Add more posthog analytics (privacy aware) (#6122)

This commit is contained in:
Zane
2025-12-16 08:59:14 -08:00
committed by GitHub
parent 036f4f74d9
commit 8a91f15731
34 changed files with 1339 additions and 48 deletions
@@ -195,11 +195,19 @@ export default function ExtensionsSection({
};
const handleDeleteExtension = async (name: string) => {
// Capture the selected extension before closing the modal
const extensionToDelete = selectedExtension;
// Close the modal immediately
handleModalClose();
try {
await deleteExtension({ name, removeFromConfig: removeExtension, sessionId: sessionId });
await deleteExtension({
name,
removeFromConfig: removeExtension,
sessionId: sessionId,
extensionConfig: extensionToDelete ?? undefined,
});
} catch (error) {
console.error('Failed to delete extension:', error);
// We don't reopen the modal on failure
@@ -1,6 +1,17 @@
import type { ExtensionConfig } from '../../../api/types.gen';
import { toastService, ToastServiceOptions } from '../../../toasts';
import { addToAgent, removeFromAgent, sanitizeName } from './agent-api';
import {
trackExtensionAdded,
trackExtensionEnabled,
trackExtensionDisabled,
trackExtensionDeleted,
getErrorType,
} from '../../../utils/analytics';
function isBuiltinExtension(config: ExtensionConfig): boolean {
return config.type === 'builtin';
}
interface ActivateExtensionProps {
addToConfig: (name: string, extensionConfig: ExtensionConfig, enabled: boolean) => Promise<void>;
@@ -58,17 +69,21 @@ export async function activateExtension({
extensionConfig,
sessionId,
}: ActivateExtensionProps): Promise<void> {
const isBuiltin = isBuiltinExtension(extensionConfig);
try {
// AddToAgent
await addToAgent(extensionConfig, sessionId, true);
} catch (error) {
console.error('Failed to add extension to agent:', error);
await addToConfig(extensionConfig.name, extensionConfig, false);
trackExtensionAdded(extensionConfig.name, false, getErrorType(error), isBuiltin);
throw error;
}
try {
await addToConfig(extensionConfig.name, extensionConfig, true);
trackExtensionAdded(extensionConfig.name, true, undefined, isBuiltin);
} catch (error) {
console.error('Failed to add extension to config:', error);
// remove from Agent
@@ -77,6 +92,7 @@ export async function activateExtension({
} catch (removeError) {
console.error('Failed to remove extension from agent after config failure:', removeError);
}
trackExtensionAdded(extensionConfig.name, false, getErrorType(error), isBuiltin);
// Rethrow the error to inform the caller
throw error;
}
@@ -252,13 +268,16 @@ export async function toggleExtension({
toastOptions = {},
sessionId,
}: ToggleExtensionProps) {
const isBuiltin = isBuiltinExtension(extensionConfig);
// disabled to enabled
if (toggle == 'toggleOn') {
try {
// add to agent with toast options
await addToAgent(extensionConfig, sessionId, !toastOptions?.silent);
} catch (error) {
console.error('Error adding extension to agent. Will try to toggle back off.');
console.error('Error adding extension to agent. Attempting to toggle back off.');
trackExtensionEnabled(extensionConfig.name, false, getErrorType(error), isBuiltin);
try {
await toggleExtension({
toggle: 'toggleOff',
@@ -276,8 +295,10 @@ export async function toggleExtension({
// update the config
try {
await addToConfig(extensionConfig.name, extensionConfig, true);
trackExtensionEnabled(extensionConfig.name, true, undefined, isBuiltin);
} catch (error) {
console.error('Failed to update config after enabling extension:', error);
trackExtensionEnabled(extensionConfig.name, false, getErrorType(error), isBuiltin);
// remove from agent
try {
await removeFromAgent(extensionConfig.name, sessionId, !toastOptions?.silent);
@@ -300,8 +321,19 @@ export async function toggleExtension({
// update the config
try {
await addToConfig(extensionConfig.name, extensionConfig, false);
if (agentRemoveError) {
trackExtensionDisabled(
extensionConfig.name,
false,
getErrorType(agentRemoveError),
isBuiltin
);
} else {
trackExtensionDisabled(extensionConfig.name, true, undefined, isBuiltin);
}
} catch (error) {
console.error('Error removing extension from config', extensionConfig.name, 'Error:', error);
trackExtensionDisabled(extensionConfig.name, false, getErrorType(error), isBuiltin);
throw error;
}
@@ -316,13 +348,20 @@ interface DeleteExtensionProps {
name: string;
removeFromConfig: (name: string) => Promise<void>;
sessionId: string;
extensionConfig?: ExtensionConfig;
}
/**
* Deletes an extension completely from both agent and config
*/
export async function deleteExtension({ name, removeFromConfig, sessionId }: DeleteExtensionProps) {
// remove from agent
export async function deleteExtension({
name,
removeFromConfig,
sessionId,
extensionConfig,
}: DeleteExtensionProps) {
const isBuiltin = extensionConfig ? isBuiltinExtension(extensionConfig) : false;
let agentRemoveError = null;
try {
await removeFromAgent(name, sessionId, true);
@@ -333,16 +372,20 @@ export async function deleteExtension({ name, removeFromConfig, sessionId }: Del
try {
await removeFromConfig(name);
if (agentRemoveError) {
trackExtensionDeleted(name, false, getErrorType(agentRemoveError), isBuiltin);
} else {
trackExtensionDeleted(name, true, undefined, isBuiltin);
}
} catch (error) {
console.error(
'Failed to remove extension from config after removing from agent. Error:',
error
);
// If we also had an agent remove error, log it but throw the config error as it's more critical
trackExtensionDeleted(name, false, getErrorType(error), isBuiltin);
throw error;
}
// If we had an error removing from agent but succeeded removing from config, still throw the original error
if (agentRemoveError) {
throw agentRemoveError;
}