Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: continue migrating Aila package to support variable documents #575

Merged
merged 2 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions apps/nextjs/src/app/api/chat/chatHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ async function setupChatHandler(req: NextRequest) {
const options: AilaOptions = {
useRag: chatOptions.useRag ?? true,
temperature: chatOptions.temperature ?? 0.7,
numberOfLessonPlansInRag: chatOptions.numberOfLessonPlansInRag ?? 5,
numberOfRecordsInRag: chatOptions.numberOfRecordsInRag ?? 5,
usePersistence: true,
useModeration: true,
};
Expand Down Expand Up @@ -110,10 +110,7 @@ function setTelemetryMetadata({
span.setTag("has_lesson_plan", Object.keys(lessonPlan).length > 0);
span.setTag("use_rag", options.useRag);
span.setTag("temperature", options.temperature);
span.setTag(
"number_of_lesson_plans_in_rag",
options.numberOfLessonPlansInRag,
);
span.setTag("number_of_records_in_rag", options.numberOfRecordsInRag);
span.setTag("use_persistence", options.usePersistence);
span.setTag("use_moderation", options.useModeration);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/aila/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ export const DEFAULT_CATEGORISE_MODEL: OpenAI.Chat.ChatModel =
"gpt-4o-2024-08-06";
export const DEFAULT_TEMPERATURE = 0.7;
export const DEFAULT_MODERATION_TEMPERATURE = 0.7;
export const DEFAULT_RAG_LESSON_PLANS = 5;
export const DEFAULT_NUMBER_OF_RECORDS_IN_RAG = 5;
export const BOT_USER_ID = "bot";
28 changes: 10 additions & 18 deletions packages/aila/src/core/Aila.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { aiLogger } from "@oakai/logger";
import {
DEFAULT_MODEL,
DEFAULT_TEMPERATURE,
DEFAULT_RAG_LESSON_PLANS,
DEFAULT_NUMBER_OF_RECORDS_IN_RAG,
} from "../constants";
import type { AilaAmericanismsFeature } from "../features/americanisms";
import { NullAilaAmericanisms } from "../features/americanisms/NullAilaAmericanisms";
Expand Down Expand Up @@ -33,7 +33,7 @@ import type { LLMService } from "./llm/LLMService";
import { OpenAIService } from "./llm/OpenAIService";
import type { AilaPlugin } from "./plugins/types";
import type {
AilaGenerateLessonPlanOptions,
AilaGenerateDocumentOptions,
AilaOptions,
AilaOptionsWithDefaultFallbackValues,
AilaInitializationOptions,
Expand Down Expand Up @@ -141,21 +141,21 @@ export class Aila implements AilaServices {
await this.loadChatIfPersisting();
const persistedLessonPlan = this._chat.persistedChat?.lessonPlan;
if (persistedLessonPlan) {
this._document.setContent(persistedLessonPlan);
this._document.content = persistedLessonPlan;
}
await this._document.initialiseContentFromMessages(this._chat.messages);

this._initialised = true;
}

private initialiseOptions(options?: AilaOptions) {
private initialiseOptions(
options?: AilaOptions,
): AilaOptionsWithDefaultFallbackValues {
return {
useRag: options?.useRag ?? true,
temperature: options?.temperature ?? DEFAULT_TEMPERATURE,
// #TODO we should find a way to make this less specifically tied
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addresses this TODO

// to lesson RAG
numberOfLessonPlansInRag:
options?.numberOfLessonPlansInRag ?? DEFAULT_RAG_LESSON_PLANS,
numberOfRecordsInRag:
options?.numberOfRecordsInRag ?? DEFAULT_NUMBER_OF_RECORDS_IN_RAG,
usePersistence: options?.usePersistence ?? true,
useAnalytics: options?.useAnalytics ?? true,
useModeration: options?.useModeration ?? true,
Expand All @@ -177,18 +177,10 @@ export class Aila implements AilaServices {
return this._chat;
}

// #TODO we should refactor this to be a document
// and not be specifically tied to a "lesson"
// so that we can handle any type of generation
public get document(): AilaDocumentService {
return this._document;
}

// #TODO we should not need this
public get lessonPlan() {
return this._document.content;
}

public get snapshotStore() {
return this._snapshotStore;
}
Expand Down Expand Up @@ -259,7 +251,7 @@ export class Aila implements AilaServices {
}

// Generation methods
public async generateSync(opts: AilaGenerateLessonPlanOptions) {
public async generateSync(opts: AilaGenerateDocumentOptions) {
this.checkInitialised();
const stream = await this.generate(opts);

Expand All @@ -280,7 +272,7 @@ export class Aila implements AilaServices {
public async generate({
input,
abortController,
}: AilaGenerateLessonPlanOptions) {
}: AilaGenerateDocumentOptions) {
this.checkInitialised();
if (this._isShutdown) {
throw new AilaGenerationError(
Expand Down
8 changes: 3 additions & 5 deletions packages/aila/src/core/AilaServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import type {
import type {
AilaPersistedChat,
AilaRagRelevantLesson,
LooseLessonPlan,
} from "../protocol/schema";
import type { Message } from "./chat";
import type { AilaDocumentContent } from "./document/types";
import type { AilaPlugin } from "./plugins";
import type { FullQuizService } from "./quiz/interfaces";
import type { AilaOptionsWithDefaultFallbackValues } from "./types";
Expand All @@ -30,12 +30,11 @@ export interface AilaAnalyticsService {
}

export interface AilaDocumentService {
readonly content: LooseLessonPlan;
content: AilaDocumentContent;
readonly hasInitialisedContentFromMessages: boolean;
setContent(content: LooseLessonPlan): void;
extractAndApplyLlmPatches(patches: string): void;
applyValidPatches(validPatches: ValidPatchDocument[]): void;
initialise(content: LooseLessonPlan): void;
initialise(content: AilaDocumentContent): void;
initialiseContentFromMessages(messages: Message[]): Promise<void>;
}

Expand All @@ -59,7 +58,6 @@ export interface AilaChatService {
export interface AilaServices {
readonly userId: string | undefined;
readonly chatId: string;
readonly lessonPlan: LooseLessonPlan;
readonly messages: Message[];
readonly options: AilaOptionsWithDefaultFallbackValues;
readonly analytics?: AilaAnalyticsFeature;
Expand Down
4 changes: 0 additions & 4 deletions packages/aila/src/core/document/AilaDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ export class AilaDocument implements AilaDocumentService {
this._content = content;
}

public setContent(content: AilaDocumentContent) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removes this method in preference of set above

this._content = content;
}

public get hasInitialisedContentFromMessages(): boolean {
return this._hasInitialisedContentFromMessages;
}
Expand Down
4 changes: 4 additions & 0 deletions packages/aila/src/core/document/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export type AilaDummyDocumentContent = {
keyStage: string;
topic?: string;
body: string;
basedOn?: {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, all document types would need a basedOn attribute

id: string;
title: string;
};
};

export type AilaDocumentContent = LooseLessonPlan | AilaDummyDocumentContent;
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { prisma as globalPrisma } from "@oakai/db/client";
import { aiLogger } from "@oakai/logger";
import { getRelevantLessonPlans, parseSubjectsForRagSearch } from "@oakai/rag";

import { DEFAULT_RAG_LESSON_PLANS } from "../../../constants";
import { DEFAULT_NUMBER_OF_RECORDS_IN_RAG } from "../../../constants";
import { tryWithErrorReporting } from "../../../helpers/errorReporting";
import { LLMResponseJsonSchema } from "../../../protocol/jsonPatchProtocol";
import type { LooseLessonPlan } from "../../../protocol/schema";
Expand Down Expand Up @@ -69,7 +69,8 @@ export class AilaLessonPromptBuilder extends AilaPromptBuilder {
};
}

const { title, subject, keyStage, topic } = this._aila?.lessonPlan ?? {};
const { title, subject, keyStage, topic } =
this._aila?.document?.content ?? {};

if (!title || !subject || !keyStage) {
log.error("Missing title, subject or keyStage, returning empty content");
Expand Down Expand Up @@ -119,8 +120,8 @@ export class AilaLessonPromptBuilder extends AilaPromptBuilder {
keyStage,
id: chatId,
k:
this._aila?.options.numberOfLessonPlansInRag ??
DEFAULT_RAG_LESSON_PLANS,
this._aila?.options.numberOfRecordsInRag ??
DEFAULT_NUMBER_OF_RECORDS_IN_RAG,
prisma: globalPrisma,
chatId,
userId,
Expand All @@ -146,7 +147,7 @@ export class AilaLessonPromptBuilder extends AilaPromptBuilder {
relevantLessonPlans: string,
baseLessonPlan: LooseLessonPlan | undefined,
): string {
const lessonPlan = this._aila?.lessonPlan ?? {};
const lessonPlan = this._aila?.document?.content ?? {};
const args: TemplateProps = {
lessonPlan,
relevantLessonPlans,
Expand Down
11 changes: 5 additions & 6 deletions packages/aila/src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,17 @@ import type {
AilaModerationFeature,
AilaThreatDetectionFeature,
} from "../features/types";
import type { LooseLessonPlan } from "../protocol/schema";
import type { AilaServices } from "./AilaServices";
import type { Message } from "./chat";
import type { AilaDocumentContent } from "./document/types";
import type { LLMService } from "./llm/LLMService";
import type { AilaPlugin } from "./plugins/types";
import type { AilaPromptBuilder } from "./prompt/AilaPromptBuilder";

export type AilaGenerateLessonPlanMode = "interactive" | "generate";
export type AilaGenerateDocumentMode = "interactive" | "generate";

export type AilaGenerateLessonPlanOptions = {
mode?: AilaGenerateLessonPlanMode;
export type AilaGenerateDocumentOptions = {
mode?: AilaGenerateDocumentMode;
input?: string;
title?: string;
topic?: string;
Expand All @@ -37,7 +36,7 @@ export type AilaGenerateLessonPlanOptions = {
export type AilaPublicChatOptions = {
useRag?: boolean;
temperature?: number;
numberOfLessonPlansInRag?: number;
numberOfRecordsInRag?: number;
};

export type AilaOptions = AilaPublicChatOptions & {
Expand All @@ -47,7 +46,7 @@ export type AilaOptions = AilaPublicChatOptions & {
useAnalytics?: boolean;
useThreatDetection?: boolean;
model?: string;
mode?: AilaGenerateLessonPlanMode;
mode?: AilaGenerateDocumentMode;
};

export type AilaOptionsWithDefaultFallbackValues = Required<AilaOptions>;
Expand Down
10 changes: 5 additions & 5 deletions packages/aila/src/features/rag/AilaRag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ export class AilaRag implements AilaRagFeature {
}

public async fetchRagContent({
numberOfLessonPlansInRag,
numberOfRecordsInRag,
lessonPlan,
}: {
numberOfLessonPlansInRag?: number;
numberOfRecordsInRag?: number;
lessonPlan?: LooseLessonPlan;
}) {
// #TODO Refactor to return an array rather than stringified JSON
let content = "[]";

const { title, keyStage, subject, topic } =
lessonPlan ?? this._aila?.lessonPlan ?? {};
lessonPlan ?? this._aila?.document?.content ?? {};
const chatId = this._aila?.chatId ?? "anonymous"; // #TODO add proper support for CLI RAG requests without a user
if (!title) {
return content;
Expand All @@ -57,8 +57,8 @@ export class AilaRag implements AilaRagFeature {
subject,
topic,
k:
numberOfLessonPlansInRag ??
this._aila?.options.numberOfLessonPlansInRag ??
numberOfRecordsInRag ??
this._aila?.options.numberOfRecordsInRag ??
5,
})
: [];
Expand Down
2 changes: 1 addition & 1 deletion packages/aila/src/features/rag/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { LooseLessonPlan } from "../../protocol/schema";

export interface AilaRagFeature {
fetchRagContent(params: {
numberOfLessonPlansInRag?: number;
numberOfRecordsInRag?: number;
lessonPlan?: LooseLessonPlan;
}): Promise<string>;
}
1 change: 0 additions & 1 deletion packages/aila/src/protocol/schema.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// import dedent from "dedent";
import dedent from "ts-dedent";
import z from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
Expand Down
Loading