harn-vm 0.5.5

Async bytecode virtual machine for the Harn programming language
Documentation
import "std/collections"
import "std/context"

pub fn workflow_model_spec(config) {
  let target = config?.model ?? config?.model_alias ?? config?.model_tier ?? config?.tier
  if target == nil || target == "" {
    return nil
  }
  return llm_pick_model(target, filter_nil({provider: config?.provider}))
}

pub fn workflow_options(config) {
  let spec = workflow_model_spec(config)
  return filter_nil({
    provider: config?.provider ?? spec?.provider,
    model: config?.model ?? spec?.id,
    max_tokens: config?.max_tokens,
    temperature: config?.temperature,
    top_p: config?.top_p,
    top_k: config?.top_k,
    stop: config?.stop,
    seed: config?.seed,
    frequency_penalty: config?.frequency_penalty,
    presence_penalty: config?.presence_penalty,
    response_format: config?.response_format,
    schema: config?.schema,
    thinking: config?.thinking,
    tools: config?.tools,
    tool_choice: config?.tool_choice,
    cache: config?.cache,
    timeout: config?.timeout,
    persistent: config?.persistent,
    max_iterations: config?.max_iterations,
    max_nudges: config?.max_nudges,
    nudge: config?.nudge,
    tool_retries: config?.tool_retries,
    tool_backoff_ms: config?.tool_backoff_ms,
    tool_format: config?.tool_format,
    transcript: config?.transcript
  })
}

pub fn stage_config(flow, overrides, stage_name) {
  let combined = (flow ?? {}) + (overrides ?? {})
  let stage = combined[stage_name] ?? {}
  let merged = combined + stage
  return filter_nil(merged + {_stage: stage_name})
}

pub fn stage_prompt(task, config) {
  let ctx = config?.context
  return prompt_compose(task, ctx, filter_nil({
    system: config?.system,
    task_label: config?.task_label,
    separator: config?.context_separator,
    max_chars: config?.context_max_chars,
    section_max_chars: config?.context_section_max_chars
  }))
}

pub fn run_stage(task, config) {
  let prompt = stage_prompt(task, config)
  let opts = workflow_options(config)
  if config?.mode == "completion" {
    return llm_completion(prompt?.prompt, config?.suffix, prompt?.system, opts)
  }
  if config?.mode == "llm" || config?.persistent == false {
    return llm_call(prompt?.prompt, prompt?.system, opts)
  }
  return agent_loop(prompt?.prompt, prompt?.system, opts + {
    persistent: config?.persistent ?? true
  })
}

pub fn verify_command(config) {
  if config?.command == nil || config?.command == "" {
    return nil
  }
  let output = host_invoke("process", "exec", {command: config?.command})
  var ok = output?.success == true
  if config?.expect_status != nil {
    ok = output?.status == config?.expect_status
  }
  if config?.expect_text != nil {
    ok = ok && contains(output?.combined ?? "", config?.expect_text)
  }
  return {
    kind: "command",
    ok: ok,
    output: output
  }
}

pub fn verify_result(task, result, config) {
  if config == nil {
    return nil
  }
  if config?.command != nil {
    return verify_command(config)
  }
  if config?.assert_text != nil {
    return {
      kind: "text",
      ok: contains(result?.text ?? "", config?.assert_text),
      output: result?.text ?? ""
    }
  }
  return nil
}

pub fn repair_task(original_task, verification, config) {
  if config?.prompt != nil {
    return config?.prompt
  }
  let summary = json_stringify(verification)
  let message = "The previous attempt did not pass verification.\n\nVerification:\n" + summary + "\n\nContinue working on the original task and fix the problem.\n\nOriginal task:\n" + original_task
  return message
}

pub fn workflow(config) {
  return workflow_graph(config ?? {})
}

pub fn task_run(task, flow, overrides) {
  let graph = workflow_graph(flow ?? {})
  let runtime = workflow_execute(task, graph, overrides?.artifacts ?? [], overrides)
  let stages = runtime?.run?.stages ?? []
  var act = nil
  var verify = nil
  var repair = nil
  let artifacts = runtime?.artifacts ?? []
  let latest_text = if len(artifacts) > 0 {
    artifacts[len(artifacts) - 1]?.text
  } else {
    act?.visible_text
  }
  for stage in stages {
    if act == nil {
      act = stage
      continue
    }
    if verify == nil && (stage?.node_id == "verify" || stage?.kind == "verify") {
      verify = stage
      continue
    }
    if repair == nil && stage?.node_id == "repair" {
      repair = stage
    }
  }
  let status = if verify?.status == "failed" || repair != nil {
    "needs_attention"
  } else {
    runtime?.status ?? "completed"
  }
  return {
    task: task,
    workflow: graph?.name ?? "workflow",
    status: status,
    text: latest_text,
    result: runtime,
    act: act,
    repair: repair,
    verification: verify,
    final_verification: verify,
    transcript: runtime?.transcript,
    run: runtime?.run,
    artifacts: artifacts
  }
}

pub fn workflow_continue(prev, task, flow, overrides) {
  let transcript = prev?.transcript ?? prev
  let merged = (overrides ?? {}) + {transcript: transcript}
  return task_run(task, flow, merged)
}

pub fn workflow_compact(prev, options) {
  let transcript = prev?.transcript ?? prev
  return transcript_summarize(transcript, options)
}

pub fn workflow_reset(prev, carry_summary) {
  let transcript = prev?.transcript ?? prev
  if carry_summary && transcript_summary(transcript) {
    return transcript_compact(transcript, {keep_last: 0})
  }
  return transcript()
}