Skip to content

Commit c863d92

Browse files
committed
Use default contract on first message
1 parent d4f3463 commit c863d92

2 files changed

Lines changed: 12 additions & 11 deletions

File tree

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ vi.mock("./slot-extractor", () => ({
1717
}));
1818

1919
import { classifyTurn } from "./llm-classifier";
20+
import { extractSlots } from "./slot-extractor";
2021

2122
const mockClassifyTurn = vi.mocked(classifyTurn);
23+
const mockExtractSlots = vi.mocked(extractSlots);
2224

2325
function mockClassification(output: Partial<TurnClassifierOutput>) {
2426
const full: TurnClassifierOutput = {
@@ -36,6 +38,11 @@ describe("turn router", () => {
3638
turnType: "planning_request",
3739
confidence: 0.95
3840
});
41+
mockExtractSlots.mockResolvedValueOnce({
42+
extractedValues: { day: "tomorrow", time: "18:00" },
43+
confidence: { day: 0.95, time: 0.95 },
44+
unresolvable: []
45+
});
3946

4047
const result = await routeMessageTurn({
4148
rawText: "Schedule gym tomorrow at 6pm for 1 hour",

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export type TurnRouterInput = TurnRoutingInput;
2727
export type TurnRouterResult = RoutedTurn;
2828

2929
const DEFAULT_CONTRACT: WriteContract = {
30-
requiredSlots: [],
30+
requiredSlots: ["day", "time"],
3131
intentKind: "plan"
3232
};
3333

@@ -46,13 +46,10 @@ export async function routeMessageTurn(input: TurnRouterInput): Promise<TurnRout
4646
const activeContract = discourseState.pending_write_contract ?? DEFAULT_CONTRACT;
4747
let slotExtraction = null;
4848

49-
if (
50-
SLOT_COMMITTING_TURN_TYPES.has(classification.turnType) &&
51-
discourseState.pending_write_contract
52-
) {
49+
if (SLOT_COMMITTING_TURN_TYPES.has(classification.turnType)) {
5350
slotExtraction = await extractSlots({
5451
currentTurnText: input.normalizedText,
55-
pendingSlots: derivePendingSlots(discourseState),
52+
pendingSlots: derivePendingSlots(activeContract, discourseState.resolved_slots ?? {}),
5653
priorResolvedSlots: discourseState.resolved_slots ?? {},
5754
conversationContext: deriveConversationContext(input.recentTurns)
5855
});
@@ -83,11 +80,8 @@ export async function routeMessageTurn(input: TurnRouterInput): Promise<TurnRout
8380
});
8481
}
8582

86-
function derivePendingSlots(discourseState: DiscourseState): SlotKey[] {
87-
const contract = discourseState.pending_write_contract;
88-
if (!contract) return [];
89-
const resolved = discourseState.resolved_slots ?? {};
90-
return contract.requiredSlots.filter((slot) => resolved[slot] === undefined);
83+
function derivePendingSlots(contract: WriteContract, resolvedSlots: Record<string, unknown>): SlotKey[] {
84+
return contract.requiredSlots.filter((slot) => resolvedSlots[slot] === undefined);
9185
}
9286

9387
function deriveConversationContext(recentTurns: ConversationTurn[]): string {

0 commit comments

Comments
 (0)