Skip to content
← Public packages

@kentcdodds/kody-issue-triage

Loop-safe triage for Kody run errors and fleet package-runtime error-rate elevations. Wakes Cole (Grok Bot) to decide; Cursor agents only when Cole escalates.

src/escalate-to-kody.ts

98 lines · 2.8 KB · TypeScript
import { createAgent } from 'kody:@kentcdodds/cursor/agents'
import { buildKodyPlatformAgentPrompt } from './kody-agent-prompt.ts'
import { emptyLoopGuardSnapshot, type LoopGuardSnapshot } from './loop-guard.ts'
import { gatherPeerContext } from './peer-context.ts'
import { emptyPeerContext } from './peer-match.ts'
import { gatherLoopGuardSnapshot } from './spawn-snapshot.ts'
import {
	agentModelId,
	kodyRef,
	kodyRepository,
	type FingerprintRecord,
} from './shared.ts'
import { getFingerprint, initSchema, updateFingerprint } from './storage.ts'

export type EscalateToKodyInput = {
	fingerprint: string
	reason: string
	/** True only when the platform fix is already clear from code. */
	obvious?: boolean
}

function agentUrlOf(agent: { id?: string; url?: string } | null) {
	if (!agent) return null
	return agent.url || (agent.id ? `https://cursor.com/agents/${agent.id}` : null)
}

/**
 * Spawn one grok-4.6 Cursor agent on kentcdodds/kody for a platform issue.
 * The use-kody triage agent must call this instead of editing Kody itself.
 */
export default async function escalateToKody(input: EscalateToKodyInput) {
	const fingerprint = String(input?.fingerprint || '').trim()
	const reason = String(input?.reason || '').trim()
	if (!fingerprint) throw new Error('fingerprint is required')
	if (!reason) throw new Error('reason is required')

	await initSchema()
	const record = await getFingerprint(fingerprint)
	if (!record) throw new Error(`unknown fingerprint: ${fingerprint}`)
	if (record.kody_agent_id) {
		return {
			ok: true,
			skipped: 'already-escalated',
			fingerprint,
			kodyAgentId: record.kody_agent_id,
			kodyAgentUrl: record.kody_agent_url,
		}
	}

	let peerContext = emptyPeerContext()
	try {
		peerContext = await gatherPeerContext(record)
	} catch {
		peerContext = emptyPeerContext()
	}
	let loopGuard: LoopGuardSnapshot = emptyLoopGuardSnapshot()
	try {
		loopGuard = await gatherLoopGuardSnapshot(record)
	} catch {
		loopGuard = emptyLoopGuardSnapshot()
	}

	const created = await createAgent({
		prompt: {
			text: buildKodyPlatformAgentPrompt({
				record,
				reason,
				obvious: input.obvious === true,
				discordMessageId: record.discord_message_id || 'unknown',
				peerContext,
				loopGuard,
			}),
		},
		model: { id: agentModelId },
		name: `kody-platform ${record.error_family}`.slice(0, 60),
		repository: kodyRepository,
		ref: kodyRef,
	})
	const agent =
		(created as { agent?: { id?: string; url?: string } })?.agent ??
		(created as { id?: string; url?: string })
	const kodyAgentId = agent?.id || null
	const kodyAgentUrl = agentUrlOf(agent)
	const fields: Partial<FingerprintRecord> = {
		classification: 'kody',
		kody_agent_id: kodyAgentId,
		kody_agent_url: kodyAgentUrl,
	}
	await updateFingerprint(fingerprint, fields)

	return {
		ok: true,
		fingerprint,
		kodyAgentId,
		kodyAgentUrl,
		obvious: input.obvious === true,
	}
}