Inspiration

We wanted to challenge ourselves by using Presage and its SDK as a large part of our project.

What it does

Focus Up using a combination of eyetracking, object detection, and biometric data captured through your camera along with what you're viewing on your screen to figure out whether or not your focused up and therefore being productive. Focus Up gives gentle reminders when its confident that you're being distracted and gives analytics about your study sessions. Our study buddy, uses Eleven Labs' voices increasing with sterness dpending how unproductive you are and the duration of that period.

How we built it

We first split apart, one of us worked on learning how chrome extensions were built, while the last person was figuring out elevenlabs. We were able to work all of these out eventually, although connecting the Presage SDK with extension was more than just a hassle. After which we built our website and dashboard and connected those to extension.

Challenges we ran into

Firstly the connecting the Presage SDK and having everthing work was by far one of the hardes issues. We were at the point of wondering whether or not it was even posssible and if we should just give up. We figured out the issued had to do with how the video was being sent and rather than sending clips of camera captures we opted with a live feed. This meant setting NGROK and a web socket to essentially live stream each attentiveness calcuation session (30 seconds every 5 minutes to avoid excess usage of credits).

On top of that Eleven Labs began to become a problem at the tail end as we realized we couldn't use a Node.js server on a chrome extension and be able to publish it. Leaving us to use the javascript SDK and adjusting how we desgined it.

Extension Tool

The lightweightedness of chrome's extensions makes it a prime tool for this project. It means its easily installable and user friendly while giving FocusUp the access it needs to read data and calculate attention scores and etc. It also helps the user manage their study sessions and be reminded when they're off topic.

Escalating Voice Nudges with ElevenLabs

We built a 5 message escalation system that gets progressively more intense. The TTS voice parameters are linear functions of the escalation tier:

function voiceSettingsForTier(tier: number): ElevenLabsVoiceSettings {
  const t = Math.min(4, Math.max(0, tier))
  return {
    stability: 0.72 - t * 0.1,        // calmer → more erratic
    similarity_boost: 0.78 - t * 0.02,
    style: 0.12 + t * 0.14,           // neutral → expressive
    use_speaker_boost: true,
  }
}

Eyetracking & Head Pose Detection

We use MediaPipe BlazeFace to extract three keypoints per frame both eyes and the nose tip and compute five normalised pose ratios in real time:

const eyeBalance     = Math.abs(noseTip.x - eyeMidX) / box.width
const noseFaceRatioX = Math.abs(noseTip.x - faceCenterX) / box.width
const eyeTilt        = Math.abs(leftEye.y - rightEye.y) / box.height
const lookDownRatio  = (noseTip.y - eyeMidY) / box.height
const lookUpMargin   = LOOK_UP_THRESHOLD - lookDownRatio

These ratios are checked against calibrated thresholds to determine yaw, roll, and pitch and the distraction rules change depending on what you're doing:

if (mode === "video") {
  // Screen-only: no glancing up or down
  distracted = faceTooSmall || poseAwayFromScreen || lookingDown || lookingUp
} else if (mode === "lecture") {
  // Allow glancing up at the board/instructor
  if (lookingUp) {
    distracted = faceTooSmall
  } else {
    distracted = faceTooSmall || poseAwayFromScreen || lookingDown
  }
} else {
  // Notes mode: can look down at paper, but not up
  distracted = faceTooSmall || poseAwayFromScreen || lookingUp
}

Biometric Attentiveness via Presage

Raw attentiveness scores from Presage are transformed through a logistic sigmoid so the display feels more responsive to the user:

export function adjustAttentivenessScore(score: number): number {
  const k = 0.18  // steeper curve
  const x0 = 45   // shift left so 55 is already "high"
  return 100 / (1 + Math.exp(-k * (score - x0)))
}

Accomplishments that we're proud of

Seeing the first score come and seeing our heartrates at about 8 am was well worth it. We spent almost the entire night trying to figure it out and to say the morale was low would be an understatement.

Raw attentiveness scores from Presage are transformed through a logistic sigmoid so the display feels more responsive to the user:

export function adjustAttentivenessScore(score: number): number {
  const k = 0.18  // steeper curve
  const x0 = 45   // shift left so 55 is already "high"
  return 100 / (1 + Math.exp(-k * (score - x0)))
}```

## What we learned
We definitely learned a lot about specific tools that aren't as widely used but still have great potential and how to implement them together along with combinging everything and building an architecture for all of the end points and data. 

## What's next for Focus Up
We want to improve quality of life on the platform and continue to increase accuracy along with just making the UX/UI more consistency and just a better overall feel.
Studying more about how people focus with biometrics would also be incredibly useful
Share this project:

Updates