← Public packages
@kentcdodds/sentry-triage
Sentry triage wakes Cole (Grok Bot) per issue: one active wake per repo (lease + queue), loop-safe Discord. Cole may spawn Cursor for isolated repo work.
src/cole-handoff.ts
161 lines · 4.4 KB · TypeScriptimport { packageStorage } from 'kody:runtime'
import directWake from 'kody:@kentcdodds/grok-bot/wake'
import { WAKE_WEBHOOK_STORAGE_KEY } from './configure-wake-webhook.ts'
export const COLE_BOT_NAME = 'cole'
export const COLE_AGENT_ID = 'cole'
export const COLE_AGENT_URL = 'grok-bot:cole'
export const GROK_BOT_WAKE_WEBHOOK_SECRET = 'grokBotWakeWebhookUrl'
type WakeSlim = {
ok?: boolean
woke?: boolean
timedOut?: boolean
dryRun?: boolean
error?: string
status?: number
}
function asRecord(value: unknown): Record<string, unknown> | null {
return value && typeof value === 'object' ? (value as Record<string, unknown>) : null
}
function unwrapWakeBody(body: unknown): WakeSlim {
const root = asRecord(body)
if (!root) return { ok: true, woke: true }
for (const key of ['result', 'data', 'value', 'output'] as const) {
const nested = asRecord(root[key])
if (
nested &&
('woke' in nested || 'ok' in nested || 'timedOut' in nested || 'error' in nested)
) {
return nested as WakeSlim
}
}
return root as WakeSlim
}
function wakeOk(input: { dryRun?: boolean }, woke: WakeSlim) {
const timedOut = woke.timedOut === true
if (input.dryRun === true) return { woke, timedOut, ok: Boolean(woke.ok) }
const explicitFail = woke.ok === false && woke.woke === false && !timedOut
const ok =
Boolean(woke.woke) ||
timedOut ||
(!explicitFail && woke.ok === true && woke.woke !== false)
return { woke, timedOut, ok }
}
async function resolveWakeWebhookTarget() {
try {
const stored = await packageStorage().get(WAKE_WEBHOOK_STORAGE_KEY)
if (typeof stored === 'string' && stored.startsWith('https://')) return stored
} catch {
// Fall through to the user-secret placeholder.
}
return `{{secret:${GROK_BOT_WAKE_WEBHOOK_SECRET}}}`
}
async function wakeViaWebhook(params: Record<string, unknown>): Promise<WakeSlim> {
const response = await fetch(await resolveWakeWebhookTarget(), {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(params),
})
const text = await response.text()
let body: unknown = null
try {
body = text ? JSON.parse(text) : null
} catch {
body = { raw: text.slice(0, 500) }
}
if (!response.ok) {
const slim = unwrapWakeBody(body)
return {
ok: false,
woke: false,
error: `wake webhook HTTP ${response.status}: ${slim.error || text.slice(0, 240)}`,
}
}
const slim = unwrapWakeBody(body)
if (slim.ok === false && slim.woke === false && slim.timedOut !== true) return slim
if (slim.woke === undefined && slim.timedOut === undefined && slim.dryRun !== true) {
return { ...slim, ok: true, woke: true }
}
return slim
}
async function wakeViaPackage(params: Record<string, unknown>): Promise<WakeSlim> {
try {
return (await directWake(
params as {
bot: string
prompt: string
dryRun?: boolean
discordChannelId?: string
discordMessageId?: string
},
)) as WakeSlim
} catch (error) {
return {
ok: false,
woke: false,
error: error instanceof Error ? error.message : String(error),
}
}
}
/** Wake Cole without auto-spawning Cursor. Cole decides whether repo work needs Cursor. */
export async function wakeColeForTriage(input: {
prompt: string
discordChannelId?: string | null
discordMessageId?: string | null
dryRun?: boolean
}) {
const params = {
bot: COLE_BOT_NAME,
prompt: input.prompt,
dryRun: input.dryRun === true,
...(input.discordChannelId ? { discordChannelId: input.discordChannelId } : {}),
...(input.discordMessageId ? { discordMessageId: input.discordMessageId } : {}),
}
let via = 'webhook'
let woke: WakeSlim
try {
woke = await wakeViaWebhook(params)
} catch (error) {
woke = {
ok: false,
woke: false,
error: error instanceof Error ? error.message : String(error),
}
}
if (!woke.ok && !woke.woke && !woke.timedOut) {
via = 'package-fallback'
woke = await wakeViaPackage(params)
}
return { ...wakeOk(input, woke), via }
}
/** Agent-shaped compatibility result for existing lease/state code. */
export async function wakeCole(input: {
promptText: string
discordMessageId?: string | null
discordChannelId?: string | null
}) {
const result = await wakeColeForTriage({
prompt: input.promptText,
discordMessageId: input.discordMessageId,
discordChannelId: input.discordChannelId,
})
if (!result.ok) {
throw new Error(`cole-wake-failed: ${result.woke.error ?? 'unknown wake failure'}`)
}
return {
id: COLE_AGENT_ID,
url: COLE_AGENT_URL,
bot: COLE_BOT_NAME,
timedOut: result.timedOut,
via: result.via,
}
}