Skip to content

Commit 47a6017

Browse files
authored
Merge pull request #74 from MaxLinCode/claude/pr73-to-main
Land PR #73 entity slot→field renames on main
2 parents a19c9ca + e382fe4 commit 47a6017

14 files changed

Lines changed: 158 additions & 138 deletions

apps/web/src/app/api/telegram/webhook/route.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ function buildRoutedTurn(input: {
195195
async function seedProposalEntity(input: {
196196
proposalId: string;
197197
originatingTurnText: string;
198-
missingSlots?: string[];
198+
missingFields?: string[];
199199
replyText?: string;
200200
}) {
201201
const entity: ConversationEntity = {
@@ -210,8 +210,8 @@ async function seedProposalEntity(input: {
210210
route: "conversation_then_mutation",
211211
replyText: input.replyText ?? "Shall I schedule that?",
212212
originatingTurnText: input.originatingTurnText,
213-
missingSlots: input.missingSlots ?? [],
214-
slotSnapshot: {},
213+
missingFields: input.missingFields ?? [],
214+
fieldSnapshot: {},
215215
},
216216
};
217217

@@ -1148,7 +1148,7 @@ describe("telegram webhook route", () => {
11481148
await seedProposalEntity({
11491149
proposalId: "proposal-1",
11501150
originatingTurnText: "Schedule the dentist reminder",
1151-
missingSlots: ["time"],
1151+
missingFields: ["time"],
11521152
replyText: "Would you like me to schedule it at 3pm?",
11531153
});
11541154
const planner = vi.fn(

apps/web/src/lib/server/conversation-state.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,8 @@ export function deriveConversationReplyState(
104104
mutationInputSource: null,
105105
confirmationRequired: true,
106106
originatingTurnText: input.userTurnText,
107-
missingSlots: input.policy.clarificationSlots,
108-
slotSnapshot:
109-
input.policy.resolvedOperation?.resolvedFields.scheduleFields ?? {},
107+
missingFields: input.policy.clarificationSlots,
108+
fieldSnapshot: input.policy.resolvedOperation?.resolvedFields ?? {},
110109
},
111110
}),
112111
);

apps/web/src/lib/server/decide-turn-policy.test.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ describe("decideTurnPolicy", () => {
163163
route: "conversation_then_mutation",
164164
replyText: "Would you like me to schedule it at 3pm?",
165165
confirmationRequired: true,
166-
slotSnapshot: {},
166+
fieldSnapshot: {},
167167
},
168168
},
169169
],
@@ -203,7 +203,7 @@ describe("decideTurnPolicy", () => {
203203
route: "conversation_then_mutation",
204204
replyText: "Would you like me to schedule it at 3pm?",
205205
confirmationRequired: true,
206-
slotSnapshot: {},
206+
fieldSnapshot: {},
207207
},
208208
},
209209
],
@@ -246,7 +246,7 @@ describe("decideTurnPolicy", () => {
246246
replyText: "Would you like me to move it to 3pm?",
247247
confirmationRequired: true,
248248
targetEntityId: "task-1",
249-
slotSnapshot: {},
249+
fieldSnapshot: {},
250250
},
251251
},
252252
],
@@ -308,7 +308,7 @@ describe("decideTurnPolicy", () => {
308308
"Would you like me to schedule it tomorrow at 6pm?",
309309
confirmationRequired: true,
310310
targetEntityId: "task-1",
311-
slotSnapshot: {},
311+
fieldSnapshot: {},
312312
},
313313
},
314314
],
@@ -350,7 +350,7 @@ describe("decideTurnPolicy", () => {
350350
replyText: "Would you like me to move it to 3:15pm?",
351351
confirmationRequired: true,
352352
targetEntityId: "task-1",
353-
slotSnapshot: {},
353+
fieldSnapshot: {},
354354
},
355355
},
356356
],
@@ -397,7 +397,9 @@ describe("decideTurnPolicy", () => {
397397
confirmationRequired: true,
398398
targetEntityId: "task-1",
399399
originatingTurnText: "move it to tomorrow 2pm",
400-
slotSnapshot: { time: t(14, 0), day: "tomorrow" },
400+
fieldSnapshot: {
401+
scheduleFields: { time: t(14, 0), day: "tomorrow" },
402+
},
401403
},
402404
},
403405
],
@@ -441,7 +443,7 @@ describe("decideTurnPolicy", () => {
441443
replyText: "Would you like me to move task one to 2pm?",
442444
confirmationRequired: true,
443445
targetEntityId: "task-1",
444-
slotSnapshot: {},
446+
fieldSnapshot: {},
445447
},
446448
},
447449
],
@@ -485,7 +487,7 @@ describe("decideTurnPolicy", () => {
485487
"Would you like me to schedule it tomorrow at 6pm?",
486488
confirmationRequired: true,
487489
targetEntityId: "task-1",
488-
slotSnapshot: {},
490+
fieldSnapshot: {},
489491
},
490492
},
491493
],
@@ -529,7 +531,7 @@ describe("decideTurnPolicy", () => {
529531
replyText: "Would you like me to schedule it at 5pm?",
530532
confirmationRequired: true,
531533
targetEntityId: "task-1",
532-
slotSnapshot: {},
534+
fieldSnapshot: {},
533535
},
534536
},
535537
],
@@ -574,7 +576,9 @@ describe("decideTurnPolicy", () => {
574576
replyText: "Would you like me to schedule it tomorrow at 3pm?",
575577
confirmationRequired: true,
576578
targetEntityId: "task-1",
577-
slotSnapshot: { day: "tomorrow", time: t(15, 0) },
579+
fieldSnapshot: {
580+
scheduleFields: { day: "tomorrow", time: t(15, 0) },
581+
},
578582
},
579583
},
580584
],
@@ -617,7 +621,7 @@ describe("decideTurnPolicy", () => {
617621
route: "conversation_then_mutation",
618622
replyText: "Would you like me to schedule it at 3pm?",
619623
confirmationRequired: true,
620-
slotSnapshot: { time: t(15, 0) },
624+
fieldSnapshot: { scheduleFields: { time: t(15, 0) } },
621625
},
622626
},
623627
],

apps/web/src/lib/server/llm-classifier.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ describe("classifyTurn", () => {
3939
replyText: "Would you like me to schedule it at 3pm?",
4040
confirmationRequired: true,
4141
targetEntityId: "task-1",
42-
slotSnapshot: {},
42+
fieldSnapshot: {},
4343
},
4444
},
4545
],
@@ -70,7 +70,7 @@ describe("classifyTurn", () => {
7070
route: "conversation_then_mutation",
7171
replyText: "Move it to 3pm?",
7272
confirmationRequired: true,
73-
slotSnapshot: {},
73+
fieldSnapshot: {},
7474
},
7575
},
7676
],
@@ -106,7 +106,7 @@ describe("classifyTurn", () => {
106106
route: "conversation_then_mutation",
107107
replyText: "A?",
108108
confirmationRequired: true,
109-
slotSnapshot: {},
109+
fieldSnapshot: {},
110110
},
111111
},
112112
{
@@ -121,7 +121,7 @@ describe("classifyTurn", () => {
121121
route: "conversation_then_mutation",
122122
replyText: "B?",
123123
confirmationRequired: true,
124-
slotSnapshot: {},
124+
fieldSnapshot: {},
125125
},
126126
},
127127
],
@@ -308,7 +308,7 @@ describe("classifyTurn", () => {
308308
route: "conversation_then_mutation",
309309
replyText: "Schedule at 3pm?",
310310
confirmationRequired: true,
311-
slotSnapshot: {},
311+
fieldSnapshot: {},
312312
},
313313
},
314314
],

apps/web/src/lib/server/telegram-webhook.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,9 @@ export async function handleTelegramWebhook(
453453
);
454454

455455
const synthesis = synthesizeMutationText({
456-
resolvedSlots:
457-
routedWithContext.policy.resolvedOperation?.resolvedFields
458-
.scheduleFields ?? {},
456+
resolvedFields:
457+
routedWithContext.policy.resolvedOperation?.resolvedFields ?? {},
458+
targetEntityId: routedWithContext.policy.targetEntityId,
459459
proposalEntity,
460460
entityRegistry,
461461
});

apps/web/src/lib/server/turn-router.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ describe("turn router", () => {
129129
originatingTurnText: "Schedule dentist reminder tomorrow",
130130
targetEntityId: null,
131131
mutationInputSource: null,
132-
slotSnapshot: {},
132+
fieldSnapshot: {},
133133
},
134134
},
135135
],
@@ -181,7 +181,7 @@ describe("turn router", () => {
181181
originatingTurnText: "Schedule Malaysia trip planning at 5pm",
182182
targetEntityId: null,
183183
mutationInputSource: null,
184-
slotSnapshot: {},
184+
fieldSnapshot: {},
185185
},
186186
},
187187
],
@@ -359,7 +359,7 @@ describe("turn router", () => {
359359
confirmationRequired: true,
360360
targetEntityId: null,
361361
mutationInputSource: null,
362-
slotSnapshot: {},
362+
fieldSnapshot: {},
363363
},
364364
},
365365
],
@@ -396,7 +396,7 @@ describe("turn router", () => {
396396
confirmationRequired: true,
397397
targetEntityId: null,
398398
mutationInputSource: null,
399-
slotSnapshot: {},
399+
fieldSnapshot: {},
400400
},
401401
},
402402
],

packages/core/src/discourse-state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export const timeSpecSchema = z.discriminatedUnion("kind", [
7171

7272
export type TimeSpec = z.infer<typeof timeSpecSchema>;
7373

74-
// Kept for entity slotSnapshot fields (proposal_option, task_draft) — not used in discourse state.
74+
// Kept for slot-extractor schemas — not used in discourse state.
7575
export const resolvedSlotsSchema = z.object({
7676
day: z.string().optional(),
7777
time: timeSpecSchema.optional(),

packages/core/src/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ describe("core package", () => {
11461146
route: "conversation_then_mutation",
11471147
replyText:
11481148
"It sounds like you want to move the dentist reminder after lunch.",
1149-
slotSnapshot: {},
1149+
fieldSnapshot: {},
11501150
},
11511151
},
11521152
],

packages/core/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -826,8 +826,8 @@ export const conversationProposalOptionEntitySchema =
826826
.optional(),
827827
confirmationRequired: z.boolean().optional(),
828828
originatingTurnText: z.string().min(1).nullable().optional(),
829-
missingSlots: z.array(z.string().min(1)).optional(),
830-
slotSnapshot: resolvedSlotsSchema,
829+
missingFields: z.array(z.string().min(1)).optional(),
830+
fieldSnapshot: resolvedFieldsSchema,
831831
}),
832832
});
833833

packages/core/src/proposal-rules.test.ts

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
import { describe, expect, it } from "vitest";
2-
import type {
3-
ConversationEntity,
4-
ResolvedFields,
5-
ResolvedSlots,
6-
TimeSpec,
7-
} from "./index";
2+
import type { ConversationEntity, ResolvedFields, TimeSpec } from "./index";
83
import { deriveProposalCompatibility } from "./proposal-rules";
94

105
function t(hour: number, minute: number): TimeSpec {
116
return { kind: "absolute", hour, minute };
127
}
138

14-
function sf(slots: ResolvedSlots): ResolvedFields {
15-
return { scheduleFields: slots };
9+
type ScheduleFields = NonNullable<ResolvedFields["scheduleFields"]>;
10+
11+
function sf(fields: ScheduleFields): ResolvedFields {
12+
return { scheduleFields: fields };
1613
}
1714

1815
type ProposalOption = Extract<ConversationEntity, { kind: "proposal_option" }>;
1916

2017
function makeProposal(
21-
overrides: Partial<ProposalOption["data"]> & { slotSnapshot: ResolvedSlots },
18+
overrides: Partial<ProposalOption["data"]> & {
19+
fieldSnapshot: ResolvedFields;
20+
},
2221
): ProposalOption {
2322
return {
2423
id: "proposal-1",
@@ -38,10 +37,10 @@ function makeProposal(
3837
}
3938

4039
describe("deriveProposalCompatibility", () => {
41-
describe("slot-based compatibility", () => {
42-
it("is compatible when committed slots match the snapshot", () => {
40+
describe("field-based compatibility", () => {
41+
it("is compatible when committed fields match the snapshot", () => {
4342
const proposal = makeProposal({
44-
slotSnapshot: { time: t(15, 0), day: "friday" },
43+
fieldSnapshot: sf({ time: t(15, 0), day: "friday" }),
4544
});
4645

4746
const result = deriveProposalCompatibility(
@@ -53,9 +52,9 @@ describe("deriveProposalCompatibility", () => {
5352
expect(result.compatible).toBe(true);
5453
});
5554

56-
it("is incompatible when a committed slot differs from the snapshot", () => {
55+
it("is incompatible when a committed field differs from the snapshot", () => {
5756
const proposal = makeProposal({
58-
slotSnapshot: { time: t(15, 0) },
57+
fieldSnapshot: sf({ time: t(15, 0) }),
5958
});
6059

6160
const result = deriveProposalCompatibility(
@@ -68,9 +67,9 @@ describe("deriveProposalCompatibility", () => {
6867
expect(result.reason).toMatch(/differs from proposal snapshot/);
6968
});
7069

71-
it("is compatible when committed slot is new (not in snapshot)", () => {
70+
it("is compatible when committed field is new (not in snapshot)", () => {
7271
const proposal = makeProposal({
73-
slotSnapshot: { day: "friday" },
72+
fieldSnapshot: sf({ day: "friday" }),
7473
});
7574

7675
const result = deriveProposalCompatibility(
@@ -82,9 +81,9 @@ describe("deriveProposalCompatibility", () => {
8281
expect(result.compatible).toBe(true);
8382
});
8483

85-
it("is compatible when committed slots are empty", () => {
84+
it("is compatible when committed fields are empty", () => {
8685
const proposal = makeProposal({
87-
slotSnapshot: { time: t(15, 0), day: "friday" },
86+
fieldSnapshot: sf({ time: t(15, 0), day: "friday" }),
8887
});
8988

9089
const result = deriveProposalCompatibility(
@@ -98,7 +97,7 @@ describe("deriveProposalCompatibility", () => {
9897

9998
it("detects duration change as incompatible", () => {
10099
const proposal = makeProposal({
101-
slotSnapshot: { duration: 30 },
100+
fieldSnapshot: sf({ duration: 30 }),
102101
});
103102

104103
const result = deriveProposalCompatibility(
@@ -116,7 +115,7 @@ describe("deriveProposalCompatibility", () => {
116115
it("is incompatible when action kind changes from plan to edit", () => {
117116
const proposal = makeProposal({
118117
originatingTurnText: "schedule a meeting",
119-
slotSnapshot: { time: t(15, 0) },
118+
fieldSnapshot: sf({ time: t(15, 0) }),
120119
});
121120

122121
const result = deriveProposalCompatibility(
@@ -132,7 +131,7 @@ describe("deriveProposalCompatibility", () => {
132131
it("skips action kind check for clarification answers", () => {
133132
const proposal = makeProposal({
134133
originatingTurnText: "move the meeting",
135-
slotSnapshot: { time: t(15, 0) },
134+
fieldSnapshot: sf({ time: t(15, 0) }),
136135
});
137136

138137
const result = deriveProposalCompatibility(

0 commit comments

Comments
 (0)