Skip to content

Commit 561fee4

Browse files
committed
Align raw text conversation inputs
1 parent ccce83d commit 561fee4

5 files changed

Lines changed: 56 additions & 8 deletions

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,7 @@ describe("telegram webhook route", () => {
14981498
});
14991499
expect(conversationResponder).toHaveBeenCalledWith({
15001500
route: "conversation",
1501+
rawText: "How should I prioritize this week?",
15011502
normalizedText: "How should I prioritize this week?",
15021503
recentTurns: [
15031504
{
@@ -1616,6 +1617,7 @@ describe("telegram webhook route", () => {
16161617
expect(listOutgoingBotEventsForTests()).toHaveLength(1);
16171618
expect(conversationResponder).toHaveBeenCalledWith({
16181619
route: "conversation_then_mutation",
1620+
rawText: "Could we move it to tomorrow morning?",
16191621
normalizedText: "Could we move it to tomorrow morning?",
16201622
recentTurns: [
16211623
{
@@ -1687,6 +1689,7 @@ describe("telegram webhook route", () => {
16871689
expect(response.status).toBe(200);
16881690
expect(conversationResponder).toHaveBeenCalledWith({
16891691
route: "conversation",
1692+
rawText: "Should we talk this through first?",
16901693
normalizedText: "Should we talk this through first?",
16911694
recentTurns: [
16921695
{

apps/web/src/lib/server/conversation-response.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ describe("conversation response service", () => {
1010
const result = await buildConversationResponse(
1111
{
1212
route: "conversation",
13+
rawText: "How should I prioritize this week?",
1314
normalizedText: "How should I prioritize this week?",
1415
recentTurns: [
1516
{
@@ -28,6 +29,7 @@ describe("conversation response service", () => {
2829
expect(result.reply).toContain("deadline-driven work");
2930
expect(respond).toHaveBeenCalledWith({
3031
route: "conversation",
32+
rawText: "How should I prioritize this week?",
3133
normalizedText: "How should I prioritize this week?",
3234
recentTurns: [
3335
{
@@ -44,6 +46,7 @@ describe("conversation response service", () => {
4446
const result = await buildConversationResponse(
4547
{
4648
route: "conversation_then_mutation",
49+
rawText: "Could we move it to tomorrow morning?",
4750
normalizedText: "Could we move it to tomorrow morning?",
4851
recentTurns: [
4952
{
@@ -68,10 +71,11 @@ describe("conversation response service", () => {
6871
await expect(
6972
buildConversationResponse({
7073
route: "conversation",
74+
rawText: " ",
7175
normalizedText: " ",
7276
recentTurns: [],
7377
memorySummary: null
7478
})
75-
).rejects.toThrow("must include non-empty normalizedText");
79+
).rejects.toThrow("must include non-empty rawText and normalizedText");
7680
});
7781
});

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ export async function handleTelegramWebhook(
325325
const memorySummary = await buildConversationMemorySummary(recentTurns, dependencies);
326326
const conversationResponse = await (dependencies.conversationResponder ?? buildConversationResponse)({
327327
route: getConversationRouteForPolicy(routedWithContext.policy.action),
328+
rawText: normalizedMessage.rawText,
328329
normalizedText: normalizedMessage.normalizedText,
329330
recentTurns,
330331
memorySummary,

packages/integrations/src/index.test.ts

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -695,9 +695,15 @@ describe("integrations", () => {
695695
});
696696

697697
it("parses structured conversation response output from the Responses API client", async () => {
698+
const parse = vi.fn(async () => ({
699+
output_parsed: {
700+
reply: "Start by picking the one thing that must happen tomorrow, then give it the first focus block."
701+
}
702+
}));
698703
const result = await respondToConversationTurnWithResponses(
699704
{
700705
route: "conversation",
706+
rawText: "How should I plan tomorrow?",
701707
normalizedText: "How should I plan tomorrow?",
702708
recentTurns: [
703709
{
@@ -709,17 +715,45 @@ describe("integrations", () => {
709715
memorySummary: "The user wants help prioritizing tomorrow."
710716
},
711717
{
712-
responses: {
713-
parse: async () => ({
714-
output_parsed: {
715-
reply: "Start by picking the one thing that must happen tomorrow, then give it the first focus block."
716-
}
717-
})
718-
}
718+
responses: { parse }
719719
}
720720
);
721721

722722
expect(result.reply).toContain("first focus block");
723+
const parseCall = (parse as unknown as { mock: { calls: Array<[{
724+
input?: Array<{ content?: Array<{ text?: string }> }>;
725+
}]> } }).mock.calls[0];
726+
const promptPayload = parseCall?.[0]?.input?.[1]?.content?.[0]?.text;
727+
expect(promptPayload).toContain("\"rawText\":\"How should I plan tomorrow?\"");
728+
expect(promptPayload).not.toContain("normalizedText");
729+
});
730+
731+
it("omits normalizedText from model prompt payloads and uses rawText instead", async () => {
732+
const parse = vi.fn(async () => ({
733+
output_parsed: {
734+
route: "conversation",
735+
reason: "The user is asking for planning advice."
736+
}
737+
}));
738+
739+
await routeTurnWithResponses(
740+
{
741+
rawText: " Review launch checklist tomorrow morning ",
742+
normalizedText: "Review launch checklist tomorrow morning",
743+
recentTurns: []
744+
},
745+
{
746+
responses: { parse }
747+
}
748+
);
749+
750+
expect(parse).toHaveBeenCalledTimes(1);
751+
const parseCall = (parse as unknown as { mock: { calls: Array<[{
752+
input?: Array<{ content?: Array<{ text?: string }> }>;
753+
}]> } }).mock.calls[0];
754+
const promptPayload = parseCall?.[0]?.input?.[1]?.content?.[0]?.text;
755+
expect(promptPayload).toContain("\"rawText\":\" Review launch checklist tomorrow morning \"");
756+
expect(promptPayload).not.toContain("normalizedText");
723757
});
724758

725759
it("rejects malformed structured conversation response output", async () => {

packages/integrations/src/manual/conversation-context.eval-suite.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const CONVERSATION_CONTEXT_EVAL_CASES: ConversationContextEvalCase[] = [
5858
name: "mixed-turn reference uses recent context and stays discuss-first",
5959
input: {
6060
route: "conversation_then_mutation",
61+
rawText: "Could we move it to Friday morning instead?",
6162
normalizedText: "Could we move it to Friday morning instead?",
6263
recentTurns: DENTIST_TURNS
6364
},
@@ -73,6 +74,7 @@ export const CONVERSATION_CONTEXT_EVAL_CASES: ConversationContextEvalCase[] = [
7374
name: "write-adjacent question stays hedged",
7475
input: {
7576
route: "conversation",
77+
rawText: "Did you already create that?",
7678
normalizedText: "Did you already create that?",
7779
recentTurns: DENTIST_TURNS
7880
},
@@ -88,6 +90,7 @@ export const CONVERSATION_CONTEXT_EVAL_CASES: ConversationContextEvalCase[] = [
8890
name: "planning dialogue uses recent continuity",
8991
input: {
9092
route: "conversation",
93+
rawText: "How should I prioritize tomorrow?",
9194
normalizedText: "How should I prioritize tomorrow?",
9295
recentTurns: PRIORITIZATION_TURNS
9396
},
@@ -100,6 +103,7 @@ export const CONVERSATION_CONTEXT_EVAL_CASES: ConversationContextEvalCase[] = [
100103
name: "unclear referent asks one narrow question",
101104
input: {
102105
route: "conversation",
106+
rawText: "Can you move that?",
103107
normalizedText: "Can you move that?",
104108
recentTurns: DENTIST_TURNS
105109
},
@@ -114,6 +118,7 @@ export const CONVERSATION_CONTEXT_EVAL_CASES: ConversationContextEvalCase[] = [
114118
name: "delegated slot choice does not ask for an exact hour",
115119
input: {
116120
route: "conversation_then_mutation",
121+
rawText: "Schedule it for me and pick an open spot.",
117122
normalizedText: "Schedule it for me and pick an open spot.",
118123
recentTurns: OIL_CHANGE_TURNS
119124
},
@@ -131,6 +136,7 @@ export const CONVERSATION_CONTEXT_EVAL_CASES: ConversationContextEvalCase[] = [
131136
name: "bare scheduling does not ask follow-up timing questions",
132137
input: {
133138
route: "conversation_then_mutation",
139+
rawText: "Schedule an oil change.",
134140
normalizedText: "Schedule an oil change.",
135141
recentTurns: []
136142
},

0 commit comments

Comments
 (0)