From 6af7fad0e44f4cac486e376a32a1d5a690463fbb Mon Sep 17 00:00:00 2001 From: MG Date: Tue, 26 Nov 2024 12:45:07 +0000 Subject: [PATCH 01/68] chore: add rag table migrations (#385) --- packages/db/package.json | 2 ++ .../migration.sql | 16 ++++++++++++ packages/db/prisma/schema.prisma | 25 +++++++++++-------- 3 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 packages/db/prisma/migrations/20241126121910_ingest_rag_published_index/migration.sql diff --git a/packages/db/package.json b/packages/db/package.json index 961782624..6ff431295 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -23,6 +23,8 @@ "db-migrate": "pnpm with-env prisma migrate dev", "db-migrate:dev": "pnpm with-env prisma migrate dev", "db-migrate:status": "pnpm with-env prisma migrate status", + "db-migrate:status:stg": "DB_ENV=stg doppler run --config stg -- prisma migrate status", + "db-migrate:status:prd": "DB_ENV=prd doppler run --config prd -- prisma migrate status", "db-migrate-resolve-applied:prd": "doppler run --config prd -- prisma migrate resolve --applied", "db-migrate-resolve-applied:stg": "doppler run --config stg -- prisma migrate resolve --applied", "db-migrate-resolve-rolled-back:prd": "doppler run --config prd -- prisma migrate resolve --rolled-back", diff --git a/packages/db/prisma/migrations/20241126121910_ingest_rag_published_index/migration.sql b/packages/db/prisma/migrations/20241126121910_ingest_rag_published_index/migration.sql new file mode 100644 index 000000000..ae31031a9 --- /dev/null +++ b/packages/db/prisma/migrations/20241126121910_ingest_rag_published_index/migration.sql @@ -0,0 +1,16 @@ +/* + Warnings: + + - Added the required column `oak_lesson_slug` to the `rag_lesson_plans` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "ingest"."ingest" ALTER COLUMN "config" DROP DEFAULT; + +-- AlterTable +ALTER TABLE "rag"."rag_lesson_plans" ADD COLUMN "is_published" BOOLEAN NOT NULL DEFAULT false, +ADD COLUMN "oak_lesson_slug" TEXT NOT NULL, +ALTER COLUMN "oak_lesson_id" DROP NOT NULL; + +-- CreateIndex +CREATE INDEX "idx_rag_lesson_plans_published_key_stage_subject" ON "rag"."rag_lesson_plans"("is_published", "key_stage_slug", "subject_slug"); diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma index 7a9cc441a..aa9b59a59 100644 --- a/packages/db/prisma/schema.prisma +++ b/packages/db/prisma/schema.prisma @@ -1117,16 +1117,21 @@ model IngestError { } model RagLessonPlan { - id String @id @default(cuid()) - oakLessonId Int @map("oak_lesson_id") - ingestLessonId String? @map("ingest_lesson_id") - lessonPlan Json @map("lesson_plan") @db.JsonB - subjectSlug String @map("subject_slug") - keyStageSlug String @map("key_stage_slug") - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - ragLessonPlanPart RagLessonPlanPart[] - + id String @id @default(cuid()) + oakLessonId Int? @map("oak_lesson_id") + oakLessonSlug String @map("oak_lesson_slug") + ingestLessonId String? @map("ingest_lesson_id") + lessonPlan Json @map("lesson_plan") @db.JsonB + subjectSlug String @map("subject_slug") + keyStageSlug String @map("key_stage_slug") + isPublished Boolean @default(false) @map("is_published") + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + ragLessonPlanParts RagLessonPlanPart[] + // The following index is not supported by prisma so is applied manually in ./additions/rag_lesson_plans_unique_slug_index.sql + // @@index([oakLessonSlug], name: "unique_published_oak_lesson_slug", dbIndex: false) @db.PartialIndex("is_published = TRUE") + + @@index([isPublished, keyStageSlug, subjectSlug], name: "idx_rag_lesson_plans_published_key_stage_subject") @@map("rag_lesson_plans") @@schema("rag") } From 610d8c838273de24212a8531a8bc4b6136c05db1 Mon Sep 17 00:00:00 2001 From: Stef Lewandowski Date: Tue, 26 Nov 2024 13:38:47 +0000 Subject: [PATCH 02/68] fix: svg clip-rule should be clipRule in JSX (#382) --- .vscode/settings.json | 2 ++ .../nextjs/src/components/Feedback/Smiley.tsx | 20 +++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 97cf21f98..fc7279251 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -48,6 +48,7 @@ "EHRC", "estree", "estruyf", + "evenodd", "eyfs", "firstname", "fkey", @@ -123,6 +124,7 @@ "psql", "pusherapp", "ratelimit", + "rect", "refs", "Regen", "remeda", diff --git a/apps/nextjs/src/components/Feedback/Smiley.tsx b/apps/nextjs/src/components/Feedback/Smiley.tsx index 62e01ab79..59fd3afc1 100644 --- a/apps/nextjs/src/components/Feedback/Smiley.tsx +++ b/apps/nextjs/src/components/Feedback/Smiley.tsx @@ -27,8 +27,8 @@ const Smiley = ({ selected, number }: SmileyProps) => { fill={color} /> @@ -57,8 +57,8 @@ const Smiley = ({ selected, number }: SmileyProps) => { fill={color} /> @@ -87,8 +87,8 @@ const Smiley = ({ selected, number }: SmileyProps) => { fill={color} /> @@ -117,8 +117,8 @@ const Smiley = ({ selected, number }: SmileyProps) => { fill={color} /> @@ -147,8 +147,8 @@ const Smiley = ({ selected, number }: SmileyProps) => { fill={color} /> From ec4ce6e5dcc7dbd4e242be65fd3b5f9708b94a40 Mon Sep 17 00:00:00 2001 From: Stef Lewandowski Date: Tue, 26 Nov 2024 13:44:27 +0000 Subject: [PATCH 03/68] fix: minor linting (#384) --- .vscode/settings.json | 15 + apps/nextjs/.storybook/public/.eslintignore | 1 + apps/nextjs/__mocks__/nextImageMock.js | 7 + apps/nextjs/src/app/aila/help/index.tsx | 370 ++-- apps/nextjs/src/app/faqs/index.tsx | 1589 ++++++++--------- .../AppComponents/Chat/chat-message/index.tsx | 11 +- .../Chat/chat-start-accordion.tsx | 2 +- .../AppComponents/Chat/markdown.tsx | 4 +- apps/nextjs/src/components/Footer.tsx | 3 +- .../nextjs/src/utils/constructOwaLessonUrl.ts | 1 - packages/aila/src/core/Aila.ts | 32 +- packages/aila/src/core/chat/AilaChat.ts | 5 +- .../aila/src/core/chat/AilaStreamHandler.ts | 4 +- packages/aila/src/core/lesson/AilaLesson.ts | 8 +- packages/aila/src/core/llm/MockLLMService.ts | 2 +- packages/aila/src/core/llm/OpenAIService.ts | 4 +- .../builders/AilaLessonPromptBuilder.ts | 4 +- .../src/features/analytics/AilaAnalytics.ts | 6 +- .../adapters/DatadogAnalyticsAdapter.ts | 2 +- .../adapters/PosthogAnalyticsAdapter.ts | 4 +- .../exports/src/gSuite/slides/deleteSlides.ts | 1 + sonar-project.properties | 1 + 22 files changed, 1040 insertions(+), 1036 deletions(-) create mode 100644 apps/nextjs/.storybook/public/.eslintignore diff --git a/.vscode/settings.json b/.vscode/settings.json index fc7279251..6e895d008 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,15 @@ ], "typescript.tsdk": "node_modules/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true, + "cSpell.ignorePaths": [ + "pnpm-lock.json", + "node_modules", + "vscode-extension", + ".git/{info,lfs,logs,refs,objects}/**", + ".git/{index,*refs,*HEAD}", + ".vscode", + ".vscode-insiders" + ], "cSpell.words": [ "Aila", "APIV", @@ -33,6 +42,7 @@ "COLOR", "compat", "contrib", + "corejs", "cuid", "dashify", "datadoghq", @@ -45,6 +55,7 @@ "dopplerhq", "dotenv", "EASS", + "Edtech", "EHRC", "estree", "estruyf", @@ -134,10 +145,13 @@ "rushstack", "Sedar", "slidedeck", + "sslcert", "sslmode", "SUBJ", "superjson", "svgs", + "svix", + "systemjs", "tailwindcss", "tanstack", "testid", @@ -146,6 +160,7 @@ "thenational", "tiktoken", "timeframe", + "transferrables", "transpiles", "trivago", "trpc", diff --git a/apps/nextjs/.storybook/public/.eslintignore b/apps/nextjs/.storybook/public/.eslintignore new file mode 100644 index 000000000..9718b3bbc --- /dev/null +++ b/apps/nextjs/.storybook/public/.eslintignore @@ -0,0 +1 @@ +apps/nextjs/.storybook/public/mockServiceWorker.js \ No newline at end of file diff --git a/apps/nextjs/__mocks__/nextImageMock.js b/apps/nextjs/__mocks__/nextImageMock.js index d3ad25552..934118671 100644 --- a/apps/nextjs/__mocks__/nextImageMock.js +++ b/apps/nextjs/__mocks__/nextImageMock.js @@ -1,7 +1,14 @@ import React from "react"; +import PropTypes from "prop-types"; + const NextImageMock = ({ src, alt, ...props }) => { return {alt}; }; +NextImageMock.propTypes = { + src: PropTypes.string.isRequired, + alt: PropTypes.string.isRequired, +}; + export default NextImageMock; diff --git a/apps/nextjs/src/app/aila/help/index.tsx b/apps/nextjs/src/app/aila/help/index.tsx index 3646ae0a9..0afe5c594 100644 --- a/apps/nextjs/src/app/aila/help/index.tsx +++ b/apps/nextjs/src/app/aila/help/index.tsx @@ -18,10 +18,10 @@ export const HelpContent = () => { const aiRef = useRef(null); const scrollToRefWithOffset = (ref) => { - if (ref && ref.current) { + if (ref?.current) { const yOffset = -72; // Adjust this value as needed const y = - ref.current.getBoundingClientRect().top + window.pageYOffset + yOffset; + ref.current.getBoundingClientRect().top + window.scrollY + yOffset; window.scrollTo({ top: y, behavior: "smooth" }); } }; @@ -30,196 +30,192 @@ export const HelpContent = () => { const ailaId = searchParams.get("ailaId"); return ( - <> -
-
-
-

Help

-
    -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
-
- -
-
- +
+
+

Help

+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • +
+ Reviewing and editing + + +
  • + +
  • +
  • + +
  • + +
    -
    - -
    -

    - Starting your first lesson -

    -

    - Create your first lesson by typing a lesson title and key stage - into the input box on the first screen and clicking the arrow key. - This will create the starting point of your lesson. You can get - back to the initial screen by clicking 'New lesson' in - the main navigation. -

    -

    - Structure of an Oak lesson -

    -

    - Lessons are created using Oak's curriculum principles and - include the following sections: -

    -
      -
    • Learning outcome
    • -
    • Learning cycle outcomes
    • -
    • Prior knowledge
    • -
    • Key learning points
    • -
    • Misconceptions
    • -
    • Starter quiz
    • -
    • Learning cycles
    • -
    • Exit quiz
    • -
    • Additional materials (optional)
    • -
    -

    Learning cycles

    -

    Each learning cycle includes 4 key sections:

    -
      -
    • Explanation
    • -
    • Checks for understanding
    • -
    • Practice
    • -
    • Feedback
    • -
    -

    - Downloads -

    -

    - Once the lesson has been created (and all sections are complete) - you will be able to download the following documents: -

    -
      -
    • Lesson, including all sections (PDF/Docx file)
    • -
    • Starter quiz (PDF/Docx file)
    • -
    • Slides (PDF/PPTX file)
    • -
    • Exit quiz (PDF/Docx file)
    • -
    -

    - If you have a Google account, you will also be able to edit these - documents directly. -

    -

    - Examples of additional materials -

    -

    - Health and safety information, lesson narration, model answers or - additional practice tasks. -

    -

    - Co-creating your lesson -

    -

    - Aila, Oak's AI lesson assistant will guide you through the - process of co-creating each section of your lesson on the - left-hand side of the screen. The lesson output will be generated - on the right-hand side. -

    -

    - Reviewing and editing -

    -

    - Aila will pause at key points during the lesson creation and will - ask you to review the content generated. You can ask Aila to adapt - each section, for example: -

    -
      -
    • adapt the content for a specific reading age.
    • -
    • - add specific case studies or examples to your explanations. -
    • -
    • change the practice tasks for you.
    • -
    • - add a narrative for each learning cycle to the Additional - Materials. -
    • -
    -

    - Downloading and sharing -

    -

    - When you have completed all the sections in the lesson, you will - be able to download the lesson resources, including the full - lesson plan (which includes all sections), editable slides and - starter and exit quizzes. You can also share your lesson as a - link, which can be viewed online. -

    -

    - AI and accuracy -

    -

    - Retrieval Augmented Generation is used to integrate Oak content - into your lessons, improving the accuracy of the content produced. - AI is not 100% accurate and mistakes can still be made. Remember, - you're still the expert, so please ensure all content is - reviewed before using it in a classroom or sharing. -

    +
    +
    + + Back to Aila +
    + +
    + +
    +

    + Starting your first lesson +

    +

    + Create your first lesson by typing a lesson title and key stage into + the input box on the first screen and clicking the arrow key. This + will create the starting point of your lesson. You can get back to + the initial screen by clicking 'New lesson' in the main + navigation. +

    +

    + Structure of an Oak lesson +

    +

    + Lessons are created using Oak's curriculum principles and + include the following sections: +

    +
      +
    • Learning outcome
    • +
    • Learning cycle outcomes
    • +
    • Prior knowledge
    • +
    • Key learning points
    • +
    • Misconceptions
    • +
    • Starter quiz
    • +
    • Learning cycles
    • +
    • Exit quiz
    • +
    • Additional materials (optional)
    • +
    +

    Learning cycles

    +

    Each learning cycle includes 4 key sections:

    +
      +
    • Explanation
    • +
    • Checks for understanding
    • +
    • Practice
    • +
    • Feedback
    • +
    +

    + Downloads +

    +

    + Once the lesson has been created (and all sections are complete) you + will be able to download the following documents: +

    +
      +
    • Lesson, including all sections (PDF/Docx file)
    • +
    • Starter quiz (PDF/Docx file)
    • +
    • Slides (PDF/PPTX file)
    • +
    • Exit quiz (PDF/Docx file)
    • +
    +

    + If you have a Google account, you will also be able to edit these + documents directly. +

    +

    + Examples of additional materials +

    +

    + Health and safety information, lesson narration, model answers or + additional practice tasks. +

    +

    + Co-creating your lesson +

    +

    + Aila, Oak's AI lesson assistant will guide you through the + process of co-creating each section of your lesson on the left-hand + side of the screen. The lesson output will be generated on the + right-hand side. +

    +

    + Reviewing and editing +

    +

    + Aila will pause at key points during the lesson creation and will + ask you to review the content generated. You can ask Aila to adapt + each section, for example: +

    +
      +
    • adapt the content for a specific reading age.
    • +
    • add specific case studies or examples to your explanations.
    • +
    • change the practice tasks for you.
    • +
    • + add a narrative for each learning cycle to the Additional + Materials. +
    • +
    +

    + Downloading and sharing +

    +

    + When you have completed all the sections in the lesson, you will be + able to download the lesson resources, including the full lesson + plan (which includes all sections), editable slides and starter and + exit quizzes. You can also share your lesson as a link, which can be + viewed online. +

    +

    + AI and accuracy +

    +

    + Retrieval Augmented Generation is used to integrate Oak content into + your lessons, improving the accuracy of the content produced. AI is + not 100% accurate and mistakes can still be made. Remember, + you're still the expert, so please ensure all content is + reviewed before using it in a classroom or sharing. +

    - +
    ); }; diff --git a/apps/nextjs/src/app/faqs/index.tsx b/apps/nextjs/src/app/faqs/index.tsx index d311c0468..ab0e60f01 100644 --- a/apps/nextjs/src/app/faqs/index.tsx +++ b/apps/nextjs/src/app/faqs/index.tsx @@ -28,828 +28,817 @@ export const FAQPageContent = () => { const concernsRef = useRef(null); const dataRef = useRef(null); const scrollToRefWithOffset = (ref) => { - if (ref && ref.current) { + if (ref?.current) { const yOffset = -72; // Adjust this value as needed const y = - ref.current.getBoundingClientRect().top + window.pageYOffset + yOffset; + ref.current.getBoundingClientRect().top + window.scrollY + yOffset; window.scrollTo({ top: y, behavior: "smooth" }); } }; return ( - <> - - - - - - FAQs - - - - - - scrollToRefWithOffset(startingRef)}> - Getting started - - - - scrollToRefWithOffset(featuresRef)}> - Features and functionality + + + + + + FAQs + + + + + + scrollToRefWithOffset(startingRef)}> + Getting started + + + + scrollToRefWithOffset(featuresRef)}> + Features and functionality + + + + scrollToRefWithOffset(supportRef)}> + Support and assistance + + + + scrollToRefWithOffset(accessibilityRef)}> + Accessibility + + + + scrollToRefWithOffset(usageRef)}> + Usage and best practices + + + + scrollToRefWithOffset(technicalRef)}> + Technical + + + + scrollToRefWithOffset(updatesRef)}> + Updates and enhancements + + + + scrollToRefWithOffset(concernsRef)}> + Other concerns + + + + scrollToRefWithOffset(dataRef)}> + Data privacy and security + + + + + + +
    + +
    + +
    + + Getting started + +
    + +
    + + How do I sign up for Aila? + + + You can sign up to access Aila and our other AI experiments{" "} + here. + + + How much does it cost to use Aila? + + + As with all of Oak's resources, Aila is completely free to + use. There are some fair use limits that we have applied that you + may reach if your use appears to be excessive. + + + What are the system requirements for using Aila? + + + We aim to make our resources as accessible as possible. Aila will + be available to any teacher with access to a laptop or computer + and the Internet. We currently don't support mobile usage. + + + What is a beta product? + + + Aila is in the beta phase, and we are still actively testing and + developing Aila. This phase helps identify issues by allowing + teachers to use the Aila in real-life conditions. Aila is not + perfect, and will make some mistakes!{" "} + + Your feedback is essential + {" "} + to refine and improve Aila. + + + Is there a tutorial or guide available to help me get started? + + + Aila provides helpful tips and prompts for getting started. If you + need additional support, you can take a look at our{" "} + + help + {" "} + section, or contact us. + +
    + +
    + + Features and functionality + +
    + +
    + + What features does Aila offer? + + + Aila offers a range of features to help teachers create + high-quality lesson plans and resources. It is designed to ensure + that lesson plans meet national curriculum standards. You can edit + your lesson plan using Aila, quickly generating downloadable + lesson plans, editable slide decks, and starter and exit quizzes. + You may also choose to adapt or add to the resources after + download. + + + Can I customise lessons? + + + Yes! Aila is designed to guide you through the process of + co-creating a lesson. The more you specify to Aila, the better + your lesson will be. You can ask Aila to adapt the lesson to suit + your geographical context, the reading age of students in your + class, or any other additional needs your pupils may have. The + materials you produce with Aila are also fully editable. + + + What are the advantages of using Aila? + + + Aila has been based upon Oak's{" "} + + curriculum principles + {" "} + Aila is designed to take you through the process that an expert + teacher would use to plan a lesson; starting with your lesson + outcome and breaking that down into manageable chunks of learning, + our learning cycles. + + + It encourages you to think about the prior knowledge that students + will require for the lesson, the vocabulary that will need to be + explicitly taught during the lesson, the key knowledge that you + want pupils to take from the lesson and the common misconceptions + or errors that pupils make in this topic. + + + Our learning cycles are designed to ensure clear explanations - we + provide image and slide text suggestions to allow for dual coding, + we've ensured slide design minimises extraneous cognitive + load for students and built-in regular checks for understanding + tasks followed by lots of practice for students. + + + The process is designed to be flexible. You can tweak and change + the lesson as it is being created to suit the needs of your + pupils, as you know them best! The beauty of Aila is that it + won't produce your generic off-the-shelf lesson; it will help + you craft a lesson that is accessible and appropriate for your + students. + + + Aila uses a technique called retrieval augmented generation (RAG) + to incorporate the high-quality Oak content, which has been + carefully and expertly created by real-life teachers and + quality-checked by subject experts. This should improve the + accuracy of the lessons being produced. Aila has been designed for + UK teachers so you are less likely to see Americanisms and the + content will be more closely aligned with the English national + curriculum. + + + Why has Oak created Aila when other AI assistants are already + available? + + + Aila draws on existing Oak content, which has been carefully and + expertly created by real-life teachers and quality-checked by + subject experts. Aila has been designed around the Oak{" "} + + curriculum principles + + , which are national curriculum aligned and geared towards UK + users. With Aila, you're less likely to see Americanisms, and + the content will align much more closely with the requirements of + teachers in England. + + + What are the limitations of Aila's features? + + + We know that images are really important to support explanations + and Aila doesn't currently produce images or diagrams. Image + production is a feature that will come with a future iteration of + Aila, but to help teachers with this aspect of lesson design, we + currently provide an 'image suggestion' to help you find + an appropriate image with Google. + + + + We are aware that complex concepts may require more than one slide + to support their explanation. We are developing this feature but + think this is the part of a lesson that will need the most + development from a teacher after export. + + + + Large Language Models are not as good at producing high-quality + content for some subjects and this is a limitation of Aila. We + know that the output isn't as good in certain subjects yet, + in particular STEM subjects and modern foreign languages. We are + actively working to improve these subjects. + + + Why does Aila only output in Oak format? + + + When designing Aila, we wanted pedagogical rigour to be at its + core. Oak's lesson design is underpinned by research in + learning and cognitive science, which has formed the structure of + the lessons that Aila produces. All outputs are fully editable, so + you can update them to your preferred formats. + + + Why is there only one type of questioning in the quizzes? + + + Multiple-choice questions are a really effective way of quickly + assessing pupils' mastery of content, but they take a really + long time to write, so we have included lots to save you time. + After export, you can edit these to remove the options and make + them short answer questions or even add additional question types + to your slides. + + + Aila is still very much in development and we're aiming to + add more question types in future. + +
    + +
    + + Support and assistance + +
    + +
    + + Is support available if I encounter any issues or have questions? + + + + Yes, we provide comprehensive support to assist with any issues or + questions users may have. You can contact us via{" "} + email. + + + Can I provide feedback or suggest improvements for Aila? + + + Yes, please do! We love to hear how users are finding our + resources and how we can improve them. Submit your{" "} + + feedback or suggestions{" "} + + . + + + + Are there resources available for troubleshooting common problems? + + + The more feedback we receive from users, the more we can identify + common problems and provide troubleshooting tips. + +
    + +
    + + Accessibility + +
    + +
    + + Are there features in place to support diverse learners and + educators? + + + We want as many people as possible to be able to use Aila. You + should be able to; change colours, contrast levels, and fonts; + read and use most of the website while zoomed in up to 400%; + navigate most of the website using just a keyboard; navigate most + of the website using speech recognition software; listen to most + of the website using a screen reader (including the most recent + versions of JAWS, NVDA, and VoiceOver). View our{" "} + + full accessibility statement + + . + + + Can lesson plans be adapted for students with SEND? + + + Of course! You can prompt Aila to factor in your pupils' + needs when generating your lesson plan. Try asking Aila to produce + texts of different reading ages, sentence starters, or alternative + activities to support pupils during the additional materials + section of the lesson. You are also able to download and edit all + resources after you have created your lesson. + +
    + +
    + + Usage and best practices + +
    + +
    + + What are some best practices for maximising the effectiveness of + Aila? + + + Work with Aila to co-create your lesson. Before you proceed to the + next steps of co-creating your lesson with Aila, it is important + to check that you are happy with your lesson outcomes and learning + cycle outcomes, as this will determine the content for the rest of + the lesson. + + + If you want the content to be adapted for a specific geographical + context, reading age or a specific pupil need, tell Aila at the + start so that that is taken into consideration when designing the + lesson content. + + + The additional materials section of the lesson is the most + flexible. If you would like teacher instructions for a practical + lesson, model answers, essay-style questions, narratives for your + explanations or texts differentiated by reading age for your + classes, just ask at the end of the lesson planning process and + Aila will create these for you. + +
    + +
    + + Technical + +
    + +
    + + How does Aila work? + + + Aila is built to use Chat GPT4, but we are also evaluating other + models. We have written a 9,000-word prompt that provides very + specific guidance on what excellence looks like for each section + of a lesson. + + + Aila also uses retrieval augmented generation (RAG) to integrate + the high-quality content of Oak's human-planned lessons into + the lessons being delivered. This means that the accuracy of the + content produced should be closely aligned with the needs of + teachers in England. + +
    + +
    + + Updates and enhancements + +
    + +
    + + Are there plans for future enhancements or new features? + + + Yes, we strive to constantly improve our resources, taking into + account feedback from our users - Aila is still very much in + development. We aim to release future iterations of Aila that + produce images and diagrams. We are also developing Aila to ensure + that it has pedagogical rigour for a range of different subjects. + + + Can users suggest features for future updates? + + + Of course, we would love to hear your thoughts and suggestions for + other features that would support your teaching. Please{" "} + + give us your feedback! + + + + + How often are updates released for Aila? + + + We're still in the beta phase, which means that whilst + we're allowing teachers to use it, it's still prone to + bugs and errors, and is still under constant development. + We're constantly receiving feedback and aim to improve and + iterate on an almost daily basis! + + + + How will Aila be evaluated? + + + The team at Oak constantly evaluates Aila, and we are designing + multiple approaches to this. We carry out consistency checks and + ensure that it follows the instructions we have built into the + prompt, and evaluate the quality of content being produced. + + + We aim to evaluate several factors, such as Americanisms, cultural + biases, the appropriateness of the literacy level, checking that + the learning cycles increase in difficulty, and more. + + + Nonetheless, generative AI will make mistakes, and the outputs + should be checked carefully. + +
    + +
    + + Other concerns + +
    + +
    + + Is Oak trying to replace teachers with AI? + + + Absolutely not! At Oak, we share the brilliance of teachers from + across the country through our resources, and our Aila is no + different. It is designed to keep teachers in the driving seat, + with support from AI to reduce their workload. + +
    + +
    + + Data privacy and security + +
    + +
    + + Is Aila safe to use? + + + Generative AI will make mistakes, and no two outputs are the same. + With that in mind, it's important to check any AI-generated + content thoroughly before using it in the classroom. We have put + in place a number of technical and policy measures to minimise the + risks that generative AI presents but care should still be taken, + for example, you must not input personally identifiable + information into Aila, and this is in breach of the terms and + conditions of use. + + + + Can I have unlimited use? + + + In order to prevent misuse, we've restricted and protected + the volume of requests that can be made, lessons, and resources + that can be generated. If you're reaching these limits, + we'd love to hear from you, and you can{" "} + + request a higher limit. + + + + + What ethical measures are you putting in place? + + + Generative AI is a new and cutting-edge technology, and it's + important that anyone developing AI products actively takes into + account privacy, security and ethical considerations. We have + looked into emerging guidance and governance on generative AI, + including; + + + + UNESCO's core principles on{" "} + + a human-rights centred approach to the Ethics of AI - - scrollToRefWithOffset(supportRef)}> - Support and assistance + + US office for Edtech;{" "} + + Artificial Intelligence and the Future of Teaching and + Learning - - scrollToRefWithOffset(accessibilityRef)} - > - Accessibility + + UK DfE position on{" "} + + Generative artificial intelligence (AI) in education - - scrollToRefWithOffset(usageRef)}> - Usage and best practices - + + Aila is designed to: + + + + keep the human in the loop, informing and involving expert + teachers and educators in the process + - scrollToRefWithOffset(technicalRef)}> - Technical - + + not involve the input of personal information to LLMs + - scrollToRefWithOffset(updatesRef)}> - Updates and enhancements - + + allow us to evaluate cultural biases that may be present in + the generated content + - scrollToRefWithOffset(concernsRef)}> - Other concerns - + + create guardrails around the generative AI to improve + pedagogical alignment + - scrollToRefWithOffset(dataRef)}> - Data privacy and security - + + be transparent and explainable to users; we openly share the + underlying prompts + - - - -
    - -
    - -
    - - Getting started - -
    - -
    - - How do I sign up for Aila? - - - You can sign up to access Aila and our other AI experiments{" "} - here. - - - How much does it cost to use Aila? - - - As with all of Oak's resources, Aila is completely free to - use. There are some fair use limits that we have applied that - you may reach if your use appears to be excessive. - - - What are the system requirements for using Aila? - - - We aim to make our resources as accessible as possible. Aila - will be available to any teacher with access to a laptop or - computer and the Internet. We currently don't support - mobile usage. - - - What is a beta product? - - - Aila is in the beta phase, and we are still actively testing and - developing Aila. This phase helps identify issues by allowing - teachers to use the Aila in real-life conditions. Aila is not - perfect, and will make some mistakes!{" "} - - Your feedback is essential - {" "} - to refine and improve Aila. - - - Is there a tutorial or guide available to help me get started? - - - Aila provides helpful tips and prompts for getting started. If - you need additional support, you can take a look at our{" "} - - help - {" "} - section, or contact us. - -
    - -
    - - Features and functionality - -
    - -
    - - What features does Aila offer? - - - Aila offers a range of features to help teachers create - high-quality lesson plans and resources. It is designed to - ensure that lesson plans meet national curriculum standards. You - can edit your lesson plan using Aila, quickly generating - downloadable lesson plans, editable slide decks, and starter and - exit quizzes. You may also choose to adapt or add to the - resources after download. - - - Can I customise lessons? - - - Yes! Aila is designed to guide you through the process of - co-creating a lesson. The more you specify to Aila, the better - your lesson will be. You can ask Aila to adapt the lesson to - suit your geographical context, the reading age of students in - your class, or any other additional needs your pupils may have. - The materials you produce with Aila are also fully editable. - - - What are the advantages of using Aila? - - - Aila has been based upon Oak's{" "} - - curriculum principles - {" "} - Aila is designed to take you through the process that an expert - teacher would use to plan a lesson; starting with your lesson - outcome and breaking that down into manageable chunks of - learning, our learning cycles. - - - It encourages you to think about the prior knowledge that - students will require for the lesson, the vocabulary that will - need to be explicitly taught during the lesson, the key - knowledge that you want pupils to take from the lesson and the - common misconceptions or errors that pupils make in this topic. - - - Our learning cycles are designed to ensure clear explanations - - we provide image and slide text suggestions to allow for dual - coding, we've ensured slide design minimises extraneous - cognitive load for students and built-in regular checks for - understanding tasks followed by lots of practice for students. - - - The process is designed to be flexible. You can tweak and change - the lesson as it is being created to suit the needs of your - pupils, as you know them best! The beauty of Aila is that it - won't produce your generic off-the-shelf lesson; it will - help you craft a lesson that is accessible and appropriate for - your students. - - - Aila uses a technique called retrieval augmented generation - (RAG) to incorporate the high-quality Oak content, which has - been carefully and expertly created by real-life teachers and - quality-checked by subject experts. This should improve the - accuracy of the lessons being produced. Aila has been designed - for UK teachers so you are less likely to see Americanisms and - the content will be more closely aligned with the English - national curriculum. - - - Why has Oak created Aila when other AI assistants are already - available? - - - Aila draws on existing Oak content, which has been carefully and - expertly created by real-life teachers and quality-checked by - subject experts. Aila has been designed around the Oak{" "} - - curriculum principles - - , which are national curriculum aligned and geared towards UK - users. With Aila, you're less likely to see Americanisms, - and the content will align much more closely with the - requirements of teachers in England. - - - What are the limitations of Aila's features? - - - We know that images are really important to support explanations - and Aila doesn't currently produce images or diagrams. - Image production is a feature that will come with a future - iteration of Aila, but to help teachers with this aspect of - lesson design, we currently provide an 'image - suggestion' to help you find an appropriate image with - Google. - - - - We are aware that complex concepts may require more than one - slide to support their explanation. We are developing this - feature but think this is the part of a lesson that will need - the most development from a teacher after export. - - - - Large Language Models are not as good at producing high-quality - content for some subjects and this is a limitation of Aila. We - know that the output isn't as good in certain subjects yet, - in particular STEM subjects and modern foreign languages. We are - actively working to improve these subjects. - - - Why does Aila only output in Oak format? - - - When designing Aila, we wanted pedagogical rigour to be at its - core. Oak's lesson design is underpinned by research in - learning and cognitive science, which has formed the structure - of the lessons that Aila produces. All outputs are fully - editable, so you can update them to your preferred formats. - - - Why is there only one type of questioning in the quizzes? - - - Multiple-choice questions are a really effective way of quickly - assessing pupils' mastery of content, but they take a - really long time to write, so we have included lots to save you - time. After export, you can edit these to remove the options and - make them short answer questions or even add additional question - types to your slides. - - - Aila is still very much in development and we're aiming to - add more question types in future. - -
    - -
    - - Support and assistance - -
    - -
    - - Is support available if I encounter any issues or have - questions? - - - - Yes, we provide comprehensive support to assist with any issues - or questions users may have. You can contact us via{" "} - email. - - - Can I provide feedback or suggest improvements for Aila? - - - Yes, please do! We love to hear how users are finding our - resources and how we can improve them. Submit your{" "} - - feedback or suggestions{" "} - - . - - - - Are there resources available for troubleshooting common - problems? - - - The more feedback we receive from users, the more we can - identify common problems and provide troubleshooting tips. - -
    - -
    - - Accessibility - -
    - -
    - - Are there features in place to support diverse learners and - educators? - - - We want as many people as possible to be able to use Aila. You - should be able to; change colours, contrast levels, and fonts; - read and use most of the website while zoomed in up to 400%; - navigate most of the website using just a keyboard; navigate - most of the website using speech recognition software; listen to - most of the website using a screen reader (including the most - recent versions of JAWS, NVDA, and VoiceOver). View our{" "} - - full accessibility statement - - . - - - Can lesson plans be adapted for students with SEND? - - - Of course! You can prompt Aila to factor in your pupils' - needs when generating your lesson plan. Try asking Aila to - produce texts of different reading ages, sentence starters, or - alternative activities to support pupils during the additional - materials section of the lesson. You are also able to download - and edit all resources after you have created your lesson. - -
    - -
    - - Usage and best practices - -
    - -
    - - What are some best practices for maximising the effectiveness of - Aila? - - - Work with Aila to co-create your lesson. Before you proceed to - the next steps of co-creating your lesson with Aila, it is - important to check that you are happy with your lesson outcomes - and learning cycle outcomes, as this will determine the content - for the rest of the lesson. - - - If you want the content to be adapted for a specific - geographical context, reading age or a specific pupil need, tell - Aila at the start so that that is taken into consideration when - designing the lesson content. - - - The additional materials section of the lesson is the most - flexible. If you would like teacher instructions for a practical - lesson, model answers, essay-style questions, narratives for - your explanations or texts differentiated by reading age for - your classes, just ask at the end of the lesson planning process - and Aila will create these for you. - -
    - -
    - - Technical - -
    - -
    - - How does Aila work? - - - Aila is built to use Chat GPT4, but we are also evaluating other - models. We have written a 9,000-word prompt that provides very - specific guidance on what excellence looks like for each section - of a lesson. - - - Aila also uses retrieval augmented generation (RAG) to integrate - the high-quality content of Oak's human-planned lessons - into the lessons being delivered. This means that the accuracy - of the content produced should be closely aligned with the needs - of teachers in England. - -
    - -
    - - Updates and enhancements - -
    - -
    - - Are there plans for future enhancements or new features? - - - Yes, we strive to constantly improve our resources, taking into - account feedback from our users - Aila is still very much in - development. We aim to release future iterations of Aila that - produce images and diagrams. We are also developing Aila to - ensure that it has pedagogical rigour for a range of different - subjects. - - - Can users suggest features for future updates? - - - Of course, we would love to hear your thoughts and suggestions - for other features that would support your teaching. Please{" "} - - give us your feedback! - - - - - How often are updates released for Aila? - - - We're still in the beta phase, which means that whilst - we're allowing teachers to use it, it's still prone to - bugs and errors, and is still under constant development. - We're constantly receiving feedback and aim to improve and - iterate on an almost daily basis! - - - - How will Aila be evaluated? - - - The team at Oak constantly evaluates Aila, and we are designing - multiple approaches to this. We carry out consistency checks and - ensure that it follows the instructions we have built into the - prompt, and evaluate the quality of content being produced. - - - We aim to evaluate several factors, such as Americanisms, - cultural biases, the appropriateness of the literacy level, - checking that the learning cycles increase in difficulty, and - more. - - - Nonetheless, generative AI will make mistakes, and the outputs - should be checked carefully. - -
    - -
    - - Other concerns - -
    - -
    - - Is Oak trying to replace teachers with AI? - - - Absolutely not! At Oak, we share the brilliance of teachers from - across the country through our resources, and our Aila is no - different. It is designed to keep teachers in the driving seat, - with support from AI to reduce their workload. - -
    - -
    - - Data privacy and security - -
    - -
    - - Is Aila safe to use? - - - Generative AI will make mistakes, and no two outputs are the - same. With that in mind, it's important to check any - AI-generated content thoroughly before using it in the - classroom. We have put in place a number of technical and policy - measures to minimise the risks that generative AI presents but - care should still be taken, for example, you must not input - personally identifiable information into Aila, and this is in - breach of the terms and conditions of use. - - - - Can I have unlimited use? - - - In order to prevent misuse, we've restricted and protected - the volume of requests that can be made, lessons, and resources - that can be generated. If you're reaching these limits, - we'd love to hear from you, and you can{" "} - - request a higher limit. - - - - - What ethical measures are you putting in place? - - - Generative AI is a new and cutting-edge technology, and - it's important that anyone developing AI products actively - takes into account privacy, security and ethical considerations. - We have looked into emerging guidance and governance on - generative AI, including; - - - - UNESCO's core principles on{" "} - - a human-rights centred approach to the Ethics of AI - - - - US office for Edtech;{" "} - - Artificial Intelligence and the Future of Teaching and - Learning - - - - UK DfE position on{" "} - - Generative artificial intelligence (AI) in education - - - - Aila is designed to: - - - - keep the human in the loop, informing and involving expert - teachers and educators in the process - - - - - not involve the input of personal information to LLMs - - - - - allow us to evaluate cultural biases that may be present in - the generated content - - - - - create guardrails around the generative AI to improve - pedagogical alignment - - - - - be transparent and explainable to users; we openly share the - underlying prompts - - - -
    - -
    - - Aila - -
    - -
    - - Why did you decide to name Oak's AI lesson assistant, Aila? - - - The name is an acronym for 'AI lesson assistant'. We - wanted the name to have 'AI' in it, as our research - found that teachers would be more likely to use an AI product if - it was clear that it was AI-powered and could save them time. - Further research into the name led to some deeper connections - which helped to solidify our decision. 'Aila' means - 'oak tree' in Hebrew, and in Scottish Gaelic, Aila - means 'from the strong place'. We believe the rigour - and quality of Aila stems from the strong foundation provided by - both Oak's strong curriculum principles and the - high-quality, teacher-generated content that we have been able - to integrate into the lesson development process. - - - Why did you give it a human name? - - - In Aila's initial testing phases, users reported being - unsure of how to 'talk' to the assistant. Giving it a - name humanises the chatbot and encourages more natural - conversation. - -
    -
    - - - +
    + +
    + + Aila + +
    + +
    + + Why did you decide to name Oak's AI lesson assistant, Aila? + + + The name is an acronym for 'AI lesson assistant'. We + wanted the name to have 'AI' in it, as our research + found that teachers would be more likely to use an AI product if + it was clear that it was AI-powered and could save them time. + Further research into the name led to some deeper connections + which helped to solidify our decision. 'Aila' means + 'oak tree' in Hebrew, and in Scottish Gaelic, Aila means + 'from the strong place'. We believe the rigour and + quality of Aila stems from the strong foundation provided by both + Oak's strong curriculum principles and the high-quality, + teacher-generated content that we have been able to integrate into + the lesson development process. + + + Why did you give it a human name? + + + In Aila's initial testing phases, users reported being unsure + of how to 'talk' to the assistant. Giving it a name + humanises the chatbot and encourages more natural conversation. + +
    +
    +
    +
    ); }; diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-message/index.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-message/index.tsx index b29b77a29..6bcab07d9 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-message/index.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-message/index.tsx @@ -8,7 +8,6 @@ import type { BadDocument, CommentDocument, ErrorDocument, - ExperimentalPatchDocument, MessagePart, ModerationDocument, PatchDocument, @@ -136,17 +135,17 @@ export function ChatMessage({ errorType={hasError ? "generic" : null} type={getAvatarType()} > -
    { setInspect(!inspect); }} /> {message.id !== "working-on-it-initial" && - messageParts.map((part, index) => { + messageParts.map((part) => { return ( -
    +
    ) { - const markdown = part.message || "Sorry, an error has occurred"; + const markdown = part.message ?? "Sorry, an error has occurred"; return ; } diff --git a/apps/nextjs/src/components/AppComponents/Chat/chat-start-accordion.tsx b/apps/nextjs/src/components/AppComponents/Chat/chat-start-accordion.tsx index 0fecdf1e6..4ce5992b9 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/chat-start-accordion.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/chat-start-accordion.tsx @@ -32,7 +32,7 @@ const ChatStartAccordion = () => { section !== "Title" && section !== "Key stage" && section !== "Subject" && - section !== "Prior lnowledge" && + section !== "Prior knowledge" && section !== "Key learning points" && section !== "Misconceptions" && section !== "Learning cycle 1" && diff --git a/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx b/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx index d935e040c..fcee6eb5b 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/markdown.tsx @@ -97,7 +97,7 @@ export const MemoizedReactMarkdownWithStyles = ({ children[0] = (children[0] as string).replace("`▍`", "▍"); } - const match = /language-(\w+)/.exec(className || ""); + const match = /language-(\w+)/.exec(className ?? ""); if (inline) { return ( @@ -110,7 +110,7 @@ export const MemoizedReactMarkdownWithStyles = ({ return ( diff --git a/apps/nextjs/src/components/Footer.tsx b/apps/nextjs/src/components/Footer.tsx index 194b60aee..25462a3b4 100644 --- a/apps/nextjs/src/components/Footer.tsx +++ b/apps/nextjs/src/components/Footer.tsx @@ -1,7 +1,6 @@ "use client"; import { useAuth } from "@clerk/nextjs"; -import type { OakIconName } from "@oaknational/oak-components"; import { OakBox, OakFlex, @@ -230,7 +229,7 @@ const FooterButton = ({ $textDecoration="none" > {children} - {href && href.includes("http") && ( + {href?.includes("http") && ( diff --git a/apps/nextjs/src/utils/constructOwaLessonUrl.ts b/apps/nextjs/src/utils/constructOwaLessonUrl.ts index b2ddc7a32..58315815f 100644 --- a/apps/nextjs/src/utils/constructOwaLessonUrl.ts +++ b/apps/nextjs/src/utils/constructOwaLessonUrl.ts @@ -42,7 +42,6 @@ export function constructOwaLessonUrl( if (lessonSlug && safeParsedKeyStage && primaryOrSecondary && subjectSlug) { return `/teachers/programmes/${syntheticProgrammeSlug}/units/${unitSlug}/lessons/${lessonSlug}`; } - return; } type KeyStage = z.infer; diff --git a/packages/aila/src/core/Aila.ts b/packages/aila/src/core/Aila.ts index da30dc549..178994094 100644 --- a/packages/aila/src/core/Aila.ts +++ b/packages/aila/src/core/Aila.ts @@ -44,23 +44,23 @@ import type { const log = aiLogger("aila"); export class Aila implements AilaServices { private _initialised: boolean = false; // We have a separate flag for this because we have an async initialise method which cannot be called in the constructor - private _analytics?: AilaAnalyticsFeature; - private _chat: AilaChatService; - private _errorReporter?: AilaErrorReportingFeature; + private readonly _analytics?: AilaAnalyticsFeature; + private readonly _chat: AilaChatService; + private readonly _errorReporter?: AilaErrorReportingFeature; private _isShutdown: boolean = false; - private _lesson: AilaLessonService; - private _chatLlmService: LLMService; - private _moderation?: AilaModerationFeature; - private _options: AilaOptionsWithDefaultFallbackValues; - private _snapshotStore: AilaSnapshotStore; - private _persistence: AilaPersistenceFeature[] = []; - private _threatDetection?: AilaThreatDetectionFeature; - private _prisma: PrismaClientWithAccelerate; - private _rag: AilaRagFeature; - private _plugins: AilaPlugin[]; - private _userId!: string | undefined; - private _chatId!: string; - private _americanisms: AilaAmericanismsFeature; + private readonly _lesson: AilaLessonService; + private readonly _chatLlmService: LLMService; + private readonly _moderation?: AilaModerationFeature; + private readonly _options: AilaOptionsWithDefaultFallbackValues; + private readonly _snapshotStore: AilaSnapshotStore; + private readonly _persistence: AilaPersistenceFeature[] = []; + private readonly _threatDetection?: AilaThreatDetectionFeature; + private readonly _prisma: PrismaClientWithAccelerate; + private readonly _rag: AilaRagFeature; + private readonly _plugins: AilaPlugin[]; + private readonly _userId!: string | undefined; + private readonly _chatId!: string; + private readonly _americanisms: AilaAmericanismsFeature; constructor(options: AilaInitializationOptions) { this._userId = options.chat.userId; diff --git a/packages/aila/src/core/chat/AilaChat.ts b/packages/aila/src/core/chat/AilaChat.ts index 1f6d75ced..7283eb01f 100644 --- a/packages/aila/src/core/chat/AilaChat.ts +++ b/packages/aila/src/core/chat/AilaChat.ts @@ -7,8 +7,7 @@ import { aiLogger } from "@oakai/logger"; import invariant from "tiny-invariant"; import { DEFAULT_MODEL, DEFAULT_TEMPERATURE } from "../../constants"; -import type { AilaChatService } from "../../core/AilaServices"; -import type { AilaServices } from "../../core/AilaServices"; +import type { AilaChatService, AilaServices } from "../../core/AilaServices"; import { AilaGeneration } from "../../features/generation/AilaGeneration"; import type { AilaGenerationStatus } from "../../features/generation/types"; import { generateMessageId } from "../../helpers/chat/generateMessageId"; @@ -51,7 +50,7 @@ export class AilaChat implements AilaChatService { private _iteration: number | undefined; private _createdAt: Date | undefined; private _persistedChat: AilaPersistedChat | undefined; - private _experimentalPatches: ExperimentalPatchDocument[]; + private readonly _experimentalPatches: ExperimentalPatchDocument[]; constructor({ id, diff --git a/packages/aila/src/core/chat/AilaStreamHandler.ts b/packages/aila/src/core/chat/AilaStreamHandler.ts index 656ee0370..bfd740457 100644 --- a/packages/aila/src/core/chat/AilaStreamHandler.ts +++ b/packages/aila/src/core/chat/AilaStreamHandler.ts @@ -9,9 +9,9 @@ import type { PatchEnqueuer } from "./PatchEnqueuer"; const log = aiLogger("aila:stream"); export class AilaStreamHandler { - private _chat: AilaChat; + private readonly _chat: AilaChat; private _controller?: ReadableStreamDefaultController; - private _patchEnqueuer: PatchEnqueuer; + private readonly _patchEnqueuer: PatchEnqueuer; private _streamReader?: ReadableStreamDefaultReader; constructor(chat: AilaChat) { diff --git a/packages/aila/src/core/lesson/AilaLesson.ts b/packages/aila/src/core/lesson/AilaLesson.ts index 8f9ee63c3..da374e0d5 100644 --- a/packages/aila/src/core/lesson/AilaLesson.ts +++ b/packages/aila/src/core/lesson/AilaLesson.ts @@ -15,12 +15,12 @@ import type { Message } from "../chat"; const log = aiLogger("aila:lesson"); export class AilaLesson implements AilaLessonService { - private _aila: AilaServices; + private readonly _aila: AilaServices; private _plan: LooseLessonPlan; private _hasSetInitialState = false; - private _appliedPatches: ValidPatchDocument[] = []; - private _invalidPatches: ValidPatchDocument[] = []; - private _categoriser: AilaCategorisationFeature; + private readonly _appliedPatches: ValidPatchDocument[] = []; + private readonly _invalidPatches: ValidPatchDocument[] = []; + private readonly _categoriser: AilaCategorisationFeature; constructor({ aila, diff --git a/packages/aila/src/core/llm/MockLLMService.ts b/packages/aila/src/core/llm/MockLLMService.ts index 034c94f60..c9b4dc744 100644 --- a/packages/aila/src/core/llm/MockLLMService.ts +++ b/packages/aila/src/core/llm/MockLLMService.ts @@ -7,7 +7,7 @@ async function sleep(ms: number) { export class MockLLMService implements LLMService { name = "MockLLM"; private responseChunks: string[]; - private responseObject: Record; + private readonly responseObject: Record; constructor( responseChunks: string[] = ["This is ", "a mock ", "response."], diff --git a/packages/aila/src/core/llm/OpenAIService.ts b/packages/aila/src/core/llm/OpenAIService.ts index 6f3d0047f..7ea16718e 100644 --- a/packages/aila/src/core/llm/OpenAIService.ts +++ b/packages/aila/src/core/llm/OpenAIService.ts @@ -11,9 +11,9 @@ import type { LLMService } from "./LLMService"; const log = aiLogger("aila:llm"); const STRUCTURED_OUTPUTS_ENABLED = - process.env.NEXT_PUBLIC_STRUCTURED_OUTPUTS_ENABLED === "true" ? true : false; + process.env.NEXT_PUBLIC_STRUCTURED_OUTPUTS_ENABLED === "true"; export class OpenAIService implements LLMService { - private _openAIProvider: OpenAIProvider; + private readonly _openAIProvider: OpenAIProvider; public name = "OpenAIService"; diff --git a/packages/aila/src/core/prompt/builders/AilaLessonPromptBuilder.ts b/packages/aila/src/core/prompt/builders/AilaLessonPromptBuilder.ts index a6142cd71..8c05b8bb3 100644 --- a/packages/aila/src/core/prompt/builders/AilaLessonPromptBuilder.ts +++ b/packages/aila/src/core/prompt/builders/AilaLessonPromptBuilder.ts @@ -114,9 +114,7 @@ export class AilaLessonPromptBuilder extends AilaPromptBuilder { lessonPlanJsonSchema: JSON.stringify(LessonPlanJsonSchema), llmResponseJsonSchema: JSON.stringify(LLMResponseJsonSchema), isUsingStructuredOutput: - process.env.NEXT_PUBLIC_STRUCTURED_OUTPUTS_ENABLED === "true" - ? true - : false, + process.env.NEXT_PUBLIC_STRUCTURED_OUTPUTS_ENABLED === "true", }; return template(args); diff --git a/packages/aila/src/features/analytics/AilaAnalytics.ts b/packages/aila/src/features/analytics/AilaAnalytics.ts index 0a28776eb..5d07854ce 100644 --- a/packages/aila/src/features/analytics/AilaAnalytics.ts +++ b/packages/aila/src/features/analytics/AilaAnalytics.ts @@ -2,9 +2,9 @@ import type { AilaServices } from "../../core/AilaServices"; import type { AnalyticsAdapter } from "./adapters/AnalyticsAdapter"; export class AilaAnalytics { - private _aila: AilaServices; - private _adapters: AnalyticsAdapter[]; - private _operations: Promise[] = []; + private readonly _aila: AilaServices; + private readonly _adapters: AnalyticsAdapter[]; + private readonly _operations: Promise[] = []; private _isShutdown: boolean = false; constructor({ diff --git a/packages/aila/src/features/analytics/adapters/DatadogAnalyticsAdapter.ts b/packages/aila/src/features/analytics/adapters/DatadogAnalyticsAdapter.ts index 6b234e182..c21795237 100644 --- a/packages/aila/src/features/analytics/adapters/DatadogAnalyticsAdapter.ts +++ b/packages/aila/src/features/analytics/adapters/DatadogAnalyticsAdapter.ts @@ -6,7 +6,7 @@ import { AnalyticsAdapter } from "./AnalyticsAdapter"; const log = aiLogger("aila:analytics"); export class DatadogAnalyticsAdapter extends AnalyticsAdapter { - private _startedAt: number = Date.now(); + private readonly _startedAt: number = Date.now(); public initialiseAnalyticsContext() { // Implement any necessary initialisation logic for Datadog diff --git a/packages/aila/src/features/analytics/adapters/PosthogAnalyticsAdapter.ts b/packages/aila/src/features/analytics/adapters/PosthogAnalyticsAdapter.ts index 4b0edb998..70552f243 100644 --- a/packages/aila/src/features/analytics/adapters/PosthogAnalyticsAdapter.ts +++ b/packages/aila/src/features/analytics/adapters/PosthogAnalyticsAdapter.ts @@ -7,8 +7,8 @@ import { reportCompletionAnalyticsEvent } from "../../../lib/openai/OpenAIComple import { AnalyticsAdapter } from "./AnalyticsAdapter"; export class PosthogAnalyticsAdapter extends AnalyticsAdapter { - private _posthogClient: PostHog; - private _startedAt: number = Date.now(); + private readonly _posthogClient: PostHog; + private readonly _startedAt: number = Date.now(); private _isShutdown: boolean = false; constructor(aila: AilaServices) { diff --git a/packages/exports/src/gSuite/slides/deleteSlides.ts b/packages/exports/src/gSuite/slides/deleteSlides.ts index 0e2370641..1b86378c1 100644 --- a/packages/exports/src/gSuite/slides/deleteSlides.ts +++ b/packages/exports/src/gSuite/slides/deleteSlides.ts @@ -2,6 +2,7 @@ import type { slides_v1 } from "@googleapis/slides"; import type { Result } from "../../types"; +// #TODO Remove this string fallback and properly type the speaker notes tags export type SpeakerNotesTag = "cycle1" | "cycle2" | "cycle3" | string; function getSpeakerNotes(slide: slides_v1.Schema$Page): string { diff --git a/sonar-project.properties b/sonar-project.properties index fe5f8b69b..e117efe64 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -11,6 +11,7 @@ sonar.sources=. sonar.exclusions=\ apps/nextjs/src/lib/avo/Avo.ts pnpm-lock.yaml + apps/nextjs/.storybook/public/mockServiceWorker.js sonar.cpd.exclusions=\ **/*.test.ts, \ From 844ed484b71f34fba58b00639b340a89a61032b4 Mon Sep 17 00:00:00 2001 From: Joe Baker Date: Tue, 26 Nov 2024 15:19:05 +0000 Subject: [PATCH 04/68] chore: copy updates for help page - AI-492 (#367) --- apps/nextjs/src/app/aila/help/index.tsx | 426 +++++++++++++----------- 1 file changed, 240 insertions(+), 186 deletions(-) diff --git a/apps/nextjs/src/app/aila/help/index.tsx b/apps/nextjs/src/app/aila/help/index.tsx index 0afe5c594..355ae6257 100644 --- a/apps/nextjs/src/app/aila/help/index.tsx +++ b/apps/nextjs/src/app/aila/help/index.tsx @@ -1,23 +1,36 @@ "use client"; -import { useRef } from "react"; +import { useRef, type MutableRefObject } from "react"; -import { OakLink } from "@oaknational/oak-components"; +import { + OakBox, + OakFlex, + OakGrid, + OakGridArea, + OakHeading, + OakLI, + OakLink, + OakMaxWidth, + OakP, + OakUL, +} from "@oaknational/oak-components"; import { useSearchParams } from "next/navigation"; -import { Header } from "@/components/AppComponents/Chat/header"; import GetInTouchBox from "@/components/AppComponents/GetInTouchBox"; +import Layout from "@/components/Layout"; export const HelpContent = () => { const startingRef = useRef(null); const structureRef = useRef(null); + const learningCycles = useRef(null); const downloadsRef = useRef(null); + const additionalMaterialsRef = useRef(null); const creatingRef = useRef(null); const reviewingRef = useRef(null); const downloadingRef = useRef(null); const aiRef = useRef(null); - const scrollToRefWithOffset = (ref) => { + const scrollToRefWithOffset = (ref: MutableRefObject) => { if (ref?.current) { const yOffset = -72; // Adjust this value as needed const y = @@ -30,200 +43,241 @@ export const HelpContent = () => { const ailaId = searchParams.get("ailaId"); return ( -
    -
    -
    -

    Help

    -
      -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    -
    - -
    -
    - - Back to Aila - -
    - -
    - -
    -

    - Starting your first lesson -

    -

    - Create your first lesson by typing a lesson title and key stage into - the input box on the first screen and clicking the arrow key. This - will create the starting point of your lesson. You can get back to - the initial screen by clicking 'New lesson' in the main - navigation. -

    -

    - Structure of an Oak lesson -

    -

    - Lessons are created using Oak's curriculum principles and - include the following sections: -

    -
      -
    • Learning outcome
    • -
    • Learning cycle outcomes
    • -
    • Prior knowledge
    • -
    • Key learning points
    • -
    • Misconceptions
    • -
    • Starter quiz
    • -
    • Learning cycles
    • -
    • Exit quiz
    • -
    • Additional materials (optional)
    • -
    -

    Learning cycles

    -

    Each learning cycle includes 4 key sections:

    -
      -
    • Explanation
    • -
    • Checks for understanding
    • -
    • Practice
    • -
    • Feedback
    • -
    -

    - Downloads -

    -

    - Once the lesson has been created (and all sections are complete) you - will be able to download the following documents: -

    -
      -
    • Lesson, including all sections (PDF/Docx file)
    • -
    • Starter quiz (PDF/Docx file)
    • -
    • Slides (PDF/PPTX file)
    • -
    • Exit quiz (PDF/Docx file)
    • -
    -

    - If you have a Google account, you will also be able to edit these - documents directly. -

    -

    - Examples of additional materials -

    -

    - Health and safety information, lesson narration, model answers or - additional practice tasks. -

    -

    - Co-creating your lesson -

    -

    - Aila, Oak's AI lesson assistant will guide you through the - process of co-creating each section of your lesson on the left-hand - side of the screen. The lesson output will be generated on the - right-hand side. -

    -

    - Reviewing and editing -

    -

    - Aila will pause at key points during the lesson creation and will - ask you to review the content generated. You can ask Aila to adapt - each section, for example: -

    -
      -
    • adapt the content for a specific reading age.
    • -
    • add specific case studies or examples to your explanations.
    • -
    • change the practice tasks for you.
    • -
    • - add a narrative for each learning cycle to the Additional - Materials. -
    • -
    -

    - Downloading and sharing -

    -

    - When you have completed all the sections in the lesson, you will be - able to download the lesson resources, including the full lesson - plan (which includes all sections), editable slides and starter and - exit quizzes. You can also share your lesson as a link, which can be - viewed online. -

    -

    - AI and accuracy -

    -

    - Retrieval Augmented Generation is used to integrate Oak content into - your lessons, improving the accuracy of the content produced. AI is - not 100% accurate and mistakes can still be made. Remember, - you're still the expert, so please ensure all content is - reviewed before using it in a classroom or sharing. -

    -
    -
    -
    + + + Retrieval augmented generation is used to integrate Oak content + into your lessons, improving the accuracy of the content + produced. AI is not 100% accurate and mistakes can still be + made. Remember, you’re still the expert, so please ensure all + content is reviewed before using it in a classroom or sharing. + + + + + + ); }; -export default function HelpPage() { +export default function HelpPageView() { return ( - <> -
    + - + ); } From 015cd25984c3e5d1a545afef39fd111aa5245d58 Mon Sep 17 00:00:00 2001 From: Stef Lewandowski Date: Tue, 26 Nov 2024 17:18:40 +0000 Subject: [PATCH 05/68] fix: minor sonar issues (#390) --- .../AppComponents/Chat/ui/codeblock.tsx | 6 +- .../AppComponents/Chat/user-or-login.tsx | 22 +++---- .../FeedbackForms/ModerationFeedbackForm.tsx | 62 +++++++++---------- .../GenerationInputAndText.tsx | 4 +- .../ContextProviders/AnalyticsProvider.tsx | 11 ++-- 5 files changed, 51 insertions(+), 54 deletions(-) diff --git a/apps/nextjs/src/components/AppComponents/Chat/ui/codeblock.tsx b/apps/nextjs/src/components/AppComponents/Chat/ui/codeblock.tsx index 1633f7d0c..fc4fcfa01 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/ui/codeblock.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/ui/codeblock.tsx @@ -18,11 +18,11 @@ interface Props { value: string; } -interface languageMap { +interface LanguageMap { [key: string]: string | undefined; } -const programmingLanguages: languageMap = { +const programmingLanguages: LanguageMap = { javascript: ".js", python: ".py", java: ".java", @@ -65,7 +65,7 @@ const CodeBlock: FC = memo(({ language, value }) => { if (typeof window === "undefined") { return; } - const fileExtension = programmingLanguages[language] || ".file"; + const fileExtension = programmingLanguages[language] ?? ".file"; const suggestedFileName = `file-${generateRandomString( 3, true, diff --git a/apps/nextjs/src/components/AppComponents/Chat/user-or-login.tsx b/apps/nextjs/src/components/AppComponents/Chat/user-or-login.tsx index 940a8f76d..f1cd37291 100644 --- a/apps/nextjs/src/components/AppComponents/Chat/user-or-login.tsx +++ b/apps/nextjs/src/components/AppComponents/Chat/user-or-login.tsx @@ -10,17 +10,15 @@ export function UserOrLogin() { return <>; } return ( - <> -
    - - - - - - -
    - +
    + + + + + + +
    ); } diff --git a/apps/nextjs/src/components/AppComponents/FeedbackForms/ModerationFeedbackForm.tsx b/apps/nextjs/src/components/AppComponents/FeedbackForms/ModerationFeedbackForm.tsx index 22366e46a..e5a072be0 100644 --- a/apps/nextjs/src/components/AppComponents/FeedbackForms/ModerationFeedbackForm.tsx +++ b/apps/nextjs/src/components/AppComponents/FeedbackForms/ModerationFeedbackForm.tsx @@ -46,39 +46,35 @@ export const ModerationFeedbackForm = ({ />
    - <> -
    - - Guidance required - - - - Contains{" "} - {moderation.categories - .map(moderationSlugToDescription) - .join(", ")} - . Check content carefully. If you have feedback on this guidance, - please provide details below. - - -
    -
    -