mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
fix(coach): hold restored dialog ids to the shapes the server mints
Table refs, step ids, chip ids, a chip's anchor ref, clarification choice ids and a reused table's source are now validated against their exact server-minted patterns when a stored reply is read back. Some of them are written into the model's context on a later turn (the earlier-tables list, the "keep looking" fetched list), so a stored row edited by hand can no longer carry text into a prompt through them.
This commit is contained in:
1 parent
d6ac4acad2
commit
6a458ac5b0
2 files changed
+36
-9
No files matched your search
@@ -50492,6 +50492,7 @@ components:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
pattern: ^s[1-9]\d{0,2}$
|
||||
description: "`s1`..`s12`, unique within a turn."
|
||||
tool:
|
||||
type: string
|
||||
@@ -50560,6 +50561,7 @@ components:
|
||||
resultRef:
|
||||
description: The table this step produced (`r1`..), when it produced one.
|
||||
type: string
|
||||
pattern: ^r[1-6]$
|
||||
required:
|
||||
- id
|
||||
- tool
|
||||
@@ -50685,6 +50687,7 @@ components:
|
||||
properties:
|
||||
ref:
|
||||
type: string
|
||||
pattern: ^r[1-6]$
|
||||
description: "`r1`..`r6`, unique within a message."
|
||||
source:
|
||||
type: object
|
||||
@@ -50764,8 +50767,10 @@ components:
|
||||
properties:
|
||||
messageId:
|
||||
type: string
|
||||
pattern: ^[A-Za-z0-9_-]{1,64}$
|
||||
ref:
|
||||
type: string
|
||||
pattern: ^r[1-6]$
|
||||
required:
|
||||
- messageId
|
||||
- ref
|
||||
@@ -50787,6 +50792,7 @@ components:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
pattern: ^f[1-3]$
|
||||
description: "`f1`..`f3`."
|
||||
kind:
|
||||
type: string
|
||||
@@ -50808,6 +50814,7 @@ components:
|
||||
properties:
|
||||
ref:
|
||||
type: string
|
||||
pattern: ^(?:r[1-6])?$
|
||||
domain:
|
||||
$ref: "#/components/schemas/CoachStepDomain"
|
||||
window:
|
||||
@@ -50868,6 +50875,7 @@ components:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
pattern: ^c[1-4]$
|
||||
labelKey:
|
||||
type: string
|
||||
label:
|
||||
@@ -50978,6 +50986,7 @@ components:
|
||||
properties:
|
||||
ref:
|
||||
type: string
|
||||
pattern: ^r[1-6]$
|
||||
description: "`r1`..`r6`, unique within a message."
|
||||
source:
|
||||
type: object
|
||||
@@ -51057,8 +51066,10 @@ components:
|
||||
properties:
|
||||
messageId:
|
||||
type: string
|
||||
pattern: ^[A-Za-z0-9_-]{1,64}$
|
||||
ref:
|
||||
type: string
|
||||
pattern: ^r[1-6]$
|
||||
required:
|
||||
- messageId
|
||||
- ref
|
||||
@@ -51231,6 +51242,7 @@ components:
|
||||
properties:
|
||||
ref:
|
||||
type: string
|
||||
pattern: ^r[1-6]$
|
||||
withheld:
|
||||
type: string
|
||||
enum:
|
||||
|
||||
@@ -51,11 +51,23 @@ export const coachStepDomainSchema = z
|
||||
const coachResultGranularitySchema = z.enum(["day", "week", "month"]);
|
||||
const coachResultPeriodSchema = z.enum(["current", "previous", "yearAgo"]);
|
||||
|
||||
// The ids and names below are restored from stored provenance and some of
|
||||
// them are written back into the model's context (`m<k>.r<n>` lines, the
|
||||
// "keep looking" fetched list). Each is held to its exact server-minted
|
||||
// shape, so a stored row edited by hand cannot carry text into a prompt.
|
||||
/** A table of a message: `r1`..`r6`. */
|
||||
const resultRefSchema = z.string().regex(/^r[1-6]$/);
|
||||
/** A server-minted row id (cuid). */
|
||||
const messageIdSchema = z.string().regex(/^[A-Za-z0-9_-]{1,64}$/);
|
||||
|
||||
// ── Steps ─────────────────────────────────────────────────────────────────
|
||||
|
||||
export const coachStepSchema = z
|
||||
.object({
|
||||
id: z.string().describe("`s1`..`s12`, unique within a turn."),
|
||||
id: z
|
||||
.string()
|
||||
.regex(/^s[1-9]\d{0,2}$/)
|
||||
.describe("`s1`..`s12`, unique within a turn."),
|
||||
tool: z.enum([...COACH_TOOL_NAMES, "show_result", "snapshot"]),
|
||||
labelKey: z
|
||||
.string()
|
||||
@@ -84,8 +96,7 @@ export const coachStepSchema = z
|
||||
"invalid_arguments",
|
||||
])
|
||||
.optional(),
|
||||
resultRef: z
|
||||
.string()
|
||||
resultRef: resultRefSchema
|
||||
.optional()
|
||||
.describe("The table this step produced (`r1`..), when it produced one."),
|
||||
})
|
||||
@@ -140,7 +151,7 @@ const coachResultSourceSchema = z.object({
|
||||
});
|
||||
|
||||
const coachResultMetaShape = {
|
||||
ref: z.string().describe("`r1`..`r6`, unique within a message."),
|
||||
ref: resultRefSchema.describe("`r1`..`r6`, unique within a message."),
|
||||
source: coachResultSourceSchema,
|
||||
shape: z.enum(["timeSeries", "categoryCounts", "distribution", "single"]),
|
||||
titleKey: z.string(),
|
||||
@@ -153,7 +164,7 @@ const coachResultMetaShape = {
|
||||
"True when the answer referenced the table (shown expanded); false when it sits under the data-used disclosure.",
|
||||
),
|
||||
reusedFrom: z
|
||||
.object({ messageId: z.string(), ref: z.string() })
|
||||
.object({ messageId: messageIdSchema, ref: resultRefSchema })
|
||||
.optional()
|
||||
.describe("Set when the table was copied from an earlier message."),
|
||||
};
|
||||
@@ -185,7 +196,7 @@ export const coachResultTableSchema = z
|
||||
});
|
||||
|
||||
const coachResultWithheldSchema = z.object({
|
||||
ref: z.string(),
|
||||
ref: resultRefSchema,
|
||||
withheld: z
|
||||
.enum(["module_disabled", "unavailable"])
|
||||
.describe(
|
||||
@@ -232,7 +243,10 @@ export const coachMethodSchema = z
|
||||
|
||||
export const coachFollowUpSchema = z
|
||||
.object({
|
||||
id: z.string().describe("`f1`..`f3`."),
|
||||
id: z
|
||||
.string()
|
||||
.regex(/^f[1-3]$/)
|
||||
.describe("`f1`..`f3`."),
|
||||
kind: z.enum([
|
||||
"widen_window",
|
||||
"previous_period",
|
||||
@@ -248,7 +262,8 @@ export const coachFollowUpSchema = z
|
||||
.describe("Rendered on the server from a catalog; never model text."),
|
||||
anchor: z
|
||||
.object({
|
||||
ref: z.string(),
|
||||
// Empty for a related metric read without a table of its own.
|
||||
ref: z.string().regex(/^(?:r[1-6])?$/),
|
||||
domain: coachStepDomainSchema,
|
||||
window: coachWindowEnum.optional(),
|
||||
granularity: coachResultGranularitySchema.optional(),
|
||||
@@ -276,7 +291,7 @@ export const coachClarificationSchema = z
|
||||
choices: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
id: z.string().regex(/^c[1-4]$/),
|
||||
labelKey: z.string(),
|
||||
label: z.string(),
|
||||
value: z.object({
|
||||
|
||||
Reference in new issue
Block a user