chore(coach): publish the trail route, list it among the mixed reads, and ship its strings in every locale

This commit is contained in:
Marc-André Bombeck committed 2026-10-06 19:53:43 +02:00
1 parent 2f5877cf97
commit 8e7fd0b873
12 files changed
+248 -61

No files matched your search

@@ -102,6 +102,11 @@ export const AI_ROUTES: Readonly<Record<string, AiRouteEntry>> = {
capabilities: ["coach"],
why: "POST streams a Coach reply from a model. The history GET in the same file asks nothing.",
},
"src/app/api/insights/chat/[id]/messages/[messageId]/trail/route.ts": {
kind: "mixed",
capabilities: ["coach"],
why: "The trail's reasoning text is model-written and served only while the Coach's text may be shown; otherwise 200 with trail null and the ai state.",
},
"src/app/api/insights/generate/route.ts": {
kind: "action",
capabilities: ["briefing"],
+1 -1
View File
@@ -21,7 +21,7 @@ import {
import {
PLAN_REVIEW_DAYS,
REMEMBER_FACT_MAX_CHARS,
} from "@/lib/ai/coach/memory/contract";
} from "@/lib/ai/coach/memory/shared";
import {
SUGGESTED_ACTION_TYPES,
type CheckupIntervalId,
+49
View File
@@ -44,6 +44,7 @@ import {
coachProvenanceSchema,
coachResultEntrySchema,
coachStreamEventSchema,
coachTrailSchema,
} from "@/lib/ai/coach/stream-events";
import {
coachAttachmentCreateSchema,
@@ -870,6 +871,54 @@ export const coachPaths: NonNullable<ZodOpenApiObject["paths"]> = {
},
},
},
"/api/insights/chat/{id}/messages/{messageId}/trail": {
get: {
tags: ["Insights"],
summary: "Read the trail text of one Coach message",
description:
"v1.41 — the model-written text of one assistant message's trail: the screened reasoning titles and summaries by trail entry, the fact texts the turn recalled, and a pending fact proposal. The trail's structure (phases, statuses, counts) is plaintext on the message's `metricSource.activity`; this route serves only the text, decrypted for the account that owns the conversation. Fetch lazily when the person opens the trail. A mixed read: while the Coach's text may not be shown for the record, the answer is 200 with `trail: null` and the `ai` state beside it. A foreign or unknown conversation or message id maps to 404 (never 403). Auth via cookie or a full-access Bearer token.",
parameters: [
{
name: "id",
in: "path",
required: true,
schema: { type: "string" },
description: "Conversation id.",
},
{
name: "messageId",
in: "path",
required: true,
schema: { type: "string" },
description: "Assistant message id within the conversation.",
},
],
responses: {
"200": {
description: "The trail text, or null while it may not be served.",
content: {
"application/json": {
schema: dataEnvelope(
z.object({
trail: coachTrailSchema.nullable(),
ai: aiCapabilityState.describe(
"The `coach` capability. While unavailable `trail` is null.",
),
}),
"CoachMessageTrailResponse",
),
},
},
},
"404": {
description:
"Conversation or message not found, or not owned by the caller.",
content: { "application/json": { schema: errorEnvelope } },
},
...stdResponses,
},
},
},
"/api/insights/chat/{id}": {
get: {
tags: ["Insights"],