mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 04:50:59 +00:00
feat(coach): expose structured snapshot sections + tool-trace provenance
The Coach snapshot builder returns the structured, post-degrade record it serialises to JSON alongside the JSON string, so a single domain block can be read out without re-parsing. Add an optional tool-call trace to the provenance envelope (which retrieval tools ran + whether each found data) and mirror it in the OpenAPI provenance schema. Groundwork for on-demand retrieval: the retrieval tools slice one section out of this record, reusing the builder's gates and I/O verbatim.
This commit is contained in:
1 parent
b07fbcb6fa
commit
ec77862286
3 files changed
+37
No files matched your search
@@ -83,6 +83,16 @@ import type {
|
||||
|
||||
export interface CoachSnapshotResult {
|
||||
snapshotJson: string;
|
||||
/**
|
||||
* v1.20.0 (F1) — the structured, post-degrade snapshot record `snapshotJson`
|
||||
* is serialised from. Keyed by domain block (`bloodPressure`, `weight`,
|
||||
* `pulse`, `mood`, `compliance`, `glucose`, `sleep`, `sleepRhythm`, `labs`,
|
||||
* `illness`, `derived`, `dayStrain`, `trajectory`, `weeklyContext`, …) plus a
|
||||
* `scope` block. The coach tool executor reads a single domain block out of
|
||||
* this so an on-demand retrieval tool returns exactly the numbers the legacy
|
||||
* snapshot-stuffing path would have shown — identical builder, gates, and I/O.
|
||||
*/
|
||||
sections: Record<string, unknown>;
|
||||
/**
|
||||
* Provenance built from snapshot keys actually present. Stays in
|
||||
* sync with the SNAPSHOT block so the source-chip row mirrors what
|
||||
@@ -2352,6 +2362,13 @@ async function buildCoachSnapshotImpl(
|
||||
|
||||
return {
|
||||
snapshotJson: JSON.stringify(compactSnapshot, null, 2),
|
||||
// v1.20.0 (F1) — the structured, post-degrade snapshot record keyed by
|
||||
// domain block (`bloodPressure`, `glucose`, `labs`, …). The coach tool
|
||||
// executor slices a single domain block out of this so a retrieval tool
|
||||
// returns exactly the numbers the legacy snapshot path would have shown —
|
||||
// same builder, same gates, same I/O. `snapshotJson` is this record
|
||||
// serialised; exposing the record avoids re-parsing it.
|
||||
sections: compactSnapshot,
|
||||
provenance: {
|
||||
windows: Array.from(windows),
|
||||
metrics: Array.from(metrics),
|
||||
|
||||
@@ -338,6 +338,15 @@ export interface CoachProvenance {
|
||||
* on a conversation reload. Absent on turns that carry no suggestion.
|
||||
*/
|
||||
suggestion?: CoachSuggestion;
|
||||
/**
|
||||
* v1.20.0 (F1) — the retrieval-tool trace for this turn: which tools the
|
||||
* Coach called and whether each found data (`present`). Metadata only — no
|
||||
* raw values beyond what `keyValues` already persists. Lets a conversation
|
||||
* reload show "what I looked at" and lets the hallucination audit replay
|
||||
* grounding. Absent on the legacy snapshot path + on turns that called no
|
||||
* tools.
|
||||
*/
|
||||
toolCalls?: ReadonlyArray<{ name: string; present: boolean }>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -277,6 +277,17 @@ const coachProvenanceSchema = z
|
||||
.describe(
|
||||
"Load-bearing numbers the assistant surfaced, rendered in the collapsible evidence block. Hard-capped at 8 entries.",
|
||||
),
|
||||
toolCalls: z
|
||||
.array(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
present: z.boolean(),
|
||||
}),
|
||||
)
|
||||
.optional()
|
||||
.describe(
|
||||
"v1.20.0 — the retrieval-tool trace for this turn: which tools the Coach called and whether each found data. Metadata only (no values). Absent on the legacy snapshot path and on turns that called no tools.",
|
||||
),
|
||||
})
|
||||
.meta({
|
||||
id: "CoachProvenance",
|
||||
|
||||
Reference in new issue
Block a user