mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
feat(coach): give the turn the memory block, its recalled facts and a pending proposal
Build the memory block for the providers the turn sends to, send it on both paths, keep the facts it recalled in the owner's trail, and offer a health fact the background found as the answer's one note. Every turn enqueues the memory refresh; the job's debounce and singleton key decide when it runs. A remembered fact points back to the stored user message.
This commit is contained in:
1 parent
f46e0960fb
commit
de5b315999
10 files changed
+176
-53
No files matched your search
+123
-27
@@ -19,6 +19,9 @@ exports[`coach chat golden transcripts > 01a tool mode, two rounds, present data
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -50,7 +53,7 @@ exports[`coach chat golden transcripts > 01a tool mode, two rounds, present data
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -265,6 +268,9 @@ exports[`coach chat golden transcripts > 01b tool mode, present data, one figure
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -296,7 +302,7 @@ exports[`coach chat golden transcripts > 01b tool mode, present data, one figure
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -523,6 +529,9 @@ exports[`coach chat golden transcripts > 02 tool mode, every tool missed, fabric
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -554,7 +563,7 @@ exports[`coach chat golden transcripts > 02 tool mode, every tool missed, fabric
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -889,6 +898,9 @@ exports[`coach chat golden transcripts > 03 no-tools path with the full snapshot
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -1339,6 +1351,9 @@ exports[`coach chat golden transcripts > 06 budget exceeded 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -1390,6 +1405,9 @@ exports[`coach chat golden transcripts > 07a all providers failed (plain) 1`] =
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -1421,7 +1439,7 @@ exports[`coach chat golden transcripts > 07a all providers failed (plain) 1`] =
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -1479,6 +1497,9 @@ exports[`coach chat golden transcripts > 07b all providers failed (every hop rat
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -1510,7 +1531,7 @@ exports[`coach chat golden transcripts > 07b all providers failed (every hop rat
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -1568,6 +1589,9 @@ exports[`coach chat golden transcripts > 07c all providers failed (primary crede
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -1599,7 +1623,7 @@ exports[`coach chat golden transcripts > 07c all providers failed (primary crede
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -1657,6 +1681,9 @@ exports[`coach chat golden transcripts > 08 an unwrapped tagged provider error 1
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -1688,7 +1715,7 @@ exports[`coach chat golden transcripts > 08 an unwrapped tagged provider error 1
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -1747,6 +1774,9 @@ exports[`coach chat golden transcripts > 09 an aborted request leaves a cancelle
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -1778,7 +1808,7 @@ exports[`coach chat golden transcripts > 09 an aborted request leaves a cancelle
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -1843,6 +1873,9 @@ exports[`coach chat golden transcripts > 10 outbound block replaces the reply an
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -1874,7 +1907,7 @@ exports[`coach chat golden transcripts > 10 outbound block replaces the reply an
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -2219,6 +2252,9 @@ exports[`coach chat golden transcripts > 11a KEYVALUES valid 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -2250,7 +2286,7 @@ exports[`coach chat golden transcripts > 11a KEYVALUES valid 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -2469,6 +2505,9 @@ exports[`coach chat golden transcripts > 11b KEYVALUES partial 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -2500,7 +2539,7 @@ exports[`coach chat golden transcripts > 11b KEYVALUES partial 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -2717,6 +2756,9 @@ exports[`coach chat golden transcripts > 11c KEYVALUES malformed (no closing mar
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -2748,7 +2790,7 @@ exports[`coach chat golden transcripts > 11c KEYVALUES malformed (no closing mar
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -2949,6 +2991,9 @@ exports[`coach chat golden transcripts > 11d sentinel-only reply is an empty rep
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -2980,7 +3025,7 @@ exports[`coach chat golden transcripts > 11d sentinel-only reply is an empty rep
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -3049,6 +3094,9 @@ exports[`coach chat golden transcripts > 11e empty provider reply 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -3080,7 +3128,7 @@ exports[`coach chat golden transcripts > 11e empty provider reply 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -3140,6 +3188,9 @@ exports[`coach chat golden transcripts > 12a SUGGEST-REMINDER surfaced 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -3171,7 +3222,7 @@ exports[`coach chat golden transcripts > 12a SUGGEST-REMINDER surfaced 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -3410,6 +3461,9 @@ exports[`coach chat golden transcripts > 12b SUGGEST-REMINDER suppressed 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -3441,7 +3495,7 @@ exports[`coach chat golden transcripts > 12b SUGGEST-REMINDER suppressed 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -3644,6 +3698,9 @@ exports[`coach chat golden transcripts > 13 SUGGEST-ACTION 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -3675,7 +3732,7 @@ exports[`coach chat golden transcripts > 13 SUGGEST-ACTION 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -3918,6 +3975,9 @@ exports[`coach chat golden transcripts > 14a REMEMBER valid 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -3949,7 +4009,7 @@ exports[`coach chat golden transcripts > 14a REMEMBER valid 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -4172,6 +4232,9 @@ exports[`coach chat golden transcripts > 14b REMEMBER malformed 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -4203,7 +4266,7 @@ exports[`coach chat golden transcripts > 14b REMEMBER malformed 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -4421,6 +4484,9 @@ exports[`coach chat golden transcripts > 15 an unknown learn link is scrubbed, a
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -4452,7 +4518,7 @@ exports[`coach chat golden transcripts > 15 an unknown learn link is scrubbed, a
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -4668,6 +4734,9 @@ exports[`coach chat golden transcripts > 16a coach.provider.none via an empty ch
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "annotate",
|
||||
"metaKeys": [],
|
||||
@@ -4707,6 +4776,9 @@ exports[`coach chat golden transcripts > 16b an empty chain served by the legacy
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -5064,6 +5136,9 @@ exports[`coach chat golden transcripts > 16d coach.provider.none from the capabi
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -5109,6 +5184,9 @@ exports[`coach chat golden transcripts > 17a a workout-scoped first turn 1`] = `
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "isModuleEnabled",
|
||||
"module": "workouts",
|
||||
@@ -5153,7 +5231,7 @@ exports[`coach chat golden transcripts > 17a a workout-scoped first turn 1`] = `
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -5368,6 +5446,9 @@ exports[`coach chat golden transcripts > 17b a workout-scoped first turn with th
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "annotate",
|
||||
"metaKeys": [
|
||||
@@ -5408,7 +5489,7 @@ exports[`coach chat golden transcripts > 17b a workout-scoped first turn with th
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -5611,6 +5692,9 @@ exports[`coach chat golden transcripts > 18 a persistence throw after the provid
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -5642,7 +5726,7 @@ exports[`coach chat golden transcripts > 18 a persistence throw after the provid
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -5757,7 +5841,7 @@ exports[`coach chat golden transcripts > 19 an existing conversation with prior
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -5984,6 +6068,9 @@ exports[`coach chat golden transcripts > 20 a guided-question turn with a scope
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -6015,7 +6102,7 @@ exports[`coach chat golden transcripts > 20 a guided-question turn with a scope
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 30000,
|
||||
"tools": 6,
|
||||
@@ -6198,6 +6285,9 @@ exports[`coach chat golden transcripts > 21 the German locale with a stored self
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -6229,7 +6319,7 @@ exports[`coach chat golden transcripts > 21 the German locale with a stored self
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "ea823e5e510a:4068",
|
||||
"system": "7c188ee61f98:5016",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -6448,6 +6538,9 @@ exports[`coach chat golden transcripts > 22 tool mode with live steps: found, em
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
{
|
||||
"call": "assertConsentForChain",
|
||||
"chain": [
|
||||
@@ -6479,7 +6572,7 @@ exports[`coach chat golden transcripts > 22 tool mode with live steps: found, em
|
||||
"window": "last30days",
|
||||
},
|
||||
"signal": true,
|
||||
"system": "d46e2a89426f:3975",
|
||||
"system": "37f58b1a7608:4923",
|
||||
"temperature": 0.4,
|
||||
"timeoutMs": 180000,
|
||||
"tools": 6,
|
||||
@@ -7064,6 +7157,9 @@ exports[`coach chat golden transcripts — refusals before the stream > R6 conse
|
||||
{
|
||||
"call": "storeDeterministicFacts",
|
||||
},
|
||||
{
|
||||
"call": "enqueueCoachMemoryRefresh",
|
||||
},
|
||||
],
|
||||
"contentType": null,
|
||||
"frames": [],
|
||||
|
||||
@@ -31,6 +31,8 @@ import {
|
||||
import {
|
||||
PLAN_REVIEW_DAYS,
|
||||
REMEMBER_FACT_MAX_CHARS,
|
||||
} from "@/lib/ai/coach/memory/shared";
|
||||
import {
|
||||
proposePlanFromTool,
|
||||
rememberFactFromTool,
|
||||
} from "@/lib/ai/coach/memory/contract";
|
||||
@@ -200,6 +202,8 @@ export interface DialogToolContext {
|
||||
locale: Locale;
|
||||
/** The person's current message: the only text a fact may come from. */
|
||||
userMessage: string;
|
||||
/** The stored id of that message, which a remembered fact points back to. */
|
||||
userMessageId?: string;
|
||||
/** What the record holds; null on the no-tools path. */
|
||||
inventory: InventoryEntry[] | null;
|
||||
/**
|
||||
@@ -319,6 +323,7 @@ export async function runDialogTool(args: {
|
||||
userId: ctx.userId,
|
||||
conversationId: ctx.conversationId,
|
||||
userMessage: ctx.userMessage,
|
||||
...(ctx.userMessageId ? { userMessageId: ctx.userMessageId } : {}),
|
||||
call: parsed.data,
|
||||
});
|
||||
if (outcome.kind === "declined") {
|
||||
|
||||
@@ -228,6 +228,12 @@ export async function runCoachToolLoop(args: {
|
||||
locale?: Locale;
|
||||
/** v1.41 — what the dialog tools need. Absent: they are declined. */
|
||||
dialog?: DialogToolContext;
|
||||
/**
|
||||
* v1.41 — a note the answer already carries before any round (a health
|
||||
* fact the background found, offered once). It is the answer's one note:
|
||||
* `remember_fact` is declined beside it.
|
||||
*/
|
||||
initialMemoryNote?: CoachMemoryNote;
|
||||
/** v1.41 — the figures read so far, for screening a checkpoint. */
|
||||
checkpointScreen?: { userMessage: string };
|
||||
}): Promise<CoachToolLoopResult> {
|
||||
@@ -276,7 +282,7 @@ export async function runCoachToolLoop(args: {
|
||||
const toolTrace: CoachToolTrace[] = [];
|
||||
const toolResults: CoachToolResult[] = [];
|
||||
const declinedClarifications: CoachClarification[] = [];
|
||||
let memoryNote: CoachMemoryNote | undefined;
|
||||
let memoryNote: CoachMemoryNote | undefined = args.initialMemoryNote;
|
||||
let planProposal: CoachPlanProposal | undefined;
|
||||
let callCount = 0;
|
||||
let stopReason: CoachStopReason | null = null;
|
||||
|
||||
@@ -131,6 +131,7 @@ function persistedProvenance(): CoachProvenance {
|
||||
|
||||
beforeEach(() => {
|
||||
for (const fn of Object.values(m)) fn.mockReset();
|
||||
m.persistUserTurn.mockResolvedValue({ messageId: "m-user" });
|
||||
m.resolveTurnConversation.mockResolvedValue({
|
||||
conversation: {
|
||||
conversationId: "c1",
|
||||
|
||||
@@ -238,6 +238,7 @@ function modelPath(prefs = DEFAULT_COACH_PREFS) {
|
||||
|
||||
beforeEach(() => {
|
||||
for (const fn of Object.values(m)) fn.mockReset();
|
||||
m.persistUserTurn.mockResolvedValue({ messageId: "m-user" });
|
||||
m.readFollowUpHistory.mockResolvedValue({
|
||||
today: "2026-09-27",
|
||||
firstDate: { bp: "2024-01-01" },
|
||||
|
||||
@@ -177,18 +177,19 @@ export async function assembleTurnContext(args: {
|
||||
// Fact capture must never break the chat turn; the >TURN_CAP LLM
|
||||
// extraction remains as the catch-all on long conversations.
|
||||
});
|
||||
if (turnContext.historyElided) {
|
||||
void enqueueCoachMemoryRefresh({
|
||||
conversationId,
|
||||
userId,
|
||||
// Coach memory prose is composed in de/en only — it is MODEL-FACING
|
||||
// context (a rolling conversation summary + extracted durable facts),
|
||||
// not user-facing prose, so English is the correct target for every
|
||||
// locale without a reviewed body. The former `=== "en" ? "en" : "de"`
|
||||
// binary composed and keyed a French account's memory in German.
|
||||
locale: instructionLocale(locale),
|
||||
});
|
||||
}
|
||||
// v1.41 — every turn enqueues the refresh; the job waits for the
|
||||
// conversation to go quiet and runs once per conversation (its debounce
|
||||
// and singleton key), so a short chat is remembered too.
|
||||
void enqueueCoachMemoryRefresh({
|
||||
conversationId,
|
||||
userId,
|
||||
// Coach memory prose is composed in de/en only — it is MODEL-FACING
|
||||
// context (a rolling conversation summary + extracted durable facts),
|
||||
// not user-facing prose, so English is the correct target for every
|
||||
// locale without a reviewed body. The former `=== "en" ? "en" : "de"`
|
||||
// binary composed and keyed a French account's memory in German.
|
||||
locale: instructionLocale(locale),
|
||||
});
|
||||
|
||||
// A workout launch is an optional narrowing of Coach, not permission to
|
||||
// bypass the workouts module. Disabled modules contribute no read and no
|
||||
|
||||
@@ -163,10 +163,12 @@ export async function resolveTurnConversation(args: {
|
||||
export async function persistUserTurn(
|
||||
conversationId: string,
|
||||
message: string,
|
||||
): Promise<void> {
|
||||
await appendMessage({
|
||||
): Promise<{ messageId: string }> {
|
||||
const stored = await appendMessage({
|
||||
conversationId,
|
||||
role: "user",
|
||||
content: message,
|
||||
});
|
||||
// v1.41 — the id a remembered fact points back to.
|
||||
return { messageId: stored.id };
|
||||
}
|
||||
@@ -282,6 +282,8 @@ export async function runTurnModel(args: {
|
||||
priorResults?: PriorResultTurn[];
|
||||
/** v1.41 — the person's message, the only source of a remembered fact. */
|
||||
message: string;
|
||||
/** v1.41 — that message's stored id. */
|
||||
userMessageId?: string;
|
||||
/** v1.41 — the reasoning the turn asks for, already resolved. */
|
||||
reasoning?: TurnReasoning;
|
||||
/** v1.41 — who pays: fixes the turn's budget. */
|
||||
@@ -333,8 +335,13 @@ export async function runTurnModel(args: {
|
||||
userId,
|
||||
conversationId,
|
||||
locale,
|
||||
// The block re-runs the wire egress check for exactly these.
|
||||
providerTypes: chain.map((entry) => entry.providerType),
|
||||
}).catch(() => null);
|
||||
if (memory) {
|
||||
recorder.setRecalled(memory.recalled);
|
||||
}
|
||||
if (memory && memory.factIds.length + memory.planIds.length > 0) {
|
||||
const count = memory.factIds.length + memory.planIds.length;
|
||||
const id = activity.start({
|
||||
phase: "memory",
|
||||
@@ -365,12 +372,8 @@ export async function runTurnModel(args: {
|
||||
reach: ctx.reach,
|
||||
prior: args.priorResults ?? [],
|
||||
});
|
||||
const requestWith = (tableRules: boolean) => {
|
||||
// `memoryBlock` is the memory package's parameter; held in a
|
||||
// variable so the request builds whether or not it is declared yet.
|
||||
const request: Parameters<typeof buildCoachToolRequest>[0] & {
|
||||
memoryBlock?: string;
|
||||
} = {
|
||||
const requestWith = (tableRules: boolean) =>
|
||||
buildCoachToolRequest({
|
||||
systemPrompt: ctx.systemPrompt,
|
||||
toolModeAddendum: appendBlocks(buildToolModeAddendum(locale), [
|
||||
buildDialogAddenda(locale, { tableRules }),
|
||||
@@ -384,9 +387,7 @@ export async function runTurnModel(args: {
|
||||
transcript: turnContext.transcript,
|
||||
languageName: LANGUAGE_NAMES[locale],
|
||||
...(memory ? { memoryBlock: memory.text } : {}),
|
||||
};
|
||||
return buildCoachToolRequest(request);
|
||||
};
|
||||
});
|
||||
// The recheck and follow-up rules are about tables: they ride the
|
||||
// prompt once the conversation holds one, or from the round after this
|
||||
// turn produced its first.
|
||||
@@ -445,11 +446,15 @@ export async function runTurnModel(args: {
|
||||
...(args.reasoning ? { reasoning: args.reasoning } : {}),
|
||||
activity,
|
||||
locale,
|
||||
...(memory?.pendingProposal
|
||||
? { initialMemoryNote: memory.pendingProposal }
|
||||
: {}),
|
||||
dialog: {
|
||||
userId,
|
||||
conversationId,
|
||||
locale,
|
||||
userMessage: args.message,
|
||||
...(args.userMessageId ? { userMessageId: args.userMessageId } : {}),
|
||||
inventory: inventory.entries,
|
||||
conversationWindowSet: args.conversationWindowSet,
|
||||
},
|
||||
@@ -698,7 +703,7 @@ export async function runTurnModel(args: {
|
||||
activity: recorder,
|
||||
toolClarification: null,
|
||||
declinedClarifications: [],
|
||||
memoryNote: null,
|
||||
memoryNote: memory?.pendingProposal ?? null,
|
||||
planProposal: null,
|
||||
interimSent: false,
|
||||
};
|
||||
|
||||
@@ -149,7 +149,10 @@ async function runTurn(
|
||||
...(clarifiedLine ? [clarifiedLine] : []),
|
||||
];
|
||||
|
||||
await persistUserTurn(workingConversationId, message);
|
||||
const { messageId: userMessageId } = await persistUserTurn(
|
||||
workingConversationId,
|
||||
message,
|
||||
);
|
||||
|
||||
const ctx = await assembleTurnContext({
|
||||
userId,
|
||||
@@ -219,6 +222,7 @@ async function runTurn(
|
||||
turnHints,
|
||||
priorResults: conversation.priorResults,
|
||||
message,
|
||||
userMessageId,
|
||||
reasoning,
|
||||
payer,
|
||||
conversationWindowSet: input.scope?.window !== undefined,
|
||||
|
||||
@@ -49,6 +49,8 @@ import { createSseStream } from "@/lib/sse/create-stream";
|
||||
import {
|
||||
COACH_MEMORY_KEYS,
|
||||
COACH_PLAN_KEYS,
|
||||
} from "@/lib/ai/coach/memory/shared";
|
||||
import {
|
||||
decideFactProposal,
|
||||
decidePlanProposal,
|
||||
} from "@/lib/ai/coach/memory/contract";
|
||||
|
||||
Reference in new issue
Block a user