fix: make schema types root-level object
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
import { llm } from "@/openrouter";
|
||||
import { extractedFactSchema } from "@/openrouter/schema";
|
||||
import { extractedFactSchema, type ExtractedFactResult } from "@/openrouter/schema";
|
||||
import { type ExtractedFact, LlmFactExtractor } from "identitydb";
|
||||
|
||||
export const factExtractor = new LlmFactExtractor({
|
||||
model: {
|
||||
async generateText({ instruction, input }) {
|
||||
return await llm.call<ExtractedFact[]>(llm.models.identity, {
|
||||
const result = await llm.call<ExtractedFactResult>(llm.models.identity, {
|
||||
instruction,
|
||||
message: input,
|
||||
jsonSchemaName: "fact-extractor",
|
||||
jsonSchema: extractedFactSchema,
|
||||
});
|
||||
return result.items;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -80,16 +80,20 @@ const mockCall = mock(async <T>(model: unknown, options: any): Promise<T> => {
|
||||
return { items: customDailySlots ?? build48Slots() } as unknown as T;
|
||||
}
|
||||
if (options.jsonSchemaName === "monthly-schedule") {
|
||||
if (customMonthlyDays) return customMonthlyDays as unknown as T;
|
||||
if (customMonthlyDays) {
|
||||
return { items: customMonthlyDays } as unknown as T;
|
||||
}
|
||||
const match = options.message.match(/\((\d+) days\)/);
|
||||
const days = match ? parseInt(match[1]!, 10) : 30;
|
||||
return Array.from({ length: days }, (_, i) => ({
|
||||
day: i + 1,
|
||||
summary: `Day ${i + 1} summary`,
|
||||
})) as unknown as T;
|
||||
return {
|
||||
items: Array.from({ length: days }, (_, i) => ({
|
||||
day: i + 1,
|
||||
summary: `Day ${i + 1} summary`,
|
||||
})),
|
||||
} as unknown as T;
|
||||
}
|
||||
if (options.jsonSchemaName === "availability") {
|
||||
return (customAvailability ?? buildAvailability()) as unknown as T;
|
||||
return { items: customAvailability ?? buildAvailability() } as unknown as T;
|
||||
}
|
||||
throw new Error(`unexpected jsonSchemaName: ${options.jsonSchemaName}`);
|
||||
});
|
||||
@@ -267,9 +271,11 @@ describe("Brain.createMonthlySchedule", () => {
|
||||
const result = await brain.createMonthlySchedule(today, "study for GRE");
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result).toHaveLength(expected.daysInMonth);
|
||||
expect(result![0]!.day).toBe(1);
|
||||
expect(result![result!.length - 1]!.day).toBe(expected.daysInMonth);
|
||||
expect(result!.items).toHaveLength(expected.daysInMonth);
|
||||
expect(result!.items[0]!.day).toBe(1);
|
||||
expect(result!.items[result!.items.length - 1]!.day).toBe(
|
||||
expected.daysInMonth,
|
||||
);
|
||||
|
||||
const llmCall = llmCalls.find(
|
||||
(c) => c.options.jsonSchemaName === "monthly-schedule",
|
||||
@@ -285,7 +291,9 @@ describe("Brain.createMonthlySchedule", () => {
|
||||
},
|
||||
);
|
||||
expect(facts).toHaveLength(1);
|
||||
expect(JSON.parse(facts[0]!.statement)).toHaveLength(expected.daysInMonth);
|
||||
expect(JSON.parse(facts[0]!.statement).items).toHaveLength(
|
||||
expected.daysInMonth,
|
||||
);
|
||||
});
|
||||
|
||||
test("S5: year wrap (December 15 -> January next year)", async () => {
|
||||
@@ -296,7 +304,7 @@ describe("Brain.createMonthlySchedule", () => {
|
||||
const result = await brain.createMonthlySchedule(today, "");
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result).toHaveLength(31);
|
||||
expect(result!.items).toHaveLength(31);
|
||||
|
||||
const facts = await brain.db.getTopicFacts(
|
||||
`monthly-schedule:${expectedKey}`,
|
||||
@@ -337,8 +345,8 @@ describe("Brain.getTodayScheduledAvailability", () => {
|
||||
const result = await brain.getTodayScheduledAvailability(today);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result!.length).toBeGreaterThan(0);
|
||||
for (const w of result!) {
|
||||
expect(result!.items.length).toBeGreaterThan(0);
|
||||
for (const w of result!.items) {
|
||||
expect(["online", "do-not-disturb", "offline"]).toContain(w.status);
|
||||
expect(w.start).toMatch(/^([01][0-9]|2[0-3]):[0-5][0-9]$/);
|
||||
expect(w.end).toMatch(/^([01][0-9]|2[0-3]):[0-5][0-9]$|^24:00$/);
|
||||
@@ -451,7 +459,7 @@ describe("Brain.createDebug", () => {
|
||||
|
||||
const schedule = await brain.createMonthlySchedule(today, "msg");
|
||||
expect(schedule).not.toBeNull();
|
||||
expect(schedule).toHaveLength(expected.daysInMonth);
|
||||
expect(schedule!.items).toHaveLength(expected.daysInMonth);
|
||||
|
||||
const facts = await brain.db.getTopicFacts(
|
||||
`monthly-schedule:${monthKey}`,
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
dailyScheduleSchema,
|
||||
monthlyScheduleSchema,
|
||||
type Availability,
|
||||
type AvailabilityWindows,
|
||||
type DailySchedule,
|
||||
type MonthlySchedule,
|
||||
} from "@/openrouter/schema";
|
||||
@@ -28,7 +29,7 @@ export interface DebugOptions {
|
||||
}
|
||||
|
||||
export class Brain {
|
||||
private availabilityCache: Map<string, Availability[]> = new Map();
|
||||
private availabilityCache: Map<string, AvailabilityWindows> = new Map();
|
||||
|
||||
constructor(
|
||||
public db: IdentityDB,
|
||||
@@ -142,7 +143,7 @@ export class Brain {
|
||||
await this.db.addFact({
|
||||
spaceName: this.space.name,
|
||||
statement: JSON.stringify(schedule),
|
||||
summary: `Monthly schedule for ${monthKey} (${schedule.length} days)`,
|
||||
summary: `Monthly schedule for ${monthKey} (${schedule.items.length} days)`,
|
||||
source: "createMonthlySchedule",
|
||||
confidence: 1.0,
|
||||
topics: [
|
||||
@@ -178,7 +179,7 @@ export class Brain {
|
||||
|
||||
async getTodayScheduledAvailability(
|
||||
datetime: Date,
|
||||
): Promise<Availability[] | null> {
|
||||
): Promise<AvailabilityWindows | null> {
|
||||
try {
|
||||
const dateKey = formatDateKey(datetime);
|
||||
const cached = this.availabilityCache.get(dateKey);
|
||||
@@ -212,7 +213,7 @@ export class Brain {
|
||||
|
||||
async deriveAvailabilityFromSchedule(
|
||||
schedule: DailySchedule,
|
||||
): Promise<Availability[]> {
|
||||
): Promise<AvailabilityWindows> {
|
||||
try {
|
||||
const instruction = await loadPrompt("SCHEDULE_AVAILABILITY");
|
||||
const promptMessage = JSON.stringify({
|
||||
@@ -220,7 +221,7 @@ export class Brain {
|
||||
personality: this.brainbase.baseSystemPrompt,
|
||||
});
|
||||
|
||||
return await llm.call<Availability[]>(llm.models.identity, {
|
||||
return await llm.call<AvailabilityWindows>(llm.models.identity, {
|
||||
instruction,
|
||||
message: promptMessage,
|
||||
jsonSchemaName: "availability",
|
||||
@@ -249,7 +250,7 @@ export class Brain {
|
||||
|
||||
const monthly = JSON.parse(facts[0]!.statement) as MonthlySchedule;
|
||||
const day = target.getDate();
|
||||
const entry = monthly.find((d) => d.day === day);
|
||||
const entry = monthly.items.find((d) => d.day === day);
|
||||
return entry?.summary ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user