harn-stdlib 0.7.58

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
    return {
      kind: "rich",
      stop: stop,
      message: verdict?.message,
      next_options: verdict?.next_options,
      llm_options: verdict?.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) != ""
}

/** 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
  if __sentinel_hit(sentinel_text, sentinel, parsed_done_marker) {
    return {
      kind: "break",
      stop_reason: "sentinel",
      needs_verify: opts?.done_judge != nil || opts?.verify_completion != nil
        || opts?.verify_completion_judge != nil,
    }
  }
  if __stop_after_successful_tools(opts, dispatch) {
    return {kind: "break", stop_reason: "natural", needs_verify: false}
  }
  let payload = {
    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,
  }
  let verdict = __post_turn_callback_verdict(opts, payload)
  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" && verdict.message != nil {
    agent_session_inject_feedback(session.session_id, "post_turn", verdict.message)
  }
  if verdict.kind == "rich" && verdict.stop {
    return {
      kind: "break",
      stop_reason: "post_turn_stop",
      needs_verify: opts?.verify_completion != nil,
      next_options: verdict?.next_options,
      llm_options: verdict?.llm_options,
    }
  }
  if verdict.kind == "rich"
    && (verdict.message != nil || verdict?.next_options != nil || verdict?.llm_options != nil) {
    return {kind: "continue", next_options: verdict?.next_options, llm_options: verdict?.llm_options}
  }
  if __native_tool_text_completion(opts, has_tool_calls, text) {
    return {
      kind: "break",
      stop_reason: "natural",
      needs_verify: opts?.done_judge != nil || opts?.verify_completion != nil
        || opts?.verify_completion_judge != nil,
    }
  }
  let loop_until_done = opts?.loop_until_done ?? false
  let daemon = opts?.daemon ?? false
  if !has_tool_calls && !loop_until_done && !daemon {
    return {
      kind: "break",
      stop_reason: "natural",
      needs_verify: opts?.done_judge != nil || opts?.verify_completion != nil,
    }
  }
  return {kind: "continue"}
}