Remove dead analytics and telemetry scaffolding
This commit is contained in:
@@ -1,13 +0,0 @@
|
||||
export function bootstrapTelemetry(): void {}
|
||||
|
||||
export function isTelemetryEnabled(): boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
export async function initializeTelemetry(): Promise<null> {
|
||||
return null
|
||||
}
|
||||
|
||||
export async function flushTelemetry(): Promise<void> {
|
||||
return
|
||||
}
|
||||
@@ -12,17 +12,10 @@
|
||||
*/
|
||||
|
||||
import { createHash } from 'crypto'
|
||||
import { sep } from 'path'
|
||||
import {
|
||||
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
type AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED,
|
||||
logEvent,
|
||||
} from '../../services/analytics/index.js'
|
||||
import type {
|
||||
LoadedPlugin,
|
||||
PluginError,
|
||||
PluginManifest,
|
||||
} from '../../types/plugin.js'
|
||||
import type { PluginManifest } from '../../types/plugin.js'
|
||||
import {
|
||||
isOfficialMarketplaceName,
|
||||
parsePluginIdentifier,
|
||||
@@ -80,17 +73,6 @@ export function getTelemetryPluginScope(
|
||||
return 'user-local'
|
||||
}
|
||||
|
||||
/**
|
||||
* How a plugin arrived in the session. Splits self-selected from org-pushed
|
||||
* — plugin_scope alone doesn't (an official plugin can be user-installed OR
|
||||
* org-pushed; both are scope='official').
|
||||
*/
|
||||
export type EnabledVia =
|
||||
| 'user-install'
|
||||
| 'org-policy'
|
||||
| 'default-enable'
|
||||
| 'seed-mount'
|
||||
|
||||
/** How a skill/command invocation was triggered. */
|
||||
export type InvocationTrigger =
|
||||
| 'user-slash'
|
||||
@@ -107,24 +89,6 @@ export type InstallSource =
|
||||
| 'ui-suggestion'
|
||||
| 'deep-link'
|
||||
|
||||
export function getEnabledVia(
|
||||
plugin: LoadedPlugin,
|
||||
managedNames: Set<string> | null,
|
||||
seedDirs: string[],
|
||||
): EnabledVia {
|
||||
if (plugin.isBuiltin) return 'default-enable'
|
||||
if (managedNames?.has(plugin.name)) return 'org-policy'
|
||||
// Trailing sep: /opt/plugins must not match /opt/plugins-extra
|
||||
if (
|
||||
seedDirs.some(dir =>
|
||||
plugin.path.startsWith(dir.endsWith(sep) ? dir : dir + sep),
|
||||
)
|
||||
) {
|
||||
return 'seed-mount'
|
||||
}
|
||||
return 'user-install'
|
||||
}
|
||||
|
||||
/**
|
||||
* Common plugin telemetry fields keyed off name@marketplace. Returns the
|
||||
* hash, scope enum, and the redacted-twin columns. Callers add the raw
|
||||
@@ -165,10 +129,7 @@ export function buildPluginTelemetryFields(
|
||||
|
||||
/**
|
||||
* Per-invocation callers (SkillTool, processSlashCommand) pass
|
||||
* managedNames=null — the session-level tengu_plugin_enabled_for_session
|
||||
* event carries the authoritative plugin_scope, and per-invocation rows can
|
||||
* join on plugin_id_hash to recover it. This keeps hot-path call sites free
|
||||
* of the extra settings read.
|
||||
* managedNames=null to keep hot-path call sites free of the extra settings read.
|
||||
*/
|
||||
export function buildPluginCommandTelemetryFields(
|
||||
pluginInfo: { pluginManifest: PluginManifest; repository: string },
|
||||
@@ -182,47 +143,6 @@ export function buildPluginCommandTelemetryFields(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit tengu_plugin_enabled_for_session once per enabled plugin at session
|
||||
* start. Supplements tengu_skill_loaded (which still fires per-skill) — use
|
||||
* this for plugin-level aggregates instead of DISTINCT-on-prefix hacks.
|
||||
* A plugin with 5 skills emits 5 skill_loaded rows but 1 of these.
|
||||
*/
|
||||
export function logPluginsEnabledForSession(
|
||||
plugins: LoadedPlugin[],
|
||||
managedNames: Set<string> | null,
|
||||
seedDirs: string[],
|
||||
): void {
|
||||
for (const plugin of plugins) {
|
||||
const { marketplace } = parsePluginIdentifier(plugin.repository)
|
||||
|
||||
logEvent('tengu_plugin_enabled_for_session', {
|
||||
_PROTO_plugin_name:
|
||||
plugin.name as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED,
|
||||
...(marketplace && {
|
||||
_PROTO_marketplace_name:
|
||||
marketplace as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED,
|
||||
}),
|
||||
...buildPluginTelemetryFields(plugin.name, marketplace, managedNames),
|
||||
enabled_via: getEnabledVia(
|
||||
plugin,
|
||||
managedNames,
|
||||
seedDirs,
|
||||
) as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
skill_path_count:
|
||||
(plugin.skillsPath ? 1 : 0) + (plugin.skillsPaths?.length ?? 0),
|
||||
command_path_count:
|
||||
(plugin.commandsPath ? 1 : 0) + (plugin.commandsPaths?.length ?? 0),
|
||||
has_mcp: plugin.manifest.mcpServers !== undefined,
|
||||
has_hooks: plugin.hooksConfig !== undefined,
|
||||
...(plugin.manifest.version && {
|
||||
version: plugin.manifest
|
||||
.version as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bounded-cardinality error bucket for CLI plugin operation failures.
|
||||
* Maps free-form error messages to 5 stable categories so dashboard
|
||||
@@ -257,33 +177,3 @@ export function classifyPluginCommandError(
|
||||
}
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit tengu_plugin_load_failed once per error surfaced by session-start
|
||||
* plugin loading. Pairs with tengu_plugin_enabled_for_session so dashboards
|
||||
* can compute a load-success rate. PluginError.type is already a bounded
|
||||
* enum — use it directly as error_category.
|
||||
*/
|
||||
export function logPluginLoadErrors(
|
||||
errors: PluginError[],
|
||||
managedNames: Set<string> | null,
|
||||
): void {
|
||||
for (const err of errors) {
|
||||
const { name, marketplace } = parsePluginIdentifier(err.source)
|
||||
// Not all PluginError variants carry a plugin name (some have pluginId,
|
||||
// some are marketplace-level). Use the 'plugin' property if present,
|
||||
// fall back to the name parsed from err.source.
|
||||
const pluginName = 'plugin' in err && err.plugin ? err.plugin : name
|
||||
logEvent('tengu_plugin_load_failed', {
|
||||
error_category:
|
||||
err.type as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
_PROTO_plugin_name:
|
||||
pluginName as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED,
|
||||
...(marketplace && {
|
||||
_PROTO_marketplace_name:
|
||||
marketplace as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED,
|
||||
}),
|
||||
...buildPluginTelemetryFields(pluginName, marketplace, managedNames),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import { getSkillToolCommands } from '../../commands.js'
|
||||
import {
|
||||
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
type AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED,
|
||||
logEvent,
|
||||
} from '../../services/analytics/index.js'
|
||||
import { getCharBudget } from '../../tools/SkillTool/prompt.js'
|
||||
|
||||
/**
|
||||
* Logs a tengu_skill_loaded event for each skill available at session startup.
|
||||
* This enables analytics on which skills are available across sessions.
|
||||
*/
|
||||
export async function logSkillsLoaded(
|
||||
cwd: string,
|
||||
contextWindowTokens: number,
|
||||
): Promise<void> {
|
||||
const skills = await getSkillToolCommands(cwd)
|
||||
const skillBudget = getCharBudget(contextWindowTokens)
|
||||
|
||||
for (const skill of skills) {
|
||||
if (skill.type !== 'prompt') continue
|
||||
|
||||
logEvent('tengu_skill_loaded', {
|
||||
// _PROTO_skill_name routes to the privileged skill_name BQ column.
|
||||
// Unredacted names don't go in additional_metadata.
|
||||
_PROTO_skill_name:
|
||||
skill.name as AnalyticsMetadata_I_VERIFIED_THIS_IS_PII_TAGGED,
|
||||
skill_source:
|
||||
skill.source as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
skill_loaded_from:
|
||||
skill.loadedFrom as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
skill_budget: skillBudget,
|
||||
...(skill.kind && {
|
||||
skill_kind:
|
||||
skill.kind as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user