diff --git a/scripts/resolvers/preamble.ts b/scripts/resolvers/preamble.ts index 49288500c..02bafaf4d 100644 --- a/scripts/resolvers/preamble.ts +++ b/scripts/resolvers/preamble.ts @@ -456,12 +456,16 @@ fi if [ "$_TEL" != "off" ] && [ -x ~/.claude/skills/gstack/bin/gstack-telemetry-log ]; then ~/.claude/skills/gstack/bin/gstack-telemetry-log \\ --skill "SKILL_NAME" --duration "$_TEL_DUR" --outcome "OUTCOME" \\ - --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" 2>/dev/null & + --used-browse "USED_BROWSE" --session-id "$_SESSION_ID" \\ + --error-message "ERROR_MESSAGE" --failed-step "FAILED_STEP" 2>/dev/null & fi \`\`\` Replace \`SKILL_NAME\` with the actual skill name from frontmatter, \`OUTCOME\` with success/error/abort, and \`USED_BROWSE\` with true/false based on whether \`$B\` was used. +Replace \`ERROR_MESSAGE\` with a short description of the error (if outcome is error, +otherwise use empty string ""), and \`FAILED_STEP\` with the step name or number where +the failure occurred (if outcome is error, otherwise use empty string ""). If you cannot determine the outcome, use "unknown". The local JSONL always logs. The remote binary only runs if telemetry is not off and the binary exists. diff --git a/supabase/functions/telemetry-ingest/index.ts b/supabase/functions/telemetry-ingest/index.ts index 07d65d364..665328662 100644 --- a/supabase/functions/telemetry-ingest/index.ts +++ b/supabase/functions/telemetry-ingest/index.ts @@ -16,6 +16,8 @@ interface TelemetryEvent { duration_s?: number; outcome: string; error_class?: string; + error_message?: string; + failed_step?: string; used_browse?: boolean; sessions?: number; installation_id?: string; @@ -77,6 +79,8 @@ Deno.serve(async (req) => { duration_s: typeof event.duration_s === "number" ? event.duration_s : null, outcome: String(event.outcome).slice(0, 20), error_class: event.error_class ? String(event.error_class).slice(0, 100) : null, + error_message: event.error_message ? String(event.error_message).slice(0, 500) : null, + failed_step: event.failed_step ? String(event.failed_step).slice(0, 100) : null, used_browse: event.used_browse === true, concurrent_sessions: typeof event.sessions === "number" ? event.sessions : 1, installation_id: event.installation_id ? String(event.installation_id).slice(0, 64) : null,