harn-stdlib 0.8.21

Embedded Harn standard library source catalog
Documentation
import { agent_session_inject_feedback } from "std/agent/state"

fn __default_done_sentinel(opts) {
  return opts?.done_sentinel
}

fn __sentinel_hit(text, sentinel, parsed_done_marker) {
  if sentinel == nil {
    return false
  }
  if parsed_done_marker != nil && parsed_done_marker != "" {
    return contains(parsed_done_marker, sentinel)
  }
  return contains(text, sentinel)
}

fn __dispatch_results_list(dispatch) {
  if dispatch == nil {
    return []
  }
  if type_of(dispatch) == "list" {
    return dispatch
  }
  return dispatch?.results ?? []
}

fn __tool_result_ok(result) {
  if result?.ok != nil {
    return result.ok ? true : false
  }
  if result?.success != nil {
    return result.success ? true : false
  }
  let status = result?.status ?? ""
  return status == "ok" || status == "success"
}

fn __tool_result_name(result) {
  return result?.tool_name ?? result?.name ?? ""
}

fn __tool_names_by_status(dispatch, want_ok) {
  let results = __dispatch_results_list(dispatch)
  var names = []
  for result in results {
    let name = __tool_result_name(result)
    if name != "" && __tool_result_ok(result) == want_ok {
      names = names.push(name)
    }
  }
  return names
}

fn __post_turn_callback_verdict(opts, payload) {
  let cb = opts?.post_turn_callback
  if cb == nil {
    return {kind: "none"}
  }
  let verdict = cb(payload)
  return __interpret_verdict(verdict)
}

fn __interpret_verdict(verdict) {
  if verdict == nil || verdict == "" {
    return {kind: "none"}
  }
  if type_of(verdict) == "bool" {
    return if verdict {
      {kind: "stop"}
    } else {
      {kind: "none"}
    }
  }
  if type_of(verdict) == "string" {
    return {kind: "inject", message: verdict}
  }
  if type_of(verdict) == "dict" {
    let stop = verdict?.stop ?? false
    let base_llm_options = if type_of(verdict?.llm_options) == "dict" {
      verdict.llm_options
    } else {
      {}
    }
    let llm_options = if verdict?.prefill != nil && verdict?.prefill != "" {
      base_llm_options + {prefill: verdict?.prefill}
    } else {
      verdict?.llm_options
    }
    return {
      kind: "rich",
      stop: stop,
      stop_reason: verdict?.stop_reason,
      message: verdict?.message,
      next_options: verdict?.next_options,
      llm_options: llm_options,
    }
  }
  return {kind: "none"}
}

fn __successful_tool_names(dispatch) {
  return __tool_names_by_status(dispatch, true)
}

fn __rejected_tool_names(dispatch) {
  return __tool_names_by_status(dispatch, false)
}

fn __stop_after_successful_tools(opts, dispatch) {
  let names = opts?.stop_after_successful_tools
  if names == nil || len(names) == 0 {
    return false
  }
  let successful = __successful_tool_names(dispatch)
  for required in names {
    if contains(successful, required) {
      return true
    }
  }
  return false
}

fn __native_tool_text_completion(opts, has_tool_calls, text) {
  if !(opts?.loop_until_done ?? false) || opts?.daemon {
    return false
  }
  if opts?.tool_format != "native" || opts?.tools == nil {
    return false
  }
  if __default_done_sentinel(opts) != nil {
    return false
  }
  if has_tool_calls {
    return false
  }
  return trim(text) != ""
}

fn __done_judge_config(opts) {
  let judge = opts?.done_judge
  if judge == nil {
    return nil
  }
  if type_of(judge) == "bool" {
    return if judge {
      {}
    } else {
      nil
    }
  }
  if type_of(judge) == "dict" {
    return judge
  }
  return nil
}

fn __done_judge_cadence(opts) {
  let judge = __done_judge_config(opts)
  if judge == nil {
    return nil
  }
  let cadence = judge?.cadence
  if type_of(cadence) == "dict" {
    return cadence
  }
  return {}
}

fn __done_judge_loop_state(opts, completion_proposed) {
  let state = opts?._done_judge_loop_state ?? {}
  let base_completion = state?.completion ?? {}
  let completion = base_completion + {proposed: completion_proposed}
  return state + {completion: completion}
}

fn __done_judge_when_due(opts, cadence, state) {
  let when = cadence?.when ?? "always"
  if type_of(when) == "closure" {
    return when(state) ? true : false
  }
  if when == "always" {
    return true
  }
  if when == "stalled" {
    let trigger = opts?._done_judge_trigger ?? ""
    let stalled = state?.stall?.triggered ?? false
    return trigger == "stalled" || stalled
  }
  return false
}

fn __done_judge_every_due(cadence, turn_number) {
  let every = cadence?.every
  if every == nil {
    return true
  }
  return turn_number % every == 0
}

fn __done_judge_past_warmup(cadence, turn_number) {
  let min_iterations = cadence?.min_iterations_before_first
  if min_iterations == nil {
    return true
  }
  return turn_number > min_iterations
}

fn __done_judge_under_cap(opts, cadence) {
  let max_invocations = cadence?.max_invocations
  if max_invocations == nil {
    return true
  }
  let invocations = opts?._done_judge_invocations ?? 0
  return invocations < max_invocations
}

fn __done_judge_due(opts, payload, completion_proposed) {
  let cadence = __done_judge_cadence(opts)
  if cadence == nil {
    return false
  }
  let raw_iteration = payload?.iteration ?? 0
  let turn_number = raw_iteration + 1
  let state = __done_judge_loop_state(opts, completion_proposed)
  return __done_judge_under_cap(opts, cadence)
    && __done_judge_past_warmup(cadence, turn_number)
    && __done_judge_every_due(cadence, turn_number)
    && __done_judge_when_due(opts, cadence, state)
}

fn __completion_result(opts, payload, stop_reason) {
  let verify_due = opts?.verify_completion != nil || opts?.verify_completion_judge != nil
  let done_due = __done_judge_due(opts, payload, true)
  if verify_due || done_due {
    return {kind: "break", stop_reason: stop_reason, needs_verify: true, done_judge_due: done_due}
  }
  if __done_judge_config(opts) != nil {
    return {kind: "continue", done_judge_due: false}
  }
  return {kind: "break", stop_reason: stop_reason, needs_verify: false, done_judge_due: false}
}

fn __post_turn_verdict_result(session, opts, verdict) {
  if verdict.kind == "stop" {
    return {kind: "break", stop_reason: "post_turn_stop", needs_verify: opts?.verify_completion != nil}
  }
  if verdict.kind == "inject" {
    agent_session_inject_feedback(session.session_id, "post_turn", verdict.message)
    return {kind: "continue"}
  }
  if verdict.kind != "rich" {
    return nil
  }
  if verdict.message != nil {
    agent_session_inject_feedback(session.session_id, "post_turn", verdict.message)
  }
  if verdict.stop {
    let stop_reason = if verdict?.stop_reason != nil && verdict.stop_reason != "" {
      to_string(verdict.stop_reason)
    } else {
      "post_turn_stop"
    }
    return {
      kind: "break",
      stop_reason: stop_reason,
      needs_verify: opts?.verify_completion != nil,
      next_options: verdict?.next_options,
      llm_options: verdict?.llm_options,
    }
  }
  if verdict.message != nil || verdict?.next_options != nil || verdict?.llm_options != nil {
    return {kind: "continue", next_options: verdict?.next_options, llm_options: verdict?.llm_options}
  }
  return nil
}

/** agent_extract_tool_calls. */
pub fn agent_extract_tool_calls(llm_result, opts) {
  if len(llm_result?.tool_calls ?? []) > 0 {
    return llm_result.tool_calls
  }
  if opts?.tools == nil {
    return []
  }
  let parsed = agent_parse_tool_calls(llm_result?.text ?? "", opts.tools)
  return parsed?.calls ?? []
}

/** agent_compute_post_turn. */
pub fn agent_compute_post_turn(session, llm_result, dispatch, opts, iteration) {
  let sentinel = __default_done_sentinel(opts)
  let text = llm_result?.text ?? ""
  let sentinel_text = llm_result?.raw_text ?? text
  let parsed_done_marker = llm_result?.parsed_done_marker
  let dispatch_results = __dispatch_results_list(dispatch)
  let successful_tool_names = __successful_tool_names(dispatch)
  let rejected_tool_names = __rejected_tool_names(dispatch)
  let has_tool_calls = len(llm_result?.tool_calls ?? []) > 0 || len(dispatch_results) > 0
  let payload = {
    session_id: session.session_id,
    session: {id: session.session_id},
    iteration: iteration,
    has_tool_calls: has_tool_calls,
    dispatch: dispatch,
    tool_results: dispatch_results,
    tool_count: len(dispatch_results),
    successful_tool_names: successful_tool_names,
    rejected_tool_names: rejected_tool_names,
    session_successful_tools: opts?._session_successful_tools ?? successful_tool_names,
    session_rejected_tools: opts?._session_rejected_tools ?? rejected_tool_names,
    text: text,
    visible_text: text,
  }
  __host_fire_session_hook("post_turn", payload)
  if __sentinel_hit(sentinel_text, sentinel, parsed_done_marker) {
    return __completion_result(opts, payload, "sentinel")
  }
  if __stop_after_successful_tools(opts, dispatch) {
    return {kind: "break", stop_reason: "natural", needs_verify: false, done_judge_due: false}
  }
  let verdict = __post_turn_callback_verdict(opts, payload)
  let verdict_result = __post_turn_verdict_result(session, opts, verdict)
  if verdict_result != nil {
    return verdict_result
  }
  if !has_tool_calls && trim(text) != "" && opts?.done_judge != nil {
    return __completion_result(opts, payload, "natural")
  }
  if __native_tool_text_completion(opts, has_tool_calls, text) {
    return __completion_result(opts, payload, "natural")
  }
  let loop_until_done = opts?.loop_until_done ?? false
  let daemon = opts?.daemon ?? false
  if !has_tool_calls && !loop_until_done && !daemon {
    return __completion_result(opts, payload, "natural")
  }
  return {kind: "continue", done_judge_due: false}
}