feat(rectification): pass ayanamsa per request

This commit is contained in:
Jesse_Chen
2026-09-04 00:25:16 +08:00
parent 3b09bbbee0
commit 44d3d3931b
15 changed files with 135 additions and 16 deletions
@@ -36,5 +36,6 @@ export async function payloadFromProfile(profile: BirthRectificationProfile) {
lon,
tz,
ayanamsa: resolveAyanamsa(resolved),
node_mode: "mean",
};
}
@@ -23,6 +23,7 @@ import {
} from "./birth-time-journey-dynamic-state.ts";
import { BirthTimeJourneyStoreError } from "./birth-time-journey-store-errors.ts";
import { resolveMissingBirthTimezoneOffset } from "./birth-profile-timezone.ts";
import { resolveAyanamsa } from "./ayanamsa.ts";
type JourneyLoadResult = { readonly data: unknown; readonly error: unknown };
type JourneyLoadQuery = {
@@ -141,7 +142,7 @@ export async function loadStoredRectificationCase(
const parsed = storedCaseSchema.parse(data);
const { data: profile, error: profileError } = await client
.from("profiles")
.select("birth_date,reported_birth_time,birth_time_period,latitude,longitude,timezone_id,timezone_offset")
.select("birth_date,reported_birth_time,birth_time_period,latitude,longitude,timezone_id,timezone_offset,ayanamsa")
.eq("id", userId)
.maybeSingle();
if (profileError || !profile) throw new BirthTimeJourneyStoreError("load_case");
@@ -200,6 +201,7 @@ export async function loadStoredRectificationCase(
lat: location.latitude,
lon: location.longitude,
tz: location.timezone_offset,
ayanamsa: resolveAyanamsa(resolvedProfile as { ayanamsa?: unknown }),
},
lifeEvents: parsed.life_events,
candidateResult,
@@ -13,6 +13,7 @@ import type {
DynamicChoiceScoreInput,
JourneyEventScoreInput,
} from "./birth-time-journey-service.ts";
import { resolveAyanamsa } from "./ayanamsa.ts";
export class BirthTimeJourneyEngineError extends Error {
readonly name = "BirthTimeJourneyEngineError";
@@ -87,6 +88,8 @@ export function eventScorePayload(input: JourneyEventScoreInput) {
lat: input.lat,
lon: input.lon,
tz: input.tz,
ayanamsa: resolveAyanamsa(input),
node_mode: "mean",
high_rigor: true,
events: (input.events ?? []).map((event) => ({
id: event.id,
@@ -163,6 +166,7 @@ export function createJourneyEngineMethods(wire: JourneyEngineWire): BirthTimeJo
lon: input.lon,
tz: input.tz,
ayanamsa: input.ayanamsa,
node_mode: "mean",
},
});
return { questionnaire: parseRectificationQuestionnaire(payload) };
@@ -70,6 +70,7 @@ export type JourneyEventScoreInput = {
readonly lat: number;
readonly lon: number;
readonly tz: number;
readonly ayanamsa?: AyanamsaName;
readonly events: readonly LifeEvent[];
};
@@ -123,6 +124,7 @@ type StoredRectificationCaseBase = {
readonly lat: number;
readonly lon: number;
readonly tz: number;
readonly ayanamsa?: AyanamsaName;
};
readonly lifeEvents?: readonly LifeEvent[];
readonly candidateResult?: CandidateResult | null;
@@ -4,6 +4,7 @@ import type {
AgenticRectificationCandidateResult,
AgenticRectificationContext,
} from "@/mastra/rectification-tools";
import { resolveAyanamsa, type AyanamsaName } from "../ayanamsa.ts";
import { normalizePersistedBirthDate } from "../birth-time-intake-model.ts";
import { declaredClockRange } from "../declared-birth-window.ts";
@@ -26,6 +27,7 @@ export type AgenticRectificationProfile = Readonly<{
lat: number;
lon: number;
tz: number;
ayanamsa: AyanamsaName;
declaredAccuracy: AgenticRectificationContext["declaredAccuracy"];
timeSource: AgenticRectificationContext["timeSource"];
baselineReportedTime: string | null;
@@ -166,7 +168,7 @@ export async function loadAgenticRectificationProfile(
): Promise<AgenticRectificationProfile> {
const { data, error } = await accounting
.from("profiles")
.select("birth_date,reported_birth_time,active_birth_time,birth_time_source,birth_time_period,declared_window_start,declared_window_end,uncertainty_before_minutes,uncertainty_after_minutes,latitude,longitude,timezone_offset")
.select("birth_date,reported_birth_time,active_birth_time,birth_time_source,birth_time_period,declared_window_start,declared_window_end,uncertainty_before_minutes,uncertainty_after_minutes,latitude,longitude,timezone_offset,ayanamsa")
.eq("id", userId)
.single();
if (error || !data) throw new AgenticRectificationProfileError("profile_unavailable");
@@ -199,6 +201,7 @@ export async function loadAgenticRectificationProfile(
lat,
lon,
tz,
ayanamsa: resolveAyanamsa(data),
declaredAccuracy: declaredAccuracyFrom(uncertaintyBefore, uncertaintyAfter, rawSource),
timeSource: timeSourceFrom(rawSource),
baselineReportedTime: reportedTime,
@@ -284,6 +287,7 @@ export function createAgenticRectificationContext(
lat: profile.lat,
lon: profile.lon,
tz: profile.tz,
ayanamsa: profile.ayanamsa,
},
candidateRange: profile.candidateRange,
declaredAccuracy: profile.declaredAccuracy,
@@ -477,6 +477,7 @@ function engineRequestBody(input: {
lon,
tz,
ayanamsa: resolveAyanamsa(snapshot),
node_mode: "mean",
events: input.events,
birth_time_source: snapshot.birth_time_source,
timezone_id: snapshot.timezone_id,
@@ -1,6 +1,7 @@
import { createTool } from "@mastra/core/tools";
import { createHash } from "node:crypto";
import { z } from "zod";
import { resolveAyanamsa, type AyanamsaName } from "../lib/ayanamsa.ts";
import { dateRangeFromDeclared } from "../lib/rectification-agentic/date-range.ts";
/**
@@ -27,6 +28,7 @@ export type AgenticRectificationBirth = Readonly<{
lat: number;
lon: number;
tz: number;
ayanamsa?: AyanamsaName | string | null;
}>;
export type AgenticRectificationCandidateRange = Readonly<{
@@ -250,6 +252,8 @@ function v5Request(
lat: ctx.birth.lat,
lon: ctx.birth.lon,
tz: ctx.birth.tz,
ayanamsa: resolveAyanamsa(ctx.birth),
node_mode: "mean",
events: events.map(toV5Event),
};
}
@@ -425,6 +429,8 @@ export function createAgenticRectificationTools(ctx: AgenticRectificationContext
lat: ctx.birth.lat,
lon: ctx.birth.lon,
tz: ctx.birth.tz,
ayanamsa: resolveAyanamsa(ctx.birth),
node_mode: "mean",
time_uncertainty_minutes: scanWindow.uncertaintyMinutes,
step_minutes: input.step_minutes,
};
@@ -533,6 +539,8 @@ export function createAgenticRectificationTools(ctx: AgenticRectificationContext
lat: ctx.birth.lat,
lon: ctx.birth.lon,
tz: ctx.birth.tz,
ayanamsa: resolveAyanamsa(ctx.birth),
node_mode: "mean",
events: [],
});
const snapshot = (data.candidate_feature_snapshot && typeof data.candidate_feature_snapshot === "object")
@@ -568,6 +576,8 @@ export function createAgenticRectificationTools(ctx: AgenticRectificationContext
lat: ctx.birth.lat,
lon: ctx.birth.lon,
tz: ctx.birth.tz,
ayanamsa: resolveAyanamsa(ctx.birth),
node_mode: "mean",
events: input.events.map(toV3Event),
high_rigor: true,
};
@@ -19,6 +19,7 @@ test("journey engine serializes only stored event-scoring inputs", () => {
lat: 31.2304,
lon: 121.4737,
tz: 8,
ayanamsa: "lahiri",
events: [
{ id: "5cb071d6-6d99-46be-85dc-a9bf59ef6ac5", domain: "career", date: "2019-07", precision: "month", summary: "晋升为团队负责人" },
{ id: "0790866c-ad5e-4a45-b2b4-a5c73f6be6ea", domain: "education", date: "2011", precision: "year" },
@@ -33,6 +34,8 @@ test("journey engine serializes only stored event-scoring inputs", () => {
lat: 31.2304,
lon: 121.4737,
tz: 8,
ayanamsa: "lahiri",
node_mode: "mean",
high_rigor: true,
events: [
{ id: "5cb071d6-6d99-46be-85dc-a9bf59ef6ac5", domain: "career", date: "2019-07", precision: "month", summary: "晋升为团队负责人" },