feat: enforce commercial Jyotish workflow contracts

This commit is contained in:
732642856
2026-07-19 09:00:14 +08:00
parent 3d6d498892
commit 8b608781c9
14 changed files with 470 additions and 16 deletions
+11 -1
View File
@@ -1,7 +1,9 @@
import { NextResponse } from "next/server";
import {
consultationInputSchema,
consultationWorkflowReceipt,
getJyotishAgent,
runConsultationWorkflow,
} from "@/mastra";
import {
languageModelConfigurationMessage,
@@ -167,8 +169,10 @@ export async function POST(request: Request) {
try {
const { history, name } = parsed.data;
const toolInput = consultationInputSchema.parse(parsed.data);
const workflowContext = await runConsultationWorkflow(toolInput);
const workflowReceipt = consultationWorkflowReceipt(workflowContext);
const result = await getJyotishAgent(selectedModel).stream([
const result = await getJyotishAgent(selectedModel, workflowContext).stream([
...history.map((message) => message.role === "user"
? { role: "user" as const, content: message.text }
: { role: "assistant" as const, content: message.text }),
@@ -191,6 +195,12 @@ export async function POST(request: Request) {
return streamTextResponse(result.textStream, {
mode: "mastra",
requestId,
headers: {
"x-jyotish-workflow-route": workflowReceipt.route,
"x-jyotish-workflow-status": workflowReceipt.status,
"x-jyotish-precise-timing": workflowReceipt.preciseTiming,
"x-jyotish-missing-layers": workflowReceipt.missingLayers,
},
onComplete: () => settle(completeAndRecordUsage),
onError: (_error, emitted) => settleInterrupted(emitted),
onCancel: settleInterrupted,
+11 -3
View File
@@ -1,12 +1,12 @@
"use client";
import Link from "next/link";
import dynamic from "next/dynamic";
import { ArrowUp, ArrowUpRight, Sparkles, Square, X } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import type { FormEvent, KeyboardEvent } from "react";
import { AppSidebar } from "@/components/app-sidebar";
import { BirthTimeIntakeFields } from "@/components/birth-time-intake";
import { BirthTimeRectification } from "@/components/birth-time-rectification";
import { ChatMessageContent } from "@/components/chat-message-content";
import { ModelSelector } from "@/components/model-selector";
import { Button } from "@/components/ui/button";
@@ -46,6 +46,14 @@ import {
} from "@/lib/public-models";
import { createBrowserSupabaseClient } from "@/lib/supabase/client";
const BirthTimeRectification = dynamic(
() => import("@/components/birth-time-rectification").then((module) => module.BirthTimeRectification),
{
ssr: false,
loading: () => <p className="birth-time-assistant-intent" role="status">...</p>,
},
);
type Theme = ReplyTheme;
type Message = { role: "user" | "assistant"; text: string; suggestions?: string[] };
type Profile = BirthTimeDraft & {
@@ -1165,7 +1173,7 @@ export default function Home() {
return () => {
cancelled = true;
};
}, [hydrated, profile.date, profile.time, profile.provinceCode, profile.cityCode, profileComplete]);
}, [hydrated, profile, profileComplete]);
useEffect(() => {
if (!hydrated || !profileComplete) return;
@@ -1181,7 +1189,7 @@ export default function Home() {
return () => {
cancelled = true;
};
}, [hydrated, profile.date, profile.time, profile.provinceCode, profile.cityCode, profileComplete]);
}, [hydrated, profile, profileComplete]);
useEffect(() => {
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;