mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 14:40:52 +00:00
feat(coach): ask back when the metric or window is ambiguous
A reply may end with a ---CLARIFY--- block (kind metric, window or
context, 512-byte cap). The server keeps only metric choices the record
holds, drops the question when fewer than two remain, takes window
choices from the presets, screens the question text like any reply, and
never offers a second question right after one. Choice labels come from
the catalog, never from the model.
An answer arrives as clarification { messageId, choiceId? }; it resolves
against the stored question on the conversation's latest message and
adds one server-written line to the next turn's context. The card sits
above the composer, announces politely and takes no focus.
A reply that is only the block, with no question before it, is now an
empty reply instead of falling back to the unstripped text.
This commit is contained in:
1 parent
78fc22d0f8
commit
6b07d48bf9
11 files changed
+1223
-52
No files matched your search
@@ -50,7 +50,7 @@ exports[`coach chat golden transcripts > 01a tool mode, two rounds, present data
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -251,7 +251,7 @@ exports[`coach chat golden transcripts > 01b tool mode, present data, one figure
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -464,7 +464,7 @@ exports[`coach chat golden transcripts > 02 tool mode, every tool missed, fabric
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -1128,7 +1128,7 @@ exports[`coach chat golden transcripts > 07a all providers failed (plain) 1`] =
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -1217,7 +1217,7 @@ exports[`coach chat golden transcripts > 07b all providers failed (every hop rat
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -1306,7 +1306,7 @@ exports[`coach chat golden transcripts > 07c all providers failed (primary crede
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -1395,7 +1395,7 @@ exports[`coach chat golden transcripts > 08 an unwrapped tagged provider error 1
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -1485,7 +1485,7 @@ exports[`coach chat golden transcripts > 09 an aborted request leaves a cancelle
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -1581,7 +1581,7 @@ exports[`coach chat golden transcripts > 10 outbound block replaces the reply an
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -1912,7 +1912,7 @@ exports[`coach chat golden transcripts > 11a KEYVALUES valid 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -2117,7 +2117,7 @@ exports[`coach chat golden transcripts > 11b KEYVALUES partial 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -2320,7 +2320,7 @@ exports[`coach chat golden transcripts > 11c KEYVALUES malformed (no closing mar
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -2507,7 +2507,7 @@ exports[`coach chat golden transcripts > 11d sentinel-only reply is an empty rep
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -2596,7 +2596,7 @@ exports[`coach chat golden transcripts > 11e empty provider reply 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -2676,7 +2676,7 @@ exports[`coach chat golden transcripts > 12a SUGGEST-REMINDER surfaced 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -2901,7 +2901,7 @@ exports[`coach chat golden transcripts > 12b SUGGEST-REMINDER suppressed 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -3090,7 +3090,7 @@ exports[`coach chat golden transcripts > 13 SUGGEST-ACTION 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -3319,7 +3319,7 @@ exports[`coach chat golden transcripts > 14a REMEMBER valid 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -3528,7 +3528,7 @@ exports[`coach chat golden transcripts > 14b REMEMBER malformed 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -3732,7 +3732,7 @@ exports[`coach chat golden transcripts > 15 an unknown learn link is scrubbed, a
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -4230,7 +4230,7 @@ exports[`coach chat golden transcripts > 17a a workout-scoped first turn 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -4440,7 +4440,7 @@ exports[`coach chat golden transcripts > 17b a workout-scoped first turn with th
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -4629,7 +4629,7 @@ exports[`coach chat golden transcripts > 18 a persistence throw after the provid
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -4722,7 +4722,7 @@ exports[`coach chat golden transcripts > 19 an existing conversation with prior
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
@@ -4935,7 +4935,7 @@ exports[`coach chat golden transcripts > 20 a guided-question turn with a scope
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "30126acc9ad2:1419",
|
||||
"system": "b5d183ae2920:2492",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 30000,
|
||||
"tools": 2,
|
||||
@@ -5104,7 +5104,7 @@ exports[`coach chat golden transcripts > 21 the German locale with a stored self
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "082a378c693f:1512",
|
||||
"system": "c746914e4df3:2620",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 2,
|
||||
|
||||
@@ -66,7 +66,8 @@ vi.mock("@/lib/ai/provider", () => ({
|
||||
}));
|
||||
vi.mock("@/lib/ai/consent-guard", () => ({ assertConsentForChain: vi.fn() }));
|
||||
vi.mock("@/lib/ai/prompts/insight-generator", () => ({ PROMPT_VERSION: "x" }));
|
||||
vi.mock("@/lib/ai/coach/types", () => ({
|
||||
vi.mock("@/lib/ai/coach/types", async (importOriginal) => ({
|
||||
...(await importOriginal<typeof import("@/lib/ai/coach/types")>()),
|
||||
coachChatRequestSchema: {
|
||||
safeParse: () => ({ success: false, error: { issues: [] } }),
|
||||
},
|
||||
|
||||
@@ -53,7 +53,8 @@ vi.mock("@/lib/ai/provider", () => ({
|
||||
}));
|
||||
vi.mock("@/lib/ai/consent-guard", () => ({ assertConsentForChain: vi.fn() }));
|
||||
vi.mock("@/lib/ai/prompts/insight-generator", () => ({ PROMPT_VERSION: "x" }));
|
||||
vi.mock("@/lib/ai/coach/types", () => ({
|
||||
vi.mock("@/lib/ai/coach/types", async (importOriginal) => ({
|
||||
...(await importOriginal<typeof import("@/lib/ai/coach/types")>()),
|
||||
coachChatRequestSchema: { safeParse: () => ({ success: false }) },
|
||||
}));
|
||||
vi.mock("@/lib/ai/coach/tools", () => ({
|
||||
|
||||
Reference in new issue
Block a user