Add message intent classification (edit/info/help) before routing
Introduces a two-LLM-call pipeline: the first call classifies the user's message intent as "edit", "info", or "help". Edit messages proceed through the existing routing → edit → propose flow. Info messages get a generated response about site content from the manifest. Help messages get a templated capabilities overview. This handles open-ended questions like "What can I do?" or "What does my site have on it?" which previously had no path through the system. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import type { EditJobPayload } from '@dynamic-sites/shared';
|
||||
import { schemaForRepoRelativePath } from '@dynamic-sites/shared';
|
||||
import { createProposal, getProposal, updateProposalStatus } from '../db.js';
|
||||
import { writeContentFile } from '../io/write-content.js';
|
||||
import { generateEditedJson, routeEditIntent, generateSummary } from '../llm/client.js';
|
||||
import { generateEditedJson, routeEditIntent, generateSummary, classifyMessageIntent, generateInfoResponse } from '../llm/client.js';
|
||||
import { buildSectionManifest } from './manifest.js';
|
||||
import { sendSms } from '../sms/reply.js';
|
||||
import { SMS_TEMPLATES } from '../sms/templates.js';
|
||||
@@ -25,6 +25,30 @@ async function handlePropose(job: Extract<EditJobPayload, { kind: 'propose' }>)
|
||||
const log = logger.child({ jobId: job.id, kind: 'propose' });
|
||||
|
||||
try {
|
||||
// Step 0: Classify message intent (edit, info, or help)
|
||||
const classification = await classifyMessageIntent({ userMessage: job.message });
|
||||
log.info({ event: 'classification.result', intent: classification.intent, reason: classification.reason }, 'Message classified');
|
||||
|
||||
// ── HELP intent: send help message, no further LLM calls ──
|
||||
if (classification.intent === 'help') {
|
||||
if (job.smsReplyMeta) {
|
||||
await sendSms(job.smsReplyMeta.from, job.smsReplyMeta.to, SMS_TEMPLATES.HELP());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ── INFO intent: generate informational response about site ──
|
||||
if (classification.intent === 'info') {
|
||||
const manifest = buildSectionManifest();
|
||||
const infoResponse = await generateInfoResponse({ userMessage: job.message, manifest });
|
||||
if (job.smsReplyMeta) {
|
||||
await sendSms(job.smsReplyMeta.from, job.smsReplyMeta.to, infoResponse);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ── EDIT intent: proceed with existing edit flow ──
|
||||
|
||||
// Step 1: Route — determine which file the edit targets
|
||||
let repoRelativePath = job.repo_relative_path;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user