Draft of the SocratiQ bot

This commit is contained in:
Vijay Janapa Reddi
2024-11-11 20:16:32 -05:00
parent 0b652a4635
commit 909f3c5ac5
22 changed files with 355 additions and 10 deletions

View File

@@ -0,0 +1,7 @@
title: Lightbox
author: Posit Software, PBC
version: 0.1.9
quarto-required: ">=1.2.198"
contributes:
filters:
- lightbox.lua

View File

@@ -0,0 +1,9 @@
body:not(.glightbox-mobile) div.gslide div.gslide-description,
body:not(.glightbox-mobile) div.gslide-description .gslide-title,
body:not(.glightbox-mobile) div.gslide-description .gslide-desc {
color: var(--quarto-body-color);
background-color: var(--quarto-body-bg);
}

View File

@@ -0,0 +1,251 @@
-- whether we're automatically lightboxing
local auto = false
-- whether we need lightbox dependencies added
local needsLightbox = false
-- a counter used to ensure each image is in its own gallery
local imgCount = 0
-- attributes to forward from the image to the newly created link
local kDescription = "description"
local kForwardedAttr = {
"title", kDescription, "desc-position",
"type", "effect", "zoomable", "draggable"
}
local kLightboxClass = "lightbox"
local kNoLightboxClass = "nolightbox"
local kGalleryPrefix = "quarto-lightbox-gallery-"
-- A list of images already within links that we can use to filter
local imagesWithinLinks = pandoc.List({})
local function readAttrValue(el, attrName)
if attrName == kDescription then
local doc = pandoc.read(el.attr.attributes[attrName])
local attrInlines = doc.blocks[1].content
return pandoc.write(pandoc.Pandoc(attrInlines), "html")
else
return el[attrName]
end
end
return {
{
Meta = function(meta)
-- If the mode is auto, we need go ahead and
-- run if there are any images (ideally we would)
-- filter to images in the body, but that can be
-- left for future me to deal with
-- supports:
-- lightbox: auto
-- or
-- lightbox:
-- match: auto
local lbMeta = meta.lightbox
if lbMeta ~= nil and type(lbMeta) == 'table' then
if lbMeta[1] ~= nil then
if lbMeta[1]['text'] == "auto" then
auto = true
end
elseif lbMeta.match ~= nil and pandoc.utils.stringify(lbMeta.match) == 'auto' then
auto = true
elseif lbMeta == true then
auto = true
end
end
end,
-- Find images that are already within links
-- we'll use this to filter out these images if
-- the most is auto
Link = function(linkEl)
pandoc.walk_inline(linkEl, {
Image = function(imageEl)
imagesWithinLinks[#imagesWithinLinks + 1] = imageEl
end
})
end
},{
Div = function(div)
if div.classes:includes("cell") and div.attributes["lightbox"] ~= nil then
meta = quarto.json.decode(div.attributes["lightbox"])
local imgCount=0
div = div:walk({
Image = function(imgEl)
imgCount = imgCount + 1
if (type(meta) == "table" and meta[kNoLightboxClass] == true) or meta == false then
imgEl.classes:insert(kNoLightboxClass)
else
if not auto and ((type(meta) == "table" and not meta[kNoLightboxClass]) or meta == true) then
imgEl.classes:insert(kLightboxClass)
end
if (type(meta) == "table") then
if meta.group then
imgEl.attr.attributes.group = meta.group or imgEl.attr.attributes.group
end
for _, v in next, kForwardedAttr do
if type(meta[v]) == "table" and #meta[v] > 1 then
-- if list attributes it should be one per plot
if imgCount > #meta[v] then
quarto.log.warning("More plots than '" .. v .. "' passed in YAML chunk options.")
else
attrLb = meta[v][imgCount]
end
else
-- Otherwise reuse the single attributes
attrLb = meta[v]
end
imgEl.attr.attributes[v] = attrLb or imgEl.attr.attributes[v]
end
end
end
return imgEl
end
})
div.attributes["lightbox"] = nil
end
return div
end
},
{
Image = function(imgEl)
if quarto.doc.is_format("html:js") then
local isAlreadyLinked = imagesWithinLinks:includes(imgEl)
if (not isAlreadyLinked and auto and not imgEl.classes:includes(kNoLightboxClass))
or imgEl.classes:includes('lightbox') then
-- note that we need to include the dependency for lightbox
needsLightbox = true
imgCount = imgCount + 1
-- remove the class from the image
imgEl.attr.classes = imgEl.attr.classes:filter(function(clz)
return clz ~= kLightboxClass
end)
-- attributes for the link
local linkAttributes = {}
-- mark this image as a lightbox target
linkAttributes.class = kLightboxClass
-- get the alt text from image and use that as title
local title = nil
if imgEl.caption ~= nil and #imgEl.caption > 0 then
linkAttributes.title = pandoc.utils.stringify(imgEl.caption)
elseif imgEl.attributes['fig-alt'] ~= nil and #imgEl.attributes['fig-alt'] > 0 then
linkAttributes.title = pandoc.utils.stringify(imgEl.attributes['fig-alt'])
end
-- move a group attribute to the link, if present
if imgEl.attr.attributes.group ~= nil then
linkAttributes.gallery = imgEl.attr.attributes.group
imgEl.attr.attributes.group = nil
else
linkAttributes.gallery = kGalleryPrefix .. imgCount
end
-- forward any other known attributes
for i, v in ipairs(kForwardedAttr) do
if imgEl.attr.attributes[v] ~= nil then
-- forward the attribute
linkAttributes[v] = readAttrValue(imgEl, v)
-- clear the attribute
imgEl.attr.attributes[v] = nil
end
-- clear the title
if (imgEl.title == 'fig:') then
imgEl.title = ""
end
end
-- wrap decorated images in a link with appropriate attrs
local link = pandoc.Link({imgEl}, imgEl.src, nil, linkAttributes)
return link
end
end
end,
Meta = function(meta)
-- If we discovered lightbox-able images
-- we need to include the dependencies
if needsLightbox then
-- add the dependency
quarto.doc.add_html_dependency({
name = 'glightbox',
scripts = {'resources/js/glightbox.min.js'},
stylesheets = {'resources/css/glightbox.min.css', 'lightbox.css'}
})
-- read lightbox options
local lbMeta = meta.lightbox
local lbOptions = {}
local readEffect = function(el)
local val = pandoc.utils.stringify(el)
if val == "fade" or val == "zoom" or val == "none" then
return val
else
error("Invalid effect " + val)
end
end
-- permitted options include:
-- lightbox:
-- effect: zoom | fade | none
-- desc-position: top | bottom | left |right
-- loop: true | false
-- class: <class-name>
local effect = "zoom"
local descPosition = "bottom"
local loop = true
local skin = nil
-- The selector controls which elements are targeted.
-- currently, it always targets .lightbox elements
-- and there is no way for the user to change this
local selector = "." .. kLightboxClass
if lbMeta ~= nil and type(lbMeta) == 'table' then
if lbMeta.effect ~= nil then
effect = readEffect(lbMeta.effect)
end
if lbMeta['desc-position'] ~= nil then
descPosition = pandoc.utils.stringify(lbMeta['desc-position'])
end
if lbMeta['css-class'] ~= nil then
skin = pandoc.utils.stringify(lbMeta['css-class'])
end
if lbMeta.loop ~= nil then
loop = lbMeta.loop
end
end
-- Generate the options to configure lightbox
local options = {
selector = selector,
closeEffect = effect,
openEffect = effect,
descPosition = descPosition,
loop = loop,
}
if skin ~= nil then
options.skin = skin
end
local optionsJson = quarto.json.encode(options)
-- generate the initialization script with the correct options
local scriptTag = "<script>var lightboxQuarto = GLightbox(" .. optionsJson .. ");</script>"
-- inject the rendering code
quarto.doc.include_text("after-body", scriptTag)
end
end
}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -96,8 +96,8 @@ book:
- contents/dedication.qmd
- contents/core/acknowledgements/acknowledgements.qmd
- contents/contributors.qmd
- contents/ai/socratiq.qmd
- contents/about.qmd
- contents/socratiq.qmd
- text: "---"
- contents/core/introduction/introduction.qmd
- contents/core/ml_systems/ml_systems.qmd
@@ -212,6 +212,7 @@ editor:
format:
html:
lightbox: true
theme:
light:
- default

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

84
contents/ai/socratiq.qmd Normal file
View File

@@ -0,0 +1,84 @@
# 🤖 SocratiQ AI Tutor {.unnumbered}
## Welcome to SocratiQ: Your AI Learning Assistant
We're excited to introduce SocratiQ (pronounced "Socratic"), an innovative AI learning assistant integrated throughout this textbook. SocratiQ helps reinforce your learning through interactive quizzes and personalized assistance. SocratiQ's goal is to adapt to your needs while generating targeted questions and engaging in meaningful dialogue about the material.
Please note that this is an experimental feature. We are experimenting with the idea of creating a dynamic and personalized learning experience by harnessing the power of generative AI. We hope that this approach will transform how you interact with and absorb the complex concepts.
:::{.callout-warning}
**About AI Responses**: While SocratiQ uses advanced AI to generate quizzes and provide assistance, like all AI systems, it may occasionally provide imperfect or incomplete answers. However, we've designed and tested it to ensure it's effective for supporting your learning journey. If you're unsure about any response, refer to the textbook content or consult your instructor.
:::
You can access SocratiQ at any time using a keyboard shortcut shown in @fig-main-shortcut, which brings up the interface shown in @fig-main-interface.
![Keyboard shortcut for SocratiQ.](images/png/shortcut.png){#fig-main-shortcut}
![The main SocratiQ interface, showing the key components of your AI learning assistant.](images/png/interface.png){#fig-main-interface}
## Personalizing Your Learning Experience
Before diving into your studies, take a moment to configure SocratiQ for your academic level. This initial setup ensures that all interactions, from quiz questions to explanations, are tailored to your background knowledge. @fig-settings-panel shows where you can adjust these preferences.
![The settings panel where you can customize SocratiQ to match your academic level.](images/png/settings.png){#fig-settings-panel}
## Learning with SocratiQ
As you progress through each section of the textbook, you'll find automatically generated quizzes designed to reinforce key concepts. These quizzes typically contain 3-5 questions, carefully crafted to check your understanding of the material you've just covered, as shown in @fig-quiz-interface.
![A typical quiz interface showing AI-generated questions.](images/png/quiz_button.png){#fig-quiz-interface}
After submitting your answers, SocratiQ provides immediate feedback and detailed explanations for each question, as demonstrated in @fig-quiz-feedback.
![Example of AI-generated feedback and explanations for quiz responses.](images/png/quiz_answers.png){#fig-quiz-feedback}
## Getting Help with Concepts
When you encounter challenging concepts, SocratiQ offers two powerful ways to get help. First, you can select any text from the textbook and ask for a detailed explanation, as demonstrated in @fig-text-selection.
![Selecting specific text to ask for clarification.](images/png/chat_context.png){#fig-text-selection}
Once you've selected the text, you can ask questions about it, and SocratiQ will provide detailed explanations based on that context, as illustrated in @fig-context-explanation.
![Example of how SocratiQ provides explanations based on selected text.](images/png/chat_ask.png){#fig-context-explanation}
@fig-interactive-chat shows the response for the ask in @fig-context-explanation.
![An interactive chat session with SocratiQ, demonstrating how to get clarification on concepts.](images/png/chat_explanation.png){#fig-interactive-chat}
To enhance your learning experience, SocratiQ doesn't just answer your questions---it also suggests related content from the textbook that might be helpful for deeper understanding, as shown in @fig-related-content.
![SocratiQ suggests related content based on your questions to help deepen your understanding.](images/png/chat_related.png){#fig-related-content}
## Tracking Your Progress
SocratiQ maintains a comprehensive record of your learning journey. The progress dashboard, shown in @fig-progress-dashboard, displays your quiz performance statistics, learning streaks, and achievement badges.
![The progress dashboard showing your learning statistics and achievements.](images/png/dashboard.png){#fig-progress-dashboard}
As you continue to engage with the material and complete quizzes, you'll earn various badges that recognize your progress, as shown in @fig-achievement-badges.
![Examples of achievement badges you can earn through consistent engagement.](images/png/badges.png){#fig-achievement-badges}
## Data Storage
:::{.callout-important}
**Important Note**: All progress data is stored locally in your browser. Clearing your browser history or cache will erase your entire learning history, including quiz scores, streaks, and achievement badges. Please keep this in mind before clearing browser data.
:::
## Technical Requirements
To use SocratiQ effectively, you'll need:
- Chrome or Safari browser
- JavaScript enabled
- Stable internet connection
## Providing Feedback
Your feedback helps us improve SocratiQ. You can report technical issues, suggest improvements to quiz questions, or share thoughts about AI responses using the feedback buttons located throughout the interface, as shown in @fig-feedback-interface.
![The location of feedback buttons and how to submit your suggestions.](images/png/buttons.png){#fig-feedback-interface}
Remember: SocratiQ is designed to help you learn effectively. By consistently engaging with the quizzes, asking questions when needed, and tracking your progress, you'll get the most out of this AI learning assistant.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,9 +0,0 @@
# SocratiQ {.unnumbered}
Coming soon.
## Generative Learning
...
## How to Use the AI Bot