mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 06:06:10 +00:00
Merge branch 'v143/ai' into release/v1.43.0
# Conflicts: # docs/api/openapi.yaml # messages/de.json # messages/en.json # messages/es.json # messages/fr.json # messages/it.json # messages/ko.json # messages/pl.json # src/__tests__/contract-stub-inventory.test.ts
This commit is contained in:
commit
fd44a8381b
143 files changed
+4806
-628
No files matched your search
@@ -43,7 +43,10 @@ export const ERROR_CODE_CATALOGUE: Readonly<Record<string, readonly string[]>> =
|
||||
"ai.provider.none",
|
||||
"ai.record.notPermitted",
|
||||
"ai.unavailable",
|
||||
"ai.usage.aboveCeiling",
|
||||
"ai.usage.defaultAboveCeiling",
|
||||
"ai.usage.invalid",
|
||||
"ai.usage.levelTooLow",
|
||||
"ai.usage.rateLimited",
|
||||
],
|
||||
ai_provider: ["ai_provider.invalid", "ai_provider.no_fields"],
|
||||
|
||||
@@ -11,12 +11,7 @@ import { z } from "zod/v4";
|
||||
|
||||
import { AI_USAGE_LEVELS, aiUsagePutSchema } from "@/lib/validations/ai-usage";
|
||||
|
||||
import {
|
||||
dataEnvelope,
|
||||
errorEnvelope,
|
||||
notImplementedResponse,
|
||||
stdResponses,
|
||||
} from "./shared";
|
||||
import { dataEnvelope, errorEnvelope, stdResponses } from "./shared";
|
||||
|
||||
export const aiUsageLevel = z.enum(AI_USAGE_LEVELS).meta({
|
||||
id: "AiUsageLevel",
|
||||
@@ -111,7 +106,6 @@ export const aiUsagePaths: NonNullable<ZodOpenApiObject["paths"]> = {
|
||||
"`ai.usage.invalid` (body) or `ai.usage.aboveCeiling` (`meta.maxLevel` names the ceiling).",
|
||||
content: { "application/json": { schema: errorEnvelope } },
|
||||
},
|
||||
...notImplementedResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -129,7 +129,7 @@ export const moduleAccessMap = z
|
||||
export const aiUnavailableReason = z.enum(AI_UNAVAILABLE_REASONS).meta({
|
||||
id: "AiUnavailableReason",
|
||||
description:
|
||||
"Why an AI capability is unavailable, listed in precedence order; only the outermost reason that applies is reported, because it names the layer that would have to change first. `check_failed` — an input could not be read and the answer failed closed. `operator_disabled` — the operator's master switch, the capability's own switch, or the operator's instance-wide availability of its module. `not_permitted_for_record` — AI work is not admitted for this record (a delegate inside somebody else's record). `module_disabled` — an owning module is off for this record, by its own switch or by the edge of the active grant. `user_disabled` — the record's own AI opt-out: the Coach preference for the Coach, the `insights` module (AI analysis) for everything else. `no_provider` — no configured provider can serve this capability's input. `consent_required` — the provider chain needs an AI consent receipt and none is active. The list is closed; a client that meets a value it does not know treats the capability as unavailable.",
|
||||
"Why an AI capability is unavailable, listed in precedence order; only the outermost reason that applies is reported, because it names the layer that would have to change first. `check_failed` — an input could not be read and the answer failed closed. `operator_disabled` — the operator's master switch, the capability's own switch, or the operator's instance-wide availability of its module. `not_permitted_for_record` — AI work is not admitted for this record (a delegate inside somebody else's record). `module_disabled` — an owning module is off for this record, by its own switch or by the edge of the active grant. `user_disabled` — the record's own AI opt-out: the Coach preference for the Coach, the `insights` module (AI analysis) for everything else. `usage_level` — the record's AI usage level (`ai.usage.level`, v1.43) is below what the capability needs; today only `supplementLabel` on `frugal`. `no_provider` — no configured provider can serve this capability's input. `consent_required` — the provider chain needs an AI consent receipt and none is active. The list is closed; a client that meets a value it does not know treats the capability as unavailable.",
|
||||
});
|
||||
|
||||
export const aiCapabilityState = z
|
||||
@@ -141,7 +141,7 @@ export const aiCapabilityState = z
|
||||
onDeviceAllowed: z
|
||||
.boolean()
|
||||
.describe(
|
||||
"Whether an on-device model may do this work. False for `operator_disabled`, `not_permitted_for_record`, `module_disabled`, `user_disabled` and `check_failed`: the operator's and the person's decisions hold on the device too. True otherwise, since a missing server provider or a missing consent for server egress do not concern a model that runs on the device. Resolved here so the client never decides which reasons apply off the server.",
|
||||
"Whether an on-device model may do this work. False for `operator_disabled`, `not_permitted_for_record`, `module_disabled`, `user_disabled`, `usage_level` and `check_failed`: the operator's and the person's decisions hold on the device too. True otherwise, since a missing server provider or a missing consent for server egress do not concern a model that runs on the device. Resolved here so the client never decides which reasons apply off the server.",
|
||||
),
|
||||
})
|
||||
.meta({
|
||||
@@ -164,7 +164,7 @@ export const aiCapabilities = z
|
||||
.meta({
|
||||
id: "AiCapabilities",
|
||||
description:
|
||||
"Every AI capability, always all present. `coach` — chat, fenced document chat, attachments, Coach memory upkeep, AI nudges, every Coach launcher. `briefing` — the daily briefing and every place its text is lifted into. `periodNarrative` — the model-written half of a period narrative (the deterministic narrative is data). `statusText` — per-metric status notes and the AI override of a derived assessment. `workoutInsights` — the paragraph on a workout. `reactionLines` — the line written after a new reading. `aboutMeQuestions` — model-written follow-up questions on the about-me profile (a deterministic set stays). `documentAi` — suggest, summary, extract, index and chat over a stored document. `labsOcr` — reading a lab report image. `medicationExtract` — turning a typed medication description into a schedule.",
|
||||
"Every AI capability, always all present. `coach` — chat, fenced document chat, attachments, Coach memory upkeep, AI nudges, every Coach launcher. `briefing` — the daily briefing and every place its text is lifted into. `periodNarrative` — the model-written half of a period narrative (the deterministic narrative is data). `statusText` — per-metric status notes and the AI override of a derived assessment. `workoutInsights` — the paragraph on a workout. `reactionLines` — the line written after a new reading. `aboutMeQuestions` — model-written follow-up questions on the about-me profile (a deterministic set stays). `documentAi` — suggest, summary, extract, index and chat over a stored document. `labsOcr` — reading a lab report image. `medicationExtract` — turning a typed medication description into a schedule. `supplementLabel` (v1.43) — reading a supplement's label photo into its ingredients; unavailable on the `frugal` usage level.",
|
||||
});
|
||||
|
||||
export const aiProviderState = z
|
||||
|
||||
@@ -91,13 +91,13 @@ export const errorEnvelope = z
|
||||
.string()
|
||||
.optional()
|
||||
.describe(
|
||||
"On an AI refusal: the capability that is unavailable, one of the keys of `AiCapabilities` (`coach`, `briefing`, `periodNarrative`, `statusText`, `workoutInsights`, `reactionLines`, `aboutMeQuestions`, `documentAi`, `labsOcr`, `medicationExtract`).",
|
||||
"On an AI refusal: the capability that is unavailable, one of the keys of `AiCapabilities` (`coach`, `briefing`, `periodNarrative`, `statusText`, `workoutInsights`, `reactionLines`, `aboutMeQuestions`, `documentAi`, `labsOcr`, `medicationExtract`, `supplementLabel`).",
|
||||
),
|
||||
reason: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe(
|
||||
"On an AI refusal: the outermost reason, one of `AiUnavailableReason`. The code maps from it: `operator_disabled` → `assistant.disabled.<switch>` (or `module.disabled` with `module` when the operator's module availability closed it), `not_permitted_for_record` → `ai.record.notPermitted`, `module_disabled` and `user_disabled` → `module.disabled` with `module`, `no_provider` → the route's own typed code where it has one, otherwise `ai.provider.none` (422), `consent_required` → `consent.ai.required`, `check_failed` → `ai.unavailable` (503).",
|
||||
"On an AI refusal: the outermost reason, one of `AiUnavailableReason`. The code maps from it: `operator_disabled` → `assistant.disabled.<switch>` (or `module.disabled` with `module` when the operator's module availability closed it), `not_permitted_for_record` → `ai.record.notPermitted`, `module_disabled` and `user_disabled` → `module.disabled` with `module`, `no_provider` → the route's own typed code where it has one, otherwise `ai.provider.none` (422), `usage_level` → `ai.usage.levelTooLow` with `requiredLevel`, `consent_required` → `consent.ai.required`, `check_failed` → `ai.unavailable` (503).",
|
||||
),
|
||||
module: z
|
||||
.string()
|
||||
@@ -105,6 +105,12 @@ export const errorEnvelope = z
|
||||
.describe(
|
||||
"Beside `module.disabled`: the module that is off. On an AI refusal it is the capability's owning module.",
|
||||
),
|
||||
requiredLevel: z
|
||||
.enum(["frugal", "standard", "full"])
|
||||
.optional()
|
||||
.describe(
|
||||
"Beside `ai.usage.levelTooLow` (v1.43): the lowest AI usage level at which the capability is offered.",
|
||||
),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user