Create Oracle Pattern Example

t-369.12·WorkTask·
·
·
·Omni/Agent.hs
Parent:t-369·Created1 month ago·Updated1 month ago

Dependencies

Description

Edit

Create an example demonstrating the Oracle pattern using Race.

Context

The Oracle pattern runs a high-capability model (e.g., Claude Opus, O3) alongside workers to provide architectural guidance. Uses Race to run advisory and work in parallel.

Deliverables

1. Create Omni/Agent/Programs/Oracle.hs

module Omni.Agent.Programs.Oracle where

import Omni.Agent.Op

-- | Run work with oracle advisor
-- Oracle watches progress and can inject advice
withOracle :: Model -> Op s a -> Op s a
withOracle oracleModel work = do
  -- Shared advice channel
  adviceRef <- liftIO (newIORef Nothing)
  
  -- Race between work completing and oracle advising
  -- But oracle should advise periodically, not complete
  -- So we need a different pattern...
  
  -- Better: oracle runs in parallel, work checks for advice periodically
  undefined

-- | Alternative: Explicit advice checkpoints
withOracleCheckpoints :: Model -> Int -> Op s a -> Op s a
withOracleCheckpoints oracleModel checkpointInterval work = do
  -- Wrap work with periodic oracle consultations
  -- Every N iterations, pause and ask oracle for advice
  undefined

-- | The oracle advisory loop
oracleAdvisor :: Model -> TVar (Maybe Text) -> Op s ()
oracleAdvisor model adviceRef = do
  -- Get current state and trace
  state <- get
  trace <- getTrace
  
  -- Ask oracle for advice
  advice <- infer model (oraclePrompt state trace)
  
  -- Post advice
  liftIO (writeIORef adviceRef (Just advice))
  
  -- Emit event
  emit (EventCustom "oracle_advice" (toJSON advice))
  
  -- Wait and repeat
  liftIO (threadDelay 30_000_000)  -- 30 seconds
  oracleAdvisor model adviceRef

-- | Worker that checks for oracle advice
workWithAdvice :: IORef (Maybe Text) -> Op s a -> Op s a
workWithAdvice adviceRef baseWork = do
  -- Check for advice
  advice <- liftIO (readIORef adviceRef)
  case advice of
    Nothing -> baseWork
    Just adv -> do
      -- Incorporate advice into context
      emit (EventCustom "incorporating_advice" (toJSON adv))
      -- Clear advice
      liftIO (writeIORef adviceRef Nothing)
      -- Continue work with advice in mind
      -- (The agent will see the advice event in trace and adjust)
      baseWork

2. Practical Oracle Pattern

-- | More practical: oracle consultation at key decision points
consultOracle :: Model -> Text -> Op s Text
consultOracle oracleModel question = do
  state <- get
  trace <- getTrace
  
  emit (EventCustom "oracle_consultation" (toJSON question))
  
  advice <- infer oracleModel (oracleConsultPrompt question state trace)
  
  emit (EventCustom "oracle_response" (toJSON advice))
  
  pure (responseContent advice)

-- | Coder with oracle for architecture decisions
coderWithOracle :: Model -> Model -> Namespace -> Task -> Op CodeState Result
coderWithOracle workerModel oracleModel ns task = do
  -- First, consult oracle for approach
  approach <- consultOracle oracleModel 
    ("How should I approach this task? " <> task)
  
  -- Do initial work
  checkpoint "after-planning"
  initialWork <- doWork workerModel approach
  
  -- Hit a tricky problem? Consult oracle
  when (hasError initialWork) do
    advice <- consultOracle oracleModel
      ("I hit this error: " <> getError initialWork <> ". What should I try?")
    doWork workerModel advice
  
  -- Continue...
  checkpoint "work-complete"
  verify ns

3. Racing Oracle (for fast feedback)

-- | Race worker against oracle
-- If oracle spots a problem before worker finishes, cancel and restart
raceWithOracle :: Model -> Model -> Op s a -> Op s a
raceWithOracle workerModel oracleModel work = do
  result <- race
    [ Left <$> work
    , Right <$> oracleWatchdog oracleModel
    ]
  
  case result of
    Left a -> pure a  -- work completed
    Right warning -> do
      -- Oracle spotted a problem
      emit (EventCustom "oracle_intervention" (toJSON warning))
      -- Could: restart work with warning in context
      -- Could: ask user what to do
      -- Could: continue anyway
      work  -- for now, just continue

oracleWatchdog :: Model -> Op s Text
oracleWatchdog model = do
  -- Periodically check trace for warning signs
  loop where
    loop = do
      liftIO (threadDelay 10_000_000)  -- 10 seconds
      trace <- getTrace
      state <- get
      
      -- Ask oracle if anything looks wrong
      response <- infer model (watchdogPrompt trace state)
      
      if detectsProblems response
        then pure (responseContent response)
        else loop

Notes

  • Oracle is for high-stakes decisions, not every step
  • Use expensive model (Opus, O3) sparingly
  • Race lets oracle interrupt runaway workers
  • Advice events create audit trail
  • Keep oracle prompts focused

Challenges

  • Running truly parallel advisory is complex
  • Better to have explicit consultation points
  • Or use Race for time-limited work

Testing

  • consultOracle calls oracle model
  • raceWithOracle cancels loser
  • Events capture oracle interactions
  • Oracle advice affects subsequent behavior

Files to Read First

  • Omni/Agent/Op.hs
  • Omni/Agent/Interpreter/Parallel.hs (for Race)
  • Anthropic oracle/advisor patterns

Timeline (2)

🔄[human]Open → InProgress1 month ago
🔄[human]InProgress → Done1 month ago